Reviewers: skybrian,

Description:
Fixing a bug in Cell Widgets when using the BOUND_TO_SELECTION
KeyboardSelectionPolicy in which programmatically deselecting a value
makes the value unselectable until the user selects a different value.
For example, in the list A, B, C, if you programmatically deselect value
B, then value B cannot be selected unless the user selects value A or C
first.  We now correctly detect this case and update the state with a
null selected value, which allows us to detect the change when the user
selects value B.

Review by: skybr...@google.com

Please review this at http://gwt-code-reviews.appspot.com/1578805/

Affected files:
  M user/src/com/google/gwt/user/cellview/client/HasDataPresenter.java
  M user/test/com/google/gwt/user/cellview/client/HasDataPresenterTest.java


Index: user/src/com/google/gwt/user/cellview/client/HasDataPresenter.java
===================================================================
--- user/src/com/google/gwt/user/cellview/client/HasDataPresenter.java (revision 10721) +++ user/src/com/google/gwt/user/cellview/client/HasDataPresenter.java (working copy)
@@ -1163,7 +1163,7 @@
* or we will have a null selection event while we wait for asynchronous
          * data to load.
          */
-        if (newKey != null && !newKey.equals(oldKey)) {
+        if (newKey != null) {
// Check both values for selection before setting selection, or the
           // selection model may resolve state early.
           boolean oldValueWasSelected =
@@ -1171,15 +1171,20 @@
           boolean newValueWasSelected =
(newValue == null) ? false : selectionModel.isSelected(newValue);

-          // Deselect the old value.
-          if (oldValueWasSelected) {
-            selectionModel.setSelected(oldValue, false);
-          }
-
-          // Select the new value.
-          pending.selectedValue = newValue;
-          if (newValue != null && !newValueWasSelected) {
-            selectionModel.setSelected(newValue, true);
+          if (!newKey.equals(oldKey)) {
+            // Deselect the old value.
+            if (oldValueWasSelected) {
+              selectionModel.setSelected(oldValue, false);
+            }
+
+            // Select the new value.
+            pending.selectedValue = newValue;
+            if (newValue != null && !newValueWasSelected) {
+              selectionModel.setSelected(newValue, true);
+            }
+          } else if (!newValueWasSelected) {
+            // The value was programmatically deselected.
+            pending.selectedValue = null;
           }
         }
       }
Index: user/test/com/google/gwt/user/cellview/client/HasDataPresenterTest.java
===================================================================
--- user/test/com/google/gwt/user/cellview/client/HasDataPresenterTest.java (revision 10721) +++ user/test/com/google/gwt/user/cellview/client/HasDataPresenterTest.java (working copy)
@@ -630,6 +630,41 @@
   }

   /**
+   * Test that programmatically deselecting a row works.
+   */
+  public void testSetKeyboardSelectedRowBoundWithDeselect() {
+    HasData<String> listView = new MockHasData<String>();
+    MockView<String> view = new MockView<String>();
+ HasDataPresenter<String> presenter = new HasDataPresenter<String>(listView, view, 10, null); + presenter.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.BOUND_TO_SELECTION);
+    presenter.setVisibleRange(new Range(0, 10));
+    populatePresenter(presenter);
+    presenter.flush();
+
+    // Add a selection model.
+ MockSingleSelectionModel<String> model = new MockSingleSelectionModel<String>(null);
+    presenter.setSelectionModel(model);
+    presenter.flush();
+    assertEquals(null, model.getSelectedObject());
+
+    // Select an item.
+    presenter.setKeyboardSelectedRow(1, false, false);
+    presenter.flush();
+    assertTrue(model.isSelected("test 1"));
+
+    // Deselect the item.
+    model.setSelected("test 1", false);
+    assertFalse(model.isSelected("test 1"));
+    presenter.flush();
+    assertEquals(1, presenter.getKeyboardSelectedRow());
+
+    // Reselect the item.
+    presenter.setKeyboardSelectedRow(1, false, false);
+    presenter.flush();
+    assertTrue(model.isSelected("test 1"));
+  }
+
+  /**
* Test that we only get one selection event when keyboard selection changes.
    */
   public void testSetKeyboardSelectedRowFiresOneSelectionEvent() {


--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to