import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderSpace;
+import com.vaadin.terminal.gwt.client.TooltipInfo;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VTooltip;
import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
import com.vaadin.terminal.gwt.client.ui.dd.DDUtil;
import com.vaadin.terminal.gwt.client.ui.dd.VAbstractDropHandler;
private void unlinkRowAtIndex(int index) {
final VScrollTableRow toBeRemoved = (VScrollTableRow) renderedRows
- .get(index);
+ .get(index);
+ // Unregister row tooltip
+ client.registerTooltip(VScrollTable.this, toBeRemoved.getElement(), null);
+ for(int i=0; i<toBeRemoved.getElement().getChildCount(); i++){
+ // Unregister cell tooltips
+ Element td = toBeRemoved.getElement().getChild(i).cast();
+ client.registerTooltip(VScrollTable.this, td, null);
+ }
lazyUnregistryBag.add(toBeRemoved);
tBodyElement.removeChild(toBeRemoved.getElement());
orphan(toBeRemoved);
setElement(rowElement);
DOM.sinkEvents(getElement(), Event.MOUSEEVENTS
| Event.TOUCHEVENTS | Event.ONDBLCLICK
- | Event.ONCONTEXTMENU);
+ | Event.ONCONTEXTMENU | VTooltip.TOOLTIP_EVENTS);
}
/**
if (rowStyle != null) {
addStyleName(CLASSNAME + "-row-" + rowStyle);
}
+
+ String rowDescription = uidl.getStringAttribute("rowdescr");
+ if(rowDescription != null && !rowDescription.equals("")) {
+ TooltipInfo info = new TooltipInfo(rowDescription);
+ client.registerTooltip(VScrollTable.this, rowElement, info);
+ }
tHead.getColumnAlignments();
int col = 0;
style = uidl.getStringAttribute("style-" + columnId);
}
+ String description = null;
+ if(uidl.hasAttribute("descr-" + columnId)) {
+ description = uidl.getStringAttribute("descr-"+columnId);
+ }
+
boolean sorted = tHead.getHeaderCell(col).isSorted();
if (cell instanceof String) {
addCell(uidl, cell.toString(), aligns[col++], style,
- false, sorted);
+ false, sorted, description);
} else {
final Paintable cellContent = client
.getPaintable((UIDL) cell);
}
public void addCell(UIDL rowUidl, String text, char align,
- String style, boolean textIsHTML, boolean sorted) {
+ String style, boolean textIsHTML, boolean sorted){
+ addCell(rowUidl, text, align, style, textIsHTML, sorted, null);
+ }
+
+ public void addCell(UIDL rowUidl, String text, char align,
+ String style, boolean textIsHTML, boolean sorted, String description) {
// String only content is optimized by not using Label widget
final Element td = DOM.createTD();
final Element container = DOM.createDiv();
break;
}
}
+
+ if(description != null && client != null){
+ TooltipInfo info = new TooltipInfo(description);
+ client.registerTooltip(VScrollTable.this, td, info);
+ }
+
td.appendChild(container);
getElement().appendChild(td);
}
}
}
+ private void handleTooltips(final Event event, Element target){
+ if(target.hasTagName("TD")){
+ // Table cell (td)
+ Element container = target.getFirstChildElement().cast();
+ Element widget = container.getFirstChildElement().cast();
+
+ boolean containsWidget = false;
+ for(Widget w : childWidgets){
+ if(widget == w.getElement()){
+ containsWidget = true;
+ break;
+ }
+ }
+
+ if(!containsWidget){
+ // Only text nodes has tooltips
+ if(client.getTooltipTitleInfo(VScrollTable.this, target) != null){
+ // Cell has description, use it
+ client.handleTooltipEvent(event, VScrollTable.this, target);
+ } else {
+ // Cell might have row description, use row description
+ client.handleTooltipEvent(event, VScrollTable.this, target.getParentElement());
+ }
+ }
+
+ } else {
+ // Table row (tr)
+ client.handleTooltipEvent(event, VScrollTable.this, target);
+ }
+ }
+
/*
* React on click that occur on content cells only
*/
}
boolean targetCellOrRowFound = targetTdOrTr != null;
+ if(targetCellOrRowFound){
+ handleTooltips(event, targetTdOrTr);
+ }
+
switch (type) {
case Event.ONDBLCLICK:
if (targetCellOrRowFound) {
}
}
+ /**
+ * Implement this interface and pass it to Tree.setCellStyleGenerator or Table.setCellStyleGenerator to
+ * generate mouse over descriptions ("tooltips") for the rows and cells in Table or for the items in Tree.
+ */
+ public interface ItemDescriptionGenerator {
+
+ /**
+ * Called by Table when a cell (and row) is painted or a item is painted in Tree
+ * @param source
+ * The source of the generator, the Tree or Table the generator is attached to
+ * @param itemId
+ * The itemId of the painted cell
+ * @param propertyId
+ * The propertyId of the cell, null when getting row description
+ * @return
+ * The description or "tooltip" of the item.
+ */
+ public String generateDescription(Component source, Object itemId, Object propertyId);
+ }
}
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.ui.VScrollTable;
import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers;
+import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator;
/**
* <p>
* Table cell specific style generator
*/
private CellStyleGenerator cellStyleGenerator = null;
+
+ /**
+ * Table cell specific tooltip generator
+ */
+ private ItemDescriptionGenerator itemDescriptionGenerator;
/*
* EXPERIMENTAL feature: will tell the client to re-calculate column widths
target.addAttribute("style-" + columnIdMap.key(columnId),
cellStyle);
}
- }
+ }
+
if ((iscomponent[currentColumn] || iseditable)
&& Component.class.isInstance(cells[CELL_FIRSTCOL
+ currentColumn][indexInRowbuffer])) {
+ currentColumn][indexInRowbuffer];
if (c == null) {
target.addText("");
+ paintCellTooltips(target, itemId, columnId);
} else {
c.paint(target);
}
} else {
- target.addText((String) cells[CELL_FIRSTCOL + currentColumn][indexInRowbuffer]);
+ target.addText((String) cells[CELL_FIRSTCOL + currentColumn][indexInRowbuffer]);
+ paintCellTooltips(target, itemId, columnId);
}
}
target.endTag("tr");
}
+
+ private void paintCellTooltips(PaintTarget target, Object itemId, Object columnId) throws PaintException {
+ if(itemDescriptionGenerator != null) {
+ String itemDescription = itemDescriptionGenerator.generateDescription(this, itemId, columnId);
+ if(itemDescription != null && !itemDescription.equals("")) {
+ target.addAttribute("descr-" + columnIdMap.key(columnId), itemDescription);
+ }
+ }
+ }
+
+ private void paintRowTooltips(PaintTarget target, Object itemId ) throws PaintException {
+ if(itemDescriptionGenerator != null) {
+ String rowDescription = itemDescriptionGenerator.generateDescription(this, itemId, null);
+ if(rowDescription != null && !rowDescription.equals("")){
+ target.addAttribute("rowdescr", rowDescription);
+ }
+ }
+ }
private void paintRowAttributes(PaintTarget target, final Object[][] cells,
final Set<Action> actionSet, int indexInRowbuffer,
if (rowStyle != null && !rowStyle.equals("")) {
target.addAttribute("rowstyle", rowStyle);
}
- }
- paintRowAttributes(target, itemId);
+ }
+
+ paintRowTooltips(target, itemId);
+
+ paintRowAttributes(target, itemId);
}
protected void paintRowHeader(PaintTarget target, Object[][] cells,
removeListener(VScrollTable.COLUMN_REORDER_EVENT_ID,
ColumnReorderEvent.class, listener);
}
+
+ /**
+ * Set the item description generator which generates tooltips
+ * for cells and rows in the Table
+ *
+ * @param generator
+ * The generator to use or null to disable
+ */
+ public void setItemDescriptionGenerator(ItemDescriptionGenerator generator){
+ itemDescriptionGenerator = generator;
+ }
+
+ /**
+ * Get the item description generator which generates tooltips
+ * for cells and rows in the Table.
+ */
+ public ItemDescriptionGenerator getItemDescriptionGenerator(){
+ return itemDescriptionGenerator;
+ }
}
--- /dev/null
+package com.vaadin.tests.components.table;
+
+import com.vaadin.data.Container;
+import com.vaadin.data.Item;
+import com.vaadin.data.util.IndexedContainer;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator;
+import com.vaadin.ui.TextField;
+
+public class TableItemDescriptionGeneratorTest extends TestBase {
+
+ private final String COLUMN1_PROPERTY_ID = "Text - Cell description";
+ private final String COLUMN2_PROPERTY_ID = "Text - Row description";
+ private final String COLUMN3_PROPERTY_ID = "Widget";
+
+ @Override
+ protected void setup() {
+ final Table table = new Table();
+ table.setDebugId("table");
+ table.setContainerDataSource(createContainer());
+ addComponent(table);
+
+ table.setItemDescriptionGenerator(new ItemDescriptionGenerator() {
+ public String generateDescription(Component source, Object itemId,
+ Object propertyId) {
+ if(propertyId == null){
+ return "Row description "+ itemId;
+ } else if(propertyId == COLUMN1_PROPERTY_ID) {
+ return "Cell description " + itemId +","+propertyId;
+ }
+ return null;
+ }
+ });
+
+ table.addGeneratedColumn(COLUMN3_PROPERTY_ID, new Table.ColumnGenerator() {
+
+ public Component generateCell(Table source, Object itemId, Object columnId) {
+ TextField lbl = new TextField();
+ lbl.setDescription("Textfields own description");
+ return lbl;
+ }
+ });
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Cells and rows should have tooltips";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return 5414;
+ }
+
+ private Container createContainer() {
+ IndexedContainer container = new IndexedContainer();
+ container.addContainerProperty(COLUMN1_PROPERTY_ID, String.class, "");
+ container.addContainerProperty(COLUMN2_PROPERTY_ID, String.class, "");
+ // container.addContainerProperty(COLUMN3_PROPERTY_ID, String.class, "");
+
+ for (int i = 0; i < 5; i++) {
+ Item item = container.addItem("item " + i);
+ item.getItemProperty(COLUMN1_PROPERTY_ID).setValue("first" + i);
+ item.getItemProperty(COLUMN2_PROPERTY_ID).setValue("middle" + i);
+ // item.getItemProperty(COLUMN3_PROPERTY_ID).setValue("last" + i);
+ }
+
+ return container;
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>New Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">New Test</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.table.TableItemDescriptionGeneratorTest?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>showTooltip</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[3]/domChild[0]/domChild[0]</td>
+ <td>57,5</td>
+</tr>
+<tr>
+ <td>pause</td>
+ <td>1000</td>
+ <td>1000</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td>
+ <td>Cell description item 3,Text - Cell description</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[0]</td>
+ <td>810,153</td>
+</tr>
+<tr>
+ <td>showTooltip</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[1]/domChild[1]/domChild[0]</td>
+ <td>57,12</td>
+</tr>
+<tr>
+ <td>pause</td>
+ <td>1000</td>
+ <td>1000</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td>
+ <td>Row description item 1</td>
+</tr>
+<tr>
+ <td>mouseClick</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/domChild[0]/domChild[0]</td>
+ <td>1011,283</td>
+</tr>
+<tr>
+ <td>showTooltip</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::PID_Stable/FocusableScrollPanel[0]/VScrollTable$VScrollTableBody[0]/VScrollTable$VScrollTableBody$VScrollTableRow[4]/VTextField[0]</td>
+ <td>58,10</td>
+</tr>
+<tr>
+ <td>pause</td>
+ <td>1000</td>
+ <td>1000</td>
+</tr>
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestscomponentstableTableItemDescriptionGeneratorTest::Root/VTooltip[0]/FlowPanel[0]/domChild[1]</td>
+ <td>Textfields own description</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>