Introduce a new method onPreviewColumnSortEvent to Header. An AbstractCellTable checks this method before firing column sort event and will not fire the event if the method returns false. This gives users an option to disable column sort if the header cell actually consume the click event (e.g., a tooltip), and to disable column sort for header/footer sections.

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

Review by: jlabanca@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10791 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 58dbc9d..fade895 100644
--- a/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
+++ b/user/src/com/google/gwt/user/cellview/client/AbstractCellTable.java
@@ -1806,21 +1806,32 @@
       headerParent = isHeader ? headerParent : footerParent;
       Element columnParent = isHeader ? headerColumnParent : footerColumnParent;
 
+      boolean shouldSortColumn = true;
       // Fire the event to the header.
       if (headerParent != null) {
         Header<?> header =
             isHeader ? headerBuilder.getHeader(headerParent) : footerBuilder
                 .getHeader(footerParent);
-        if (header != null && cellConsumesEventType(header.getCell(), eventType)) {
+
+        if (header != null) {
           int headerIndex = isHeader ? headerBuilder.getRowIndex(targetTableRow) :
               footerBuilder.getRowIndex(targetTableRow);
           Context context = new Context(headerIndex, col, header.getKey());
-          header.onBrowserEvent(context, headerParent, event);
+
+          if (cellConsumesEventType(header.getCell(), eventType)) {          
+            header.onBrowserEvent(context, headerParent, event);
+          }
+
+          if (isClick) {
+            // Preview the event, and possibily disable the column sort event. The event preview is
+            // forced even if the header cell does not consume click event
+            shouldSortColumn = header.onPreviewColumnSortEvent(context, headerParent, event);
+          }
         }
       }
 
       // Sort the header.
-      if (isClick && columnParent != null) {
+      if (isClick && shouldSortColumn && columnParent != null) {
         Column<T, ?> column =
             isHeader ? headerBuilder.getColumn(columnParent) : footerBuilder
                 .getColumn(columnParent);
diff --git a/user/src/com/google/gwt/user/cellview/client/Header.java b/user/src/com/google/gwt/user/cellview/client/Header.java
index 5123461..ad8b95b 100644
--- a/user/src/com/google/gwt/user/cellview/client/Header.java
+++ b/user/src/com/google/gwt/user/cellview/client/Header.java
@@ -93,6 +93,25 @@
   }
 
   /**
+   * Preview a browser event that may trigger a column sort event. Return true if the
+   * {@link CellTable} should proceed with sorting the column. Subclasses can override this method
+   * to disable column sort for some click events, or particular header/footer sections.
+   * <p>
+   * This method will be invoked even if the header's cell does not consume a click event.
+   * </p>
+   * 
+   * @param context the context of the header
+   * @param elem the parent Element
+   * @param event the native browser event
+   * @return true if the {@link CellTable} should continue respond to the event (i.e., if this is
+   *         a click event on a sortable column's header, fire {@link ColumnSortEvent}). False if
+   *         the {@link CellTable} should stop respond to the event. 
+   */
+  public boolean onPreviewColumnSortEvent(Context context, Element elem, NativeEvent event) {
+    return true;
+  }
+
+  /**
    * Render the header.
    * 
    * @param context the context of the header