Adding a BlacklistEventTranslator and WhitelistEventTranslator to DefaultSelectionEventManager to make it easy to deny/allow selection for specific columns in a CellTable. This is useful when you have a Cell that responds to events, such as a button or link, and should not participate in Selection.
Review at http://gwt-code-reviews.appspot.com/1368804
Review by: sbrubaker@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9788 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/cellview/client/AbstractHasData.java b/user/src/com/google/gwt/user/cellview/client/AbstractHasData.java
index 6c94271..00de218 100644
--- a/user/src/com/google/gwt/user/cellview/client/AbstractHasData.java
+++ b/user/src/com/google/gwt/user/cellview/client/AbstractHasData.java
@@ -598,6 +598,24 @@
presenter.setRowData(start, values);
}
+ /**
+ * Set the {@link SelectionModel} used by this {@link HasData}.
+ *
+ * <p>
+ * By default, selection occurs when the user clicks on a Cell or presses the
+ * spacebar. If you need finer control over selection, you can specify a
+ * {@link DefaultSelectionEventManager} using
+ * {@link #setSelectionModel(SelectionModel, com.google.gwt.view.client.CellPreviewEvent.Handler)}.
+ * {@link DefaultSelectionEventManager} provides some default
+ * implementations to handle checkbox based selection, as well as a blacklist
+ * or whitelist of columns to prevent or allow selection.
+ * </p>
+ *
+ * @param selectionModel the {@link SelectionModel}
+ * @see #setSelectionModel(SelectionModel,
+ * com.google.gwt.view.client.CellPreviewEvent.Handler)
+ * @see #getSelectionModel()
+ */
public void setSelectionModel(SelectionModel<? super T> selectionModel) {
presenter.setSelectionModel(selectionModel);
}
diff --git a/user/src/com/google/gwt/view/client/DefaultSelectionEventManager.java b/user/src/com/google/gwt/view/client/DefaultSelectionEventManager.java
index 22b40cc..5651fe4 100644
--- a/user/src/com/google/gwt/view/client/DefaultSelectionEventManager.java
+++ b/user/src/com/google/gwt/view/client/DefaultSelectionEventManager.java
@@ -20,7 +20,9 @@
import com.google.gwt.dom.client.NativeEvent;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* An implementation of {@link CellPreviewEvent.Handler} that adds selection
@@ -39,6 +41,69 @@
CellPreviewEvent.Handler<T> {
/**
+ * An event translator that disables selection for the specified blacklisted
+ * columns.
+ *
+ * @param <T> the data type
+ */
+ public static class BlacklistEventTranslator<T> implements EventTranslator<T> {
+ private final Set<Integer> blacklist = new HashSet<Integer>();
+
+ /**
+ * Construct a new {@link BlacklistEventTranslator}.
+ *
+ * @param blacklistedColumns the columns to blacklist
+ */
+ public BlacklistEventTranslator(int... blacklistedColumns) {
+ if (blacklistedColumns != null) {
+ for (int i : blacklistedColumns) {
+ setColumnBlacklisted(i, true);
+ }
+ }
+ }
+
+ /**
+ * Clear all columns from the blacklist.
+ */
+ public void clearBlacklist() {
+ blacklist.clear();
+ }
+
+ public boolean clearCurrentSelection(CellPreviewEvent<T> event) {
+ return false;
+ }
+
+ /**
+ * Check if the specified column is blacklisted.
+ *
+ * @param index the column index
+ * @return true if blacklisted, false if not
+ */
+ public boolean isColumnBlacklisted(int index) {
+ return blacklist.contains(index);
+ }
+
+ /**
+ * Set whether or not the specified column in blacklisted.
+ *
+ * @param index the column index
+ * @param isBlacklisted true to blacklist, false to allow selection
+ */
+ public void setColumnBlacklisted(int index, boolean isBlacklisted) {
+ if (isBlacklisted) {
+ blacklist.add(index);
+ } else {
+ blacklist.remove(index);
+ }
+ }
+
+ public SelectAction translateSelectionEvent(CellPreviewEvent<T> event) {
+ return isColumnBlacklisted(event.getColumn()) ? SelectAction.IGNORE
+ : SelectAction.DEFAULT;
+ }
+ }
+
+ /**
* Implementation of {@link EventTranslator} that only triggers selection when
* any checkbox is selected.
*
@@ -133,6 +198,83 @@
}
/**
+ * An event translator that allows selection only for the specified
+ * whitelisted columns.
+ *
+ * @param <T> the data type
+ */
+ public static class WhitelistEventTranslator<T> implements EventTranslator<T> {
+ private final Set<Integer> whitelist = new HashSet<Integer>();
+
+ /**
+ * Construct a new {@link WhitelistEventTranslator}.
+ *
+ * @param whitelistedColumns the columns to whitelist
+ */
+ public WhitelistEventTranslator(int... whitelistedColumns) {
+ if (whitelistedColumns != null) {
+ for (int i : whitelistedColumns) {
+ setColumnWhitelisted(i, true);
+ }
+ }
+ }
+
+ public boolean clearCurrentSelection(CellPreviewEvent<T> event) {
+ return false;
+ }
+
+ /**
+ * Clear all columns from the whitelist.
+ */
+ public void clearWhitelist() {
+ whitelist.clear();
+ }
+
+ /**
+ * Check if the specified column is whitelisted.
+ *
+ * @param index the column index
+ * @return true if whitelisted, false if not
+ */
+ public boolean isColumnWhitelisted(int index) {
+ return whitelist.contains(index);
+ }
+
+ /**
+ * Set whether or not the specified column in whitelisted.
+ *
+ * @param index the column index
+ * @param isWhitelisted true to whitelist, false to allow disallow selection
+ */
+ public void setColumnWhitelisted(int index, boolean isWhitelisted) {
+ if (isWhitelisted) {
+ whitelist.add(index);
+ } else {
+ whitelist.remove(index);
+ }
+ }
+
+ public SelectAction translateSelectionEvent(CellPreviewEvent<T> event) {
+ return isColumnWhitelisted(event.getColumn()) ? SelectAction.DEFAULT
+ : SelectAction.IGNORE;
+ }
+ }
+
+ /**
+ * Construct a new {@link DefaultSelectionEventManager} that ignores selection
+ * for the columns in the specified blacklist.
+ *
+ * @param <T> the data type of the display
+ * @param blacklistedColumns the columns to include in the blacklist
+ * @return a {@link DefaultSelectionEventManager} instance
+ */
+ public static <T> DefaultSelectionEventManager<T> createBlacklistManager(
+ int... blacklistedColumns) {
+ return new DefaultSelectionEventManager<T>(new BlacklistEventTranslator<T>(
+ blacklistedColumns));
+ }
+
+ /**
* Construct a new {@link DefaultSelectionEventManager} that triggers
* selection when any checkbox in any column is clicked.
*
@@ -183,6 +325,20 @@
}
/**
+ * Construct a new {@link DefaultSelectionEventManager} that allows selection
+ * only for the columns in the specified whitelist.
+ *
+ * @param <T> the data type of the display
+ * @param whitelistedColumns the columns to include in the whitelist
+ * @return a {@link DefaultSelectionEventManager} instance
+ */
+ public static <T> DefaultSelectionEventManager<T> createWhitelistManager(
+ int... whitelistedColumns) {
+ return new DefaultSelectionEventManager<T>(new WhitelistEventTranslator<T>(
+ whitelistedColumns));
+ }
+
+ /**
* The last {@link HasData} that was handled.
*/
private HasData<T> lastDisplay;
diff --git a/user/test/com/google/gwt/view/client/DefaultSelectionEventManagerTest.java b/user/test/com/google/gwt/view/client/DefaultSelectionEventManagerTest.java
index c1cec44..9369a01 100644
--- a/user/test/com/google/gwt/view/client/DefaultSelectionEventManagerTest.java
+++ b/user/test/com/google/gwt/view/client/DefaultSelectionEventManagerTest.java
@@ -19,7 +19,9 @@
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.view.client.DefaultSelectionEventManager.BlacklistEventTranslator;
import com.google.gwt.view.client.DefaultSelectionEventManager.SelectAction;
+import com.google.gwt.view.client.DefaultSelectionEventManager.WhitelistEventTranslator;
import java.util.ArrayList;
import java.util.List;
@@ -44,6 +46,29 @@
return "com.google.gwt.view.View";
}
+ public void testBlacklistEventTranslator() {
+ BlacklistEventTranslator<String> translator = new BlacklistEventTranslator<String>(
+ 1, 3);
+ assertTrue(translator.isColumnBlacklisted(1));
+ assertFalse(translator.isColumnBlacklisted(2));
+ assertTrue(translator.isColumnBlacklisted(3));
+
+ translator.setColumnBlacklisted(2, true);
+ assertTrue(translator.isColumnBlacklisted(1));
+ assertTrue(translator.isColumnBlacklisted(2));
+ assertTrue(translator.isColumnBlacklisted(3));
+
+ translator.setColumnBlacklisted(2, false);
+ assertTrue(translator.isColumnBlacklisted(1));
+ assertFalse(translator.isColumnBlacklisted(2));
+ assertTrue(translator.isColumnBlacklisted(3));
+
+ translator.clearBlacklist();
+ assertFalse(translator.isColumnBlacklisted(1));
+ assertFalse(translator.isColumnBlacklisted(2));
+ assertFalse(translator.isColumnBlacklisted(3));
+ }
+
public void testClearSelection() {
MultiSelectionModel<String> model = new MultiSelectionModel<String>();
model.setSelected("foo", true);
@@ -384,6 +409,29 @@
assertSelected(model, "test 1");
}
+ public void testWhitelistEventTranslator() {
+ WhitelistEventTranslator<String> translator = new WhitelistEventTranslator<String>(
+ 1, 3);
+ assertTrue(translator.isColumnWhitelisted(1));
+ assertFalse(translator.isColumnWhitelisted(2));
+ assertTrue(translator.isColumnWhitelisted(3));
+
+ translator.setColumnWhitelisted(2, true);
+ assertTrue(translator.isColumnWhitelisted(1));
+ assertTrue(translator.isColumnWhitelisted(2));
+ assertTrue(translator.isColumnWhitelisted(3));
+
+ translator.setColumnWhitelisted(2, false);
+ assertTrue(translator.isColumnWhitelisted(1));
+ assertFalse(translator.isColumnWhitelisted(2));
+ assertTrue(translator.isColumnWhitelisted(3));
+
+ translator.clearWhitelist();
+ assertFalse(translator.isColumnWhitelisted(1));
+ assertFalse(translator.isColumnWhitelisted(2));
+ assertFalse(translator.isColumnWhitelisted(3));
+ }
+
/**
* Assert that the expected values are selected in the specified
* {@link MultiSelectionModel}.