From 98976f6d1a7111e26f164f6fba03b23057d4a65f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Johannes=20Dahlstr=C3=B6m?= Date: Wed, 7 Dec 2011 09:20:41 +0000 Subject: [PATCH] Fix for #7127 - Table selection breaks if ItemClickListener calls requestRepaint svn changeset:22263/svn branch:6.7 --- .../terminal/gwt/client/ui/VScrollTable.java | 98 +++++++++++-------- 1 file changed, 58 insertions(+), 40 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index d5593486de..f8bfc2c9ad 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -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; -- 2.39.5