package org.ovirt.engine.ui.common.widget.table.cell;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.ovirt.engine.ui.common.utils.ElementIdUtils;
import org.ovirt.engine.ui.common.utils.ElementTooltipUtils;
import org.ovirt.engine.ui.common.widget.tooltip.ProvidesTooltipForObject;
import com.google.gwt.cell.client.HasCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.DOM;
/**
* <p>
* Base class for all Cells that would otherwise extend GWT AbstractCell.
* Supports rendering Element ids via the oVirt Element-ID framework.
* Support tooltips. Note that for a Composite cell, you may want tooltips on each component
* of the cell. In that case, do not implement getTooltip() in this cell's Column. Instead, implement
* it in each component Cell. (The downside of this is that you have no access to the row type, so
* you cannot make a component tooltip be a property of that row type. For example, you cannot have
* a component tooltip be a VM's name. It must be a constant.)
* </p>
* @param <C> Cell data type.
*/
public class CompositeCell<C> extends com.google.gwt.cell.client.CompositeCell<C> implements Cell<C>,
ProvidesTooltipForObject<C> {
private final List<HasCell<C, ?>> hasCells;
// DOM element ID settings for text container element
private String elementIdPrefix = DOM.createUniqueId();
private String columnId;
private SafeHtml tooltipFallback;
public CompositeCell(List<HasCell<C, ?>> hasCells) {
super(hasCells);
this.hasCells = hasCells;
}
@Override
public Set<String> getConsumedEvents() {
return new HashSet<>(ElementTooltipUtils.HANDLED_CELL_EVENTS);
}
@Override
public void onBrowserEvent(Context context, Element parent, C value,
NativeEvent event, ValueUpdater<C> valueUpdater) {
ElementTooltipUtils.handleCellEvent(event, parent, getTooltip(value));
super.onBrowserEvent(context, parent, value, event, valueUpdater);
}
/**
* Let the Cell render the tooltip using C value. This is only attempted if the Column itself
* did not provide a tooltip. This is usually only used when there is a Composite Column that
* contains multiple Cells, but each Cell needs its own tooltip.
*/
public SafeHtml getTooltip(C value) {
return tooltipFallback;
}
@Override
public void setTooltipFallback(SafeHtml tooltipFallback) {
this.tooltipFallback = tooltipFallback;
}
/**
* Override the normal render to pass along an id.
*
* @see com.google.gwt.cell.client.AbstractCell#render(com.google.gwt.cell.client.Cell.Context, java.lang.Object, com.google.gwt.safehtml.shared.SafeHtmlBuilder)
*/
public final void render(Context context, C value, SafeHtmlBuilder sb) {
String id = ElementIdUtils.createTableCellElementId(getElementIdPrefix(), getColumnId(), context);
render(context, value, sb, id);
}
/**
* Override the normal render just to prevent anyone from calling it.
*/
protected final <X> void render(Context context, C value, SafeHtmlBuilder sb, HasCell<C, X> hasCell) {
throw new IllegalStateException("Please do not call this overload of render(). Use the overload with an id."); //$NON-NLS-1$
}
/**
* Render the cell. Using the value, the id, and the context, append some HTML to the
* SafeHtmlBuilder that will show in the cell when it is rendered.
*
* Override this and use the id in your render.
*
* @see org.ovirt.engine.ui.common.widget.table.cell.Cell#render(com.google.gwt.cell.client.Cell.Context, java.lang.Object, com.google.gwt.safehtml.shared.SafeHtmlBuilder, java.lang.String)
*/
public void render(Context context, C value, SafeHtmlBuilder sb, String id) {
int i = 1;
for (HasCell<C, ?> hasCell : hasCells) {
render(context, value, sb, hasCell, id + "_" + i); //$NON-NLS-1$
i++;
}
}
// TODO-GWT: copied from GWT CompositeCell, with ID injected. Keep in sync on GWT upgrade.
protected <X> void render(Context context, C value, SafeHtmlBuilder sb, HasCell<C, X> hasCell, String id) {
com.google.gwt.cell.client.Cell<X> _cell = hasCell.getCell();
if (_cell instanceof Cell) {
Cell<X> cell = (Cell<X>) _cell; // cast from GWT Cell to our Cell impl
sb.appendHtmlConstant("<span id=\"" + id + "\">"); //$NON-NLS-1$ //$NON-NLS-2$
cell.render(context, hasCell.getValue(value), sb, id);
sb.appendHtmlConstant("</span>"); //$NON-NLS-1$
} else {
throw new IllegalStateException("CompositeCell cannot render Cells that do not implement " //$NON-NLS-1$
+ Cell.class.getName());
}
}
public void setElementIdPrefix(String elementIdPrefix) {
this.elementIdPrefix = elementIdPrefix;
}
public void setColumnId(String columnId) {
this.columnId = columnId;
}
public String getElementIdPrefix() {
return elementIdPrefix;
}
public String getColumnId() {
return columnId;
}
}