]> source.dussan.org Git - vaadin-framework.git/commitdiff
Merge remote-tracking branch 'origin/6.8'
authorLeif Åstrand <leif@vaadin.com>
Tue, 31 Jul 2012 09:00:44 +0000 (12:00 +0300)
committerLeif Åstrand <leif@vaadin.com>
Tue, 31 Jul 2012 09:00:44 +0000 (12:00 +0300)
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

1  2 
src/com/vaadin/data/util/sqlcontainer/SQLContainer.java
src/com/vaadin/terminal/gwt/client/ui/popupview/VPopupView.java
src/com/vaadin/terminal/gwt/client/ui/splitpanel/VAbstractSplitPanel.java
src/com/vaadin/ui/AbstractSelect.java
src/com/vaadin/ui/Table.java
tests/testbench/com/vaadin/tests/components/abstractfield/AbstractFieldTest.java
tests/testbench/com/vaadin/tests/components/popupview/PopupViewClickShortcut.java
tests/testbench/com/vaadin/tests/containers/sqlcontainer/CheckboxUpdateProblem.java
tests/testbench/com/vaadin/tests/containers/sqlcontainer/ComboBoxUpdateProblem.java

index 250b2eb4c3f38c32f6cd16045da4970d530c8f72,156b51b94c4abf3440ee675922f1e179a90748e8..58273907231f87b86582c06a41644f191707cf4e
@@@ -530,10 -508,9 +530,11 @@@ public class SQLContainer implements Co
      /**
       * {@inheritDoc}
       */
 +
 +    @Override
      public void removeContainerFilter(Filter filter) {
          filters.remove(filter);
+         refresh();
      }
  
      /**
index c923c5d0abdfa50f1807068bb92c1e807c272c56,0000000000000000000000000000000000000000..1b7cfd091fc42def21b2744d769fa45ce622983b
mode 100644,000000..100644
--- /dev/null
@@@ -1,340 -1,0 +1,373 @@@
 +/*
 +@VaadinApache2LicenseForJavaFiles@
 + */
 +package com.vaadin.terminal.gwt.client.ui.popupview;
 +
 +import java.util.HashSet;
 +import java.util.Iterator;
 +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;
 +import com.google.gwt.user.client.Element;
 +import com.google.gwt.user.client.Event;
 +import com.google.gwt.user.client.ui.Focusable;
 +import com.google.gwt.user.client.ui.HTML;
 +import com.google.gwt.user.client.ui.HasWidgets;
 +import com.google.gwt.user.client.ui.Label;
 +import com.google.gwt.user.client.ui.PopupPanel;
 +import com.google.gwt.user.client.ui.RootPanel;
 +import com.google.gwt.user.client.ui.Widget;
 +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;
 +
 +public class VPopupView extends HTML {
 +
 +    public static final String CLASSNAME = "v-popupview";
 +
 +    /** For server-client communication */
 +    String uidlId;
 +    ApplicationConnection client;
 +
 +    /** This variable helps to communicate popup visibility to the server */
 +    boolean hostPopupVisible;
 +
 +    final CustomPopup popup;
 +    private final Label loading = new Label();
 +
 +    /**
 +     * loading constructor
 +     */
 +    public VPopupView() {
 +        super();
 +        popup = new CustomPopup();
 +
 +        setStyleName(CLASSNAME);
 +        popup.setStyleName(CLASSNAME + "-popup");
 +        loading.setStyleName(CLASSNAME + "-loading");
 +
 +        setHTML("");
 +        popup.setWidget(loading);
 +
 +        // When we click to open the popup...
 +        addClickHandler(new ClickHandler() {
 +            @Override
 +            public void onClick(ClickEvent event) {
 +                updateState(true);
 +            }
 +        });
 +
 +        // ..and when we close it
 +        popup.addCloseHandler(new CloseHandler<PopupPanel>() {
 +            @Override
 +            public void onClose(CloseEvent<PopupPanel> event) {
 +                updateState(false);
 +            }
 +        });
 +
 +        popup.setAnimationEnabled(true);
 +    }
 +
 +    /**
 +     * Update popup visibility to server
 +     * 
 +     * @param visibility
 +     */
 +    private void updateState(boolean visible) {
 +        // If we know the server connection
 +        // then update the current situation
 +        if (uidlId != null && client != null && isAttached()) {
 +            client.updateVariable(uidlId, "popupVisibility", visible, true);
 +        }
 +    }
 +
 +    void preparePopup(final CustomPopup popup) {
 +        popup.setVisible(false);
 +        popup.show();
 +    }
 +
 +    /**
 +     * Determines the correct position for a popup and displays the popup at
 +     * that position.
 +     * 
 +     * By default, the popup is shown centered relative to its host component,
 +     * ensuring it is visible on the screen if possible.
 +     * 
 +     * Can be overridden to customize the popup position.
 +     * 
 +     * @param popup
 +     */
 +    protected void showPopup(final CustomPopup popup) {
 +        popup.setPopupPosition(0, 0);
 +
 +        popup.setVisible(true);
 +    }
 +
 +    void center() {
 +        int windowTop = RootPanel.get().getAbsoluteTop();
 +        int windowLeft = RootPanel.get().getAbsoluteLeft();
 +        int windowRight = windowLeft + RootPanel.get().getOffsetWidth();
 +        int windowBottom = windowTop + RootPanel.get().getOffsetHeight();
 +
 +        int offsetWidth = popup.getOffsetWidth();
 +        int offsetHeight = popup.getOffsetHeight();
 +
 +        int hostHorizontalCenter = VPopupView.this.getAbsoluteLeft()
 +                + VPopupView.this.getOffsetWidth() / 2;
 +        int hostVerticalCenter = VPopupView.this.getAbsoluteTop()
 +                + VPopupView.this.getOffsetHeight() / 2;
 +
 +        int left = hostHorizontalCenter - offsetWidth / 2;
 +        int top = hostVerticalCenter - offsetHeight / 2;
 +
 +        // Don't show the popup outside the screen.
 +        if ((left + offsetWidth) > windowRight) {
 +            left -= (left + offsetWidth) - windowRight;
 +        }
 +
 +        if ((top + offsetHeight) > windowBottom) {
 +            top -= (top + offsetHeight) - windowBottom;
 +        }
 +
 +        if (left < 0) {
 +            left = 0;
 +        }
 +
 +        if (top < 0) {
 +            top = 0;
 +        }
 +
 +        popup.setPopupPosition(left, top);
 +    }
 +
 +    /**
 +     * Make sure that we remove the popup when the main widget is removed.
 +     * 
 +     * @see com.google.gwt.user.client.ui.Widget#onUnload()
 +     */
 +    @Override
 +    protected void onDetach() {
 +        popup.hide();
 +        super.onDetach();
 +    }
 +
 +    private static native void nativeBlur(Element e)
 +    /*-{
 +        if(e && e.blur) {
 +            e.blur();
 +        }
 +    }-*/;
 +
 +    /**
 +     * This class is only protected to enable overriding showPopup, and is
 +     * currently not intended to be extended or otherwise used directly. Its API
 +     * (other than it being a VOverlay) is to be considered private and
 +     * potentially subject to change.
 +     */
 +    protected class CustomPopup extends VOverlay {
 +
 +        private ComponentConnector popupComponentPaintable = null;
 +        Widget popupComponentWidget = null;
 +        VCaptionWrapper captionWrapper = null;
 +
 +        private boolean hasHadMouseOver = false;
 +        private boolean hideOnMouseOut = true;
 +        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
 +        // to use ONMOUSEMOVE that doesn't target the popup
 +        @Override
 +        public boolean onEventPreview(Event event) {
 +            Element target = DOM.eventGetTarget(event);
 +            boolean eventTargetsPopup = DOM.isOrHasChild(getElement(), target);
 +            int type = DOM.eventGetType(event);
 +
 +            // Catch children that use keyboard, so we can unfocus them when
 +            // hiding
 +            if (eventTargetsPopup && type == Event.ONKEYPRESS) {
 +                activeChildren.add(target);
 +            }
 +
 +            if (eventTargetsPopup && type == Event.ONMOUSEMOVE) {
 +                hasHadMouseOver = true;
 +            }
 +
 +            if (!eventTargetsPopup && type == Event.ONMOUSEMOVE) {
 +                if (hasHadMouseOver && hideOnMouseOut) {
 +                    hide();
 +                    return true;
 +                }
 +            }
 +
 +            // Was the TAB key released outside of our popup?
 +            if (!eventTargetsPopup && type == Event.ONKEYUP
 +                    && event.getKeyCode() == KeyCodes.KEY_TAB) {
 +                // Should we hide on focus out (mouse out)?
 +                if (hideOnMouseOut) {
 +                    hide();
 +                    return true;
 +                }
 +            }
 +
 +            return super.onEventPreview(event);
 +        }
 +
 +        @Override
 +        public void hide(boolean autoClosed) {
 +            hiding = true;
 +            syncChildren();
 +            if (popupComponentWidget != null && popupComponentWidget != loading) {
 +                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();
 +        }
 +
 +        /**
 +         * Try to sync all known active child widgets to server
 +         */
 +        public void syncChildren() {
 +            // Notify children with focus
 +            if ((popupComponentWidget instanceof Focusable)) {
 +                ((Focusable) popupComponentWidget).setFocus(false);
 +            } else {
 +
 +                checkForRTE(popupComponentWidget);
 +            }
 +
 +            // Notify children that have used the keyboard
 +            for (Element e : activeChildren) {
 +                try {
 +                    nativeBlur(e);
 +                } catch (Exception ignored) {
 +                }
 +            }
 +            activeChildren.clear();
 +        }
 +
 +        private void checkForRTE(Widget popupComponentWidget2) {
 +            if (popupComponentWidget2 instanceof VRichTextArea) {
 +                ((VRichTextArea) popupComponentWidget2)
 +                        .synchronizeContentToServer();
 +            } else if (popupComponentWidget2 instanceof HasWidgets) {
 +                HasWidgets hw = (HasWidgets) popupComponentWidget2;
 +                Iterator<Widget> iterator = hw.iterator();
 +                while (iterator.hasNext()) {
 +                    checkForRTE(iterator.next());
 +                }
 +            }
 +        }
 +
 +        @Override
 +        public boolean remove(Widget w) {
 +
 +            popupComponentPaintable = null;
 +            popupComponentWidget = null;
 +            captionWrapper = null;
 +
 +            return super.remove(w);
 +        }
 +
 +        public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
 +
 +            ComponentConnector newPopupComponent = client.getPaintable(uidl
 +                    .getChildUIDL(0));
 +
 +            if (newPopupComponent != popupComponentPaintable) {
 +                Widget newWidget = newPopupComponent.getWidget();
 +                setWidget(newWidget);
 +                popupComponentWidget = newWidget;
 +                popupComponentPaintable = newPopupComponent;
 +            }
 +
 +        }
 +
 +        public void setHideOnMouseOut(boolean hideOnMouseOut) {
 +            this.hideOnMouseOut = hideOnMouseOut;
 +        }
 +
 +        /*
 +         * 
 +         * We need a hack make popup act as a child of VPopupView in Vaadin's
 +         * component tree, but work in default GWT manner when closing or
 +         * opening.
 +         * 
 +         * (non-Javadoc)
 +         * 
 +         * @see com.google.gwt.user.client.ui.Widget#getParent()
 +         */
 +        @Override
 +        public Widget getParent() {
 +            if (!isAttached() || hiding) {
 +                return super.getParent();
 +            } else {
 +                return VPopupView.this;
 +            }
 +        }
 +
 +        @Override
 +        protected void onDetach() {
 +            super.onDetach();
 +            hiding = false;
 +        }
 +
 +        @Override
 +        public Element getContainerElement() {
 +            return super.getContainerElement();
 +        }
 +
 +    }// class CustomPopup
 +
 +}// class VPopupView
