From a9a7a79e0f4611be13a2e5eb0a152601831c8b7c Mon Sep 17 00:00:00 2001 From: Henri Sara Date: Mon, 1 Feb 2010 08:52:51 +0000 Subject: Merged code changes from 6.2 svn changeset:11069/svn branch:6.3 --- .../vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml | 6 +++ .../vaadin/terminal/gwt/client/ui/VGridLayout.java | 55 +++++++++++++--------- .../terminal/gwt/client/ui/VPopupCalendar.java | 7 ++- .../gwt/widgetsetutils/ClassPathExplorer.java | 16 +++++-- src/com/vaadin/ui/Select.java | 6 +++ 5 files changed, 63 insertions(+), 27 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml index d7cf1ca4d0..8918b4b5e7 100644 --- a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml +++ b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml @@ -27,6 +27,12 @@ + + + + + + diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java index 1c2fcf5b6f..416455c162 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java @@ -191,6 +191,7 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { renderRemainingComponents(pendingCells); for (Cell cell : relativeHeighted) { + // rendering done above so cell.cc should not be null Widget widget2 = cell.cc.getWidget(); client.handleComponentRelativeSize(widget2); cell.cc.updateWidgetSize(); @@ -685,19 +686,20 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { Cell cell = paintableToCell.get(paintable); if (!cell.hasRelativeHeight() || !cell.hasRelativeWidth()) { // cell sizes will only stay still if only relatively - // sized - // components + // sized components // check if changed child affects min col widths - cell.cc.setWidth(""); - cell.cc.setHeight(""); + if (cell.cc != null) { + cell.cc.setWidth(""); + cell.cc.setHeight(""); - cell.cc.updateWidgetSize(); + cell.cc.updateWidgetSize(); - /* - * If this is the result of an caption icon onload event the - * caption size may have changed - */ - cell.cc.updateCaptionSize(); + /* + * If this is the result of an caption icon onload event the + * caption size may have changed + */ + cell.cc.updateCaptionSize(); + } int width = cell.getWidth(); int allocated = columnWidths[cell.col]; @@ -853,9 +855,16 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { } public RenderSpace getAllocatedSpace() { - return new RenderSpace(getAvailableWidth() - - cc.getCaptionWidthAfterComponent(), getAvailableHeight() - - cc.getCaptionHeightAboveComponent()); + if (cc != null) { + return new RenderSpace(getAvailableWidth() + - cc.getCaptionWidthAfterComponent(), + getAvailableHeight() + - cc.getCaptionHeightAboveComponent()); + } else { + // this should not happen normally + return new RenderSpace(getAvailableWidth(), + getAvailableHeight()); + } } public boolean hasContent() { @@ -965,6 +974,8 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { int rowspan = 1; UIDL childUidl; int alignment; + // may be null after setUidl() if content has vanished or changed, set + // in render() ChildComponentContainer cc; public void setUidl(UIDL c) { @@ -986,21 +997,21 @@ public class VGridLayout extends SimplePanel implements Paintable, Container { if (childUidl != null) { if (c == null) { // content has vanished, old content will be removed from - // canvas - // later durin render phase + // canvas later during the render phase cc = null; } else if (cc != null && cc.getWidget() != client.getPaintable(c)) { // content has changed - cc = null; - if (widgetToComponentContainer.containsKey(client - .getPaintable(c))) { - // cc exist for this component (moved) use that for this - // cell - cc = widgetToComponentContainer.get(client - .getPaintable(c)); + Paintable newPaintable = client.getPaintable(c); + if (widgetToComponentContainer.containsKey(newPaintable)) { + // if a key in the map, newPaintable must be a widget + replaceChildComponent(cc.getWidget(), + (Widget) newPaintable); + cc = widgetToComponentContainer.get(newPaintable); cc.setWidth(""); cc.setHeight(""); + } else { + cc = null; } } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java index 8d83e8b2b5..9b504bc5f3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPopupCalendar.java @@ -52,7 +52,6 @@ public class VPopupCalendar extends VTextualDate implements Paintable, Field, public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { boolean lastReadOnlyState = readonly; super.updateFromUIDL(uidl, client); - addStyleName(CLASSNAME + "-popupcalendar"); popup.setStyleName(VDateField.CLASSNAME + "-popup " + VDateField.CLASSNAME + "-" + resolutionToString(currentResolution)); @@ -67,6 +66,12 @@ public class VPopupCalendar extends VTextualDate implements Paintable, Field, } + @Override + public void setStyleName(String style) { + // make sure the style is there before size calculation + super.setStyleName(style + " " + CLASSNAME + "-popupcalendar"); + } + public void onClick(ClickEvent event) { if (event.getSource() == calendarToggle && !open && !readonly) { open = true; diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java b/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java index 912cfa37a3..c18fc73b08 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/ClassPathExplorer.java @@ -19,7 +19,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.TreeSet; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -164,7 +163,9 @@ public class ClassPathExplorer { for (int i = 0; i < widgetsetNames.length; i++) { String widgetsetname = widgetsetNames[i].trim() .intern(); - widgetsets.put(widgetsetname, location); + if (!widgetsetname.equals("")) { + widgetsets.put(widgetsetname, location); + } } } } @@ -423,8 +424,15 @@ public class ClassPathExplorer { * @return URL */ public static URL getDefaultSourceDirectory() { - logger.fine("classpathLocations keys: " - + new TreeSet(classpathLocations.keySet())); + if (logger.isLoggable(Level.FINE)) { + logger.fine("classpathLocations keys:"); + ArrayList locations = new ArrayList(classpathLocations + .keySet()); + for (URL location : locations) { + logger.fine(location.toString()); + } + } + Iterator it = rawClasspathEntries.iterator(); while (it.hasNext()) { String entry = it.next(); diff --git a/src/com/vaadin/ui/Select.java b/src/com/vaadin/ui/Select.java index e8e0dfebaa..4174001d87 100644 --- a/src/com/vaadin/ui/Select.java +++ b/src/com/vaadin/ui/Select.java @@ -234,6 +234,12 @@ public class Select extends AbstractSelect implements AbstractSelect.Filtering, currentPage = -1; // current page is always set by client optionRequest = true; + + // Hide the error indicator if needed + if (isRequired() && isEmpty() && getComponentError() == null + && getErrorMessage() != null) { + target.addAttribute("hideErrors", true); + } } /** -- cgit v1.2.3 From 48dbc19590b75cbabe0332a5e153e9a8fbbe0673 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Thu, 4 Feb 2010 15:27:12 +0000 Subject: #4130: Javadoc typos in ApplicationConnection svn changeset:11145/svn branch:6.3 --- .../terminal/gwt/client/ApplicationConnection.java | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 1c3128dbdf..e35176a5fa 100755 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -1109,7 +1109,7 @@ public class ApplicationConnection { * @param newValue * the new value to be sent * @param immediate - * true if the update is to be sent as suun as possible + * true if the update is to be sent as soon as possible */ public void updateVariable(String paintableId, String variableName, Paintable newValue, boolean immediate) { @@ -1132,7 +1132,7 @@ public class ApplicationConnection { * @param newValue * the new value to be sent * @param immediate - * true if the update is to be sent as suun as possible + * true if the update is to be sent as soon as possible */ public void updateVariable(String paintableId, String variableName, @@ -1155,7 +1155,7 @@ public class ApplicationConnection { * @param newValue * the new value to be sent * @param immediate - * true if the update is to be sent as suun as possible + * true if the update is to be sent as soon as possible */ public void updateVariable(String paintableId, String variableName, @@ -1179,7 +1179,7 @@ public class ApplicationConnection { * @param newValue * the new value to be sent * @param immediate - * true if the update is to be sent as suun as possible + * true if the update is to be sent as soon as possible */ public void updateVariable(String paintableId, String variableName, @@ -1203,7 +1203,7 @@ public class ApplicationConnection { * @param newValue * the new value to be sent * @param immediate - * true if the update is to be sent as suun as possible + * true if the update is to be sent as soon as possible */ public void updateVariable(String paintableId, String variableName, @@ -1227,7 +1227,7 @@ public class ApplicationConnection { * @param newValue * the new value to be sent * @param immediate - * true if the update is to be sent as suun as possible + * true if the update is to be sent as soon as possible */ public void updateVariable(String paintableId, String variableName, @@ -1251,7 +1251,7 @@ public class ApplicationConnection { * @param newValue * the new value to be sent * @param immediate - * true if the update is to be sent as suun as possible + * true if the update is to be sent as soon as possible */ public void updateVariable(String paintableId, String variableName, @@ -1275,7 +1275,7 @@ public class ApplicationConnection { * @param newValue * the new value to be sent * @param immediate - * true if the update is to be sent as suun as possible + * true if the update is to be sent as soon as possible */ public void updateVariable(String paintableId, String variableName, Map map, boolean immediate) { @@ -1338,7 +1338,7 @@ public class ApplicationConnection { * @param newValue * the new value to be sent * @param immediate - * true if the update is to be sent as suun as possible + * true if the update is to be sent as soon as possible */ public void updateVariable(String paintableId, String variableName, String[] values, boolean immediate) { @@ -1373,7 +1373,7 @@ public class ApplicationConnection { * @param newValue * the new value to be sent * @param immediate - * true if the update is to be sent as suun as possible + * true if the update is to be sent as soon as possible */ public void updateVariable(String paintableId, String variableName, Object[] values, boolean immediate) { -- cgit v1.2.3 From 05c3c650e2b78dc17256b5237c8a9f14eb13a554 Mon Sep 17 00:00:00 2001 From: John Alhroos Date: Wed, 10 Feb 2010 11:07:01 +0000 Subject: Merged changes from 6.2 branch. svn changeset:11245/svn branch:6.3 --- .../VAADIN/themes/base/datefield/datefield.css | 3 ++ WebContent/VAADIN/themes/base/styles.css | 3 ++ .../vaadin/terminal/gwt/client/ui/VEmbedded.java | 11 +++++-- .../terminal/gwt/client/ui/VNativeButton.java | 36 ++++++++++++++-------- 4 files changed, 38 insertions(+), 15 deletions(-) (limited to 'src/com') diff --git a/WebContent/VAADIN/themes/base/datefield/datefield.css b/WebContent/VAADIN/themes/base/datefield/datefield.css index 720a80716f..fd2730bf24 100644 --- a/WebContent/VAADIN/themes/base/datefield/datefield.css +++ b/WebContent/VAADIN/themes/base/datefield/datefield.css @@ -51,6 +51,9 @@ .v-datefield-time .v-label { display: inline; } +.v-datefield-popup { + background: #fff; +} /* Disabled by default .v-datefield-error .v-textfield, .v-datefield-error .v-datefield-calendarpanel { diff --git a/WebContent/VAADIN/themes/base/styles.css b/WebContent/VAADIN/themes/base/styles.css index 28d412536e..af82ec079d 100644 --- a/WebContent/VAADIN/themes/base/styles.css +++ b/WebContent/VAADIN/themes/base/styles.css @@ -528,6 +528,9 @@ div.v-app-loading { .v-datefield-time .v-label { display: inline; } +.v-datefield-popup { + background: #fff; +} /* Disabled by default .v-datefield-error .v-textfield, .v-datefield-error .v-datefield-calendarpanel { diff --git a/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java b/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java index 7d69e5682a..ffd09dab2c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java @@ -140,6 +140,7 @@ public class VEmbedded extends HTML implements Paintable { parameters.put("movie", getSrc(uidl, client)); } + // Add the parameters to the Object for (String name : parameters.keySet()) { html += ""; + + width + "\" height=\"" + height + "\" "; - html += ""; + // Add the parameters to the Embed + for (String name : parameters.keySet()) { + html += escapeAttribute(name) + "=\"" + + escapeAttribute(parameters.get(name)) + "\" "; + } + + html += ">"; setHTML(html); } else if (mime.equals("image/svg+xml")) { String data; diff --git a/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java b/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java index e544e1f9ce..ef7e183698 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VNativeButton.java @@ -19,7 +19,7 @@ import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VTooltip; -public class VNativeButton extends Button implements Paintable { +public class VNativeButton extends Button implements Paintable, ClickHandler { public static final String CLASSNAME = "v-nativebutton"; @@ -48,18 +48,8 @@ public class VNativeButton extends Button implements Paintable { getElement().appendChild(captionElement); captionElement.setClassName(getStyleName() + "-caption"); - addClickHandler(new ClickHandler() { - public void onClick(ClickEvent event) { - if (id == null || client == null) { - return; - } - if (BrowserInfo.get().isSafari()) { - VNativeButton.this.setFocus(true); - } - client.updateVariable(id, "state", true, true); - clickPending = false; - } - }); + addClickHandler(this); + sinkEvents(VTooltip.TOOLTIP_EVENTS); sinkEvents(Event.ONMOUSEDOWN); sinkEvents(Event.ONMOUSEUP); @@ -179,4 +169,24 @@ public class VNativeButton extends Button implements Paintable { } } + /* + * (non-Javadoc) + * + * @see + * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event + * .dom.client.ClickEvent) + */ + public void onClick(ClickEvent event) { + if (id == null || client == null) { + return; + } + + if (BrowserInfo.get().isSafari()) { + VNativeButton.this.setFocus(true); + } + + client.updateVariable(id, "state", true, true); + clickPending = false; + } + } -- cgit v1.2.3 From ec4b0f0c8b7de237b11245ae595df4052e3f21cd Mon Sep 17 00:00:00 2001 From: John Alhroos Date: Wed, 10 Feb 2010 13:37:41 +0000 Subject: Merged fix for #4109 to 6.3 branch. svn changeset:11252/svn branch:6.3 --- src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java | 16 +++++++++++++++- src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java | 12 +++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java index 0a28fd6b41..75ecbd3249 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java @@ -8,11 +8,14 @@ import java.util.Stack; import com.google.gwt.dom.client.NodeList; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; +import com.google.gwt.event.logical.shared.ValueChangeEvent; +import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.History; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.HasHTML; import com.google.gwt.user.client.ui.PopupPanel; @@ -27,7 +30,8 @@ import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; public class VMenuBar extends Widget implements Paintable, - CloseHandler, ContainerResizedListener { +CloseHandler, ContainerResizedListener, +ValueChangeHandler { /** Set the CSS class name to allow styling. */ public static final String CLASSNAME = "v-menubar"; @@ -76,6 +80,8 @@ public class VMenuBar extends Widget implements Paintable, if (!subMenu) { setStylePrimaryName(CLASSNAME); + // Monitor back&forward buttons + History.addValueChangeHandler(this); } else { setStylePrimaryName(CLASSNAME + "-submenu"); } @@ -866,4 +872,12 @@ public class VMenuBar extends Widget implements Paintable, return w; } + public void onValueChange(ValueChangeEvent arg0) { + // Close menu if user uses back & forward buttons #4109 + if (!subMenu) { + setSelected(null); + hideChildren(); + menuVisible = false; + } + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index 8520e52eec..04a73939a7 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -19,11 +19,14 @@ import com.google.gwt.dom.client.TableRowElement; import com.google.gwt.dom.client.TableSectionElement; import com.google.gwt.event.dom.client.ScrollEvent; import com.google.gwt.event.dom.client.ScrollHandler; +import com.google.gwt.event.logical.shared.ValueChangeEvent; +import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.History; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.FlowPanel; @@ -64,7 +67,8 @@ import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTa * * TODO implement unregistering for child components in Cells */ -public class VScrollTable extends FlowPanel implements Table, ScrollHandler { +public class VScrollTable extends FlowPanel implements Table, ScrollHandler, + ValueChangeHandler { public static final String CLASSNAME = "v-table"; public static final String ITEM_CLICK_EVENT_ID = "itemClick"; @@ -159,6 +163,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { rowRequestHandler = new RowRequestHandler(); + // Handle back & forward browser buttons + History.addValueChangeHandler(this); } @SuppressWarnings("unchecked") @@ -3064,4 +3070,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler { } } + public void onValueChange(ValueChangeEvent arg0) { + client.getContextMenu().hide(); + } + } -- cgit v1.2.3 From 87102e2ed9d2daf6ed4e2141cc1c3bef6262ad43 Mon Sep 17 00:00:00 2001 From: Marc Englund Date: Wed, 10 Feb 2010 20:35:26 +0000 Subject: Merged [11258] from 6.2 for #3974 svn changeset:11259/svn branch:6.3 --- src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java | 3 ++- src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java index 39f4e845f7..060c4dedf1 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java @@ -148,6 +148,7 @@ public class ApplicationConfiguration { int lastdot = module.lastIndexOf("."); String base = module.substring(0, lastdot); String simpleName = module.substring(lastdot + 1); + // TODO figure out (ask around) WTF this is almost-removed // if (!wsname.startsWith(base) || !wsname.endsWith(simpleName)) { // // WidgetSet module name does not match implementation name; // // probably inherited WidgetSet with entry-point. Skip. @@ -161,7 +162,7 @@ public class ApplicationConfiguration { String msg = "Tried to init " + widgetset.getClass().getName() + ", but " + initedWidgetSet.getClass().getName() + " was already inited."; - ApplicationConnection.getConsole().log(msg); + throw new IllegalStateException(msg); } initedWidgetSet = widgetset; ArrayList appIds = new ArrayList(); diff --git a/src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java b/src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java index 919c267eb0..feefdc7421 100644 --- a/src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java +++ b/src/com/vaadin/terminal/gwt/client/DefaultWidgetSet.java @@ -37,7 +37,14 @@ public class DefaultWidgetSet implements WidgetSet { * This is the entry point method. It will start the first */ public void onModuleLoad() { - ApplicationConfiguration.initConfigurations(this); + try { + ApplicationConfiguration.initConfigurations(this); + } catch (Exception e) { + // Log & don't continue; + // custom WidgetSets w/ entry points will cause this + ApplicationConnection.getConsole().log(e.getMessage()); + return; + } ApplicationConfiguration.startNextApplication(); // start first app map = GWT.create(WidgetMap.class); } -- cgit v1.2.3 From f1bd9c8f2a9f063dfc36d0cbb488df16dae00f37 Mon Sep 17 00:00:00 2001 From: Marc Englund Date: Thu, 11 Feb 2010 10:24:59 +0000 Subject: Merged from 6.2: Better warning & removed old commented code for #3974 (multiple entrypoints detection) svn changeset:11270/svn branch:6.3 --- .../terminal/gwt/client/ApplicationConfiguration.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java index 060c4dedf1..5bcf613f6d 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java @@ -148,20 +148,14 @@ public class ApplicationConfiguration { int lastdot = module.lastIndexOf("."); String base = module.substring(0, lastdot); String simpleName = module.substring(lastdot + 1); - // TODO figure out (ask around) WTF this is almost-removed - // if (!wsname.startsWith(base) || !wsname.endsWith(simpleName)) { - // // WidgetSet module name does not match implementation name; - // // probably inherited WidgetSet with entry-point. Skip. - // GWT.log("Ignored init for " + wsname + " when starting " + module, - // null); - // return; - // } if (initedWidgetSet != null) { - // Something went wrong: multiple widgetsets inited - String msg = "Tried to init " + widgetset.getClass().getName() - + ", but " + initedWidgetSet.getClass().getName() - + " was already inited."; + // Multiple widgetsets inited; can happen with custom WS + entry + // point + String msg = "Ignoring " + widgetset.getClass().getName() + + ", because " + initedWidgetSet.getClass().getName() + + " was already inited (if this is wrong, your entry point" + + " is probably not first your .gwt.xml)."; throw new IllegalStateException(msg); } initedWidgetSet = widgetset; -- cgit v1.2.3 From dea99fd63f72d205292cdbcda7f70cc2b49be6fd Mon Sep 17 00:00:00 2001 From: Marc Englund Date: Fri, 12 Feb 2010 12:28:53 +0000 Subject: Merged portlet mode and windowing changes from 6.2. For #4143 svn changeset:11297/svn branch:6.3 --- WebContent/WEB-INF/portlet.xml | 167 +++++++++------------ .../gwt/server/AbstractApplicationPortlet.java | 85 +++-------- .../gwt/server/PortletCommunicationManager.java | 27 ---- 3 files changed, 92 insertions(+), 187 deletions(-) (limited to 'src/com') diff --git a/WebContent/WEB-INF/portlet.xml b/WebContent/WEB-INF/portlet.xml index b1a6d4722d..bab08d4eb1 100644 --- a/WebContent/WEB-INF/portlet.xml +++ b/WebContent/WEB-INF/portlet.xml @@ -2,7 +2,7 @@ - + PortletDemoPortlet Vaadin PortletDemo @@ -120,7 +120,7 @@ user - + HelloWorldPortlet Hello World @@ -136,92 +136,75 @@ HelloWorld HelloWorld - + - + + Portlet Mode Example + Portlet Mode Example + com.vaadin.demo.portlet.PortletModePortlet + + widgetset + com.vaadin.portal.gwt.PortalDefaultWidgetSet + + + application + com.vaadin.demo.portlet.PortletModeExample + + text/html view + edit + help + config - Inter-portlet events (non-Vaadin) - Inter-portlet events (non-Vaadin) + PortletModeExample + PortletModeExample - - vaadin:Reply - - - vaadin:FromVaadin - - - vaadin:Hello - - - vaadin:ReplyToVaadin - - HelloState - --> - - Portlet Mode Example - Portlet Mode Example - com.vaadin.demo.portlet.PortletModePortlet - - widgetset - com.vaadin.portal.gwt.PortalDefaultWidgetSet - - - text/html - view - edit - help - config - - - PortletModeExample - PortletModeExample - - AddressBookPortlet @@ -238,9 +221,9 @@ Address Book Address Book - - - + + + SamplerPortlet Sampler @@ -260,9 +243,9 @@ Sampler Sampler - + - + CalcPortlet Calc @@ -274,7 +257,7 @@ widgetset com.vaadin.demo.sampler.gwt.SamplerWidgetSet - + text/html view @@ -282,8 +265,8 @@ Calc Calc - - + + ChatServletPortlet Vaadin ChatServlet @@ -361,23 +344,23 @@ user - + - - Custom mode - config - false - + + Custom mode + config + false + vaadin:Hello java.lang.String - - + + vaadin:Reply java.lang.String @@ -387,7 +370,7 @@ HelloState vaadin:HelloState - + - - - - - -- cgit v1.2.3 From 7fc1c4c0d18680ba34e8f0cb779d91e12742ee3a Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 1 Mar 2010 15:21:36 +0000 Subject: #4170 - IndexedContainer.addItemAfter(null, Object) does not work svn changeset:11565/svn branch:6.3 --- src/com/vaadin/data/util/IndexedContainer.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/com') diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java index f5dddf5e23..3d4a98fb97 100644 --- a/src/com/vaadin/data/util/IndexedContainer.java +++ b/src/com/vaadin/data/util/IndexedContainer.java @@ -548,6 +548,11 @@ public class IndexedContainer implements Container.Indexed, * java.lang.Object) */ public Item addItemAfter(Object previousItemId, Object newItemId) { + // Adding an item after null item adds the item as first item of the + // ordered container. + if (previousItemId == null) { + return addItemAt(0, newItemId); + } // Get the index of the addition int index = -1; -- cgit v1.2.3 From b9d426e2d06f8dbc78b74e1e76a1ee03b2a218a7 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 1 Mar 2010 15:42:21 +0000 Subject: #4249 - IndexedContainer.addItemAfter(Object) should return item id, not item svn changeset:11566/svn branch:6.3 --- src/com/vaadin/data/util/IndexedContainer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/com') diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java index 3d4a98fb97..048d868ee0 100644 --- a/src/com/vaadin/data/util/IndexedContainer.java +++ b/src/com/vaadin/data/util/IndexedContainer.java @@ -576,7 +576,11 @@ public class IndexedContainer implements Container.Indexed, // Creates a new id final Object id = generateId(); - return addItemAfter(previousItemId, id); + if (addItemAfter(previousItemId, id) != null) { + return id; + } else { + return null; + } } /* -- cgit v1.2.3 From 6b3d7c1d61c43bf03c2cc99053eb393457e71df4 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 1 Mar 2010 15:44:39 +0000 Subject: #4250 - IndexedContainer.nextItemId should return null for item ids not in container svn changeset:11567/svn branch:6.3 --- src/com/vaadin/data/util/IndexedContainer.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/com') diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java index 048d868ee0..1d2726cdeb 100644 --- a/src/com/vaadin/data/util/IndexedContainer.java +++ b/src/com/vaadin/data/util/IndexedContainer.java @@ -469,7 +469,13 @@ public class IndexedContainer implements Container.Indexed, return null; } try { - return itemIds.get(itemIds.indexOf(itemId) + 1); + int idx = itemIds.indexOf(itemId); + if (idx == -1) { + // If the given Item is not found in the Container, + // null is returned. + return null; + } + return itemIds.get(idx + 1); } catch (final IndexOutOfBoundsException e) { return null; } -- cgit v1.2.3 From 5b2c7f48d8f12cc3d1e4d1e854211210ed9b7304 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 1 Mar 2010 16:30:48 +0000 Subject: #4128 - Allow custom servlets to send critical notifications to client svn changeset:11569/svn branch:6.3 --- .../gwt/server/AbstractApplicationServlet.java | 30 ++++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index f2725055a4..39a9248409 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -535,35 +535,37 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements } /** - * Send notification to client's application. Used to notify client of - * critical errors and session expiration due to long inactivity. Server has - * no knowledge of what application client refers to. + * Send a notification to client's application. Used to notify client of + * critical errors, session expiration and more. Server has no knowledge of + * what application client refers to. * * @param request * the HTTP request instance. * @param response * the HTTP response to write to. * @param caption - * for the notification + * the notification caption * @param message - * for the notification + * to notification body * @param details - * a detail message to show in addition to the passed message. - * Currently shown directly but could be hidden behind a details - * drop down. + * a detail message to show in addition to the message. Currently + * shown directly below the message but could be hidden behind a + * details drop down in the future. Mainly used to give + * additional information not necessarily useful to the end user. * @param url - * url to load after message, null for current page + * url to load when the message is dismissed. Null will reload + * the current page. * @throws IOException * if the writing failed due to input/output error. */ - void criticalNotification(HttpServletRequest request, + protected final void criticalNotification(HttpServletRequest request, HttpServletResponse response, String caption, String message, String details, String url) throws IOException { - // clients JS app is still running, but server application either - // no longer exists or it might fail to perform reasonably. - // send a notification to client's application and link how - // to "restart" application. + if (!isUIDLRequest(request)) { + throw new RuntimeException( + "criticalNotification can only be used in UIDL requests"); + } if (caption != null) { caption = "\"" + caption + "\""; -- cgit v1.2.3 From 4ac442c4ff3763b087812e3d290388b28d886300 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 1 Mar 2010 17:04:19 +0000 Subject: #4129 - Show a message if cookie support is disabled in the browser svn changeset:11570/svn branch:6.3 --- src/com/vaadin/Application.java | 106 +++++++++++++++++++++ .../gwt/server/AbstractApplicationServlet.java | 36 +++++++ 2 files changed, 142 insertions(+) (limited to 'src/com') diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java index 67bc5e9da6..0d6c5721d9 100644 --- a/src/com/vaadin/Application.java +++ b/src/com/vaadin/Application.java @@ -1303,6 +1303,13 @@ public abstract class Application implements URIHandler, *
  • outOfSyncMessage = "Something has caused us to be out of sync * with the server.
    * Take note of any unsaved data, and click here to re-sync."
  • + *
  • cookiesDisabledURL = null
  • + *
  • outOfSyncNotificationEnabled = true
  • + *
  • outOfSyncCaption = "Cookies disabled"
  • + *
  • outOfSyncMessage = "This application requires cookies to + * function.
    + * Please enable cookies in your browser and click here to try again. + *
  • * *

    * @@ -1328,6 +1335,11 @@ public abstract class Application implements URIHandler, protected String outOfSyncCaption = "Out of sync"; protected String outOfSyncMessage = "Something has caused us to be out of sync with the server.
    Take note of any unsaved data, and click here to re-sync."; + protected String cookiesDisabledURL = null; + protected boolean cookiesDisabledNotificationEnabled = true; + protected String cookiesDisabledCaption = "Cookies disabled"; + protected String cookiesDisabledMessage = "This application requires cookies to function.
    Please enable cookies in your browser and click here to try again."; + /** * Use {@link CustomizedSystemMessages} to customize */ @@ -1462,6 +1474,52 @@ public abstract class Application implements URIHandler, return (outOfSyncNotificationEnabled ? outOfSyncMessage : null); } + /** + * Returns the URL the user should be redirected to after dismissing the + * "you have to enable your cookies" message. Typically null. + * + * @return A URL the user should be redirected to after dismissing the + * message or null to reload the current URL. + */ + public String getCookiesDisabledURL() { + return cookiesDisabledURL; + } + + /** + * Determines if "cookies disabled" messages should be shown to the end + * user or not. If the notification is disabled the user will be + * immediately redirected to the URL returned by + * {@link #getCookiesDisabledURL()}. + * + * @return true to show "cookies disabled" messages to the end user, + * false to redirect to the given URL directly + */ + public boolean isCookiesDisabledNotificationEnabled() { + return cookiesDisabledNotificationEnabled; + } + + /** + * Returns the caption of the message shown to the user when cookies are + * disabled in the browser. + * + * @return The caption of the "cookies disabled" message + */ + public String getCookiesDisabledCaption() { + return (cookiesDisabledNotificationEnabled ? cookiesDisabledCaption + : null); + } + + /** + * Returns the message shown to the user when cookies are disabled in + * the browser. + * + * @return The "cookies disabled" message + */ + public String getCookiesDisabledMessage() { + return (cookiesDisabledNotificationEnabled ? cookiesDisabledMessage + : null); + } + } /** @@ -1688,6 +1746,54 @@ public abstract class Application implements URIHandler, this.outOfSyncMessage = outOfSyncMessage; } + /** + * Sets the URL to redirect to when the browser has cookies disabled. + * + * @param cookiesDisabledURL + * the URL to redirect to, or null to reload the current URL + */ + public void setCookiesDisabledURL(String cookiesDisabledURL) { + this.cookiesDisabledURL = cookiesDisabledURL; + } + + /** + * Enables or disables the notification for "cookies disabled" messages. + * If disabled, the URL returned by {@link #getCookiesDisabledURL()} is + * loaded directly. + * + * @param cookiesDisabledNotificationEnabled + * true to enable "cookies disabled" messages, false + * otherwise + */ + public void setCookiesDisabledNotificationEnabled( + boolean cookiesDisabledNotificationEnabled) { + this.cookiesDisabledNotificationEnabled = cookiesDisabledNotificationEnabled; + } + + /** + * Sets the caption of the "cookies disabled" notification. Set to null + * for no caption. If both caption and message is null, the notification + * is disabled. + * + * @param cookiesDisabledCaption + * the caption for the "cookies disabled" notification + */ + public void setCookiesDisableCaption(String cookiesDisabledCaption) { + this.cookiesDisabledCaption = cookiesDisabledCaption; + } + + /** + * Sets the message of the "cookies disabled" notification. Set to null + * for no message. If both caption and message is null, the notification + * is disabled. + * + * @param cookiesDisabledMessage + * the message for the "cookies disabled" notification + */ + public void setCookiesDisableMessage(String cookiesDisabledMessage) { + this.cookiesDisabledMessage = cookiesDisabledMessage; + } + } /** diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index 39a9248409..0fd4e46f8c 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -362,6 +362,9 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements HttpServletResponse response) throws ServletException, IOException { RequestType requestType = getRequestType(request); + if (!ensureCookiesEnabled(requestType, request, response)) { + return; + } if (requestType == RequestType.STATIC_FILE) { serveStaticResources(request, response); @@ -502,6 +505,39 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements } } + /** + * Check that cookie support is enabled in the browser. Only checks UIDL + * requests. + * + * @param requestType + * Type of the request as returned by + * {@link #getRequestType(HttpServletRequest)} + * @param request + * The request from the browser + * @param response + * The response to which an error can be written + * @return false if cookies are disabled, true otherwise + * @throws IOException + */ + private boolean ensureCookiesEnabled(RequestType requestType, + HttpServletRequest request, HttpServletResponse response) + throws IOException { + if (requestType == RequestType.UIDL && !isRepaintAll(request)) { + // In all other but the first UIDL request a cookie should be + // returned by the browser. + // This can be removed if cookieless mode (#3228) is supported + if (request.getRequestedSessionId() == null) { + // User has cookies disabled + criticalNotification(request, response, getSystemMessages() + .getCookiesDisabledCaption(), getSystemMessages() + .getCookiesDisabledMessage(), null, getSystemMessages() + .getCookiesDisabledURL()); + return false; + } + } + return true; + } + private void updateBrowserProperties(WebBrowser browser, HttpServletRequest request) { browser.updateBrowserProperties(request.getLocale(), request -- cgit v1.2.3 From f0c6a51e3b2ecf62226621ab630069f28862b352 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 1 Mar 2010 17:31:16 +0000 Subject: #3734 - Widgetset fails to load when customized system messages contain special characters svn changeset:11572/svn branch:6.3 --- src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index 0fd4e46f8c..77e83838c5 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -604,7 +604,7 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements } if (caption != null) { - caption = "\"" + caption + "\""; + caption = "\"" + JsonPaintTarget.escapeJSON(caption) + "\""; } if (details != null) { if (message == null) { @@ -613,11 +613,12 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements message += "

    " + details; } } + if (message != null) { - message = "\"" + message + "\""; + message = "\"" + JsonPaintTarget.escapeJSON(message) + "\""; } if (url != null) { - url = "\"" + url + "\""; + url = "\"" + JsonPaintTarget.escapeJSON(url) + "\""; } // Set the response type -- cgit v1.2.3 From 27aa8c33e28deb9516eac2f702904fbd1dae9e6f Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 2 Mar 2010 07:15:00 +0000 Subject: #4192 - HierarchicalContainer implements Container.Filterable but does not allow filtering svn changeset:11576/svn branch:6.3 --- .../vaadin/data/util/HierarchicalContainer.java | 204 ++++++++++++++++++--- src/com/vaadin/data/util/IndexedContainer.java | 8 +- .../server/container/AbstractContainerTest.java | 57 ++++-- .../AbstractHierarchicalContainerTest.java | 144 ++++++++++----- .../container/TestHierarchicalContainer.java | 4 + 5 files changed, 333 insertions(+), 84 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/data/util/HierarchicalContainer.java b/src/com/vaadin/data/util/HierarchicalContainer.java index 988676be8c..a264eafc71 100644 --- a/src/com/vaadin/data/util/HierarchicalContainer.java +++ b/src/com/vaadin/data/util/HierarchicalContainer.java @@ -41,11 +41,21 @@ public class HierarchicalContainer extends IndexedContainer implements */ private final HashMap> children = new HashMap>(); + /** + * Mapping from Item ID to a list of child IDs when filtered + */ + private HashMap> filteredChildren = null; + /** * List that contains all root elements of the container. */ private final LinkedList roots = new LinkedList(); + /** + * List that contains all filtered root elements of the container. + */ + private LinkedList filteredRoots = null; + /* * Can the specified Item have any children? Don't add a JavaDoc comment * here, we use the default documentation from implemented interface. @@ -63,7 +73,14 @@ public class HierarchicalContainer extends IndexedContainer implements * interface. */ public Collection getChildren(Object itemId) { - final Collection c = children.get(itemId); + LinkedList c; + + if (filteredChildren != null) { + c = filteredChildren.get(itemId); + } else { + c = children.get(itemId); + } + if (c == null) { return null; } @@ -85,7 +102,11 @@ public class HierarchicalContainer extends IndexedContainer implements * interface. */ public boolean hasChildren(Object itemId) { - return children.get(itemId) != null; + if (filteredChildren != null) { + return filteredChildren.containsKey(itemId); + } else { + return children.containsKey(itemId); + } } /* @@ -94,6 +115,10 @@ public class HierarchicalContainer extends IndexedContainer implements * interface. */ public boolean isRoot(Object itemId) { + if (filteredRoots != null && !filteredRoots.contains(itemId)) { + return false; + } + if (parent.containsKey(itemId)) { return false; } @@ -107,7 +132,11 @@ public class HierarchicalContainer extends IndexedContainer implements * interface. */ public Collection rootItemIds() { - return Collections.unmodifiableCollection(roots); + if (filteredRoots != null) { + return Collections.unmodifiableCollection(filteredRoots); + } else { + return Collections.unmodifiableCollection(roots); + } } /** @@ -179,20 +208,39 @@ public class HierarchicalContainer extends IndexedContainer implements return true; } - // Making root + // Making root? if (newParentId == null) { - + // The itemId should become a root so we need to + // - Remove it from the old parent's children list (also filtered list) + // - Add it as a root + // - Remove it from the item -> parent list (parent is null for roots) + // Removes from old parents children list - final LinkedList l = children.get(itemId); + final LinkedList l = children.get(itemId); if (l != null) { l.remove(itemId); if (l.isEmpty()) { children.remove(itemId); } + + if (filteredChildren != null) { + LinkedList f = filteredChildren.get(itemId); + if (f != null) { + f.remove(itemId); + if (f.isEmpty()) { + filteredChildren.remove(f); + } + } + } } // Add to be a root roots.add(itemId); + if (filteredRoots != null) { + if (passesFilters(itemId)) { + filteredRoots.add(itemId); + } + } // Updates parent parent.remove(itemId); @@ -200,6 +248,13 @@ public class HierarchicalContainer extends IndexedContainer implements return true; } + // We get here when the item should not become a root and we need to + // - Verify the new parent exists and can have children + // - Check that the new parent is not a child of the selected itemId + // - Updated the item -> parent mapping to point to the new parent + // - Remove the item from the roots list if it was a root + // - Remove the item from the old parent's children list if it was not a root + // Checks that the new parent exists in container and can have // children if (!containsId(newParentId) || noChildrenAllowed.contains(newParentId)) { @@ -217,24 +272,46 @@ public class HierarchicalContainer extends IndexedContainer implements // Updates parent parent.put(itemId, newParentId); - LinkedList pcl = children.get(newParentId); + LinkedList pcl = children.get(newParentId); if (pcl == null) { - pcl = new LinkedList(); + // Create an empty list for holding children if one were not + // previously created + pcl = new LinkedList(); children.put(newParentId, pcl); } pcl.add(itemId); + // Add children list for filtered case also + if (filteredChildren != null) { + LinkedList f = filteredChildren.get(newParentId); + if (f == null) { + // Create an empty list for holding children if one were not + // previously created + f = new LinkedList(); + filteredChildren.put(newParentId, f); + } + } + // Removes from old parent or root if (oldParentId == null) { roots.remove(itemId); } else { - final LinkedList l = children.get(oldParentId); + final LinkedList l = children.get(oldParentId); if (l != null) { l.remove(itemId); if (l.isEmpty()) { children.remove(oldParentId); } } + if (filteredChildren != null) { + LinkedList f = filteredChildren.get(oldParentId); + if (f != null) { + f.remove(itemId); + if (f.isEmpty()) { + filteredChildren.remove(oldParentId); + } + } + } } return true; @@ -247,12 +324,21 @@ public class HierarchicalContainer extends IndexedContainer implements */ @Override public Object addItem() { - final Object id = super.addItem(); - if (id != null && !roots.contains(id)) { - roots.add(id); + final Object itemId = super.addItem(); + if (itemId == null) { + return null; + } + + if (!roots.contains(itemId)) { + roots.add(itemId); + if (filteredRoots != null) { + if (passesFilters(itemId)) { + filteredRoots.add(itemId); + } + } } - return id; + return itemId; } /* @@ -263,9 +349,18 @@ public class HierarchicalContainer extends IndexedContainer implements @Override public Item addItem(Object itemId) { final Item item = super.addItem(itemId); - if (item != null) { - roots.add(itemId); + if (item == null) { + return null; } + + roots.add(itemId); + + if (filteredRoots != null) { + if (passesFilters(itemId)) { + filteredRoots.add(itemId); + } + } + return item; } @@ -283,6 +378,12 @@ public class HierarchicalContainer extends IndexedContainer implements parent.clear(); children.clear(); noChildrenAllowed.clear(); + if (filteredRoots != null) { + filteredRoots = null; + } + if (filteredChildren != null) { + filteredChildren = null; + } } return success; } @@ -297,15 +398,41 @@ public class HierarchicalContainer extends IndexedContainer implements final boolean success = super.removeItem(itemId); if (success) { - if (isRoot(itemId)) { - roots.remove(itemId); + + // Remove from roots if this was a root + if (roots.remove(itemId)) { + + // If filtering is enabled we might need to remove it from the + // filtered list also + if (filteredRoots != null) { + filteredRoots.remove(itemId); + } + } + + // Clear the children list. Old children will now be unattached + // FIXME Should these be made into roots? + if (children.remove(itemId) != null) { + if (filteredChildren != null) { + filteredChildren.remove(itemId); + } } - children.remove(itemId); - final Object p = parent.get(itemId); - if (p != null) { - final LinkedList c = children.get(p); + + // Parent of the item that we are removing will contain the item id + // in its children list + final Object parentItemId = parent.get(itemId); + if (parentItemId != null) { + final LinkedList c = children.get(parentItemId); if (c != null) { c.remove(itemId); + + // Found in the children list so might also be in the + // filteredChildren list + if (filteredChildren != null) { + LinkedList f = filteredChildren.get(parentItemId); + if (f != null) { + f.remove(parentItemId); + } + } } } parent.remove(itemId); @@ -330,4 +457,39 @@ public class HierarchicalContainer extends IndexedContainer implements } } + /* + * Overridden to provide filtering for root & children items. + * + * (non-Javadoc) + * + * @see com.vaadin.data.util.IndexedContainer#updateContainerFiltering() + */ + @Override + protected void updateContainerFiltering() { + super.updateContainerFiltering(); + + filteredRoots = new LinkedList(); + filteredChildren = new HashMap>(); + + // Filter root item ids + for (Object rootId : roots) { + if (passesFilters(rootId)) { + filteredRoots.add(rootId); + } + } + + // Filter children + for (Object parent : children.keySet()) { + if (passesFilters(parent)) { + LinkedList filtered = new LinkedList(); + filteredChildren.put(parent, filtered); + for (Object child : children.get(parent)) { + if (passesFilters(child)) { + filtered.add(child); + } + } + } + } + + } } diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java index 1d2726cdeb..5131923eac 100644 --- a/src/com/vaadin/data/util/IndexedContainer.java +++ b/src/com/vaadin/data/util/IndexedContainer.java @@ -1561,7 +1561,7 @@ public class IndexedContainer implements Container.Indexed, } } - private void updateContainerFiltering() { + protected void updateContainerFiltering() { // Clearing filters? if (filters == null || filters.isEmpty()) { @@ -1583,7 +1583,7 @@ public class IndexedContainer implements Container.Indexed, // Filter for (final Iterator i = itemIds.iterator(); i.hasNext();) { final Object id = i.next(); - if (passesFilters(new IndexedContainerItem(id))) { + if (passesFilters(id)) { filteredItemIds.add(id); } } @@ -1591,6 +1591,10 @@ public class IndexedContainer implements Container.Indexed, fireContentsChange(-1); } + protected final boolean passesFilters(Object itemId) { + return passesFilters(new IndexedContainerItem(itemId)); + } + private boolean passesFilters(Item item) { if (filters == null) { return true; diff --git a/tests/src/com/vaadin/tests/server/container/AbstractContainerTest.java b/tests/src/com/vaadin/tests/server/container/AbstractContainerTest.java index 09e9fff169..e20f54dc39 100644 --- a/tests/src/com/vaadin/tests/server/container/AbstractContainerTest.java +++ b/tests/src/com/vaadin/tests/server/container/AbstractContainerTest.java @@ -81,9 +81,10 @@ public abstract class AbstractContainerTest extends TestCase { } - protected static final Object PROP1 = "PROP1"; - protected static final Object PROP2 = "PROP2"; - protected static final Object PROP3 = "PROP3"; + protected static final Object FULLY_QUALIFIED_NAME = "PROP1"; + protected static final Object SIMPLE_NAME = "simplename"; + protected static final Object REVERSE_FULLY_QUALIFIED_NAME = "PROP2"; + protected static final Object ID_NUMBER = "PROP3"; protected void testBasicContainerOperations(Container container) { initializeContainer(container); @@ -165,7 +166,7 @@ public abstract class AbstractContainerTest extends TestCase { initializeContainer(container); // Filter by "contains ab" - container.addContainerFilter(PROP1, "ab", false, false); + container.addContainerFilter(FULLY_QUALIFIED_NAME, "ab", false, false); validateContainer(container, "com.vaadin.data.BufferedValidatable", "com.vaadin.ui.TabSheet", @@ -174,7 +175,8 @@ public abstract class AbstractContainerTest extends TestCase { // Filter by "contains da" (reversed as ad here) container.removeAllContainerFilters(); - container.addContainerFilter(PROP2, "ad", false, false); + container.addContainerFilter(REVERSE_FULLY_QUALIFIED_NAME, "ad", false, + false); validateContainer(container, "com.vaadin.data.Buffered", "com.vaadin.terminal.gwt.server.ComponentSizeValidator", @@ -188,12 +190,14 @@ public abstract class AbstractContainerTest extends TestCase { initializeContainer(sortable); // Filter by "contains ab" - filterable.addContainerFilter(PROP1, "ab", false, false); + filterable.addContainerFilter(FULLY_QUALIFIED_NAME, "ab", false, false); // Must be able to sort based on PROP1 for this test - assertTrue(sortable.getSortableContainerPropertyIds().contains(PROP1)); + assertTrue(sortable.getSortableContainerPropertyIds().contains( + FULLY_QUALIFIED_NAME)); - sortable.sort(new Object[] { PROP1 }, new boolean[] { true }); + sortable.sort(new Object[] { FULLY_QUALIFIED_NAME }, + new boolean[] { true }); validateContainer(sortable, "com.vaadin.data.BufferedValidatable", "com.vaadin.ui.TableFieldFactory", @@ -207,17 +211,21 @@ public abstract class AbstractContainerTest extends TestCase { initializeContainer(container); // Must be able to sort based on PROP1 for this test - assertTrue(sortable.getSortableContainerPropertyIds().contains(PROP1)); - assertTrue(sortable.getSortableContainerPropertyIds().contains(PROP2)); + assertTrue(sortable.getSortableContainerPropertyIds().contains( + FULLY_QUALIFIED_NAME)); + assertTrue(sortable.getSortableContainerPropertyIds().contains( + REVERSE_FULLY_QUALIFIED_NAME)); - sortable.sort(new Object[] { PROP1 }, new boolean[] { true }); + sortable.sort(new Object[] { FULLY_QUALIFIED_NAME }, + new boolean[] { true }); validateContainer(container, "com.vaadin.Application", "com.vaadin.util.SerializerHelper", "com.vaadin.terminal.ApplicationResource", "blah", sampleData.length); - sortable.sort(new Object[] { PROP2 }, new boolean[] { true }); + sortable.sort(new Object[] { REVERSE_FULLY_QUALIFIED_NAME }, + new boolean[] { true }); validateContainer(container, "com.vaadin.terminal.gwt.server.ApplicationPortlet2", @@ -233,17 +241,30 @@ public abstract class AbstractContainerTest extends TestCase { container.removeContainerProperty(propertyId); } - container.addContainerProperty(PROP1, String.class, ""); - container.addContainerProperty(PROP2, String.class, null); - container.addContainerProperty(PROP3, Integer.class, null); + container.addContainerProperty(FULLY_QUALIFIED_NAME, String.class, ""); + container.addContainerProperty(SIMPLE_NAME, String.class, ""); + container.addContainerProperty(REVERSE_FULLY_QUALIFIED_NAME, + String.class, null); + container.addContainerProperty(ID_NUMBER, Integer.class, null); for (int i = 0; i < sampleData.length; i++) { String id = sampleData[i]; Item item = container.addItem(id); - item.getItemProperty(PROP1).setValue(sampleData[i]); - item.getItemProperty(PROP2).setValue(reverse(sampleData[i])); - item.getItemProperty(PROP3).setValue(i); + item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(sampleData[i]); + item.getItemProperty(SIMPLE_NAME).setValue( + getSimpleName(sampleData[i])); + item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME).setValue( + reverse(sampleData[i])); + item.getItemProperty(ID_NUMBER).setValue(i); + } + } + + protected String getSimpleName(String name) { + if (name.contains(".")) { + return name.substring(name.lastIndexOf('.') + 1); + } else { + return name; } } diff --git a/tests/src/com/vaadin/tests/server/container/AbstractHierarchicalContainerTest.java b/tests/src/com/vaadin/tests/server/container/AbstractHierarchicalContainerTest.java index 12037259fd..7aeef3e1b1 100644 --- a/tests/src/com/vaadin/tests/server/container/AbstractHierarchicalContainerTest.java +++ b/tests/src/com/vaadin/tests/server/container/AbstractHierarchicalContainerTest.java @@ -9,10 +9,31 @@ import com.vaadin.data.Container.Sortable; public class AbstractHierarchicalContainerTest extends AbstractContainerTest { + /** + * @param container + * The container to validate + * @param expectedFirstItemId + * Expected first item id + * @param expectedLastItemId + * Expected last item id + * @param itemIdInSet + * An item id that is in the container + * @param itemIdNotInSet + * An item id that is not in the container + * @param expectedSize + * Expected number of items in the container. Not related to + * hierarchy. + * @param expectedTraversalSize + * Expected number of items found when traversing from the roots + * down to all available nodes. + * @param expectedRootSize + * Expected number of root items + */ private void validateHierarchicalContainer(Hierarchical container, Object expectedFirstItemId, Object expectedLastItemId, - Object itemIdInSet, Object itemIdNotInSet, int expectedSize, - int expectedRootSize) { + Object itemIdInSet, Object itemIdNotInSet, + boolean rootsHaveChildren, int expectedSize, + int expectedTraversalSize, int expectedRootSize) { validateContainer(container, expectedFirstItemId, expectedLastItemId, itemIdInSet, itemIdNotInSet, expectedSize); @@ -35,13 +56,18 @@ public class AbstractHierarchicalContainerTest extends AbstractContainerTest { assertTrue(container.areChildrenAllowed(rootId)); // all roots have children in this case - Collection children = container.getChildren(rootId); - assertNotNull(rootId + " should have children", children); - assertTrue(rootId + " should have children", (children.size() > 0)); + if (rootsHaveChildren) { + Collection children = container.getChildren(rootId); + assertNotNull(rootId + " should have children", children); + assertTrue(rootId + " should have children", + (children.size() > 0)); + + // getParent + for (Object childId : children) { + assertEquals(container.getParent(childId), rootId); + } + } else { - // getParent - for (Object childId : children) { - assertEquals(container.getParent(childId), rootId); } } @@ -57,7 +83,7 @@ public class AbstractHierarchicalContainerTest extends AbstractContainerTest { // removeItem of unknown items should return false assertFalse(container.removeItem(itemIdNotInSet)); - assertEquals(expectedSize, countNodes(container)); + assertEquals(expectedTraversalSize, countNodes(container)); validateHierarchy(container); } @@ -114,10 +140,11 @@ public class AbstractHierarchicalContainerTest extends AbstractContainerTest { initializeContainer(container); int packages = 21; + int expectedSize = sampleData.length + packages; validateHierarchicalContainer(container, "com", "com.vaadin.util.SerializerHelper", - "com.vaadin.terminal.ApplicationResource", "blah", - sampleData.length + packages, 1); + "com.vaadin.terminal.ApplicationResource", "blah", true, + expectedSize, expectedSize, 1); } @@ -127,24 +154,29 @@ public class AbstractHierarchicalContainerTest extends AbstractContainerTest { initializeContainer(container); // Must be able to sort based on PROP1 and PROP2 for this test - assertTrue(sortable.getSortableContainerPropertyIds().contains(PROP1)); - assertTrue(sortable.getSortableContainerPropertyIds().contains(PROP2)); + assertTrue(sortable.getSortableContainerPropertyIds().contains( + FULLY_QUALIFIED_NAME)); + assertTrue(sortable.getSortableContainerPropertyIds().contains( + REVERSE_FULLY_QUALIFIED_NAME)); - sortable.sort(new Object[] { PROP1 }, new boolean[] { true }); + sortable.sort(new Object[] { FULLY_QUALIFIED_NAME }, + new boolean[] { true }); int packages = 21; + int expectedSize = sampleData.length + packages; validateHierarchicalContainer(container, "com", "com.vaadin.util.SerializerHelper", - "com.vaadin.terminal.ApplicationResource", "blah", - sampleData.length + packages, 1); + "com.vaadin.terminal.ApplicationResource", "blah", true, + expectedSize, expectedSize, 1); - sortable.sort(new Object[] { PROP2 }, new boolean[] { true }); + sortable.sort(new Object[] { REVERSE_FULLY_QUALIFIED_NAME }, + new boolean[] { true }); validateHierarchicalContainer(container, "com.vaadin.terminal.gwt.server.ApplicationPortlet2", "com.vaadin.data.util.ObjectProperty", - "com.vaadin.terminal.ApplicationResource", "blah", - sampleData.length + packages, 1); + "com.vaadin.terminal.ApplicationResource", "blah", true, + expectedSize, expectedSize, 1); } @@ -154,31 +186,47 @@ public class AbstractHierarchicalContainerTest extends AbstractContainerTest { initializeContainer(container); // Filter by "contains ab" - filterable.addContainerFilter(PROP1, "ab", false, false); + filterable.addContainerFilter(FULLY_QUALIFIED_NAME, "ab", false, false); + + // 20 items should remain in the container but the root should be + // filtered + int expectedSize = 20; + int expectedTraversalSize = 0; + int expectedRoots = 0; validateHierarchicalContainer(container, "com.vaadin.data.BufferedValidatable", "com.vaadin.ui.TabSheet", - "com.vaadin.terminal.gwt.client.Focusable", "blah", 20, 0); + "com.vaadin.terminal.gwt.client.Focusable", "blah", true, + expectedSize, expectedTraversalSize, expectedRoots); // filter out every second item except hierarchy items filterable.removeAllContainerFilters(); - filterable.addContainerFilter(PROP3, "1", false, false); + filterable.addContainerFilter(ID_NUMBER, "1", false, false); int packages = 21; int other = sampleData.length / 2; + + expectedSize = packages + other; + expectedRoots = 1; + expectedTraversalSize = expectedSize; + validateHierarchicalContainer(container, "com", "com.vaadin.util", - "com.vaadin.data.util.IndexedContainer", - "com.vaadin.data.util.ObjectProperty", packages + other, 0); + "com.vaadin.data.util.IndexedContainer", "blah", true, + expectedSize, expectedTraversalSize, expectedRoots); + + // Additionally remove all without 'm' in the simple name. Hierarchy is + // now one root only. + filterable.addContainerFilter(SIMPLE_NAME, "m", false, false); - // Additionally remove all without 'm'. Hierarchy is now one root only. - filterable.addContainerFilter(PROP1, "m", false, false); + expectedSize = 27; + expectedRoots = 1; + expectedTraversalSize = 1; - validateHierarchicalContainer(container, "com.vaadin.data.Buffered", - "com.vaadin.terminal.gwt.server.ComponentSizeValidator", - "com.vaadin.data.util.IndexedContainer", - "com.vaadin.terminal.gwt.client.ui.VUriFragmentUtility", - packages + other, 0); + validateHierarchicalContainer(container, "com", + "com.vaadin.ui.UriFragmentUtility", + "com.vaadin.terminal.gwt.client.ui.TreeImages", "blah", false, + expectedSize, expectedTraversalSize, expectedRoots); } @@ -189,9 +237,11 @@ public class AbstractHierarchicalContainerTest extends AbstractContainerTest { container.removeContainerProperty(propertyId); } - container.addContainerProperty(PROP1, String.class, ""); - container.addContainerProperty(PROP2, String.class, null); - container.addContainerProperty(PROP3, Integer.class, null); + container.addContainerProperty(FULLY_QUALIFIED_NAME, String.class, ""); + container.addContainerProperty(SIMPLE_NAME, String.class, ""); + container.addContainerProperty(REVERSE_FULLY_QUALIFIED_NAME, + String.class, null); + container.addContainerProperty(ID_NUMBER, Integer.class, null); for (int i = 0; i < sampleData.length; i++) { String id = sampleData[i]; @@ -204,9 +254,11 @@ public class AbstractHierarchicalContainerTest extends AbstractContainerTest { if (container.addItem(path) != null) { assertTrue(container.setChildrenAllowed(path, false)); Item item = container.getItem(path); - item.getItemProperty(PROP1).setValue(path); - item.getItemProperty(PROP2).setValue(reverse(path)); - item.getItemProperty(PROP3).setValue(1); + item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(path); + item.getItemProperty(SIMPLE_NAME).setValue(getSimpleName(path)); + item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME).setValue( + reverse(path)); + item.getItemProperty(ID_NUMBER).setValue(1); } for (int j = 1; j < paths.length; j++) { String parent = path; @@ -218,9 +270,12 @@ public class AbstractHierarchicalContainerTest extends AbstractContainerTest { assertTrue(container.setChildrenAllowed(path, false)); Item item = container.getItem(path); - item.getItemProperty(PROP1).setValue(path); - item.getItemProperty(PROP2).setValue(reverse(path)); - item.getItemProperty(PROP3).setValue(1); + item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(path); + item.getItemProperty(SIMPLE_NAME).setValue( + getSimpleName(path)); + item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME) + .setValue(reverse(path)); + item.getItemProperty(ID_NUMBER).setValue(1); } assertTrue(container.setChildrenAllowed(parent, true)); @@ -233,9 +288,12 @@ public class AbstractHierarchicalContainerTest extends AbstractContainerTest { assertNotNull(item); String parent = id.substring(0, id.lastIndexOf('.')); assertTrue(container.setParent(id, parent)); - item.getItemProperty(PROP1).setValue(sampleData[i]); - item.getItemProperty(PROP2).setValue(reverse(sampleData[i])); - item.getItemProperty(PROP3).setValue(i % 2); + item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(sampleData[i]); + item.getItemProperty(SIMPLE_NAME).setValue( + getSimpleName(sampleData[i])); + item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME).setValue( + reverse(sampleData[i])); + item.getItemProperty(ID_NUMBER).setValue(i % 2); } } diff --git a/tests/src/com/vaadin/tests/server/container/TestHierarchicalContainer.java b/tests/src/com/vaadin/tests/server/container/TestHierarchicalContainer.java index 79f1cf6075..0f60e133c1 100644 --- a/tests/src/com/vaadin/tests/server/container/TestHierarchicalContainer.java +++ b/tests/src/com/vaadin/tests/server/container/TestHierarchicalContainer.java @@ -21,6 +21,10 @@ public class TestHierarchicalContainer extends testContainerSorting(new HierarchicalContainer()); } + public void testOrdered() { + testContainerOrdered(new HierarchicalContainer()); + } + public void testHierarchicalSorting() { testHierarchicalSorting(new HierarchicalContainer()); } -- cgit v1.2.3 From 9afeeff7b2b1f3a21909a69bfb201e54b9a3da6c Mon Sep 17 00:00:00 2001 From: John Alhroos Date: Tue, 2 Mar 2010 10:56:42 +0000 Subject: Merged fix for #3991 from 6.2 to 6.3. svn changeset:11585/svn branch:6.3 --- .../terminal/gwt/client/ui/VFilterSelect.java | 19 ++++++++++++- .../components/select/SelectIconPlacement.java | 33 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tests/src/com/vaadin/tests/components/select/SelectIconPlacement.java (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java index 2dcf7562ae..669b5b90ea 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VFilterSelect.java @@ -631,6 +631,23 @@ public class VFilterSelect extends Composite implements Paintable, Field, public void onLoad(LoadEvent event) { updateRootWidth(); updateSelectedIconPosition(); + + /* + * We need to re-calculate the widths in IE at load time to + * ensure that the text is not placed behind the icon. #3991 + */ + if (BrowserInfo.get().isIE()) { + int tbWidth = Util.getRequiredWidth(tb); + int openerWidth = Util.getRequiredWidth(popupOpener); + int iconWidth = selectedItemIcon.isAttached() ? Util + .measureMarginLeft(tb.getElement()) + - Util.measureMarginLeft(selectedItemIcon + .getElement()) : 0; + + int w = tbWidth + openerWidth + iconWidth; + tb.setWidth((tbWidth - getTextboxPadding()) + "px"); + setTextboxWidth(w); + } } }); @@ -883,8 +900,8 @@ public class VFilterSelect extends Composite implements Paintable, Field, panel.remove(selectedItemIcon); updateRootWidth(); } else { - selectedItemIcon.setUrl(iconUri); panel.insert(selectedItemIcon, 0); + selectedItemIcon.setUrl(iconUri); updateRootWidth(); updateSelectedIconPosition(); } diff --git a/tests/src/com/vaadin/tests/components/select/SelectIconPlacement.java b/tests/src/com/vaadin/tests/components/select/SelectIconPlacement.java new file mode 100644 index 0000000000..2fcf730669 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/select/SelectIconPlacement.java @@ -0,0 +1,33 @@ +package com.vaadin.tests.components.select; + +import com.vaadin.terminal.ThemeResource; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Select; + +public class SelectIconPlacement extends TestBase { + private static final long serialVersionUID = 1L; + + private Select mySelect; + + @Override + protected void setup() { + mySelect = new Select("Foo"); + String bar = "FooBarBaz"; + mySelect.addItem(bar); + mySelect.setItemIcon(bar, new ThemeResource("common/icons/error.png")); + mySelect.select(bar); + addComponent(mySelect); + } + + @Override + protected String getDescription() { + return "A select with item icons pushes the caption of that item to the right to make room for the icon. It works fine in all browsers except IE8.
    "+ + "Upon component render the icon and caption is on top of each others, and it corrects itself when you open the dropdown. "; + } + + @Override + protected Integer getTicketNumber() { + return 3991; + } + +} -- cgit v1.2.3 From c6f947a05979ab629ad31ce0c86f14a0e82b7f4f Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 2 Mar 2010 12:51:27 +0000 Subject: Renamed list to filteredItems svn changeset:11587/svn branch:6.3 --- src/com/vaadin/data/util/BeanItemContainer.java | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/data/util/BeanItemContainer.java b/src/com/vaadin/data/util/BeanItemContainer.java index 7848de5eed..59ffdbfce1 100644 --- a/src/com/vaadin/data/util/BeanItemContainer.java +++ b/src/com/vaadin/data/util/BeanItemContainer.java @@ -39,7 +39,7 @@ import com.vaadin.data.Property.ValueChangeNotifier; public class BeanItemContainer implements Indexed, Sortable, Filterable, ItemSetChangeNotifier, ValueChangeListener { // filtered and unfiltered item IDs - private ArrayList list = new ArrayList(); + private ArrayList filteredItems = new ArrayList(); private ArrayList allItems = new ArrayList(); private final Map> beanToItem = new HashMap>(); @@ -172,11 +172,11 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, } public BT getIdByIndex(int index) { - return list.get(index); + return filteredItems.get(index); } public int indexOfId(Object itemId) { - return list.indexOf(itemId); + return filteredItems.indexOf(itemId); } /** @@ -296,7 +296,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, public boolean containsId(Object itemId) { // only look at visible items after filtering - return list.contains(itemId); + return filteredItems.contains(itemId); } public Property getContainerProperty(Object itemId, Object propertyId) { @@ -312,7 +312,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, } public Collection getItemIds() { - return (Collection) list.clone(); + return (Collection) filteredItems.clone(); } public Class getType(Object propertyId) { @@ -321,7 +321,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, public boolean removeAllItems() throws UnsupportedOperationException { allItems.clear(); - list.clear(); + filteredItems.clear(); // detach listeners from all BeanItems for (BeanItem item : beanToItem.values()) { removeAllValueChangeListeners(item); @@ -345,7 +345,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, removeAllValueChangeListeners(getItem(itemId)); // remove item beanToItem.remove(itemId); - list.remove(itemId); + filteredItems.remove(itemId); fireItemSetChange(); return true; } @@ -375,7 +375,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, } public int size() { - return list.size(); + return filteredItems.size(); } public Collection getSortableContainerPropertyIds() { @@ -445,7 +445,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, public void addContainerFilter(Object propertyId, String filterString, boolean ignoreCase, boolean onlyMatchPrefix) { if (filters.isEmpty()) { - list = (ArrayList) allItems.clone(); + filteredItems = (ArrayList) allItems.clone(); } // listen to change events to be able to update filtering for (BeanItem item : beanToItem.values()) { @@ -465,22 +465,22 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, */ protected void filterAll() { // avoid notification if the filtering had no effect - List originalItems = list; + List originalItems = filteredItems; // it is somewhat inefficient to do a (shallow) clone() every time - list = (ArrayList) allItems.clone(); + filteredItems = (ArrayList) allItems.clone(); for (Filter f : filters) { filter(f); } // check if exactly the same items are there after filtering to avoid // unnecessary notifications // this may be slow in some cases as it uses BT.equals() - if (!originalItems.equals(list)) { + if (!originalItems.equals(filteredItems)) { fireItemSetChange(); } } protected void filter(Filter f) { - Iterator iterator = list.iterator(); + Iterator iterator = filteredItems.iterator(); while (iterator.hasNext()) { BT bean = iterator.next(); if (!f.passesFilter(getItem(bean))) { -- cgit v1.2.3 From 44ca84275d8e3858dfc605e02852c2c670d99cfc Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 2 Mar 2010 13:52:40 +0000 Subject: svn changeset:11591/svn branch:6.3 --- src/com/vaadin/data/util/BeanItemContainer.java | 108 ++++++++++++++++++------ 1 file changed, 82 insertions(+), 26 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/data/util/BeanItemContainer.java b/src/com/vaadin/data/util/BeanItemContainer.java index 59ffdbfce1..0efbdd3416 100644 --- a/src/com/vaadin/data/util/BeanItemContainer.java +++ b/src/com/vaadin/data/util/BeanItemContainer.java @@ -38,9 +38,23 @@ import com.vaadin.data.Property.ValueChangeNotifier; @SuppressWarnings("serial") public class BeanItemContainer implements Indexed, Sortable, Filterable, ItemSetChangeNotifier, ValueChangeListener { - // filtered and unfiltered item IDs - private ArrayList filteredItems = new ArrayList(); - private ArrayList allItems = new ArrayList(); + /** + * The filteredItems variable contains the items that are visible outside + * the container. If filters are enabled this contains a subset of allItems, + * if no filters are set this contains the same items as allItems. + */ + private ListSet filteredItems = new ListSet(); + + /** + * The allItems variable always contains all the items in the container. + * Some or all of these are also in the filteredItems list. + */ + private ListSet allItems = new ListSet(); + + /** + * Maps all pojos (item ids) in the container (including filtered) to their + * corresponding BeanItem. + */ private final Map> beanToItem = new HashMap>(); // internal data model to obtain property IDs etc. @@ -89,6 +103,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, * @throws IllegalArgumentException * If the collection is null or empty. */ + @SuppressWarnings("unchecked") public BeanItemContainer(Collection collection) throws IllegalArgumentException { if (collection == null || collection.isEmpty()) { @@ -98,10 +113,22 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, type = (Class) collection.iterator().next().getClass(); model = BeanItem.getPropertyDescriptors(type); - int i = 0; - for (BT bt : collection) { - addItemAt(i++, bt); + addAll(collection); + } + + private void addAll(Collection collection) { + // Pre-allocate space for the collection + allItems.ensureCapacity(allItems.size() + collection.size()); + + int idx = size(); + for (BT bean : collection) { + if (internalAddAt(idx, bean) != null) { + idx++; + } } + + // Filter the contents when all items have been added + filterAll(); } /** @@ -147,30 +174,58 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, * @return Returns new item or null if the operation fails. */ private BeanItem addItemAtInternalIndex(int index, Object newItemId) { - // Make sure that the Item has not been created yet - if (allItems.contains(newItemId)) { + BeanItem beanItem = internalAddAt(index, (BT) newItemId); + if (beanItem != null) { + filterAll(); + } + + return beanItem; + } + + + /** + * Adds the bean to all internal data structures at the given position. + * Fails if the bean is already in the container or is not assignable to the + * correct type. Returns the new BeanItem if the bean was added successfully. + * + *

    + * Caller should call {@link #filterAll()} after calling this method to + * ensure the filtered list is updated. + *

    + * + * @param position + * The position at which the bean should be inserted + * @param bean + * The bean to insert + * + * @return true if the bean was added successfully, false otherwise + */ + private BeanItem internalAddAt(int position, BT bean) { + // Make sure that the item has not been added previously + if (allItems.contains(bean)) { return null; } - if (type.isAssignableFrom(newItemId.getClass())) { - BT pojo = (BT) newItemId; - // "list" will be updated in filterAll() - allItems.add(index, pojo); - BeanItem beanItem = new BeanItem(pojo, model); - beanToItem.put(pojo, beanItem); - // add listeners to be able to update filtering on property changes - for (Filter filter : filters) { - // addValueChangeListener avoids adding duplicates - addValueChangeListener(beanItem, filter.propertyId); - } - // it is somewhat suboptimal to filter all items - filterAll(); - return beanItem; - } else { + if (!type.isAssignableFrom(bean.getClass())) { return null; } - } + // "filteredList" will be updated in filterAll() which should be invoked + // by the caller after calling this method. + allItems.add(position, bean); + BeanItem beanItem = new BeanItem(bean, model); + beanToItem.put(bean, beanItem); + + // add listeners to be able to update filtering on property + // changes + for (Filter filter : filters) { + // addValueChangeListener avoids adding duplicates + addValueChangeListener(beanItem, filter.propertyId); + } + + return beanItem; + } + @SuppressWarnings("unchecked") public BT getIdByIndex(int index) { return filteredItems.get(index); } @@ -311,6 +366,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, return beanToItem.get(itemId); } + @SuppressWarnings("unchecked") public Collection getItemIds() { return (Collection) filteredItems.clone(); } @@ -445,7 +501,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, public void addContainerFilter(Object propertyId, String filterString, boolean ignoreCase, boolean onlyMatchPrefix) { if (filters.isEmpty()) { - filteredItems = (ArrayList) allItems.clone(); + filteredItems = (ListSet) allItems.clone(); } // listen to change events to be able to update filtering for (BeanItem item : beanToItem.values()) { @@ -467,7 +523,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, // avoid notification if the filtering had no effect List originalItems = filteredItems; // it is somewhat inefficient to do a (shallow) clone() every time - filteredItems = (ArrayList) allItems.clone(); + filteredItems = (ListSet) allItems.clone(); for (Filter f : filters) { filter(f); } -- cgit v1.2.3 From 503da3311c73ee52a7af049517dbb59f43169998 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 2 Mar 2010 13:55:37 +0000 Subject: #4106 - BeanItemContainer slow in some instances svn changeset:11592/svn branch:6.3 --- src/com/vaadin/data/util/BeanItemContainer.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/data/util/BeanItemContainer.java b/src/com/vaadin/data/util/BeanItemContainer.java index 0efbdd3416..6510229d5a 100644 --- a/src/com/vaadin/data/util/BeanItemContainer.java +++ b/src/com/vaadin/data/util/BeanItemContainer.java @@ -182,11 +182,11 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, return beanItem; } - /** * Adds the bean to all internal data structures at the given position. * Fails if the bean is already in the container or is not assignable to the - * correct type. Returns the new BeanItem if the bean was added successfully. + * correct type. Returns the new BeanItem if the bean was added + * successfully. * *

    * Caller should call {@link #filterAll()} after calling this method to @@ -225,6 +225,7 @@ public class BeanItemContainer implements Indexed, Sortable, Filterable, return beanItem; } + @SuppressWarnings("unchecked") public BT getIdByIndex(int index) { return filteredItems.get(index); -- cgit v1.2.3 From b4a62c4b8f69cd8f1c15d5983821b51ebc428235 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 2 Mar 2010 13:57:28 +0000 Subject: ListSet implementation for #4106 - BeanItemContainer slow in some instances svn changeset:11593/svn branch:6.3 --- src/com/vaadin/data/util/ListSet.java | 198 ++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 src/com/vaadin/data/util/ListSet.java (limited to 'src/com') diff --git a/src/com/vaadin/data/util/ListSet.java b/src/com/vaadin/data/util/ListSet.java new file mode 100644 index 0000000000..8dc8c6bbfd --- /dev/null +++ b/src/com/vaadin/data/util/ListSet.java @@ -0,0 +1,198 @@ +package com.vaadin.data.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +/** + * ListSet is an internal Vaadin class which implements a combination of a List + * and a Set. The main purpose of this class is to provide a fast + * {@link #contains(Object)} method. Each inserted object must by unique (as + * specified by {@link #equals(Object)}). + * + * This class is subject to change and should not be used outside Vaadin core. + */ +public class ListSet extends ArrayList { + private HashSet itemSet = null; + + public ListSet() { + super(); + itemSet = new HashSet(); + } + + public ListSet(Collection c) { + super(c); + itemSet = new HashSet(c.size()); + itemSet.addAll(c); + } + + public ListSet(int initialCapacity) { + super(initialCapacity); + itemSet = new HashSet(initialCapacity); + } + + // Delegate contains operations to the set + @Override + public boolean contains(Object o) { + return itemSet.contains(o); + } + + @Override + public boolean containsAll(Collection c) { + return itemSet.containsAll(c); + } + + // Methods for updating the set when the list is updated. + @Override + public boolean add(E e) { + if (contains(e)) { + // Duplicates are not allowed + return false; + } + + if (super.add(e)) { + itemSet.add(e); + return true; + } else { + return false; + } + }; + + /** + * Works as java.util.ArrayList#add(int, java.lang.Object) but returns + * immediately if the element is already in the ListSet. + */ + @Override + public void add(int index, E element) { + if (contains(element)) { + // Duplicates are not allowed + return; + } + + super.add(index, element); + itemSet.add(element); + } + + @Override + public boolean addAll(Collection c) { + boolean modified = false; + Iterator i = c.iterator(); + while (i.hasNext()) { + E e = i.next(); + if (contains(e)) { + continue; + } + + if (add(e)) { + itemSet.add(e); + modified = true; + } + } + return modified; + } + + @Override + public boolean addAll(int index, Collection c) { + ensureCapacity(size() + c.size()); + + boolean modified = false; + Iterator i = c.iterator(); + while (i.hasNext()) { + E e = i.next(); + if (contains(e)) { + continue; + } + + add(index++, e); + itemSet.add(e); + modified = true; + } + + return modified; + } + + @Override + public void clear() { + super.clear(); + itemSet.clear(); + } + + @Override + public int indexOf(Object o) { + if (!contains(o)) { + return -1; + } + + return super.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + if (!contains(o)) { + return -1; + } + + return super.lastIndexOf(o); + } + + @Override + public E remove(int index) { + E e = super.remove(index); + + if (e != null) { + itemSet.remove(e); + } + + return e; + } + + @Override + public boolean remove(Object o) { + if (super.remove(o)) { + itemSet.remove(o); + return true; + } else { + return false; + } + } + + @Override + protected void removeRange(int fromIndex, int toIndex) { + HashSet toRemove = new HashSet(); + for (int idx = fromIndex; idx < toIndex; idx++) { + toRemove.add(get(idx)); + } + super.removeRange(fromIndex, toIndex); + itemSet.removeAll(toRemove); + } + + @Override + public E set(int index, E element) { + if (contains(element)) { + // Element already exist in the list + if (get(index) == element) { + // At the same position, nothing to be done + return element; + } else { + // At another position, cannot set + return null; + } + } + + E old = super.set(index, element); + itemSet.remove(old); + itemSet.add(element); + + return old; + } + + @SuppressWarnings("unchecked") + @Override + public Object clone() { + ListSet v = (ListSet) super.clone(); + v.itemSet = new HashSet(itemSet); + return v; + } + +} -- cgit v1.2.3 From d959c77523f807aed1f7ed4920d5f584c0f8f831 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 2 Mar 2010 14:09:19 +0000 Subject: Corrected copy/paste error svn changeset:11594/svn branch:6.3 --- src/com/vaadin/Application.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java index 0d6c5721d9..463d234489 100644 --- a/src/com/vaadin/Application.java +++ b/src/com/vaadin/Application.java @@ -1304,9 +1304,9 @@ public abstract class Application implements URIHandler, * with the server.
    * Take note of any unsaved data, and click here to re-sync." *

  • cookiesDisabledURL = null
  • - *
  • outOfSyncNotificationEnabled = true
  • - *
  • outOfSyncCaption = "Cookies disabled"
  • - *
  • outOfSyncMessage = "This application requires cookies to + *
  • cookiesDisabledNotificationEnabled = true
  • + *
  • cookiesDisabledCaption = "Cookies disabled"
  • + *
  • cookiesDisabledMessage = "This application requires cookies to * function.
    * Please enable cookies in your browser and click here to try again. *
  • -- cgit v1.2.3 From c85c13acce3f6ca09c58337b94c3bb72600ea181 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 2 Mar 2010 20:06:23 +0000 Subject: Added javadoc explaning that how Container.Filterable and Container.Hierarchical work together is implementation dependent svn changeset:11597/svn branch:6.3 --- src/com/vaadin/data/Container.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/data/Container.java b/src/com/vaadin/data/Container.java index 5777bf2b05..6dbcfe779f 100644 --- a/src/com/vaadin/data/Container.java +++ b/src/com/vaadin/data/Container.java @@ -562,26 +562,34 @@ public interface Container extends Serializable { } /** - * Interface is implemented by containers that allow reducing their visible - * contents with set of filters. - * + * Interface that is implemented by containers which allow reducing their + * visible contents based on a set of filters. + *

    * When a set of filters are set, only items that match the filters are * included in the visible contents of the container. Still new items that * do not match filters can be added to the container. Multiple filters can * be added and the container remembers the state of the filters. When * multiple filters are added, all filters must match for an item to be * visible in the container. - * + *

    + *

    * When an {@link com.vaadin.data.Ordered} or * {@link com.vaadin.data.Indexed} container is filtered, all operations of * these interfaces should only use the filtered contents and the filtered * indices to the container. - * + *

    + *

    + * How filtering is performed when a {@link Hierarchical} container + * implements {@link Filterable} is implementation specific and should be + * documented in the implementing class. + *

    + *

    * Adding items (if supported) to a filtered {@link com.vaadin.data.Ordered} * or {@link com.vaadin.data.Indexed} container should insert them * immediately after the indicated visible item. The unfiltered position of * items added at index 0, at index {@link com.vaadin.data.Container#size()} * or at an undefined position is up to the implementation. + *

    * * @since 5.0 */ -- cgit v1.2.3 From ae106c9b5e64a8ea88965ca850eef78c3e6d109b Mon Sep 17 00:00:00 2001 From: Jouni Koivuviita Date: Wed, 3 Mar 2010 11:05:31 +0000 Subject: Fixes #3736 "Split up style and type definitions" and #3467 "Button styles missing?" * Now all built-in themes have an accompanying class file that describes all provided style names. * Deprecated Button.STYLE_LINK in favor of BaseTheme.BUTTON_LINK * Deprecated Panel.STYLE_LIGHT in favor of Reindeer.PANEL_LIGHT and Runo.PANEL_LIGHT svn changeset:11601/svn branch:6.3 --- src/com/vaadin/ui/Button.java | 8 +- src/com/vaadin/ui/Panel.java | 12 +++ src/com/vaadin/ui/themes/BaseTheme.java | 44 +++++++++ src/com/vaadin/ui/themes/Reindeer.java | 163 ++++++++++++++++++++++++++++++++ src/com/vaadin/ui/themes/Runo.java | 30 ++++++ 5 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 src/com/vaadin/ui/themes/BaseTheme.java create mode 100644 src/com/vaadin/ui/themes/Reindeer.java create mode 100644 src/com/vaadin/ui/themes/Runo.java (limited to 'src/com') diff --git a/src/com/vaadin/ui/Button.java b/src/com/vaadin/ui/Button.java index 3ed50b2d42..65a34a18bb 100644 --- a/src/com/vaadin/ui/Button.java +++ b/src/com/vaadin/ui/Button.java @@ -13,6 +13,7 @@ import com.vaadin.data.Property; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.gwt.client.ui.VButton; +import com.vaadin.ui.themes.BaseTheme; /** * A generic button component. @@ -239,7 +240,12 @@ public class Button extends AbstractField { private static final Method BUTTON_CLICK_METHOD; - /* Button style with no decorations. Looks like a link, acts like a button */ + /** + * Button style with no decorations. Looks like a link, acts like a button + * + * @deprecated use {@link BaseTheme#BUTTON_LINK} instead. + */ + @Deprecated public static final String STYLE_LINK = "link"; static { diff --git a/src/com/vaadin/ui/Panel.java b/src/com/vaadin/ui/Panel.java index df08c4e62b..f4ce352687 100644 --- a/src/com/vaadin/ui/Panel.java +++ b/src/com/vaadin/ui/Panel.java @@ -19,6 +19,8 @@ import com.vaadin.terminal.PaintTarget; import com.vaadin.terminal.Scrollable; import com.vaadin.terminal.gwt.client.MouseEventDetails; import com.vaadin.terminal.gwt.client.ui.VPanel; +import com.vaadin.ui.themes.Reindeer; +import com.vaadin.ui.themes.Runo; /** * Panel - a simple single component container. @@ -36,6 +38,16 @@ public class Panel extends AbstractComponentContainer implements Scrollable, private static final String CLICK_EVENT = VPanel.CLICK_EVENT_IDENTIFIER; + /** + * Removes extra decorations from the Panel. + * + * @deprecated this style is no longer part of the core framework and this + * component, even though most built-in themes implement this + * style. Use the constant specified in the theme class file + * that you're using, if it provides one, e.g. + * {@link Reindeer#PANEL_LIGHT} or {@link Runo#PANEL_LIGHT} . + */ + @Deprecated public static final String STYLE_LIGHT = "light"; /** diff --git a/src/com/vaadin/ui/themes/BaseTheme.java b/src/com/vaadin/ui/themes/BaseTheme.java new file mode 100644 index 0000000000..48083f5240 --- /dev/null +++ b/src/com/vaadin/ui/themes/BaseTheme.java @@ -0,0 +1,44 @@ +package com.vaadin.ui.themes; + +/** + *

    + * The Base theme is the foundation for all Vaadin themes. Although it is not + * necessary to use it as the starting point for all other themes, it is heavily + * encouraged, since it abstracts and hides away many necessary style properties + * that the Vaadin terminal expects and needs. + *

    + *

    + * When creating your own theme, either extend this class and specify the styles + * implemented in your theme here, or extend some other theme that has a class + * file specified (e.g. Reindeer or Runo). + *

    + *

    + * All theme class files should follow the convention of specifying the theme + * name as a string constant THEME_NAME. + * + * @since 6.3.0 + * + */ +public class BaseTheme { + + public static final String THEME_NAME = "Base"; + + /** + * Creates a button that looks like a regular hypertext link but still acts + * like a normal button. + */ + public static final String BUTTON_LINK = "link"; + + /** + * Removes extra decorations from the panel. + * + * @deprecated Base theme does not implement this style, but it is defined + * here since it has been a part of the framework before + * multiple themes were available. Use the constant provided by + * the theme you're using instead, e.g. + * {@link Reindeer#PANEL_LIGHT} or {@link Runo#PANEL_LIGHT}. + */ + @Deprecated + public static final String PANEL_LIGHT = "light"; + +} \ No newline at end of file diff --git a/src/com/vaadin/ui/themes/Reindeer.java b/src/com/vaadin/ui/themes/Reindeer.java new file mode 100644 index 0000000000..acbf003151 --- /dev/null +++ b/src/com/vaadin/ui/themes/Reindeer.java @@ -0,0 +1,163 @@ +package com.vaadin.ui.themes; + +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.VerticalLayout; + +public class Reindeer extends BaseTheme { + + public static final String THEME_NAME = "Reindeer"; + + /*************************************************************************** + * + * Label styles + * + **************************************************************************/ + + /** + * Large font for main application headings + */ + public static final String LABEL_H1 = "h1"; + + /** + * Large font for different sections in the application + */ + public static final String LABEL_H2 = "h2"; + + /** + * Small and a little lighter font + */ + public static final String LABEL_SMALL = "light"; + + /*************************************************************************** + * + * Button styles + * + **************************************************************************/ + + /** + * Default action style for buttons (the button that gets activated when + * user presses 'enter' in a form). Use sparingly, only one default button + * per screen should be visible. + */ + public static final String BUTTON_DEFAULT = "primary"; + + /** + * Small sized button, use for context specific actions for example + */ + public static final String BUTTON_SMALL = "small"; + + /*************************************************************************** + * + * TextField styles + * + **************************************************************************/ + + /** + * Small sized text field with small font + */ + public static final String TEXTFIELD_SMALL = "small"; + + /*************************************************************************** + * + * Panel styles + * + **************************************************************************/ + + /** + * Removes borders and background color from the panel + */ + public static final String PANEL_LIGHT = "light"; + + /*************************************************************************** + * + * SplitPanel styles + * + **************************************************************************/ + + /** + * Reduces the split handle to a minimal size (1 pixel) + */ + public static final String SPLITPANEL_SMALL = "small"; + + /*************************************************************************** + * + * TabSheet styles + * + **************************************************************************/ + + /** + * Removes borders and background color from the tab sheet, and shows the + * tabs as a small bar. + */ + public static final String TABSHEET_BAR = "bar"; + + /** + * Removes borders and background color from the tab sheet. The tabs are + * presented with minimal lines indicating the selected tab. + */ + public static final String TABSHEET_MINIMAL = "minimal"; + + /*************************************************************************** + * + * Table styles + * + **************************************************************************/ + + /** + * Removes borders from the table + */ + public static final String TABLE_BORDERLESS = "borderless"; + + /** + * Makes the table headers dark and more prominent. + */ + public static final String TABLE_STRONG = "strong"; + + /*************************************************************************** + * + * Layout styles + * + **************************************************************************/ + + /** + * Changes the background of a layout to a shade of blue. Applies to + * {@link VerticalLayout}, {@link HorizontalLayout}, {@link GridLayout}, + * {@link FormLayout} and {@link CssLayout}. + */ + public static final String LAYOUT_BLUE = "blue"; + + /** + *

    + * Changes the background of a layout to almost black, and at the same time + * transforms contained components to their black style correspondents when + * available. At least texts, buttons, text fields, selects, date fields, + * tables and a few other component styles should change. + *

    + *

    + * Applies to {@link VerticalLayout}, {@link HorizontalLayout}, + * {@link GridLayout}, {@link FormLayout} and {@link CssLayout}. + *

    + * + */ + public static final String LAYOUT_BLACK = "black"; + + /*************************************************************************** + * + * Window styles + * + **************************************************************************/ + + /** + * Makes the whole window white and increases the font size of the title. + */ + public static final String WINDOW_LIGHT = "light"; + + /** + * Makes the whole window black, and changes contained components in the + * same way as {@link #LAYOUT_BLACK} does. + */ + public static final String WINDOW_BLACK = "black"; +} diff --git a/src/com/vaadin/ui/themes/Runo.java b/src/com/vaadin/ui/themes/Runo.java new file mode 100644 index 0000000000..4df6046756 --- /dev/null +++ b/src/com/vaadin/ui/themes/Runo.java @@ -0,0 +1,30 @@ +package com.vaadin.ui.themes; + + +public class Runo extends BaseTheme { + + public static final String THEME_NAME = "Runo"; + + /*************************************************************************** + * + * Button styles + * + **************************************************************************/ + + /** + * Small sized button, use for context specific actions for example + */ + public static final String BUTTON_SMALL = "small"; + + /*************************************************************************** + * + * Panel styles + * + **************************************************************************/ + + /** + * Removes borders and background color from the panel + */ + public static final String PANEL_LIGHT = "light"; + +} -- cgit v1.2.3 From d70fbb818d408555ebadb8d5d06a9529298177fd Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Thu, 4 Mar 2010 09:28:03 +0000 Subject: Fixed typos in [11570] (#4129 Show a message if cookie support is disabled in the browser) svn changeset:11629/svn branch:6.3 --- src/com/vaadin/Application.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/Application.java b/src/com/vaadin/Application.java index 463d234489..9a0c180a1d 100644 --- a/src/com/vaadin/Application.java +++ b/src/com/vaadin/Application.java @@ -1778,7 +1778,7 @@ public abstract class Application implements URIHandler, * @param cookiesDisabledCaption * the caption for the "cookies disabled" notification */ - public void setCookiesDisableCaption(String cookiesDisabledCaption) { + public void setCookiesDisabledCaption(String cookiesDisabledCaption) { this.cookiesDisabledCaption = cookiesDisabledCaption; } @@ -1790,7 +1790,7 @@ public abstract class Application implements URIHandler, * @param cookiesDisabledMessage * the message for the "cookies disabled" notification */ - public void setCookiesDisableMessage(String cookiesDisabledMessage) { + public void setCookiesDisabledMessage(String cookiesDisabledMessage) { this.cookiesDisabledMessage = cookiesDisabledMessage; } -- cgit v1.2.3 From 2559e674bce8306b3d9919f4e38fecd2e58b7b96 Mon Sep 17 00:00:00 2001 From: Henri Sara Date: Thu, 4 Mar 2010 14:48:28 +0000 Subject: #4188 PortletListener window parameter and #3921 limited GateIn support svn changeset:11646/svn branch:6.3 --- .../gwt/server/AbstractApplicationPortlet.java | 48 +++++++++++----- .../gwt/server/AbstractApplicationServlet.java | 5 +- .../gwt/server/AbstractCommunicationManager.java | 66 +++++++++++----------- .../terminal/gwt/server/CommunicationManager.java | 12 +++- .../gwt/server/PortletApplicationContext2.java | 26 ++++----- .../gwt/server/PortletCommunicationManager.java | 48 +++++++++++++++- 6 files changed, 136 insertions(+), 69 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index 522293c00b..5c0e40b38b 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -321,8 +321,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet final PrintWriter outWriter = new PrintWriter(new BufferedWriter( new OutputStreamWriter(out, "UTF-8"))); outWriter.print("dummy page"); - outWriter.flush(); - out.close(); + outWriter.close(); } else if (requestType == RequestType.STATIC_FILE) { serveStaticResources((ResourceRequest) request, (ResourceResponse) response); @@ -390,20 +389,43 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet /* Notify listeners */ + // Finds the window within the application + Window window = null; + synchronized (application) { + if (application.isRunning()) { + switch (requestType) { + case FILE_UPLOAD: + // no window + break; + case APPLICATION_RESOURCE: + // use main window - should not need any window + window = application.getMainWindow(); + break; + default: + window = applicationManager.getApplicationWindow( + request, this, application, null); + } + // if window not found, not a problem - use null + } + } + // TODO Should this happen before or after the transaction // starts? if (request instanceof RenderRequest) { applicationContext.firePortletRenderRequest(application, - (RenderRequest) request, (RenderResponse) response); + window, (RenderRequest) request, + (RenderResponse) response); } else if (request instanceof ActionRequest) { applicationContext.firePortletActionRequest(application, - (ActionRequest) request, (ActionResponse) response); + window, (ActionRequest) request, + (ActionResponse) response); } else if (request instanceof EventRequest) { applicationContext.firePortletEventRequest(application, - (EventRequest) request, (EventResponse) response); + window, (EventRequest) request, + (EventResponse) response); } else if (request instanceof ResourceRequest) { applicationContext.firePortletResourceRequest(application, - (ResourceRequest) request, + window, (ResourceRequest) request, (ResourceResponse) response); } @@ -416,7 +438,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet // Handles AJAX UIDL requests applicationManager.handleUidlRequest( (ResourceRequest) request, - (ResourceResponse) response, this); + (ResourceResponse) response, this, window); return; } else { /* @@ -428,7 +450,8 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet } handleOtherRequest(request, response, requestType, - application, applicationContext, applicationManager); + application, window, applicationContext, + applicationManager); } } catch (final SessionExpiredException e) { // TODO Figure out a better way to deal with @@ -485,14 +508,10 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet */ private void handleOtherRequest(PortletRequest request, PortletResponse response, RequestType requestType, - Application application, + Application application, Window window, PortletApplicationContext2 applicationContext, PortletCommunicationManager applicationManager) throws PortletException, IOException, MalformedURLException { - /* - * Always use the main window when running inside a portlet. - */ - Window window = application.getMainWindow(); if (window == null) { throw new PortletException(ERROR_NO_WINDOW_FOUND); } @@ -623,6 +642,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet while ((bytesRead = data.read(buffer)) > 0) { out.write(buffer, 0, bytesRead); + // TODO this may cause problems on GateIn out.flush(); } out.close(); @@ -1360,9 +1380,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet + "\"appError\": {" + "\"caption\":" + caption + "," + "\"message\" : " + message + "," + "\"url\" : " + url + "}}, \"resources\": {}, \"locales\":[]}]"); - outWriter.flush(); outWriter.close(); - out.flush(); } /** diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java index 77e83838c5..8c901ba7e7 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationServlet.java @@ -438,7 +438,10 @@ public abstract class AbstractApplicationServlet extends HttpServlet implements return; } else if (requestType == RequestType.UIDL) { // Handles AJAX UIDL requests - applicationManager.handleUidlRequest(request, response, this); + Window window = applicationManager.getApplicationWindow( + request, this, application, null); + applicationManager.handleUidlRequest(request, response, this, + window); return; } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index 2bc10b4cc0..66b3eb30ca 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -4,32 +4,6 @@ package com.vaadin.terminal.gwt.server; -import com.vaadin.Application; -import com.vaadin.Application.SystemMessages; -import com.vaadin.external.org.apache.commons.fileupload.FileItemIterator; -import com.vaadin.external.org.apache.commons.fileupload.FileItemStream; -import com.vaadin.external.org.apache.commons.fileupload.FileUpload; -import com.vaadin.external.org.apache.commons.fileupload.FileUploadException; -import com.vaadin.external.org.apache.commons.fileupload.ProgressListener; -import com.vaadin.terminal.ApplicationResource; -import com.vaadin.terminal.DownloadStream; -import com.vaadin.terminal.PaintException; -import com.vaadin.terminal.PaintTarget; -import com.vaadin.terminal.Paintable; -import com.vaadin.terminal.URIHandler; -import com.vaadin.terminal.UploadStream; -import com.vaadin.terminal.VariableOwner; -import com.vaadin.terminal.Paintable.RepaintRequestEvent; -import com.vaadin.terminal.Terminal.ErrorEvent; -import com.vaadin.terminal.Terminal.ErrorListener; -import com.vaadin.terminal.gwt.client.ApplicationConnection; -import com.vaadin.terminal.gwt.server.ComponentSizeValidator.InvalidLayout; -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; - import java.io.BufferedWriter; import java.io.CharArrayWriter; import java.io.IOException; @@ -66,6 +40,32 @@ import javax.portlet.PortletResponse; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import com.vaadin.Application; +import com.vaadin.Application.SystemMessages; +import com.vaadin.external.org.apache.commons.fileupload.FileItemIterator; +import com.vaadin.external.org.apache.commons.fileupload.FileItemStream; +import com.vaadin.external.org.apache.commons.fileupload.FileUpload; +import com.vaadin.external.org.apache.commons.fileupload.FileUploadException; +import com.vaadin.external.org.apache.commons.fileupload.ProgressListener; +import com.vaadin.terminal.ApplicationResource; +import com.vaadin.terminal.DownloadStream; +import com.vaadin.terminal.PaintException; +import com.vaadin.terminal.PaintTarget; +import com.vaadin.terminal.Paintable; +import com.vaadin.terminal.URIHandler; +import com.vaadin.terminal.UploadStream; +import com.vaadin.terminal.VariableOwner; +import com.vaadin.terminal.Paintable.RepaintRequestEvent; +import com.vaadin.terminal.Terminal.ErrorEvent; +import com.vaadin.terminal.Terminal.ErrorListener; +import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.server.ComponentSizeValidator.InvalidLayout; +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; + /** * This is a common base class for the server-side implementations of the * communication system between the client code (compiled with GWT into @@ -496,11 +496,14 @@ public abstract class AbstractCommunicationManager implements * @param request * @param response * @param callback + * @param window + * target window for the UIDL request, can be null if target not + * found * @throws IOException * @throws InvalidUIDLSecurityKeyException */ protected void doHandleUidlRequest(Request request, Response response, - Callback callback) throws IOException, + Callback callback, Window window) throws IOException, InvalidUIDLSecurityKeyException { // repaint requested or session has timed out and new one is created @@ -526,10 +529,7 @@ public abstract class AbstractCommunicationManager implements synchronized (application) { // Finds the window within the application - Window window = null; if (application.isRunning()) { - window = doGetApplicationWindow(request, callback, application, - null); // Returns if no window found if (window == null) { // This should not happen, no windows exists but @@ -586,8 +586,7 @@ public abstract class AbstractCommunicationManager implements } } - // out.flush(); - this line will cause errors when deployed on GateIn. - out.close(); + outWriter.close(); } /** @@ -941,7 +940,6 @@ public abstract class AbstractCommunicationManager implements outWriter.print("}]"); } - outWriter.flush(); outWriter.close(); } @@ -1846,7 +1844,7 @@ public abstract class AbstractCommunicationManager implements } return stream; } else { - // Resolve the prefix end inded + // Resolve the prefix end index final int index = uri.indexOf('/'); if (index > 0) { String prefix = uri.substring(0, index); diff --git a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java index 8799e37899..4e6bfbd158 100644 --- a/src/com/vaadin/terminal/gwt/server/CommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/CommunicationManager.java @@ -238,16 +238,22 @@ public class CommunicationManager extends AbstractCommunicationManager { * * @param request * @param response + * @param applicationServlet + * @param window + * target window of the UIDL request, can be null if window not + * found * @throws IOException * @throws ServletException */ public void handleUidlRequest(HttpServletRequest request, HttpServletResponse response, - AbstractApplicationServlet applicationServlet) throws IOException, - ServletException, InvalidUIDLSecurityKeyException { + AbstractApplicationServlet applicationServlet, Window window) + throws IOException, ServletException, + InvalidUIDLSecurityKeyException { doHandleUidlRequest(new HttpServletRequestWrapper(request), new HttpServletResponseWrapper(response), - new AbstractApplicationServletWrapper(applicationServlet)); + new AbstractApplicationServletWrapper(applicationServlet), + window); } /** diff --git a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java index ab1b1da81f..a6f8d7f204 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java +++ b/src/com/vaadin/terminal/gwt/server/PortletApplicationContext2.java @@ -139,18 +139,18 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { } } - public void firePortletRenderRequest(Application app, + public void firePortletRenderRequest(Application app, Window window, RenderRequest request, RenderResponse response) { Set listeners = portletListeners.get(app); if (listeners != null) { for (PortletListener l : listeners) { l.handleRenderRequest(request, new RestrictedRenderResponse( - response)); + response), window); } } } - public void firePortletActionRequest(Application app, + public void firePortletActionRequest(Application app, Window window, ActionRequest request, ActionResponse response) { String key = request.getParameter(ActionRequest.ACTION_NAME); if (eventActionDestinationMap.containsKey(key)) { @@ -172,28 +172,28 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { Set listeners = portletListeners.get(app); if (listeners != null) { for (PortletListener l : listeners) { - l.handleActionRequest(request, response); + l.handleActionRequest(request, response, window); } } } } - public void firePortletEventRequest(Application app, EventRequest request, - EventResponse response) { + public void firePortletEventRequest(Application app, Window window, + EventRequest request, EventResponse response) { Set listeners = portletListeners.get(app); if (listeners != null) { for (PortletListener l : listeners) { - l.handleEventRequest(request, response); + l.handleEventRequest(request, response, window); } } } - public void firePortletResourceRequest(Application app, + public void firePortletResourceRequest(Application app, Window window, ResourceRequest request, ResourceResponse response) { Set listeners = portletListeners.get(app); if (listeners != null) { for (PortletListener l : listeners) { - l.handleResourceRequest(request, response); + l.handleResourceRequest(request, response, window); } } } @@ -201,16 +201,16 @@ public class PortletApplicationContext2 extends AbstractWebApplicationContext { public interface PortletListener extends Serializable { public void handleRenderRequest(RenderRequest request, - RenderResponse response); + RenderResponse response, Window window); public void handleActionRequest(ActionRequest request, - ActionResponse response); + ActionResponse response, Window window); public void handleEventRequest(EventRequest request, - EventResponse response); + EventResponse response, Window window); public void handleResourceRequest(ResourceRequest request, - ResourceResponse response); + ResourceResponse response, Window window); } /** diff --git a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java index 0a3307fbb0..7fe324b1db 100644 --- a/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/PortletCommunicationManager.java @@ -3,6 +3,7 @@ package com.vaadin.terminal.gwt.server; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.Method; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; @@ -13,6 +14,8 @@ import javax.portlet.PortletResponse; import javax.portlet.PortletSession; import javax.portlet.ResourceRequest; import javax.portlet.ResourceResponse; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequestWrapper; import com.vaadin.Application; import com.vaadin.external.org.apache.commons.fileupload.FileItemIterator; @@ -54,7 +57,20 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { } public String getParameter(String name) { - return request.getParameter(name); + String value = request.getParameter(name); + if (value == null) { + // for GateIn portlet container simple-portal + try { + Method getRealReq = request.getClass().getMethod( + "getRealRequest"); + HttpServletRequestWrapper origRequest = (HttpServletRequestWrapper) getRealReq + .invoke(request); + value = origRequest.getParameter(name); + } catch (Exception e) { + // do nothing - not on GateIn simple-portal + } + } + return value; } public String getRequestID() { @@ -209,11 +225,12 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { public void handleUidlRequest(ResourceRequest request, ResourceResponse response, - AbstractApplicationPortlet applicationPortlet) + AbstractApplicationPortlet applicationPortlet, Window window) throws InvalidUIDLSecurityKeyException, IOException { doHandleUidlRequest(new PortletRequestWrapper(request), new PortletResponseWrapper(response), - new AbstractApplicationPortletWrapper(applicationPortlet)); + new AbstractApplicationPortletWrapper(applicationPortlet), + window); } DownloadStream handleURI(Window window, ResourceRequest request, @@ -224,4 +241,29 @@ public class PortletCommunicationManager extends AbstractCommunicationManager { new AbstractApplicationPortletWrapper(applicationPortlet)); } + /** + * Gets the existing application or creates a new one. Get a window within + * an application based on the requested URI. + * + * @param request + * the portlet Request. + * @param applicationPortlet + * @param application + * the Application to query for window. + * @param assumedWindow + * if the window has been already resolved once, this parameter + * must contain the window. + * @return Window matching the given URI or null if not found. + * @throws ServletException + * if an exception has occurred that interferes with the + * servlet's normal operation. + */ + Window getApplicationWindow(PortletRequest request, + AbstractApplicationPortlet applicationPortlet, + Application application, Window assumedWindow) { + return doGetApplicationWindow(new PortletRequestWrapper(request), + new AbstractApplicationPortletWrapper(applicationPortlet), + application, assumedWindow); + } + } -- cgit v1.2.3 From e8f6aa927673434673c648fd37ddacb40f69f369 Mon Sep 17 00:00:00 2001 From: Henri Sara Date: Fri, 5 Mar 2010 07:52:34 +0000 Subject: #3921 removed TODO about potential GateIn problem. svn changeset:11653/svn branch:6.3 --- src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index 5c0e40b38b..148474bccc 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -642,7 +642,6 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet while ((bytesRead = data.read(buffer)) > 0) { out.write(buffer, 0, bytesRead); - // TODO this may cause problems on GateIn out.flush(); } out.close(); -- cgit v1.2.3 From 2b1deeeced6d098a22d6e52b70e94dbb9e96df57 Mon Sep 17 00:00:00 2001 From: Jouni Koivuviita Date: Fri, 5 Mar 2010 12:09:04 +0000 Subject: Fixes #3322: SplitPanel with split position 100% doesn't resize correctly * Percentage sizes now remain percentages, even if the end user drags the split handle to a new position. An rounding to nearest percentage is done at that point. svn changeset:11661/svn branch:6.3 --- .../vaadin/terminal/gwt/client/ui/VSplitPanel.java | 71 ++++++++++++++++------ src/com/vaadin/ui/SplitPanel.java | 14 +++-- 2 files changed, 63 insertions(+), 22 deletions(-) (limited to 'src/com') diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java index d7a11427fb..101c1e9848 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VSplitPanel.java @@ -122,6 +122,9 @@ public class VSplitPanel extends ComplexPanel implements Container, private boolean rendering = false; + /* The current position of the split handle in either percentages or pixels */ + private String position; + public VSplitPanel() { this(ORIENTATION_HORIZONTAL); } @@ -208,7 +211,8 @@ public class VSplitPanel extends ComplexPanel implements Container, setStylenames(); - setSplitPosition(uidl.getStringAttribute("position")); + position = uidl.getStringAttribute("position"); + setSplitPosition(position); final Paintable newFirstChild = client.getPaintable(uidl .getChildUIDL(0)); @@ -257,14 +261,26 @@ public class VSplitPanel extends ComplexPanel implements Container, } private void setSplitPosition(String pos) { + if (pos == null) { + return; + } + + // Convert percentage values to pixels + if (pos.indexOf("%") > 0) { + pos = Float.parseFloat(pos.substring(0, pos.length() - 1)) + / 100 + * (orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth() + : getOffsetHeight()) + "px"; + } + if (orientation == ORIENTATION_HORIZONTAL) { DOM.setStyleAttribute(splitter, "left", pos); } else { DOM.setStyleAttribute(splitter, "top", pos); } + iLayout(); client.runDescendentsLayout(this); - } /* @@ -441,9 +457,6 @@ public class VSplitPanel extends ComplexPanel implements Container, onVerticalMouseMove(y); break; } - iLayout(); - // TODO Check if this is needed - client.runDescendentsLayout(this); } @@ -455,7 +468,18 @@ public class VSplitPanel extends ComplexPanel implements Container, if (newX + getSplitterSize() > getOffsetWidth()) { newX = getOffsetWidth() - getSplitterSize(); } - DOM.setStyleAttribute(splitter, "left", newX + "px"); + + if (position.indexOf("%") > 0) { + float pos = newX; + // 100% needs special handling + if (newX + getSplitterSize() >= getOffsetWidth()) { + pos = getOffsetWidth(); + } + position = pos / getOffsetWidth() * 100 + "%"; + } + + setSplitPosition(newX + "px"); + if (origX != newX) { resized = true; } @@ -470,7 +494,18 @@ public class VSplitPanel extends ComplexPanel implements Container, if (newY + getSplitterSize() > getOffsetHeight()) { newY = getOffsetHeight() - getSplitterSize(); } - DOM.setStyleAttribute(splitter, "top", newY + "px"); + + if (position.indexOf("%") > 0) { + float pos = newY; + // 100% needs special handling + if (newY + getSplitterSize() >= getOffsetHeight()) { + pos = getOffsetHeight(); + } + position = pos / getOffsetHeight() * 100 + "%"; + } + + setSplitPosition(newY + "px"); + if (origY != newY) { resized = true; } @@ -554,9 +589,9 @@ public class VSplitPanel extends ComplexPanel implements Container, this.height = height; super.setHeight(height); + if (!rendering && client != null) { - iLayout(); - client.runDescendentsLayout(this); + setSplitPosition(position); } } @@ -568,9 +603,9 @@ public class VSplitPanel extends ComplexPanel implements Container, this.width = width; super.setWidth(width); + if (!rendering && client != null) { - iLayout(); - client.runDescendentsLayout(this); + setSplitPosition(position); } } @@ -627,12 +662,14 @@ public class VSplitPanel extends ComplexPanel implements Container, * Updates the new split position back to server. */ private void updateSplitPositionToServer() { - // We always send pixel values to server - final String position = orientation == ORIENTATION_HORIZONTAL ? splitter - .getStyle().getProperty("left") - : splitter.getStyle().getProperty("top"); - final int pos = Integer.parseInt(position.substring(0, position - .length() - 2)); + int pos = 0; + if (position.indexOf("%") > 0) { + pos = Float.valueOf(position.substring(0, position.length() - 1)) + .intValue(); + } else { + pos = Integer + .parseInt(position.substring(0, position.length() - 2)); + } client.updateVariable(id, "position", pos, immediate); } diff --git a/src/com/vaadin/ui/SplitPanel.java b/src/com/vaadin/ui/SplitPanel.java index 5e67b93369..1a149d7394 100644 --- a/src/com/vaadin/ui/SplitPanel.java +++ b/src/com/vaadin/ui/SplitPanel.java @@ -281,10 +281,11 @@ public class SplitPanel extends AbstractLayout { * Moves the position of the splitter. * * @param pos - * the new size of the first region in percentage + * the new size of the first region in the unit that was last + * used (default is percentage) */ public void setSplitPosition(int pos) { - setSplitPosition(pos, UNITS_PERCENTAGE, true); + setSplitPosition(pos, posUnit, true); } /** @@ -303,7 +304,7 @@ public class SplitPanel extends AbstractLayout { * Moves the position of the splitter. * * @param pos - * the new size of the first region in percentage + * the new size of the first region * @param unit * the unit (from {@link Sizeable}) in which the size is given. * @param repaintNotNeeded @@ -312,6 +313,10 @@ public class SplitPanel extends AbstractLayout { * knows the position. */ private void setSplitPosition(int pos, int unit, boolean repaintNeeded) { + if (unit != UNITS_PERCENTAGE && unit != UNITS_PIXELS) { + throw new IllegalArgumentException( + "Only percentage and pixel units are allowed"); + } this.pos = pos; posUnit = unit; if (repaintNeeded) { @@ -353,8 +358,7 @@ public class SplitPanel extends AbstractLayout { if (variables.containsKey("position") && !isLocked()) { Integer newPos = (Integer) variables.get("position"); - // Client always sends pixel values. Repaint is not needed. - setSplitPosition(newPos, UNITS_PIXELS, false); + setSplitPosition(newPos, posUnit, false); } if (variables.containsKey(SPLITTER_CLICK_EVENT)) { -- cgit v1.2.3