]> source.dussan.org Git - vaadin-framework.git/commitdiff
Added tooltips to Table cells and rows (ItemDescriptionGenerator) + Testbench test...
authorJohn Alhroos <john.ahlroos@itmill.com>
Mon, 15 Aug 2011 13:50:27 +0000 (13:50 +0000)
committerJohn Alhroos <john.ahlroos@itmill.com>
Mon, 15 Aug 2011 13:50:27 +0000 (13:50 +0000)
svn changeset:20392/svn branch:6.7

src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
src/com/vaadin/ui/AbstractSelect.java
src/com/vaadin/ui/Table.java
tests/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.java [new file with mode: 0644]
tests/src/com/vaadin/tests/components/table/TableTooltips.html [new file with mode: 0644]

index 2e4b2fc9482a09784b9b941419be33a60f7cbaeb..d4e09ba1a9da78d6e994b94c37ed6284931f6026 100644 (file)
@@ -63,9 +63,11 @@ import com.vaadin.terminal.gwt.client.Focusable;
 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;
@@ -4039,7 +4041,14 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
 
         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);
@@ -4281,7 +4290,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 setElement(rowElement);
                 DOM.sinkEvents(getElement(), Event.MOUSEEVENTS
                         | Event.TOUCHEVENTS | Event.ONDBLCLICK
-                        | Event.ONCONTEXTMENU);
+                        | Event.ONCONTEXTMENU | VTooltip.TOOLTIP_EVENTS);
             }
 
             /**
@@ -4387,6 +4396,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 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;
@@ -4416,10 +4431,15 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                         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);
@@ -4444,7 +4464,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
             }
 
             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();
@@ -4473,6 +4498,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                         break;
                     }
                 }
+                
+                if(description != null && client != null){
+                         TooltipInfo info = new TooltipInfo(description);
+                         client.registerTooltip(VScrollTable.this, td, info);                  
+                }
+                                                              
                 td.appendChild(container);
                 getElement().appendChild(td);
             }
@@ -4572,6 +4603,37 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                 }
             }
 
+            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
              */
@@ -4596,6 +4658,10 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
                     }
 
                     boolean targetCellOrRowFound = targetTdOrTr != null;
+                    if(targetCellOrRowFound){
+                        handleTooltips(event, targetTdOrTr);                    
+                    }
+                    
                     switch (type) {
                     case Event.ONDBLCLICK:
                         if (targetCellOrRowFound) {
index b2d1bedbeddc4e721b00fdc40d2b2d71ff7bffb4..f80fe7058009959fb1b2940aea20f8ae28541a11 100644 (file)
@@ -1931,4 +1931,23 @@ public abstract class AbstractSelect extends AbstractField implements
         }
     }
 
+    /**
+     * 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);
+    }        
 }
index 5cdb2118a4331edb849ec42b45638af7d28842ae..d9446de5d1773e741e4416178a22f56f26959ee8 100644 (file)
@@ -46,6 +46,7 @@ import com.vaadin.terminal.Resource;
 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>
@@ -378,6 +379,11 @@ public class Table extends AbstractSelect implements Action.Container,
      * 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
@@ -2862,7 +2868,8 @@ public class Table extends AbstractSelect implements Action.Container,
                     target.addAttribute("style-" + columnIdMap.key(columnId),
                             cellStyle);
                 }
-            }
+            }           
+            
             if ((iscomponent[currentColumn] || iseditable)
                     && Component.class.isInstance(cells[CELL_FIRSTCOL
                             + currentColumn][indexInRowbuffer])) {
@@ -2870,16 +2877,36 @@ public class Table extends AbstractSelect implements Action.Container,
                         + 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,
@@ -2921,8 +2948,11 @@ public class Table extends AbstractSelect implements Action.Container,
             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,
@@ -4547,5 +4577,24 @@ public class Table extends AbstractSelect implements Action.Container,
         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;
+    }
 
 }
diff --git a/tests/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.java b/tests/src/com/vaadin/tests/components/table/TableItemDescriptionGeneratorTest.java
new file mode 100644 (file)
index 0000000..2f53b91
--- /dev/null
@@ -0,0 +1,75 @@
+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;
+    }
+
+}
diff --git a/tests/src/com/vaadin/tests/components/table/TableTooltips.html b/tests/src/com/vaadin/tests/components/table/TableTooltips.html
new file mode 100644 (file)
index 0000000..989fb86
--- /dev/null
@@ -0,0 +1,77 @@
+<?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>