diff options
author | Leif Åstrand <leif@vaadin.com> | 2012-07-31 12:00:44 +0300 |
---|---|---|
committer | Leif Åstrand <leif@vaadin.com> | 2012-07-31 12:00:44 +0300 |
commit | e6ba86347ce0aea0b2dd7aa064586ce4fe7f2096 (patch) | |
tree | 5d07d002edd4984536ade795c8c42451651d6f5c /src | |
parent | 569a82a7bfc4958a9ac164e16caecc3fb47fdbc7 (diff) | |
parent | 64c7bbb569d5194eb9c5c083726a8c96053368e8 (diff) | |
download | vaadin-framework-e6ba86347ce0aea0b2dd7aa064586ce4fe7f2096.tar.gz vaadin-framework-e6ba86347ce0aea0b2dd7aa064586ce4fe7f2096.zip |
Merge remote-tracking branch 'origin/6.8'
Conflicts:
src/com/vaadin/terminal/gwt/client/ui/popupview/VPopupView.java
tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.java
tests/testbench/com/vaadin/tests/containers/sqlcontainer/CheckboxUpdateProblem.java
Diffstat (limited to 'src')
5 files changed, 84 insertions, 39 deletions
diff --git a/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java b/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java index 250b2eb4c3..5827390723 100644 --- a/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java +++ b/src/com/vaadin/data/util/sqlcontainer/SQLContainer.java @@ -534,6 +534,7 @@ public class SQLContainer implements Container, Container.Filterable, @Override public void removeContainerFilter(Filter filter) { filters.remove(filter); + refresh(); } /** diff --git a/src/com/vaadin/terminal/gwt/client/ui/popupview/VPopupView.java b/src/com/vaadin/terminal/gwt/client/ui/popupview/VPopupView.java index c923c5d0ab..1b7cfd091f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/popupview/VPopupView.java +++ b/src/com/vaadin/terminal/gwt/client/ui/popupview/VPopupView.java @@ -10,6 +10,8 @@ import java.util.Set; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.KeyDownEvent; +import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.user.client.DOM; @@ -26,6 +28,8 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.ComponentConnector; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.VCaptionWrapper; +import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler; +import com.vaadin.terminal.gwt.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner; import com.vaadin.terminal.gwt.client.ui.VOverlay; import com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextArea; @@ -183,8 +187,23 @@ public class VPopupView extends HTML { private final Set<Element> activeChildren = new HashSet<Element>(); private boolean hiding = false; + private ShortcutActionHandler shortcutActionHandler; + public CustomPopup() { super(true, false, true); // autoHide, not modal, dropshadow + + // Delegate popup keyboard events to the relevant handler. The + // events do not propagate automatically because the popup is + // directly attached to the RootPanel. + addDomHandler(new KeyDownHandler() { + @Override + public void onKeyDown(KeyDownEvent event) { + if (shortcutActionHandler != null) { + shortcutActionHandler.handleKeyboardEvent(Event + .as(event.getNativeEvent())); + } + } + }, KeyDownEvent.getType()); } // For some reason ONMOUSEOUT events are not always received, so we have @@ -233,12 +252,26 @@ public class VPopupView extends HTML { remove(popupComponentWidget); } hasHadMouseOver = false; + shortcutActionHandler = null; super.hide(autoClosed); } @Override public void show() { hiding = false; + + // Find the shortcut action handler that should handle keyboard + // events from the popup. The events do not propagate automatically + // because the popup is directly attached to the RootPanel. + Widget widget = VPopupView.this; + while (shortcutActionHandler == null && widget != null) { + if (widget instanceof ShortcutActionHandlerOwner) { + shortcutActionHandler = ((ShortcutActionHandlerOwner) widget) + .getShortcutActionHandler(); + } + widget = widget.getParent(); + } + super.show(); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java b/src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java index 1c14ce2a73..a20c0476a5 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java @@ -255,23 +255,22 @@ public class VAbstractSplitPanel extends ComplexPanel { * @return */ private float convertToPercentage(String pos) { - float posAsFloat = 0; - - if (pos.indexOf("px") > 0) { - int posAsInt = Integer.parseInt(pos.substring(0, pos.length() - 2)); + if (pos.endsWith("px")) { + float pixelPosition = Float.parseFloat(pos.substring(0, + pos.length() - 2)); int offsetLength = orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth() : getOffsetHeight(); - // 100% needs special handling - if (posAsInt + getSplitterSize() >= offsetLength) { - posAsInt = offsetLength; + // Take splitter size into account at the edge + if (pixelPosition + getSplitterSize() >= offsetLength) { + return 100; } - posAsFloat = ((float) posAsInt / (float) offsetLength * 100); + return pixelPosition / offsetLength * 100; } else { - posAsFloat = Float.parseFloat(pos.substring(0, pos.length() - 1)); + assert pos.endsWith("%"); + return Float.parseFloat(pos.substring(0, pos.length() - 1)); } - return posAsFloat; } /** diff --git a/src/com/vaadin/ui/AbstractSelect.java b/src/com/vaadin/ui/AbstractSelect.java index 63e7ae92fe..0a97ceb649 100644 --- a/src/com/vaadin/ui/AbstractSelect.java +++ b/src/com/vaadin/ui/AbstractSelect.java @@ -436,7 +436,8 @@ public abstract class AbstractSelect extends AbstractField<Object> implements // Selection change if (variables.containsKey("selected")) { - final String[] ka = (String[]) variables.get("selected"); + final String[] clientSideSelectedKeys = (String[]) variables + .get("selected"); // Multiselect mode if (isMultiSelect()) { @@ -444,19 +445,20 @@ public abstract class AbstractSelect extends AbstractField<Object> implements // TODO Optimize by adding repaintNotNeeded when applicable // Converts the key-array to id-set - final LinkedList<Object> s = new LinkedList<Object>(); - for (int i = 0; i < ka.length; i++) { - final Object id = itemIdMapper.get(ka[i]); + final LinkedList<Object> acceptedSelections = new LinkedList<Object>(); + for (int i = 0; i < clientSideSelectedKeys.length; i++) { + final Object id = itemIdMapper + .get(clientSideSelectedKeys[i]); if (!isNullSelectionAllowed() && (id == null || id == getNullSelectionItemId())) { // skip empty selection if nullselection is not allowed requestRepaint(); } else if (id != null && containsId(id)) { - s.add(id); + acceptedSelections.add(id); } } - if (!isNullSelectionAllowed() && s.size() < 1) { + if (!isNullSelectionAllowed() && acceptedSelections.size() < 1) { // empty selection not allowed, keep old value requestRepaint(); return; @@ -464,27 +466,32 @@ public abstract class AbstractSelect extends AbstractField<Object> implements // Limits the deselection to the set of visible items // (non-visible items can not be deselected) - final Collection<?> visible = getVisibleItemIds(); - if (visible != null) { + Collection<?> visibleNotSelected = getVisibleItemIds(); + if (visibleNotSelected != null) { + visibleNotSelected = new HashSet<Object>(visibleNotSelected); + // Don't remove those that will be added to preserve order + visibleNotSelected.removeAll(acceptedSelections); + @SuppressWarnings("unchecked") Set<Object> newsel = (Set<Object>) getValue(); if (newsel == null) { - newsel = new HashSet<Object>(); + newsel = new LinkedHashSet<Object>(); } else { - newsel = new HashSet<Object>(newsel); + newsel = new LinkedHashSet<Object>(newsel); } - newsel.removeAll(visible); - newsel.addAll(s); + newsel.removeAll(visibleNotSelected); + newsel.addAll(acceptedSelections); setValue(newsel, true); } } else { // Single select mode if (!isNullSelectionAllowed() - && (ka.length == 0 || ka[0] == null || ka[0] == getNullSelectionItemId())) { + && (clientSideSelectedKeys.length == 0 + || clientSideSelectedKeys[0] == null || clientSideSelectedKeys[0] == getNullSelectionItemId())) { requestRepaint(); return; } - if (ka.length == 0) { + if (clientSideSelectedKeys.length == 0) { // Allows deselection only if the deselected item is // visible final Object current = getValue(); @@ -493,7 +500,8 @@ public abstract class AbstractSelect extends AbstractField<Object> implements setValue(null, true); } } else { - final Object id = itemIdMapper.get(ka[0]); + final Object id = itemIdMapper + .get(clientSideSelectedKeys[0]); if (!isNullSelectionAllowed() && id == null) { requestRepaint(); } else if (id != null @@ -675,10 +683,10 @@ public abstract class AbstractSelect extends AbstractField<Object> implements if (isMultiSelect()) { if (newValue == null) { - super.setValue(new HashSet<Object>(), repaintIsNotNeeded); + super.setValue(new LinkedHashSet<Object>(), repaintIsNotNeeded); } else if (Collection.class.isAssignableFrom(newValue.getClass())) { - super.setValue(new HashSet<Object>((Collection<?>) newValue), - repaintIsNotNeeded); + super.setValue(new LinkedHashSet<Object>( + (Collection<?>) newValue), repaintIsNotNeeded); } } else if (newValue == null || items.containsId(newValue)) { super.setValue(newValue, repaintIsNotNeeded); diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java index 78427a0a66..71f41fb257 100644 --- a/src/com/vaadin/ui/Table.java +++ b/src/com/vaadin/ui/Table.java @@ -2410,8 +2410,9 @@ public class Table extends AbstractSelect implements Action.Container, * The end key * @return */ - private Set<Object> getItemIdsInRange(Object itemId, final int length) { - HashSet<Object> ids = new HashSet<Object>(); + private LinkedHashSet<Object> getItemIdsInRange(Object itemId, + final int length) { + LinkedHashSet<Object> ids = new LinkedHashSet<Object>(); for (int i = 0; i < length; i++) { assert itemId != null; // should not be null unless client-server // are out of sync @@ -2431,21 +2432,15 @@ public class Table extends AbstractSelect implements Action.Container, final String[] ka = (String[]) variables.get("selected"); final String[] ranges = (String[]) variables.get("selectedRanges"); - Set<Object> renderedItemIds = getCurrentlyRenderedItemIds(); + Set<Object> renderedButNotSelectedItemIds = getCurrentlyRenderedItemIds(); @SuppressWarnings("unchecked") - HashSet<Object> newValue = new HashSet<Object>( + HashSet<Object> newValue = new LinkedHashSet<Object>( (Collection<Object>) getValue()); if (variables.containsKey("clearSelections")) { // the client side has instructed to swipe all previous selections newValue.clear(); - } else { - /* - * first clear all selections that are currently rendered rows (the - * ones that the client side counterpart is aware of) - */ - newValue.removeAll(renderedItemIds); } /* @@ -2462,6 +2457,7 @@ public class Table extends AbstractSelect implements Action.Container, requestRepaint(); } else if (id != null && containsId(id)) { newValue.add(id); + renderedButNotSelectedItemIds.remove(id); } } @@ -2471,9 +2467,17 @@ public class Table extends AbstractSelect implements Action.Container, String[] split = range.split("-"); Object startItemId = itemIdMapper.get(split[0]); int length = Integer.valueOf(split[1]); - newValue.addAll(getItemIdsInRange(startItemId, length)); + LinkedHashSet<Object> itemIdsInRange = getItemIdsInRange( + startItemId, length); + newValue.addAll(itemIdsInRange); + renderedButNotSelectedItemIds.removeAll(itemIdsInRange); } } + /* + * finally clear all currently rendered rows (the ones that the client + * side counterpart is aware of) that the client didn't send as selected + */ + newValue.removeAll(renderedButNotSelectedItemIds); if (!isNullSelectionAllowed() && newValue.isEmpty()) { // empty selection not allowed, keep old value |