/******************************************************************************* * Copyright (c) 2008 Pierre-Antoine Grégoire. * 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: * Pierre-Antoine Grégoire - initial API and implementation *******************************************************************************/ package org.org.eclipse.cheatsheet.catalog.internal.views; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.window.ToolTip; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.forms.FormColors; import org.eclipse.ui.forms.IFormColors; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.forms.widgets.FormToolkit; import org.org.eclipse.cheatsheet.catalog.internal.model.CheatSheetCatalog; import org.org.eclipse.cheatsheet.catalog.internal.model.CheatSheetCategory; import org.org.eclipse.cheatsheet.catalog.internal.model.CheatSheetReference; import org.org.model.IModelItem; /** */ @SuppressWarnings("rawtypes") public class CheatCheatCatalogViewToolTip extends ToolTip { private static final String LINE_FEED = "\n"; private final static int X_SHIFT; static { if ("gtk".equals(SWT.getPlatform()) || "carbon".equals(SWT.getPlatform())) { X_SHIFT = -26; } else { X_SHIFT = -23; } } private final static int Y_SHIFT = 1; private IModelItem currentTipElement; private final List<CheatSheetCatalogViewToolTipListener> listeners = new ArrayList<CheatSheetCatalogViewToolTipListener>(); private boolean visible; private boolean triggeredByMouse; private final Control control; public CheatCheatCatalogViewToolTip(Control control) { super(control); this.control = control; setShift(new Point(1, 1)); } public void dispose() { hide(); } @Override protected void afterHideToolTip(Event event) { triggeredByMouse = true; visible = false; for (CheatSheetCatalogViewToolTipListener listener : listeners.toArray(new CheatSheetCatalogViewToolTipListener[0])) { listener.toolTipHidden(event); } } public void addTaskListToolTipListener(CheatSheetCatalogViewToolTipListener listener) { listeners.add(listener); } public void removeTaskListToolTipListener(CheatSheetCatalogViewToolTipListener listener) { listeners.remove(listener); } private IModelItem getViewElement(Object hoverObject) { if (hoverObject instanceof Widget) { Object data = ((Widget) hoverObject).getData(); if (data != null) { if (data instanceof IModelItem) { return (IModelItem) data; } else if (data instanceof IAdaptable) { return (IModelItem) ((IAdaptable) data).getAdapter(IModelItem.class); } } } return null; } private String getTitleText(IModelItem element) { StringBuilder sb = new StringBuilder(); if (element instanceof CheatSheetCatalog) { CheatSheetCatalog catalog = (CheatSheetCatalog) element; sb.append(catalog.getName()); } else if (element instanceof CheatSheetCategory) { CheatSheetCategory category = (CheatSheetCategory) element; sb.append(category.getName()); } else if (element instanceof CheatSheetReference) { CheatSheetReference reference = (CheatSheetReference) element; sb.append(reference.getName()); } return sb.toString(); } private String getDetailsText(IModelItem element) { StringBuilder sb = new StringBuilder(); if (element instanceof CheatSheetCatalog) { CheatSheetCatalog catalog = (CheatSheetCatalog) element; sb.append("<b>Provider:</b> " + catalog.getName() + LINE_FEED); if (catalog.getDescription() != null && !catalog.getDescription().trim().equals("")) { sb.append("<b>Description:</b> " + catalog.getDescription() + LINE_FEED); } if (catalog.getReference() != null) { sb.append("<b>Reference CheatSheetReferenceType:</b> " + catalog.getReference().getReferenceType() + LINE_FEED); sb.append("<b>Reference Url:</b> " + LINE_FEED + catalog.getReference().getUri() + LINE_FEED); } sb.append("<b>Locked:</b> " + catalog.getReadOnly() + LINE_FEED); } else if (element instanceof CheatSheetCategory) { CheatSheetCategory category = (CheatSheetCategory) element; sb.append("<b>UID:</b> " + category.getUID()); } else if (element instanceof CheatSheetReference) { CheatSheetReference reference = (CheatSheetReference) element; if (reference.getDescription() != null && !reference.getDescription().trim().equals("")) { sb.append("<b>Description:</b> " + reference.getDescription() + LINE_FEED); } sb.append("<b>Url:</b> " + LINE_FEED + reference.getUrl() + LINE_FEED); sb.append("<b>Tags:</b> " + reference.getTags() + LINE_FEED); } return sb.toString(); } @Override public Point getLocation(Point tipSize, Event event) { Widget widget = getTipWidget(event); if (widget != null) { Rectangle bounds = getBounds(widget); if (bounds != null) { return control.toDisplay(bounds.x + X_SHIFT, bounds.y + bounds.height + Y_SHIFT); } } return super.getLocation(tipSize, event);// control.toDisplay(event.x + xShift, event.y + yShift); } private Image getImage(IModelItem element) { return new ViewLabelProvider().getImage(element); } protected Widget getTipWidget(Event event) { Point widgetPosition = new Point(event.x, event.y); Widget widget = event.widget; if (widget instanceof ToolBar) { ToolBar w = (ToolBar) widget; return w.getItem(widgetPosition); } if (widget instanceof Table) { Table w = (Table) widget; return w.getItem(widgetPosition); } if (widget instanceof Tree) { Tree w = (Tree) widget; return w.getItem(widgetPosition); } return widget; } private Rectangle getBounds(Widget widget) { if (widget instanceof ToolItem) { ToolItem w = (ToolItem) widget; return w.getBounds(); } if (widget instanceof TableItem) { TableItem w = (TableItem) widget; return w.getBounds(); } if (widget instanceof TreeItem) { TreeItem w = (TreeItem) widget; return w.getBounds(); } return null; } @Override protected boolean shouldCreateToolTip(Event event) { currentTipElement = null; if (super.shouldCreateToolTip(event)) { Widget tipWidget = getTipWidget(event); if (tipWidget != null) { currentTipElement = getViewElement(tipWidget); } } if (currentTipElement == null) { hide(); return false; } else { return true; } } @Override protected Composite createToolTipContentArea(Event event, Composite parent) { assert currentTipElement != null; FormToolkit toolkit = createToolTipContentAreaToolkit(parent); Form form = addIconAndLabel(parent, toolkit, getImage(currentTipElement), getTitleText(currentTipElement)); String detailsText = getDetailsText(currentTipElement); if (detailsText != null) { addDetails(parent, toolkit, form, detailsText); } visible = true; return form; } private void addDetails(Composite parent, FormToolkit toolkit, Form form, String detailsText) { // create the text for user information FormText text = toolkit.createFormText(form.getBody(), true); GridData td = new GridData(); td.horizontalSpan = 2; td.heightHint = 200; td.widthHint = 400; text.setLayoutData(td); detailsText = removeTrailingNewline(detailsText); detailsText = escapeLabelText(detailsText); detailsText = replaceLineFeedWithFormTags(detailsText); text.setText("<form><p>" + detailsText + "</p></form>", true, false); } private String replaceLineFeedWithFormTags(String detailsText) { return detailsText.replaceAll("\n", "</p><p>"); } protected FormToolkit createToolTipContentAreaToolkit(Composite parent) { FormToolkit toolkit = new FormToolkit(parent.getDisplay()); return toolkit; } private String removeTrailingNewline(String text) { if (text.endsWith(LINE_FEED)) { return text.substring(0, text.length() - 1); } return text; } protected Form addIconAndLabel(Composite parent, FormToolkit toolkit, Image image, String titleText) { FormColors colors = toolkit.getColors(); Color top = colors.getColor(IFormColors.H_GRADIENT_END); Color bot = colors.getColor(IFormColors.H_GRADIENT_START); // create the base form Form form = toolkit.createForm(parent); form.setText(titleText); form.setImage(image); form.setTextBackground(new Color[] { top, bot }, new int[] { 100 }, true); GridLayout layout = new GridLayout(); layout.numColumns = 3; form.getBody().setLayout(layout); return form; } private String escapeLabelText(String text) { return (text != null) ? text.replace("&", "&&") : null; // mask & from SWT } public static interface CheatSheetCatalogViewToolTipListener { void toolTipHidden(Event event); } public boolean isVisible() { return visible; } public boolean isTriggeredByMouse() { return triggeredByMouse; } @Override public void show(Point location) { super.show(location); triggeredByMouse = false; } }