/** * ClippedCellToolTip.java * Created on Jul 3, 2015 * * Copyright (c) 2015 Wind River Systems, Inc. * * The right to copy, distribute, modify, or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. */ package org.eclipse.tcf.te.ui.jface.tooltips; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.viewers.ColumnViewer; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.jface.window.DefaultToolTip; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.ScrollBar; /** * A tooltip which shows the full content of clipped viewer cell text. */ public class ClippedCellToolTip extends DefaultToolTip { @SuppressWarnings("unused") public static void enableFor(ColumnViewer viewer) { if (Platform.OS_WIN32.equals(Platform.getOS())) return; new ClippedCellToolTip(viewer, NO_RECREATE); } private final ColumnViewer fViewer; /** * Constructor. * @param viewer * @param style */ protected ClippedCellToolTip(ColumnViewer viewer, int style) { super(viewer.getControl(), style, false); fViewer = viewer; } @Override protected Object getToolTipArea(Event event) { return fViewer.getCell(new Point(event.x, event.y)); } @Override protected boolean shouldCreateToolTip(Event event) { if (!super.shouldCreateToolTip(event)) return false; ColumnViewer viewer = fViewer; Point point = new Point(event.x, event.y); ViewerCell cell = viewer.getCell(point); if (cell == null) return false; String text = cell.getText(); Rectangle cellBounds = cell.getBounds(); Rectangle textBounds = cell.getTextBounds(); int maxWidth = textBounds != null ? textBounds.width : cellBounds.width; GC gc = new GC(viewer.getControl()); gc.setFont(cell.getFont()); int width = gc.textExtent(text).x; gc.dispose(); if (width <= maxWidth) { // test against viewer bounds int cellMargin = cellBounds.x + width + 4; Rectangle viewerBounds = viewer.getControl().getBounds(); int viewerMargin = viewerBounds.x + viewerBounds.width - 4; ScrollBar vsb = null; if (viewer instanceof TableViewer) vsb = ((TableViewer) viewer).getTable().getVerticalBar(); else if (viewer instanceof TreeViewer) vsb = ((TreeViewer) viewer).getTree().getVerticalBar(); if (vsb != null && vsb.isVisible()) viewerMargin -= vsb.getSize().x; if (cellMargin <= viewerMargin) return false; } setText(wrapText(text)); return true; } @Override protected void afterHideToolTip(Event event) { super.afterHideToolTip(event); if (event != null && event.widget != fViewer.getControl()) { fViewer.getControl().setFocus(); } } private String wrapText(String tooltipText) { StringBuilder buf = new StringBuilder(); final int maxCol = 80; int col = 0; int wordIdx = 0; int breakIdx = 0; int i; for (i = 0; i<tooltipText.length(); ++i) { char c = tooltipText.charAt(i); if (col >= maxCol && c != '\n') { if (breakIdx == wordIdx) { if (wordIdx > 0) buf.append('\n'); buf.append(tooltipText.substring(wordIdx, i)); col = i - wordIdx; wordIdx = i; } else { buf.append(tooltipText.substring(wordIdx, i)); wordIdx = breakIdx = i; } } switch (c) { case ' ': buf.append(tooltipText.substring(wordIdx, i)); buf.append(c); ++col; wordIdx = breakIdx = i+1; continue; case '\n': buf.append(tooltipText.substring(wordIdx, i)); buf.append(c); col = 0; wordIdx = breakIdx = i+1; continue; } ++col; } buf.append(tooltipText.substring(wordIdx, i)); return buf.toString(); } }