index 1c14ce2a73ecb31fde40b9face3852f6dc19a63b,0000000000000000000000000000000000000000..a20c0476a538c202083867db1aaaf18a4981ec72
mode 100644,000000..100644
--- /dev/null
@@@ -1,773 -1,0 +1,772 @@@
-         float posAsFloat = 0;
-         if (pos.indexOf("px") > 0) {
-             int posAsInt = Integer.parseInt(pos.substring(0, pos.length() - 2));
 +/*
 +@VaadinApache2LicenseForJavaFiles@
 + */
 +
 +package com.vaadin.terminal.gwt.client.ui.splitpanel;
 +
 +import java.util.Collections;
 +import java.util.List;
 +
 +import com.google.gwt.dom.client.Node;
 +import com.google.gwt.dom.client.Style;
 +import com.google.gwt.event.dom.client.TouchCancelEvent;
 +import com.google.gwt.event.dom.client.TouchCancelHandler;
 +import com.google.gwt.event.dom.client.TouchEndEvent;
 +import com.google.gwt.event.dom.client.TouchEndHandler;
 +import com.google.gwt.event.dom.client.TouchMoveEvent;
 +import com.google.gwt.event.dom.client.TouchMoveHandler;
 +import com.google.gwt.event.dom.client.TouchStartEvent;
 +import com.google.gwt.event.dom.client.TouchStartHandler;
 +import com.google.gwt.event.shared.EventHandler;
 +import com.google.gwt.event.shared.GwtEvent;
 +import com.google.gwt.user.client.DOM;
 +import com.google.gwt.user.client.Element;
 +import com.google.gwt.user.client.Event;
 +import com.google.gwt.user.client.ui.ComplexPanel;
 +import com.google.gwt.user.client.ui.Widget;
 +import com.vaadin.terminal.gwt.client.ApplicationConnection;
 +import com.vaadin.terminal.gwt.client.BrowserInfo;
 +import com.vaadin.terminal.gwt.client.ComponentConnector;
 +import com.vaadin.terminal.gwt.client.ConnectorMap;
 +import com.vaadin.terminal.gwt.client.LayoutManager;
 +import com.vaadin.terminal.gwt.client.Util;
 +import com.vaadin.terminal.gwt.client.VConsole;
 +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate;
 +import com.vaadin.terminal.gwt.client.ui.TouchScrollDelegate.TouchScrollHandler;
 +import com.vaadin.terminal.gwt.client.ui.VOverlay;
 +import com.vaadin.terminal.gwt.client.ui.splitpanel.VAbstractSplitPanel.SplitterMoveHandler.SplitterMoveEvent;
 +
 +public class VAbstractSplitPanel extends ComplexPanel {
 +
 +    private boolean enabled = false;
 +
 +    public static final String CLASSNAME = "v-splitpanel";
 +
 +    public static final int ORIENTATION_HORIZONTAL = 0;
 +
 +    public static final int ORIENTATION_VERTICAL = 1;
 +
 +    private static final int MIN_SIZE = 30;
 +
 +    private int orientation = ORIENTATION_HORIZONTAL;
 +
 +    Widget firstChild;
 +
 +    Widget secondChild;
 +
 +    private final Element wrapper = DOM.createDiv();
 +
 +    private final Element firstContainer = DOM.createDiv();
 +
 +    private final Element secondContainer = DOM.createDiv();
 +
 +    final Element splitter = DOM.createDiv();
 +
 +    private boolean resizing;
 +
 +    private boolean resized = false;
 +
 +    private int origX;
 +
 +    private int origY;
 +
 +    private int origMouseX;
 +
 +    private int origMouseY;
 +
 +    private boolean locked = false;
 +
 +    private boolean positionReversed = false;
 +
 +    List<String> componentStyleNames = Collections.emptyList();
 +
 +    private Element draggingCurtain;
 +
 +    ApplicationConnection client;
 +
 +    boolean immediate;
 +
 +    /* The current position of the split handle in either percentages or pixels */
 +    String position;
 +
 +    String maximumPosition;
 +
 +    String minimumPosition;
 +
 +    private TouchScrollHandler touchScrollHandler;
 +
 +    protected Element scrolledContainer;
 +
 +    protected int origScrollTop;
 +
 +    public VAbstractSplitPanel() {
 +        this(ORIENTATION_HORIZONTAL);
 +    }
 +
 +    public VAbstractSplitPanel(int orientation) {
 +        setElement(DOM.createDiv());
 +        switch (orientation) {
 +        case ORIENTATION_HORIZONTAL:
 +            setStyleName(CLASSNAME + "-horizontal");
 +            break;
 +        case ORIENTATION_VERTICAL:
 +        default:
 +            setStyleName(CLASSNAME + "-vertical");
 +            break;
 +        }
 +        // size below will be overridden in update from uidl, initial size
 +        // needed to keep IE alive
 +        setWidth(MIN_SIZE + "px");
 +        setHeight(MIN_SIZE + "px");
 +        constructDom();
 +        setOrientation(orientation);
 +        sinkEvents(Event.MOUSEEVENTS);
 +
 +        makeScrollable();
 +
 +        addDomHandler(new TouchCancelHandler() {
 +            @Override
 +            public void onTouchCancel(TouchCancelEvent event) {
 +                // TODO When does this actually happen??
 +                VConsole.log("TOUCH CANCEL");
 +            }
 +        }, TouchCancelEvent.getType());
 +        addDomHandler(new TouchStartHandler() {
 +            @Override
 +            public void onTouchStart(TouchStartEvent event) {
 +                Node target = event.getTouches().get(0).getTarget().cast();
 +                if (splitter.isOrHasChild(target)) {
 +                    onMouseDown(Event.as(event.getNativeEvent()));
 +                }
 +            }
 +        }, TouchStartEvent.getType());
 +        addDomHandler(new TouchMoveHandler() {
 +            @Override
 +            public void onTouchMove(TouchMoveEvent event) {
 +                if (resizing) {
 +                    onMouseMove(Event.as(event.getNativeEvent()));
 +                }
 +            }
 +        }, TouchMoveEvent.getType());
 +        addDomHandler(new TouchEndHandler() {
 +            @Override
 +            public void onTouchEnd(TouchEndEvent event) {
 +                if (resizing) {
 +                    onMouseUp(Event.as(event.getNativeEvent()));
 +                }
 +            }
 +        }, TouchEndEvent.getType());
 +
 +    }
 +
 +    protected void constructDom() {
 +        DOM.appendChild(splitter, DOM.createDiv()); // for styling
 +        DOM.appendChild(getElement(), wrapper);
 +        DOM.setStyleAttribute(wrapper, "position", "relative");
 +        DOM.setStyleAttribute(wrapper, "width", "100%");
 +        DOM.setStyleAttribute(wrapper, "height", "100%");
 +
 +        DOM.appendChild(wrapper, secondContainer);
 +        DOM.appendChild(wrapper, firstContainer);
 +        DOM.appendChild(wrapper, splitter);
 +
 +        DOM.setStyleAttribute(splitter, "position", "absolute");
 +        DOM.setStyleAttribute(secondContainer, "position", "absolute");
 +
 +        setStylenames();
 +    }
 +
 +    private void setOrientation(int orientation) {
 +        this.orientation = orientation;
 +        if (orientation == ORIENTATION_HORIZONTAL) {
 +            DOM.setStyleAttribute(splitter, "height", "100%");
 +            DOM.setStyleAttribute(splitter, "top", "0");
 +            DOM.setStyleAttribute(firstContainer, "height", "100%");
 +            DOM.setStyleAttribute(secondContainer, "height", "100%");
 +        } else {
 +            DOM.setStyleAttribute(splitter, "width", "100%");
 +            DOM.setStyleAttribute(splitter, "left", "0");
 +            DOM.setStyleAttribute(firstContainer, "width", "100%");
 +            DOM.setStyleAttribute(secondContainer, "width", "100%");
 +        }
 +    }
 +
 +    @Override
 +    public boolean remove(Widget w) {
 +        boolean removed = super.remove(w);
 +        if (removed) {
 +            if (firstChild == w) {
 +                firstChild = null;
 +            } else {
 +                secondChild = null;
 +            }
 +        }
 +        return removed;
 +    }
 +
 +    void setLocked(boolean newValue) {
 +        if (locked != newValue) {
 +            locked = newValue;
 +            splitterSize = -1;
 +            setStylenames();
 +        }
 +    }
 +
 +    void setPositionReversed(boolean reversed) {
 +        if (positionReversed != reversed) {
 +            if (orientation == ORIENTATION_HORIZONTAL) {
 +                DOM.setStyleAttribute(splitter, "right", "");
 +                DOM.setStyleAttribute(splitter, "left", "");
 +            } else if (orientation == ORIENTATION_VERTICAL) {
 +                DOM.setStyleAttribute(splitter, "top", "");
 +                DOM.setStyleAttribute(splitter, "bottom", "");
 +            }
 +
 +            positionReversed = reversed;
 +        }
 +    }
 +
 +    /**
 +     * Converts given split position string (in pixels or percentage) to a
 +     * floating point pixel value.
 +     * 
 +     * @param pos
 +     * @return
 +     */
 +    private float convertToPixels(String pos) {
 +        float posAsFloat;
 +        if (pos.indexOf("%") > 0) {
 +            posAsFloat = Math.round(Float.parseFloat(pos.substring(0,
 +                    pos.length() - 1))
 +                    / 100
 +                    * (orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth()
 +                            : getOffsetHeight()));
 +        } else {
 +            posAsFloat = Float.parseFloat(pos.substring(0, pos.length() - 2));
 +        }
 +        return posAsFloat;
 +    }
 +
 +    /**
 +     * Converts given split position string (in pixels or percentage) to a float
 +     * percentage value.
 +     * 
 +     * @param pos
 +     * @return
 +     */
 +    private float convertToPercentage(String pos) {
-             // 100% needs special handling
-             if (posAsInt + getSplitterSize() >= offsetLength) {
-                 posAsInt = offsetLength;
++        if (pos.endsWith("px")) {
++            float pixelPosition = Float.parseFloat(pos.substring(0,
++                    pos.length() - 2));
 +            int offsetLength = orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth()
 +                    : getOffsetHeight();
 +
-             posAsFloat = ((float) posAsInt / (float) offsetLength * 100);
++            // Take splitter size into account at the edge
++            if (pixelPosition + getSplitterSize() >= offsetLength) {
++                return 100;
 +            }
-             posAsFloat = Float.parseFloat(pos.substring(0, pos.length() - 1));
 +
++            return pixelPosition / offsetLength * 100;
 +        } else {
-         return posAsFloat;
++            assert pos.endsWith("%");
++            return Float.parseFloat(pos.substring(0, pos.length() - 1));
 +        }
 +    }
 +
 +    /**
 +     * Returns the given position clamped to the range between current minimum
 +     * and maximum positions.
 +     * 
 +     * TODO Should this be in the connector?
 +     * 
 +     * @param pos
 +     *            Position of the splitter as a CSS string, either pixels or a
 +     *            percentage.
 +     * @return minimumPosition if pos is less than minimumPosition;
 +     *         maximumPosition if pos is greater than maximumPosition; pos
 +     *         otherwise.
 +     */
 +    private String checkSplitPositionLimits(String pos) {
 +        float positionAsFloat = convertToPixels(pos);
 +
 +        if (maximumPosition != null
 +                && convertToPixels(maximumPosition) < positionAsFloat) {
 +            pos = maximumPosition;
 +        } else if (minimumPosition != null
 +                && convertToPixels(minimumPosition) > positionAsFloat) {
 +            pos = minimumPosition;
 +        }
 +        return pos;
 +    }
 +
 +    /**
 +     * Converts given string to the same units as the split position is.
 +     * 
 +     * @param pos
 +     *            position to be converted
 +     * @return converted position string
 +     */
 +    private String convertToPositionUnits(String pos) {
 +        if (position.indexOf("%") != -1 && pos.indexOf("%") == -1) {
 +            // position is in percentage, pos in pixels
 +            pos = convertToPercentage(pos) + "%";
 +        } else if (position.indexOf("px") > 0 && pos.indexOf("px") == -1) {
 +            // position is in pixels and pos in percentage
 +            pos = convertToPixels(pos) + "px";
 +        }
 +
 +        return pos;
 +    }
 +
 +    void setSplitPosition(String pos) {
 +        if (pos == null) {
 +            return;
 +        }
 +
 +        pos = checkSplitPositionLimits(pos);
 +        if (!pos.equals(position)) {
 +            position = convertToPositionUnits(pos);
 +        }
 +
 +        // Convert percentage values to pixels
 +        if (pos.indexOf("%") > 0) {
 +            int size = orientation == ORIENTATION_HORIZONTAL ? getOffsetWidth()
 +                    : getOffsetHeight();
 +            float percentage = Float.parseFloat(pos.substring(0,
 +                    pos.length() - 1));
 +            pos = percentage / 100 * size + "px";
 +        }
 +
 +        String attributeName;
 +        if (orientation == ORIENTATION_HORIZONTAL) {
 +            if (positionReversed) {
 +                attributeName = "right";
 +            } else {
 +                attributeName = "left";
 +            }
 +        } else {
 +            if (positionReversed) {
 +                attributeName = "bottom";
 +            } else {
 +                attributeName = "top";
 +            }
 +        }
 +
 +        Style style = splitter.getStyle();
 +        if (!pos.equals(style.getProperty(attributeName))) {
 +            style.setProperty(attributeName, pos);
 +            updateSizes();
 +        }
 +    }
 +
 +    void updateSizes() {
 +        if (!isAttached()) {
 +            return;
 +        }
 +
 +        int wholeSize;
 +        int pixelPosition;
 +
 +        switch (orientation) {
 +        case ORIENTATION_HORIZONTAL:
 +            wholeSize = DOM.getElementPropertyInt(wrapper, "clientWidth");
 +            pixelPosition = DOM.getElementPropertyInt(splitter, "offsetLeft");
 +
 +            // reposition splitter in case it is out of box
 +            if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize)
 +                    || (positionReversed && pixelPosition < 0)) {
 +                pixelPosition = wholeSize - getSplitterSize();
 +                if (pixelPosition < 0) {
 +                    pixelPosition = 0;
 +                }
 +                setSplitPosition(pixelPosition + "px");
 +                return;
 +            }
 +
 +            DOM.setStyleAttribute(firstContainer, "width", pixelPosition + "px");
 +            int secondContainerWidth = (wholeSize - pixelPosition - getSplitterSize());
 +            if (secondContainerWidth < 0) {
 +                secondContainerWidth = 0;
 +            }
 +            DOM.setStyleAttribute(secondContainer, "width",
 +                    secondContainerWidth + "px");
 +            DOM.setStyleAttribute(secondContainer, "left",
 +                    (pixelPosition + getSplitterSize()) + "px");
 +
 +            LayoutManager layoutManager = LayoutManager.get(client);
 +            ConnectorMap connectorMap = ConnectorMap.get(client);
 +            if (firstChild != null) {
 +                ComponentConnector connector = connectorMap
 +                        .getConnector(firstChild);
 +                if (connector.isRelativeWidth()) {
 +                    layoutManager.reportWidthAssignedToRelative(connector,
 +                            pixelPosition);
 +                } else {
 +                    layoutManager.setNeedsMeasure(connector);
 +                }
 +            }
 +            if (secondChild != null) {
 +                ComponentConnector connector = connectorMap
 +                        .getConnector(secondChild);
 +                if (connector.isRelativeWidth()) {
 +                    layoutManager.reportWidthAssignedToRelative(connector,
 +                            secondContainerWidth);
 +                } else {
 +                    layoutManager.setNeedsMeasure(connector);
 +                }
 +            }
 +            break;
 +        case ORIENTATION_VERTICAL:
 +            wholeSize = DOM.getElementPropertyInt(wrapper, "clientHeight");
 +            pixelPosition = DOM.getElementPropertyInt(splitter, "offsetTop");
 +
 +            // reposition splitter in case it is out of box
 +            if ((pixelPosition > 0 && pixelPosition + getSplitterSize() > wholeSize)
 +                    || (positionReversed && pixelPosition < 0)) {
 +                pixelPosition = wholeSize - getSplitterSize();
 +                if (pixelPosition < 0) {
 +                    pixelPosition = 0;
 +                }
 +                setSplitPosition(pixelPosition + "px");
 +                return;
 +            }
 +
 +            DOM.setStyleAttribute(firstContainer, "height", pixelPosition
 +                    + "px");
 +            int secondContainerHeight = (wholeSize - pixelPosition - getSplitterSize());
 +            if (secondContainerHeight < 0) {
 +                secondContainerHeight = 0;
 +            }
 +            DOM.setStyleAttribute(secondContainer, "height",
 +                    secondContainerHeight + "px");
 +            DOM.setStyleAttribute(secondContainer, "top",
 +                    (pixelPosition + getSplitterSize()) + "px");
 +
 +            layoutManager = LayoutManager.get(client);
 +            connectorMap = ConnectorMap.get(client);
 +            if (firstChild != null) {
 +                ComponentConnector connector = connectorMap
 +                        .getConnector(firstChild);
 +                if (connector.isRelativeHeight()) {
 +                    layoutManager.reportHeightAssignedToRelative(connector,
 +                            pixelPosition);
 +                } else {
 +                    layoutManager.setNeedsMeasure(connector);
 +                }
 +            }
 +            if (secondChild != null) {
 +                ComponentConnector connector = connectorMap
 +                        .getConnector(secondChild);
 +                if (connector.isRelativeHeight()) {
 +                    layoutManager.reportHeightAssignedToRelative(connector,
 +                            secondContainerHeight);
 +                } else {
 +                    layoutManager.setNeedsMeasure(connector);
 +                }
 +            }
 +            break;
 +        }
 +    }
 +
 +    void setFirstWidget(Widget w) {
 +        if (firstChild != null) {
 +            firstChild.removeFromParent();
 +        }
 +        if (w != null) {
 +            super.add(w, firstContainer);
 +        }
 +        firstChild = w;
 +    }
 +
 +    void setSecondWidget(Widget w) {
 +        if (secondChild != null) {
 +            secondChild.removeFromParent();
 +        }
 +        if (w != null) {
 +            super.add(w, secondContainer);
 +        }
 +        secondChild = w;
 +    }
 +
 +    @Override
 +    public void onBrowserEvent(Event event) {
 +        switch (DOM.eventGetType(event)) {
 +        case Event.ONMOUSEMOVE:
 +            // case Event.ONTOUCHMOVE:
 +            if (resizing) {
 +                onMouseMove(event);
 +            }
 +            break;
 +        case Event.ONMOUSEDOWN:
 +            // case Event.ONTOUCHSTART:
 +            onMouseDown(event);
 +            break;
 +        case Event.ONMOUSEOUT:
 +            // Dragging curtain interferes with click events if added in
 +            // mousedown so we add it only when needed i.e., if the mouse moves
 +            // outside the splitter.
 +            if (resizing) {
 +                showDraggingCurtain();
 +            }
 +            break;
 +        case Event.ONMOUSEUP:
 +            // case Event.ONTOUCHEND:
 +            if (resizing) {
 +                onMouseUp(event);
 +            }
 +            break;
 +        case Event.ONCLICK:
 +            resizing = false;
 +            break;
 +        }
 +        // Only fire click event listeners if the splitter isn't moved
 +        if (Util.isTouchEvent(event) || !resized) {
 +            super.onBrowserEvent(event);
 +        } else if (DOM.eventGetType(event) == Event.ONMOUSEUP) {
 +            // Reset the resized flag after a mouseup has occured so the next
 +            // mousedown/mouseup can be interpreted as a click.
 +            resized = false;
 +        }
 +    }
 +
 +    public void onMouseDown(Event event) {
 +        if (locked || !isEnabled()) {
 +            return;
 +        }
 +        final Element trg = event.getEventTarget().cast();
 +        if (trg == splitter || trg == DOM.getChild(splitter, 0)) {
 +            resizing = true;
 +            DOM.setCapture(getElement());
 +            origX = DOM.getElementPropertyInt(splitter, "offsetLeft");
 +            origY = DOM.getElementPropertyInt(splitter, "offsetTop");
 +            origMouseX = Util.getTouchOrMouseClientX(event);
 +            origMouseY = Util.getTouchOrMouseClientY(event);
 +            event.stopPropagation();
 +            event.preventDefault();
 +        }
 +    }
 +
 +    public void onMouseMove(Event event) {
 +        switch (orientation) {
 +        case ORIENTATION_HORIZONTAL:
 +            final int x = Util.getTouchOrMouseClientX(event);
 +            onHorizontalMouseMove(x);
 +            break;
 +        case ORIENTATION_VERTICAL:
 +        default:
 +            final int y = Util.getTouchOrMouseClientY(event);
 +            onVerticalMouseMove(y);
 +            break;
 +        }
 +
 +    }
 +
 +    private void onHorizontalMouseMove(int x) {
 +        int newX = origX + x - origMouseX;
 +        if (newX < 0) {
 +            newX = 0;
 +        }
 +        if (newX + getSplitterSize() > getOffsetWidth()) {
 +            newX = getOffsetWidth() - getSplitterSize();
 +        }
 +
 +        if (position.indexOf("%") > 0) {
 +            position = convertToPositionUnits(newX + "px");
 +        } else {
 +            // Reversed position
 +            if (positionReversed) {
 +                position = (getOffsetWidth() - newX - getSplitterSize()) + "px";
 +            } else {
 +                position = newX + "px";
 +            }
 +        }
 +
 +        if (origX != newX) {
 +            resized = true;
 +        }
 +
 +        // Reversed position
 +        if (positionReversed) {
 +            newX = getOffsetWidth() - newX - getSplitterSize();
 +        }
 +
 +        setSplitPosition(newX + "px");
 +    }
 +
 +    private void onVerticalMouseMove(int y) {
 +        int newY = origY + y - origMouseY;
 +        if (newY < 0) {
 +            newY = 0;
 +        }
 +
 +        if (newY + getSplitterSize() > getOffsetHeight()) {
 +            newY = getOffsetHeight() - getSplitterSize();
 +        }
 +
 +        if (position.indexOf("%") > 0) {
 +            position = convertToPositionUnits(newY + "px");
 +        } else {
 +            // Reversed position
 +            if (positionReversed) {
 +                position = (getOffsetHeight() - newY - getSplitterSize())
 +                        + "px";
 +            } else {
 +                position = newY + "px";
 +            }
 +        }
 +
 +        if (origY != newY) {
 +            resized = true;
 +        }
 +
 +        // Reversed position
 +        if (positionReversed) {
 +            newY = getOffsetHeight() - newY - getSplitterSize();
 +        }
 +
 +        setSplitPosition(newY + "px");
 +    }
 +
 +    public void onMouseUp(Event event) {
 +        DOM.releaseCapture(getElement());
 +        hideDraggingCurtain();
 +        resizing = false;
 +        if (!Util.isTouchEvent(event)) {
 +            onMouseMove(event);
 +        }
 +        fireEvent(new SplitterMoveEvent(this));
 +    }
 +
 +    public interface SplitterMoveHandler extends EventHandler {
 +        public void splitterMoved(SplitterMoveEvent event);
 +
 +        public static class SplitterMoveEvent extends
 +                GwtEvent<SplitterMoveHandler> {
 +
 +            public static final Type<SplitterMoveHandler> TYPE = new Type<SplitterMoveHandler>();
 +
 +            private Widget splitPanel;
 +
 +            public SplitterMoveEvent(Widget splitPanel) {
 +                this.splitPanel = splitPanel;
 +            }
 +
 +            @Override
 +            public com.google.gwt.event.shared.GwtEvent.Type<SplitterMoveHandler> getAssociatedType() {
 +                return TYPE;
 +            }
 +
 +            @Override
 +            protected void dispatch(SplitterMoveHandler handler) {
 +                handler.splitterMoved(this);
 +            }
 +
 +        }
 +    }
 +
 +    String getSplitterPosition() {
 +        return position;
 +    }
 +
 +    /**
 +     * Used in FF to avoid losing mouse capture when pointer is moved on an
 +     * iframe.
 +     */
 +    private void showDraggingCurtain() {
 +        if (!isDraggingCurtainRequired()) {
 +            return;
 +        }
 +        if (draggingCurtain == null) {
 +            draggingCurtain = DOM.createDiv();
 +            DOM.setStyleAttribute(draggingCurtain, "position", "absolute");
 +            DOM.setStyleAttribute(draggingCurtain, "top", "0px");
 +            DOM.setStyleAttribute(draggingCurtain, "left", "0px");
 +            DOM.setStyleAttribute(draggingCurtain, "width", "100%");
 +            DOM.setStyleAttribute(draggingCurtain, "height", "100%");
 +            DOM.setStyleAttribute(draggingCurtain, "zIndex", ""
 +                    + VOverlay.Z_INDEX);
 +
 +            DOM.appendChild(wrapper, draggingCurtain);
 +        }
 +    }
 +
 +    /**
 +     * A dragging curtain is required in Gecko and Webkit.
 +     * 
 +     * @return true if the browser requires a dragging curtain
 +     */
 +    private boolean isDraggingCurtainRequired() {
 +        return (BrowserInfo.get().isGecko() || BrowserInfo.get().isWebkit());
 +    }
 +
 +    /**
 +     * Hides dragging curtain
 +     */
 +    private void hideDraggingCurtain() {
 +        if (draggingCurtain != null) {
 +            DOM.removeChild(wrapper, draggingCurtain);
 +            draggingCurtain = null;
 +        }
 +    }
 +
 +    private int splitterSize = -1;
 +
 +    private int getSplitterSize() {
 +        if (splitterSize < 0) {
 +            if (isAttached()) {
 +                switch (orientation) {
 +                case ORIENTATION_HORIZONTAL:
 +                    splitterSize = DOM.getElementPropertyInt(splitter,
 +                            "offsetWidth");
 +                    break;
 +
 +                default:
 +                    splitterSize = DOM.getElementPropertyInt(splitter,
 +                            "offsetHeight");
 +                    break;
 +                }
 +            }
 +        }
 +        return splitterSize;
 +    }
 +
 +    void setStylenames() {
 +        final String splitterClass = CLASSNAME
 +                + (orientation == ORIENTATION_HORIZONTAL ? "-hsplitter"
 +                        : "-vsplitter");
 +        final String firstContainerClass = CLASSNAME + "-first-container";
 +        final String secondContainerClass = CLASSNAME + "-second-container";
 +        final String lockedSuffix = locked ? "-locked" : "";
 +
 +        splitter.setClassName(splitterClass + lockedSuffix);
 +        firstContainer.setClassName(firstContainerClass);
 +        secondContainer.setClassName(secondContainerClass);
 +
 +        for (String styleName : componentStyleNames) {
 +            splitter.addClassName(splitterClass + "-" + styleName
 +                    + lockedSuffix);
 +            firstContainer.addClassName(firstContainerClass + "-" + styleName);
 +            secondContainer
 +                    .addClassName(secondContainerClass + "-" + styleName);
 +        }
 +    }
 +
 +    public void setEnabled(boolean enabled) {
 +        this.enabled = enabled;
 +    }
 +
 +    public boolean isEnabled() {
 +        return enabled;
 +    }
 +
 +    /**
 +     * Ensures the panels are scrollable eg. after style name changes
 +     */
 +    void makeScrollable() {
 +        if (touchScrollHandler == null) {
 +            touchScrollHandler = TouchScrollDelegate.enableTouchScrolling(this);
 +        }
 +        touchScrollHandler.addElement(firstContainer);
 +        touchScrollHandler.addElement(secondContainer);
 +    }
 +}
