Vojtech Szocs has uploaded a new change for review.

Change subject: webadmin,userportal: Support column resizing for all tables
......................................................................

webadmin,userportal: Support column resizing for all tables

This patch moves column resize implementation out of AbstractActionTable
and into dedicated table widget, ColumnResizeCellTable.

1. All custom CellTable widgets now inherit from ColumnResizeCellTable:
   - ElementIdCellTable [ActionCellTable + EntityModelCellTable]
   - IVdcQueryableCellTable

2. ColumnResizeCellTable now contains enableColumnResizing() method,
   plus some other related/useful methods

3. Columns added to ColumnResizeCellTable automatically benefit from
   tooltip displayed when the given header has its content (text)
   truncated, i.e. after shrinking the column or with long header text

4. AbstractActionTable now just delegates to table/tableHeader widgets,
   plus code to synchronize both tables (during column resize, etc.)

5. AbstractCellWithTooltip now contains common tooltip-related logic
   used by different subclasses:
   - SafeHtmlCellWithTooltip [resizable + non-resizable header cells]
   - TextCellWithTooltip [textual body cells]

6. Minor ElementIdCellTable improvement: call configureElementId()
   for every insertColumn() call for better consistency

AbstractCellWithTooltip does two kinds of content overflow detection:
   (a) scrollWidth with temporary CSS 'overflow:auto'
   (b) clientHeight with temporary CSS 'whiteSpace:normal'

In practice, (a) is used for both header and body cells. In Firefox,
header cells (SafeHtmlCellWithTooltip) use <div> with 'display:block'
to work around Firefox-specific issue with scrollWidth.

Change-Id: Ic69b597d7c5f2330cef5a93bc8812494af731734
Bug-Url: https://bugzilla.redhat.com/956378
Signed-off-by: Vojtech Szocs <vsz...@redhat.com>
---
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/editor/EntityModelCellTable.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/editor/IVdcQueryableCellTable.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/AbstractActionTable.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/ElementIdCellTable.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/SimpleActionTable.java
A 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/AbstractCellWithTooltip.java
A 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/SafeHtmlCellWithTooltip.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/TextCellWithTooltip.java
A 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ColumnResizeCellTable.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ResizableHeader.java
D 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ResizableHeaderCell.java
11 files changed, 490 insertions(+), 228 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/41/14341/1

diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/editor/EntityModelCellTable.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/editor/EntityModelCellTable.java
index 52ef6e4..e41c97b 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/editor/EntityModelCellTable.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/editor/EntityModelCellTable.java
@@ -325,12 +325,6 @@
         super.onLoadingStateChanged(state);
     }
 
