From b0d7766a7228d9a746f1ae0e44894cd4cac5f404 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 25 Jul 2011 14:14:28 +0000 Subject: [PATCH] #5924 Link as generated table column does not present browser context menu on right click svn changeset:19927/svn branch:6.7 --- .../terminal/gwt/client/ui/VScrollTable.java | 21 ++- .../table/TableAndBrowserContextMenu.java | 150 ++++++++++++++++++ 2 files changed, 166 insertions(+), 5 deletions(-) create mode 100644 tests/src/com/vaadin/tests/components/table/TableAndBrowserContextMenu.java diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index ba076eb0ed..1226c5ae79 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -478,9 +478,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, top += Window.getScrollTop(); left += Window.getScrollLeft(); client.getContextMenu().showAt(this, left, top); + + // Only prevent browser context menu if there are action handlers + // registered + event.stopPropagation(); + event.preventDefault(); } - event.stopPropagation(); - event.preventDefault(); } /** @@ -4470,7 +4473,16 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, final Element targetTdOrTr = getEventTargetTdOrTr(event); if (type == Event.ONCONTEXTMENU) { showContextMenu(event); - event.stopPropagation(); + if (enabled + && (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 + event.stopPropagation(); + event.preventDefault(); + } return; } @@ -4811,14 +4823,13 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, public void showContextMenu(Event event) { if (enabled && actionKeys != null) { + // Show context menu if there are registered action handlers int left = Util.getTouchOrMouseClientX(event); int top = Util.getTouchOrMouseClientY(event); top += Window.getScrollTop(); left += Window.getScrollLeft(); client.getContextMenu().showAt(this, left, top); } - event.stopPropagation(); - event.preventDefault(); } /** diff --git a/tests/src/com/vaadin/tests/components/table/TableAndBrowserContextMenu.java b/tests/src/com/vaadin/tests/components/table/TableAndBrowserContextMenu.java new file mode 100644 index 0000000000..d1fce928d4 --- /dev/null +++ b/tests/src/com/vaadin/tests/components/table/TableAndBrowserContextMenu.java @@ -0,0 +1,150 @@ +package com.vaadin.tests.components.table; + +import com.vaadin.data.Item; +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.event.Action; +import com.vaadin.event.ItemClickEvent; +import com.vaadin.event.ItemClickEvent.ItemClickListener; +import com.vaadin.terminal.ExternalResource; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.Component; +import com.vaadin.ui.Link; +import com.vaadin.ui.Table; + +public class TableAndBrowserContextMenu extends TestBase implements + Action.Handler, ItemClickListener { + + private Table table; + private boolean actionHandlerHasActions = false; + + @Override + public void setup() { + CheckBox cb = new CheckBox("Item click listener"); + cb.setImmediate(true); + cb.addListener(new ValueChangeListener() { + + public void valueChange(ValueChangeEvent event) { + if (((Boolean) event.getProperty().getValue())) { + table.addListener(TableAndBrowserContextMenu.this); + } else { + table.removeListener(TableAndBrowserContextMenu.this); + } + + } + }); + addComponent(cb); + + CheckBox cbActionHandler = new CheckBox("Action handler"); + cbActionHandler.setImmediate(true); + cbActionHandler.addListener(new ValueChangeListener() { + + public void valueChange(ValueChangeEvent event) { + if (((Boolean) event.getProperty().getValue())) { + table.addActionHandler(TableAndBrowserContextMenu.this); + } else { + table.removeActionHandler(TableAndBrowserContextMenu.this); + } + + } + }); + addComponent(cbActionHandler); + + CheckBox cbActionHasActions = new CheckBox("Action handler has actions"); + cbActionHasActions.setImmediate(true); + cbActionHasActions.addListener(new ValueChangeListener() { + + public void valueChange(ValueChangeEvent event) { + actionHandlerHasActions = ((Boolean) event.getProperty() + .getValue()); + + // Workaround to ensure actions are repainted + removeComponent(table); + addComponent(table); + + } + }); + addComponent(cbActionHasActions); + + createTable(); + addComponent(table); + + } + + private void createTable() { + // Have a table with a numeric column + table = new Table("A table"); + table.addContainerProperty("Name", String.class, null); + table.addContainerProperty("Died At Age", Integer.class, null); + + // Add a generated column with a link to Google + table.addGeneratedColumn("Search", new Table.ColumnGenerator() { + public Component generateCell(Table source, Object itemId, + Object columnId) { + Item item = source.getItem(itemId); + String name = (String) item.getItemProperty("Name").getValue(); + return new Link("Google for " + name, new ExternalResource( + "http://www.google.co.uk/search?q=" + name)); + } + }); + + // Insert some data + Object people[][] = { { "Galileo", 77 }, { "Monnier", 83 }, + { "Vaisala", 79 }, { "Oterma", 86 } }; + + for (int i = 0; i < people.length; i++) { + table.addItem(people[i], i); + } + + // Calculate the average of the numeric column + double avgAge = 0; + for (int i = 0; i < people.length; i++) { + avgAge += (Integer) people[i][1]; + } + avgAge /= people.length; + + // Set the footers + table.setFooterVisible(true); + table.setColumnFooter("Name", "Average"); + table.setColumnFooter("Died At Age", String.valueOf(avgAge)); + + // Adjust the table height a bit + table.setPageLength(table.size() + 2); + + for (int i = 0; i < people.length; i++) { + Object[] person = people[i]; + String name = (String) person[0]; + addComponent(new Link("Google for " + name, new ExternalResource( + "http://www.google.co.uk/search?q=" + name))); + } + + } + + @Override + protected String getDescription() { + return "Table should only prevent the browser context menu when the right click is used for some Table specific operation. In practice these are either action handlers/context menu or item click listeners (right click). Note that item click listeners affects rows only, not the body."; + } + + @Override + protected Integer getTicketNumber() { + return 5924; + } + + public void itemClick(ItemClickEvent event) { + getMainWindow() + .showNotification("Click using " + event.getButtonName()); + } + + public Action[] getActions(Object target, Object sender) { + if (!actionHandlerHasActions) { + return null; + } + + return new Action[] { new Action("test") }; + } + + public void handleAction(Action action, Object sender, Object target) { + getMainWindow().showNotification("Action: " + action.getCaption()); + } +} \ No newline at end of file -- 2.39.5