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