]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix for #7127 - Table selection breaks if ItemClickListener calls requestRepaint
authorJohannes Dahlström <johannes.dahlstrom@vaadin.com>
Wed, 7 Dec 2011 09:20:41 +0000 (09:20 +0000)
committerJohannes Dahlström <johannes.dahlstrom@vaadin.com>
Wed, 7 Dec 2011 09:20:41 +0000 (09:20 +0000)
svn changeset:22263/svn branch:6.7

src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java

index d5593486de599b02ad9765a6874a89697bb43395..f8bfc2c9adc65912f546323535f1e6fadc9e82ea 100644 (file)
@@ -56,6 +56,7 @@ import com.google.gwt.user.client.ui.Panel;
 import com.google.gwt.user.client.ui.RootPanel;
 import com.google.gwt.user.client.ui.UIObject;
 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.Container;
@@ -4852,44 +4853,44 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 }
             }
 
-            private void handleClickEvent(Event event, Element targetTdOrTr) {
-                if (client.hasEventListeners(VScrollTable.this,
+            /**
+             * If there are registered click listeners, sends a click event and
+             * returns true. Otherwise, does nothing and returns false.
+             * 
+             * @param event
+             * @param targetTdOrTr
+             * @param immediate
+             *            Whether the event is sent immediately
+             * @return Whether a click event was sent
+             */
+            private boolean handleClickEvent(Event event, Element targetTdOrTr,
+                    boolean immediate) {
+                if (!client.hasEventListeners(VScrollTable.this,
                         ITEM_CLICK_EVENT_ID)) {
-                    boolean doubleClick = (DOM.eventGetType(event) == Event.ONDBLCLICK);
-
-                    /* This row was clicked */
-                    client.updateVariable(paintableId, "clickedKey", ""
-                            + rowKey, false);
-
-                    if (getElement() == targetTdOrTr.getParentElement()) {
-                        /* A specific column was clicked */
-                        int childIndex = DOM.getChildIndex(getElement(),
-                                targetTdOrTr);
-                        String colKey = null;
-                        colKey = tHead.getHeaderCell(childIndex).getColKey();
-                        client.updateVariable(paintableId, "clickedColKey",
-                                colKey, false);
-                    }
-
-                    MouseEventDetails details = new MouseEventDetails(event);
+                    // Don't send an event if nobody is listening
+                    return false;
+                }
 
-                    boolean imm = true;
-                    if (immediate && event.getButton() == Event.BUTTON_LEFT
-                            && !doubleClick && isSelectable() && !isSelected()) {
-                        /*
-                         * A left click when the table is selectable and in
-                         * immediate mode on a row that is not currently
-                         * selected will cause a selection event to be fired
-                         * after this click event. By making the click event
-                         * non-immediate we avoid sending two separate messages
-                         * to the server.
-                         */
-                        imm = false;
-                    }
+                // This row was clicked
+                client.updateVariable(paintableId, "clickedKey", "" + rowKey,
+                        false);
 
-                    client.updateVariable(paintableId, "clickEvent",
-                            details.toString(), imm);
+                if (getElement() == targetTdOrTr.getParentElement()) {
+                    // A specific column was clicked
+                    int childIndex = DOM.getChildIndex(getElement(),
+                            targetTdOrTr);
+                    String colKey = null;
+                    colKey = tHead.getHeaderCell(childIndex).getColKey();
+                    client.updateVariable(paintableId, "clickedColKey", colKey,
+                            false);
                 }
+
+                MouseEventDetails details = new MouseEventDetails(event);
+
+                client.updateVariable(paintableId, "clickEvent",
+                        details.toString(), immediate);
+
+                return true;
             }
 
             private void handleTooltips(final Event event, Element target) {
@@ -4941,9 +4942,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                                 && (actionKeys != null || client
                                         .hasEventListeners(VScrollTable.this,
                                                 ITEM_CLICK_EVENT_ID))) {
-                            // Prevent browser context menu only if there are
-                            // action handlers or item click listeners
-                            // registered
+                            /*
+                             * Prevent browser context menu only if there are
+                             * action handlers or item click listeners
+                             * registered
+                             */
                             event.stopPropagation();
                             event.preventDefault();
                         }
@@ -4958,13 +4961,19 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                     switch (type) {
                     case Event.ONDBLCLICK:
                         if (targetCellOrRowFound) {
-                            handleClickEvent(event, targetTdOrTr);
+                            handleClickEvent(event, targetTdOrTr, immediate);
                         }
                         break;
                     case Event.ONMOUSEUP:
                         if (targetCellOrRowFound) {
                             mDown = false;
-                            handleClickEvent(event, targetTdOrTr);
+                            /*
+                             * Queue here, send at the same time as the
+                             * corresponding value change event - see #7127
+                             */
+                            boolean clickEventSent = handleClickEvent(event,
+                                    targetTdOrTr, false);
+
                             if (event.getButton() == Event.BUTTON_LEFT
                                     && isSelectable()) {
 
@@ -5053,7 +5062,16 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                                             .setPropertyJSO("onselectstart",
                                                     null);
                                 }
-                                sendSelectedRows();
+                                // Queue value change
+                                sendSelectedRows(false);
+                            }
+                            /*
+                             * Send queued click and value change events if any
+                             * If a click event is sent, send value change with
+                             * it regardless of the immediate flag, see #7127
+                             */
+                            if (immediate || clickEventSent) {
+                                client.sendPendingVariableChanges();
                             }
                         }
                         break;