Simple merge
Simple merge
index 66b5e23cda88f822b54968305d900e28f9140338,c1107061ed192eb00da695b65bd13859e99e69af..1bc76fff1e13acc7fcb43d44532ba7fecde26a07
@@@ -20,10 -24,12 +20,12 @@@ import com.vaadin.ui.AbstractField
  import com.vaadin.ui.MenuBar;
  import com.vaadin.ui.MenuBar.MenuItem;
  
 -public abstract class AbstractFieldTest<T extends AbstractField> extends
 +public abstract class AbstractFieldTest<T extends AbstractField<?>> extends
          AbstractComponentTest<T> implements ValueChangeListener,
 -        ReadOnlyStatusChangeListener, FocusListener, BlurListener {
 +        ReadOnlyStatusChangeListener {
  
+     private boolean sortValueChanges = true;
      @Override
      protected void createActions() {
          super.createActions();
index 47c97bbc21092d072174ef0f091c252ed7863c05,c8d4ee985854a244dac85f29ac2a2dba70e97088..6461d10277b13765dbf9570587a2bb81f27ade57
@@@ -45,17 -45,18 +45,19 @@@ public class PopupViewClickShortcut ext
          l.setCaption(caption);
          l.setWidth(null);
  
-         Button b = new Button("Submit " + caption, new Button.ClickListener() {
-             private int i = 5;
+         Button b = new Button("Submit " + caption + " (Ctrl+Alt+"
+                 + String.valueOf(Character.toChars(keyCode)) + ")",
+                 new Button.ClickListener() {
+                     private int i = 5;
  
-             @Override
-             public void buttonClick(ClickEvent event) {
-                 log.log("Submitted from "
-                         + event.getButton().getParent().getCaption());
-                 t.addItem(new String[] { "added " + i++ }, i);
-             }
-         });
-         b.setClickShortcut(keyCode, ModifierKey.ALT);
++                    @Override
+                     public void buttonClick(ClickEvent event) {
+                         log.log("Submitted from "
+                                 + event.getButton().getParent().getCaption());
+                         t.addItem(new String[] { "added " + i++ }, i);
+                     }
+                 });
+         b.setClickShortcut(keyCode, ModifierKey.CTRL, ModifierKey.ALT);
  
          l.addComponent(t);
          l.addComponent(b);
index a5a8f7d24b8f150b13efa8bb25a10fa898071c54,e06db94589ea38d4f985235d933a3af005917790..f34c12607a995706c6bceefdbcdb1cb655633cdd
@@@ -10,20 -8,16 +8,15 @@@ import com.vaadin.data.Container.ItemSe
  import com.vaadin.data.Item;
  import com.vaadin.data.Property;
  import com.vaadin.data.Property.ValueChangeEvent;
- import com.vaadin.data.util.sqlcontainer.AllTests;
- import com.vaadin.data.util.sqlcontainer.SQLContainer;
- import com.vaadin.data.util.sqlcontainer.connection.JDBCConnectionPool;
- import com.vaadin.data.util.sqlcontainer.connection.SimpleJDBCConnectionPool;
- import com.vaadin.data.util.sqlcontainer.query.TableQuery;
  import com.vaadin.ui.Button;
  import com.vaadin.ui.Button.ClickEvent;
 -import com.vaadin.ui.Button.ClickListener;
  import com.vaadin.ui.Form;
  import com.vaadin.ui.HorizontalSplitPanel;
 +import com.vaadin.ui.Root.LegacyWindow;
  import com.vaadin.ui.Table;
 -import com.vaadin.ui.Window;
  
 -public class CheckboxUpdateProblem extends Application implements
 -        Property.ValueChangeListener {
 +public class CheckboxUpdateProblem extends Application.LegacyApplication
 +        implements Property.ValueChangeListener {
      private final DatabaseHelper databaseHelper = new DatabaseHelper();
      private Table testList;
      private final HorizontalSplitPanel horizontalSplit = new HorizontalSplitPanel();
  
      }
  
-     private class DatabaseHelper {
-         private JDBCConnectionPool connectionPool = null;
-         private SQLContainer testContainer = null;
-         private static final String TABLENAME = "testtable";
-         public DatabaseHelper() {
-             initConnectionPool();
-             initDatabase();
-             initContainers();
-         }
-         private void initDatabase() {
-             try {
-                 Connection conn = connectionPool.reserveConnection();
-                 Statement statement = conn.createStatement();
-                 try {
-                     statement.execute("drop table " + TABLENAME);
-                 } catch (SQLException e) {
-                     // Will fail if table doesn't exist, which is OK.
-                     conn.rollback();
-                 }
-                 switch (AllTests.db) {
-                 case MYSQL:
-                     statement
-                             .execute("create table "
-                                     + TABLENAME
-                                     + " (id integer auto_increment not null, field1 varchar(100), field2 boolean, primary key(id))");
-                     break;
-                 case POSTGRESQL:
-                     statement
-                             .execute("create table "
-                                     + TABLENAME
-                                     + " (\"id\" serial primary key, \"field1\" varchar(100), \"field2\" boolean)");
-                     break;
-                 }
-                 statement.executeUpdate("insert into " + TABLENAME
-                         + " values(default, 'Kalle', 'true')");
-                 statement.close();
-                 conn.commit();
-                 connectionPool.releaseConnection(conn);
-             } catch (SQLException e) {
-                 e.printStackTrace();
-             }
-         }
-         private void initContainers() {
-             try {
-                 TableQuery q1 = new TableQuery(TABLENAME, connectionPool);
-                 q1.setVersionColumn("id");
-                 testContainer = new SQLContainer(q1);
-             } catch (SQLException e) {
-                 e.printStackTrace();
-             }
-         }
-         private void initConnectionPool() {
-             try {
-                 connectionPool = new SimpleJDBCConnectionPool(
-                         AllTests.dbDriver, AllTests.dbURL, AllTests.dbUser,
-                         AllTests.dbPwd, 2, 5);
-             } catch (SQLException e) {
-                 e.printStackTrace();
-             }
-         }
-         public SQLContainer getTestContainer() {
-             return testContainer;
-         }
-     }
 -}
 +}
index 0000000000000000000000000000000000000000,ed6d39bb6233b48c9f0ededba29e15b0efa056b2..b7d1b8c37e664ea4bd0602065fa67bb7fe9caf03
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,27 +1,27 @@@
 -import com.vaadin.ui.Window;
+ package com.vaadin.tests.containers.sqlcontainer;
+ import com.vaadin.Application;
+ import com.vaadin.ui.AbstractSelect.Filtering;
+ import com.vaadin.ui.ComboBox;
 -public class ComboBoxUpdateProblem extends Application {
++import com.vaadin.ui.Root;
+ /**
+  * See http://dev.vaadin.com/ticket/9155 .
+  */
 -        setMainWindow(new Window("Test window"));
++public class ComboBoxUpdateProblem extends Application.LegacyApplication {
+     private final DatabaseHelper databaseHelper = new DatabaseHelper();
+     @Override
+     public void init() {
++        setMainWindow(new Root.LegacyWindow("Test window"));
+         ComboBox combo = new ComboBox("Names",
+                 databaseHelper.getTestContainer());
+         combo.setItemCaptionPropertyId("FIELD1");
+         combo.setFilteringMode(Filtering.FILTERINGMODE_CONTAINS);
+         combo.setImmediate(true);
+         getMainWindow().addComponent(combo);
+     }
+ }