]> source.dussan.org Git - vaadin-framework.git/commitdiff
Merged with 6.2
authorPetter Holmström <petter.holmstrom@itmill.com>
Fri, 30 Oct 2009 11:04:13 +0000 (11:04 +0000)
committerPetter Holmström <petter.holmstrom@itmill.com>
Fri, 30 Oct 2009 11:04:13 +0000 (11:04 +0000)
svn changeset:9505/svn branch:portlet_2.0

13 files changed:
WebContent/VAADIN/themes/reindeer/common/common.css
WebContent/VAADIN/themes/reindeer/styles.css
WebContent/VAADIN/themes/runo/common/common.css
WebContent/VAADIN/themes/runo/styles.css
src/com/vaadin/terminal/gwt/client/ui/VForm.java
src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
src/com/vaadin/terminal/gwt/client/ui/VView.java
src/com/vaadin/terminal/gwt/server/CommunicationManager.java
src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java
src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java
src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java
src/com/vaadin/ui/Upload.java
src/com/vaadin/ui/Window.java

index 09d22f35bbdc71512b787f0e7ad32d8a6cba9112..731e0eaf1bdbbbfc69b34f56b7fd0adb808b1be8 100644 (file)
@@ -73,7 +73,6 @@
        background-color: #fffcdd;
        border: 1px solid #b8b295;
        font-size: 11px;
