package edu.ualberta.med.biobank.widgets.trees; import java.io.File; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.PlatformUI; import edu.ualberta.med.biobank.SessionManager; import edu.ualberta.med.biobank.common.reports.AbstractReportTreeNode; import edu.ualberta.med.biobank.common.reports.ReportTreeNode; import edu.ualberta.med.biobank.forms.input.ReportInput; import edu.ualberta.med.biobank.gui.common.BgcPlugin; public class ReportTreeWidget extends Composite { private TreeViewer treeViewer; public ReportTreeWidget(Composite parent) { super(parent, SWT.BORDER); setLayout(new FillLayout()); treeViewer = new TreeViewer(this); treeViewer.setUseHashlookup(true); treeViewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { if (SessionManager.getInstance().isConnected()) executeDoubleClick(event); } }); treeViewer.setContentProvider(new ITreeContentProvider() { @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } @Override public void dispose() { } @Override public Object[] getElements(Object inputElement) { return ((AbstractReportTreeNode) inputElement).getChildren() .toArray(); } @Override public boolean hasChildren(Object element) { return !((AbstractReportTreeNode) element).isLeaf(); } @Override public Object getParent(Object element) { return ((AbstractReportTreeNode) element).getParent(); } @Override public Object[] getChildren(Object parentElement) { return ((AbstractReportTreeNode) parentElement).getChildren() .toArray(); } }); treeViewer.setLabelProvider(new ILabelProvider() { @Override public Image getImage(Object element) { return null; } @Override public String getText(Object element) { return ((AbstractReportTreeNode) element).getLabel(); } @Override public void addListener(ILabelProviderListener listener) { } @Override public void dispose() { } @Override public boolean isLabelProperty(Object element, String property) { return false; } @Override public void removeListener(ILabelProviderListener listener) { } }); addTooltipBehaviour(); Menu menu = new Menu(PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getShell(), SWT.NONE); menu.addListener(SWT.Show, new Listener() { @Override public void handleEvent(Event event) { Menu menu = treeViewer.getTree().getMenu(); for (MenuItem menuItem : menu.getItems()) { menuItem.dispose(); } Object element = ((StructuredSelection) treeViewer .getSelection()).getFirstElement(); final ReportTreeNode node = (ReportTreeNode) element; if (node != null && node.getParent().getLabel() .compareTo(Messages.ReportTreeWidget_custom_label) == 0) { MenuItem mi = new MenuItem(menu, SWT.NONE); mi.setText(Messages.ReportTreeWidget_delete_label); mi.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { File file = new File(Platform.getInstanceLocation() .getURL().getPath() + "/saved_reports/" + node.getLabel() + ".xml"); //$NON-NLS-1$ //$NON-NLS-2$ file.delete(); node.getParent().removeChild(node); treeViewer.refresh(); } }); } } }); treeViewer.getTree().setMenu(menu); } public TreeViewer getTreeViewer() { return treeViewer; } private void addTooltipBehaviour() { // lengthy tooltip faking code here final Tree tree = treeViewer.getTree(); // Disable native tooltip tree.setToolTipText(""); //$NON-NLS-1$ final Display display = tree.getDisplay(); final Shell shell = new Shell(display); shell.setLayout(new FillLayout()); // Implement a "fake" tooltip final Listener labelListener = new Listener() { @Override public void handleEvent(Event event) { Label label = (Label) event.widget; Shell shell = label.getShell(); switch (event.type) { case SWT.MouseDown: Event e = new Event(); e.item = (TreeItem) label.getData("_TREEITEM"); //$NON-NLS-1$ // Assuming table is single select, set the selection as if // the mouse down event went through to the table tree.setSelection(new TreeItem[] { (TreeItem) e.item }); tree.notifyListeners(SWT.Selection, e); shell.dispose(); tree.setFocus(); break; case SWT.MouseExit: shell.dispose(); break; } } }; Listener tableListener = new Listener() { Shell tip = null; Label label = null; @Override public void handleEvent(Event event) { switch (event.type) { case SWT.Dispose: case SWT.KeyDown: case SWT.MouseMove: { if (tip == null) break; tip.dispose(); tip = null; label = null; break; } case SWT.MouseHover: { TreeItem item = tree.getItem(new Point(event.x, event.y)); if (item != null) { if (tip != null && !tip.isDisposed()) tip.dispose(); tip = new Shell(shell, SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL); tip.setBackground(display .getSystemColor(SWT.COLOR_INFO_BACKGROUND)); FillLayout layout = new FillLayout(); layout.marginWidth = 2; tip.setLayout(layout); label = new Label(tip, SWT.NONE); label.setForeground(display .getSystemColor(SWT.COLOR_INFO_FOREGROUND)); label.setBackground(display .getSystemColor(SWT.COLOR_INFO_BACKGROUND)); label.setData("_TREEITEM", item); //$NON-NLS-1$ String text = ((AbstractReportTreeNode) item.getData()) .getToolTipText(); if (text == null || text.equalsIgnoreCase("")) //$NON-NLS-1$ return; label.setText(text); label.addListener(SWT.MouseExit, labelListener); label.addListener(SWT.MouseDown, labelListener); Point size = tip.computeSize(SWT.DEFAULT, SWT.DEFAULT); Rectangle rect = item.getBounds(0); Point pt = tree.toDisplay(rect.x, rect.y); tip.setBounds(pt.x, pt.y, size.x, size.y); tip.setVisible(true); } } } } }; tree.addListener(SWT.Dispose, tableListener); tree.addListener(SWT.KeyDown, tableListener); tree.addListener(SWT.MouseMove, tableListener); tree.addListener(SWT.MouseHover, tableListener); } private void executeDoubleClick(DoubleClickEvent event) { AbstractReportTreeNode node = (AbstractReportTreeNode) ((IStructuredSelection) event .getSelection()).getFirstElement(); try { if (((ReportTreeNode) node).getReport() != null) PlatformUI .getWorkbench() .getActiveWorkbenchWindow() .getActivePage() .openEditor(new ReportInput(node), ((ReportTreeNode) node).getReport().getEditorId()); } catch (Exception ex) { BgcPlugin.openAsyncError(Messages.ReportTreeWidget_error_title, ex, Messages.ReportTreeWidget_error_msg); } } @Override public boolean setFocus() { return treeViewer.getTree().setFocus(); } public void setInput(Object input) { this.treeViewer.setInput(input); } public void expandAll() { this.treeViewer.expandAll(); } }