Fix for JBPM-3095 - added expand/collapse for subprocesses
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIImport.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIImport.java
index e0fa2aa..8c5f9b7 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIImport.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/di/DIImport.java
@@ -47,15 +47,16 @@
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.graphiti.datatypes.ILocation;
import org.eclipse.graphiti.features.IAddFeature;
import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.ILayoutFeature;
import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
import org.eclipse.graphiti.features.context.impl.AddContext;
import org.eclipse.graphiti.features.context.impl.AreaContext;
+import org.eclipse.graphiti.features.context.impl.LayoutContext;
import org.eclipse.graphiti.mm.algorithms.Rectangle;
import org.eclipse.graphiti.mm.pictograms.AnchorContainer;
import org.eclipse.graphiti.mm.pictograms.Connection;
@@ -129,12 +130,26 @@
relayoutLanes(ownedElement);
// FIXME: we don't really want to leave, but we also don't want all diagrams mixed together
- return;
+ break;
}
+
+ layoutAll();
}
});
}
+
+ private void layoutAll() {
+ for (BaseElement be : elements.keySet()) {
+// if (be instanceof SubProcess) {
+ PictogramElement pe = elements.get(be);
+ LayoutContext context = new LayoutContext(pe);
+ ILayoutFeature feature = featureProvider.getLayoutFeature(context);
+ if (feature.canLayout(context))
+ feature.layout(context);
+// }
+ }
+ }
public void setDiagram(Diagram diagram) {
this.diagram = diagram;
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 bf6b2d8..8f360b8 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
@@ -1,166 +1,165 @@
-/*******************************************************************************
- * 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 Ivar Meikas
- ******************************************************************************/
-package org.eclipse.bpmn2.modeler.core.di;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.eclipse.bpmn2.BaseElement;
-import org.eclipse.bpmn2.di.BPMNDiagram;
-import org.eclipse.bpmn2.di.BPMNEdge;
-import org.eclipse.bpmn2.di.BPMNShape;
-import org.eclipse.bpmn2.di.BpmnDiFactory;
-import org.eclipse.bpmn2.modeler.core.Activator;
-import org.eclipse.bpmn2.modeler.core.ModelHandler;
-import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
-import org.eclipse.bpmn2.modeler.core.features.BusinessObjectUtil;
-import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
-import org.eclipse.dd.dc.Bounds;
-import org.eclipse.dd.dc.DcFactory;
-import org.eclipse.dd.dc.Point;
-import org.eclipse.dd.di.DiagramElement;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.graphiti.datatypes.IDimension;
-import org.eclipse.graphiti.datatypes.ILocation;
-import org.eclipse.graphiti.features.IFeatureProvider;
-import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
-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.mm.pictograms.impl.FreeFormConnectionImpl;
-import org.eclipse.graphiti.services.Graphiti;
-
-public class DIUtils {
-
- public static void updateDIShape(PictogramElement element) {
-
- PictogramLink link = element.getLink();
- if (link == null) {
- return;
- }
-
- BPMNShape bpmnShape = BusinessObjectUtil.getFirstElementOfType(element, BPMNShape.class);
- if (bpmnShape == null) {
- return;
- }
-
- ILocation loc = Graphiti.getLayoutService().getLocationRelativeToDiagram((Shape) element);
- Bounds bounds = bpmnShape.getBounds();
-
- bounds.setX(loc.getX());
- bounds.setY(loc.getY());
-
- GraphicsAlgorithm graphicsAlgorithm = element.getGraphicsAlgorithm();
- IDimension size = Graphiti.getGaService().calculateSize(graphicsAlgorithm);
- bounds.setHeight(size.getHeight());
- bounds.setWidth(size.getWidth());
-
- if (element instanceof ContainerShape) {
- EList<Shape> children = ((ContainerShape) element).getChildren();
- for (Shape shape : children) {
- if (shape instanceof ContainerShape) {
- updateDIShape(shape);
- }
- }
- }
- }
-
- public static void updateDIEdge(Diagram diagram, Connection connection, Class clazz) {
- try {
- ModelHandler modelHandler = ModelHandlerLocator.getModelHandler(connection.getLink().getBusinessObjects()
- .get(0).eResource());
-
- EObject be = BusinessObjectUtil.getFirstElementOfType(connection, clazz);
- BPMNEdge edge = (BPMNEdge) modelHandler.findDIElement(diagram, (BaseElement) be);
- Point point = DcFactory.eINSTANCE.createPoint();
-
- List<Point> waypoint = edge.getWaypoint();
- waypoint.clear();
-
- GraphicsAlgorithm graphicsAlgorithm = connection.getStart().getGraphicsAlgorithm();
- // FIXME connections must create anchors!!!
- if (graphicsAlgorithm != null) {
- point.setX(graphicsAlgorithm.getX());
- point.setY(graphicsAlgorithm.getY());
- } else {
- point.setX(connection.getStart().getParent().getGraphicsAlgorithm().getX());
- point.setY(connection.getStart().getParent().getGraphicsAlgorithm().getY());
- }
- waypoint.add(point);
-
- if (connection instanceof FreeFormConnectionImpl) {
- FreeFormConnectionImpl freeForm = (FreeFormConnectionImpl) connection;
- EList<org.eclipse.graphiti.mm.algorithms.styles.Point> bendpoints = freeForm.getBendpoints();
- for (org.eclipse.graphiti.mm.algorithms.styles.Point bp : bendpoints) {
- addBendPoint(freeForm, point);
- }
- }
-
- point = DcFactory.eINSTANCE.createPoint();
- graphicsAlgorithm = connection.getEnd().getGraphicsAlgorithm();
- if (graphicsAlgorithm != null) {
- point.setX(graphicsAlgorithm.getX());
- point.setY(graphicsAlgorithm.getY());
- } else {
- point.setX(connection.getEnd().getParent().getGraphicsAlgorithm().getX());
- point.setY(connection.getEnd().getParent().getGraphicsAlgorithm().getY());
- }
- waypoint.add(point);
-
- } catch (IOException e) {
- Activator.logError(e);
- }
- }
-
- static void addBendPoint(FreeFormConnectionImpl freeForm, Point point) {
- freeForm.getBendpoints().add(Graphiti.getGaService().createPoint((int) point.getX(), (int) point.getY()));
- }
-
- public static BPMNShape createDIShape(Shape shape, BaseElement elem, int x, int y, int w, int h,
- IFeatureProvider fp, Diagram diagram) {
-
- EList<EObject> businessObjects = Graphiti.getLinkService().getLinkForPictogramElement(diagram)
- .getBusinessObjects();
- BPMNShape bpmnShape = null;
-
- for (EObject eObject : businessObjects) {
- if (eObject instanceof BPMNDiagram) {
- BPMNDiagram bpmnDiagram = (BPMNDiagram) eObject;
-
- bpmnShape = BpmnDiFactory.eINSTANCE.createBPMNShape();
-// bpmnShape.setId(EcoreUtil.generateUUID());
- bpmnShape.setBpmnElement(elem);
- Bounds bounds = DcFactory.eINSTANCE.createBounds();
- bounds.setX(x);
- bounds.setY(y);
- bounds.setWidth(w);
- bounds.setHeight(h);
- bpmnShape.setBounds(bounds);
-
- List<DiagramElement> elements = bpmnDiagram.getPlane().getPlaneElement();
- elements.add(bpmnShape);
- ModelUtil.setID(shape);
-
- fp.link(shape, new Object[] { elem, bpmnShape });
- break;
- }
- }
-
- return bpmnShape;
- }
-}
+/*******************************************************************************
+ * 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 Ivar Meikas
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.core.di;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.di.BPMNDiagram;
+import org.eclipse.bpmn2.di.BPMNEdge;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.di.BpmnDiFactory;
+import org.eclipse.bpmn2.modeler.core.Activator;
+import org.eclipse.bpmn2.modeler.core.ModelHandler;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.features.BusinessObjectUtil;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.dd.dc.Bounds;
+import org.eclipse.dd.dc.DcFactory;
+import org.eclipse.dd.dc.Point;
+import org.eclipse.dd.di.DiagramElement;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.graphiti.datatypes.IDimension;
+import org.eclipse.graphiti.datatypes.ILocation;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+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.mm.pictograms.impl.FreeFormConnectionImpl;
+import org.eclipse.graphiti.services.Graphiti;
+
+public class DIUtils {
+
+ public static void updateDIShape(PictogramElement element) {
+
+ PictogramLink link = element.getLink();
+ if (link == null) {
+ return;
+ }
+
+ BPMNShape bpmnShape = BusinessObjectUtil.getFirstElementOfType(element, BPMNShape.class);
+ if (bpmnShape == null) {
+ return;
+ }
+
+ ILocation loc = Graphiti.getLayoutService().getLocationRelativeToDiagram((Shape) element);
+ Bounds bounds = bpmnShape.getBounds();
+
+ bounds.setX(loc.getX());
+ bounds.setY(loc.getY());
+
+ GraphicsAlgorithm graphicsAlgorithm = element.getGraphicsAlgorithm();
+ IDimension size = Graphiti.getGaService().calculateSize(graphicsAlgorithm);
+ bounds.setHeight(size.getHeight());
+ bounds.setWidth(size.getWidth());
+
+ if (element instanceof ContainerShape) {
+ EList<Shape> children = ((ContainerShape) element).getChildren();
+ for (Shape shape : children) {
+ if (shape instanceof ContainerShape) {
+ updateDIShape(shape);
+ }
+ }
+ }
+ }
+
+ public static void updateDIEdge(Diagram diagram, Connection connection, Class clazz) {
+ try {
+ ModelHandler modelHandler = ModelHandlerLocator.getModelHandler(connection.getLink().getBusinessObjects()
+ .get(0).eResource());
+
+ EObject be = BusinessObjectUtil.getFirstElementOfType(connection, clazz);
+ BPMNEdge edge = (BPMNEdge) modelHandler.findDIElement(diagram, (BaseElement) be);
+ Point point = DcFactory.eINSTANCE.createPoint();
+
+ List<Point> waypoint = edge.getWaypoint();
+ waypoint.clear();
+
+ GraphicsAlgorithm graphicsAlgorithm = connection.getStart().getGraphicsAlgorithm();
+ // FIXME connections must create anchors!!!
+ if (graphicsAlgorithm != null) {
+ point.setX(graphicsAlgorithm.getX());
+ point.setY(graphicsAlgorithm.getY());
+ } else {
+ point.setX(connection.getStart().getParent().getGraphicsAlgorithm().getX());
+ point.setY(connection.getStart().getParent().getGraphicsAlgorithm().getY());
+ }
+ waypoint.add(point);
+
+ if (connection instanceof FreeFormConnectionImpl) {
+ FreeFormConnectionImpl freeForm = (FreeFormConnectionImpl) connection;
+ EList<org.eclipse.graphiti.mm.algorithms.styles.Point> bendpoints = freeForm.getBendpoints();
+ for (org.eclipse.graphiti.mm.algorithms.styles.Point bp : bendpoints) {
+ addBendPoint(freeForm, point);
+ }
+ }
+
+ point = DcFactory.eINSTANCE.createPoint();
+ graphicsAlgorithm = connection.getEnd().getGraphicsAlgorithm();
+ if (graphicsAlgorithm != null) {
+ point.setX(graphicsAlgorithm.getX());
+ point.setY(graphicsAlgorithm.getY());
+ } else {
+ point.setX(connection.getEnd().getParent().getGraphicsAlgorithm().getX());
+ point.setY(connection.getEnd().getParent().getGraphicsAlgorithm().getY());
+ }
+ waypoint.add(point);
+
+ } catch (IOException e) {
+ Activator.logError(e);
+ }
+ }
+
+ static void addBendPoint(FreeFormConnectionImpl freeForm, Point point) {
+ freeForm.getBendpoints().add(Graphiti.getGaService().createPoint((int) point.getX(), (int) point.getY()));
+ }
+
+ public static BPMNShape createDIShape(Shape shape, BaseElement elem, int x, int y, int w, int h,
+ IFeatureProvider fp, Diagram diagram) {
+
+ EList<EObject> businessObjects = Graphiti.getLinkService().getLinkForPictogramElement(diagram)
+ .getBusinessObjects();
+ BPMNShape bpmnShape = null;
+
+ for (EObject eObject : businessObjects) {
+ if (eObject instanceof BPMNDiagram) {
+ BPMNDiagram bpmnDiagram = (BPMNDiagram) eObject;
+
+ bpmnShape = BpmnDiFactory.eINSTANCE.createBPMNShape();
+// bpmnShape.setId(EcoreUtil.generateUUID());
+ bpmnShape.setBpmnElement(elem);
+ Bounds bounds = DcFactory.eINSTANCE.createBounds();
+ bounds.setX(x);
+ bounds.setY(y);
+ bounds.setWidth(w);
+ bounds.setHeight(h);
+ bpmnShape.setBounds(bounds);
+
+ List<DiagramElement> elements = bpmnDiagram.getPlane().getPlaneElement();
+ elements.add(bpmnShape);
+ ModelUtil.setID(shape);
+
+ fp.link(shape, new Object[] { elem, bpmnShape });
+ break;
+ }
+ }
+
+ return bpmnShape;
+ }
+}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/AbstractBpmnAddFeature.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/AbstractBpmnAddFeature.java
index dcb894f..531f686 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/AbstractBpmnAddFeature.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/AbstractBpmnAddFeature.java
@@ -1,158 +1,157 @@
-/*******************************************************************************
- * 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 Ivar Meikas
- ******************************************************************************/
-package org.eclipse.bpmn2.modeler.core.features;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.eclipse.bpmn2.Activity;
-import org.eclipse.bpmn2.Association;
-import org.eclipse.bpmn2.BaseElement;
-import org.eclipse.bpmn2.MessageFlow;
-import org.eclipse.bpmn2.SequenceFlow;
-import org.eclipse.bpmn2.di.BPMNDiagram;
-import org.eclipse.bpmn2.di.BPMNEdge;
-import org.eclipse.bpmn2.di.BPMNShape;
-import org.eclipse.bpmn2.di.BpmnDiFactory;
-import org.eclipse.bpmn2.modeler.core.Activator;
-import org.eclipse.bpmn2.modeler.core.ModelHandler;
-import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
-import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
-import org.eclipse.dd.dc.Bounds;
-import org.eclipse.dd.dc.DcFactory;
-import org.eclipse.dd.dc.Point;
-import org.eclipse.dd.di.DiagramElement;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.graphiti.datatypes.ILocation;
-import org.eclipse.graphiti.features.IFeatureProvider;
-import org.eclipse.graphiti.features.impl.AbstractAddShapeFeature;
-import org.eclipse.graphiti.mm.pictograms.Connection;
-import org.eclipse.graphiti.mm.pictograms.Shape;
-import org.eclipse.graphiti.services.Graphiti;
-
-public abstract class AbstractBpmnAddFeature extends AbstractAddShapeFeature {
-
- public AbstractBpmnAddFeature(IFeatureProvider fp) {
- super(fp);
- }
-
- protected void createDIShape(Shape gShape, BaseElement elem) {
- try {
- BPMNShape shape = (BPMNShape) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
- getDiagram(), elem);
- createDIShape(gShape, elem, shape);
- } catch (IOException e) {
- Activator.logError(e);
- }
- }
-
- protected void createDIShape(Shape gShape, BaseElement elem, BPMNShape shape) {
- ILocation loc = Graphiti.getLayoutService().getLocationRelativeToDiagram(gShape);
- if (shape == null) {
- EList<EObject> businessObjects = Graphiti.getLinkService().getLinkForPictogramElement(getDiagram())
- .getBusinessObjects();
- for (EObject eObject : businessObjects) {
- if (eObject instanceof BPMNDiagram) {
- BPMNDiagram bpmnDiagram = (BPMNDiagram) eObject;
-
- shape = BpmnDiFactory.eINSTANCE.createBPMNShape();
-// shape.setId(EcoreUtil.generateUUID());
- shape.setBpmnElement(elem);
- Bounds bounds = DcFactory.eINSTANCE.createBounds();
- if (elem instanceof Activity) {
- bounds.setHeight(gShape.getGraphicsAlgorithm().getHeight());
- } else {
- bounds.setHeight(gShape.getGraphicsAlgorithm().getHeight());
- }
- bounds.setWidth(gShape.getGraphicsAlgorithm().getWidth());
- bounds.setX(loc.getX());
- bounds.setY(loc.getY());
- shape.setBounds(bounds);
-
- addShape(shape, bpmnDiagram);
- ModelUtil.setID(shape);
- }
- }
- }
- link(gShape, new Object[] { elem, shape });
- }
-
- private void addShape(DiagramElement elem, BPMNDiagram bpmnDiagram) {
- List<DiagramElement> elements = bpmnDiagram.getPlane().getPlaneElement();
- elements.add(elem);
- }
-
- protected void createDIEdge(Connection connection, BaseElement conElement) {
- try {
- BPMNEdge edge = (BPMNEdge) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
- getDiagram(), conElement);
- createDIEdge(connection, conElement, edge);
- } catch (IOException e) {
- Activator.logError(e);
- }
-
- }
-
- protected void createDIEdge(Connection connection, BaseElement conElement, BPMNEdge edge) throws IOException {
- ModelHandler modelHandler = ModelHandlerLocator.getModelHandler(getDiagram().eResource());
- if (edge == null) {
- EList<EObject> businessObjects = Graphiti.getLinkService().getLinkForPictogramElement(getDiagram())
- .getBusinessObjects();
- for (EObject eObject : businessObjects) {
- if (eObject instanceof BPMNDiagram) {
- BPMNDiagram bpmnDiagram = (BPMNDiagram) eObject;
-
- edge = BpmnDiFactory.eINSTANCE.createBPMNEdge();
-// edge.setId(EcoreUtil.generateUUID());
- edge.setBpmnElement(conElement);
-
- if (conElement instanceof Association) {
- edge.setSourceElement(modelHandler.findDIElement(getDiagram(),
- ((Association) conElement).getSourceRef()));
- edge.setTargetElement(modelHandler.findDIElement(getDiagram(),
- ((Association) conElement).getTargetRef()));
- } else if (conElement instanceof MessageFlow) {
- edge.setSourceElement(modelHandler.findDIElement(getDiagram(),
- (BaseElement) ((MessageFlow) conElement).getSourceRef()));
- edge.setTargetElement(modelHandler.findDIElement(getDiagram(),
- (BaseElement) ((MessageFlow) conElement).getTargetRef()));
- } else if (conElement instanceof SequenceFlow) {
- edge.setSourceElement(modelHandler.findDIElement(getDiagram(),
- ((SequenceFlow) conElement).getSourceRef()));
- edge.setTargetElement(modelHandler.findDIElement(getDiagram(),
- ((SequenceFlow) conElement).getTargetRef()));
- }
-
- ILocation sourceLoc = Graphiti.getPeService().getLocationRelativeToDiagram(connection.getStart());
- ILocation targetLoc = Graphiti.getPeService().getLocationRelativeToDiagram(connection.getEnd());
-
- Point point = DcFactory.eINSTANCE.createPoint();
- point.setX(sourceLoc.getX());
- point.setY(sourceLoc.getY());
- edge.getWaypoint().add(point);
-
- point = DcFactory.eINSTANCE.createPoint();
- point.setX(targetLoc.getX());
- point.setY(targetLoc.getY());
- edge.getWaypoint().add(point);
-
- addShape(edge, bpmnDiagram);
- ModelUtil.setID(edge);
- }
- }
- }
- link(connection, new Object[] { conElement, edge });
- }
+/*******************************************************************************
+ * 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 Ivar Meikas
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.core.features;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.bpmn2.Activity;
+import org.eclipse.bpmn2.Association;
+import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.MessageFlow;
+import org.eclipse.bpmn2.SequenceFlow;
+import org.eclipse.bpmn2.di.BPMNDiagram;
+import org.eclipse.bpmn2.di.BPMNEdge;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.di.BpmnDiFactory;
+import org.eclipse.bpmn2.modeler.core.Activator;
+import org.eclipse.bpmn2.modeler.core.ModelHandler;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.dd.dc.Bounds;
+import org.eclipse.dd.dc.DcFactory;
+import org.eclipse.dd.dc.Point;
+import org.eclipse.dd.di.DiagramElement;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.graphiti.datatypes.ILocation;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.impl.AbstractAddShapeFeature;
+import org.eclipse.graphiti.mm.pictograms.Connection;
+import org.eclipse.graphiti.mm.pictograms.Shape;
+import org.eclipse.graphiti.services.Graphiti;
+
+public abstract class AbstractBpmnAddFeature extends AbstractAddShapeFeature {
+
+ public AbstractBpmnAddFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ protected void createDIShape(Shape gShape, BaseElement elem) {
+ try {
+ BPMNShape shape = (BPMNShape) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
+ getDiagram(), elem);
+ createDIShape(gShape, elem, shape);
+ } catch (IOException e) {
+ Activator.logError(e);
+ }
+ }
+
+ protected void createDIShape(Shape gShape, BaseElement elem, BPMNShape shape) {
+ ILocation loc = Graphiti.getLayoutService().getLocationRelativeToDiagram(gShape);
+ if (shape == null) {
+ EList<EObject> businessObjects = Graphiti.getLinkService().getLinkForPictogramElement(getDiagram())
+ .getBusinessObjects();
+ for (EObject eObject : businessObjects) {
+ if (eObject instanceof BPMNDiagram) {
+ BPMNDiagram bpmnDiagram = (BPMNDiagram) eObject;
+
+ shape = BpmnDiFactory.eINSTANCE.createBPMNShape();
+// shape.setId(EcoreUtil.generateUUID());
+ shape.setBpmnElement(elem);
+ Bounds bounds = DcFactory.eINSTANCE.createBounds();
+ if (elem instanceof Activity) {
+ bounds.setHeight(gShape.getGraphicsAlgorithm().getHeight());
+ } else {
+ bounds.setHeight(gShape.getGraphicsAlgorithm().getHeight());
+ }
+ bounds.setWidth(gShape.getGraphicsAlgorithm().getWidth());
+ bounds.setX(loc.getX());
+ bounds.setY(loc.getY());
+ shape.setBounds(bounds);
+
+ addShape(shape, bpmnDiagram);
+ ModelUtil.setID(shape);
+ }
+ }
+ }
+ link(gShape, new Object[] { elem, shape });
+ }
+
+ private void addShape(DiagramElement elem, BPMNDiagram bpmnDiagram) {
+ List<DiagramElement> elements = bpmnDiagram.getPlane().getPlaneElement();
+ elements.add(elem);
+ }
+
+ protected void createDIEdge(Connection connection, BaseElement conElement) {
+ try {
+ BPMNEdge edge = (BPMNEdge) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
+ getDiagram(), conElement);
+ createDIEdge(connection, conElement, edge);
+ } catch (IOException e) {
+ Activator.logError(e);
+ }
+
+ }
+
+ protected void createDIEdge(Connection connection, BaseElement conElement, BPMNEdge edge) throws IOException {
+ ModelHandler modelHandler = ModelHandlerLocator.getModelHandler(getDiagram().eResource());
+ if (edge == null) {
+ EList<EObject> businessObjects = Graphiti.getLinkService().getLinkForPictogramElement(getDiagram())
+ .getBusinessObjects();
+ for (EObject eObject : businessObjects) {
+ if (eObject instanceof BPMNDiagram) {
+ BPMNDiagram bpmnDiagram = (BPMNDiagram) eObject;
+
+ edge = BpmnDiFactory.eINSTANCE.createBPMNEdge();
+// edge.setId(EcoreUtil.generateUUID());
+ edge.setBpmnElement(conElement);
+
+ if (conElement instanceof Association) {
+ edge.setSourceElement(modelHandler.findDIElement(getDiagram(),
+ ((Association) conElement).getSourceRef()));
+ edge.setTargetElement(modelHandler.findDIElement(getDiagram(),
+ ((Association) conElement).getTargetRef()));
+ } else if (conElement instanceof MessageFlow) {
+ edge.setSourceElement(modelHandler.findDIElement(getDiagram(),
+ (BaseElement) ((MessageFlow) conElement).getSourceRef()));
+ edge.setTargetElement(modelHandler.findDIElement(getDiagram(),
+ (BaseElement) ((MessageFlow) conElement).getTargetRef()));
+ } else if (conElement instanceof SequenceFlow) {
+ edge.setSourceElement(modelHandler.findDIElement(getDiagram(),
+ ((SequenceFlow) conElement).getSourceRef()));
+ edge.setTargetElement(modelHandler.findDIElement(getDiagram(),
+ ((SequenceFlow) conElement).getTargetRef()));
+ }
+
+ ILocation sourceLoc = Graphiti.getPeService().getLocationRelativeToDiagram(connection.getStart());
+ ILocation targetLoc = Graphiti.getPeService().getLocationRelativeToDiagram(connection.getEnd());
+
+ Point point = DcFactory.eINSTANCE.createPoint();
+ point.setX(sourceLoc.getX());
+ point.setY(sourceLoc.getY());
+ edge.getWaypoint().add(point);
+
+ point = DcFactory.eINSTANCE.createPoint();
+ point.setX(targetLoc.getX());
+ point.setY(targetLoc.getY());
+ edge.getWaypoint().add(point);
+
+ addShape(edge, bpmnDiagram);
+ ModelUtil.setID(edge);
+ }
+ }
+ }
+ link(connection, new Object[] { conElement, edge });
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/AbstractAddActivityFeature.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/AbstractAddActivityFeature.java
index eea322e..90b0598 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/AbstractAddActivityFeature.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/AbstractAddActivityFeature.java
@@ -35,6 +35,8 @@
public abstract class AbstractAddActivityFeature extends AbstractBpmnAddFeature {
+ public static final String ACTIVITY_DECORATOR = "activity-decorator";
+
public AbstractAddActivityFeature(IFeatureProvider fp) {
super(fp);
}
@@ -44,7 +46,9 @@
boolean intoDiagram = context.getTargetContainer().equals(getDiagram());
boolean intoLane = FeatureSupport.isTargetLane(context) && FeatureSupport.isTargetLaneOnTop(context);
boolean intoParticipant = FeatureSupport.isTargetParticipant(context);
- return intoDiagram || intoLane || intoParticipant;
+ boolean intoSubProcess = FeatureSupport.isTargetSubProcess(context);
+
+ return intoDiagram || intoLane || intoParticipant || intoSubProcess;
}
@Override
@@ -86,6 +90,11 @@
Graphiti.getPeService().setPropertyValue(containerShape, IS_COMPENSATE_PROPERTY, Boolean.toString(false));
Graphiti.getPeService().setPropertyValue(containerShape, IS_LOOP_OR_MULTI_INSTANCE,
LoopCharacteristicType.NULL.getName());
+ // set a property on the decorators so we can distinguish them from the real children (i.e. tasks, etc.)
+ for (PictogramElement pe : containerShape.getChildren()) {
+ Graphiti.getPeService().setPropertyValue(pe, ACTIVITY_DECORATOR, "true");
+ }
+
updatePictogramElement(containerShape);
layoutPictogramElement(containerShape);
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/ActivityLayoutFeature.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/ActivityLayoutFeature.java
index fdc8409..77be33a 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/ActivityLayoutFeature.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/ActivityLayoutFeature.java
@@ -16,9 +16,12 @@
import org.eclipse.bpmn2.Activity;
import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.di.BPMNShape;
import org.eclipse.bpmn2.modeler.core.di.DIUtils;
import org.eclipse.bpmn2.modeler.core.features.BusinessObjectUtil;
import org.eclipse.bpmn2.modeler.core.features.event.AbstractBoundaryEventOperation;
+import org.eclipse.bpmn2.modeler.core.utils.AnchorUtil;
import org.eclipse.bpmn2.modeler.core.utils.FeatureSupport;
import org.eclipse.bpmn2.modeler.core.utils.GraphicsUtil;
import org.eclipse.graphiti.features.IFeatureProvider;
@@ -27,6 +30,8 @@
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.algorithms.RoundedRectangle;
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.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.services.IGaService;
@@ -85,8 +90,50 @@
}.doWork(activity, getDiagram());
DIUtils.updateDIShape(containerShape);
+ layoutConnections(containerShape);
+
+ if (containerShape.eContainer() instanceof ContainerShape) {
+ PictogramElement pe = (PictogramElement) containerShape.eContainer();
+ if (BusinessObjectUtil.containsElementOfType(pe, SubProcess.class)) {
+ layoutPictogramElement(pe);
+ }
+ }
return true;
}
+
+ public static Diagram getDiagram(ContainerShape container) {
+ while ( !(container instanceof Diagram) ) {
+ container = container.getContainer();
+ }
+ return (Diagram)container;
+ }
+
+ public void layoutConnections(Shape shape) {
+ Diagram diagram = getDiagram();
+ if (diagram!=null) {
+ if (shape.getLink()!=null) {
+ for (Object object : shape.getLink().getBusinessObjects()) {
+ if (object instanceof BPMNShape) {
+ BPMNShape s = (BPMNShape) object;
+ AnchorUtil.reConnect(s, diagram);
+ }
+ }
+ }
+
+ if (shape instanceof ContainerShape) {
+ for (PictogramElement pe : FeatureSupport.getContainerChildren((ContainerShape)shape)) {
+ if (pe.getLink()!=null) {
+ for (Object object : pe.getLink().getBusinessObjects()) {
+ if (object instanceof BPMNShape) {
+ BPMNShape s = (BPMNShape) object;
+ AnchorUtil.reConnect(s, diagram);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
protected int getMarkerContainerOffset() {
return 0;
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/ActivityMoveFeature.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/ActivityMoveFeature.java
index 954794a..ef04b97 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/ActivityMoveFeature.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/features/activity/ActivityMoveFeature.java
@@ -1,59 +1,130 @@
-/*******************************************************************************
- * 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 Ivar Meikas
- ******************************************************************************/
-package org.eclipse.bpmn2.modeler.core.features.activity;
-
-import org.eclipse.bpmn2.Activity;
-import org.eclipse.bpmn2.modeler.core.features.BusinessObjectUtil;
-import org.eclipse.bpmn2.modeler.core.features.MoveFlowNodeFeature;
-import org.eclipse.bpmn2.modeler.core.features.event.AbstractBoundaryEventOperation;
-import org.eclipse.graphiti.features.IFeatureProvider;
-import org.eclipse.graphiti.features.IMoveShapeFeature;
-import org.eclipse.graphiti.features.context.IMoveShapeContext;
-import org.eclipse.graphiti.features.context.impl.MoveShapeContext;
-import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
-import org.eclipse.graphiti.mm.pictograms.ContainerShape;
-
-public class ActivityMoveFeature extends MoveFlowNodeFeature {
-
- public static final String ACTIVITY_MOVE_PROPERTY = "activity.move";
-
- public ActivityMoveFeature(IFeatureProvider fp) {
- super(fp);
- }
-
- @Override
- protected void postMoveShape(final IMoveShapeContext context) {
- super.postMoveShape(context);
- Activity activity = BusinessObjectUtil.getFirstElementOfType(context.getPictogramElement(), Activity.class);
- new AbstractBoundaryEventOperation() {
- @Override
- protected void doWorkInternal(ContainerShape container) {
- GraphicsAlgorithm ga = container.getGraphicsAlgorithm();
-
- MoveShapeContext newContext = new MoveShapeContext(container);
- newContext.setDeltaX(context.getDeltaX());
- newContext.setDeltaY(context.getDeltaY());
- newContext.setSourceContainer(context.getSourceContainer());
- newContext.setTargetContainer(context.getTargetContainer());
- newContext.setTargetConnection(context.getTargetConnection());
- newContext.setLocation(ga.getX(), ga.getY());
- newContext.putProperty(ACTIVITY_MOVE_PROPERTY, true);
-
- IMoveShapeFeature moveFeature = getFeatureProvider().getMoveShapeFeature(newContext);
- if (moveFeature.canMoveShape(newContext)) {
- moveFeature.moveShape(newContext);
- }
- }
- }.doWork(activity, getDiagram());
- }
+/*******************************************************************************
+ * 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 Ivar Meikas
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.core.features.activity;
+
+import org.eclipse.bpmn2.Activity;
+import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.modeler.core.features.BusinessObjectUtil;
+import org.eclipse.bpmn2.modeler.core.features.MoveFlowNodeFeature;
+import org.eclipse.bpmn2.modeler.core.features.event.AbstractBoundaryEventOperation;
+import org.eclipse.graphiti.datatypes.ILocation;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.IMoveShapeFeature;
+import org.eclipse.graphiti.features.context.IMoveShapeContext;
+import org.eclipse.graphiti.features.context.impl.MoveShapeContext;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.services.IPeLayoutService;
+
+public class ActivityMoveFeature extends MoveFlowNodeFeature {
+
+ public static final String ACTIVITY_MOVE_PROPERTY = "activity.move";
+
+ public ActivityMoveFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ protected void preMoveShape(IMoveShapeContext context) {
+ MoveShapeContext msc = (MoveShapeContext)context;
+ ContainerShape oldContainer = context.getSourceContainer();
+ ContainerShape newContainer = context.getTargetContainer();
+ IPeLayoutService peLayoutService = Graphiti.getPeLayoutService();
+// Shape shape = context.getShape();
+// ILocation loc = peService.getLocationRelativeToDiagram(shape);
+ ILocation oldLoc = peLayoutService.getLocationRelativeToDiagram(oldContainer);
+ ILocation newLoc = peLayoutService.getLocationRelativeToDiagram(newContainer);
+// System.out.println(
+// (oldContainer==newContainer ? "inside:\n" : "outside:\n")+
+// "oldContainer:\n" +
+// " x="+oldLoc.getX()+"\n"+
+// " y="+oldLoc.getY()+"\n"+
+// "newContainer:\n" +
+// " x="+newLoc.getX()+"\n"+
+// " y="+newLoc.getY()+"\n"+
+// "shape:\n" +
+// " rel x="+shape.getGraphicsAlgorithm().getX()+"\n"+
+// " rel y="+shape.getGraphicsAlgorithm().getY()+"\n"+
+// " abs x="+loc.getX()+"\n"+
+// " abs y="+loc.getY()+"\n"+
+// "context:\n" +
+// " x="+msc.getX()+"\n"+
+// " y="+msc.getY()+"\n"+
+// " deltaX="+msc.getDeltaX()+"\n"+
+// " deltaY="+msc.getDeltaY()+"\n"+
+// "\n"
+// );
+
+ if (oldContainer!=newContainer) {
+ int x = newLoc.getX() + msc.getX() - oldLoc.getX();
+ int y = newLoc.getY() + msc.getY() - oldLoc.getY();
+ int deltaX = newLoc.getX() + msc.getDeltaX() - oldLoc.getX();
+ int deltaY = newLoc.getY() + msc.getDeltaY() - oldLoc.getY();
+
+// System.out.println(
+// "new context:\n"+
+// " x="+( newLoc.getX() + msc.getX() - oldLoc.getX() )+"\n"+
+// " y="+msc.getY()+"\n"+
+// " deltaX="+( newLoc.getX() + msc.getDeltaX() - oldLoc.getX() )+"\n"+
+// " deltaY="+msc.getDeltaY()+"\n"+
+// "\n"
+// );
+
+ msc.setX(x);
+ msc.setY(y);
+ msc.setDeltaX(deltaX);
+ msc.setDeltaY(deltaY);
+ msc.setTargetContainer(oldContainer);
+ }
+
+ super.preMoveShape(context);
+ }
+
+ @Override
+ protected void postMoveShape(final IMoveShapeContext context) {
+ super.postMoveShape(context);
+ PictogramElement containerShape = context.getPictogramElement();
+ Activity activity = BusinessObjectUtil.getFirstElementOfType(containerShape, Activity.class);
+ new AbstractBoundaryEventOperation() {
+ @Override
+ protected void doWorkInternal(ContainerShape container) {
+ GraphicsAlgorithm ga = container.getGraphicsAlgorithm();
+
+ MoveShapeContext newContext = new MoveShapeContext(container);
+ newContext.setDeltaX(context.getDeltaX());
+ newContext.setDeltaY(context.getDeltaY());
+ newContext.setSourceContainer(context.getSourceContainer());
+ newContext.setTargetContainer(context.getTargetContainer());
+ newContext.setTargetConnection(context.getTargetConnection());
+ newContext.setLocation(ga.getX(), ga.getY());
+ newContext.putProperty(ACTIVITY_MOVE_PROPERTY, true);
+
+ IMoveShapeFeature moveFeature = getFeatureProvider().getMoveShapeFeature(newContext);
+ if (moveFeature.canMoveShape(newContext)) {
+ moveFeature.moveShape(newContext);
+ }
+
+ Graphiti.getPeService().sendToFront(context.getShape());
+ }
+ }.doWork(activity, getDiagram());
+
+ if (containerShape.eContainer() instanceof ContainerShape) {
+ PictogramElement pe = (PictogramElement) containerShape.eContainer();
+ if (BusinessObjectUtil.containsElementOfType(pe, SubProcess.class)) {
+ layoutPictogramElement(pe);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/AnchorUtil.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/AnchorUtil.java
index 45e0c55..7daf0b2 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/AnchorUtil.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/AnchorUtil.java
@@ -1,429 +1,440 @@
-/*******************************************************************************
- * 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 Ivar Meikas
- ******************************************************************************/
-package org.eclipse.bpmn2.modeler.core.utils;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.bpmn2.di.BPMNEdge;
-import org.eclipse.bpmn2.di.BPMNShape;
-import org.eclipse.bpmn2.modeler.core.Activator;
-import org.eclipse.bpmn2.modeler.core.ModelHandler;
-import org.eclipse.dd.di.DiagramElement;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.graphiti.datatypes.IDimension;
-import org.eclipse.graphiti.datatypes.ILocation;
-import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
-import org.eclipse.graphiti.mm.algorithms.styles.Point;
-import org.eclipse.graphiti.mm.pictograms.Anchor;
-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.FixPointAnchor;
-import org.eclipse.graphiti.mm.pictograms.Shape;
-import org.eclipse.graphiti.mm.pictograms.impl.FreeFormConnectionImpl;
-import org.eclipse.graphiti.services.Graphiti;
-import org.eclipse.graphiti.services.IGaService;
-import org.eclipse.graphiti.services.IPeService;
-
-public class AnchorUtil {
-
- public static final String BOUNDARY_FIXPOINT_ANCHOR = "boundary.fixpoint.anchor";
-
- private static final IPeService peService = Graphiti.getPeService();
- private static final IGaService gaService = Graphiti.getGaService();
-
- public enum AnchorLocation {
- TOP("anchor.top"), BOTTOM("anchor.bottom"), LEFT("anchor.left"), RIGHT("anchor.right");
-
- private final String key;
-
- private AnchorLocation(String key) {
- this.key = key;
- }
-
- public String getKey() {
- return key;
- }
-
- public static AnchorLocation getLocation(String key) {
- for (AnchorLocation l : values()) {
- if (l.getKey().equals(key)) {
- return l;
- }
- }
- return null;
- }
- }
-
- public static class AnchorTuple {
- public FixPointAnchor sourceAnchor;
- public FixPointAnchor targetAnchor;
- }
-
- public static class BoundaryAnchor {
- public FixPointAnchor anchor;
- public AnchorLocation locationType;
- public ILocation location;
- }
-
- public static FixPointAnchor createAnchor(Shape s, AnchorLocation loc, int x, int y) {
- IGaService gaService = Graphiti.getGaService();
- IPeService peService = Graphiti.getPeService();
-
- FixPointAnchor anchor = peService.createFixPointAnchor(s);
- peService.setPropertyValue(anchor, BOUNDARY_FIXPOINT_ANCHOR, loc.getKey());
- anchor.setLocation(gaService.createPoint(x, y));
- gaService.createInvisibleRectangle(anchor);
-
- return anchor;
- }
-
- public static Map<AnchorLocation, BoundaryAnchor> getBoundaryAnchors(Shape s) {
- Map<AnchorLocation, BoundaryAnchor> map = new HashMap<AnchorLocation, AnchorUtil.BoundaryAnchor>(4);
- Iterator<Anchor> iterator = s.getAnchors().iterator();
- while (iterator.hasNext()) {
- Anchor anchor = iterator.next();
- String property = Graphiti.getPeService().getPropertyValue(anchor, BOUNDARY_FIXPOINT_ANCHOR);
- if (property != null && anchor instanceof FixPointAnchor) {
- BoundaryAnchor a = new BoundaryAnchor();
- a.anchor = (FixPointAnchor) anchor;
- a.locationType = AnchorLocation.getLocation(property);
- a.location = peService.getLocationRelativeToDiagram(anchor);
- map.put(a.locationType, a);
- }
- }
- return map;
- }
-
- public static Point getCenterPoint(Shape s) {
- GraphicsAlgorithm ga = s.getGraphicsAlgorithm();
- ILocation loc = peService.getLocationRelativeToDiagram(s);
- return gaService.createPoint(loc.getX() + (ga.getWidth() / 2), loc.getY() + (ga.getHeight() / 2));
- }
-
- @SuppressWarnings("restriction")
- public static Tuple<FixPointAnchor, FixPointAnchor> getSourceAndTargetBoundaryAnchors(Shape source, Shape target,
- Connection connection) {
- Map<AnchorLocation, BoundaryAnchor> sourceBoundaryAnchors = getBoundaryAnchors(source);
- Map<AnchorLocation, BoundaryAnchor> targetBoundaryAnchors = getBoundaryAnchors(target);
-
- if (connection instanceof FreeFormConnectionImpl) {
- EList<Point> bendpoints = ((FreeFormConnectionImpl) connection).getBendpoints();
- if (bendpoints.size() > 0) {
- FixPointAnchor sourceAnchor = getCorrectAnchor(sourceBoundaryAnchors, bendpoints.get(0));
- FixPointAnchor targetAnchor = getCorrectAnchor(targetBoundaryAnchors,
- bendpoints.get(bendpoints.size() - 1));
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceAnchor, targetAnchor);
- }
- }
-
- BoundaryAnchor sourceTop = sourceBoundaryAnchors.get(AnchorLocation.TOP);
- BoundaryAnchor sourceBottom = sourceBoundaryAnchors.get(AnchorLocation.BOTTOM);
- BoundaryAnchor sourceLeft = sourceBoundaryAnchors.get(AnchorLocation.LEFT);
- BoundaryAnchor sourceRight = sourceBoundaryAnchors.get(AnchorLocation.RIGHT);
- BoundaryAnchor targetBottom = targetBoundaryAnchors.get(AnchorLocation.BOTTOM);
- BoundaryAnchor targetTop = targetBoundaryAnchors.get(AnchorLocation.TOP);
- BoundaryAnchor targetRight = targetBoundaryAnchors.get(AnchorLocation.RIGHT);
- BoundaryAnchor targetLeft = targetBoundaryAnchors.get(AnchorLocation.LEFT);
-
- boolean sLower = sourceTop.location.getY() > targetBottom.location.getY();
- boolean sHigher = sourceBottom.location.getY() < targetTop.location.getY();
- boolean sRight = sourceLeft.location.getX() > targetRight.location.getX();
- boolean sLeft = sourceRight.location.getX() < targetLeft.location.getX();
-
- if (sLower) {
- if (!sLeft && !sRight) {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceTop.anchor, targetBottom.anchor);
- } else if (sLeft) {
- FixPointAnchor fromTopAnchor = getCorrectAnchor(targetBoundaryAnchors,
- peService.getLocationRelativeToDiagram(sourceTop.anchor));
- FixPointAnchor fromRightAnchor = getCorrectAnchor(targetBoundaryAnchors,
- peService.getLocationRelativeToDiagram(sourceRight.anchor));
-
- double topLength = getLength(peService.getLocationRelativeToDiagram(fromTopAnchor),
- peService.getLocationRelativeToDiagram(sourceTop.anchor));
- double rightLength = getLength(peService.getLocationRelativeToDiagram(fromRightAnchor),
- peService.getLocationRelativeToDiagram(sourceRight.anchor));
-
- if (topLength < rightLength) {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceTop.anchor, fromTopAnchor);
- } else {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceRight.anchor, fromRightAnchor);
- }
- } else {
- FixPointAnchor fromTopAnchor = getCorrectAnchor(targetBoundaryAnchors,
- peService.getLocationRelativeToDiagram(sourceTop.anchor));
- FixPointAnchor fromLeftAnchor = getCorrectAnchor(targetBoundaryAnchors,
- peService.getLocationRelativeToDiagram(sourceLeft.anchor));
-
- double topLength = getLength(peService.getLocationRelativeToDiagram(fromTopAnchor),
- peService.getLocationRelativeToDiagram(sourceTop.anchor));
- double leftLength = getLength(peService.getLocationRelativeToDiagram(fromLeftAnchor),
- peService.getLocationRelativeToDiagram(sourceLeft.anchor));
- if (topLength < leftLength) {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceTop.anchor, fromTopAnchor);
- } else {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceLeft.anchor, fromLeftAnchor);
- }
- }
-
- }
-
- if (sHigher) {
- if (!sLeft && !sRight) {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceBottom.anchor, targetTop.anchor);
- } else if (sLeft) {
- FixPointAnchor fromBottomAnchor = getCorrectAnchor(targetBoundaryAnchors,
- peService.getLocationRelativeToDiagram(sourceBottom.anchor));
- FixPointAnchor fromRightAnchor = getCorrectAnchor(targetBoundaryAnchors,
- peService.getLocationRelativeToDiagram(sourceRight.anchor));
-
- double bottomLength = getLength(peService.getLocationRelativeToDiagram(fromBottomAnchor),
- peService.getLocationRelativeToDiagram(sourceBottom.anchor));
- double rightLength = getLength(peService.getLocationRelativeToDiagram(fromRightAnchor),
- peService.getLocationRelativeToDiagram(sourceRight.anchor));
-
- if (bottomLength < rightLength) {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceBottom.anchor, fromBottomAnchor);
- } else {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceRight.anchor, fromRightAnchor);
- }
- } else {
- FixPointAnchor fromBottomAnchor = getCorrectAnchor(targetBoundaryAnchors,
- peService.getLocationRelativeToDiagram(sourceBottom.anchor));
- FixPointAnchor fromLeftAnchor = getCorrectAnchor(targetBoundaryAnchors,
- peService.getLocationRelativeToDiagram(sourceLeft.anchor));
-
- double bottomLength = getLength(peService.getLocationRelativeToDiagram(fromBottomAnchor),
- peService.getLocationRelativeToDiagram(sourceBottom.anchor));
- double leftLength = getLength(peService.getLocationRelativeToDiagram(fromLeftAnchor),
- peService.getLocationRelativeToDiagram(sourceLeft.anchor));
- if (bottomLength < leftLength) {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceBottom.anchor, fromBottomAnchor);
- } else {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceLeft.anchor, fromLeftAnchor);
- }
- }
- }
-
- // if source left is further than target right then use source left and target right
- if (sRight) {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceLeft.anchor, targetRight.anchor);
- }
-
- // if source right is smaller than target left then use source right and target left
- if (sLeft) {
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceRight.anchor, targetLeft.anchor);
- }
-
- return new Tuple<FixPointAnchor, FixPointAnchor>(sourceTop.anchor, targetTop.anchor);
- }
-
- private static FixPointAnchor getCorrectAnchor(Map<AnchorLocation, BoundaryAnchor> targetBoundaryAnchors,
- ILocation loc) {
- return getCorrectAnchor(targetBoundaryAnchors, gaService.createPoint(loc.getX(), loc.getY()));
- }
-
- private static double getLength(ILocation start, ILocation end) {
- return Math.sqrt(Math.pow(start.getX() - end.getX(), 2) + Math.pow(start.getY() - end.getY(), 2));
- }
-
- private static FixPointAnchor getCorrectAnchor(Map<AnchorLocation, BoundaryAnchor> boundaryAnchors, Point point) {
-
- BoundaryAnchor bottom = boundaryAnchors.get(AnchorLocation.BOTTOM);
- BoundaryAnchor top = boundaryAnchors.get(AnchorLocation.TOP);
- BoundaryAnchor right = boundaryAnchors.get(AnchorLocation.RIGHT);
- BoundaryAnchor left = boundaryAnchors.get(AnchorLocation.LEFT);
-
- boolean pointLower = point.getY() > bottom.location.getY();
- boolean pointHigher = point.getY() < top.location.getY();
- boolean pointRight = point.getX() > right.location.getX();
- boolean pointLeft = point.getX() < left.location.getX();
-
- // Find the best connector.
- if (pointLower) {
- if (!pointLeft && !pointRight) {
- // bendpoint is straight below the shape
- return bottom.anchor;
- } else if (pointLeft) {
-
- int deltaX = left.location.getX() - point.getX();
- int deltaY = point.getY() - bottom.location.getY();
- if (deltaX > deltaY) {
- return left.anchor;
- } else {
- return bottom.anchor;
- }
- } else {
- int deltaX = point.getX() - right.location.getX();
- int deltaY = point.getY() - bottom.location.getY();
- if (deltaX > deltaY) {
- return right.anchor;
- } else {
- return bottom.anchor;
- }
- }
- }
-
- if (pointHigher) {
- if (!pointLeft && !pointRight) {
- // bendpoint is straight above the shape
- return top.anchor;
- } else if (pointLeft) {
- int deltaX = left.location.getX() - point.getX();
- int deltaY = top.location.getY() - point.getY();
- if (deltaX > deltaY) {
- return left.anchor;
- } else {
- return top.anchor;
- }
- } else {
- int deltaX = point.getX() - right.location.getX();
- int deltaY = top.location.getY() - point.getY();
- if (deltaX > deltaY) {
- return right.anchor;
- } else {
- return top.anchor;
- }
- }
-
- }
-
- // if we reach here, then the point is neither above or below the shape and we only need to determine if we need
- // to connect to the left or right part of the shape
- if (pointRight) {
- return right.anchor;
- }
-
- if (pointLeft) {
- return left.anchor;
- }
-
- return top.anchor;
- }
-
- public static void reConnect(BPMNShape shape, Diagram diagram) {
- try {
- ModelHandler handler = ModelHandler.getInstance(diagram);
- for (BPMNEdge bpmnEdge : handler.getAll(BPMNEdge.class)) {
- DiagramElement sourceElement = bpmnEdge.getSourceElement();
- DiagramElement targetElement = bpmnEdge.getTargetElement();
- if (sourceElement != null && targetElement != null) {
- boolean sourceMatches = sourceElement.getId().equals(shape.getId());
- boolean targetMatches = targetElement.getId().equals(shape.getId());
- if (sourceMatches || targetMatches) {
- updateEdge(bpmnEdge, diagram);
- }
- }
- }
- } catch (Exception e) {
- Activator.logError(e);
- }
- }
-
- private static void updateEdge(BPMNEdge edge, Diagram diagram) {
- ContainerShape source = (ContainerShape) Graphiti.getLinkService()
- .getPictogramElements(diagram, edge.getSourceElement()).get(0);
- ContainerShape target = (ContainerShape) Graphiti.getLinkService()
- .getPictogramElements(diagram, edge.getTargetElement()).get(0);
- Connection connection = (Connection) Graphiti.getLinkService().getPictogramElements(diagram, edge).get(0);
- Tuple<FixPointAnchor, FixPointAnchor> anchors = getSourceAndTargetBoundaryAnchors(source, target, connection);
-
- ILocation loc = peService.getLocationRelativeToDiagram(anchors.getFirst());
- org.eclipse.dd.dc.Point p = edge.getWaypoint().get(0);
- p.setX(loc.getX());
- p.setY(loc.getY());
-
- loc = peService.getLocationRelativeToDiagram(anchors.getSecond());
- p = edge.getWaypoint().get(edge.getWaypoint().size() - 1);
- p.setX(loc.getX());
- p.setY(loc.getY());
-
- relocateConnection(source.getAnchors(), anchors, target);
- deleteEmptyAdHocAnchors(source);
- deleteEmptyAdHocAnchors(target);
- }
-
- private static void relocateConnection(EList<Anchor> anchors, Tuple<FixPointAnchor, FixPointAnchor> newAnchors,
- ContainerShape target) {
-
- List<Connection> connectionsToBeUpdated = new ArrayList<Connection>();
-
- for (Anchor anchor : anchors) {
- if (!(anchor instanceof FixPointAnchor)) {
- continue;
- }
-
- for (Connection connection : anchor.getOutgoingConnections()) {
- if (connection.getEnd().eContainer().equals(target)) {
- connectionsToBeUpdated.add(connection);
- }
- }
- }
-
- for (Connection c : connectionsToBeUpdated) {
- c.setStart(newAnchors.getFirst());
- c.setEnd(newAnchors.getSecond());
- }
- }
-
- private static void deleteEmptyAdHocAnchors(Shape s) {
- List<Integer> indexes = new ArrayList<Integer>();
-
- for (int i = s.getAnchors().size()-1; i>=0; --i) {
- Anchor a = s.getAnchors().get(i);
- if (!(a instanceof FixPointAnchor)) {
- continue;
- }
-
- if (peService.getProperty(a, BOUNDARY_FIXPOINT_ANCHOR) == null && a.getIncomingConnections().isEmpty()
- && a.getOutgoingConnections().isEmpty()) {
- indexes.add(i);
- }
- }
-
- for (int i : indexes) {
- peService.deletePictogramElement(s.getAnchors().get(i));
- }
- }
-
- public static void addFixedPointAnchors(Shape shape, GraphicsAlgorithm ga) {
- IDimension size = gaService.calculateSize(ga);
- int w = size.getWidth();
- int h = size.getHeight();
- AnchorUtil.createAnchor(shape, AnchorLocation.TOP, w / 2, 0);
- AnchorUtil.createAnchor(shape, AnchorLocation.RIGHT, w, h / 2);
- AnchorUtil.createAnchor(shape, AnchorLocation.BOTTOM, w / 2, h);
- AnchorUtil.createAnchor(shape, AnchorLocation.LEFT, 0, h / 2);
- }
-
- public static void relocateFixPointAnchors(Shape shape, int w, int h) {
- Map<AnchorLocation, BoundaryAnchor> anchors = AnchorUtil.getBoundaryAnchors(shape);
-
- FixPointAnchor anchor = anchors.get(AnchorLocation.TOP).anchor;
- anchor.setLocation(gaService.createPoint(w / 2, 0));
-
- anchor = anchors.get(AnchorLocation.RIGHT).anchor;
- anchor.setLocation(gaService.createPoint(w, h / 2));
-
- anchor = anchors.get(AnchorLocation.BOTTOM).anchor;
- anchor.setLocation(gaService.createPoint(w / 2, h));
-
- anchor = anchors.get(AnchorLocation.LEFT).anchor;
- anchor.setLocation(gaService.createPoint(0, h / 2));
- }
+/*******************************************************************************
+ * 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 Ivar Meikas
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.core.utils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.bpmn2.di.BPMNEdge;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.modeler.core.Activator;
+import org.eclipse.bpmn2.modeler.core.ModelHandler;
+import org.eclipse.dd.di.DiagramElement;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.graphiti.datatypes.IDimension;
+import org.eclipse.graphiti.datatypes.ILocation;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.algorithms.styles.Point;
+import org.eclipse.graphiti.mm.pictograms.Anchor;
+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.FixPointAnchor;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.mm.pictograms.Shape;
+import org.eclipse.graphiti.mm.pictograms.impl.FreeFormConnectionImpl;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.services.IGaService;
+import org.eclipse.graphiti.services.IPeService;
+
+public class AnchorUtil {
+
+ public static final String BOUNDARY_FIXPOINT_ANCHOR = "boundary.fixpoint.anchor";
+
+ private static final IPeService peService = Graphiti.getPeService();
+ private static final IGaService gaService = Graphiti.getGaService();
+
+ public enum AnchorLocation {
+ TOP("anchor.top"), BOTTOM("anchor.bottom"), LEFT("anchor.left"), RIGHT("anchor.right");
+
+ private final String key;
+
+ private AnchorLocation(String key) {
+ this.key = key;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public static AnchorLocation getLocation(String key) {
+ for (AnchorLocation l : values()) {
+ if (l.getKey().equals(key)) {
+ return l;
+ }
+ }
+ return null;
+ }
+ }
+
+ public static class AnchorTuple {
+ public FixPointAnchor sourceAnchor;
+ public FixPointAnchor targetAnchor;
+ }
+
+ public static class BoundaryAnchor {
+ public FixPointAnchor anchor;
+ public AnchorLocation locationType;
+ public ILocation location;
+ }
+
+ public static FixPointAnchor createAnchor(Shape s, AnchorLocation loc, int x, int y) {
+ IGaService gaService = Graphiti.getGaService();
+ IPeService peService = Graphiti.getPeService();
+
+ FixPointAnchor anchor = peService.createFixPointAnchor(s);
+ peService.setPropertyValue(anchor, BOUNDARY_FIXPOINT_ANCHOR, loc.getKey());
+ anchor.setLocation(gaService.createPoint(x, y));
+ gaService.createInvisibleRectangle(anchor);
+
+ return anchor;
+ }
+
+ public static Map<AnchorLocation, BoundaryAnchor> getBoundaryAnchors(Shape s) {
+ Map<AnchorLocation, BoundaryAnchor> map = new HashMap<AnchorLocation, AnchorUtil.BoundaryAnchor>(4);
+ Iterator<Anchor> iterator = s.getAnchors().iterator();
+ while (iterator.hasNext()) {
+ Anchor anchor = iterator.next();
+ String property = Graphiti.getPeService().getPropertyValue(anchor, BOUNDARY_FIXPOINT_ANCHOR);
+ if (property != null && anchor instanceof FixPointAnchor) {
+ BoundaryAnchor a = new BoundaryAnchor();
+ a.anchor = (FixPointAnchor) anchor;
+ a.locationType = AnchorLocation.getLocation(property);
+ a.location = peService.getLocationRelativeToDiagram(anchor);
+ map.put(a.locationType, a);
+ }
+ }
+ return map;
+ }
+
+ public static Point getCenterPoint(Shape s) {
+ GraphicsAlgorithm ga = s.getGraphicsAlgorithm();
+ ILocation loc = peService.getLocationRelativeToDiagram(s);
+ return gaService.createPoint(loc.getX() + (ga.getWidth() / 2), loc.getY() + (ga.getHeight() / 2));
+ }
+
+ @SuppressWarnings("restriction")
+ public static Tuple<FixPointAnchor, FixPointAnchor> getSourceAndTargetBoundaryAnchors(Shape source, Shape target,
+ Connection connection) {
+ Map<AnchorLocation, BoundaryAnchor> sourceBoundaryAnchors = getBoundaryAnchors(source);
+ Map<AnchorLocation, BoundaryAnchor> targetBoundaryAnchors = getBoundaryAnchors(target);
+
+ if (connection instanceof FreeFormConnectionImpl) {
+ EList<Point> bendpoints = ((FreeFormConnectionImpl) connection).getBendpoints();
+ if (bendpoints.size() > 0) {
+ FixPointAnchor sourceAnchor = getCorrectAnchor(sourceBoundaryAnchors, bendpoints.get(0));
+ FixPointAnchor targetAnchor = getCorrectAnchor(targetBoundaryAnchors,
+ bendpoints.get(bendpoints.size() - 1));
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceAnchor, targetAnchor);
+ }
+ }
+
+ BoundaryAnchor sourceTop = sourceBoundaryAnchors.get(AnchorLocation.TOP);
+ BoundaryAnchor sourceBottom = sourceBoundaryAnchors.get(AnchorLocation.BOTTOM);
+ BoundaryAnchor sourceLeft = sourceBoundaryAnchors.get(AnchorLocation.LEFT);
+ BoundaryAnchor sourceRight = sourceBoundaryAnchors.get(AnchorLocation.RIGHT);
+ BoundaryAnchor targetBottom = targetBoundaryAnchors.get(AnchorLocation.BOTTOM);
+ BoundaryAnchor targetTop = targetBoundaryAnchors.get(AnchorLocation.TOP);
+ BoundaryAnchor targetRight = targetBoundaryAnchors.get(AnchorLocation.RIGHT);
+ BoundaryAnchor targetLeft = targetBoundaryAnchors.get(AnchorLocation.LEFT);
+
+ boolean sLower = sourceTop.location.getY() > targetBottom.location.getY();
+ boolean sHigher = sourceBottom.location.getY() < targetTop.location.getY();
+ boolean sRight = sourceLeft.location.getX() > targetRight.location.getX();
+ boolean sLeft = sourceRight.location.getX() < targetLeft.location.getX();
+
+ if (sLower) {
+ if (!sLeft && !sRight) {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceTop.anchor, targetBottom.anchor);
+ } else if (sLeft) {
+ FixPointAnchor fromTopAnchor = getCorrectAnchor(targetBoundaryAnchors,
+ peService.getLocationRelativeToDiagram(sourceTop.anchor));
+ FixPointAnchor fromRightAnchor = getCorrectAnchor(targetBoundaryAnchors,
+ peService.getLocationRelativeToDiagram(sourceRight.anchor));
+
+ double topLength = getLength(peService.getLocationRelativeToDiagram(fromTopAnchor),
+ peService.getLocationRelativeToDiagram(sourceTop.anchor));
+ double rightLength = getLength(peService.getLocationRelativeToDiagram(fromRightAnchor),
+ peService.getLocationRelativeToDiagram(sourceRight.anchor));
+
+ if (topLength < rightLength) {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceTop.anchor, fromTopAnchor);
+ } else {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceRight.anchor, fromRightAnchor);
+ }
+ } else {
+ FixPointAnchor fromTopAnchor = getCorrectAnchor(targetBoundaryAnchors,
+ peService.getLocationRelativeToDiagram(sourceTop.anchor));
+ FixPointAnchor fromLeftAnchor = getCorrectAnchor(targetBoundaryAnchors,
+ peService.getLocationRelativeToDiagram(sourceLeft.anchor));
+
+ double topLength = getLength(peService.getLocationRelativeToDiagram(fromTopAnchor),
+ peService.getLocationRelativeToDiagram(sourceTop.anchor));
+ double leftLength = getLength(peService.getLocationRelativeToDiagram(fromLeftAnchor),
+ peService.getLocationRelativeToDiagram(sourceLeft.anchor));
+ if (topLength < leftLength) {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceTop.anchor, fromTopAnchor);
+ } else {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceLeft.anchor, fromLeftAnchor);
+ }
+ }
+
+ }
+
+ if (sHigher) {
+ if (!sLeft && !sRight) {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceBottom.anchor, targetTop.anchor);
+ } else if (sLeft) {
+ FixPointAnchor fromBottomAnchor = getCorrectAnchor(targetBoundaryAnchors,
+ peService.getLocationRelativeToDiagram(sourceBottom.anchor));
+ FixPointAnchor fromRightAnchor = getCorrectAnchor(targetBoundaryAnchors,
+ peService.getLocationRelativeToDiagram(sourceRight.anchor));
+
+ double bottomLength = getLength(peService.getLocationRelativeToDiagram(fromBottomAnchor),
+ peService.getLocationRelativeToDiagram(sourceBottom.anchor));
+ double rightLength = getLength(peService.getLocationRelativeToDiagram(fromRightAnchor),
+ peService.getLocationRelativeToDiagram(sourceRight.anchor));
+
+ if (bottomLength < rightLength) {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceBottom.anchor, fromBottomAnchor);
+ } else {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceRight.anchor, fromRightAnchor);
+ }
+ } else {
+ FixPointAnchor fromBottomAnchor = getCorrectAnchor(targetBoundaryAnchors,
+ peService.getLocationRelativeToDiagram(sourceBottom.anchor));
+ FixPointAnchor fromLeftAnchor = getCorrectAnchor(targetBoundaryAnchors,
+ peService.getLocationRelativeToDiagram(sourceLeft.anchor));
+
+ double bottomLength = getLength(peService.getLocationRelativeToDiagram(fromBottomAnchor),
+ peService.getLocationRelativeToDiagram(sourceBottom.anchor));
+ double leftLength = getLength(peService.getLocationRelativeToDiagram(fromLeftAnchor),
+ peService.getLocationRelativeToDiagram(sourceLeft.anchor));
+ if (bottomLength < leftLength) {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceBottom.anchor, fromBottomAnchor);
+ } else {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceLeft.anchor, fromLeftAnchor);
+ }
+ }
+ }
+
+ // if source left is further than target right then use source left and target right
+ if (sRight) {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceLeft.anchor, targetRight.anchor);
+ }
+
+ // if source right is smaller than target left then use source right and target left
+ if (sLeft) {
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceRight.anchor, targetLeft.anchor);
+ }
+
+ return new Tuple<FixPointAnchor, FixPointAnchor>(sourceTop.anchor, targetTop.anchor);
+ }
+
+ private static FixPointAnchor getCorrectAnchor(Map<AnchorLocation, BoundaryAnchor> targetBoundaryAnchors,
+ ILocation loc) {
+ return getCorrectAnchor(targetBoundaryAnchors, gaService.createPoint(loc.getX(), loc.getY()));
+ }
+
+ private static double getLength(ILocation start, ILocation end) {
+ return Math.sqrt(Math.pow(start.getX() - end.getX(), 2) + Math.pow(start.getY() - end.getY(), 2));
+ }
+
+ private static FixPointAnchor getCorrectAnchor(Map<AnchorLocation, BoundaryAnchor> boundaryAnchors, Point point) {
+
+ BoundaryAnchor bottom = boundaryAnchors.get(AnchorLocation.BOTTOM);
+ BoundaryAnchor top = boundaryAnchors.get(AnchorLocation.TOP);
+ BoundaryAnchor right = boundaryAnchors.get(AnchorLocation.RIGHT);
+ BoundaryAnchor left = boundaryAnchors.get(AnchorLocation.LEFT);
+
+ boolean pointLower = point.getY() > bottom.location.getY();
+ boolean pointHigher = point.getY() < top.location.getY();
+ boolean pointRight = point.getX() > right.location.getX();
+ boolean pointLeft = point.getX() < left.location.getX();
+
+ // Find the best connector.
+ if (pointLower) {
+ if (!pointLeft && !pointRight) {
+ // bendpoint is straight below the shape
+ return bottom.anchor;
+ } else if (pointLeft) {
+
+ int deltaX = left.location.getX() - point.getX();
+ int deltaY = point.getY() - bottom.location.getY();
+ if (deltaX > deltaY) {
+ return left.anchor;
+ } else {
+ return bottom.anchor;
+ }
+ } else {
+ int deltaX = point.getX() - right.location.getX();
+ int deltaY = point.getY() - bottom.location.getY();
+ if (deltaX > deltaY) {
+ return right.anchor;
+ } else {
+ return bottom.anchor;
+ }
+ }
+ }
+
+ if (pointHigher) {
+ if (!pointLeft && !pointRight) {
+ // bendpoint is straight above the shape
+ return top.anchor;
+ } else if (pointLeft) {
+ int deltaX = left.location.getX() - point.getX();
+ int deltaY = top.location.getY() - point.getY();
+ if (deltaX > deltaY) {
+ return left.anchor;
+ } else {
+ return top.anchor;
+ }
+ } else {
+ int deltaX = point.getX() - right.location.getX();
+ int deltaY = top.location.getY() - point.getY();
+ if (deltaX > deltaY) {
+ return right.anchor;
+ } else {
+ return top.anchor;
+ }
+ }
+
+ }
+
+ // if we reach here, then the point is neither above or below the shape and we only need to determine if we need
+ // to connect to the left or right part of the shape
+ if (pointRight) {
+ return right.anchor;
+ }
+
+ if (pointLeft) {
+ return left.anchor;
+ }
+
+ return top.anchor;
+ }
+
+ public static void reConnect(BPMNShape shape, Diagram diagram) {
+ try {
+ ModelHandler handler = ModelHandler.getInstance(diagram);
+ for (BPMNEdge bpmnEdge : handler.getAll(BPMNEdge.class)) {
+ DiagramElement sourceElement = bpmnEdge.getSourceElement();
+ DiagramElement targetElement = bpmnEdge.getTargetElement();
+ if (sourceElement != null && targetElement != null) {
+ boolean sourceMatches = sourceElement.getId().equals(shape.getId());
+ boolean targetMatches = targetElement.getId().equals(shape.getId());
+ if (sourceMatches || targetMatches) {
+ updateEdge(bpmnEdge, diagram);
+ }
+ }
+ }
+ } catch (Exception e) {
+ Activator.logError(e);
+ }
+ }
+
+ private static void updateEdge(BPMNEdge edge, Diagram diagram) {
+ List<PictogramElement> elements;
+ elements = Graphiti.getLinkService().getPictogramElements(diagram, edge.getSourceElement());
+ if (elements.size()==0)
+ return;
+ ContainerShape source = (ContainerShape) elements.get(0);
+
+ elements = Graphiti.getLinkService().getPictogramElements(diagram, edge.getTargetElement());
+ if (elements.size()==0)
+ return;
+ ContainerShape target = (ContainerShape) elements.get(0);
+
+ elements = Graphiti.getLinkService().getPictogramElements(diagram, edge);
+ if (elements.size()==0)
+ return;
+ Connection connection = (Connection) elements.get(0);
+ Tuple<FixPointAnchor, FixPointAnchor> anchors = getSourceAndTargetBoundaryAnchors(source, target, connection);
+
+ ILocation loc = peService.getLocationRelativeToDiagram(anchors.getFirst());
+ org.eclipse.dd.dc.Point p = edge.getWaypoint().get(0);
+ p.setX(loc.getX());
+ p.setY(loc.getY());
+
+ loc = peService.getLocationRelativeToDiagram(anchors.getSecond());
+ p = edge.getWaypoint().get(edge.getWaypoint().size() - 1);
+ p.setX(loc.getX());
+ p.setY(loc.getY());
+
+ relocateConnection(source.getAnchors(), anchors, target);
+ deleteEmptyAdHocAnchors(source);
+ deleteEmptyAdHocAnchors(target);
+ }
+
+ private static void relocateConnection(EList<Anchor> anchors, Tuple<FixPointAnchor, FixPointAnchor> newAnchors,
+ ContainerShape target) {
+
+ List<Connection> connectionsToBeUpdated = new ArrayList<Connection>();
+
+ for (Anchor anchor : anchors) {
+ if (!(anchor instanceof FixPointAnchor)) {
+ continue;
+ }
+
+ for (Connection connection : anchor.getOutgoingConnections()) {
+ if (connection.getEnd().eContainer().equals(target)) {
+ connectionsToBeUpdated.add(connection);
+ }
+ }
+ }
+
+ for (Connection c : connectionsToBeUpdated) {
+ c.setStart(newAnchors.getFirst());
+ c.setEnd(newAnchors.getSecond());
+ }
+ }
+
+ private static void deleteEmptyAdHocAnchors(Shape s) {
+ List<Integer> indexes = new ArrayList<Integer>();
+
+ for (int i = s.getAnchors().size()-1; i>=0; --i) {
+ Anchor a = s.getAnchors().get(i);
+ if (!(a instanceof FixPointAnchor)) {
+ continue;
+ }
+
+ if (peService.getProperty(a, BOUNDARY_FIXPOINT_ANCHOR) == null && a.getIncomingConnections().isEmpty()
+ && a.getOutgoingConnections().isEmpty()) {
+ indexes.add(i);
+ }
+ }
+
+ for (int i : indexes) {
+ peService.deletePictogramElement(s.getAnchors().get(i));
+ }
+ }
+
+ public static void addFixedPointAnchors(Shape shape, GraphicsAlgorithm ga) {
+ IDimension size = gaService.calculateSize(ga);
+ int w = size.getWidth();
+ int h = size.getHeight();
+ AnchorUtil.createAnchor(shape, AnchorLocation.TOP, w / 2, 0);
+ AnchorUtil.createAnchor(shape, AnchorLocation.RIGHT, w, h / 2);
+ AnchorUtil.createAnchor(shape, AnchorLocation.BOTTOM, w / 2, h);
+ AnchorUtil.createAnchor(shape, AnchorLocation.LEFT, 0, h / 2);
+ }
+
+ public static void relocateFixPointAnchors(Shape shape, int w, int h) {
+ Map<AnchorLocation, BoundaryAnchor> anchors = AnchorUtil.getBoundaryAnchors(shape);
+
+ FixPointAnchor anchor = anchors.get(AnchorLocation.TOP).anchor;
+ anchor.setLocation(gaService.createPoint(w / 2, 0));
+
+ anchor = anchors.get(AnchorLocation.RIGHT).anchor;
+ anchor.setLocation(gaService.createPoint(w, h / 2));
+
+ anchor = anchors.get(AnchorLocation.BOTTOM).anchor;
+ anchor.setLocation(gaService.createPoint(w / 2, h));
+
+ anchor = anchors.get(AnchorLocation.LEFT).anchor;
+ anchor.setLocation(gaService.createPoint(0, h / 2));
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/FeatureSupport.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/FeatureSupport.java
index 2116999..33816c7 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/FeatureSupport.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/FeatureSupport.java
@@ -12,6 +12,8 @@
******************************************************************************/
package org.eclipse.bpmn2.modeler.core.utils;
+import static org.eclipse.bpmn2.modeler.core.features.activity.AbstractAddActivityFeature.ACTIVITY_DECORATOR;
+
import java.awt.Dimension;
import java.io.IOException;
import java.util.ArrayList;
@@ -38,6 +40,9 @@
import org.eclipse.graphiti.mm.algorithms.Polyline;
import org.eclipse.graphiti.mm.algorithms.Text;
import org.eclipse.graphiti.mm.algorithms.styles.Point;
+import org.eclipse.graphiti.mm.pictograms.Anchor;
+import org.eclipse.graphiti.mm.pictograms.AnchorContainer;
+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;
@@ -77,6 +82,41 @@
return lane.getChildLaneSet() == null || lane.getChildLaneSet().getLanes().isEmpty();
}
+ public static List<PictogramElement> getContainerChildren(ContainerShape container) {
+ List<PictogramElement> list = new ArrayList<PictogramElement>();
+ for (PictogramElement pe : container.getChildren()) {
+ String value = Graphiti.getPeService().getPropertyValue(pe, ACTIVITY_DECORATOR);
+ if (value!=null && "true".equals(value))
+ continue;
+ list.add(pe);
+ }
+ return list;
+ }
+
+ public static List<PictogramElement> getContainerDecorators(ContainerShape container) {
+ List<PictogramElement> list = new ArrayList<PictogramElement>();
+ for (PictogramElement pe : container.getChildren()) {
+ String value = Graphiti.getPeService().getPropertyValue(pe, ACTIVITY_DECORATOR);
+ if (value!=null && "true".equals(value))
+ list.add(pe);
+ }
+ return list;
+ }
+
+ public static void setContainerChildrenVisible(ContainerShape container, boolean visible) {
+ for (PictogramElement pe : getContainerChildren(container)) {
+ pe.setVisible(visible);
+ if (pe instanceof AnchorContainer) {
+ AnchorContainer ac = (AnchorContainer)pe;
+ for (Anchor a : ac.getAnchors()) {
+ for (Connection c : a.getOutgoingConnections()) {
+ c.setVisible(visible);
+ }
+ }
+ }
+ }
+ }
+
/**
* Use ModelHandler.getInstance(diagram) instead
*
diff --git a/org.eclipse.bpmn2.modeler.ui/icons/16/collapse.png b/org.eclipse.bpmn2.modeler.ui/icons/16/collapse.png
new file mode 100644
index 0000000..a54ded9
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/icons/16/collapse.png
Binary files differ
diff --git a/org.eclipse.bpmn2.modeler.ui/icons/16/expand.png b/org.eclipse.bpmn2.modeler.ui/icons/16/expand.png
new file mode 100644
index 0000000..0258923
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/icons/16/expand.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 10dff3d..c739d5a 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
@@ -142,6 +142,9 @@
public static final String IMG_20_MULTIPLE = PREFIX + "multipleeventdefinition" + dot20; // FIXME
public static final String IMG_16_ACTION = "default_action";
+
+ public static final String IMG_16_EXPAND = PREFIX + "expand" + dot16;
+ public static final String IMG_16_COLLAPSE = PREFIX + "collapse" + dot16;
@Override
protected void addAvailableImages() {
@@ -197,5 +200,7 @@
addImageFilePath(IMG_20_MULTIPLE, ICONS_20 + "Multiple.png");
addImageFilePath(IMG_16_ACTION, ICONS_16 + "action.gif");
+ addImageFilePath(IMG_16_EXPAND, ICONS_16 + "expand.png");
+ addImageFilePath(IMG_16_COLLAPSE, ICONS_16 + "collapse.png");
}
}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BPMNFeatureProvider.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BPMNFeatureProvider.java
index 9a0512d..0aef007 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BPMNFeatureProvider.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BPMNFeatureProvider.java
@@ -15,6 +15,8 @@
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.modeler.core.features.BusinessObjectUtil;
import org.eclipse.bpmn2.modeler.core.features.ConnectionFeatureContainer;
import org.eclipse.bpmn2.modeler.core.features.DefaultBpmnDeleteFeature;
import org.eclipse.bpmn2.modeler.core.features.FeatureContainer;
@@ -24,6 +26,8 @@
import org.eclipse.bpmn2.modeler.core.features.bendpoint.RemoveBendpointFeature;
import org.eclipse.bpmn2.modeler.ui.features.activity.subprocess.AdHocSubProcessFeatureContainer;
import org.eclipse.bpmn2.modeler.ui.features.activity.subprocess.CallActivityFeatureContainer;
+import org.eclipse.bpmn2.modeler.ui.features.activity.subprocess.SubProcessCollapseFeature;
+import org.eclipse.bpmn2.modeler.ui.features.activity.subprocess.SubProcessExpandFeature;
import org.eclipse.bpmn2.modeler.ui.features.activity.subprocess.SubProcessFeatureContainer;
import org.eclipse.bpmn2.modeler.ui.features.activity.subprocess.TransactionFeatureContainer;
import org.eclipse.bpmn2.modeler.ui.features.activity.task.BusinessRuleTaskFeatureContainer;
@@ -92,6 +96,7 @@
import org.eclipse.graphiti.features.IUpdateFeature;
import org.eclipse.graphiti.features.context.IAddBendpointContext;
import org.eclipse.graphiti.features.context.IAddContext;
+import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.features.context.IDeleteContext;
import org.eclipse.graphiti.features.context.IDirectEditingContext;
import org.eclipse.graphiti.features.context.ILayoutContext;
@@ -101,8 +106,8 @@
import org.eclipse.graphiti.features.context.IRemoveBendpointContext;
import org.eclipse.graphiti.features.context.IResizeShapeContext;
import org.eclipse.graphiti.features.context.IUpdateContext;
+import org.eclipse.graphiti.features.custom.ICustomFeature;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
-import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.ui.features.DefaultFeatureProvider;
/**
@@ -422,4 +427,17 @@
return new DefaultBpmnDeleteFeature(this);
}
+ @Override
+ public ICustomFeature[] getCustomFeatures(ICustomContext context) {
+ PictogramElement[] elements = context.getPictogramElements();
+ for (PictogramElement pe : elements) {
+ if (BusinessObjectUtil.containsElementOfType(pe, SubProcess.class)) {
+ return new ICustomFeature[] {
+ new SubProcessExpandFeature(this),
+ new SubProcessCollapseFeature(this)
+ };
+ }
+ }
+ return new ICustomFeature[] {};
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BpmnToolBehaviourFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BpmnToolBehaviourFeature.java
index b0ccbde..48bc9cf 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BpmnToolBehaviourFeature.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/diagram/BpmnToolBehaviourFeature.java
@@ -1,330 +1,331 @@
-/*******************************************************************************
- * 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 Innar Made
- ******************************************************************************/
-package org.eclipse.bpmn2.modeler.ui.diagram;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.bpmn2.modeler.core.Activator;
-import org.eclipse.bpmn2.modeler.core.features.activity.ActivitySelectionBehavior;
-import org.eclipse.bpmn2.modeler.core.features.event.EventSelectionBehavior;
-import org.eclipse.bpmn2.modeler.core.preferences.ToolEnablementPreferences;
-import org.eclipse.bpmn2.modeler.core.runtime.CustomTaskDescriptor;
-import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
-import org.eclipse.bpmn2.modeler.ui.FeatureMap;
-import org.eclipse.bpmn2.modeler.ui.ImageProvider;
-import org.eclipse.bpmn2.modeler.ui.editor.BPMN2Editor;
-import org.eclipse.bpmn2.modeler.ui.features.activity.task.CustomTaskFeatureContainer;
-import org.eclipse.bpmn2.modeler.ui.features.choreography.ChoreographySelectionBehavior;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.ecore.EClass;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.graphiti.dt.IDiagramTypeProvider;
-import org.eclipse.graphiti.features.FeatureCheckerAdapter;
-import org.eclipse.graphiti.features.ICreateConnectionFeature;
-import org.eclipse.graphiti.features.ICreateFeature;
-import org.eclipse.graphiti.features.IFeature;
-import org.eclipse.graphiti.features.IFeatureChecker;
-import org.eclipse.graphiti.features.IFeatureCheckerHolder;
-import org.eclipse.graphiti.features.IFeatureProvider;
-import org.eclipse.graphiti.features.context.IContext;
-import org.eclipse.graphiti.features.context.IPictogramElementContext;
-import org.eclipse.graphiti.features.context.impl.CreateConnectionContext;
-import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
-import org.eclipse.graphiti.mm.pictograms.Anchor;
-import org.eclipse.graphiti.mm.pictograms.AnchorContainer;
-import org.eclipse.graphiti.mm.pictograms.PictogramElement;
-import org.eclipse.graphiti.palette.IPaletteCompartmentEntry;
-import org.eclipse.graphiti.palette.impl.ConnectionCreationToolEntry;
-import org.eclipse.graphiti.palette.impl.ObjectCreationToolEntry;
-import org.eclipse.graphiti.palette.impl.PaletteCompartmentEntry;
-import org.eclipse.graphiti.services.Graphiti;
-import org.eclipse.graphiti.tb.ContextButtonEntry;
-import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;
-import org.eclipse.graphiti.tb.IContextButtonPadData;
-
-public class BpmnToolBehaviourFeature extends DefaultToolBehaviorProvider implements IFeatureCheckerHolder {
-
- public BpmnToolBehaviourFeature(IDiagramTypeProvider diagramTypeProvider) {
- super(diagramTypeProvider);
- }
-
- @Override
- public IPaletteCompartmentEntry[] getPalette() {
-
- EList<Resource> resources = getDiagramTypeProvider().getDiagram().eResource().getResourceSet().getResources();
- IProject project = null;
- for (Resource resource : resources) {
- if (resource.getURI().segmentCount() > 1) {
- String projectName = resource.getURI().segment(1);
- project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
- if (project != null) {
- break;
- }
- }
- }
-
- ToolEnablementPreferences pref = ToolEnablementPreferences.getPreferences(project);
-
- List<IPaletteCompartmentEntry> ret = new ArrayList<IPaletteCompartmentEntry>();
-
- // add compartments from super class
-
- IFeatureProvider featureProvider = getFeatureProvider();
-
- createConnectors(pref, ret, featureProvider);
-
- createEventsCompartments(pref, ret, featureProvider);
- createTasksCompartments(pref, ret, featureProvider);
- createGatewaysCompartments(pref, ret, featureProvider);
- createEventDefinitionsCompartments(pref, ret, featureProvider);
- createDataCompartments(pref, ret, featureProvider);
- createOtherCompartments(pref, ret, featureProvider);
-
- createCustomTasks(ret, featureProvider);
-
- return ret.toArray(new IPaletteCompartmentEntry[ret.size()]);
- }
-
- private void createEventsCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
- IFeatureProvider featureProvider) {
- PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Events", null);
- ret.add(compartmentEntry);
-
- createEntries(pref, FeatureMap.EVENTS, compartmentEntry, featureProvider);
- }
-
- private void createOtherCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
- IFeatureProvider featureProvider) {
- PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Other", null);
- compartmentEntry.setInitiallyOpen(false);
- ret.add(compartmentEntry);
-
- createEntries(pref, FeatureMap.OTHER, compartmentEntry, featureProvider);
-
- }
-
- private void createDataCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
- IFeatureProvider featureProvider) {
- PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Data Items", null);
- compartmentEntry.setInitiallyOpen(false);
- ret.add(compartmentEntry);
-
- createEntries(pref, FeatureMap.DATA, compartmentEntry, featureProvider);
-
- }
-
- private void createEventDefinitionsCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
- IFeatureProvider featureProvider) {
- PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Event Definitions", null);
- compartmentEntry.setInitiallyOpen(false);
- ret.add(compartmentEntry);
-
- createEntries(pref, FeatureMap.EVENT_DEFINITIONS, compartmentEntry, featureProvider);
-
- }
-
- private void createGatewaysCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
- IFeatureProvider featureProvider) {
- PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Gateways", null);
- ret.add(compartmentEntry);
-
- createEntries(pref, FeatureMap.GATEWAYS, compartmentEntry, featureProvider);
-
- }
-
- private void createTasksCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
- IFeatureProvider featureProvider) {
- PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Tasks", null);
- ret.add(compartmentEntry);
-
- createEntries(pref, FeatureMap.TASKS, compartmentEntry, featureProvider);
-
- }
-
- private void createConnectors(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
- IFeatureProvider featureProvider) {
- PaletteCompartmentEntry compartmentEntry;
- compartmentEntry = new PaletteCompartmentEntry("Connectors", null);
- ret.add(compartmentEntry);
- // add all create-connection-features to the new stack-entry
- ICreateConnectionFeature[] createConnectionFeatures = featureProvider.getCreateConnectionFeatures();
- for (ICreateConnectionFeature cf : createConnectionFeatures) {
- if (pref.isEnabled(FeatureMap.getElement(cf))) {
- ConnectionCreationToolEntry connectionCreationToolEntry = new ConnectionCreationToolEntry(
- cf.getCreateName(), cf.getCreateDescription(), cf.getCreateImageId(),
- cf.getCreateLargeImageId());
- connectionCreationToolEntry.addCreateConnectionFeature(cf);
- compartmentEntry.addToolEntry(connectionCreationToolEntry);
- }
- }
- }
-
- private void createEntries(ToolEnablementPreferences pref, List<Class<? extends IFeature>> neededEntries,
- PaletteCompartmentEntry compartmentEntry, IFeatureProvider featureProvider) {
- List<ICreateFeature> tools = Arrays.asList(featureProvider.getCreateFeatures());
-
- for (ICreateFeature cf : tools) {
- EClass feature = FeatureMap.getElement(cf);
- if (pref.isEnabled(feature) && neededEntries.contains(cf.getClass())) {
- ObjectCreationToolEntry objectCreationToolEntry = new ObjectCreationToolEntry(cf.getCreateName(),
- cf.getCreateDescription(), cf.getCreateImageId(), cf.getCreateLargeImageId(), cf);
- compartmentEntry.addToolEntry(objectCreationToolEntry);
- }
- }
- }
-
- private void createCustomTasks(List<IPaletteCompartmentEntry> ret, IFeatureProvider featureProvider) {
- PaletteCompartmentEntry compartmentEntry = null;
- BPMN2Editor editor = (BPMN2Editor) getDiagramTypeProvider().getDiagramEditor();
- TargetRuntime rt = editor.getTargetRuntime();
-
- try {
- for (CustomTaskDescriptor tc : rt.getCustomTasks()) {
-
- CustomTaskFeatureContainer container = (CustomTaskFeatureContainer)tc.getCreateFeature();
-
- container.setId(featureProvider, tc.getId());
- ICreateFeature cf = container.getCreateFeature(featureProvider);
- ObjectCreationToolEntry objectCreationToolEntry = new ObjectCreationToolEntry(tc.getName(),
- cf.getCreateDescription(), cf.getCreateImageId(), cf.getCreateLargeImageId(), cf);
-
- if (compartmentEntry==null) {
- compartmentEntry = new PaletteCompartmentEntry("Custom Task", null);
- compartmentEntry.setInitiallyOpen(false);
- ret.add(compartmentEntry);
- }
-
- compartmentEntry.addToolEntry(objectCreationToolEntry);
-
- }
- } catch (Exception ex) {
- Activator.logError(ex);
- }
- }
-
- @Override
- public IFeatureChecker getFeatureChecker() {
- return new FeatureCheckerAdapter(false) {
- @Override
- public boolean allowAdd(IContext context) {
- return super.allowAdd(context);
- }
-
- @Override
- public boolean allowCreate() {
- return super.allowCreate();
- }
- };
- }
-
- @Override
- public GraphicsAlgorithm[] getClickArea(PictogramElement pe) {
- if (ActivitySelectionBehavior.canApplyTo(pe)) {
- return ActivitySelectionBehavior.getClickArea(pe);
- } else if (EventSelectionBehavior.canApplyTo(pe)) {
- return EventSelectionBehavior.getClickArea(pe);
- } else if (ChoreographySelectionBehavior.canApplyTo(pe)) {
- return ChoreographySelectionBehavior.getClickArea(pe);
- }
- return super.getClickArea(pe);
- }
-
- @Override
- public GraphicsAlgorithm getSelectionBorder(PictogramElement pe) {
- if (ActivitySelectionBehavior.canApplyTo(pe)) {
- return ActivitySelectionBehavior.getSelectionBorder(pe);
- } else if (EventSelectionBehavior.canApplyTo(pe)) {
- return EventSelectionBehavior.getSelectionBorder(pe);
- } else if (ChoreographySelectionBehavior.canApplyTo(pe)) {
- return ChoreographySelectionBehavior.getSelectionBorder(pe);
- }
- return super.getSelectionBorder(pe);
- }
-
- @Override
- public IContextButtonPadData getContextButtonPad(IPictogramElementContext context) {
- IContextButtonPadData data = super.getContextButtonPad(context);
- PictogramElement pe = context.getPictogramElement();
-
- // 1. set the generic context buttons
- // note, that we do not add 'remove' (just as an example)
- setGenericContextButtons(data, pe, CONTEXT_BUTTON_DELETE | CONTEXT_BUTTON_UPDATE);
-
- // 2. set the expand & collapse buttons
- // TODO: implement this as a resizable container shape within the current editor instead of as a drilldown feature
-// CustomContext cc = new CustomContext(new PictogramElement[] { pe });
-// ICustomFeature[] cf = getFeatureProvider().getCustomFeatures(cc);
-// for (int i = 0; i < cf.length; i++) {
-// ICustomFeature iCustomFeature = cf[i];
-// ContextButtonEntry button = new ContextButtonEntry(iCustomFeature, cc);
-// button.setText(iCustomFeature.getName()); //$NON-NLS-1$
-// button.setIconId(iCustomFeature.getImageId());
-// button.setDescription(iCustomFeature.getDescription());
-//
-// data.getDomainSpecificContextButtons().add(button);
-// }
-
- // 3. add one domain specific context-button, which offers all
- // available connection-features as drag&drop features...
-
- // 3.a. create new CreateConnectionContext
- CreateConnectionContext ccc = new CreateConnectionContext();
- ccc.setSourcePictogramElement(pe);
- Anchor anchor = null;
- if (pe instanceof Anchor) {
- anchor = (Anchor) pe;
- } else if (pe instanceof AnchorContainer) {
- // assume, that our shapes always have chopbox anchors
- anchor = Graphiti.getPeService().getChopboxAnchor((AnchorContainer) pe);
- }
- ccc.setSourceAnchor(anchor);
-
- // 3.b. create context button and add "Create Connections" feature
- ICreateConnectionFeature[] features = getFeatureProvider().getCreateConnectionFeatures();
- ContextButtonEntry button = new ContextButtonEntry(null, context);
- button.setText("Create Connection"); //$NON-NLS-1$
- String description = null;
- ArrayList<String> names = new ArrayList<String>();
- button.setIconId(ImageProvider.IMG_16_SEQUENCE_FLOW);
- for (ICreateConnectionFeature feature : features) {
- if (feature.isAvailable(ccc) && feature.canStartConnection(ccc)) {
- button.addDragAndDropFeature(feature);
- names.add(feature.getCreateName());
- }
- }
-
- // 3.c. build a reasonable description for the context button action
- for (int i=0; i<names.size(); ++i) {
- if (description==null)
- description = "Click and drag to create a\n";
- description += names.get(i);
- if (i+2 == names.size())
- description += " or ";
- else if (i+1 < names.size())
- description += ", ";
- }
- button.setDescription(description);
-
- // 3.d. add context button, but only if it contains at least one feature
- if (button.getDragAndDropFeatures().size() > 0) {
- data.getDomainSpecificContextButtons().add(button);
- }
-
- return data;
- }
-
+/*******************************************************************************
+ * 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 Innar Made
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.ui.diagram;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.bpmn2.modeler.core.Activator;
+import org.eclipse.bpmn2.modeler.core.features.activity.ActivitySelectionBehavior;
+import org.eclipse.bpmn2.modeler.core.features.event.EventSelectionBehavior;
+import org.eclipse.bpmn2.modeler.core.preferences.ToolEnablementPreferences;
+import org.eclipse.bpmn2.modeler.core.runtime.CustomTaskDescriptor;
+import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
+import org.eclipse.bpmn2.modeler.ui.FeatureMap;
+import org.eclipse.bpmn2.modeler.ui.ImageProvider;
+import org.eclipse.bpmn2.modeler.ui.editor.BPMN2Editor;
+import org.eclipse.bpmn2.modeler.ui.features.activity.task.CustomTaskFeatureContainer;
+import org.eclipse.bpmn2.modeler.ui.features.choreography.ChoreographySelectionBehavior;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.graphiti.dt.IDiagramTypeProvider;
+import org.eclipse.graphiti.features.FeatureCheckerAdapter;
+import org.eclipse.graphiti.features.ICreateConnectionFeature;
+import org.eclipse.graphiti.features.ICreateFeature;
+import org.eclipse.graphiti.features.IFeature;
+import org.eclipse.graphiti.features.IFeatureChecker;
+import org.eclipse.graphiti.features.IFeatureCheckerHolder;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.IContext;
+import org.eclipse.graphiti.features.context.IPictogramElementContext;
+import org.eclipse.graphiti.features.context.impl.CreateConnectionContext;
+import org.eclipse.graphiti.features.context.impl.CustomContext;
+import org.eclipse.graphiti.features.custom.ICustomFeature;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.pictograms.Anchor;
+import org.eclipse.graphiti.mm.pictograms.AnchorContainer;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.palette.IPaletteCompartmentEntry;
+import org.eclipse.graphiti.palette.impl.ConnectionCreationToolEntry;
+import org.eclipse.graphiti.palette.impl.ObjectCreationToolEntry;
+import org.eclipse.graphiti.palette.impl.PaletteCompartmentEntry;
+import org.eclipse.graphiti.services.Graphiti;
+import org.eclipse.graphiti.tb.ContextButtonEntry;
+import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider;
+import org.eclipse.graphiti.tb.IContextButtonPadData;
+
+public class BpmnToolBehaviourFeature extends DefaultToolBehaviorProvider implements IFeatureCheckerHolder {
+
+ public BpmnToolBehaviourFeature(IDiagramTypeProvider diagramTypeProvider) {
+ super(diagramTypeProvider);
+ }
+
+ @Override
+ public IPaletteCompartmentEntry[] getPalette() {
+
+ EList<Resource> resources = getDiagramTypeProvider().getDiagram().eResource().getResourceSet().getResources();
+ IProject project = null;
+ for (Resource resource : resources) {
+ if (resource.getURI().segmentCount() > 1) {
+ String projectName = resource.getURI().segment(1);
+ project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+ if (project != null) {
+ break;
+ }
+ }
+ }
+
+ ToolEnablementPreferences pref = ToolEnablementPreferences.getPreferences(project);
+
+ List<IPaletteCompartmentEntry> ret = new ArrayList<IPaletteCompartmentEntry>();
+
+ // add compartments from super class
+
+ IFeatureProvider featureProvider = getFeatureProvider();
+
+ createConnectors(pref, ret, featureProvider);
+
+ createEventsCompartments(pref, ret, featureProvider);
+ createTasksCompartments(pref, ret, featureProvider);
+ createGatewaysCompartments(pref, ret, featureProvider);
+ createEventDefinitionsCompartments(pref, ret, featureProvider);
+ createDataCompartments(pref, ret, featureProvider);
+ createOtherCompartments(pref, ret, featureProvider);
+
+ createCustomTasks(ret, featureProvider);
+
+ return ret.toArray(new IPaletteCompartmentEntry[ret.size()]);
+ }
+
+ private void createEventsCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
+ IFeatureProvider featureProvider) {
+ PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Events", null);
+ ret.add(compartmentEntry);
+
+ createEntries(pref, FeatureMap.EVENTS, compartmentEntry, featureProvider);
+ }
+
+ private void createOtherCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
+ IFeatureProvider featureProvider) {
+ PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Other", null);
+ compartmentEntry.setInitiallyOpen(false);
+ ret.add(compartmentEntry);
+
+ createEntries(pref, FeatureMap.OTHER, compartmentEntry, featureProvider);
+
+ }
+
+ private void createDataCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
+ IFeatureProvider featureProvider) {
+ PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Data Items", null);
+ compartmentEntry.setInitiallyOpen(false);
+ ret.add(compartmentEntry);
+
+ createEntries(pref, FeatureMap.DATA, compartmentEntry, featureProvider);
+
+ }
+
+ private void createEventDefinitionsCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
+ IFeatureProvider featureProvider) {
+ PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Event Definitions", null);
+ compartmentEntry.setInitiallyOpen(false);
+ ret.add(compartmentEntry);
+
+ createEntries(pref, FeatureMap.EVENT_DEFINITIONS, compartmentEntry, featureProvider);
+
+ }
+
+ private void createGatewaysCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
+ IFeatureProvider featureProvider) {
+ PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Gateways", null);
+ ret.add(compartmentEntry);
+
+ createEntries(pref, FeatureMap.GATEWAYS, compartmentEntry, featureProvider);
+
+ }
+
+ private void createTasksCompartments(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
+ IFeatureProvider featureProvider) {
+ PaletteCompartmentEntry compartmentEntry = new PaletteCompartmentEntry("Tasks", null);
+ ret.add(compartmentEntry);
+
+ createEntries(pref, FeatureMap.TASKS, compartmentEntry, featureProvider);
+
+ }
+
+ private void createConnectors(ToolEnablementPreferences pref, List<IPaletteCompartmentEntry> ret,
+ IFeatureProvider featureProvider) {
+ PaletteCompartmentEntry compartmentEntry;
+ compartmentEntry = new PaletteCompartmentEntry("Connectors", null);
+ ret.add(compartmentEntry);
+ // add all create-connection-features to the new stack-entry
+ ICreateConnectionFeature[] createConnectionFeatures = featureProvider.getCreateConnectionFeatures();
+ for (ICreateConnectionFeature cf : createConnectionFeatures) {
+ if (pref.isEnabled(FeatureMap.getElement(cf))) {
+ ConnectionCreationToolEntry connectionCreationToolEntry = new ConnectionCreationToolEntry(
+ cf.getCreateName(), cf.getCreateDescription(), cf.getCreateImageId(),
+ cf.getCreateLargeImageId());
+ connectionCreationToolEntry.addCreateConnectionFeature(cf);
+ compartmentEntry.addToolEntry(connectionCreationToolEntry);
+ }
+ }
+ }
+
+ private void createEntries(ToolEnablementPreferences pref, List<Class<? extends IFeature>> neededEntries,
+ PaletteCompartmentEntry compartmentEntry, IFeatureProvider featureProvider) {
+ List<ICreateFeature> tools = Arrays.asList(featureProvider.getCreateFeatures());
+
+ for (ICreateFeature cf : tools) {
+ EClass feature = FeatureMap.getElement(cf);
+ if (pref.isEnabled(feature) && neededEntries.contains(cf.getClass())) {
+ ObjectCreationToolEntry objectCreationToolEntry = new ObjectCreationToolEntry(cf.getCreateName(),
+ cf.getCreateDescription(), cf.getCreateImageId(), cf.getCreateLargeImageId(), cf);
+ compartmentEntry.addToolEntry(objectCreationToolEntry);
+ }
+ }
+ }
+
+ private void createCustomTasks(List<IPaletteCompartmentEntry> ret, IFeatureProvider featureProvider) {
+ PaletteCompartmentEntry compartmentEntry = null;
+ BPMN2Editor editor = (BPMN2Editor) getDiagramTypeProvider().getDiagramEditor();
+ TargetRuntime rt = editor.getTargetRuntime();
+
+ try {
+ for (CustomTaskDescriptor tc : rt.getCustomTasks()) {
+
+ CustomTaskFeatureContainer container = (CustomTaskFeatureContainer)tc.getCreateFeature();
+
+ container.setId(featureProvider, tc.getId());
+ ICreateFeature cf = container.getCreateFeature(featureProvider);
+ ObjectCreationToolEntry objectCreationToolEntry = new ObjectCreationToolEntry(tc.getName(),
+ cf.getCreateDescription(), cf.getCreateImageId(), cf.getCreateLargeImageId(), cf);
+
+ if (compartmentEntry==null) {
+ compartmentEntry = new PaletteCompartmentEntry("Custom Task", null);
+ compartmentEntry.setInitiallyOpen(false);
+ ret.add(compartmentEntry);
+ }
+
+ compartmentEntry.addToolEntry(objectCreationToolEntry);
+
+ }
+ } catch (Exception ex) {
+ Activator.logError(ex);
+ }
+ }
+
+ @Override
+ public IFeatureChecker getFeatureChecker() {
+ return new FeatureCheckerAdapter(false) {
+ @Override
+ public boolean allowAdd(IContext context) {
+ return super.allowAdd(context);
+ }
+
+ @Override
+ public boolean allowCreate() {
+ return super.allowCreate();
+ }
+ };
+ }
+
+ @Override
+ public GraphicsAlgorithm[] getClickArea(PictogramElement pe) {
+ if (ActivitySelectionBehavior.canApplyTo(pe)) {
+ return ActivitySelectionBehavior.getClickArea(pe);
+ } else if (EventSelectionBehavior.canApplyTo(pe)) {
+ return EventSelectionBehavior.getClickArea(pe);
+ } else if (ChoreographySelectionBehavior.canApplyTo(pe)) {
+ return ChoreographySelectionBehavior.getClickArea(pe);
+ }
+ return super.getClickArea(pe);
+ }
+
+ @Override
+ public GraphicsAlgorithm getSelectionBorder(PictogramElement pe) {
+ if (ActivitySelectionBehavior.canApplyTo(pe)) {
+ return ActivitySelectionBehavior.getSelectionBorder(pe);
+ } else if (EventSelectionBehavior.canApplyTo(pe)) {
+ return EventSelectionBehavior.getSelectionBorder(pe);
+ } else if (ChoreographySelectionBehavior.canApplyTo(pe)) {
+ return ChoreographySelectionBehavior.getSelectionBorder(pe);
+ }
+ return super.getSelectionBorder(pe);
+ }
+
+ @Override
+ public IContextButtonPadData getContextButtonPad(IPictogramElementContext context) {
+ IContextButtonPadData data = super.getContextButtonPad(context);
+ PictogramElement pe = context.getPictogramElement();
+
+ // 1. set the generic context buttons
+ // note, that we do not add 'remove' (just as an example)
+ setGenericContextButtons(data, pe, CONTEXT_BUTTON_DELETE | CONTEXT_BUTTON_UPDATE);
+
+ // 2. set the expand & collapse buttons
+ CustomContext cc = new CustomContext(new PictogramElement[] { pe });
+ ICustomFeature[] cf = getFeatureProvider().getCustomFeatures(cc);
+ for (int i = 0; i < cf.length; i++) {
+ ICustomFeature iCustomFeature = cf[i];
+ ContextButtonEntry button = new ContextButtonEntry(iCustomFeature, cc);
+ button.setText(iCustomFeature.getName()); //$NON-NLS-1$
+ button.setIconId(iCustomFeature.getImageId());
+ button.setDescription(iCustomFeature.getDescription());
+
+ data.getDomainSpecificContextButtons().add(button);
+ }
+
+ // 3. add one domain specific context-button, which offers all
+ // available connection-features as drag&drop features...
+
+ // 3.a. create new CreateConnectionContext
+ CreateConnectionContext ccc = new CreateConnectionContext();
+ ccc.setSourcePictogramElement(pe);
+ Anchor anchor = null;
+ if (pe instanceof Anchor) {
+ anchor = (Anchor) pe;
+ } else if (pe instanceof AnchorContainer) {
+ // assume, that our shapes always have chopbox anchors
+ anchor = Graphiti.getPeService().getChopboxAnchor((AnchorContainer) pe);
+ }
+ ccc.setSourceAnchor(anchor);
+
+ // 3.b. create context button and add "Create Connections" feature
+ ICreateConnectionFeature[] features = getFeatureProvider().getCreateConnectionFeatures();
+ ContextButtonEntry button = new ContextButtonEntry(null, context);
+ button.setText("Create Connection"); //$NON-NLS-1$
+ String description = null;
+ ArrayList<String> names = new ArrayList<String>();
+ button.setIconId(ImageProvider.IMG_16_SEQUENCE_FLOW);
+ for (ICreateConnectionFeature feature : features) {
+ if (feature.isAvailable(ccc) && feature.canStartConnection(ccc)) {
+ button.addDragAndDropFeature(feature);
+ names.add(feature.getCreateName());
+ }
+ }
+
+ // 3.c. build a reasonable description for the context button action
+ for (int i=0; i<names.size(); ++i) {
+ if (description==null)
+ description = "Click and drag to create a\n";
+ description += names.get(i);
+ if (i+2 == names.size())
+ description += " or ";
+ else if (i+1 < names.size())
+ description += ", ";
+ }
+ button.setDescription(description);
+
+ // 3.d. add context button, but only if it contains at least one feature
+ if (button.getDragAndDropFeatures().size() > 0) {
+ data.getDomainSpecificContextButtons().add(button);
+ }
+
+ return data;
+ }
+
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java
index e433406..8203f7c 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java
@@ -1,326 +1,333 @@
-/*******************************************************************************
- * 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 Innar Made
- ******************************************************************************/
-package org.eclipse.bpmn2.modeler.ui.editor;
-
-import java.io.IOException;
-
-import org.eclipse.bpmn2.modeler.core.ModelHandler;
-import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
-import org.eclipse.bpmn2.modeler.core.ProxyURIConverterImplExtension;
-import org.eclipse.bpmn2.modeler.core.di.DIImport;
-import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceImpl;
-import org.eclipse.bpmn2.modeler.core.preferences.Bpmn2Preferences;
-import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
-import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
-import org.eclipse.bpmn2.modeler.ui.Activator;
-import org.eclipse.bpmn2.modeler.ui.BPMN2ContentDescriber;
-import org.eclipse.bpmn2.modeler.ui.preferences.Bpmn2PropertyPage;
-import org.eclipse.bpmn2.modeler.ui.util.ErrorUtils;
-import org.eclipse.bpmn2.modeler.ui.wizards.BPMN2DiagramCreator;
-import org.eclipse.bpmn2.util.Bpmn2ResourceImpl;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.emf.common.command.BasicCommandStack;
-import org.eclipse.emf.common.util.BasicDiagnostic;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.transaction.ExceptionHandler;
-import org.eclipse.emf.transaction.RecordingCommand;
-import org.eclipse.emf.transaction.TransactionalCommandStack;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.emf.transaction.TransactionalEditingDomain.Lifecycle;
-import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl;
-import org.eclipse.graphiti.tb.IToolBehaviorProvider;
-import org.eclipse.graphiti.ui.editor.DiagramEditor;
-import org.eclipse.graphiti.ui.editor.DiagramEditorInput;
-import org.eclipse.jface.action.IStatusLineManager;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorReference;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.IFileEditorInput;
-import org.eclipse.ui.IViewSite;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchListener;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.IWorkbenchPartSite;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.application.WorkbenchAdvisor;
-
-/**
- *
- */
-@SuppressWarnings("restriction")
-public class BPMN2Editor extends DiagramEditor {
-
- public static final String EDITOR_ID = "org.eclipse.bpmn2.modeler.ui.bpmn2editor";
- public static final String CONTRIBUTOR_ID = "org.eclipse.bpmn2.modeler.ui.PropertyContributor";
-
- private ModelHandler modelHandler;
- private URI modelUri;
- private URI diagramUri;
-
- private IFile modelFile;
- private IFile diagramFile;
-
- private IWorkbenchListener workbenchListener;
- private boolean workbenchShutdown = false;
-
- private BPMN2EditingDomainListener editingDomainListener;
-
- private Bpmn2Preferences preferences;
- private TargetRuntime targetRuntime;
-
- @Override
- public void init(IEditorSite site, IEditorInput input) throws PartInitException {
-
- try {
- if (input instanceof IFileEditorInput) {
- modelFile = ((IFileEditorInput) input).getFile();
- loadPreferences(modelFile.getProject());
-
- input = createNewDiagramEditorInput();
-
- } else if (input instanceof DiagramEditorInput) {
- getModelPathFromInput((DiagramEditorInput) input);
- loadPreferences(modelFile.getProject());
-
- // This was incorrectly constructed input, we ditch the old one and make a new and clean one instead
- input = createNewDiagramEditorInput();
- }
- } catch (CoreException e) {
- Activator.showErrorWithLogging(e);
- }
-
- // add a listener so we get notified if the workbench is shutting down.
- // in this case we don't want to delete the temp file!
- addWorkbenchListener();
-
- super.init(site, input);
- }
-
- public Bpmn2Preferences getPreferences() {
- if (preferences==null) {
- assert(modelFile!=null);
- IProject project = modelFile.getProject();
- loadPreferences(project);
- }
- return preferences;
- }
-
- private void loadPreferences(IProject project) {
- preferences = new Bpmn2Preferences(project);
- preferences.load();
- }
-
- /**
- * ID for tabbed property sheets.
- *
- * @return the contributor id
- */
- @Override
- public String getContributorId() {
- return CONTRIBUTOR_ID;
- }
-
- public TargetRuntime getTargetRuntime() {
- if (targetRuntime==null)
- targetRuntime = getPreferences().getRuntime(modelFile);
- return targetRuntime;
- }
-
- private void getModelPathFromInput(DiagramEditorInput input) {
- URI uri = input.getDiagram().eResource().getURI();
- String uriString = uri.trimFragment().toPlatformString(true);
- modelFile = BPMN2DiagramCreator.getModelFile(new Path(uriString));
- }
-
- /**
- * Beware, creates a new input and changes this editor!
- */
- private IEditorInput createNewDiagramEditorInput() throws CoreException {
- IPath fullPath = modelFile.getFullPath();
- modelUri = URI.createPlatformResourceURI(fullPath.toString(), true);
-
- IFolder folder = BPMN2DiagramCreator.getTempFolder(fullPath);
- diagramFile = BPMN2DiagramCreator.getTempFile(fullPath,folder);
-
- // Create new temporary diagram file
- BPMN2DiagramCreator creator = new BPMN2DiagramCreator();
- creator.setDiagramFile(diagramFile);
-
- IEditorInput input = creator.createDiagram(false);
- diagramUri = creator.getUri();
-
- return input;
- }
-
- @Override
- public void doSave(IProgressMonitor monitor) {
- modelHandler.save();
- ((BasicCommandStack) getEditingDomain().getCommandStack()).saveIsDone();
- }
-
- @Override
- protected void setInput(IEditorInput input) {
- super.setInput(input);
-
- // Hook a transaction exception handler so we can get diagnostics about EMF validation errors.
- getEditingDomainListener();
-
- BasicCommandStack basicCommandStack = (BasicCommandStack) getEditingDomain().getCommandStack();
-
- if (input instanceof DiagramEditorInput) {
- ResourceSet resourceSet = getEditingDomain().getResourceSet();
- getTargetRuntime().setResourceSet(resourceSet);
-
- Bpmn2ResourceImpl bpmnResource = (Bpmn2ResourceImpl) resourceSet.createResource(modelUri,
- Bpmn2ModelerResourceImpl.BPMN2_CONTENT_TYPE_ID);
-
- resourceSet.setURIConverter(new ProxyURIConverterImplExtension());
-
- modelHandler = ModelHandlerLocator.createModelHandler(modelUri, bpmnResource);
- ModelHandlerLocator.put(diagramUri, modelHandler);
-
- try {
- if (modelFile.exists()) {
- bpmnResource.load(null);
- } else {
- doSave(null);
- }
- } catch (IOException e) {
- Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e);
- ErrorUtils.showErrorWithLogging(status);
- }
- basicCommandStack.execute(new RecordingCommand(getEditingDomain()) {
-
- @Override
- protected void doExecute() {
- importDiagram();
- }
- });
- }
- basicCommandStack.saveIsDone();
- }
-
- private void importDiagram() {
- DIImport di = new DIImport();
- di.setDiagram(getDiagramTypeProvider().getDiagram());
- di.setDomain(getEditingDomain());
- di.setModelHandler(modelHandler);
- di.setFeatureProvider(getDiagramTypeProvider().getFeatureProvider());
- di.generateFromDI();
- }
-
- private void addWorkbenchListener() {
- if (workbenchListener==null) {
- workbenchListener = new IWorkbenchListener() {
- @Override
- public boolean preShutdown(IWorkbench workbench, boolean forced) {
- workbenchShutdown = true;
- return true;
- }
-
- @Override
- public void postShutdown(IWorkbench workbench) {
- }
-
- };
- PlatformUI.getWorkbench().addWorkbenchListener(workbenchListener);
- }
- }
-
- private void removeWorkbenchListener()
- {
- if (workbenchListener!=null) {
- PlatformUI.getWorkbench().removeWorkbenchListener(workbenchListener);
- workbenchListener = null;
- }
- }
-
- public BPMN2EditingDomainListener getEditingDomainListener() {
- if (editingDomainListener==null) {
- TransactionalEditingDomainImpl editingDomain = (TransactionalEditingDomainImpl)getEditingDomain();
- if (editingDomain==null) {
- return null;
- }
- editingDomainListener = new BPMN2EditingDomainListener(this);
-
- Lifecycle domainLifeCycle = (Lifecycle) editingDomain.getAdapter(Lifecycle.class);
- domainLifeCycle.addTransactionalEditingDomainListener(editingDomainListener);
- }
- return editingDomainListener;
- }
-
- public BasicDiagnostic getDiagnostics() {
- return getEditingDomainListener().getDiagnostics();
- }
-
- public void showErrorMessage(String msg) {
- IWorkbench wb = PlatformUI.getWorkbench();
- IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
- IWorkbenchPage page = win.getActivePage();
- IWorkbenchPart part = page.getActivePart();
- IWorkbenchPartSite site = part.getSite();
- IViewSite vSite = ( IViewSite ) site;
- IActionBars actionBars = vSite.getActionBars();
-
- if( actionBars == null )
- return;
-
- IStatusLineManager statusLineManager = actionBars.getStatusLineManager();
- if( statusLineManager == null )
- return;
-
- statusLineManager.setErrorMessage(msg);
- statusLineManager.markDirty();
- statusLineManager.update(true);
- }
-
- @Override
- public void dispose() {
- // clear ID mapping tables if no more instances of editor are active
- int instances = 0;
- IWorkbenchPage[] pages = getEditorSite().getWorkbenchWindow().getPages();
- for (IWorkbenchPage p : pages) {
- IEditorReference[] refs = p.getEditorReferences();
- instances += refs.length;
- }
- ModelUtil.clearIDs(modelHandler.getResource(), instances==0);
- super.dispose();
- ModelHandlerLocator.releaseModel(modelUri);
- // get rid of temp files and folders, but only if the workbench is being shut down.
- // when the workbench is restarted, we need to have those temp files around!
- if (!workbenchShutdown)
- BPMN2DiagramCreator.dispose(diagramFile);
- removeWorkbenchListener();
- getPreferences().dispose();
- }
-
- public IFile getModelFile() {
- return modelFile;
- }
-}
+/*******************************************************************************
+ * 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 Innar Made
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.ui.editor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.eclipse.bpmn2.modeler.core.ModelHandler;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.ProxyURIConverterImplExtension;
+import org.eclipse.bpmn2.modeler.core.di.DIImport;
+import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceImpl;
+import org.eclipse.bpmn2.modeler.core.preferences.Bpmn2Preferences;
+import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.bpmn2.modeler.ui.Activator;
+import org.eclipse.bpmn2.modeler.ui.util.ErrorUtils;
+import org.eclipse.bpmn2.modeler.ui.wizards.BPMN2DiagramCreator;
+import org.eclipse.bpmn2.util.Bpmn2ResourceImpl;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.command.BasicCommandStack;
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain.Lifecycle;
+import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.graphiti.ui.editor.DiagramEditorInput;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchListener;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ *
+ */
+@SuppressWarnings("restriction")
+public class BPMN2Editor extends DiagramEditor {
+
+ public static final String EDITOR_ID = "org.eclipse.bpmn2.modeler.ui.bpmn2editor";
+ public static final String CONTRIBUTOR_ID = "org.eclipse.bpmn2.modeler.ui.PropertyContributor";
+
+ private ModelHandler modelHandler;
+ private URI modelUri;
+ private URI diagramUri;
+
+ private IFile modelFile;
+ private IFile diagramFile;
+
+ private IWorkbenchListener workbenchListener;
+ private boolean workbenchShutdown = false;
+
+ private BPMN2EditingDomainListener editingDomainListener;
+
+ private Bpmn2Preferences preferences;
+ private TargetRuntime targetRuntime;
+
+ @Override
+ public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+
+ try {
+ if (input instanceof IFileEditorInput) {
+ modelFile = ((IFileEditorInput) input).getFile();
+ loadPreferences(modelFile.getProject());
+
+ input = createNewDiagramEditorInput();
+
+ } else if (input instanceof DiagramEditorInput) {
+ getModelPathFromInput((DiagramEditorInput) input);
+ loadPreferences(modelFile.getProject());
+
+ // This was incorrectly constructed input, we ditch the old one and make a new and clean one instead
+ input = createNewDiagramEditorInput();
+ }
+ } catch (CoreException e) {
+ Activator.showErrorWithLogging(e);
+ }
+
+ // add a listener so we get notified if the workbench is shutting down.
+ // in this case we don't want to delete the temp file!
+ addWorkbenchListener();
+
+ super.init(site, input);
+ }
+
+ public Bpmn2Preferences getPreferences() {
+ if (preferences==null) {
+ assert(modelFile!=null);
+ IProject project = modelFile.getProject();
+ loadPreferences(project);
+ }
+ return preferences;
+ }
+
+ private void loadPreferences(IProject project) {
+ preferences = new Bpmn2Preferences(project);
+ preferences.load();
+ }
+
+ /**
+ * ID for tabbed property sheets.
+ *
+ * @return the contributor id
+ */
+ @Override
+ public String getContributorId() {
+ return CONTRIBUTOR_ID;
+ }
+
+ public TargetRuntime getTargetRuntime() {
+ if (targetRuntime==null)
+ targetRuntime = getPreferences().getRuntime(modelFile);
+ return targetRuntime;
+ }
+
+ private void getModelPathFromInput(DiagramEditorInput input) {
+ URI uri = input.getDiagram().eResource().getURI();
+ String uriString = uri.trimFragment().toPlatformString(true);
+ modelFile = BPMN2DiagramCreator.getModelFile(new Path(uriString));
+ }
+
+ /**
+ * Beware, creates a new input and changes this editor!
+ */
+ private IEditorInput createNewDiagramEditorInput() throws CoreException {
+ IPath fullPath = modelFile.getFullPath();
+ modelUri = URI.createPlatformResourceURI(fullPath.toString(), true);
+
+ IFolder folder = BPMN2DiagramCreator.getTempFolder(fullPath);
+ diagramFile = BPMN2DiagramCreator.getTempFile(fullPath,folder);
+
+ // Create new temporary diagram file
+ BPMN2DiagramCreator creator = new BPMN2DiagramCreator();
+ creator.setDiagramFile(diagramFile);
+
+ IEditorInput input = creator.createDiagram(false);
+ diagramUri = creator.getUri();
+
+ return input;
+ }
+
+ @Override
+ public void doSave(IProgressMonitor monitor) {
+ modelHandler.save();
+ ((BasicCommandStack) getEditingDomain().getCommandStack()).saveIsDone();
+ }
+
+ @Override
+ protected void setInput(IEditorInput input) {
+ super.setInput(input);
+
+ // Hook a transaction exception handler so we can get diagnostics about EMF validation errors.
+ getEditingDomainListener();
+
+ BasicCommandStack basicCommandStack = (BasicCommandStack) getEditingDomain().getCommandStack();
+
+ if (input instanceof DiagramEditorInput) {
+ ResourceSet resourceSet = getEditingDomain().getResourceSet();
+ getTargetRuntime().setResourceSet(resourceSet);
+
+ Bpmn2ResourceImpl bpmnResource = (Bpmn2ResourceImpl) resourceSet.createResource(modelUri,
+ Bpmn2ModelerResourceImpl.BPMN2_CONTENT_TYPE_ID);
+
+ resourceSet.setURIConverter(new ProxyURIConverterImplExtension());
+
+ modelHandler = ModelHandlerLocator.createModelHandler(modelUri, bpmnResource);
+ ModelHandlerLocator.put(diagramUri, modelHandler);
+
+ try {
+ if (modelFile.exists()) {
+ bpmnResource.load(null);
+ } else {
+ doSave(null);
+ }
+ } catch (IOException e) {
+ Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e);
+ ErrorUtils.showErrorWithLogging(status);
+ }
+ basicCommandStack.execute(new RecordingCommand(getEditingDomain()) {
+
+ @Override
+ protected void doExecute() {
+ importDiagram();
+ }
+ });
+ }
+ basicCommandStack.saveIsDone();
+ }
+
+ private void importDiagram() {
+ // make sure this guy is active, otherwise it's not selectable
+ getDiagramTypeProvider().getDiagram().setActive(true);
+
+ DIImport di = new DIImport();
+ di.setDiagram(getDiagramTypeProvider().getDiagram());
+ di.setDomain(getEditingDomain());
+ di.setModelHandler(modelHandler);
+ di.setFeatureProvider(getDiagramTypeProvider().getFeatureProvider());
+ di.generateFromDI();
+ }
+
+ @Override
+ protected PictogramElement[] getPictogramElementsForSelection() {
+ // filter out invisible elements when setting selection
+ ArrayList<PictogramElement> visibleList = new ArrayList<PictogramElement>();
+ PictogramElement[] pictogramElements = getSelectedPictogramElements();
+ for (PictogramElement pe : pictogramElements) {
+ if (pe.isVisible())
+ visibleList.add(pe);
+ }
+ return visibleList.toArray(new PictogramElement[visibleList.size()]);
+ }
+
+ private void addWorkbenchListener() {
+ if (workbenchListener==null) {
+ workbenchListener = new IWorkbenchListener() {
+ @Override
+ public boolean preShutdown(IWorkbench workbench, boolean forced) {
+ workbenchShutdown = true;
+ return true;
+ }
+
+ @Override
+ public void postShutdown(IWorkbench workbench) {
+ }
+
+ };
+ PlatformUI.getWorkbench().addWorkbenchListener(workbenchListener);
+ }
+ }
+
+ private void removeWorkbenchListener()
+ {
+ if (workbenchListener!=null) {
+ PlatformUI.getWorkbench().removeWorkbenchListener(workbenchListener);
+ workbenchListener = null;
+ }
+ }
+
+ public BPMN2EditingDomainListener getEditingDomainListener() {
+ if (editingDomainListener==null) {
+ TransactionalEditingDomainImpl editingDomain = (TransactionalEditingDomainImpl)getEditingDomain();
+ if (editingDomain==null) {
+ return null;
+ }
+ editingDomainListener = new BPMN2EditingDomainListener(this);
+
+ Lifecycle domainLifeCycle = (Lifecycle) editingDomain.getAdapter(Lifecycle.class);
+ domainLifeCycle.addTransactionalEditingDomainListener(editingDomainListener);
+ }
+ return editingDomainListener;
+ }
+
+ public BasicDiagnostic getDiagnostics() {
+ return getEditingDomainListener().getDiagnostics();
+ }
+
+ public void showErrorMessage(String msg) {
+ IWorkbench wb = PlatformUI.getWorkbench();
+ IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
+ IWorkbenchPage page = win.getActivePage();
+ IWorkbenchPart part = page.getActivePart();
+ IWorkbenchPartSite site = part.getSite();
+ IViewSite vSite = ( IViewSite ) site;
+ IActionBars actionBars = vSite.getActionBars();
+
+ if( actionBars == null )
+ return;
+
+ IStatusLineManager statusLineManager = actionBars.getStatusLineManager();
+ if( statusLineManager == null )
+ return;
+
+ statusLineManager.setErrorMessage(msg);
+ statusLineManager.markDirty();
+ statusLineManager.update(true);
+ }
+
+ @Override
+ public void dispose() {
+ // clear ID mapping tables if no more instances of editor are active
+ int instances = 0;
+ IWorkbenchPage[] pages = getEditorSite().getWorkbenchWindow().getPages();
+ for (IWorkbenchPage p : pages) {
+ IEditorReference[] refs = p.getEditorReferences();
+ instances += refs.length;
+ }
+ ModelUtil.clearIDs(modelHandler.getResource(), instances==0);
+ super.dispose();
+ ModelHandlerLocator.releaseModel(modelUri);
+ // get rid of temp files and folders, but only if the workbench is being shut down.
+ // when the workbench is restarted, we need to have those temp files around!
+ if (!workbenchShutdown)
+ BPMN2DiagramCreator.dispose(diagramFile);
+ removeWorkbenchListener();
+ getPreferences().dispose();
+ }
+
+ public IFile getModelFile() {
+ return modelFile;
+ }
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractSubProcessFeatureContainer.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractSubProcessFeatureContainer.java
index 0851e0d..cca5596 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractSubProcessFeatureContainer.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/AbstractSubProcessFeatureContainer.java
@@ -1,49 +1,55 @@
-/*******************************************************************************
- * 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 Innar Made
- ******************************************************************************/
-package org.eclipse.bpmn2.modeler.ui.features.activity.subprocess;
-
-import org.eclipse.bpmn2.BaseElement;
-import org.eclipse.bpmn2.modeler.core.features.AbstractBaseElementUpdateFeature;
-import org.eclipse.bpmn2.modeler.core.features.MultiUpdateFeature;
-import org.eclipse.bpmn2.modeler.ui.features.activity.AbstractActivityFeatureContainer;
-import org.eclipse.graphiti.features.IDirectEditingFeature;
-import org.eclipse.graphiti.features.IFeatureProvider;
-import org.eclipse.graphiti.features.ILayoutFeature;
-import org.eclipse.graphiti.features.context.IUpdateContext;
-
-public abstract class AbstractSubProcessFeatureContainer extends AbstractActivityFeatureContainer {
-
- @Override
- public IDirectEditingFeature getDirectEditingFeature(IFeatureProvider fp) {
- return null;
- }
-
- @Override
- public ILayoutFeature getLayoutFeature(IFeatureProvider fp) {
- return new SubProcessLayoutFeature(fp);
- }
-
- @Override
- public MultiUpdateFeature getUpdateFeature(IFeatureProvider fp) {
- MultiUpdateFeature multiUpdate = super.getUpdateFeature(fp);
- AbstractBaseElementUpdateFeature nameUpdateFeature = new AbstractBaseElementUpdateFeature(fp) {
- @Override
- public boolean canUpdate(IUpdateContext context) {
- Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
- return bo != null && bo instanceof BaseElement && canApplyTo((BaseElement) bo);
- }
- };
- multiUpdate.addUpdateFeature(nameUpdateFeature);
- return multiUpdate;
- }
+/*******************************************************************************
+ * 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 Innar Made
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.ui.features.activity.subprocess;
+
+import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.modeler.core.features.AbstractBaseElementUpdateFeature;
+import org.eclipse.bpmn2.modeler.core.features.MultiUpdateFeature;
+import org.eclipse.bpmn2.modeler.ui.features.activity.AbstractActivityFeatureContainer;
+import org.eclipse.graphiti.features.IDirectEditingFeature;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.ILayoutFeature;
+import org.eclipse.graphiti.features.IResizeShapeFeature;
+import org.eclipse.graphiti.features.context.IUpdateContext;
+
+public abstract class AbstractSubProcessFeatureContainer extends AbstractActivityFeatureContainer {
+
+ @Override
+ public IDirectEditingFeature getDirectEditingFeature(IFeatureProvider fp) {
+ return null;
+ }
+
+ @Override
+ public ILayoutFeature getLayoutFeature(IFeatureProvider fp) {
+ return new SubProcessLayoutFeature(fp);
+ }
+
+ @Override
+ public MultiUpdateFeature getUpdateFeature(IFeatureProvider fp) {
+ MultiUpdateFeature multiUpdate = super.getUpdateFeature(fp);
+ AbstractBaseElementUpdateFeature nameUpdateFeature = new AbstractBaseElementUpdateFeature(fp) {
+ @Override
+ public boolean canUpdate(IUpdateContext context) {
+ Object bo = getBusinessObjectForPictogramElement(context.getPictogramElement());
+ return bo != null && bo instanceof BaseElement && canApplyTo((BaseElement) bo);
+ }
+ };
+ multiUpdate.addUpdateFeature(nameUpdateFeature);
+ return multiUpdate;
+ }
+
+ @Override
+ public IResizeShapeFeature getResizeFeature(IFeatureProvider fp) {
+ return new SubProcessResizeFeature(fp);
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessCollapseFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessCollapseFeature.java
new file mode 100644
index 0000000..aef1fc4
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessCollapseFeature.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * 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 org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.utils.GraphicsUtil;
+import org.eclipse.bpmn2.modeler.ui.ImageProvider;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.IResizeShapeFeature;
+import org.eclipse.graphiti.features.context.IContext;
+import org.eclipse.graphiti.features.context.ICustomContext;
+import org.eclipse.graphiti.features.context.impl.ResizeShapeContext;
+import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+
+public class SubProcessCollapseFeature extends AbstractCustomFeature {
+
+ public SubProcessCollapseFeature(IFeatureProvider fp) {
+ super(fp);
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public String getName() {
+ return "Collapse"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getDescription() {
+
+ return "Collapse the Sub-Process and hide contents"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getImageId() {
+ return ImageProvider.IMG_16_COLLAPSE;
+ }
+
+ @Override
+ public boolean isAvailable(IContext context) {
+ return true;
+ }
+
+ @Override
+ public boolean canExecute(ICustomContext context) {
+ boolean ret = false;
+ PictogramElement[] pes = context.getPictogramElements();
+ if (pes != null && pes.length == 1) {
+ Object bo = getBusinessObjectForPictogramElement(pes[0]);
+ if (bo instanceof SubProcess) {
+ try {
+ BPMNShape bpmnShape = (BPMNShape) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
+ getDiagram(), (SubProcess)bo);
+ if (bpmnShape.isIsExpanded())
+ ret = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return ret;
+ }
+
+ @Override
+ public void execute(ICustomContext context) {
+ PictogramElement[] pes = context.getPictogramElements();
+ if (pes != null && pes.length == 1) {
+ PictogramElement pe0 = pes[0];
+ Object bo = getBusinessObjectForPictogramElement(pe0);
+ if (pe0 instanceof ContainerShape && bo instanceof SubProcess) {
+ ContainerShape containerShape = (ContainerShape)pe0;
+ SubProcess subProcess = (SubProcess)bo;
+ try {
+ BPMNShape bpmnShape = (BPMNShape) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
+ getDiagram(), subProcess);
+ if (bpmnShape.isIsExpanded()) {
+
+ // SubProcess is collapsed - resize to standard task size
+ // NOTE: children tasks will be set not-visible in SubProcessLayoutFeature
+
+ bpmnShape.setIsExpanded(false);
+
+ GraphicsAlgorithm ga = containerShape.getGraphicsAlgorithm();
+ ResizeShapeContext resizeContext = new ResizeShapeContext(containerShape);
+ IResizeShapeFeature resizeFeature = getFeatureProvider().getResizeShapeFeature(resizeContext);
+ int oldWidth = ga.getWidth();
+ int oldHeight = ga.getHeight();
+ int newWidth = GraphicsUtil.TASK_DEFAULT_WIDTH;
+ int newHeight = GraphicsUtil.TASK_DEFAULT_HEIGHT;
+ resizeContext.setX(ga.getX() + oldWidth/2 - newWidth/2);
+ resizeContext.setY(ga.getY() + oldHeight/2 - newHeight/2);
+ resizeContext.setWidth(newWidth);
+ resizeContext.setHeight(newHeight);
+ resizeFeature.resizeShape(resizeContext);
+
+ getDiagramEditor().selectPictogramElements(new PictogramElement[] {});
+ }
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessDrilldownFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessDrilldownFeature.java
deleted file mode 100644
index 952c499..0000000
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessDrilldownFeature.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*******************************************************************************
- * 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 Innar Made
- ******************************************************************************/
-package org.eclipse.bpmn2.modeler.ui.features.activity.subprocess;
-
-import java.util.Collection;
-
-import org.eclipse.bpmn2.SubProcess;
-import org.eclipse.graphiti.features.IFeatureProvider;
-import org.eclipse.graphiti.features.context.ICustomContext;
-import org.eclipse.graphiti.mm.pictograms.Diagram;
-import org.eclipse.graphiti.mm.pictograms.PictogramElement;
-import org.eclipse.graphiti.ui.features.AbstractDrillDownFeature;
-
-// NOT USED YET
-public class SubProcessDrilldownFeature extends AbstractDrillDownFeature {
-
- public SubProcessDrilldownFeature(IFeatureProvider fp) {
- super(fp);
- }
-
- @Override
- public String getName() {
- return "Open sub-process";
- }
-
- @Override
- public String getDescription() {
- return "Shows sub-process contents";
- }
-
- @Override
- public boolean canExecute(ICustomContext context) {
- PictogramElement[] elements = context.getPictogramElements();
- if(elements != null && elements.length == 1) {
- Object o = getBusinessObjectForPictogramElement(elements[0]);
- if( o instanceof SubProcess ) {
- return super.canExecute(context);
- }
- }
- return false;
- }
-
- @Override
- protected Collection<Diagram> getDiagrams() {
- return null;
- }
-}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessExpandFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessExpandFeature.java
new file mode 100644
index 0000000..f6285f4
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessExpandFeature.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * 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 org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.ui.ImageProvider;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.IResizeShapeFeature;
+import org.eclipse.graphiti.features.context.IContext;
+import org.eclipse.graphiti.features.context.ICustomContext;
+import org.eclipse.graphiti.features.context.impl.ResizeShapeContext;
+import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+
+// NOT USED YET
+public class SubProcessExpandFeature extends AbstractCustomFeature {
+
+ public SubProcessExpandFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public String getName() {
+ return "Expand";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Expand the Sub-Process and show contents";
+ }
+
+ @Override
+ public String getImageId() {
+ return ImageProvider.IMG_16_EXPAND;
+ }
+
+ @Override
+ public boolean isAvailable(IContext context) {
+ return true;
+ }
+
+ @Override
+ public boolean canExecute(ICustomContext context) {
+ boolean ret = false;
+ PictogramElement[] pes = context.getPictogramElements();
+ if (pes != null && pes.length == 1) {
+ Object bo = getBusinessObjectForPictogramElement(pes[0]);
+ if (bo instanceof SubProcess) {
+ try {
+ BPMNShape bpmnShape = (BPMNShape) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
+ getDiagram(), (SubProcess)bo);
+ if (!bpmnShape.isIsExpanded())
+ ret = true;
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ return ret;
+ }
+
+ @Override
+ public void execute(ICustomContext context) {
+ PictogramElement[] pes = context.getPictogramElements();
+ if (pes != null && pes.length == 1) {
+ PictogramElement pe0 = pes[0];
+ Object bo = getBusinessObjectForPictogramElement(pe0);
+ if (pe0 instanceof ContainerShape && bo instanceof SubProcess) {
+ ContainerShape containerShape = (ContainerShape)pe0;
+ SubProcess subProcess = (SubProcess)bo;
+ try {
+ BPMNShape bpmnShape = (BPMNShape) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
+ getDiagram(), subProcess);
+ if (!bpmnShape.isIsExpanded()) {
+
+ // SubProcess is collapsed - resize to minimum size such that all children are visible
+ // NOTE: children tasks will be set visible in SubProcessLayoutFeature
+
+ bpmnShape.setIsExpanded(true);
+
+ GraphicsAlgorithm ga = containerShape.getGraphicsAlgorithm();
+ ResizeShapeContext resizeContext = new ResizeShapeContext(containerShape);
+ IResizeShapeFeature resizeFeature = getFeatureProvider().getResizeShapeFeature(resizeContext);
+ int oldWidth = ga.getWidth();
+ int oldHeight = ga.getHeight();
+ SubProcessResizeFeature.SizeCalculator newSize = new SubProcessResizeFeature.SizeCalculator(containerShape);
+ int newWidth = newSize.getWidth();
+ int newHeight = newSize.getHeight();
+ resizeContext.setX(ga.getX() + oldWidth/2 - newWidth/2);
+ resizeContext.setY(ga.getY() + oldHeight/2 - newHeight/2);
+ resizeContext.setWidth(newWidth);
+ resizeContext.setHeight(newHeight);
+ resizeFeature.resizeShape(resizeContext);
+ }
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessFeatureContainer.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessFeatureContainer.java
index a235aa1..15e1142 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessFeatureContainer.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessFeatureContainer.java
@@ -1,71 +1,87 @@
-/*******************************************************************************
- * 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 Innar Made
- ******************************************************************************/
-package org.eclipse.bpmn2.modeler.ui.features.activity.subprocess;
-
-import org.eclipse.bpmn2.SubProcess;
-import org.eclipse.bpmn2.modeler.core.ModelHandler;
-import org.eclipse.bpmn2.modeler.core.features.MultiUpdateFeature;
-import org.eclipse.bpmn2.modeler.core.features.activity.subprocess.AbstractCreateSubProcess;
-import org.eclipse.bpmn2.modeler.ui.ImageProvider;
-import org.eclipse.graphiti.features.IAddFeature;
-import org.eclipse.graphiti.features.ICreateFeature;
-import org.eclipse.graphiti.features.IFeatureProvider;
-import org.eclipse.graphiti.features.context.ICreateContext;
-
-public class SubProcessFeatureContainer extends AbstractSubProcessFeatureContainer {
-
- public static final String TRIGGERED_BY_EVENT = "triggered-by-event-key";
-
- @Override
- public boolean canApplyTo(Object o) {
- return super.canApplyTo(o) && o instanceof SubProcess;
- }
-
- @Override
- public ICreateFeature getCreateFeature(IFeatureProvider fp) {
- return new CreateSubProcessFeature(fp);
- }
-
- @Override
- public IAddFeature getAddFeature(IFeatureProvider fp) {
- return new AddExpandedSubProcessFeature(fp);
- }
-
- @Override
- public MultiUpdateFeature getUpdateFeature(IFeatureProvider fp) {
- MultiUpdateFeature multiUpdate = super.getUpdateFeature(fp);
- UpdateSubProcessFeature updateSubProcessFeature = new UpdateSubProcessFeature(fp);
- multiUpdate.addUpdateFeature(updateSubProcessFeature);
- return multiUpdate;
- }
-
- public static class CreateSubProcessFeature extends AbstractCreateSubProcess {
-
- public CreateSubProcessFeature(IFeatureProvider fp) {
- super(fp, "Expanded Sub-Process", "Inner activity");
- }
-
- @Override
- protected SubProcess createFlowElement(ICreateContext context) {
- SubProcess subProcess = ModelHandler.FACTORY.createSubProcess();
- subProcess.setName("SubProcess");
- subProcess.setTriggeredByEvent(false);
- return subProcess;
- }
-
- @Override
- protected String getStencilImageId() {
- return ImageProvider.IMG_16_SUB_PROCESS;
- }
- }
+/*******************************************************************************
+ * 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 Innar Made
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.ui.features.activity.subprocess;
+
+import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.modeler.core.ModelHandler;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.features.MultiUpdateFeature;
+import org.eclipse.bpmn2.modeler.core.features.activity.subprocess.AbstractCreateSubProcess;
+import org.eclipse.bpmn2.modeler.ui.ImageProvider;
+import org.eclipse.graphiti.features.IAddFeature;
+import org.eclipse.graphiti.features.ICreateFeature;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.ICreateContext;
+
+public class SubProcessFeatureContainer extends AbstractSubProcessFeatureContainer {
+
+ public static final String TRIGGERED_BY_EVENT = "triggered-by-event-key";
+
+ @Override
+ public boolean canApplyTo(Object o) {
+ return super.canApplyTo(o) && o instanceof SubProcess;
+ }
+
+ @Override
+ public ICreateFeature getCreateFeature(IFeatureProvider fp) {
+ return new CreateSubProcessFeature(fp);
+ }
+
+ @Override
+ public IAddFeature getAddFeature(IFeatureProvider fp) {
+ return new AddExpandedSubProcessFeature(fp);
+ }
+
+ @Override
+ public MultiUpdateFeature getUpdateFeature(IFeatureProvider fp) {
+ MultiUpdateFeature multiUpdate = super.getUpdateFeature(fp);
+ UpdateSubProcessFeature updateSubProcessFeature = new UpdateSubProcessFeature(fp);
+ multiUpdate.addUpdateFeature(updateSubProcessFeature);
+ return multiUpdate;
+ }
+
+ public static class CreateSubProcessFeature extends AbstractCreateSubProcess {
+
+ public CreateSubProcessFeature(IFeatureProvider fp) {
+ super(fp, "Expanded Sub-Process", "Inner activity");
+ }
+
+ @Override
+ public Object[] create(ICreateContext context) {
+ Object[] elems = super.create(context);
+ try {
+ BPMNShape shape = (BPMNShape) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
+ getDiagram(), (SubProcess)elems[0]);
+ shape.setIsExpanded(true);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return elems;
+ }
+
+ @Override
+ protected SubProcess createFlowElement(ICreateContext context) {
+ SubProcess subProcess = ModelHandler.FACTORY.createSubProcess();
+ subProcess.setName("SubProcess");
+ subProcess.setTriggeredByEvent(false);
+ return subProcess;
+ }
+
+ @Override
+ protected String getStencilImageId() {
+ return ImageProvider.IMG_16_SUB_PROCESS;
+ }
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessLayoutFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessLayoutFeature.java
index f0ab21c..ce80836 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessLayoutFeature.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessLayoutFeature.java
@@ -13,9 +13,16 @@
package org.eclipse.bpmn2.modeler.ui.features.activity.subprocess;
import org.eclipse.bpmn2.Activity;
+import org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.features.BusinessObjectUtil;
import org.eclipse.bpmn2.modeler.core.features.activity.ActivityLayoutFeature;
+import org.eclipse.bpmn2.modeler.core.utils.FeatureSupport;
import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.IResizeShapeFeature;
import org.eclipse.graphiti.features.context.ILayoutContext;
+import org.eclipse.graphiti.features.context.impl.ResizeShapeContext;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.algorithms.Text;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
@@ -25,9 +32,6 @@
public class SubProcessLayoutFeature extends ActivityLayoutFeature {
- private final static int MARGIN = 2;
- private final static int NUMBER_OF_PARENT_ELEMENTS = 3;
-
public SubProcessLayoutFeature(IFeatureProvider fp) {
super(fp);
}
@@ -44,86 +48,59 @@
@Override
public boolean layout(ILayoutContext context) {
ContainerShape containerShape = (ContainerShape) context.getPictogramElement();
- GraphicsAlgorithm parentGa = containerShape.getGraphicsAlgorithm();
- int newWidth = parentGa.getWidth();
- int newHeight = parentGa.getHeight();
-
- int minX = Integer.MAX_VALUE;
- int minY = Integer.MAX_VALUE;
- int minWidth = 0;
- int minHeight = 0;
- int size = containerShape.getChildren().size();
- for (int i=NUMBER_OF_PARENT_ELEMENTS; i<size; ++i) {
- PictogramElement pe = containerShape.getChildren().get(i);
- GraphicsAlgorithm ga = pe.getGraphicsAlgorithm();
- if (ga!=null) {
- int x = ga.getX();
- int y = ga.getY();
- if (x < minX)
- minX = x;
- if (y < minY)
- minY = y;
- }
- }
- for (int i=NUMBER_OF_PARENT_ELEMENTS; i<size; ++i) {
- PictogramElement pe = containerShape.getChildren().get(i);
- GraphicsAlgorithm ga = pe.getGraphicsAlgorithm();
- if (ga!=null) {
- int w = ga.getX() - minX + ga.getWidth();
- int h = ga.getY() - minY + ga.getHeight();
- if (w > minWidth)
- minWidth = w;
- if (h > minHeight)
- minHeight = h;
- }
- }
-
- if (minX < MARGIN)
- minX = MARGIN;
- if (minY < MARGIN)
- minY = MARGIN;
- minWidth += 2 * MARGIN;
- minHeight += 2 * MARGIN;
-
- if (newWidth < minWidth) {
- parentGa.setWidth(minWidth);
- }
- if (newWidth < minX + minWidth) {
- int shift = minX + minWidth - newWidth;
- if (shift>minX-MARGIN) {
- shift = minX-MARGIN;
- }
- if (shift>0) {
- for (int i=NUMBER_OF_PARENT_ELEMENTS; i<size; ++i) {
- PictogramElement pe = containerShape.getChildren().get(i);
+ SubProcess subProcess = BusinessObjectUtil.getFirstElementOfType(containerShape, SubProcess.class);
+ try {
+ BPMNShape shape = (BPMNShape) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
+ getDiagram(), subProcess);
+
+ if (shape.isIsExpanded()) {
+
+ // SubProcess is expanded
+
+ boolean needResize = false;
+ GraphicsAlgorithm parentGa = containerShape.getGraphicsAlgorithm();
+
+ for (PictogramElement pe : FeatureSupport.getContainerChildren(containerShape)) {
GraphicsAlgorithm ga = pe.getGraphicsAlgorithm();
if (ga!=null) {
- int x = ga.getX() - shift;
- ga.setX(x);
+ if (ga.getX() < 0 || ga.getY() < 0) {
+ needResize = true;
+ break;
+ }
+ if (ga.getX() + ga.getWidth() > parentGa.getWidth()) {
+ needResize = true;
+ break;
+ }
+ if (ga.getY() + ga.getHeight() > parentGa.getHeight()) {
+ needResize = true;
+ break;
+ }
}
}
- }
- }
- if (newHeight < minHeight) {
- parentGa.setHeight(minHeight);
- }
- if (newHeight < minY + minHeight) {
- int shift = minY + minHeight - newHeight;
- if (shift>minY-MARGIN) {
- shift = minY-MARGIN;
- }
- if (shift>0) {
- for (int i=NUMBER_OF_PARENT_ELEMENTS; i<size; ++i) {
- PictogramElement pe = containerShape.getChildren().get(i);
- GraphicsAlgorithm ga = pe.getGraphicsAlgorithm();
- if (ga!=null) {
- int y = ga.getY() - shift;
- ga.setY(y);
- }
+ if (needResize) {
+ ResizeShapeContext resizeContext = new ResizeShapeContext(containerShape);
+ resizeContext.setX(parentGa.getX());
+ resizeContext.setY(parentGa.getY());
+ resizeContext.setWidth(parentGa.getWidth());
+ resizeContext.setHeight(parentGa.getHeight());
+ IResizeShapeFeature resizeFeature = getFeatureProvider().getResizeShapeFeature(resizeContext);
+ resizeFeature.resizeShape(resizeContext);
}
+
+ FeatureSupport.setContainerChildrenVisible(containerShape, true);
}
+ else {
+
+ // SubProcess is collapsed
+
+ FeatureSupport.setContainerChildrenVisible(containerShape, false);
+ }
+
+ } catch (Exception e) {
+ // It's OK, I've played a programmer before...
+ // e.printStackTrace();
}
-
+
return super.layout(context);
}
}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessResizeFeature.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessResizeFeature.java
new file mode 100644
index 0000000..6bce020
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/features/activity/subprocess/SubProcessResizeFeature.java
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * 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 org.eclipse.bpmn2.SubProcess;
+import org.eclipse.bpmn2.di.BPMNShape;
+import org.eclipse.bpmn2.modeler.core.ModelHandlerLocator;
+import org.eclipse.bpmn2.modeler.core.features.BusinessObjectUtil;
+import org.eclipse.bpmn2.modeler.core.features.DefaultBPMNResizeFeature;
+import org.eclipse.bpmn2.modeler.core.utils.FeatureSupport;
+import org.eclipse.bpmn2.modeler.core.utils.GraphicsUtil;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.IResizeShapeContext;
+import org.eclipse.graphiti.features.context.impl.ResizeShapeContext;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+import org.eclipse.graphiti.mm.pictograms.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.services.Graphiti;
+
+public class SubProcessResizeFeature extends DefaultBPMNResizeFeature {
+ public final static int MARGIN = 20;
+
+ public SubProcessResizeFeature(IFeatureProvider fp) {
+ super(fp);
+ }
+
+ @Override
+ public void resizeShape(IResizeShapeContext context) {
+
+ ResizeShapeContext resizeShapeContext = (ResizeShapeContext)context;
+
+ ContainerShape containerShape = (ContainerShape) context.getPictogramElement();
+ SubProcess subProcess = BusinessObjectUtil.getFirstElementOfType(containerShape, SubProcess.class);
+ try {
+ BPMNShape shape = (BPMNShape) ModelHandlerLocator.getModelHandler(getDiagram().eResource()).findDIElement(
+ getDiagram(), subProcess);
+
+ if (shape.isIsExpanded()) {
+
+ // SubProcess is expanded
+
+ GraphicsAlgorithm parentGa = containerShape.getGraphicsAlgorithm();
+ int newWidth = resizeShapeContext.getWidth();
+ int newHeight = resizeShapeContext.getHeight();
+ SizeCalculator sizeCalc = new SizeCalculator(containerShape);
+ int shiftX = sizeCalc.shiftX;
+ int shiftY = sizeCalc.shiftY;
+ int minWidth = sizeCalc.minWidth;
+ int minHeight = sizeCalc.minHeight;
+
+ if (shiftX < 0) {
+ for (PictogramElement pe : FeatureSupport.getContainerChildren(containerShape)) {
+ GraphicsAlgorithm childGa = pe.getGraphicsAlgorithm();
+ if (childGa!=null) {
+ int x = childGa.getX() - shiftX + MARGIN;
+ childGa.setX(x);
+ }
+ }
+ resizeShapeContext.setX(resizeShapeContext.getX() + shiftX - MARGIN);
+ shiftX = MARGIN;
+ }
+
+ if (shiftY < 0) {
+ for (PictogramElement pe : FeatureSupport.getContainerChildren(containerShape)) {
+ GraphicsAlgorithm childGa = pe.getGraphicsAlgorithm();
+ if (childGa!=null) {
+ int y = childGa.getY() - shiftY + MARGIN;
+ childGa.setY(y);
+ }
+ }
+ resizeShapeContext.setY(resizeShapeContext.getY() + shiftY - MARGIN);
+ shiftX = MARGIN;
+ }
+
+ if (shiftX < MARGIN)
+ shiftX = MARGIN;
+ if (shiftY < MARGIN)
+ shiftY = MARGIN;
+ minWidth += 2 * MARGIN;
+ minHeight += 2 * MARGIN;
+
+ if (newWidth < minWidth) {
+ parentGa.setWidth(minWidth);
+ }
+ if (newWidth < shiftX + minWidth) {
+ int shift = shiftX + minWidth - newWidth;
+ if (shift>shiftX-MARGIN) {
+ shift = shiftX-MARGIN;
+ }
+ if (shift>0) {
+ for (PictogramElement pe : FeatureSupport.getContainerChildren(containerShape)) {
+ GraphicsAlgorithm childGa = pe.getGraphicsAlgorithm();
+ if (childGa!=null) {
+ int x = childGa.getX() - shift;
+ childGa.setX(x);
+ }
+ }
+ }
+ }
+ if (newHeight < minHeight) {
+ parentGa.setHeight(minHeight);
+ }
+ if (newHeight < shiftY + minHeight) {
+ int shift = shiftY + minHeight - newHeight;
+ if (shift>shiftY-MARGIN) {
+ shift = shiftY-MARGIN;
+ }
+ if (shift>0) {
+ for (PictogramElement pe : FeatureSupport.getContainerChildren(containerShape)) {
+ GraphicsAlgorithm childGa = pe.getGraphicsAlgorithm();
+ if (childGa!=null) {
+ int y = childGa.getY() - shift;
+ childGa.setY(y);
+ }
+ }
+ }
+ }
+
+ if (resizeShapeContext.getWidth() < minWidth)
+ resizeShapeContext.setWidth(minWidth);
+ if (resizeShapeContext.getHeight() < minHeight)
+ resizeShapeContext.setHeight(minHeight);
+ }
+ else {
+
+ // SubProcess is collapsed
+
+ for (PictogramElement pe : FeatureSupport.getContainerDecorators(containerShape)) {
+ GraphicsAlgorithm childGa = pe.getGraphicsAlgorithm();
+ if (childGa!=null) {
+ childGa.setWidth(GraphicsUtil.TASK_DEFAULT_WIDTH);
+ childGa.setHeight(GraphicsUtil.TASK_DEFAULT_HEIGHT);
+ }
+ }
+
+ resizeShapeContext.setWidth(GraphicsUtil.TASK_DEFAULT_WIDTH);
+ resizeShapeContext.setHeight(GraphicsUtil.TASK_DEFAULT_HEIGHT);
+ }
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ Graphiti.getPeService().sendToFront(containerShape);
+
+ super.resizeShape(context);
+ }
+
+ public static class SizeCalculator {
+
+ int shiftX;
+ int shiftY;
+ int minWidth;
+ int minHeight;
+ ContainerShape containerShape;
+
+ public SizeCalculator(ContainerShape containerShape) {
+ setShape(containerShape);
+ }
+
+ public void setShape(ContainerShape containerShape) {
+ this.containerShape = containerShape;
+ calculate();
+ }
+
+ private void calculate() {
+ int minX = Integer.MAX_VALUE;
+ int minY = Integer.MAX_VALUE;
+ minWidth = 0;
+ minHeight = 0;
+
+ int size = containerShape.getChildren().size();
+ for (PictogramElement pe : FeatureSupport.getContainerChildren(containerShape)) {
+ GraphicsAlgorithm ga = pe.getGraphicsAlgorithm();
+ if (ga!=null) {
+ int x = ga.getX();
+ int y = ga.getY();
+ if (x < minX)
+ minX = x;
+ if (y < minY)
+ minY = y;
+ }
+ }
+
+ shiftX = minX;
+ shiftY = minY;
+
+ for (PictogramElement pe : FeatureSupport.getContainerChildren(containerShape)) {
+ GraphicsAlgorithm ga = pe.getGraphicsAlgorithm();
+ if (ga!=null) {
+ int w = ga.getX() - minX + ga.getWidth();
+ int h = ga.getY() - minY + ga.getHeight();
+ if (w > minWidth)
+ minWidth = w;
+ if (h > minHeight)
+ minHeight = h;
+ }
+ }
+ if (minWidth<=0)
+ minWidth = GraphicsUtil.SUB_PROCEESS_DEFAULT_WIDTH;
+ if (minHeight<=0)
+ minHeight = GraphicsUtil.SUB_PROCESS_DEFAULT_HEIGHT;
+ }
+
+ public int getShiftX() {
+ return shiftX;
+ }
+
+ public int getShiftY() {
+ return shiftY;
+ }
+
+ public int getWidth() {
+ return minWidth;
+ }
+
+ public int getHeight() {
+ return minHeight;
+ }
+ }
+}