/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.team.ui; import java.util.Map; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.resource.LocalResourceManager; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerCell; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.window.ToolTip; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; 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.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.IMemento; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.ViewPart; import org.simantics.browsing.ui.swt.ViewArgumentUtils; import org.simantics.db.management.ISessionContext; import org.simantics.db.management.ISessionContextChangedListener; import org.simantics.db.management.ISessionContextProvider; import org.simantics.db.management.SessionContextChangedEvent; import org.simantics.utils.datastructures.disposable.DisposeState; /** * @author Kalle Kondelin */ abstract class TreeView extends ViewPart { protected ISessionContextChangedListener contextChangeListener = new ISessionContextChangedListener() { @Override public void sessionContextChanged(SessionContextChangedEvent event) { sessionContext = event.getNewValue(); } }; protected LocalResourceManager resourceManager; protected Composite parent; protected TreeViewer treeViewer; protected IMemento memento; private Map args; private ISessionContextProvider contextProvider; private ISessionContext sessionContext; private DisposeState disposeState = DisposeState.Alive; public TreeView() { } protected Map getViewArguments() { return args; } protected DisposeState getDisposeState() { return disposeState; } public ISessionContext getSessionContext() { return sessionContext; } public ISessionContextProvider getSessionContextProvider() { return contextProvider; } /** * Invoked when this viewpart is disposed. Unhooks the view from its * ISessionContextProvider. Overriding is allowed but super.dispose() must * be called. * * @see org.eclipse.ui.part.WorkbenchPart#dispose() */ @Override public void dispose() { disposeState = DisposeState.Disposing; try { if (contextProvider != null) { contextProvider.removeContextChangedListener(contextChangeListener); contextProvider = null; } resourceManager.dispose(); resourceManager = null; args = null; sessionContext = null; parent = null; super.dispose(); } finally { disposeState = DisposeState.Disposed; } } @Override public void setFocus() { treeViewer.getTree().setFocus(); } @Override public void init(IViewSite site) throws PartInitException { super.init(site); this.args = ViewArgumentUtils.parseViewArguments(this); } @Override public void init(IViewSite site, IMemento memento) throws PartInitException { super.init(site, memento); this.args = ViewArgumentUtils.parseViewArguments(this); this.memento = memento; } @Override public void saveState(IMemento memento) { if (this.memento != null) { memento.putMemento(this.memento); } // if (explorer != null) // explorer.saveState(memento); } protected static abstract class NameAndDescriptionToolTip extends ToolTip { public NameAndDescriptionToolTip(Control control, int style) { super(control, style, false); } protected abstract Object getModelElement(Event event); /** * Adds logic to only show a tooltip if a meaningful item is under the * cursor. */ protected boolean shouldCreateToolTip(Event event) { if (!super.shouldCreateToolTip(event)) return false; Object tableElement = getModelElement(event); return tableElement != null && tableElement instanceof DisplayElement; } protected Composite createToolTipContentArea(Event event, Composite parent) { Object modelElement = getModelElement(event); Image iconImage = null; String nameString = "no name"; if (modelElement instanceof DisplayElement) { iconImage = null; nameString = ((DisplayElement)modelElement).getIdText(); } // Create the content area Composite composite = new Composite(parent, SWT.NONE); composite.setBackground(parent.getDisplay().getSystemColor( SWT.COLOR_INFO_BACKGROUND)); composite.setLayout(new GridLayout(2, false)); // The title area with the icon (if there is one) and label. Label title = createEntry(composite, iconImage, nameString); // title.setFont(tooltipHeading); GridDataFactory.createFrom((GridData)title.getLayoutData()) .hint(SWT.DEFAULT, SWT.DEFAULT) // .minSize(MIN_TOOLTIP_WIDTH, 1) .applyTo(title); // The description (if there is one) // String descriptionString = "description"; // if (descriptionString != null) // createEntry(composite, null, descriptionString); // Other Content to add addContent(composite, modelElement); return composite; } /** * Adds a line of information to parent. If * icon is not null, an icon is placed on the * left, and then a label with text. * * @param parent * the composite to add the entry to * @param icon * the icon to place next to the text. null for * none. * @param text * the text to display * @return the created label */ protected Label createEntry(Composite parent, Image icon, String text) { if (icon != null) { Label iconLabel = new Label(parent, SWT.NONE); iconLabel.setImage(icon); iconLabel.setBackground(parent.getDisplay().getSystemColor( SWT.COLOR_INFO_BACKGROUND)); iconLabel.setData(new GridData()); } Label textLabel = new Label(parent, SWT.WRAP); if(icon == null) { GridDataFactory.generate(textLabel, 2, 1); } else { GridDataFactory.generate(textLabel, 1, 1); } textLabel.setText(text); textLabel.setBackground(parent.getDisplay().getSystemColor( SWT.COLOR_INFO_BACKGROUND)); return textLabel; } /** * Adds a line of information to parent. If * icon is not null, an icon is placed on the * left, and then a label with text, which supports using * anchor tags to creates links * * @param parent * the composite to add the entry to * @param icon * the icon to place next to the text. null for * none. * @param text * the text to display * @return the created link */ protected Text createEntryWithText(Composite parent, Image icon, String text) { if (icon != null) { Label iconLabel = new Label(parent, SWT.NONE); iconLabel.setImage(icon); iconLabel.setBackground(parent.getDisplay().getSystemColor( SWT.COLOR_INFO_BACKGROUND)); iconLabel.setData(new GridData()); } Text texts = new Text(parent, SWT.READ_ONLY | SWT.MULTI | SWT.V_SCROLL); if(icon == null) { GridDataFactory.generate(texts, 2, 1); } texts.setText(text); texts.setBackground(parent.getDisplay().getSystemColor( SWT.COLOR_INFO_BACKGROUND)); return texts; } protected void addContent(Composite destination, Object modelElement) { } } protected static class ItemDetailToolTip extends NameAndDescriptionToolTip { // private final boolean DEBUG = false; private TreeViewer viewer; private Tree tree; ItemDetailToolTip(TreeViewer viewer, Tree tree, ViewerFilter filter) { super(tree,NO_RECREATE); this.tree = tree; this.viewer = viewer; this.setHideOnMouseDown(false); } public Point getLocation(Point tipSize, Event event) { // try to position the tooltip at the bottom of the cell ViewerCell cell = viewer.getCell(new Point(event.x, event.y)); if( cell != null ) return tree.toDisplay(event.x,cell.getBounds().y+cell.getBounds().height); return super.getLocation(tipSize, event); } protected Object getToolTipArea(Event event) { // Ensure that the tooltip is hidden when the cell is left return viewer.getCell(new Point(event.x, event.y)); } protected void addContent(Composite destination, Object modelElement) { final DisplayElement item = (DisplayElement)modelElement; String text = null; if (null != item) { text = item.getValue(); createEntryWithText(destination, null, text.toString()); } } protected Object getModelElement(Event event) { org.eclipse.swt.widgets.TreeItem treeItem = tree.getItem(new Point(event.x, event.y)); if (treeItem == null) return null; return treeItem.getData(); } } }