/* * Copyright (c) 2011, M. Woelker, H. Westphal * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of jo-widgets.org nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL jo-widgets.org BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ package org.jowidgets.workbench.impl.rcp.internal; import java.util.ArrayList; import java.util.List; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; 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.MenuDetectEvent; import org.eclipse.swt.events.MenuDetectListener; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; import org.jowidgets.api.model.item.IMenuModel; import org.jowidgets.api.model.item.IToolBarModel; import org.jowidgets.api.toolkit.Toolkit; import org.jowidgets.api.widgets.IPopupMenu; import org.jowidgets.common.types.Position; import org.jowidgets.workbench.api.IComponentNodeContext; import org.jowidgets.workbench.api.IWorkbenchApplication; import org.jowidgets.workbench.api.IWorkbenchPart; import org.jowidgets.workbench.impl.rcp.internal.util.FolderToolBarHelper; import org.jowidgets.workbench.impl.rcp.internal.util.ImageHelper; public final class WorkbenchApplicationTree extends Composite { private final IWorkbenchApplication application; private final WorkbenchApplicationFolder folder; private final FolderToolBarHelper toolBarHelper; private TreeViewer treeViewer; private IMenuModel popupMenuModel; private IPopupMenu popupMenu; private boolean notifyUnselection; private static class ViewLabelProvider extends ColumnLabelProvider { @Override public String getToolTipText(final Object element) { if (element instanceof IWorkbenchPart) { final IWorkbenchPart part = (IWorkbenchPart) element; return part.getTooltip(); } return super.getToolTipText(element); } @Override public String getText(final Object element) { if (element instanceof IWorkbenchPart) { final IWorkbenchPart part = (IWorkbenchPart) element; return part.getLabel(); } return super.getText(element); } @Override public Image getImage(final Object element) { if (element instanceof IWorkbenchPart) { final IWorkbenchPart part = (IWorkbenchPart) element; return ImageHelper.getImage( part.getIcon(), PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER)); } return super.getImage(element); } } public WorkbenchApplicationTree( final Composite parent, final IWorkbenchApplication application, final WorkbenchApplicationFolder folder) { super(parent, SWT.NONE); setLayout(new FillLayout()); this.application = application; this.folder = folder; toolBarHelper = new FolderToolBarHelper(parent); addTreeViewer(); } public IWorkbenchApplication getApplication() { return application; } private void addTreeViewer() { treeViewer = new TreeViewer(this, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL); ColumnViewerToolTipSupport.enableFor(treeViewer); treeViewer.setContentProvider(new ITreeContentProvider() { @Override public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {} @Override public void dispose() {} @Override public Object[] getElements(final Object inputElement) { return getChildren(inputElement); } @Override public boolean hasChildren(final Object element) { return getChildren(element).length > 0; } @Override public Object getParent(final Object element) { return null; } @Override public Object[] getChildren(final Object parentElement) { if (parentElement instanceof WorkbenchApplicationContext) { return ((WorkbenchApplicationContext) parentElement).getComponentTreeNodeContexts(); } if (parentElement instanceof IComponentNodeContext) { return ((ComponentNodeContext) parentElement).getComponentTreeNodeContexts(); } return new Object[0]; } }); treeViewer.setLabelProvider(new ViewLabelProvider()); final Tree tree = treeViewer.getTree(); tree.addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(final MenuDetectEvent e) { final Point position = WorkbenchApplicationTree.this.toControl(e.x, e.y); final TreeItem item = tree.getItem(position); if (item != null) { final ComponentNodeContext context = (ComponentNodeContext) item.getData(); final IPopupMenu nodeMenu = context.getJoPopupMenu(); if (nodeMenu != null) { nodeMenu.show(new Position(position.x, position.y)); } } else if (popupMenu != null) { popupMenu.show(new Position(position.x, position.y)); } } }); treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(final SelectionChangedEvent event) { if (!event.getSelection().isEmpty()) { final ComponentNodeContext context = (ComponentNodeContext) ((ITreeSelection) treeViewer.getSelection()).getFirstElement(); folder.onTreeNodeSelectionChange(WorkbenchApplicationTree.this, context); } else if (notifyUnselection) { folder.onTreeNodeUnselection(); notifyUnselection = false; } } }); } public void setInput(final WorkbenchApplicationContext applicationContext) { treeViewer.setInput(applicationContext); } public void refresh(final Object object) { treeViewer.refresh(object); } public Composite getFolderComposite() { return toolBarHelper.getUiReference(); } public void selectTreeNode(final List<String> nodes) { selectTreeNode(new ArrayList<String>(nodes), null); } private void selectTreeNode(final List<String> nodes, final TreeItem parent) { if (nodes.isEmpty()) { if (parent != null) { final ComponentNodeContext context = (ComponentNodeContext) parent.getData(); treeViewer.setSelection(new StructuredSelection(context)); } return; } final TreeItem[] items; if (parent == null) { items = treeViewer.getTree().getItems(); } else { items = parent.getItems(); } final String id = nodes.remove(0); for (final TreeItem item : items) { final ComponentNodeContext context = (ComponentNodeContext) item.getData(); if (context != null && context.getId().equals(id)) { treeViewer.expandToLevel(context, 1); selectTreeNode(nodes, item); break; } } nodes.add(0, id); } public void clearSelection(final boolean notify) { notifyUnselection = notify; treeViewer.setSelection(null); } public IToolBarModel getToolBar() { return toolBarHelper.getToolBarModel(); } public IMenuModel getToolBarMenu() { return toolBarHelper.getToolBarMenuModel(); } public IMenuModel getPopupMenu() { if (popupMenuModel == null) { popupMenu = Toolkit.getWidgetWrapperFactory().createComposite(treeViewer.getTree()).createPopupMenu(); popupMenuModel = Toolkit.getModelFactoryProvider().getItemModelFactory().menu(); popupMenu.setModel(popupMenuModel); } return popupMenuModel; } public void expand(final ComponentNodeContext componentTreeNodeContext) { treeViewer.expandToLevel(componentTreeNodeContext, 1); } public void collapse(final ComponentNodeContext componentTreeNodeContext) { treeViewer.collapseToLevel(componentTreeNodeContext, 1); } public boolean selectDefault() { return selectDefault(null); } private boolean selectDefault(final TreeItem parent) { final TreeItem[] items; if (parent == null) { items = treeViewer.getTree().getItems(); } else { items = parent.getItems(); } if (items.length == 0 && parent != null) { final ComponentNodeContext context = (ComponentNodeContext) parent.getData(); treeViewer.setSelection(new StructuredSelection(context)); return true; } for (final TreeItem item : items) { final ComponentNodeContext context = (ComponentNodeContext) item.getData(); if (context != null) { treeViewer.expandToLevel(context, 1); if (selectDefault(item)) { return true; } } } return false; } @Override public void setLayout(final Layout layout) { // prevent setting layout when wrapped by jo-widgets // TODO MG check widget wrapping with already set layout if (layout instanceof FillLayout) { super.setLayout(layout); } } }