-    @Override
-    public void insertColumn(int beforeIndex, Column col, Header header, 
Header footer) {
-        super.insertColumn(beforeIndex, col, header, footer);
-        configureElementId(col);
-    }
-
     @SuppressWarnings("unchecked")
     @Override
     public void edit(M object) {
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/editor/IVdcQueryableCellTable.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/editor/IVdcQueryableCellTable.java
index 7d24033..04cdeb7 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/editor/IVdcQueryableCellTable.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/editor/IVdcQueryableCellTable.java
@@ -8,6 +8,7 @@
 import org.ovirt.engine.ui.common.widget.HasEditorDriver;
 import org.ovirt.engine.ui.common.widget.table.column.RadioboxCell;
 import org.ovirt.engine.ui.common.widget.table.header.SelectAllCheckBoxHeader;
+import org.ovirt.engine.ui.common.widget.table.resize.ColumnResizeCellTable;
 import org.ovirt.engine.ui.uicommonweb.models.ListModel;
 import org.ovirt.engine.ui.uicompat.Event;
 import org.ovirt.engine.ui.uicompat.EventArgs;
@@ -26,7 +27,7 @@
 import com.google.gwt.view.client.SelectionModel;
 import com.google.gwt.view.client.SingleSelectionModel;
 
-public class IVdcQueryableCellTable<IVdcQueryable, M extends ListModel> 
extends CellTable<IVdcQueryable> implements HasEditorDriver<M> {
+public class IVdcQueryableCellTable<IVdcQueryable, M extends ListModel> 
extends ColumnResizeCellTable<IVdcQueryable> implements HasEditorDriver<M> {
 
     private static final int DEFAULT_PAGESIZE = 1000;
     private static final int CHECK_COLUMN_WIDTH = 27;
@@ -36,7 +37,7 @@
     private M listModel;
 
     public IVdcQueryableCellTable() {
-        super(DEFAULT_PAGESIZE, (Resources) 
GWT.create(PopupTableResources.class));
+        super(DEFAULT_PAGESIZE, (CellTable.Resources) 
GWT.create(PopupTableResources.class));
 
         SingleSelectionModel<IVdcQueryable> selectionModel = new 
SingleSelectionModel<IVdcQueryable>();
         setSelectionModel(selectionModel);
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/AbstractActionTable.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/AbstractActionTable.java
index de1db2f..cd95534 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/AbstractActionTable.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/AbstractActionTable.java
@@ -1,7 +1,6 @@
 package org.ovirt.engine.ui.common.widget.table;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 import org.ovirt.engine.ui.common.CommonApplicationConstants;
@@ -10,22 +9,16 @@
 import org.ovirt.engine.ui.common.uicommon.model.SearchableTableModelProvider;
 import org.ovirt.engine.ui.common.widget.action.AbstractActionPanel;
 import org.ovirt.engine.ui.common.widget.label.NoItemsLabel;
-import org.ovirt.engine.ui.common.widget.table.column.EmptyColumn;
-import org.ovirt.engine.ui.common.widget.table.resize.HasResizableColumns;
-import org.ovirt.engine.ui.common.widget.table.resize.ResizableHeader;
 import org.ovirt.engine.ui.uicommonweb.UICommand;
 import org.ovirt.engine.ui.uicommonweb.models.Model;
 
 import com.google.gwt.core.client.Scheduler;
 import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.NodeList;
 import com.google.gwt.dom.client.Style.Position;
 import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.dom.client.TableCellElement;
-import com.google.gwt.dom.client.TableElement;
 import com.google.gwt.dom.client.TableRowElement;
-import com.google.gwt.dom.client.TableSectionElement;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ContextMenuEvent;
 import com.google.gwt.event.dom.client.DoubleClickEvent;
@@ -36,18 +29,14 @@
 import com.google.gwt.event.dom.client.ScrollEvent;
 import com.google.gwt.event.dom.client.ScrollHandler;
 import com.google.gwt.event.shared.EventBus;
-import com.google.gwt.safehtml.shared.SafeHtml;
-import com.google.gwt.safehtml.shared.SafeHtmlUtils;
 import com.google.gwt.uibinder.client.UiField;
 import com.google.gwt.uibinder.client.UiHandler;
 import com.google.gwt.user.cellview.client.CellTable.Resources;
 import com.google.gwt.user.cellview.client.Column;
 import com.google.gwt.user.cellview.client.ColumnSortEvent.AsyncHandler;
 import 
com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
-import com.google.gwt.user.cellview.client.Header;
 import 
com.google.gwt.user.cellview.client.LoadingStateChangeEvent.LoadingState;
 import com.google.gwt.user.cellview.client.RowStyles;
-import com.google.gwt.user.cellview.client.SafeHtmlHeader;
 import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.Timer;
 import com.google.gwt.user.client.Window;
@@ -68,17 +57,14 @@
  * <li>{@link #actionPanel} widget into which action button widgets will be 
rendered
  * <li>{@link #prevPageButton} widget representing the "previous page" button
  * <li>{@link #nextPageButton} widget representing the "next page" button
- * <li>{@link #refreshPageButton} widget representing the "refresh current 
page" button
  * <li>{@link #tableContainer} widget for displaying the actual table
+ * <li>{@link #tableHeaderContainer} widget for displaying the table header
  * </ul>
  *
  * @param <T>
  *            Table row data type.
  */
-public abstract class AbstractActionTable<T> extends AbstractActionPanel<T> 
implements ActionTable<T>, HasResizableColumns<T> {
-
-    // Minimum width of a column used with column resizing, in pixels
-    private static final int RESIZE_MINIMUM_COLUMN_WIDTH = 30;
+public abstract class AbstractActionTable<T> extends AbstractActionPanel<T> 
implements ActionTable<T> {
 
     // Click event type
     private static final String CLICK = "click"; //$NON-NLS-1$
@@ -97,9 +83,6 @@
     @UiField
     public SimplePanel tableHeaderContainer;
 
-    @UiField
-    public SimplePanel tableOverhead;
-
     private final OrderedMultiSelectionModel<T> selectionModel;
 
     @WithElementId("content")
@@ -112,11 +95,6 @@
 
     private boolean multiSelectionDisabled;
     private final int[] mousePosition = new int[2];
-
-    private boolean columnResizingEnabled = false;
-
-    // Reference to an empty, no-width column used with resizable columns
-    private Column<T, ?> emptyNoWidthColumn;
 
     // Table container's horizontal scroll position, used to align table 
header with main table
     private int tableContainerHorizontalScrollPosition = 0;
@@ -137,8 +115,9 @@
                     selectionModel.setMultiSelectEnabled(event.getCtrlKey());
                     
selectionModel.setMultiRangeSelectEnabled(event.getShiftKey());
                 }
+
                 // Remove focus from the table so refreshes won't try to focus 
on the
-                // selected row. This important when the user has scrolled the 
selected
+                // selected row. This is important when the user has scrolled 
the selected
                 // row off the screen, we don't want the browser to scroll 
back.
                 table.setFocus(false);
                 super.onBrowserEvent2(event);
@@ -191,7 +170,7 @@
 
         };
 
-        // Can't do this in the onBrowserEvent, as the GWT Cell table doesn't 
support double click.
+        // Can't do this in the onBrowserEvent, as GWT CellTable doesn't 
support double click.
         this.table.addDomHandler(new DoubleClickHandler() {
             @Override
             public void onDoubleClick(DoubleClickEvent event) {
@@ -205,7 +184,26 @@
         }, DoubleClickEvent.getType());
 
         // Create table header row
-        this.tableHeader = new ActionCellTable<T>(dataProvider, 
headerResources);
+        this.tableHeader = new ActionCellTable<T>(dataProvider, 
headerResources) {
+
+            @Override
+            public void onResizeEnd(Column<T, ?> column, Element 
headerElement) {
+                super.onResizeEnd(column, headerElement);
+
+                // Redraw main table
+                table.redraw();
+            }
+
+            @Override
+            public void resizeColumn(Column<T, ?> column, int newWidth) {
+                super.resizeColumn(column, newWidth);
+
+                // Resize the corresponding column in main table
+                table.resizeColumn(column, newWidth);
+            }
+
+        };
+
         this.tableHeader.setRowData(new ArrayList<T>());
         this.showDefaultHeader = headerResources == null;
 
@@ -426,81 +424,21 @@
         getDataProvider().goForward();
     }
 
-    void addColumn(Column<T, ?> column, Header<?> header) {
-        table.addColumn(column, header);
-        tableHeader.addColumn(column, header);
-
-        // Configure column content element ID options
-        table.configureElementId(column);
-
-        // Resizable columns require empty, no-width column to be the last 
table column
-        if (columnResizingEnabled) {
-            if (emptyNoWidthColumn != null) {
-                table.removeColumn(emptyNoWidthColumn);
-                tableHeader.removeColumn(emptyNoWidthColumn);
-            }
-
-            emptyNoWidthColumn = new EmptyColumn<T>();
-            table.addColumn(emptyNoWidthColumn);
-            tableHeader.addColumn(emptyNoWidthColumn);
-        }
-    }
-
     void setColumnWidth(Column<T, ?> column, String width) {
         table.setColumnWidth(column, width);
         tableHeader.setColumnWidth(column, width);
-
-        // Update cell widths
-        int columnIndex = table.getColumnIndex(column);
-        for (TableCellElement cell : getTableBodyCells(columnIndex)) {
-            cell.getStyle().setProperty("width", width); //$NON-NLS-1$
-        }
-        for (TableCellElement cell : getTableHeaderCells(columnIndex)) {
-            cell.getStyle().setProperty("width", width); //$NON-NLS-1$
-        }
-    }
-
-    List<TableCellElement> getTableBodyCells(int columnIndex) {
-        TableElement tableElement = table.getElement().cast();
-        TableSectionElement firstTBodyElement = 
tableElement.getTBodies().getItem(0);
-        return firstTBodyElement != null ? 
getCells(firstTBodyElement.getRows(), columnIndex)
-                : Collections.<TableCellElement> emptyList();
-    }
-
-    List<TableCellElement> getTableHeaderCells(int columnIndex) {
-        Element tableHeaderElement = showDefaultHeader ? table.getElement() : 
tableHeader.getElement();
-        TableElement tableHeaderElementCast = tableHeaderElement.cast();
-        TableSectionElement tHeadElement = tableHeaderElementCast.getTHead();
-        return tHeadElement != null ? getCells(tHeadElement.getRows(), 
columnIndex)
-                : Collections.<TableCellElement> emptyList();
-    }
-
-    List<TableCellElement> getCells(NodeList<TableRowElement> rows, int 
columnIndex) {
-        List<TableCellElement> result = new ArrayList<TableCellElement>();
-        for (int i = 0; i < rows.getLength(); i++) {
-            TableCellElement cell = 
rows.getItem(i).getCells().getItem(columnIndex);
-            if (cell != null) {
-                result.add(cell);
-            }
-        }
-        return result;
-    }
-
-    Header<?> getHeader(Column<T, ?> column, String headerTextOrHtml, boolean 
allowHtml) {
-        SafeHtml text = allowHtml ? 
SafeHtmlUtils.fromSafeConstant(headerTextOrHtml)
-                : SafeHtmlUtils.fromString(headerTextOrHtml);
-        return columnResizingEnabled ? new ResizableHeader<T>(text, column, 
this) : new SafeHtmlHeader(text);
     }
 
     /**
-     * Adds a new table column, without specifying the column width.
+     * Adds a new column, without specifying column width.
      */
     public void addColumn(Column<T, ?> column, String headerText) {
-        addColumn(column, getHeader(column, headerText, false));
+        table.addColumn(column, headerText);
+        tableHeader.addColumn(column, headerText);
     }
 
     /**
-     * Adds a new table column, using the given column width.
+     * Adds a new column, setting the column width.
      */
     public void addColumn(Column<T, ?> column, String headerText, String 
width) {
         addColumn(column, headerText);
@@ -508,24 +446,25 @@
     }
 
     /**
-     * Adds a new table column with HTML in the header text, without 
specifying the column width.
+     * Adds a new column with HTML header text, without specifying column 
width.
      * <p>
-     * {@code headerHtml} must honor the {@link SafeHtml} contract as 
specified in
-     * {@link SafeHtmlUtils#fromSafeConstant(String) fromSafeConstant}.
+     * {@code headerHtml} must honor the SafeHtml contract as specified in
+     * {@link 
com.google.gwt.safehtml.shared.SafeHtmlUtils#fromSafeConstant(String) 
SafeHtmlUtils.fromSafeConstant}.
      */
     public void addColumnWithHtmlHeader(Column<T, ?> column, String 
headerHtml) {
-        addColumn(column, getHeader(column, headerHtml, true));
+        table.addColumnWithHtmlHeader(column, headerHtml);
+        tableHeader.addColumnWithHtmlHeader(column, headerHtml);
     }
 
     /**
-     * Adds a new table column with HTML in the header text, using the given 
column width.
+     * Adds a new column with HTML header text, setting the column width.
      * <p>
-     * {@code headerHtml} must honor the {@link SafeHtml} contract as 
specified in
-     * {@link SafeHtmlUtils#fromSafeConstant(String) fromSafeConstant}.
+     * {@code headerHtml} must honor the SafeHtml contract as specified in
+     * {@link 
com.google.gwt.safehtml.shared.SafeHtmlUtils#fromSafeConstant(String) 
SafeHtmlUtils.fromSafeConstant}.
      */
     public void addColumnWithHtmlHeader(Column<T, ?> column, String 
headerHtml, String width) {
-        addColumnWithHtmlHeader(column, headerHtml);
-        setColumnWidth(column, width);
+        table.addColumnWithHtmlHeader(column, headerHtml, width);
+        tableHeader.addColumnWithHtmlHeader(column, headerHtml, width);
     }
 
     /**
@@ -540,28 +479,18 @@
      * Ensures that the given column is added (or removed), unless it's 
already present (or absent).
      */
     public void ensureColumnPresent(Column<T, ?> column, String headerText, 
boolean present) {
-        ensureColumnPresent(column, headerText, present, null);
+        table.ensureColumnPresent(column, headerText, present);
+        tableHeader.ensureColumnPresent(column, headerText, present);
     }
 
     /**
      * Ensures that the given column is added (or removed), unless it's 
already present (or absent).
      * <p>
-     * This method also sets the width of the column in case the column needs 
to be added.
+     * This method also sets the column width in case the column needs to be 
added.
      */
     public void ensureColumnPresent(Column<T, ?> column, String headerText, 
boolean present, String width) {
-        if (present) {
-            if (table.getColumnIndex(column) != -1) {
-                removeColumn(column);
-            }
-
-            if (width == null) {
-                addColumnWithHtmlHeader(column, headerText);
-            } else {
-                addColumnWithHtmlHeader(column, headerText, width);
-            }
-        } else if (!present && table.getColumnIndex(column) != -1) {
-            removeColumn(column);
-        }
+        table.ensureColumnPresent(column, headerText, present, width);
+        tableHeader.ensureColumnPresent(column, headerText, present, width);
     }
 
     /**
@@ -569,38 +498,15 @@
      * <p>
      * This method should be called before calling any {@code addColumn} 
methods.
      * <p>
-     * After calling this method, each column must have an explicit width 
defined in PX units.
+     * <em>After calling this method, each column must have an explicit width 
defined in PX units, otherwise the resize
+     * behavior will not function properly.</em>
      */
     public void enableColumnResizing() {
         // Column resizing is supported only when the tableHeader widget is 
visible
-        columnResizingEnabled = !showDefaultHeader;
-    }
-
-    @Override
-    public void onResizeStart(Column<T, ?> column, Element headerElement) {
-        headerElement.getStyle().setBackgroundColor("#D6DCFF"); //$NON-NLS-1$
-    }
-
-    @Override
-    public void onResizeEnd(Column<T, ?> column, Element headerElement) {
-        headerElement.getStyle().clearBackgroundColor();
-
-        // Redraw main table
-        table.redraw();
-
-        // Note: DO NOT redraw tableHeader, as this would cause header cell 
elements
-        // to be re-created, and any event handlers attached to original 
header cell
-        // elements would be lost
-    }
-
-    @Override
-    public void resizeColumn(Column<T, ?> column, int newWidth) {
-        setColumnWidth(column, newWidth + "px"); //$NON-NLS-1$
-    }
-
-    @Override
-    public int getMinimumColumnWidth(Column<T, ?> column) {
-        return RESIZE_MINIMUM_COLUMN_WIDTH;
+        if (!showDefaultHeader) {
+            table.enableColumnResizing();
+            tableHeader.enableColumnResizing();
+        }
     }
 
     @Override
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/ElementIdCellTable.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/ElementIdCellTable.java
index 6f28b28..f96e213 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/ElementIdCellTable.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/ElementIdCellTable.java
@@ -2,9 +2,11 @@
 
 import org.ovirt.engine.ui.common.idhandler.HasElementId;
 import org.ovirt.engine.ui.common.widget.table.column.ColumnWithElementId;
+import org.ovirt.engine.ui.common.widget.table.resize.ColumnResizeCellTable;
 
 import com.google.gwt.user.cellview.client.CellTable;
 import com.google.gwt.user.cellview.client.Column;
+import com.google.gwt.user.cellview.client.Header;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.ui.Widget;
 import com.google.gwt.view.client.ProvidesKey;
@@ -12,8 +14,11 @@
 /**
  * A {@link CellTable} which adds support for configuring column DOM element 
IDs through {@link ColumnWithElementId}
  * interface.
+ *
+ * @param <T>
+ *            Table row data type.
  */
-public abstract class ElementIdCellTable<T> extends CellTable<T> implements 
HasElementId {
+public class ElementIdCellTable<T> extends ColumnResizeCellTable<T> implements 
HasElementId {
 
     private String elementId = DOM.createUniqueId();
 
@@ -47,6 +52,12 @@
         super(keyProvider);
     }
 
+    @Override
+    public void insertColumn(int beforeIndex, Column<T, ?> col, Header<?> 
header, Header<?> footer) {
+        super.insertColumn(beforeIndex, col, header, footer);
+        configureElementId(col);
+    }
+
     /**
      * Sets up the element ID for the given column, if the column implements 
{@link ColumnWithElementId}.
      */
@@ -73,4 +84,5 @@
     public String getElementId() {
         return elementId;
     }
+
 }
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/SimpleActionTable.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/SimpleActionTable.java
index 17f3bca..6bb7bc6 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/SimpleActionTable.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/SimpleActionTable.java
@@ -22,6 +22,7 @@
 import com.google.gwt.user.client.ui.HTMLPanel;
 import com.google.gwt.user.client.ui.Label;
 import com.google.gwt.user.client.ui.MenuItem;
+import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
 
 public class SimpleActionTable<T> extends AbstractActionTable<T> {
@@ -34,6 +35,9 @@
     Style style;
 
     @UiField
+    SimplePanel tableOverhead;
+
+    @UiField
     HTMLPanel barPanel;
 
     @UiField(provided = true)
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/AbstractCellWithTooltip.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/AbstractCellWithTooltip.java
new file mode 100644
index 0000000..cbf4b0c
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/AbstractCellWithTooltip.java
@@ -0,0 +1,89 @@
+package org.ovirt.engine.ui.common.widget.table.column;
+
+import com.google.gwt.cell.client.AbstractCell;
+import com.google.gwt.cell.client.ValueUpdater;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NativeEvent;
+
+/**
+ * An {@link AbstractCell} that provides tooltip in case the content doesn't 
fit the parent element.
+ * <p>
+ * Make sure to specify {@code mouseover} within cell consumed events, 
otherwise the tooltip feature will not work.
+ *
+ * @param <C>
+ *            Cell data type.
+ */
+public abstract class AbstractCellWithTooltip<C> extends AbstractCell<C> {
+
+    public AbstractCellWithTooltip(String... consumedEvents) {
+        super(consumedEvents);
+    }
+
+    @Override
+    public void onBrowserEvent(Context context, Element parent, C value,
+            NativeEvent event, ValueUpdater<C> valueUpdater) {
+        super.onBrowserEvent(context, parent, value, event, valueUpdater);
+
+        // Skip events other than 'mouseover'
+        if (!"mouseover".equals(event.getType())) { //$NON-NLS-1$
+            return;
+        }
+
+        if (value != null && showTooltip(parent, value)) {
+            parent.setTitle(getTooltip(value));
+        } else {
+            parent.setTitle(""); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Returns tooltip to show for the given value.
+     */
+    protected abstract String getTooltip(C value);
+
+    /**
+     * Returns {@code true} if tooltip should be shown for the given {@code 
parent} element.
+     */
+    protected boolean showTooltip(Element parent, C value) {
+        return contentOverflows(parent);
+    }
+
+    /**
+     * Returns {@code true} when the content of the given {@code parent} 
element overflows its area.
+     */
+    protected boolean contentOverflows(Element parent) {
+        return parent != null && (detectOverflowUsingScrollWidth(parent) || 
detectOverflowUsingClientHeight(parent));
+    }
+
+    /**
+     * Uses scrollWidth with temporary CSS 'overflow:auto' to detect 
horizontal overflow.
+     */
+    boolean detectOverflowUsingScrollWidth(Element parent) {
+        int scrollWidthBefore = parent.getScrollWidth();
+        String overflowValue = parent.getStyle().getProperty("overflow"); 
//$NON-NLS-1$
+        parent.getStyle().setProperty("overflow", "auto"); //$NON-NLS-1$ 
//$NON-NLS-2$
+
+        int scrollWidthAfter = parent.getScrollWidth();
+        parent.getStyle().setProperty("overflow", overflowValue); //$NON-NLS-1$
+
+        return scrollWidthAfter > scrollWidthBefore;
+    }
+
+    /**
+     * Uses clientHeight with temporary CSS 'whiteSpace:normal' to detect 
vertical overflow.
+     * <p>
+     * This is necessary due to some browsers (Firefox) having issues with 
scrollWidth (e.g. elements with CSS 'display'
+     * other than 'block' have incorrect scrollWidth value).
+     */
+    boolean detectOverflowUsingClientHeight(Element parent) {
+        int clientHeightBefore = parent.getClientHeight();
+        String whiteSpaceValue = parent.getStyle().getProperty("whiteSpace"); 
//$NON-NLS-1$
+        parent.getStyle().setProperty("whiteSpace", "normal"); //$NON-NLS-1$ 
//$NON-NLS-2$
+
+        int clientHeightAfter = parent.getClientHeight();
+        parent.getStyle().setProperty("whiteSpace", whiteSpaceValue); 
//$NON-NLS-1$
+
+        return clientHeightAfter > clientHeightBefore;
+    }
+
+}
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/SafeHtmlCellWithTooltip.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/SafeHtmlCellWithTooltip.java
new file mode 100644
index 0000000..2f89c97
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/SafeHtmlCellWithTooltip.java
@@ -0,0 +1,37 @@
+package org.ovirt.engine.ui.common.widget.table.column;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+
+public class SafeHtmlCellWithTooltip extends AbstractCellWithTooltip<SafeHtml> 
{
+
+    public SafeHtmlCellWithTooltip() {
+        super("mouseover"); //$NON-NLS-1$
+    }
+
+    public SafeHtmlCellWithTooltip(String... consumedEvents) {
+        super(consumedEvents);
+    }
+
+    @Override
+    public void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
+        if (value != null) {
+            sb.appendHtmlConstant("<div style='display:block'>"); //$NON-NLS-1$
+            sb.append(value);
+            sb.appendHtmlConstant("</div>"); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    protected boolean contentOverflows(Element parent) {
+        // Perform content overflow detection on child DIV element
+        return super.contentOverflows(parent.getFirstChildElement());
+    }
+
+    @Override
+    protected String getTooltip(SafeHtml value) {
+        return value.asString();
+    }
+
+}
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/TextCellWithTooltip.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/TextCellWithTooltip.java
index 75a7f70..ba74330 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/TextCellWithTooltip.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/TextCellWithTooltip.java
@@ -2,45 +2,42 @@
 
 import org.ovirt.engine.ui.common.utils.ElementIdUtils;
 
-import com.google.gwt.cell.client.AbstractSafeHtmlCell;
-import com.google.gwt.cell.client.Cell;
-import com.google.gwt.cell.client.ValueUpdater;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.NativeEvent;
 import com.google.gwt.safehtml.client.SafeHtmlTemplates;
 import com.google.gwt.safehtml.shared.SafeHtml;
 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
 import com.google.gwt.safehtml.shared.SafeHtmlUtils;
-import com.google.gwt.text.shared.SimpleSafeHtmlRenderer;
 import com.google.gwt.user.client.DOM;
 
 /**
- * A {@link Cell} used to render text, providing a tooltip in case the text 
does not fit within the parent element.
+ * A Cell used to render text, providing tooltip in case the content doesn't 
fit the parent element.
  *
  * @see com.google.gwt.cell.client.TextCell
  */
-public class TextCellWithTooltip extends AbstractSafeHtmlCell<String> {
+public class TextCellWithTooltip extends AbstractCellWithTooltip<String> {
 
     interface CellTemplate extends SafeHtmlTemplates {
+
         @Template("<div id=\"{0}\">{1}</div>")
         SafeHtml textContainer(String id, SafeHtml text);
+
     }
 
     public static final int UNLIMITED_LENGTH = -1;
     private static final String TOO_LONG_TEXT_POSTFIX = "..."; //$NON-NLS-1$
 
-    // DOM element ID settings for the text container element
+    // DOM element ID settings for text container element
     private String elementIdPrefix = DOM.createUniqueId();
     private String columnId;
 
-    // Text longer than this value will be shortened, providing a tooltip with 
original text
+    // Text longer than this value will be shortened, providing tooltip with 
original text
     private final int maxTextLength;
 
     private static CellTemplate template;
 
     public TextCellWithTooltip(int maxTextLength) {
-        super(SimpleSafeHtmlRenderer.getInstance(), "mouseover"); //$NON-NLS-1$
+        super("mouseover"); //$NON-NLS-1$
         this.maxTextLength = maxTextLength;
 
         // Delay cell template creation until the first time it's needed
@@ -58,67 +55,47 @@
     }
 
     @Override
-    public void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
-        String rawData = value != null ? value.asString() : ""; //$NON-NLS-1$
+    public void render(Context context, String value, SafeHtmlBuilder sb) {
+        if (value != null) {
+            SafeHtml escapedValue = getEscapedValue(value);
+            SafeHtml renderedValue = getRenderedValue(escapedValue);
 
-        sb.append(template.textContainer(
-                ElementIdUtils.createTableCellElementId(elementIdPrefix, 
columnId, context),
-                getRenderedValue(rawData)));
+            sb.append(template.textContainer(
+                    ElementIdUtils.createTableCellElementId(elementIdPrefix, 
columnId, context),
+                    renderedValue));
+        }
     }
 
     @Override
-    public void onBrowserEvent(Cell.Context context, Element parent,
-            String value, NativeEvent event, ValueUpdater<String> 
valueUpdater) {
-        super.onBrowserEvent(context, parent, value, event, valueUpdater);
+    protected String getTooltip(String value) {
+        return getEscapedValue(value).asString();
+    }
 
-        // Ignore events other than 'mouseover'
-        if (!"mouseover".equals(event.getType())) { //$NON-NLS-1$
-            return;
-        }
+    @Override
+    protected boolean showTooltip(Element parent, String value) {
+        // Enforce tooltip when the presented text gets truncated due to 
maxTextLength
+        SafeHtml escapedValue = getEscapedValue(value);
+        SafeHtml renderedValue = getRenderedValue(escapedValue);
+        return super.showTooltip(parent, value) || 
!escapedValue.equals(renderedValue);
+    }
 
-        // Enforce tooltip when the presented text doesn't match original value
-        SafeHtml safeValue = value != null ? 
SafeHtmlUtils.fromSafeConstant(value) : null;
-        boolean forceTooltip = (safeValue != null && 
!safeValue.equals(getRenderedValue(value)));
-
-        // If the parent element content overflows its area, provide tooltip 
to the element
-        if (forceTooltip || contentOverflows(parent)) {
-            parent.setTitle(value);
-        } else {
-            parent.setTitle(""); //$NON-NLS-1$
-        }
+    SafeHtml getEscapedValue(String value) {
+        return SafeHtmlUtils.fromString(value);
     }
 
     /**
-     * Returns the text value to be rendered by this cell.
+     * Returns the (possibly truncated) value to be rendered by this cell.
      */
-    SafeHtml getRenderedValue(final String text) {
-        String result = text;
+    SafeHtml getRenderedValue(SafeHtml value) {
+        String result = value.asString();
 
         // Check if the text needs to be shortened
-        if (maxTextLength > 0 && text.length() > maxTextLength) {
+        if (maxTextLength > 0 && result.length() > maxTextLength) {
             result = result.substring(0, Math.max(maxTextLength - 
TOO_LONG_TEXT_POSTFIX.length(), 0));
             result = result + TOO_LONG_TEXT_POSTFIX;
         }
 
         return SafeHtmlUtils.fromSafeConstant(result);
-    }
-
-    /**
-     * Returns {@code true} when the content of the given element overflows 
the element's content area, {@code false}
-     * otherwise.
-     */
-    boolean contentOverflows(Element elm) {
-        String overflowValue = elm.getStyle().getOverflow();
-
-        // Temporarily allow element content to overflow through scroll bars
-        elm.getStyle().setProperty("overflow", "auto"); //$NON-NLS-1$ 
//$NON-NLS-2$
-        boolean overflowX = elm.getScrollWidth() > elm.getClientWidth();
-        boolean overflowY = elm.getScrollHeight() > elm.getClientHeight();
-
-        // Revert to the original overflow value
-        elm.getStyle().setProperty("overflow", overflowValue); //$NON-NLS-1$
-
-        return overflowX || overflowY;
     }
 
 }
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ColumnResizeCellTable.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ColumnResizeCellTable.java
new file mode 100644
index 0000000..400bccf
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ColumnResizeCellTable.java
@@ -0,0 +1,258 @@
+package org.ovirt.engine.ui.common.widget.table.resize;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.ovirt.engine.ui.common.widget.table.column.EmptyColumn;
+import org.ovirt.engine.ui.common.widget.table.column.SafeHtmlCellWithTooltip;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.dom.client.TableCellElement;
+import com.google.gwt.dom.client.TableElement;
+import com.google.gwt.dom.client.TableRowElement;
+import com.google.gwt.dom.client.TableSectionElement;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlUtils;
+import com.google.gwt.user.cellview.client.CellTable;
+import com.google.gwt.user.cellview.client.Column;
+import com.google.gwt.user.cellview.client.Header;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.gwt.view.client.ProvidesKey;
+
+/**
+ * A {@link CellTable} that supports resizing its columns using mouse.
+ * <p>
+ * Column resize feature is disabled by default, use {@link 
#enableColumnResizing} to enable it.
+ *
+ * @param <T>
+ *            Table row data type.
+ */
+public class ColumnResizeCellTable<T> extends CellTable<T> implements 
HasResizableColumns<T> {
+
+    private static final int DEFAULT_MINIMUM_COLUMN_WIDTH = 30;
+
+    private int minimumColumnWidth = DEFAULT_MINIMUM_COLUMN_WIDTH;
+
+    // Empty, no-width column used with resizable columns feature
+    // that occupies remaining horizontal space within the table
+    private Column<T, ?> emptyNoWidthColumn;
+
+    private boolean columnResizingEnabled = false;
+
+    public ColumnResizeCellTable() {
+        super();
+    }
+
+    public ColumnResizeCellTable(int pageSize, ProvidesKey<T> keyProvider) {
+        super(pageSize, keyProvider);
+    }
+
+    public ColumnResizeCellTable(int pageSize, CellTable.Resources resources,
+            ProvidesKey<T> keyProvider, Widget loadingIndicator) {
+        super(pageSize, resources, keyProvider, loadingIndicator);
+    }
+
+    public ColumnResizeCellTable(int pageSize, CellTable.Resources resources,
+            ProvidesKey<T> keyProvider) {
+        super(pageSize, resources, keyProvider);
+    }
+
+    public ColumnResizeCellTable(int pageSize, CellTable.Resources resources) {
+        super(pageSize, resources);
+    }
+
+    public ColumnResizeCellTable(int pageSize) {
+        super(pageSize);
+    }
+
+    public ColumnResizeCellTable(ProvidesKey<T> keyProvider) {
+        super(keyProvider);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * When calling this method, consider using a header that supports 
displaying tooltip in case the header content
+     * doesn't fit the header element.
+     */
+    @Override
+    public void addColumn(Column<T, ?> column, Header<?> header) {
+        super.addColumn(column, header);
+
+        if (columnResizingEnabled) {
+            if (emptyNoWidthColumn != null) {
+                removeColumn(emptyNoWidthColumn);
+            }
+
+            // Add empty, no-width column as the last column
+            emptyNoWidthColumn = new EmptyColumn<T>();
+            addColumn(emptyNoWidthColumn);
+        }
+    }
+
+    /**
+     * Adds a new column, without specifying column width.
+     */
+    @Override
+    public void addColumn(Column<T, ?> column, String headerText) {
+        addColumn(column, createHeader(column, headerText, false));
+    }
+
+    /**
+     * Adds a new column, setting the column width.
+     */
+    public void addColumnAndSetWidth(Column<T, ?> column, String headerText, 
String width) {
+        addColumn(column, headerText);
+        setColumnWidth(column, width);
+    }
+
+    /**
+     * Adds a new column with HTML header text, without specifying column 
width.
+     * <p>
+     * {@code headerHtml} must honor the SafeHtml contract as specified in
+     * {@link 
com.google.gwt.safehtml.shared.SafeHtmlUtils#fromSafeConstant(String) 
SafeHtmlUtils.fromSafeConstant}.
+     */
+    public void addColumnWithHtmlHeader(Column<T, ?> column, String 
headerHtml) {
+        addColumn(column, createHeader(column, headerHtml, true));
+    }
+
+    /**
+     * Adds a new column with HTML header text, setting the column width.
+     * <p>
+     * {@code headerHtml} must honor the SafeHtml contract as specified in
+     * {@link 
com.google.gwt.safehtml.shared.SafeHtmlUtils#fromSafeConstant(String) 
SafeHtmlUtils.fromSafeConstant}.
+     */
+    public void addColumnWithHtmlHeader(Column<T, ?> column, String 
headerHtml, String width) {
+        addColumnWithHtmlHeader(column, headerHtml);
+        setColumnWidth(column, width);
+    }
+
+    Header<?> createHeader(Column<T, ?> column, String headerTextOrHtml, 
boolean allowHtml) {
+        SafeHtml text = allowHtml ? 
SafeHtmlUtils.fromSafeConstant(headerTextOrHtml)
+                : SafeHtmlUtils.fromString(headerTextOrHtml);
+        return columnResizingEnabled ? new ResizableHeader<T>(text, column, 
this) : createSafeHtmlHeader(text);
+    }
+
+    Header<?> createSafeHtmlHeader(final SafeHtml text) {
+        return new Header<SafeHtml>(new SafeHtmlCellWithTooltip()) {
+            @Override
+            public SafeHtml getValue() {
+                return text;
+            }
+        };
+    }
+
+    /**
+     * Ensures that the given column is added (or removed), unless it's 
already present (or absent).
+     */
+    public void ensureColumnPresent(Column<T, ?> column, String headerText, 
boolean present) {
+        ensureColumnPresent(column, headerText, present, null);
+    }
+
+    /**
+     * Ensures that the given column is added (or removed), unless it's 
already present (or absent).
+     * <p>
+     * This method also sets the column width in case the column needs to be 
added.
+     */
+    public void ensureColumnPresent(Column<T, ?> column, String headerText, 
boolean present, String width) {
+        if (present) {
+            // Remove the column first
+            if (getColumnIndex(column) != -1) {
+                removeColumn(column);
+            }
+
+            // Re-add the column
+            if (width == null) {
+                addColumnWithHtmlHeader(column, headerText);
+            } else {
+                addColumnWithHtmlHeader(column, headerText, width);
+            }
+        } else if (!present && getColumnIndex(column) != -1) {
+            // Remove the column
+            removeColumn(column);
+        }
+    }
+
+    @Override
+    public void setColumnWidth(Column<T, ?> column, String width) {
+        super.setColumnWidth(column, width);
+
+        if (columnResizingEnabled) {
+            int columnIndex = getColumnIndex(column);
+            TableElement tableElement = getElement().cast();
+
+            // Update body and header cell widths
+            for (TableCellElement cell : getTableBodyCells(tableElement, 
columnIndex)) {
+                cell.getStyle().setProperty("width", width); //$NON-NLS-1$
+            }
+            for (TableCellElement cell : getTableHeaderCells(tableElement, 
columnIndex)) {
+                cell.getStyle().setProperty("width", width); //$NON-NLS-1$
+            }
+        }
+    }
+
+    List<TableCellElement> getTableBodyCells(TableElement tableElement, int 
columnIndex) {
+        TableSectionElement firstTBodyElement = 
tableElement.getTBodies().getItem(0);
+        return firstTBodyElement != null ? 
getCells(firstTBodyElement.getRows(), columnIndex)
+                : Collections.<TableCellElement> emptyList();
+    }
+
+    List<TableCellElement> getTableHeaderCells(TableElement tableElement, int 
columnIndex) {
+        TableSectionElement tHeadElement = tableElement.getTHead();
+        return tHeadElement != null ? getCells(tHeadElement.getRows(), 
columnIndex)
+                : Collections.<TableCellElement> emptyList();
+    }
+
+    List<TableCellElement> getCells(NodeList<TableRowElement> rows, int 
columnIndex) {
+        List<TableCellElement> result = new ArrayList<TableCellElement>();
+        for (int i = 0; i < rows.getLength(); i++) {
+            TableCellElement cell = 
rows.getItem(i).getCells().getItem(columnIndex);
+            if (cell != null) {
+                result.add(cell);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Allows table columns to be resized by dragging their right-hand border 
using mouse.
+     * <p>
+     * This method should be called before calling any {@code addColumn} 
methods.
+     * <p>
+     * <em>After calling this method, each column must have an explicit width 
defined in PX units, otherwise the resize
+     * behavior will not function properly.</em>
+     */
+    public void enableColumnResizing() {
+        columnResizingEnabled = true;
+    }
+
+    @Override
+    public void onResizeStart(Column<T, ?> column, Element headerElement) {
+        headerElement.getStyle().setBackgroundColor("#D6DCFF"); //$NON-NLS-1$
+    }
+
+    @Override
+    public void onResizeEnd(Column<T, ?> column, Element headerElement) {
+        headerElement.getStyle().clearBackgroundColor();
+
+        // Redraw the table
+        redraw();
+    }
+
+    @Override
+    public void resizeColumn(Column<T, ?> column, int newWidth) {
+        setColumnWidth(column, newWidth + "px"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getMinimumColumnWidth(Column<T, ?> column) {
+        return minimumColumnWidth;
+    }
+
+    public void setMinimumColumnWidth(int minimumColumnWidth) {
+        this.minimumColumnWidth = minimumColumnWidth;
+    }
+
+}
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ResizableHeader.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ResizableHeader.java
index 7d3c5d7..19cea6f 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ResizableHeader.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ResizableHeader.java
@@ -1,5 +1,7 @@
 package org.ovirt.engine.ui.common.widget.table.resize;
 
+import org.ovirt.engine.ui.common.widget.table.column.SafeHtmlCellWithTooltip;
+
 import com.google.gwt.cell.client.Cell.Context;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.NativeEvent;
@@ -26,7 +28,7 @@
     private final HasResizableColumns<T> table;
 
     public ResizableHeader(SafeHtml text, Column<T, ?> column, 
HasResizableColumns<T> table) {
-        super(new ResizableHeaderCell());
+        super(new SafeHtmlCellWithTooltip("click", "mousedown", "mousemove", 
"mouseover")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
         this.text = text;
         this.column = column;
         this.table = table;
@@ -39,6 +41,8 @@
 
     @Override
     public void onBrowserEvent(Context context, Element target, NativeEvent 
event) {
+        super.onBrowserEvent(context, target, event);
+
         int clientX = event.getClientX();
         int absoluteLeft = target.getAbsoluteLeft();
         int offsetWidth = target.getOffsetWidth();
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ResizableHeaderCell.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ResizableHeaderCell.java
deleted file mode 100644
index efe4a48..0000000
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/resize/ResizableHeaderCell.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.ovirt.engine.ui.common.widget.table.resize;
-
-import com.google.gwt.cell.client.AbstractCell;
-import com.google.gwt.safehtml.shared.SafeHtml;
-import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
-
-public class ResizableHeaderCell extends AbstractCell<SafeHtml> {
-
-    public ResizableHeaderCell() {
-        super("click", "dblclick", "mousedown", "mousemove"); //$NON-NLS-1$ 
//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
-    }
-
-    @Override
-    public void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
-        if (value != null) {
-            sb.append(value);
-        }
-    }
-
-}


--
To view, visit http://gerrit.ovirt.org/14341
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic69b597d7c5f2330cef5a93bc8812494af731734
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Vojtech Szocs <vsz...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to