/******************************************************************************* * Copyright 2005-2007, CHISEL Group, University of Victoria, Victoria, BC, Canada * and IBM Corporation. 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: * The Chisel Group, University of Victoria *******************************************************************************/ package net.sourceforge.tagsea.core.ui.internal.clouds; import net.sourceforge.tagsea.clouds.viewers.CloudViewer; import net.sourceforge.tagsea.clouds.viewers.ICloudLabelProvider; import net.sourceforge.tagsea.clouds.widgets.CloudItem; import net.sourceforge.tagsea.core.ui.internal.tags.TagTreeItem; import net.sourceforge.tagsea.core.ui.internal.tags.TagsTree; import org.eclipse.jface.viewers.IColorProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.forms.events.HyperlinkEvent; import org.eclipse.ui.forms.events.IHyperlinkListener; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.forms.widgets.FormToolkit; /** * A composite that contains a tag cloud that can be organised as a tree. * @author Del Myers * */ public class CloudTreeViewer extends Composite { private Composite breadcrumbComposite; private CloudViewer viewer; private TagsTree input; private boolean flat; private FormToolkit toolkit; private FormText formText; private class CloudListener implements KeyListener, MouseListener { public void keyPressed(KeyEvent e) { IStructuredSelection s = (IStructuredSelection) getSelection(); switch (e.keyCode) { case SWT.CR: if (isHierarchical()) { if (s.size() == 1) { TagTreeItem selected = (TagTreeItem) s.getFirstElement(); if (selected.hasChildren()) { viewer.setInput(selected); refresh(); } } } break; case SWT.BS: if (isHierarchical()) { TagTreeItem current = (TagTreeItem) viewer.getInput(); if (current.getParent() != null) { viewer.setInput(current.getParent()); refresh(); } } break; } } public void keyReleased(KeyEvent e) { } public void mouseDoubleClick(MouseEvent e) { if (e.button == 1) { CloudItem item = viewer.getCloud().findItemAt(e.x, e.y); TagTreeItem treeItem = (TagTreeItem) item.getData(); if (treeItem.hasChildren()) { viewer.setInput(treeItem); refresh(); } } } public void mouseDown(MouseEvent e) { } public void mouseUp(MouseEvent e) { } } private class BreadCrumbListener implements IHyperlinkListener { public void linkActivated(HyperlinkEvent e) { String ref = (String) e.getHref(); int number = Integer.parseInt(ref); if (number == 0) { // Clear the selection if root is selected if(viewer.getInput() == input.getRoot()) viewer.setSelection(new StructuredSelection(new Object[0]),true); return; } //get the parent numbered "number" TagTreeItem current = (TagTreeItem) viewer.getInput(); while (current != null && number > 0) { current = current.getParent(); number--; } if (current == null) { viewer.setInput(input.getRoot()); } else { viewer.setInput(current); } refresh(); } public void linkEntered(HyperlinkEvent e) {} public void linkExited(HyperlinkEvent e) {} } private class CloudContentProvider implements IStructuredContentProvider { public Object[] getElements(Object inputElement) { if (inputElement instanceof TagTreeItem) { return ((TagTreeItem)inputElement).getChildren(); } return new Object[0]; } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } private class CloudLabelProvider implements ICloudLabelProvider, IColorProvider { public Image getImage(Object element) { return null; } public String getText(Object element) { String text = ""; if (element instanceof TagTreeItem) { TagTreeItem tti = (TagTreeItem) element; text = tti.getName(); if (isHierarchical()) { int dot = text.lastIndexOf('.'); if (dot > 0 && dot < text.length()-1) { text = text.substring(dot+1); } } text += "(" + tti.getWaypointCount() + ")"; if (tti.hasChildren()) { text += "+"; } } return text; } public void addListener(ILabelProviderListener listener) {} public void dispose() {} public boolean isLabelProperty(Object element, String property) { return true; } public void removeListener(ILabelProviderListener listener) {} public Color getBackground(Object element) { return null; } public Color getForeground(Object element) { if (element instanceof TagTreeItem) { TagTreeItem tti = (TagTreeItem) element; if (tti.hasChildren()) { return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_CYAN); } } return null; } public int getPriority(Object element) { if (element instanceof TagTreeItem) { return ((TagTreeItem)element).getWaypointCount(); } return 0; } } /** * @param parent * @param style */ public CloudTreeViewer(Composite parent, int style) { super(parent, style); setLayout(new GridLayout(1, true)); this.flat = false; this.toolkit = new FormToolkit(Display.getCurrent()); breadcrumbComposite = new Composite(this, SWT.NONE); breadcrumbComposite.setLayout(new FillLayout()); GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); breadcrumbComposite.setLayoutData(data); createBreadCrumb(breadcrumbComposite); createViewer(); addDisposeListener(new DisposeListener(){ public void widgetDisposed(DisposeEvent e) { CloudTreeViewer.this.widgetDisposed(e); } }); } /** * @param cloudTreeViewer */ private void createViewer() { viewer = new CloudViewer(this, SWT.FLAT | SWT.MULTI); viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); viewer.setContentProvider(new CloudContentProvider()); viewer.setLabelProvider(new CloudLabelProvider()); CloudListener cloudListener = new CloudListener(); viewer.getControl().addKeyListener(cloudListener); viewer.getControl().addMouseListener(cloudListener); viewer.getControl().setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); } /** * @param e */ void widgetDisposed(DisposeEvent e) { if (toolkit != null) { toolkit.dispose(); } } /** * @param breadcrumbComposite2 */ private void createBreadCrumb(Composite parent) { this.formText = toolkit.createFormText(parent, false); formText.addHyperlinkListener(new BreadCrumbListener()); formText.setBackground(parent.getBackground()); } public void setInput(TagsTree input) { if (this.input == input) { return; } this.flat = input.isFlat(); this.input = input; viewer.setInput(input.getRoot()); refresh(); } public void refresh() { this.flat = input.isFlat(); if (flat) { viewer.setInput(input.getRoot()); } refreshBreadCrumb(); viewer.refresh(); if(viewer.getInput() == input.getRoot()) viewer.setSelection(new StructuredSelection(new Object[]{input.getRoot()}), true); // if (viewer.getCloud().getItems().length > 0) { // viewer.setSelection(new StructuredSelection(viewer.getCloud().getItems()[0].getData()), true); // } } /** * */ private void refreshBreadCrumb() { String linkText = ""; TagTreeItem current = (TagTreeItem) viewer.getInput(); int parentNum = 0; while (current != null) { String text = current.getName(); int dot = text.lastIndexOf('.'); if (dot > 0 && dot < text.length()-1) { text = text.substring(dot+1); } linkText = "<a href=\""+parentNum+"\">" + text + "</a>" + linkText; if (current.getParent() != null && current.getParent() != input.getRoot()) { linkText = "." + linkText; } else { linkText = " " + linkText; } current = current.getParent(); parentNum++; } formText.setText("<form><p>"+linkText+"</p></form>", true, false); } public ISelection getSelection() { return viewer.getSelection(); } public boolean isHierarchical() { return !flat; } /** * @return */ public CloudViewer getViewer() { return viewer; } }