diff options
author | Gabriel Pascual | 2014-10-21 12:32:40 +0000 |
---|---|---|
committer | Gabriel Pascual | 2015-01-29 10:57:11 +0000 |
commit | d3914090f105a4115d213060da82453e65ad0a37 (patch) | |
tree | 8a0ef12c3ee774a54a8427148a7a632ed2f0f877 /plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse | |
parent | 8c6be54105c3480e839406fe8dd41043570bd8b9 (diff) | |
download | org.eclipse.papyrus-d3914090f105a4115d213060da82453e65ad0a37.tar.gz org.eclipse.papyrus-d3914090f105a4115d213060da82453e65ad0a37.tar.xz org.eclipse.papyrus-d3914090f105a4115d213060da82453e65ad0a37.zip |
420593 -[Model Explorer] Drag and drop of multiple selection does not
working correctly
Drop several Structural Features from/to an object of the ModelExplorer
should be fixed with this commit. If one feature in the selection cannot
be moved, nothing happen, the feature remains at its previous location.
Change-Id: Id6f67b9ea5cda51c7a72e4847c62d6cc3a553dd8
Signed-off-by: Céline Janssens <Celine.Janssens@all4tec.net>
Signed-off-by: Gabriel Pascual <gabriel.pascual@all4tec.net>
Diffstat (limited to 'plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse')
-rw-r--r-- | plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/dnd/CommonDropAdapterAssistant.java | 422 |
1 files changed, 376 insertions, 46 deletions
diff --git a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/dnd/CommonDropAdapterAssistant.java b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/dnd/CommonDropAdapterAssistant.java index ba56fdf5cc3..1cc7e1e68e0 100644 --- a/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/dnd/CommonDropAdapterAssistant.java +++ b/plugins/views/modelexplorer/org.eclipse.papyrus.views.modelexplorer/src/org/eclipse/papyrus/views/modelexplorer/dnd/CommonDropAdapterAssistant.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2010 CEA LIST. + * Copyright (c) 2010-2014 CEA LIST. * * * All rights reserved. This program and the accompanying materials @@ -9,6 +9,7 @@ * * Contributors: * Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation + * Céline Janssens (ALL4TEC) Celine.Janssens@all4tec.net - Bug 420593 * Gabriel Pascual (ALL4TEC) gabriel.pascual@all4tec.net - Bug 447025 *****************************************************************************/ @@ -25,6 +26,7 @@ import org.eclipse.core.runtime.Status; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.command.CompoundCommand; import org.eclipse.emf.common.command.UnexecutableCommand; +import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; @@ -38,7 +40,6 @@ import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gmf.runtime.common.core.command.ICommand; import org.eclipse.gmf.runtime.emf.type.core.requests.MoveRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest; -import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.jface.util.LocalSelectionTransfer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; @@ -63,13 +64,31 @@ import org.eclipse.swt.dnd.TransferData; import org.eclipse.ui.navigator.CommonDropAdapter; /** - * this class manage the drop inside the model explorer + * This class manage the drop inside the model explorer. */ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonDropAdapterAssistant { + /** The Constant CHANGE_OF_RESOURCE_COMMAND. */ + private static final String CHANGE_OF_RESOURCE_COMMAND = "Change of Resource"; + + /** The Constant REORDER_COMMAND_LABEL. */ + private static final String REORDER_COMMAND_LABEL = "Move Selected Elements in Model Explorer"; + + + /** + * Instantiates a new common drop adapter assistant. + */ public CommonDropAdapterAssistant() { } + /** + * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#handleDrop(org.eclipse.ui.navigator.CommonDropAdapter, org.eclipse.swt.dnd.DropTargetEvent, java.lang.Object) + * + * @param dropAdapter + * @param dropTargetEvent + * @param dropTarget + * @return + */ @Override public IStatus handleDrop(CommonDropAdapter dropAdapter, DropTargetEvent dropTargetEvent, Object dropTarget) { EObject targetElement = EMFHelper.getEObject(dropTarget); @@ -79,8 +98,8 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD } /** - * get the list of command to put an eobject into another EObject, - * if the parameter eref is null,It will look for the good role of the child eobject + * Get the list of command to put an eobject into another EObject, + * if the parameter eref is null,It will look for the good role of the child eobject. * * @param domain * the Transactional Domain , cannot be null @@ -88,8 +107,8 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD * the eobject that will contain the drop object, cannot be null * @param childElement * that we want to move, cannot be null - * @param the - * EREFERENCE for the role of the child element, can be null + * @param eref + * role where the child element must be drop if eref is not null * @return the list of commands to to the drop */ protected List<Command> getDropIntoCommand(TransactionalEditingDomain domain, EObject targetOwner, EObject childElement, EReference eref) { @@ -103,14 +122,13 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD if (command != null) { commandList.add(new GMFtoEMFCommandWrapper(command)); } - } return commandList; } /** - * get a list that contains command to move a view into a new element + * get a list that contains command to move a view into a new element. * * @param domain * the transactionnal edit domain, cannot be null @@ -140,7 +158,7 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD if (!targetNotationResource.equals(view.eResource())) { List<Command> list = new ArrayList<Command>(); list.add(command); - list.add(new GMFtoEMFCommandWrapper(new MoveOpenableCommand(domain, "", view, targetNotationResource))); + list.add(new GMFtoEMFCommandWrapper(new MoveOpenableCommand(domain, CHANGE_OF_RESOURCE_COMMAND, view, targetNotationResource))); return new CompoundCommand(list); } else { // diagram stays in the same resource. Only execute the set command return command; @@ -152,6 +170,13 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD return UnexecutableCommand.INSTANCE; } + /** + * Gets the target notation resource. + * + * @param targetOwner + * the target owner + * @return the target notation resource + */ protected Resource getTargetNotationResource(EObject targetOwner) { if (targetOwner.eResource() != null && targetOwner.eResource().getResourceSet() instanceof ModelSet) { ModelSet modelSet = (ModelSet) targetOwner.eResource().getResourceSet(); @@ -162,7 +187,7 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD /** * get the list of command to put an eobject before or after another EObject - * It will look for the good role of the child eobject + * It will look for the good role of the child eobject. * * @param domain * the Transactional Domain, cannot be null @@ -172,6 +197,8 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD * the object where we want to drop the object * @param newElement * that we want to move, cannot be null + * @param before + * flag to know if the element have to put before the drop target * @return the list of commands to to the drop */ protected List<Command> getOrderChangeCommand(TransactionalEditingDomain domain, EObject targetOwner, EObject objectLocation, EObject newElement, boolean before) { @@ -199,7 +226,7 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD * @param newElement * the new element * @param before - * the before + * flag to know if the selection have to put before the object location * @return the list */ private List<Command> handleEObject(final EObject targetOwner, final EObject objectLocation, final EObject newElement, boolean before) { @@ -288,7 +315,7 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD } /** - * get the list of good command by taking in account if this is a change order or a drop into + * get the list of good command by taking in account if this is a change order or a drop into. * * @param target * the target object of the drop @@ -297,22 +324,27 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD public CompoundCommand getDrop(Object target) { CommonDropAdapter dropAdapter = getCommonDropAdapter(); List<Command> commandList = new ArrayList<Command>(); + boolean before; switch (dropAdapter.getCurrentOperation()) { case DND.DROP_MOVE: if (dropAdapter.getCurrentLocation() == ViewerDropAdapter.LOCATION_BEFORE) { + before = true; if (target instanceof EObjectTreeElement) { - commandList = getOrderChangeCommand(target, true); + commandList.addAll(getOrderChangeCommand(target, before)); + } } else if (dropAdapter.getCurrentLocation() == ViewerDropAdapter.LOCATION_AFTER) { + before = false; if (target instanceof EObjectTreeElement) { - commandList = getOrderChangeCommand(target, false); + commandList.addAll(getOrderChangeCommand(target, before)); + } } else if (dropAdapter.getCurrentLocation() == ViewerDropAdapter.LOCATION_ON) { if (target instanceof EObjectTreeElement) { - commandList = getDropIntoCommand(target, null); + commandList.addAll(getDropIntoCommand(target, null)); } if (target instanceof EReferenceTreeElement) { - commandList = getDropIntoCommand(((EReferenceTreeElement) target).getParent(), ((EReferenceTreeElement) target).getEReference()); + commandList.addAll(getDropIntoCommand(((EReferenceTreeElement) target).getParent(), ((EReferenceTreeElement) target).getEReference())); } } @@ -324,7 +356,7 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD } /** - * Test if a possibleSub eclass is a sub eclass + * Test if a possibleSub eclass is a sub eclass. * * @param aclass * , cannot be null @@ -343,6 +375,14 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD return false; } + /** + * @see org.eclipse.ui.navigator.CommonDropAdapterAssistant#validateDrop(java.lang.Object, int, org.eclipse.swt.dnd.TransferData) + * + * @param target + * @param operation + * @param transferType + * @return + */ @Override public IStatus validateDrop(Object target, int operation, TransferData transferType) { Command dropCommand = getDrop(target); @@ -353,18 +393,18 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD } /** - * get the list of commands to drop an element + * get the list of commands to drop an element. * * @param target * , can be null but do nothing - * @param the + * @param eref * role where there is a drop ( can be null) * @return the list of the commands */ protected List<Command> getDropIntoCommand(final Object target, EReference eref) { - // init - ArrayList<Command> result = new ArrayList<Command>(); + // Initialise + List<Command> result = new ArrayList<Command>(); EObject targetEObject = null; targetEObject = EMFHelper.getEObject(target); @@ -396,9 +436,11 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD } /** + * Gets the editors. * - * @return - * the list of the editors + * @param context + * the context + * @return the list of the editors */ private List<Object> getEditors(EObject context) { try { @@ -409,51 +451,339 @@ public class CommonDropAdapterAssistant extends org.eclipse.ui.navigator.CommonD } /** - * get the list of commands to drop an element + * get the list of commands to drop an element. * * @param target * , can be null but do nothing + * @param before + * flag to know if the selection have to put before the target * @return the list of the commands */ protected List<Command> getOrderChangeCommand(final Object target, boolean before) { - // init - ArrayList<Command> result = new ArrayList<Command>(); - EObject objectLocation = null; - EObject objectOwner = null; + // Initialise + List<Command> result = new ArrayList<Command>(); - objectLocation = EMFHelper.getEObject(target); - if (objectLocation == null) { + // Get EObject of the Target + EObject dropTarget = EMFHelper.getEObject(target); + if (dropTarget == null) { return result; } - if (objectLocation instanceof Diagram) { - objectOwner = ((Diagram) objectLocation).getElement(); - } else { - objectOwner = objectLocation.eContainer(); - } - // get Command from the selection - ISelection selection = LocalSelectionTransfer.getTransfer().getSelection(); - if (selection instanceof IStructuredSelection) { - List<?> selectedElements = ((IStructuredSelection) selection).toList(); + // list of commands required to add the selection to the Target place + Collection<? extends Command> orderCommandList = getSelectionOrderCommand(dropTarget, before); + result.addAll(orderCommandList); + + + return result; + } + + /** + * Gets the e object selection. + * + * @return List of Selected EObjects + */ + private List<EObject> geEObjectSelection() { + List<EObject> selection = new ArrayList<EObject>(); + ISelection select = LocalSelectionTransfer.getTransfer().getSelection(); + if (select instanceof IStructuredSelection) { + List<?> selectedElements = ((IStructuredSelection) select).toList(); Iterator<?> it = selectedElements.iterator(); while (it.hasNext()) { Object object = it.next(); EObject eObjectchild = EMFHelper.getEObject(object); - // test if object is an eobject - if (eObjectchild != null && objectOwner != null) { + // test if object is an eObject + if (eObjectchild != null && eObjectchild.eContainer() != null) { - result.addAll(getOrderChangeCommand(getEditingDomain(eObjectchild), objectOwner, objectLocation, eObjectchild, before)); + selection.add(eObjectchild); } } } - return result; + + return selection; + } + + + /** + * Gets the selection order command. + * + * @param dropTarget + * the drop target + * @param before + * flag to know if the selection have to put before the drop target + * @return the selection order command + */ + private List<Command> getSelectionOrderCommand(EObject dropTarget, boolean before) { + + // Get selection + List<EObject> selection = geEObjectSelection(); + + // Build list of commands according of the selection + List<Command> commandList = null; + if (isSelectionReorderAllowed(dropTarget, selection)) { + commandList = getReorderCommands(dropTarget, before, selection); + } else { + commandList = Collections.emptyList(); + } + + return commandList; + + } + + /** + * Gets the reorder commands. + * + * @param dropTarget + * the drop target + * @param before + * flag to know if the selection have to put before the drop target + * @param selection + * the selection + * @return the reorder commands + */ + private List<Command> getReorderCommands(EObject dropTarget, boolean before, List<EObject> selection) { + + // List of Command to drop the selection to the Target place + List<Command> separateCommand = new ArrayList<Command>(); + + // Target Container + EObject targetContainer = dropTarget.eContainer(); + + List<EObject> treatedSelection = new ArrayList<EObject>(); + Iterator<EObject> selectionIterator = selection.iterator(); + + while (selectionIterator.hasNext()) { + + // Current item + EObject currentItem = selectionIterator.next(); + + if (!treatedSelection.contains(currentItem)) { + + List<EObject> subSelection = getSameTypeSubSelection(currentItem, selection); + treatedSelection.addAll(subSelection); + + if (!subSelection.isEmpty()) { + + + // Get list of the feature with the same type as the selected item into the target container + // List of structural Feature of the selection type. + // Possible Features + + List<EStructuralFeature> possibleFeatures = getStructuralFeatureList(targetContainer, currentItem.eClass()); + for (EStructuralFeature eStructuralFeature : possibleFeatures) { + // List of all Reference into TargetContainer of type eStructuralFeature + Object targetStructuralFeatureOld = targetContainer.eGet(eStructuralFeature); + + SetRequest setRequest = null; + // Check if targetStructuralFeatureOld is a List or a single EStructuralFeature + if (eStructuralFeature.isMany()) { + // Cast Check + if (targetStructuralFeatureOld instanceof EList) { + + // Build new feature list with correct order of features to be set + List<EObject> targetStructuralFeatureNewList = new ArrayList<EObject>(); + targetStructuralFeatureNewList.addAll(getNewFeatureList(dropTarget, (EList<EObject>) targetStructuralFeatureOld, subSelection, before)); + + // Create Set Request for the new feature list + setRequest = new SetRequest(targetContainer, eStructuralFeature, targetStructuralFeatureNewList); + } + + } else { + // if only one instance possible, replace the actual one + // Cast Check + if (targetStructuralFeatureOld instanceof EStructuralFeature) { + setRequest = new SetRequest(targetContainer, eStructuralFeature, subSelection.get(0)); + + } + } + + Command requestCommand = getRequestCommand(targetContainer, setRequest); + if (requestCommand != null) { + separateCommand.add(requestCommand); + } + } + } + } + } + + + return separateCommand; + } + + /** + * Gets the request command. + * + * @param container + * the container + * @param setRequest + * the set request + * @return the request command + */ + private Command getRequestCommand(EObject container, SetRequest setRequest) { + + // List of Command to drop the selection to the Target place + Command separateCommand = null; + + IElementEditService provider = ElementEditServiceUtils.getCommandProvider(container); + + + if (provider != null) { + // Retrieve delete command from the Element Edit service + ICommand command = provider.getEditCommand(setRequest); + + if (command != null && command.canExecute()) { + command.setLabel(REORDER_COMMAND_LABEL); + separateCommand = GMFtoEMFCommandWrapper.wrap(command); + } + } + return separateCommand; } /** - * get the editing domain + * Gets sub selection of elements which have same type as item in selection. + * + * @param item + * the item + * @param selection + * the selection + * @return the item sublist + */ + private List<EObject> getSameTypeSubSelection(EObject item, List<EObject> selection) { + List<EObject> subSelection = new ArrayList<EObject>(); + + // Get item type + EClass itemType = item.eClass(); + Iterator<EObject> selectionIterator = selection.iterator(); + + // Define a sub list from the selection of the same type + while (selectionIterator.hasNext()) { + + // Current item + EObject current = selectionIterator.next(); + EClass currentType = current.eClass(); + if (currentType.equals(itemType)) { + subSelection.add(current); + } + } + + return subSelection; + + } + + /** + * Gets the new feature list. + * + * @param dropTarget + * the e target + * @param oldList + * the old list + * @param subSelection + * the sub selection + * @param before + * flag to know if the sub selection have to put before the drop target + * @return the new feature list + */ + private EList<EObject> getNewFeatureList(EObject dropTarget, EList<EObject> oldList, List<EObject> subSelection, boolean before) { + + EList<EObject> newFeatureList = new BasicEList<EObject>(oldList); + + for (EObject subItem : subSelection) { + + if (!subItem.equals(dropTarget)) { + + + // Get index of drop target + int indexObject = newFeatureList.indexOf(dropTarget); + + if (indexObject != -1) { + + // Remove sub item of the list + newFeatureList.remove(subItem); + if (before) { + // Add subItem to index of dorpTarget + newFeatureList.add(indexObject, subItem); + } else { + // Add subItem after dropTarget position according to the index of subItem in subselection + int behindPosition = indexObject + 1 + subSelection.indexOf(subItem); + if (behindPosition < newFeatureList.size()) { + newFeatureList.add(behindPosition, subItem); + } else { + newFeatureList.add(subItem); + } + } + } + + } else { + newFeatureList.add(subItem); + } + + } + + + return newFeatureList; + + } + + + /** + * Checks if is selection reorder allowed. + * + * @param dropTarget + * the drop target + * @param selection + * Selection list to be tested + * @return <code>true</code> if the selection is not empty and the Drop target is contained, otherwise <code>false</code> + */ + private boolean isSelectionReorderAllowed(EObject dropTarget, List<EObject> selection) { + // Check selection + return !selection.isEmpty() && dropTarget.eContainer() != null; + } + + /** + * Gets the structural feature list. + * + * @param targetOwner + * the target owner + * @param itemSelected + * the item selected + * @return the structural feature list + */ + private List<EStructuralFeature> getStructuralFeatureList(EObject targetOwner, EClass itemSelected) { + + // List of possible target feature to drop selection + List<EStructuralFeature> possibleFeaturesList = new ArrayList<EStructuralFeature>(); + EList<EStructuralFeature> targetFeaturesList = targetOwner.eClass().getEAllStructuralFeatures(); + + // Find the feature between children and owner + Iterator<EStructuralFeature> featuresIterator = targetFeaturesList.iterator(); + + while (featuresIterator.hasNext()) { + EStructuralFeature currentFeature = featuresIterator.next(); + + // Only Reference type of feature that can be a container should be taken into account + if (currentFeature instanceof EReference) { + EReference reference = (EReference) currentFeature; + if (reference.isContainment()) { + // In case of the selected item is a sub class of the current fetaure, it is considered as part of the feature list + if (isSubClass(reference.getEType(), itemSelected)) { + possibleFeaturesList.add(currentFeature); + } + + } + } + } + + return possibleFeaturesList; + + } + + + /** + * Gets the editing domain. * - * @return get the Transaction Editing Domain + * @param context + * the context + * @return the editing domain */ protected TransactionalEditingDomain getEditingDomain(EObject context) { try { |