This patch allow empty row data lists that start on the pageStart to pass through the AbstractListViewAdapter and HasDataPresenter down to the HasData implementation (such as CellList).  This ensures that Cell Widgets clear the view when the row count goes to 0.  Before this change, setting the rowCount to zero would redraw with the empty list, but the empty list was considered "out of range."
http://code.google.com/p/google-web-toolkit/issues/detail?id=5149

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

Review by: rice@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@8527 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 2100f0b..92deeb4 100644
--- a/user/src/com/google/gwt/user/cellview/client/HasDataPresenter.java
+++ b/user/src/com/google/gwt/user/cellview/client/HasDataPresenter.java
@@ -381,8 +381,9 @@
     int pageEnd = pageStart + pageSize;
     int boundedStart = Math.max(start, pageStart);
     int boundedEnd = Math.min(valuesEnd, pageEnd);
-    if (boundedStart >= boundedEnd) {
+    if (start != pageStart && boundedStart >= boundedEnd) {
       // The data is out of range for the current page.
+      // Intentionally allow empty lists that start on the page start.
       return;
     }
 
diff --git a/user/src/com/google/gwt/view/client/AbstractListViewAdapter.java b/user/src/com/google/gwt/view/client/AbstractListViewAdapter.java
index 9318821..90b8f27 100644
--- a/user/src/com/google/gwt/view/client/AbstractListViewAdapter.java
+++ b/user/src/com/google/gwt/view/client/AbstractListViewAdapter.java
@@ -207,8 +207,9 @@
     int curStart = range.getStart();
     int curLength = range.getLength();
     int curEnd = curStart + curLength;
-    if (curStart < end && curEnd > start) {
+    if (start == curStart || (curStart < end && curEnd > start)) {
       // Fire the handler with the data that is in the range.
+      // Allow an empty list that starts on the page start.
       int realStart = curStart < start ? start : curStart;
       int realEnd = curEnd > end ? end : curEnd;
       int realLength = realEnd - realStart;
diff --git a/user/src/com/google/gwt/view/client/ListViewAdapter.java b/user/src/com/google/gwt/view/client/ListViewAdapter.java
index 3f0ac0c..9ddbc1a 100644
--- a/user/src/com/google/gwt/view/client/ListViewAdapter.java
+++ b/user/src/com/google/gwt/view/client/ListViewAdapter.java
@@ -489,6 +489,10 @@
 
   @Override
   protected void onRangeChanged(HasData<T> view) {
-    updateViewData(view, 0, listWrapper.size(), listWrapper);
+    int size = listWrapper.size();
+    if (size > 0) {
+      // Do not push data if the data set is empty.
+      updateViewData(view, 0, size, listWrapper);
+    }
   }
 }
diff --git a/user/test/com/google/gwt/user/cellview/client/HasDataPresenterTest.java b/user/test/com/google/gwt/user/cellview/client/HasDataPresenterTest.java
index b865773..cd4335c 100644
--- a/user/test/com/google/gwt/user/cellview/client/HasDataPresenterTest.java
+++ b/user/test/com/google/gwt/user/cellview/client/HasDataPresenterTest.java
@@ -509,6 +509,27 @@
     view.assertLoadingState(LoadingState.LOADED);
   }
 
+  /**
+   * Setting an empty list that starts on the page start should pass through to
+   * the view.
+   */
+  public void testSetRowValuesEmptySet() {
+    HasData<String> listView = new MockHasData<String>();
+    MockView<String> view = new MockView<String>();
+    HasDataPresenter<String> presenter = new HasDataPresenter<String>(
+        listView, view, 10);
+
+    // Set the initial data size.
+    presenter.setRowCount(10, true);
+    view.assertLoadingState(LoadingState.LOADING);
+
+    // Set an empty list of row values.
+    presenter.setRowValues(0, createData(0, 0));
+    view.assertLoadingState(LoadingState.LOADING);
+    view.assertReplaceAllChildrenCalled(true);
+    view.assertReplaceChildrenCalled(false);
+  }
+
   public void testSetRowValuesOutsideRange() {
     HasData<String> listView = new MockHasData<String>();
     MockView<String> view = new MockView<String>();
diff --git a/user/test/com/google/gwt/view/client/AbstractListViewAdapterTest.java b/user/test/com/google/gwt/view/client/AbstractListViewAdapterTest.java
index 7840434..a1b5845 100644
--- a/user/test/com/google/gwt/view/client/AbstractListViewAdapterTest.java
+++ b/user/test/com/google/gwt/view/client/AbstractListViewAdapterTest.java
@@ -217,6 +217,15 @@
       view.clearLastRowValuesAndRange();
     }
 
+    // Empty data list starting at page start.
+    {
+      List<String> values = createData(10, 0);
+      adapter.updateViewData(10, 0, values);
+      assertEquals(values, view.getLastRowValues());
+      assertEquals(new Range(10, 0), view.getLastRowValuesRange());
+      view.clearLastRowValuesAndRange();
+    }
+
     // Data before range.
     {
       List<String> values = createData(5, 5);
diff --git a/user/test/com/google/gwt/view/client/ListViewAdapterTest.java b/user/test/com/google/gwt/view/client/ListViewAdapterTest.java
index e4dd016..8242e3b 100644
--- a/user/test/com/google/gwt/view/client/ListViewAdapterTest.java
+++ b/user/test/com/google/gwt/view/client/ListViewAdapterTest.java
@@ -460,9 +460,9 @@
     List<String> replace = new ArrayList<String>();
     adapter.setList(replace);
     assertEquals(0, view.getRowCount());
-    // An empty set should NOT set the row values.
-    assertEquals(null, view.getLastRowValues());
-    assertEquals(null, view.getLastRowValuesRange());
+    // An empty set should set the row values.
+    assertEquals(replace, view.getLastRowValues());
+    assertEquals(new Range(0, 0), view.getLastRowValuesRange());
   }
 
   @Override