summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/com/vaadin/client/renderers/ClickableRenderer.java5
-rw-r--r--client/src/com/vaadin/client/widget/grid/EventCellReference.java62
-rw-r--r--client/src/com/vaadin/client/widgets/Grid.java29
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientContextMenuEventTest.java67
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java44
5 files changed, 201 insertions, 6 deletions
diff --git a/client/src/com/vaadin/client/renderers/ClickableRenderer.java b/client/src/com/vaadin/client/renderers/ClickableRenderer.java
index f5368d31c9..83059f8f01 100644
--- a/client/src/com/vaadin/client/renderers/ClickableRenderer.java
+++ b/client/src/com/vaadin/client/renderers/ClickableRenderer.java
@@ -33,6 +33,7 @@ import com.vaadin.client.widget.grid.CellReference;
import com.vaadin.client.widget.grid.EventCellReference;
import com.vaadin.client.widgets.Escalator;
import com.vaadin.client.widgets.Grid;
+import com.vaadin.client.widgets.Grid.Section;
/**
* An abstract superclass for renderers that render clickable widgets. Click
@@ -152,7 +153,9 @@ public abstract class ClickableRenderer<T, W extends Widget> extends
Cell cell = container.getCell(e);
EventCellReference<T> cellReference = new EventCellReference<T>(
grid);
- cellReference.set(cell);
+ // FIXME: Section is currently always body. Might be useful for the
+ // future to have an actual check.
+ cellReference.set(cell, Section.BODY);
return cellReference;
}
diff --git a/client/src/com/vaadin/client/widget/grid/EventCellReference.java b/client/src/com/vaadin/client/widget/grid/EventCellReference.java
index 7ca1d5de75..98878339d1 100644
--- a/client/src/com/vaadin/client/widget/grid/EventCellReference.java
+++ b/client/src/com/vaadin/client/widget/grid/EventCellReference.java
@@ -19,6 +19,7 @@ import com.google.gwt.dom.client.TableCellElement;
import com.vaadin.client.widget.escalator.Cell;
import com.vaadin.client.widgets.Grid;
import com.vaadin.client.widgets.Grid.Column;
+import com.vaadin.client.widgets.Grid.Section;
/**
* A data class which contains information which identifies a cell being the
@@ -33,12 +34,11 @@ import com.vaadin.client.widgets.Grid.Column;
*/
public class EventCellReference<T> extends CellReference<T> {
- private Grid<T> grid;
+ private Section section;
private TableCellElement element;
public EventCellReference(Grid<T> grid) {
super(new RowReference<T>(grid));
- this.grid = grid;
}
/**
@@ -47,22 +47,76 @@ public class EventCellReference<T> extends CellReference<T> {
* @param targetCell
* cell to point to
*/
- public void set(Cell targetCell) {
+ public void set(Cell targetCell, Section section) {
+ Grid<T> grid = getGrid();
int row = targetCell.getRow();
int columnIndexDOM = targetCell.getColumn();
Column<?, T> column = grid.getVisibleColumns().get(columnIndexDOM);
+ // Row objects only make sense for body section of Grid.
+ T rowObject;
+ if (section == Section.BODY) {
+ rowObject = grid.getDataSource().getRow(row);
+ } else {
+ rowObject = null;
+ }
+
// At least for now we don't need to have the actual TableRowElement
// available.
- getRowReference().set(row, grid.getDataSource().getRow(row), null);
+ getRowReference().set(row, rowObject, null);
+
int columnIndex = grid.getColumns().indexOf(column);
set(columnIndexDOM, columnIndex, column);
this.element = targetCell.getElement();
+ this.section = section;
}
@Override
public TableCellElement getElement() {
return element;
}
+
+ /**
+ * Is the cell reference for a cell in the header of the Grid.
+ *
+ * @since
+ * @return <code>true</true> if referenced cell is in the header,
+ * <code>false</code> if not
+ */
+ public boolean isHeader() {
+ return section == Section.HEADER;
+ }
+
+ /**
+ * Is the cell reference for a cell in the body of the Grid.
+ *
+ * @since
+ * @return <code>true</true> if referenced cell is in the body,
+ * <code>false</code> if not
+ */
+ public boolean isBody() {
+ return section == Section.BODY;
+ }
+
+ /**
+ * Is the cell reference for a cell in the footer of the Grid.
+ *
+ * @since
+ * @return <code>true</true> if referenced cell is in the footer,
+ * <code>false</code> if not
+ */
+ public boolean isFooter() {
+ return section == Section.FOOTER;
+ }
+
+ /**
+ * Gets the Grid section where the referenced cell is.
+ *
+ * @since
+ * @return grid section
+ */
+ public Section getSection() {
+ return section;
+ }
}
diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java
index 50bc778736..f1edefc8ba 100644
--- a/client/src/com/vaadin/client/widgets/Grid.java
+++ b/client/src/com/vaadin/client/widgets/Grid.java
@@ -6202,7 +6202,7 @@ public class Grid<T> extends ResizeComposite implements
assert cell != null : "received " + eventType
+ "-event with a null cell target";
- eventCell.set(cell);
+ eventCell.set(cell, getSectionFromContainer(container));
// Editor can steal focus from Grid and is still handled
if (handleEditorEvent(event, container)) {
@@ -6237,6 +6237,20 @@ public class Grid<T> extends ResizeComposite implements
}
}
+ private Section getSectionFromContainer(RowContainer container) {
+ assert container != null : "RowContainer should not be null";
+
+ if (container == escalator.getBody()) {
+ return Section.BODY;
+ } else if (container == escalator.getFooter()) {
+ return Section.FOOTER;
+ } else if (container == escalator.getHeader()) {
+ return Section.HEADER;
+ }
+ assert false : "RowContainer was not header, footer or body.";
+ return null;
+ }
+
private boolean isOrContainsInSpacer(Node node) {
Node n = node;
while (n != null && n != getElement()) {
@@ -7780,4 +7794,17 @@ public class Grid<T> extends ResizeComposite implements
sidebar.close();
}
}
+
+ /**
+ * Returns the {@link EventCellReference} for the latest event fired from
+ * this Grid.
+ * <p>
+ * Note: This cell reference will be updated when firing the next event.
+ *
+ * @since
+ * @return event cell reference
+ */
+ public EventCellReference<T> getEventCell() {
+ return eventCell;
+ }
}
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientContextMenuEventTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientContextMenuEventTest.java
new file mode 100644
index 0000000000..b7242c87be
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientContextMenuEventTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.tests.components.grid.basicfeatures.client;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest;
+
+public class GridClientContextMenuEventTest extends GridBasicClientFeaturesTest {
+
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ // PhantomJS doesn't support context click..
+ return getBrowsersExcludingPhantomJS();
+ }
+
+ @Test
+ public void testContextMenuEventIsHandledCorrectly() {
+ setDebug(true);
+ openTestURL();
+
+ selectMenuPath("Component", "Internals", "Listeners",
+ "Add context menu listener");
+
+ openDebugLogTab();
+ clearDebugMessages();
+
+ new Actions(getDriver())
+ .moveToElement(getGridElement().getCell(0, 0), 5, 5)
+ .contextClick().perform();
+
+ assertTrue(
+ "Debug log was not visible",
+ isElementPresent(By
+ .xpath("//span[text() = 'Prevented opening a context menu in grid body']")));
+
+ new Actions(getDriver())
+ .moveToElement(getGridElement().getHeaderCell(0, 0), 5, 5)
+ .contextClick().perform();
+
+ assertTrue(
+ "Debug log was not visible",
+ isElementPresent(By
+ .xpath("//span[text() = 'Prevented opening a context menu in grid header']")));
+
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
index 81f000c44e..12c2443c01 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
@@ -28,7 +28,10 @@ import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.ContextMenuEvent;
+import com.google.gwt.event.dom.client.ContextMenuHandler;
import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
@@ -52,6 +55,7 @@ import com.vaadin.client.widget.grid.CellReference;
import com.vaadin.client.widget.grid.CellStyleGenerator;
import com.vaadin.client.widget.grid.DetailsGenerator;
import com.vaadin.client.widget.grid.EditorHandler;
+import com.vaadin.client.widget.grid.EventCellReference;
import com.vaadin.client.widget.grid.RendererCellReference;
import com.vaadin.client.widget.grid.RowReference;
import com.vaadin.client.widget.grid.RowStyleGenerator;
@@ -521,6 +525,46 @@ public class GridBasicClientFeaturesWidget extends
.addColumnVisibilityChangeHandler(handler);
}
}, listenersPath);
+ addMenuCommand("Add context menu listener", new ScheduledCommand() {
+
+ HandlerRegistration handler = null;
+ ContextMenuHandler contextMenuHandler = new ContextMenuHandler() {
+
+ @Override
+ public void onContextMenu(ContextMenuEvent event) {
+ event.preventDefault();
+ final String location;
+ EventCellReference<?> cellRef = grid
+ .getEventCell();
+ if (cellRef.isHeader()) {
+ location = "header";
+ } else if (cellRef.isBody()) {
+ location = "body";
+ } else if (cellRef.isFooter()) {
+ location = "footer";
+ } else {
+ location = "somewhere";
+ }
+
+ getLogger().info(
+ "Prevented opening a context menu in grid "
+ + location);
+ }
+ };
+
+ @Override
+ public void execute() {
+ if (handler != null) {
+ grid.unsinkEvents(Event.ONCONTEXTMENU);
+ handler.removeHandler();
+ } else {
+ grid.sinkEvents(Event.ONCONTEXTMENU);
+ handler = grid.addDomHandler(contextMenuHandler,
+ ContextMenuEvent.getType());
+ }
+ }
+
+ }, listenersPath);
}
private void createStateMenu() {