Skip to content

Commit

Permalink
[380] Consider PasteDescription tools of other diagrams
Browse files Browse the repository at this point in the history
Before this commit the PasteDescription tools of other diagrams are
visible in the VSM by the specifier but ignored at runtime.

Bug: #380
  • Loading branch information
lredor committed May 24, 2024
1 parent b072f1c commit 115b9f8
Showing 1 changed file with 66 additions and 18 deletions.
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();
}
}

0 comments on commit 115b9f8

Please sign in to comment.