]> source.dussan.org Git - vaadin-framework.git/commitdiff
Merge changes from master to rpc branch.
authorHenri Sara <hesara@vaadin.com>
Fri, 27 Jan 2012 16:38:13 +0000 (18:38 +0200)
committerHenri Sara <hesara@vaadin.com>
Fri, 27 Jan 2012 16:38:13 +0000 (18:38 +0200)
89 files changed:
WebContent/VAADIN/themes/base/datefield/datefield.css
WebContent/VAADIN/themes/base/table/table.css
WebContent/VAADIN/themes/base/tabsheet/tabsheet.css
WebContent/VAADIN/themes/base/textfield/textfield-normal.css
WebContent/VAADIN/themes/base/window/window.css
WebContent/VAADIN/themes/chameleon/components/tabsheet/tabsheet.css
WebContent/VAADIN/themes/reindeer-tests/styles.css
WebContent/VAADIN/themes/reindeer/tabsheet/tabsheet-scroller.css
build/build.properties
build/build.xml
build/ivy/ivy.xml
src/com/vaadin/data/validator/CompositeValidator.java
src/com/vaadin/launcher/util/BrowserLauncher.java [deleted file]
src/com/vaadin/terminal/Sizeable.java
src/com/vaadin/terminal/UserError.java
src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
src/com/vaadin/terminal/gwt/client/Container.java
src/com/vaadin/terminal/gwt/client/Util.java
src/com/vaadin/terminal/gwt/client/VDebugConsole.java
src/com/vaadin/terminal/gwt/client/VPaintable.java
src/com/vaadin/terminal/gwt/client/VPaintableMap.java
src/com/vaadin/terminal/gwt/client/VPaintableWidget.java
src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java
src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
src/com/vaadin/terminal/gwt/client/ui/VButton.java
src/com/vaadin/terminal/gwt/client/ui/VButtonPaintable.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/VCalendarPanel.java
src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
src/com/vaadin/terminal/gwt/client/ui/VFormLayout.java
src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java
src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java
src/com/vaadin/terminal/gwt/client/ui/VNativeButtonPaintable.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java
src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/VSlider.java
src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java
src/com/vaadin/terminal/gwt/client/ui/VTextArea.java
src/com/vaadin/terminal/gwt/client/ui/VTextField.java
src/com/vaadin/terminal/gwt/client/ui/VTextualDate.java
src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java
src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/ui/VUpload.java
src/com/vaadin/terminal/gwt/client/ui/VView.java
src/com/vaadin/terminal/gwt/client/ui/VWindow.java
src/com/vaadin/terminal/gwt/client/ui/label/VLabel.java
src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java
src/com/vaadin/ui/AbstractComponent.java
src/com/vaadin/ui/AbstractSelect.java
src/com/vaadin/ui/Button.java
src/com/vaadin/ui/Component.java
src/com/vaadin/ui/CssLayout.java
src/com/vaadin/ui/MenuBar.java
src/com/vaadin/ui/NativeButton.java
src/com/vaadin/ui/Table.java
src/com/vaadin/ui/TreeTable.java
tests/integration_base_files/lock_age.sh
tests/integration_tests.xml
tests/server-side/com/vaadin/tests/VaadinClasses.java [new file with mode: 0644]
tests/server-side/com/vaadin/tests/server/component/datefield/ResolutionTest.java [new file with mode: 0644]
tests/server-side/com/vaadin/tests/server/component/table/TableColumnAlignments.java
tests/server-side/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTest.java [new file with mode: 0644]
tests/server-side/com/vaadin/tests/server/componentcontainer/CssLayoutTest.java [new file with mode: 0644]
tests/server-side/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java [new file with mode: 0644]
tests/server-side/com/vaadin/tests/server/componentcontainer/VerticalLayoutTest.java [new file with mode: 0644]
tests/test.xml
tests/testbench/com/vaadin/launcher/util/BrowserLauncher.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/Components.java
tests/testbench/com/vaadin/tests/VaadinClasses.java [deleted file]
tests/testbench/com/vaadin/tests/components/combobox/ComboBoxIdenticalItems.html
tests/testbench/com/vaadin/tests/components/datefield/DatePopupStyleName.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/datefield/DatePopupStyleName.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/datefield/ResolutionTest.java [deleted file]
tests/testbench/com/vaadin/tests/components/datefield/WidthRecalculationOnEnableStateChange.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/datefield/WidthRecalculationOnEnableStateChange.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/formlayout/FormLayoutCaptionStyles.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/formlayout/FormLayoutCaptionStyles.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.java
tests/testbench/com/vaadin/tests/components/orderedlayout/VerticalLayoutChangingChildrenSizes.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/table/ScrollDetachSynchronization.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/table/TableHeaderZoom.java
tests/testbench/com/vaadin/tests/components/table/TableRepaintWhenMadeVisibile.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/table/TableRepaintWhenMadeVisible.html [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/table/Tables.java
tests/testbench/com/vaadin/tests/components/tabsheet/WrapTabSheetInTabSheet.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/textarea/TextAreaCursorPosition.java [new file with mode: 0644]
tests/testbench/com/vaadin/tests/components/textfield/TextFieldInputPromptAndClickShortcut.java [new file with mode: 0644]

index 88d6f92c79b654f8d4ba27420b6dfa57f5f15b02..7af440c735bdd436e7d5a1c95e15f6601a1b4acb 100644 (file)
@@ -60,6 +60,9 @@
 .v-datefield-calendarpanel-day-focused {
        outline: 1px dotted black;
 }
+.v-datefield-calendarpanel-day-offmonth {
+    color: #666;
+}
 
 .v-datefield-time {
        white-space: nowrap;
index e2b2a16ffe98d45d8b6dced7df752c6847a12250..877faf364f252dbaad249979a99c39fcd7dad787 100644 (file)
        cursor: pointer;
 }
 
+.v-table.v-disabled .v-table-header-cell,
+.v-table.v-disabled .v-table-header-cell-asc,
+.v-table.v-disabled .v-table-header-cell-desc {
+       cursor: default;
+}
+
 .v-table-footer-wrap {
        overflow: hidden;
        border: 1px solid #aaa;
@@ -85,6 +91,9 @@
        width: 1px;
        overflow: hidden;
 }
+.v-table.v-disabled .v-table-resizer {
+       cursor: default;        
+}
 .v-table-caption-container {
        overflow: hidden;
        white-space: nowrap;
        position: relative; /* hide this from IE, it works without it */
        cursor: pointer;
 }
+.v-table.v-disabled .v-table-column-selector {
+       cursor: default;
+}
 .v-table-focus-slot-left {
        border-left: 2px solid #999;
        float: none;
index 7f978076b8de5987049557afd514b73af44b8cd3..892b2958a472460d138c1bafc63466744b4f827f 100644 (file)
        padding: 0.2em 0.5em;
 }
 .v-tabsheet-tabitem .v-caption {
-       cursor: pointer;
+       cursor: inherit;
+}
+.v-tabsheet.v-disabled .v-tabsheet-tabitem,
+.v-tabsheet-tabitemcell-disabled .v-tabsheet-tabitem {
+       cursor: default;
 }
 .v-tabsheet-tabitem-selected {
        cursor: default;
index aa787dd4dc614c532703858567be005f0054e9ea..557a960c769ca33ade21bda54b7ce3f3b789feb7 100644 (file)
@@ -2,6 +2,7 @@
        text-align: left /* Force default alignment */
 }
 .v-textarea {
+       resize: none;
 }
 .v-textfield-focus,
 .v-textarea-focus {
index d5dfd66e2b6248b5b138e0e7efa28d45ae1bfc57..5f014247e266ef79b3decae49bfe38e62e877e71 100644 (file)
@@ -2,10 +2,15 @@
        background: #fff;
 }
 .v-window-outerheader {
-       cursor: move;
        padding: 0.3em 1em;
        height: 1em;
 }
+
+.v-window-outerheader,
+.v-window-draggingCurtain {
+       cursor: move;   
+}
+
 .v-window-header {
        font-weight: bold;
 }
@@ -37,16 +42,22 @@ div.v-window-header {
        zoom: 1;
        height: 10px;
        position: relative;
+       cursor: move;
 }
 .v-window-resizebox {
        width: 10px;
        height: 10px;
-       cursor: se-resize;
        background: #ddd;
        overflow: hidden;
        position: absolute;
        right: 0;
 }
+
+.v-window-resizebox,
+.v-window-resizingCurtain {
+       cursor: se-resize;
+}
+
 .v-window div.v-window-footer-noresize {
        height: 0;
 }
index 0db9b9d960733b2dde3b3e8525e16105162aa94a..d1697c584a7417e6d78228ca0a47f85788784027 100644 (file)
@@ -93,7 +93,6 @@
        width: 16px;
        height: 14px;
        overflow: hidden;
-       cursor: default;
        opacity: .5;
        filter: alpha(opacity=50);
        }
index 7d1727d4ca09e8ba6261ecdcb81d310e025ba368..243d1b87d4ac8d48101094715192df6848f503a9 100644 (file)
@@ -1,4 +1,29 @@
 @import url(../reindeer/styles.css);
 
 .table-equal-rowheight .v-table-row {height: 30px;}
-.table-equal-rowheight .v-table-row-odd {height: 30px;}
\ No newline at end of file
+.table-equal-rowheight .v-table-row-odd {height: 30px;}
+
+.v-datefield-enabled-readonly-styled {
+       background: #ddd;
+}
+
+.v-datefield-enabled-readonly-styled input.v-datefield-textfield {
+       border: 1px solid black;
+}
+
+.v-datefield-enabled-readonly-styled .v-datefield.v-disabled {
+       opacity: 1;
+}
+
+.v-disabled.v-datefield-enabled-readonly-styled .v-datefield-button,
+.v-readonly.v-datefield-enabled-readonly-styled .v-datefield-button {
+       display: none;
+}
+
+.popup-style .v-datefield-calendarpanel-header,
+.v-datefield-popup-popup-style .v-datefield-calendarpanel-time {
+       background: red;
+}
+.popup-style .v-datefield-calendarpanel-body {
+       background: yellow;
+}
index 217676558ea5f06f552a3c5a2243f266941b9c90..18ad5c9194d9d064d9691575227db444893902d0 100644 (file)
@@ -24,7 +24,6 @@
        width: 18px;
        height: 17px;
        overflow: hidden;
-       cursor: default;
 }
 .v-tabsheet-scroller button::-moz-focus-inner {
        border: none;
index df8e6e77a8e920627372305e5fe707b70b875a76..a1b285c9526e1650ade8c40ac44cb1e7bcd2ae40 100644 (file)
@@ -2,7 +2,7 @@ result-path=build/result
 checkout-path=build/checkout
 product-file=vaadin
 product-name=Vaadin
-toolkit-package=com/vaadin
+vaadin-package=com/vaadin
 gwt-dir=lib/core/gwt
 
 # repository into which Maven snapshots should be published 
index e21984cf061087489a1b3f9792e68b5b276e8c43..0fe17a5b732a0990d331a67bde2c095a3bf5b9fe 100644 (file)
        
     <target name="init-deps" depends="common.init-deps" >
         <property name="ivy.resolved" value="1" />
-        <ivy:resolve file="build/ivy/ivy.xml" resolveid="common" conf="ss.compile, cs.compile, ss.test.runtime"/>
-        <ivy:cachepath pathid="compile.classpath" conf="ss.compile"/>
-        <ivy:cachepath pathid="client-side.compile.classpath" conf="cs.compile"/>
-        <ivy:cachepath pathid="test.runtime.classpath" conf="ss.test.runtime"/>
+        <ivy:resolve file="build/ivy/ivy.xml" resolveid="common" conf="ss.compile, cs.compile, ss.test.compile"/>
+        <ivy:cachepath pathid="compile.classpath.server-side" conf="ss.compile"/>
+        <ivy:cachepath pathid="compile.classpath.client-side" conf="cs.compile"/>
+        <ivy:cachepath pathid="compile.classpath.server-side-tests" conf="ss.test.compile"/>
     </target>
 
     <!-- Clean results - - - - - - - - - - - - - - - - - - - - - - - - - -->
-    <target name="clean-result" depends="">
-        <property file="build/build.properties" />
+    <target name="clean-result" depends="build.properties">
 
         <!-- Clean build result directory. -->
         <delete dir="${result-path}" includes="**/*" followsymlinks="false" defaultexcludes="false" includeemptydirs="true" failonerror="false"/>
     </target>
 
+       <target name="build.properties">
+        <property file="build/build.properties" />
+               
+        <property file="build/VERSION.properties" />
+        <property file="build/GWT-VERSION.properties" />
+
+               <!-- result source and classes folders -->
+               <property name="result-src-core" value="${result-path}/src/core"/>
+               <property name="result-src-junit" value="${result-path}/src/junit"/>
+               <property name="result-src-testbench" value="${result-path}/src/testbench"/>
+               <property name="result-classes-core" value="${result-path}/classes/core"/>
+               <property name="result-classes-junit" value="${result-path}/classes/junit"/>
+               <property name="result-classes-testbench" value="${result-path}/classes/testbench"/>
+               <!-- Folder where Emma instrumented classes are placed (if Emma is used)-->
+               <property name="result-classes-core-for-emma-war" value="${result-path}/classes/emma-war"/>
+               <property name="result-classes-core-for-emma-junit" value="${result-path}/classes/emma-junit"/>
+
+       </target>
     <target name="clean-all" depends="clean-result">
     </target>
 
@@ -62,7 +79,7 @@
     <!-- Initialization - - - - - - - - - - - - - - - - - - - - - - - - - - -->
     <!-- ================================================================== -->
 
-     <target name="init" depends="init-deps">
+     <target name="init" depends="init-deps, build.properties">
         <!-- Current timestamp in different formats. -->
         <tstamp>
             <format property="build.date" pattern="yyyy-MM-dd"/>
@@ -71,9 +88,6 @@
             <format property="build.date.compact" pattern="yyyyMMdd"/>
         </tstamp>
 
-        <property file="build/VERSION.properties" />
-        <property file="build/GWT-VERSION.properties" />
-
         <antcontrib:propertyregex property="version.major" input="${version}" regexp="([^\.]*)\.([^\.]*)\.([^\.]*)" select="\1"/>
         <antcontrib:propertyregex property="version.minor" input="${version}" regexp="([^\.]*)\.([^\.]*)\.([^\.]*)" select="\2"/>
         <antcontrib:propertyregex property="version.revision" input="${version}" regexp="([^\.]*)\.([^\.]*)\.([^\.]*)" select="\3"/>
         <echo>Full Version: ${version.full}</echo>
 
         <!-- Other properties -->
-        <property file="build/build.properties" />
         <property file="build/html-style.properties" />
 
-        <echo>Vaadin package is: ${toolkit-package}</echo>
+        <echo>Vaadin package is: ${vaadin-package}</echo>
 
         <!-- Create result dir unless already exists -->
         <mkdir dir="${result-path}" />
 
         <!-- Create dirs that might be used by the test coverage generation -->
-       <mkdir dir="${result-path}/war_emma_classes" />
-       <mkdir dir="${result-path}/junit_emma_classes" />
+       <mkdir dir="${result-classes-core-for-emma-war}" />
+       <mkdir dir="${result-classes-core-for-emma-junit}" />
        <mkdir dir="${result-path}/coverage" />
 
         <echo>We are using gwt version ${gwt-version}.</echo>
 
         <echo>Adding test class files and resources and launcher configuration.</echo>
         <copy todir="${output-dir}/WebContent/WEB-INF/classes">
-            <fileset dir="${result-path}/classes">
-                <include name="${toolkit-package}/tests/**/*" />
-                <include name="${toolkit-package}/launcher/**" />
+            <fileset dir="${result-classes-testbench}">
+                <include name="${vaadin-package}/tests/**/*" />
+                <include name="${vaadin-package}/launcher/**" />
+            </fileset>
+            <fileset dir="${result-classes-junit}">
+               <!-- VaadinClasses is used by both JUnit and TestBench tests -->
+                <include name="**/VaadinClasses*.class" />
             </fileset>
             <!-- test resources -->
             <fileset dir="tests/testbench">
-                <include name="${toolkit-package}/tests/**/*" />
+                <include name="${vaadin-package}/tests/**/*" />
                 <!-- Pre-processed versions of these copied above -->
                 <exclude name="**/*.java" />
                 <exclude name="**/*.html" />
 
                <!-- Include files required by the DemoLauncher/DevelopmentServerLauncher -->
             <fileset dir="tests/testbench">
-                       <include name="${toolkit-package}/launcher/jetty-webdefault.xml" />
-                       <include name="${toolkit-package}/launcher/keystore" />
+                       <include name="${vaadin-package}/launcher/jetty-webdefault.xml" />
+                       <include name="${vaadin-package}/launcher/keystore" />
             </fileset>
         </copy>
 
     <!-- However, since compiling the server-side is required by the client-side -->
     <!-- compilation, the server-side will actually be built before it.          -->
     <target name="build"
-            depends="compile-server-side, compile-client-side, vaadin.jar, vaadin-sources.jar"
+            depends="compile-server-side, compile-tests, compile-client-side, vaadin.jar, vaadin-sources.jar"
             description="Build package required files, without packing them.">
     </target>
 
-    <target name="compile-server-side" depends="compile-java, webcontent"/>
+    <target name="compile-server-side" depends="compile-core, webcontent"/>
 
     <!-- Copy and preprocess sources for packaging 
     NOTE: Replaces <version></version> tags with build version tag for some "textual" files
          * tests/client-side (Client-side JUnit test cases)
 
         These are copied to 
-         * {$result-path}/src/core
-         * {$result-path}/src/tests
-         * {$result-path}/src/junit
-
+         * ${result-path}/src/core
+         * ${result-path}/src/tests
+         * ${result-path}/src/junit
+
+        And compiled to 
+         * ${result-path}/classes/core
+         * ${result-path}/classes/tests
+         * ${result-path}/classes/junit
+         
         Java/HTML/CSS/XML files are filtered so the license is added and the version is set. 
         Other files are just copied.
         -->
         
         <loadfile property="VaadinApache2LicenseForJavaFiles" srcFile="build/VaadinApache2LicenseForJavaFiles.txt" />
-        <mkdir dir="${result-path}/src" />
         
-        <mkdir dir="${result-path}/src/core" />
-        <mkdir dir="${result-path}/src/tests" />
-        <mkdir dir="${result-path}/src/junit" />
+        <mkdir dir="${result-path}/src" />
+        <mkdir dir="${result-src-core}" />
+        <mkdir dir="${result-src-testbench}" />
+        <mkdir dir="${result-src-junit}" />
 
         <patternset id="preprocessable-files">
             <include name="**/*.java" />
 
         <echo>Copying src directory and processing copied files.</echo>
         <echo>Replacing &lt;version&gt; tag with build version for java/html/css/xml files.</echo>
-        <copy todir="${result-path}/src/core" overwrite="yes">
+        <copy todir="${result-src-core}" overwrite="yes">
             <filterset refid="version-and-license"/>
             <filterset refid="pre-css-style"/>
             <fileset dir="src">
             </fileset>
         </copy>
 
-        <copy todir="${result-path}/src/tests">
+        <copy todir="${result-src-testbench}">
             <filterset refid="version-and-license"/>
             <fileset dir="tests/testbench">
                 <patternset refid="preprocessable-files" />
             </fileset>
         </copy>
-        <copy todir="${result-path}/src/junit">
+        <copy todir="${result-src-junit}">
             <filterset refid="version-and-license"/>
             <fileset dir="tests/server-side">
                 <patternset refid="preprocessable-files" />
 
         <!-- Add other files such as images, these are not filtered or processed by fixcrlf task -->
         <echo>Copying non java/html/css/xml files such as images.</echo>
-        <copy todir="${result-path}/src/core">
+        <copy todir="${result-src-core}">
             <fileset dir="src">
                 <patternset refid="non-preprocessable-files" />
             </fileset>
         </copy>
-        <copy todir="${result-path}/src/tests">
+        <copy todir="${result-src-testbench}">
             <fileset dir="tests/testbench">
                 <patternset refid="non-preprocessable-files" />
             </fileset>
         </copy>
-        <copy todir="${result-path}/src/junit">
+        <copy todir="${result-src-junit}">
             <fileset dir="tests/server-side">
                 <patternset refid="non-preprocessable-files" />
             </fileset>
     <target name="webcontent" depends="preprocess-src,defaulttheme">
 
         <!-- Add WebContent -->
-        <echo>Adding VAADIN/themes and demo files.</echo>
+        <echo>Adding VAADIN/themes and META-INF</echo>
         <copy todir="${output-dir}/WebContent">
             <fileset dir="WebContent">
                 <exclude name="**/.svn" />
-                <!-- TODO check what is necessary -->
-                <include name="demo/**/*" />
+                <include name="WEB-INF/lib/hsqldb.jar" />
                 <include name="VAADIN/themes/**/*" />
                <include name="VAADIN/vaadinBootstrap.js" />
                 <include name="META-INF/**/*" />
         </copy>
     </target>
 
-    <target name="compile-java" depends="init, webcontent">
+    <target name="compile-core" depends="init, preprocess-src">
         <echo>Compiling src (server-side)</echo>
-        
-        <!-- Compile all sources at the same time as they depend on each other -->
-        <mkdir dir="${result-path}/classes" />
-        <javac source="1.5" target="1.5" includeantruntime="false" destdir="${result-path}/classes" debug="true" encoding="UTF-8">
-               <classpath>
-                       <path refid="compile.classpath" />
-                       <path refid="test.runtime.classpath" />
-                       </classpath>                           
-             <src path="${result-path}/src/core"/>
-             <src path="${result-path}/src/tests"/>
-             <src path="${result-path}/src/junit"/>
+       <!-- Compile core sources first as the other sources depend on these -->
+        <mkdir dir="${result-classes-core}" />
+        <javac source="1.5" target="1.5" classpathref="compile.classpath.server-side" destdir="${result-classes-core}" debug="true" encoding="UTF-8" includeantruntime="false">
+            <src path="${result-src-core}"/>
+        </javac>
+    </target>
+       
+    <target name="compile-tests" depends="compile-core">
+        <echo>Compiling src (Server and client side JUnit tests)</echo>
+       <!-- Compile server and client side JUnit tests -->
+        <mkdir dir="${result-classes-junit}" />
+        <javac source="1.5" target="1.5" classpathref="compile.classpath.server-side-tests" destdir="${result-classes-junit}" debug="true" encoding="UTF-8" includeantruntime="false">
+               <classpath path="${result-classes-core}"></classpath>
+            <src path="${result-src-junit}"/>
+        </javac>
+       
+        <echo>Compiling src (TestBench tests)</echo>
+       <!-- Compile TestBench tests -->
+        <mkdir dir="${result-classes-testbench}" />
+        <javac source="1.5" target="1.5" classpathref="compile.classpath.server-side" destdir="${result-classes-testbench}" debug="true" encoding="UTF-8" includeantruntime="false">
+               <classpath path="${result-classes-junit}"></classpath>
+               <classpath path="${result-classes-core}"></classpath>
+            <src path="${result-src-testbench}"/>
         </javac>
+       
     </target>
 
     <target name="compile-helpers" depends="init">
        <mkdir dir="${buildhelpers-classes}" />
         <ivy:cachepath pathid="buildhelpers.dependencies" resolveId="buildhelpers" conf="compile" file="build/ivy/buildhelpers-ivy.xml"/>        
         <javac source="1.5" target="1.5" includeantruntime="false" srcdir="${buildhelpers-src}" 
-               classpathref="buildhelpers.dependencies" destdir="${buildhelpers-classes}" debug="true" encoding="UTF-8" />
+                       classpathref="buildhelpers.dependencies" destdir="${buildhelpers-classes}" debug="true" encoding="UTF-8" />
     </target>
     
     <target name="defaulttheme" depends="init, compile-helpers">
     </target>
 
     <!-- The widgetset generator is currently compiled along with rest of server-side Java. -->    
-    <target name="compile-widgetset-generator" depends="init, preprocess-src, compile-java"/>
-    
+    <target name="compile-widgetset-generator" depends="compile-core"/>
+
     <target name="compile-widgetset" depends="init-deps" description="Compiles the widgetset given as the first parameter">
         <fail unless="widgetset" message="No widgetset parameter set"/>
         <property name="widgetset-style" value="OBF" />
        <mkdir dir="${widgetsets-output-dir}"/>
         <java classname="com.google.gwt.dev.Compiler" failonerror="yes" fork="yes" maxmemory="512m">
                <classpath>
-                          <path refid="client-side.compile.classpath" />
-                          <pathelement location="${result-path}/classes" />
-                      <pathelement location="${result-path}/src/core" />
+                          <path refid="compile.classpath.client-side" />
+                          <pathelement location="${result-classes-core}" />
+                      <pathelement location="${result-src-core}" />
             </classpath>            
             <arg value="-war" />
             <arg value="${widgetsets-output-dir}" />
     
     <target name="compile-widgetset-default">
         <antcall target="compile-widgetset">
-            <reference refid="client-side.compile.classpath" />
+            <reference refid="compile.classpath.client-side" />
             <param name="widgetset" value="com.vaadin.terminal.gwt.DefaultWidgetSet"/>
         </antcall>
     </target>
     
     <target name="compile-widgetset-portal-default" unless="compile.only.default-widgetset">
         <antcall target="compile-widgetset">
-            <reference refid="client-side.compile.classpath" />
+            <reference refid="compile.classpath.client-side" />
             <param name="widgetset" value="com.vaadin.portal.gwt.PortalDefaultWidgetSet"/>
         </antcall>
     </target>
     </target>
 
     <!-- Definitions for building local components, i.e., not for an installation package. -->
-    <target name="init-nonpackage">
-        <property file="build/VERSION.properties" />
-        <property file="build/GWT-VERSION.properties" />
-
-        <property file="build/build.properties" />
-
+    <target name="init-nonpackage" depends="build.properties">
         <!-- Definitions for building the client-side. -->
         <property name="widgetsets-output-dir" value="WebContent/VAADIN/widgetsets" />
 
         <echo file="${output-dir}/META-INF/GWT-VERSION">${gwt-version}</echo> 
                
                <emma enabled="${emma.enabled}" >
-                       <instr instrpath="${result-path}/classes"
-                               destdir="${result-path}/war_emma_classes"
+                       <instr instrpath="${result-classes-core}"
+                               destdir="${result-classes-core-for-emma-war}"
                                mode="copy"
                                metadatafile="${result-path}/war.es"
                                merge="false"
                        >
                                <filter includes="com.vaadin.*" />
                                <filter excludes="com.vaadin.terminal.gwt.*" />
-                               <filter excludes="com.vaadin.tests.*" />
-                               <filter excludes="*Test*" />
-                               <filter excludes="com.vaadin.launcher.*" />
-                               <filter excludes="com.vaadin.data.util.sqlcontainer.*" />
                        </instr>
                </emma>         
        
                 <attribute name="Bundle-Version" value="${version.full}" />
             </manifest>
             <!-- Include any instrumented class files before the normal classes -->
-            <fileset dir="${result-path}/war_emma_classes">
-                <patternset>
-                    <exclude name="${toolkit-package}/tests/**"/>
-                    <exclude name="${toolkit-package}/launcher/**" />
-                </patternset>
-            </fileset>
-            <fileset dir="${result-path}/classes">
-                <patternset>
-                    <exclude name="${toolkit-package}/tests/**"/>
-                    <exclude name="${toolkit-package}/launcher/**" />
-                </patternset>
-            </fileset>
+            <fileset dir="${result-classes-core-for-emma-war}" />
+            <fileset dir="${result-classes-core}"/>
             <!-- add sources -->
-            <fileset dir="${result-path}/src/core">
-                <patternset>
-                    <exclude name="${toolkit-package}/launcher/**" />
-                </patternset>
-            </fileset>
+            <fileset dir="${result-src-core}"/>
             <fileset dir="${output-dir}/WebContent">
                 <patternset>
                     <include name="VAADIN/widgetsets/com.vaadin.terminal.gwt.DefaultWidgetSet/**/*" />
 
     <target name="vaadin-sources.jar" depends="init">
         <jar file="${result-path}/${lib-sources-jar-name}" compress="true">
-            <fileset dir="${result-path}/src/core">
+            <fileset dir="${result-src-core}">
                 <patternset>
                     <include name="**/*.java" />
                 </patternset>
     <target name="javadoc" depends="init, preprocess-src">
         <property name="javadoc.destdir" value="${output-dir}/WebContent/docs/api"/>
         
-        <javadoc destdir="${javadoc.destdir}" author="true" version="true" use="true" windowtitle="${product-name}" classpathref="compile.classpath">
-            <packageset dir="${result-path}/src/core">
-                <include name="${toolkit-package}/**" />
-            </packageset>
+        <javadoc destdir="${javadoc.destdir}" author="true" version="true" use="true" windowtitle="${product-name}" classpathref="compile.classpath.client-side">
+            <packageset dir="${result-src-core}"/>
             <doctitle>${javadoc.doctitle}</doctitle>
             <!-- <header><![CDATA[<script type="text/javascript" src=".html-style/style.js"></script>]]></header> -->
             <bottom>${javadoc.bottom}</bottom>
 
 
     <!-- Initialize a nightly build. -->
-    <target name="nightly-init">
+    <target name="nightly-init" depends="build.properties">
 
         <!-- Mandatory parameters. -->
         <fail unless="build.number" message="The build.number property must be defined."/>
         <!-- Optional parameters. -->
         <property name="build.tag" value="dev"/>
 
-        <property file="build/VERSION.properties" />
-
         <echo>Base version: ${version}</echo>
         <echo>Build number: ${build.number}</echo>
         <echo>Build tag: ${build.tag}</echo>
     <!-- Automated tests.                                                   -->
     <!-- ================================================================== -->
 
-    <target name="tests" depends="compile-java, internal-package-war">
+    <target name="tests" depends="compile-tests, internal-package-war">
         <!-- Run all different types of tests in parallel to decrease testing time -->
         <parallel threadcount="3">
                <sequential>
                                        <include name="*.em" />
                                </fileset>
                        </merge>
-                       <report sourcepath="${result-path}/src/core" >
+                       <report sourcepath="${result-src-core}" >
                                <fileset dir="${result-path}" >
                                        <include name="combined.es" />
                                </fileset>
     </target>
     
     <!-- Assumes java classes have been compiled but depends does not work out well as this is run from a <parallel> task-->
-    <target name="server-side-tests" depends="init-deps" unless="tests.serverside.skip">       
+    <target name="server-side-tests" unless="tests.serverside.skip" depends="compile-tests">
                <emma enabled="${emma.enabled}" >
-                       <instr instrpath="${result-path}/classes"
+                       <instr instrpath="${result-classes-core}"
+                               destdir="${result-classes-core-for-emma-junit}"
                                mode="copy"
-                               destdir="${result-path}/junit_emma_classes"
                                metadatafile="${result-path}/unittests.em"
-                               merge="false"
-                       >
+                           merge="false"
+                       >
                                <filter includes="com.vaadin.*" />
-                               <filter excludes="com.vaadin.tests.*" />
-                               <filter excludes="com.vaadin.terminal.gwt.client.*" />
-                               <filter excludes="com.vaadin.terminal.gwt.widgetsetutils.*" />
-                               <filter excludes="*Test*" />
-                               <filter excludes="com.vaadin.launcher.*" />
+                               <filter excludes="com.vaadin.terminal.gwt.*" />
                        </instr>
                </emma>                 
         <junit printsummary="yes"> 
             <classpath> 
-                <pathelement path="${result-path}/junit_emma_classes" />
-                <pathelement path="${result-path}/classes" />                  
-               <path refid="test.runtime.classpath"></path>
-                <path refid="compile.classpath"></path>
+                <pathelement path="${result-classes-core-for-emma-junit}" />
+                <pathelement path="${result-classes-core}" />
+                <pathelement path="${result-classes-junit}" />
+               <path refid="compile.classpath.server-side-tests"></path>
             </classpath>
                <jvmarg value="-Demma.coverage.out.file=../${result-path}/unittests.ec" />
 
             <batchtest fork="yes">
-                <fileset dir="tests/server-side" includes="**/*.java" excludes="**/Abstract*.java,com/vaadin/tests/data/bean/*.java,com/vaadin/tests/util/*.java" />
+                <fileset dir="tests/server-side" includes="**/*.java" excludes="**/Abstract*.java,com/vaadin/tests/data/bean/*.java,com/vaadin/tests/util/*.java,**/VaadinClasses.java" />
                 <fileset dir="tests/client-side" includes="**/*.java" excludes="**/Abstract*.java" />
             </batchtest>
         </junit>
                <emma enabled="${emma.enabled}" >
-                       <report sourcepath="${result-path}/src/core" >
+                       <report sourcepath="${result-src-core}" >
                                <fileset dir="${result-path}" >
                                        <include name="unittests.*" />
                                </fileset>
         </ant>
        
                <emma enabled="${emma.enabled}" >
-                       <report sourcepath="${result-path}/src/core" >
+                       <report sourcepath="${result-src-core}" >
                                <fileset dir="${result-path}" >
                                        <include name="war.*" />
                                </fileset>
index 4fcb44887b18a9ff64b3c0195b541ab120667a50..ffcf7b19c80dc4247f61d3e577968cdff9f6b066 100644 (file)
@@ -6,7 +6,7 @@
     <configurations >
                <conf name="ss.compile" extends="cs.compile" description="Server side compilation dependencies" visibility="private"/>
                <conf name="cs.compile" description="Client side compilation dependencies" visibility="private"/>
-               <conf name="ss.test.runtime" description="Test runtime dependencies" visibility="private"/>
+               <conf name="ss.test.compile" extends="ss.compile" description="Test compilation dependencies" visibility="private"/>
                <conf name="taskdefs" description="Ant task definitions" visibility="private" />
        </configurations>
     <publications />        
         <dependency org="com.google.gwt" name="gwt-dev" rev="2.4.0" conf="cs.compile->master" />
          
                <!-- Test frameworks & related -->
-               <dependency org="junit" name="junit" rev="4.5" conf="ss.test.runtime -> master"/>
-               <dependency org="org.easymock" name="easymock" rev="3.0" conf="ss.test.runtime -> master, runtime(*)"/>  
-               <dependency org="org.hsqldb" name="hsqldb" rev="2.2.6" conf="ss.test.runtime -> master, runtime(*)"/>  
+               <dependency org="junit" name="junit" rev="4.5" conf="ss.test.compile -> master"/>
+               <dependency org="org.easymock" name="easymock" rev="3.0" conf="ss.test.compile -> master, runtime(*)"/>  
+               <dependency org="org.hsqldb" name="hsqldb" rev="2.2.6" conf="ss.test.compile -> master, runtime(*)"/>  
                                
                <!-- Ant tasks -->      
                <dependency org="ant-contrib" name="ant-contrib" rev="1.0b3" conf="taskdefs ->master"/>
                <dependency org="org.apache.maven" name="maven-ant-tasks" rev="2.0.10" conf="taskdefs ->master"/>
                                
                <!-- Emma -->
-               <dependency org="emma" name="emma_ant" rev="2.0.5312" conf="ss.test.runtime,taskdefs ->master"/>
-               <dependency org="emma" name="emma" rev="2.0.5312-patched" conf="ss.test.runtime,taskdefs ->*"/>
+               <dependency org="emma" name="emma_ant" rev="2.0.5312" conf="ss.test.compile,taskdefs ->master"/>
+               <dependency org="emma" name="emma" rev="2.0.5312-patched" conf="ss.test.compile,taskdefs ->*"/>
 
         <!-- Bean Validation implementation -->
-        <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.6.1" conf="ss.test.runtime -> default"/>
-        <dependency org="org.hibernate" name="hibernate-validator" rev="4.2.0.Final" conf="ss.test.runtime -> default"/>
+        <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.6.1" conf="ss.test.compile -> default"/>
+        <dependency org="org.hibernate" name="hibernate-validator" rev="4.2.0.Final" conf="ss.test.compile -> default"/>
        </dependencies>
 
 </ivy-module>
\ No newline at end of file
index 083af70f303407c93d08764bf8c6efb56acdabb9..956d7730327f2dea12f3d6aadabbd016a72f63eb 100644 (file)
@@ -155,7 +155,7 @@ public class CompositeValidator implements Validator {
      */
     public void setMode(CombinationMode mode) {
         if (mode == null) {
-            throw new IllegalStateException(
+            throw new IllegalArgumentException(
                     "The validator can't be set to null");
         }
         this.mode = mode;
diff --git a/src/com/vaadin/launcher/util/BrowserLauncher.java b/src/com/vaadin/launcher/util/BrowserLauncher.java
deleted file mode 100644 (file)
index 55692cb..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* \r
-@VaadinApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.launcher.util;\r
-\r
-import java.io.BufferedInputStream;\r
-import java.io.BufferedReader;\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.io.InputStreamReader;\r
-\r
-/**\r
- * This class opens default browser for DemoLauncher class. Default browser is\r
- * detected by the operating system.\r
- * \r
- */\r
-public class BrowserLauncher {\r
-\r
-    /**\r
-     * Open browser on specified URL.\r
-     * \r
-     * @param url\r
-     */\r
-    public static void openBrowser(String url) {\r
-\r
-        final Runtime runtime = Runtime.getRuntime();\r
-        boolean started = false;\r
-\r
-        final String os = System.getProperty("os.name", "windows")\r
-                .toLowerCase();\r
-\r
-        // Linux\r
-        if (os.indexOf("linux") >= 0) {\r
-            // See if the default browser is Konqueror by resolving the symlink.\r
-            boolean isDefaultKonqueror = false;\r
-            try {\r
-                // Find out the location of the x-www-browser link from path.\r
-                Process process = runtime.exec("which x-www-browser");\r
-                BufferedInputStream ins = new BufferedInputStream(\r
-                        process.getInputStream());\r
-                BufferedReader bufreader = new BufferedReader(\r
-                        new InputStreamReader(ins));\r
-                String defaultLinkPath = bufreader.readLine();\r
-                ins.close();\r
-\r
-                // The path is null if the link did not exist.\r
-                if (defaultLinkPath != null) {\r
-                    // See if the default browser is Konqueror.\r
-                    File file = new File(defaultLinkPath);\r
-                    String canonical = file.getCanonicalPath();\r
-                    if (canonical.indexOf("konqueror") != -1) {\r
-                        isDefaultKonqueror = true;\r
-                    }\r
-                }\r
-            } catch (IOException e1) {\r
-                // The symlink was probably not found, so this is ok.\r
-            }\r
-\r
-            // Try x-www-browser, which is symlink to the default browser,\r
-            // except if we found that it is Konqueror.\r
-            if (!started && !isDefaultKonqueror) {\r
-                try {\r
-                    runtime.exec("x-www-browser " + url);\r
-                    started = true;\r
-                } catch (final IOException e) {\r
-                }\r
-            }\r
-\r
-            // Try firefox\r
-            if (!started) {\r
-                try {\r
-                    runtime.exec("firefox " + url);\r
-                    started = true;\r
-                } catch (final IOException e) {\r
-                }\r
-            }\r
-\r
-            // Try mozilla\r
-            if (!started) {\r
-                try {\r
-                    runtime.exec("mozilla " + url);\r
-                    started = true;\r
-                } catch (final IOException e) {\r
-                }\r
-            }\r
-\r
-            // Try konqueror\r
-            if (!started) {\r
-                try {\r
-                    runtime.exec("konqueror " + url);\r
-                    started = true;\r
-                } catch (final IOException e) {\r
-                }\r
-            }\r
-        }\r
-\r
-        // OS X\r
-        if (os.indexOf("mac os x") >= 0) {\r
-\r
-            // Try open\r
-            if (!started) {\r
-                try {\r
-                    runtime.exec("open " + url);\r
-                    started = true;\r
-                } catch (final IOException e) {\r
-                }\r
-            }\r
-        }\r
-\r
-        // Try cmd /start command on windows\r
-        if (os.indexOf("win") >= 0) {\r
-            if (!started) {\r
-                try {\r
-                    runtime.exec("cmd /c start " + url);\r
-                    started = true;\r
-                } catch (final IOException e) {\r
-                }\r
-            }\r
-        }\r
-\r
-        if (!started) {\r
-            System.out.println("Failed to open browser. Please go to " + url);\r
-        }\r
-    }\r
-\r
-}\r
index 055c74f20f239ffb14f5b8026fba6379870b13a8..e3c98e0fa94c868577f542dfc1753932ca6c102e 100644 (file)
@@ -129,14 +129,14 @@ public interface Sizeable extends Serializable {
 
         public static Unit getUnitFromSymbol(String symbol) {
             if (symbol == null) {
-                return null;
+                return Unit.PIXELS; // Defaults to pixels
             }
             for (Unit unit : Unit.values()) {
                 if (symbol.equals(unit.getSymbol())) {
                     return unit;
                 }
             }
-            return null;
+            return Unit.PIXELS; // Defaults to pixels
         }
     }
 
index 1cb79c146aee58e358da54e104a7fc6d11ea01d2..8ec45ac725b3cde752eaf2e35ac4265c57de2d03 100644 (file)
@@ -89,6 +89,12 @@ public class UserError implements ErrorMessage {
 
     public UserError(String message, ContentMode contentMode,
             ErrorLevel errorLevel) {
+        if (contentMode == null) {
+            contentMode = ContentMode.TEXT;
+        }
+        if (errorLevel == null) {
+            errorLevel = ErrorLevel.ERROR;
+        }
         msg = message;
         mode = contentMode;
         level = errorLevel;
index 5e1bb89b0c086f301f9e491b2b7a0e320ba68f57..e790c1d3fc68751dbd05abf236544cfbe8b0566b 100644 (file)
@@ -25,6 +25,8 @@ import com.google.gwt.http.client.RequestException;
 import com.google.gwt.http.client.Response;
 import com.google.gwt.json.client.JSONArray;
 import com.google.gwt.json.client.JSONString;
+import com.google.gwt.regexp.shared.MatchResult;
+import com.google.gwt.regexp.shared.RegExp;
 import com.google.gwt.user.client.Command;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
@@ -41,6 +43,7 @@ import com.vaadin.terminal.gwt.client.RenderInformation.Size;
 import com.vaadin.terminal.gwt.client.communication.JsonEncoder;
 import com.vaadin.terminal.gwt.client.communication.MethodInvocation;
 import com.vaadin.terminal.gwt.client.ui.Field;
+import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
 import com.vaadin.terminal.gwt.client.ui.VContextMenu;
 import com.vaadin.terminal.gwt.client.ui.VNotification;
 import com.vaadin.terminal.gwt.client.ui.VNotification.HideEvent;
@@ -102,6 +105,27 @@ public class ApplicationConnection {
     public static final String ATTRIBUTE_DESCRIPTION = "description";
     public static final String ATTRIBUTE_ERROR = "error";
 
+    /**
+     * A string that, if found in a non-JSON response to a UIDL request, will
+     * cause the browser to refresh the page. If followed by a colon, optional
+     * whitespace, and a URI, causes the browser to synchronously load the URI.
+     * 
+     * <p>
+     * This allows, for instance, a servlet filter to redirect the application
+     * to a custom login page when the session expires. For example:
+     * </p>
+     * 
+     * <pre>
+     * if (sessionExpired) {
+     *     response.setHeader(&quot;Content-Type&quot;, &quot;text/html&quot;);
+     *     response.getWriter().write(
+     *             myLoginPageHtml + &quot;&lt;!-- Vaadin-Refresh: &quot;
+     *                     + request.getContextPath() + &quot; --&gt;&quot;);
+     * }
+     * </pre>
+     */
+    public static final String UIDL_REFRESH_TOKEN = "Vaadin-Refresh";
+
     // will hold the UIDL security key (for XSS protection) once received
     private String uidlSecurityKey = "init";
 
@@ -526,6 +550,25 @@ public class ApplicationConnection {
                         return;
                     }
 
+                    String contentType = response.getHeader("Content-Type");
+                    if (contentType == null
+                            || !contentType.startsWith("application/json")) {
+                        /*
+                         * A servlet filter or equivalent may have intercepted
+                         * the request and served non-UIDL content (for
+                         * instance, a login page if the session has expired.)
+                         * If the response contains a magic substring, do a
+                         * synchronous refresh. See #8241.
+                         */
+                        MatchResult refreshToken = RegExp.compile(
+                                UIDL_REFRESH_TOKEN + "(:\\s*(.*?))?(\\s|$)")
+                                .exec(response.getText());
+                        if (refreshToken != null) {
+                            redirect(refreshToken.getGroup(2));
+                            return;
+                        }
+                    }
+
                     // for(;;);[realjson]
                     final String jsonText = response.getText().substring(9,
                             response.getText().length() - 1);
@@ -1540,9 +1583,10 @@ public class ApplicationConnection {
      * 
      * @return Returns true iff no further painting is needed by caller
      */
-    public boolean updateComponent(Widget component, UIDL uidl,
+    @Deprecated
+    public boolean updateComponent(VPaintableWidget paintable, UIDL uidl,
             boolean manageCaption) {
-        VPaintableWidget paintable = paintableMap.getPaintable(component);
+        Widget component = paintable.getWidgetForPaintable();
 
         String pid = paintableMap.getPid(paintable);
         if (pid == null) {
@@ -1603,9 +1647,68 @@ public class ApplicationConnection {
             fw.setEnabled(enabled);
         }
 
+        // Style names
+        component.setStyleName(getStyleName(component.getStylePrimaryName(),
+                uidl, component instanceof Field));
+
+        TooltipInfo tooltipInfo = paintableMap.getTooltipInfo(paintable, null);
+        // Update tooltip
+        if (uidl.hasAttribute(ATTRIBUTE_DESCRIPTION)) {
+            tooltipInfo
+                    .setTitle(uidl.getStringAttribute(ATTRIBUTE_DESCRIPTION));
+        } else {
+            tooltipInfo.setTitle(null);
+        }
+
+        // Set captions
+        if (manageCaption) {
+            final Container parent = Util.getLayout(component);
+            if (parent != null) {
+                parent.updateCaption(paintable, uidl);
+            }
+        }
+
+        // add error classname to components w/ error
+        if (uidl.hasAttribute(ATTRIBUTE_ERROR)) {
+            tooltipInfo.setErrorUidl(uidl.getErrors());
+        } else {
+            tooltipInfo.setErrorUidl(null);
+        }
+
+        // Set captions
+        if (manageCaption) {
+            final Container parent = Util.getLayout(component);
+            if (parent != null) {
+                parent.updateCaption(paintable, uidl);
+            }
+        }
+        /*
+         * updateComponentSize need to be after caption update so caption can be
+         * taken into account
+         */
+
+        updateComponentSize(paintable, uidl);
+
+        return false;
+    }
+
+    /**
+     * Generates the style name for the widget based on the given primary style
+     * name (typically returned by Widget.getPrimaryStyleName()) and the UIDL.
+     * An additional "modified" style name can be added if the field parameter
+     * is set to true.
+     * 
+     * @param primaryStyleName
+     * @param uidl
+     * @param isField
+     * @return
+     */
+    public static String getStyleName(String primaryStyleName, UIDL uidl,
+            boolean field) {
+        boolean enabled = !uidl.getBooleanAttribute("disabled");
+
         StringBuffer styleBuf = new StringBuffer();
-        final String primaryName = component.getStylePrimaryName();
-        styleBuf.append(primaryName);
+        styleBuf.append(primaryStyleName);
 
         // first disabling and read-only status
         if (!enabled) {
@@ -1623,7 +1726,7 @@ public class ApplicationConnection {
             final String[] styles = uidl.getStringAttribute("style").split(" ");
             for (int i = 0; i < styles.length; i++) {
                 styleBuf.append(" ");
-                styleBuf.append(primaryName);
+                styleBuf.append(primaryStyleName);
                 styleBuf.append("-");
                 styleBuf.append(styles[i]);
                 styleBuf.append(" ");
@@ -1632,55 +1735,25 @@ public class ApplicationConnection {
         }
 
         // add modified classname to Fields
-        if (uidl.hasAttribute("modified") && component instanceof Field) {
+        if (field && uidl.hasAttribute("modified")) {
             styleBuf.append(" ");
             styleBuf.append(MODIFIED_CLASSNAME);
         }
 
-        TooltipInfo tooltipInfo = paintableMap.getTooltipInfo(paintable, null);
-        // Update tooltip
-        if (uidl.hasAttribute(ATTRIBUTE_DESCRIPTION)) {
-            tooltipInfo
-                    .setTitle(uidl.getStringAttribute(ATTRIBUTE_DESCRIPTION));
-        } else {
-            tooltipInfo.setTitle(null);
-        }
-
         // add error classname to components w/ error
         if (uidl.hasAttribute(ATTRIBUTE_ERROR)) {
-            tooltipInfo.setErrorUidl(uidl.getErrors());
             styleBuf.append(" ");
-            styleBuf.append(primaryName);
+            styleBuf.append(primaryStyleName);
             styleBuf.append(ERROR_CLASSNAME_EXT);
-        } else {
-            tooltipInfo.setErrorUidl(null);
         }
-
         // add required style to required components
         if (uidl.hasAttribute("required")) {
             styleBuf.append(" ");
-            styleBuf.append(primaryName);
+            styleBuf.append(primaryStyleName);
             styleBuf.append(REQUIRED_CLASSNAME_EXT);
         }
 
-        // Styles + disabled & readonly
-        component.setStyleName(styleBuf.toString());
-
-        // Set captions
-        if (manageCaption) {
-            final Container parent = Util.getLayout(component);
-            if (parent != null) {
-                parent.updateCaption(paintable, uidl);
-            }
-        }
-        /*
-         * updateComponentSize need to be after caption update so caption can be
-         * taken into account
-         */
-
-        updateComponentSize(paintable, uidl);
-
-        return false;
+        return styleBuf.toString();
     }
 
     private void updateComponentSize(VPaintableWidget paintable, UIDL uidl) {
@@ -1773,7 +1846,7 @@ public class ApplicationConnection {
         while (childWidgets.hasNext()) {
             final Widget child = childWidgets.next();
 
-            if (child instanceof VPaintableWidget) {
+            if (getPaintableMap().isPaintable(child)) {
 
                 if (handleComponentRelativeSize(child)) {
                     /*
@@ -1808,7 +1881,7 @@ public class ApplicationConnection {
         if (paintable == null) {
             return false;
         }
-        boolean debugSizes = false;
+        boolean debugSizes = true;
 
         FloatSize relativeSize = paintableMap.getRelativeSize(paintable);
         if (relativeSize == null) {
@@ -1983,6 +2056,10 @@ public class ApplicationConnection {
         if (!paintableMap.hasPaintable(pid)) {
             // Create and register a new paintable if no old was found
             VPaintableWidget p = widgetSet.createWidget(uidl, configuration);
+            if (p instanceof VAbstractPaintableWidget) {
+                ((VAbstractPaintableWidget) p).setConnection(this);
+                ((VAbstractPaintableWidget) p).init();
+            }
             paintableMap.registerPaintable(pid, p);
         }
         return (VPaintableWidget) paintableMap.getPaintable(pid);
@@ -2146,7 +2223,7 @@ public class ApplicationConnection {
         }
     };
 
-    private VPaintableMap paintableMap = new VPaintableMap();
+    private VPaintableMap paintableMap = GWT.create(VPaintableMap.class);
 
     /**
      * Components can call this function to run all layout functions. This is
@@ -2229,7 +2306,7 @@ public class ApplicationConnection {
      * @return true if at least one listener has been registered on server side
      *         for the event identified by eventIdentifier.
      */
-    public boolean hasEventListeners(VPaintable paintable,
+    public boolean hasEventListeners(VPaintableWidget paintable,
             String eventIdentifier) {
         return paintableMap.hasEventListeners(paintable, eventIdentifier);
     }
@@ -2284,4 +2361,31 @@ public class ApplicationConnection {
         paintableMap.unregisterPaintable(p);
     }
 
+    public VTooltip getVTooltip() {
+        return tooltip;
+    }
+
+    @Deprecated
+    public void handleWidgetTooltipEvent(Event event, Widget owner, Object key) {
+        handleTooltipEvent(event, getPaintableMap().getPaintable(owner), key);
+
+    }
+
+    @Deprecated
+    public void handleWidgetTooltipEvent(Event event, Widget owner) {
+        handleTooltipEvent(event, getPaintableMap().getPaintable(owner));
+
+    }
+
+    @Deprecated
+    public void registerWidgetTooltip(Widget owner, Object key, TooltipInfo info) {
+        registerTooltip(getPaintableMap().getPaintable(owner), key, info);
+    }
+
+    @Deprecated
+    public boolean hasWidgetEventListeners(Widget widget, String eventIdentifier) {
+        return hasEventListeners(getPaintableMap().getPaintable(widget),
+                eventIdentifier);
+    }
+
 }
index 7c92bc261bcc16fa9357e0801c5499340a57e5ba..db6bbf0ee40c1aa58378197637ae59b9ec190b91 100644 (file)
@@ -42,12 +42,12 @@ public interface Container extends VPaintableWidget {
      * must provide service for it's childen to show those elements for them.
      * </p>
      * 
-     * @param component
+     * @param paintable
      *            Child component for which service is requested.
      * @param uidl
      *            UIDL of the child component.
      */
-    void updateCaption(VPaintableWidget component, UIDL uidl);
+    void updateCaption(VPaintableWidget paintable, UIDL uidl);
 
     /**
      * Called when a child components size has been updated in the rendering
index b411d9a89e40beeb6496a9ea65b18a3e10b496f1..4487341bd7166a3546e83d5f2807ca11b4a0b25e 100644 (file)
@@ -831,6 +831,24 @@ public class Util {
         }
     }-*/;
 
+    /**
+     * Helper method to find the nearest parent paintable instance by traversing
+     * the DOM upwards from given element.
+     * 
+     * @param element
+     *            the element to start from
+     */
+    public static VPaintableWidget findPaintable(ApplicationConnection client,
+            Element element) {
+        Widget widget = Util.findWidget(element, null);
+        VPaintableMap vPaintableMap = VPaintableMap.get(client);
+        while (widget != null && !vPaintableMap.isPaintable(widget)) {
+            widget = widget.getParent();
+        }
+        return vPaintableMap.getPaintable(widget);
+
+    }
+
     /**
      * Helper method to find first instance of given Widget type found by
      * traversing DOM upwards from given element.
@@ -968,6 +986,8 @@ public class Util {
                         + invocation.getMethodName() + "(" + formattedParams
                         + ")");
             }
+        } else {
+            VConsole.log("\t" + id + ": Warning: no corresponding paintable!");
         }
     }
 
index 892260e6ca8fc9d4e45ad88f87d877cd3e50b688..fdaf944b9f8628cade26f7a79fe6d03d8725e4cc 100644 (file)
@@ -734,8 +734,10 @@ public class VDebugConsole extends VOverlay implements Console {
 
             forceLayout.addClickHandler(new ClickHandler() {
                 public void onClick(ClickEvent event) {
-                    // TODO for each client in appconf force layout
-                    // VDebugConsole.this.client.forceLayout();
+                    for (ApplicationConnection applicationConnection : ApplicationConfiguration
+                            .getRunningApplications()) {
+                        applicationConnection.forceLayout();
+                    }
                 }
             });
 
index 02b529b428d6af97313d2f12a1e10072a58142d0..d85c6d33e24065ac230fd8b978c75d4d23488d65 100644 (file)
@@ -4,8 +4,13 @@
 package com.vaadin.terminal.gwt.client;\r
 \r
 /**\r
- * TODO\r
+ * Interface implemented by all client side classes that can be communicate with\r
+ * the server. Classes implementing this interface are initialized by the\r
+ * framework when needed and have the ability to communicate with the server.\r
  * \r
+ * @author Vaadin Ltd\r
+ * @version @VERSION@\r
+ * @since 7.0.0\r
  */\r
 public interface VPaintable {\r
     /**\r
@@ -16,4 +21,54 @@ public interface VPaintable {
      */\r
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client);\r
 \r
+    // /**\r
+    // * Returns the id for this VPaintable. This must always be what has been\r
+    // set\r
+    // * using {@link #setId(String)}.\r
+    // *\r
+    // * @return The id for the VPaintable.\r
+    // */\r
+    // public String getId();\r
+    //\r
+    // /**\r
+    // * Sets the id for the VPaintable. This method is called once by the\r
+    // * framework when the VPaintable is initialized and should never be called\r
+    // * otherwise.\r
+    // * <p>\r
+    // * The VPaintable id is used to map the server and the client paintables\r
+    // * together. It is unique in this root and assigned by the framework.\r
+    // * </p>\r
+    // *\r
+    // * @param id\r
+    // * The id of the paintable.\r
+    // */\r
+    // public void setId(String id);\r
+\r
+    /**\r
+     * Gets ApplicationConnection instance that created this VPaintable.\r
+     * \r
+     * @return The ApplicationConnection as set by\r
+     *         {@link #setConnection(ApplicationConnection)}\r
+     */\r
+    // public ApplicationConnection getConnection();\r
+\r
+    /**\r
+     * Sets the reference to ApplicationConnection. This method is called by the\r
+     * framework when the VPaintable is created and should never be called\r
+     * otherwise.\r
+     * \r
+     * @param connection\r
+     *            The ApplicationConnection that created this VPaintable\r
+     */\r
+    // public void setConnection(ApplicationConnection connection);\r
+\r
+    /**\r
+     * Tests whether the component is enabled or not. A user can not interact\r
+     * with disabled components. Disabled components are rendered in a style\r
+     * that indicates the status, usually in gray color. Children of a disabled\r
+     * component are also disabled.\r
+     * \r
+     * @return true if the component is enabled, false otherwise\r
+     */\r
+    // public boolean isEnabled();\r
 }\r
index ef355d3cad92c86c68edfa798a72e8f2e9cb0916..f21d85558c2776703b0ed4a64201f3a09db0aac0 100644 (file)
@@ -335,7 +335,7 @@ public class VPaintableMap {
 \r
     }\r
 \r
-    private ComponentDetail getComponentDetail(VPaintable paintable) {\r
+    private ComponentDetail getComponentDetail(VPaintableWidget paintable) {\r
         return idToComponentDetail.get(getPid(paintable));\r
     }\r
 \r
@@ -344,7 +344,7 @@ public class VPaintableMap {
     }\r
 \r
     /**\r
-     * FIXME: Should not be here\r
+     * FIXME: Should be moved to VAbstractPaintableWidget\r
      * \r
      * @param paintable\r
      * @return\r
@@ -354,6 +354,11 @@ public class VPaintableMap {
         return getComponentDetail(paintable).getTooltipInfo(key);\r
     }\r
 \r
+    @Deprecated\r
+    public TooltipInfo getWidgetTooltipInfo(Widget widget, Object key) {\r
+        return getTooltipInfo(getPaintable(widget), key);\r
+    }\r
+\r
     public Collection<? extends VPaintable> getPaintables() {\r
         return Collections.unmodifiableCollection(paintableToId.keySet());\r
     }\r
@@ -378,7 +383,7 @@ public class VPaintableMap {
      * @return\r
      */\r
     @Deprecated\r
-    public boolean hasEventListeners(VPaintable paintable,\r
+    public boolean hasEventListeners(VPaintableWidget paintable,\r
             String eventIdentifier) {\r
         return getComponentDetail(paintable).hasEventListeners(eventIdentifier);\r
     }\r
index 9171fdcedad94923084a25488da10af3ab647cce..2f0cae1cc1eca9c0153fffb0ce89a6cab8edefd3 100644 (file)
@@ -17,7 +17,8 @@ import com.google.gwt.user.client.ui.Widget;
 public interface VPaintableWidget extends VPaintable {
 
     /**
-     * TODO: Renamed to getWidget
+     * TODO: Rename to getWidget
      */
     public Widget getWidgetForPaintable();
+
 }
index 38f7878ba419aa5cc7e75e33cbfd1bfd2aa454f4..2bd578a45d27523b545b55a795aab6f322e9905a 100644 (file)
@@ -15,13 +15,11 @@ import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.ui.HasWidgets;
 import com.google.gwt.user.client.ui.KeyboardListener;
 import com.google.gwt.user.client.ui.KeyboardListenerCollection;
-import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.Container;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
 import com.vaadin.terminal.gwt.client.VPaintableWidget;
 import com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextArea;
 
@@ -137,12 +135,7 @@ public class ShortcutActionHandler {
             VPaintableWidget target) {
         final Element et = DOM.eventGetTarget(event);
         if (target == null) {
-            Widget w = Util.findWidget(et, null);
-            VPaintableMap paintableMap = VPaintableMap.get(client);
-            while (w != null && !paintableMap.isPaintable(w)) {
-                w = w.getParent();
-            }
-            target = paintableMap.getPaintable(w);
+            target = Util.findPaintable(client, et);
         }
         final VPaintableWidget finalTarget = target;
 
index dff5a286ba92ca8e1b6c1ff7a5bfb94ffa09ab50..9a2e728454944d8122610bfe0c18ca143083d23f 100644 (file)
@@ -1,12 +1,19 @@
+/*\r
+@VaadinApache2LicenseForJavaFiles@\r
+ */\r
 package com.vaadin.terminal.gwt.client.ui;\r
 \r
-import com.google.gwt.core.client.GWT;\r
 import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
 import com.vaadin.terminal.gwt.client.VPaintableWidget;\r
 \r
 public abstract class VAbstractPaintableWidget implements VPaintableWidget {\r
 \r
     private Widget widget;\r
+    private ApplicationConnection connection;\r
+\r
+    /* State variables */\r
+    // private boolean enabled = true;\r
 \r
     /**\r
      * Default constructor\r
@@ -14,15 +21,19 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget {
     public VAbstractPaintableWidget() {\r
     }\r
 \r
+    /**\r
+     * Called after the application connection reference has been set up\r
+     */\r
+    public void init() {\r
+    }\r
+\r
     /**\r
      * Creates and returns the widget for this VPaintableWidget. This method\r
      * should only be called once when initializing the paintable.\r
      * \r
      * @return\r
      */\r
-    protected Widget createWidget() {\r
-        return GWT.create(getWidgetClass());\r
-    }\r
+    protected abstract Widget createWidget();\r
 \r
     /**\r
      * Returns the widget associated with this paintable. The widget returned by\r
@@ -38,12 +49,27 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget {
         return widget;\r
     }\r
 \r
-    /**\r
-     * Returns the class of the widget for this paintable. Used to instansiate\r
-     * the widget.\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see com.vaadin.terminal.gwt.client.VPaintable#getConnection()\r
+     */\r
+    public final ApplicationConnection getConnection() {\r
+        return connection;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
      * \r
-     * @return The widget class.\r
+     * @see\r
+     * com.vaadin.terminal.gwt.client.VPaintable#setConnection(com.vaadin.terminal\r
+     * .gwt.client.ApplicationConnection)\r
      */\r
-    protected abstract Class<? extends Widget> getWidgetClass();\r
+    public final void setConnection(ApplicationConnection connection) {\r
+        this.connection = connection;\r
+    }\r
 \r
+    // public boolean isEnabled() {\r
+    // return enabled;\r
+    // }\r
 }\r
index b638304657bfb14aecd5be67a9c9aa0a5e29d06a..6872d5f640010d32a23c4896d96b1638b8fda62c 100644 (file)
@@ -23,18 +23,15 @@ import com.google.gwt.user.client.ui.FocusWidget;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.EventHelper;
 import com.vaadin.terminal.gwt.client.EventId;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.VTooltip;
 import com.vaadin.terminal.gwt.client.communication.ClientToServerRpc;
 import com.vaadin.terminal.gwt.client.communication.ClientToServerRpc.InitializableClientToServerRpc;
 
-public class VButton extends FocusWidget implements VPaintableWidget,
-        ClickHandler, FocusHandler, BlurHandler {
+public class VButton extends FocusWidget implements ClickHandler, FocusHandler,
+        BlurHandler {
 
     public static final String CLASSNAME = "v-button";
     private static final String CLASSNAME_PRESSED = "v-pressed";
@@ -67,7 +64,7 @@ public class VButton extends FocusWidget implements VPaintableWidget,
     protected int mousedownX = 0;
     protected int mousedownY = 0;
 
-    protected String id;
+    protected String paintableId;
 
     protected ApplicationConnection client;
 
@@ -90,7 +87,7 @@ public class VButton extends FocusWidget implements VPaintableWidget,
 
     private int tabIndex = 0;
 
-    private boolean disableOnClick = false;
+    protected boolean disableOnClick = false;
 
     /*
      * BELOW PRIVATE MEMBERS COPY-PASTED FROM GWT CustomButton
@@ -113,10 +110,10 @@ public class VButton extends FocusWidget implements VPaintableWidget,
     private boolean disallowNextClick = false;
     private boolean isHovering;
 
-    private HandlerRegistration focusHandlerRegistration;
-    private HandlerRegistration blurHandlerRegistration;
+    protected HandlerRegistration focusHandlerRegistration;
+    protected HandlerRegistration blurHandlerRegistration;
 
-    private int clickShortcut = 0;
+    protected int clickShortcut = 0;
     private ButtonClientToServerRpc buttonRpcProxy;
 
     public VButton() {
@@ -139,59 +136,6 @@ public class VButton extends FocusWidget implements VPaintableWidget,
         addClickHandler(this);
     }
 
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
-        // Ensure correct implementation,
-        // but don't let container manage caption etc.
-        if (client.updateComponent(this, uidl, false)) {
-            return;
-        }
-
-        focusHandlerRegistration = EventHelper.updateFocusHandler(this, client,
-                focusHandlerRegistration);
-        blurHandlerRegistration = EventHelper.updateBlurHandler(this, client,
-                blurHandlerRegistration);
-
-        // Save details
-        this.client = client;
-        id = uidl.getId();
-
-        // Set text
-        setText(uidl.getStringAttribute("caption"));
-
-        disableOnClick = uidl.hasAttribute(ATTR_DISABLE_ON_CLICK);
-
-        // handle error
-        if (uidl.hasAttribute("error")) {
-            if (errorIndicatorElement == null) {
-                errorIndicatorElement = DOM.createSpan();
-                errorIndicatorElement.setClassName("v-errorindicator");
-            }
-            wrapper.insertBefore(errorIndicatorElement, captionElement);
-
-        } else if (errorIndicatorElement != null) {
-            wrapper.removeChild(errorIndicatorElement);
-            errorIndicatorElement = null;
-        }
-
-        if (uidl.hasAttribute("icon")) {
-            if (icon == null) {
-                icon = new Icon(client);
-                wrapper.insertBefore(icon.getElement(), captionElement);
-            }
-            icon.setUri(uidl.getStringAttribute("icon"));
-        } else {
-            if (icon != null) {
-                wrapper.removeChild(icon.getElement());
-                icon = null;
-            }
-        }
-
-        if (uidl.hasAttribute("keycode")) {
-            clickShortcut = uidl.getIntAttribute("keycode");
-        }
-    }
-
     public void setText(String text) {
         captionElement.setInnerText(text);
     }
@@ -212,7 +156,7 @@ public class VButton extends FocusWidget implements VPaintableWidget,
      */
     public void onBrowserEvent(Event event) {
         if (client != null) {
-            client.handleTooltipEvent(event, this);
+            client.handleWidgetTooltipEvent(event, this);
         }
         if (DOM.eventGetType(event) == Event.ONLOAD) {
             Util.notifyParentOfSizeChange(this, true);
@@ -374,7 +318,7 @@ public class VButton extends FocusWidget implements VPaintableWidget,
      * .dom.client.ClickEvent)
      */
     public void onClick(ClickEvent event) {
-        if (id == null || client == null) {
+        if (paintableId == null || client == null) {
             return;
         }
         if (BrowserInfo.get().isSafari()) {
@@ -396,8 +340,8 @@ public class VButton extends FocusWidget implements VPaintableWidget,
     protected ButtonClientToServerRpc getButtonRpcProxy() {
         if (null == buttonRpcProxy) {
             buttonRpcProxy = GWT.create(ButtonClientToServerRpc.class);
-            ((InitializableClientToServerRpc) buttonRpcProxy).initRpc(id,
-                    client);
+            ((InitializableClientToServerRpc) buttonRpcProxy).initRpc(
+                    paintableId, client);
         }
         return buttonRpcProxy;
     }
@@ -531,11 +475,11 @@ public class VButton extends FocusWidget implements VPaintableWidget,
     }-*/;
 
     public void onFocus(FocusEvent arg0) {
-        client.updateVariable(id, EventId.FOCUS, "", true);
+        client.updateVariable(paintableId, EventId.FOCUS, "", true);
     }
 
     public void onBlur(BlurEvent arg0) {
-        client.updateVariable(id, EventId.BLUR, "", true);
+        client.updateVariable(paintableId, EventId.BLUR, "", true);
     }
 
     public Widget getWidgetForPaintable() {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VButtonPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VButtonPaintable.java
new file mode 100644 (file)
index 0000000..1367d41
--- /dev/null
@@ -0,0 +1,87 @@
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventHelper;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VButtonPaintable extends VAbstractPaintableWidget {
+
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+
+        // Ensure correct implementation,
+        // but don't let container manage caption etc.
+        if (client.updateComponent(this, uidl, false)) {
+            return;
+        }
+
+        getWidgetForPaintable().focusHandlerRegistration = EventHelper
+                .updateFocusHandler(this, client,
+                        getWidgetForPaintable().focusHandlerRegistration);
+        getWidgetForPaintable().blurHandlerRegistration = EventHelper
+                .updateBlurHandler(this, client,
+                        getWidgetForPaintable().blurHandlerRegistration);
+
+        // Save details
+        getWidgetForPaintable().client = client;
+        getWidgetForPaintable().paintableId = uidl.getId();
+
+        // Set text
+        getWidgetForPaintable().setText(uidl.getStringAttribute("caption"));
+
+        getWidgetForPaintable().disableOnClick = uidl
+                .hasAttribute(VButton.ATTR_DISABLE_ON_CLICK);
+
+        // handle error
+        if (uidl.hasAttribute("error")) {
+            if (getWidgetForPaintable().errorIndicatorElement == null) {
+                getWidgetForPaintable().errorIndicatorElement = DOM
+                        .createSpan();
+                getWidgetForPaintable().errorIndicatorElement
+                        .setClassName("v-errorindicator");
+            }
+            getWidgetForPaintable().wrapper.insertBefore(
+                    getWidgetForPaintable().errorIndicatorElement,
+                    getWidgetForPaintable().captionElement);
+
+        } else if (getWidgetForPaintable().errorIndicatorElement != null) {
+            getWidgetForPaintable().wrapper
+                    .removeChild(getWidgetForPaintable().errorIndicatorElement);
+            getWidgetForPaintable().errorIndicatorElement = null;
+        }
+
+        if (uidl.hasAttribute("icon")) {
+            if (getWidgetForPaintable().icon == null) {
+                getWidgetForPaintable().icon = new Icon(client);
+                getWidgetForPaintable().wrapper.insertBefore(
+                        getWidgetForPaintable().icon.getElement(),
+                        getWidgetForPaintable().captionElement);
+            }
+            getWidgetForPaintable().icon
+                    .setUri(uidl.getStringAttribute("icon"));
+        } else {
+            if (getWidgetForPaintable().icon != null) {
+                getWidgetForPaintable().wrapper
+                        .removeChild(getWidgetForPaintable().icon.getElement());
+                getWidgetForPaintable().icon = null;
+            }
+        }
+
+        if (uidl.hasAttribute("keycode")) {
+            getWidgetForPaintable().clickShortcut = uidl
+                    .getIntAttribute("keycode");
+        }
+    }
+
+    @Override
+    protected Widget createWidget() {
+        return GWT.create(VButton.class);
+    }
+
+    @Override
+    public VButton getWidgetForPaintable() {
+        return (VButton) super.getWidgetForPaintable();
+    }
+}
index ed05a3e67dcd7ef291de3a98aaa7d81316b3bacb..b318fe0af3180dd396030832ff24bd08db031851 100644 (file)
@@ -104,6 +104,8 @@ public class VCalendarPanel extends FocusableFlexTable implements
 \r
     private static final String CN_SELECTED = "selected";\r
 \r
+    private static final String CN_OFFMONTH = "offmonth";\r
+\r
     /**\r
      * Represents a click handler for when a user selects a value by using the\r
      * mouse\r
@@ -118,7 +120,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
          */\r
         public void onClick(ClickEvent event) {\r
             Day day = (Day) event.getSource();\r
-            focusDay(day.getDay());\r
+            focusDay(day.getDate());\r
             selectFocused();\r
             onSubmit();\r
         }\r
@@ -152,6 +154,8 @@ public class VCalendarPanel extends FocusableFlexTable implements
 \r
     private boolean showISOWeekNumbers;\r
 \r
+    private Date displayedMonth;\r
+\r
     private Date focusedDate;\r
 \r
     private Day selectedDay;\r
@@ -191,18 +195,18 @@ public class VCalendarPanel extends FocusableFlexTable implements
      * Sets the focus to given day of current time. Used when moving in the\r
      * calender with the keyboard.\r
      * \r
-     * @param day\r
+     * @param date\r
      *            The day number from by Date.getDate()\r
      */\r
-    private void focusDay(int day) {\r
+    private void focusDay(Date day) {\r
         // Only used when calender body is present\r
         if (resolution > VDateField.RESOLUTION_MONTH) {\r
             if (focusedDay != null) {\r
                 focusedDay.removeStyleDependentName(CN_FOCUSED);\r
             }\r
 \r
-            if (day > 0 && focusedDate != null) {\r
-                focusedDate.setDate(day);\r
+            if (day != null && focusedDate != null) {\r
+                focusedDate.setTime(day.getTime());\r
                 int rowCount = days.getRowCount();\r
                 for (int i = 0; i < rowCount; i++) {\r
                     int cellCount = days.getCellCount(i);\r
@@ -210,7 +214,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
                         Widget widget = days.getWidget(i, j);\r
                         if (widget != null && widget instanceof Day) {\r
                             Day curday = (Day) widget;\r
-                            if (curday.getDay() == day) {\r
+                            if (curday.getDate().equals(day)) {\r
                                 curday.addStyleDependentName(CN_FOCUSED);\r
                                 focusedDay = curday;\r
                                 focusedRow = i;\r
@@ -226,9 +230,9 @@ public class VCalendarPanel extends FocusableFlexTable implements
     /**\r
      * Sets the selection hightlight to a given date of current time\r
      * \r
-     * @param day\r
+     * @param date\r
      */\r
-    private void selectDate(int day) {\r
+    private void selectDate(Date date) {\r
         if (selectedDay != null) {\r
             selectedDay.removeStyleDependentName(CN_SELECTED);\r
         }\r
@@ -240,7 +244,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
                 Widget widget = days.getWidget(i, j);\r
                 if (widget != null && widget instanceof Day) {\r
                     Day curday = (Day) widget;\r
-                    if (curday.getDay() == day) {\r
+                    if (curday.getDate().equals(date)) {\r
                         curday.addStyleDependentName(CN_SELECTED);\r
                         selectedDay = curday;\r
                         return;\r
@@ -279,7 +283,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
             // it was forced to 1 above.\r
             value.setDate(focusedDate.getDate());\r
 \r
-            selectDate(focusedDate.getDate());\r
+            selectDate(focusedDate);\r
         } else {\r
             VConsole.log("Trying to select a the focused date which is NULL!");\r
         }\r
@@ -468,97 +472,62 @@ public class VCalendarPanel extends FocusableFlexTable implements
             }\r
         }\r
 \r
-        // The day of month that is selected, -1 if no day of this month is\r
-        // selected (i.e, showing another month/year than selected or nothing is\r
-        // selected)\r
-        int dayOfMonthSelected = -1;\r
-        // The day of month that is today, -1 if no day of this month is today\r
-        // (i.e., showing another month/year than current)\r
-        int dayOfMonthToday = -1;\r
-\r
-        boolean initiallyNull = value == null;\r
-\r
-        if (!initiallyNull && value.getMonth() == focusedDate.getMonth()\r
-                && value.getYear() == focusedDate.getYear()) {\r
-            dayOfMonthSelected = value.getDate();\r
-        }\r
-        final Date today = new Date();\r
-        if (today.getMonth() == focusedDate.getMonth()\r
-                && today.getYear() == focusedDate.getYear()) {\r
-            dayOfMonthToday = today.getDate();\r
-        }\r
+        // today must have zeroed hours, minutes, seconds, and milliseconds\r
+        final Date tmp = new Date();\r
+        final Date today = new Date(tmp.getYear(), tmp.getMonth(),\r
+                tmp.getDate());\r
 \r
         final int startWeekDay = getDateTimeService().getStartWeekDay(\r
                 focusedDate);\r
-        final int daysInMonth = DateTimeService\r
-                .getNumberOfDaysInMonth(focusedDate);\r
-\r
-        int dayCount = 0;\r
-        final Date curr = new Date(focusedDate.getTime());\r
+        final Date curr = (Date) focusedDate.clone();\r
+        // Start from the first day of the week that at least partially belongs\r
+        // to the current month\r
+        curr.setDate(-startWeekDay);\r
 \r
         // No month has more than 6 weeks so 6 is a safe maximum for rows.\r
         for (int weekOfMonth = 1; weekOfMonth < 7; weekOfMonth++) {\r
-            boolean weekNumberProcessed[] = new boolean[] { false, false,\r
-                    false, false, false, false, false };\r
-\r
             for (int dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {\r
-                if (!(weekOfMonth == 1 && dayOfWeek < startWeekDay)) {\r
-\r
-                    if (dayCount >= daysInMonth) {\r
-                        // All days printed and we are done\r
-                        break;\r
-                    }\r
-\r
-                    final int dayOfMonth = ++dayCount;\r
-\r
-                    curr.setDate(dayCount);\r
 \r
-                    // Actually write the day of month\r
-                    Day day = new Day(dayOfMonth);\r
+                // Actually write the day of month\r
+                Day day = new Day((Date) curr.clone());\r
 \r
-                    if (dayOfMonthSelected == dayOfMonth) {\r
-                        day.addStyleDependentName(CN_SELECTED);\r
-                        selectedDay = day;\r
+                if (curr.equals(value)) {\r
+                    day.addStyleDependentName(CN_SELECTED);\r
+                    selectedDay = day;\r
+                }\r
+                if (curr.equals(today)) {\r
+                    day.addStyleDependentName(CN_TODAY);\r
+                }\r
+                if (curr.equals(focusedDate)) {\r
+                    focusedDay = day;\r
+                    focusedRow = weekOfMonth;\r
+                    if (hasFocus) {\r
+                        day.addStyleDependentName(CN_FOCUSED);\r
                     }\r
+                }\r
+                if (curr.getMonth() != focusedDate.getMonth()) {\r
+                    day.addStyleDependentName(CN_OFFMONTH);\r
+                }\r
 \r
-                    if (dayOfMonthToday == dayOfMonth) {\r
-                        day.addStyleDependentName(CN_TODAY);\r
-                    }\r
+                days.setWidget(weekOfMonth, firstWeekdayColumn + dayOfWeek, day);\r
 \r
-                    if (dayOfMonth == focusedDate.getDate()) {\r
-                        focusedDay = day;\r
-                        focusedRow = weekOfMonth;\r
-                        if (hasFocus) {\r
-                            day.addStyleDependentName(CN_FOCUSED);\r
-                        }\r
-                    }\r
+                // ISO week numbers if requested\r
+                days.getCellFormatter().setVisible(weekOfMonth, weekColumn,\r
+                        isShowISOWeekNumbers());\r
+                if (isShowISOWeekNumbers()) {\r
+                    final String baseCssClass = VDateField.CLASSNAME\r
+                            + "-calendarpanel-weeknumber";\r
+                    String weekCssClass = baseCssClass;\r
 \r
-                    days.setWidget(weekOfMonth, firstWeekdayColumn + dayOfWeek,\r
-                            day);\r
-\r
-                    // ISO week numbers if requested\r
-                    if (!weekNumberProcessed[weekOfMonth]) {\r
-                        days.getCellFormatter().setVisible(weekOfMonth,\r
-                                weekColumn, isShowISOWeekNumbers());\r
-                        if (isShowISOWeekNumbers()) {\r
-                            final String baseCssClass = VDateField.CLASSNAME\r
-                                    + "-calendarpanel-weeknumber";\r
-                            String weekCssClass = baseCssClass;\r
-\r
-                            int weekNumber = DateTimeService\r
-                                    .getISOWeekNumber(curr);\r
-\r
-                            days.setHTML(weekOfMonth, 0, "<span class=\""\r
-                                    + weekCssClass + "\"" + ">" + weekNumber\r
-                                    + "</span>");\r
-                            weekNumberProcessed[weekOfMonth] = true;\r
-                        }\r
+                    int weekNumber = DateTimeService.getISOWeekNumber(curr);\r
 \r
-                    }\r
+                    days.setHTML(weekOfMonth, 0, "<span class=\""\r
+                            + weekCssClass + "\"" + ">" + weekNumber\r
+                            + "</span>");\r
                 }\r
+                curr.setDate(curr.getDate() + 1);\r
             }\r
         }\r
-\r
     }\r
 \r
     /**\r
@@ -622,6 +591,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
         while (focusedDate.getMonth() != requestedMonth) {\r
             focusedDate.setDate(focusedDate.getDate() - 1);\r
         }\r
+        displayedMonth.setMonth(displayedMonth.getMonth() + 1);\r
 \r
         renderCalendar();\r
     }\r
@@ -641,6 +611,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
         while (focusedDate.getMonth() == currentMonth) {\r
             focusedDate.setDate(focusedDate.getDate() - 1);\r
         }\r
+        displayedMonth.setMonth(displayedMonth.getMonth() - 1);\r
 \r
         renderCalendar();\r
     }\r
@@ -650,6 +621,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
      */\r
     private void focusPreviousYear(int years) {\r
         focusedDate.setYear(focusedDate.getYear() - years);\r
+        displayedMonth.setYear(displayedMonth.getYear() - years);\r
         renderCalendar();\r
     }\r
 \r
@@ -658,6 +630,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
      */\r
     private void focusNextYear(int years) {\r
         focusedDate.setYear(focusedDate.getYear() + years);\r
+        displayedMonth.setYear(displayedMonth.getYear() + years);\r
         renderCalendar();\r
     }\r
 \r
@@ -906,7 +879,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
 \r
             if (newCurrentDate.getMonth() == focusedDate.getMonth()) {\r
                 // Month did not change, only move the selection\r
-                focusDay(focusedDate.getDate() + 1);\r
+                focusDay(newCurrentDate);\r
             } else {\r
                 // If the month changed we need to re-render the calendar\r
                 focusedDate.setDate(focusedDate.getDate() + 1);\r
@@ -925,7 +898,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
 \r
             if (newCurrentDate.getMonth() == focusedDate.getMonth()) {\r
                 // Month did not change, only move the selection\r
-                focusDay(focusedDate.getDate() - 1);\r
+                focusDay(newCurrentDate);\r
             } else {\r
                 // If the month changed we need to re-render the calendar\r
                 focusedDate.setDate(focusedDate.getDate() - 1);\r
@@ -945,10 +918,10 @@ public class VCalendarPanel extends FocusableFlexTable implements
             if (newCurrentDate.getMonth() == focusedDate.getMonth()\r
                     && focusedRow > 1) {\r
                 // Month did not change, only move the selection\r
-                focusDay(focusedDate.getDate() - 7);\r
+                focusDay(newCurrentDate);\r
             } else {\r
                 // If the month changed we need to re-render the calendar\r
-                focusedDate.setDate(focusedDate.getDate() - 7);\r
+                focusedDate = newCurrentDate;\r
                 renderCalendar();\r
             }\r
 \r
@@ -964,10 +937,10 @@ public class VCalendarPanel extends FocusableFlexTable implements
 \r
             if (newCurrentDate.getMonth() == focusedDate.getMonth()) {\r
                 // Month did not change, only move the selection\r
-                focusDay(focusedDate.getDate() + 7);\r
+                focusDay(newCurrentDate);\r
             } else {\r
                 // If the month changed we need to re-render the calendar\r
-                focusedDate.setDate(focusedDate.getDate() + 7);\r
+                focusedDate = newCurrentDate;\r
                 renderCalendar();\r
 \r
             }\r
@@ -1211,27 +1184,28 @@ public class VCalendarPanel extends FocusableFlexTable implements
             return;\r
         }\r
 \r
-        Date oldFocusedValue = focusedDate;\r
+        Date oldDisplayedMonth = displayedMonth;\r
         value = currentDate;\r
 \r
         if (value == null) {\r
-            focusedDate = null;\r
+            focusedDate = displayedMonth = null;\r
         } else {\r
             focusedDate = (Date) value.clone();\r
+            displayedMonth = (Date) value.clone();\r
         }\r
 \r
         // Re-render calendar if month or year of focused date has changed\r
-        if (oldFocusedValue == null || value == null\r
-                || oldFocusedValue.getYear() != value.getYear()\r
-                || oldFocusedValue.getMonth() != value.getMonth()) {\r
+        if (oldDisplayedMonth == null || value == null\r
+                || oldDisplayedMonth.getYear() != value.getYear()\r
+                || oldDisplayedMonth.getMonth() != value.getMonth()) {\r
             renderCalendar();\r
         } else {\r
-            focusDay(currentDate.getDate());\r
+            focusDay(currentDate);\r
             selectFocused();\r
         }\r
 \r
         if (!hasFocus) {\r
-            focusDay(-1);\r
+            focusDay((Date) null);\r
         }\r
     }\r
 \r
@@ -1512,17 +1486,17 @@ public class VCalendarPanel extends FocusableFlexTable implements
     private class Day extends InlineHTML {\r
         private static final String BASECLASS = VDateField.CLASSNAME\r
                 + "-calendarpanel-day";\r
-        private final int day;\r
+        private final Date date;\r
 \r
-        Day(int dayOfMonth) {\r
-            super("" + dayOfMonth);\r
+        Day(Date date) {\r
+            super("" + date.getDate());\r
             setStyleName(BASECLASS);\r
-            day = dayOfMonth;\r
+            this.date = date;\r
             addClickHandler(dayClickHandler);\r
         }\r
 \r
-        public int getDay() {\r
-            return day;\r
+        public Date getDate() {\r
+            return date;\r
         }\r
     }\r
 \r
@@ -1605,7 +1579,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
     public void onBlur(final BlurEvent event) {\r
         if (event.getSource() instanceof VCalendarPanel) {\r
             hasFocus = false;\r
-            focusDay(-1);\r
+            focusDay(null);\r
         }\r
     }\r
 \r
@@ -1622,7 +1596,7 @@ public class VCalendarPanel extends FocusableFlexTable implements
 \r
             // Focuses the current day if the calendar shows the days\r
             if (focusedDay != null) {\r
-                focusDay(focusedDay.getDay());\r
+                focusDay(focusedDate);\r
             }\r
         }\r
     }\r
@@ -1653,7 +1627,15 @@ public class VCalendarPanel extends FocusableFlexTable implements
             // Day, find out which dayOfMonth and use that as the identifier\r
             Day day = Util.findWidget(subElement, Day.class);\r
             if (day != null) {\r
-                return SUBPART_DAY + day.getDay();\r
+                Date date = day.getDate();\r
+                int id = date.getDate();\r
+                if (date.getMonth() < displayedMonth.getMonth()) {\r
+                    id -= DateTimeService.getNumberOfDaysInMonth(date);\r
+                } else if (date.getMonth() > displayedMonth.getMonth()) {\r
+                    id += DateTimeService\r
+                            .getNumberOfDaysInMonth(displayedMonth);\r
+                }\r
+                return SUBPART_DAY + id;\r
             }\r
         } else if (time != null) {\r
             if (contains(time.hours, subElement)) {\r
@@ -1714,14 +1696,18 @@ public class VCalendarPanel extends FocusableFlexTable implements
             return time.ampm.getElement();\r
         }\r
         if (subPart.startsWith(SUBPART_DAY)) {\r
+            // can be less than 1 or greater than the number of days in the current month\r
+            // these map to the "off-month" days\r
             int dayOfMonth = Integer.parseInt(subPart.substring(SUBPART_DAY\r
                     .length()));\r
+            Date date = new Date(displayedMonth.getYear(),\r
+                    displayedMonth.getMonth(), dayOfMonth);\r
             Iterator<Widget> iter = days.iterator();\r
             while (iter.hasNext()) {\r
                 Widget w = iter.next();\r
                 if (w instanceof Day) {\r
                     Day day = (Day) w;\r
-                    if (day.getDay() == dayOfMonth) {\r
+                    if (day.getDate().equals(date)) {\r
                         return day.getElement();\r
                     }\r
                 }\r
index da916f262e0c92e8f44149fc3a3e6afaaf596188..3251a03d6afad2535f57e4d2312c873b1f8d4852 100644 (file)
@@ -113,14 +113,9 @@ public class VDragAndDropWrapper extends VCustomComponent implements
             VTransferable transferable = new VTransferable();
             transferable.setDragSource(VDragAndDropWrapper.this);
 
-            Widget widget = Util.findWidget((Element) event.getEventTarget()
-                    .cast(), null);
-            VPaintableMap vPaintableMap = VPaintableMap.get(client);
-            while (widget != null && !vPaintableMap.isPaintable(widget)) {
-                widget = widget.getParent();
-            }
-            VPaintableWidget paintable = vPaintableMap.getPaintable(widget);
-
+            VPaintableWidget paintable = Util.findPaintable(client,
+                    (Element) event.getEventTarget().cast());
+            Widget widget = paintable.getWidgetForPaintable();
             transferable.setData("component", paintable);
             VDragEvent dragEvent = VDragAndDropManager.get().startDrag(
                     transferable, event, true);
index 6d068dd11a1d846e79471aae4aac7b37138aa217..e6305b3c42f830c7d663ca906cb09e71cdcd0fa9 100644 (file)
@@ -117,8 +117,7 @@ public class VFormLayout extends SimplePanel implements Container {
                 Widget childWidget = childPaintable.getWidgetForPaintable();
                 Caption caption = widgetToCaption.get(childWidget);
                 if (caption == null) {
-                    caption = new Caption(childPaintable, client,
-                            getStylesFromUIDL(childUidl));
+                    caption = new Caption(childPaintable, client);
                     caption.addClickHandler(this);
                     widgetToCaption.put(childWidget, caption);
                 }
@@ -208,8 +207,7 @@ public class VFormLayout extends SimplePanel implements Container {
                     VPaintableWidget newPaintable = paintableMap
                             .getPaintable(newComponent);
                     Caption oldCap = widgetToCaption.get(oldComponent);
-                    final Caption newCap = new Caption(newPaintable, client,
-                            null);
+                    final Caption newCap = new Caption(newPaintable, client);
                     newCap.addClickHandler(this);
                     newCap.setStyleName(oldCap.getStyleName());
                     widgetToCaption.put(newComponent, newCap);
@@ -333,29 +331,37 @@ public class VFormLayout extends SimplePanel implements Container {
          *            return null
          * @param client
          */
-        public Caption(VPaintableWidget component,
-                ApplicationConnection client, String[] styles) {
+        public Caption(VPaintableWidget component, ApplicationConnection client) {
             super();
             this.client = client;
             owner = component;
 
-            String style = CLASSNAME;
+            sinkEvents(VTooltip.TOOLTIP_EVENTS);
+        }
+
+        private void setStyles(String[] styles) {
+            String styleName = CLASSNAME;
+
             if (styles != null) {
-                for (int i = 0; i < styles.length; i++) {
-                    style += " " + CLASSNAME + "-" + styles[i];
+                for (String style : styles) {
+                    if (ApplicationConnection.DISABLED_CLASSNAME.equals(style)) {
+                        // Add v-disabled also without classname prefix so
+                        // generic v-disabled CSS rules work
+                        styleName += " " + style;
+                    }
+
+                    styleName += " " + CLASSNAME + "-" + style;
                 }
             }
-            setStyleName(style);
 
-            sinkEvents(VTooltip.TOOLTIP_EVENTS);
+            setStyleName(styleName);
         }
 
         public void updateCaption(UIDL uidl) {
             setVisible(!uidl.getBooleanAttribute("invisible"));
 
-            setStyleName(getElement(),
-                    ApplicationConnection.DISABLED_CLASSNAME,
-                    uidl.hasAttribute("disabled"));
+            // Update styles as they might have changed when the caption changed
+            setStyles(getStylesFromUIDL(uidl));
 
             boolean isEmpty = true;
 
index 306086e35777941a66ae2f10f0c25d4ce99780fb..c39155d032f8f5a76cc5a91d5d28bc57a3e79053 100644 (file)
@@ -4,9 +4,7 @@
 package com.vaadin.terminal.gwt.client.ui;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Stack;
 
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.Scheduler;
@@ -35,14 +33,12 @@ import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
 import com.vaadin.terminal.gwt.client.TooltipInfo;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
 import com.vaadin.terminal.gwt.client.VTooltip;
 
-public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
+public class VMenuBar extends SimpleFocusablePanel implements
         CloseHandler<PopupPanel>, ContainerResizedListener, KeyPressHandler,
         KeyDownHandler, FocusHandler, SubPartAware {
 
@@ -82,7 +78,7 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
     protected VMenuBar parentMenu;
     protected CustomMenuItem selected;
 
-    private boolean enabled = true;
+    boolean enabled = true;
 
     private String width = "notinited";
 
@@ -94,9 +90,9 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
                 }
             });
 
-    private boolean openRootOnHover;
+    boolean openRootOnHover;
 
-    private boolean htmlContentAllowed;
+    boolean htmlContentAllowed;
 
     public VMenuBar() {
         // Create an empty horizontal menubar
@@ -167,133 +163,6 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
         }
     }
 
-    /**
-     * 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.
-     */
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-        // This call should be made first. Ensure correct implementation,
-        // and let the containing layout manage caption, etc.
-        if (client.updateComponent(this, uidl, true)) {
-            return;
-        }
-
-        htmlContentAllowed = uidl.hasAttribute(HTML_CONTENT_ALLOWED);
-
-        openRootOnHover = uidl.getBooleanAttribute(OPEN_ROOT_MENU_ON_HOWER);
-
-        enabled = !uidl.getBooleanAttribute("disabled");
-
-        // For future connections
-        this.client = client;
-        uidlId = uidl.getId();
-
-        // Empty the menu every time it receives new information
-        if (!getItems().isEmpty()) {
-            clearItems();
-        }
-
-        UIDL options = uidl.getChildUIDL(0);
-
-        if (uidl.hasAttribute("width")) {
-            UIDL moreItemUIDL = options.getChildUIDL(0);
-            StringBuffer itemHTML = new StringBuffer();
-
-            if (moreItemUIDL.hasAttribute("icon")) {
-                itemHTML.append("<img src=\""
-                        + Util.escapeAttribute(client
-                                .translateVaadinUri(moreItemUIDL
-                                        .getStringAttribute("icon")))
-                        + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />");
-            }
-
-            String moreItemText = moreItemUIDL.getStringAttribute("text");
-            if ("".equals(moreItemText)) {
-                moreItemText = "&#x25BA;";
-            }
-            itemHTML.append(moreItemText);
-
-            moreItem = GWT.create(CustomMenuItem.class);
-            moreItem.setHTML(itemHTML.toString());
-            moreItem.setCommand(emptyCommand);
-
-            collapsedRootItems = new VMenuBar(true, (VMenuBar) VPaintableMap
-                    .get(client).getPaintable(uidlId));
-            moreItem.setSubMenu(collapsedRootItems);
-            moreItem.addStyleName(CLASSNAME + "-more-menuitem");
-        }
-
-        UIDL uidlItems = uidl.getChildUIDL(1);
-        Iterator<Object> itr = uidlItems.getChildIterator();
-        Stack<Iterator<Object>> iteratorStack = new Stack<Iterator<Object>>();
-        Stack<VMenuBar> menuStack = new Stack<VMenuBar>();
-        VMenuBar currentMenu = this;
-
-        while (itr.hasNext()) {
-            UIDL item = (UIDL) itr.next();
-            CustomMenuItem currentItem = null;
-
-            final int itemId = item.getIntAttribute("id");
-
-            boolean itemHasCommand = item.hasAttribute("command");
-            boolean itemIsCheckable = item.hasAttribute(ATTRIBUTE_CHECKED);
-
-            String itemHTML = buildItemHTML(item);
-
-            Command cmd = null;
-            if (!item.hasAttribute("separator")) {
-                if (itemHasCommand || itemIsCheckable) {
-                    // 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.updateFromUIDL(item, client);
-
-            if (item.getChildCount() > 0) {
-                menuStack.push(currentMenu);
-                iteratorStack.push(itr);
-                itr = item.getChildIterator();
-                currentMenu = new VMenuBar(true, currentMenu);
-                if (uidl.hasAttribute("style")) {
-                    for (String style : uidl.getStringAttribute("style").split(
-                            " ")) {
-                        currentMenu.addStyleDependentName(style);
-                    }
-                }
-                currentItem.setSubMenu(currentMenu);
-            }
-
-            while (!itr.hasNext() && !iteratorStack.empty()) {
-                boolean hasCheckableItem = false;
-                for (CustomMenuItem menuItem : currentMenu.getItems()) {
-                    hasCheckableItem = hasCheckableItem
-                            || menuItem.isCheckable();
-                }
-                if (hasCheckableItem) {
-                    currentMenu.addStyleDependentName("check-column");
-                } else {
-                    currentMenu.removeStyleDependentName("check-column");
-                }
-
-                itr = iteratorStack.pop();
-                currentMenu = menuStack.pop();
-            }
-        }// while
-
-        iLayout(false);
-
-    }// updateFromUIDL
-
     /**
      * Build the HTML content for a menu item.
      * 
@@ -473,7 +342,7 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
         // Handle tooltips
         if (targetItem == null && client != null) {
             // Handle root menubar tooltips
-            client.handleTooltipEvent(e, this);
+            client.handleWidgetTooltipEvent(e, this);
         } else if (targetItem != null) {
             // Handle item tooltips
             targetItem.onBrowserEvent(e);
@@ -1051,7 +920,7 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
                 TooltipInfo info = new TooltipInfo(description);
 
                 VMenuBar root = findRootMenu();
-                client.registerTooltip(root, this, info);
+                client.registerWidgetTooltip(root, this, info);
             }
         }
 
@@ -1059,7 +928,7 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
         public void onBrowserEvent(Event event) {
             super.onBrowserEvent(event);
             if (client != null) {
-                client.handleTooltipEvent(event, findRootMenu(), this);
+                client.handleWidgetTooltipEvent(event, findRootMenu(), this);
             }
         }
 
@@ -1551,8 +1420,4 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
         return null;
     }
 
-    public Widget getWidgetForPaintable() {
-        return this;
-    }
-
 }
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
new file mode 100644 (file)
index 0000000..fabc77b
--- /dev/null
@@ -0,0 +1,161 @@
+/*\r
+@VaadinApache2LicenseForJavaFiles@\r
+ */\r
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import java.util.Iterator;\r
+import java.util.Stack;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.user.client.Command;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
+import com.vaadin.terminal.gwt.client.UIDL;\r
+import com.vaadin.terminal.gwt.client.Util;\r
+import com.vaadin.terminal.gwt.client.ui.VMenuBar.CustomMenuItem;\r
+\r
+public class VMenuBarPaintable extends VAbstractPaintableWidget {\r
+    /**\r
+     * This method must be implemented to update the client-side component from\r
+     * UIDL data received from server.\r
+     * \r
+     * This method is called when the page is loaded for the first time, and\r
+     * every time UI changes in the component are received from the server.\r
+     */\r
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+        // This call should be made first. Ensure correct implementation,\r
+        // and let the containing layout manage caption, etc.\r
+        if (client.updateComponent(this, uidl, true)) {\r
+            return;\r
+        }\r
+\r
+        getWidgetForPaintable().htmlContentAllowed = uidl\r
+                .hasAttribute(VMenuBar.HTML_CONTENT_ALLOWED);\r
+\r
+        getWidgetForPaintable().openRootOnHover = uidl\r
+                .getBooleanAttribute(VMenuBar.OPEN_ROOT_MENU_ON_HOWER);\r
+\r
+        getWidgetForPaintable().enabled = !uidl.getBooleanAttribute("disabled");\r
+\r
+        // For future connections\r
+        getWidgetForPaintable().client = client;\r
+        getWidgetForPaintable().uidlId = uidl.getId();\r
+\r
+        // Empty the menu every time it receives new information\r
+        if (!getWidgetForPaintable().getItems().isEmpty()) {\r
+            getWidgetForPaintable().clearItems();\r
+        }\r
+\r
+        UIDL options = uidl.getChildUIDL(0);\r
+\r
+        if (uidl.hasAttribute("width")) {\r
+            UIDL moreItemUIDL = options.getChildUIDL(0);\r
+            StringBuffer itemHTML = new StringBuffer();\r
+\r
+            if (moreItemUIDL.hasAttribute("icon")) {\r
+                itemHTML.append("<img src=\""\r
+                        + Util.escapeAttribute(client\r
+                                .translateVaadinUri(moreItemUIDL\r
+                                        .getStringAttribute("icon")))\r
+                        + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />");\r
+            }\r
+\r
+            String moreItemText = moreItemUIDL.getStringAttribute("text");\r
+            if ("".equals(moreItemText)) {\r
+                moreItemText = "&#x25BA;";\r
+            }\r
+            itemHTML.append(moreItemText);\r
+\r
+            getWidgetForPaintable().moreItem = GWT.create(CustomMenuItem.class);\r
+            getWidgetForPaintable().moreItem.setHTML(itemHTML.toString());\r
+            getWidgetForPaintable().moreItem.setCommand(VMenuBar.emptyCommand);\r
+\r
+            getWidgetForPaintable().collapsedRootItems = new VMenuBar(true,\r
+                    getWidgetForPaintable());\r
+            getWidgetForPaintable().moreItem\r
+                    .setSubMenu(getWidgetForPaintable().collapsedRootItems);\r
+            getWidgetForPaintable().moreItem.addStyleName(VMenuBar.CLASSNAME\r
+                    + "-more-menuitem");\r
+        }\r
+\r
+        UIDL uidlItems = uidl.getChildUIDL(1);\r
+        Iterator<Object> itr = uidlItems.getChildIterator();\r
+        Stack<Iterator<Object>> iteratorStack = new Stack<Iterator<Object>>();\r
+        Stack<VMenuBar> menuStack = new Stack<VMenuBar>();\r
+        VMenuBar currentMenu = getWidgetForPaintable();\r
+\r
+        while (itr.hasNext()) {\r
+            UIDL item = (UIDL) itr.next();\r
+            CustomMenuItem currentItem = null;\r
+\r
+            final int itemId = item.getIntAttribute("id");\r
+\r
+            boolean itemHasCommand = item.hasAttribute("command");\r
+            boolean itemIsCheckable = item\r
+                    .hasAttribute(VMenuBar.ATTRIBUTE_CHECKED);\r
+\r
+            String itemHTML = getWidgetForPaintable().buildItemHTML(item);\r
+\r
+            Command cmd = null;\r
+            if (!item.hasAttribute("separator")) {\r
+                if (itemHasCommand || itemIsCheckable) {\r
+                    // Construct a command that fires onMenuClick(int) with the\r
+                    // item's id-number\r
+                    cmd = new Command() {\r
+                        public void execute() {\r
+                            getWidgetForPaintable().hostReference\r
+                                    .onMenuClick(itemId);\r
+                        }\r
+                    };\r
+                }\r
+            }\r
+\r
+            currentItem = currentMenu.addItem(itemHTML.toString(), cmd);\r
+            currentItem.updateFromUIDL(item, client);\r
+\r
+            if (item.getChildCount() > 0) {\r
+                menuStack.push(currentMenu);\r
+                iteratorStack.push(itr);\r
+                itr = item.getChildIterator();\r
+                currentMenu = new VMenuBar(true, currentMenu);\r
+                if (uidl.hasAttribute("style")) {\r
+                    for (String style : uidl.getStringAttribute("style").split(\r
+                            " ")) {\r
+                        currentMenu.addStyleDependentName(style);\r
+                    }\r
+                }\r
+                currentItem.setSubMenu(currentMenu);\r
+            }\r
+\r
+            while (!itr.hasNext() && !iteratorStack.empty()) {\r
+                boolean hasCheckableItem = false;\r
+                for (CustomMenuItem menuItem : currentMenu.getItems()) {\r
+                    hasCheckableItem = hasCheckableItem\r
+                            || menuItem.isCheckable();\r
+                }\r
+                if (hasCheckableItem) {\r
+                    currentMenu.addStyleDependentName("check-column");\r
+                } else {\r
+                    currentMenu.removeStyleDependentName("check-column");\r
+                }\r
+\r
+                itr = iteratorStack.pop();\r
+                currentMenu = menuStack.pop();\r
+            }\r
+        }// while\r
+\r
+        getWidgetForPaintable().iLayout(false);\r
+\r
+    }// updateFromUIDL\r
+\r
+    @Override\r
+    protected Widget createWidget() {\r
+        return GWT.create(VMenuBar.class);\r
+    }\r
+\r
+    @Override\r
+    public VMenuBar getWidgetForPaintable() {\r
+        return (VMenuBar) super.getWidgetForPaintable();\r
+    }\r
+\r
+}\r
index 8385130a420257e4d32cfea96c7cadccb287bcc2..a0b374c97ef3ae9e65474348245335e81ef97a3d 100644 (file)
@@ -19,24 +19,21 @@ import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.EventHelper;
 import com.vaadin.terminal.gwt.client.EventId;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.VTooltip;
 import com.vaadin.terminal.gwt.client.communication.ClientToServerRpc.InitializableClientToServerRpc;
 import com.vaadin.terminal.gwt.client.ui.VButton.ButtonClientToServerRpc;
 
-public class VNativeButton extends Button implements VPaintableWidget,
-        ClickHandler, FocusHandler, BlurHandler {
+public class VNativeButton extends Button implements ClickHandler,
+        FocusHandler, BlurHandler {
 
     public static final String CLASSNAME = "v-nativebutton";
 
     protected String width = null;
 
-    protected String id;
+    protected String paintableId;
 
     protected ApplicationConnection client;
 
@@ -55,10 +52,10 @@ public class VNativeButton extends Button implements VPaintableWidget,
      */
     private boolean clickPending;
 
-    private HandlerRegistration focusHandlerRegistration;
-    private HandlerRegistration blurHandlerRegistration;
+    protected HandlerRegistration focusHandlerRegistration;
+    protected HandlerRegistration blurHandlerRegistration;
 
-    private boolean disableOnClick = false;
+    protected boolean disableOnClick = false;
 
     public VNativeButton() {
         setStyleName(CLASSNAME);
@@ -73,56 +70,6 @@ public class VNativeButton extends Button implements VPaintableWidget,
         sinkEvents(Event.ONMOUSEUP);
     }
 
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
-        // Ensure correct implementation,
-        // but don't let container manage caption etc.
-        if (client.updateComponent(this, uidl, false)) {
-            return;
-        }
-
-        disableOnClick = uidl.hasAttribute(VButton.ATTR_DISABLE_ON_CLICK);
-
-        focusHandlerRegistration = EventHelper.updateFocusHandler(this, client,
-                focusHandlerRegistration);
-        blurHandlerRegistration = EventHelper.updateBlurHandler(this, client,
-                blurHandlerRegistration);
-
-        // Save details
-        this.client = client;
-        id = uidl.getId();
-
-        // Set text
-        setText(uidl.getStringAttribute("caption"));
-
-        // handle error
-        if (uidl.hasAttribute("error")) {
-            if (errorIndicatorElement == null) {
-                errorIndicatorElement = DOM.createSpan();
-                errorIndicatorElement.setClassName("v-errorindicator");
-            }
-            getElement().insertBefore(errorIndicatorElement, captionElement);
-
-        } else if (errorIndicatorElement != null) {
-            getElement().removeChild(errorIndicatorElement);
-            errorIndicatorElement = null;
-        }
-
-        if (uidl.hasAttribute("icon")) {
-            if (icon == null) {
-                icon = new Icon(client);
-                getElement().insertBefore(icon.getElement(), captionElement);
-            }
-            icon.setUri(uidl.getStringAttribute("icon"));
-        } else {
-            if (icon != null) {
-                getElement().removeChild(icon.getElement());
-                icon = null;
-            }
-        }
-
-    }
-
     @Override
     public void setText(String text) {
         captionElement.setInnerText(text);
@@ -148,7 +95,7 @@ public class VNativeButton extends Button implements VPaintableWidget,
         }
 
         if (client != null) {
-            client.handleTooltipEvent(event, this);
+            client.handleWidgetTooltipEvent(event, this);
         }
     }
 
@@ -166,7 +113,7 @@ public class VNativeButton extends Button implements VPaintableWidget,
      * .dom.client.ClickEvent)
      */
     public void onClick(ClickEvent event) {
-        if (id == null || client == null) {
+        if (paintableId == null || client == null) {
             return;
         }
 
@@ -189,18 +136,18 @@ public class VNativeButton extends Button implements VPaintableWidget,
     protected ButtonClientToServerRpc getButtonRpcProxy() {
         if (null == buttonRpcProxy) {
             buttonRpcProxy = GWT.create(ButtonClientToServerRpc.class);
-            ((InitializableClientToServerRpc) buttonRpcProxy).initRpc(id,
-                    client);
+            ((InitializableClientToServerRpc) buttonRpcProxy).initRpc(
+                    paintableId, client);
         }
         return buttonRpcProxy;
     }
 
     public void onFocus(FocusEvent arg0) {
-        client.updateVariable(id, EventId.FOCUS, "", true);
+        client.updateVariable(paintableId, EventId.FOCUS, "", true);
     }
 
     public void onBlur(BlurEvent arg0) {
-        client.updateVariable(id, EventId.BLUR, "", true);
+        client.updateVariable(paintableId, EventId.BLUR, "", true);
     }
 
     @Override
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNativeButtonPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VNativeButtonPaintable.java
new file mode 100644 (file)
index 0000000..5e0dcee
--- /dev/null
@@ -0,0 +1,83 @@
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.EventHelper;
+import com.vaadin.terminal.gwt.client.UIDL;
+
+public class VNativeButtonPaintable extends VAbstractPaintableWidget {
+
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+
+        // Ensure correct implementation,
+        // but don't let container manage caption etc.
+        if (client.updateComponent(this, uidl, false)) {
+            return;
+        }
+
+        getWidgetForPaintable().disableOnClick = uidl
+                .hasAttribute(VButton.ATTR_DISABLE_ON_CLICK);
+
+        getWidgetForPaintable().focusHandlerRegistration = EventHelper
+                .updateFocusHandler(this, client,
+                        getWidgetForPaintable().focusHandlerRegistration);
+        getWidgetForPaintable().blurHandlerRegistration = EventHelper
+                .updateBlurHandler(this, client,
+                        getWidgetForPaintable().blurHandlerRegistration);
+
+        // Save details
+        getWidgetForPaintable().client = client;
+        getWidgetForPaintable().paintableId = uidl.getId();
+
+        // Set text
+        getWidgetForPaintable().setText(uidl.getStringAttribute("caption"));
+
+        // handle error
+        if (uidl.hasAttribute("error")) {
+            if (getWidgetForPaintable().errorIndicatorElement == null) {
+                getWidgetForPaintable().errorIndicatorElement = DOM
+                        .createSpan();
+                getWidgetForPaintable().errorIndicatorElement
+                        .setClassName("v-errorindicator");
+            }
+            getWidgetForPaintable().getElement().insertBefore(
+                    getWidgetForPaintable().errorIndicatorElement,
+                    getWidgetForPaintable().captionElement);
+
+        } else if (getWidgetForPaintable().errorIndicatorElement != null) {
+            getWidgetForPaintable().getElement().removeChild(
+                    getWidgetForPaintable().errorIndicatorElement);
+            getWidgetForPaintable().errorIndicatorElement = null;
+        }
+
+        if (uidl.hasAttribute("icon")) {
+            if (getWidgetForPaintable().icon == null) {
+                getWidgetForPaintable().icon = new Icon(client);
+                getWidgetForPaintable().getElement().insertBefore(
+                        getWidgetForPaintable().icon.getElement(),
+                        getWidgetForPaintable().captionElement);
+            }
+            getWidgetForPaintable().icon
+                    .setUri(uidl.getStringAttribute("icon"));
+        } else {
+            if (getWidgetForPaintable().icon != null) {
+                getWidgetForPaintable().getElement().removeChild(
+                        getWidgetForPaintable().icon.getElement());
+                getWidgetForPaintable().icon = null;
+            }
+        }
+
+    }
+
+    @Override
+    protected Widget createWidget() {
+        return GWT.create(VNativeButton.class);
+    }
+
+    @Override
+    public VNativeButton getWidgetForPaintable() {
+        return (VNativeButton) super.getWidgetForPaintable();
+    }
+}
\ No newline at end of file
index 7de1658c5da36d5f81ac509f0a02530c87a4525c..44fb9ac69caabba574cd4cdd32d170ba7ae801b1 100644 (file)
-/*
-@VaadinApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client.ui;
-
-import java.util.Date;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.DomEvent;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.logical.shared.CloseEvent;
-import com.google.gwt.event.logical.shared.CloseHandler;
-import com.google.gwt.user.client.DOM;
-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.Window;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.PopupPanel;
-import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.DateTimeService;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.VConsole;
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusChangeListener;
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;
-import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.TimeChangeListener;
-
-/**
- * Represents a date selection component with a text field and a popup date
- * selector.
- * 
- * <b>Note:</b> To change the keyboard assignments used in the popup dialog you
- * should extend <code>com.vaadin.terminal.gwt.client.ui.VCalendarPanel</code>
- * and then pass set it by calling the
- * <code>setCalendarPanel(VCalendarPanel panel)</code> method.
- * 
- */
-public class VPopupCalendar extends VTextualDate implements VPaintableWidget,
-        Field, ClickHandler, CloseHandler<PopupPanel>, SubPartAware {
-
-    private final Button calendarToggle;
-
-    private VCalendarPanel calendar;
-
-    private final VOverlay popup;
-    private boolean open = false;
-    private boolean parsable = true;
-
-    public VPopupCalendar() {
-        super();
-
-        calendarToggle = new Button();
-        calendarToggle.setStyleName(CLASSNAME + "-button");
-        calendarToggle.setText("");
-        calendarToggle.addClickHandler(this);
-        // -2 instead of -1 to avoid FocusWidget.onAttach to reset it
-        calendarToggle.getElement().setTabIndex(-2);
-        add(calendarToggle);
-
-        calendar = GWT.create(VCalendarPanel.class);
-        calendar.setFocusOutListener(new FocusOutListener() {
-            public boolean onFocusOut(DomEvent<?> event) {
-                event.preventDefault();
-                closeCalendarPanel();
-                return true;
-            }
-        });
-
-        calendar.setSubmitListener(new SubmitListener() {
-            public void onSubmit() {
-                // Update internal value and send valuechange event if immediate
-                updateValue(calendar.getDate());
-
-                // Update text field (a must when not immediate).
-                buildDate(true);
-
-                closeCalendarPanel();
-            }
-
-            public void onCancel() {
-                closeCalendarPanel();
-            }
-        });
-
-        popup = new VOverlay(true, true, true);
-        popup.setStyleName(VDateField.CLASSNAME + "-popup");
-        popup.setWidget(calendar);
-        popup.addCloseHandler(this);
-
-        DOM.setElementProperty(calendar.getElement(), "id",
-                "PID_VAADIN_POPUPCAL");
-
-        sinkEvents(Event.ONKEYDOWN);
-
-    }
-
-    @SuppressWarnings("deprecation")
-    private void updateValue(Date newDate) {
-        Date currentDate = getCurrentDate();
-        if (currentDate == null || newDate.getTime() != currentDate.getTime()) {
-            setCurrentDate((Date) newDate.clone());
-            getClient().updateVariable(getId(), "year",
-                    newDate.getYear() + 1900, false);
-            if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {
-                getClient().updateVariable(getId(), "month",
-                        newDate.getMonth() + 1, false);
-                if (getCurrentResolution() > RESOLUTION_MONTH) {
-                    getClient().updateVariable(getId(), "day",
-                            newDate.getDate(), false);
-                    if (getCurrentResolution() > RESOLUTION_DAY) {
-                        getClient().updateVariable(getId(), "hour",
-                                newDate.getHours(), false);
-                        if (getCurrentResolution() > RESOLUTION_HOUR) {
-                            getClient().updateVariable(getId(), "min",
-                                    newDate.getMinutes(), false);
-                            if (getCurrentResolution() > RESOLUTION_MIN) {
-                                getClient().updateVariable(getId(), "sec",
-                                        newDate.getSeconds(), false);
-                            }
-                        }
-                    }
-                }
-            }
-            if (isImmediate()) {
-                getClient().sendPendingVariableChanges();
-            }
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * com.vaadin.terminal.gwt.client.ui.VTextualDate#updateFromUIDL(com.vaadin
-     * .terminal.gwt.client.UIDL,
-     * com.vaadin.terminal.gwt.client.ApplicationConnection)
-     */
-    @Override
-    @SuppressWarnings("deprecation")
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-        boolean lastReadOnlyState = readonly;
-        parsable = uidl.getBooleanAttribute("parsable");
-
-        super.updateFromUIDL(uidl, client);
-
-        popup.setStyleName(VDateField.CLASSNAME + "-popup "
-                + VDateField.CLASSNAME + "-"
-                + resolutionToString(currentResolution));
-        calendar.setDateTimeService(getDateTimeService());
-        calendar.setShowISOWeekNumbers(isShowISOWeekNumbers());
-        if (calendar.getResolution() != currentResolution) {
-            calendar.setResolution(currentResolution);
-            if (calendar.getDate() != null) {
-                calendar.setDate((Date) getCurrentDate().clone());
-                // force re-render when changing resolution only
-                calendar.renderCalendar();
-            }
-        }
-        calendarToggle.setEnabled(enabled);
-
-        if (currentResolution <= RESOLUTION_MONTH) {
-            calendar.setFocusChangeListener(new FocusChangeListener() {
-                public void focusChanged(Date date) {
-                    updateValue(date);
-                    buildDate();
-                    Date date2 = calendar.getDate();
-                    date2.setYear(date.getYear());
-                    date2.setMonth(date.getMonth());
-                }
-            });
-        } else {
-            calendar.setFocusChangeListener(null);
-        }
-
-        if (currentResolution > RESOLUTION_DAY) {
-            calendar.setTimeChangeListener(new TimeChangeListener() {
-                public void changed(int hour, int min, int sec, int msec) {
-                    Date d = getDate();
-                    if (d == null) {
-                        // date currently null, use the value from calendarPanel
-                        // (~ client time at the init of the widget)
-                        d = (Date) calendar.getDate().clone();
-                    }
-                    d.setHours(hour);
-                    d.setMinutes(min);
-                    d.setSeconds(sec);
-                    DateTimeService.setMilliseconds(d, msec);
-
-                    // Always update time changes to the server
-                    updateValue(d);
-
-                    // Update text field
-                    buildDate();
-                }
-            });
-        }
-
-        if (readonly) {
-            calendarToggle.addStyleName(CLASSNAME + "-button-readonly");
-        } else {
-            calendarToggle.removeStyleName(CLASSNAME + "-button-readonly");
-        }
-
-        if (lastReadOnlyState != readonly) {
-            updateWidth();
-        }
-
-        calendarToggle.setEnabled(true);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)
-     */
-    @Override
-    public void setStyleName(String style) {
-        // make sure the style is there before size calculation
-        super.setStyleName(style + " " + CLASSNAME + "-popupcalendar");
-    }
-
-    /**
-     * Opens the calendar panel popup
-     */
-    public void openCalendarPanel() {
-
-        if (!open && !readonly) {
-            open = true;
-
-            if (getCurrentDate() != null) {
-                calendar.setDate((Date) getCurrentDate().clone());
-            } else {
-                calendar.setDate(new Date());
-            }
-
-            // clear previous values
-            popup.setWidth("");
-            popup.setHeight("");
-            popup.setPopupPositionAndShow(new PositionCallback() {
-                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();
-
-                    // Add a little extra space to the right to avoid
-                    // problems with 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 > 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
-                    popup.setWidth(w + "px");
-                    popup.setHeight(h + "px");
-
-                    popup.setPopupPosition(l,
-                            t + calendarToggle.getOffsetHeight() + 2);
-
-                    /*
-                     * We have to wait a while before focusing since the popup
-                     * needs to be opened before we can focus
-                     */
-                    Timer focusTimer = new Timer() {
-                        @Override
-                        public void run() {
-                            setFocus(true);
-                        }
-                    };
-
-                    focusTimer.schedule(100);
-                }
-            });
-        } else {
-            VConsole.error("Cannot reopen popup, it is already open!");
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event
-     * .dom.client.ClickEvent)
-     */
-    public void onClick(ClickEvent event) {
-        if (event.getSource() == calendarToggle && isEnabled()) {
-            openCalendarPanel();
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt
-     * .event.logical.shared.CloseEvent)
-     */
-    public void onClose(CloseEvent<PopupPanel> event) {
-        if (event.getSource() == popup) {
-            buildDate();
-            if (!BrowserInfo.get().isTouchDevice()) {
-                /*
-                 * Move focus to textbox, unless on touch device (avoids opening
-                 * virtual keyboard).
-                 */
-                focus();
-            }
-
-            // TODO resolve what the "Sigh." is all about and document it here
-            // Sigh.
-            Timer t = new Timer() {
-                @Override
-                public void run() {
-                    open = false;
-                }
-            };
-            t.schedule(100);
-        }
-    }
-
-    /**
-     * Sets focus to Calendar panel.
-     * 
-     * @param focus
-     */
-    public void setFocus(boolean focus) {
-        calendar.setFocus(focus);
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#getFieldExtraWidth()
-     */
-    @Override
-    protected int getFieldExtraWidth() {
-        if (fieldExtraWidth < 0) {
-            fieldExtraWidth = super.getFieldExtraWidth();
-            fieldExtraWidth += calendarToggle.getOffsetWidth();
-        }
-        return fieldExtraWidth;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#buildDate()
-     */
-    @Override
-    protected void buildDate() {
-        // Save previous value
-        String previousValue = getText();
-        super.buildDate();
-
-        // Restore previous value if the input could not be parsed
-        if (!parsable) {
-            setText(previousValue);
-        }
-    }
-
-    /**
-     * Update the text field contents from the date. See {@link #buildDate()}.
-     * 
-     * @param forceValid
-     *            true to force the text field to be updated, false to only
-     *            update if the parsable flag is true.
-     */
-    protected void buildDate(boolean forceValid) {
-        if (forceValid) {
-            parsable = true;
-        }
-        buildDate();
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * com.vaadin.terminal.gwt.client.ui.VDateField#onBrowserEvent(com.google
-     * .gwt.user.client.Event)
-     */
-    @Override
-    public void onBrowserEvent(com.google.gwt.user.client.Event event) {
-        super.onBrowserEvent(event);
-        if (DOM.eventGetType(event) == Event.ONKEYDOWN
-                && event.getKeyCode() == getOpenCalenderPanelKey()) {
-            openCalendarPanel();
-            event.preventDefault();
-        }
-    }
-
-    /**
-     * Get the key code that opens the calendar panel. By default it is the down
-     * key but you can override this to be whatever you like
-     * 
-     * @return
-     */
-    protected int getOpenCalenderPanelKey() {
-        return KeyCodes.KEY_DOWN;
-    }
-
-    /**
-     * Closes the open popup panel
-     */
-    public void closeCalendarPanel() {
-        if (open) {
-            popup.hide(true);
-        }
-    }
-
-    private final String CALENDAR_TOGGLE_ID = "popupButton";
-
-    @Override
-    public Element getSubPartElement(String subPart) {
-        if (subPart.equals(CALENDAR_TOGGLE_ID)) {
-            return calendarToggle.getElement();
-        }
-
-        return super.getSubPartElement(subPart);
-    }
-
-    @Override
-    public String getSubPartName(Element subElement) {
-        if (calendarToggle.getElement().isOrHasChild(subElement)) {
-            return CALENDAR_TOGGLE_ID;
-        }
-
-        return super.getSubPartName(subElement);
-    }
-
-}
+/*\r
+@VaadinApache2LicenseForJavaFiles@\r
+ */\r
+\r
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import java.util.Date;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.event.dom.client.ClickEvent;\r
+import com.google.gwt.event.dom.client.ClickHandler;\r
+import com.google.gwt.event.dom.client.DomEvent;\r
+import com.google.gwt.event.dom.client.KeyCodes;\r
+import com.google.gwt.event.logical.shared.CloseEvent;\r
+import com.google.gwt.event.logical.shared.CloseHandler;\r
+import com.google.gwt.user.client.DOM;\r
+import com.google.gwt.user.client.Element;\r
+import com.google.gwt.user.client.Event;\r
+import com.google.gwt.user.client.Timer;\r
+import com.google.gwt.user.client.Window;\r
+import com.google.gwt.user.client.ui.Button;\r
+import com.google.gwt.user.client.ui.PopupPanel;\r
+import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
+import com.vaadin.terminal.gwt.client.BrowserInfo;\r
+import com.vaadin.terminal.gwt.client.DateTimeService;\r
+import com.vaadin.terminal.gwt.client.VPaintableWidget;\r
+import com.vaadin.terminal.gwt.client.UIDL;\r
+import com.vaadin.terminal.gwt.client.VConsole;\r
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusChangeListener;\r
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.FocusOutListener;\r
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.SubmitListener;\r
+import com.vaadin.terminal.gwt.client.ui.VCalendarPanel.TimeChangeListener;\r
+\r
+/**\r
+ * Represents a date selection component with a text field and a popup date\r
+ * selector.\r
+ * \r
+ * <b>Note:</b> To change the keyboard assignments used in the popup dialog you\r
+ * should extend <code>com.vaadin.terminal.gwt.client.ui.VCalendarPanel</code>\r
+ * and then pass set it by calling the\r
+ * <code>setCalendarPanel(VCalendarPanel panel)</code> method.\r
+ * \r
+ */\r
+public class VPopupCalendar extends VTextualDate implements VPaintableWidget,\r
+        Field, ClickHandler, CloseHandler<PopupPanel>, SubPartAware {\r
+\r
+    private static final String POPUP_PRIMARY_STYLE_NAME = VDateField.CLASSNAME\r
+            + "-popup";\r
+\r
+    private final Button calendarToggle;\r
+\r
+    private VCalendarPanel calendar;\r
+\r
+    private final VOverlay popup;\r
+    private boolean open = false;\r
+    private boolean parsable = true;\r
+\r
+    public VPopupCalendar() {\r
+        super();\r
+\r
+        calendarToggle = new Button();\r
+        calendarToggle.setStyleName(CLASSNAME + "-button");\r
+        calendarToggle.setText("");\r
+        calendarToggle.addClickHandler(this);\r
+        // -2 instead of -1 to avoid FocusWidget.onAttach to reset it\r
+        calendarToggle.getElement().setTabIndex(-2);\r
+        add(calendarToggle);\r
+\r
+        calendar = GWT.create(VCalendarPanel.class);\r
+        calendar.setFocusOutListener(new FocusOutListener() {\r
+            public boolean onFocusOut(DomEvent<?> event) {\r
+                event.preventDefault();\r
+                closeCalendarPanel();\r
+                return true;\r
+            }\r
+        });\r
+\r
+        calendar.setSubmitListener(new SubmitListener() {\r
+            public void onSubmit() {\r
+                // Update internal value and send valuechange event if immediate\r
+                updateValue(calendar.getDate());\r
+\r
+                // Update text field (a must when not immediate).\r
+                buildDate(true);\r
+\r
+                closeCalendarPanel();\r
+            }\r
+\r
+            public void onCancel() {\r
+                closeCalendarPanel();\r
+            }\r
+        });\r
+\r
+        popup = new VOverlay(true, true, true);\r
+        popup.setStyleName(POPUP_PRIMARY_STYLE_NAME);\r
+        popup.setWidget(calendar);\r
+        popup.addCloseHandler(this);\r
+\r
+        DOM.setElementProperty(calendar.getElement(), "id",\r
+                "PID_VAADIN_POPUPCAL");\r
+\r
+        sinkEvents(Event.ONKEYDOWN);\r
+\r
+    }\r
+\r
+    @SuppressWarnings("deprecation")\r
+    private void updateValue(Date newDate) {\r
+        Date currentDate = getCurrentDate();\r
+        if (currentDate == null || newDate.getTime() != currentDate.getTime()) {\r
+            setCurrentDate((Date) newDate.clone());\r
+            getClient().updateVariable(getId(), "year",\r
+                    newDate.getYear() + 1900, false);\r
+            if (getCurrentResolution() > VDateField.RESOLUTION_YEAR) {\r
+                getClient().updateVariable(getId(), "month",\r
+                        newDate.getMonth() + 1, false);\r
+                if (getCurrentResolution() > RESOLUTION_MONTH) {\r
+                    getClient().updateVariable(getId(), "day",\r
+                            newDate.getDate(), false);\r
+                    if (getCurrentResolution() > RESOLUTION_DAY) {\r
+                        getClient().updateVariable(getId(), "hour",\r
+                                newDate.getHours(), false);\r
+                        if (getCurrentResolution() > RESOLUTION_HOUR) {\r
+                            getClient().updateVariable(getId(), "min",\r
+                                    newDate.getMinutes(), false);\r
+                            if (getCurrentResolution() > RESOLUTION_MIN) {\r
+                                getClient().updateVariable(getId(), "sec",\r
+                                        newDate.getSeconds(), false);\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            if (isImmediate()) {\r
+                getClient().sendPendingVariableChanges();\r
+            }\r
+        }\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * com.vaadin.terminal.gwt.client.ui.VTextualDate#updateFromUIDL(com.vaadin\r
+     * .terminal.gwt.client.UIDL,\r
+     * com.vaadin.terminal.gwt.client.ApplicationConnection)\r
+     */\r
+    @Override\r
+    @SuppressWarnings("deprecation")\r
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+        boolean lastReadOnlyState = readonly;\r
+        boolean lastEnabledState = isEnabled();\r
+\r
+        parsable = uidl.getBooleanAttribute("parsable");\r
+\r
+        super.updateFromUIDL(uidl, client);\r
+\r
+        String popupStyleNames = ApplicationConnection.getStyleName(\r
+                POPUP_PRIMARY_STYLE_NAME, uidl, false);\r
+        popupStyleNames += " " + VDateField.CLASSNAME + "-"\r
+                + resolutionToString(currentResolution);\r
+        popup.setStyleName(popupStyleNames);\r
+\r
+        calendar.setDateTimeService(getDateTimeService());\r
+        calendar.setShowISOWeekNumbers(isShowISOWeekNumbers());\r
+        if (calendar.getResolution() != currentResolution) {\r
+            calendar.setResolution(currentResolution);\r
+            if (calendar.getDate() != null) {\r
+                calendar.setDate((Date) getCurrentDate().clone());\r
+                // force re-render when changing resolution only\r
+                calendar.renderCalendar();\r
+            }\r
+        }\r
+        calendarToggle.setEnabled(enabled);\r
+\r
+        if (currentResolution <= RESOLUTION_MONTH) {\r
+            calendar.setFocusChangeListener(new FocusChangeListener() {\r
+                public void focusChanged(Date date) {\r
+                    updateValue(date);\r
+                    buildDate();\r
+                    Date date2 = calendar.getDate();\r
+                    date2.setYear(date.getYear());\r
+                    date2.setMonth(date.getMonth());\r
+                }\r
+            });\r
+        } else {\r
+            calendar.setFocusChangeListener(null);\r
+        }\r
+\r
+        if (currentResolution > RESOLUTION_DAY) {\r
+            calendar.setTimeChangeListener(new TimeChangeListener() {\r
+                public void changed(int hour, int min, int sec, int msec) {\r
+                    Date d = getDate();\r
+                    if (d == null) {\r
+                        // date currently null, use the value from calendarPanel\r
+                        // (~ client time at the init of the widget)\r
+                        d = (Date) calendar.getDate().clone();\r
+                    }\r
+                    d.setHours(hour);\r
+                    d.setMinutes(min);\r
+                    d.setSeconds(sec);\r
+                    DateTimeService.setMilliseconds(d, msec);\r
+\r
+                    // Always update time changes to the server\r
+                    updateValue(d);\r
+\r
+                    // Update text field\r
+                    buildDate();\r
+                }\r
+            });\r
+        }\r
+\r
+        if (readonly) {\r
+            calendarToggle.addStyleName(CLASSNAME + "-button-readonly");\r
+        } else {\r
+            calendarToggle.removeStyleName(CLASSNAME + "-button-readonly");\r
+        }\r
+\r
+        if (lastReadOnlyState != readonly || lastEnabledState != isEnabled()) {\r
+            // Enabled or readonly state changed. Differences in theming might\r
+            // affect the width (for instance if the popup button is hidden) so\r
+            // we have to recalculate the width (IF the width of the field is\r
+            // fixed)\r
+            updateWidth();\r
+        }\r
+\r
+        calendarToggle.setEnabled(true);\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * com.google.gwt.user.client.ui.UIObject#setStyleName(java.lang.String)\r
+     */\r
+    @Override\r
+    public void setStyleName(String style) {\r
+        // make sure the style is there before size calculation\r
+        super.setStyleName(style + " " + CLASSNAME + "-popupcalendar");\r
+    }\r
+\r
+    /**\r
+     * Opens the calendar panel popup\r
+     */\r
+    public void openCalendarPanel() {\r
+\r
+        if (!open && !readonly) {\r
+            open = true;\r
+\r
+            if (getCurrentDate() != null) {\r
+                calendar.setDate((Date) getCurrentDate().clone());\r
+            } else {\r
+                calendar.setDate(new Date());\r
+            }\r
+\r
+            // clear previous values\r
+            popup.setWidth("");\r
+            popup.setHeight("");\r
+            popup.setPopupPositionAndShow(new PositionCallback() {\r
+                public void setPosition(int offsetWidth, int offsetHeight) {\r
+                    final int w = offsetWidth;\r
+                    final int h = offsetHeight;\r
+                    final int browserWindowWidth = Window.getClientWidth()\r
+                            + Window.getScrollLeft();\r
+                    final int browserWindowHeight = Window.getClientHeight()\r
+                            + Window.getScrollTop();\r
+                    int t = calendarToggle.getAbsoluteTop();\r
+                    int l = calendarToggle.getAbsoluteLeft();\r
+\r
+                    // Add a little extra space to the right to avoid\r
+                    // problems with IE7 scrollbars and to make it look\r
+                    // nicer.\r
+                    int extraSpace = 30;\r
+\r
+                    boolean overflowRight = false;\r
+                    if (l + +w + extraSpace > browserWindowWidth) {\r
+                        overflowRight = true;\r
+                        // Part of the popup is outside the browser window\r
+                        // (to the right)\r
+                        l = browserWindowWidth - w - extraSpace;\r
+                    }\r
+\r
+                    if (t + h + calendarToggle.getOffsetHeight() + 30 > browserWindowHeight) {\r
+                        // Part of the popup is outside the browser window\r
+                        // (below)\r
+                        t = browserWindowHeight - h\r
+                                - calendarToggle.getOffsetHeight() - 30;\r
+                        if (!overflowRight) {\r
+                            // Show to the right of the popup button unless we\r
+                            // are in the lower right corner of the screen\r
+                            l += calendarToggle.getOffsetWidth();\r
+                        }\r
+                    }\r
+\r
+                    // fix size\r
+                    popup.setWidth(w + "px");\r
+                    popup.setHeight(h + "px");\r
+\r
+                    popup.setPopupPosition(l,\r
+                            t + calendarToggle.getOffsetHeight() + 2);\r
+\r
+                    /*\r
+                     * We have to wait a while before focusing since the popup\r
+                     * needs to be opened before we can focus\r
+                     */\r
+                    Timer focusTimer = new Timer() {\r
+                        @Override\r
+                        public void run() {\r
+                            setFocus(true);\r
+                        }\r
+                    };\r
+\r
+                    focusTimer.schedule(100);\r
+                }\r
+            });\r
+        } else {\r
+            VConsole.error("Cannot reopen popup, it is already open!");\r
+        }\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event\r
+     * .dom.client.ClickEvent)\r
+     */\r
+    public void onClick(ClickEvent event) {\r
+        if (event.getSource() == calendarToggle && isEnabled()) {\r
+            openCalendarPanel();\r
+        }\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * com.google.gwt.event.logical.shared.CloseHandler#onClose(com.google.gwt\r
+     * .event.logical.shared.CloseEvent)\r
+     */\r
+    public void onClose(CloseEvent<PopupPanel> event) {\r
+        if (event.getSource() == popup) {\r
+            buildDate();\r
+            if (!BrowserInfo.get().isTouchDevice()) {\r
+                /*\r
+                 * Move focus to textbox, unless on touch device (avoids opening\r
+                 * virtual keyboard).\r
+                 */\r
+                focus();\r
+            }\r
+\r
+            // TODO resolve what the "Sigh." is all about and document it here\r
+            // Sigh.\r
+            Timer t = new Timer() {\r
+                @Override\r
+                public void run() {\r
+                    open = false;\r
+                }\r
+            };\r
+            t.schedule(100);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Sets focus to Calendar panel.\r
+     * \r
+     * @param focus\r
+     */\r
+    public void setFocus(boolean focus) {\r
+        calendar.setFocus(focus);\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#getFieldExtraWidth()\r
+     */\r
+    @Override\r
+    protected int getFieldExtraWidth() {\r
+        if (fieldExtraWidth < 0) {\r
+            fieldExtraWidth = super.getFieldExtraWidth();\r
+            fieldExtraWidth += calendarToggle.getOffsetWidth();\r
+        }\r
+        return fieldExtraWidth;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see com.vaadin.terminal.gwt.client.ui.VTextualDate#buildDate()\r
+     */\r
+    @Override\r
+    protected void buildDate() {\r
+        // Save previous value\r
+        String previousValue = getText();\r
+        super.buildDate();\r
+\r
+        // Restore previous value if the input could not be parsed\r
+        if (!parsable) {\r
+            setText(previousValue);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Update the text field contents from the date. See {@link #buildDate()}.\r
+     * \r
+     * @param forceValid\r
+     *            true to force the text field to be updated, false to only\r
+     *            update if the parsable flag is true.\r
+     */\r
+    protected void buildDate(boolean forceValid) {\r
+        if (forceValid) {\r
+            parsable = true;\r
+        }\r
+        buildDate();\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * com.vaadin.terminal.gwt.client.ui.VDateField#onBrowserEvent(com.google\r
+     * .gwt.user.client.Event)\r
+     */\r
+    @Override\r
+    public void onBrowserEvent(com.google.gwt.user.client.Event event) {\r
+        super.onBrowserEvent(event);\r
+        if (DOM.eventGetType(event) == Event.ONKEYDOWN\r
+                && event.getKeyCode() == getOpenCalenderPanelKey()) {\r
+            openCalendarPanel();\r
+            event.preventDefault();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Get the key code that opens the calendar panel. By default it is the down\r
+     * key but you can override this to be whatever you like\r
+     * \r
+     * @return\r
+     */\r
+    protected int getOpenCalenderPanelKey() {\r
+        return KeyCodes.KEY_DOWN;\r
+    }\r
+\r
+    /**\r
+     * Closes the open popup panel\r
+     */\r
+    public void closeCalendarPanel() {\r
+        if (open) {\r
+            popup.hide(true);\r
+        }\r
+    }\r
+\r
+    private final String CALENDAR_TOGGLE_ID = "popupButton";\r
+\r
+    @Override\r
+    public Element getSubPartElement(String subPart) {\r
+        if (subPart.equals(CALENDAR_TOGGLE_ID)) {\r
+            return calendarToggle.getElement();\r
+        }\r
+\r
+        return super.getSubPartElement(subPart);\r
+    }\r
+\r
+    @Override\r
+    public String getSubPartName(Element subElement) {\r
+        if (calendarToggle.getElement().isOrHasChild(subElement)) {\r
+            return CALENDAR_TOGGLE_ID;\r
+        }\r
+\r
+        return super.getSubPartName(subElement);\r
+    }\r
+\r
+}\r
index 736635ecd0c32236be316a499d8ab2a7fcbac091..de68ae96a4f54d09663f12f3c9d48b062987be64 100644 (file)
@@ -52,6 +52,7 @@ import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.Timer;
 import com.google.gwt.user.client.Window;
 import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HasWidgets;
 import com.google.gwt.user.client.ui.Panel;
 import com.google.gwt.user.client.ui.RootPanel;
 import com.google.gwt.user.client.ui.UIObject;
@@ -103,17 +104,31 @@ import com.vaadin.terminal.gwt.client.ui.label.VLabel;
  * 
  * TODO implement unregistering for child components in Cells
  */
-public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
-        VHasDropHandler, FocusHandler, BlurHandler, Focusable, ActionOwner {
+public class VScrollTable extends FlowPanel implements HasWidgets,
+        ScrollHandler, VHasDropHandler, FocusHandler, BlurHandler, Focusable,
+        ActionOwner {
 
-    public static final String ATTRIBUTE_PAGEBUFFER_FIRST = "pb-ft";
-    public static final String ATTRIBUTE_PAGEBUFFER_LAST = "pb-l";
+    public enum SelectMode {
+        NONE(0), SINGLE(1), MULTI(2);
+        private int id;
+
+        private SelectMode(int id) {
+            this.id = id;
+        }
+
+        public int getId() {
+            return id;
+        }
+    }
 
     private static final String ROW_HEADER_COLUMN_KEY = "0";
 
     public static final String CLASSNAME = "v-table";
     public static final String CLASSNAME_SELECTION_FOCUS = CLASSNAME + "-focus";
 
+    public static final String ATTRIBUTE_PAGEBUFFER_FIRST = "pb-ft";
+    public static final String ATTRIBUTE_PAGEBUFFER_LAST = "pb-l";
+
     public static final String ITEM_CLICK_EVENT_ID = "itemClick";
     public static final String HEADER_CLICK_EVENT_ID = "handleHeaderClick";
     public static final String FOOTER_CLICK_EVENT_ID = "handleFooterClick";
@@ -162,10 +177,10 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
     protected ApplicationConnection client;
     protected String paintableId;
 
-    private boolean immediate;
+    boolean immediate;
     private boolean nullSelectionAllowed = true;
 
-    private int selectMode = Table.SELECT_MODE_NONE;
+    private SelectMode selectMode = SelectMode.NONE;
 
     private final HashSet<String> selectedRowKeys = new HashSet<String>();
 
@@ -178,15 +193,15 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
     /*
      * These are used when jumping between pages when pressing Home and End
      */
-    private boolean selectLastItemInNextRender = false;
-    private boolean selectFirstItemInNextRender = false;
-    private boolean focusFirstItemInNextRender = false;
-    private boolean focusLastItemInNextRender = false;
+    boolean selectLastItemInNextRender = false;
+    boolean selectFirstItemInNextRender = false;
+    boolean focusFirstItemInNextRender = false;
+    boolean focusLastItemInNextRender = false;
 
     /*
      * The currently focused row
      */
-    private VScrollTableRow focusedRow;
+    VScrollTableRow focusedRow;
 
     /*
      * Helper to store selection range start in when using the keyboard
@@ -197,7 +212,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
      * Flag for notifying when the selection has changed and should be sent to
      * the server
      */
-    private boolean selectionChanged = false;
+    boolean selectionChanged = false;
 
     /*
      * The speed (in pixels) which the scrolling scrolls vertically/horizontally
@@ -206,7 +221,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
     private Timer scrollingVelocityTimer = null;
 
-    private String[] bodyActionKeys;
+    String[] bodyActionKeys;
 
     private boolean enableDebug = false;
 
@@ -282,19 +297,18 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
     private final HashSet<SelectionRange> selectedRowRanges = new HashSet<SelectionRange>();
 
-    private boolean initializedAndAttached = false;
+    boolean initializedAndAttached = false;
 
     /**
      * Flag to indicate if a column width recalculation is needed due update.
      */
-    private boolean headerChangedDuringUpdate = false;
+    boolean headerChangedDuringUpdate = false;
 
     protected final TableHead tHead = new TableHead();
 
-    private final TableFooter tFoot = new TableFooter();
+    final TableFooter tFoot = new TableFooter();
 
-    private final FocusableScrollPanel scrollBodyPanel = new FocusableScrollPanel(
-            true);
+    final FocusableScrollPanel scrollBodyPanel = new FocusableScrollPanel(true);
 
     private KeyPressHandler navKeyPressHandler = new KeyPressHandler() {
         public void onKeyPress(KeyPressEvent keyPressEvent) {
@@ -383,12 +397,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
             }
         }
     };
-    private int totalRows;
+    int totalRows;
 
     private Set<String> collapsedColumns;
 
-    private final RowRequestHandler rowRequestHandler;
-    private VScrollTableBody scrollBody;
+    final RowRequestHandler rowRequestHandler;
+    VScrollTableBody scrollBody;
     private int firstvisible = 0;
     private boolean sortAscending;
     private String sortColumn;
@@ -403,9 +417,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
     private String[] visibleColOrder;
     private boolean initialContentReceived = false;
     private Element scrollPositionElement;
-    private boolean enabled;
-    private boolean showColHeaders;
-    private boolean showColFooters;
+    boolean enabled;
+    boolean showColHeaders;
+    boolean showColFooters;
 
     /** flag to indicate that table body has changed */
     private boolean isNewBody = true;
@@ -420,15 +434,15 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
     private final ArrayList<Panel> lazyUnregistryBag = new ArrayList<Panel>();
     private String height;
     private String width = "";
-    private boolean rendering = false;
+    boolean rendering = false;
     private boolean hasFocus = false;
     private int dragmode;
 
     private int multiselectmode;
-    private int tabIndex;
+    int tabIndex;
     private TouchScrollDelegate touchScrollDelegate;
 
-    private int lastRenderedHeight;
+    int lastRenderedHeight;
 
     /**
      * Values (serverCacheFirst+serverCacheLast) sent by server that tells which
@@ -442,8 +456,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
      * scrolling in the client will cause empty buttons to be rendered
      * (cached=true request for non-existing components)
      */
-    private int serverCacheFirst = -1;
-    private int serverCacheLast = -1;
+    int serverCacheFirst = -1;
+    int serverCacheLast = -1;
 
     public VScrollTable() {
         setMultiSelectMode(MULTISELECT_MODE_DEFAULT);
@@ -810,211 +824,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         return KeyCodes.KEY_END;
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal
-     * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)
-     */
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-        rendering = true;
-
-        if (uidl.hasAttribute(ATTRIBUTE_PAGEBUFFER_FIRST)) {
-            serverCacheFirst = uidl.getIntAttribute(ATTRIBUTE_PAGEBUFFER_FIRST);
-            serverCacheLast = uidl.getIntAttribute(ATTRIBUTE_PAGEBUFFER_LAST);
-        } else {
-            serverCacheFirst = -1;
-            serverCacheLast = -1;
-        }
-        /*
-         * We need to do this before updateComponent since updateComponent calls
-         * this.setHeight() which will calculate a new body height depending on
-         * the space available.
-         */
-        if (uidl.hasAttribute("colfooters")) {
-            showColFooters = uidl.getBooleanAttribute("colfooters");
-        }
-
-        tFoot.setVisible(showColFooters);
-
-        if (client.updateComponent(this, uidl, true)) {
-            rendering = false;
-            return;
-        }
-
-        enabled = !uidl.hasAttribute("disabled");
-
-        if (BrowserInfo.get().isIE8() && !enabled) {
-            /*
-             * The disabled shim will not cover the table body if it is relative
-             * in IE8. See #7324
-             */
-            scrollBodyPanel.getElement().getStyle()
-                    .setPosition(Position.STATIC);
-        } else if (BrowserInfo.get().isIE8()) {
-            scrollBodyPanel.getElement().getStyle()
-                    .setPosition(Position.RELATIVE);
-        }
-
-        this.client = client;
-        paintableId = uidl.getStringAttribute("id");
-        immediate = uidl.getBooleanAttribute("immediate");
-
-        int previousTotalRows = totalRows;
-        updateTotalRows(uidl);
-        boolean totalRowsChanged = (totalRows != previousTotalRows);
-
-        updateDragMode(uidl);
-
-        updateSelectionProperties(uidl);
-
-        if (uidl.hasAttribute("alb")) {
-            bodyActionKeys = uidl.getStringArrayAttribute("alb");
-        } else {
-            // Need to clear the actions if the action handlers have been
-            // removed
-            bodyActionKeys = null;
-        }
-
-        setCacheRateFromUIDL(uidl);
-
-        recalcWidths = uidl.hasAttribute("recalcWidths");
-        if (recalcWidths) {
-            tHead.clear();
-            tFoot.clear();
-        }
-
-        updatePageLength(uidl);
-
-        updateFirstVisibleAndScrollIfNeeded(uidl);
-
-        showRowHeaders = uidl.getBooleanAttribute("rowheaders");
-        showColHeaders = uidl.getBooleanAttribute("colheaders");
-
-        updateSortingProperties(uidl);
-
-        boolean keyboardSelectionOverRowFetchInProgress = selectSelectedRows(uidl);
-
-        updateActionMap(uidl);
-
-        updateColumnProperties(uidl);
-
-        UIDL ac = uidl.getChildByTagName("-ac");
-        if (ac == null) {
-            if (dropHandler != null) {
-                // remove dropHandler if not present anymore
-                dropHandler = null;
-            }
-        } else {
-            if (dropHandler == null) {
-                dropHandler = new VScrollTableDropHandler();
-            }
-            dropHandler.updateAcceptRules(ac);
-        }
-
-        UIDL partialRowAdditions = uidl.getChildByTagName("prows");
-        UIDL partialRowUpdates = uidl.getChildByTagName("urows");
-        if (partialRowUpdates != null || partialRowAdditions != null) {
-            // we may have pending cache row fetch, cancel it. See #2136
-            rowRequestHandler.cancel();
-
-            updateRowsInBody(partialRowUpdates);
-            addAndRemoveRows(partialRowAdditions);
-        } else {
-            UIDL rowData = uidl.getChildByTagName("rows");
-            if (rowData != null) {
-                // we may have pending cache row fetch, cancel it. See #2136
-                rowRequestHandler.cancel();
-
-                if (!recalcWidths && initializedAndAttached) {
-                    updateBody(rowData, uidl.getIntAttribute("firstrow"),
-                            uidl.getIntAttribute("rows"));
-                    if (headerChangedDuringUpdate) {
-                        triggerLazyColumnAdjustment(true);
-                    } else if (!isScrollPositionVisible()
-                            || totalRowsChanged
-                            || lastRenderedHeight != scrollBody
-                                    .getOffsetHeight()) {
-                        // webkits may still bug with their disturbing scrollbar
-                        // bug, see #3457
-                        // Run overflow fix for the scrollable area
-                        // #6698 - If there's a scroll going on, don't abort it
-                        // by changing overflows as the length of the contents
-                        // *shouldn't* have changed (unless the number of rows
-                        // or the height of the widget has also changed)
-                        Scheduler.get().scheduleDeferred(new Command() {
-                            public void execute() {
-                                Util.runWebkitOverflowAutoFix(scrollBodyPanel
-                                        .getElement());
-                            }
-                        });
-                    }
-                } else {
-                    initializeRows(uidl, rowData);
-                }
-            }
-        }
-
-        if (!isSelectable()) {
-            scrollBody.addStyleName(CLASSNAME + "-body-noselection");
-        } else {
-            scrollBody.removeStyleName(CLASSNAME + "-body-noselection");
-        }
-
-        hideScrollPositionAnnotation();
-        purgeUnregistryBag();
-
-        // selection is no in sync with server, avoid excessive server visits by
-        // clearing to flag used during the normal operation
-        if (!keyboardSelectionOverRowFetchInProgress) {
-            selectionChanged = false;
-        }
-
-        /*
-         * This is called when the Home or page up button has been pressed in
-         * selectable mode and the next selected row was not yet rendered in the
-         * client
-         */
-        if (selectFirstItemInNextRender || focusFirstItemInNextRender) {
-            selectFirstRenderedRowInViewPort(focusFirstItemInNextRender);
-            selectFirstItemInNextRender = focusFirstItemInNextRender = false;
-        }
-
-        /*
-         * This is called when the page down or end button has been pressed in
-         * selectable mode and the next selected row was not yet rendered in the
-         * client
-         */
-        if (selectLastItemInNextRender || focusLastItemInNextRender) {
-            selectLastRenderedRowInViewPort(focusLastItemInNextRender);
-            selectLastItemInNextRender = focusLastItemInNextRender = false;
-        }
-        multiselectPending = false;
-
-        if (focusedRow != null) {
-            if (!focusedRow.isAttached() && !rowRequestHandler.isRunning()) {
-                // focused row has been orphaned, can't focus
-                focusRowFromBody();
-            }
-        }
-
-        tabIndex = uidl.hasAttribute("tabindex") ? uidl
-                .getIntAttribute("tabindex") : 0;
-        setProperTabIndex();
-
-        resizeSortedColumnForSortIndicator();
-
-        // Remember this to detect situations where overflow hack might be
-        // needed during scrolling
-        lastRenderedHeight = scrollBody.getOffsetHeight();
-
-        rendering = false;
-        headerChangedDuringUpdate = false;
-
-    }
-
-    private void initializeRows(UIDL uidl, UIDL rowData) {
+    void initializeRows(UIDL uidl, UIDL rowData) {
         if (scrollBody != null) {
             scrollBody.removeFromParent();
             lazyUnregistryBag.add(scrollBody);
@@ -1037,7 +847,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         scrollBody.restoreRowVisibility();
     }
 
-    private void updateColumnProperties(UIDL uidl) {
+    void updateColumnProperties(UIDL uidl) {
         updateColumnOrder(uidl);
 
         updateCollapsedColumns(uidl);
@@ -1072,7 +882,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         }
     }
 
-    private boolean selectSelectedRows(UIDL uidl) {
+    boolean selectSelectedRows(UIDL uidl) {
         boolean keyboardSelectionOverRowFetchInProgress = false;
 
         if (uidl.hasVariable("selected")) {
@@ -1109,7 +919,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         return keyboardSelectionOverRowFetchInProgress;
     }
 
-    private void updateSortingProperties(UIDL uidl) {
+    void updateSortingProperties(UIDL uidl) {
         oldSortColumn = sortColumn;
         if (uidl.hasVariable("sortascending")) {
             sortAscending = uidl.getBooleanVariable("sortascending");
@@ -1117,7 +927,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         }
     }
 
-    private void resizeSortedColumnForSortIndicator() {
+    void resizeSortedColumnForSortIndicator() {
         // Force recalculation of the captionContainer element inside the header
         // cell to accomodate for the size of the sort arrow.
         HeaderCell sortedHeader = tHead.getHeaderCell(sortColumn);
@@ -1132,7 +942,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         }
     }
 
-    private void updateFirstVisibleAndScrollIfNeeded(UIDL uidl) {
+    void updateFirstVisibleAndScrollIfNeeded(UIDL uidl) {
         firstvisible = uidl.hasVariable("firstvisible") ? uidl
                 .getIntVariable("firstvisible") : 0;
         if (firstvisible != lastRequestedFirstvisible && scrollBody != null) {
@@ -1147,7 +957,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         return (int) (rowIx * scrollBody.getRowHeight());
     }
 
-    private void updatePageLength(UIDL uidl) {
+    void updatePageLength(UIDL uidl) {
         int oldPageLength = pageLength;
         if (uidl.hasAttribute("pagelength")) {
             pageLength = uidl.getIntAttribute("pagelength");
@@ -1162,7 +972,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         }
     }
 
-    private void updateSelectionProperties(UIDL uidl) {
+    void updateSelectionProperties(UIDL uidl) {
         setMultiSelectMode(uidl.hasAttribute("multiselectmode") ? uidl
                 .getIntAttribute("multiselectmode") : MULTISELECT_MODE_DEFAULT);
 
@@ -1171,18 +981,18 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
         if (uidl.hasAttribute("selectmode")) {
             if (uidl.getBooleanAttribute("readonly")) {
-                selectMode = Table.SELECT_MODE_NONE;
+                selectMode = SelectMode.NONE;
             } else if (uidl.getStringAttribute("selectmode").equals("multi")) {
-                selectMode = Table.SELECT_MODE_MULTI;
+                selectMode = SelectMode.MULTI;
             } else if (uidl.getStringAttribute("selectmode").equals("single")) {
-                selectMode = Table.SELECT_MODE_SINGLE;
+                selectMode = SelectMode.SINGLE;
             } else {
-                selectMode = Table.SELECT_MODE_NONE;
+                selectMode = SelectMode.NONE;
             }
         }
     }
 
-    private void updateDragMode(UIDL uidl) {
+    void updateDragMode(UIDL uidl) {
         dragmode = uidl.hasAttribute("dragmode") ? uidl
                 .getIntAttribute("dragmode") : 0;
         if (BrowserInfo.get().isIE()) {
@@ -1219,7 +1029,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         return totalRows;
     }
 
-    private void focusRowFromBody() {
+    void focusRowFromBody() {
         if (selectedRowKeys.size() == 1) {
             // try to focus a row currently selected and in viewport
             String selectedRowKey = selectedRowKeys.iterator().next();
@@ -1247,7 +1057,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
      * @param focusOnly
      *            Should the focus only be moved to the last row
      */
-    private void selectLastRenderedRowInViewPort(boolean focusOnly) {
+    void selectLastRenderedRowInViewPort(boolean focusOnly) {
         int index = firstRowInViewPort + getFullyVisibleRowCount();
         VScrollTableRow lastRowInViewport = scrollBody.getRowByRowIndex(index);
         if (lastRowInViewport == null) {
@@ -1272,7 +1082,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
      * @param focusOnly
      *            Should the focus only be moved to the first row
      */
-    private void selectFirstRenderedRowInViewPort(boolean focusOnly) {
+    void selectFirstRenderedRowInViewPort(boolean focusOnly) {
         int index = firstRowInViewPort;
         VScrollTableRow firstInViewport = scrollBody.getRowByRowIndex(index);
         if (firstInViewport == null) {
@@ -1286,7 +1096,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         }
     }
 
-    private void setCacheRateFromUIDL(UIDL uidl) {
+    void setCacheRateFromUIDL(UIDL uidl) {
         setCacheRate(uidl.hasAttribute("cr") ? uidl.getDoubleAttribute("cr")
                 : CACHE_RATE_DEFAULT);
     }
@@ -1303,7 +1113,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
      * IScrollTableRows). This is done lazily as Table must survive from
      * "subtreecaching" logic.
      */
-    private void purgeUnregistryBag() {
+    void purgeUnregistryBag() {
         for (Iterator<Panel> iterator = lazyUnregistryBag.iterator(); iterator
                 .hasNext();) {
             VPaintableMap.get(client)
@@ -1312,7 +1122,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         lazyUnregistryBag.clear();
     }
 
-    private void updateActionMap(UIDL mainUidl) {
+    void updateActionMap(UIDL mainUidl) {
         UIDL actionsUidl = mainUidl.getChildByTagName("actions");
         if (actionsUidl == null) {
             return;
@@ -1414,7 +1224,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
      * @param reqRows
      *            amount of rows in data set
      */
-    private void updateBody(UIDL uidl, int firstRow, int reqRows) {
+    void updateBody(UIDL uidl, int firstRow, int reqRows) {
         if (uidl == null || reqRows < 1) {
             // container is empty, remove possibly existing rows
             if (firstRow <= 0) {
@@ -1431,7 +1241,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         discardRowsOutsideCacheWindow();
     }
 
-    private void updateRowsInBody(UIDL partialRowUpdates) {
+    void updateRowsInBody(UIDL partialRowUpdates) {
         if (partialRowUpdates == null) {
             return;
         }
@@ -1564,20 +1374,20 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
     }
 
     private boolean isMultiSelectModeSimple() {
-        return selectMode == Table.SELECT_MODE_MULTI
+        return selectMode == SelectMode.MULTI
                 && multiselectmode == MULTISELECT_MODE_SIMPLE;
     }
 
     private boolean isSingleSelectMode() {
-        return selectMode == Table.SELECT_MODE_SINGLE;
+        return selectMode == SelectMode.SINGLE;
     }
 
     private boolean isMultiSelectModeAny() {
-        return selectMode == Table.SELECT_MODE_MULTI;
+        return selectMode == SelectMode.MULTI;
     }
 
     private boolean isMultiSelectModeDefault() {
-        return selectMode == Table.SELECT_MODE_MULTI
+        return selectMode == SelectMode.MULTI
                 && multiselectmode == MULTISELECT_MODE_DEFAULT;
     }
 
@@ -1593,7 +1403,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
     }
 
     protected boolean isSelectable() {
-        return selectMode > Table.SELECT_MODE_NONE;
+        return selectMode.getId() > SelectMode.NONE.getId();
     }
 
     private boolean isCollapsedColumn(String colKey) {
@@ -1769,7 +1579,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
             }
         }
         client.updateVariable(paintableId, "columnorder", columnOrder, false);
-        if (client.hasEventListeners(this, COLUMN_REORDER_EVENT_ID)) {
+        if (client.hasWidgetEventListeners(this, COLUMN_REORDER_EVENT_ID)) {
             client.sendPendingVariableChanges();
         }
     }
@@ -2108,19 +1918,19 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
         style.setDisplay(Display.BLOCK);
     }
 
-    private void hideScrollPositionAnnotation() {
+    void hideScrollPositionAnnotation() {
         if (scrollPositionElement != null) {
             DOM.setStyleAttribute(scrollPositionElement, "display", "none");
         }
     }
 
-    private boolean isScrollPositionVisible() {
+    boolean isScrollPositionVisible() {
         return scrollPositionElement != null
                 && !scrollPositionElement.getStyle().getDisplay()
                         .equals(Display.NONE.toString());
     }
 
-    private class RowRequestHandler extends Timer {
+    class RowRequestHandler extends Timer {
 
         private int reqFirstRow = 0;
         private int reqRows = 0;
@@ -2295,26 +2105,16 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
          * of the caption container element by the correct amount
          */
         public void resizeCaptionContainer(int rightSpacing) {
+            int captionContainerWidth = width
+                    - colResizeWidget.getOffsetWidth() - rightSpacing;
+
             if (td.getClassName().contains("-asc")
                     || td.getClassName().contains("-desc")) {
-                /*
-                 * Room for the sort indicator is made by subtracting the styled
-                 * margin and width of the resizer from the width of the caption
-                 * container.
-                 */
-                int captionContainerWidth = width
-                        - sortIndicator.getOffsetWidth()
-                        - colResizeWidget.getOffsetWidth() - rightSpacing;
-                captionContainer.getStyle().setPropertyPx("width",
-                        captionContainerWidth);
-            } else {
-                /*
-                 * Set the caption container element as wide as possible when
-                 * the sorting indicator is not visible.
-                 */
-                captionContainer.getStyle().setPropertyPx("width",
-                        width - rightSpacing);
+                // Leave room for the sort indicator
+                captionContainerWidth -= sortIndicator.getOffsetWidth();
             }
+            captionContainer.getStyle().setPropertyPx("width",
+                    captionContainerWidth);
 
             // Apply/Remove spacing if defined
             if (rightSpacing > 0) {
@@ -2512,7 +2312,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
          *            The click event
          */
         private void fireHeaderClickedEvent(Event event) {
-            if (client.hasEventListeners(VScrollTable.this,
+            if (client.hasWidgetEventListeners(VScrollTable.this,
                     HEADER_CLICK_EVENT_ID)) {
                 MouseEventDetails details = new MouseEventDetails(event);
                 client.updateVariable(paintableId, "headerClickEvent",
@@ -3543,7 +3343,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
          *            The click event
          */
         private void fireFooterClickedEvent(Event event) {
-            if (client.hasEventListeners(VScrollTable.this,
+            if (client.hasWidgetEventListeners(VScrollTable.this,
                     FOOTER_CLICK_EVENT_ID)) {
                 MouseEventDetails details = new MouseEventDetails(event);
                 client.updateVariable(paintableId, "footerClickEvent",
@@ -4295,12 +4095,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
             final VScrollTableRow toBeRemoved = (VScrollTableRow) renderedRows
                     .get(index);
             // Unregister row tooltip
-            client.registerTooltip(VScrollTable.this, toBeRemoved.getElement(),
-                    null);
+            client.registerWidgetTooltip(VScrollTable.this,
+                    toBeRemoved.getElement(), null);
             for (int i = 0; i < toBeRemoved.getElement().getChildCount(); i++) {
                 // Unregister cell tooltips
                 Element td = toBeRemoved.getElement().getChild(i).cast();
-                client.registerTooltip(VScrollTable.this, td, null);
+                client.registerWidgetTooltip(VScrollTable.this, td, null);
             }
             lazyUnregistryBag.add(toBeRemoved);
             tBodyElement.removeChild(toBeRemoved.getElement());
@@ -4559,10 +4359,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 String rowDescription = uidl.getStringAttribute("rowdescr");
                 if (rowDescription != null && !rowDescription.equals("")) {
                     TooltipInfo info = new TooltipInfo(rowDescription);
-                    client.registerTooltip(VScrollTable.this, rowElement, info);
+                    client.registerWidgetTooltip(VScrollTable.this, rowElement,
+                            info);
                 } else {
                     // Remove possibly previously set tooltip
-                    client.registerTooltip(VScrollTable.this, rowElement, null);
+                    client.registerWidgetTooltip(VScrollTable.this, rowElement,
+                            null);
                 }
 
                 tHead.getColumnAlignments();
@@ -4797,10 +4599,10 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
                 if (description != null && !description.equals("")) {
                     TooltipInfo info = new TooltipInfo(description);
-                    client.registerTooltip(VScrollTable.this, td, info);
+                    client.registerWidgetTooltip(VScrollTable.this, td, info);
                 } else {
                     // Remove possibly previously set tooltip
-                    client.registerTooltip(VScrollTable.this, td, null);
+                    client.registerWidgetTooltip(VScrollTable.this, td, null);
                 }
 
                 td.appendChild(container);
@@ -4879,7 +4681,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
              */
             private boolean handleClickEvent(Event event, Element targetTdOrTr,
                     boolean immediate) {
-                if (!client.hasEventListeners(VScrollTable.this,
+                if (!client.hasWidgetEventListeners(VScrollTable.this,
                         ITEM_CLICK_EVENT_ID)) {
                     // Don't send an event if nobody is listening
                     return false;
@@ -4923,22 +4725,24 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
                     if (!containsWidget) {
                         // Only text nodes has tooltips
-                        if (client.getTooltipTitleInfo(VScrollTable.this,
-                                target) != null) {
+                        if (VPaintableMap.get(client).getWidgetTooltipInfo(
+                                VScrollTable.this, target) != null) {
                             // Cell has description, use it
-                            client.handleTooltipEvent(event, VScrollTable.this,
-                                    target);
+                            client.handleWidgetTooltipEvent(event,
+                                    VScrollTable.this, target);
                         } else {
                             // Cell might have row description, use row
                             // description
-                            client.handleTooltipEvent(event, VScrollTable.this,
+                            client.handleWidgetTooltipEvent(event,
+                                    VScrollTable.this,
                                     target.getParentElement());
                         }
                     }
 
                 } else {
                     // Table row (tr)
-                    client.handleTooltipEvent(event, VScrollTable.this, target);
+                    client.handleWidgetTooltipEvent(event, VScrollTable.this,
+                            target);
                 }
             }
 
@@ -4954,7 +4758,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                         showContextMenu(event);
                         if (enabled
                                 && (actionKeys != null || client
-                                        .hasEventListeners(VScrollTable.this,
+                                        .hasWidgetEventListeners(
+                                                VScrollTable.this,
                                                 ITEM_CLICK_EVENT_ID))) {
                             /*
                              * Prevent browser context menu only if there are
@@ -5243,7 +5048,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                     Element targetTdOrTr) {
                 mDown = true;
                 VTransferable transferable = new VTransferable();
-                transferable.setDragSource(VScrollTable.this);
+                transferable.setDragSource(VPaintableMap.get(client)
+                        .getPaintable(VScrollTable.this));
                 transferable.setData("itemId", "" + rowKey);
                 NodeList<TableCellElement> cells = rowElement.getCells();
                 for (int i = 0; i < cells.getLength(); i++) {
@@ -5972,9 +5778,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
     private int contentAreaBorderHeight = -1;
     private int scrollLeft;
     private int scrollTop;
-    private VScrollTableDropHandler dropHandler;
+    VScrollTableDropHandler dropHandler;
     private boolean navKeyDown;
-    private boolean multiselectPending;
+    boolean multiselectPending;
 
     /**
      * @return border top + border bottom of the scrollable area of table
@@ -6066,7 +5872,15 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
     public void onScroll(ScrollEvent event) {
         scrollLeft = scrollBodyPanel.getElement().getScrollLeft();
         scrollTop = scrollBodyPanel.getScrollPosition();
-        if (!initializedAndAttached) {
+        /*
+         * #6970 - IE sometimes fires scroll events for a detached table.
+         * 
+         * FIXME initializedAndAttached should probably be renamed - its name
+         * doesn't seem to reflect its semantics. onDetach() doesn't set it to
+         * false, and changing that might break something else, so we need to
+         * check isAttached() separately.
+         */
+        if (!initializedAndAttached || !isAttached()) {
             return;
         }
         if (!enabled) {
@@ -6315,7 +6129,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
         @Override
         public VPaintableWidget getPaintable() {
-            return VScrollTable.this;
+            return VPaintableMap.get(client).getPaintable(VScrollTable.this);
         }
 
         public ApplicationConnection getApplicationConnection() {
@@ -6752,7 +6566,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
      * actions may need focus.
      * 
      */
-    private void setProperTabIndex() {
+    void setProperTabIndex() {
         int storedScrollTop = 0;
         int storedScrollLeft = 0;
 
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java
new file mode 100644 (file)
index 0000000..fa7cc3d
--- /dev/null
@@ -0,0 +1,254 @@
+/*\r
+@VaadinApache2LicenseForJavaFiles@\r
+ */\r
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.core.client.Scheduler;\r
+import com.google.gwt.dom.client.Style.Position;\r
+import com.google.gwt.user.client.Command;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
+import com.vaadin.terminal.gwt.client.BrowserInfo;\r
+import com.vaadin.terminal.gwt.client.UIDL;\r
+import com.vaadin.terminal.gwt.client.Util;\r
+\r
+public class VScrollTablePaintable extends VAbstractPaintableWidget {\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * \r
+     * @see\r
+     * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal\r
+     * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)\r
+     */\r
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+        getWidgetForPaintable().rendering = true;\r
+\r
+        if (uidl.hasAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST)) {\r
+            getWidgetForPaintable().serverCacheFirst = uidl\r
+                    .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST);\r
+            getWidgetForPaintable().serverCacheLast = uidl\r
+                    .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_LAST);\r
+        } else {\r
+            getWidgetForPaintable().serverCacheFirst = -1;\r
+            getWidgetForPaintable().serverCacheLast = -1;\r
+        }\r
+        /*\r
+         * We need to do this before updateComponent since updateComponent calls\r
+         * this.setHeight() which will calculate a new body height depending on\r
+         * the space available.\r
+         */\r
+        if (uidl.hasAttribute("colfooters")) {\r
+            getWidgetForPaintable().showColFooters = uidl\r
+                    .getBooleanAttribute("colfooters");\r
+        }\r
+\r
+        getWidgetForPaintable().tFoot\r
+                .setVisible(getWidgetForPaintable().showColFooters);\r
+\r
+        if (client.updateComponent(this, uidl, true)) {\r
+            getWidgetForPaintable().rendering = false;\r
+            return;\r
+        }\r
+\r
+        getWidgetForPaintable().enabled = !uidl.hasAttribute("disabled");\r
+\r
+        if (BrowserInfo.get().isIE8() && !getWidgetForPaintable().enabled) {\r
+            /*\r
+             * The disabled shim will not cover the table body if it is relative\r
+             * in IE8. See #7324\r
+             */\r
+            getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()\r
+                    .setPosition(Position.STATIC);\r
+        } else if (BrowserInfo.get().isIE8()) {\r
+            getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()\r
+                    .setPosition(Position.RELATIVE);\r
+        }\r
+\r
+        getWidgetForPaintable().client = client;\r
+        getWidgetForPaintable().paintableId = uidl.getStringAttribute("id");\r
+        getWidgetForPaintable().immediate = uidl\r
+                .getBooleanAttribute("immediate");\r
+\r
+        int previousTotalRows = getWidgetForPaintable().totalRows;\r
+        getWidgetForPaintable().updateTotalRows(uidl);\r
+        boolean totalRowsChanged = (getWidgetForPaintable().totalRows != previousTotalRows);\r
+\r
+        getWidgetForPaintable().updateDragMode(uidl);\r
+\r
+        getWidgetForPaintable().updateSelectionProperties(uidl);\r
+\r
+        if (uidl.hasAttribute("alb")) {\r
+            getWidgetForPaintable().bodyActionKeys = uidl\r
+                    .getStringArrayAttribute("alb");\r
+        } else {\r
+            // Need to clear the actions if the action handlers have been\r
+            // removed\r
+            getWidgetForPaintable().bodyActionKeys = null;\r
+        }\r
+\r
+        getWidgetForPaintable().setCacheRateFromUIDL(uidl);\r
+\r
+        getWidgetForPaintable().recalcWidths = uidl\r
+                .hasAttribute("recalcWidths");\r
+        if (getWidgetForPaintable().recalcWidths) {\r
+            getWidgetForPaintable().tHead.clear();\r
+            getWidgetForPaintable().tFoot.clear();\r
+        }\r
+\r
+        getWidgetForPaintable().updatePageLength(uidl);\r
+\r
+        getWidgetForPaintable().updateFirstVisibleAndScrollIfNeeded(uidl);\r
+\r
+        getWidgetForPaintable().showRowHeaders = uidl\r
+                .getBooleanAttribute("rowheaders");\r
+        getWidgetForPaintable().showColHeaders = uidl\r
+                .getBooleanAttribute("colheaders");\r
+\r
+        getWidgetForPaintable().updateSortingProperties(uidl);\r
+\r
+        boolean keyboardSelectionOverRowFetchInProgress = getWidgetForPaintable()\r
+                .selectSelectedRows(uidl);\r
+\r
+        getWidgetForPaintable().updateActionMap(uidl);\r
+\r
+        getWidgetForPaintable().updateColumnProperties(uidl);\r
+\r
+        UIDL ac = uidl.getChildByTagName("-ac");\r
+        if (ac == null) {\r
+            if (getWidgetForPaintable().dropHandler != null) {\r
+                // remove dropHandler if not present anymore\r
+                getWidgetForPaintable().dropHandler = null;\r
+            }\r
+        } else {\r
+            if (getWidgetForPaintable().dropHandler == null) {\r
+                getWidgetForPaintable().dropHandler = getWidgetForPaintable().new VScrollTableDropHandler();\r
+            }\r
+            getWidgetForPaintable().dropHandler.updateAcceptRules(ac);\r
+        }\r
+\r
+        UIDL partialRowAdditions = uidl.getChildByTagName("prows");\r
+        UIDL partialRowUpdates = uidl.getChildByTagName("urows");\r
+        if (partialRowUpdates != null || partialRowAdditions != null) {\r
+            // we may have pending cache row fetch, cancel it. See #2136\r
+            getWidgetForPaintable().rowRequestHandler.cancel();\r
+\r
+            getWidgetForPaintable().updateRowsInBody(partialRowUpdates);\r
+            getWidgetForPaintable().addAndRemoveRows(partialRowAdditions);\r
+        } else {\r
+            UIDL rowData = uidl.getChildByTagName("rows");\r
+            if (rowData != null) {\r
+                // we may have pending cache row fetch, cancel it. See #2136\r
+                getWidgetForPaintable().rowRequestHandler.cancel();\r
+\r
+                if (!getWidgetForPaintable().recalcWidths\r
+                        && getWidgetForPaintable().initializedAndAttached) {\r
+                    getWidgetForPaintable().updateBody(rowData,\r
+                            uidl.getIntAttribute("firstrow"),\r
+                            uidl.getIntAttribute("rows"));\r
+                    if (getWidgetForPaintable().headerChangedDuringUpdate) {\r
+                        getWidgetForPaintable().triggerLazyColumnAdjustment(\r
+                                true);\r
+                    } else if (!getWidgetForPaintable()\r
+                            .isScrollPositionVisible()\r
+                            || totalRowsChanged\r
+                            || getWidgetForPaintable().lastRenderedHeight != getWidgetForPaintable().scrollBody\r
+                                    .getOffsetHeight()) {\r
+                        // webkits may still bug with their disturbing scrollbar\r
+                        // bug, see #3457\r
+                        // Run overflow fix for the scrollable area\r
+                        // #6698 - If there's a scroll going on, don't abort it\r
+                        // by changing overflows as the length of the contents\r
+                        // *shouldn't* have changed (unless the number of rows\r
+                        // or the height of the widget has also changed)\r
+                        Scheduler.get().scheduleDeferred(new Command() {\r
+                            public void execute() {\r
+                                Util.runWebkitOverflowAutoFix(getWidgetForPaintable().scrollBodyPanel\r
+                                        .getElement());\r
+                            }\r
+                        });\r
+                    }\r
+                } else {\r
+                    getWidgetForPaintable().initializeRows(uidl, rowData);\r
+                }\r
+            }\r
+        }\r
+\r
+        if (!getWidgetForPaintable().isSelectable()) {\r
+            getWidgetForPaintable().scrollBody\r
+                    .addStyleName(VScrollTable.CLASSNAME + "-body-noselection");\r
+        } else {\r
+            getWidgetForPaintable().scrollBody\r
+                    .removeStyleName(VScrollTable.CLASSNAME\r
+                            + "-body-noselection");\r
+        }\r
+\r
+        getWidgetForPaintable().hideScrollPositionAnnotation();\r
+        getWidgetForPaintable().purgeUnregistryBag();\r
+\r
+        // selection is no in sync with server, avoid excessive server visits by\r
+        // clearing to flag used during the normal operation\r
+        if (!keyboardSelectionOverRowFetchInProgress) {\r
+            getWidgetForPaintable().selectionChanged = false;\r
+        }\r
+\r
+        /*\r
+         * This is called when the Home or page up button has been pressed in\r
+         * selectable mode and the next selected row was not yet rendered in the\r
+         * client\r
+         */\r
+        if (getWidgetForPaintable().selectFirstItemInNextRender\r
+                || getWidgetForPaintable().focusFirstItemInNextRender) {\r
+            getWidgetForPaintable().selectFirstRenderedRowInViewPort(\r
+                    getWidgetForPaintable().focusFirstItemInNextRender);\r
+            getWidgetForPaintable().selectFirstItemInNextRender = getWidgetForPaintable().focusFirstItemInNextRender = false;\r
+        }\r
+\r
+        /*\r
+         * This is called when the page down or end button has been pressed in\r
+         * selectable mode and the next selected row was not yet rendered in the\r
+         * client\r
+         */\r
+        if (getWidgetForPaintable().selectLastItemInNextRender\r
+                || getWidgetForPaintable().focusLastItemInNextRender) {\r
+            getWidgetForPaintable().selectLastRenderedRowInViewPort(\r
+                    getWidgetForPaintable().focusLastItemInNextRender);\r
+            getWidgetForPaintable().selectLastItemInNextRender = getWidgetForPaintable().focusLastItemInNextRender = false;\r
+        }\r
+        getWidgetForPaintable().multiselectPending = false;\r
+\r
+        if (getWidgetForPaintable().focusedRow != null) {\r
+            if (!getWidgetForPaintable().focusedRow.isAttached()\r
+                    && !getWidgetForPaintable().rowRequestHandler.isRunning()) {\r
+                // focused row has been orphaned, can't focus\r
+                getWidgetForPaintable().focusRowFromBody();\r
+            }\r
+        }\r
+\r
+        getWidgetForPaintable().tabIndex = uidl.hasAttribute("tabindex") ? uidl\r
+                .getIntAttribute("tabindex") : 0;\r
+        getWidgetForPaintable().setProperTabIndex();\r
+\r
+        getWidgetForPaintable().resizeSortedColumnForSortIndicator();\r
+\r
+        // Remember this to detect situations where overflow hack might be\r
+        // needed during scrolling\r
+        getWidgetForPaintable().lastRenderedHeight = getWidgetForPaintable().scrollBody\r
+                .getOffsetHeight();\r
+\r
+        getWidgetForPaintable().rendering = false;\r
+        getWidgetForPaintable().headerChangedDuringUpdate = false;\r
+\r
+    }\r
+\r
+    @Override\r
+    protected Widget createWidget() {\r
+        return GWT.create(VScrollTable.class);\r
+    }\r
+\r
+    @Override\r
+    public VScrollTable getWidgetForPaintable() {\r
+        return (VScrollTable) super.getWidgetForPaintable();\r
+    }\r
+}\r
index 6b55fa08024fa989d341e41f69781800e1951aab..3632e90956f5034d1454867428a11a21f893f7dc 100644 (file)
-/* 
-@VaadinApache2LicenseForJavaFiles@
- */
-// 
-package com.vaadin.terminal.gwt.client.ui;
-
-import com.google.gwt.core.client.Scheduler;
-import com.google.gwt.core.client.Scheduler.ScheduledCommand;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-import com.vaadin.terminal.gwt.client.UIDL;
-import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VConsole;
-
-public class VSlider extends SimpleFocusablePanel implements VPaintableWidget,
-        Field, ContainerResizedListener {
-
-    public static final String CLASSNAME = "v-slider";
-
-    /**
-     * Minimum size (width or height, depending on orientation) of the slider
-     * base.
-     */
-    private static final int MIN_SIZE = 50;
-
-    ApplicationConnection client;
-
-    String id;
-
-    private boolean immediate;
-    private boolean disabled;
-    private boolean readonly;
-
-    private int acceleration = 1;
-    private double min;
-    private double max;
-    private int resolution;
-    private Double value;
-    private boolean vertical;
-
-    private final HTML feedback = new HTML("", false);
-    private final VOverlay feedbackPopup = new VOverlay(true, false, true) {
-        @Override
-        public void show() {
-            super.show();
-            updateFeedbackPosition();
-        }
-    };
-
-    /* DOM element for slider's base */
-    private final Element base;
-    private final int BASE_BORDER_WIDTH = 1;
-
-    /* DOM element for slider's handle */
-    private final Element handle;
-
-    /* DOM element for decrement arrow */
-    private final Element smaller;
-
-    /* DOM element for increment arrow */
-    private final Element bigger;
-
-    /* Temporary dragging/animation variables */
-    private boolean dragging = false;
-
-    private VLazyExecutor delayedValueUpdater = new VLazyExecutor(100,
-            new ScheduledCommand() {
-
-                public void execute() {
-                    updateValueToServer();
-                    acceleration = 1;
-                }
-            });
-
-    public VSlider() {
-        super();
-
-        base = DOM.createDiv();
-        handle = DOM.createDiv();
-        smaller = DOM.createDiv();
-        bigger = DOM.createDiv();
-
-        setStyleName(CLASSNAME);
-        DOM.setElementProperty(base, "className", CLASSNAME + "-base");
-        DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
-        DOM.setElementProperty(smaller, "className", CLASSNAME + "-smaller");
-        DOM.setElementProperty(bigger, "className", CLASSNAME + "-bigger");
-
-        DOM.appendChild(getElement(), bigger);
-        DOM.appendChild(getElement(), smaller);
-        DOM.appendChild(getElement(), base);
-        DOM.appendChild(base, handle);
-
-        // Hide initially
-        DOM.setStyleAttribute(smaller, "display", "none");
-        DOM.setStyleAttribute(bigger, "display", "none");
-        DOM.setStyleAttribute(handle, "visibility", "hidden");
-
-        sinkEvents(Event.MOUSEEVENTS | Event.ONMOUSEWHEEL | Event.KEYEVENTS
-                | Event.FOCUSEVENTS | Event.TOUCHEVENTS);
-
-        feedbackPopup.addStyleName(CLASSNAME + "-feedback");
-        feedbackPopup.setWidget(feedback);
-    }
-
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
-        this.client = client;
-        id = uidl.getId();
-
-        // Ensure correct implementation
-        if (client.updateComponent(this, uidl, true)) {
-            return;
-        }
-
-        immediate = uidl.getBooleanAttribute("immediate");
-        disabled = uidl.getBooleanAttribute("disabled");
-        readonly = uidl.getBooleanAttribute("readonly");
-
-        vertical = uidl.hasAttribute("vertical");
-
-        String style = "";
-        if (uidl.hasAttribute("style")) {
-            style = uidl.getStringAttribute("style");
-        }
-
-        if (vertical) {
-            addStyleName(CLASSNAME + "-vertical");
-        } else {
-            removeStyleName(CLASSNAME + "-vertical");
-        }
-
-        min = uidl.getDoubleAttribute("min");
-        max = uidl.getDoubleAttribute("max");
-        resolution = uidl.getIntAttribute("resolution");
-        value = new Double(uidl.getDoubleVariable("value"));
-
-        setFeedbackValue(value);
-
-        buildBase();
-
-        if (!vertical) {
-            // Draw handle with a delay to allow base to gain maximum width
-            Scheduler.get().scheduleDeferred(new Command() {
-                public void execute() {
-                    buildHandle();
-                    setValue(value, false);
-                }
-            });
-        } else {
-            buildHandle();
-            setValue(value, false);
-        }
-    }
-
-    private void setFeedbackValue(double value) {
-        String currentValue = "" + value;
-        if (resolution == 0) {
-            currentValue = "" + new Double(value).intValue();
-        }
-        feedback.setText(currentValue);
-    }
-
-    private void updateFeedbackPosition() {
-        if (vertical) {
-            feedbackPopup.setPopupPosition(
-                    DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth(),
-                    DOM.getAbsoluteTop(handle) + handle.getOffsetHeight() / 2
-                            - feedbackPopup.getOffsetHeight() / 2);
-        } else {
-            feedbackPopup.setPopupPosition(
-                    DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth() / 2
-                            - feedbackPopup.getOffsetWidth() / 2,
-                    DOM.getAbsoluteTop(handle)
-                            - feedbackPopup.getOffsetHeight());
-        }
-    }
-
-    private void buildBase() {
-        final String styleAttribute = vertical ? "height" : "width";
-        final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
-
-        final Element p = DOM.getParent(getElement());
-        if (DOM.getElementPropertyInt(p, domProperty) > 50) {
-            if (vertical) {
-                setHeight();
-            } else {
-                DOM.setStyleAttribute(base, styleAttribute, "");
-            }
-        } else {
-            // Set minimum size and adjust after all components have
-            // (supposedly) been drawn completely.
-            DOM.setStyleAttribute(base, styleAttribute, MIN_SIZE + "px");
-            Scheduler.get().scheduleDeferred(new Command() {
-                public void execute() {
-                    final Element p = DOM.getParent(getElement());
-                    if (DOM.getElementPropertyInt(p, domProperty) > (MIN_SIZE + 5)) {
-                        if (vertical) {
-                            setHeight();
-                        } else {
-                            DOM.setStyleAttribute(base, styleAttribute, "");
-                        }
-                        // Ensure correct position
-                        setValue(value, false);
-                    }
-                }
-            });
-        }
-
-        // TODO attach listeners for focusing and arrow keys
-    }
-
-    private void buildHandle() {
-        final String handleAttribute = vertical ? "marginTop" : "marginLeft";
-
-        DOM.setStyleAttribute(handle, handleAttribute, "0");
-
-        // Restore visibility
-        DOM.setStyleAttribute(handle, "visibility", "visible");
-
-    }
-
-    private void setValue(Double value, boolean updateToServer) {
-        if (value == null) {
-            return;
-        }
-
-        if (value < min) {
-            value = min;
-        } else if (value > max) {
-            value = max;
-        }
-
-        // Update handle position
-        final String styleAttribute = vertical ? "marginTop" : "marginLeft";
-        final String domProperty = vertical ? "offsetHeight" : "offsetWidth";
-        final int handleSize = Integer.parseInt(DOM.getElementProperty(handle,
-                domProperty));
-        final int baseSize = Integer.parseInt(DOM.getElementProperty(base,
-                domProperty)) - (2 * BASE_BORDER_WIDTH);
-
-        final int range = baseSize - handleSize;
-        double v = value.doubleValue();
-
-        // Round value to resolution
-        if (resolution > 0) {
-            v = Math.round(v * Math.pow(10, resolution));
-            v = v / Math.pow(10, resolution);
-        } else {
-            v = Math.round(v);
-        }
-        final double valueRange = max - min;
-        double p = 0;
-        if (valueRange > 0) {
-            p = range * ((v - min) / valueRange);
-        }
-        if (p < 0) {
-            p = 0;
-        }
-        if (vertical) {
-            p = range - p;
-        }
-        final double pos = p;
-
-        DOM.setStyleAttribute(handle, styleAttribute, (Math.round(pos)) + "px");
-
-        // Update value
-        this.value = new Double(v);
-        setFeedbackValue(v);
-
-        if (updateToServer) {
-            updateValueToServer();
-        }
-    }
-
-    @Override
-    public void onBrowserEvent(Event event) {
-        if (disabled || readonly) {
-            return;
-        }
-        final Element targ = DOM.eventGetTarget(event);
-
-        if (DOM.eventGetType(event) == Event.ONMOUSEWHEEL) {
-            processMouseWheelEvent(event);
-        } else if (dragging || targ == handle) {
-            processHandleEvent(event);
-        } else if (targ == smaller) {
-            decreaseValue(true);
-        } else if (targ == bigger) {
-            increaseValue(true);
-        } else if (DOM.eventGetType(event) == Event.MOUSEEVENTS) {
-            processBaseEvent(event);
-        } else if ((BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYPRESS)
-                || (!BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYDOWN)) {
-
-            if (handleNavigation(event.getKeyCode(), event.getCtrlKey(),
-                    event.getShiftKey())) {
-
-                feedbackPopup.show();
-
-                delayedValueUpdater.trigger();
-
-                DOM.eventPreventDefault(event);
-                DOM.eventCancelBubble(event, true);
-            }
-        } else if (targ.equals(getElement())
-                && DOM.eventGetType(event) == Event.ONFOCUS) {
-            feedbackPopup.show();
-        } else if (targ.equals(getElement())
-                && DOM.eventGetType(event) == Event.ONBLUR) {
-            feedbackPopup.hide();
-        } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
-            feedbackPopup.show();
-        }
-        if (Util.isTouchEvent(event)) {
-            event.preventDefault(); // avoid simulated events
-            event.stopPropagation();
-        }
-    }
-
-    private void processMouseWheelEvent(final Event event) {
-        final int dir = DOM.eventGetMouseWheelVelocityY(event);
-
-        if (dir < 0) {
-            increaseValue(false);
-        } else {
-            decreaseValue(false);
-        }
-
-        delayedValueUpdater.trigger();
-
-        DOM.eventPreventDefault(event);
-        DOM.eventCancelBubble(event, true);
-    }
-
-    private void processHandleEvent(Event event) {
-        switch (DOM.eventGetType(event)) {
-        case Event.ONMOUSEDOWN:
-        case Event.ONTOUCHSTART:
-            if (!disabled && !readonly) {
-                focus();
-                feedbackPopup.show();
-                dragging = true;
-                DOM.setElementProperty(handle, "className", CLASSNAME
-                        + "-handle " + CLASSNAME + "-handle-active");
-                DOM.setCapture(getElement());
-                DOM.eventPreventDefault(event); // prevent selecting text
-                DOM.eventCancelBubble(event, true);
-                event.stopPropagation();
-                VConsole.log("Slider move start");
-            }
-            break;
-        case Event.ONMOUSEMOVE:
-        case Event.ONTOUCHMOVE:
-            if (dragging) {
-                VConsole.log("Slider move");
-                setValueByEvent(event, false);
-                updateFeedbackPosition();
-                event.stopPropagation();
-            }
-            break;
-        case Event.ONTOUCHEND:
-            feedbackPopup.hide();
-        case Event.ONMOUSEUP:
-            // feedbackPopup.hide();
-            VConsole.log("Slider move end");
-            dragging = false;
-            DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");
-            DOM.releaseCapture(getElement());
-            setValueByEvent(event, true);
-            event.stopPropagation();
-            break;
-        default:
-            break;
-        }
-    }
-
-    private void processBaseEvent(Event event) {
-        if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
-            if (!disabled && !readonly && !dragging) {
-                setValueByEvent(event, true);
-                DOM.eventCancelBubble(event, true);
-            }
-        } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN && dragging) {
-            dragging = false;
-            DOM.releaseCapture(getElement());
-            setValueByEvent(event, true);
-        }
-    }
-
-    private void decreaseValue(boolean updateToServer) {
-        setValue(new Double(value.doubleValue() - Math.pow(10, -resolution)),
-                updateToServer);
-    }
-
-    private void increaseValue(boolean updateToServer) {
-        setValue(new Double(value.doubleValue() + Math.pow(10, -resolution)),
-                updateToServer);
-    }
-
-    private void setValueByEvent(Event event, boolean updateToServer) {
-        double v = min; // Fallback to min
-
-        final int coord = getEventPosition(event);
-
-        final int handleSize, baseSize, baseOffset;
-        if (vertical) {
-            handleSize = handle.getOffsetHeight();
-            baseSize = base.getOffsetHeight();
-            baseOffset = base.getAbsoluteTop() - Window.getScrollTop()
-                    - handleSize / 2;
-        } else {
-            handleSize = handle.getOffsetWidth();
-            baseSize = base.getOffsetWidth();
-            baseOffset = base.getAbsoluteLeft() - Window.getScrollLeft()
-                    + handleSize / 2;
-        }
-
-        if (vertical) {
-            v = ((baseSize - (coord - baseOffset)) / (double) (baseSize - handleSize))
-                    * (max - min) + min;
-        } else {
-            v = ((coord - baseOffset) / (double) (baseSize - handleSize))
-                    * (max - min) + min;
-        }
-
-        if (v < min) {
-            v = min;
-        } else if (v > max) {
-            v = max;
-        }
-
-        setValue(v, updateToServer);
-    }
-
-    /**
-     * TODO consider extracting touches support to an impl class specific for
-     * webkit (only browser that really supports touches).
-     * 
-     * @param event
-     * @return
-     */
-    protected int getEventPosition(Event event) {
-        if (vertical) {
-            return Util.getTouchOrMouseClientY(event);
-        } else {
-            return Util.getTouchOrMouseClientX(event);
-        }
-    }
-
-    public void iLayout() {
-        if (vertical) {
-            setHeight();
-        }
-        // Update handle position
-        setValue(value, false);
-    }
-
-    private void setHeight() {
-        // Calculate decoration size
-        DOM.setStyleAttribute(base, "height", "0");
-        DOM.setStyleAttribute(base, "overflow", "hidden");
-        int h = DOM.getElementPropertyInt(getElement(), "offsetHeight");
-        if (h < MIN_SIZE) {
-            h = MIN_SIZE;
-        }
-        DOM.setStyleAttribute(base, "height", h + "px");
-        DOM.setStyleAttribute(base, "overflow", "");
-    }
-
-    private void updateValueToServer() {
-        client.updateVariable(id, "value", value.doubleValue(), immediate);
-    }
-
-    /**
-     * Handles the keyboard events handled by the Slider
-     * 
-     * @param event
-     *            The keyboard event received
-     * @return true iff the navigation event was handled
-     */
-    public boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {
-
-        // No support for ctrl moving
-        if (ctrl) {
-            return false;
-        }
-
-        if ((keycode == getNavigationUpKey() && vertical)
-                || (keycode == getNavigationRightKey() && !vertical)) {
-            if (shift) {
-                for (int a = 0; a < acceleration; a++) {
-                    increaseValue(false);
-                }
-                acceleration++;
-            } else {
-                increaseValue(false);
-            }
-            return true;
-        } else if (keycode == getNavigationDownKey() && vertical
-                || (keycode == getNavigationLeftKey() && !vertical)) {
-            if (shift) {
-                for (int a = 0; a < acceleration; a++) {
-                    decreaseValue(false);
-                }
-                acceleration++;
-            } else {
-                decreaseValue(false);
-            }
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Get the key that increases the vertical slider. By default it is the up
-     * arrow key but by overriding this you can change the key to whatever you
-     * want.
-     * 
-     * @return The keycode of the key
-     */
-    protected int getNavigationUpKey() {
-        return KeyCodes.KEY_UP;
-    }
-
-    /**
-     * Get the key that decreases the vertical slider. By default it is the down
-     * arrow key but by overriding this you can change the key to whatever you
-     * want.
-     * 
-     * @return The keycode of the key
-     */
-    protected int getNavigationDownKey() {
-        return KeyCodes.KEY_DOWN;
-    }
-
-    /**
-     * Get the key that decreases the horizontal slider. By default it is the
-     * left arrow key but by overriding this you can change the key to whatever
-     * you want.
-     * 
-     * @return The keycode of the key
-     */
-    protected int getNavigationLeftKey() {
-        return KeyCodes.KEY_LEFT;
-    }
-
-    /**
-     * Get the key that increases the horizontal slider. By default it is the
-     * right arrow key but by overriding this you can change the key to whatever
-     * you want.
-     * 
-     * @return The keycode of the key
-     */
-    protected int getNavigationRightKey() {
-        return KeyCodes.KEY_RIGHT;
-    }
-
-    public Widget getWidgetForPaintable() {
-        return this;
-    }
-}
+/* \r
+@VaadinApache2LicenseForJavaFiles@\r
+ */\r
+// \r
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.core.client.Scheduler;\r
+import com.google.gwt.core.client.Scheduler.ScheduledCommand;\r
+import com.google.gwt.event.dom.client.KeyCodes;\r
+import com.google.gwt.user.client.Command;\r
+import com.google.gwt.user.client.DOM;\r
+import com.google.gwt.user.client.Element;\r
+import com.google.gwt.user.client.Event;\r
+import com.google.gwt.user.client.Window;\r
+import com.google.gwt.user.client.ui.HTML;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
+import com.vaadin.terminal.gwt.client.BrowserInfo;\r
+import com.vaadin.terminal.gwt.client.ContainerResizedListener;\r
+import com.vaadin.terminal.gwt.client.VPaintableWidget;\r
+import com.vaadin.terminal.gwt.client.UIDL;\r
+import com.vaadin.terminal.gwt.client.Util;\r
+import com.vaadin.terminal.gwt.client.VConsole;\r
+\r
+public class VSlider extends SimpleFocusablePanel implements VPaintableWidget,\r
+        Field, ContainerResizedListener {\r
+\r
+    public static final String CLASSNAME = "v-slider";\r
+\r
+    /**\r
+     * Minimum size (width or height, depending on orientation) of the slider\r
+     * base.\r
+     */\r
+    private static final int MIN_SIZE = 50;\r
+\r
+    ApplicationConnection client;\r
+\r
+    String id;\r
+\r
+    private boolean immediate;\r
+    private boolean disabled;\r
+    private boolean readonly;\r
+\r
+    private int acceleration = 1;\r
+    private double min;\r
+    private double max;\r
+    private int resolution;\r
+    private Double value;\r
+    private boolean vertical;\r
+\r
+    private final HTML feedback = new HTML("", false);\r
+    private final VOverlay feedbackPopup = new VOverlay(true, false, true) {\r
+        @Override\r
+        public void show() {\r
+            super.show();\r
+            updateFeedbackPosition();\r
+        }\r
+    };\r
+\r
+    /* DOM element for slider's base */\r
+    private final Element base;\r
+    private final int BASE_BORDER_WIDTH = 1;\r
+\r
+    /* DOM element for slider's handle */\r
+    private final Element handle;\r
+\r
+    /* DOM element for decrement arrow */\r
+    private final Element smaller;\r
+\r
+    /* DOM element for increment arrow */\r
+    private final Element bigger;\r
+\r
+    /* Temporary dragging/animation variables */\r
+    private boolean dragging = false;\r
+\r
+    private VLazyExecutor delayedValueUpdater = new VLazyExecutor(100,\r
+            new ScheduledCommand() {\r
+\r
+                public void execute() {\r
+                    updateValueToServer();\r
+                    acceleration = 1;\r
+                }\r
+            });\r
+\r
+    public VSlider() {\r
+        super();\r
+\r
+        base = DOM.createDiv();\r
+        handle = DOM.createDiv();\r
+        smaller = DOM.createDiv();\r
+        bigger = DOM.createDiv();\r
+\r
+        setStyleName(CLASSNAME);\r
+        DOM.setElementProperty(base, "className", CLASSNAME + "-base");\r
+        DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");\r
+        DOM.setElementProperty(smaller, "className", CLASSNAME + "-smaller");\r
+        DOM.setElementProperty(bigger, "className", CLASSNAME + "-bigger");\r
+\r
+        DOM.appendChild(getElement(), bigger);\r
+        DOM.appendChild(getElement(), smaller);\r
+        DOM.appendChild(getElement(), base);\r
+        DOM.appendChild(base, handle);\r
+\r
+        // Hide initially\r
+        DOM.setStyleAttribute(smaller, "display", "none");\r
+        DOM.setStyleAttribute(bigger, "display", "none");\r
+        DOM.setStyleAttribute(handle, "visibility", "hidden");\r
+\r
+        sinkEvents(Event.MOUSEEVENTS | Event.ONMOUSEWHEEL | Event.KEYEVENTS\r
+                | Event.FOCUSEVENTS | Event.TOUCHEVENTS);\r
+\r
+        feedbackPopup.addStyleName(CLASSNAME + "-feedback");\r
+        feedbackPopup.setWidget(feedback);\r
+    }\r
+\r
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+\r
+        this.client = client;\r
+        id = uidl.getId();\r
+\r
+        // Ensure correct implementation\r
+        if (client.updateComponent(this, uidl, true)) {\r
+            return;\r
+        }\r
+\r
+        immediate = uidl.getBooleanAttribute("immediate");\r
+        disabled = uidl.getBooleanAttribute("disabled");\r
+        readonly = uidl.getBooleanAttribute("readonly");\r
+\r
+        vertical = uidl.hasAttribute("vertical");\r
+\r
+        String style = "";\r
+        if (uidl.hasAttribute("style")) {\r
+            style = uidl.getStringAttribute("style");\r
+        }\r
+\r
+        if (vertical) {\r
+            addStyleName(CLASSNAME + "-vertical");\r
+        } else {\r
+            removeStyleName(CLASSNAME + "-vertical");\r
+        }\r
+\r
+        min = uidl.getDoubleAttribute("min");\r
+        max = uidl.getDoubleAttribute("max");\r
+        resolution = uidl.getIntAttribute("resolution");\r
+        value = new Double(uidl.getDoubleVariable("value"));\r
+\r
+        setFeedbackValue(value);\r
+\r
+        buildBase();\r
+\r
+        if (!vertical) {\r
+            // Draw handle with a delay to allow base to gain maximum width\r
+            Scheduler.get().scheduleDeferred(new Command() {\r
+                public void execute() {\r
+                    buildHandle();\r
+                    setValue(value, false);\r
+                }\r
+            });\r
+        } else {\r
+            buildHandle();\r
+            setValue(value, false);\r
+        }\r
+    }\r
+\r
+    private void setFeedbackValue(double value) {\r
+        String currentValue = "" + value;\r
+        if (resolution == 0) {\r
+            currentValue = "" + new Double(value).intValue();\r
+        }\r
+        feedback.setText(currentValue);\r
+    }\r
+\r
+    private void updateFeedbackPosition() {\r
+        if (vertical) {\r
+            feedbackPopup.setPopupPosition(\r
+                    DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth(),\r
+                    DOM.getAbsoluteTop(handle) + handle.getOffsetHeight() / 2\r
+                            - feedbackPopup.getOffsetHeight() / 2);\r
+        } else {\r
+            feedbackPopup.setPopupPosition(\r
+                    DOM.getAbsoluteLeft(handle) + handle.getOffsetWidth() / 2\r
+                            - feedbackPopup.getOffsetWidth() / 2,\r
+                    DOM.getAbsoluteTop(handle)\r
+                            - feedbackPopup.getOffsetHeight());\r
+        }\r
+    }\r
+\r
+    private void buildBase() {\r
+        final String styleAttribute = vertical ? "height" : "width";\r
+        final String domProperty = vertical ? "offsetHeight" : "offsetWidth";\r
+\r
+        final Element p = DOM.getParent(getElement());\r
+        if (DOM.getElementPropertyInt(p, domProperty) > 50) {\r
+            if (vertical) {\r
+                setHeight();\r
+            } else {\r
+                DOM.setStyleAttribute(base, styleAttribute, "");\r
+            }\r
+        } else {\r
+            // Set minimum size and adjust after all components have\r
+            // (supposedly) been drawn completely.\r
+            DOM.setStyleAttribute(base, styleAttribute, MIN_SIZE + "px");\r
+            Scheduler.get().scheduleDeferred(new Command() {\r
+                public void execute() {\r
+                    final Element p = DOM.getParent(getElement());\r
+                    if (DOM.getElementPropertyInt(p, domProperty) > (MIN_SIZE + 5)) {\r
+                        if (vertical) {\r
+                            setHeight();\r
+                        } else {\r
+                            DOM.setStyleAttribute(base, styleAttribute, "");\r
+                        }\r
+                        // Ensure correct position\r
+                        setValue(value, false);\r
+                    }\r
+                }\r
+            });\r
+        }\r
+\r
+        // TODO attach listeners for focusing and arrow keys\r
+    }\r
+\r
+    private void buildHandle() {\r
+        final String handleAttribute = vertical ? "marginTop" : "marginLeft";\r
+\r
+        DOM.setStyleAttribute(handle, handleAttribute, "0");\r
+\r
+        // Restore visibility\r
+        DOM.setStyleAttribute(handle, "visibility", "visible");\r
+\r
+    }\r
+\r
+    private void setValue(Double value, boolean updateToServer) {\r
+        if (value == null) {\r
+            return;\r
+        }\r
+\r
+        if (value < min) {\r
+            value = min;\r
+        } else if (value > max) {\r
+            value = max;\r
+        }\r
+\r
+        // Update handle position\r
+        final String styleAttribute = vertical ? "marginTop" : "marginLeft";\r
+        final String domProperty = vertical ? "offsetHeight" : "offsetWidth";\r
+        final int handleSize = Integer.parseInt(DOM.getElementProperty(handle,\r
+                domProperty));\r
+        final int baseSize = Integer.parseInt(DOM.getElementProperty(base,\r
+                domProperty)) - (2 * BASE_BORDER_WIDTH);\r
+\r
+        final int range = baseSize - handleSize;\r
+        double v = value.doubleValue();\r
+\r
+        // Round value to resolution\r
+        if (resolution > 0) {\r
+            v = Math.round(v * Math.pow(10, resolution));\r
+            v = v / Math.pow(10, resolution);\r
+        } else {\r
+            v = Math.round(v);\r
+        }\r
+        final double valueRange = max - min;\r
+        double p = 0;\r
+        if (valueRange > 0) {\r
+            p = range * ((v - min) / valueRange);\r
+        }\r
+        if (p < 0) {\r
+            p = 0;\r
+        }\r
+        if (vertical) {\r
+            p = range - p;\r
+        }\r
+        final double pos = p;\r
+\r
+        DOM.setStyleAttribute(handle, styleAttribute, (Math.round(pos)) + "px");\r
+\r
+        // Update value\r
+        this.value = new Double(v);\r
+        setFeedbackValue(v);\r
+\r
+        if (updateToServer) {\r
+            updateValueToServer();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void onBrowserEvent(Event event) {\r
+        if (disabled || readonly) {\r
+            return;\r
+        }\r
+        final Element targ = DOM.eventGetTarget(event);\r
+\r
+        if (DOM.eventGetType(event) == Event.ONMOUSEWHEEL) {\r
+            processMouseWheelEvent(event);\r
+        } else if (dragging || targ == handle) {\r
+            processHandleEvent(event);\r
+        } else if (targ == smaller) {\r
+            decreaseValue(true);\r
+        } else if (targ == bigger) {\r
+            increaseValue(true);\r
+        } else if (DOM.eventGetType(event) == Event.MOUSEEVENTS) {\r
+            processBaseEvent(event);\r
+        } else if ((BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYPRESS)\r
+                || (!BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYDOWN)) {\r
+\r
+            if (handleNavigation(event.getKeyCode(), event.getCtrlKey(),\r
+                    event.getShiftKey())) {\r
+\r
+                feedbackPopup.show();\r
+\r
+                delayedValueUpdater.trigger();\r
+\r
+                DOM.eventPreventDefault(event);\r
+                DOM.eventCancelBubble(event, true);\r
+            }\r
+        } else if (targ.equals(getElement())\r
+                && DOM.eventGetType(event) == Event.ONFOCUS) {\r
+            feedbackPopup.show();\r
+        } else if (targ.equals(getElement())\r
+                && DOM.eventGetType(event) == Event.ONBLUR) {\r
+            feedbackPopup.hide();\r
+        } else if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {\r
+            feedbackPopup.show();\r
+        }\r
+        if (Util.isTouchEvent(event)) {\r
+            event.preventDefault(); // avoid simulated events\r
+            event.stopPropagation();\r
+        }\r
+    }\r
+\r
+    private void processMouseWheelEvent(final Event event) {\r
+        final int dir = DOM.eventGetMouseWheelVelocityY(event);\r
+\r
+        if (dir < 0) {\r
+            increaseValue(false);\r
+        } else {\r
+            decreaseValue(false);\r
+        }\r
+\r
+        delayedValueUpdater.trigger();\r
+\r
+        DOM.eventPreventDefault(event);\r
+        DOM.eventCancelBubble(event, true);\r
+    }\r
+\r
+    private void processHandleEvent(Event event) {\r
+        switch (DOM.eventGetType(event)) {\r
+        case Event.ONMOUSEDOWN:\r
+        case Event.ONTOUCHSTART:\r
+            if (!disabled && !readonly) {\r
+                focus();\r
+                feedbackPopup.show();\r
+                dragging = true;\r
+                DOM.setElementProperty(handle, "className", CLASSNAME\r
+                        + "-handle " + CLASSNAME + "-handle-active");\r
+                DOM.setCapture(getElement());\r
+                DOM.eventPreventDefault(event); // prevent selecting text\r
+                DOM.eventCancelBubble(event, true);\r
+                event.stopPropagation();\r
+                VConsole.log("Slider move start");\r
+            }\r
+            break;\r
+        case Event.ONMOUSEMOVE:\r
+        case Event.ONTOUCHMOVE:\r
+            if (dragging) {\r
+                VConsole.log("Slider move");\r
+                setValueByEvent(event, false);\r
+                updateFeedbackPosition();\r
+                event.stopPropagation();\r
+            }\r
+            break;\r
+        case Event.ONTOUCHEND:\r
+            feedbackPopup.hide();\r
+        case Event.ONMOUSEUP:\r
+            // feedbackPopup.hide();\r
+            VConsole.log("Slider move end");\r
+            dragging = false;\r
+            DOM.setElementProperty(handle, "className", CLASSNAME + "-handle");\r
+            DOM.releaseCapture(getElement());\r
+            setValueByEvent(event, true);\r
+            event.stopPropagation();\r
+            break;\r
+        default:\r
+            break;\r
+        }\r
+    }\r
+\r
+    private void processBaseEvent(Event event) {\r
+        if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {\r
+            if (!disabled && !readonly && !dragging) {\r
+                setValueByEvent(event, true);\r
+                DOM.eventCancelBubble(event, true);\r
+            }\r
+        }\r
+    }\r
+\r
+    private void decreaseValue(boolean updateToServer) {\r
+        setValue(new Double(value.doubleValue() - Math.pow(10, -resolution)),\r
+                updateToServer);\r
+    }\r
+\r
+    private void increaseValue(boolean updateToServer) {\r
+        setValue(new Double(value.doubleValue() + Math.pow(10, -resolution)),\r
+                updateToServer);\r
+    }\r
+\r
+    private void setValueByEvent(Event event, boolean updateToServer) {\r
+        double v = min; // Fallback to min\r
+\r
+        final int coord = getEventPosition(event);\r
+\r
+        final int handleSize, baseSize, baseOffset;\r
+        if (vertical) {\r
+            handleSize = handle.getOffsetHeight();\r
+            baseSize = base.getOffsetHeight();\r
+            baseOffset = base.getAbsoluteTop() - Window.getScrollTop()\r
+                    - handleSize / 2;\r
+        } else {\r
+            handleSize = handle.getOffsetWidth();\r
+            baseSize = base.getOffsetWidth();\r
+            baseOffset = base.getAbsoluteLeft() - Window.getScrollLeft()\r
+                    + handleSize / 2;\r
+        }\r
+\r
+        if (vertical) {\r
+            v = ((baseSize - (coord - baseOffset)) / (double) (baseSize - handleSize))\r
+                    * (max - min) + min;\r
+        } else {\r
+            v = ((coord - baseOffset) / (double) (baseSize - handleSize))\r
+                    * (max - min) + min;\r
+        }\r
+\r
+        if (v < min) {\r
+            v = min;\r
+        } else if (v > max) {\r
+            v = max;\r
+        }\r
+\r
+        setValue(v, updateToServer);\r
+    }\r
+\r
+    /**\r
+     * TODO consider extracting touches support to an impl class specific for\r
+     * webkit (only browser that really supports touches).\r
+     * \r
+     * @param event\r
+     * @return\r
+     */\r
+    protected int getEventPosition(Event event) {\r
+        if (vertical) {\r
+            return Util.getTouchOrMouseClientY(event);\r
+        } else {\r
+            return Util.getTouchOrMouseClientX(event);\r
+        }\r
+    }\r
+\r
+    public void iLayout() {\r
+        if (vertical) {\r
+            setHeight();\r
+        }\r
+        // Update handle position\r
+        setValue(value, false);\r
+    }\r
+\r
+    private void setHeight() {\r
+        // Calculate decoration size\r
+        DOM.setStyleAttribute(base, "height", "0");\r
+        DOM.setStyleAttribute(base, "overflow", "hidden");\r
+        int h = DOM.getElementPropertyInt(getElement(), "offsetHeight");\r
+        if (h < MIN_SIZE) {\r
+            h = MIN_SIZE;\r
+        }\r
+        DOM.setStyleAttribute(base, "height", h + "px");\r
+        DOM.setStyleAttribute(base, "overflow", "");\r
+    }\r
+\r
+    private void updateValueToServer() {\r
+        client.updateVariable(id, "value", value.doubleValue(), immediate);\r
+    }\r
+\r
+    /**\r
+     * Handles the keyboard events handled by the Slider\r
+     * \r
+     * @param event\r
+     *            The keyboard event received\r
+     * @return true iff the navigation event was handled\r
+     */\r
+    public boolean handleNavigation(int keycode, boolean ctrl, boolean shift) {\r
+\r
+        // No support for ctrl moving\r
+        if (ctrl) {\r
+            return false;\r
+        }\r
+\r
+        if ((keycode == getNavigationUpKey() && vertical)\r
+                || (keycode == getNavigationRightKey() && !vertical)) {\r
+            if (shift) {\r
+                for (int a = 0; a < acceleration; a++) {\r
+                    increaseValue(false);\r
+                }\r
+                acceleration++;\r
+            } else {\r
+                increaseValue(false);\r
+            }\r
+            return true;\r
+        } else if (keycode == getNavigationDownKey() && vertical\r
+                || (keycode == getNavigationLeftKey() && !vertical)) {\r
+            if (shift) {\r
+                for (int a = 0; a < acceleration; a++) {\r
+                    decreaseValue(false);\r
+                }\r
+                acceleration++;\r
+            } else {\r
+                decreaseValue(false);\r
+            }\r
+            return true;\r
+        }\r
+\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * Get the key that increases the vertical slider. By default it is the up\r
+     * arrow key but by overriding this you can change the key to whatever you\r
+     * want.\r
+     * \r
+     * @return The keycode of the key\r
+     */\r
+    protected int getNavigationUpKey() {\r
+        return KeyCodes.KEY_UP;\r
+    }\r
+\r
+    /**\r
+     * Get the key that decreases the vertical slider. By default it is the down\r
+     * arrow key but by overriding this you can change the key to whatever you\r
+     * want.\r
+     * \r
+     * @return The keycode of the key\r
+     */\r
+    protected int getNavigationDownKey() {\r
+        return KeyCodes.KEY_DOWN;\r
+    }\r
+\r
+    /**\r
+     * Get the key that decreases the horizontal slider. By default it is the\r
+     * left arrow key but by overriding this you can change the key to whatever\r
+     * you want.\r
+     * \r
+     * @return The keycode of the key\r
+     */\r
+    protected int getNavigationLeftKey() {\r
+        return KeyCodes.KEY_LEFT;\r
+    }\r
+\r
+    /**\r
+     * Get the key that increases the horizontal slider. By default it is the\r
+     * right arrow key but by overriding this you can change the key to whatever\r
+     * you want.\r
+     * \r
+     * @return The keycode of the key\r
+     */\r
+    protected int getNavigationRightKey() {\r
+        return KeyCodes.KEY_RIGHT;\r
+    }\r
+\r
+    public Widget getWidgetForPaintable() {\r
+        return this;\r
+    }\r
+}\r
index 32a9cf3e117ac4901bd7dd624fe040a583db0094..74ff3287106a84dbf693eb34b6b0eaccc303ae9d 100644 (file)
@@ -54,7 +54,7 @@ public class VTabsheet extends VTabsheetBase {
 
     /**
      * Representation of a single "tab" shown in the TabBar
-     * 
+     *
      */
     private static class Tab extends SimplePanel {
         private static final String TD_CLASSNAME = CLASSNAME + "-tabitemcell";
@@ -64,6 +64,8 @@ public class VTabsheet extends VTabsheetBase {
                 + "-selected";
         private static final String TD_SELECTED_FIRST_CLASSNAME = TD_SELECTED_CLASSNAME
                 + "-first";
+        private static final String TD_DISABLED_CLASSNAME = TD_CLASSNAME
+                + "-disabled";
 
         private static final String DIV_CLASSNAME = CLASSNAME + "-tabitem";
         private static final String DIV_SELECTED_CLASSNAME = DIV_CLASSNAME
@@ -116,6 +118,7 @@ public class VTabsheet extends VTabsheetBase {
 
         public void setEnabledOnServer(boolean enabled) {
             enabledOnServer = enabled;
+            setStyleName(td, TD_DISABLED_CLASSNAME, !enabled);
         }
 
         public void addClickHandler(ClickHandler handler) {
index a74fd9f5dcc3cba741721bb82934f20566a14b27..cd09e24d67ea6177a51c97d8bef98c62475b4317 100644 (file)
@@ -69,4 +69,11 @@ public class VTextArea extends VTextField {
         super.onBrowserEvent(event);\r
     }\r
 \r
+    @Override\r
+    public int getCursorPos() {\r
+        // This is needed so that TextBoxImplIE6 is used to return the correct\r
+        // position for old Internet Explorer versions where it has to be\r
+        // detected in a different way.\r
+        return getImpl().getTextAreaCursorPos(getElement());\r
+    }\r
 }\r
index 26c7430e74dc12e717ebf7ff75c7cbda751a50f1..80dad78e58b4d2a3fcd83551a79bb0e8bf7dcf7c 100644 (file)
@@ -90,12 +90,6 @@ public class VTextField extends TextBoxBase implements VPaintableWidget, Field,
 
     protected VTextField(Element node) {
         super(node);
-        if (BrowserInfo.get().getIEVersion() > 0
-                && BrowserInfo.get().getIEVersion() < 8) {
-            // Fixes IE margin problem (#2058)
-            DOM.setStyleAttribute(node, "marginTop", "-1px");
-            DOM.setStyleAttribute(node, "marginBottom", "-1px");
-        }
         setStyleName(CLASSNAME);
         addChangeHandler(this);
         if (BrowserInfo.get().isIE()) {
index ed4953d463bb29449cd8c5e11c9e087dc8633b3b..a522c7973643aa1c4eb7fbbab7c2e5f1c28d67d8 100644 (file)
@@ -20,12 +20,12 @@ import com.vaadin.terminal.gwt.client.EventId;
 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.VPaintableWidget;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
 
-public class VTextualDate extends VDateField implements VPaintableWidget, Field,
-        ChangeHandler, ContainerResizedListener, Focusable, SubPartAware {
+public class VTextualDate extends VDateField implements VPaintableWidget,
+        Field, ChangeHandler, ContainerResizedListener, Focusable, SubPartAware {
 
     private static final String PARSE_ERROR_CLASSNAME = CLASSNAME
             + "-parseerror";
@@ -331,7 +331,8 @@ public class VTextualDate extends VDateField implements VPaintableWidget, Field,
 
     @Override
     public void setWidth(String newWidth) {
-        if (!"".equals(newWidth) && (width == null || !newWidth.equals(width))) {
+        if (!"".equals(newWidth)
+                && (isUndefinedWidth() || !newWidth.equals(width))) {
             needLayout = true;
             width = newWidth;
             super.setWidth(width);
@@ -340,16 +341,18 @@ public class VTextualDate extends VDateField implements VPaintableWidget, Field,
                 needLayout = false;
             }
         } else {
-            if ("".equals(newWidth) && width != null && !"".equals(width)) {
+            if ("".equals(newWidth) && !isUndefinedWidth()) {
                 super.setWidth("");
-                needLayout = true;
-                iLayout();
-                needLayout = false;
+                iLayout(true);
                 width = null;
             }
         }
     }
 
+    protected boolean isUndefinedWidth() {
+        return width == null || "".equals(width);
+    }
+
     /**
      * Returns pixels in x-axis reserved for other than textfield content.
      * 
@@ -363,14 +366,26 @@ public class VTextualDate extends VDateField implements VPaintableWidget, Field,
         return fieldExtraWidth;
     }
 
+    /**
+     * Force an recalculation of the width of the component IF the width has
+     * been defined. Does nothing if width is undefined as the width will be
+     * automatically adjusted by the browser.
+     */
     public void updateWidth() {
+        if (isUndefinedWidth()) {
+            return;
+        }
         needLayout = true;
         fieldExtraWidth = -1;
-        iLayout();
+        iLayout(true);
     }
 
     public void iLayout() {
-        if (needLayout) {
+        iLayout(false);
+    }
+
+    public void iLayout(boolean force) {
+        if (needLayout || force) {
             int textFieldWidth = getOffsetWidth() - getFieldExtraWidth();
             if (textFieldWidth < 0) {
                 // Field can never be smaller than 0 (causes exception in IE)
index 77dd1cc39e1f927aad16f45c9c8e1243cc650590..0eddca0ed33818822b73ec71e0f9b6e14073c304 100644 (file)
@@ -24,21 +24,19 @@ import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.ComputedStyle;
 import com.vaadin.terminal.gwt.client.RenderSpace;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
 import com.vaadin.terminal.gwt.client.ui.VTreeTable.VTreeTableScrollBody.VTreeTableRow;
 
 public class VTreeTable extends VScrollTable {
 
-    private static class PendingNavigationEvent {
-        private final int keycode;
-        private final boolean ctrl;
-        private final boolean shift;
+    static class PendingNavigationEvent {
+        final int keycode;
+        final boolean ctrl;
+        final boolean shift;
 
         public PendingNavigationEvent(int keycode, boolean ctrl, boolean shift) {
             this.keycode = keycode;
@@ -59,82 +57,14 @@ public class VTreeTable extends VScrollTable {
         }
     }
 
-    public static final String ATTRIBUTE_HIERARCHY_COLUMN_INDEX = "hci";
-    private boolean collapseRequest;
+    boolean collapseRequest;
     private boolean selectionPending;
-    private int colIndexOfHierarchy;
-    private String collapsedRowKey;
-    private VTreeTableScrollBody scrollBody;
-    private boolean animationsEnabled;
-    private LinkedList<PendingNavigationEvent> pendingNavigationEvents = new LinkedList<VTreeTable.PendingNavigationEvent>();
-    private boolean focusParentResponsePending;
-
-    @Override
-    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-        FocusableScrollPanel widget = null;
-        int scrollPosition = 0;
-        if (collapseRequest) {
-            widget = (FocusableScrollPanel) getWidget(1);
-            scrollPosition = widget.getScrollPosition();
-        }
-        animationsEnabled = uidl.getBooleanAttribute("animate");
-        colIndexOfHierarchy = uidl
-                .hasAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) ? uidl
-                .getIntAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) : 0;
-        int oldTotalRows = getTotalRows();
-        super.updateFromUIDL(uidl, client);
-        if (collapseRequest) {
-            if (collapsedRowKey != null && scrollBody != null) {
-                VScrollTableRow row = getRenderedRowByKey(collapsedRowKey);
-                if (row != null) {
-                    setRowFocus(row);
-                    focus();
-                }
-            }
-
-            int scrollPosition2 = widget.getScrollPosition();
-            if (scrollPosition != scrollPosition2) {
-                widget.setScrollPosition(scrollPosition);
-            }
-
-            // check which rows are needed from the server and initiate a
-            // deferred fetch
-            onScroll(null);
-        }
-        // Recalculate table size if collapse request, or if page length is zero
-        // (not sent by server) and row count changes (#7908).
-        if (collapseRequest
-                || (!uidl.hasAttribute("pagelength") && getTotalRows() != oldTotalRows)) {
-            /*
-             * Ensure that possibly removed/added scrollbars are considered.
-             * Triggers row calculations, removes cached rows etc. Basically
-             * cleans up state. Be careful if touching this, you will break
-             * pageLength=0 if you remove this.
-             */
-            triggerLazyColumnAdjustment(true);
-
-            collapseRequest = false;
-        }
-        if (uidl.hasAttribute("focusedRow")) {
-            String key = uidl.getStringAttribute("focusedRow");
-            setRowFocus(getRenderedRowByKey(key));
-            focusParentResponsePending = false;
-        } else if (uidl.hasAttribute("clearFocusPending")) {
-            // Special case to detect a response to a focusParent request that
-            // does not return any focusedRow because the selected node has no
-            // parent
-            focusParentResponsePending = false;
-        }
-
-        while (!collapseRequest && !focusParentResponsePending
-                && !pendingNavigationEvents.isEmpty()) {
-            // Keep replaying any queued events as long as we don't have any
-            // potential content changes pending
-            PendingNavigationEvent event = pendingNavigationEvents
-                    .removeFirst();
-            handleNavigation(event.keycode, event.ctrl, event.shift);
-        }
-    }
+    int colIndexOfHierarchy;
+    String collapsedRowKey;
+    VTreeTableScrollBody scrollBody;
+    boolean animationsEnabled;
+    LinkedList<PendingNavigationEvent> pendingNavigationEvents = new LinkedList<VTreeTable.PendingNavigationEvent>();
+    boolean focusParentResponsePending;
 
     @Override
     protected VScrollTableBody createScrollBody() {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java
new file mode 100644 (file)
index 0000000..9b6f03f
--- /dev/null
@@ -0,0 +1,101 @@
+/*\r
+@VaadinApache2LicenseForJavaFiles@\r
+ */\r
+package com.vaadin.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.core.client.GWT;\r
+import com.google.gwt.user.client.ui.Widget;\r
+import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
+import com.vaadin.terminal.gwt.client.UIDL;\r
+import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;\r
+import com.vaadin.terminal.gwt.client.ui.VTreeTable.PendingNavigationEvent;\r
+\r
+public class VTreeTablePaintable extends VScrollTablePaintable {\r
+    public static final String ATTRIBUTE_HIERARCHY_COLUMN_INDEX = "hci";\r
+\r
+    @Override\r
+    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+        FocusableScrollPanel widget = null;\r
+        int scrollPosition = 0;\r
+        if (getWidgetForPaintable().collapseRequest) {\r
+            widget = (FocusableScrollPanel) getWidgetForPaintable()\r
+                    .getWidget(1);\r
+            scrollPosition = widget.getScrollPosition();\r
+        }\r
+        getWidgetForPaintable().animationsEnabled = uidl\r
+                .getBooleanAttribute("animate");\r
+        getWidgetForPaintable().colIndexOfHierarchy = uidl\r
+                .hasAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) ? uidl\r
+                .getIntAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) : 0;\r
+        int oldTotalRows = getWidgetForPaintable().getTotalRows();\r
+        super.updateFromUIDL(uidl, client);\r
+        if (getWidgetForPaintable().collapseRequest) {\r
+            if (getWidgetForPaintable().collapsedRowKey != null\r
+                    && getWidgetForPaintable().scrollBody != null) {\r
+                VScrollTableRow row = getWidgetForPaintable()\r
+                        .getRenderedRowByKey(\r
+                                getWidgetForPaintable().collapsedRowKey);\r
+                if (row != null) {\r
+                    getWidgetForPaintable().setRowFocus(row);\r
+                    getWidgetForPaintable().focus();\r
+                }\r
+            }\r
+\r
+            int scrollPosition2 = widget.getScrollPosition();\r
+            if (scrollPosition != scrollPosition2) {\r
+                widget.setScrollPosition(scrollPosition);\r
+            }\r
+\r
+            // check which rows are needed from the server and initiate a\r
+            // deferred fetch\r
+            getWidgetForPaintable().onScroll(null);\r
+        }\r
+        // Recalculate table size if collapse request, or if page length is zero\r
+        // (not sent by server) and row count changes (#7908).\r
+        if (getWidgetForPaintable().collapseRequest\r
+                || (!uidl.hasAttribute("pagelength") && getWidgetForPaintable()\r
+                        .getTotalRows() != oldTotalRows)) {\r
+            /*\r
+             * Ensure that possibly removed/added scrollbars are considered.\r
+             * Triggers row calculations, removes cached rows etc. Basically\r
+             * cleans up state. Be careful if touching this, you will break\r
+             * pageLength=0 if you remove this.\r
+             */\r
+            getWidgetForPaintable().triggerLazyColumnAdjustment(true);\r
+\r
+            getWidgetForPaintable().collapseRequest = false;\r
+        }\r
+        if (uidl.hasAttribute("focusedRow")) {\r
+            String key = uidl.getStringAttribute("focusedRow");\r
+            getWidgetForPaintable().setRowFocus(\r
+                    getWidgetForPaintable().getRenderedRowByKey(key));\r
+            getWidgetForPaintable().focusParentResponsePending = false;\r
+        } else if (uidl.hasAttribute("clearFocusPending")) {\r
+            // Special case to detect a response to a focusParent request that\r
+            // does not return any focusedRow because the selected node has no\r
+            // parent\r
+            getWidgetForPaintable().focusParentResponsePending = false;\r
+        }\r
+\r
+        while (!getWidgetForPaintable().collapseRequest\r
+                && !getWidgetForPaintable().focusParentResponsePending\r
+                && !getWidgetForPaintable().pendingNavigationEvents.isEmpty()) {\r
+            // Keep replaying any queued events as long as we don't have any\r
+            // potential content changes pending\r
+            PendingNavigationEvent event = getWidgetForPaintable().pendingNavigationEvents\r
+                    .removeFirst();\r
+            getWidgetForPaintable().handleNavigation(event.keycode, event.ctrl,\r
+                    event.shift);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected Widget createWidget() {\r
+        return GWT.create(VTreeTable.class);\r
+    }\r
+\r
+    @Override\r
+    public VTreeTable getWidgetForPaintable() {\r
+        return (VTreeTable) super.getWidgetForPaintable();\r
+    }\r
+}\r
index 3d49b8d9d103a7152e50d1059ee1c92e276b6f32..66894417f3ce9d5fbb8f821896c51e9dc8860140 100644 (file)
@@ -24,9 +24,9 @@ import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
 import com.vaadin.terminal.gwt.client.VTooltip;
 
 /**
index 8eabf6c625a90de2371bfa6e462794d19bf230f2..e3aba2109678a1130ee91320d79c08ffe69cba36 100644 (file)
@@ -640,6 +640,11 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
 
             String ownAppId = connection.getConfiguration().getRootPanelId();
 
+            // Hiding elements causes browser to forget scroll position -> must
+            // save values and restore when the elements are visible again #7976
+            int originalScrollTop = Window.getScrollTop();
+            int originalScrollLeft = Window.getScrollLeft();
+
             // Set display: none for all Vaadin apps
             for (int i = 0; i < vaadinApps.size(); i++) {
                 String appId = vaadinApps.get(i);
@@ -678,6 +683,9 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
                 }
             }
 
+            // Scroll back to original location
+            Window.scrollTo(originalScrollLeft, originalScrollTop);
+
             return w;
         }
 
index c1ef2bbac404017da72c9e181fa6e0b474b88e55..95ab0dc7735eab7cb9d19fa881bc81caf3d19a82 100644 (file)
@@ -140,6 +140,7 @@ public class VWindow extends VOverlay implements Container,
 
     private Element modalityCurtain;
     private Element draggingCurtain;
+    private Element resizingCurtain;
 
     private Element headerText;
 
@@ -568,12 +569,17 @@ public class VWindow extends VOverlay implements Container,
 
         this.draggable = draggable;
 
+        setCursorProperties();
+    }
+
+    private void setCursorProperties() {
         if (!this.draggable) {
             header.getStyle().setProperty("cursor", "default");
+            footer.getStyle().setProperty("cursor", "default");
         } else {
             header.getStyle().setProperty("cursor", "");
+            footer.getStyle().setProperty("cursor", "");
         }
-
     }
 
     private void setNaturalWidth() {
@@ -703,28 +709,62 @@ public class VWindow extends VOverlay implements Container,
     }
 
     /*
-     * Shows (or hides) an empty div on top of all other content; used when
-     * resizing or moving, so that iframes (etc) do not steal event.
+     * Shows an empty div on top of all other content; used when moving, so that
+     * iframes (etc) do not steal event.
      */
-    private void showDraggingCurtain(boolean show) {
-        if (show && draggingCurtain == null) {
+    private void showDraggingCurtain() {
+        DOM.appendChild(RootPanel.getBodyElement(), getDraggingCurtain());
+    }
 
-            draggingCurtain = DOM.createDiv();
-            DOM.setStyleAttribute(draggingCurtain, "position", "absolute");
-            DOM.setStyleAttribute(draggingCurtain, "top", "0px");
-            DOM.setStyleAttribute(draggingCurtain, "left", "0px");
-            DOM.setStyleAttribute(draggingCurtain, "width", "100%");
-            DOM.setStyleAttribute(draggingCurtain, "height", "100%");
-            DOM.setStyleAttribute(draggingCurtain, "zIndex", ""
-                    + VOverlay.Z_INDEX);
+    private void hideDraggingCurtain() {
+        if (draggingCurtain != null) {
+            DOM.removeChild(RootPanel.getBodyElement(), draggingCurtain);
+        }
+    }
 
-            DOM.appendChild(RootPanel.getBodyElement(), draggingCurtain);
-        } else if (!show && draggingCurtain != null) {
+    /*
+     * Shows an empty div on top of all other content; used when resizing, so
+     * that iframes (etc) do not steal event.
+     */
+    private void showResizingCurtain() {
+        DOM.appendChild(RootPanel.getBodyElement(), getResizingCurtain());
+    }
 
-            DOM.removeChild(RootPanel.getBodyElement(), draggingCurtain);
-            draggingCurtain = null;
+    private void hideResizingCurtain() {
+        if (resizingCurtain != null) {
+            DOM.removeChild(RootPanel.getBodyElement(), resizingCurtain);
         }
+    }
+
+    private Element getDraggingCurtain() {
+        if (draggingCurtain == null) {
+            draggingCurtain = createCurtain();
+            draggingCurtain.setClassName(CLASSNAME + "-draggingCurtain");
+        }
+
+        return draggingCurtain;
+    }
+
+    private Element getResizingCurtain() {
+        if (resizingCurtain == null) {
+            resizingCurtain = createCurtain();
+            resizingCurtain.setClassName(CLASSNAME + "-resizingCurtain");
+        }
+
+        return resizingCurtain;
+    }
+
+    private Element createCurtain() {
+        Element curtain = DOM.createDiv();
+
+        DOM.setStyleAttribute(curtain, "position", "absolute");
+        DOM.setStyleAttribute(curtain, "top", "0px");
+        DOM.setStyleAttribute(curtain, "left", "0px");
+        DOM.setStyleAttribute(curtain, "width", "100%");
+        DOM.setStyleAttribute(curtain, "height", "100%");
+        DOM.setStyleAttribute(curtain, "zIndex", "" + VOverlay.Z_INDEX);
 
+        return curtain;
     }
 
     private void setResizable(boolean resizability) {
@@ -844,7 +884,7 @@ public class VWindow extends VOverlay implements Container,
                 if (!isActive()) {
                     bringToFront();
                 }
-                showDraggingCurtain(true);
+                showResizingCurtain();
                 if (BrowserInfo.get().isIE()) {
                     DOM.setStyleAttribute(resizeBox, "visibility", "hidden");
                 }
@@ -862,7 +902,7 @@ public class VWindow extends VOverlay implements Container,
             case Event.ONTOUCHCANCEL:
                 DOM.releaseCapture(getElement());
             case Event.ONLOSECAPTURE:
-                showDraggingCurtain(false);
+                hideResizingCurtain();
                 if (BrowserInfo.get().isIE()) {
                     DOM.setStyleAttribute(resizeBox, "visibility", "");
                 }
@@ -1097,7 +1137,7 @@ public class VWindow extends VOverlay implements Container,
 
     private void beginMovingWindow(Event event) {
         if (draggable) {
-            showDraggingCurtain(true);
+            showDraggingCurtain();
             dragging = true;
             startX = Util.getTouchOrMouseClientX(event);
             startY = Util.getTouchOrMouseClientY(event);
@@ -1110,7 +1150,7 @@ public class VWindow extends VOverlay implements Container,
 
     private void stopMovingWindow() {
         dragging = false;
-        showDraggingCurtain(false);
+        hideDraggingCurtain();
         DOM.releaseCapture(getElement());
     }
 
index 09f435227dbdb8859d6ad2501c6a7c6fe056837c..8828582b5711201398a1c70045ce1a9f41b986b9 100644 (file)
@@ -34,15 +34,10 @@ public class VLabel extends HTML {
     public void onBrowserEvent(Event event) {
         super.onBrowserEvent(event);
         if (event.getTypeInt() == Event.ONLOAD) {
-            // FIXME: Should not be here but in paintable
             Util.notifyParentOfSizeChange(this, true);
-            event.cancelBubble(true);
+            event.stopPropagation();
             return;
         }
-        // FIXME: Move to paintable
-        // if (client != null) {
-        // client.handleTooltipEvent(event, this);
-        // }
     }
 
     @Override
index 796bce265e0c978173c649ef885c8f2497b80baf..269afde25d62a31de36ee5d4f8d0da10fa46d48a 100644 (file)
@@ -6,27 +6,21 @@ package com.vaadin.terminal.gwt.client.ui.label;
 import com.google.gwt.core.client.GWT;\r
 import com.google.gwt.dom.client.Document;\r
 import com.google.gwt.dom.client.PreElement;\r
+import com.google.gwt.user.client.ui.Widget;\r
 import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
 import com.vaadin.terminal.gwt.client.UIDL;\r
 import com.vaadin.terminal.gwt.client.Util;\r
-import com.vaadin.terminal.gwt.client.VPaintableWidget;\r
-\r
-public class VLabelPaintable implements VPaintableWidget {\r
-\r
-    private VLabel widget = GWT.create(VLabel.class);\r
-    private ApplicationConnection client;\r
+import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;\r
 \r
+public class VLabelPaintable extends VAbstractPaintableWidget {\r
     public VLabelPaintable() {\r
     }\r
 \r
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
-\r
-        if (client.updateComponent(getWidgetForPaintable(), uidl, true)) {\r
+        if (client.updateComponent(this, uidl, true)) {\r
             return;\r
         }\r
 \r
-        this.client = client;\r
-\r
         boolean sinkOnloads = false;\r
 \r
         final String mode = uidl.getStringAttribute("mode");\r
@@ -64,8 +58,14 @@ public class VLabelPaintable implements VPaintableWidget {
         }\r
     }\r
 \r
+    @Override\r
+    protected Widget createWidget() {\r
+        return GWT.create(VLabel.class);\r
+    }\r
+\r
+    @Override\r
     public VLabel getWidgetForPaintable() {\r
-        return widget;\r
+        return (VLabel) super.getWidgetForPaintable();\r
     }\r
 \r
 }\r
index de114e996eed05afd131df579b7722d51fdd6f34..318bcd7ea2aceacba99d94d1d0c8669ca82dce9a 100644 (file)
@@ -1334,9 +1334,12 @@ public abstract class AbstractComponent implements Component, MethodEventSource
     /*
      * (non-Javadoc)
      * 
-     * @see com.vaadin.terminal.Sizeable#setHeight(float, int)
+     * @see com.vaadin.terminal.Sizeable#setHeight(float, Unit)
      */
     public void setHeight(float height, Unit unit) {
+        if (unit == null) {
+            throw new IllegalArgumentException("Unit can not be null");
+        }
         this.height = height;
         heightUnit = unit;
         requestRepaint();
@@ -1366,9 +1369,12 @@ public abstract class AbstractComponent implements Component, MethodEventSource
     /*
      * (non-Javadoc)
      * 
-     * @see com.vaadin.terminal.Sizeable#setWidth(float, int)
+     * @see com.vaadin.terminal.Sizeable#setWidth(float, Unit)
      */
     public void setWidth(float width, Unit unit) {
+        if (unit == null) {
+            throw new IllegalArgumentException("Unit can not be null");
+        }
         this.width = width;
         widthUnit = unit;
         requestRepaint();
index b65cb61450595376783b8a4e553f571c8c501d04..5e086f0b8d216450439458af062287a7a8735c07 100644 (file)
@@ -61,41 +61,85 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
         Container.PropertySetChangeNotifier, Container.ItemSetChangeNotifier,
         Container.ItemSetChangeListener {
 
+    public enum ItemCaptionMode {
+        /**
+         * Item caption mode: Item's ID's <code>String</code> representation is
+         * used as caption.
+         */
+        ID,
+        /**
+         * Item caption mode: Item's <code>String</code> representation is used
+         * as caption.
+         */
+        ITEM,
+        /**
+         * Item caption mode: Index of the item is used as caption. The index
+         * mode can only be used with the containers implementing the
+         * {@link com.vaadin.data.Container.Indexed} interface.
+         */
+        INDEX,
+        /**
+         * Item caption mode: If an Item has a caption it's used, if not, Item's
+         * ID's <code>String</code> representation is used as caption. <b>This
+         * is the default</b>.
+         */
+        EXPLICIT_DEFAULTS_ID,
+        /**
+         * Item caption mode: Captions must be explicitly specified.
+         */
+        EXPLICIT,
+        /**
+         * Item caption mode: Only icons are shown, captions are hidden.
+         */
+        ICON_ONLY,
+        /**
+         * Item caption mode: Item captions are read from property specified
+         * with <code>setItemCaptionPropertyId</code>.
+         */
+        PROPERTY;
+    }
+
     /**
-     * Item caption mode: Item's ID's <code>String</code> representation is used
-     * as caption.
+     * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
      */
-    public static final int ITEM_CAPTION_MODE_ID = 0;
+    @Deprecated
+    public static final ItemCaptionMode ITEM_CAPTION_MODE_ID = ItemCaptionMode.ID;
+
     /**
-     * Item caption mode: Item's <code>String</code> representation is used as
-     * caption.
+     * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
      */
-    public static final int ITEM_CAPTION_MODE_ITEM = 1;
+    @Deprecated
+    public static final ItemCaptionMode ITEM_CAPTION_MODE_ITEM = ItemCaptionMode.ITEM;
+
     /**
-     * Item caption mode: Index of the item is used as caption. The index mode
-     * can only be used with the containers implementing the
-     * {@link com.vaadin.data.Container.Indexed} interface.
+     * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
      */
-    public static final int ITEM_CAPTION_MODE_INDEX = 2;
+    @Deprecated
+    public static final ItemCaptionMode ITEM_CAPTION_MODE_INDEX = ItemCaptionMode.INDEX;
+
     /**
-     * Item caption mode: If an Item has a caption it's used, if not, Item's
-     * ID's <code>String</code> representation is used as caption. <b>This is
-     * the default</b>.
+     * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
      */
-    public static final int ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID = 3;
+    @Deprecated
+    public static final ItemCaptionMode ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID = ItemCaptionMode.EXPLICIT_DEFAULTS_ID;
+
     /**
-     * Item caption mode: Captions must be explicitly specified.
+     * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
      */
-    public static final int ITEM_CAPTION_MODE_EXPLICIT = 4;
+    @Deprecated
+    public static final ItemCaptionMode ITEM_CAPTION_MODE_EXPLICIT = ItemCaptionMode.EXPLICIT;
+
     /**
-     * Item caption mode: Only icons are shown, captions are hidden.
+     * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
      */
-    public static final int ITEM_CAPTION_MODE_ICON_ONLY = 5;
+    @Deprecated
+    public static final ItemCaptionMode ITEM_CAPTION_MODE_ICON_ONLY = ItemCaptionMode.ICON_ONLY;
+
     /**
-     * Item caption mode: Item captions are read from property specified with
-     * <code>setItemCaptionPropertyId</code>.
+     * @deprecated from 7.0, use {@link ItemCaptionMode.ID} instead
      */
-    public static final int ITEM_CAPTION_MODE_PROPERTY = 6;
+    @Deprecated
+    public static final ItemCaptionMode ITEM_CAPTION_MODE_PROPERTY = ItemCaptionMode.PROPERTY;
 
     /**
      * Interface for option filtering, used to filter options based on user
@@ -175,7 +219,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
     /**
      * Item caption mode.
      */
-    private int itemCaptionMode = ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID;
+    private ItemCaptionMode itemCaptionMode = ItemCaptionMode.EXPLICIT_DEFAULTS_ID;
 
     /**
      * Item caption source property id.
@@ -1038,11 +1082,11 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
 
         switch (getItemCaptionMode()) {
 
-        case ITEM_CAPTION_MODE_ID:
+        case ID:
             caption = itemId.toString();
             break;
 
-        case ITEM_CAPTION_MODE_INDEX:
+        case INDEX:
             if (items instanceof Container.Indexed) {
                 caption = String.valueOf(((Container.Indexed) items)
                         .indexOfId(itemId));
@@ -1051,25 +1095,25 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
             }
             break;
 
-        case ITEM_CAPTION_MODE_ITEM:
+        case ITEM:
             final Item i = getItem(itemId);
             if (i != null) {
                 caption = i.toString();
             }
             break;
 
-        case ITEM_CAPTION_MODE_EXPLICIT:
+        case EXPLICIT:
             caption = itemCaptions.get(itemId);
             break;
 
-        case ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID:
+        case EXPLICIT_DEFAULTS_ID:
             caption = itemCaptions.get(itemId);
             if (caption == null) {
                 caption = itemId.toString();
             }
             break;
 
-        case ITEM_CAPTION_MODE_PROPERTY:
+        case PROPERTY:
             final Property<?> p = getContainerProperty(itemId,
                     getItemCaptionPropertyId());
             if (p != null) {
@@ -1086,7 +1130,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
     }
 
     /**
-     * Sets the icon for an item.
+     * Sets tqhe icon for an item.
      * 
      * @param itemId
      *            the id of the item to be assigned an icon.
@@ -1163,8 +1207,8 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
      * @param mode
      *            the One of the modes listed above.
      */
-    public void setItemCaptionMode(int mode) {
-        if (ITEM_CAPTION_MODE_ID <= mode && mode <= ITEM_CAPTION_MODE_PROPERTY) {
+    public void setItemCaptionMode(ItemCaptionMode mode) {
+        if (mode != null) {
             itemCaptionMode = mode;
             requestRepaint();
         }
@@ -1198,7 +1242,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
      * 
      * @return the One of the modes listed above.
      */
-    public int getItemCaptionMode() {
+    public ItemCaptionMode getItemCaptionMode() {
         return itemCaptionMode;
     }
 
@@ -1689,7 +1733,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
 
         public void addNotifierForItem(Object itemId) {
             switch (getItemCaptionMode()) {
-            case ITEM_CAPTION_MODE_ITEM:
+            case ITEM:
                 final Item i = getItem(itemId);
                 if (i == null) {
                     return;
@@ -1713,7 +1757,7 @@ public abstract class AbstractSelect extends AbstractField<Object> implements
 
                 }
                 break;
-            case ITEM_CAPTION_MODE_PROPERTY:
+            case PROPERTY:
                 final Property<?> p = getContainerProperty(itemId,
                         getItemCaptionPropertyId());
                 if (p != null && p instanceof Property.ValueChangeNotifier) {
index 7c0811008a32b41772b3e588066c9fc64f42e1b1..9910f3a4c43e8f09139d85cce550102af0b9830c 100644 (file)
@@ -24,6 +24,7 @@ import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.ui.VButton;
 import com.vaadin.terminal.gwt.client.ui.VButton.ButtonClientToServerRpc;
+import com.vaadin.terminal.gwt.client.ui.VButtonPaintable;
 import com.vaadin.terminal.gwt.server.RpcTarget;
 import com.vaadin.tools.ReflectTools;
 import com.vaadin.ui.ClientWidget.LoadStyle;
@@ -38,7 +39,7 @@ import com.vaadin.ui.Component.Focusable;
  * @since 3.0
  */
 @SuppressWarnings("serial")
-@ClientWidget(value = VButton.class, loadStyle = LoadStyle.EAGER)
+@ClientWidget(value = VButtonPaintable.class, loadStyle = LoadStyle.EAGER)
 public class Button extends AbstractComponent implements
         FieldEvents.BlurNotifier, FieldEvents.FocusNotifier, Focusable,
         Action.ShortcutNotifier, RpcTarget {
index 53fdfdb4ffc39a0d73ff14da945c77611b50c337..1289b57bd98dd3a62c41f8853ef00b41c6842043 100644 (file)
@@ -11,7 +11,6 @@ import java.util.EventObject;
 import java.util.Locale;
 
 import com.vaadin.Application;
-import com.vaadin.data.Property;
 import com.vaadin.event.FieldEvents;
 import com.vaadin.terminal.ErrorMessage;
 import com.vaadin.terminal.Paintable;
@@ -363,12 +362,6 @@ public interface Component extends Paintable, VariableOwner, Sizeable,
      * </p>
      * 
      * <p>
-     * The read-only status affects only the user; the value can still be
-     * changed programmatically, for example, with
-     * {@link Property#setValue(Object)}.
-     * </p>
-     * 
-     * <p>
      * The method will return {@code true} if the component or any of its
      * parents is in the read-only mode.
      * </p>
@@ -396,12 +389,6 @@ public interface Component extends Paintable, VariableOwner, Sizeable,
      * </p>
      * 
      * <p>
-     * The read-only status affects only the user; the value can still be
-     * changed programmatically, for example, with
-     * {@link Property#setValue(Object)}.
-     * </p>
-     * 
-     * <p>
      * This method will trigger a
      * {@link com.vaadin.terminal.Paintable.RepaintRequestEvent
      * RepaintRequestEvent}.
index b952609b20ba45b05051aa40648c71ad88cc7c20..b9432df6b60b5f9d7dcea7224ea4563b00555cae 100644 (file)
@@ -125,7 +125,7 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
         // see ticket #7668
         if (c.getParent() == this) {
             // When c is removed, all components after it are shifted down
-            if (index > components.indexOf(c)) {
+            if (index > getComponentIndex(c)) {
                 index--;
             }
             removeComponent(c);
@@ -275,4 +275,28 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier {
         removeListener(CLICK_EVENT, LayoutClickEvent.class, listener);
     }
 
+    /**
+     * Returns the index of the given component.
+     * 
+     * @param component
+     *            The component to look up.
+     * @return The index of the component or -1 if the component is not a child.
+     */
+    public int getComponentIndex(Component component) {
+        return components.indexOf(component);
+    }
+
+    /**
+     * Returns the component at the given position.
+     * 
+     * @param index
+     *            The position of the component.
+     * @return The component at the given index.
+     * @throws IndexOutOfBoundsException
+     *             If the index is out of range.
+     */
+    public Component getComponent(int index) throws IndexOutOfBoundsException {
+        return components.get(index);
+    }
+
 }
index 7ed432a12b3c498745660de75f43a7f12be48982..54a094a4e75f1b99989f60156d7490d1171a34d2 100644 (file)
@@ -14,6 +14,7 @@ import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
 import com.vaadin.terminal.gwt.client.ui.VMenuBar;
+import com.vaadin.terminal.gwt.client.ui.VMenuBarPaintable;
 import com.vaadin.ui.ClientWidget.LoadStyle;
 
 /**
@@ -24,7 +25,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
  * </p>
  */
 @SuppressWarnings("serial")
-@ClientWidget(value = VMenuBar.class, loadStyle = LoadStyle.LAZY)
+@ClientWidget(value = VMenuBarPaintable.class, loadStyle = LoadStyle.LAZY)
 public class MenuBar extends AbstractComponent {
 
     // Items of the top-level menu
index 46d13c41503377115109538d980db7945ff52cfc..b7b7fcb38ca60cfc070bfef0750e09950fef2c6f 100644 (file)
@@ -3,10 +3,10 @@
  */
 package com.vaadin.ui;
 
-import com.vaadin.terminal.gwt.client.ui.VNativeButton;
+import com.vaadin.terminal.gwt.client.ui.VNativeButtonPaintable;
 
 @SuppressWarnings("serial")
-@ClientWidget(VNativeButton.class)
+@ClientWidget(VNativeButtonPaintable.class)
 public class NativeButton extends Button {
 
     public NativeButton() {
index 8b9dc3ef81144276165a5d815630a77747773caf..003ef6978c95787ef3e52b1c98f7dd30c6391422 100644 (file)
@@ -47,6 +47,7 @@ import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.ui.VScrollTable;
+import com.vaadin.terminal.gwt.client.ui.VScrollTablePaintable;
 import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers;
 
 /**
@@ -73,7 +74,7 @@ import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers;
  * @since 3.0
  */
 @SuppressWarnings({ "deprecation" })
-@ClientWidget(VScrollTable.class)
+@ClientWidget(VScrollTablePaintable.class)
 public class Table extends AbstractSelect implements Action.Container,
         Container.Ordered, Container.Sortable, ItemClickSource,
         ItemClickNotifier, DragSource, DropTarget {
@@ -115,91 +116,215 @@ public class Table extends AbstractSelect implements Action.Container,
 
     protected static final int CELL_FIRSTCOL = 5;
 
+    public enum Align {
+        /**
+         * Left column alignment. <b>This is the default behaviour. </b>
+         */
+        LEFT("b"),
+
+        /**
+         * Center column alignment.
+         */
+        CENTER("c"),
+
+        /**
+         * Right column alignment.
+         */
+        RIGHT("e");
+
+        private String alignment;
+
+        private Align(String alignment) {
+            this.alignment = alignment;
+        }
+
+        @Override
+        public String toString() {
+            return alignment;
+        }
+
+        public Align convertStringToAlign(String string) {
+            if (string == null) {
+                return null;
+            }
+            if (string.equals("b")) {
+                return Align.LEFT;
+            } else if (string.equals("c")) {
+                return Align.CENTER;
+            } else if (string.equals("e")) {
+                return Align.RIGHT;
+            } else {
+                return null;
+            }
+        }
+    }
+
     /**
-     * Left column alignment. <b>This is the default behaviour. </b>
+     * @deprecated from 7.0, use {@link Align#LEFT} instead
      */
-    public static final String ALIGN_LEFT = "b";
+    @Deprecated
+    public static final Align ALIGN_LEFT = Align.LEFT;
 
     /**
-     * Center column alignment.
+     * @deprecated from 7.0, use {@link Align#CENTER} instead
      */
-    public static final String ALIGN_CENTER = "c";
+    @Deprecated
+    public static final Align ALIGN_CENTER = Align.CENTER;
 
     /**
-     * Right column alignment.
+     * @deprecated from 7.0, use {@link Align#RIGHT} instead
      */
-    public static final String ALIGN_RIGHT = "e";
+    @Deprecated
+    public static final Align ALIGN_RIGHT = Align.RIGHT;
+
+    public enum ColumnHeaderMode {
+        /**
+         * Column headers are hidden.
+         */
+        HIDDEN,
+        /**
+         * Property ID:s are used as column headers.
+         */
+        ID,
+        /**
+         * Column headers are explicitly specified with
+         * {@link #setColumnHeaders(String[])}.
+         */
+        EXPLICIT,
+        /**
+         * Column headers are explicitly specified with
+         * {@link #setColumnHeaders(String[])}. If a header is not specified for
+         * a given property, its property id is used instead.
+         * <p>
+         * <b>This is the default behavior. </b>
+         */
+        EXPLICIT_DEFAULTS_ID
+    }
 
     /**
-     * Column header mode: Column headers are hidden.
+     * @deprecated from 7.0, use {@link ColumnHeaderMode#HIDDEN} instead
      */
-    public static final int COLUMN_HEADER_MODE_HIDDEN = -1;
+    @Deprecated
+    public static final ColumnHeaderMode COLUMN_HEADER_MODE_HIDDEN = ColumnHeaderMode.HIDDEN;
 
     /**
-     * Column header mode: Property ID:s are used as column headers.
+     * @deprecated from 7.0, use {@link ColumnHeaderMode#ID} instead
      */
-    public static final int COLUMN_HEADER_MODE_ID = 0;
+    @Deprecated
+    public static final ColumnHeaderMode COLUMN_HEADER_MODE_ID = ColumnHeaderMode.ID;
 
     /**
-     * Column header mode: Column headers are explicitly specified with
-     * {@link #setColumnHeaders(String[])}.
+     * @deprecated from 7.0, use {@link ColumnHeaderMode#EXPLICIT} instead
      */
-    public static final int COLUMN_HEADER_MODE_EXPLICIT = 1;
+    @Deprecated
+    public static final ColumnHeaderMode COLUMN_HEADER_MODE_EXPLICIT = ColumnHeaderMode.EXPLICIT;
 
     /**
-     * Column header mode: Column headers are explicitly specified with
-     * {@link #setColumnHeaders(String[])}. If a header is not specified for a
-     * given property, its property id is used instead.
-     * <p>
-     * <b>This is the default behavior. </b>
+     * @deprecated from 7.0, use {@link ColumnHeaderMode#EXPLICIT_DEFAULTS_ID}
+     *             instead
      */
-    public static final int COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID = 2;
+    @Deprecated
+    public static final ColumnHeaderMode COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID = ColumnHeaderMode.EXPLICIT_DEFAULTS_ID;
+
+    public enum RowHeaderMode {
+        /**
+         * Row caption mode: The row headers are hidden. <b>This is the default
+         * mode. </b>
+         */
+        HIDDEN(null),
+        /**
+         * Row caption mode: Items Id-objects toString is used as row caption.
+         */
+        ID(ItemCaptionMode.ID),
+        /**
+         * Row caption mode: Item-objects toString is used as row caption.
+         */
+        ITEM(ItemCaptionMode.ITEM),
+        /**
+         * Row caption mode: Index of the item is used as item caption. The
+         * index mode can only be used with the containers implementing the
+         * {@link com.vaadin.data.Container.Indexed} interface.
+         */
+        INDEX(ItemCaptionMode.INDEX),
+        /**
+         * Row caption mode: Item captions are explicitly specified, but if the
+         * caption is missing, the item id objects <code>toString()</code> is
+         * used instead.
+         */
+        EXPLICIT_DEFAULTS_ID(ItemCaptionMode.EXPLICIT_DEFAULTS_ID),
+        /**
+         * Row caption mode: Item captions are explicitly specified.
+         */
+        EXPLICIT(ItemCaptionMode.EXPLICIT),
+        /**
+         * Row caption mode: Only icons are shown, the captions are hidden.
+         */
+        ICON_ONLY(ItemCaptionMode.ICON_ONLY),
+        /**
+         * Row caption mode: Item captions are read from property specified with
+         * {@link #setItemCaptionPropertyId(Object)}.
+         */
+        PROPERTY(ItemCaptionMode.PROPERTY);
+
+        ItemCaptionMode mode;
+
+        private RowHeaderMode(ItemCaptionMode mode) {
+            this.mode = mode;
+        }
+
+        public ItemCaptionMode getItemCaptionMode() {
+            return mode;
+        }
+    }
 
     /**
-     * Row caption mode: The row headers are hidden. <b>This is the default
-     * mode. </b>
+     * @deprecated from 7.0, use {@link RowHeaderMode#HIDDEN} instead
      */
-    public static final int ROW_HEADER_MODE_HIDDEN = -1;
+    @Deprecated
+    public static final RowHeaderMode ROW_HEADER_MODE_HIDDEN = RowHeaderMode.HIDDEN;
 
     /**
-     * Row caption mode: Items Id-objects toString is used as row caption.
+     * @deprecated from 7.0, use {@link RowHeaderMode#ID} instead
      */
-    public static final int ROW_HEADER_MODE_ID = AbstractSelect.ITEM_CAPTION_MODE_ID;
+    @Deprecated
+    public static final RowHeaderMode ROW_HEADER_MODE_ID = RowHeaderMode.ID;
 
     /**
-     * Row caption mode: Item-objects toString is used as row caption.
+     * @deprecated from 7.0, use {@link RowHeaderMode#ITEM} instead
      */
-    public static final int ROW_HEADER_MODE_ITEM = AbstractSelect.ITEM_CAPTION_MODE_ITEM;
+    @Deprecated
+    public static final RowHeaderMode ROW_HEADER_MODE_ITEM = RowHeaderMode.ITEM;
 
     /**
-     * Row caption mode: Index of the item is used as item caption. The index
-     * mode can only be used with the containers implementing Container.Indexed
-     * interface.
+     * @deprecated from 7.0, use {@link RowHeaderMode#INDEX} instead
      */
-    public static final int ROW_HEADER_MODE_INDEX = AbstractSelect.ITEM_CAPTION_MODE_INDEX;
+    @Deprecated
+    public static final RowHeaderMode ROW_HEADER_MODE_INDEX = RowHeaderMode.INDEX;
 
     /**
-     * Row caption mode: Item captions are explicitly specified.
+     * @deprecated from 7.0, use {@link RowHeaderMode#EXPLICIT_DEFAULTS_ID}
+     *             instead
      */
-    public static final int ROW_HEADER_MODE_EXPLICIT = AbstractSelect.ITEM_CAPTION_MODE_EXPLICIT;
+    @Deprecated
+    public static final RowHeaderMode ROW_HEADER_MODE_EXPLICIT_DEFAULTS_ID = RowHeaderMode.EXPLICIT_DEFAULTS_ID;
 
     /**
-     * Row caption mode: Item captions are read from property specified with
-     * {@link #setItemCaptionPropertyId(Object)}.
+     * @deprecated from 7.0, use {@link RowHeaderMode#EXPLICIT} instead
      */
-    public static final int ROW_HEADER_MODE_PROPERTY = AbstractSelect.ITEM_CAPTION_MODE_PROPERTY;
+    @Deprecated
+    public static final RowHeaderMode ROW_HEADER_MODE_EXPLICIT = RowHeaderMode.EXPLICIT;
 
     /**
-     * Row caption mode: Only icons are shown, the captions are hidden.
+     * @deprecated from 7.0, use {@link RowHeaderMode#ICON_ONLY} instead
      */
-    public static final int ROW_HEADER_MODE_ICON_ONLY = AbstractSelect.ITEM_CAPTION_MODE_ICON_ONLY;
+    @Deprecated
+    public static final RowHeaderMode ROW_HEADER_MODE_ICON_ONLY = RowHeaderMode.ICON_ONLY;
 
     /**
-     * Row caption mode: Item captions are explicitly specified, but if the
-     * caption is missing, the item id objects <code>toString()</code> is used
-     * instead.
+     * @deprecated from 7.0, use {@link RowHeaderMode#PROPERTY} instead
      */
-    public static final int ROW_HEADER_MODE_EXPLICIT_DEFAULTS_ID = AbstractSelect.ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID;
+    @Deprecated
+    public static final RowHeaderMode ROW_HEADER_MODE_PROPERTY = RowHeaderMode.PROPERTY;
 
     /**
      * The default rate that table caches rows for smooth scrolling.
@@ -254,7 +379,7 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Holds alignments for visible columns (by propertyId).
      */
-    private HashMap<Object, String> columnAlignments = new HashMap<Object, String>();
+    private HashMap<Object, Align> columnAlignments = new HashMap<Object, Align>();
 
     /**
      * Holds column widths in pixels (Integer) or expand ratios (Float) for
@@ -290,17 +415,17 @@ public class Table extends AbstractSelect implements Action.Container,
     /**
      * Holds value of property columnHeaderMode.
      */
-    private int columnHeaderMode = COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID;
+    private ColumnHeaderMode columnHeaderMode = ColumnHeaderMode.EXPLICIT_DEFAULTS_ID;
 
     /**
-     * Should the Table footer be visible?
+     * Holds value of property rowHeaderMode.
      */
-    private boolean columnFootersVisible = false;
+    private RowHeaderMode rowHeaderMode = RowHeaderMode.EXPLICIT_DEFAULTS_ID;
 
     /**
-     * True iff the row captions are hidden.
+     * Should the Table footer be visible?
      */
-    private boolean rowCaptionsAreHidden = true;
+    private boolean columnFootersVisible = false;
 
     /**
      * Page contents buffer used in buffered mode.
@@ -512,7 +637,7 @@ public class Table extends AbstractSelect implements Action.Container,
                     final Object col = i.next();
                     if (!newVC.contains(col)) {
                         setColumnHeader(col, null);
-                        setColumnAlignment(col, null);
+                        setColumnAlignment(col, (Align) null);
                         setColumnIcon(col, null);
                     }
                 }
@@ -656,21 +781,21 @@ public class Table extends AbstractSelect implements Action.Container,
      * {@link #getVisibleColumns()}. The possible values for the alignments
      * include:
      * <ul>
-     * <li>{@link #ALIGN_LEFT}: Left alignment</li>
-     * <li>{@link #ALIGN_CENTER}: Centered</li>
-     * <li>{@link #ALIGN_RIGHT}: Right alignment</li>
+     * <li>{@link Align#LEFT}: Left alignment</li>
+     * <li>{@link Align#CENTER}: Centered</li>
+     * <li>{@link Align#RIGHT}: Right alignment</li>
      * </ul>
-     * The alignments default to {@link #ALIGN_LEFT}: any null values are
+     * The alignments default to {@link Align#LEFT}: any null values are
      * rendered as align lefts.
      * </p>
      * 
      * @return the Column alignments array.
      */
-    public String[] getColumnAlignments() {
+    public Align[] getColumnAlignments() {
         if (columnAlignments == null) {
             return null;
         }
-        final String[] alignments = new String[visibleColumns.size()];
+        final Align[] alignments = new Align[visibleColumns.size()];
         int i = 0;
         for (final Iterator<Object> it = visibleColumns.iterator(); it
                 .hasNext(); i++) {
@@ -684,39 +809,29 @@ public class Table extends AbstractSelect implements Action.Container,
      * Sets the column alignments.
      * 
      * <p>
-     * The items in the array must match the properties identified by
-     * {@link #getVisibleColumns()}. The possible values for the alignments
-     * include:
+     * The amount of items in the array must match the amount of properties
+     * identified by {@link #getVisibleColumns()}. The possible values for the
+     * alignments include:
      * <ul>
-     * <li>{@link #ALIGN_LEFT}: Left alignment</li>
-     * <li>{@link #ALIGN_CENTER}: Centered</li>
-     * <li>{@link #ALIGN_RIGHT}: Right alignment</li>
+     * <li>{@link Align#LEFT}: Left alignment</li>
+     * <li>{@link Align#CENTER}: Centered</li>
+     * <li>{@link Align#RIGHT}: Right alignment</li>
      * </ul>
-     * The alignments default to {@link #ALIGN_LEFT}
+     * The alignments default to {@link Align#LEFT}
      * </p>
      * 
      * @param columnAlignments
      *            the Column alignments array.
      */
-    public void setColumnAlignments(String[] columnAlignments) {
+    public void setColumnAlignments(Align... columnAlignments) {
 
         if (columnAlignments.length != visibleColumns.size()) {
             throw new IllegalArgumentException(
                     "The length of the alignments array must match the number of visible columns");
         }
 
-        // Checks all alignments
-        for (int i = 0; i < columnAlignments.length; i++) {
-            final String a = columnAlignments[i];
-            if (a != null && !a.equals(ALIGN_LEFT) && !a.equals(ALIGN_CENTER)
-                    && !a.equals(ALIGN_RIGHT)) {
-                throw new IllegalArgumentException("Column " + i
-                        + " aligment '" + a + "' is invalid");
-            }
-        }
-
         // Resets the alignments
-        final HashMap<Object, String> newCA = new HashMap<Object, String>();
+        final HashMap<Object, Align> newCA = new HashMap<Object, Align>();
         int i = 0;
         for (final Iterator<Object> it = visibleColumns.iterator(); it
                 .hasNext() && i < columnAlignments.length; i++) {
@@ -1034,13 +1149,13 @@ public class Table extends AbstractSelect implements Action.Container,
      * @return the header for the specified column if it has one.
      */
     public String getColumnHeader(Object propertyId) {
-        if (getColumnHeaderMode() == COLUMN_HEADER_MODE_HIDDEN) {
+        if (getColumnHeaderMode() == ColumnHeaderMode.HIDDEN) {
             return null;
         }
 
         String header = columnHeaders.get(propertyId);
-        if ((header == null && getColumnHeaderMode() == COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID)
-                || getColumnHeaderMode() == COLUMN_HEADER_MODE_ID) {
+        if ((header == null && getColumnHeaderMode() == ColumnHeaderMode.EXPLICIT_DEFAULTS_ID)
+                || getColumnHeaderMode() == ColumnHeaderMode.ID) {
             header = propertyId.toString();
         }
 
@@ -1073,9 +1188,9 @@ public class Table extends AbstractSelect implements Action.Container,
      *            the propertyID identifying the column.
      * @return the specified column's alignment if it as one; null otherwise.
      */
-    public String getColumnAlignment(Object propertyId) {
-        final String a = columnAlignments.get(propertyId);
-        return a == null ? ALIGN_LEFT : a;
+    public Align getColumnAlignment(Object propertyId) {
+        final Align a = columnAlignments.get(propertyId);
+        return a == null ? Align.LEFT : a;
     }
 
     /**
@@ -1083,8 +1198,8 @@ public class Table extends AbstractSelect implements Action.Container,
      * 
      * <p>
      * Throws IllegalArgumentException if the alignment is not one of the
-     * following: {@link #ALIGN_LEFT}, {@link #ALIGN_CENTER} or
-     * {@link #ALIGN_RIGHT}
+     * following: {@link Align#LEFT}, {@link Align#CENTER} or
+     * {@link Align#RIGHT}
      * </p>
      * 
      * @param propertyId
@@ -1092,17 +1207,8 @@ public class Table extends AbstractSelect implements Action.Container,
      * @param alignment
      *            the desired alignment.
      */
-    public void setColumnAlignment(Object propertyId, String alignment) {
-
-        // Checks for valid alignments
-        if (alignment != null && !alignment.equals(ALIGN_LEFT)
-                && !alignment.equals(ALIGN_CENTER)
-                && !alignment.equals(ALIGN_RIGHT)) {
-            throw new IllegalArgumentException("Column alignment '" + alignment
-                    + "' is not supported.");
-        }
-
-        if (alignment == null || alignment.equals(ALIGN_LEFT)) {
+    public void setColumnAlignment(Object propertyId, Align alignment) {
+        if (alignment == null || alignment == Align.LEFT) {
             columnAlignments.remove(propertyId);
         } else {
             columnAlignments.put(propertyId, alignment);
@@ -1397,7 +1503,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * 
      * @return the Value of property columnHeaderMode.
      */
-    public int getColumnHeaderMode() {
+    public ColumnHeaderMode getColumnHeaderMode() {
         return columnHeaderMode;
     }
 
@@ -1407,10 +1513,12 @@ public class Table extends AbstractSelect implements Action.Container,
      * @param columnHeaderMode
      *            the New value of property columnHeaderMode.
      */
-    public void setColumnHeaderMode(int columnHeaderMode) {
-        if (columnHeaderMode != this.columnHeaderMode
-                && columnHeaderMode >= COLUMN_HEADER_MODE_HIDDEN
-                && columnHeaderMode <= COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID) {
+    public void setColumnHeaderMode(ColumnHeaderMode columnHeaderMode) {
+        if (columnHeaderMode == null) {
+            throw new IllegalArgumentException(
+                    "Column header mode can not be null");
+        }
+        if (columnHeaderMode != this.columnHeaderMode) {
             this.columnHeaderMode = columnHeaderMode;
             requestRepaint();
         }
@@ -1750,7 +1858,7 @@ public class Table extends AbstractSelect implements Action.Container,
             }
         }
 
-        final int headmode = getRowHeaderMode();
+        final RowHeaderMode headmode = getRowHeaderMode();
         final boolean[] iscomponent = new boolean[cols];
         for (int i = 0; i < cols; i++) {
             iscomponent[i] = columnGenerators.containsKey(colids[i])
@@ -1771,7 +1879,7 @@ public class Table extends AbstractSelect implements Action.Container,
             cells[CELL_KEY][i] = itemIdMapper.key(id);
             if (headmode != ROW_HEADER_MODE_HIDDEN) {
                 switch (headmode) {
-                case ROW_HEADER_MODE_INDEX:
+                case INDEX:
                     cells[CELL_HEADER][i] = String.valueOf(i + firstIndex + 1);
                     break;
                 default:
@@ -2070,17 +2178,17 @@ public class Table extends AbstractSelect implements Action.Container,
      * @param mode
      *            the One of the modes listed above.
      */
-    public void setRowHeaderMode(int mode) {
-        if (ROW_HEADER_MODE_HIDDEN == mode) {
-            rowCaptionsAreHidden = true;
-        } else {
-            rowCaptionsAreHidden = false;
-            setItemCaptionMode(mode);
+    public void setRowHeaderMode(RowHeaderMode mode) {
+        if (mode != null) {
+            rowHeaderMode = mode;
+            if (mode != RowHeaderMode.HIDDEN) {
+                setItemCaptionMode(mode.getItemCaptionMode());
+            }
+            // Assures the visual refresh. No need to reset the page buffer
+            // before
+            // as the content has not changed, only the alignments.
+            refreshRenderedCells();
         }
-
-        // Assures the visual refresh. No need to reset the page buffer before
-        // as the content has not changed, only the alignments.
-        refreshRenderedCells();
     }
 
     /**
@@ -2089,9 +2197,8 @@ public class Table extends AbstractSelect implements Action.Container,
      * @return the Row header mode.
      * @see #setRowHeaderMode(int)
      */
-    public int getRowHeaderMode() {
-        return rowCaptionsAreHidden ? ROW_HEADER_MODE_HIDDEN
-                : getItemCaptionMode();
+    public RowHeaderMode getRowHeaderMode() {
+        return rowHeaderMode;
     }
 
     /**
@@ -2928,7 +3035,7 @@ public class Table extends AbstractSelect implements Action.Container,
     }
 
     private boolean areColumnHeadersEnabled() {
-        return getColumnHeaderMode() != COLUMN_HEADER_MODE_HIDDEN;
+        return getColumnHeaderMode() != ColumnHeaderMode.HIDDEN;
     }
 
     private void paintVisibleColumns(PaintTarget target) throws PaintException {
@@ -2959,8 +3066,9 @@ public class Table extends AbstractSelect implements Action.Container,
                         target.addAttribute("sortable", true);
                     }
                 }
-                if (!ALIGN_LEFT.equals(getColumnAlignment(colId))) {
-                    target.addAttribute("align", getColumnAlignment(colId));
+                if (!Align.LEFT.equals(getColumnAlignment(colId))) {
+                    target.addAttribute("align", getColumnAlignment(colId)
+                            .toString());
                 }
                 paintColumnWidth(target, colId);
                 target.endTag("column");
@@ -3051,6 +3159,9 @@ public class Table extends AbstractSelect implements Action.Container,
         if (start > cells[CELL_ITEMID].length || start < 0) {
             start = 0;
         }
+        if (end > cells[CELL_ITEMID].length) {
+            end = cells[CELL_ITEMID].length;
+        }
 
         for (int indexInRowbuffer = start; indexInRowbuffer < end; indexInRowbuffer++) {
             final Object itemId = cells[CELL_ITEMID][indexInRowbuffer];
@@ -3721,7 +3832,7 @@ public class Table extends AbstractSelect implements Action.Container,
      */
     public boolean addContainerProperty(Object propertyId, Class<?> type,
             Object defaultValue, String columnHeader, Resource columnIcon,
-            String columnAlignment) throws UnsupportedOperationException {
+            Align columnAlignment) throws UnsupportedOperationException {
         if (!this.addContainerProperty(propertyId, type, defaultValue)) {
             return false;
         }
@@ -5187,4 +5298,13 @@ public class Table extends AbstractSelect implements Action.Container,
         return propertyValueConverters.get(propertyId);
     }
 
+    @Override
+    public void setVisible(boolean visible) {
+        if (!isVisible() && visible) {
+            // We need to ensure that the rows are sent to the client when the
+            // Table is made visible if it has been rendered as invisible.
+            setRowCacheInvalidated(true);
+        }
+        super.setVisible(visible);
+    }
 }
index 43bc7a80fe19c4917234e9baf027ab996fedce94..09417e1e16b71618abadd76ad7dc075f69132d0c 100644 (file)
@@ -22,7 +22,7 @@ import com.vaadin.data.util.HierarchicalContainer;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.gwt.client.ui.VTreeTable;
+import com.vaadin.terminal.gwt.client.ui.VTreeTablePaintable;
 import com.vaadin.ui.Tree.CollapseEvent;
 import com.vaadin.ui.Tree.CollapseListener;
 import com.vaadin.ui.Tree.ExpandEvent;
@@ -48,7 +48,7 @@ import com.vaadin.ui.treetable.HierarchicalContainerOrderedWrapper;
  * share UI state in the container.
  */
 @SuppressWarnings({ "serial" })
-@ClientWidget(VTreeTable.class)
+@ClientWidget(VTreeTablePaintable.class)
 public class TreeTable extends Table implements Hierarchical {
 
     private static final Logger logger = Logger.getLogger(TreeTable.class
@@ -454,7 +454,8 @@ public class TreeTable extends Table implements Hierarchical {
                 Object object = visibleColumns2[i];
                 if (hierarchyColumnId.equals(object)) {
                     target.addAttribute(
-                            VTreeTable.ATTRIBUTE_HIERARCHY_COLUMN_INDEX, i);
+                            VTreeTablePaintable.ATTRIBUTE_HIERARCHY_COLUMN_INDEX,
+                            i);
                     break;
                 }
             }
index 6b78acb590b1f75d6afa21dd21dba99a443576f2..115a8fef79aef906af1ed370bd2f81a04aefce34 100644 (file)
@@ -8,7 +8,7 @@ if lockfile -r0 -! /home/integration/deploy/lock.file &> /dev/null
 
   AGE=$[($DATE - $LOCK_AGE)/60]
 
-  if [ "$AGE" -gt "15" ]
+  if [ "$AGE" -gt "20" ]
     then
      echo lock.file is $AGE min old.
      ./cleanup.sh
index 60e4882044facc558f91c7621670324bbee73170..1b37347dddb748430b858de04c3438e3b8a506f4 100644 (file)
@@ -7,20 +7,20 @@
     <import file="../build/common.xml" />\r
 \r
        <!-- Target deploying demo.war -->\r
-       <fail unless="test.integration.server" message="test.integration.server must be set for integration tests to run"/>\r
-       \r
-       <fail unless="test.integration.user" message="test.integration.user must be set for integration tests to run"/>\r
-       <fail unless="test.integration.antfile" message="test.integration.antfile must be set for integration tests to run"/>\r
+       <fail unless="test.integration.server" message="test.integration.server must be set for integration tests to run" />\r
+\r
+       <fail unless="test.integration.user" message="test.integration.user must be set for integration tests to run" />\r
+       <fail unless="test.integration.antfile" message="test.integration.antfile must be set for integration tests to run" />\r
 \r
        <!-- Test with these browsers -->\r
        <property name="test_browsers" value="winxp-firefox9" />\r
 \r
        <!-- Path to key file. Default value -->\r
        <property name="sshkey.file" value="id_dsa" />\r
-       \r
+\r
        <!-- path and name for demo.war to be deployed -->\r
-       <property name="demo.war" value="demo.war"/>\r
-       \r
+       <property name="demo.war" value="demo.war" />\r
+\r
        <!-- Host running Testbench RC or Testbench Hub. Default value -->\r
        <property name="com.vaadin.testbench.tester.host" value="127.0.0.1" />\r
 \r
@@ -36,7 +36,7 @@
        <target name="integration-test-upload-demo">\r
                <scp file="${demo.war}" todir="${user}@${test.integration.server}:integration-tests/servers/demo.war" keyfile="${sshkey.file}" passphrase="${passphrase}" />\r
        </target>\r
-       \r
+\r
        <!-- Run basic integration test test -->\r
        <target name="integration-test-servlet">\r
                <fileset dir="integration-testscripts" id="html-test-files" includes="integration-test-${server-name}-servlet.html" />\r
                        <property name="testfiles" value="${testfiles}" />\r
                        <property name="test-output-dir" value="../build/integration-test-output/${server-name}" />\r
                        <property name="retries" value="0" />\r
-                       \r
+\r
                        <fileset dir="." includes="test.xml" />\r
                </subant>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-theme">\r
                <subant target="run-tests" failonerror="false" antfile="test.xml">\r
                        <property name="com.vaadin.testbench.lib.dir" value="${com.vaadin.testbench.lib.dir}" />\r
                        <property name="server.start.succeeded" value="1" />\r
                        <property name="testfiles" value="${testfiles-theme}" />\r
                        <property name="test-output-dir" value="../build/integration-test-output/${server-name}" />\r
-               \r
+\r
                        <fileset dir="." includes="test.xml" />\r
                </subant>\r
        </target>\r
-       \r
+\r
        <!-- Run integration test on GAE -->\r
        <target name="integration-test-test-GAE">\r
                <fileset dir="integration-testscripts" id="html-test-files" includes="GoogleAppEngine/integration-test-GAE.html" />\r
                <pathconvert pathsep=" " property="test-GAE" refid="html-test-files" />\r
-               \r
+\r
                <subant target="run-tests" failonerror="false" antfile="test.xml">\r
                        <property name="com.vaadin.testbench.lib.dir" value="${com.vaadin.testbench.lib.dir}" />\r
                        <property name="com.vaadin.testbench.tester.host" value="${com.vaadin.testbench.tester.host}" />\r
                        <property name="browsers" value="${test_browsers}" />\r
                        <property name="testfiles" value="${test-GAE}" />\r
                        <property name="test-output-dir" value="../build/integration-test-gae-output" />\r
-                       \r
+\r
                        <fileset dir="." includes="test.xml" />\r
                </subant>\r
        </target>\r
-               \r
+\r
        <target name="integration-test-deploy-to-GAE">\r
                <sshexec host="${test.integration.server}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} deploy-to-GAE" />\r
        </target>\r
-                       \r
-       \r
+\r
+\r
        <target name="integration-test-tomcat7">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
+                       <param name="startDelay" value="10" />\r
                        <param name="target-server" value="tomcat7" />\r
                </antcall>\r
        </target>\r
-       \r
        <target name="integration-test-tomcat5">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
+                       <param name="startDelay" value="10" />\r
                        <param name="target-server" value="tomcat5" />\r
                </antcall>\r
-       </target>       \r
-       \r
+       </target>\r
+\r
        <target name="integration-test-tomcat6">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
+                       <param name="startDelay" value="10" />\r
                        <param name="target-server" value="tomcat6" />\r
                </antcall>\r
-       </target>       \r
-       \r
+       </target>\r
+\r
        <target name="integration-test-jetty5">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
                        <param name="target-server" value="jetty5" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-jetty6">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
                        <param name="target-server" value="jetty6" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-jetty7">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
                        <param name="target-server" value="jetty7" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
+       <target name="integration-test-jetty8">\r
+               <antcall target="run-generic-integration-test">\r
+                       <param name="target-server" value="jetty8" />\r
+               </antcall>\r
+       </target>\r
+\r
        <target name="integration-test-jboss4">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
+                       <param name="startDelay" value="10" />\r
                        <param name="target-server" value="jboss4" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-jboss5">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
+                       <param name="startDelay" value="10" />\r
                        <param name="target-server" value="jboss5" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-jboss6">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
+                       <param name="startDelay" value="10" />\r
                        <param name="target-server" value="jboss6" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-jboss7">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
+                       <param name="startDelay" value="10" />\r
                        <param name="target-server" value="jboss7" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-glassfish2">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
+                       <param name="startDelay" value="10" />\r
                        <param name="target-server" value="glassfish2" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-glassfish3">\r
                <antcall target="run-generic-integration-test">\r
-                       <param name="startDelay" value="300" />\r
+                       <param name="startDelay" value="10" />\r
                        <param name="target-server" value="glassfish3" />\r
                </antcall>\r
        </target>\r
-       \r
-       \r
+\r
+\r
        <target name="integration-test-liferay6">\r
                <fileset dir="integration-testscripts" id="html-test-files" includes="Liferay-6/integration-test-liferay-6.0.5.html" />\r
                <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />\r
-               \r
+\r
                <fileset dir="integration-testscripts" id="html-theme-files" includes="Liferay-6/Liferay6-theme.html" />\r
                <pathconvert pathsep=" " property="testfiles-theme" refid="html-theme-files" />\r
-               \r
-               \r
+\r
+\r
                <antcall target="run-generic-integration-test">\r
+                       <param name="startDelay" value="600" />\r
                        <param name="target-server" value="liferay6" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-liferay5">\r
                <fileset dir="integration-testscripts" id="html-test-files" includes="Liferay-5/integration-test-liferay-5.2.3-portlet2.html" />\r
                <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />\r
-               \r
+\r
                <antcall target="run-generic-integration-test">\r
+                       <param name="startDelay" value="600" />\r
                        <param name="target-server" value="liferay5" />\r
                </antcall>\r
        </target>\r
        <target name="integration-test-liferay6ee">\r
                <fileset dir="integration-testscripts" id="html-test-files" includes="Liferay-6EE/integration-test-liferay-6ee.html" />\r
                <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />\r
-               \r
+\r
                <fileset dir="integration-testscripts" id="html-theme-files" includes="Liferay-6EE/Liferay6EE-theme.html" />\r
                <pathconvert pathsep=" " property="testfiles-theme" refid="html-theme-files" />\r
-               \r
+\r
                <antcall target="run-generic-integration-test">\r
+                       <param name="startDelay" value="600" />\r
                        <param name="target-server" value="liferay6ee" />\r
-               </antcall>              \r
+               </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-gatein3">\r
                <fileset dir="integration-testscripts" id="html-test-files" includes="GateIn-3/integration-test-GateIn-3.1.0-portlet2.html" />\r
                <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />\r
                <antcall target="run-generic-integration-test">\r
+                       <param name="startDelay" value="600" />\r
                        <param name="test_browsers" value="winxp-firefox36" />\r
                        <param name="target-server" value="gatein3" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-exo3">\r
                <fileset dir="integration-testscripts" id="html-test-files" includes="eXo-3/integration-test-eXo-3.0.3-portlet2.html" />\r
                <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />\r
                <antcall target="run-generic-integration-test">\r
+                       <param name="startDelay" value="600" />\r
                        <param name="test_browsers" value="winxp-firefox36" />\r
                        <param name="target-server" value="exo3" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-weblogic9">\r
                <antcall target="run-generic-integration-test">\r
+                       <param name="startDelay" value="600" />\r
                        <param name="target-port" value="7001" />\r
                        <param name="target-server" value="weblogic9" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-weblogic10">\r
                <antcall target="run-generic-integration-test">\r
+                       <param name="startDelay" value="600" />\r
                        <param name="target-port" value="7001" />\r
                        <param name="target-server" value="weblogic10" />\r
                </antcall>\r
        </target>\r
-       \r
-       \r
+\r
+       <target name="integration-test-weblogic12">\r
+               <antcall target="run-generic-integration-test">\r
+                       <param name="startDelay" value="600" />\r
+                       <param name="target-port" value="7001" />\r
+                       <param name="target-server" value="weblogic12" />\r
+               </antcall>\r
+       </target>\r
+\r
        <target name="integration-test-weblogicPortal">\r
                <fileset dir="integration-testscripts" id="html-test-files" includes="weblogic-portal/integration-test-WebLogic-Portal-10.3.2-portlet2.html" />\r
                <pathconvert pathsep=" " property="testfiles" refid="html-test-files" />\r
                <antcall target="run-generic-integration-test">\r
+                       <param name="startDelay" value="600" />\r
                        <param name="target-port" value="7001" />\r
                        <param name="target-server" value="weblogicportal" />\r
                </antcall>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-GAE">\r
-               <antcall target="integration-test-deploy-to-GAE"/>\r
+               <antcall target="integration-test-deploy-to-GAE" />\r
                <antcall target="integration-test-test-GAE" />\r
        </target>\r
-                       \r
+\r
        <!-- Upload demo, clean error screenshots and test deployment on all servers -->\r
        <target name="integration-test-all" depends="common.init-deps">\r
-               \r
                <parallel>\r
                        <antcontrib:trycatch property="tried">\r
                                <try>\r
                                        <antcall target="integration-test-get-lock" />\r
                                        <echo message="Got lock" />\r
                                        <antcall target="integration-test-upload-demo" />\r
-       \r
+\r
                                        <antcall target="run-integration-test">\r
-                                               <param name="target-server" value="GAE"/>\r
+                                               <param name="target-server" value="GAE" />\r
                                        </antcall>\r
-                                       \r
+\r
                                        <antcall target="integration-test-clean" />\r
                                        <echo message="Getting lock" />\r
                                        <antcall target="integration-test-release-lock" />\r
                                        <echo message="Lock released" />\r
-                                       \r
+\r
                                </try>\r
                                <catch>\r
                                        <echo message="Uploading of demo.war failed. ${tried}" />\r
                                </catch>\r
                        </antcontrib:trycatch>\r
-                                                       \r
                        <antcall target="integration-test-liferay6" />\r
                        <antcall target="integration-test-liferay6ee" />\r
                        <antcall target="integration-test-exo3" />\r
                        <antcall target="integration-test-liferay5" />\r
                        <antcall target="integration-test-weblogic9" />\r
                        <antcall target="integration-test-weblogic10" />\r
+                       <antcall target="integration-test-weblogic12" />\r
                        <antcall target="integration-test-gatein3" />\r
                        <antcall target="integration-test-glassfish2" />\r
                        <antcall target="integration-test-glassfish3" />\r
                        <antcall target="integration-test-jetty5" />\r
                        <antcall target="integration-test-jetty6" />\r
                        <antcall target="integration-test-jetty7" />\r
+                       <antcall target="integration-test-jetty8" />\r
                        <antcall target="integration-test-tomcat5" />\r
                        <antcall target="integration-test-tomcat6" />\r
                        <antcall target="integration-test-tomcat7" />\r
-                       \r
+\r
                </parallel>\r
-               \r
+\r
        </target>\r
-       \r
+\r
        <target name="do-run-generic-test">\r
                <property name="target-host" value="${target-server}.devnet.vaadin.com" />\r
                <property name="target-port" value="8080" />\r
-               \r
                <antcontrib:if>\r
                        <isset property="startDelay" />\r
                        <then>\r
                                <antcontrib:math result="sleepTime" datatype="int">\r
                                        <op op="rint">\r
                                                <op op="*">\r
-                                                       <num value="${startDelay}"/>\r
-                                                       <op op="random"/>\r
+                                                       <num value="${startDelay}" />\r
+                                                       <op op="random" />\r
                                                </op>\r
                                        </op>\r
                                </antcontrib:math>\r
                                <include name="*" />\r
                        </fileset>\r
                </scp>\r
-               \r
+\r
                <!-- trycatch probably not needed any more as it just fails with the original message and doesn't do anything in the finally block -->\r
                <antcontrib:trycatch property="error_message">\r
                        <try>\r
                                </antcall>\r
 \r
                                <scp file="${demo.war}" todir="${user}@${target-host}:demo.war" keyfile="${sshkey.file}" trust="yes" passphrase="${passphrase}" />\r
-                               \r
+\r
                                <!-- timeout in 15 minutes -->\r
                                <sshexec host="${target-host}" outputproperty="start-output" timeout="900000" username="${user}" keyfile="${sshkey.file}" trust="yes" command="ant -f deploy.xml startup-and-deploy" failonerror="false" />\r
                                <antcall target="echo-prefix">\r
                                        <param name="prefix" value="${target-server}: " />\r
                                        <param name="message" value="${start-output}" />\r
                                </antcall>\r
-                               \r
+\r
                                <fail message="${start-output}">\r
                                        <condition>\r
                                                <not>\r
                                        <param name="server-name" value="${target-server}" />\r
                                        <param name="deployment.url" value="http://${target-host}:${target-port}" />\r
                                </antcall>\r
-                               \r
+\r
                                <!-- Run theme tests in all browsers if there's a property with the test files -->\r
                                <antcontrib:if>\r
                                        <isset property="testfiles-theme" />\r
                                </antcontrib:if>\r
                                \r
                                <!-- timeout in five minutes -->\r
-                               <sshexec host="${target-host}" outputproperty="stop-output" timeout="300000" username="${user}" keyfile="${sshkey.file}" trust="yes" command="ant -f deploy.xml shutdown-and-cleanup" failonerror="false" />\r
+                               <sshexec host="${target-host}" outputproperty="stop-output" timeout="600000" username="${user}" keyfile="${sshkey.file}" trust="yes" command="ant -f deploy.xml shutdown-and-cleanup" failonerror="false" />\r
                                <antcall target="echo-prefix">\r
                                        <param name="prefix" value="${target-server}: " />\r
                                        <param name="message" value="${stop-output}" />\r
                        </catch>\r
                </antcontrib:trycatch>\r
        </target>\r
-       \r
+\r
        <target name="echo-prefix">\r
                <antcontrib:propertyregex property="message-prefixed" input="${prefix}${message}" regexp="\n" replace="\0${prefix}" global="true" defaultValue="${prefix}${message}" />\r
                <echo message="${message-prefixed}" />\r
        </target>\r
-       \r
+\r
        <target name="run-generic-integration-test">\r
                <concat>##teamcity[testStarted name='${target-server}' flowId='${target-server}']</concat>\r
                <antcontrib:trycatch property="tried">\r
                        </catch>\r
                </antcontrib:trycatch>\r
                <concat>##teamcity[testFinished name='${target-server}' flowId='${target-server}']"</concat>\r
-       </target>       \r
+       </target>\r
 \r
        <target name="teamcity-escape">\r
                <property name="returnTo" value="return" />\r
-               \r
+\r
                <!-- Should also perform other escaping (\u0085, \u2028 and \u2029) - see http://confluence.jetbrains.net/display/TCD65/Build+Script+Interaction+with+TeamCity -->\r
                <!-- Immutable properties -> needs to create a new one every time -->\r
                <antcontrib:propertyregex property="details-escaped1" input="${message}" regexp="['|\[\]]" replace="|\0" global="true" defaultValue="${message}" />\r
                <antcontrib:propertyregex property="details-escaped2" input="${details-escaped1}" regexp="\n" replace="|n" global="true" defaultValue="${details-escaped1}" />\r
                <antcontrib:propertyregex property="details-escaped3" input="${details-escaped2}" regexp="\r" replace="|r" global="true" defaultValue="${details-escaped2}" />\r
-               \r
+\r
                <property name="${returnTo}" value="${details-escaped3}" />\r
        </target>\r
-       \r
+\r
        <target name="run-integration-test">\r
                <concat>##teamcity[testStarted name='${target-server}' flowId='${target-server}']</concat>\r
                <antcontrib:trycatch property="tried">\r
                </antcontrib:trycatch>\r
                <concat>##teamcity[testFinished name='${target-server}' flowId='${target-server}']"</concat>\r
        </target>\r
-       \r
+\r
        <target name="integration-test-get-lock">\r
                <sshexec host="${test.integration.server}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} get-lock" />\r
        </target>\r
-       \r
+\r
        <target name="integration-test-release-lock">\r
                <sshexec host="${test.integration.server}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} release-lock" />\r
        </target>\r
-               \r
+\r
        <!-- Remove demo.war -->\r
        <target name="integration-test-clean">\r
                <sshexec host="${test.integration.server}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} clean" />\r
diff --git a/tests/server-side/com/vaadin/tests/VaadinClasses.java b/tests/server-side/com/vaadin/tests/VaadinClasses.java
new file mode 100644 (file)
index 0000000..707fc02
--- /dev/null
@@ -0,0 +1,248 @@
+package com.vaadin.tests;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.JarURLConnection;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+
+import org.junit.Test;
+
+import com.vaadin.Application;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.ComponentContainer;
+import com.vaadin.ui.CustomComponent;
+import com.vaadin.ui.DragAndDropWrapper;
+import com.vaadin.ui.Field;
+import com.vaadin.ui.HorizontalSplitPanel;
+import com.vaadin.ui.LoginForm;
+import com.vaadin.ui.PopupView;
+import com.vaadin.ui.Root;
+import com.vaadin.ui.SplitPanel;
+import com.vaadin.ui.VerticalSplitPanel;
+import com.vaadin.ui.Window;
+
+@SuppressWarnings("deprecation")
+public class VaadinClasses {
+
+    public static void main(String[] args) {
+        System.out.println("ComponentContainers");
+        System.out.println("===================");
+        for (Class<? extends ComponentContainer> c : getComponentContainers()) {
+            System.out.println(c.getName());
+        }
+        System.out.println();
+        System.out.println("Components");
+        System.out.println("==========");
+        for (Class<? extends Component> c : getComponents()) {
+            System.out.println(c.getName());
+        }
+        System.out.println();
+        System.out.println("Server side classes");
+        System.out.println("===================");
+        for (Class<?> c : getAllServerSideClasses()) {
+            System.out.println(c.getName());
+        }
+    }
+
+    public static List<Class<? extends Component>> getComponents() {
+        try {
+            return findClasses(Component.class, "com.vaadin.ui");
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static List<Class<? extends Field>> getFields() {
+        try {
+            return findClasses(Field.class, "com.vaadin.ui");
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static List<Class<? extends Object>> getAllServerSideClasses() {
+        try {
+            return findClassesNoTests(Object.class, "com.vaadin", new String[] {
+                    "com.vaadin.tests", "com.vaadin.terminal.gwt.client" });
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static List<Class<? extends ComponentContainer>> getComponentContainers() {
+        try {
+            return findClasses(ComponentContainer.class, "com.vaadin.ui");
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static List<Class<? extends ComponentContainer>> getComponentContainersSupportingAddRemoveComponent() {
+        List<Class<? extends ComponentContainer>> classes = getComponentContainers();
+        classes.remove(PopupView.class);
+        classes.remove(CustomComponent.class);
+        classes.remove(DragAndDropWrapper.class);
+        classes.remove(CustomComponent.class);
+        classes.remove(LoginForm.class);
+        classes.remove(Root.class);
+
+        return classes;
+    }
+
+    public static List<Class<? extends ComponentContainer>> getComponentContainersSupportingUnlimitedNumberOfComponents() {
+        List<Class<? extends ComponentContainer>> classes = getComponentContainersSupportingAddRemoveComponent();
+        classes.remove(SplitPanel.class);
+        classes.remove(VerticalSplitPanel.class);
+        classes.remove(HorizontalSplitPanel.class);
+        classes.remove(Window.class);
+
+        return classes;
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public static List<Class<?>> getBasicComponentTests() {
+        try {
+            // Given as name to avoid dependencies on testbench source folder
+            return (List) findClasses(
+                    Class.forName("com.vaadin.tests.components.AbstractComponentTest"),
+                    "com.vaadin.tests.components");
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+
+    }
+
+    private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
+            String basePackage) throws IOException {
+        return findClasses(baseClass, basePackage, new String[] {});
+    }
+
+    private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
+            String basePackage, String[] ignoredPackages) throws IOException {
+        List<Class<? extends T>> classes = new ArrayList<Class<? extends T>>();
+        String basePackageDirName = "/" + basePackage.replace('.', '/');
+        URL location = Application.class.getResource(basePackageDirName);
+        if (location.getProtocol().equals("file")) {
+            try {
+                File f = new File(location.toURI());
+                if (!f.exists()) {
+                    throw new IOException("Directory " + f.toString()
+                            + " does not exist");
+                }
+                findPackages(f, basePackage, baseClass, classes,
+                        ignoredPackages);
+            } catch (URISyntaxException e) {
+                throw new IOException(e.getMessage());
+            }
+        } else if (location.getProtocol().equals("jar")) {
+            JarURLConnection juc = (JarURLConnection) location.openConnection();
+            findPackages(juc, basePackage, baseClass, classes);
+        }
+
+        Collections.sort(classes, new Comparator<Class<? extends T>>() {
+
+            public int compare(Class<? extends T> o1, Class<? extends T> o2) {
+                return o1.getName().compareTo(o2.getName());
+            }
+
+        });
+        return classes;
+    }
+
+    private static <T> List<Class<? extends T>> findClassesNoTests(
+            Class<T> baseClass, String basePackage, String[] ignoredPackages)
+            throws IOException {
+        List<Class<? extends T>> classes = findClasses(baseClass, basePackage,
+                ignoredPackages);
+        List<Class<? extends T>> classesNoTests = new ArrayList<Class<? extends T>>();
+        for (Class<? extends T> clazz : classes) {
+            if (!clazz.getName().contains("Test")) {
+                boolean testPresent = false;
+                for (Method method : clazz.getMethods()) {
+                    if (method.isAnnotationPresent(Test.class)) {
+                        testPresent = true;
+                        break;
+                    }
+                }
+                if (!testPresent) {
+                    classesNoTests.add(clazz);
+                }
+            }
+        }
+        return classesNoTests;
+    }
+
+    private static <T> void findPackages(JarURLConnection juc,
+            String javaPackage, Class<T> baseClass,
+            Collection<Class<? extends T>> result) throws IOException {
+        String prefix = "com/vaadin/ui";
+        Enumeration<JarEntry> ent = juc.getJarFile().entries();
+        while (ent.hasMoreElements()) {
+            JarEntry e = ent.nextElement();
+            if (e.getName().endsWith(".class")
+                    && e.getName().startsWith(prefix)) {
+                String fullyQualifiedClassName = e.getName().replace('/', '.')
+                        .replace(".class", "");
+                addClassIfMatches(result, fullyQualifiedClassName, baseClass);
+            }
+        }
+    }
+
+    private static <T> void findPackages(File parent, String javaPackage,
+            Class<T> baseClass, Collection<Class<? extends T>> result,
+            String[] ignoredPackages) {
+        for (String ignoredPackage : ignoredPackages) {
+            if (javaPackage.equals(ignoredPackage)) {
+                return;
+            }
+        }
+
+        for (File file : parent.listFiles()) {
+            if (file.isDirectory()) {
+                findPackages(file, javaPackage + "." + file.getName(),
+                        baseClass, result, ignoredPackages);
+            } else if (file.getName().endsWith(".class")) {
+                String fullyQualifiedClassName = javaPackage + "."
+                        + file.getName().replace(".class", "");
+                addClassIfMatches(result, fullyQualifiedClassName, baseClass);
+            }
+        }
+
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> void addClassIfMatches(
+            Collection<Class<? extends T>> result,
+            String fullyQualifiedClassName, Class<T> baseClass) {
+        try {
+            // Try to load the class
+
+            Class<?> c = Class.forName(fullyQualifiedClassName);
+            if (baseClass.isAssignableFrom(c)
+                    && !Modifier.isAbstract(c.getModifiers())) {
+                result.add((Class<? extends T>) c);
+            }
+        } catch (Exception e) {
+            // Could ignore that class cannot be loaded
+            e.printStackTrace();
+        } catch (LinkageError e) {
+            // Ignore. Client side classes will at least throw LinkageErrors
+        }
+
+    }
+}
diff --git a/tests/server-side/com/vaadin/tests/server/component/datefield/ResolutionTest.java b/tests/server-side/com/vaadin/tests/server/component/datefield/ResolutionTest.java
new file mode 100644 (file)
index 0000000..88dceca
--- /dev/null
@@ -0,0 +1,61 @@
+package com.vaadin.tests.server.component.datefield;\r
+\r
+import java.util.ArrayList;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import com.vaadin.tests.util.TestUtil;\r
+import com.vaadin.ui.DateField.Resolution;\r
+\r
+public class ResolutionTest extends TestCase {\r
+\r
+    public void testResolutionHigherOrEqualToYear() {\r
+        Iterable<Resolution> higherOrEqual = Resolution\r
+                .getResolutionsHigherOrEqualTo(Resolution.YEAR);\r
+        ArrayList<Resolution> expected = new ArrayList<Resolution>();\r
+        expected.add(Resolution.YEAR);\r
+        TestUtil.assertIterableEquals(expected, higherOrEqual);\r
+    }\r
+\r
+    public void testResolutionHigherOrEqualToDay() {\r
+        Iterable<Resolution> higherOrEqual = Resolution\r
+                .getResolutionsHigherOrEqualTo(Resolution.DAY);\r
+        ArrayList<Resolution> expected = new ArrayList<Resolution>();\r
+        expected.add(Resolution.DAY);\r
+        expected.add(Resolution.MONTH);\r
+        expected.add(Resolution.YEAR);\r
+        TestUtil.assertIterableEquals(expected, higherOrEqual);\r
+\r
+    }\r
+\r
+    public void testResolutionLowerThanDay() {\r
+        Iterable<Resolution> higherOrEqual = Resolution\r
+                .getResolutionsLowerThan(Resolution.DAY);\r
+        ArrayList<Resolution> expected = new ArrayList<Resolution>();\r
+        expected.add(Resolution.HOUR);\r
+        expected.add(Resolution.MINUTE);\r
+        expected.add(Resolution.SECOND);\r
+        TestUtil.assertIterableEquals(expected, higherOrEqual);\r
+\r
+    }\r
+\r
+    public void testResolutionLowerThanSecond() {\r
+        Iterable<Resolution> higherOrEqual = Resolution\r
+                .getResolutionsLowerThan(Resolution.SECOND);\r
+        ArrayList<Resolution> expected = new ArrayList<Resolution>();\r
+        TestUtil.assertIterableEquals(expected, higherOrEqual);\r
+    }\r
+\r
+    public void testResolutionLowerThanYear() {\r
+        Iterable<Resolution> higherOrEqual = Resolution\r
+                .getResolutionsLowerThan(Resolution.YEAR);\r
+        ArrayList<Resolution> expected = new ArrayList<Resolution>();\r
+        expected.add(Resolution.MONTH);\r
+        expected.add(Resolution.DAY);\r
+        expected.add(Resolution.HOUR);\r
+        expected.add(Resolution.MINUTE);\r
+        expected.add(Resolution.SECOND);\r
+        TestUtil.assertIterableEquals(expected, higherOrEqual);\r
+\r
+    }\r
+}\r
index 04f436f5c4823d5c6ae6f0542c7392aba7425bf2..299f9c79d4984b33590d7240af26e34fc27eedf3 100644 (file)
@@ -5,6 +5,7 @@ import static org.junit.Assert.assertArrayEquals;
 import org.junit.Test;
 
 import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.Align;
 
 public class TableColumnAlignments {
 
@@ -15,7 +16,7 @@ public class TableColumnAlignments {
                     properties, 10);
             Object[] expected = new Object[properties];
             for (int i = 0; i < properties; i++) {
-                expected[i] = Table.ALIGN_LEFT;
+                expected[i] = Align.LEFT;
             }
             org.junit.Assert.assertArrayEquals("getColumnAlignments", expected,
                     t.getColumnAlignments());
@@ -27,9 +28,8 @@ public class TableColumnAlignments {
         int properties = 5;
         Table t = TableGenerator
                 .createTableWithDefaultContainer(properties, 10);
-        String[] explicitAlignments = new String[] { Table.ALIGN_CENTER,
-                Table.ALIGN_LEFT, Table.ALIGN_RIGHT, Table.ALIGN_RIGHT,
-                Table.ALIGN_LEFT };
+        Align[] explicitAlignments = new Align[] { Align.CENTER, Align.LEFT,
+                Align.RIGHT, Align.RIGHT, Align.LEFT };
 
         t.setColumnAlignments(explicitAlignments);
 
@@ -40,28 +40,10 @@ public class TableColumnAlignments {
     @Test
     public void invalidColumnAlignmentStrings() {
         Table t = TableGenerator.createTableWithDefaultContainer(3, 7);
-        String[] defaultAlignments = new String[] { Table.ALIGN_LEFT,
-                Table.ALIGN_LEFT, Table.ALIGN_LEFT };
+        Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT,
+                Align.LEFT };
         try {
-            t.setColumnAlignments(new String[] { "a", "b", "c" });
-            junit.framework.Assert
-                    .fail("No exception thrown for invalid array length");
-        } catch (IllegalArgumentException e) {
-            // Ok, expected
-        }
-
-        assertArrayEquals("Invalid change affected alignments",
-                defaultAlignments, t.getColumnAlignments());
-
-    }
-
-    @Test
-    public void invalidColumnAlignmentString() {
-        Table t = TableGenerator.createTableWithDefaultContainer(3, 7);
-        String[] defaultAlignments = new String[] { Table.ALIGN_LEFT,
-                Table.ALIGN_LEFT, Table.ALIGN_LEFT };
-        try {
-            t.setColumnAlignment("Property 1", "a");
+            t.setColumnAlignments(new Align[] { Align.RIGHT, Align.RIGHT });
             junit.framework.Assert
                     .fail("No exception thrown for invalid array length");
         } catch (IllegalArgumentException e) {
@@ -76,10 +58,10 @@ public class TableColumnAlignments {
     @Test
     public void columnAlignmentForPropertyNotInContainer() {
         Table t = TableGenerator.createTableWithDefaultContainer(3, 7);
-        String[] defaultAlignments = new String[] { Table.ALIGN_LEFT,
-                Table.ALIGN_LEFT, Table.ALIGN_LEFT };
+        Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT,
+                Align.LEFT };
         try {
-            t.setColumnAlignment("Property 1200", Table.ALIGN_LEFT);
+            t.setColumnAlignment("Property 1200", Align.LEFT);
             // FIXME: Uncomment as there should be an exception (#6475)
             // junit.framework.Assert
             // .fail("No exception thrown for property not in container");
@@ -100,12 +82,11 @@ public class TableColumnAlignments {
     @Test
     public void invalidColumnAlignmentsLength() {
         Table t = TableGenerator.createTableWithDefaultContainer(7, 7);
-        String[] defaultAlignments = new String[] { Table.ALIGN_LEFT,
-                Table.ALIGN_LEFT, Table.ALIGN_LEFT, Table.ALIGN_LEFT,
-                Table.ALIGN_LEFT, Table.ALIGN_LEFT, Table.ALIGN_LEFT };
+        Align[] defaultAlignments = new Align[] { Align.LEFT, Align.LEFT,
+                Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT };
 
         try {
-            t.setColumnAlignments(new String[] { Table.ALIGN_LEFT });
+            t.setColumnAlignments(new Align[] { Align.LEFT });
             junit.framework.Assert
                     .fail("No exception thrown for invalid array length");
         } catch (IllegalArgumentException e) {
@@ -115,7 +96,7 @@ public class TableColumnAlignments {
                 defaultAlignments, t.getColumnAlignments());
 
         try {
-            t.setColumnAlignments(new String[] {});
+            t.setColumnAlignments(new Align[] {});
             junit.framework.Assert
                     .fail("No exception thrown for invalid array length");
         } catch (IllegalArgumentException e) {
@@ -125,10 +106,9 @@ public class TableColumnAlignments {
                 defaultAlignments, t.getColumnAlignments());
 
         try {
-            t.setColumnAlignments(new String[] { Table.ALIGN_LEFT,
-                    Table.ALIGN_LEFT, Table.ALIGN_LEFT, Table.ALIGN_LEFT,
-                    Table.ALIGN_LEFT, Table.ALIGN_LEFT, Table.ALIGN_LEFT,
-                    Table.ALIGN_LEFT });
+            t.setColumnAlignments(new Align[] { Align.LEFT, Align.LEFT,
+                    Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT, Align.LEFT,
+                    Align.LEFT });
             junit.framework.Assert
                     .fail("No exception thrown for invalid array length");
         } catch (IllegalArgumentException e) {
@@ -144,13 +124,11 @@ public class TableColumnAlignments {
         int properties = 5;
         Table t = TableGenerator
                 .createTableWithDefaultContainer(properties, 10);
-        String[] explicitAlignments = new String[] { Table.ALIGN_CENTER,
-                Table.ALIGN_LEFT, Table.ALIGN_RIGHT, Table.ALIGN_RIGHT,
-                Table.ALIGN_LEFT };
+        Align[] explicitAlignments = new Align[] { Align.CENTER, Align.LEFT,
+                Align.RIGHT, Align.RIGHT, Align.LEFT };
 
-        String[] currentAlignments = new String[] { Table.ALIGN_LEFT,
-                Table.ALIGN_LEFT, Table.ALIGN_LEFT, Table.ALIGN_LEFT,
-                Table.ALIGN_LEFT };
+        Align[] currentAlignments = new Align[] { Align.LEFT, Align.LEFT,
+                Align.LEFT, Align.LEFT, Align.LEFT };
 
         for (int i = 0; i < properties; i++) {
             t.setColumnAlignment("Property " + i, explicitAlignments[i]);
diff --git a/tests/server-side/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTest.java b/tests/server-side/com/vaadin/tests/server/componentcontainer/AbstractIndexedLayoutTest.java
new file mode 100644 (file)
index 0000000..9271e9f
--- /dev/null
@@ -0,0 +1,84 @@
+package com.vaadin.tests.server.componentcontainer;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import com.vaadin.ui.Component;\r
+import com.vaadin.ui.Label;\r
+import com.vaadin.ui.Layout;\r
+\r
+public abstract class AbstractIndexedLayoutTest extends TestCase {\r
+\r
+    private Layout layout;\r
+\r
+    protected abstract Layout createLayout();\r
+\r
+    @Override\r
+    protected void setUp() throws Exception {\r
+        layout = createLayout();\r
+    }\r
+\r
+    public Layout getLayout() {\r
+        return layout;\r
+    }\r
+\r
+    public void testAddRemoveComponent() {\r
+        Label c1 = new Label();\r
+        Label c2 = new Label();\r
+\r
+        layout.addComponent(c1);\r
+\r
+        assertEquals(c1, getComponent(0));\r
+        assertEquals(1, getComponentCount());\r
+        layout.addComponent(c2);\r
+        assertEquals(c1, getComponent(0));\r
+        assertEquals(c2, getComponent(1));\r
+        assertEquals(2, getComponentCount());\r
+        layout.removeComponent(c1);\r
+        assertEquals(c2, getComponent(0));\r
+        assertEquals(1, getComponentCount());\r
+        layout.removeComponent(c2);\r
+        assertEquals(0, getComponentCount());\r
+    }\r
+\r
+    protected abstract int getComponentCount();\r
+\r
+    protected abstract Component getComponent(int index);\r
+\r
+    protected abstract int getComponentIndex(Component c);\r
+\r
+    public void testGetComponentIndex() {\r
+        Label c1 = new Label();\r
+        Label c2 = new Label();\r
+\r
+        layout.addComponent(c1);\r
+        assertEquals(0, getComponentIndex(c1));\r
+        layout.addComponent(c2);\r
+        assertEquals(0, getComponentIndex(c1));\r
+        assertEquals(1, getComponentIndex(c2));\r
+        layout.removeComponent(c1);\r
+        assertEquals(0, getComponentIndex(c2));\r
+        layout.removeComponent(c2);\r
+        assertEquals(-1, getComponentIndex(c2));\r
+        assertEquals(-1, getComponentIndex(c1));\r
+    }\r
+\r
+    public void testGetComponent() {\r
+        Label c1 = new Label();\r
+        Label c2 = new Label();\r
+\r
+        layout.addComponent(c1);\r
+        assertEquals(c1, getComponent(0));\r
+        layout.addComponent(c2);\r
+        assertEquals(c1, getComponent(0));\r
+        assertEquals(c2, getComponent(1));\r
+        layout.removeComponent(c1);\r
+        assertEquals(c2, getComponent(0));\r
+        layout.removeComponent(c2);\r
+        try {\r
+            getComponent(0);\r
+            fail();\r
+        } catch (IndexOutOfBoundsException e) {\r
+            // Expected\r
+        }\r
+    }\r
+}\r
diff --git a/tests/server-side/com/vaadin/tests/server/componentcontainer/CssLayoutTest.java b/tests/server-side/com/vaadin/tests/server/componentcontainer/CssLayoutTest.java
new file mode 100644 (file)
index 0000000..dc9667c
--- /dev/null
@@ -0,0 +1,34 @@
+package com.vaadin.tests.server.componentcontainer;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.CssLayout;
+import com.vaadin.ui.Layout;
+
+public class CssLayoutTest extends AbstractIndexedLayoutTest {
+
+    @Override
+    protected Layout createLayout() {
+        return new CssLayout();
+    }
+
+    @Override
+    public CssLayout getLayout() {
+        return (CssLayout) super.getLayout();
+    }
+
+    @Override
+    protected Component getComponent(int index) {
+        return getLayout().getComponent(index);
+    }
+
+    @Override
+    protected int getComponentIndex(Component c) {
+        return getLayout().getComponentIndex(c);
+    }
+
+    @Override
+    protected int getComponentCount() {
+        return getLayout().getComponentCount();
+    }
+
+}
diff --git a/tests/server-side/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java b/tests/server-side/com/vaadin/tests/server/componentcontainer/FormLayoutTest.java
new file mode 100644 (file)
index 0000000..71a813d
--- /dev/null
@@ -0,0 +1,34 @@
+package com.vaadin.tests.server.componentcontainer;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.Layout;
+
+public class FormLayoutTest extends AbstractIndexedLayoutTest {
+
+    @Override
+    protected Layout createLayout() {
+        return new FormLayout();
+    }
+
+    @Override
+    public FormLayout getLayout() {
+        return (FormLayout) super.getLayout();
+    }
+
+    @Override
+    protected Component getComponent(int index) {
+        return getLayout().getComponent(index);
+    }
+
+    @Override
+    protected int getComponentIndex(Component c) {
+        return getLayout().getComponentIndex(c);
+    }
+
+    @Override
+    protected int getComponentCount() {
+        return getLayout().getComponentCount();
+    }
+
+}
diff --git a/tests/server-side/com/vaadin/tests/server/componentcontainer/VerticalLayoutTest.java b/tests/server-side/com/vaadin/tests/server/componentcontainer/VerticalLayoutTest.java
new file mode 100644 (file)
index 0000000..0e3a1d5
--- /dev/null
@@ -0,0 +1,34 @@
+package com.vaadin.tests.server.componentcontainer;
+
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Layout;
+import com.vaadin.ui.VerticalLayout;
+
+public class VerticalLayoutTest extends AbstractIndexedLayoutTest {
+
+    @Override
+    protected Layout createLayout() {
+        return new VerticalLayout();
+    }
+
+    @Override
+    public VerticalLayout getLayout() {
+        return (VerticalLayout) super.getLayout();
+    }
+
+    @Override
+    protected Component getComponent(int index) {
+        return getLayout().getComponent(index);
+    }
+
+    @Override
+    protected int getComponentIndex(Component c) {
+        return getLayout().getComponentIndex(c);
+    }
+
+    @Override
+    protected int getComponentCount() {
+        return getLayout().getComponentCount();
+    }
+
+}
index d4a8f5918c3d1dbd41979060ecbdd4c95632898a..9d060c9a29e57edb4445cbdd488198ce976d79c1 100644 (file)
@@ -94,7 +94,7 @@
                        <include name="**/**.java" />
                </fileset>
                
-               <antcontrib:for threadCount="40" parallel="true" keepgoing="true" param="target">
+               <antcontrib:for threadCount="30" parallel="true" keepgoing="true" param="target">
                        <path>
                                <fileset refid="tests-fileset" />
                        </path>
diff --git a/tests/testbench/com/vaadin/launcher/util/BrowserLauncher.java b/tests/testbench/com/vaadin/launcher/util/BrowserLauncher.java
new file mode 100644 (file)
index 0000000..55692cb
--- /dev/null
@@ -0,0 +1,127 @@
+/* \r
+@VaadinApache2LicenseForJavaFiles@\r
+ */\r
+\r
+package com.vaadin.launcher.util;\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.BufferedReader;\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.InputStreamReader;\r
+\r
+/**\r
+ * This class opens default browser for DemoLauncher class. Default browser is\r
+ * detected by the operating system.\r
+ * \r
+ */\r
+public class BrowserLauncher {\r
+\r
+    /**\r
+     * Open browser on specified URL.\r
+     * \r
+     * @param url\r
+     */\r
+    public static void openBrowser(String url) {\r
+\r
+        final Runtime runtime = Runtime.getRuntime();\r
+        boolean started = false;\r
+\r
+        final String os = System.getProperty("os.name", "windows")\r
+                .toLowerCase();\r
+\r
+        // Linux\r
+        if (os.indexOf("linux") >= 0) {\r
+            // See if the default browser is Konqueror by resolving the symlink.\r
+            boolean isDefaultKonqueror = false;\r
+            try {\r
+                // Find out the location of the x-www-browser link from path.\r
+                Process process = runtime.exec("which x-www-browser");\r
+                BufferedInputStream ins = new BufferedInputStream(\r
+                        process.getInputStream());\r
+                BufferedReader bufreader = new BufferedReader(\r
+                        new InputStreamReader(ins));\r
+                String defaultLinkPath = bufreader.readLine();\r
+                ins.close();\r
+\r
+                // The path is null if the link did not exist.\r
+                if (defaultLinkPath != null) {\r
+                    // See if the default browser is Konqueror.\r
+                    File file = new File(defaultLinkPath);\r
+                    String canonical = file.getCanonicalPath();\r
+                    if (canonical.indexOf("konqueror") != -1) {\r
+                        isDefaultKonqueror = true;\r
+                    }\r
+                }\r
+            } catch (IOException e1) {\r
+                // The symlink was probably not found, so this is ok.\r
+            }\r
+\r
+            // Try x-www-browser, which is symlink to the default browser,\r
+            // except if we found that it is Konqueror.\r
+            if (!started && !isDefaultKonqueror) {\r
+                try {\r
+                    runtime.exec("x-www-browser " + url);\r
+                    started = true;\r
+                } catch (final IOException e) {\r
+                }\r
+            }\r
+\r
+            // Try firefox\r
+            if (!started) {\r
+                try {\r
+                    runtime.exec("firefox " + url);\r
+                    started = true;\r
+                } catch (final IOException e) {\r
+                }\r
+            }\r
+\r
+            // Try mozilla\r
+            if (!started) {\r
+                try {\r
+                    runtime.exec("mozilla " + url);\r
+                    started = true;\r
+                } catch (final IOException e) {\r
+                }\r
+            }\r
+\r
+            // Try konqueror\r
+            if (!started) {\r
+                try {\r
+                    runtime.exec("konqueror " + url);\r
+                    started = true;\r
+                } catch (final IOException e) {\r
+                }\r
+            }\r
+        }\r
+\r
+        // OS X\r
+        if (os.indexOf("mac os x") >= 0) {\r
+\r
+            // Try open\r
+            if (!started) {\r
+                try {\r
+                    runtime.exec("open " + url);\r
+                    started = true;\r
+                } catch (final IOException e) {\r
+                }\r
+            }\r
+        }\r
+\r
+        // Try cmd /start command on windows\r
+        if (os.indexOf("win") >= 0) {\r
+            if (!started) {\r
+                try {\r
+                    runtime.exec("cmd /c start " + url);\r
+                    started = true;\r
+                } catch (final IOException e) {\r
+                }\r
+            }\r
+        }\r
+\r
+        if (!started) {\r
+            System.out.println("Failed to open browser. Please go to " + url);\r
+        }\r
+    }\r
+\r
+}\r
index 414c97c951cee89468bdf7ba65cb97c808697068..6bc6860607a448f7f3f54db45de9c1099ebeaee5 100644 (file)
@@ -33,7 +33,7 @@ import com.vaadin.ui.VerticalLayout;
 public class Components extends Application.LegacyApplication {\r
 \r
     private static final Object CAPTION = "c";\r
-    private Map<Class<? extends AbstractComponentTest<?>>, String> tests = new HashMap<Class<? extends AbstractComponentTest<?>>, String>();\r
+    private Map<Class<? extends AbstractComponentTest>, String> tests = new HashMap<Class<? extends AbstractComponentTest>, String>();\r
     private Tree naviTree;\r
     private HorizontalSplitPanel sp;\r
     private LegacyWindow mainWindow;\r
@@ -42,10 +42,9 @@ public class Components extends Application.LegacyApplication {
     private List<Class<? extends Component>> componentsWithoutTests = new ArrayList<Class<? extends Component>>();\r
 \r
     {\r
-        for (Class<? extends AbstractComponentTest<?>> c : VaadinClasses\r
-                .getBasicComponentTests()) {\r
+        for (Class<?> c : VaadinClasses.getBasicComponentTests()) {\r
             String testClass = c.getSimpleName();\r
-            tests.put(c, testClass);\r
+            tests.put((Class<? extends AbstractComponentTest>) c, testClass);\r
         }\r
 \r
         List<Class<? extends Component>> componentsWithoutTest = VaadinClasses\r
@@ -172,7 +171,7 @@ public class Components extends Application.LegacyApplication {
         hc.setItemSorter(sorter);\r
         naviTree.addContainerProperty(CAPTION, String.class, "");\r
         naviTree.setItemCaptionPropertyId(CAPTION);\r
-        for (Class<? extends AbstractComponentTest<?>> cls : tests.keySet()) {\r
+        for (Class<? extends AbstractComponentTest> cls : tests.keySet()) {\r
             addTreeItem(cls);\r
         }\r
         hc.sort(new Object[] { CAPTION }, new boolean[] { true });\r
@@ -227,13 +226,13 @@ public class Components extends Application.LegacyApplication {
     }\r
 \r
     @SuppressWarnings("unchecked")\r
-    private void addTreeItem(Class<? extends AbstractComponentTest<?>> cls) {\r
+    private void addTreeItem(Class<? extends AbstractComponentTest> cls) {\r
         String name = tests.get(cls);\r
         if (name == null) {\r
             name = cls.getSimpleName();\r
         }\r
 \r
-        Class<? extends AbstractComponentTest<?>> superClass = (Class<? extends AbstractComponentTest<?>>) cls\r
+        Class<? extends AbstractComponentTest> superClass = (Class<? extends AbstractComponentTest>) cls\r
                 .getSuperclass();\r
 \r
         // This cast is needed only to make compilation through Ant work ..\r
@@ -250,9 +249,9 @@ public class Components extends Application.LegacyApplication {
     }\r
 \r
     protected Component createTestComponent(\r
-            Class<? extends AbstractComponentTest<?>> cls) {\r
+            Class<? extends AbstractComponentTest> cls) {\r
         try {\r
-            AbstractComponentTest<?> t = cls.newInstance();\r
+            AbstractComponentTest t = cls.newInstance();\r
             t.init();\r
             ComponentContainer c = t.getMainWindow().getContent();\r
             t.getMainWindow().setContent(null);\r
diff --git a/tests/testbench/com/vaadin/tests/VaadinClasses.java b/tests/testbench/com/vaadin/tests/VaadinClasses.java
deleted file mode 100644 (file)
index cb430d9..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-package com.vaadin.tests;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.net.JarURLConnection;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.jar.JarEntry;
-
-import org.junit.Test;
-
-import com.vaadin.Application;
-import com.vaadin.tests.components.AbstractComponentTest;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.ComponentContainer;
-import com.vaadin.ui.CustomComponent;
-import com.vaadin.ui.DragAndDropWrapper;
-import com.vaadin.ui.Field;
-import com.vaadin.ui.HorizontalSplitPanel;
-import com.vaadin.ui.LoginForm;
-import com.vaadin.ui.PopupView;
-import com.vaadin.ui.Root;
-import com.vaadin.ui.SplitPanel;
-import com.vaadin.ui.VerticalSplitPanel;
-import com.vaadin.ui.Window;
-
-@SuppressWarnings("deprecation")
-public class VaadinClasses {
-
-    public static void main(String[] args) {
-        System.out.println("ComponentContainers");
-        System.out.println("===================");
-        for (Class<? extends ComponentContainer> c : getComponentContainers()) {
-            System.out.println(c.getName());
-        }
-        System.out.println();
-        System.out.println("Components");
-        System.out.println("==========");
-        for (Class<? extends Component> c : getComponents()) {
-            System.out.println(c.getName());
-        }
-        System.out.println();
-        System.out.println("Server side classes");
-        System.out.println("===================");
-        for (Class<?> c : getAllServerSideClasses()) {
-            System.out.println(c.getName());
-        }
-    }
-
-    public static List<Class<? extends Component>> getComponents() {
-        try {
-            return findClasses(Component.class, "com.vaadin.ui");
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static List<Class<? extends Field>> getFields() {
-        try {
-            return findClasses(Field.class, "com.vaadin.ui");
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static List<Class<? extends Object>> getAllServerSideClasses() {
-        try {
-            return findClassesNoTests(Object.class, "com.vaadin", new String[] {
-                    "com.vaadin.tests", "com.vaadin.terminal.gwt.client" });
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static List<Class<? extends ComponentContainer>> getComponentContainers() {
-        try {
-            return findClasses(ComponentContainer.class, "com.vaadin.ui");
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-    }
-
-    public static List<Class<? extends ComponentContainer>> getComponentContainersSupportingAddRemoveComponent() {
-        List<Class<? extends ComponentContainer>> classes = getComponentContainers();
-        classes.remove(PopupView.class);
-        classes.remove(CustomComponent.class);
-        classes.remove(DragAndDropWrapper.class);
-        classes.remove(CustomComponent.class);
-        classes.remove(LoginForm.class);
-        classes.remove(Root.class);
-
-        return classes;
-    }
-
-    public static List<Class<? extends ComponentContainer>> getComponentContainersSupportingUnlimitedNumberOfComponents() {
-        List<Class<? extends ComponentContainer>> classes = getComponentContainersSupportingAddRemoveComponent();
-        classes.remove(SplitPanel.class);
-        classes.remove(VerticalSplitPanel.class);
-        classes.remove(HorizontalSplitPanel.class);
-        classes.remove(Window.class);
-
-        return classes;
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    public static List<Class<? extends AbstractComponentTest<?>>> getBasicComponentTests() {
-        try {
-            return (List) findClasses(AbstractComponentTest.class,
-                    "com.vaadin.tests.components");
-        } catch (IOException e) {
-            e.printStackTrace();
-            return null;
-        }
-
-    }
-
-    private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
-            String basePackage) throws IOException {
-        return findClasses(baseClass, basePackage, new String[] {});
-    }
-
-    private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
-            String basePackage, String[] ignoredPackages) throws IOException {
-        List<Class<? extends T>> classes = new ArrayList<Class<? extends T>>();
-        String basePackageDirName = "/" + basePackage.replace('.', '/');
-        URL location = Application.class.getResource(basePackageDirName);
-        if (location.getProtocol().equals("file")) {
-            try {
-                File f = new File(location.toURI());
-                if (!f.exists()) {
-                    throw new IOException("Directory " + f.toString()
-                            + " does not exist");
-                }
-                findPackages(f, basePackage, baseClass, classes,
-                        ignoredPackages);
-            } catch (URISyntaxException e) {
-                throw new IOException(e.getMessage());
-            }
-        } else if (location.getProtocol().equals("jar")) {
-            JarURLConnection juc = (JarURLConnection) location.openConnection();
-            findPackages(juc, basePackage, baseClass, classes);
-        }
-
-        Collections.sort(classes, new Comparator<Class<? extends T>>() {
-
-            public int compare(Class<? extends T> o1, Class<? extends T> o2) {
-                return o1.getName().compareTo(o2.getName());
-            }
-
-        });
-        return classes;
-    }
-
-    private static <T> List<Class<? extends T>> findClassesNoTests(
-            Class<T> baseClass, String basePackage, String[] ignoredPackages)
-            throws IOException {
-        List<Class<? extends T>> classes = findClasses(baseClass, basePackage,
-                ignoredPackages);
-        List<Class<? extends T>> classesNoTests = new ArrayList<Class<? extends T>>();
-        for (Class<? extends T> clazz : classes) {
-            if (!clazz.getName().contains("Test")) {
-                boolean testPresent = false;
-                for (Method method : clazz.getMethods()) {
-                    if (method.isAnnotationPresent(Test.class)) {
-                        testPresent = true;
-                        break;
-                    }
-                }
-                if (!testPresent) {
-                    classesNoTests.add(clazz);
-                }
-            }
-        }
-        return classesNoTests;
-    }
-
-    private static <T> void findPackages(JarURLConnection juc,
-            String javaPackage, Class<T> baseClass,
-            Collection<Class<? extends T>> result) throws IOException {
-        String prefix = "com/vaadin/ui";
-        Enumeration<JarEntry> ent = juc.getJarFile().entries();
-        while (ent.hasMoreElements()) {
-            JarEntry e = ent.nextElement();
-            if (e.getName().endsWith(".class")
-                    && e.getName().startsWith(prefix)) {
-                String fullyQualifiedClassName = e.getName().replace('/', '.')
-                        .replace(".class", "");
-                addClassIfMatches(result, fullyQualifiedClassName, baseClass);
-            }
-        }
-    }
-
-    private static <T> void findPackages(File parent, String javaPackage,
-            Class<T> baseClass, Collection<Class<? extends T>> result,
-            String[] ignoredPackages) {
-        for (String ignoredPackage : ignoredPackages) {
-            if (javaPackage.equals(ignoredPackage)) {
-                return;
-            }
-        }
-
-        for (File file : parent.listFiles()) {
-            if (file.isDirectory()) {
-                findPackages(file, javaPackage + "." + file.getName(),
-                        baseClass, result, ignoredPackages);
-            } else if (file.getName().endsWith(".class")) {
-                String fullyQualifiedClassName = javaPackage + "."
-                        + file.getName().replace(".class", "");
-                addClassIfMatches(result, fullyQualifiedClassName, baseClass);
-            }
-        }
-
-    }
-
-    @SuppressWarnings("unchecked")
-    private static <T> void addClassIfMatches(
-            Collection<Class<? extends T>> result,
-            String fullyQualifiedClassName, Class<T> baseClass) {
-        try {
-            // Try to load the class
-
-            Class<?> c = Class.forName(fullyQualifiedClassName);
-            if (baseClass.isAssignableFrom(c)
-                    && !Modifier.isAbstract(c.getModifiers())) {
-                result.add((Class<? extends T>) c);
-            }
-        } catch (Exception e) {
-            // Could ignore that class cannot be loaded
-            e.printStackTrace();
-        } catch (LinkageError e) {
-            // Ignore. Client side classes will at least throw LinkageErrors
-        }
-
-    }
-}
index 6d18c6003896a2a84f00fe4a064b66a390447ff6..3ad7d62a096a6517d84c46c5e4769ad0be6d1617 100644 (file)
        <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td>
        <td>enter</td>
 </tr>
+<tr>
+       <td>pause</td>
+       <td>100</td>
+       <td></td>
+</tr>
 <tr>
        <td>assertText</td>
        <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxIdenticalItems::PID_SLog_row_0</td>
        <td>4. Item one-1 selected</td>
 </tr>
-
 </tbody></table>
 </body>
 </html>
diff --git a/tests/testbench/com/vaadin/tests/components/datefield/DatePopupStyleName.html b/tests/testbench/com/vaadin/tests/components/datefield/DatePopupStyleName.html
new file mode 100644 (file)
index 0000000..f367fc3
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.datefield.DatePopupStyleName?&amp;restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestscomponentsdatefieldDatePopupStyleName::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VPopupCalendar[0]#popupButton</td>
+       <td>4,10</td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>styled-popup</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/datefield/DatePopupStyleName.java b/tests/testbench/com/vaadin/tests/components/datefield/DatePopupStyleName.java
new file mode 100644 (file)
index 0000000..ba4e324
--- /dev/null
@@ -0,0 +1,33 @@
+package com.vaadin.tests.components.datefield;\r
+\r
+import java.util.Date;\r
+\r
+import com.vaadin.terminal.UserError;\r
+import com.vaadin.tests.components.TestBase;\r
+import com.vaadin.ui.DateField;\r
+\r
+public class DatePopupStyleName extends TestBase {\r
+    @Override\r
+    public void setup() {\r
+        setTheme("reindeer-tests");\r
+\r
+        final DateField df = new DateField();\r
+        df.setValue(new Date(1203910239L));\r
+        df.setWidth("200px");\r
+        df.setRequired(true);\r
+        df.setComponentError(new UserError("abc"));\r
+        df.addStyleName("popup-style");\r
+        addComponent(df);\r
+    }\r
+\r
+    @Override\r
+    protected String getDescription() {\r
+        return "The DateField is given a style name 'test', but that style isn't applied on the calendar popup element.";\r
+    }\r
+\r
+    @Override\r
+    protected Integer getTicketNumber() {\r
+        return 8083;\r
+    }\r
+\r
+}\r
diff --git a/tests/testbench/com/vaadin/tests/components/datefield/ResolutionTest.java b/tests/testbench/com/vaadin/tests/components/datefield/ResolutionTest.java
deleted file mode 100644 (file)
index e54e1cd..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.vaadin.tests.components.datefield;\r
-\r
-import java.util.ArrayList;\r
-\r
-import junit.framework.TestCase;\r
-\r
-import com.vaadin.tests.util.TestUtil;\r
-import com.vaadin.ui.DateField.Resolution;\r
-\r
-public class ResolutionTest extends TestCase {\r
-\r
-    public void testResolutionHigherOrEqualToYear() {\r
-        Iterable<Resolution> higherOrEqual = Resolution\r
-                .getResolutionsHigherOrEqualTo(Resolution.YEAR);\r
-        ArrayList<Resolution> expected = new ArrayList<Resolution>();\r
-        expected.add(Resolution.YEAR);\r
-        TestUtil.assertIterableEquals(expected, higherOrEqual);\r
-    }\r
-\r
-    public void testResolutionHigherOrEqualToDay() {\r
-        Iterable<Resolution> higherOrEqual = Resolution\r
-                .getResolutionsHigherOrEqualTo(Resolution.DAY);\r
-        ArrayList<Resolution> expected = new ArrayList<Resolution>();\r
-        expected.add(Resolution.DAY);\r
-        expected.add(Resolution.MONTH);\r
-        expected.add(Resolution.YEAR);\r
-        TestUtil.assertIterableEquals(expected, higherOrEqual);\r
-\r
-    }\r
-\r
-    public void testResolutionLowerThanDay() {\r
-        Iterable<Resolution> higherOrEqual = Resolution\r
-                .getResolutionsLowerThan(Resolution.DAY);\r
-        ArrayList<Resolution> expected = new ArrayList<Resolution>();\r
-        expected.add(Resolution.HOUR);\r
-        expected.add(Resolution.MINUTE);\r
-        expected.add(Resolution.SECOND);\r
-        TestUtil.assertIterableEquals(expected, higherOrEqual);\r
-\r
-    }\r
-\r
-    public void testResolutionLowerThanSecond() {\r
-        Iterable<Resolution> higherOrEqual = Resolution\r
-                .getResolutionsLowerThan(Resolution.SECOND);\r
-        ArrayList<Resolution> expected = new ArrayList<Resolution>();\r
-        TestUtil.assertIterableEquals(expected, higherOrEqual);\r
-    }\r
-\r
-    public void testResolutionLowerThanYear() {\r
-        Iterable<Resolution> higherOrEqual = Resolution\r
-                .getResolutionsLowerThan(Resolution.YEAR);\r
-        ArrayList<Resolution> expected = new ArrayList<Resolution>();\r
-        expected.add(Resolution.MONTH);\r
-        expected.add(Resolution.DAY);\r
-        expected.add(Resolution.HOUR);\r
-        expected.add(Resolution.MINUTE);\r
-        expected.add(Resolution.SECOND);\r
-        TestUtil.assertIterableEquals(expected, higherOrEqual);\r
-\r
-    }\r
-}\r
diff --git a/tests/testbench/com/vaadin/tests/components/datefield/WidthRecalculationOnEnableStateChange.html b/tests/testbench/com/vaadin/tests/components/datefield/WidthRecalculationOnEnableStateChange.html
new file mode 100644 (file)
index 0000000..70441ef
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.datefield.WidthRecalculationOnEnableStateChange?restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsdatefieldWidthRecalculationOnEnableStateChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>disabled</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsdatefieldWidthRecalculationOnEnableStateChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>enabled</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsdatefieldWidthRecalculationOnEnableStateChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>readonly</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/datefield/WidthRecalculationOnEnableStateChange.java b/tests/testbench/com/vaadin/tests/components/datefield/WidthRecalculationOnEnableStateChange.java
new file mode 100644 (file)
index 0000000..f25a9f0
--- /dev/null
@@ -0,0 +1,44 @@
+package com.vaadin.tests.components.datefield;\r
+\r
+import java.util.Date;\r
+\r
+import com.vaadin.tests.components.TestBase;\r
+import com.vaadin.ui.Button;\r
+import com.vaadin.ui.Button.ClickEvent;\r
+import com.vaadin.ui.DateField;\r
+\r
+public class WidthRecalculationOnEnableStateChange extends TestBase {\r
+    @Override\r
+    public void setup() {\r
+        setTheme("reindeer-tests");\r
+\r
+        final DateField df = new DateField();\r
+        df.setValue(new Date(1203910239L));\r
+        df.setWidth("200px");\r
+        df.addStyleName("enabled-readonly-styled");\r
+        addComponent(df);\r
+        addComponent(new Button("Toggle disabled for date field",\r
+                new Button.ClickListener() {\r
+                    public void buttonClick(ClickEvent event) {\r
+                        df.setEnabled(!df.isEnabled());\r
+                    }\r
+                }));\r
+        addComponent(new Button("Toggle read only for date field",\r
+                new Button.ClickListener() {\r
+                    public void buttonClick(ClickEvent event) {\r
+                        df.setReadOnly(!df.isReadOnly());\r
+                    }\r
+                }));\r
+    }\r
+\r
+    @Override\r
+    protected String getDescription() {\r
+        return "Setting the disabled state doesn't recalculate the input element width. Setting the read-only state instead recalculates the width. In both cases, the popup button is hidden using CSS.<br><br>The DateField is also given a style name 'test', but that style isn't applied on the calendar popup element.";\r
+    }\r
+\r
+    @Override\r
+    protected Integer getTicketNumber() {\r
+        return 8085;\r
+    }\r
+\r
+}\r
diff --git a/tests/testbench/com/vaadin/tests/components/formlayout/FormLayoutCaptionStyles.html b/tests/testbench/com/vaadin/tests/components/formlayout/FormLayoutCaptionStyles.html
new file mode 100644 (file)
index 0000000..14b5cc4
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.formlayout.FormLayoutCaptionStyles?restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentsformlayoutFormLayoutCaptionStyles::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFormLayout[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>v-caption-bold</td>
+</tr>
+<tr>
+       <td>assertCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentsformlayoutFormLayoutCaptionStyles::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[1]</td>
+       <td>bold</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsformlayoutFormLayoutCaptionStyles::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertNotCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentsformlayoutFormLayoutCaptionStyles::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VTextField[1]</td>
+       <td>bold</td>
+</tr>
+<tr>
+       <td>assertNotCSSClass</td>
+       <td>vaadin=runcomvaadintestscomponentsformlayoutFormLayoutCaptionStyles::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFormLayout[0]/domChild[0]/domChild[1]/domChild[2]/domChild[0]/domChild[0]</td>
+       <td>v-caption-bold</td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/tests/testbench/com/vaadin/tests/components/formlayout/FormLayoutCaptionStyles.java b/tests/testbench/com/vaadin/tests/components/formlayout/FormLayoutCaptionStyles.java
new file mode 100644 (file)
index 0000000..e74969f
--- /dev/null
@@ -0,0 +1,55 @@
+package com.vaadin.tests.components.formlayout;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.TextField;
+
+public class FormLayoutCaptionStyles extends TestBase {
+
+    @Override
+    protected void setup() {
+        setTheme("reindeer-tests");
+        FormLayout fl = new FormLayout();
+
+        TextField f1 = createTextField("Text field 1", "");
+        final TextField f2 = createTextField("Text field 2", "bold");
+
+        fl.addComponent(f1);
+        fl.addComponent(new Button("Toggle Text field 2 bold style",
+                new Button.ClickListener() {
+
+                    public void buttonClick(ClickEvent event) {
+                        if ("bold".equals(f2.getStyleName())) {
+                            f2.setStyleName("");
+                        } else {
+                            f2.setStyleName("bold");
+                        }
+
+                    }
+
+                }));
+        fl.addComponent(f2);
+
+        addComponent(fl);
+
+    }
+
+    private TextField createTextField(String caption, String style) {
+        TextField tf = new TextField(caption);
+        tf.setStyleName(style);
+        return tf;
+    }
+
+    @Override
+    protected String getDescription() {
+        return "The component style should be copied to the caption element. Changing the component style should update the caption style also";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 5982;
+    }
+
+}
diff --git a/tests/testbench/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.html b/tests/testbench/com/vaadin/tests/components/orderedlayout/OrderedLayoutCases.html
new file mode 100644 (file)
index 0000000..9e14005
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.orderedlayout.OrderedLayoutCases?restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutOrderedLayoutCases::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>1-undefined-without-relative</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutOrderedLayoutCases::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>2-undefined-with-relative</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutOrderedLayoutCases::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>3-fixed-with-overflow</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutOrderedLayoutCases::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[3]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>4-fixed-with-extra-space</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutOrderedLayoutCases::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[7]/VButton[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<!-- Going in the reverse direction from here to avoid some bugs where state is not properly updated -->
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>8-undefined-relative-height</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutOrderedLayoutCases::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[6]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>7-fixed-relative-height</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutOrderedLayoutCases::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[5]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>6-multiple-expands</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutOrderedLayoutCases::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[4]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>5-expand-with-alignment</td>
+</tr>
+</tbody></table>
+</body>
+</html>
index 85cc6ca5e1e6b87dc45be450817adf67534bd25b..447b5b4be64d8b9b35789757545f32bb4924d7b6 100644 (file)
@@ -12,17 +12,21 @@ import com.vaadin.tests.components.AbstractTestRoot;
 import com.vaadin.tests.util.TestUtils;
 import com.vaadin.ui.AbstractOrderedLayout;
 import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.Component;
 import com.vaadin.ui.HorizontalLayout;
 import com.vaadin.ui.NativeSelect;
 import com.vaadin.ui.VerticalLayout;
 
 public class OrderedLayoutCases extends AbstractTestRoot {
-    private static final String[] dimensionValues = { "-1px", "5px", "300px",
+    private static final String[] dimensionValues = { "-1px", "5px", "350px",
             "800px", "100%", "50%" };
 
     private static class SampleChild extends VerticalLayout {
         public SampleChild() {
-            setStyleName("showBorders");
+            setStyleName("sampleChild");
             addComponent(createSimpleSelector("Child width",
                     new ValueChangeListener() {
                         public void valueChange(ValueChangeEvent event) {
@@ -102,18 +106,24 @@ public class OrderedLayoutCases extends AbstractTestRoot {
     }
 
     private AbstractOrderedLayout currentLayout;
+    private HorizontalLayout sizeBar;
 
     @Override
     protected void setup(WrappedRequest request) {
-        TestUtils.injectCSS(getRoot(),
-                ".showBorders {border: 1px solid black};");
+        TestUtils
+                .injectCSS(
+                        getRoot(),
+                        ".sampleChild, .theLayout {border: 1px solid black;}"
+                                + ".theLayout > div > div:first-child {background: aqua;}"
+                                + ".theLayout > div > div:first-child + div {background: yellow;}"
+                                + ".theLayout > div > div:first-child + div + div {background: lightgrey;}");
 
         currentLayout = new HorizontalLayout();
         for (int i = 0; i < 3; i++) {
             currentLayout.addComponent(new SampleChild());
         }
 
-        HorizontalLayout sizeBar = new HorizontalLayout();
+        sizeBar = new HorizontalLayout();
         sizeBar.setSpacing(true);
 
         sizeBar.addComponent(createSimpleSelector("Layout width",
@@ -130,6 +140,20 @@ public class OrderedLayoutCases extends AbstractTestRoot {
                                 .toString());
                     }
                 }, dimensionValues));
+        sizeBar.addComponent(createSimpleSelector("Spacing",
+                new ValueChangeListener() {
+                    public void valueChange(ValueChangeEvent event) {
+                        currentLayout.setSpacing(Boolean.parseBoolean(event
+                                .getProperty().getValue().toString()));
+                    }
+                }, "false", "true"));
+        sizeBar.addComponent(createSimpleSelector("Margin",
+                new ValueChangeListener() {
+                    public void valueChange(ValueChangeEvent event) {
+                        currentLayout.setMargin(Boolean.parseBoolean(event
+                                .getProperty().getValue().toString()));
+                    }
+                }, "false", "true"));
         sizeBar.addComponent(createSimpleSelector("Direction",
                 new ValueChangeListener() {
                     public void valueChange(ValueChangeEvent event) {
@@ -146,7 +170,7 @@ public class OrderedLayoutCases extends AbstractTestRoot {
                             newLayout.addComponent(currentLayout
                                     .getComponent(0));
                         }
-                        newLayout.setStyleName("showBorders");
+                        newLayout.setStyleName("theLayout");
 
                         newLayout.setHeight(currentLayout.getHeight(),
                                 currentLayout.getHeightUnits());
@@ -158,6 +182,112 @@ public class OrderedLayoutCases extends AbstractTestRoot {
                     }
                 }, "Horizontal", "Vertical"));
 
+        HorizontalLayout caseBar = new HorizontalLayout();
+        caseBar.addComponent(new Button("Undefined without relative",
+                new ClickListener() {
+                    public void buttonClick(ClickEvent event) {
+                        resetState();
+                        // width: 350px to middle child
+                        setChildState(1, 0, 2);
+                    }
+                }));
+        caseBar.addComponent(new Button("Undefined with relative",
+                new ClickListener() {
+                    public void buttonClick(ClickEvent event) {
+                        resetState();
+                        // width: 100% to middle child
+                        setChildState(1, 0, 4);
+                    }
+                }));
+        caseBar.addComponent(new Button("Fixed with overflow",
+                new ClickListener() {
+                    public void buttonClick(ClickEvent event) {
+                        resetState();
+                        // layout width: 350px
+                        setState(sizeBar, 0, 2);
+                        // layout margin enabled
+                        setState(sizeBar, 3, 1);
+                    }
+                }));
+        caseBar.addComponent(new Button("Fixed with extra space",
+                new ClickListener() {
+                    public void buttonClick(ClickEvent event) {
+                        resetState();
+                        // Layout width: 800px
+                        setState(sizeBar, 0, 3);
+                        // layout margin enabled
+                        setState(sizeBar, 3, 1);
+                        // width: 350px to middle child
+                        setChildState(1, 0, 2);
+                    }
+                }));
+
+        caseBar.addComponent(new Button("Expand with alignment",
+                new ClickListener() {
+                    public void buttonClick(ClickEvent event) {
+                        resetState();
+                        // Layout width: 800px
+                        setState(sizeBar, 0, 3);
+                        // Layout height: 350px
+                        setState(sizeBar, 1, 2);
+                        // Expand: 1 to middle child
+                        setChildState(1, 3, 1);
+                        // Align bottom left to middle child
+                        setChildState(1, 4, 6);
+                    }
+                }));
+
+        caseBar.addComponent(new Button("Multiple expands",
+                new ClickListener() {
+                    public void buttonClick(ClickEvent event) {
+                        resetState();
+                        // Layout width: 800px
+                        setState(sizeBar, 0, 3);
+                        // Layout height: 350px
+                        setState(sizeBar, 1, 2);
+                        // Width 350px to middle child
+                        setChildState(1, 0, 2);
+                        // Apply to left and middle child
+                        for (int i = 0; i < 2; i++) {
+                            // Expand: 1
+                            setChildState(i, 3, 1);
+                            // Align: middle center
+                            setChildState(i, 4, 5);
+                        }
+                    }
+                }));
+
+        caseBar.addComponent(new Button("Fixed + relative height",
+                new ClickListener() {
+                    public void buttonClick(ClickEvent event) {
+                        resetState();
+                        // Layout height: 100%
+                        setState(sizeBar, 1, 4);
+                        // Height: 350px to left child
+                        setChildState(0, 1, 2);
+                        // Height: 100% to middle child
+                        setChildState(1, 1, 4);
+                        // Alignment: bottom left to right child
+                        setChildState(2, 4, 7);
+                    }
+                }));
+
+        caseBar.addComponent(new Button("Undefined + relative height",
+                new ClickListener() {
+                    public void buttonClick(ClickEvent event) {
+                        resetState();
+                        // Height: 350px to left child
+                        setChildState(0, 1, 2);
+                        // Height: 100% to middle child
+                        setChildState(1, 1, 4);
+                        // Alignment: bottom left to right child
+                        setChildState(2, 4, 7);
+                    }
+                }));
+
+        caseBar.setSpacing(true);
+
+        addComponent(caseBar);
         addComponent(sizeBar);
         addComponent(currentLayout);
 
@@ -167,6 +297,34 @@ public class OrderedLayoutCases extends AbstractTestRoot {
         getLayout().setExpandRatio(currentLayout, 1);
     }
 
+    private void resetState() {
+        for (int i = 0; i < sizeBar.getComponentCount(); i++) {
+            setState(sizeBar, i, 0);
+        }
+        for (int i = 0; i < 3; i++) {
+            // Child width and height -> -1px
+            SampleChild child = (SampleChild) currentLayout.getComponent(i);
+            for (int j = 0; j < child.getComponentCount(); j++) {
+                if (j == 4) {
+                    setState(child, j, 1);
+                } else {
+                    setState(child, j, 0);
+                }
+            }
+        }
+    }
+
+    private void setChildState(int childIndex, int selectIndex, int valueIndex) {
+        Component child = currentLayout.getComponent(childIndex);
+        setState(child, selectIndex, valueIndex);
+    }
+
+    private static void setState(Component container, int selectIndex, int value) {
+        NativeSelect select = (NativeSelect) ((AbstractOrderedLayout) container)
+                .getComponent(selectIndex);
+        select.setValue(new ArrayList<Object>(select.getItemIds()).get(value));
+    }
+
     private static NativeSelect createSimpleSelector(String caption,
             ValueChangeListener listener, String... values) {
         return createSimpleSelector(caption, listener, Arrays.asList(values),
@@ -185,14 +343,13 @@ public class OrderedLayoutCases extends AbstractTestRoot {
     }
 
     @Override
-    protected String getTestDescription() {
-        return "Tester application for exploring how Horizontal/VerticalLayout reacts to various settings ";
+    protected Integer getTicketNumber() {
+        return null;
     }
 
     @Override
-    protected Integer getTicketNumber() {
-        // TODO Auto-generated method stub
-        return null;
+    protected String getTestDescription() {
+        return "Tester application for exploring how Horizontal/VerticalLayout reacts to various settings ";
     }
 
 }
diff --git a/tests/testbench/com/vaadin/tests/components/orderedlayout/VerticalLayoutChangingChildrenSizes.html b/tests/testbench/com/vaadin/tests/components/orderedlayout/VerticalLayoutChangingChildrenSizes.html
new file mode 100644 (file)
index 0000000..edcf601
--- /dev/null
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\r
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">\r
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />\r
+<link rel="selenium.base" href="" />\r
+<title>New Test</title>\r
+</head>\r
+<body>\r
+<table cellpadding="1" cellspacing="1" border="1">\r
+<thead>\r
+<tr><td rowspan="1" colspan="3">New Test</td></tr>\r
+</thead><tbody>\r
+<tr>\r
+       <td>open</td>\r
+       <td>/run/com.vaadin.tests.components.orderedlayout.VerticalLayoutTest?restartApplication</td>\r
+       <td></td>\r
+</tr>\r
+<!--Hide event log-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::PID_Smenu#item1</td>\r
+       <td>28,5</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[0]/VMenuBar[0]#item0</td>\r
+       <td>30,8</td>\r
+</tr>\r
+<!--Add components-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::PID_Smenu#item0</td>\r
+       <td>41,8</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[0]/VMenuBar[0]#item3</td>\r
+       <td>84,6</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[1]/VMenuBar[0]#item0</td>\r
+       <td>43,6</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[2]/VMenuBar[0]#item0</td>\r
+       <td>68,8</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[3]/VMenuBar[0]#item0</td>\r
+       <td>30,11</td>\r
+</tr>\r
+<tr>\r
+       <td>screenCapture</td>\r
+       <td></td>\r
+       <td>auto-auto-one-button</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::PID_Smenu#item0</td>\r
+       <td>35,11</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[0]/VMenuBar[0]#item3</td>\r
+       <td>85,5</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[1]/VMenuBar[0]#item0</td>\r
+       <td>83,3</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[2]/VMenuBar[0]#item1</td>\r
+       <td>28,7</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[3]/VMenuBar[0]#item1</td>\r
+       <td>40,10</td>\r
+</tr>\r
+<tr>\r
+       <td>screenCapture</td>\r
+       <td></td>\r
+       <td>auto-auto-two-buttons</td>\r
+</tr>\r
+<!--Component 0 -> 100%-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::PID_Smenu#item0</td>\r
+       <td>42,6</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[0]/VMenuBar[0]#item3</td>\r
+       <td>77,6</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[1]/VMenuBar[0]#item2</td>\r
+       <td>115,7</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[2]/VMenuBar[0]#item0</td>\r
+       <td>72,8</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[3]/VMenuBar[0]#item4</td>\r
+       <td>14,2</td>\r
+</tr>\r
+<tr>\r
+       <td>screenCapture</td>\r
+       <td></td>\r
+       <td>auto-auto-two-buttons-equal-width</td>\r
+</tr>\r
+<!--Component 1 -> 200px height-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::PID_Smenu#item0</td>\r
+       <td>22,9</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[0]/VMenuBar[0]#item3</td>\r
+       <td>117,9</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[1]/VMenuBar[0]#item3</td>\r
+       <td>104,8</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[2]/VMenuBar[0]#item1</td>\r
+       <td>74,12</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[3]/VMenuBar[0]#item2</td>\r
+       <td>23,8</td>\r
+</tr>\r
+<tr>\r
+       <td>screenCapture</td>\r
+       <td></td>\r
+       <td>auto-auto-two-buttons-lower-higher</td>\r
+</tr>\r
+<!--Back to what we had before-->\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::PID_Smenu#item0</td>\r
+       <td>24,11</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[0]/VMenuBar[0]#item3</td>\r
+       <td>104,12</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[1]/VMenuBar[0]#item2</td>\r
+       <td>114,10</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[2]/VMenuBar[0]#item0</td>\r
+       <td>87,11</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[3]/VMenuBar[0]#item0</td>\r
+       <td>17,8</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::PID_Smenu#item0</td>\r
+       <td>28,3</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[0]/VMenuBar[0]#item3</td>\r
+       <td>77,8</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[1]/VMenuBar[0]#item3</td>\r
+       <td>96,6</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[2]/VMenuBar[0]#item1</td>\r
+       <td>75,10</td>\r
+</tr>\r
+<tr>\r
+       <td>mouseClick</td>\r
+       <td>vaadin=runcomvaadintestscomponentsorderedlayoutVerticalLayoutTest::Root/VOverlay[3]/VMenuBar[0]#item0</td>\r
+       <td>19,3</td>\r
+</tr>\r
+<tr>\r
+       <td>screenCapture</td>\r
+       <td></td>\r
+       <td>auto-auto-two-buttons</td>\r
+</tr>\r
+</tbody></table>\r
+</body>\r
+</html>\r
diff --git a/tests/testbench/com/vaadin/tests/components/table/ScrollDetachSynchronization.java b/tests/testbench/com/vaadin/tests/components/table/ScrollDetachSynchronization.java
new file mode 100644 (file)
index 0000000..3b0234d
--- /dev/null
@@ -0,0 +1,88 @@
+package com.vaadin.tests.components.table;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Layout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.VerticalLayout;
+
+public class ScrollDetachSynchronization extends TestBase {
+
+    @Override
+    public void setup() {
+        getMainWindow().setContent(buildLayout());
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Scrolling, then detaching, a table causes out of sync on IE";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 6970;
+    }
+
+    private Layout buildLayout() {
+        final VerticalLayout mainLayout = new VerticalLayout();
+        mainLayout.setSizeFull();
+
+        HorizontalLayout buttonBar = new HorizontalLayout();
+        buttonBar.setSizeUndefined();
+        Button first = new Button("First layout");
+        Button second = new Button("Second layout");
+        first.setDebugId("FirstButton");
+        second.setDebugId("SecondButton");
+        buttonBar.addComponent(first);
+        buttonBar.addComponent(second);
+        mainLayout.addComponent(buttonBar);
+
+        final HorizontalLayout firstLayout = buildTestLayout(true);
+        final HorizontalLayout secondLayout = buildTestLayout(false);
+
+        mainLayout.addComponent(firstLayout);
+        mainLayout.setExpandRatio(firstLayout, 1);
+
+        first.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                if (mainLayout.getComponent(1).equals(secondLayout)) {
+                    mainLayout.replaceComponent(secondLayout, firstLayout);
+                    mainLayout.setExpandRatio(firstLayout, 1);
+                }
+            }
+        });
+        second.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                if (mainLayout.getComponent(1).equals(firstLayout)) {
+                    mainLayout.replaceComponent(firstLayout, secondLayout);
+                    mainLayout.setExpandRatio(secondLayout, 1);
+                }
+            }
+        });
+        return mainLayout;
+    }
+
+    private HorizontalLayout buildTestLayout(boolean first) {
+        String which = first ? "First" : "Second";
+
+        HorizontalLayout hl = new HorizontalLayout();
+        hl.setSizeFull();
+        hl.setDebugId(which + "Layout");
+
+        Table t = new Table();
+        t.addContainerProperty("name", String.class, null);
+        for (int i = 0; i < 10; i++) {
+            String id = which + " " + i;
+            t.addItem(new String[] { id }, id);
+        }
+        t.setDebugId(which + "Table");
+        t.setItemCaptionPropertyId("name");
+        t.setSizeFull();
+
+        hl.addComponent(t);
+
+        return hl;
+    }
+}
index 8540e39c8c198391a73f07d79ef79a3de6dda8fd..bce96ebceda589d1e97dadbf0fbf6ae83778b61c 100644 (file)
@@ -10,10 +10,14 @@ public class TableHeaderZoom extends TestBase {
     @Override
     protected void setup() {
         Table table = new Table();
-        table.setHeight("100px");
-        table.setWidth("200px");
-        table.setEnabled(false);
+        table.setHeight("400px");
+        table.setWidth("400px");
         table.addContainerProperty("Column 1", String.class, "");
+        table.addContainerProperty("Column 2", String.class, "");
+
+        for (int i = 0; i < 100; ++i) {
+            table.addItem(new Object[] { "" + i, "foo" }, i);
+        }
 
         LegacyWindow main = getMainWindow();
         main.setContent(new CssLayout());
diff --git a/tests/testbench/com/vaadin/tests/components/table/TableRepaintWhenMadeVisibile.java b/tests/testbench/com/vaadin/tests/components/table/TableRepaintWhenMadeVisibile.java
new file mode 100644 (file)
index 0000000..a536303
--- /dev/null
@@ -0,0 +1,43 @@
+package com.vaadin.tests.components.table;\r
+\r
+import com.vaadin.tests.components.TestBase;\r
+import com.vaadin.ui.Button;\r
+import com.vaadin.ui.Button.ClickEvent;\r
+import com.vaadin.ui.Button.ClickListener;\r
+import com.vaadin.ui.Table;\r
+\r
+public class TableRepaintWhenMadeVisibile extends TestBase {\r
+\r
+    @Override\r
+    public void setup() {\r
+        final Table table = new Table();\r
+        table.addContainerProperty("sth", String.class, null);\r
+        table.addItem(new Object[] { "something" }, 1);\r
+        addComponent(table);\r
+\r
+        Button show = new Button("show", new ClickListener() {\r
+\r
+            public void buttonClick(ClickEvent event) {\r
+                table.setVisible(true);\r
+            }\r
+        });\r
+        addComponent(show);\r
+        Button hide = new Button("hide", new ClickListener() {\r
+\r
+            public void buttonClick(ClickEvent event) {\r
+                table.setVisible(false);\r
+            }\r
+        });\r
+        addComponent(hide);\r
+    }\r
+\r
+    @Override\r
+    protected String getDescription() {\r
+        return "A Table should be rendered correctly when made visible again after being initially rendered invisible. Click 'hide', refresh the application and then click 'show'";\r
+    }\r
+\r
+    @Override\r
+    protected Integer getTicketNumber() {\r
+        return 7986;\r
+    }\r
+}\r
diff --git a/tests/testbench/com/vaadin/tests/components/table/TableRepaintWhenMadeVisible.html b/tests/testbench/com/vaadin/tests/components/table/TableRepaintWhenMadeVisible.html
new file mode 100644 (file)
index 0000000..0563acd
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.table.TableRepaintWhenMadeVisibile?restartApplication</td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableRepaintWhenMadeVisibile::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.components.table.TableRepaintWhenMadeVisibile</td>
+       <td></td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestscomponentstableTableRepaintWhenMadeVisibile::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>hidden-then-shown</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
index afdf72bb83164f29306ba05708deb3124a252bfc..3b13c9136b84c32e9a86244564db95d37e219f2a 100644 (file)
@@ -15,8 +15,10 @@ import com.vaadin.ui.Button;
 import com.vaadin.ui.Label;\r
 import com.vaadin.ui.Label.ContentMode;\r
 import com.vaadin.ui.Table;\r
+import com.vaadin.ui.Table.Align;\r
 import com.vaadin.ui.Table.CellStyleGenerator;\r
 import com.vaadin.ui.Table.ColumnGenerator;\r
+import com.vaadin.ui.Table.ColumnHeaderMode;\r
 import com.vaadin.ui.Table.ColumnResizeEvent;\r
 import com.vaadin.ui.Table.ColumnResizeListener;\r
 import com.vaadin.ui.Table.FooterClickEvent;\r
@@ -25,6 +27,7 @@ import com.vaadin.ui.Table.GeneratedRow;
 import com.vaadin.ui.Table.HeaderClickEvent;\r
 import com.vaadin.ui.Table.HeaderClickListener;\r
 import com.vaadin.ui.Table.RowGenerator;\r
+import com.vaadin.ui.Table.RowHeaderMode;\r
 \r
 public class Tables<T extends Table> extends AbstractSelectTestCase<T>\r
         implements ItemClickListener, HeaderClickListener, FooterClickListener,\r
@@ -42,9 +45,9 @@ public class Tables<T extends Table> extends AbstractSelectTestCase<T>
     }\r
 \r
     /* COMMANDS */\r
-    private Command<T, String> columnAlignmentCommand = new Command<T, String>() {\r
+    private Command<T, Align> columnAlignmentCommand = new Command<T, Align>() {\r
 \r
-        public void execute(T c, String alignment, Object propertyId) {\r
+        public void execute(T c, Align alignment, Object propertyId) {\r
             c.setColumnAlignment(propertyId, alignment);\r
         }\r
 \r
@@ -108,10 +111,10 @@ public class Tables<T extends Table> extends AbstractSelectTestCase<T>
         }\r
     };\r
 \r
-    protected Command<T, Integer> rowHeaderModeCommand = new Command<T, Integer>() {\r
+    protected Command<T, RowHeaderMode> rowHeaderModeCommand = new Command<T, RowHeaderMode>() {\r
 \r
-        public void execute(Table c, Integer value, Object data) {\r
-            if (value == Table.ROW_HEADER_MODE_PROPERTY) {\r
+        public void execute(Table c, RowHeaderMode value, Object data) {\r
+            if (value == RowHeaderMode.PROPERTY) {\r
                 c.setItemCaptionPropertyId("Property 3");\r
             }\r
             c.setRowHeaderMode(value);\r
@@ -135,7 +138,7 @@ public class Tables<T extends Table> extends AbstractSelectTestCase<T>
     protected Command<T, Object> alignColumnLeftCommand = new Command<T, Object>() {\r
 \r
         public void execute(T c, Object propertyId, Object data) {\r
-            c.setColumnAlignment(propertyId, (String) data);\r
+            c.setColumnAlignment(propertyId, (Align) data);\r
         }\r
     };\r
 \r
@@ -174,9 +177,9 @@ public class Tables<T extends Table> extends AbstractSelectTestCase<T>
 \r
         }\r
     };\r
-    private Command<T, Integer> columnHeaderModeCommand = new Command<T, Integer>() {\r
+    private Command<T, ColumnHeaderMode> columnHeaderModeCommand = new Command<T, ColumnHeaderMode>() {\r
 \r
-        public void execute(T c, Integer columnHeaderMode, Object data) {\r
+        public void execute(T c, ColumnHeaderMode columnHeaderMode, Object data) {\r
             c.setColumnHeaderMode(columnHeaderMode);\r
 \r
         }\r
@@ -477,13 +480,12 @@ public class Tables<T extends Table> extends AbstractSelectTestCase<T>
     }\r
 \r
     private void createColumnHeaderMode(String category) {\r
-        LinkedHashMap<String, Integer> columnHeaderModeOptions = new LinkedHashMap<String, Integer>();\r
-        columnHeaderModeOptions.put("Hidden", Table.COLUMN_HEADER_MODE_HIDDEN);\r
-        columnHeaderModeOptions.put("Id", Table.COLUMN_HEADER_MODE_ID);\r
-        columnHeaderModeOptions.put("Explicit",\r
-                Table.COLUMN_HEADER_MODE_EXPLICIT);\r
+        LinkedHashMap<String, ColumnHeaderMode> columnHeaderModeOptions = new LinkedHashMap<String, ColumnHeaderMode>();\r
+        columnHeaderModeOptions.put("Hidden", ColumnHeaderMode.HIDDEN);\r
+        columnHeaderModeOptions.put("Id", ColumnHeaderMode.ID);\r
+        columnHeaderModeOptions.put("Explicit", ColumnHeaderMode.EXPLICIT);\r
         columnHeaderModeOptions.put("Explicit defaults id",\r
-                Table.COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID);\r
+                ColumnHeaderMode.EXPLICIT_DEFAULTS_ID);\r
 \r
         createSelectAction("Column header mode", category,\r
                 columnHeaderModeOptions, "Explicit defaults id",\r
@@ -603,10 +605,10 @@ public class Tables<T extends Table> extends AbstractSelectTestCase<T>
         createBooleanAction("Collapsed", category, false, columnCollapsed,\r
                 propertyId);\r
         t.log("Collapsed");\r
-        LinkedHashMap<String, String> options = new LinkedHashMap<String, String>();\r
-        options.put("Left", Table.ALIGN_LEFT);\r
-        options.put("Center", Table.ALIGN_CENTER);\r
-        options.put("Right", Table.ALIGN_RIGHT);\r
+        LinkedHashMap<String, Align> options = new LinkedHashMap<String, Align>();\r
+        options.put("Left", Align.LEFT);\r
+        options.put("Center", Align.CENTER);\r
+        options.put("Right", Align.RIGHT);\r
 \r
         createSelectAction("Alignment", category, options, "Left",\r
                 columnAlignmentCommand, propertyId);\r
@@ -652,16 +654,15 @@ public class Tables<T extends Table> extends AbstractSelectTestCase<T>
     }\r
 \r
     private void createRowHeaderModeSelect(String category) {\r
-        LinkedHashMap<String, Integer> options = new LinkedHashMap<String, Integer>();\r
-        options.put("Explicit", Table.ROW_HEADER_MODE_EXPLICIT);\r
-        options.put("Explicit defaults id",\r
-                Table.ROW_HEADER_MODE_EXPLICIT_DEFAULTS_ID);\r
-        options.put("Hidden", Table.ROW_HEADER_MODE_HIDDEN);\r
-        options.put("Icon only", Table.ROW_HEADER_MODE_ICON_ONLY);\r
-        options.put("Id", Table.ROW_HEADER_MODE_ID);\r
-        options.put("Index", Table.ROW_HEADER_MODE_INDEX);\r
-        options.put("Item", Table.ROW_HEADER_MODE_ITEM);\r
-        options.put("'Property 3' property", Table.ROW_HEADER_MODE_PROPERTY);\r
+        LinkedHashMap<String, RowHeaderMode> options = new LinkedHashMap<String, RowHeaderMode>();\r
+        options.put("Explicit", RowHeaderMode.EXPLICIT);\r
+        options.put("Explicit defaults id", RowHeaderMode.EXPLICIT_DEFAULTS_ID);\r
+        options.put("Hidden", RowHeaderMode.HIDDEN);\r
+        options.put("Icon only", RowHeaderMode.ICON_ONLY);\r
+        options.put("Id", RowHeaderMode.ID);\r
+        options.put("Index", RowHeaderMode.INDEX);\r
+        options.put("Item", RowHeaderMode.ITEM);\r
+        options.put("'Property 3' property", RowHeaderMode.PROPERTY);\r
 \r
         createSelectAction("Row header mode", category, options, "Hidden",\r
                 rowHeaderModeCommand);\r
@@ -741,17 +742,17 @@ public class Tables<T extends Table> extends AbstractSelectTestCase<T>
     }\r
 \r
     protected void createHeaderVisibilitySelect(String category) {\r
-        LinkedHashMap<String, Integer> options = new LinkedHashMap<String, Integer>();\r
-        options.put("Explicit", Table.COLUMN_HEADER_MODE_EXPLICIT);\r
+        LinkedHashMap<String, ColumnHeaderMode> options = new LinkedHashMap<String, ColumnHeaderMode>();\r
+        options.put("Explicit", ColumnHeaderMode.EXPLICIT);\r
         options.put("Explicit defaults id",\r
-                Table.COLUMN_HEADER_MODE_EXPLICIT_DEFAULTS_ID);\r
-        options.put("Id", Table.COLUMN_HEADER_MODE_ID);\r
-        options.put("Hidden", Table.COLUMN_HEADER_MODE_HIDDEN);\r
+                ColumnHeaderMode.EXPLICIT_DEFAULTS_ID);\r
+        options.put("Id", ColumnHeaderMode.ID);\r
+        options.put("Hidden", ColumnHeaderMode.HIDDEN);\r
 \r
         createSelectAction("Header mode", category, options,\r
-                "Explicit defaults id", new Command<T, Integer>() {\r
+                "Explicit defaults id", new Command<T, ColumnHeaderMode>() {\r
 \r
-                    public void execute(T c, Integer value, Object data) {\r
+                    public void execute(T c, ColumnHeaderMode value, Object data) {\r
                         c.setColumnHeaderMode(value);\r
 \r
                     }\r
diff --git a/tests/testbench/com/vaadin/tests/components/tabsheet/WrapTabSheetInTabSheet.java b/tests/testbench/com/vaadin/tests/components/tabsheet/WrapTabSheetInTabSheet.java
new file mode 100644 (file)
index 0000000..e594757
--- /dev/null
@@ -0,0 +1,42 @@
+package com.vaadin.tests.components.tabsheet;\r
+\r
+import com.vaadin.Application;\r
+import com.vaadin.tests.components.TestBase;\r
+import com.vaadin.ui.Button;\r
+import com.vaadin.ui.Button.ClickEvent;\r
+import com.vaadin.ui.ComponentContainer;\r
+import com.vaadin.ui.Label;\r
+import com.vaadin.ui.TabSheet;\r
+import com.vaadin.ui.VerticalLayout;\r
+import com.vaadin.ui.Window;\r
+\r
+public class WrapTabSheetInTabSheet extends TestBase {\r
+    @Override\r
+    protected void setup() {\r
+        final VerticalLayout mainLayout = new VerticalLayout();\r
+        mainLayout.addComponent(new Label("This is main layout"));\r
+        addComponent(mainLayout);\r
+\r
+        Button b = new Button("Wrap main layout in a TabSheet");\r
+        b.addListener(new Button.ClickListener() {\r
+            public void buttonClick(ClickEvent event) {\r
+                TabSheet tabsheet = new TabSheet();\r
+                ComponentContainer mainParent = (ComponentContainer) mainLayout\r
+                        .getParent();\r
+                mainParent.replaceComponent(mainLayout, tabsheet);\r
+                tabsheet.addTab(mainLayout, "Default tab");\r
+            }\r
+        });\r
+        mainLayout.addComponent(b);\r
+    }\r
+\r
+    @Override\r
+    protected String getDescription() {\r
+        return "Click the button to add a TabSheet and move the window content into the TabSheet. Every click should wrap the contents with a new TabSheet and the contents should remain visible.";\r
+    }\r
+\r
+    @Override\r
+    protected Integer getTicketNumber() {\r
+        return 8238;\r
+    }\r
+}\r
diff --git a/tests/testbench/com/vaadin/tests/components/textarea/TextAreaCursorPosition.java b/tests/testbench/com/vaadin/tests/components/textarea/TextAreaCursorPosition.java
new file mode 100644 (file)
index 0000000..0fc6386
--- /dev/null
@@ -0,0 +1,54 @@
+package com.vaadin.tests.components.textarea;
+
+import com.vaadin.event.FieldEvents.TextChangeEvent;
+import com.vaadin.event.FieldEvents.TextChangeListener;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.AbstractField;
+import com.vaadin.ui.AbstractTextField;
+import com.vaadin.ui.AbstractTextField.TextChangeEventMode;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextArea;
+import com.vaadin.ui.TextField;
+
+public class TextAreaCursorPosition extends TestBase {
+
+    private TextField cursorPosition = new TextField("Cursor position");
+
+    @Override
+    public void setup() {
+        Label label = new Label(
+                "Test of calculation of cursor position of TextArea");
+        TextArea textArea = new TextArea();
+        addListener(textArea);
+        addComponent(label);
+        addComponent(textArea);
+        addComponent(cursorPosition);
+        cursorPosition.setValue("?");
+        addComponent(new Button("Force position update"));
+    }
+
+    public void addListener(AbstractField newField) {
+        AbstractTextField newTextField = (AbstractTextField) newField;
+        newTextField.setTextChangeEventMode(TextChangeEventMode.EAGER);
+
+        newTextField.addListener(new TextChangeListener() {
+            public void textChange(TextChangeEvent event) {
+                AbstractTextField component = (AbstractTextField) event
+                        .getComponent();
+                cursorPosition.setValue(component.getCursorPosition());
+            }
+        });
+    }
+
+    @Override
+    protected String getDescription() {
+        return "Writing something in the field updates the cursor position field. The position field can also be updated using the button.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 7726;
+    }
+
+}
diff --git a/tests/testbench/com/vaadin/tests/components/textfield/TextFieldInputPromptAndClickShortcut.java b/tests/testbench/com/vaadin/tests/components/textfield/TextFieldInputPromptAndClickShortcut.java
new file mode 100644 (file)
index 0000000..c04c9d6
--- /dev/null
@@ -0,0 +1,59 @@
+package com.vaadin.tests.components.textfield;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.event.ShortcutAction.KeyCode;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.tests.util.Log;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.TextField;
+
+public class TextFieldInputPromptAndClickShortcut extends TestBase {
+
+    @Override
+    protected void setup() {
+        final Log log = new Log(5);
+
+        final TextField textField = new TextField();
+        Button button = new Button("Show Text", new ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                log.log("Field value: " + textField.getValue());
+            }
+        });
+        button.setClickShortcut(KeyCode.ESCAPE);
+
+        final CheckBox inputPromptSelection = new CheckBox("Input prompt");
+        inputPromptSelection.setImmediate(true);
+        inputPromptSelection.addListener(new ValueChangeListener() {
+            public void valueChange(ValueChangeEvent event) {
+                if (event.getProperty().getValue() == Boolean.TRUE) {
+                    textField.setInputPrompt("Input prompt");
+                } else {
+                    textField.setInputPrompt(null);
+                }
+                log.log("Set input prompt: " + textField.getInputPrompt());
+            }
+        });
+        inputPromptSelection.setImmediate(true);
+
+        addComponent(textField);
+        addComponent(button);
+        addComponent(inputPromptSelection);
+        addComponent(log);
+    }
+
+    @Override
+    protected String getDescription() {
+        return "With the input propmpt enabled, enter something into the field, press enter, remove the entered text and press the button. The previous text is still reported as the value. Without the input prompt, the new value is instead reported as blank.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}