|
| 1 | +/** |
| 2 | + * Copyright (c) 2011-2024 Obeo. |
| 3 | + * All rights reserved. This program and the accompanying materials |
| 4 | + * are made available under the terms of the Eclipse Public License v1.0 |
| 5 | + * which accompanies this distribution, and is available at |
| 6 | + * http://www.eclipse.org/legal/epl-v10.html |
| 7 | + * |
| 8 | + * Contributors: |
| 9 | + * Obeo - initial API and implementation |
| 10 | + * |
| 11 | + */ |
| 12 | +package org.obeonetwork.bpmn2.design; |
| 13 | + |
| 14 | +import java.util.ArrayList; |
| 15 | +import java.util.List; |
| 16 | +import java.util.Optional; |
| 17 | +import java.util.stream.Collectors; |
| 18 | + |
| 19 | +import org.eclipse.core.runtime.IStatus; |
| 20 | +import org.eclipse.emf.common.command.CommandStack; |
| 21 | +import org.eclipse.emf.common.util.EList; |
| 22 | +import org.eclipse.emf.ecore.EObject; |
| 23 | +import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; |
| 24 | +import org.eclipse.emf.transaction.RecordingCommand; |
| 25 | +import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| 26 | +import org.eclipse.gmf.runtime.notation.Bounds; |
| 27 | +import org.eclipse.gmf.runtime.notation.Edge; |
| 28 | +import org.eclipse.gmf.runtime.notation.FontStyle; |
| 29 | +import org.eclipse.gmf.runtime.notation.IdentityAnchor; |
| 30 | +import org.eclipse.gmf.runtime.notation.Location; |
| 31 | +import org.eclipse.gmf.runtime.notation.Node; |
| 32 | +import org.eclipse.gmf.runtime.notation.NotationFactory; |
| 33 | +import org.eclipse.gmf.runtime.notation.RelativeBendpoints; |
| 34 | +import org.eclipse.gmf.runtime.notation.View; |
| 35 | +import org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint; |
| 36 | +import org.eclipse.sirius.diagram.AbstractDNode; |
| 37 | +import org.eclipse.sirius.diagram.DDiagramElement; |
| 38 | +import org.eclipse.sirius.diagram.DEdge; |
| 39 | +import org.eclipse.sirius.diagram.DSemanticDiagram; |
| 40 | +import org.eclipse.sirius.diagram.EdgeStyle; |
| 41 | +import org.eclipse.sirius.diagram.FlatContainerStyle; |
| 42 | +import org.eclipse.sirius.diagram.WorkspaceImage; |
| 43 | +import org.eclipse.sirius.viewpoint.Style; |
| 44 | +import org.eclipse.ui.IWorkbench; |
| 45 | +import org.eclipse.ui.IWorkbenchPage; |
| 46 | +import org.eclipse.ui.PlatformUI; |
| 47 | +import org.obeonetwork.bpmn2.design.util.GMFHelper; |
| 48 | +import org.obeonetwork.bpmn2.design.util.GMFStyleCopier; |
| 49 | +import org.obeonetwork.bpmn2.design.util.SiriusHelper; |
| 50 | +import org.obeonetwork.bpmn2.design.util.SiriusStyleCopier; |
| 51 | +import org.obeonetwork.dsl.bpmn2.BoundaryEvent; |
| 52 | +import org.obeonetwork.dsl.bpmn2.FlowNode; |
| 53 | +import org.obeonetwork.dsl.bpmn2.SequenceFlow; |
| 54 | + |
| 55 | +public class CopySiriusGMFStylesHelper { |
| 56 | + |
| 57 | + public static void copyStyles(EObject newElement, DDiagramElement containerView, String oldId, String newId) { |
| 58 | + if (newElement instanceof BoundaryEvent) { |
| 59 | + copyBoundaryEvent((BoundaryEvent) newElement, containerView, oldId, newId); |
| 60 | + } else if (newElement instanceof FlowNode) { |
| 61 | + copyFlowNode((FlowNode) newElement, containerView, oldId, newId); |
| 62 | + } else if (newElement instanceof SequenceFlow) { |
| 63 | + copySequenceFlow((SequenceFlow) newElement, containerView, oldId, newId); |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + private static void copyBoundaryEvent(BoundaryEvent newElement, DDiagramElement containerView, String oldId, |
| 68 | + String newId) { |
| 69 | + IWorkbench workbench = PlatformUI.getWorkbench(); |
| 70 | + IWorkbenchPage[] pages = workbench.getActiveWorkbenchWindow().getPages(); |
| 71 | + AbstractDNode oldAbstractDNode = SiriusHelper.getAbstractDNode(oldId, pages); |
| 72 | + if (oldAbstractDNode != null) { |
| 73 | + SiriusHelper.refresh((DSemanticDiagram) containerView.getParentDiagram()); |
| 74 | + // Update boundary event asynchronously. |
| 75 | + Thread t = new Thread() { |
| 76 | + public void run() { |
| 77 | + int cpt = 0; |
| 78 | + while (cpt < 100) { |
| 79 | + AbstractDNode newAbstractDNode = SiriusHelper.getAbstractDNode(containerView.getParentDiagram(), |
| 80 | + newId); |
| 81 | + if (newAbstractDNode == null) { |
| 82 | + try { |
| 83 | + Thread.sleep(1000); |
| 84 | + cpt++; |
| 85 | + } catch (InterruptedException e) { |
| 86 | + Activator.log(IStatus.ERROR, e.getMessage(), e); |
| 87 | + } |
| 88 | + } else { |
| 89 | + TransactionalEditingDomain ted = (TransactionalEditingDomain) AdapterFactoryEditingDomain |
| 90 | + .getEditingDomainFor(newAbstractDNode); |
| 91 | + CommandStack commandStack = ted.getCommandStack(); |
| 92 | + commandStack.execute(new RecordingCommand(ted) { |
| 93 | + @Override |
| 94 | + protected void doExecute() { |
| 95 | + updateStyles(oldAbstractDNode, newAbstractDNode); |
| 96 | + } |
| 97 | + }); |
| 98 | + return; |
| 99 | + } |
| 100 | + } |
| 101 | + }; |
| 102 | + }; |
| 103 | + t.start(); |
| 104 | + } |
| 105 | + } |
| 106 | + |
| 107 | + private static void copyFlowNode(FlowNode newElement, DDiagramElement containerView, String oldId, String newId) { |
| 108 | + IWorkbench workbench = PlatformUI.getWorkbench(); |
| 109 | + IWorkbenchPage[] pages = workbench.getActiveWorkbenchWindow().getPages(); |
| 110 | + AbstractDNode oldAbstractDNode = SiriusHelper.getAbstractDNode(oldId, pages); |
| 111 | + |
| 112 | + if (oldAbstractDNode != null) { |
| 113 | + SiriusHelper.refresh((DSemanticDiagram) containerView.getParentDiagram()); |
| 114 | + AbstractDNode newAbstractDNode = SiriusHelper.getAbstractDNode(containerView.getParentDiagram(), newId); |
| 115 | + |
| 116 | + if (newAbstractDNode != null) { |
| 117 | + updateStyles(oldAbstractDNode, newAbstractDNode); |
| 118 | + } |
| 119 | + } |
| 120 | + } |
| 121 | + |
| 122 | + private static void copySequenceFlow(SequenceFlow newElement, DDiagramElement containerView, String oldId, |
| 123 | + String newId) { |
| 124 | + IWorkbench workbench = PlatformUI.getWorkbench(); |
| 125 | + IWorkbenchPage[] pages = workbench.getActiveWorkbenchWindow().getPages(); |
| 126 | + // Update edges asynchronously. |
| 127 | + Thread t = new Thread() { |
| 128 | + public void run() { |
| 129 | + int cpt = 0; |
| 130 | + DEdge oldDEdge = SiriusHelper.getDEdge(oldId, pages); |
| 131 | + if (oldDEdge != null) { |
| 132 | + while (cpt < 100) { |
| 133 | + DEdge newDEdge = SiriusHelper.getDEdge(containerView.getParentDiagram(), newId); |
| 134 | + if (newDEdge == null) { |
| 135 | + try { |
| 136 | + Thread.sleep(1000); |
| 137 | + cpt++; |
| 138 | + } catch (InterruptedException e) { |
| 139 | + Activator.log(IStatus.ERROR, e.getMessage(), e); |
| 140 | + } |
| 141 | + } else { |
| 142 | + Edge newGMFEdge = (Edge) SiriusHelper.getGMFView(newDEdge); |
| 143 | + if (newGMFEdge != null && newDEdge.getStyle() != null) { |
| 144 | + updateStyles(oldDEdge, newDEdge); |
| 145 | + return; |
| 146 | + } |
| 147 | + } |
| 148 | + } |
| 149 | + } |
| 150 | + }; |
| 151 | + }; |
| 152 | + t.start(); |
| 153 | + } |
| 154 | + |
| 155 | + private static void updateStyles(DEdge oldAbstractDNode, DEdge newAbstractDNode) { |
| 156 | + Edge oldGMFView = (Edge) SiriusHelper.getGMFView(oldAbstractDNode); |
| 157 | + Edge newGMFView = (Edge) SiriusHelper.getGMFView(newAbstractDNode); |
| 158 | + |
| 159 | + RelativeBendpoints bendPoints = (RelativeBendpoints) oldGMFView.getBendpoints(); |
| 160 | + IdentityAnchor sourceAnchor = (IdentityAnchor) oldGMFView.getSourceAnchor(); |
| 161 | + IdentityAnchor targetAnchor = (IdentityAnchor) oldGMFView.getTargetAnchor(); |
| 162 | + EdgeStyle oldSiriusStyle = (oldAbstractDNode instanceof DEdge) ? (EdgeStyle) oldAbstractDNode.getStyle() : null; |
| 163 | + EList<?> oldGMFStyles = oldGMFView.getStyles(); |
| 164 | + |
| 165 | + List<Node> labels = ((List<?>) oldGMFView.getPersistedChildren()).stream() |
| 166 | + .filter(it -> GMFHelper.isGmfLabelNode(it)).map(Node.class::cast).collect(Collectors.toList()); |
| 167 | + |
| 168 | + TransactionalEditingDomain ted = (TransactionalEditingDomain) AdapterFactoryEditingDomain |
| 169 | + .getEditingDomainFor(newAbstractDNode); |
| 170 | + CommandStack commandStack = ted.getCommandStack(); |
| 171 | + commandStack.execute(new RecordingCommand(ted) { |
| 172 | + @Override |
| 173 | + protected void doExecute() { |
| 174 | + RelativeBendpoints newBendpoints = NotationFactory.eINSTANCE.createRelativeBendpoints(); |
| 175 | + List<RelativeBendpoint> list = new ArrayList<RelativeBendpoint>(); |
| 176 | + for (Object o : bendPoints.getPoints()) { |
| 177 | + if (o instanceof RelativeBendpoint) { |
| 178 | + RelativeBendpoint point = (RelativeBendpoint) o; |
| 179 | + RelativeBendpoint newPoint = new RelativeBendpoint(point.getSourceX(), point.getSourceY(), |
| 180 | + point.getTargetX(), point.getTargetY()); |
| 181 | + list.add(newPoint); |
| 182 | + } |
| 183 | + } |
| 184 | + newBendpoints.setPoints(list); |
| 185 | + newGMFView.setBendpoints(newBendpoints); |
| 186 | + |
| 187 | + IdentityAnchor newSourceAnchor = (IdentityAnchor) newGMFView.getSourceAnchor(); |
| 188 | + IdentityAnchor newTargetAnchor = (IdentityAnchor) newGMFView.getTargetAnchor(); |
| 189 | + if (sourceAnchor != null) { |
| 190 | + newSourceAnchor.setId(sourceAnchor.getId()); |
| 191 | + } |
| 192 | + if (targetAnchor != null) { |
| 193 | + newTargetAnchor.setId(targetAnchor.getId()); |
| 194 | + } |
| 195 | + SiriusStyleCopier.updateEdgeStyle(newAbstractDNode, newGMFView, oldSiriusStyle, oldGMFStyles); |
| 196 | + if (!labels.isEmpty()) { |
| 197 | + GMFStyleCopier.updateLabels(newGMFView, labels); |
| 198 | + } |
| 199 | + } |
| 200 | + }); |
| 201 | + } |
| 202 | + |
| 203 | + private static void updateStyles(AbstractDNode oldAbstractDNode, AbstractDNode newAbstractDNode) { |
| 204 | + Style oldStyle = oldAbstractDNode.getStyle(); |
| 205 | + Style newStyle = newAbstractDNode.getStyle(); |
| 206 | + if (oldStyle instanceof FlatContainerStyle && newStyle instanceof FlatContainerStyle) { |
| 207 | + SiriusStyleCopier.updateSiriusNodeContainerFlatContainerStyle((FlatContainerStyle) oldStyle, |
| 208 | + (FlatContainerStyle) newStyle); |
| 209 | + } else if (oldStyle instanceof WorkspaceImage && newStyle instanceof WorkspaceImage) { |
| 210 | + SiriusStyleCopier.updateSiriusNodeContainerWorkspaceImageStyle((WorkspaceImage) oldStyle, |
| 211 | + (WorkspaceImage) newStyle); |
| 212 | + } |
| 213 | + |
| 214 | + View oldGMFView = SiriusHelper.getGMFView(oldAbstractDNode); |
| 215 | + View newGMFView = SiriusHelper.getGMFView(newAbstractDNode); |
| 216 | + updateGMFStyles(oldGMFView, newGMFView); |
| 217 | + } |
| 218 | + |
| 219 | + private static void updateGMFStyles(View oldGMFView, View newGMFView) { |
| 220 | + if (oldGMFView instanceof Node && newGMFView instanceof Node) { |
| 221 | + Node oldNode = (Node) oldGMFView; |
| 222 | + Node newNode = (Node) newGMFView; |
| 223 | + if (oldNode.getLayoutConstraint() instanceof Bounds) { |
| 224 | + Bounds oldBounds = (Bounds) oldNode.getLayoutConstraint(); |
| 225 | + Bounds newBounds = NotationFactory.eINSTANCE.createBounds(); |
| 226 | + newBounds.setHeight(oldBounds.getHeight()); |
| 227 | + newBounds.setWidth(oldBounds.getWidth()); |
| 228 | + newBounds.setX(oldBounds.getX()); |
| 229 | + newBounds.setY(oldBounds.getY()); |
| 230 | + newNode.setLayoutConstraint(newBounds); |
| 231 | + } |
| 232 | + newNode.getStyles().forEach(newStyle -> { |
| 233 | + Optional<?> oldStyleOpt = oldNode.getStyles().stream() |
| 234 | + .filter(oldStyle -> oldStyle.getClass().equals(newStyle.getClass())).findFirst(); |
| 235 | + |
| 236 | + oldStyleOpt.ifPresent(oldStyle -> { |
| 237 | + if (oldStyle instanceof FontStyle && newStyle instanceof FontStyle) { |
| 238 | + GMFStyleCopier.updateFontStyle((FontStyle) oldStyle, (FontStyle) newStyle); |
| 239 | + } |
| 240 | + }); |
| 241 | + }); |
| 242 | + for (Object o : oldNode.getChildren()) { |
| 243 | + if (o instanceof Node) { |
| 244 | + Node subOldNode = (Node) o; |
| 245 | + if (SiriusHelper.LABEL_NODE_TYPE.equals(subOldNode.getType()) |
| 246 | + && subOldNode.getLayoutConstraint() instanceof Location) { |
| 247 | + Location oldBounds = (Location) subOldNode.getLayoutConstraint(); |
| 248 | + Location newBounds = NotationFactory.eINSTANCE.createLocation(); |
| 249 | + newBounds.setX(oldBounds.getX()); |
| 250 | + newBounds.setY(oldBounds.getY()); |
| 251 | + |
| 252 | + for (Object o2 : newNode.getChildren()) { |
| 253 | + if (o2 instanceof Node) { |
| 254 | + Node subNewNode = (Node) o2; |
| 255 | + if (SiriusHelper.LABEL_NODE_TYPE.equals(subNewNode.getType()) |
| 256 | + && subNewNode.getLayoutConstraint() instanceof Location) { |
| 257 | + subNewNode.setLayoutConstraint(newBounds); |
| 258 | + } |
| 259 | + } |
| 260 | + } |
| 261 | + } |
| 262 | + } |
| 263 | + } |
| 264 | + } |
| 265 | + } |
| 266 | + |
| 267 | +} |
0 commit comments