Adding Column#set/getCellStyleNames() to specify style names to apply to individual cells of a CellTable/DataGrid.  Users can set a general style name to apply to the column, or override getCellStyleNames() to provide style names based on the row/cell value.

I added the methods to Column instead of creating a CellStyles class (similar to RowStyles) because users will most likely want to choose styles based on the Cell value.  If we provide one CellStyles for a CellTable, then it won't be parameterized to the Column type, making it difficult to get the cell value out of the row value.

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

Review by: rchandia@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10309 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java b/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
index 169d915..01e9179 100644
--- a/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
+++ b/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
@@ -1274,9 +1274,15 @@
           tdClasses += lastColumnStyle;
         }
 
+        // Add class names specific to the cell.
+        Context context = new Context(i, curColumn, getValueKey(value));
+        String cellStyles = column.getCellStyleNames(context, value);
+        if (cellStyles != null) {
+          tdClasses += " " + cellStyles;
+        }
+
         SafeHtmlBuilder cellBuilder = new SafeHtmlBuilder();
         if (value != null) {
-          Context context = new Context(i, curColumn, getValueKey(value));
           column.render(context, value, cellBuilder);
         }
 
diff --git a/user/src/com/google/gwt/user/cellview/client/Column.java b/user/src/com/google/gwt/user/cellview/client/Column.java
index 5a6f96c..e1490e6 100644
--- a/user/src/com/google/gwt/user/cellview/client/Column.java
+++ b/user/src/com/google/gwt/user/cellview/client/Column.java
@@ -41,6 +41,8 @@
    */
   private final Cell<C> cell;
 
+  private String cellStyleNames = null;
+
   /**
    * The {@link FieldUpdater} used for updating values in the column.
    */
@@ -64,20 +66,36 @@
    * 
    * @return a Cell
    */
+  @Override
   public Cell<C> getCell() {
     return cell;
   }
 
   /**
+   * Get extra style names that should be applied to a cell in this column.
+   * 
+   * @param context the cell context
+   * @param object the base object to be updated, or null if the row is empty
+   * @return the extra styles of the given row in a space-separated list, or
+   *         {@code null} if there are no extra styles for the cells in this
+   *         column
+   */
+  public String getCellStyleNames(Context context, T object) {
+    return cellStyleNames;
+  }
+
+  /**
    * Returns the {@link FieldUpdater} used for updating values in the column.
    * 
    * @return an instance of FieldUpdater<T, C>
    * @see #setFieldUpdater(FieldUpdater)
    */
+  @Override
   public FieldUpdater<T, C> getFieldUpdater() {
     return fieldUpdater;
   }
 
+  @Override
   public HorizontalAlignmentConstant getHorizontalAlignment() {
     return hAlign;
   }
@@ -85,8 +103,10 @@
   /**
    * Returns the column value from within the underlying data object.
    */
+  @Override
   public abstract C getValue(T object);
 
+  @Override
   public VerticalAlignmentConstant getVerticalAlignment() {
     return vAlign;
   }
@@ -108,15 +128,14 @@
    * @param object the base object to be updated
    * @param event the native browser event
    */
-  public void onBrowserEvent(Context context, Element elem, final T object,
-      NativeEvent event) {
+  public void onBrowserEvent(Context context, Element elem, final T object, NativeEvent event) {
     final int index = context.getIndex();
-    ValueUpdater<C> valueUpdater = (fieldUpdater == null) ? null
-        : new ValueUpdater<C>() {
-          public void update(C value) {
-            fieldUpdater.update(index, object, value);
-          }
-        };
+    ValueUpdater<C> valueUpdater = (fieldUpdater == null) ? null : new ValueUpdater<C>() {
+      @Override
+      public void update(C value) {
+        fieldUpdater.update(index, object, value);
+      }
+    };
     cell.onBrowserEvent(context, elem, getValue(object), event, valueUpdater);
   }
 
@@ -132,6 +151,21 @@
   }
 
   /**
+   * Set extra style names that should be applied to every cell.
+   * 
+   * <p>
+   * If you want to apply style names based on the row or cell value, override
+   * {@link #getCellStyleNames(Context, Object)} directly.
+   * </p>
+   * 
+   * @param styleNames the extra style names to applyin a space-separated list,
+   *          or {@code null} if there are no extra styles for this cell
+   */
+  public void setCellStyleNames(String styleNames) {
+    this.cellStyleNames = styleNames;
+  }
+
+  /**
    * Set the {@link FieldUpdater} used for updating values in the column.
    * 
    * @param fieldUpdater the field updater
@@ -149,6 +183,7 @@
    * rendered.
    * </p>
    */
+  @Override
   public void setHorizontalAlignment(HorizontalAlignmentConstant align) {
     this.hAlign = align;
   }
@@ -170,6 +205,7 @@
    * The new vertical alignment will apply the next time the table is rendered.
    * </p>
    */
+  @Override
   public void setVerticalAlignment(VerticalAlignmentConstant align) {
     this.vAlign = align;
   }
diff --git a/user/test/com/google/gwt/user/cellview/client/AbstractCellTableTestBase.java b/user/test/com/google/gwt/user/cellview/client/AbstractCellTableTestBase.java
index 185ff86..713c664 100644
--- a/user/test/com/google/gwt/user/cellview/client/AbstractCellTableTestBase.java
+++ b/user/test/com/google/gwt/user/cellview/client/AbstractCellTableTestBase.java
@@ -18,6 +18,7 @@
 import com.google.gwt.cell.client.AbstractCell;
 import com.google.gwt.cell.client.Cell;
 import com.google.gwt.cell.client.TextCell;
+import com.google.gwt.cell.client.Cell.Context;
 import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.NativeEvent;
 import com.google.gwt.dom.client.TableCellElement;
@@ -164,6 +165,43 @@
     RootPanel.get().remove(table);
   }
 
+  public void testCellStyles() {
+    T table = createAbstractHasData();
+
+    // A column that return a static cell style.
+    TextColumn<String> col0 = new TextColumn<String>() {
+      @Override
+      public String getValue(String object) {
+        return object;
+      }
+    };
+    col0.setCellStyleNames("col0");
+    table.addColumn(col0);
+
+    // A column that returns dynamic cell styles.
+    TextColumn<String> col1 = new TextColumn<String>() {
+      @Override
+      public String getCellStyleNames(Context context, String object) {
+        return object.replace(" ", "_");
+      }
+
+      @Override
+      public String getValue(String object) {
+        return object;
+      }
+    };
+    table.addColumn(col1);
+
+    // Populate the table.
+    table.setRowData(createData(0, 10));
+    table.flush();
+
+    assertTrue(getBodyElement(table, 1, 0).getClassName().contains(" col0"));
+    assertFalse(getBodyElement(table, 1, 0).getClassName().contains(" test_1"));
+    assertFalse(getBodyElement(table, 1, 1).getClassName().contains(" col0"));
+    assertTrue(getBodyElement(table, 1, 1).getClassName().contains(" test_1"));
+  }
+
   public void testGetColumnIndex() {
     T table = createAbstractHasData();
     Column<String, String> col0 = new IdentityColumn<String>(new TextCell());