Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider DropDescription and PasteDescription tools of other diagrams #398

Merged
merged 5 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2021 THALES GLOBAL SERVICES.
* Copyright (c) 2007, 2024 THALES GLOBAL SERVICES.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand All @@ -16,6 +16,9 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
Expand All @@ -32,13 +35,13 @@
import org.eclipse.sirius.diagram.business.api.query.DDiagramQuery;
import org.eclipse.sirius.diagram.business.api.query.DiagramElementMappingQuery;
import org.eclipse.sirius.diagram.business.internal.metamodel.helper.ContainerMappingWithInterpreterHelper;
import org.eclipse.sirius.diagram.description.AdditionalLayer;
import org.eclipse.sirius.diagram.description.DiagramElementMapping;
import org.eclipse.sirius.diagram.description.DragAndDropTargetDescription;
import org.eclipse.sirius.diagram.description.Layer;
import org.eclipse.sirius.diagram.description.tool.ContainerDropDescription;
import org.eclipse.sirius.diagram.tools.api.Messages;
import org.eclipse.sirius.tools.api.SiriusPlugin;
import org.eclipse.sirius.viewpoint.description.tool.AbstractToolDescription;
import org.eclipse.sirius.viewpoint.description.tool.DragSource;
import org.eclipse.sirius.viewpoint.description.tool.ToolPackage;

