diff options
58 files changed, 2388 insertions, 1422 deletions
diff --git a/WebContent/VAADIN/themes/base/menubar/menubar.css b/WebContent/VAADIN/themes/base/menubar/menubar.css index e39598d7f2..45170ff99f 100644 --- a/WebContent/VAADIN/themes/base/menubar/menubar.css +++ b/WebContent/VAADIN/themes/base/menubar/menubar.css @@ -1,23 +1,20 @@ .v-menubar table { - white-space: nowrap; border-collapse: collapse; padding: 0; margin: 0; } -.v-menubar table { +.v-menubar .v-menubar-menuitem { + cursor: default; + vertical-align: middle; white-space: nowrap; - border-collapse: collapse; - padding: 0; - margin: 0; } -.v-menubar .menuitem { - cursor: default; +.v-menubar .v-menubar-menuitem * { + vertical-align: middle; } .v-menubar-submenu { background: #fff; } .v-menubar-submenu table { - white-space: nowrap; border-collapse: collapse; padding: 0; margin: 0; @@ -27,11 +24,54 @@ padding: 0; margin: 0; } -.v-menubar .menuitem-selected, -.v-menubar-submenu .menuitem-selected { +.v-menubar-menuitem-selected{ background: #333; color: #fff; } -.v-menubar-submenu .menuitem { +.v-menubar-submenu .v-menubar-menuitem { cursor: default; + vertical-align: middle; + white-space: nowrap; +} +.v-menubar-submenu .v-menubar-menuitem * { + vertical-align: middle; +} +.v-menubar-submenu-indicator { + display: none; + /* Arial has the most coverage for geometric entity characters */ + font-family: arial, helvetica, sans-serif; +} +.v-menubar-submenu .v-menubar-submenu-indicator { + display: inline; + display: inline-block; + zoom: 1; + margin-left: 1em; + float: right; + height: 100%; + font-size: 0.9em; +} +.v-ie6 .v-menubar-submenu .v-menubar-submenu-indicator { + position: absolute; + right: 0; + margin-right: 0; + margin-top: -2px; +} +.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator { + position: relative; + margin-left: 0; +} +.v-menubar-menuitem-disabled { + color: #999; +} +.v-menubar-more-menuitem { + /* Arial has the most coverage for geometric entity characters */ + font-family: arial, helvetica, sans-serif; +} +.v-menubar-separator span { + display: block; + text-indent: -9999px; + height: 1px; + margin: 3px 0; + overflow: hidden; + background: #ddd; }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/notification/notification.css b/WebContent/VAADIN/themes/base/notification/notification.css index 6ab069b08c..9455c25a36 100644 --- a/WebContent/VAADIN/themes/base/notification/notification.css +++ b/WebContent/VAADIN/themes/base/notification/notification.css @@ -4,6 +4,8 @@ cursor: pointer; overflow: hidden; padding: 1em; + max-width:85%; + } .v-Notification h1, .v-Notification p, @@ -12,7 +14,6 @@ .v-Notification-warning h1, .v-Notification-warning p { display: inline; - white-space: nowrap; margin: 0 0.5em 0 0; } .v-Notification-warning { @@ -36,6 +37,3 @@ display: block;
margin: 0;
}
-.v-Notification-system p {
- white-space: nowrap;
-}
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/shadow/shadow.css b/WebContent/VAADIN/themes/base/shadow/shadow.css index bc67f3cc59..209dd0e235 100644 --- a/WebContent/VAADIN/themes/base/shadow/shadow.css +++ b/WebContent/VAADIN/themes/base/shadow/shadow.css @@ -80,6 +80,6 @@ .v-ie6 .v-shadow { background: #000; filter: progid:DXImageTransform.Microsoft.Blur(pixelRadius=2) alpha(opacity=20); - margin-top: -3px; - margin-left: -4px; + margin-top: -2px; + margin-left: -2px; }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/styles.css b/WebContent/VAADIN/themes/base/styles.css index a1b560ec23..e0908ddd88 100644 --- a/WebContent/VAADIN/themes/base/styles.css +++ b/WebContent/VAADIN/themes/base/styles.css @@ -622,25 +622,22 @@ div.v-app-loading { } .v-menubar table { - white-space: nowrap; border-collapse: collapse; padding: 0; margin: 0; } -.v-menubar table { +.v-menubar .v-menubar-menuitem { + cursor: default; + vertical-align: middle; white-space: nowrap; - border-collapse: collapse; - padding: 0; - margin: 0; } -.v-menubar .menuitem { - cursor: default; +.v-menubar .v-menubar-menuitem * { + vertical-align: middle; } .v-menubar-submenu { background: #fff; } .v-menubar-submenu table { - white-space: nowrap; border-collapse: collapse; padding: 0; margin: 0; @@ -650,13 +647,56 @@ div.v-app-loading { padding: 0; margin: 0; } -.v-menubar .menuitem-selected, -.v-menubar-submenu .menuitem-selected { +.v-menubar-menuitem-selected{ background: #333; color: #fff; } -.v-menubar-submenu .menuitem { +.v-menubar-submenu .v-menubar-menuitem { cursor: default; + vertical-align: middle; + white-space: nowrap; +} +.v-menubar-submenu .v-menubar-menuitem * { + vertical-align: middle; +} +.v-menubar-submenu-indicator { + display: none; + /* Arial has the most coverage for geometric entity characters */ + font-family: arial, helvetica, sans-serif; +} +.v-menubar-submenu .v-menubar-submenu-indicator { + display: inline; + display: inline-block; + zoom: 1; + margin-left: 1em; + float: right; + height: 100%; + font-size: 0.9em; +} +.v-ie6 .v-menubar-submenu .v-menubar-submenu-indicator { + position: absolute; + right: 0; + margin-right: 0; + margin-top: -2px; +} +.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator { + position: relative; + margin-left: 0; +} +.v-menubar-menuitem-disabled { + color: #999; +} +.v-menubar-more-menuitem { + /* Arial has the most coverage for geometric entity characters */ + font-family: arial, helvetica, sans-serif; +} +.v-menubar-separator span { + display: block; + text-indent: -9999px; + height: 1px; + margin: 3px 0; + overflow: hidden; + background: #ddd; } .v-Notification { @@ -665,6 +705,8 @@ div.v-app-loading { cursor: pointer; overflow: hidden; padding: 1em; + max-width:85%; + } .v-Notification h1, .v-Notification p, @@ -673,7 +715,6 @@ div.v-app-loading { .v-Notification-warning h1, .v-Notification-warning p { display: inline; - white-space: nowrap; margin: 0 0.5em 0 0; } .v-Notification-warning { @@ -697,9 +738,6 @@ div.v-app-loading { display: block; margin: 0; } -.v-Notification-system p { - white-space: nowrap; -} .v-orderedlayout-margin-top, .v-horizontallayout-margin-top, @@ -1049,8 +1087,8 @@ div.v-progressindicator-indeterminate-disabled { .v-ie6 .v-shadow { background: #000; filter: progid:DXImageTransform.Microsoft.Blur(pixelRadius=2) alpha(opacity=20); - margin-top: -3px; - margin-left: -4px; + margin-top: -2px; + margin-left: -2px; } .v-slider { @@ -1349,6 +1387,9 @@ div.v-progressindicator-indeterminate-disabled { .v-ff2 .v-tabsheet-scroller { position: relative; } +.v-disabled .v-tabsheet-scroller { + display: none; +} .v-tabsheet-scrollerPrev, .v-tabsheet-scrollerNext, .v-tabsheet-scrollerPrev-disabled, @@ -1368,6 +1409,33 @@ div.v-progressindicator-indeterminate-disabled { .v-tabsheet-tabs .v-caption span { white-space: nowrap; } +.v-tabsheet-caption-close { + display: inline; + display: inline-block; + zoom: 1; + width: 16px; + height: 16px; + text-align: center; + font-weight: bold; + cursor: pointer; + vertical-align: middle; + user-select: none; + -khtml-user-select: none; + -ms-user-select: none; + -moz-user-select: none; + -webkit-user-select: none; +} +.v-tabsheet .v-disabled .v-tabsheet-caption-close { + cursor: default; + visibility: hidden; +} +.v-tabsheet-tabitemcell:hover .v-tabsheet-caption-close, +.v-ie6 .v-tabsheet-caption-close { + visibility: visible; +} +.v-ie6 .v-tabsheet-caption-close { + float: right; +} .v-tabsheet-tabitem { border: 1px solid #aaa; border-right: none; diff --git a/WebContent/VAADIN/themes/base/tabsheet/tabsheet.css b/WebContent/VAADIN/themes/base/tabsheet/tabsheet.css index 8520f35913..6fd1f1470a 100644 --- a/WebContent/VAADIN/themes/base/tabsheet/tabsheet.css +++ b/WebContent/VAADIN/themes/base/tabsheet/tabsheet.css @@ -39,6 +39,9 @@ .v-ff2 .v-tabsheet-scroller { position: relative; } +.v-disabled .v-tabsheet-scroller { + display: none; +} .v-tabsheet-scrollerPrev, .v-tabsheet-scrollerNext, .v-tabsheet-scrollerPrev-disabled, @@ -58,6 +61,33 @@ .v-tabsheet-tabs .v-caption span { white-space: nowrap; } +.v-tabsheet-caption-close { + display: inline; + display: inline-block; + zoom: 1; + width: 16px; + height: 16px; + text-align: center; + font-weight: bold; + cursor: pointer; + vertical-align: middle; + user-select: none; + -khtml-user-select: none; + -ms-user-select: none; + -moz-user-select: none; + -webkit-user-select: none; +} +.v-tabsheet .v-disabled .v-tabsheet-caption-close { + cursor: default; + visibility: hidden; +} +.v-tabsheet-tabitemcell:hover .v-tabsheet-caption-close, +.v-ie6 .v-tabsheet-caption-close { + visibility: visible; +} +.v-ie6 .v-tabsheet-caption-close { + float: right; +} .v-tabsheet-tabitem { border: 1px solid #aaa; border-right: none; diff --git a/WebContent/VAADIN/themes/reindeer/button/button.css b/WebContent/VAADIN/themes/reindeer/button/button.css index 1dc2e25551..fa8014cddb 100644 --- a/WebContent/VAADIN/themes/reindeer/button/button.css +++ b/WebContent/VAADIN/themes/reindeer/button/button.css @@ -1,16 +1,16 @@ /* Standard implementation of the button theme * These files contain styles that apply to all browsers */ -@import "standard.css"; -@import "primary-style.css"; -@import "small-style.css"; -@import "link-style.css"; +@import "button-standard.css"; +@import "button-primary-style.css"; +@import "button-small-style.css"; +@import "button-link-style.css"; /* Browser-specific corrections to the standard implementation */ -@import "safari.css"; -@import "firefox.css"; -@import "opera.css"; -@import "ie.css"; +@import "button-safari.css"; +@import "button-firefox.css"; +@import "button-opera.css"; +@import "button-ie.css"; diff --git a/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites-ie6.png b/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites-ie6.png Binary files differindex 028218a6ab..c11ee47f9e 100644 --- a/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites-ie6.png +++ b/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites-ie6.png diff --git a/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites.png b/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites.png Binary files differindex b68e51aca4..4a4537ac06 100644 --- a/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites.png +++ b/WebContent/VAADIN/themes/reindeer/common/img/vertical-sprites.png diff --git a/WebContent/VAADIN/themes/reindeer/menubar/menubar.css b/WebContent/VAADIN/themes/reindeer/menubar/menubar.css index a5090003cd..e109a04681 100644 --- a/WebContent/VAADIN/themes/reindeer/menubar/menubar.css +++ b/WebContent/VAADIN/themes/reindeer/menubar/menubar.css @@ -7,12 +7,13 @@ text-shadow: rgba(0,0,0,.9) 0 1px 0; } .v-menubar table { - margin-left: 8px; + margin: 0 8px; height: 23px; } -.v-menubar .menuitem { +.v-menubar .v-menubar-menuitem { padding: 3px 8px; height: 17px; + line-height: 16px; } .v-menubar-submenu { background: #f8f8f9; @@ -24,25 +25,33 @@ overflow: hidden; padding: 4px 0; } -.v-menubar-submenu .menuitem { - padding: 1px 15px 1px 10px; +.v-menubar-submenu .v-menubar-menuitem { + padding: 1px 20px 1px 10px; height: 16px; + line-height: 16px; } -.v-menubar .menuitem-selected, -.v-menubar-submenu .menuitem-selected { +.v-menubar .v-menubar-menuitem-selected, +.v-menubar-submenu .v-menubar-menuitem-selected { background: #4d749f repeat-x; background-image: url(../common/img/sel-bg.png); /** sprite-ref: verticals; sprite-alignment: repeat */ color: #fff; text-shadow: #3b5a7a 0 1px 0; } -.v-menubar .menuitem-selected { +.v-menubar .v-menubar-menuitem-selected { background-image: url(img/menu-sel-bg.png); /** sprite-ref: verticals; sprite-alignment: repeat */ } - -/* Submenu icon (remove after #2849 is fixed) */ -.v-menubar-submenu .menuitem img[align="right"] { - margin-right: -15px; +.v-menubar-submenu .v-menubar-submenu-indicator { + background: transparent url(img/submenu-icon.png) no-repeat right 70%; + width: 16px; + margin: 0 -20px 0 5px; + text-indent: -999px; + vertical-align: middle; } -.v-ie .v-menubar-submenu .menuitem img[align="right"] { - margin-top: -14px; +.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator { + margin: 0 -20px 0 0; + position: relative; + right: -4px; +} +.v-menubar-submenu .v-menubar-menuitem-selected .v-menubar-submenu-indicator { + background-image: url(img/submenu-icon-hover.png); }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/reindeer/panel/panel.css b/WebContent/VAADIN/themes/reindeer/panel/panel.css index 1faa9a66b4..583e5319eb 100644 --- a/WebContent/VAADIN/themes/reindeer/panel/panel.css +++ b/WebContent/VAADIN/themes/reindeer/panel/panel.css @@ -17,6 +17,8 @@ border-bottom: none; border-top: none; } +.blue .v-panel-caption, +.blue .v-panel-nocaption, .blue .v-panel-content { border-color: #a8bcc5; } @@ -24,11 +26,13 @@ .v-ff3 .v-panel-content { border-color: rgba(0,0,0,.1); } -.v-panel-content > div, -.v-ie6 .v-panel-content { +.v-panel-content > div { background: #fff; min-height: 100%; } +.v-ie6 .v-panel-content { + background: #fff; +} .v-panel-deco { height: 1px; border-top: 1px solid #bebebe; @@ -70,6 +74,9 @@ .v-panel-content-light > div { background: transparent; } +.v-ie6 .v-panel-content-light { + background: transparent; +} .v-panel-deco-light { height: 0; border: none; diff --git a/WebContent/VAADIN/themes/reindeer/styles.css b/WebContent/VAADIN/themes/reindeer/styles.css index e2f782424d..be563abfc3 100644 --- a/WebContent/VAADIN/themes/reindeer/styles.css +++ b/WebContent/VAADIN/themes/reindeer/styles.css @@ -622,25 +622,22 @@ div.v-app-loading { } .v-menubar table { - white-space: nowrap; border-collapse: collapse; padding: 0; margin: 0; } -.v-menubar table { +.v-menubar .v-menubar-menuitem { + cursor: default; + vertical-align: middle; white-space: nowrap; - border-collapse: collapse; - padding: 0; - margin: 0; } -.v-menubar .menuitem { - cursor: default; +.v-menubar .v-menubar-menuitem * { + vertical-align: middle; } .v-menubar-submenu { background: #fff; } .v-menubar-submenu table { - white-space: nowrap; border-collapse: collapse; padding: 0; margin: 0; @@ -650,13 +647,56 @@ div.v-app-loading { padding: 0; margin: 0; } -.v-menubar .menuitem-selected, -.v-menubar-submenu .menuitem-selected { +.v-menubar-menuitem-selected{ background: #333; color: #fff; } -.v-menubar-submenu .menuitem { +.v-menubar-submenu .v-menubar-menuitem { cursor: default; + vertical-align: middle; + white-space: nowrap; +} +.v-menubar-submenu .v-menubar-menuitem * { + vertical-align: middle; +} +.v-menubar-submenu-indicator { + display: none; + /* Arial has the most coverage for geometric entity characters */ + font-family: arial, helvetica, sans-serif; +} +.v-menubar-submenu .v-menubar-submenu-indicator { + display: inline; + display: inline-block; + zoom: 1; + margin-left: 1em; + float: right; + height: 100%; + font-size: 0.9em; +} +.v-ie6 .v-menubar-submenu .v-menubar-submenu-indicator { + position: absolute; + right: 0; + margin-right: 0; + margin-top: -2px; +} +.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator { + position: relative; + margin-left: 0; +} +.v-menubar-menuitem-disabled { + color: #999; +} +.v-menubar-more-menuitem { + /* Arial has the most coverage for geometric entity characters */ + font-family: arial, helvetica, sans-serif; +} +.v-menubar-separator span { + display: block; + text-indent: -9999px; + height: 1px; + margin: 3px 0; + overflow: hidden; + background: #ddd; } .v-Notification { @@ -665,6 +705,8 @@ div.v-app-loading { cursor: pointer; overflow: hidden; padding: 1em; + max-width:85%; + } .v-Notification h1, .v-Notification p, @@ -673,7 +715,6 @@ div.v-app-loading { .v-Notification-warning h1, .v-Notification-warning p { display: inline; - white-space: nowrap; margin: 0 0.5em 0 0; } .v-Notification-warning { @@ -697,9 +738,6 @@ div.v-app-loading { display: block; margin: 0; } -.v-Notification-system p { - white-space: nowrap; -} .v-orderedlayout-margin-top, .v-horizontallayout-margin-top, @@ -1049,8 +1087,8 @@ div.v-progressindicator-indeterminate-disabled { .v-ie6 .v-shadow { background: #000; filter: progid:DXImageTransform.Microsoft.Blur(pixelRadius=2) alpha(opacity=20); - margin-top: -3px; - margin-left: -4px; + margin-top: -2px; + margin-left: -2px; } .v-slider { @@ -1349,6 +1387,9 @@ div.v-progressindicator-indeterminate-disabled { .v-ff2 .v-tabsheet-scroller { position: relative; } +.v-disabled .v-tabsheet-scroller { + display: none; +} .v-tabsheet-scrollerPrev, .v-tabsheet-scrollerNext, .v-tabsheet-scrollerPrev-disabled, @@ -1368,6 +1409,33 @@ div.v-progressindicator-indeterminate-disabled { .v-tabsheet-tabs .v-caption span { white-space: nowrap; } +.v-tabsheet-caption-close { + display: inline; + display: inline-block; + zoom: 1; + width: 16px; + height: 16px; + text-align: center; + font-weight: bold; + cursor: pointer; + vertical-align: middle; + user-select: none; + -khtml-user-select: none; + -ms-user-select: none; + -moz-user-select: none; + -webkit-user-select: none; +} +.v-tabsheet .v-disabled .v-tabsheet-caption-close { + cursor: default; + visibility: hidden; +} +.v-tabsheet-tabitemcell:hover .v-tabsheet-caption-close, +.v-ie6 .v-tabsheet-caption-close { + visibility: visible; +} +.v-ie6 .v-tabsheet-caption-close { + float: right; +} .v-tabsheet-tabitem { border: 1px solid #aaa; border-right: none; @@ -2981,12 +3049,13 @@ td.v-datefield-calendarpanel-nextyear { text-shadow: rgba(0,0,0,.9) 0 1px 0; } .v-menubar table { - margin-left: 8px; + margin: 0 8px; height: 23px; } -.v-menubar .menuitem { +.v-menubar .v-menubar-menuitem { padding: 3px 8px; height: 17px; + line-height: 16px; } .v-menubar-submenu { background: #f8f8f9; @@ -2998,12 +3067,13 @@ td.v-datefield-calendarpanel-nextyear { overflow: hidden; padding: 4px 0; } -.v-menubar-submenu .menuitem { - padding: 1px 15px 1px 10px; +.v-menubar-submenu .v-menubar-menuitem { + padding: 1px 20px 1px 10px; height: 16px; + line-height: 16px; } -.v-menubar .menuitem-selected, -.v-menubar-submenu .menuitem-selected { +.v-menubar .v-menubar-menuitem-selected, +.v-menubar-submenu .v-menubar-menuitem-selected { background: #4d749f repeat-x; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); @@ -3011,18 +3081,25 @@ td.v-datefield-calendarpanel-nextyear { color: #fff; text-shadow: #3b5a7a 0 1px 0; } -.v-menubar .menuitem-selected { +.v-menubar .v-menubar-menuitem-selected { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); background-position: left -423px; } - -/* Submenu icon (remove after #2849 is fixed) */ -.v-menubar-submenu .menuitem img[align="right"] { - margin-right: -15px; +.v-menubar-submenu .v-menubar-submenu-indicator { + background: transparent url(menubar/img/submenu-icon.png) no-repeat right 70%; + width: 16px; + margin: 0 -20px 0 5px; + text-indent: -999px; + vertical-align: middle; +} +.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator { + margin: 0 -20px 0 0; + position: relative; + right: -4px; } -.v-ie .v-menubar-submenu .menuitem img[align="right"] { - margin-top: -14px; +.v-menubar-submenu .v-menubar-menuitem-selected .v-menubar-submenu-indicator { + background-image: url(menubar/img/submenu-icon-hover.png); } .v-Notification { @@ -3083,6 +3160,8 @@ td.v-datefield-calendarpanel-nextyear { border-bottom: none; border-top: none; } +.blue .v-panel-caption, +.blue .v-panel-nocaption, .blue .v-panel-content { border-color: #a8bcc5; } @@ -3090,11 +3169,13 @@ td.v-datefield-calendarpanel-nextyear { .v-ff3 .v-panel-content { border-color: rgba(0,0,0,.1); } -.v-panel-content > div, -.v-ie6 .v-panel-content { +.v-panel-content > div { background: #fff; min-height: 100%; } +.v-ie6 .v-panel-content { + background: #fff; +} .v-panel-deco { height: 1px; border-top: 1px solid #bebebe; @@ -3136,6 +3217,9 @@ td.v-datefield-calendarpanel-nextyear { .v-panel-content-light > div { background: transparent; } +.v-ie6 .v-panel-content-light { + background: transparent; +} .v-panel-deco-light { height: 0; border: none; @@ -3907,6 +3991,10 @@ td.v-datefield-calendarpanel-nextyear { border: none; } +/* These styles get catenated together on build */ + +/* Default Tabsheet styles */ + .v-tabsheet-tabitemcell, .v-tabsheet-spacertd { height: 32px; @@ -3945,30 +4033,80 @@ td.v-datefield-calendarpanel-nextyear { background-position: right -1304px; padding: 9px 8px 0 6px; } +.v-tabsheet-tabitem .v-caption-closable { + padding-right: 0; + padding-left: 17px; +} .v-tabsheet-tabitem .v-captiontext { height: 16px; line-height: 16px; } -.v-tabsheet-tabitemcell-selected { +.v-tabsheet-caption-close { + float: right; + width: 19px; + height: 18px; + margin: -1px -1px 0; + padding-left: 2px; + background: transparent; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); background-position: left -1336px; + cursor: default; + text-indent: -999px; + overflow: hidden; +} +.v-ff .v-tabsheet-caption-close, +.v-ie7 .v-tabsheet-caption-close { + margin-top: -17px; +} +.v-ie6 .v-tabsheet-caption-close { + float: none; +} +.v-tabsheet-caption-close:hover { + background-image: url(common/img/vertical-sprites.png); + -background-image: url(common/img/vertical-sprites-ie6.png); + background-position: left -1354px; +} +.v-tabsheet-caption-close:active { + background-image: url(common/img/vertical-sprites.png); + -background-image: url(common/img/vertical-sprites-ie6.png); + background-position: left -1372px; +} +.v-tabsheet-tabitem-selected .v-tabsheet-caption-close { + background-image: url(common/img/vertical-sprites.png); + -background-image: url(common/img/vertical-sprites-ie6.png); + background-position: left -1390px; +} +.v-tabsheet-tabitem-selected .v-tabsheet-caption-close:hover { + background-image: url(common/img/vertical-sprites.png); + -background-image: url(common/img/vertical-sprites-ie6.png); + background-position: left -1408px; +} +.v-tabsheet-tabitem-selected .v-tabsheet-caption-close:active { + background-image: url(common/img/vertical-sprites.png); + -background-image: url(common/img/vertical-sprites-ie6.png); + background-position: left -1426px; +} +.v-tabsheet-tabitemcell-selected { + background-image: url(common/img/vertical-sprites.png); + -background-image: url(common/img/vertical-sprites-ie6.png); + background-position: left -1444px; } .v-tabsheet-tabitemcell-selected-first { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1368px; + background-position: left -1476px; } .v-tabsheet-tabitem-selected { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1400px; + background-position: left -1508px; color: #232930; } .v-tabsheet-tabitem-selected .v-caption { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: right -1432px; + background-position: right -1540px; } .v-tabsheet-spacertd div { margin-right: 4px; @@ -3977,7 +4115,7 @@ td.v-datefield-calendarpanel-nextyear { background: transparent no-repeat right top; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: right -1464px; + background-position: right -1572px; } .v-tabsheet-content { border: 1px solid #dcdcdc; @@ -4011,13 +4149,53 @@ td.v-datefield-calendarpanel-nextyear { border-top-color: rgba(0,0,0,.1); background: rgba(0,0,0,.08); } + + +/* Icons & error indicators */ + +.v-tabsheet-tabs .v-icon, +.v-tabsheet-tabs .v-captiontext, +.v-tabsheet-tabs .v-errorindicator { + display: inline; + float: none; +} +.v-sa .v-tabsheet-tabs .v-captiontext { + display: inline-block; +} +.v-tabsheet-tabs .v-icon { + width: 16px !important; + height: 16px !important; +} +.v-tabsheet-tabs .v-errorindicator { + display: inline-block; + width: 13px; + height: 16px; + background: transparent url(common/icons/error.png) no-repeat 50%; +} +.v-ff2 .v-tabsheet-tabs .v-icon, +.v-ff2 .v-tabsheet-tabs .v-errorindicator { + display: -moz-inline-stack; +} +.v-ie6 .v-tabsheet-tabs .v-errorindicator { + background-image: url(common/icons/error-ie6.png); +} +.v-ie .v-tabsheet-tabs .v-errorindicator { + zoom: 1; + display: inline; +} + +/* Tabsheet scroller styles */ + .v-tabsheet-scroller { height: 31px; margin-top: -31px; - padding-right: 3px; - border-right: 1px solid #afafaf; + padding: 0 3px 0 4px; + border-right: 1px solid #c2c2c2; + border-left: 1px solid #cfcfcf; position: relative; float: right; + background: transparent url(tabsheet/img/framed/tab-bg.png) repeat-x left -1px; + width: 36px; } .v-tabsheet-scroller button { margin-top: 7px; @@ -4030,7 +4208,7 @@ td.v-datefield-calendarpanel-nextyear { background: transparent; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1496px; + background-position: left -1604px; width: 18px; height: 17px; overflow: hidden; @@ -4042,23 +4220,23 @@ td.v-datefield-calendarpanel-nextyear { .v-tabsheet-scrollerNext { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1513px; + background-position: left -1621px; } .v-tabsheet-scrollerPrev:active { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1530px; + background-position: left -1638px; } .v-tabsheet-scrollerNext:active { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1547px; + background-position: left -1655px; } .v-tabsheet-scrollerPrev-disabled, .v-tabsheet-scrollerPrev-disabled:active { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1564px; + background-position: left -1672px; opacity: 1; filter: none; } @@ -4066,48 +4244,13 @@ td.v-datefield-calendarpanel-nextyear { .v-tabsheet-scrollerNext-disabled:active { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1581px; + background-position: left -1689px; opacity: 1; filter: none; } -.v-tabsheet-tabs .v-icon, -.v-tabsheet-tabs .v-captiontext, -.v-tabsheet-tabs .v-errorindicator { - display: inline; - float: none; -} -.v-sa .v-tabsheet-tabs .v-captiontext { - display: inline-block; -} -.v-tabsheet-tabs .v-icon { - width: 16px !important; - height: 16px !important; -} -.v-tabsheet-tabs .v-errorindicator { - display: inline-block; - width: 13px; - height: 16px; - background: transparent url(common/icons/error.png) no-repeat 50%; -} -.v-ff2 .v-tabsheet-tabs .v-icon, -.v-ff2 .v-tabsheet-tabs .v-errorindicator { - display: -moz-inline-stack; -} -.v-ie6 .v-tabsheet-tabs .v-errorindicator { - background-image: url(common/icons/error-ie6.png); -} -.v-ie .v-tabsheet-tabs .v-errorindicator { - zoom: 1; - display: inline; -} - - - - - /** - * Minimal style -------------- + * Tabsheet "minimal" style -------------- */ .v-tabsheet-minimal .v-tabsheet-spacertd div { border-bottom: 1px solid #bfbfbf; @@ -4147,6 +4290,10 @@ td.v-datefield-calendarpanel-nextyear { background: transparent; padding: 4px 15px 6px 15px; } +.v-tabsheet-minimal .v-tabsheet-tabitem .v-caption-closable, +.v-tabsheet-minimal .v-tabsheet-tabitem-selected .v-caption-closable { + padding-right: 6px; +} .v-tabsheet-content-minimal { border: none; } @@ -4160,20 +4307,58 @@ td.v-datefield-calendarpanel-nextyear { .v-tabsheet-minimal .v-tabsheet-scroller { margin-top: -20px; height: 17px; - padding-right: 0; - border-right: none; - position: static; - float: none; + padding: 0; + border: none; + background: transparent; } .v-tabsheet-minimal .v-tabsheet-scroller button { margin-top: 0; } +.v-tabsheet-minimal .v-tabsheet-caption-close, +.v-tabsheet-minimal .v-tabsheet-caption-close:hover, +.v-tabsheet-minimal .v-tabsheet-caption-close:active { + text-indent: 0; + background: transparent; + margin-left: 3px; + margin-right: -3px; + padding: 0; + color: #999; + width: 15px; + height: 15px; + line-height: 14px; + -webkit-border-radius: 7px; + -moz-border-radius: 7px; +} +.v-tabsheet-minimal .v-tabsheet-caption-close { + margin-top: 1px; +} +.v-ff .v-tabsheet-minimal .v-tabsheet-caption-close, +.v-ie7 .v-tabsheet-minimal .v-tabsheet-caption-close { + margin-top: -15px; +} +.v-tabsheet-minimal .v-tabsheet-caption-close:hover { + color: #fff; + background: #aaa; +} +.v-tabsheet-minimal .v-tabsheet-caption-close:active { + background: #777; +} /* Minimal tabsheet on blue background */ .blue .v-tabsheet-minimal .v-tabsheet-spacertd div, .blue .v-tabsheet-minimal .v-tabsheet-tabitem, .blue .v-tabsheet-minimal .v-tabsheet-tabitem-selected { border-color: #7c8a91; } +.blue .v-tabsheet-minimal .v-tabsheet-caption-close { + color: #7c8a91; +} +.blue .v-tabsheet-minimal .v-tabsheet-caption-close:hover { + color: #BCD3DE; + background: #778d98; +} +.blue .v-tabsheet-minimal .v-tabsheet-caption-close:active { + background: #4f6874; +} /* Minimal tabsheet on black background */ .black .v-tabsheet-minimal .v-tabsheet-spacertd div, .black .v-tabsheet-minimal .v-tabsheet-tabitem, @@ -4189,14 +4374,19 @@ td.v-datefield-calendarpanel-nextyear { color: #c9ccce; text-shadow: #000 0 0 1px; } - - - - - +.black .v-tabsheet-minimal .v-tabsheet-caption-close { + color: #72787c; +} +.black .v-tabsheet-minimal .v-tabsheet-caption-close:hover { + color: #1d2021; + background: #4d5154; +} +.black .v-tabsheet-minimal .v-tabsheet-caption-close:active { + background: #626669; +} /** - * Bar style --------------- + * Tabsheet bar style --------------- */ .v-tabsheet-bar .v-tabsheet-tabitemcell, .v-tabsheet-bar .v-tabsheet-spacertd { @@ -4208,20 +4398,20 @@ td.v-datefield-calendarpanel-nextyear { .v-tabsheet-bar .v-tabsheet-tabitemcell { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1599px; + background-position: left -1707px; } .v-tabsheet-bar .v-tabsheet-tabitemcell-first { padding-left: 6px; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1619px; + background-position: left -1727px; } .v-tabsheet-bar .v-tabsheet-tabitem, .v-tabsheet-bar .v-tabsheet-spacertd div { height: 20px; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1639px; + background-position: left -1747px; font-size: 11px; margin: 0; } @@ -4229,43 +4419,86 @@ td.v-datefield-calendarpanel-nextyear { height: 18px; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: right -1659px; + background-position: right -1767px; padding: 2px 12px 0 10px; } +.v-tabsheet-bar .v-tabsheet-tabitem .v-caption-closable, +.v-tabsheet-bar .v-tabsheet-tabitem-selected .v-caption-closable { + padding-right: 8px; + padding-left: 14px; +} +.v-tabsheet-bar .v-tabsheet-caption-close, +.v-tabsheet-bar .v-tabsheet-caption-close:hover, +.v-tabsheet-bar .v-tabsheet-caption-close:active { + text-indent: 0; + background: transparent; + margin-left: 3px; + margin-right: -3px; + padding: 0; + color: #3c3c3c; + width: 14px; + height: 14px; + line-height: 12px; + -webkit-border-radius: 7px; + -moz-border-radius: 7px; +} +.v-tabsheet-bar .v-tabsheet-caption-close { + margin-top: 0; +} +.v-ff .v-tabsheet-bar .v-tabsheet-caption-close, +.v-ie7 .v-tabsheet-bar .v-tabsheet-caption-close { + margin-top: -15px; +} +.v-tabsheet-bar .v-tabsheet-caption-close:hover { + background: #bfbfbf; + -webkit-box-shadow: 0 1px 0 #fff; +} +.v-tabsheet-bar .v-tabsheet-caption-close:active { + background: #a9a9a9; +} +.v-tabsheet-bar .v-tabsheet-tabitem-selected .v-tabsheet-caption-close { + color: #404142; +} +.v-tabsheet-bar .v-tabsheet-tabitem-selected .v-tabsheet-caption-close:hover { + background: #5e666e; + color: #fff; + text-shadow: 0 -1px 0 #222; +} +.v-tabsheet-bar .v-tabsheet-tabitem-selected .v-tabsheet-caption-close:active { + background: #404142; +} + .v-tabsheet-bar .v-tabsheet-tabitemcell-selected { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1679px; + background-position: left -1787px; } .v-tabsheet-bar .v-tabsheet-tabitemcell-selected-first { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1699px; + background-position: left -1807px; } .v-tabsheet-bar .v-tabsheet-tabitem-selected { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1719px; + background-position: left -1827px; color: #232930; } .v-tabsheet-bar .v-tabsheet-tabitem-selected .v-caption { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: right -1739px; -} -.v-tabsheet-bar .v-tabsheet-scroller { - margin-top: -19px; + background-position: right -1847px; } .v-tabsheet-bar .v-tabsheet-scroller { - margin-top: -19px; - height: 17px; - padding-right: 0; + margin-top: -20px; + height: 19px; border-right: none; - position: static; - float: none; + background-image: url(common/img/vertical-sprites.png); + -background-image: url(common/img/vertical-sprites-ie6.png); + background-position: left -1867px; } .v-tabsheet-bar .v-tabsheet-scroller button { - margin-top: 0; + margin-top: 1px; } .v-tabsheet-content-bar { border: none; @@ -4290,7 +4523,7 @@ td.v-datefield-calendarpanel-nextyear { background-repeat: repeat-x; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1759px; + background-position: left -1887px; border-radius: 3px; -moz-border-radius: 3px; margin: 0; @@ -4449,7 +4682,7 @@ input.v-textfield-readonly, background: #4d749f repeat-x; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1782px; + background-position: left -1910px; color: #fff; padding: 1px 2px; -webkit-border-radius: 2px; @@ -4504,7 +4737,7 @@ input.v-textfield-readonly, background: transparent repeat-x; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1802px; + background-position: left -1930px; } .v-window-header { font-weight: bold; @@ -4531,13 +4764,13 @@ input.v-textfield-readonly, background: transparent; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1839px; + background-position: left -1967px; } .v-window-footer { background-repeat: repeat-x; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1854px; + background-position: left -1982px; height: 15px; } .v-window-closebox { @@ -4548,17 +4781,17 @@ input.v-textfield-readonly, background: transparent; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1869px; + background-position: left -1997px; } .v-window-closebox:hover { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1885px; + background-position: left -2013px; } .v-window-closebox:active { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1901px; + background-position: left -2029px; } .v-window-contents { background: #fff; @@ -4591,7 +4824,7 @@ input.v-textfield-readonly, height: 12px; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1917px; + background-position: left -2045px; } .v-window-light .v-window-footer { background: transparent; @@ -4604,17 +4837,17 @@ input.v-textfield-readonly, height: 15px; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1929px; + background-position: left -2057px; } .v-window-light .v-window-closebox:hover { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1944px; + background-position: left -2072px; } .v-window-light .v-window-closebox:active { background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1959px; + background-position: left -2087px; } .v-window-light .v-window-contents { background: transparent; @@ -4624,7 +4857,7 @@ input.v-textfield-readonly, background: #f7f7f8 repeat-x; background-image: url(common/img/vertical-sprites.png); -background-image: url(common/img/vertical-sprites-ie6.png); - background-position: left -1974px; + background-position: left -2102px; } .v-ie6 .v-window-light .v-window-wrap2 { background-image: none; diff --git a/WebContent/VAADIN/themes/reindeer/tabsheet/tabsheet.css b/WebContent/VAADIN/themes/reindeer/tabsheet/tabsheet.css index 289660eb3b..fddef9a287 100644 --- a/WebContent/VAADIN/themes/reindeer/tabsheet/tabsheet.css +++ b/WebContent/VAADIN/themes/reindeer/tabsheet/tabsheet.css @@ -1,325 +1,5 @@ -.v-tabsheet-tabitemcell, -.v-tabsheet-spacertd { - height: 32px; -} -.v-tabsheet-tabitemcell { - background: no-repeat; - background-image: url(img/framed/tab-left.png); /** sprite-ref: verticals */ - padding-left: 3px; -} -.v-tabsheet-tabitemcell-first { - padding-left: 10px; - background-image: url(img/framed/tab-first-left.png); /** sprite-ref: verticals */ -} -.v-tabsheet-tabitem, -.v-tabsheet-spacertd div { - border: none; - height: 32px; - background: transparent repeat-x; - background-image: url(img/framed/tab-bg.png); /** sprite-ref: verticals; sprite-alignment: repeat */ - padding: 0; - color: #222; - text-shadow: #fff 0 1px 0; -} -.v-tabsheet-tabitem .v-caption { - border: none; - height: 23px; - background: no-repeat right top; - background-image: url(img/framed/tab-right.png); /** sprite-ref: verticals; sprite-alignment: right */ - padding: 9px 8px 0 6px; -} -.v-tabsheet-tabitem .v-captiontext { - height: 16px; - line-height: 16px; -} -.v-tabsheet-tabitemcell-selected { - background-image: url(img/framed/tab-left-sel.png); /** sprite-ref: verticals */ -} -.v-tabsheet-tabitemcell-selected-first { - background-image: url(img/framed/tab-first-left-sel.png); /** sprite-ref: verticals */ -} -.v-tabsheet-tabitem-selected { - background-image: url(img/framed/tab-bg-sel.png); /** sprite-ref: verticals; sprite-alignment: repeat */ - color: #232930; -} -.v-tabsheet-tabitem-selected .v-caption { - background-image: url(img/framed/tab-right-sel.png); /** sprite-ref: verticals; sprite-alignment: right */ -} -.v-tabsheet-spacertd div { - margin-right: 4px; -} -.v-tabsheet-spacertd { - background: transparent no-repeat right top; - background-image: url(img/framed/tab-spacer-right.png); /** sprite-ref: verticals; sprite-alignment: right */ -} -.v-tabsheet-content { - border: 1px solid #dcdcdc; - border-bottom: none; - border-top: none; - color: #222; - text-shadow: none; -} -.blue .v-tabsheet-content { - border-color: #a8bcc5; -} -.v-tabsheet-tabsheetpanel { - background: #fff; -} -.v-sa .v-tabsheet-content, -.v-ff3 .v-tabsheet-content { - border-color: rgba(0,0,0,.1); -} -.v-tabsheet-deco { - height: 1px; - border-top: 1px solid #bebebe; - background: #e2e2e2; - overflow: hidden; -} -.blue .v-tabsheet-deco { - border-color: #92a3ac; - background: #adc2cd; -} -.v-sa .v-tabsheet-deco, -.v-ff3 .v-tabsheet-deco { - border-top-color: rgba(0,0,0,.1); - background: rgba(0,0,0,.08); -} -.v-tabsheet-scroller { - height: 31px; - margin-top: -31px; - padding-right: 3px; - border-right: 1px solid #afafaf; - position: relative; - float: right; -} -.v-tabsheet-scroller button { - margin-top: 7px; -} -.v-tabsheet-scrollerPrev, -.v-tabsheet-scrollerNext, -.v-tabsheet-scrollerPrev-disabled, -.v-tabsheet-scrollerNext-disabled { - border: none; - background: transparent; - background-image: url(img/tab-prev.png); /** sprite-ref: verticals */ - width: 18px; - height: 17px; - overflow: hidden; - cursor: default; -} -.v-tabsheet-scroller button::-moz-focus-inner { - border: none; -} -.v-tabsheet-scrollerNext { - background-image: url(img/tab-next.png); /** sprite-ref: verticals */ -} -.v-tabsheet-scrollerPrev:active { - background-image: url(img/tab-prev-pressed.png); /** sprite-ref: verticals */ -} -.v-tabsheet-scrollerNext:active { - background-image: url(img/tab-next-pressed.png); /** sprite-ref: verticals */ -} -.v-tabsheet-scrollerPrev-disabled, -.v-tabsheet-scrollerPrev-disabled:active { - background-image: url(img/tab-prev-disabled.png); /** sprite-ref: verticals */ - opacity: 1; - filter: none; -} -.v-tabsheet-scrollerNext-disabled, -.v-tabsheet-scrollerNext-disabled:active { - background-image: url(img/tab-next-disabled.png); /** sprite-ref: verticals; sprite-margin-bottom: 1px */ - opacity: 1; - filter: none; -} -.v-tabsheet-tabs .v-icon, -.v-tabsheet-tabs .v-captiontext, -.v-tabsheet-tabs .v-errorindicator { - display: inline; - float: none; -} -.v-sa .v-tabsheet-tabs .v-captiontext { - display: inline-block; -} -.v-tabsheet-tabs .v-icon { - width: 16px !important; - height: 16px !important; -} -.v-tabsheet-tabs .v-errorindicator { - display: inline-block; - width: 13px; - height: 16px; - background: transparent url(../common/icons/error.png) no-repeat 50%; -} -.v-ff2 .v-tabsheet-tabs .v-icon, -.v-ff2 .v-tabsheet-tabs .v-errorindicator { - display: -moz-inline-stack; -} -.v-ie6 .v-tabsheet-tabs .v-errorindicator { - background-image: url(../common/icons/error-ie6.png); -} -.v-ie .v-tabsheet-tabs .v-errorindicator { - zoom: 1; - display: inline; -} - - - - - - -/** - * Minimal style -------------- - */ -.v-tabsheet-minimal .v-tabsheet-spacertd div { - border-bottom: 1px solid #bfbfbf; - height: auto; - background: transparent; -} -.v-tabsheet-minimal .v-tabsheet-tabitemcell, -.v-tabsheet-minimal .v-tabsheet-spacertd { - height: auto; - background: transparent; - padding-left: 0; -} -.v-tabsheet-minimal .v-tabsheet-tabitem { - border: none; - border-bottom: 1px solid #bfbfbf; - color: #4d748f; - padding: 0; - height: auto; - background: transparent; - text-shadow: none; -} -.v-tabsheet-minimal .v-tabsheet-tabitem .v-caption { - padding: 5px 16px; - height: auto; - background: transparent; -} -.v-tabsheet-minimal .v-tabsheet-tabitemcell-selected { - background: transparent; -} -.v-tabsheet-minimal .v-tabsheet-tabitem-selected { - background: transparent; - border: 1px solid #bfbfbf; - border-bottom: none; - color: #222; -} -.v-tabsheet-minimal .v-tabsheet-tabitem-selected .v-caption { - background: transparent; - padding: 4px 15px 6px 15px; -} -.v-tabsheet-content-minimal { - border: none; -} -.v-tabsheet-content-minimal .v-tabsheet-tabsheetpanel { - background: transparent; -} -.v-tabsheet-deco-minimal { - height: 0; - border: none; -} -.v-tabsheet-minimal .v-tabsheet-scroller { - margin-top: -20px; - height: 17px; - padding-right: 0; - border-right: none; - position: static; - float: none; -} -.v-tabsheet-minimal .v-tabsheet-scroller button { - margin-top: 0; -} -/* Minimal tabsheet on blue background */ -.blue .v-tabsheet-minimal .v-tabsheet-spacertd div, -.blue .v-tabsheet-minimal .v-tabsheet-tabitem, -.blue .v-tabsheet-minimal .v-tabsheet-tabitem-selected { - border-color: #7c8a91; -} -/* Minimal tabsheet on black background */ -.black .v-tabsheet-minimal .v-tabsheet-spacertd div, -.black .v-tabsheet-minimal .v-tabsheet-tabitem, -.black .v-tabsheet-minimal .v-tabsheet-tabitem-selected { - border-color: #3e4044; - color: #6a7f89; -} -.black .v-tabsheet-minimal .v-tabsheet-tabitem-selected { - color: #c9ccce; -} -.black .v-tabsheet-content-minimal, -.black .v-tabsheet-content-bar { - color: #c9ccce; - text-shadow: #000 0 0 1px; -} - - - - - - -/** - * Bar style --------------- - */ -.v-tabsheet-bar .v-tabsheet-tabitemcell, -.v-tabsheet-bar .v-tabsheet-spacertd { - height: 20px; -} -.v-tabsheet-bar .v-tabsheet-spacertd { - background: transparent; -} -.v-tabsheet-bar .v-tabsheet-tabitemcell { - background-image: url(img/bar/tab-left.png); /** sprite-ref: verticals */ -} -.v-tabsheet-bar .v-tabsheet-tabitemcell-first { - padding-left: 6px; - background-image: url(img/bar/tab-first-left.png); /** sprite-ref: verticals */ -} -.v-tabsheet-bar .v-tabsheet-tabitem, -.v-tabsheet-bar .v-tabsheet-spacertd div { - height: 20px; - background-image: url(img/bar/tab-bg.png); /** sprite-ref: verticals; sprite-alignment: repeat */ - font-size: 11px; - margin: 0; -} -.v-tabsheet-bar .v-tabsheet-tabitem .v-caption { - height: 18px; - background-image: url(img/bar/tab-right.png); /** sprite-ref: verticals; sprite-alignment: right */ - padding: 2px 12px 0 10px; -} -.v-tabsheet-bar .v-tabsheet-tabitemcell-selected { - background-image: url(img/bar/tab-left-sel.png); /** sprite-ref: verticals */ -} -.v-tabsheet-bar .v-tabsheet-tabitemcell-selected-first { - background-image: url(img/bar/tab-first-left-sel.png); /** sprite-ref: verticals */ -} -.v-tabsheet-bar .v-tabsheet-tabitem-selected { - background-image: url(img/bar/tab-bg-sel.png); /** sprite-ref: verticals; sprite-alignment: repeat */ - color: #232930; -} -.v-tabsheet-bar .v-tabsheet-tabitem-selected .v-caption { - background-image: url(img/bar/tab-right-sel.png); /** sprite-ref: verticals; sprite-alignment: right */ -} -.v-tabsheet-bar .v-tabsheet-scroller { - margin-top: -19px; -} -.v-tabsheet-bar .v-tabsheet-scroller { - margin-top: -19px; - height: 17px; - padding-right: 0; - border-right: none; - position: static; - float: none; -} -.v-tabsheet-bar .v-tabsheet-scroller button { - margin-top: 0; -} -.v-tabsheet-content-bar { - border: none; -} -.v-tabsheet-content-bar .v-tabsheet-tabsheetpanel { - background: transparent; -} -.v-tabsheet-deco-bar { - height: 0; - border: none; -} -/* Content area font color specified with minimal style (reduces additional selectors) */
\ No newline at end of file +/* These styles get catenated together on build */ +@import "tabsheet-normal-style.css"; +@import "tabsheet-scroller.css"; +@import "tabsheet-minimal-style.css"; +@import "tabsheet-bar-style.css";
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/runo/menubar/menubar.css b/WebContent/VAADIN/themes/runo/menubar/menubar.css index 650d00b1f2..324713db6e 100644 --- a/WebContent/VAADIN/themes/runo/menubar/menubar.css +++ b/WebContent/VAADIN/themes/runo/menubar/menubar.css @@ -1,14 +1,14 @@ .v-menubar { color: #464f52; - border: 1px solid #c6cbcc; - border-right: none; + border-left: 1px solid #c6cbcc; } -.v-menubar .menuitem { +.v-menubar .v-menubar-menuitem { padding: 0 10px; margin: 0 10px; - border-right: 1px solid #c6cbcc; + border: 1px solid #c6cbcc; + border-left: none; } -.v-menubar .menuitem-selected { +.v-menubar .v-menubar-menuitem-selected { color: #fff; background: #5daee8; } @@ -23,10 +23,18 @@ border-top: 1px solid #d0d4d5; border-left: 1px solid #d0d4d5; } -.v-menubar-submenu .menuitem { - padding: 2px 10px; +.v-menubar-submenu .v-menubar-menuitem { + padding: 2px 16px 2px 10px; } -.v-menubar-submenu .menuitem-selected { +.v-menubar-submenu .v-menubar-menuitem-selected { color: #fff; background: #5daee8; +} +.v-menubar-submenu .v-menubar-submenu-indicator { + margin-right: -12px; + height: 14px; +} +.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator { + margin-right: -12px; + right: -3px; }
\ No newline at end of file diff --git a/WebContent/VAADIN/themes/runo/notification/notification.css b/WebContent/VAADIN/themes/runo/notification/notification.css index e526877f2d..431392d562 100644 --- a/WebContent/VAADIN/themes/runo/notification/notification.css +++ b/WebContent/VAADIN/themes/runo/notification/notification.css @@ -17,7 +17,6 @@ .v-Notification-warning p { display: inline; font-weight: normal; - white-space: nowrap; margin: 0 10px 0 0; } .v-Notification-warning { diff --git a/WebContent/VAADIN/themes/runo/styles.css b/WebContent/VAADIN/themes/runo/styles.css index 88e08840e1..8a35c1e439 100644 --- a/WebContent/VAADIN/themes/runo/styles.css +++ b/WebContent/VAADIN/themes/runo/styles.css @@ -622,25 +622,22 @@ div.v-app-loading { } .v-menubar table { - white-space: nowrap; border-collapse: collapse; padding: 0; margin: 0; } -.v-menubar table { +.v-menubar .v-menubar-menuitem { + cursor: default; + vertical-align: middle; white-space: nowrap; - border-collapse: collapse; - padding: 0; - margin: 0; } -.v-menubar .menuitem { - cursor: default; +.v-menubar .v-menubar-menuitem * { + vertical-align: middle; } .v-menubar-submenu { background: #fff; } .v-menubar-submenu table { - white-space: nowrap; border-collapse: collapse; padding: 0; margin: 0; @@ -650,13 +647,56 @@ div.v-app-loading { padding: 0; margin: 0; } -.v-menubar .menuitem-selected, -.v-menubar-submenu .menuitem-selected { +.v-menubar-menuitem-selected{ background: #333; color: #fff; } -.v-menubar-submenu .menuitem { +.v-menubar-submenu .v-menubar-menuitem { cursor: default; + vertical-align: middle; + white-space: nowrap; +} +.v-menubar-submenu .v-menubar-menuitem * { + vertical-align: middle; +} +.v-menubar-submenu-indicator { + display: none; + /* Arial has the most coverage for geometric entity characters */ + font-family: arial, helvetica, sans-serif; +} +.v-menubar-submenu .v-menubar-submenu-indicator { + display: inline; + display: inline-block; + zoom: 1; + margin-left: 1em; + float: right; + height: 100%; + font-size: 0.9em; +} +.v-ie6 .v-menubar-submenu .v-menubar-submenu-indicator { + position: absolute; + right: 0; + margin-right: 0; + margin-top: -2px; +} +.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator { + position: relative; + margin-left: 0; +} +.v-menubar-menuitem-disabled { + color: #999; +} +.v-menubar-more-menuitem { + /* Arial has the most coverage for geometric entity characters */ + font-family: arial, helvetica, sans-serif; +} +.v-menubar-separator span { + display: block; + text-indent: -9999px; + height: 1px; + margin: 3px 0; + overflow: hidden; + background: #ddd; } .v-Notification { @@ -665,6 +705,8 @@ div.v-app-loading { cursor: pointer; overflow: hidden; padding: 1em; + max-width:85%; + } .v-Notification h1, .v-Notification p, @@ -673,7 +715,6 @@ div.v-app-loading { .v-Notification-warning h1, .v-Notification-warning p { display: inline; - white-space: nowrap; margin: 0 0.5em 0 0; } .v-Notification-warning { @@ -697,9 +738,6 @@ div.v-app-loading { display: block; margin: 0; } -.v-Notification-system p { - white-space: nowrap; -} .v-orderedlayout-margin-top, .v-horizontallayout-margin-top, @@ -1049,8 +1087,8 @@ div.v-progressindicator-indeterminate-disabled { .v-ie6 .v-shadow { background: #000; filter: progid:DXImageTransform.Microsoft.Blur(pixelRadius=2) alpha(opacity=20); - margin-top: -3px; - margin-left: -4px; + margin-top: -2px; + margin-left: -2px; } .v-slider { @@ -1349,6 +1387,9 @@ div.v-progressindicator-indeterminate-disabled { .v-ff2 .v-tabsheet-scroller { position: relative; } +.v-disabled .v-tabsheet-scroller { + display: none; +} .v-tabsheet-scrollerPrev, .v-tabsheet-scrollerNext, .v-tabsheet-scrollerPrev-disabled, @@ -1368,6 +1409,33 @@ div.v-progressindicator-indeterminate-disabled { .v-tabsheet-tabs .v-caption span { white-space: nowrap; } +.v-tabsheet-caption-close { + display: inline; + display: inline-block; + zoom: 1; + width: 16px; + height: 16px; + text-align: center; + font-weight: bold; + cursor: pointer; + vertical-align: middle; + user-select: none; + -khtml-user-select: none; + -ms-user-select: none; + -moz-user-select: none; + -webkit-user-select: none; +} +.v-tabsheet .v-disabled .v-tabsheet-caption-close { + cursor: default; + visibility: hidden; +} +.v-tabsheet-tabitemcell:hover .v-tabsheet-caption-close, +.v-ie6 .v-tabsheet-caption-close { + visibility: visible; +} +.v-ie6 .v-tabsheet-caption-close { + float: right; +} .v-tabsheet-tabitem { border: 1px solid #aaa; border-right: none; @@ -2114,15 +2182,15 @@ div.v-tree-node-leaf { .v-menubar { color: #464f52; - border: 1px solid #c6cbcc; - border-right: none; + border-left: 1px solid #c6cbcc; } -.v-menubar .menuitem { +.v-menubar .v-menubar-menuitem { padding: 0 10px; margin: 0 10px; - border-right: 1px solid #c6cbcc; + border: 1px solid #c6cbcc; + border-left: none; } -.v-menubar .menuitem-selected { +.v-menubar .v-menubar-menuitem-selected { color: #fff; background: #5daee8; } @@ -2137,13 +2205,21 @@ div.v-tree-node-leaf { border-top: 1px solid #d0d4d5; border-left: 1px solid #d0d4d5; } -.v-menubar-submenu .menuitem { - padding: 2px 10px; +.v-menubar-submenu .v-menubar-menuitem { + padding: 2px 16px 2px 10px; } -.v-menubar-submenu .menuitem-selected { +.v-menubar-submenu .v-menubar-menuitem-selected { color: #fff; background: #5daee8; } +.v-menubar-submenu .v-menubar-submenu-indicator { + margin-right: -12px; + height: 14px; +} +.v-ie7 .v-menubar-submenu .v-menubar-submenu-indicator { + margin-right: -12px; + right: -3px; +} .v-Notification { font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif; @@ -2164,7 +2240,6 @@ div.v-tree-node-leaf { .v-Notification-warning p { display: inline; font-weight: normal; - white-space: nowrap; margin: 0 10px 0 0; } .v-Notification-warning { @@ -2961,6 +3036,23 @@ div.v-tree-node-leaf { padding: 16px 16px 14px 7px; overflow: visible; } +.v-tabsheet-caption-close { + margin-left: 3px; + margin-right: -3px; + width: 16px; + height: 16px; + -webkit-border-radius: 8px; + -moz-border-radius: 8px; + color: #777f85; + line-height: 13px; +} +.v-tabsheet-caption-close:hover { + background: #dce0e0; +} +.v-tabsheet-caption-close:active { + background: #b6bbbc; + color: #fff; +} .v-tabsheet-content { border: 1px solid #babfc0; background-color: #fff; diff --git a/WebContent/VAADIN/themes/runo/tabsheet/tabsheet.css b/WebContent/VAADIN/themes/runo/tabsheet/tabsheet.css index fa99f6ae43..3b738107b2 100644 --- a/WebContent/VAADIN/themes/runo/tabsheet/tabsheet.css +++ b/WebContent/VAADIN/themes/runo/tabsheet/tabsheet.css @@ -83,6 +83,23 @@ padding: 16px 16px 14px 7px; overflow: visible; } +.v-tabsheet-caption-close { + margin-left: 3px; + margin-right: -3px; + width: 16px; + height: 16px; + -webkit-border-radius: 8px; + -moz-border-radius: 8px; + color: #777f85; + line-height: 13px; +} +.v-tabsheet-caption-close:hover { + background: #dce0e0; +} +.v-tabsheet-caption-close:active { + background: #b6bbbc; + color: #fff; +} .v-tabsheet-content { border: 1px solid #babfc0; background-color: #fff; diff --git a/WebContent/VAADIN/themes/sampler/sampler/styles.css b/WebContent/VAADIN/themes/sampler/sampler/styles.css index a60db36a75..3eb778ab2d 100644 --- a/WebContent/VAADIN/themes/sampler/sampler/styles.css +++ b/WebContent/VAADIN/themes/sampler/sampler/styles.css @@ -304,6 +304,7 @@ line-height: 16px; color: #787b7e; float: left; + clear: left; width: 155px; height: 131px; padding: 15px 175px 0 15px; diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index ecec5fa76f..ce3c2bba13 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -24,7 +24,7 @@ <servlet-name>VaadinApplicationRunner</servlet-name>
<servlet-class>com.vaadin.terminal.gwt.server.ApplicationRunnerServlet</servlet-class>
<init-param><param-name>defaultPackages</param-name>
- <param-value>com.vaadin.tests,com.vaadin.demo,com.vaadin.tests,com.vaadin.tests.components,com.vaadin.tests.components.layouts,com.vaadin.tests.components.panel,com.vaadin.tests.components.combobox,com.vaadin.tests.components.popupview,com.vaadin.tests.components.datefield,com.vaadin.tests.components.richtextarea,com.vaadin.tests.components.absolutelayout,com.vaadin.tests.components.embedded,com.vaadin.tests.components.splitpanel,com.vaadin.tests.components.abstractfield,com.vaadin.tests.components.form,com.vaadin.tests.components.table,com.vaadin.tests.components.accordion,com.vaadin.tests.components.label,com.vaadin.tests.components.tabsheet,com.vaadin.tests.components.beanitemcontainer,com.vaadin.tests.components.link,com.vaadin.tests.components.textfield,com.vaadin.tests.components.button,com.vaadin.tests.components.optiongroup,com.vaadin.tests.components.tree,com.vaadin.tests.components.caption,com.vaadin.tests.components.orderedlayout,com.vaadin.tests.components.window</param-value></init-param>
+ <param-value>com.vaadin.tests,com.vaadin.demo,com.vaadin.tests.tickets,com.vaadin.tests.components,com.vaadin.tests.components.layouts,com.vaadin.tests.components.panel,com.vaadin.tests.components.combobox,com.vaadin.tests.components.popupview,com.vaadin.tests.components.datefield,com.vaadin.tests.components.richtextarea,com.vaadin.tests.components.absolutelayout,com.vaadin.tests.components.embedded,com.vaadin.tests.components.splitpanel,com.vaadin.tests.components.abstractfield,com.vaadin.tests.components.form,com.vaadin.tests.components.table,com.vaadin.tests.components.accordion,com.vaadin.tests.components.label,com.vaadin.tests.components.tabsheet,com.vaadin.tests.components.beanitemcontainer,com.vaadin.tests.components.link,com.vaadin.tests.components.textfield,com.vaadin.tests.components.button,com.vaadin.tests.components.optiongroup,com.vaadin.tests.components.tree,com.vaadin.tests.components.caption,com.vaadin.tests.components.orderedlayout,com.vaadin.tests.components.window</param-value></init-param>
</servlet>
diff --git a/build/maven/pom.xml b/build/maven/pom.xml index b686b17827..8008b6e77a 100644 --- a/build/maven/pom.xml +++ b/build/maven/pom.xml @@ -2,7 +2,7 @@ <modelVersion>4.0.0</modelVersion>
<groupId>com.vaadin</groupId>
<artifactId>vaadin</artifactId>
- <version>6.1-SNAPSHOT</version>
+ <version>6.2-SNAPSHOT</version>
<name>Vaadin</name>
<organization>
<name>Oy IT Mill Ltd</name>
diff --git a/src/com/vaadin/data/util/BeanItemContainer.java b/src/com/vaadin/data/util/BeanItemContainer.java index 03616821bf..aaa7d9cd56 100644 --- a/src/com/vaadin/data/util/BeanItemContainer.java +++ b/src/com/vaadin/data/util/BeanItemContainer.java @@ -414,7 +414,7 @@ public class BeanItemContainer<BT> implements Indexed, Sortable, Filterable, if (va == null) { return (vb == null) ? 0 : -1; } else if (vb == null) { - return (va == null) ? 0 : 1; + return 1; } return va.compareTo(vb); diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java index 296a1b0072..15c36953a1 100644 --- a/src/com/vaadin/data/util/IndexedContainer.java +++ b/src/com/vaadin/data/util/IndexedContainer.java @@ -681,7 +681,7 @@ public class IndexedContainer implements Container.Indexed, private Serializable generateId() { Serializable id; do { - id = new Integer(nextGeneratedItemId++); + id = Integer.valueOf(nextGeneratedItemId++); } while (items.containsKey(id)); return id; @@ -1387,7 +1387,7 @@ public class IndexedContainer implements Container.Indexed, for (int i = 0; i < propertyId.length; i++) { if (sortable.contains(propertyId[i])) { ids.add(propertyId[i]); - orders.add(new Boolean(i < ascending.length ? ascending[i] + orders.add(Boolean.valueOf(i < ascending.length ? ascending[i] : true)); } } diff --git a/src/com/vaadin/data/util/MethodProperty.java b/src/com/vaadin/data/util/MethodProperty.java index 5b15b66cd5..d0a6a9cbd7 100644 --- a/src/com/vaadin/data/util/MethodProperty.java +++ b/src/com/vaadin/data/util/MethodProperty.java @@ -473,21 +473,21 @@ public class MethodProperty implements Property, Property.ValueChangeNotifier, // Gets the return type from get method if (type.isPrimitive()) { if (type.equals(Boolean.TYPE)) { - type = Boolean.class; + this.type = Boolean.class; } else if (type.equals(Integer.TYPE)) { - type = Integer.class; + this.type = Integer.class; } else if (type.equals(Float.TYPE)) { - type = Float.class; + this.type = Float.class; } else if (type.equals(Double.TYPE)) { - type = Double.class; + this.type = Double.class; } else if (type.equals(Byte.TYPE)) { - type = Byte.class; + this.type = Byte.class; } else if (type.equals(Character.TYPE)) { - type = Character.class; + this.type = Character.class; } else if (type.equals(Short.TYPE)) { - type = Short.class; + this.type = Short.class; } else if (type.equals(Long.TYPE)) { - type = Long.class; + this.type = Long.class; } } diff --git a/src/com/vaadin/data/validator/CompositeValidator.java b/src/com/vaadin/data/validator/CompositeValidator.java index 99eb15b422..8fa01affba 100644 --- a/src/com/vaadin/data/validator/CompositeValidator.java +++ b/src/com/vaadin/data/validator/CompositeValidator.java @@ -191,8 +191,8 @@ public class CompositeValidator extends AbstractValidator { */ @Override public String getErrorMessage() { - if (getErrorMessage() != null) { - return getErrorMessage(); + if (super.getErrorMessage() != null) { + return super.getErrorMessage(); } // TODO Return composite error message diff --git a/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml b/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml index 0963760035..682534e16e 100644 --- a/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml +++ b/src/com/vaadin/portal/gwt/PortalDefaultWidgetSet.gwt.xml @@ -1,4 +1,6 @@ <module> + <!-- WS Compiler: manually edited --> + <!-- Inherit the SamplerWidgetSet --> <inherits name="com.vaadin.demo.sampler.gwt.SamplerWidgetSet" /> </module> diff --git a/src/com/vaadin/service/ApplicationContext.java b/src/com/vaadin/service/ApplicationContext.java index 96a6f60906..756a8e50c8 100644 --- a/src/com/vaadin/service/ApplicationContext.java +++ b/src/com/vaadin/service/ApplicationContext.java @@ -14,7 +14,8 @@ import com.vaadin.terminal.ApplicationResource; /** * <code>ApplicationContext</code> provides information about the running * context of the application. Each context is shared by all applications that - * are open for one user. In web-environment this corresponds to HttpSession. + * are open for one user. In a web-environment this corresponds to a + * HttpSession. * * @author IT Mill Ltd. * @version @@ -26,28 +27,28 @@ public interface ApplicationContext extends Serializable { /** * Returns application context base directory. * - * Typically an application is deployed in a such way that is has + * Typically an application is deployed in a such way that is has an * application directory. For web applications this directory is the root - * directory of the web applications. In some cases application might not - * have application directory (for example web applications running inside - * of war). + * directory of the web applications. In some cases applications might not + * have an application directory (for example web applications running + * inside a war). * - * @return The application base directory + * @return The application base directory or null if the application has no + * base directory. */ public File getBaseDirectory(); /** - * Gets the applications in this context. + * Returns a collection of all the applications in this context. * - * Gets all applications in this context. Each application context contains - * all applications that are open for one user. + * Each application context contains all active applications for one user. * - * @return Collection containing all applications in this context + * @return A collection containing all the applications in this context. */ public Collection<Application> getApplications(); /** - * Adds transaction listener to this context. + * Adds a transaction listener to this context. * * @param listener * the listener to be added. @@ -56,7 +57,7 @@ public interface ApplicationContext extends Serializable { public void addTransactionListener(TransactionListener listener); /** - * Removes transaction listener from this context. + * Removes a transaction listener from this context. * * @param listener * the listener to be removed. @@ -65,9 +66,8 @@ public interface ApplicationContext extends Serializable { public void removeTransactionListener(TransactionListener listener); /** - * Interface for listening the application transaction events. - * Implementations of this interface can be used to listen all transactions - * between the client and the application. + * Interface for listening to transaction events. Implement this interface + * to listen to all transactions between the client and the application. * */ public interface TransactionListener extends Serializable { @@ -75,6 +75,11 @@ public interface ApplicationContext extends Serializable { /** * Invoked at the beginning of every transaction. * + * The transaction is linked to the context, not the application so if + * you have multiple applications running in the same context you need + * to check that the request is associated with the application you are + * interested in. This can be done looking at the application parameter. + * * @param application * the Application object. * @param transactionData @@ -86,6 +91,11 @@ public interface ApplicationContext extends Serializable { /** * Invoked at the end of every transaction. * + * The transaction is linked to the context, not the application so if + * you have multiple applications running in the same context you need + * to check that the request is associated with the application you are + * interested in. This can be done looking at the application parameter. + * * @param applcation * the Application object. * @param transactionData diff --git a/src/com/vaadin/terminal/SystemError.java b/src/com/vaadin/terminal/SystemError.java index 6f29970f6b..8b721c07f5 100644 --- a/src/com/vaadin/terminal/SystemError.java +++ b/src/com/vaadin/terminal/SystemError.java @@ -75,20 +75,27 @@ public class SystemError extends RuntimeException implements ErrorMessage { target.startTag("error"); target.addAttribute("level", "system"); - // Paint the error message + StringBuilder sb = new StringBuilder(); final String message = getLocalizedMessage(); if (message != null) { - target.addSection("h2", message); + sb.append("<h2>"); + sb.append(message); + sb.append("</h2>"); } // Paint the exception if (cause != null) { - target.addSection("h3", "Exception"); + sb.append("<h3>Exception</h3>"); final StringWriter buffer = new StringWriter(); cause.printStackTrace(new PrintWriter(buffer)); - target.addSection("pre", buffer.toString()); + sb.append("<pre>"); + sb.append(buffer.toString()); + sb.append("</pre>"); } + target.addXMLSection("div", sb.toString(), + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"); + target.endTag("error"); } diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml index 0c139aabc4..d7cf1ca4d0 100644 --- a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml +++ b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml @@ -1,18 +1,14 @@ <module> <!-- + This GWT module defines the Vaadin DefaultWidgetSet. This is the module you want to extend when creating an extended widget set, or when creating a specialized widget set with a subset of the components. - --> - <!-- - NOTE that your WidgetSet entry-point (.java) should have the same - "logical" name (a.k.a SimpleName) as the specification (.gwt.xml). - --> - <!-- - E.g: com/example/gwt/MyWidgetSet.gwt.xml should point to the - entry-point - com.example.gwt.client[.some.package].MyWidgetSet.java + + + WS Compiler: manually edited + --> <inherits name="com.google.gwt.user.User" /> diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 4719b0cbd3..8ea94fcc6b 100755 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -346,7 +346,6 @@ public class ApplicationConnection { } if (!forceSync) { - boolean success = false; final RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, uri); // TODO enable timeout @@ -369,11 +368,14 @@ public class ApplicationConnection { + String.valueOf((new Date()).getTime() - requestStartTime.getTime()) + "ms"); - switch (response.getStatusCode()) { + int statusCode = response.getStatusCode(); + switch (statusCode) { case 0: showCommunicationError("Invalid status code 0 (server down?)"); return; - // TODO could add more cases + case 404: + showCommunicationError("UIDL could not be read from server. Check servlets mappings."); + return; case 503: // We'll assume msec instead of the usual seconds int delay = Integer.parseInt(response diff --git a/src/com/vaadin/terminal/gwt/client/VCaption.java b/src/com/vaadin/terminal/gwt/client/VCaption.java index de40940ad2..5a6306b79b 100644 --- a/src/com/vaadin/terminal/gwt/client/VCaption.java +++ b/src/com/vaadin/terminal/gwt/client/VCaption.java @@ -343,26 +343,26 @@ public class VCaption extends HTML { int h; if (icon != null) { - h = icon.getOffsetHeight(); + h = Util.getRequiredHeight(icon.getElement()); if (h > height) { height = h; } } if (captionText != null) { - h = captionText.getOffsetHeight(); + h = Util.getRequiredHeight(captionText); if (h > height) { height = h; } } if (requiredFieldIndicator != null) { - h = requiredFieldIndicator.getOffsetHeight(); + h = Util.getRequiredHeight(requiredFieldIndicator); if (h > height) { height = h; } } if (errorIndicatorElement != null) { - h = errorIndicatorElement.getOffsetHeight(); + h = Util.getRequiredHeight(errorIndicatorElement); if (h > height) { height = h; } diff --git a/src/com/vaadin/terminal/gwt/client/VErrorMessage.java b/src/com/vaadin/terminal/gwt/client/VErrorMessage.java index ba25dd23db..ba5d5a9d24 100644 --- a/src/com/vaadin/terminal/gwt/client/VErrorMessage.java +++ b/src/com/vaadin/terminal/gwt/client/VErrorMessage.java @@ -30,13 +30,18 @@ public class VErrorMessage extends FlowPanel { if (child instanceof String) { final String errorMessage = (String) child; add(new HTML(errorMessage)); - } else if (child instanceof UIDL.XML) { - final UIDL.XML xml = (UIDL.XML) child; - add(new HTML(xml.getXMLAsString())); } else { - final VErrorMessage childError = new VErrorMessage(); - add(childError); - childError.updateFromUIDL((UIDL) child); + try { + final VErrorMessage childError = new VErrorMessage(); + childError.updateFromUIDL((UIDL) child); + add(childError); + } catch (Exception e) { + // TODO XML type error, check if this can even happen + // anymore?? + final UIDL.XML xml = (UIDL.XML) child; + add(new HTML(xml.getXMLAsString())); + + } } } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/Icon.java b/src/com/vaadin/terminal/gwt/client/ui/Icon.java index 1ee19c1d17..eba1a9bd78 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/Icon.java +++ b/src/com/vaadin/terminal/gwt/client/ui/Icon.java @@ -10,13 +10,14 @@ import com.google.gwt.user.client.ui.UIObject; import com.vaadin.terminal.gwt.client.ApplicationConnection; public class Icon extends UIObject { + public static final String CLASSNAME = "v-icon"; private final ApplicationConnection client; private String myUri; public Icon(ApplicationConnection client) { setElement(DOM.createImg()); DOM.setElementProperty(getElement(), "alt", ""); - setStyleName("v-icon"); + setStyleName(CLASSNAME); this.client = client; client.addPngFix(getElement()); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java index d0c140dac0..dc3cd6b2e3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VCustomComponent.java @@ -68,6 +68,12 @@ public class VCustomComponent extends SimplePanel implements Container { renderSpace.setWidth(getElement().getOffsetWidth()); renderSpace.setHeight(getElement().getOffsetHeight()); + /* + * Needed to update client size if the size of this component has + * changed and the child uses relative size(s). + */ + client.runDescendentsLayout(this); + rendering = false; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java index 7e9cf96d72..e2f217267a 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java @@ -272,15 +272,31 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { c.cc.updateWidgetSize(); int newHeight = c.getHeight(); if (columnWidths[i] < oldWidths[i] - && newHeight > minRowHeights[j]) { + && newHeight > minRowHeights[j] + && c.rowspan == 1) { + /* + * The width of this column was reduced and + * this affected the height. The height is + * now greater than the previously + * calculated minHeight for the row. + */ minRowHeights[j] = newHeight; if (newHeight > rowHeights[j]) { + /* + * The new height is greater than the + * previously calculated rowHeight -> we + * need to recalculate heights later on + */ rowHeights[j] = newHeight; heightChanged = true; } } else if (newHeight < minRowHeights[j]) { - // need to recalculate new minimum height - // for this row + /* + * The new height of the component is less + * than the previously calculated min row + * height. The min row height may be + * affected and must thus be recalculated + */ if (dirtyRows == null) { dirtyRows = new HashSet<Integer>(); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java index 5bfaea9243..0e09c7a287 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java @@ -12,16 +12,20 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.HasHTML; import com.google.gwt.user.client.ui.PopupPanel; +import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.UIObject; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.ContainerResizedListener; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; +import com.vaadin.terminal.gwt.client.Util; public class VMenuBar extends Widget implements Paintable, - CloseHandler<PopupPanel> { + CloseHandler<PopupPanel>, ContainerResizedListener { /** Set the CSS class name to allow styling. */ public static final String CLASSNAME = "v-menubar"; @@ -32,8 +36,8 @@ public class VMenuBar extends Widget implements Paintable, protected final VMenuBar hostReference = this; protected String submenuIcon = null; - protected boolean collapseItems = true; protected CustomMenuItem moreItem = null; + protected VMenuBar collapsedRootItems; // Construct an empty command to be used when the item has no command // associated @@ -45,9 +49,12 @@ public class VMenuBar extends Widget implements Paintable, protected Element containerElement; protected VOverlay popup; protected VMenuBar visibleChildMenu; + protected boolean menuVisible = false; protected VMenuBar parentMenu; protected CustomMenuItem selected; + private Timer layoutTimer; + public VMenuBar() { // Create an empty horizontal menubar this(false); @@ -67,23 +74,24 @@ public class VMenuBar extends Widget implements Paintable, DOM.appendChild(table, tbody); if (!subMenu) { - setStyleName(CLASSNAME); + setStylePrimaryName(CLASSNAME); Element tr = DOM.createTR(); DOM.appendChild(tbody, tr); containerElement = tr; } else { - setStyleName(CLASSNAME + "-submenu"); + setStylePrimaryName(CLASSNAME + "-submenu"); containerElement = tbody; } this.subMenu = subMenu; - sinkEvents(Event.ONCLICK | Event.ONMOUSEOVER | Event.ONMOUSEOUT); + sinkEvents(Event.ONCLICK | Event.ONMOUSEOVER | Event.ONMOUSEOUT + | Event.ONLOAD); } /** * This method must be implemented to update the client-side component from * UIDL data received from server. - * + * * This method is called when the page is loaded for the first time, and * every time UI changes in the component are received from the server. */ @@ -105,6 +113,7 @@ public class VMenuBar extends Widget implements Paintable, UIDL options = uidl.getChildUIDL(0); + // FIXME remove in version 7 if (options.hasAttribute("submenuIcon")) { submenuIcon = client.translateVaadinUri(uidl.getChildUIDL(0) .getStringAttribute("submenuIcon")); @@ -112,21 +121,27 @@ public class VMenuBar extends Widget implements Paintable, submenuIcon = null; } - collapseItems = options.getBooleanAttribute("collapseItems"); - - if (collapseItems) { + if (uidl.hasAttribute("width")) { UIDL moreItemUIDL = options.getChildUIDL(0); StringBuffer itemHTML = new StringBuffer(); if (moreItemUIDL.hasAttribute("icon")) { itemHTML.append("<img src=\"" + client.translateVaadinUri(moreItemUIDL - .getStringAttribute("icon")) - + "\" align=\"left\" />"); + .getStringAttribute("icon")) + "\" class=\"" + + Icon.CLASSNAME + "\" alt=\"\" />"); + } + + String moreItemText = moreItemUIDL.getStringAttribute("text"); + if ("".equals(moreItemText)) { + moreItemText = "►"; } - itemHTML.append(moreItemUIDL.getStringAttribute("text")); + itemHTML.append(moreItemText); moreItem = new CustomMenuItem(itemHTML.toString(), emptyCommand); + collapsedRootItems = new VMenuBar(true); + moreItem.setSubMenu(collapsedRootItems); + moreItem.addStyleName(CLASSNAME + "-more-menuitem"); } UIDL uidlItems = uidl.getChildUIDL(1); @@ -142,45 +157,66 @@ public class VMenuBar extends Widget implements Paintable, String itemText = item.getStringAttribute("text"); final int itemId = item.getIntAttribute("id"); - boolean itemHasCommand = item.getBooleanAttribute("command"); + boolean itemHasCommand = item.hasAttribute("command"); // Construct html from the text and the optional icon StringBuffer itemHTML = new StringBuffer(); + Command cmd = null; - if (item.hasAttribute("icon")) { - itemHTML.append("<img src=\"" - + client.translateVaadinUri(item - .getStringAttribute("icon")) - + "\" align=\"left\" />"); - } - - itemHTML.append(itemText); + if (item.hasAttribute("separator")) { + itemHTML.append("<span>---</span>"); + } else { + // Add submenu indicator + if (item.getChildCount() > 0) { + // FIXME For compatibility reasons: remove in version 7 + String bgStyle = ""; + if (submenuIcon != null) { + bgStyle = " style=\"background-image: url(" + + submenuIcon + + "); text-indent: -999px; width: 1em;\""; + } + itemHTML.append("<span class=\"" + CLASSNAME + + "-submenu-indicator\"" + bgStyle + + ">►</span>"); + } - if (currentMenu != this && item.getChildCount() > 0 - && submenuIcon != null) { - itemHTML.append("<img src=\"" + submenuIcon - + "\" align=\"right\" />"); - } + if (item.hasAttribute("icon")) { + itemHTML + .append("<img src=\"" + + client.translateVaadinUri(item + .getStringAttribute("icon")) + + "\" class=\"" + Icon.CLASSNAME + + "\" alt=\"\" />"); + } - Command cmd = null; + itemHTML.append(Util.escapeHTML(itemText)); - if (itemHasCommand) { - // Construct a command that fires onMenuClick(int) with the - // item's id-number - cmd = new Command() { - public void execute() { - hostReference.onMenuClick(itemId); - } - }; + if (itemHasCommand) { + // Construct a command that fires onMenuClick(int) with the + // item's id-number + cmd = new Command() { + public void execute() { + hostReference.onMenuClick(itemId); + } + }; + } } currentItem = currentMenu.addItem(itemHTML.toString(), cmd); + currentItem.setSeparator(item.hasAttribute("separator")); + currentItem.setEnabled(!item.hasAttribute("disabled")); if (item.getChildCount() > 0) { menuStack.push(currentMenu); iteratorStack.push(itr); itr = item.getChildIterator(); currentMenu = new VMenuBar(true); + if (uidl.hasAttribute("style")) { + for (String style : uidl.getStringAttribute("style").split( + " ")) { + currentMenu.addStyleDependentName(style); + } + } currentItem.setSubMenu(currentMenu); } @@ -190,54 +226,14 @@ public class VMenuBar extends Widget implements Paintable, } }// while - // we might need to collapse the top-level menu - // Only needed if there is more than 1 top level item - // TODO and if width is defined - if (collapseItems && getItems().size() > 1) { - - int topLevelWidth = 0; + iLayout(); - int ourWidth = getOffsetWidth(); - - int i = 0; - for (; i < getItems().size() && topLevelWidth < ourWidth; i++) { - CustomMenuItem item = getItems().get(i); - topLevelWidth += item.getOffsetWidth(); - } - - if (topLevelWidth > getOffsetWidth()) { - ArrayList<CustomMenuItem> toBeCollapsed = new ArrayList<CustomMenuItem>(); - VMenuBar collapsed = new VMenuBar(true); - for (int j = i - 2; j < getItems().size(); j++) { - toBeCollapsed.add(getItems().get(j)); - } - - for (int j = 0; j < toBeCollapsed.size(); j++) { - CustomMenuItem item = toBeCollapsed.get(j); - removeItem(item); - - // it's ugly, but we have to insert the submenu icon - if (item.getSubMenu() != null && submenuIcon != null) { - StringBuffer itemText = new StringBuffer(item.getHTML()); - itemText.append("<img src=\""); - itemText.append(submenuIcon); - itemText.append("\" align=\"right\" />"); - item.setHTML(itemText.toString()); - } - - collapsed.addItem(item); - } - - moreItem.setSubMenu(collapsed); - addItem(moreItem); - } - } }// updateFromUIDL /** * This is called by the items in the menu and it communicates the * information to the server - * + * * @param clickedItemId * id of the item that was clicked */ @@ -274,7 +270,7 @@ public class VMenuBar extends Widget implements Paintable, /** * Returns the containing element of the menu - * + * * @return */ public Element getContainingElement() { @@ -283,23 +279,30 @@ public class VMenuBar extends Widget implements Paintable, /** * Returns a new child element to add an item to - * + * + * @param index + * the index in which point to add a new element in a submenu. -1 + * will add the new element as the last child (append) + * * @return */ - public Element getNewChildElement() { + public Element getNewChildElement(int index) { if (subMenu) { Element tr = DOM.createTR(); - DOM.appendChild(getContainingElement(), tr); + if (index == -1) { + DOM.appendChild(getContainingElement(), tr); + } else { + DOM.insertChild(getContainingElement(), tr, index); + } return tr; } else { return getContainingElement(); } - } /** * Add a new item to this menu - * + * * @param html * items text * @param cmd @@ -314,19 +317,36 @@ public class VMenuBar extends Widget implements Paintable, /** * Add a new item to this menu - * + * * @param item */ public void addItem(CustomMenuItem item) { - DOM.appendChild(getNewChildElement(), item.getElement()); + if (items.contains(item)) { + return; + } + DOM.appendChild(getNewChildElement(-1), item.getElement()); item.setParentMenu(this); item.setSelected(false); items.add(item); } + public void addItem(CustomMenuItem item, int index) { + if (items.contains(item)) { + return; + } + if (subMenu) { + DOM.appendChild(getNewChildElement(index), item.getElement()); + } else { + DOM.insertChild(getNewChildElement(-1), item.getElement(), index); + } + item.setParentMenu(this); + item.setSelected(false); + items.add(index, item); + } + /** * Remove the given item from this menu - * + * * @param item */ public void removeItem(CustomMenuItem item) { @@ -348,6 +368,12 @@ public class VMenuBar extends Widget implements Paintable, public void onBrowserEvent(Event e) { super.onBrowserEvent(e); + // Handle onload events (icon loaded, size changes) + if (DOM.eventGetType(e) == Event.ONLOAD) { + requestLayout(); + return; + } + Element targetElement = DOM.eventGetTarget(e); CustomMenuItem targetItem = null; for (int i = 0; i < items.size(); i++) { @@ -361,11 +387,15 @@ public class VMenuBar extends Widget implements Paintable, switch (DOM.eventGetType(e)) { case Event.ONCLICK: - itemClick(targetItem); + if (targetItem.isEnabled()) { + itemClick(targetItem); + } break; case Event.ONMOUSEOVER: - itemOver(targetItem); + if (targetItem.isEnabled()) { + itemOver(targetItem); + } break; case Event.ONMOUSEOUT: @@ -375,9 +405,22 @@ public class VMenuBar extends Widget implements Paintable, } } + private void requestLayout() { + if (layoutTimer == null) { + layoutTimer = new Timer() { + @Override + public void run() { + layoutTimer = null; + iLayout(); + } + }; + } + layoutTimer.schedule(100); + } + /** * When an item is clicked - * + * * @param item */ public void itemClick(CustomMenuItem item) { @@ -388,7 +431,8 @@ public class VMenuBar extends Widget implements Paintable, visibleChildMenu.hideChildren(); } - hideParents(); + hideParents(true); + menuVisible = false; DeferredCommand.addCommand(item.getCommand()); } else { @@ -396,26 +440,31 @@ public class VMenuBar extends Widget implements Paintable, && item.getSubMenu() != visibleChildMenu) { setSelected(item); showChildMenu(item); + menuVisible = true; + } else if (!subMenu) { + setSelected(null); + hideChildren(); + menuVisible = false; } } } /** * When the user hovers the mouse over the item - * + * * @param item */ public void itemOver(CustomMenuItem item) { - setSelected(item); - - boolean menuWasVisible = visibleChildMenu != null; + if ((subMenu || menuVisible) && !item.isSeparator()) { + setSelected(item); + } - if (menuWasVisible && visibleChildMenu != item.getSubMenu()) { + if (menuVisible && visibleChildMenu != item.getSubMenu() + && popup != null) { popup.hide(); - visibleChildMenu = null; } - if (item.getSubMenu() != null && (parentMenu != null || menuWasVisible) + if (menuVisible && item.getSubMenu() != null && visibleChildMenu != item.getSubMenu()) { showChildMenu(item); } @@ -423,54 +472,78 @@ public class VMenuBar extends Widget implements Paintable, /** * When the mouse is moved away from an item - * + * * @param item */ public void itemOut(CustomMenuItem item) { - if (visibleChildMenu != item.getSubMenu() || visibleChildMenu == null) { + if (visibleChildMenu != item.getSubMenu()) { hideChildMenu(item); setSelected(null); + } else if (visibleChildMenu == null) { + setSelected(null); } } /** * Shows the child menu of an item. The caller must ensure that the item has * a submenu. - * + * * @param item */ public void showChildMenu(CustomMenuItem item) { + final int shadowSpace = 10; + popup = new VOverlay(true, false, true); popup.setWidget(item.getSubMenu()); popup.addCloseHandler(this); + popup.addAutoHidePartner(item.getElement()); + int left = 0; + int top = 0; if (subMenu) { - popup.setPopupPosition(item.getParentMenu().getAbsoluteLeft() - + item.getParentMenu().getOffsetWidth(), item - .getAbsoluteTop()); + left = item.getParentMenu().getAbsoluteLeft() + + item.getParentMenu().getOffsetWidth(); + top = item.getAbsoluteTop(); } else { - popup.setPopupPosition(item.getAbsoluteLeft(), item.getParentMenu() - .getAbsoluteTop() - + item.getParentMenu().getOffsetHeight()); + left = item.getAbsoluteLeft(); + top = item.getParentMenu().getAbsoluteTop() + + item.getParentMenu().getOffsetHeight(); } + popup.setPopupPosition(left, top); item.getSubMenu().onShow(); visibleChildMenu = item.getSubMenu(); item.getSubMenu().setParentMenu(this); popup.show(); + + if (left + popup.getOffsetWidth() >= RootPanel.getBodyElement() + .getOffsetWidth() + - shadowSpace) { + if (subMenu) { + left = item.getParentMenu().getAbsoluteLeft() + - popup.getOffsetWidth() - shadowSpace; + } else { + left = RootPanel.getBodyElement().getOffsetWidth() + - popup.getOffsetWidth() - shadowSpace; + } + // Accommodate space for shadow + if (left < shadowSpace) { + left = shadowSpace; + } + popup.setPopupPosition(left, top); + } } /** * Hides the submenu of an item - * + * * @param item */ public void hideChildMenu(CustomMenuItem item) { if (visibleChildMenu != null && !(visibleChildMenu == item.getSubMenu())) { popup.hide(); - } } @@ -478,9 +551,25 @@ public class VMenuBar extends Widget implements Paintable, * When the menu is shown. */ public void onShow() { - if (!items.isEmpty()) { - (items.get(0)).setSelected(true); + // remove possible previous selection + if (selected != null) { + selected.setSelected(false); + selected = null; } + menuVisible = true; + } + + /** + * Listener method, fired when this menu is closed + */ + public void onClose(CloseEvent<PopupPanel> event) { + hideChildren(); + if (event.isAutoClosed()) { + hideParents(true); + menuVisible = false; + } + visibleChildMenu = null; + popup = null; } /** @@ -496,22 +585,22 @@ public class VMenuBar extends Widget implements Paintable, /** * Recursively hide all parent menus */ - public void hideParents() { - + public void hideParents(boolean autoClosed) { if (visibleChildMenu != null) { popup.hide(); setSelected(null); + menuVisible = !autoClosed; } if (getParentMenu() != null) { - getParentMenu().hideParents(); + getParentMenu().hideParents(autoClosed); } } /** * Returns the parent menu of this menu, or null if this is the top-level * menu - * + * * @return */ public VMenuBar getParentMenu() { @@ -520,7 +609,7 @@ public class VMenuBar extends Widget implements Paintable, /** * Set the parent menu of this menu - * + * * @param parent */ public void setParentMenu(VMenuBar parent) { @@ -530,7 +619,7 @@ public class VMenuBar extends Widget implements Paintable, /** * Returns the currently selected item of this menu, or null if nothing is * selected - * + * * @return */ public CustomMenuItem getSelected() { @@ -539,7 +628,7 @@ public class VMenuBar extends Widget implements Paintable, /** * Set the currently selected item of this menu - * + * * @param item */ public void setSelected(CustomMenuItem item) { @@ -556,23 +645,9 @@ public class VMenuBar extends Widget implements Paintable, } /** - * Listener method, fired when this menu is closed - */ - public void onClose(CloseEvent<PopupPanel> event) { - hideChildren(); - if (event.isAutoClosed()) { - hideParents(); - } - // setSelected(null); - visibleChildMenu = null; - popup = null; - - } - - /** - * + * * A class to hold information on menu items - * + * */ private class CustomMenuItem extends UIObject implements HasHTML { @@ -580,6 +655,8 @@ public class VMenuBar extends Widget implements Paintable, protected Command command = null; protected VMenuBar subMenu = null; protected VMenuBar parentMenu = null; + protected boolean enabled = true; + protected boolean isSeparator = false; public CustomMenuItem(String html, Command cmd) { setElement(DOM.createTD()); @@ -588,11 +665,11 @@ public class VMenuBar extends Widget implements Paintable, setCommand(cmd); setSelected(false); - addStyleName("menuitem"); + setStylePrimaryName(CLASSNAME + "-menuitem"); } public void setSelected(boolean selected) { - if (selected) { + if (selected && !isSeparator) { addStyleDependentName("selected"); } else { removeStyleDependentName("selected"); @@ -642,8 +719,104 @@ public class VMenuBar extends Widget implements Paintable, public void setText(String text) { setHTML(text); + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + if (enabled) { + removeStyleDependentName("disabled"); + } else { + addStyleDependentName("disabled"); + } + } + public boolean isEnabled() { + return enabled; + } + + private void setSeparator(boolean separator) { + isSeparator = separator; + if (separator) { + setStyleName(CLASSNAME + "-separator"); + } else { + setStyleName(CLASSNAME + "-menuitem"); + setEnabled(enabled); + } + } + + public boolean isSeparator() { + return isSeparator; + } + } + + /** + * @author Jouni Koivuviita / IT Mill Ltd. + */ + + public void iLayout() { + // Only collapse if there is more than one item in the root menu and the + // menu has an explicit size + if ((getItems().size() > 1 || collapsedRootItems.getItems().size() > 0) + && getElement().getStyle().getProperty("width") != null + && moreItem != null) { + + // Measure the width of the "more" item + final boolean morePresent = getItems().contains(moreItem); + addItem(moreItem); + final int moreItemWidth = moreItem.getOffsetWidth(); + if (!morePresent) { + removeItem(moreItem); + } + + // Measure available space + int availableWidth = getElement().getClientWidth(); + final int rootWidth = getElement().getFirstChildElement() + .getOffsetWidth(); + int diff = availableWidth - rootWidth; + + removeItem(moreItem); + + if (diff < 0) { + // Too many items: collapse last items from root menu + final int widthNeeded = moreItemWidth - diff; + int widthReduced = 0; + + while (widthReduced < widthNeeded && getItems().size() > 0) { + // Move last root menu item to collapsed menu + CustomMenuItem collapse = getItems().get( + getItems().size() - 1); + widthReduced += collapse.getOffsetWidth(); + removeItem(collapse); + collapsedRootItems.addItem(collapse, 0); + } + } else if (collapsedRootItems.getItems().size() > 0) { + // Space available for items: expand first items from collapsed + // menu + int widthAvailable = diff + moreItemWidth; + int widthGrowth = 0; + + while (widthAvailable > widthGrowth) { + // Move first item from collapsed menu to the root menu + CustomMenuItem expand = collapsedRootItems.getItems() + .get(0); + collapsedRootItems.removeItem(expand); + addItem(expand); + widthGrowth += expand.getOffsetWidth(); + if (collapsedRootItems.getItems().size() > 0) { + widthAvailable -= moreItemWidth; + } + if (widthGrowth > widthAvailable) { + removeItem(expand); + collapsedRootItems.addItem(expand, 0); + } else { + widthAvailable = diff; + } + } + } + if (collapsedRootItems.getItems().size() > 0) { + addItem(moreItem); + } } } -}// class VMenuBar +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java b/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java index fb6831e31a..43f08b6a0c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VOverlay.java @@ -213,6 +213,7 @@ public class VOverlay extends PopupPanel { zIndex = DOM.getStyleAttribute(getElement(), "zIndex"); } catch (Exception ignore) { // Ignored, will cause no harm + zIndex = "1000"; } if (zIndex == null) { zIndex = "" + Z_INDEX; diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java index 9b74167689..0f269722de 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java @@ -78,19 +78,36 @@ public class VPopupCalendar extends VTextualDate implements Paintable, Field, public void setPosition(int offsetWidth, int offsetHeight) {
final int w = offsetWidth;
final int h = offsetHeight;
+ final int browserWindowWidth = Window.getClientWidth()
+ + Window.getScrollLeft();
+ final int browserWindowHeight = Window.getClientHeight()
+ + Window.getScrollTop();
int t = calendarToggle.getAbsoluteTop();
int l = calendarToggle.getAbsoluteLeft();
- if (l + w > Window.getClientWidth()
- + Window.getScrollLeft()) {
- l = Window.getClientWidth() + Window.getScrollLeft()
- - w;
+
+ // Add a little extra space to the right to avoid
+ // problems with IE6/IE7 scrollbars and to make it look
+ // nicer.
+ int extraSpace = 30;
+
+ boolean overflowRight = false;
+ if (l + +w + extraSpace > browserWindowWidth) {
+ overflowRight = true;
+ // Part of the popup is outside the browser window
+ // (to the right)
+ l = browserWindowWidth - w - extraSpace;
}
- if (t + h + calendarToggle.getOffsetHeight() + 30 > Window
- .getClientHeight()
- + Window.getScrollTop()) {
- t = Window.getClientHeight() + Window.getScrollTop()
- - h - calendarToggle.getOffsetHeight() - 30;
- l += calendarToggle.getOffsetWidth();
+
+ if (t + h + calendarToggle.getOffsetHeight() + 30 > browserWindowHeight) {
+ // Part of the popup is outside the browser window
+ // (below)
+ t = browserWindowHeight - h
+ - calendarToggle.getOffsetHeight() - 30;
+ if (!overflowRight) {
+ // Show to the right of the popup button unless we
+ // are in the lower right corner of the screen
+ l += calendarToggle.getOffsetWidth();
+ }
}
// fix size
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java index 8e8a640e47..866ca99a0f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupView.java @@ -150,7 +150,18 @@ public class VPopupView extends HTML implements Container, Iterable<Widget> { popup.show(); } - private void showPopup(final CustomPopup popup) { + /** + * Determines the correct position for a popup and displays the popup at + * that position. + * + * By default, the popup is shown centered relative to its host component, + * ensuring it is visible on the screen if possible. + * + * Can be overridden to customize the popup position. + * + * @param popup + */ + protected void showPopup(final CustomPopup popup) { int windowTop = RootPanel.get().getAbsoluteTop(); int windowLeft = RootPanel.get().getAbsoluteLeft(); int windowRight = windowLeft + RootPanel.get().getOffsetWidth(); @@ -207,7 +218,13 @@ public class VPopupView extends HTML implements Container, Iterable<Widget> { } }-*/; - private class CustomPopup extends VOverlay { + /** + * This class is only protected to enable overriding showPopup, and is + * currently not intended to be extended or otherwise used directly. Its API + * (other than it being a VOverlay) is to be considered private and + * potentially subject to change. + */ + protected class CustomPopup extends VOverlay { private Paintable popupComponentPaintable = null; private Widget popupComponentWidget = null; diff --git a/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java b/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java index 58d4d5c021..ab9f20bcc3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VProgressIndicator.java @@ -21,6 +21,7 @@ public class VProgressIndicator extends Widget implements Paintable { private final Poller poller; private boolean indeterminate = false; private boolean pollerSuspendedDueDetach; + private int interval; public VProgressIndicator() { setElement(DOM.createDiv()); @@ -33,12 +34,10 @@ public class VProgressIndicator extends Widget implements Paintable { } public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { - if (client.updateComponent(this, uidl, true)) { - return; - } - - poller.cancel(); this.client = client; + if (!uidl.getBooleanAttribute("cached")) { + poller.cancel(); + } if (client.updateComponent(this, uidl, true)) { return; } @@ -61,7 +60,8 @@ public class VProgressIndicator extends Widget implements Paintable { } if (!uidl.getBooleanAttribute("disabled")) { - poller.scheduleRepeating(uidl.getIntAttribute("pollinginterval")); + interval = uidl.getIntAttribute("pollinginterval"); + poller.scheduleRepeating(interval); } } @@ -69,7 +69,7 @@ public class VProgressIndicator extends Widget implements Paintable { protected void onAttach() { super.onAttach(); if (pollerSuspendedDueDetach) { - poller.run(); + poller.scheduleRepeating(interval); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java index f73a2d4fc1..e66bf0fbc9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java @@ -36,6 +36,8 @@ public class VTabsheet extends VTabsheetBase { private class TabSheetCaption extends VCaption { private boolean hidden = false; + private boolean closable = false; + private Element closeButton; TabSheetCaption() { super(null, client); @@ -57,12 +59,29 @@ public class VTabsheet extends VTabsheetBase { client.registerTooltip(VTabsheet.this, getElement(), null); } - return super.updateCaption(uidl); + boolean ret = super.updateCaption(uidl); + + setClosable(uidl.hasAttribute("closable")); + + return ret; } @Override public void onBrowserEvent(Event event) { + if (closable && event.getTypeInt() == Event.ONCLICK + && event.getEventTarget().cast() == closeButton) { + final String tabKey = tabKeys.get(tb.getTabIndex(this)) + .toString(); + if (!disabledTabKeys.contains(tabKey)) { + client.updateVariable(id, "close", tabKey, true); + event.stopPropagation(); + event.preventDefault(); + return; + } + } + super.onBrowserEvent(event); + if (event.getTypeInt() == Event.ONLOAD) { // icon onloads may change total width of tabsheet if (isDynamicWidth()) { @@ -108,6 +127,35 @@ public class VTabsheet extends VTabsheetBase { this.hidden = hidden; } + public void setClosable(boolean closable) { + this.closable = closable; + if (closable && closeButton == null) { + closeButton = DOM.createSpan(); + closeButton.setInnerText("x"); + closeButton + .setClassName(VTabsheet.CLASSNAME + "-caption-close"); + getElement().insertBefore(closeButton, + getElement().getLastChild()); + } else if (!closable && closeButton != null) { + getElement().removeChild(closeButton); + closeButton = null; + } + if (closable) { + addStyleDependentName("closable"); + } else { + removeStyleDependentName("closable"); + } + } + + @Override + public int getRequiredWidth() { + int width = super.getRequiredWidth(); + if (closeButton != null) { + width += Util.getRequiredWidth(closeButton); + } + return width; + } + } class TabBar extends ComplexPanel implements ClickHandler { @@ -217,6 +265,10 @@ public class VTabsheet extends VTabsheetBase { return (TabSheetCaption) getWidget(index); } + public int getTabIndex(TabSheetCaption tab) { + return getChildren().indexOf(tab); + } + public void setVisible(int index, boolean visible) { com.google.gwt.dom.client.Element e = getTab(index).getElement() .getParentElement().getParentElement(); @@ -804,13 +856,13 @@ public class VTabsheet extends VTabsheetBase { // Make sure scrollerIndex is valid if (scrollerIndex > tb.getTabCount()) { scrollerIndex = getNextVisibleTab(-1); - } else if (tb.getTab(scrollerIndex).isHidden()) { + } else if (tb.getTabCount() > 0 && tb.getTab(scrollerIndex).isHidden()) { scrollerIndex = getNextVisibleTab(scrollerIndex); } boolean scrolled = isScrolledTabs(); boolean clipped = isClippedTabs(); - if (tb.isVisible() && (scrolled || clipped)) { + if (tb.getTabCount() > 0 && tb.isVisible() && (scrolled || clipped)) { DOM.setStyleAttribute(scroller, "display", ""); DOM.setElementProperty(scrollerPrev, "className", SCROLLER_CLASSNAME + (scrolled ? "Prev" : "Prev-disabled")); diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java index 4403aede35..845a50e793 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java @@ -10,7 +10,9 @@ import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; +import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.TextBoxBase; @@ -61,7 +63,8 @@ public class VTextField extends TextBoxBase implements Paintable, Field, protected VTextField(Element node) { super(node); - if (BrowserInfo.get().isIE()) { + if (BrowserInfo.get().getIEVersion() > 0 + && BrowserInfo.get().getIEVersion() < 8) { // Fixes IE margin problem (#2058) DOM.setStyleAttribute(node, "marginTop", "-1px"); DOM.setStyleAttribute(node, "marginBottom", "-1px"); @@ -110,13 +113,32 @@ public class VTextField extends TextBoxBase implements Paintable, Field, : null; setPrompting(inputPrompt != null && focusedTextField != this && (text == null || text.equals(""))); + + final String fieldValue; if (prompting) { - setText(inputPrompt); + fieldValue = inputPrompt; addStyleDependentName(CLASSNAME_PROMPT); } else { - setText(text); + fieldValue = text; removeStyleDependentName(CLASSNAME_PROMPT); } + if (BrowserInfo.get().isGecko()) { + /* + * Gecko is really sluggish when updating input attached to dom. + * Some optimizations seems to work much better in Gecko if we + * update the actual content lazily when the rest of the DOM has + * stabilized. In tests, about ten times better performance is + * achieved with this optimization. See for eg. #2898 + */ + DeferredCommand.addCommand(new Command() { + public void execute() { + setText(fieldValue); + } + }); + } else { + setText(fieldValue); + } + valueBeforeEdit = uidl.getStringVariable("text"); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java index af04890881..ea91c5eac1 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java @@ -1,330 +1,346 @@ -/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Date;
-
-import com.google.gwt.event.dom.client.BlurEvent;
-import com.google.gwt.event.dom.client.BlurHandler;
-import com.google.gwt.event.dom.client.ChangeEvent;
-import com.google.gwt.event.dom.client.ChangeHandler;
-import com.google.gwt.event.dom.client.FocusEvent;
-import com.google.gwt.event.dom.client.FocusHandler;
-import com.google.gwt.i18n.client.DateTimeFormat;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.ui.TextBox;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.ClientExceptionHandler;
-import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.Focusable;
-import com.vaadin.terminal.gwt.client.LocaleNotLoadedException;
-import com.vaadin.terminal.gwt.client.LocaleService;
-import com.vaadin.terminal.gwt.client.Paintable;
-import com.vaadin.terminal.gwt.client.UIDL;
-
-public class VTextualDate extends VDateField implements Paintable, Field,
- ChangeHandler, ContainerResizedListener, Focusable {
-
- private static final String PARSE_ERROR_CLASSNAME = CLASSNAME
- + "-parseerror";
-
- private final TextBox text;
-
- private String formatStr;
-
- private String width;
-
- private boolean needLayout;
-
- protected int fieldExtraWidth = -1;
-
- public VTextualDate() {
- super();
- text = new TextBox();
- // use normal textfield styles as a basis
- text.setStyleName(VTextField.CLASSNAME);
- // add datefield spesific style name also
- text.addStyleName(CLASSNAME + "-textfield");
- text.addChangeHandler(this);
- text.addFocusHandler(new FocusHandler() {
- public void onFocus(FocusEvent event) {
- text.addStyleName(VTextField.CLASSNAME + "-"
- + VTextField.CLASSNAME_FOCUS);
- }
- });
- text.addBlurHandler(new BlurHandler() {
- public void onBlur(BlurEvent event) {
- text.removeStyleName(VTextField.CLASSNAME + "-"
- + VTextField.CLASSNAME_FOCUS);
- }
- });
- add(text);
- }
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
- int origRes = currentResolution;
- super.updateFromUIDL(uidl, client);
- if (origRes != currentResolution) {
- // force recreating format string
- formatStr = null;
- }
- if (uidl.hasAttribute("format")) {
- formatStr = uidl.getStringAttribute("format");
- }
-
- buildDate();
- // not a FocusWidget -> needs own tabindex handling
- if (uidl.hasAttribute("tabindex")) {
- text.setTabIndex(uidl.getIntAttribute("tabindex"));
- }
-
- if (readonly) {
- text.addStyleDependentName("readonly");
- } else {
- text.removeStyleDependentName("readonly");
- }
- }
-
- protected String getFormatString() {
- if (formatStr == null) {
- if (currentResolution == RESOLUTION_YEAR) {
- formatStr = "yyyy"; // force full year
- } else {
-
- try {
- String frmString = LocaleService
- .getDateFormat(currentLocale);
- frmString = cleanFormat(frmString);
- String delim = LocaleService
- .getClockDelimiter(currentLocale);
-
- if (currentResolution >= RESOLUTION_HOUR) {
- if (dts.isTwelveHourClock()) {
- frmString += " hh";
- } else {
- frmString += " HH";
- }
- if (currentResolution >= RESOLUTION_MIN) {
- frmString += ":mm";
- if (currentResolution >= RESOLUTION_SEC) {
- frmString += ":ss";
- if (currentResolution >= RESOLUTION_MSEC) {
- frmString += ".SSS";
- }
- }
- }
- if (dts.isTwelveHourClock()) {
- frmString += " aaa";
- }
-
- }
-
- formatStr = frmString;
- } catch (LocaleNotLoadedException e) {
- ClientExceptionHandler.displayError(e);
- }
- }
- }
- return formatStr;
- }
-
- /**
- *
- */
- protected void buildDate() {
- removeStyleName(PARSE_ERROR_CLASSNAME);
- // Create the initial text for the textfield
- String dateText;
- if (date != null) {
- dateText = DateTimeFormat.getFormat(getFormatString()).format(date);
- } else {
- dateText = "";
- }
-
- text.setText(dateText);
- text.setEnabled(enabled);
- text.setReadOnly(readonly);
-
- if (readonly) {
- text.addStyleName("v-readonly");
- } else {
- text.removeStyleName("v-readonly");
- }
-
- }
-
- public void onChange(ChangeEvent event) {
- if (!text.getText().equals("")) {
- try {
- DateTimeFormat format = DateTimeFormat
- .getFormat(getFormatString());
- date = format.parse(text.getText());
- long stamp = date.getTime();
- if (stamp == 0) {
- // If date parsing fails in firefox the stamp will be 0
- date = null;
- addStyleName(PARSE_ERROR_CLASSNAME);
- } else {
- // remove possibly added invalid value indication
- removeStyleName(PARSE_ERROR_CLASSNAME);
- }
- } catch (final Exception e) {
- ClientExceptionHandler.displayError(e.getMessage());
-
- addStyleName(PARSE_ERROR_CLASSNAME);
- // this is a hack that may eventually be removed
- client.updateVariable(id, "lastInvalidDateString", text
- .getText(), false);
- date = null;
- }
- } else {
- date = null;
- // remove possibly added invalid value indication
- removeStyleName(PARSE_ERROR_CLASSNAME);
- }
- // always send the date string
- client.updateVariable(id, "dateString", text.getText(), false);
-
- if (date != null) {
- showingDate = new Date(date.getTime());
- }
-
- // Update variables
- // (only the smallest defining resolution needs to be
- // immediate)
- client.updateVariable(id, "year", date != null ? date.getYear() + 1900
- : -1, currentResolution == VDateField.RESOLUTION_YEAR
- && immediate);
- if (currentResolution >= VDateField.RESOLUTION_MONTH) {
- client.updateVariable(id, "month",
- date != null ? date.getMonth() + 1 : -1,
- currentResolution == VDateField.RESOLUTION_MONTH
- && immediate);
- }
- if (currentResolution >= VDateField.RESOLUTION_DAY) {
- client
- .updateVariable(id, "day", date != null ? date.getDate()
- : -1,
- currentResolution == VDateField.RESOLUTION_DAY
- && immediate);
- }
- if (currentResolution >= VDateField.RESOLUTION_HOUR) {
- client.updateVariable(id, "hour", date != null ? date.getHours()
- : -1, currentResolution == VDateField.RESOLUTION_HOUR
- && immediate);
- }
- if (currentResolution >= VDateField.RESOLUTION_MIN) {
- client.updateVariable(id, "min", date != null ? date.getMinutes()
- : -1, currentResolution == VDateField.RESOLUTION_MIN
- && immediate);
- }
- if (currentResolution >= VDateField.RESOLUTION_SEC) {
- client.updateVariable(id, "sec", date != null ? date.getSeconds()
- : -1, currentResolution == VDateField.RESOLUTION_SEC
- && immediate);
- }
- if (currentResolution == VDateField.RESOLUTION_MSEC) {
- client.updateVariable(id, "msec", date != null ? getMilliseconds()
- : -1, immediate);
- }
-
- }
-
- private String cleanFormat(String format) {
- // Remove unnecessary d & M if resolution is too low
- if (currentResolution < VDateField.RESOLUTION_DAY) {
- format = format.replaceAll("d", "");
- }
- if (currentResolution < VDateField.RESOLUTION_MONTH) {
- format = format.replaceAll("M", "");
- }
-
- // Remove unsupported patterns
- // TODO support for 'G', era designator (used at least in Japan)
- format = format.replaceAll("[GzZwWkK]", "");
-
- // Remove extra delimiters ('/' and '.')
- while (format.startsWith("/") || format.startsWith(".")
- || format.startsWith("-")) {
- format = format.substring(1);
- }
- while (format.endsWith("/") || format.endsWith(".")
- || format.endsWith("-")) {
- format = format.substring(0, format.length() - 1);
- }
-
- // Remove duplicate delimiters
- format = format.replaceAll("//", "/");
- format = format.replaceAll("\\.\\.", ".");
- format = format.replaceAll("--", "-");
-
- return format.trim();
- }
-
- @Override
- public void setWidth(String newWidth) {
- if (!"".equals(newWidth) && (width == null || !newWidth.equals(width))) {
- if (BrowserInfo.get().isIE6()) {
- // in IE6 cols ~ min-width
- DOM.setElementProperty(text.getElement(), "size", "1");
- }
- needLayout = true;
- width = newWidth;
- super.setWidth(width);
- iLayout();
- if (newWidth.indexOf("%") < 0) {
- needLayout = false;
- }
- } else {
- if ("".equals(newWidth) && width != null && !"".equals(width)) {
- if (BrowserInfo.get().isIE6()) {
- // revert IE6 hack
- DOM.setElementProperty(text.getElement(), "size", "");
- }
- super.setWidth("");
- needLayout = true;
- iLayout();
- needLayout = false;
- width = null;
- }
- }
- }
-
- /**
- * Returns pixels in x-axis reserved for other than textfield content.
- *
- * @return extra width in pixels
- */
- protected int getFieldExtraWidth() {
- if (fieldExtraWidth < 0) {
- text.setWidth("0");
- fieldExtraWidth = text.getOffsetWidth();
- if (BrowserInfo.get().isFF3()) {
- // Firefox somehow always leaves the INPUT element 2px wide
- fieldExtraWidth -= 2;
- }
- }
- return fieldExtraWidth;
- }
-
- public void updateWidth() {
- needLayout = true;
- fieldExtraWidth = -1;
- iLayout();
- }
-
- public void iLayout() {
- if (needLayout) {
- text.setWidth((getOffsetWidth() - getFieldExtraWidth()) + "px");
- }
- }
-
- public void focus() {
- text.setFocus(true);
- }
-}
+/* +@ITMillApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.ui; + +import java.util.Date; + +import com.google.gwt.event.dom.client.BlurEvent; +import com.google.gwt.event.dom.client.BlurHandler; +import com.google.gwt.event.dom.client.ChangeEvent; +import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.dom.client.FocusEvent; +import com.google.gwt.event.dom.client.FocusHandler; +import com.google.gwt.i18n.client.DateTimeFormat; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.ui.TextBox; +import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.BrowserInfo; +import com.vaadin.terminal.gwt.client.ClientExceptionHandler; +import com.vaadin.terminal.gwt.client.ContainerResizedListener; +import com.vaadin.terminal.gwt.client.Focusable; +import com.vaadin.terminal.gwt.client.LocaleNotLoadedException; +import com.vaadin.terminal.gwt.client.LocaleService; +import com.vaadin.terminal.gwt.client.Paintable; +import com.vaadin.terminal.gwt.client.UIDL; + +public class VTextualDate extends VDateField implements Paintable, Field, + ChangeHandler, ContainerResizedListener, Focusable { + + private static final String PARSE_ERROR_CLASSNAME = CLASSNAME + + "-parseerror"; + + private final TextBox text; + + private String formatStr; + + private String width; + + private boolean needLayout; + + protected int fieldExtraWidth = -1; + + private boolean lenient; + + public VTextualDate() { + + super(); + text = new TextBox(); + // use normal textfield styles as a basis + text.setStyleName(VTextField.CLASSNAME); + // add datefield spesific style name also + text.addStyleName(CLASSNAME + "-textfield"); + text.addChangeHandler(this); + text.addFocusHandler(new FocusHandler() { + public void onFocus(FocusEvent event) { + text.addStyleName(VTextField.CLASSNAME + "-" + + VTextField.CLASSNAME_FOCUS); + } + }); + text.addBlurHandler(new BlurHandler() { + public void onBlur(BlurEvent event) { + text.removeStyleName(VTextField.CLASSNAME + "-" + + VTextField.CLASSNAME_FOCUS); + } + }); + add(text); + } + + @Override + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + + int origRes = currentResolution; + super.updateFromUIDL(uidl, client); + if (origRes != currentResolution) { + // force recreating format string + formatStr = null; + } + if (uidl.hasAttribute("format")) { + formatStr = uidl.getStringAttribute("format"); + } + + lenient = !uidl.getBooleanAttribute("strict"); + + buildDate(); + // not a FocusWidget -> needs own tabindex handling + if (uidl.hasAttribute("tabindex")) { + text.setTabIndex(uidl.getIntAttribute("tabindex")); + } + + if (readonly) { + text.addStyleDependentName("readonly"); + } else { + text.removeStyleDependentName("readonly"); + } + } + + protected String getFormatString() { + if (formatStr == null) { + if (currentResolution == RESOLUTION_YEAR) { + formatStr = "yyyy"; // force full year + } else { + + try { + String frmString = LocaleService + .getDateFormat(currentLocale); + frmString = cleanFormat(frmString); + String delim = LocaleService + .getClockDelimiter(currentLocale); + + if (currentResolution >= RESOLUTION_HOUR) { + if (dts.isTwelveHourClock()) { + frmString += " hh"; + } else { + frmString += " HH"; + } + if (currentResolution >= RESOLUTION_MIN) { + frmString += ":mm"; + if (currentResolution >= RESOLUTION_SEC) { + frmString += ":ss"; + if (currentResolution >= RESOLUTION_MSEC) { + frmString += ".SSS"; + } + } + } + if (dts.isTwelveHourClock()) { + frmString += " aaa"; + } + + } + + formatStr = frmString; + } catch (LocaleNotLoadedException e) { + ClientExceptionHandler.displayError(e); + } + } + } + return formatStr; + } + + /** + * + */ + protected void buildDate() { + removeStyleName(PARSE_ERROR_CLASSNAME); + // Create the initial text for the textfield + String dateText; + if (date != null) { + dateText = DateTimeFormat.getFormat(getFormatString()).format(date); + } else { + dateText = ""; + } + + text.setText(dateText); + text.setEnabled(enabled); + text.setReadOnly(readonly); + + if (readonly) { + text.addStyleName("v-readonly"); + } else { + text.removeStyleName("v-readonly"); + } + + } + + public void onChange(ChangeEvent event) { + if (!text.getText().equals("")) { + try { + DateTimeFormat format = DateTimeFormat + .getFormat(getFormatString()); + if (lenient) { + date = format.parse(text.getText()); + if (date != null) { + // if date value was leniently parsed, normalize text + // presentation + text.setValue(DateTimeFormat.getFormat( + getFormatString()).format(date), false); + } + } else { + date = format.parseStrict(text.getText()); + } + + long stamp = date.getTime(); + if (stamp == 0) { + // If date parsing fails in firefox the stamp will be 0 + date = null; + addStyleName(PARSE_ERROR_CLASSNAME); + } else { + // remove possibly added invalid value indication + removeStyleName(PARSE_ERROR_CLASSNAME); + } + } catch (final Exception e) { + ClientExceptionHandler.displayError(e.getMessage()); + + addStyleName(PARSE_ERROR_CLASSNAME); + // this is a hack that may eventually be removed + client.updateVariable(id, "lastInvalidDateString", text + .getText(), false); + date = null; + } + } else { + date = null; + // remove possibly added invalid value indication + removeStyleName(PARSE_ERROR_CLASSNAME); + } + // always send the date string + client.updateVariable(id, "dateString", text.getText(), false); + + if (date != null) { + showingDate = new Date(date.getTime()); + } + + // Update variables + // (only the smallest defining resolution needs to be + // immediate) + client.updateVariable(id, "year", date != null ? date.getYear() + 1900 + : -1, currentResolution == VDateField.RESOLUTION_YEAR + && immediate); + if (currentResolution >= VDateField.RESOLUTION_MONTH) { + client.updateVariable(id, "month", + date != null ? date.getMonth() + 1 : -1, + currentResolution == VDateField.RESOLUTION_MONTH + && immediate); + } + if (currentResolution >= VDateField.RESOLUTION_DAY) { + client + .updateVariable(id, "day", date != null ? date.getDate() + : -1, + currentResolution == VDateField.RESOLUTION_DAY + && immediate); + } + if (currentResolution >= VDateField.RESOLUTION_HOUR) { + client.updateVariable(id, "hour", date != null ? date.getHours() + : -1, currentResolution == VDateField.RESOLUTION_HOUR + && immediate); + } + if (currentResolution >= VDateField.RESOLUTION_MIN) { + client.updateVariable(id, "min", date != null ? date.getMinutes() + : -1, currentResolution == VDateField.RESOLUTION_MIN + && immediate); + } + if (currentResolution >= VDateField.RESOLUTION_SEC) { + client.updateVariable(id, "sec", date != null ? date.getSeconds() + : -1, currentResolution == VDateField.RESOLUTION_SEC + && immediate); + } + if (currentResolution == VDateField.RESOLUTION_MSEC) { + client.updateVariable(id, "msec", date != null ? getMilliseconds() + : -1, immediate); + } + + } + + private String cleanFormat(String format) { + // Remove unnecessary d & M if resolution is too low + if (currentResolution < VDateField.RESOLUTION_DAY) { + format = format.replaceAll("d", ""); + } + if (currentResolution < VDateField.RESOLUTION_MONTH) { + format = format.replaceAll("M", ""); + } + + // Remove unsupported patterns + // TODO support for 'G', era designator (used at least in Japan) + format = format.replaceAll("[GzZwWkK]", ""); + + // Remove extra delimiters ('/' and '.') + while (format.startsWith("/") || format.startsWith(".") + || format.startsWith("-")) { + format = format.substring(1); + } + while (format.endsWith("/") || format.endsWith(".") + || format.endsWith("-")) { + format = format.substring(0, format.length() - 1); + } + + // Remove duplicate delimiters + format = format.replaceAll("//", "/"); + format = format.replaceAll("\\.\\.", "."); + format = format.replaceAll("--", "-"); + + return format.trim(); + } + + @Override + public void setWidth(String newWidth) { + if (!"".equals(newWidth) && (width == null || !newWidth.equals(width))) { + if (BrowserInfo.get().isIE6()) { + // in IE6 cols ~ min-width + DOM.setElementProperty(text.getElement(), "size", "1"); + } + needLayout = true; + width = newWidth; + super.setWidth(width); + iLayout(); + if (newWidth.indexOf("%") < 0) { + needLayout = false; + } + } else { + if ("".equals(newWidth) && width != null && !"".equals(width)) { + if (BrowserInfo.get().isIE6()) { + // revert IE6 hack + DOM.setElementProperty(text.getElement(), "size", ""); + } + super.setWidth(""); + needLayout = true; + iLayout(); + needLayout = false; + width = null; + } + } + } + + /** + * Returns pixels in x-axis reserved for other than textfield content. + * + * @return extra width in pixels + */ + protected int getFieldExtraWidth() { + if (fieldExtraWidth < 0) { + text.setWidth("0"); + fieldExtraWidth = text.getOffsetWidth(); + if (BrowserInfo.get().isFF3()) { + // Firefox somehow always leaves the INPUT element 2px wide + fieldExtraWidth -= 2; + } + } + return fieldExtraWidth; + } + + public void updateWidth() { + needLayout = true; + fieldExtraWidth = -1; + iLayout(); + } + + public void iLayout() { + if (needLayout) { + text.setWidth((getOffsetWidth() - getFieldExtraWidth()) + "px"); + } + } + + public void focus() { + text.setFocus(true); + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java index 64b86c47b3..aded833138 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java @@ -122,8 +122,9 @@ public class VUpload extends FormPanel implements Paintable, if (uidl.hasAttribute("disabled") || uidl.hasAttribute("readonly")) { disableUpload(); - } else if (uidl.getBooleanAttribute("state")) { - enableUploaod(); + } else if (!uidl.getBooleanAttribute("state")) { + // Enable the button only if an upload is not in progress + enableUpload(); } } @@ -150,13 +151,17 @@ public class VUpload extends FormPanel implements Paintable, protected void disableUpload() { submitButton.setEnabled(false); - // fu.getElement().setPropertyBoolean("disabled", true); + if (!submitted) { + // Cannot disable the fileupload while submitting or the file won't + // be submitted at all + fu.getElement().setPropertyBoolean("disabled", true); + } enabled = false; } - protected void enableUploaod() { + protected void enableUpload() { submitButton.setEnabled(true); - // fu.getElement().setPropertyBoolean("disabled", false); + fu.getElement().setPropertyBoolean("disabled", false); enabled = true; } @@ -169,7 +174,7 @@ public class VUpload extends FormPanel implements Paintable, panel.remove(fu); fu = new MyFileUpload(); fu.setName(paintableId + "_file"); - // fu.getElement().setPropertyBoolean("disabled", !enabled); + fu.getElement().setPropertyBoolean("disabled", !enabled); panel.add(fu); panel.add(submitButton); if (immediate) { @@ -189,7 +194,7 @@ public class VUpload extends FormPanel implements Paintable, rebuildPanel(); submitted = false; - enableUploaod(); + enableUpload(); } public void onSubmit(SubmitEvent event) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VView.java b/src/com/vaadin/terminal/gwt/client/ui/VView.java index 35b411ff1b..bfa4a653bd 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VView.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VView.java @@ -143,6 +143,21 @@ public class VView extends SimplePanel implements Container, ResizeHandler, $wnd.location.reload(); }-*/; + /** + * Evaluate the given script in the browser document. + * + * @param script + * Script to be executed. + */ + private static native void eval(String script) + /*-{ + try { + if (script == null) return; + $wnd.eval(script); + } catch (e) { + } + }-*/; + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { rendering = true; @@ -263,6 +278,9 @@ public class VView extends SimplePanel implements Container, ResizeHandler, actionHandler = new ShortcutActionHandler(id, client); } actionHandler.updateActionMap(childUidl); + } else if (tag == "execJS") { + String script = childUidl.getStringAttribute("script"); + eval(script); } else if (tag == "notifications") { for (final Iterator it = childUidl.getChildIterator(); it .hasNext();) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java index 90d31698ed..a2a64dcf5a 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VWindow.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VWindow.java @@ -39,19 +39,34 @@ import com.vaadin.terminal.gwt.client.VDebugConsole; */ public class VWindow extends VOverlay implements Container, ScrollListener { - private static final int MIN_HEIGHT = 100; + /** + * Minimum allowed height of a window. This refers to the content area, not + * the outer borders. + */ + private static final int MIN_CONTENT_AREA_HEIGHT = 100; - private static final int MIN_WIDTH = 150; + /** + * Minimum allowed width of a window. This refers to the content area, not + * the outer borders. + */ + private static final int MIN_CONTENT_AREA_WIDTH = 150; private static ArrayList<VWindow> windowOrder = new ArrayList<VWindow>(); public static final String CLASSNAME = "v-window"; /** + * Difference between offsetWidth and inner width for the content area. + */ + private int contentAreaBorderPadding = -1; + /** * Pixels used by inner borders and paddings horizontally (calculated only - * once) + * once). This is the difference between the width of the root element and + * the content area, such that if root element width is set to "XYZpx" the + * inner width (width-border-padding) of the content area is + * X-contentAreaRootDifference. */ - private int borderWidth = -1; + private int contentAreaToRootDifference = -1; private static final int STACKING_OFFSET_PIXELS = 15; @@ -120,8 +135,8 @@ public class VWindow extends VOverlay implements Container, ScrollListener { // resizes the window. boolean centered = false; - private RenderSpace renderSpace = new RenderSpace(MIN_WIDTH, MIN_HEIGHT, - true); + private RenderSpace renderSpace = new RenderSpace(MIN_CONTENT_AREA_WIDTH, + MIN_CONTENT_AREA_HEIGHT, true); private String width; @@ -129,6 +144,8 @@ public class VWindow extends VOverlay implements Container, ScrollListener { private boolean immediate; + private Element wrapper, wrapper2; + public VWindow() { super(false, false, true); // no autohide, not modal, shadow // Different style of shadow for windows @@ -198,10 +215,10 @@ public class VWindow extends VOverlay implements Container, ScrollListener { DOM.sinkEvents(closeBox, Event.ONCLICK); DOM.sinkEvents(contents, Event.ONCLICK); - final Element wrapper = DOM.createDiv(); + wrapper = DOM.createDiv(); DOM.setElementProperty(wrapper, "className", CLASSNAME + "-wrap"); - final Element wrapper2 = DOM.createDiv(); + wrapper2 = DOM.createDiv(); DOM.setElementProperty(wrapper2, "className", CLASSNAME + "-wrap2"); DOM.sinkEvents(wrapper, Event.ONKEYDOWN); @@ -439,39 +456,78 @@ public class VWindow extends VOverlay implements Container, ScrollListener { client.updateVariable(id, "width", w, true); } + Util.runWebkitOverflowAutoFix(contentPanel.getElement()); + } private void setNaturalWidth() { /* - * For some reason IE6 has title DIV set to width 100% which messes this - * up. Also IE6 has a 0 wide element so we use the container element. + * Use max(layout width, window width) i.e layout content width or + * caption width. We remove the previous set width so the width is + * allowed to shrink. All widths are measured as outer sizes, i.e. the + * borderWidth is added to the content. */ - int naturalWidth; + + DOM.setStyleAttribute(getElement(), "width", ""); + + String oldHeaderWidth = ""; // Only for IE6 if (BrowserInfo.get().isIE6()) { - String headerW = headerText.getStyle().getProperty("width"); + /* + * For some reason IE6 has title DIV set to width 100% which + * interferes with the header measuring. Also IE6 has width set to + * the contentPanel. + */ + oldHeaderWidth = headerText.getStyle().getProperty("width"); + DOM.setStyleAttribute(contentPanel.getElement(), "width", "auto"); + DOM.setStyleAttribute(contentPanel.getElement(), "zoom", "1"); headerText.getStyle().setProperty("width", "auto"); - naturalWidth = getElement().getOffsetWidth(); - headerText.getStyle().setProperty("width", headerW); - } else { - // use max(layout width, window width) - // i.e layout content width or caption width - int lowidth = contentPanel.getElement().getScrollWidth() - + getBorderWidth(); // layout does not know about border - int elwidth = getElement().getOffsetWidth(); - naturalWidth = (lowidth > elwidth ? lowidth : elwidth); + } + + // Content + int contentWidth = contentPanel.getElement().getScrollWidth(); + contentWidth += getContentAreaToRootDifference(); + + // Window width (caption) + int windowCaptionWidth = getOffsetWidth(); + + int naturalWidth = (contentWidth > windowCaptionWidth ? contentWidth + : windowCaptionWidth); + + if (BrowserInfo.get().isIE6()) { + headerText.getStyle().setProperty("width", oldHeaderWidth); } setWidth(naturalWidth + "px"); } - private int getBorderWidth() { - if (borderWidth < 0) { - if (!isAttached()) { - return 0; - } - borderWidth = Util.measureHorizontalPaddingAndBorder(contents, 4); + private int getContentAreaToRootDifference() { + if (contentAreaToRootDifference < 0) { + measure(); + } + return contentAreaToRootDifference; + } + + private int getContentAreaBorderPadding() { + if (contentAreaBorderPadding < 0) { + measure(); + } + return contentAreaBorderPadding; + } + + private void measure() { + if (!isAttached()) { + return; } - return borderWidth; + + contentAreaBorderPadding = Util.measureHorizontalPaddingAndBorder( + contents, 4); + int wrapperPaddingBorder = Util.measureHorizontalPaddingAndBorder( + wrapper, 0) + + Util.measureHorizontalPaddingAndBorder(wrapper2, 0); + + contentAreaToRootDifference = wrapperPaddingBorder + + contentAreaBorderPadding; + } private void setReadOnly(boolean readonly) { @@ -753,15 +809,45 @@ public class VWindow extends VOverlay implements Container, ScrollListener { } } + /** + * Checks if the cursor was inside the browser content area when the event + * happened. + * + * @param event + * The event to be checked + * @return true, if the cursor is inside the browser content area + * + * false, otherwise + */ + private boolean cursorInsideBrowserContentArea(Event event) { + if (event.getClientX() < 0 || event.getClientY() < 0) { + // Outside to the left or above + return false; + } + + if (event.getClientX() > Window.getClientWidth() + || event.getClientY() > Window.getClientHeight()) { + // Outside to the right or below + return false; + } + + return true; + } + private void setSize(Event event, boolean updateVariables) { + if (!cursorInsideBrowserContentArea(event)) { + // Only drag while cursor is inside the browser client area + return; + } + int w = event.getScreenX() - startX + origW; - if (w < MIN_WIDTH + getBorderWidth()) { - w = MIN_WIDTH + getBorderWidth(); + if (w < MIN_CONTENT_AREA_WIDTH + getContentAreaToRootDifference()) { + w = MIN_CONTENT_AREA_WIDTH + getContentAreaToRootDifference(); } int h = event.getScreenY() - startY + origH; - if (h < MIN_HEIGHT + getExtraHeight()) { - h = MIN_HEIGHT + getExtraHeight(); + if (h < MIN_CONTENT_AREA_HEIGHT + getExtraHeight()) { + h = MIN_CONTENT_AREA_HEIGHT + getExtraHeight(); } setWidth(w + "px"); @@ -795,22 +881,37 @@ public class VWindow extends VOverlay implements Container, ScrollListener { return; } if (width != null && !"".equals(width)) { - int pixelWidth; - // Convert non-pixel values to pixels + int rootPixelWidth = -1; if (width.indexOf("px") < 0) { + /* + * Convert non-pixel values to pixels by setting the width and + * then measuring it. Updates the "width" variable with the + * pixel width. + */ DOM.setStyleAttribute(getElement(), "width", width); - pixelWidth = getElement().getOffsetWidth(); - width = pixelWidth + "px"; + rootPixelWidth = getElement().getOffsetWidth(); + width = rootPixelWidth + "px"; + } else { + rootPixelWidth = Integer.parseInt(width.substring(0, width + .indexOf("px"))); } + + // "width" now contains the new width in pixels + if (BrowserInfo.get().isIE6()) { getElement().getStyle().setProperty("overflow", "hidden"); } + + // Apply the new pixel width getElement().getStyle().setProperty("width", width); - pixelWidth = getElement().getOffsetWidth() - getBorderWidth(); - if (pixelWidth < MIN_WIDTH) { - pixelWidth = MIN_WIDTH; - int rootWidth = pixelWidth + getBorderWidth(); + // Caculate the inner width of the content area + int contentAreaInnerWidth = rootPixelWidth + - getContentAreaToRootDifference(); + if (contentAreaInnerWidth < MIN_CONTENT_AREA_WIDTH) { + contentAreaInnerWidth = MIN_CONTENT_AREA_WIDTH; + int rootWidth = contentAreaInnerWidth + + getContentAreaToRootDifference(); DOM.setStyleAttribute(getElement(), "width", rootWidth + "px"); } @@ -819,10 +920,10 @@ public class VWindow extends VOverlay implements Container, ScrollListener { // appear, content flows out of window) if (BrowserInfo.get().isIE6()) { DOM.setStyleAttribute(contentPanel.getElement(), "width", - pixelWidth + "px"); + contentAreaInnerWidth + "px"); } - renderSpace.setWidth(contents.getOffsetWidth() - getBorderWidth()); + renderSpace.setWidth(contentAreaInnerWidth); updateShadowSizeAndPosition(); } @@ -843,8 +944,8 @@ public class VWindow extends VOverlay implements Container, ScrollListener { if (height != null && !"".equals(height)) { DOM.setStyleAttribute(getElement(), "height", height); int pixels = getElement().getOffsetHeight() - getExtraHeight(); - if (pixels < MIN_HEIGHT) { - pixels = MIN_HEIGHT; + if (pixels < MIN_CONTENT_AREA_HEIGHT) { + pixels = MIN_CONTENT_AREA_HEIGHT; int rootHeight = pixels + getExtraHeight(); DOM.setStyleAttribute(getElement(), "height", (rootHeight) + "px"); @@ -892,9 +993,12 @@ public class VWindow extends VOverlay implements Container, ScrollListener { case Event.ONMOUSEMOVE: if (dragging) { centered = false; - final int x = DOM.eventGetScreenX(event) - startX + origX; - final int y = DOM.eventGetScreenY(event) - startY + origY; - setPopupPosition(x, y); + if (cursorInsideBrowserContentArea(event)) { + // Only drag while cursor is inside the browser client area + final int x = DOM.eventGetScreenX(event) - startX + origX; + final int y = DOM.eventGetScreenY(event) - startY + origY; + setPopupPosition(x, y); + } DOM.eventPreventDefault(event); } break; diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index 995ec384a1..5fe2bacfc9 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -45,11 +45,11 @@ import com.vaadin.ui.Window; /** * Abstract implementation of the ApplicationServlet which handles all * communication between the client and the server. - * + * * It is possible to extend this class to provide own functionality but in most * cases this is unnecessary. - * - * + * + * * @author IT Mill Ltd. * @version * @VERSION@ @@ -146,7 +146,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Called by the servlet container to indicate to a servlet that the servlet * is being placed into service. - * + * * @param servletConfig * the object containing the servlet's configuration and * initialization parameters @@ -215,7 +215,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets an application property value. - * + * * @param parameterName * the Name or the parameter. * @return String value or null if not found @@ -236,7 +236,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets an system property value. - * + * * @param parameterName * the Name or the parameter. * @return String value or null if not found @@ -265,7 +265,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets an application or system property value. - * + * * @param parameterName * the Name or the parameter. * @param defaultValue @@ -295,7 +295,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Returns true if the servlet is running in production mode. Production * mode disables all debug facilities. - * + * * @return true if in production mode, false if in debug mode */ public boolean isProductionMode() { @@ -305,7 +305,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Receives standard HTTP requests from the public service method and * dispatches them. - * + * * @param request * the object that contains the request the client made of the * servlet. @@ -469,7 +469,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Send notification to client's application. Used to notify client of * critical errors and session expiration due to long inactivity. Server has * no knowledge of what application client refers to. - * + * * @param request * the HTTP request instance. * @param response @@ -531,7 +531,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Returns the application instance to be used for the request. If an * existing instance is not found a new one is created or null is returned * to indicate that the application is not available. - * + * * @param request * @param requestType * @return @@ -596,7 +596,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Check if the request should create an application if an existing * application is not found. - * + * * @param request * @param requestType * @return true if an application should be created, false otherwise @@ -627,7 +627,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Gets resource path using different implementations. Required to * supporting different servlet container implementations (application * servers). - * + * * @param servletContext * @param path * the resource path. @@ -656,16 +656,16 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * processing, when a certain URI is requested. The handlers are invoked * before any windows URIs are processed and if a DownloadStream is returned * it is sent to the client. - * + * * @param stream * the download stream. - * + * * @param request * the HTTP request instance. * @param response * the HTTP response to write to. * @throws IOException - * + * * @see com.vaadin.terminal.URIHandler */ @SuppressWarnings("unchecked") @@ -737,7 +737,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements out.flush(); } out.close(); - + data.close(); } } @@ -746,7 +746,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Creates a new application and registers it into WebApplicationContext * (aka session). This is not meant to be overridden. Override * getNewApplication to create the application instance in a custom way. - * + * * @param request * @return * @throws ServletException @@ -787,7 +787,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Returns the theme for given request/window - * + * * @param request * @param window * @return @@ -818,7 +818,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Returns the default theme. Must never return null. - * + * * @return */ public static String getDefaultTheme() { @@ -828,7 +828,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Calls URI handlers for the request. If an URI handler returns a * DownloadStream the stream is passed to the client for downloading. - * + * * @param applicationManager * @param window * @param request @@ -875,7 +875,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Invalidate session (weird to have session if we're saying * that it's expired, and worse: portal integration will fail * since the session is not created by the portal. - * + * * Session must be invalidated before criticalNotification as it * commits the response. */ @@ -931,7 +931,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Creates a new application for the given request. - * + * * @param request * the HTTP request. * @return A new Application instance. @@ -942,7 +942,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Starts the application if it is not already running. - * + * * @param request * @param application * @param webApplicationContext @@ -969,7 +969,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Check if this is a request for a static resource and, if it is, serve the * resource to the client. Returns true if a file was served and the request * has been handled, false otherwise. - * + * * @param request * @param response * @return @@ -1001,7 +1001,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Serve resources from VAADIN directory. - * + * * @param request * @param response * @throws IOException @@ -1111,7 +1111,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Get system messages from the current application class - * + * * @return */ protected SystemMessages getSystemMessages() { @@ -1147,10 +1147,10 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Return the URL from where static files, e.g. the widgetset and the theme, * are served. In a standard configuration the VAADIN folder inside the * returned folder is what is used for widgetsets and themes. - * + * * The returned folder is usually the same as the context path and * independent of the application. - * + * * @param request * @return The location of static resources (should contain the VAADIN * directory). Never ends with a slash (/). @@ -1172,7 +1172,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * The default method to fetch static files location. This method does not * check for request attribute {@value #REQUEST_VAADIN_STATIC_FILE_PATH}. - * + * * @param request * @return */ @@ -1215,7 +1215,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Remove any heading or trailing "what" from the "string". - * + * * @param string * @param what * @return @@ -1234,7 +1234,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Write a redirect response to the main page of the application. - * + * * @param request * @param response * @throws IOException @@ -1264,7 +1264,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * {@link #writeAjaxPageHtmlMainDiv(BufferedWriter, String, String, String)} * <li> {@link #writeAjaxPageHtmlBodyEnd(BufferedWriter)} * </ul> - * + * * @param request * the HTTP request. * @param response @@ -1376,10 +1376,10 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Get the URI for the application theme. - * + * * A portal-wide default theme is fetched from the portal shared resource * directory (if any), other themes from the portlet. - * + * * @param themeName * @param request * @return @@ -1409,7 +1409,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Override this method if you want to add some custom html around around * the div element into which the actual vaadin application will be * rendered. - * + * * @param page * @param appId * @param classNames @@ -1425,12 +1425,12 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements } /** - * + * * * Method to write the script part of the page which loads needed vaadin * scripts and themes. * <p> * Override this method if you want to add some custom html around scripts. - * + * * @param window * @param themeName * @param application @@ -1458,8 +1458,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements // If no shared widgetset is specified, the default widgetset is // assumed to be in the servlet/portlet itself. requestWidgetset = getApplicationOrSystemProperty( - PARAMETER_WIDGETSET, - DEFAULT_WIDGETSET); + PARAMETER_WIDGETSET, DEFAULT_WIDGETSET); } String widgetset; @@ -1573,14 +1572,14 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements } /** - * + * * Method to open the body tag of the html kickstart page. * <p> * This method is responsible for closing the head tag and opening the body * tag. * <p> * Override this method if you want to add some custom html to the page. - * + * * @param page * @throws IOException */ @@ -1595,7 +1594,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * <p> * Override this method if you want to add some custom html to the header of * the page. - * + * * @param page * @param title * @param themeUri @@ -1606,7 +1605,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements page .write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n"); page.write("<style type=\"text/css\">" - + "html, body {height:100%;}</style>"); + + "html, body {height:100%;margin:0;}</style>"); // Add favicon links page @@ -1627,7 +1626,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * <p> * Override this method if you want to add some custom html to the very * beginning of the page. - * + * * @param page * @throws IOException */ @@ -1647,7 +1646,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements * Method to set http request headers for the Vaadin kickstart page. * <p> * Override this method if you need to customize http headers of the page. - * + * * @param response */ protected void setAjaxPageHeaders(HttpServletResponse response) { @@ -1668,7 +1667,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets the current application URL from request. - * + * * @param request * the HTTP request. * @throws MalformedURLException @@ -1708,7 +1707,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets the existing application for given request. Looks for application * instance for given request based on the requested URL. - * + * * @param request * the HTTP request. * @param allowSessionCreation @@ -1768,7 +1767,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Ends the application. - * + * * @param request * the HTTP request. * @param response @@ -1799,7 +1798,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets the existing application or create a new one. Get a window within an * application based on the requested URI. - * + * * @param request * the HTTP Request. * @param application @@ -1845,7 +1844,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Returns the path info; note that this _can_ be different than * request.getPathInfo() (e.g application runner). - * + * * @param request * @return */ @@ -1855,7 +1854,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets relative location of a theme resource. - * + * * @param theme * the Theme name. * @param resource @@ -1902,7 +1901,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets the contained throwable. - * + * * @see com.vaadin.terminal.Terminal.ErrorEvent#getThrowable() */ public Throwable getThrowable() { @@ -1911,7 +1910,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets the source ParameterHandler. - * + * * @see com.vaadin.terminal.ParameterHandler.ErrorEvent#getParameterHandler() */ public ParameterHandler getParameterHandler() { @@ -1931,7 +1930,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements private final Throwable throwable; /** - * + * * @param owner * @param throwable */ @@ -1942,7 +1941,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets the contained throwable. - * + * * @see com.vaadin.terminal.Terminal.ErrorEvent#getThrowable() */ public Throwable getThrowable() { @@ -1951,7 +1950,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements /** * Gets the source URIHandler. - * + * * @see com.vaadin.terminal.URIHandler.ErrorEvent#getURIHandler() */ public URIHandler getURIHandler() { diff --git a/src/com/vaadin/terminal/gwt/server/ApplicationRunnerServlet.java b/src/com/vaadin/terminal/gwt/server/ApplicationRunnerServlet.java index 8ffd7b3f16..aeb1b50c9c 100644 --- a/src/com/vaadin/terminal/gwt/server/ApplicationRunnerServlet.java +++ b/src/com/vaadin/terminal/gwt/server/ApplicationRunnerServlet.java @@ -19,7 +19,7 @@ public class ApplicationRunnerServlet extends AbstractApplicationServlet { * request. */ private String[] defaultPackages; - private HttpServletRequest request; + private ThreadLocal<HttpServletRequest> request = new ThreadLocal<HttpServletRequest>(); @Override public void init(ServletConfig servletConfig) throws ServletException { @@ -34,9 +34,9 @@ public class ApplicationRunnerServlet extends AbstractApplicationServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - this.request = request; + this.request.set(request); super.service(request, response); - this.request = null; + this.request.set(null); } @Override @@ -150,25 +150,30 @@ public class ApplicationRunnerServlet extends AbstractApplicationServlet { Class<? extends Application> appClass = null; - String baseName = getApplicationRunnerApplicationClassName(request); + String baseName = getApplicationRunnerApplicationClassName(request + .get()); try { appClass = (Class<? extends Application>) getClass() .getClassLoader().loadClass(baseName); return appClass; } catch (Exception e) { // - for (int i = 0; i < defaultPackages.length; i++) { - try { - appClass = (Class<? extends Application>) getClass() - .getClassLoader().loadClass( - defaultPackages[i] + "." + baseName); - } catch (Exception e2) { - // TODO: handle exception - } - if (appClass != null) { - return appClass; + if (defaultPackages != null) { + for (int i = 0; i < defaultPackages.length; i++) { + try { + appClass = (Class<? extends Application>) getClass() + .getClassLoader().loadClass( + defaultPackages[i] + "." + baseName); + } catch (Exception e2) { + // TODO: handle exception + e2.printStackTrace(); + } + if (appClass != null) { + return appClass; + } } } + } throw new ClassNotFoundException(); diff --git a/src/com/vaadin/terminal/gwt/server/WebApplicationContext.java b/src/com/vaadin/terminal/gwt/server/WebApplicationContext.java index 304282fd9f..e49c95d905 100644 --- a/src/com/vaadin/terminal/gwt/server/WebApplicationContext.java +++ b/src/com/vaadin/terminal/gwt/server/WebApplicationContext.java @@ -36,7 +36,8 @@ import com.vaadin.service.ApplicationContext; public class WebApplicationContext implements ApplicationContext, HttpSessionBindingListener, Serializable { - protected List<TransactionListener> listeners; + protected List<TransactionListener> listeners = Collections + .synchronizedList(new LinkedList<TransactionListener>()); protected transient HttpSession session; @@ -87,7 +88,7 @@ public class WebApplicationContext implements ApplicationContext, } /** - * Gets the application context for HttpSession. + * Gets the application context for an HttpSession. * * @param session * the HTTP session. @@ -108,70 +109,68 @@ public class WebApplicationContext implements ApplicationContext, } /** - * Adds the transaction listener to this context. + * Adds a transaction listener to this context. The transaction listener is + * called before and after each each HTTP request related to this session + * except when serving static resources. + * * * @see com.vaadin.service.ApplicationContext#addTransactionListener(com.vaadin.service.ApplicationContext.TransactionListener) */ public void addTransactionListener(TransactionListener listener) { - if (listeners == null) { - listeners = new LinkedList<TransactionListener>(); - } listeners.add(listener); } /** - * Removes the transaction listener from this context. + * Removes a transaction listener from this context. The transaction + * listener is called before and after each each HTTP request related to + * this session except when serving static resources. * * @see com.vaadin.service.ApplicationContext#removeTransactionListener(com.vaadin.service.ApplicationContext.TransactionListener) */ public void removeTransactionListener(TransactionListener listener) { - if (listeners != null) { - listeners.remove(listener); - } + listeners.remove(listener); } /** - * Notifies the transaction start. + * Sends a notification that a transaction is starting. * * @param application + * The application associated with the transaction. * @param request - * the HTTP request. + * the HTTP request that triggered the transaction. */ protected void startTransaction(Application application, HttpServletRequest request) { - if (listeners == null) { - return; - } - for (final Iterator i = listeners.iterator(); i.hasNext();) { - ((ApplicationContext.TransactionListener) i.next()) - .transactionStart(application, request); + synchronized (listeners) { + for (TransactionListener listener : listeners) { + listener.transactionStart(application, request); + } } } /** - * Notifies the transaction end. + * Sends a notification that a transaction has ended. * * @param application + * The application associated with the transaction. * @param request - * the HTTP request. + * the HTTP request that triggered the transaction. */ protected void endTransaction(Application application, HttpServletRequest request) { - if (listeners == null) { - return; - } - LinkedList<Exception> exceptions = null; - for (final Iterator i = listeners.iterator(); i.hasNext();) { - try { - ((ApplicationContext.TransactionListener) i.next()) - .transactionEnd(application, request); - } catch (final RuntimeException t) { - if (exceptions == null) { - exceptions = new LinkedList<Exception>(); + + synchronized (listeners) { + for (TransactionListener listener : listeners) { + try { + listener.transactionEnd(application, request); + } catch (final RuntimeException t) { + if (exceptions == null) { + exceptions = new LinkedList<Exception>(); + } + exceptions.add(t); } - exceptions.add(t); } } diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java b/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java index 269d911ad1..29e92fb625 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java @@ -41,7 +41,7 @@ import com.vaadin.ui.ClientWidget; * appropriate monkey code for gwt directly in annotation processor and get rid * of {@link WidgetMapGenerator}. Using annotation processor might be a good * idea when dropping Java 1.5 support (integrated to javac in 6). - * + * */ public class ClassPathExplorer { private final static FileFilter DIRECTORIES_ONLY = new FileFilter() { @@ -75,7 +75,7 @@ public class ClassPathExplorer { /** * Finds available widgetset names. - * + * * @return */ public static Map<String, URL> getAvailableWidgetSets() { @@ -133,6 +133,10 @@ public class ClassPathExplorer { JarFile jarFile = conn.getJarFile(); Manifest manifest = jarFile.getManifest(); + if (manifest == null) { + // No manifest so this is not a Vaadin Add-on + return; + } String value = manifest.getMainAttributes().getValue( "Vaadin-Widgetsets"); if (value != null) { @@ -218,10 +222,13 @@ public class ClassPathExplorer { System.out.println(url); JarFile jarFile = conn.getJarFile(); Manifest manifest = jarFile.getManifest(); - Attributes mainAttributes = manifest.getMainAttributes(); - if (mainAttributes.getValue("Vaadin-Widgetsets") != null) { - System.err.println("Accepted jar file" + url); - return true; + if (manifest != null) { + Attributes mainAttributes = manifest + .getMainAttributes(); + if (mainAttributes.getValue("Vaadin-Widgetsets") != null) { + System.err.println("Accepted jar file" + url); + return true; + } } } catch (MalformedURLException e) { // TODO Auto-generated catch block @@ -238,7 +245,7 @@ public class ClassPathExplorer { /** * Recursively add subdirectories and jar files to classpathlocations - * + * * @param name * @param file * @param locations @@ -374,12 +381,12 @@ public class ClassPathExplorer { /** * Find and return the default source directory where to create new * widgetsets. - * + * * Return the first directory (not a JAR file etc.) on the classpath by * default. - * + * * TODO this could be done better... - * + * * @return URL */ public static URL getDefaultSourceDirectory() { diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java index d849c85fc7..2278488c1a 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java @@ -20,6 +20,11 @@ import java.util.regex.Pattern; /** * Helper class to update widgetsets GWT module configuration file. Can be used * command line or via IDE tools. + * + * <p> + * If module definition file contains text "WS Compiler: manually edited", tool + * will skip editing file. + * */ public class WidgetSetBuilder { @@ -60,38 +65,62 @@ public class WidgetSetBuilder { + "Google Web Toolkit 1.7.0//EN\" \"http://google" + "-web-toolkit.googlecode.com/svn/tags/1.7.0/dis" + "tro-source/core/src/gwt-module.dtd\">\n"); - printStream.print("<module>\n\n</module>\n"); + printStream.print("<module>\n"); + printStream + .print(" <!--\n" + + " Uncomment the following to compile the widgetset for one browser only.\n" + + " This can reduce the GWT compilation time significantly when debugging.\n" + + " The line should be commented out before deployment to production\n" + + " environments.\n\n" + + " Multiple browsers can be specified for GWT 1.7 as a comma separated\n" + + " list. The supported user agents at the moment of writing were:\n" + + " ie6,ie8,gecko,gecko1_8,safari,opera\n\n" + + " The value gecko is used for Firefox 3 and later, gecko1_8 is for\n" + + " Firefox 2 and safari is used for webkit based browsers including\n" + + " Google Chrome.\n" + + " -->\n" + + " <!-- <set-property name=\"user.agent\" value=\"gecko\"/> -->\n"); + printStream.print("\n</module>\n"); printStream.close(); changed = true; } String content = readFile(widgetsetFile); - String originalContent = content; - - Collection<String> oldInheritedWidgetsets = getCurrentWidgetSets(content); - - // add widgetsets that do not exist - for (String ws : availableWidgetSets.keySet()) { - if (ws.equals(widgetset)) { - // do not inherit the module itself - continue; + if (isEditable(content)) { + String originalContent = content; + + Collection<String> oldInheritedWidgetsets = getCurrentWidgetSets(content); + + // add widgetsets that do not exist + for (String ws : availableWidgetSets.keySet()) { + if (ws.equals(widgetset)) { + // do not inherit the module itself + continue; + } + if (!oldInheritedWidgetsets.contains(ws)) { + content = addWidgetSet(ws, content); + } } - if (!oldInheritedWidgetsets.contains(ws)) { - content = addWidgetSet(ws, content); + + for (String ws : oldInheritedWidgetsets) { + if (!availableWidgetSets.containsKey(ws)) { + // widgetset not available in classpath + content = removeWidgetSet(ws, content); + } } - } - for (String ws : oldInheritedWidgetsets) { - if (!availableWidgetSets.containsKey(ws)) { - // widgetset not available in classpath - content = removeWidgetSet(ws, content); + changed = changed || !content.equals(originalContent); + if (changed) { + commitChanges(widgetsetfilename, content); } + } else { + System.out + .println("Widgetset is manually edited. Skipping updates."); } + } - changed = changed || !content.equals(originalContent); - if (changed) { - commitChanges(widgetsetfilename, content); - } + private static boolean isEditable(String content) { + return !content.contains("WS Compiler: manually edited"); } private static String removeWidgetSet(String ws, String content) { @@ -135,6 +164,7 @@ public class WidgetSetBuilder { sb.append(line); sb.append("\n"); } + fi.close(); return sb.toString(); } diff --git a/src/com/vaadin/ui/Button.java b/src/com/vaadin/ui/Button.java index 6801bfa176..3ed50b2d42 100644 --- a/src/com/vaadin/ui/Button.java +++ b/src/com/vaadin/ui/Button.java @@ -36,7 +36,7 @@ public class Button extends AbstractField { * */ public Button() { - setValue(new Boolean(false)); + setValue(Boolean.FALSE); setSwitchMode(false); } @@ -96,7 +96,7 @@ public class Button extends AbstractField { */ public Button(String caption, boolean initialState) { setCaption(caption); - setValue(new Boolean(initialState)); + setValue(Boolean.valueOf(initialState)); setSwitchMode(true); } @@ -167,7 +167,7 @@ public class Button extends AbstractField { // If the button is true for some reason, release it if (oldValue.booleanValue()) { - setValue(new Boolean(false)); + setValue(Boolean.FALSE); } } } @@ -194,7 +194,7 @@ public class Button extends AbstractField { if (!switchMode) { setImmediate(true); if (booleanValue()) { - setValue(new Boolean(false)); + setValue(Boolean.FALSE); } } } diff --git a/src/com/vaadin/ui/DateField.java b/src/com/vaadin/ui/DateField.java index 69d6108152..425040a016 100644 --- a/src/com/vaadin/ui/DateField.java +++ b/src/com/vaadin/ui/DateField.java @@ -116,6 +116,8 @@ public class DateField extends AbstractField { */ private String dateString; + private boolean lenient = false; + /* Constructors */ /** @@ -202,6 +204,10 @@ public class DateField extends AbstractField { target.addAttribute("format", dateFormat); } + if (!isLenient()) { + target.addAttribute("strict", true); + } + target.addAttribute("type", type); // Gets the calendar @@ -332,13 +338,13 @@ public class DateField extends AbstractField { newDate = cal.getTime(); } - if (newDate != oldDate + if (newDate == null && dateString != null && !"".equals(dateString) + && !dateString.equals(oldDateString)) { + setValue(handleUnparsableDateString(dateString)); + } else if (newDate != oldDate && (newDate == null || !newDate.equals(oldDate))) { setValue(newDate, true); // Don't require a repaint, client // updates itself - } else if (dateString != null && !"".equals(dateString) - && !dateString.equals(oldDateString)) { - setValue(handleUnparsableDateString(dateString)); } } } @@ -511,4 +517,32 @@ public class DateField extends AbstractField { return dateFormat; } + /** + * Specifies whether or not date/time interpretation in component is to be + * lenient. + * + * @see Calendar#setLenient(boolean) + * @see #isLenient() + * + * @param lenient + * true if the lenient mode is to be turned on; false if it is to + * be turned off. + */ + public void setLenient(boolean lenient) { + this.lenient = lenient; + requestRepaint(); + } + + /** + * Specifies whether or not date/time interpretation is to be lenient. + * + * @see #setLenient(boolean) + * + * @return true if the interpretation mode of this calendar is lenient; + * false otherwise. + */ + public boolean isLenient() { + return lenient; + } + } diff --git a/src/com/vaadin/ui/LoginForm.java b/src/com/vaadin/ui/LoginForm.java index 33ee670f4b..76c567dc5e 100644 --- a/src/com/vaadin/ui/LoginForm.java +++ b/src/com/vaadin/ui/LoginForm.java @@ -161,12 +161,14 @@ public class LoginForm extends CustomComponent { + "document.getElementsByTagName('head')[0].appendChild(stylesheet);\n" + "}" + "}\n" + + "function submitOnEnter(e) { var keycode = e.keyCode || e.which;" + + " if (keycode == 13) {document.forms[0].submit();} } \n" + "</script>" + "</head><body onload='setTarget();' style='margin:0;padding:0; background:transparent;' class=\"v-generated-body\">" + "<div class='v-app v-app-loginpage' style=\"background:transparent;\">" + "<iframe name='logintarget' style='width:0;height:0;" + "border:0;margin:0;padding:0;'></iframe>" - + "<form id='loginf' target='logintarget'>" + + "<form id='loginf' target='logintarget' onkeypress=\"submitOnEnter(event)\">" + "<div>Username</div><div >" + "<input class='v-textfield' style='display:block;' type='text' name='username'></div>" + "<div>Password</div>" diff --git a/src/com/vaadin/ui/MenuBar.java b/src/com/vaadin/ui/MenuBar.java index 30049431d3..5715e230c4 100644 --- a/src/com/vaadin/ui/MenuBar.java +++ b/src/com/vaadin/ui/MenuBar.java @@ -29,8 +29,20 @@ public class MenuBar extends AbstractComponent { // Number of items in this menu private static int numberOfItems = 0; + /** + * @deprecated + * @see #setCollapse(boolean) + */ + @Deprecated private boolean collapseItems; + + /** + * @deprecated + * @see #setSubmenuIcon(Resource) + */ + @Deprecated private Resource submenuIcon; + private MenuItem moreItem; /** Paint (serialise) the component for the client. */ @@ -49,9 +61,7 @@ public class MenuBar extends AbstractComponent { target.addAttribute("submenuIcon", submenuIcon); } - target.addAttribute("collapseItems", collapseItems); - - if (collapseItems) { + if (getWidth() > -1) { target.startTag("moreItem"); target.addAttribute("text", moreItem.getText()); if (moreItem.getIcon() != null) { @@ -69,31 +79,43 @@ public class MenuBar extends AbstractComponent { while (itr.hasNext()) { MenuItem item = itr.next(); + if (!item.isVisible()) { + continue; + } target.startTag("item"); - - target.addAttribute("text", item.getText()); target.addAttribute("id", item.getId()); - Command command = item.getCommand(); - if (command != null) { - target.addAttribute("command", true); + if (item.isSeparator()) { + target.addAttribute("separator", true); + target.endTag("item"); } else { - target.addAttribute("command", false); - } + target.addAttribute("text", item.getText()); - Resource icon = item.getIcon(); - if (icon != null) { - target.addAttribute("icon", icon); - } + Command command = item.getCommand(); + if (command != null) { + target.addAttribute("command", true); + } + + Resource icon = item.getIcon(); + if (icon != null) { + target.addAttribute("icon", icon); + } + + if (!item.isEnabled()) { + target.addAttribute("disabled", true); + } - if (item.hasChildren()) { - iteratorStack.push(itr); // For later use + if (item.hasChildren()) { + iteratorStack.push(itr); // For later use + + // Go through the children + itr = item.getChildren().iterator(); + } else { + target.endTag("item"); // Item had no children, end + // description + } - // Go through the children - itr = item.getChildren().iterator(); - } else { - target.endTag("item"); // Item had no children, end description } // The end submenu. More than one submenu may end at once. @@ -101,7 +123,6 @@ public class MenuBar extends AbstractComponent { itr = iteratorStack.pop(); target.endTag("item"); } - } target.endTag("items"); @@ -138,7 +159,7 @@ public class MenuBar extends AbstractComponent { }// while // If we got the clicked item, launch the command. - if (found) { + if (found && tmpItem.isEnabled()) { tmpItem.getCommand().menuSelected(tmpItem); } }// if @@ -270,40 +291,46 @@ public class MenuBar extends AbstractComponent { * Set the icon to be used if a sub-menu has children. Defaults to null; * * @param icon + * @deprecated (since 6.2, will be removed in 7.0) Icon is set in theme, no + * need to worry about the visual representation here. */ + @Deprecated public void setSubmenuIcon(Resource icon) { submenuIcon = icon; requestRepaint(); } /** - * Get the icon used for sub-menus. Returns null if no icon is set. - * - * @return + * @deprecated + * @see #setSubmenuIcon(Resource) */ + @Deprecated public Resource getSubmenuIcon() { return submenuIcon; } /** * Enable or disable collapsing top-level items. Top-level items will - * collapse to if there is not enough room for them. Items that don't fit - * will be placed under the "More" menu item. + * collapse together if there is not enough room for them. Items that don't + * fit will be placed under the "More" menu item. * * Collapsing is enabled by default. * * @param collapse + * @deprecated (since 6.2, will be removed in 7.0) Collapsing is always + * enabled if the MenuBar has a specified width. */ + @Deprecated public void setCollapse(boolean collapse) { collapseItems = collapse; requestRepaint(); } /** - * Collapsing is enabled by default. - * - * @return true if the top-level items will be collapsed + * @see #setCollapse(boolean) + * @deprecated */ + @Deprecated public boolean getCollapse() { return collapseItems; } @@ -311,8 +338,9 @@ public class MenuBar extends AbstractComponent { /** * Set the item that is used when collapsing the top level menu. All * "overflowing" items will be added below this. The item command will be - * ignored. If set to null, the default item with the "More" text is be - * used. + * ignored. If set to null, the default item with a downwards arrow is used. + * + * The item command (if specified) is ignored. * * @param item */ @@ -320,7 +348,7 @@ public class MenuBar extends AbstractComponent { if (item != null) { moreItem = item; } else { - moreItem = new MenuItem("More", null, null); + moreItem = new MenuItem("", null, null); } requestRepaint(); } @@ -360,6 +388,9 @@ public class MenuBar extends AbstractComponent { private List<MenuItem> itsChildren; private Resource itsIcon; private MenuItem itsParent; + private boolean enabled = true; + private boolean visible = true; + private boolean isSeparator = false; /** * Constructs a new menu item that can optionally have an icon and a @@ -388,7 +419,27 @@ public class MenuBar extends AbstractComponent { * @return True if this item has children */ public boolean hasChildren() { - return itsChildren != null; + return !isSeparator() && itsChildren != null; + } + + /** + * Adds a separator to this menu. A separator is a way to visually group + * items in a menu, to make it easier for users to find what they are + * looking for in the menu. + * + * @author Jouni Koivuviita / IT Mill Ltd. + * @since 6.2.0 + */ + public MenuBar.MenuItem addSeparator() { + MenuItem item = addItem("", null, null); + item.setSeparator(true); + return item; + } + + public MenuBar.MenuItem addSeparatorBefore(MenuItem itemToAddBefore) { + MenuItem item = addItemBefore("", null, null, itemToAddBefore); + item.setSeparator(true); + return item; } /** @@ -417,8 +468,12 @@ public class MenuBar extends AbstractComponent { */ public MenuBar.MenuItem addItem(String caption, Resource icon, MenuBar.Command command) { + if (isSeparator()) { + throw new UnsupportedOperationException( + "Cannot add items to a separator"); + } if (caption == null) { - throw new IllegalArgumentException("caption cannot be null"); + throw new IllegalArgumentException("Caption cannot be null"); } if (itsChildren == null) { @@ -461,7 +516,6 @@ public class MenuBar extends AbstractComponent { newItem = new MenuItem(caption, icon, command); newItem.setParent(this); itsChildren.add(index, newItem); - } else { newItem = addItem(caption, icon, command); } @@ -524,7 +578,10 @@ public class MenuBar extends AbstractComponent { * @return The number of child items */ public int getSize() { - return itsChildren.size(); + if (itsChildren != null) { + return itsChildren.size(); + } + return -1; } /** @@ -582,8 +639,8 @@ public class MenuBar extends AbstractComponent { if (itsChildren.isEmpty()) { itsChildren = null; } + requestRepaint(); } - requestRepaint(); } /** @@ -593,8 +650,8 @@ public class MenuBar extends AbstractComponent { if (itsChildren != null) { itsChildren.clear(); itsChildren = null; + requestRepaint(); } - requestRepaint(); } /** @@ -607,6 +664,33 @@ public class MenuBar extends AbstractComponent { itsParent = parent; } + public void setEnabled(boolean enabled) { + this.enabled = enabled; + requestRepaint(); + } + + public boolean isEnabled() { + return enabled; + } + + public void setVisible(boolean visible) { + this.visible = visible; + requestRepaint(); + } + + public boolean isVisible() { + return visible; + } + + private void setSeparator(boolean isSeparator) { + this.isSeparator = isSeparator; + requestRepaint(); + } + + public boolean isSeparator() { + return isSeparator; + } + }// class MenuItem }// class MenuBar diff --git a/src/com/vaadin/ui/TabSheet.java b/src/com/vaadin/ui/TabSheet.java index ed81fdb655..b58e7be7bf 100644 --- a/src/com/vaadin/ui/TabSheet.java +++ b/src/com/vaadin/ui/TabSheet.java @@ -35,7 +35,7 @@ public class TabSheet extends AbstractComponentContainer implements /** * Linked list of component tabs. */ - private final LinkedList components = new LinkedList(); + private final LinkedList<Component> components = new LinkedList<Component>(); /** * Map containing information related to the tabs (caption, icon etc). @@ -54,7 +54,9 @@ public class TabSheet extends AbstractComponentContainer implements */ private boolean tabsHidden; - private LinkedList paintedTabs = new LinkedList(); + private LinkedList<Component> paintedTabs = new LinkedList<Component>(); + + private CloseHandler closeHandler; /** * Constructs a new Tabsheet. Tabsheet is immediate by default. @@ -64,6 +66,11 @@ public class TabSheet extends AbstractComponentContainer implements // expand horizontally by default setWidth(100, UNITS_PERCENTAGE); setImmediate(true); + setCloseHandler(new CloseHandler() { + public void onTabClose(TabSheet tabsheet, Component c) { + tabsheet.removeComponent(c); + } + }); } /** @@ -72,7 +79,7 @@ public class TabSheet extends AbstractComponentContainer implements * * @return the Iterator of the components inside the container. */ - public Iterator getComponentIterator() { + public Iterator<Component> getComponentIterator() { return java.util.Collections.unmodifiableList(components).iterator(); } @@ -93,7 +100,7 @@ public class TabSheet extends AbstractComponentContainer implements if (components.isEmpty()) { selected = null; } else { - selected = (Component) components.getFirst(); + selected = components.getFirst(); fireSelectedTabChange(); } } @@ -168,8 +175,9 @@ public class TabSheet extends AbstractComponentContainer implements */ @Override public void moveComponentsFrom(ComponentContainer source) { - for (final Iterator i = source.getComponentIterator(); i.hasNext();) { - final Component c = (Component) i.next(); + for (final Iterator<Component> i = source.getComponentIterator(); i + .hasNext();) { + final Component c = i.next(); String caption = null; Resource icon = null; if (TabSheet.class.isAssignableFrom(source.getClass())) { @@ -199,8 +207,8 @@ public class TabSheet extends AbstractComponentContainer implements target.startTag("tabs"); - for (final Iterator i = getComponentIterator(); i.hasNext();) { - final Component component = (Component) i.next(); + for (final Iterator<Component> i = getComponentIterator(); i.hasNext();) { + final Component component = i.next(); Tab tab = tabs.get(component); /* @@ -236,6 +244,10 @@ public class TabSheet extends AbstractComponentContainer implements target.addAttribute("hidden", true); } + if (tab.isClosable()) { + target.addAttribute("closable", true); + } + final Resource icon = tab.getIcon(); if (icon != null) { target.addAttribute("icon", icon); @@ -417,6 +429,13 @@ public class TabSheet extends AbstractComponentContainer implements setSelectedTab((Component) keyMapper.get((String) variables .get("selected"))); } + if (variables.containsKey("close")) { + final Component tab = (Component) keyMapper.get((String) variables + .get("close")); + if (tab != null) { + closeHandler.onTabClose(this, tab); + } + } } /* Documented in superclass */ @@ -453,8 +472,8 @@ public class TabSheet extends AbstractComponentContainer implements int oldLocation = -1; int newLocation = -1; int location = 0; - for (final Iterator i = components.iterator(); i.hasNext();) { - final Component component = (Component) i.next(); + for (final Iterator<Component> i = components.iterator(); i.hasNext();) { + final Component component = i.next(); if (component == oldComponent) { oldLocation = location; @@ -636,6 +655,23 @@ public class TabSheet extends AbstractComponentContainer implements public void setVisible(boolean visible); /** + * Returns the closability status for the tab. + * + * @return true if the tab is allowed to be closed by the end user, + * false for not allowing closing + */ + public boolean isClosable(); + + /** + * Sets the closability status for the tab. + * + * @param visible + * true if the end user is allowed to close the tab, false + * for not allowing to close. Should default to false. + */ + public void setClosable(boolean closable); + + /** * Returns the enabled status for the tab. * * @return true for enabled, false for disabled @@ -710,6 +746,7 @@ public class TabSheet extends AbstractComponentContainer implements private Resource icon = null; private boolean enabled = true; private boolean visible = true; + private boolean closable = false; private String description = null; private ErrorMessage componentError = null; @@ -760,6 +797,19 @@ public class TabSheet extends AbstractComponentContainer implements requestRepaint(); } + public boolean isClosable() { + return closable; + } + + public void setClosable(boolean closable) { + this.closable = closable; + requestRepaint(); + } + + public void close() { + + } + public String getDescription() { return description; } @@ -777,6 +827,44 @@ public class TabSheet extends AbstractComponentContainer implements this.componentError = componentError; requestRepaint(); } + } + + /** + * CloseHandler is used to process tab closing events. Default behavior is + * to remove the tab from the TabSheet. + * + * @author Jouni Koivuviita / IT Mill Ltd. + * @since 6.2.0 + * + */ + public interface CloseHandler { + /** + * Called when a user has pressed the close icon of a tab in the client + * side widget. + * + * @param tabsheet + * the TabSheet to which the tab belongs to + * @param tabContent + * the component that corresponds to the tab whose close + * button was clicked + */ + void onTabClose(final TabSheet tabsheet, final Component tabContent); + } + + /** + * Provide a custom {@link CloseHandler} for this TabSheet if you wish to + * perform some additional tasks when a user clicks on a tabs close button, + * e.g. show a confirmation dialogue before removing the tab. + * + * To remove the tab, if you provide your own close handler, you must call + * {@link #removeComponent(Component)} yourself. + * + * The default CloseHandler for TabSheet will only remove the tab. + * + * @param handler + */ + public void setCloseHandler(CloseHandler handler) { + closeHandler = handler; } } diff --git a/src/com/vaadin/ui/Upload.java b/src/com/vaadin/ui/Upload.java index dfbbbfc103..e3512a4795 100644 --- a/src/com/vaadin/ui/Upload.java +++ b/src/com/vaadin/ui/Upload.java @@ -244,8 +244,6 @@ public class Upload extends AbstractComponent implements Component.Focusable { target.addAttribute("buttoncaption", buttonCaption); - target.addVariable(this, "fake", true); - target.addUploadStreamVariable(this, "stream"); } diff --git a/src/com/vaadin/ui/Window.java b/src/com/vaadin/ui/Window.java index dc1bf7e18f..d234f7aaac 100644 --- a/src/com/vaadin/ui/Window.java +++ b/src/com/vaadin/ui/Window.java @@ -8,6 +8,7 @@ import java.io.Serializable; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashSet; @@ -119,6 +120,8 @@ public class Window extends Panel implements URIHandler, ParameterHandler { private Focusable pendingFocus; + private ArrayList<String> jsExecQueue = null; + /* ********************************************************************* */ /** @@ -381,7 +384,7 @@ public class Window extends Panel implements URIHandler, ParameterHandler { if (getParent() != null) { // this is subwindow Window mainWindow = (Window) getParent(); - mainWindow.addParameterHandler(handler); + mainWindow.removeParameterHandler(handler); } else { if (handler == null || parameterHandlerList == null) { return; @@ -520,6 +523,16 @@ public class Window extends Panel implements URIHandler, ParameterHandler { // Contents of the window panel is painted super.paintContent(target); + // Add executable javascripts if needed + if (jsExecQueue != null) { + for (String script : jsExecQueue) { + target.startTag("execJS"); + target.addAttribute("script", script); + target.endTag("execJS"); + } + jsExecQueue = null; + } + // Window position target.addVariable(this, "positionx", getPositionX()); target.addVariable(this, "positiony", getPositionY()); @@ -1632,4 +1645,39 @@ public class Window extends Panel implements URIHandler, ParameterHandler { } } + /** + * Executes JavaScript in this window. + * + * <p> + * This method allows one to inject javascript from the server to client. A + * client implementation is not required to implement this functionality, + * but currently all web-based clients do implement this. + * </p> + * + * <p> + * Executing javascript this way often leads to cross-browser compatibility + * issues and regressions that are hard to resolve. Use of this method + * should be avoided and instead it is recommended to create new widgets + * with GWT. For more info on creating own, reusable client-side widgets in + * Java, read the corresponding chapter in Book of Vaadin. + * </p> + * + * @param script + * JavaScript snippet that will be executed. + */ + public void executeJavaScript(String script) { + + if (getParent() != null) { + throw new UnsupportedOperationException( + "Only application level windows can execute javascript."); + } + + if (jsExecQueue == null) { + jsExecQueue = new ArrayList<String>(); + } + + jsExecQueue.add(script); + + requestRepaint(); + } } diff --git a/tests/scripts/sampler-all-samples.html b/tests/scripts/sampler-all-samples.html index 9eb9d17aef..00e794c77b 100644 --- a/tests/scripts/sampler-all-samples.html +++ b/tests/scripts/sampler-all-samples.html @@ -50,7 +50,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>1</td> + <td>Components-Common-Tooltips</td> </tr> <tr> <td>mouseClick</td> @@ -65,7 +65,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>2</td> + <td>Components-Common-Icons</td> </tr> <tr> <td>mouseClick</td> @@ -80,7 +80,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>3</td> + <td>Components-Common-Errors</td> </tr> <tr> <td>mouseClick</td> @@ -95,7 +95,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>4</td> + <td>Components-Common-Validation</td> </tr> <tr> <td>mouseClick</td> @@ -110,7 +110,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>5</td> + <td>Components-Accordions-AccordionIcons</td> </tr> <tr> <td>mouseClick</td> @@ -125,7 +125,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>6</td> + <td>Components-Accordions-AccordionDisabled</td> </tr> <tr> <td>mouseClick</td> @@ -140,7 +140,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>7</td> + <td>Components-Buttons-ButtonPush</td> </tr> <tr> <td>mouseClick</td> @@ -155,7 +155,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>8</td> + <td>Components-Buttons-ButtonLink</td> </tr> <tr> <td>mouseClick</td> @@ -170,7 +170,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>9</td> + <td>Components-Dates-DatePopup</td> </tr> <tr> <td>mouseClick</td> @@ -225,7 +225,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>14</td> + <td>Components-Forms-FormBasic</td> </tr> <tr> <td>mouseClick</td> @@ -240,7 +240,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>15</td> + <td>Components-Layouts-LayoutMargin</td> </tr> <tr> <td>mouseClick</td> @@ -255,7 +255,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>16</td> + <td>Components-Layouts-LayoutSpacing</td> </tr> <tr> <td>mouseClick</td> @@ -270,7 +270,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>17</td> + <td>Components-Layouts-VerticalLayoutBasic</td> </tr> <tr> <td>mouseClick</td> @@ -285,7 +285,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>18</td> + <td>Components-Layouts-HorizontalLayoutBasic</td> </tr> <tr> <td>mouseClick</td> @@ -300,7 +300,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>19</td> + <td>Components-Layouts-GridLayoutBasic</td> </tr> <tr> <td>mouseClick</td> @@ -315,7 +315,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>20</td> + <td>Components-Layouts-LayoutAlignment</td> </tr> <tr> <td>mouseClick</td> @@ -330,7 +330,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>21</td> + <td>Components-Layouts-ExpandingComponent</td> </tr> <tr> <td>mouseClick</td> @@ -345,7 +345,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>22</td> + <td>Components-Layouts-SplitPanelBasic</td> </tr> <tr> <td>mouseClick</td> @@ -360,7 +360,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>23</td> + <td>Components-Layouts-ApplicationLayout</td> </tr> <tr> <td>mouseClick</td> @@ -375,7 +375,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>24</td> + <td>Components-Layouts-WebLayout</td> </tr> <tr> <td>mouseClick</td> @@ -390,7 +390,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>25</td> + <td>Components-Layouts-CustomLayouts</td> </tr> <tr> <td>mouseClick</td> @@ -405,7 +405,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>26</td> + <td>Components-Layouts-CssLayouts</td> </tr> <tr> <td>mouseClick</td> @@ -420,7 +420,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>27</td> + <td>Components-Links-LinkCurrentWindow</td> </tr> <tr> <td>mouseClick</td> @@ -435,7 +435,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>28</td> + <td>Components-Links-LinkNoDecorations</td> </tr> <tr> <td>mouseClick</td> @@ -450,7 +450,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>29</td> + <td>Components-Links-LinkSizedWindow</td> </tr> <tr> <td>mouseClick</td> @@ -465,7 +465,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>30</td> + <td>Components-Notifications-NotificationHumanized</td> </tr> <tr> <td>mouseClick</td> @@ -480,7 +480,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>31</td> + <td>Components-Notifications-NotificationWarning</td> </tr> <tr> <td>mouseClick</td> @@ -495,7 +495,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>32</td> + <td>Components-Notifications-NotificationTray</td> </tr> <tr> <td>mouseClick</td> @@ -510,7 +510,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>33</td> + <td>Components-Notifications-NotificationError</td> </tr> <tr> <td>mouseClick</td> @@ -525,7 +525,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>34</td> + <td>Components-Notifications-NotificationCustom</td> </tr> <tr> <td>mouseClick</td> @@ -540,7 +540,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>35</td> + <td>Components-Panels-PanelBasic</td> </tr> <tr> <td>mouseClick</td> @@ -555,7 +555,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>36</td> + <td>Components-Panels-PanelLight</td> </tr> <tr> <td>mouseClick</td> @@ -570,7 +570,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>37</td> + <td>Components-Selects-ListSelectSingle</td> </tr> <tr> <td>mouseClick</td> @@ -585,7 +585,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>38</td> + <td>Components-Selects-ListSelectMultiple</td> </tr> <tr> <td>mouseClick</td> @@ -600,7 +600,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>39</td> + <td>Components-Selects-TwinColumnSelect</td> </tr> <tr> <td>mouseClick</td> @@ -615,7 +615,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>40</td> + <td>Components-Selects-NativeSelection</td> </tr> <tr> <td>mouseClick</td> @@ -630,7 +630,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>41</td> + <td>Components-Selects-ComboBoxPlain</td> </tr> <tr> <td>mouseClick</td> @@ -645,7 +645,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>42</td> + <td>Components-Selects-ComboBoxInputPrompt</td> </tr> <tr> <td>mouseClick</td> @@ -660,7 +660,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>43</td> + <td>Components-Selects-ComboBoxStartsWith</td> </tr> <tr> <td>mouseClick</td> @@ -675,7 +675,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>44</td> + <td>Components-Selects-ComboBoxContains</td> </tr> <tr> <td>mouseClick</td> @@ -690,7 +690,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>45</td> + <td>Components-Selects-ComboBoxNewItems</td> </tr> <tr> <td>mouseClick</td> @@ -705,7 +705,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>46</td> + <td>Components-Table-Grid-TableHeaderIcons</td> </tr> <tr> <td>mouseClick</td> @@ -720,7 +720,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>47</td> + <td>Components-Table-Grid-TableColumnHeaders</td> </tr> <tr> <td>mouseClick</td> @@ -735,7 +735,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>48</td> + <td>Components-Table-Grid-TableColumnReordering</td> </tr> <tr> <td>mouseClick</td> @@ -750,7 +750,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>49</td> + <td>Components-Table-Grid-TableColumnCollapsing</td> </tr> <tr> <td>mouseClick</td> @@ -765,7 +765,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>50</td> + <td>Components-Table-Grid-TableColumnAlignment</td> </tr> <tr> <td>mouseClick</td> @@ -790,7 +790,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>52</td> + <td>Components-Table-Grid-TableSorting</td> </tr> <tr> <td>mouseClick</td> @@ -805,7 +805,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>53</td> + <td>Components-Table-Grid-TableRowHeaders</td> </tr> <tr> <td>mouseClick</td> @@ -820,7 +820,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>54</td> + <td>Components-Table-Grid-TableRowStyling</td> </tr> <tr> <td>mouseClick</td> @@ -835,7 +835,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>55</td> + <td>Components-Table-Grid-TableActions</td> </tr> <tr> <td>mouseClick</td> @@ -850,7 +850,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>56</td> + <td>Components-Table-Grid-TableMouseEvents</td> </tr> <tr> <td>mouseClick</td> @@ -865,7 +865,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>57</td> + <td>Components-Table-Grid-TableLazyLoading</td> </tr> <tr> <td>mouseClick</td> @@ -880,7 +880,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>58</td> + <td>Components-Tabsheets-TabSheetIcons</td> </tr> <tr> <td>mouseClick</td> @@ -895,7 +895,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>59</td> + <td>Components-Tabsheets-TabSheetScrolling</td> </tr> <tr> <td>mouseClick</td> @@ -910,7 +910,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>60</td> + <td>Components-Tabsheets-TabSheetDisabled</td> </tr> <tr> <td>mouseClick</td> @@ -925,7 +925,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>61</td> + <td>Components-Tabsheets-TabSheetClosing</td> </tr> <tr> <td>mouseClick</td> @@ -940,7 +940,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>62</td> + <td>Components-Texts-LabelPlain</td> </tr> <tr> <td>mouseClick</td> @@ -955,7 +955,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>63</td> + <td>Components-Texts-LabelPreformatted</td> </tr> <tr> <td>mouseClick</td> @@ -970,7 +970,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>64</td> + <td>Components-Texts-LabelRich</td> </tr> <tr> <td>mouseClick</td> @@ -985,7 +985,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>65</td> + <td>Components-TextFields-TextFieldSingle</td> </tr> <tr> <td>mouseClick</td> @@ -1000,7 +1000,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>66</td> + <td>Components-TextFields-TextFieldSecret</td> </tr> <tr> <td>mouseClick</td> @@ -1015,7 +1015,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>67</td> + <td>Components-TextFields-TextFieldInputPrompt</td> </tr> <tr> <td>mouseClick</td> @@ -1030,7 +1030,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>68</td> + <td>Components-TextFields-TextArea</td> </tr> <tr> <td>mouseClick</td> @@ -1045,7 +1045,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>69</td> + <td>Components-TextFields-RichTextEditor</td> </tr> <tr> <td>mouseClick</td> @@ -1060,7 +1060,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>70</td> + <td>Components-Trees-TreeSingleSelect</td> </tr> <tr> <td>mouseClick</td> @@ -1075,7 +1075,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>71</td> + <td>Components-Trees-TreeMultiSelect</td> </tr> <tr> <td>mouseClick</td> @@ -1090,7 +1090,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>72</td> + <td>Components-Trees-TreeActions</td> </tr> <tr> <td>mouseClick</td> @@ -1105,7 +1105,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>73</td> + <td>Components-Trees-TreeMouseEvents</td> </tr> <tr> <td>mouseClick</td> @@ -1120,7 +1120,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>74</td> + <td>Components-Windows-Subwindow</td> </tr> <tr> <td>mouseClick</td> @@ -1135,7 +1135,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>75</td> + <td>Components-Windows-SubwindowModal</td> </tr> <tr> <td>mouseClick</td> @@ -1150,7 +1150,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>76</td> + <td>Components-Windows-SubwindowAutoSized</td> </tr> <tr> <td>mouseClick</td> @@ -1165,7 +1165,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>77</td> + <td>Components-Windows-SubwindowSized</td> </tr> <tr> <td>mouseClick</td> @@ -1180,7 +1180,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>78</td> + <td>Components-Windows-SubwindowPositioned</td> </tr> <tr> <td>mouseClick</td> @@ -1195,7 +1195,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>79</td> + <td>Components-Windows-SubwindowClose</td> </tr> <tr> <td>mouseClick</td> @@ -1210,7 +1210,7 @@ <tr> <td>screenCapture</td> <td></td> - <td>80</td> + <td>Components-Windows-NativeWindow</td> </tr> <tr> <td>mouseClick</td> @@ -1225,7 +1225,22 @@ <tr> <td>screenCapture</td> <td></td> - <td>81</td> + <td>Components-Uploads-UploadBasic</td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=sampler::/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[7]/VHorizontalLayout[0]/ChildComponentContainer[1]/VNativeButton[0]</td> + <td>11,13</td> +</tr> +<tr> + <td>waitForVaadin</td> + <td></td> + <td></td> +</tr> +<tr> + <td>screenCapture</td> + <td></td> + <td>Components-Uploads-UploadWithProgressMonitoring</td> </tr> </tbody></table> diff --git a/tests/test.xml b/tests/test.xml index 20d7649e96..c841f8e03b 100644 --- a/tests/test.xml +++ b/tests/test.xml @@ -4,14 +4,19 @@ <!-- ================================================================== --> <!-- Configuration --> <!-- ================================================================== --> - <!-- Temporary output directory, created and removed by this script --> - <property name="test-output-dir" value="../build/test-output" /> - <property name="class-dir" value="${test-output-dir}/classes" /> + <!-- Browsers to use for testing --> + <property name="browsers" value="winxp-ie6,winxp-ie7,winxp-ie8,winxp-firefox35,winxp-safari4,winxp-googlechrome3,winxp-opera10" /> + + <!-- Screen shot base directory --> <property name="com.vaadin.testbench.screenshot.directory" value="../tests/screenshots" /> + + <!-- Host running Testbench Hub --> <property name="com.vaadin.testbench.tester.host" value="192.168.1.44" /> - <!-- Browsers to use for testing --> - <property name="test-browsers" value="winxp-ie6,winxp-ie7,winxp-ie8,winxp-firefox35,winxp-safari4,winxp-googlechrome3,winxp-opera10" /> + <!-- Temporary output directory, created and removed by this script --> + <property name="test-output-dir" value="../build/test-output" /> + + <property name="class-dir" value="${test-output-dir}/classes" /> <taskdef resource="net/sf/antcontrib/antcontrib.properties"> <classpath> <pathelement location="../build/lib/ant-contrib-1.0b3.jar"/> @@ -38,7 +43,7 @@ <java classname="com.vaadin.testbench.util.TestConverter" classpathref="classpath"> <arg value="${test-output-dir}" /> - <arg value="${test-browsers}" /> + <arg value="${browsers}" /> <arg line="${testfiles}" /> </java> </target> @@ -99,8 +104,8 @@ <fail unless="com.vaadin.testbench.deployment.url" message="The 'com.vaadin.testbench.deployment.url' property must be defined." /> </target> - <target name="run-tests" depends="remove-error-screens,compile-tests"> - <foreach parallel="true" target="execute-tests" param="target"> + <target name="run-tests" depends="remove-error-screens, compile-tests"> + <foreach maxthreads="10" parallel="true" target="execute-tests" param="target"> <path> <fileset dir="${test-output-dir}" includes="**/**.java" /> </path> |