diff --git a/org.fortiss.tooling.base/trunk/src/org/fortiss/tooling/base/editor/TreeViewerEditorBase.java b/org.fortiss.tooling.base/trunk/src/org/fortiss/tooling/base/editor/TreeViewerEditorBase.java new file mode 100644 index 0000000000000000000000000000000000000000..a744b54e8b8cfe285c4a888701253c503a8ef0f7 --- /dev/null +++ b/org.fortiss.tooling.base/trunk/src/org/fortiss/tooling/base/editor/TreeViewerEditorBase.java @@ -0,0 +1,193 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.editor; + +import java.util.Collection; +import java.util.List; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.util.EContentAdapter; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.util.LocalSelectionTransfer; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerDropAdapter; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.dnd.TransferData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.fortiss.tooling.kernel.base.EditorBase; +import org.fortiss.tooling.kernel.services.ICompositorService; +import org.fortiss.tooling.kernel.util.DragAndDropUtils; +import org.fortiss.tooling.kernel.util.EObjectSelectionUtils; + +/** + * An editor which only consists of a tree viewer. It uses {@link TreeViewer}, + * which also allows to define columns, i.e., use the tree and table at the same + * time. + * + * @author hoelzl + * @author $Author$ + * @version $Rev$ + * @levd.rating RED Rev: + */ +public abstract class TreeViewerEditorBase<T extends EObject> extends + EditorBase<T> { + + /** Stores the {@link TreeViewer}. */ + private TreeViewer treeViewer; + + /** The adapter used for dealing with changes of the */ + private final Adapter editedObjectChanged = new EContentAdapter() { + @Override + public void notifyChanged(Notification notification) { + super.notifyChanged(notification); + if (notification.getEventType() != Notification.REMOVING_ADAPTER) { + treeViewer.refresh(true); + } + } + }; + + /** {@inheritDoc} */ + @Override + public void createPartControl(Composite parent) { + treeViewer = new TreeViewer(parent); + + setupTreeViewer(treeViewer); + + treeViewer.addDropSupport( + DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK, + new Transfer[] { LocalSelectionTransfer.getTransfer() }, + new TreeDropAdapter(treeViewer)); + + treeViewer.setInput(editedObject); + getEditorSite().setSelectionProvider(treeViewer); + + editedObject.eAdapters().add(editedObjectChanged); + + initContextMenu(); + } + + /** + * Initializes context menu support. + */ + protected void initContextMenu() { + MenuManager menuManager = new MenuManager("#PopupMenu"); + menuManager.setRemoveAllWhenShown(true); + menuManager.addMenuListener(new IMenuListener() { + @Override + public void menuAboutToShow(IMenuManager manager) { + // TODO: add context menu support + } + }); + Menu menu = menuManager.createContextMenu(treeViewer.getTree()); + treeViewer.getTree().setMenu(menu); + getSite().registerContextMenu(menuManager, treeViewer); + } + + /** {@inheritDoc} */ + @Override + public void dispose() { + editedObject.eAdapters().remove(editedObjectChanged); + super.dispose(); + } + + /** Returns the elements currently selected in the tree. */ + protected Collection<EObject> getTreeSelection() { + List<EObject> result = EObjectSelectionUtils + .getEObjectElements(treeViewer.getSelection()); + if (result.isEmpty()) { + result.add(editedObject); + } + return result; + } + + /** + * This method is used to configure the tree viewer, e.g. set the content + * provider, and the label provider. + */ + protected abstract void setupTreeViewer(TreeViewer treeViewer); + + /** {@inheritDoc} */ + @Override + public void setFocus() { + treeViewer.getTree().setFocus(); + } + + /** The drop adapter for the tree. */ + private class TreeDropAdapter extends ViewerDropAdapter { + + /** Remember the last target. */ + Object lastTarget = null; + + /** Constructor. */ + private TreeDropAdapter(Viewer viewer) { + super(viewer); + setExpandEnabled(true); + } + + /** + * {@inheritDoc} + * <p> + * Hook this method to set a "valid" details field. + */ + @Override + public void dragEnter(DropTargetEvent event) { + event.detail = DND.DROP_COPY; + super.dragEnter(event); + } + + /** {@inheritDoc} */ + @Override + public boolean validateDrop(Object target, int operation, + TransferData transferType) { + if (target == null) { + target = treeViewer.getInput(); + } + lastTarget = target; + return true; + } + + /** {@inheritDoc} */ + @Override + public boolean performDrop(Object data) { + if (lastTarget instanceof EObject) { + final EObject dropped = DragAndDropUtils + .extractDroppedEObject(data); + if (ICompositorService.INSTANCE.canCompose( + (EObject) lastTarget, dropped, null)) { + TreeViewerEditorBase.this.executeCommand(new Runnable() { + @Override + public void run() { + ICompositorService.INSTANCE.compose( + (EObject) lastTarget, dropped, null); + } + }); + return true; + } + } + return false; + } + } +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/DragAndDropUtils.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/DragAndDropUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..4137f3178acb2b091deb7f473f41f06ec01d86db --- /dev/null +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/DragAndDropUtils.java @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------+ +$Id$ +| | +| Copyright 2011 ForTISS GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.util; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.fortiss.tooling.kernel.services.IPrototypeService.Prototype; + +/** + * Utility methods for drag and drop support. + * + * @author hoelzlf + * @author $Author$ + * @version $Rev$ + * @levd.rating RED Rev: + */ +public final class DragAndDropUtils { + + /** Extracts the EObject contained in the given drop object. */ + public static EObject extractDroppedEObject(Object data) { + if (data instanceof IStructuredSelection) { + return EObjectSelectionUtils.getFirstElement((ISelection) data); + } + if (data instanceof Prototype) { + return ((Prototype) data).getPrototypeCopy(); + } + return null; + } +} diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EObjectSelectionUtils.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EObjectSelectionUtils.java index 146f1a58bd5fd69bfc57e39c4564661146c44b75..08f86437c663bfb7693c6a50b8aa1e3b3edffe6f 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EObjectSelectionUtils.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/util/EObjectSelectionUtils.java @@ -17,9 +17,13 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.util; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.ui.PlatformUI; /** @@ -40,6 +44,13 @@ public final class EObjectSelectionUtils { return getFirstElement(getCurrentSelection()); } + /** + * Returns the list of selected elements filtered for EObjects. + */ + public static List<EObject> getCurrentSelectionEObjects() { + return getEObjectElements(getCurrentSelection()); + } + /** * Returns the first selected EObject or <code>null</code> if no EObject is * selected. @@ -61,4 +72,18 @@ public final class EObjectSelectionUtils { return PlatformUI.getWorkbench().getActiveWorkbenchWindow() .getSelectionService().getSelection(); } + + /** Extracts all {@link EObject}s from the given selection. */ + public static List<EObject> getEObjectElements(ISelection selection) { + List<EObject> result = new ArrayList<EObject>(); + if (selection instanceof StructuredSelection) { + for (Object o : ((StructuredSelection) selection).toList()) { + if (o instanceof EObject) { + result.add((EObject) o); + } + } + } + return result; + } + }