/*******************************************************************************
* Copyright (c) 2012, 2013 Original authors and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Original authors and others - initial API and implementation
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.tooltip;
import org.eclipse.jface.window.DefaultToolTip;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.cell.CellDisplayConversionUtils;
import org.eclipse.nebula.widgets.nattable.layer.cell.ILayerCell;
import org.eclipse.nebula.widgets.nattable.painter.cell.CellPainterWrapper;
import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.PasswordTextPainter;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Event;
/**
* {@link ToolTip} implementation for the {@link NatTable} which will show the
* display value of the cell of which the tooltip is requested.
* <p>
* It is possible to configure for which regions the tooltips should be
* activated. If none are configured, the tooltips are active for every region
* of the {@link NatTable}.
*
* @author Dirk Fauth
* @version 1.0.0
*/
public class NatTableContentTooltip extends DefaultToolTip {
/**
* The {@link NatTable} instance for which this {@link ToolTip} is used.
*/
protected NatTable natTable;
/**
* The regions of the {@link NatTable} for which this {@link ToolTip} is
* active.
*/
protected String[] tooltipRegions;
/**
* Creates a new {@link ToolTip} object, attaches it to the given
* {@link NatTable} instance and configures and activates it.
*
* @param natTable
* The {@link NatTable} instance for which this {@link ToolTip}
* is used.
* @param tooltipRegions
* The regions of the {@link NatTable} for which this
* {@link ToolTip} is active. If none are given, the tooltip will
* be active for all regions.
*/
public NatTableContentTooltip(NatTable natTable, String... tooltipRegions) {
super(natTable, ToolTip.NO_RECREATE, false);
setPopupDelay(500);
setShift(new Point(10, 10));
activate();
this.natTable = natTable;
this.tooltipRegions = tooltipRegions;
}
/**
* {@inheritDoc}
*
* <p>
* Implementation here means the tooltip is not redrawn unless mouse hover
* moves outside of the current cell (the combination of ToolTip.NO_RECREATE
* style and override of this method).
*/
@Override
protected Object getToolTipArea(Event event) {
int col = this.natTable.getColumnPositionByX(event.x);
int row = this.natTable.getRowPositionByY(event.y);
return new Point(col, row);
}
/**
* {@inheritDoc}
*
* <p>
* Evaluates the cell for which the tooltip should be rendered and checks
* the display value. If the display value is empty <code>null</code> will
* be returned which will result in not showing a tooltip.
*/
@Override
protected String getText(Event event) {
int col = this.natTable.getColumnPositionByX(event.x);
int row = this.natTable.getRowPositionByY(event.y);
ILayerCell cell = this.natTable.getCellByPosition(col, row);
if (cell != null) {
// if the registered cell painter is the PasswordCellPainter, there
// will be no tooltip
ICellPainter painter = this.natTable.getConfigRegistry()
.getConfigAttribute(CellConfigAttributes.CELL_PAINTER,
DisplayMode.NORMAL,
cell.getConfigLabels().getLabels());
if (isVisibleContentPainter(painter)) {
String tooltipValue = CellDisplayConversionUtils
.convertDataType(cell, this.natTable.getConfigRegistry());
if (tooltipValue.length() > 0) {
return tooltipValue;
}
}
}
return null;
}
/**
* Checks if the given {@link ICellPainter} is showing the content directly
* or if it is anonymized by using the {@link PasswordTextPainter}
*
* @param painter
* The {@link ICellPainter} to check.
* @return <code>true</code> if the painter is not a
* {@link PasswordTextPainter}
*/
protected boolean isVisibleContentPainter(ICellPainter painter) {
if (painter instanceof PasswordTextPainter) {
return false;
} else if (painter instanceof CellPainterWrapper) {
return isVisibleContentPainter(((CellPainterWrapper) painter)
.getWrappedPainter());
}
return true;
}
/**
* {@inheritDoc}
*
* <p>
* Will only display a tooltip if the value of the cell for which the
* tooltip should be rendered is not empty.
* <p>
* If there are regions configured for which the tooltip should be visible,
* it is also checked if the the region for which the tooltip should be
* rendered is in one of the configured tooltip regions.
*/
@Override
protected boolean shouldCreateToolTip(Event event) {
// check the region?
boolean regionCheckPassed = false;
if (this.tooltipRegions.length > 0) {
LabelStack regionLabels = this.natTable.getRegionLabelsByXY(event.x,
event.y);
if (regionLabels != null) {
for (String label : this.tooltipRegions) {
if (regionLabels.hasLabel(label)) {
regionCheckPassed = true;
break;
}
}
}
} else {
regionCheckPassed = true;
}
if (regionCheckPassed && getText(event) != null) {
return super.shouldCreateToolTip(event);
}
return false;
}
}