Add pullup and pushdown for subprocesses
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/ModelHandler.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/ModelHandler.java
index 27f656b..1d92979 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/ModelHandler.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/ModelHandler.java
@@ -886,6 +886,11 @@
@SuppressWarnings("unchecked")
public <T> List<T> getAll(final Class<T> class1) {
+ return getAll(this.resource, class1);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> List<T> getAll(Resource resource, final Class<T> class1) {
ArrayList<T> l = new ArrayList<T>();
TreeIterator<EObject> contents = resource.getAllContents();
for (; contents.hasNext();) {
@@ -897,12 +902,12 @@
return l;
}
- public DiagramElement findDIElement(BaseElement element) {
+ public static DiagramElement findDIElement(BaseElement element) {
String id = element.getId();
if (id==null || id.isEmpty())
return null;
- List<BPMNDiagram> diagrams = getAll(BPMNDiagram.class);
+ List<BPMNDiagram> diagrams = getAll(element.eResource(), BPMNDiagram.class);
for (BPMNDiagram d : diagrams) {
// Process elements correspond to BPMNPlane DI elements
BPMNPlane plane = d.getPlane();
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIUtils.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIUtils.java
index 230ab0c..13824a6 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIUtils.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIUtils.java
@@ -13,6 +13,7 @@
package org.eclipse.bpmn2.modeler.core.di;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import org.eclipse.bpmn2.BaseElement;
@@ -47,6 +48,9 @@
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.algorithms.styles.Color;
+import org.eclipse.graphiti.mm.algorithms.styles.Font;
+import org.eclipse.graphiti.mm.algorithms.styles.Style;
import org.eclipse.graphiti.mm.pictograms.Anchor;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
@@ -281,11 +285,31 @@
public static void deleteDiagram(final IDiagramEditor editor, final BPMNDiagram bpmnDiagram) {
Diagram diagram = DIUtils.findDiagram(editor, bpmnDiagram);
if (diagram!=null) {
- int n = diagram.getPictogramLinks().size();
- for (int i=n-1; i>=0; --i) {
- PictogramLink link = diagram.getPictogramLinks().remove(i);
- EcoreUtil.delete(link);
+ List<EObject> list = new ArrayList<EObject>();
+ TreeIterator<EObject> iter = diagram.eAllContents();
+ while (iter.hasNext()) {
+ EObject o = iter.next();
+ if (o instanceof PictogramLink) {
+ ((PictogramLink)o).getBusinessObjects().clear();
+ if (!list.contains(o))
+ list.add(o);
+ }
+ else if (o instanceof Color) {
+ if (!list.contains(o))
+ list.add(o);
+ }
+ else if (o instanceof Font) {
+ if (!list.contains(o))
+ list.add(o);
+ }
+ else if (o instanceof Style) {
+ if (!list.contains(o))
+ list.add(o);
+ }
}
+ for (EObject o : list)
+ EcoreUtil.delete(o);
+
EcoreUtil.delete(diagram);
EcoreUtil.delete(bpmnDiagram);
}
@@ -315,5 +339,24 @@
}
return null;
}
+
+ public static BPMNDiagram createBPMNDiagram(Definitions definitions, BaseElement container) {
+
+ Resource resource = definitions.eResource();
+ BPMNDiagram bpmnDiagram = BpmnDiFactory.eINSTANCE.createBPMNDiagram();
+ ModelUtil.setID(bpmnDiagram, resource);
+ bpmnDiagram.setName(ModelUtil.getDisplayName(container));
+ BPMNPlane plane = BpmnDiFactory.eINSTANCE.createBPMNPlane();
+ ModelUtil.setID(plane, resource);
+ plane.setBpmnElement(container);
+
+ bpmnDiagram.setPlane(plane);
+
+ // this has to happen last because the IResourceChangeListener in the DesignEditor
+ // looks for add/remove to Definitions.diagrams
+ definitions.getDiagrams().add(bpmnDiagram);
+
+ return bpmnDiagram;
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java
index b1339f8..8634ef8 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/GraphicsUtil.java
@@ -1169,4 +1169,8 @@
}
return true;
}
+
+ public static Color clone(Color c) {
+ return c;
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/icons/16/pullup.png b/org.eclipse.bpmn2.modeler.ui/icons/16/pullup.png
new file mode 100644
index 0000000..c6ef26e
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/icons/16/pullup.png
Binary files differ
diff --git a/org.eclipse.bpmn2.modeler.ui/icons/16/pushdown.png b/org.eclipse.bpmn2.modeler.ui/icons/16/pushdown.png
new file mode 100644
index 0000000..de94fa0
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/icons/16/pushdown.png
Binary files differ
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/ImageProvider.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/ImageProvider.java
index 6be2187..049657c 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/ImageProvider.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/ImageProvider.java
@@ -152,6 +152,8 @@
public static final String IMG_16_ROTATE = PREFIX + "rotate" + dot16;
public static final String IMG_16_WHITEBOX = PREFIX + "whitebox" + dot16;
public static final String IMG_16_BLACKBOX = PREFIX + "blackbox" + dot16;
+ public static final String IMG_16_PUSHDOWN = PREFIX + "pushdown" + dot16;
+ public static final String IMG_16_PULLUP = PREFIX + "pullup" + dot16;
public final String IMG_16_PROPERTIES = "org.eclipse.bpmn2.modeler.icons." + "properties" + dot16; //$NON-NLS-1$
@@ -220,6 +222,8 @@
addImageFilePath(IMG_16_WHITEBOX, ICONS_16 + "whitebox.png");
addImageFilePath(IMG_16_BLACKBOX, ICONS_16 + "blackbox.png");
+ addImageFilePath(IMG_16_PUSHDOWN, ICONS_16 + "pushdown.png");
+ addImageFilePath(IMG_16_PULLUP, ICONS_16 + "pullup.png");
}
}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractExpandableActivityFeatureContainer.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractExpandableActivityFeatureContainer.java
index 9055bbe..8adef34 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractExpandableActivityFeatureContainer.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractExpandableActivityFeatureContainer.java
@@ -15,6 +15,7 @@
import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.CallActivity;
import org.eclipse.bpmn2.CallChoreography;
+import org.eclipse.bpmn2.FlowElementsContainer;
import org.eclipse.bpmn2.SubChoreography;
import org.eclipse.bpmn2.SubProcess;
import org.eclipse.bpmn2.modeler.core.features.AbstractUpdateBaseElementFeature;
@@ -61,18 +62,19 @@
@Override
public ICustomFeature[] getCustomFeatures(IFeatureProvider fp) {
ICustomFeature[] superFeatures = super.getCustomFeatures(fp);
- ICustomFeature[] thisFeatures = new ICustomFeature[2 + superFeatures.length];
+ ICustomFeature[] thisFeatures = new ICustomFeature[4 + superFeatures.length];
thisFeatures[0] = new ExpandFlowNodeFeature(fp);
thisFeatures[1] = new CollapseFlowNodeFeature(fp);
+ thisFeatures[2] = new PushdownFeature(fp);
+ thisFeatures[3] = new PullupFeature(fp);
for (int i=0; i<superFeatures.length; ++i)
- thisFeatures[2+i] = superFeatures[i];
+ thisFeatures[4+i] = superFeatures[i];
return thisFeatures;
}
public static boolean isExpandableElement(Object be) {
- return be instanceof SubProcess
+ return be instanceof FlowElementsContainer
|| be instanceof CallActivity
- || be instanceof SubChoreography
|| be instanceof CallChoreography;
}
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PullupFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PullupFeature.java
new file mode 100644
index 0000000..1365bfb
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PullupFeature.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *
+ * @author Bob Brodt
+ ******************************************************************************/
+
+package org.eclipse.bpmn2.modeler.ui.features.activity.subprocess;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.Bpmn2Package;
+import org.eclipse.bpmn2.Choreography;
+import org.eclipse.bpmn2.ChoreographyTask;
+import org.eclipse.bpmn2.Collaboration;
+import org.eclipse.bpmn2.Definitions;
+import org.eclipse.bpmn2.FlowElement;
+import org.eclipse.bpmn2.FlowElementsContainer;
+import org.eclipse.bpmn2.Message;
+import org.eclipse.bpmn2.MessageFlow;
+import org.eclipse.bpmn2.Participant;
+import org.eclipse.bpmn2.Process;
+import org.eclipse.bpmn2.RootElement;
+import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.di.BPMNDiagram;
+import org.eclipse.bpmn2.di.BPMNEdge;
+import org.eclipse.bpmn2.di.BPMNLabel;
+import org.eclipse.bpmn2.di.BPMNPlane;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.di.BpmnDiFactory;
+import org.eclipse.bpmn2.modeler.core.ModelHandler;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.di.DIUtils;
+import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.bpmn2.modeler.ui.Activator;
+import org.eclipse.bpmn2.modeler.ui.ImageProvider;
+import org.eclipse.dd.di.DiagramElement;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.IContext;
+import org.eclipse.graphiti.features.context.ICustomContext;
+import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
+import org.eclipse.graphiti.mm.algorithms.styles.Color;
+import org.eclipse.graphiti.mm.algorithms.styles.Font;
+import org.eclipse.graphiti.mm.algorithms.styles.Style;
+import org.eclipse.graphiti.mm.pictograms.Connection;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.Diagram;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.mm.pictograms.PictogramLink;
+import org.eclipse.graphiti.mm.pictograms.Shape;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.graphiti.ui.internal.util.ui.PopupMenu;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author Bob Brodt
+ *
+ */
+public class PullupFeature extends AbstractCustomFeature {
+
+ /**
+ * @param fp
+ */
+ public PullupFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public String getName() {
+ return "Pull up";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Pull the contents of the Diagram for this Activity Container back into the container";
+ }
+
+ @Override
+ public String getImageId() {
+ return ImageProvider.IMG_16_PULLUP;
+ }
+
+ @Override
+ public boolean isAvailable(IContext context) {
+ return true;
+ }
+
+ @Override
+ public boolean canExecute(ICustomContext context) {
+ PictogramElement[] pes = context.getPictogramElements();
+ if (pes != null && pes.length == 1) {
+ PictogramElement pe = pes[0];
+ Object bo = getBusinessObjectForPictogramElement(pe);
+ if (bo instanceof FlowElementsContainer) {
+ return DIUtils.findBPMNDiagram(getDiagramEditor(), (BaseElement)bo) != null;
+ }
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.graphiti.features.custom.ICustomFeature#execute(org.eclipse.graphiti.features.context.ICustomContext)
+ */
+ @Override
+ public void execute(ICustomContext context) {
+ // we already know there's one and only one PE element in canExecute() and that it's
+ // a ContainerShape for an expandable activity
+ PictogramElement pe = context.getPictogramElements()[0];
+ FlowElementsContainer container = (FlowElementsContainer)getBusinessObjectForPictogramElement(pe);
+ Definitions definitions = ModelUtil.getDefinitions(container);
+
+ // find out which BPMNPlane this sub process lives in - this will be the new home
+ // for the DI elements in the existing BPMNDiagram.
+ BPMNDiagram newBpmnDiagram = (BPMNDiagram)ModelHandler.findDIElement(container).eContainer().eContainer();
+ BPMNPlane newPlane = newBpmnDiagram.getPlane();
+ Diagram newDiagram = DIUtils.findDiagram(getDiagramEditor(), newBpmnDiagram);
+
+ BPMNDiagram oldBpmnDiagram = DIUtils.findBPMNDiagram(getDiagramEditor(), container);
+ BPMNPlane oldPlane = oldBpmnDiagram.getPlane();
+ Diagram oldDiagram = DIUtils.findDiagram(getDiagramEditor(), oldBpmnDiagram);
+
+ // copy the elements into the same plane as the sub process
+ while (oldPlane.getPlaneElement().size()>0) {
+ DiagramElement de = oldPlane.getPlaneElement().get(0);
+ newPlane.getPlaneElement().add(de);
+ }
+
+ // copy the Graphiti diagram elements: first find the ContainerShape for the sub process
+ List <PictogramElement> pes = Graphiti.getLinkService().getPictogramElements(newDiagram, container);
+ for (PictogramElement p : pes) {
+ if (p instanceof ContainerShape) {
+ if (BusinessObjectUtil.getFirstElementOfType(p, BPMNShape.class)!=null) {
+ // this is it!
+ List <EObject> moved = new ArrayList<EObject>();
+ for (Shape shape : oldDiagram.getChildren()) {
+ TreeIterator<EObject> iter = shape.eAllContents();
+ while (iter.hasNext()) {
+ EObject o = iter.next();
+ if (o instanceof PictogramLink || o instanceof Color || o instanceof Font || o instanceof Style)
+ moved.add(o);
+ }
+ }
+ for (Connection connection : oldDiagram.getConnections()) {
+ TreeIterator<EObject> iter = connection.eAllContents();
+ while (iter.hasNext()) {
+ EObject o = iter.next();
+ if (o instanceof PictogramLink || o instanceof Color || o instanceof Font || o instanceof Style)
+ moved.add(o);
+ }
+ }
+ ((ContainerShape)p).getChildren().addAll( oldDiagram.getChildren() );
+ newDiagram.getConnections().addAll( oldDiagram.getConnections() );
+
+ oldDiagram.getPictogramLinks().removeAll(moved);
+ oldDiagram.getColors().removeAll(moved);
+ oldDiagram.getFonts().removeAll(moved);
+ oldDiagram.getStyles().removeAll(moved);
+
+ break;
+ }
+ }
+ }
+
+ // get rid of the old BPMNDiagram
+ DIUtils.deleteDiagram(getDiagramEditor(), oldBpmnDiagram);
+
+ // now expand the sub process
+ ExpandFlowNodeFeature expandFeature = new ExpandFlowNodeFeature(getFeatureProvider());
+ expandFeature.execute(context);
+ }
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PushdownFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PushdownFeature.java
new file mode 100644
index 0000000..201cf6c
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/PushdownFeature.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *
+ * @author Bob Brodt
+ ******************************************************************************/
+
+package org.eclipse.bpmn2.modeler.ui.features.activity.subprocess;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.Bpmn2Package;
+import org.eclipse.bpmn2.CallActivity;
+import org.eclipse.bpmn2.CallChoreography;
+import org.eclipse.bpmn2.CallableElement;
+import org.eclipse.bpmn2.Choreography;
+import org.eclipse.bpmn2.ChoreographyTask;
+import org.eclipse.bpmn2.Collaboration;
+import org.eclipse.bpmn2.Definitions;
+import org.eclipse.bpmn2.FlowElement;
+import org.eclipse.bpmn2.FlowElementsContainer;
+import org.eclipse.bpmn2.Message;
+import org.eclipse.bpmn2.MessageFlow;
+import org.eclipse.bpmn2.Participant;
+import org.eclipse.bpmn2.Process;
+import org.eclipse.bpmn2.RootElement;
+import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.di.BPMNDiagram;
+import org.eclipse.bpmn2.di.BPMNEdge;
+import org.eclipse.bpmn2.di.BPMNPlane;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.di.BpmnDiFactory;
+import org.eclipse.bpmn2.modeler.core.ModelHandler;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.di.DIUtils;
+import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ModelSubclassSelectionDialog;
+import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
+import org.eclipse.bpmn2.modeler.core.utils.GraphicsUtil;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.bpmn2.modeler.ui.Activator;
+import org.eclipse.bpmn2.modeler.ui.ImageProvider;
+import org.eclipse.dd.di.DiagramElement;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.IContext;
+import org.eclipse.graphiti.features.context.ICustomContext;
+import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
+import org.eclipse.graphiti.mm.algorithms.styles.Color;
+import org.eclipse.graphiti.mm.algorithms.styles.Font;
+import org.eclipse.graphiti.mm.algorithms.styles.Style;
+import org.eclipse.graphiti.mm.pictograms.Connection;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.Diagram;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.mm.pictograms.PictogramLink;
+import org.eclipse.graphiti.mm.pictograms.Shape;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.graphiti.ui.internal.util.ui.PopupMenu;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author Bob Brodt
+ *
+ */
+public class PushdownFeature extends AbstractCustomFeature {
+
+ /**
+ * @param fp
+ */
+ public PushdownFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public String getName() {
+ return "Push down";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Push the contents of this Activity Container into a new Diagram";
+ }
+
+ @Override
+ public String getImageId() {
+ return ImageProvider.IMG_16_PUSHDOWN;
+ }
+
+ @Override
+ public boolean isAvailable(IContext context) {
+ return true;
+ }
+
+ @Override
+ public boolean canExecute(ICustomContext context) {
+ PictogramElement[] pes = context.getPictogramElements();
+ if (pes != null && pes.length == 1) {
+ PictogramElement pe = pes[0];
+ Object bo = getBusinessObjectForPictogramElement(pe);
+ if (bo instanceof FlowElementsContainer) {
+ return DIUtils.findBPMNDiagram(getDiagramEditor(), (BaseElement)bo) == null;
+ }
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.graphiti.features.custom.ICustomFeature#execute(org.eclipse.graphiti.features.context.ICustomContext)
+ */
+ @Override
+ public void execute(ICustomContext context) {
+ // we already know there's one and only one PE element in canExecute() and that it's
+ // a ContainerShape for an expandable activity
+ PictogramElement pe = context.getPictogramElements()[0];
+ FlowElementsContainer container = (FlowElementsContainer)getBusinessObjectForPictogramElement(pe);
+ Definitions definitions = ModelUtil.getDefinitions(container);
+
+ BPMNDiagram oldBpmnDiagram = (BPMNDiagram)ModelHandler.findDIElement(container).eContainer().eContainer();
+ Diagram oldDiagram = DIUtils.findDiagram(getDiagramEditor(), oldBpmnDiagram);
+
+ // the contents of this expandable element is in the flowElements list
+ BPMNDiagram newBpmnDiagram = DIUtils.createBPMNDiagram(definitions, container);
+ BPMNPlane newPlane = newBpmnDiagram.getPlane();
+
+ Diagram newDiagram = DIUtils.getOrCreateDiagram(getDiagramEditor(), newBpmnDiagram);
+
+ for (FlowElement fe : container.getFlowElements()) {
+ DiagramElement de = ModelHandler.findDIElement(fe);
+ newPlane.getPlaneElement().add(de);
+
+ List <PictogramElement> pes = Graphiti.getLinkService().getPictogramElements(oldDiagram, fe);
+ List <EObject> moved = new ArrayList<EObject>();
+ for (PictogramElement p : pes) {
+ PictogramElement pictogramElement = null;
+ if (p instanceof Shape) {
+ if (BusinessObjectUtil.getFirstElementOfType(p, BPMNShape.class)!=null) {
+ newDiagram.getChildren().add((Shape)p);
+ pictogramElement = p;
+ }
+ else if (Graphiti.getPeService().getPropertyValue(p, GraphicsUtil.LABEL_PROPERTY) != null) {
+ newDiagram.getChildren().add((Shape)p);
+ pictogramElement = p;
+ }
+ }
+ else if (p instanceof Connection) {
+ if (BusinessObjectUtil.getFirstElementOfType(p, BPMNEdge.class)!=null) {
+ newDiagram.getConnections().add((Connection)p);
+ pictogramElement = p;
+ }
+ }
+ if (pictogramElement!=null) {
+ TreeIterator<EObject> iter = pictogramElement.eAllContents();
+ while (iter.hasNext()) {
+ EObject o = iter.next();
+ if (o instanceof PictogramLink || o instanceof Color || o instanceof Font || o instanceof Style)
+ moved.add(o);
+ }
+ }
+ }
+ oldDiagram.getPictogramLinks().removeAll(moved);
+ oldDiagram.getColors().removeAll(moved);
+ oldDiagram.getFonts().removeAll(moved);
+ oldDiagram.getStyles().removeAll(moved);
+ }
+
+ // now collapse the sub process
+ CollapseFlowNodeFeature collapseFeature = new CollapseFlowNodeFeature(getFeatureProvider());
+ collapseFeature.execute(context);
+ }
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/choreography/WhiteboxFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/choreography/WhiteboxFeature.java
index d06ce7f..b60dc8f 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/choreography/WhiteboxFeature.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/choreography/WhiteboxFeature.java
@@ -18,6 +18,8 @@
import java.util.List;
import org.eclipse.bpmn2.Bpmn2Package;
+import org.eclipse.bpmn2.CallActivity;
+import org.eclipse.bpmn2.CallableElement;
import org.eclipse.bpmn2.Choreography;
import org.eclipse.bpmn2.ChoreographyTask;
import org.eclipse.bpmn2.Collaboration;
@@ -32,6 +34,7 @@
import org.eclipse.bpmn2.di.BpmnDiFactory;
import org.eclipse.bpmn2.modeler.core.ModelHandler;
import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.di.DIUtils;
import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
import org.eclipse.bpmn2.modeler.ui.Activator;
import org.eclipse.bpmn2.modeler.ui.ImageProvider;
@@ -69,7 +72,7 @@
@Override
public String getDescription() {
- return "Create a new Diagram for this Participant";
+ return "Create a new Diagram for this Participant or CallActivity";
}
@Override
@@ -87,21 +90,27 @@
PictogramElement[] pes = context.getPictogramElements();
if (pes != null && pes.length == 1) {
PictogramElement pe = pes[0];
+ Process process = null;
Object bo = getBusinessObjectForPictogramElement(pe);
if (bo instanceof Participant) {
- Participant participant = (Participant)bo;
- Process process = participant.getProcessRef();
- if (process!=null) {
- try {
- ModelHandler mh = ModelHandlerLocator.getModelHandler(participant.eResource());
- DiagramElement de = mh.findDIElement(process);
- return de==null;
- }
- catch (Exception e){
- }
- }
- return true;
+ process = ((Participant)bo).getProcessRef();
}
+ else if (bo instanceof CallActivity) {
+ CallableElement ce = ((CallActivity)bo).getCalledElementRef();
+ if (ce instanceof Process)
+ process = (Process)ce;
+ }
+
+ if (process!=null) {
+ try {
+ ModelHandler mh = ModelHandlerLocator.getModelHandler(process.eResource());
+ DiagramElement de = mh.findDIElement(process);
+ return de==null;
+ }
+ catch (Exception e){
+ }
+ }
+ return true;
}
return false;
}
@@ -111,50 +120,36 @@
*/
@Override
public void execute(ICustomContext context) {
- PictogramElement[] pes = context.getPictogramElements();
- if (pes != null && pes.length == 1) {
- PictogramElement pe = pes[0];
- Object bo = getBusinessObjectForPictogramElement(pe);
- if (bo instanceof Participant) {
- Participant participant = (Participant)bo;
- Definitions definitions = ModelUtil.getDefinitions(participant);
- Resource resource = definitions.eResource();
- Process process = participant.getProcessRef();
+ PictogramElement pe = context.getPictogramElements()[0];
+ Object bo = getBusinessObjectForPictogramElement(pe);
+ if (bo instanceof Participant) {
+ Participant participant = (Participant)bo;
+ Definitions definitions = ModelUtil.getDefinitions(participant);
+ Resource resource = definitions.eResource();
+ Process process = participant.getProcessRef();
- if (process==null) {
- // create a Process for this Participant
- process = (Process) ModelUtil.createObject(resource, Bpmn2Package.eINSTANCE.getProcess());
- participant.setProcessRef(process);
-
- // NOTE: this is needed because it fires the InsertionAdapter, which adds the new Process
- // to Definitions.rootElements, otherwise the Process would be a dangling object
- process.setName("Process for "+participant.getName());
- }
-
- // add the Participant to the first Choreography or Collaboration we find.
- // TODO: when (and if) multipage editor allows additional Choreography or
- // Collaboration diagrams to be created, this will be the specific diagram
- // that is being rendered on the current page.
- List<RootElement> rootElements = definitions.getRootElements();
- for (RootElement element : rootElements) {
- if (element instanceof Collaboration || element instanceof Choreography) {
- ((Collaboration)element).getParticipants().add(participant);
- break;
- }
- }
-
- BPMNDiagram bpmnDiagram = BpmnDiFactory.eINSTANCE.createBPMNDiagram();
- ModelUtil.setID(bpmnDiagram, resource);
- bpmnDiagram.setName(process.getName());
-
- definitions.getDiagrams().add(bpmnDiagram);
+ if (process==null) {
+ // create a Process for this Participant
+ process = (Process) ModelUtil.createObject(resource, Bpmn2Package.eINSTANCE.getProcess());
+ participant.setProcessRef(process);
- BPMNPlane plane = BpmnDiFactory.eINSTANCE.createBPMNPlane();
- ModelUtil.setID(plane, resource);
- plane.setBpmnElement(process);
-
- bpmnDiagram.setPlane(plane);
+ // NOTE: this is needed because it fires the InsertionAdapter, which adds the new Process
+ // to Definitions.rootElements, otherwise the Process would be a dangling object
+ process.setName("Process for "+participant.getName());
}
+
+ // add the Participant to the first Choreography or Collaboration we find.
+ // TODO: when (and if) multipage editor allows additional Choreography or
+ // Collaboration diagrams to be created, this will be the specific diagram
+ // that is being rendered on the current page.
+ List<RootElement> rootElements = definitions.getRootElements();
+ for (RootElement element : rootElements) {
+ if (element instanceof Collaboration || element instanceof Choreography) {
+ ((Collaboration)element).getParticipants().add(participant);
+ break;
+ }
+ }
+ DIUtils.createBPMNDiagram(definitions, process);
}
}
}