Expand Down Expand Up @@ -112,7 +115,7 @@ public static ContainerDropDescription getBestDropDescription(final DragAndDropT

/* find valid candidates */
final Collection<ContainerDropDescription> candidates = new ArrayList<>();
for (final ContainerDropDescription dropTool : DDiagramElementContainerWithInterpreterOperations.getDropToolsOnActivatedLayers(diagram, description)) {
for (final ContainerDropDescription dropTool : DDiagramElementContainerWithInterpreterOperations.getActivatedDropTools(diagram, description)) {
if (DDiagramElementContainerWithInterpreterOperations.checkDragSource(dropTool, dragSource)
&& DDiagramElementContainerWithInterpreterOperations.checkDroppedDiagramElement(dropTool, droppedDiagramElement, newViewContainer)) {
if (DDiagramElementContainerWithInterpreterOperations.checkPrecondition(dropTool, safeInterpreter, droppedElement)) {
Expand Down Expand Up @@ -169,20 +172,6 @@ private static boolean checkPrecondition(final ContainerDropDescription dropTool
return true;
}

private static Collection<ContainerDropDescription> getDropToolsOnActivatedLayers(final DDiagram diagram, final DragAndDropTargetDescription mapping) {
if (diagram.getDescription().getDefaultLayer() != null) {
final Collection<AbstractToolDescription> allActivatedTools = new HashSet<>();
allActivatedTools.addAll(diagram.getDescription().getDefaultLayer().getAllTools());
for (Layer layer : new DDiagramQuery(diagram).getAllActivatedLayers()) {
allActivatedTools.addAll(layer.getAllTools());
}
Collection<ContainerDropDescription> dropTools = DDiagramElementContainerWithInterpreterOperations.getDropTools(mapping);
dropTools.retainAll(allActivatedTools);
return dropTools;
}
return DDiagramElementContainerWithInterpreterOperations.getDropTools(mapping);
}

/**
* Returns the drop tools of the mapping.
*
Expand All @@ -198,4 +187,62 @@ private static Collection<ContainerDropDescription> getDropTools(final DragAndDr
}
return dropTools;
}

/**
* Returns the list of the activated drop tools for the <code>mapping</code>. An activated drop tool is:
* <UL>
* <LI>in a default layer of any diagram,</LI>
* <LI>or in an activated layer of the current diagram (contained in or reused by).</LI>
* </UL>
*
* @param diagram
* The current diagram
* @param mapping
* The mapping of the current drag'n'droped element
* @return the list of the activated drop tools.
*/
private static Collection<ContainerDropDescription> getActivatedDropTools(final DDiagram diagram, final DragAndDropTargetDescription mapping) {
Collection<ContainerDropDescription> dropTools = DDiagramElementContainerWithInterpreterOperations.getDropTools(mapping);
return dropTools.stream().filter(desc -> isActive(desc, diagram)).collect(Collectors.toCollection(HashSet<ContainerDropDescription>::new));
}

/**
* Tests whether a {@link ContainerDropDescription} belongs to a default layer or to an activated layer of the
* current diagram.
*
* @param dropDesc
* the current {@link ContainerDropDescription} of the drag'n'dropped element.
* @param diagram
* the current diagram
* @return <code>true</code> if the ContainerDropDescription is active, false otherwise.
*/
private static boolean isActive(final ContainerDropDescription dropDesc, final DDiagram diagram) {
boolean result = false;
Optional<Layer> optionalParentLayer = getLayer(dropDesc);
if (optionalParentLayer.isPresent()) {
if (!(optionalParentLayer.get() instanceof AdditionalLayer)) {
// This layer is a default layer.
result = true;
} else {
List<Layer> activatedLayers = new DDiagramQuery(diagram).getAllActivatedLayers();
if (activatedLayers.contains(optionalParentLayer.get()) || activatedLayers.stream().anyMatch(layer -> layer.getReusedTools().contains(dropDesc))) {
// The dropDesc is in an activated layer of the current diagram or it is reused by an activated
// layer of the current diagram.
result = true;
}
}
}
return result;
}

private static Optional<Layer> getLayer(ContainerDropDescription containerDropDescription) {
EObject current = containerDropDescription;
while (current != null) {
if (current instanceof Layer) {
return Optional.of((Layer) current);
}
current = current.eContainer();
}
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2011, 2017 THALES GLOBAL SERVICES.
* Copyright (c) 2011, 2024 THALES GLOBAL SERVICES.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
Expand All @@ -15,18 +15,22 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.business.api.query.DDiagramQuery;
import org.eclipse.sirius.diagram.business.api.query.DiagramDescriptionQuery;
import org.eclipse.sirius.diagram.business.api.query.DiagramElementMappingQuery;
import org.eclipse.sirius.diagram.description.AdditionalLayer;
import org.eclipse.sirius.diagram.description.DiagramDescription;
import org.eclipse.sirius.diagram.description.DiagramElementMapping;
import org.eclipse.sirius.diagram.description.Layer;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.sirius.viewpoint.description.PasteTargetDescription;
import org.eclipse.sirius.viewpoint.description.tool.AbstractToolDescription;
import org.eclipse.sirius.viewpoint.description.tool.PasteDescription;

import com.google.common.collect.Sets;
Expand Down Expand Up @@ -63,30 +67,16 @@ public Collection<PasteDescription> getAvailablePasteTools() {
final Collection<PasteDescription> result = new ArrayList<>();
if (semDec instanceof DDiagram) {
DDiagram diag = (DDiagram) semDec;
result.addAll(getPasteToolsOnActivatedLayers(diag, diag.getDescription()));
result.addAll(getActivatedPasteTools(diag, diag.getDescription()));
} else if (semDec instanceof DDiagramElement) {
DDiagramElement dde = (DDiagramElement) semDec;
result.addAll(getPasteToolsOnActivatedLayers(dde.getParentDiagram(), dde.getDiagramElementMapping()));
result.addAll(getActivatedPasteTools(dde.getParentDiagram(), dde.getDiagramElementMapping()));
}
// No other cases : DDiagram could only handle paste operation on itself
// or on of its element.
return result;
}

private Collection<PasteDescription> getPasteToolsOnActivatedLayers(final DDiagram dDiagram, final PasteTargetDescription pasteTargetDescription) {
if (dDiagram.getDescription().getDefaultLayer() != null) {
final Collection<AbstractToolDescription> allActivatedTools = new HashSet<>();
allActivatedTools.addAll(dDiagram.getDescription().getDefaultLayer().getAllTools());
for (Layer layer : new DDiagramQuery(dDiagram).getAllActivatedLayers()) {
allActivatedTools.addAll(layer.getAllTools());
}
Collection<PasteDescription> pasteTools = getAllPasteTools(pasteTargetDescription);
pasteTools.retainAll(allActivatedTools);
return pasteTools;
}
return getAllPasteTools(pasteTargetDescription);
}

/**
* Returns the paste tools of the pasteTargetDescription.
*
Expand All @@ -104,4 +94,62 @@ private Collection<PasteDescription> getAllPasteTools(final PasteTargetDescripti
}
return pasteTools;
}

/**
* Returns the list of the activated drop tools for the <code>mapping</code>. An activated drop tool is:
* <UL>
* <LI>in a default layer of any diagram,</LI>
* <LI>or in an activated layer of the current diagram (contained in or reused by).</LI>
* </UL>
*
* @param diagram
* The current diagram
* @param pasteTargetDesc
* The current paste target description
* @return the list of the activated paste tools.
*/
private Collection<PasteDescription> getActivatedPasteTools(final DDiagram diagram, final PasteTargetDescription pasteTargetDesc) {
Collection<PasteDescription> pasteTools = getAllPasteTools(pasteTargetDesc);
return pasteTools.stream().filter(desc -> isActive(desc, diagram)).collect(Collectors.toCollection(HashSet<PasteDescription>::new));
}

/**
* Tests whether a {@link PasteDescription} belongs to a default layer or to an activated layer of the current
* diagram.
*
* @param pasteDesc
* the current {@link PasteDescription} of the drag'n'dropped element.
* @param diagram
* the current diagram
* @return <code>true</code> if the PasteDescription is active, false otherwise.
*/
private static boolean isActive(final PasteDescription pasteDesc, final DDiagram diagram) {
boolean result = false;
Optional<Layer> optionalParentLayer = getLayer(pasteDesc);
if (optionalParentLayer.isPresent()) {
if (!(optionalParentLayer.get() instanceof AdditionalLayer)) {
// This layer is a default layer.
result = true;
} else {
List<Layer> activatedLayers = new DDiagramQuery(diagram).getAllActivatedLayers();
if (activatedLayers.contains(optionalParentLayer.get()) || activatedLayers.stream().anyMatch(layer -> layer.getReusedTools().contains(pasteDesc))) {
// The pasteDesc is in an activated layer of the current diagram or it is reused by an activated
// layer of the current diagram.
result = true;
}
}
}
return result;
}

private static Optional<Layer> getLayer(PasteDescription containerDropDescription) {
EObject current = containerDropDescription;
while (current != null) {
if (current instanceof Layer) {
return Optional.of((Layer) current);
}
current = current.eContainer();
}
return Optional.empty();
}
}
Loading