Fixing a bug in HasDataPresenter where it does not pass the complete list of modified rows if a pending state is detecting while we are resolving the current state.  We were leaving off rows that were modified, as well as the keyboard selected rows.  By passing all of these rows to the recursive call to resolvePendingState(), we ensure that all modified rows are updated.

Review at http://gwt-code-reviews.appspot.com/1583805

Review by: devint@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10729 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/cellview/client/HasDataPresenter.java b/user/src/com/google/gwt/user/cellview/client/HasDataPresenter.java
index f129db5..0c1e01f 100644
--- a/user/src/com/google/gwt/user/cellview/client/HasDataPresenter.java
+++ b/user/src/com/google/gwt/user/cellview/client/HasDataPresenter.java
@@ -1056,7 +1056,7 @@
    * Resolve the pending state and push updates to the view.
    * 
    * @param modifiedRows the modified rows that need to be updated, or null if
-   *          none. The modified rows may be mutated.
+   *        none. The modified rows may be mutated.
    * @return true if the state changed, false if not
    */
   private boolean resolvePendingState(JsArrayInteger modifiedRows) {
@@ -1247,24 +1247,6 @@
       throw e;
     }
 
-    /*
-     * We called methods in user code that could modify the view, so early exit
-     * if there is a new pending state waiting to be resolved.
-     */
-    if (pendingState != null) {
-      isResolvingState = false;
-      // Do not reset pendingStateLoop, or we will not detect the infinite loop.
-
-      /*
-       * Try to resolve state again. If we are successful, then the modified
-       * rows will be redrawn. If we are not successful, then we still need to
-       * redraw the modified rows.
-       */
-      if (resolvePendingState(modifiedRows)) {
-        return true;
-      }
-    }
-
     // Add the replaced ranges as modified rows.
     boolean replacedEmptyRange = false;
     for (Range replacedRange : pending.replacedRanges) {
@@ -1285,6 +1267,32 @@
       modifiedRows.push(pending.keyboardSelectedRow);
     }
 
+    /*
+     * We called methods in user code that could modify the view, so early exit
+     * if there is a new pending state waiting to be resolved.
+     */
+    if (pendingState != null) {
+      isResolvingState = false;
+      // Do not reset pendingStateLoop, or we will not detect the infinite loop.
+
+      /*
+       * Add the keyboard selected rows to the modified rows so they can be
+       * re-rendered in the new state. These rows may already be added, but
+       * modifiedRows can contain duplicates.
+       */
+      modifiedRows.push(oldState.getKeyboardSelectedRow());
+      modifiedRows.push(pending.keyboardSelectedRow);
+
+      /*
+       * Try to resolve state again. If we are successful, then the modified
+       * rows will be redrawn. If we are not successful, then we still need to
+       * redraw the modified rows.
+       */
+      if (resolvePendingState(modifiedRows)) {
+        return true;
+      }
+    }
+
     // Calculate the modified ranges.
     List<Range> modifiedRanges = calculateModifiedRanges(modifiedRows, pageStart, pageEnd);
     Range range0 = modifiedRanges.size() > 0 ? modifiedRanges.get(0) : null;