* Allow configuring content modes for Grid cell tooltipstags/8.3.2
@@ -55,6 +55,7 @@ import com.vaadin.client.ui.layout.ElementResizeListener; | |||
import com.vaadin.shared.MouseEventDetails; | |||
import com.vaadin.shared.data.sort.SortDirection; | |||
import com.vaadin.shared.ui.Connect; | |||
import com.vaadin.shared.ui.ContentMode; | |||
import com.vaadin.v7.client.connectors.RpcDataSourceConnector.DetailsListener; | |||
import com.vaadin.v7.client.connectors.RpcDataSourceConnector.RpcDataSource; | |||
import com.vaadin.v7.client.widget.escalator.events.RowHeightChangedEvent; | |||
@@ -1301,10 +1302,12 @@ public class GridConnector extends AbstractHasComponentsConnector | |||
.getObject(GridState.JSONKEY_CELLDESCRIPTION); | |||
if (cellDescriptions != null && cellDescriptions.hasKey(c.id)) { | |||
return new TooltipInfo(cellDescriptions.getString(c.id)); | |||
return createCellTooltipInfo(cellDescriptions.getString(c.id), | |||
getState().cellTooltipContentMode); | |||
} else if (row.hasKey(GridState.JSONKEY_ROWDESCRIPTION)) { | |||
return new TooltipInfo( | |||
row.getString(GridState.JSONKEY_ROWDESCRIPTION)); | |||
return createCellTooltipInfo( | |||
row.getString(GridState.JSONKEY_ROWDESCRIPTION), | |||
getState().rowTooltipContentMode); | |||
} else { | |||
return null; | |||
} | |||
@@ -1313,6 +1316,12 @@ public class GridConnector extends AbstractHasComponentsConnector | |||
return super.getTooltipInfo(element); | |||
} | |||
private static TooltipInfo createCellTooltipInfo(String text, | |||
ContentMode contentMode) { | |||
TooltipInfo info = new TooltipInfo(text); | |||
info.setContentMode(contentMode); | |||
return info; | |||
} | |||
@Override | |||
protected void sendContextClickEvent(MouseEventDetails details, | |||
EventTarget eventTarget) { |
@@ -58,6 +58,7 @@ import com.vaadin.server.VaadinSession; | |||
import com.vaadin.shared.MouseEventDetails; | |||
import com.vaadin.shared.Registration; | |||
import com.vaadin.shared.data.sort.SortDirection; | |||
import com.vaadin.shared.ui.ContentMode; | |||
import com.vaadin.shared.ui.ErrorLevel; | |||
import com.vaadin.shared.util.SharedUtil; | |||
import com.vaadin.ui.AbstractComponent; | |||
@@ -6719,21 +6720,47 @@ public class Grid extends AbstractComponent | |||
* optional descriptions (tooltips) for individual Grid cells. If a | |||
* {@link RowDescriptionGenerator} is also set, the row description it | |||
* generates is displayed for cells for which {@code generator} returns | |||
* null. | |||
* <code>null</code>. | |||
* <p> | |||
* | |||
* @param generator | |||
* the description generator to use or {@code null} to remove a | |||
* previously set generator if any | |||
* the description generator to use or <code>null</code> to | |||
* remove a previously set generator if any | |||
* | |||
* @see #setCellDescriptionGenerator(CellDescriptionGenerator, ContentMode) | |||
* @see #setRowDescriptionGenerator(RowDescriptionGenerator) | |||
* | |||
* @since 7.6 | |||
*/ | |||
public void setCellDescriptionGenerator( | |||
CellDescriptionGenerator generator) { | |||
public void setCellDescriptionGenerator(CellDescriptionGenerator generator) { | |||
setCellDescriptionGenerator(generator, ContentMode.PREFORMATTED); | |||
} | |||
/** | |||
* Sets the {@code CellDescriptionGenerator} instance and content mode for | |||
* generating optional descriptions (tooltips) for individual Grid cells. If | |||
* a {@link RowDescriptionGenerator} is also set, the row description it | |||
* generates is displayed for cells for which {@code generator} returns | |||
* <code>null</code>. | |||
* | |||
* @param generator | |||
* the description generator to use or <code>null</code> to | |||
* remove a previously set generator if any | |||
* @param contentMode | |||
* the content mode for cell tooltips, not <code>null</code> | |||
* @see #setRowDescriptionGenerator(RowDescriptionGenerator) | |||
* | |||
* @since | |||
*/ | |||
public void setCellDescriptionGenerator(CellDescriptionGenerator generator, | |||
ContentMode contentMode) { | |||
if (contentMode == null) { | |||
throw new IllegalArgumentException("Content mode cannot be null"); | |||
} | |||
cellDescriptionGenerator = generator; | |||
getState().hasDescriptions = (generator != null | |||
|| rowDescriptionGenerator != null); | |||
getState().hasDescriptions = (generator != null || rowDescriptionGenerator != null); | |||
getState().cellTooltipContentMode = contentMode; | |||
datasourceExtension.refreshCache(); | |||
} | |||
@@ -6749,29 +6776,78 @@ public class Grid extends AbstractComponent | |||
return cellDescriptionGenerator; | |||
} | |||
/** | |||
* Gets the content mode used for cell descriptions. | |||
* | |||
* @return the content mode used for cell descriptions, not | |||
* <code>null</code> | |||
* @see #setCellDescriptionGenerator(CellDescriptionGenerator, ContentMode) | |||
* @since | |||
*/ | |||
public ContentMode getCellDescriptionContentMode() { | |||
return getState(false).cellTooltipContentMode; | |||
} | |||
/** | |||
* Sets the {@code RowDescriptionGenerator} instance for generating optional | |||
* descriptions (tooltips) for Grid rows. If a | |||
* {@link CellDescriptionGenerator} is also set, the row description | |||
* generated by {@code generator} is used for cells for which the cell | |||
* description generator returns null. | |||
* | |||
* description generator returns <code>null</code>. | |||
* | |||
* @param generator | |||
* the description generator to use or {@code null} to remove a | |||
* previously set generator if any | |||
* the description generator to use or <code>null</code> to | |||
* remove a previously set generator if any | |||
* | |||
* @see #setRowDescriptionGenerator(RowDescriptionGenerator, ContentMode) | |||
* @see #setCellDescriptionGenerator(CellDescriptionGenerator) | |||
* | |||
* @since 7.6 | |||
*/ | |||
public void setRowDescriptionGenerator(RowDescriptionGenerator generator) { | |||
setRowDescriptionGenerator(generator, ContentMode.PREFORMATTED ); | |||
} | |||
/** | |||
* Sets the {@code RowDescriptionGenerator} instance for generating optional | |||
* descriptions (tooltips) for Grid rows. If a | |||
* {@link CellDescriptionGenerator} is also set, the row description | |||
* generated by {@code generator} is used for cells for which the cell | |||
* description generator returns <code>null</code>. | |||
* | |||
* @param generator | |||
* the description generator to use or <code>null</code> to | |||
* remove a previously set generator if any | |||
* @param contentMode | |||
* the content mode for row tooltips, not <code>null</code> | |||
* | |||
* @see #setCellDescriptionGenerator(CellDescriptionGenerator) | |||
* | |||
* @since | |||
*/ | |||
public void setRowDescriptionGenerator(RowDescriptionGenerator generator, | |||
ContentMode contentMode) { | |||
if (contentMode == null) { | |||
throw new IllegalArgumentException("Content mode cannot be null"); | |||
} | |||
rowDescriptionGenerator = generator; | |||
getState().hasDescriptions = (generator != null | |||
|| cellDescriptionGenerator != null); | |||
getState().rowTooltipContentMode = contentMode; | |||
datasourceExtension.refreshCache(); | |||
} | |||
/** | |||
* Gets the content mode used for row descriptions. | |||
* | |||
* @return the content mode used for row descriptions, not <code>null</code> | |||
* @see #setRowDescriptionGenerator(RowDescriptionGenerator, ContentMode) | |||
* @since | |||
*/ | |||
public ContentMode getRowDescriptionContentMode() { | |||
return getState(false).rowTooltipContentMode; | |||
} | |||
/** | |||
* Returns the {@code RowDescriptionGenerator} instance used to generate | |||
* descriptions (tooltips) for Grid rows. |
@@ -21,6 +21,7 @@ import java.util.List; | |||
import com.vaadin.shared.annotations.DelegateToWidget; | |||
import com.vaadin.shared.data.sort.SortDirection; | |||
import com.vaadin.shared.ui.ContentMode; | |||
import com.vaadin.shared.ui.TabIndexState; | |||
/** | |||
@@ -210,4 +211,18 @@ public class GridState extends TabIndexState { | |||
@DelegateToWidget | |||
public boolean columnReorderingAllowed; | |||
/** | |||
* The content mode used for cell tooltips. | |||
* | |||
* @since | |||
*/ | |||
public ContentMode cellTooltipContentMode = ContentMode.PREFORMATTED; | |||
/** | |||
* The content mode used for row tooltips. | |||
* | |||
* @since | |||
*/ | |||
public ContentMode rowTooltipContentMode = ContentMode.PREFORMATTED; | |||
} |
@@ -30,6 +30,7 @@ import java.util.Random; | |||
import com.vaadin.annotations.Theme; | |||
import com.vaadin.shared.data.sort.SortDirection; | |||
import com.vaadin.shared.ui.ContentMode; | |||
import com.vaadin.tests.components.AbstractComponentTest; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Button.ClickEvent; | |||
@@ -138,7 +139,7 @@ public class GridBasicFeatures extends AbstractComponentTest<Grid> { | |||
@Override | |||
public String getDescription(RowReference row) { | |||
return "Row tooltip for row " + row.getItemId(); | |||
return "<b>Row</b> tooltip\n for row " + row.getItemId(); | |||
} | |||
}; | |||
@@ -147,7 +148,7 @@ public class GridBasicFeatures extends AbstractComponentTest<Grid> { | |||
@Override | |||
public String getDescription(CellReference cell) { | |||
if ("Column 0".equals(cell.getPropertyId())) { | |||
return "Cell tooltip for row " + cell.getItemId() | |||
return "<b>Cell</b> tooltip\n for row " + cell.getItemId() | |||
+ ", column 0"; | |||
} else { | |||
return null; | |||
@@ -668,22 +669,40 @@ public class GridBasicFeatures extends AbstractComponentTest<Grid> { | |||
} | |||
}); | |||
createBooleanAction("Row description generator", "State", false, | |||
new Command<Grid, Boolean>() { | |||
LinkedHashMap<String, ContentMode> contentModes = new LinkedHashMap<String, ContentMode>(); | |||
contentModes.put("None", null); | |||
// Abusing an unused value for this special case | |||
contentModes.put("Plain text", ContentMode.TEXT); | |||
contentModes.put("Preformatted(Default)", ContentMode.PREFORMATTED); | |||
contentModes.put("HTML", ContentMode.HTML); | |||
createSelectAction("Row description generator", "State", contentModes, | |||
"None", new Command<Grid, ContentMode>() { | |||
@Override | |||
public void execute(Grid c, Boolean value, Object data) { | |||
c.setRowDescriptionGenerator( | |||
value ? rowDescriptionGenerator : null); | |||
public void execute(Grid grid, ContentMode mode, Object data) { | |||
if (mode == null) { | |||
grid.setRowDescriptionGenerator(null); | |||
} else if (mode == ContentMode.PREFORMATTED) { | |||
grid.setRowDescriptionGenerator(rowDescriptionGenerator); | |||
} else { | |||
grid.setRowDescriptionGenerator( | |||
rowDescriptionGenerator, mode); | |||
} | |||
} | |||
}); | |||
createBooleanAction("Cell description generator", "State", false, | |||
new Command<Grid, Boolean>() { | |||
createSelectAction("Cell description generator", "State", | |||
contentModes, "None", new Command<Grid, ContentMode>() { | |||
@Override | |||
public void execute(Grid c, Boolean value, Object data) { | |||
c.setCellDescriptionGenerator( | |||
value ? cellDescriptionGenerator : null); | |||
public void execute(Grid grid, ContentMode mode, Object data) { | |||
if (mode == null) { | |||
grid.setCellDescriptionGenerator(null); | |||
} else if (mode == ContentMode.PREFORMATTED) { | |||
grid.setCellDescriptionGenerator(cellDescriptionGenerator); | |||
} else { | |||
grid.setCellDescriptionGenerator( | |||
cellDescriptionGenerator, mode); | |||
} | |||
} | |||
}); | |||
@@ -16,6 +16,7 @@ | |||
package com.vaadin.v7.tests.components.grid.basicfeatures; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertFalse; | |||
import static org.junit.Assert.assertTrue; | |||
import java.util.List; | |||
@@ -75,6 +76,88 @@ public class GridDescriptionGeneratorTest extends GridBasicFeaturesTest { | |||
assertEquals("Tooltip text", "Row tooltip for row 5", tooltipText); | |||
} | |||
@Test | |||
public void testContentTypes() { | |||
openTestURL(); | |||
selectCellGenerator("Default"); | |||
showCellTooltip(1, 0); | |||
/* | |||
* When porting this to the v7 version in Framework 8, the default | |||
* should be changed to PREFORMATTED to preserve the more secure default | |||
* that has accidentally been used there. | |||
*/ | |||
assertHtmlTooltipShown(); | |||
selectRowGenerator("Default"); | |||
showCellTooltip(1, 1); | |||
/* | |||
* When porting this to the v7 version in Framework 8, the default | |||
* should be changed to PREFORMATTED to preserve the more secure default | |||
* that has accidentally been used there. | |||
*/ | |||
assertHtmlTooltipShown(); | |||
selectCellGenerator("Plain text"); | |||
showCellTooltip(2, 0); | |||
assertPlainTooltipShown(); | |||
selectRowGenerator("Plain text"); | |||
showCellTooltip(2, 1); | |||
assertPlainTooltipShown(); | |||
selectCellGenerator("Preformatted"); | |||
showCellTooltip(3, 0); | |||
assertPreTooltipShown(); | |||
selectRowGenerator("Preformatted"); | |||
showCellTooltip(3, 1); | |||
assertPreTooltipShown(); | |||
selectCellGenerator("HTML"); | |||
showCellTooltip(4, 0); | |||
assertHtmlTooltipShown(); | |||
selectRowGenerator("HTML"); | |||
showCellTooltip(4, 1); | |||
assertHtmlTooltipShown(); | |||
} | |||
private void assertPreTooltipShown() { | |||
assertTrue("Tooltip should contain <b> as text", getTooltipText() | |||
.contains("<b>")); | |||
assertTrue("Tooltip should contain a newline", getTooltipText() | |||
.contains("\n")); | |||
} | |||
private void assertPlainTooltipShown() { | |||
assertTrue("Tooltip should contain <b> as text", getTooltipText() | |||
.contains("<b>")); | |||
assertFalse("Tooltip should not contain a newline", getTooltipText() | |||
.contains("\n")); | |||
} | |||
private void assertHtmlTooltipShown() { | |||
assertTrue("Tooltip should contain <b> tag", | |||
isElementPresent(By.cssSelector(".v-tooltip-text b"))); | |||
} | |||
private void showCellTooltip(int row, int col) { | |||
getGridElement().getCell(row, col).showTooltip(); | |||
} | |||
private void selectCellGenerator(String name) { | |||
selectMenuPath("Component", "State", "Cell description generator", name); | |||
} | |||
private void selectRowGenerator(String name) { | |||
selectMenuPath("Component", "State", "Row description generator", name); | |||
} | |||
private String getTooltipText() { | |||
return findElement(By.className("v-tooltip-text")).getText(); | |||
} | |||
@Override | |||
public List<DesiredCapabilities> getBrowsersToTest() { | |||
return getBrowsersExcludingFirefox(); |