-       line-height: 13px;
        color: #222;
 }
 .v-tooltip-text {
index 65e64a0724c70abe6c6f23fa4a132ab6c9d2a165..e2f782424debfc5f94a80a618c06db432f95df66 100644 (file)
@@ -2304,7 +2304,6 @@ div.v-tree-node-leaf {
        background-color: #fffcdd;
        border: 1px solid #b8b295;
        font-size: 11px;
-       line-height: 13px;
        color: #222;
 }
 .v-tooltip-text {
index 7b40130c45c2b690cd64ff421b0f7027f533633c..7b8317c4f3a78a84561f6ab206707f8c6b528e11 100644 (file)
@@ -38,7 +38,6 @@
        border-top-color: #d5d2c1;
        border-left-color: #d5d2c1;
        font-size: 11px;
-       line-height: 13px;
        font-family: arial, helvetica, tahoma, verdana, sans-serif;
        color: #5d5444;
 }
index 94d2f81d33dd7834f1a8a1407709ddf6a4cb95e5..88e08840e118150ce141246a40e289140151a0af 100644 (file)
@@ -1847,7 +1847,6 @@ div.v-tree-node-leaf {
        border-top-color: #d5d2c1;
        border-left-color: #d5d2c1;
        font-size: 11px;
-       line-height: 13px;
        font-family: arial, helvetica, tahoma, verdana, sans-serif;
        color: #5d5444;
 }
index 97fbf9b72aa48030f744a5a8cc73679f423a7f22..7117d2cebff60982cdcbb77fd6b9282efb3d25b3 100644 (file)
@@ -48,9 +48,7 @@ public class VForm extends ComplexPanel implements Container {
 \r
     private RenderInformation renderInformation = new RenderInformation();\r
 \r
-    private int borderPaddingHorizontal;\r
-\r
-    private int borderPaddingVertical;\r
+    private int borderPaddingHorizontal = -1;\r
 \r
     private boolean rendering = false;\r
 \r
@@ -75,25 +73,13 @@ public class VForm extends ComplexPanel implements Container {
 \r
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
         rendering = true;\r
-        boolean measure = false;\r
-        if (this.client == null) {\r
-            this.client = client;\r
-            measure = true;\r
-        }\r
+        this.client = client;\r
 \r
         if (client.updateComponent(this, uidl, false)) {\r
             rendering = false;\r
             return;\r
         }\r
 \r
-        if (measure) {\r
-            // Measure the border when the style names have been set\r
-            borderPaddingVertical = getOffsetHeight();\r
-            int ow = getOffsetWidth();\r
-            int dow = desc.getOffsetWidth();\r
-            borderPaddingHorizontal = ow - dow;\r
-        }\r
-\r
         boolean legendEmpty = true;\r
         if (uidl.hasAttribute("caption")) {\r
             DOM.setInnerText(caption, uidl.getStringAttribute("caption"));\r
@@ -138,19 +124,8 @@ public class VForm extends ComplexPanel implements Container {
         // TODO Check if this is needed\r
         client.runDescendentsLayout(this);\r
 \r
-        final UIDL layoutUidl = uidl.getChildUIDL(0);\r
-        Container newLo = (Container) client.getPaintable(layoutUidl);\r
-        if (lo == null) {\r
-            lo = newLo;\r
-            add((Widget) lo, fieldContainer);\r
-        } else if (lo != newLo) {\r
-            client.unregisterPaintable(lo);\r
-            remove((Widget) lo);\r
-            lo = newLo;\r
-            add((Widget) lo, fieldContainer);\r
-        }\r
-        lo.updateFromUIDL(layoutUidl, client);\r
-\r
+        // first render footer so it will be easier to handle relative height of\r
+        // main layout\r
         if (uidl.getChildCount() > 1) {\r
             // render footer\r
             Container newFooter = (Container) client.getPaintable(uidl\r
@@ -165,13 +140,28 @@ public class VForm extends ComplexPanel implements Container {
             }\r
             footer = newFooter;\r
             footer.updateFromUIDL(uidl.getChildUIDL(1), client);\r
+            updateSize();\r
         } else {\r
             if (footer != null) {\r
                 remove((Widget) footer);\r
                 client.unregisterPaintable(footer);\r
+                updateSize();\r
             }\r
         }\r
 \r
+        final UIDL layoutUidl = uidl.getChildUIDL(0);\r
+        Container newLo = (Container) client.getPaintable(layoutUidl);\r
+        if (lo == null) {\r
+            lo = newLo;\r
+            add((Widget) lo, fieldContainer);\r
+        } else if (lo != newLo) {\r
+            client.unregisterPaintable(lo);\r
+            remove((Widget) lo);\r
+            lo = newLo;\r
+            add((Widget) lo, fieldContainer);\r
+        }\r
+        lo.updateFromUIDL(layoutUidl, client);\r
+\r
         rendering = false;\r
     }\r
 \r
@@ -181,7 +171,7 @@ public class VForm extends ComplexPanel implements Container {
 \r
         renderInformation.setContentAreaHeight(renderInformation\r
                 .getRenderedSize().getHeight()\r
-                - borderPaddingVertical);\r
+                - getSpaceConsumedVertically());\r
         if (BrowserInfo.get().isIE6()) {\r
             getElement().getStyle().setProperty("overflow", "hidden");\r
         }\r
@@ -192,18 +182,7 @@ public class VForm extends ComplexPanel implements Container {
 \r
     public RenderSpace getAllocatedSpace(Widget child) {\r
         if (child == lo) {\r
-            int hPixels = 0;\r
-            if (!"".equals(height)) {\r
-                hPixels = getOffsetHeight();\r
-                hPixels -= borderPaddingVertical;\r
-                hPixels -= footerContainer.getOffsetHeight();\r
-                hPixels -= errorMessage.getOffsetHeight();\r
-                hPixels -= desc.getOffsetHeight();\r
-\r
-            }\r
-\r
-            return new RenderSpace(renderInformation.getContentAreaSize()\r
-                    .getWidth(), hPixels);\r
+            return renderInformation.getContentAreaSize();\r
         } else if (child == footer) {\r
             return new RenderSpace(renderInformation.getContentAreaSize()\r
                     .getWidth(), 0);\r
@@ -271,8 +250,26 @@ public class VForm extends ComplexPanel implements Container {
         updateSize();\r
     }\r
 \r
+    /**\r
+     * @return pixels consumed by decoration, captions, descrioptiosn etc.. In\r
+     *         other words space, not used by the actual layout in form.\r
+     */\r
+    private int getSpaceConsumedVertically() {\r
+        int offsetHeight2 = fieldSet.getOffsetHeight();\r
+        int offsetHeight3 = fieldContainer.getOffsetHeight();\r
+        int borderPadding = offsetHeight2 - offsetHeight3;\r
+        return borderPadding;\r
+    }\r
+\r
     @Override\r
     public void setWidth(String width) {\r
+        if (borderPaddingHorizontal < 0) {\r
+            // measure excess size lazyly after stylename setting, but before\r
+            // setting width\r
+            int ow = getOffsetWidth();\r
+            int dow = desc.getOffsetWidth();\r
+            borderPaddingHorizontal = ow - dow;\r
+        }\r
         if (Util.equals(this.width, width)) {\r
             return;\r
         }\r
index 50b34193bda3d854640e1279cdf5bf3d04e931ac..575d35e5f09c93b044f15846db4d8014d0cafd05 100644 (file)
@@ -271,6 +271,16 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler {
                     .getIntAttribute("rows"));
             if (headerChangedDuringUpdate) {
                 lazyAdjustColumnWidths.schedule(1);
+            } else {
+                // webkits may still bug with their disturbing scrollbar bug,
+                // See #3457
+                // run overflow fix for scrollable area
+                DeferredCommand.addCommand(new Command() {
+                    public void execute() {
+                        Util.runWebkitOverflowAutoFix(bodyContainer
+                                .getElement());
+                    }
+                });
             }
         } else {
             if (scrollBody != null) {
index 422583cb19b6e0985311b25624677e62a764dc0b..35b411ff1bf6d79467a0a45e7f0218445399fc38 100644 (file)
@@ -183,8 +183,17 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
             final String url = open.getStringAttribute("src");
             final String target = open.getStringAttribute("name");
             if (target == null) {
-                // This window is closing. Nothing was done in the close event,
-                // so don't need to call it before going to the new url
+                // source will be opened to this browser window, but we may have
+                // to finish rendering this window in case this is a download
+                // (and window stays open).
+                DeferredCommand.addCommand(new Command() {
+                    public void execute() {
+                        goTo(url);
+                    }
+                });
+            } else if ("_self".equals(target)) {
+                // This window is closing (for sure). Only other opens are
+                // relevant in this change. See #3558, #2144
                 isClosed = true;
                 goTo(url);
             } else {
@@ -214,7 +223,8 @@ public class VView extends SimplePanel implements Container, ResizeHandler,
             childIndex++;
         }
         if (isClosed) {
-            // don't render the content
+            // don't render the content, something else will be opened to this
+            // browser view
             rendering = false;
             return;
         }
index 8e73098454351162bebd981b76918c69d398bcd6..4238aab01919b0c641b9120b7f3db82a5c9d0ccc 100644 (file)
@@ -62,6 +62,7 @@ import com.vaadin.ui.AbstractField;
 import com.vaadin.ui.Component;
 import com.vaadin.ui.Upload;
 import com.vaadin.ui.Window;
+import com.vaadin.ui.Upload.UploadException;
 
 /**
  * Application manager processes changes and paints for single application
@@ -203,7 +204,18 @@ public class CommunicationManager implements Paintable.RepaintRequestListener,
                     // file
                     pl.setUpload(uploadComponent);
 
-                    uploadComponent.receiveUpload(upstream);
+                    try {
+                        uploadComponent.receiveUpload(upstream);
+                    } catch (UploadException e) {
+                        // error happened while receiving file. Handle the
+                        // error in the same manner as it would have happened in
+                        // variable change.
+                        synchronized (application) {
+                            handleChangeVariablesError(application,
+                                    uploadComponent, e,
+                                    new HashMap<String, Object>());
+                        }
+                    }
                 }
             }
         } catch (final FileUploadException e) {
index 023764ca43064608e61851ab551dc25cdd001068..9497b26b00629ae64e1a5c5ad3417d0ac97836c2 100644 (file)
@@ -212,7 +212,7 @@ public class JsonPaintTarget implements PaintTarget {
         if (xml == null || xml.length() <= 0) {
             return "";
         }
-        return escapeXML(new StringBuffer(xml)).toString();
+        return escapeXML(new StringBuilder(xml)).toString();
     }
 
     /**
@@ -220,16 +220,16 @@ public class JsonPaintTarget implements PaintTarget {
      * 
      * @param xml
      *            the String to be substituted.
-     * @return A new StringBuffer instance where all occurrences of XML
+     * @return A new StringBuilder instance where all occurrences of XML
      *         sensitive characters are substituted with entities.
      * 
      */
-    static public StringBuffer escapeXML(StringBuffer xml) {
+    static StringBuilder escapeXML(StringBuilder xml) {
         if (xml == null || xml.length() <= 0) {
-            return new StringBuffer("");
+            return new StringBuilder("");
         }
 
-        final StringBuffer result = new StringBuffer(xml.length() * 2);
+        final StringBuilder result = new StringBuilder(xml.length() * 2);
 
         for (int i = 0; i < xml.length(); i++) {
             final char c = xml.charAt(i);
@@ -247,7 +247,7 @@ public class JsonPaintTarget implements PaintTarget {
         if (s == null) {
             return "";
         }
-        final StringBuffer sb = new StringBuffer();
+        final StringBuilder sb = new StringBuilder();
         for (int i = 0; i < s.length(); i++) {
             final char ch = s.charAt(i);
             switch (ch) {
@@ -531,7 +531,7 @@ public class JsonPaintTarget implements PaintTarget {
             throw new NullPointerException(
                     "Parameters must be non-null strings");
         }
-        final StringBuffer buf = new StringBuffer();
+        final StringBuilder buf = new StringBuilder();
         buf.append("\"" + name + "\":[");
         for (int i = 0; i < values.length; i++) {
             if (i > 0) {
@@ -875,7 +875,7 @@ public class JsonPaintTarget implements PaintTarget {
 
         Vector attr = new Vector();
 
-        StringBuffer data = new StringBuffer();
+        StringBuilder data = new StringBuilder();
 
         public boolean childrenArrayOpen = false;
 
@@ -944,7 +944,7 @@ public class JsonPaintTarget implements PaintTarget {
         }
 
         public String getData() {
-            final StringBuffer buf = new StringBuffer();
+            final StringBuilder buf = new StringBuilder();
             final Iterator it = children.iterator();
             while (it.hasNext()) {
                 buf.append(startField());
@@ -958,7 +958,7 @@ public class JsonPaintTarget implements PaintTarget {
         }
 
         private String attributesAsJsonObject() {
-            final StringBuffer buf = new StringBuffer();
+            final StringBuilder buf = new StringBuilder();
             buf.append(startField());
             buf.append("{");
             for (final Iterator iter = attr.iterator(); iter.hasNext();) {
@@ -981,7 +981,7 @@ public class JsonPaintTarget implements PaintTarget {
             if (variables.size() == 0) {
                 return "";
             }
-            final StringBuffer buf = new StringBuffer();
+            final StringBuilder buf = new StringBuilder();
             buf.append(startField());
             buf.append("\"v\":{");
             final Iterator iter = variables.iterator();
@@ -1119,16 +1119,21 @@ public class JsonPaintTarget implements PaintTarget {
 
         @Override
         public String getJsonPresentation() {
-            String pres = "\"" + name + "\":[";
+            StringBuilder sb = new StringBuilder();
+            sb.append("\"");
+            sb.append(name);
+            sb.append("\":[");
             for (int i = 0; i < value.length;) {
-                pres += "\"" + value[i] + "\"";
+                sb.append("\"");
+                sb.append(escapeJSON(value[i]));
+                sb.append("\"");
                 i++;
                 if (i < value.length) {
-                    pres += ",";
+                    sb.append(",");
                 }
             }
-            pres += "]";
-            return pres;
+            sb.append("]");
+            return sb.toString();
         }
     }
 
index 6a458608038e3e9af23f35b33f8df960e7c8cb52..269d911ad1368b4c4c3f2d03da3b7dbbf146f682 100644 (file)
@@ -7,10 +7,14 @@ import java.net.JarURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.jar.Attributes;
@@ -50,7 +54,8 @@ public class ClassPathExplorer {
         }
     };
 
-    private static Map<URL, String> classpathLocations = getClasspathLocations();
+    private static List<String> rawClasspathEntries = getRawClasspathEntries();
+    private static Map<URL, String> classpathLocations = getClasspathLocations(rawClasspathEntries);
 
     private ClassPathExplorer() {
     }
@@ -150,8 +155,9 @@ public class ClassPathExplorer {
      * Determine every URL location defined by the current classpath, and it's
      * associated package name.
      */
-    private final static Map<URL, String> getClasspathLocations() {
-        Map<URL, String> locations = new HashMap<URL, String>();
+    private final static List<String> getRawClasspathEntries() {
+        // try to keep the order of the classpath
+        List<String> locations = new ArrayList<String>();
 
         String pathSep = System.getProperty("path.separator");
         String classpath = System.getProperty("java.class.path");
@@ -169,14 +175,28 @@ public class ClassPathExplorer {
         for (int i = 0; i < split.length; i++) {
             String classpathEntry = split[i];
             if (acceptClassPathEntry(classpathEntry)) {
-                File file = new File(classpathEntry);
-                include(null, file, locations);
+                locations.add(classpathEntry);
             }
         }
 
         return locations;
     }
 
+    /**
+     * Determine every URL location defined by the current classpath, and it's
+     * associated package name.
+     */
+    private final static Map<URL, String> getClasspathLocations(
+            List<String> rawClasspathEntries) {
+        // try to keep the order of the classpath
+        Map<URL, String> locations = new LinkedHashMap<URL, String>();
+        for (String classpathEntry : rawClasspathEntries) {
+            File file = new File(classpathEntry);
+            include(null, file, locations);
+        }
+        return locations;
+    }
+
     private static boolean acceptClassPathEntry(String classpathEntry) {
         if (!classpathEntry.endsWith(".jar")) {
             // accept all non jars (practically directories)
@@ -351,6 +371,41 @@ public class ClassPathExplorer {
         }
     }
 
+    /**
+     * Find and return the default source directory where to create new
+     * widgetsets.
+     *
+     * Return the first directory (not a JAR file etc.) on the classpath by
+     * default.
+     *
+     * TODO this could be done better...
+     *
+     * @return URL
+     */
+    public static URL getDefaultSourceDirectory() {
+        System.err.println("classpathLocations keys:  "
+                + classpathLocations.keySet());
+        Iterator<String> it = rawClasspathEntries.iterator();
+        while (it.hasNext()) {
+            String entry = it.next();
+
+            File directory = new File(entry);
+            if (directory.exists() && !directory.isHidden()
+                    && directory.isDirectory()) {
+                try {
+                    return new URL("file://" + directory.getCanonicalPath());
+                } catch (MalformedURLException e) {
+                    e.printStackTrace();
+                    // ignore: continue to the next classpath entry
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    // ignore: continue to the next classpath entry
+                }
+            }
+        }
+        return null;
+    }
+
     /**
      * Test method for helper tool
      */
index 6ce60972699c36c15a01eed60f2e95553e914b32..d849c85fc71bf2e169613ad2ee720b87c60a4fa6 100644 (file)
@@ -41,9 +41,14 @@ public class WidgetSetBuilder {
                 .getAvailableWidgetSets();
 
         URL sourceUrl = availableWidgetSets.get(widgetset);
+        if (sourceUrl == null) {
+            // find first/default source directory
+            sourceUrl = ClassPathExplorer.getDefaultSourceDirectory();
+        }
 
         String widgetsetfilename = sourceUrl.getFile() + "/"
                 + widgetset.replace(".", "/") + ".gwt.xml";
+
         File widgetsetFile = new File(widgetsetfilename);
         if (!widgetsetFile.exists()) {
             // create empty gwt module file
@@ -83,7 +88,7 @@ public class WidgetSetBuilder {
             }
         }
 
-        changed = changed ? true : content.equals(originalContent);
+        changed = changed || !content.equals(originalContent);
         if (changed) {
             commitChanges(widgetsetfilename, content);
         }
index 4789641193db22414a620a354b5feb95d290ec96..dfbbbfc103306589b65c5f70def776ba1dacd3ef 100644 (file)
@@ -122,7 +122,7 @@ public class Upload extends AbstractComponent implements Component.Focusable {
      * 
      * @param upload
      */
-    public void receiveUpload(UploadStream upload) {
+    public void receiveUpload(UploadStream upload) throws UploadException {
         if (!isUploading) {
             throw new IllegalStateException("uploading not started");
         }
@@ -174,7 +174,7 @@ public class Upload extends AbstractComponent implements Component.Focusable {
                     }
                 }
                 if (interrupted) {
-                    throw new Exception("Upload interrupted by other thread");
+                    throw new UploadInterruptedException();
                 }
             }
 
@@ -188,17 +188,22 @@ public class Upload extends AbstractComponent implements Component.Focusable {
 
         } catch (final Exception e) {
             synchronized (application) {
-                // Download interrupted
-                try {
-                    // still try to close output stream
-                    out.close();
-                } catch (IOException ignored) {
+                if (e instanceof UploadInterruptedException) {
+                    // Download interrupted
+                    try {
+                        // still try to close output stream
+                        out.close();
+                    } catch (IOException e1) {
+                        // NOP
+                    }
                 }
                 fireUploadInterrupted(filename, type, totalBytes, e);
                 endUpload();
                 interrupted = false;
-                // throw cause ahead
-                throw new IllegalStateException("Uploading failed", e);
+                if (!(e instanceof UploadInterruptedException)) {
+                    // throw exception for terminal to be handled
+                    throw new UploadException(e);
+                }
             }
         }
     }
@@ -296,6 +301,19 @@ public class Upload extends AbstractComponent implements Component.Focusable {
         }
     }
 
+    private class UploadInterruptedException extends Exception {
+        public UploadInterruptedException() {
+            super("Upload interrupted by other thread");
+        }
+
+    }
+
+    public class UploadException extends Exception {
+        public UploadException(Exception e) {
+            super("Upload failed", e);
+        }
+    }
+
     /**
      * Upload.Received event is sent when the upload receives a file, regardless
      * of whether the reception was successful or failed. If you wish to
index 828f98fc33e05aa6bc771111e9996f80a12dd445..dc1bf7e18fe094fcb3b84b47c32c01abe6ceca8a 100644 (file)
@@ -601,6 +601,14 @@ public class Window extends Panel implements URIHandler, ParameterHandler {
      * <code>null</code> window name results the resource to be opened in this
      * window.
      * 
+     * <p>
+     * Note! When opening browser window with name "_self", client will skip
+     * rendering rest of the changes as it considers them irrelevant. This may
+     * speed up opening resource, but it may also put client side into an
+     * inconsistent state with server in case nothing is actually opened to
+     * window (like if browser decided to download the resource instead of
+     * displaying it).
+     * 
      * @param resource
      *            the resource.
      * @param windowName