From 925a4c913eff0ebcefc763c2de0aaafadc09c8d3 Mon Sep 17 00:00:00 2001 From: Vincent Aravantinos <aravantinos@fortiss.org> Date: Thu, 6 Mar 2014 17:29:59 +0000 Subject: [PATCH] Fixed the issue refs 1925 --- .../ui/extension/base/EObjectActionBase.java | 17 ++++++--- .../ui/internal/actions/CopyAction.java | 14 +++++-- .../kernel/ui/internal/actions/CutAction.java | 15 +++----- .../ui/internal/actions/DeleteAction.java | 14 ++++--- .../kernel/ui/util/CopyPasteUtils.java | 38 ++++++++++++++----- .../trunk/model/kernel.ecore | 26 +++++++++++++ .../trunk/model/kernel.genmodel | 8 ++++ .../kernel/utils/KernelModelElementUtils.java | 26 ++++++++++++- 8 files changed, 125 insertions(+), 33 deletions(-) diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/EObjectActionBase.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/EObjectActionBase.java index 40ec62ecc..09058c916 100644 --- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/EObjectActionBase.java +++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/extension/base/EObjectActionBase.java @@ -21,6 +21,8 @@ import static java.util.Arrays.asList; import java.util.List; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.action.Action; import org.eclipse.jface.resource.ImageDescriptor; @@ -32,7 +34,7 @@ import org.eclipse.jface.resource.ImageDescriptor; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating YELLOW Hash: 1D6CCC2A2CE03ACD4F8129DD9FCEAFCF + * @ConQAT.Rating YELLOW Hash: A544F6FF5459D4E0041E5E37EFD33867 */ public abstract class EObjectActionBase<T extends EObject> extends Action { @@ -43,7 +45,7 @@ public abstract class EObjectActionBase<T extends EObject> extends Action { } /** Stores the target elements. */ - private List<T> targets; + private EList<T> targets; /** Constructor. */ public EObjectActionBase(String text, ImageDescriptor image) { @@ -67,8 +69,13 @@ public abstract class EObjectActionBase<T extends EObject> extends Action { } /** Sets the target object. */ - public void setTargets(List<T> targets) { - this.targets = targets; + public void setTargets(List<T> newTargets) { + if(targets == null) { + targets = new BasicEList<T>(newTargets); + } else { + targets.clear(); + targets.addAll(newTargets); + } } /** Sets the target object. */ @@ -85,7 +92,7 @@ public abstract class EObjectActionBase<T extends EObject> extends Action { } /** Returns the current targets. */ - public List<T> getTargets() { + public EList<T> getTargets() { return targets; } diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/CopyAction.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/CopyAction.java index 314226da1..dcf3c7851 100644 --- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/CopyAction.java +++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/CopyAction.java @@ -19,11 +19,13 @@ package org.fortiss.tooling.kernel.ui.internal.actions; import static org.fortiss.tooling.kernel.ui.util.CopyPasteUtils.copyToClipboard; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; import org.fortiss.tooling.kernel.ui.extension.base.EObjectActionBase; +import org.fortiss.tooling.kernel.utils.KernelModelElementUtils; /** * Action for copying the current selection. @@ -32,7 +34,7 @@ import org.fortiss.tooling.kernel.ui.extension.base.EObjectActionBase; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating GREEN Hash: 69A8F1BDE380BB57E2F811EC4A75A83C + * @ConQAT.Rating YELLOW Hash: 454F12FE73DC98AC62710AAC69469E57 */ public class CopyAction extends EObjectActionBase<EObject> { @@ -46,10 +48,16 @@ public class CopyAction extends EObjectActionBase<EObject> { /** {@inheritDoc} */ @Override public void run() { - if(getTarget() == null) { + doCopy(getTargets()); + } + + /** Copy the targets if non empty. */ + public static void doCopy(EList<EObject> targets) { + if(targets == null || targets.isEmpty()) { return; } - copyToClipboard(getTargets()); + EList<EObject> cleanedTargets = KernelModelElementUtils.topParents(targets); + copyToClipboard(KernelModelElementUtils.topParents(cleanedTargets)); } /** {@inheritDoc} */ diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/CutAction.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/CutAction.java index aaf0e113e..13df511e6 100644 --- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/CutAction.java +++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/CutAction.java @@ -17,8 +17,8 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.ui.internal.actions; -import java.util.Collection; -import java.util.LinkedList; +import static org.fortiss.tooling.kernel.ui.internal.actions.CopyAction.doCopy; +import static org.fortiss.tooling.kernel.ui.internal.actions.DeleteAction.doDelete; import org.eclipse.emf.ecore.EObject; import org.eclipse.ui.ISharedImages; @@ -27,7 +27,6 @@ import org.eclipse.ui.actions.ActionFactory; import org.fortiss.tooling.kernel.service.ICommandStackService; import org.fortiss.tooling.kernel.service.IElementCompositorService; import org.fortiss.tooling.kernel.ui.extension.base.EObjectActionBase; -import org.fortiss.tooling.kernel.ui.util.CopyPasteUtils; /** * Action for cutting the current selection. @@ -36,7 +35,7 @@ import org.fortiss.tooling.kernel.ui.util.CopyPasteUtils; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating GREEN Hash: 83600A03B6ECB95C8C98C805953C9890 + * @ConQAT.Rating YELLOW Hash: 60F02762C4975F4926ABDCC29611BBC8 */ public class CutAction extends EObjectActionBase<EObject> { @@ -53,12 +52,8 @@ public class CutAction extends EObjectActionBase<EObject> { ICommandStackService.INSTANCE.runAsCommand(getTarget(), new Runnable() { @Override public void run() { - // currently we support only single element cutting - // see ActionService.refresh() - Collection<EObject> targets = new LinkedList<EObject>(); - targets.add(getTarget()); - CopyPasteUtils.copyToClipboard(targets); - IElementCompositorService.INSTANCE.decompose(getTarget()); + doCopy(getTargets()); + doDelete(getTargets()); } }); } diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/DeleteAction.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/DeleteAction.java index 09a2ccfc3..231b41de3 100644 --- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/DeleteAction.java +++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/actions/DeleteAction.java @@ -47,7 +47,7 @@ import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating YELLOW Hash: E733E0FF17436B878C53DDF807C7E373 + * @ConQAT.Rating YELLOW Hash: 4E9C8E039F44355D95C95D006A5369AD */ public class DeleteAction extends EObjectActionBase<EObject> { @@ -61,8 +61,12 @@ public class DeleteAction extends EObjectActionBase<EObject> { /** {@inheritDoc} */ @Override public void run() { - Map<ITopLevelElement, List<EObject>> topLevelTargetsMap = topLevelMap(getTargets()); + doDelete(getTargets()); + } + /** Deletes the given targets (organized in a map by topLevel element). */ + public static void doDelete(List<EObject> unorganizedTargets) { + Map<ITopLevelElement, List<EObject>> topLevelTargetsMap = topLevelMap(unorganizedTargets); for(ITopLevelElement topLevel : topLevelTargetsMap.keySet()) { final List<EObject> targets = topLevelTargetsMap.get(topLevel); boolean topLevelDeleted = false; @@ -112,7 +116,7 @@ public class DeleteAction extends EObjectActionBase<EObject> { } /** Executes the delete using the correct service. */ - private void doCompositorBasedDelete(List<EObject> targets) { + private static void doCompositorBasedDelete(List<EObject> targets) { for(EObject target : targets) { if(IElementCompositorService.INSTANCE.canDecompose(target)) { IElementCompositorService.INSTANCE.decompose(target); @@ -123,7 +127,7 @@ public class DeleteAction extends EObjectActionBase<EObject> { } /** User interaction before deleting a top-level element. */ - private void doTopLevelElementDelete(EObject target) { + private static void doTopLevelElementDelete(EObject target) { ITopLevelElement topElement = IPersistencyService.INSTANCE.getTopLevelElementFor(target); Shell sh = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); String message = "Are you sure you want to delete '" + topElement.getSaveableName() + "'?"; @@ -156,7 +160,7 @@ public class DeleteAction extends EObjectActionBase<EObject> { * i.e., given a set of model elements M, returns a map f s.t., for every top level element top, * f(top) = { m in M | top is the top level element of m } */ - public Map<ITopLevelElement, List<EObject>> topLevelMap(List<EObject> modelElements) { + public static Map<ITopLevelElement, List<EObject>> topLevelMap(List<EObject> modelElements) { HashMap<ITopLevelElement, List<EObject>> res = new HashMap<ITopLevelElement, List<EObject>>(); for(EObject eo : modelElements) { diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/util/CopyPasteUtils.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/util/CopyPasteUtils.java index ee870c6af..19275bfc4 100644 --- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/util/CopyPasteUtils.java +++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/util/CopyPasteUtils.java @@ -17,8 +17,12 @@ $Id$ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.ui.util; +import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf; + import java.util.Collection; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jface.dialogs.MessageDialog; @@ -28,6 +32,7 @@ import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.widgets.Display; import org.fortiss.tooling.kernel.extension.data.IElementCompositionContext; +import org.fortiss.tooling.kernel.model.SpeciallyCopyiable; import org.fortiss.tooling.kernel.service.IElementCompositorService; import org.fortiss.tooling.kernel.ui.dnd.CompositionServiceLocalCopyPasteTransfer; @@ -40,33 +45,42 @@ import org.fortiss.tooling.kernel.ui.dnd.CompositionServiceLocalCopyPasteTransfe * * @author $Author$ * @version $Rev$ - * @ConQAT.Rating GREEN Hash: A40EF644FB2792BDE3DB675D3D7FA0C8 + * @ConQAT.Rating YELLOW Hash: E84BD272D73E0D834E3535040340CBDD */ public class CopyPasteUtils { /** * Copies the given selected objects to the clipboard. * - * @param selection + * @param sel * the collection of {@link EObject}s to be copyied to the * clipboard. */ - public static void copyToClipboard(Collection<EObject> selection) { + public static void copyToClipboard(Collection<EObject> sel) { try { - EObject[] content = new EObject[selection.size()]; + EObject[] content = new EObject[sel.size()]; int i = 0; EcoreUtil.Copier copier = new EcoreUtil.Copier(true, true); - for(EObject sel : selection) { - content[i] = copier.copy(sel); + for(EObject obj : sel) { + content[i] = copier.copy(obj); copier.copyReferences(); i++; } + EList<SpeciallyCopyiable> specialSel = + pickInstanceOf(SpeciallyCopyiable.class, new BasicEList<EObject>(sel)); + for(SpeciallyCopyiable obj : specialSel) { + obj.completeCopyEnvironment(copier); + } + for(SpeciallyCopyiable obj : specialSel) { + obj.copyConnections(copier); + } Clipboard clipboard = new Clipboard(Display.getDefault()); clipboard.setContents(new Object[] {content}, new Transfer[] {CompositionServiceLocalCopyPasteTransfer.getInstance()}, DND.CLIPBOARD | DND.SELECTION_CLIPBOARD); clipboard.dispose(); } catch(Exception e) { + e.printStackTrace(); MessageDialog.openError(Display.getDefault().getActiveShell(), "Copy", "Clipboard contents not writeable: " + e.getMessage()); return; @@ -98,12 +112,18 @@ public class CopyPasteUtils { if(!canPasteInto(target, context)) { return; } - for(EObject insertObj : getClipBoardContent()) { - EcoreUtil.Copier copier = new EcoreUtil.Copier(); - EObject copy = copier.copy(insertObj); + + EcoreUtil.Copier copier = new EcoreUtil.Copier(); + for(EObject obj : getClipBoardContent()) { + EObject copy = copier.copy(obj); copier.copyReferences(); IElementCompositorService.INSTANCE.compose(target, copy, context); } + for(EObject obj : getClipBoardContent()) { + if(obj instanceof SpeciallyCopyiable) { + ((SpeciallyCopyiable)obj).copyConnections(copier); + } + } } /** diff --git a/org.fortiss.tooling.kernel/trunk/model/kernel.ecore b/org.fortiss.tooling.kernel/trunk/model/kernel.ecore index 67a18eeac..7d5cad2ab 100644 --- a/org.fortiss.tooling.kernel/trunk/model/kernel.ecore +++ b/org.fortiss.tooling.kernel/trunk/model/kernel.ecore @@ -100,4 +100,30 @@ <eClassifiers xsi:type="ecore:EClass" name="IExternalDocumentReference"> <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/> </eClassifiers> + <eClassifiers xsi:type="ecore:EClass" name="SpeciallyCopyiable"> + <eOperations name="completeCopyEnvironment"> + <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel"> + <details key="body" value="/** To be implemented by subclasses. **/"/> + <details key="documentation" value="Hook to allow changing the copy map, typically by adding elements that are not copied but might still be necessary to preserve some information.
The typical example is to copy connections between elements: the top element containing the connections is not copied, but necessary to copy the connections."/> + </eAnnotations> + <eParameters name="copyMap"> + <eGenericType eClassifier="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EMap"> + <eTypeArguments eClassifier="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EObject"/> + <eTypeArguments eClassifier="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EObject"/> + </eGenericType> + </eParameters> + </eOperations> + <eOperations name="copyConnections"> + <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel"> + <details key="body" value="/** To be implemented by subclasses. **/"/> + <details key="documentation" value="Hook to allow copying the connections between elements.
Goes hand in hand with completeCopyEnvironment.
Typically, one first calls completeCopyEnvironment on all copied elements and then copyConnections to copy the connections."/> + </eAnnotations> + <eParameters name="copyMap"> + <eGenericType eClassifier="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EMap"> + <eTypeArguments eClassifier="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EObject"/> + <eTypeArguments eClassifier="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EObject"/> + </eGenericType> + </eParameters> + </eOperations> + </eClassifiers> </ecore:EPackage> diff --git a/org.fortiss.tooling.kernel/trunk/model/kernel.genmodel b/org.fortiss.tooling.kernel/trunk/model/kernel.genmodel index e6d29aa99..27e1a2d44 100644 --- a/org.fortiss.tooling.kernel/trunk/model/kernel.genmodel +++ b/org.fortiss.tooling.kernel/trunk/model/kernel.genmodel @@ -46,5 +46,13 @@ <genClasses ecoreClass="kernel.ecore#//IExternalDocumentReference"> <genFeatures createChild="false" ecoreFeature="ecore:EAttribute kernel.ecore#//IExternalDocumentReference/uri"/> </genClasses> + <genClasses ecoreClass="kernel.ecore#//SpeciallyCopyiable"> + <genOperations ecoreOperation="kernel.ecore#//SpeciallyCopyiable/completeCopyEnvironment"> + <genParameters ecoreParameter="kernel.ecore#//SpeciallyCopyiable/completeCopyEnvironment/copyMap"/> + </genOperations> + <genOperations ecoreOperation="kernel.ecore#//SpeciallyCopyiable/copyConnections"> + <genParameters ecoreParameter="kernel.ecore#//SpeciallyCopyiable/copyConnections/copyMap"/> + </genOperations> + </genClasses> </genPackages> </genmodel:GenModel> diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/utils/KernelModelElementUtils.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/utils/KernelModelElementUtils.java index af86e1088..476c7575d 100644 --- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/utils/KernelModelElementUtils.java +++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/utils/KernelModelElementUtils.java @@ -20,6 +20,8 @@ package org.fortiss.tooling.kernel.utils; import java.util.Iterator; import java.util.List; +import org.eclipse.emf.common.util.BasicEList; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.fortiss.tooling.kernel.extension.data.ITopLevelElement; import org.fortiss.tooling.kernel.model.IIdLabeled; @@ -36,7 +38,7 @@ import org.fortiss.tooling.kernel.service.IPersistencyService; * @author hoelzl * @author $Author$ * @version $Rev$ - * @ConQAT.Rating GREEN Hash: 7043206480716A4D94F8FF968AA13525 + * @ConQAT.Rating YELLOW Hash: E6EC9303F505DCCC8EE14C09D896D380 */ public final class KernelModelElementUtils { @@ -177,6 +179,28 @@ public final class KernelModelElementUtils { return false; } + /** + * Keeps only the top-most parents of a list. + * i.e., if the list contains two elements, one is the (direct or indirect) child of the other, + * then it is removed. + */ + public static EList<EObject> topParents(EList<EObject> objs) { + EList<EObject> res = new BasicEList<EObject>(); + for(EObject o1 : objs) { + boolean hasParent = false; + for(EObject o2 : objs) { + if(KernelModelElementUtils.isChildElementOf(o1, o2)) { + hasParent = true; + break; + } + } + if(!hasParent) { + res.add(o1); + } + } + return res; + } + /** * Iterates the content of the given root element and finds a contained * element with the given name and the given class. -- GitLab