Skip to content

Commit

Permalink
[346] Support "Paste Style" when source and target are of different
Browse files Browse the repository at this point in the history
types

Note that paste style has been disabled from Edge to Node or from Edge
to Container to avoid inconsistency between Sirius and GMF style.

#346
Signed-off-by: Laurent Fasani <laurent.fasani@obeo.fr>
Signed-off-by: Séraphin Costa <seraphin.costa@obeosoft.com>
  • Loading branch information
lfasani authored and scosta-obeo committed Apr 8, 2024
1 parent 830c2f6 commit 0915ecc
Show file tree
Hide file tree
Showing 7 changed files with 342 additions and 42 deletions.
Expand Up @@ -63,6 +63,7 @@
import org.eclipse.sirius.diagram.DNodeContainer;
import org.eclipse.sirius.diagram.DNodeList;
import org.eclipse.sirius.diagram.DNodeListElement;
import org.eclipse.sirius.diagram.EdgeStyle;
import org.eclipse.sirius.diagram.EdgeTarget;
import org.eclipse.sirius.diagram.business.api.query.DDiagramElementQuery;
import org.eclipse.sirius.diagram.formatdata.AbstractFormatData;
Expand Down Expand Up @@ -788,15 +789,17 @@ protected void applySiriusStyle(DSemanticDecorator semanticDecorator, AbstractFo
@SuppressWarnings("unchecked")
protected void applyGMFStyle(View newView, AbstractFormatData formatData) {
if (newView != null && formatData.getGmfView() != null) {
@SuppressWarnings("rawtypes")
List excludedStyles = new ArrayList<>();
if (newView instanceof Edge) {
// The style of RoutingStyle class is considered as format
// properties. So they have already been pasted during paste
// format.
excludedStyles.add(NotationPackage.eINSTANCE.getRoutingStyle());
if (!(formatData.getSiriusStyle() instanceof EdgeStyle) || newView.getElement() instanceof DEdge) {
@SuppressWarnings("rawtypes")
List excludedStyles = new ArrayList<>();
if (newView instanceof Edge) {
// The style of RoutingStyle class is considered as format
// properties. So they have already been pasted during paste
// format.
excludedStyles.add(NotationPackage.eINSTANCE.getRoutingStyle());
}
new ViewRefactorHelper().copyViewAppearance(formatData.getGmfView(), newView, excludedStyles);
}
new ViewRefactorHelper().copyViewAppearance(formatData.getGmfView(), newView, excludedStyles);
}
}

Expand Down
Expand Up @@ -12,6 +12,11 @@
*******************************************************************************/
package org.eclipse.sirius.diagram.ui.tools.api.format;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.sirius.diagram.ContainerStyle;
Expand All @@ -22,6 +27,7 @@
import org.eclipse.sirius.diagram.EdgeStyle;
import org.eclipse.sirius.diagram.NodeStyle;
import org.eclipse.sirius.tools.internal.SiriusCopierHelper;
import org.eclipse.sirius.viewpoint.Customizable;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
import org.eclipse.sirius.viewpoint.Style;
import org.eclipse.sirius.viewpoint.ViewpointPackage;
Expand Down Expand Up @@ -69,7 +75,66 @@ default void applySiriusStyle(DSemanticDecorator semanticDecorator, Style sirius
} else if (semanticDecorator instanceof DEdge && copyOfSiriusStyle instanceof EdgeStyle) {
computeCustomFeatures(((DEdge) semanticDecorator).getOwnedStyle(), copyOfSiriusStyle);
((DEdge) semanticDecorator).setOwnedStyle((EdgeStyle) copyOfSiriusStyle);
} else {
// try to apply style if the Diagram elements are different
applySiriusStyleAtBest(semanticDecorator, siriusStyle);
}
}

private void applySiriusStyleAtBest(DSemanticDecorator targetSemanticDecorator, Style siriusSourceStyle) {
if (!(siriusSourceStyle instanceof EdgeStyle)) {
for (Customizable targetStyle : getStyle(targetSemanticDecorator)) {
addNewValueAndSetCustomFeaturesAtBest(siriusSourceStyle, targetStyle);
}
}
}

/**
* Check for each attribute of targetStyleToChange if it is the same or equivalent in sourceStyle.</br>
* Then it changes the value and add a custom feature.
*
* @param sourceStyle
* The style to compare with
* @param targetStyleToChange
* The style to update.
*/
private void addNewValueAndSetCustomFeaturesAtBest(Customizable sourceStyle, Customizable targetStyleToChange) {
final EAttribute[] exceptionAttributes = { //
ViewpointPackage.Literals.IDENTIFIED_ELEMENT__UID, //
ViewpointPackage.Literals.CUSTOMIZABLE__CUSTOM_FEATURES, //
ViewpointPackage.Literals.BASIC_LABEL_STYLE__SHOW_ICON, //
ViewpointPackage.Literals.BASIC_LABEL_STYLE__ICON_PATH, //
};
for (EAttribute targetStyleAttribute : targetStyleToChange.eClass().getEAllAttributes()) {
if (!Arrays.asList(exceptionAttributes).contains(targetStyleAttribute)) {
EAttribute sourceStyleAttribute = getCorrespondingEAttribute(targetStyleAttribute, sourceStyle);
if (sourceStyleAttribute != null) {
if (!targetStyleToChange.eGet(targetStyleAttribute).equals(sourceStyle.eGet(sourceStyleAttribute))) {
targetStyleToChange.getCustomFeatures().add(targetStyleAttribute.getName());
targetStyleToChange.eSet(targetStyleAttribute, sourceStyle.eGet(sourceStyleAttribute));
}
}
}
}
}

private List<Customizable> getStyle(DSemanticDecorator semanticDecorator) {
List<Customizable> styles = new ArrayList<>();
if (semanticDecorator instanceof DNode node) {
styles.add(node.getOwnedStyle());
} else if (semanticDecorator instanceof DNodeListElement listElement) {
styles.add(listElement.getOwnedStyle());
} else if (semanticDecorator instanceof DDiagramElementContainer container) {
styles.add(container.getOwnedStyle());
} else if (semanticDecorator instanceof DEdge edge) {
Style ownedStyle = edge.getOwnedStyle();
if (ownedStyle instanceof EdgeStyle edgeStyle) {
Arrays.asList(edgeStyle.getCenterLabelStyle(), edgeStyle.getBeginLabelStyle(), edgeStyle.getEndLabelStyle()).stream()//
.filter(Objects::nonNull) //
.forEach(styles::add); //
}
}
return styles;
}

/**
Expand All @@ -81,9 +146,13 @@ default void applySiriusStyle(DSemanticDecorator semanticDecorator, Style sirius
* @param newStyle
* The new style in which to add custom features.
*/
default void computeCustomFeatures(Style oldStyle, Style newStyle) {
private void computeCustomFeatures(Style oldStyle, Style newStyle) {
final EAttribute[] exceptionAttributes = { //
ViewpointPackage.Literals.IDENTIFIED_ELEMENT__UID, //
ViewpointPackage.Literals.CUSTOMIZABLE__CUSTOM_FEATURES, //
};
for (EAttribute attribute : newStyle.eClass().getEAllAttributes()) {
if (!ViewpointPackage.Literals.CUSTOMIZABLE__CUSTOM_FEATURES.equals(attribute)) {
if (!Arrays.asList(exceptionAttributes).contains(attribute)) {
EAttribute attributeOfOldStyle = getCorrespondingEAttribute(attribute, oldStyle);
if (attributeOfOldStyle != null) {
if (newStyle.eIsSet(attribute)) {
Expand All @@ -98,7 +167,7 @@ default void computeCustomFeatures(Style oldStyle, Style newStyle) {
}
}

private EAttribute getCorrespondingEAttribute(EAttribute attribute, Style style) {
private EAttribute getCorrespondingEAttribute(EAttribute attribute, Customizable style) {
EAttribute result = null;
if (style.eClass().getFeatureID(attribute) != -1) {
result = attribute;
Expand Down
Expand Up @@ -31,6 +31,8 @@
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.sirius.common.ui.tools.api.util.EclipseUIUtil;
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.DEdge;
import org.eclipse.sirius.diagram.EdgeStyle;
import org.eclipse.sirius.diagram.ui.provider.DiagramUIPlugin;
import org.eclipse.sirius.diagram.ui.provider.Messages;
import org.eclipse.sirius.diagram.ui.tools.api.format.SiriusStyleClipboard;
Expand Down Expand Up @@ -233,12 +235,15 @@ public void run() {

for (IGraphicalEditPart targetEditPart : targetEditParts) {
if (targetEditPart.resolveSemanticElement() instanceof DDiagramElement targetElement && canEditElement(targetElement)) {
// create command
clipboard.getGmfView().ifPresent(gmfView -> {
command.add(PasteStyleCommandProvider.createGMFCommand(domain, targetEditPart, gmfView));
});
clipboard.getSiriusStyle().ifPresent(siriusStyle -> {
command.add(PasteStyleCommandProvider.createSiriusCommand(domain, targetElement, siriusStyle));
clipboard.getGmfView().ifPresent(gmfView -> {
// exclude copy-paste from Edge to Node/Container
if (!(siriusStyle instanceof EdgeStyle) || targetElement instanceof DEdge) {
// create command
command.add(PasteStyleCommandProvider.createGMFCommand(domain, targetEditPart, gmfView));
command.add(PasteStyleCommandProvider.createSiriusCommand(domain, targetElement, siriusStyle));
}
});
});
}
}
Expand Down

0 comments on commit 0915ecc

Please sign in to comment.