background-color: #fffcdd;
border: 1px solid #b8b295;
font-size: 11px;
- line-height: 13px;
color: #222;
}
.v-tooltip-text {
background-color: #fffcdd;
border: 1px solid #b8b295;
font-size: 11px;
- line-height: 13px;
color: #222;
}
.v-tooltip-text {
border-top-color: #d5d2c1;
border-left-color: #d5d2c1;
font-size: 11px;
- line-height: 13px;
font-family: arial, helvetica, tahoma, verdana, sans-serif;
color: #5d5444;
}
border-top-color: #d5d2c1;
border-left-color: #d5d2c1;
font-size: 11px;
- line-height: 13px;
font-family: arial, helvetica, tahoma, verdana, sans-serif;
color: #5d5444;
}
\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
\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
// 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
}\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
\r
renderInformation.setContentAreaHeight(renderInformation\r
.getRenderedSize().getHeight()\r
- - borderPaddingVertical);\r
+ - getSpaceConsumedVertically());\r
if (BrowserInfo.get().isIE6()) {\r
getElement().getStyle().setProperty("overflow", "hidden");\r
}\r
\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
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
.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) {
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 {
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;
}
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
// 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) {
if (xml == null || xml.length() <= 0) {
return "";
}
- return escapeXML(new StringBuffer(xml)).toString();
+ return escapeXML(new StringBuilder(xml)).toString();
}
/**
*
* @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);
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) {
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) {
Vector attr = new Vector();
- StringBuffer data = new StringBuffer();
+ StringBuilder data = new StringBuilder();
public boolean childrenArrayOpen = false;
}
public String getData() {
- final StringBuffer buf = new StringBuffer();
+ final StringBuilder buf = new StringBuilder();
final Iterator it = children.iterator();
while (it.hasNext()) {
buf.append(startField());
}
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();) {
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();
@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();
}
}
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;
}
};
- private static Map<URL, String> classpathLocations = getClasspathLocations();
+ private static List<String> rawClasspathEntries = getRawClasspathEntries();
+ private static Map<URL, String> classpathLocations = getClasspathLocations(rawClasspathEntries);
private 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");
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)
}
}
+ /**
+ * 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
*/
.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
}
}
- changed = changed ? true : content.equals(originalContent);
+ changed = changed || !content.equals(originalContent);
if (changed) {
commitChanges(widgetsetfilename, content);
}
*
* @param upload
*/
- public void receiveUpload(UploadStream upload) {
+ public void receiveUpload(UploadStream upload) throws UploadException {
if (!isUploading) {
throw new IllegalStateException("uploading not started");
}
}
}
if (interrupted) {
- throw new Exception("Upload interrupted by other thread");
+ throw new UploadInterruptedException();
}
}
} 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);
+ }
}
}
}
}
}
+ 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
* <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