Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.etrice.ui.layout/src/org')
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorDiagramLayoutManager.java150
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java526
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceLayoutCommand.java167
-rw-r--r--plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureDiagramLayoutmanager.java134
4 files changed, 977 insertions, 0 deletions
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorDiagramLayoutManager.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorDiagramLayoutManager.java
new file mode 100644
index 000000000..63329e1b2
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/BehaviorDiagramLayoutManager.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * This program and the accompanying materials
+ * are 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:
+ * Jayant Gupta (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.layout;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.etrice.core.room.StateGraph;
+import org.eclipse.etrice.core.room.TrPoint;
+import org.eclipse.etrice.ui.behavior.editor.BehaviorEditor;
+import org.eclipse.etrice.ui.behavior.support.StateSupport;
+import org.eclipse.graphiti.mm.pictograms.Anchor;
+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.ui.internal.parts.IPictogramElementEditPart;
+
+import de.cau.cs.kieler.core.kgraph.KNode;
+import de.cau.cs.kieler.kiml.LayoutContext;
+import de.cau.cs.kieler.kiml.config.VolatileLayoutConfig;
+import de.cau.cs.kieler.kiml.graphiti.KimlGraphitiUtil;
+import de.cau.cs.kieler.kiml.options.LayoutOptions;
+import de.cau.cs.kieler.kiml.ui.diagram.LayoutMapping;
+import de.cau.cs.kieler.kiml.util.KimlUtil;
+
+/**
+ * Layout Manager implementation for eTrice Structure Editor.
+ *
+ * @author jayant
+ */
+@SuppressWarnings("restriction")
+public class BehaviorDiagramLayoutManager extends ETriceDiagramLayoutManager {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ public boolean supports(final Object object) {
+
+ return object instanceof BehaviorEditor
+ || object instanceof IPictogramElementEditPart
+ || object instanceof PictogramElement;
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected void buildLayoutGraphForBoundingBox(
+ LayoutMapping<PictogramElement> mapping, Diagram diagram,
+ KNode diagramNode, boolean onlyVisible) {
+
+ if (onlyVisible) {
+ for (Shape boundingBox : ((Diagram) diagram).getChildren()) {
+ if (boundingBox.isVisible()) {
+ buildAllLevels(mapping, boundingBox, diagramNode);
+ break;
+ }
+ }
+ } else {
+ // This happens when the user requests Layout of the whole hierarchy
+ // of Diagrams in the behavior editor
+ // FIXME need to be corrected.
+ for (Shape boundingBox : ((Diagram) diagram).getChildren())
+ buildAllLevels(mapping, boundingBox, diagramNode);
+ }
+
+ }
+
+ /** the fixed minimal height of nodes. */
+ public static final float MIN_HEIGHT = StateSupport.DEFAULT_SIZE_Y;
+ /** the fixed minimal width of shapes. */
+ public static final float MIN_WIDHT = StateSupport.DEFAULT_SIZE_X;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ protected KNode createNode(final LayoutMapping<PictogramElement> mapping,
+ final KNode parentNode, final Shape shape) {
+ KNode node = KimlUtil.createInitializedNode();
+ node.setParent(parentNode);
+
+ setCurrentPositionAndSize(mapping, parentNode, node, shape);
+
+ VolatileLayoutConfig staticConfig = mapping
+ .getProperty(KimlGraphitiUtil.STATIC_CONFIG);
+ // FIXME find a way to specify the minimal size dynamically
+
+ staticConfig.setValue(LayoutOptions.MIN_WIDTH, node,
+ LayoutContext.GRAPH_ELEM, MIN_WIDHT);
+ staticConfig.setValue(LayoutOptions.MIN_HEIGHT, node,
+ LayoutContext.GRAPH_ELEM, MIN_HEIGHT);
+
+ mapping.getGraphMap().put(node, shape);
+
+ // gather all connections directly connected to the Node (not the
+ // connections connected via ports). These only exist in the behavior
+ // editor.
+ for (Anchor anchor : shape.getAnchors()) {
+ mapping.getProperty(KimlGraphitiUtil.CONNECTIONS).addAll(
+ anchor.getOutgoingConnections());
+ }
+
+ return node;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected boolean isPort(Shape shape) {
+ EObject modelObject = shape.getLink().getBusinessObjects().get(0);
+ if (modelObject instanceof TrPoint)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected boolean isTopLevelBoundingBox(Shape shape) {
+ EObject modelObject = shape.getLink().getBusinessObjects().get(0);
+ if (modelObject instanceof StateGraph)
+ return true;
+
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java
new file mode 100644
index 000000000..a5a83b706
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceDiagramLayoutManager.java
@@ -0,0 +1,526 @@
+/*******************************************************************************
+ * This program and the accompanying materials
+ * are 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:
+ * Jayant Gupta (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.layout;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.etrice.ui.common.editor.RoomDiagramEditor;
+import org.eclipse.gef.EditPart;
+import org.eclipse.graphiti.mm.algorithms.AbstractText;
+import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
+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.FreeFormConnection;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.mm.pictograms.Shape;
+import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.graphiti.ui.internal.parts.IPictogramElementEditPart;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+
+import de.cau.cs.kieler.core.kgraph.KGraphElement;
+import de.cau.cs.kieler.core.kgraph.KLabeledGraphElement;
+import de.cau.cs.kieler.core.kgraph.KNode;
+import de.cau.cs.kieler.core.kgraph.KPort;
+import de.cau.cs.kieler.kiml.LayoutContext;
+import de.cau.cs.kieler.kiml.config.VolatileLayoutConfig;
+import de.cau.cs.kieler.kiml.graphiti.GefDiagramLayoutManager;
+import de.cau.cs.kieler.kiml.graphiti.GraphitiLayoutCommand;
+import de.cau.cs.kieler.kiml.graphiti.GraphitiLayoutConfig;
+import de.cau.cs.kieler.kiml.graphiti.KimlGraphitiUtil;
+import de.cau.cs.kieler.kiml.klayoutdata.KInsets;
+import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout;
+import de.cau.cs.kieler.kiml.klayoutdata.impl.KShapeLayoutImpl;
+import de.cau.cs.kieler.kiml.ui.diagram.LayoutMapping;
+import de.cau.cs.kieler.kiml.util.KimlUtil;
+
+/**
+ * The abstract class to support the creation of eTrice
+ * {@link BehaviorDiagramLayoutManager } and
+ * {@link StructureDiagramLayoutmanager}
+ *
+ * @author jayant
+ */
+@SuppressWarnings("restriction")
+public abstract class ETriceDiagramLayoutManager extends
+ GefDiagramLayoutManager<PictogramElement> {
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract boolean supports(Object object);
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public Object getAdapter(final Object object, final Class adapterType) {
+ if (adapterType.isAssignableFrom(GraphitiLayoutConfig.class)) {
+ return layoutConfig;
+ } else if (adapterType
+ .isAssignableFrom(IPictogramElementEditPart.class)) {
+ if (object instanceof IPictogramElementEditPart) {
+ return object;
+ } else if (object instanceof DiagramEditor) {
+ return ((DiagramEditor) object).getGraphicalViewer()
+ .getContents();
+ }
+ } else if (adapterType.isAssignableFrom(EObject.class)) {
+ if (object instanceof IPictogramElementEditPart) {
+ PictogramElement pe = ((IPictogramElementEditPart) object)
+ .getPictogramElement();
+ if (pe.getLink() != null) {
+ List<EObject> businessObjects = pe.getLink()
+ .getBusinessObjects();
+ if (!businessObjects.isEmpty()) {
+ return businessObjects.get(0);
+ }
+ }
+ } else if (object instanceof PictogramElement) {
+ PictogramElement pe = (PictogramElement) object;
+ if (pe.getLink() != null) {
+ List<EObject> businessObjects = pe.getLink()
+ .getBusinessObjects();
+ if (!businessObjects.isEmpty()) {
+ return businessObjects.get(0);
+ }
+ }
+ }
+ } else if (adapterType.isAssignableFrom(PictogramElement.class)) {
+ if (object instanceof PictogramElement) {
+ return object;
+ } else if (object instanceof IPictogramElementEditPart) {
+ return ((IPictogramElementEditPart) object)
+ .getPictogramElement();
+ } else if (object instanceof DiagramEditor) {
+ EditPart contents = ((DiagramEditor) object)
+ .getGraphicalViewer().getContents();
+ if (contents instanceof IPictogramElementEditPart) {
+ return ((IPictogramElementEditPart) contents)
+ .getPictogramElement();
+ }
+ }
+ } else if (adapterType
+ .isAssignableFrom(TransactionalEditingDomain.class)) {
+ if (object instanceof DiagramEditor) {
+ return ((DiagramEditor) object).getEditingDomain();
+ } else if (object instanceof IPictogramElementEditPart) {
+ return ((IPictogramElementEditPart) object)
+ .getConfigurationProvider().getDiagramEditor()
+ .getEditingDomain();
+ }
+ }
+ if (object instanceof IAdaptable) {
+ return ((IAdaptable) object).getAdapter(adapterType);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Class<?>[] getAdapterList() {
+ return new Class<?>[] { PictogramElement.class };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+
+ @Override
+ protected void transferLayout(final LayoutMapping<PictogramElement> mapping) {
+ DiagramEditor diagramEditor = mapping
+ .getProperty(KimlGraphitiUtil.DIAGRAM_EDITOR);
+ ETriceLayoutCommand command = new ETriceLayoutCommand(
+ diagramEditor.getEditingDomain(), diagramEditor
+ .getDiagramTypeProvider().getFeatureProvider());
+ for (Entry<KGraphElement, PictogramElement> entry : mapping
+ .getGraphMap().entrySet()) {
+ command.add(entry.getKey(), entry.getValue());
+ }
+ mapping.setProperty(KimlGraphitiUtil.LAYOUT_COMMAND, command);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void applyLayout(final LayoutMapping<PictogramElement> mapping) {
+ TransactionalEditingDomain editingDomain = mapping.getProperty(
+ KimlGraphitiUtil.DIAGRAM_EDITOR).getEditingDomain();
+ editingDomain.getCommandStack().execute(
+ mapping.getProperty(KimlGraphitiUtil.LAYOUT_COMMAND));
+ }
+
+ /** the cached layout configuration for Graphiti. */
+ private GraphitiLayoutConfig layoutConfig = new GraphitiLayoutConfig();
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public LayoutMapping<PictogramElement> buildLayoutGraph(
+ final IWorkbenchPart workbenchPart, final Object diagramPart) {
+ LayoutMapping<PictogramElement> mapping = new LayoutMapping<PictogramElement>(
+ this);
+ mapping.setProperty(KimlGraphitiUtil.CONNECTIONS,
+ new LinkedList<Connection>());
+ mapping.setProperty(KimlGraphitiUtil.STATIC_CONFIG,
+ new VolatileLayoutConfig());
+
+ if (workbenchPart instanceof RoomDiagramEditor) {
+ mapping.setProperty(KimlGraphitiUtil.DIAGRAM_EDITOR,
+ (RoomDiagramEditor) workbenchPart);
+ }
+
+ EditPart layoutRootPart = null;
+ if (diagramPart instanceof IPictogramElementEditPart) {
+ layoutRootPart = (EditPart) diagramPart;
+ } else if (mapping.getProperty(KimlGraphitiUtil.DIAGRAM_EDITOR) != null) {
+ layoutRootPart = mapping
+ .getProperty(KimlGraphitiUtil.DIAGRAM_EDITOR)
+ .getGraphicalViewer().getContents();
+ }
+ if (!(layoutRootPart instanceof IPictogramElementEditPart)) {
+ throw new UnsupportedOperationException(
+ "Not supported by this layout manager: Workbench part "
+ + workbenchPart + ", Edit part " + diagramPart);
+ }
+ PictogramElement element = ((IPictogramElementEditPart) layoutRootPart)
+ .getPictogramElement();
+ mapping.setParentElement(element);
+
+ if (element instanceof Diagram) {
+
+ KNode diagramNode = KimlUtil.createInitializedNode();
+ KShapeLayout shapeLayout = diagramNode.getData(KShapeLayout.class);
+ GraphicsAlgorithm ga = element.getGraphicsAlgorithm();
+ shapeLayout.setPos(ga.getX(), ga.getY());
+ shapeLayout.setSize(ga.getWidth(), ga.getHeight());
+ mapping.getGraphMap().put(diagramNode, element);
+
+ // Node creation for currently visible top-level Container
+ // Shape(Bounding Box) in
+ // eTrice Diagrams
+ buildLayoutGraphForBoundingBox(mapping, (Diagram) element,
+ diagramNode, true);
+
+ mapping.setLayoutGraph(diagramNode);
+
+ } else if (element instanceof Shape) {
+
+ if ( isTopLevelBoundingBox( (Shape)element) ) {
+ // The selected Element is the Top Level Top Level Bounding Box
+ mapping.setLayoutGraph((KNode) buildAllLevels(mapping,
+ (Shape) element, null));
+ } else {
+ KGraphElement internalKGraphElement = createKGaphElementFromShape(
+ mapping, null, (Shape) element);
+
+ if (internalKGraphElement instanceof KNode) {
+ // The selected Element is a Node.
+ for (Shape childShape : ((ContainerShape) element)
+ .getChildren()) {
+
+ createKGaphElementFromShape(mapping,
+ internalKGraphElement, childShape);
+ }
+
+ mapping.setLayoutGraph((KNode) internalKGraphElement);
+
+ } else {
+ // The selected Element is a Port or an Edge Label.
+
+ // Giving the user a SWT dialog indicating that this Shape
+ // cannot be lay-outed.
+ Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+ MessageBox dialog = new MessageBox(shell, SWT.ICON_ERROR
+ | SWT.OK | SWT.CANCEL);
+ dialog.setText("Invalid Layout Call");
+ dialog.setMessage("This shape connot be layouted saparately.");
+ System.out.println(dialog.open());
+
+ }
+
+ }
+ } else if (element instanceof FreeFormConnection) {
+ // This gives the user a SWT dialog indicating this is a connection and
+ // cannot be lay-outed.
+ Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+ .getShell();
+ MessageBox dialog = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK
+ | SWT.CANCEL);
+ dialog.setText("Invalid Layout Call");
+ dialog.setMessage("A connection connot be layouted saparately");
+ System.out.println(dialog.open());
+ }
+
+ for (Connection entry : mapping
+ .getProperty(KimlGraphitiUtil.CONNECTIONS)) {
+ KimlGraphitiUtil.createEdge(mapping, entry);
+ }
+
+ // create a layout configuration
+ mapping.getLayoutConfigs().add(
+ mapping.getProperty(KimlGraphitiUtil.STATIC_CONFIG));
+ mapping.getLayoutConfigs().add(layoutConfig);
+
+ return mapping;
+ }
+
+ /**
+ * Identifies the visible Bounding Box (Top Level Container) and delegates
+ * the control to {@link #buildAllLevels(LayoutMapping, Shape, KNode)}
+ *
+ * @param mapping
+ * the mapping of pictogram elements to graph elements
+ * @param diagram
+ * @param diagramNode
+ * @param onlyVisible
+ *
+ * @author jayant
+ */
+ protected abstract void buildLayoutGraphForBoundingBox(
+ final LayoutMapping<PictogramElement> mapping,
+ final Diagram diagram, final KNode diagramNode,
+ final boolean onlyVisible);
+
+ /**
+ * Develops the complete LayoutGraph for the eTrice Diagram starting from
+ * the Bounding Box.
+ *
+ * @param mapping
+ * the mapping of pictogram elements to graph elements
+ * @param topLevelBoundingBox
+ * The Top Level Container Shape containing all other shapes
+ * @param diagramNode
+ * The KNode corresponding to the Diagram
+ *
+ * @author jayant
+ */
+ /* This is fairly general for both the eTrice editors */
+ protected KNode buildAllLevels(LayoutMapping<PictogramElement> mapping,
+ Shape topLevelBoundingBox, KNode diagramNode) {
+ // Top Level
+ KNode topLevelBoundingBoxNode = createNode(mapping, diagramNode,
+ topLevelBoundingBox);
+
+ for (Shape secondtLevelShape : ((ContainerShape) topLevelBoundingBox)
+ .getChildren()) {
+ // Second Level
+ KGraphElement secondLevelKGraphElement = createKGaphElementFromShape(
+ mapping, topLevelBoundingBoxNode, secondtLevelShape);
+
+ if (secondLevelKGraphElement instanceof KNode) {
+ for (Shape thirdLevelShape : ((ContainerShape) secondtLevelShape)
+ .getChildren()) {
+ // Third Level
+ createKGaphElementFromShape(mapping,
+ secondLevelKGraphElement, thirdLevelShape);
+ }
+ }
+ }
+
+ return topLevelBoundingBoxNode;
+ }
+
+ /**
+ * Identifies the type of Shape (Label, Port or Node) and creates the
+ * corresponding KGraphElement Element
+ *
+ * @param mapping
+ * the mapping of pictogram elements to graph elements
+ * @param parent
+ * the parent KNode
+ * @param shape
+ * the shape for which a KGraphElement is required
+ *
+ * @return the created KGraphElement for the given Shape
+ *
+ * @author jayant
+ */
+ /* This is fairly general for both the eTrice editors */
+ private KGraphElement createKGaphElementFromShape(
+ LayoutMapping<PictogramElement> mapping, KGraphElement parent,
+ Shape shape) {
+
+ GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
+
+ // Checking whether this shape is a label
+ if (ga instanceof AbstractText) {
+
+ KInsets parentInsets = parent.getData(KShapeLayout.class)
+ .getProperty(GraphitiLayoutCommand.INVIS_INSETS);
+
+ assert (parentInsets != null) : "There must be an invisible insets attached to all ports and nodes(except diagramNode)";
+ return KimlGraphitiUtil.createLabel((KLabeledGraphElement) parent,
+ (AbstractText) ga, -parentInsets.getLeft(),
+ -parentInsets.getTop());
+ }
+
+ else if (shape instanceof ContainerShape) {
+
+ // Checking whether this shape is a Port
+ if (isPort(shape))
+ return createPort(mapping, (KNode) parent, shape);
+
+ else
+ // This shape is a node
+ return createNode(mapping, (KNode) parent, shape);
+
+ } else
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ protected abstract KNode createNode(
+ final LayoutMapping<PictogramElement> mapping,
+ final KNode parentNode, final Shape shape);
+
+ /**
+ * Create a port for the layout graph.
+ *
+ * @param mapping
+ * the mapping of pictogram elements to graph elements
+ * @param parentNode
+ * the parent node
+ * @param shape
+ * the shape for a new port
+ * @return a new layout node
+ *
+ * @author jayant
+ */
+ /* This is fairly general for both the eTrice editors */
+ protected KPort createPort(final LayoutMapping<PictogramElement> mapping,
+ final KNode parentNode, final Shape shape) {
+ KPort port = KimlUtil.createInitializedPort();
+ port.setNode(parentNode);
+
+ setCurrentPositionAndSize(mapping, parentNode, port, shape);
+
+ mapping.getGraphMap().put(port, shape.getAnchors().get(0));
+
+ // Set Port label
+ Shape portLabelShape = ((ContainerShape) shape).getChildren().get(0);
+ createKGaphElementFromShape(mapping, port, portLabelShape);
+
+ // gather all connections connected to the parentNode via this port
+ for (Anchor anchor : shape.getAnchors()) {
+ mapping.getProperty(KimlGraphitiUtil.CONNECTIONS).addAll(
+ anchor.getOutgoingConnections());
+ }
+
+ return port;
+ }
+
+ /**
+ * Sets the insets(border) and calculates the position and size of the
+ * KgraphElement.
+ *
+ * @param mapping
+ * the mapping of pictogram elements to graph elements
+ * @param parentNode
+ * the parent node
+ * @param kelem
+ * the kGraphElement whose size and position is to be determined
+ * @param shape
+ * the corresponding shape
+ *
+ * @author jayant
+ */
+ /*
+ * This is fairly general for both the eTrice editors and same for Nodes and
+ * Ports
+ */
+ public static void setCurrentPositionAndSize(
+ final LayoutMapping<PictogramElement> mapping,
+ final KNode parentNode, final KGraphElement kelem, final Shape shape) {
+
+ VolatileLayoutConfig staticConfig = mapping
+ .getProperty(KimlGraphitiUtil.STATIC_CONFIG);
+
+ KShapeLayout shapeLayout = kelem.getData(KShapeLayout.class);
+ GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
+
+ // Calculate and set the invisible insets
+ KInsets shapeInsets = KimlGraphitiUtil.calcInsets(ga);
+ shapeLayout
+ .setProperty(GraphitiLayoutCommand.INVIS_INSETS, shapeInsets);
+ staticConfig.setValue(GraphitiLayoutCommand.INVIS_INSETS, kelem,
+ LayoutContext.GRAPH_ELEM, shapeInsets);
+
+ // Get the parent insets
+ KInsets parentInsets = parentNode == null ? null : parentNode.getData(
+ KShapeLayout.class).getProperty(
+ GraphitiLayoutCommand.INVIS_INSETS);
+
+ // Set Position
+ if (parentInsets == null) {
+ shapeLayout.setPos(ga.getX() + shapeInsets.getLeft(), ga.getY()
+ + shapeInsets.getTop());
+ } else {
+ shapeLayout.setPos(
+ ga.getX() + shapeInsets.getLeft() - parentInsets.getLeft(),
+ ga.getY() + shapeInsets.getTop() - parentInsets.getTop());
+ }
+
+ // Set Size
+ shapeLayout
+ .setSize(
+ ga.getWidth() - shapeInsets.getLeft()
+ - shapeInsets.getRight(),
+ ga.getHeight() - shapeInsets.getTop()
+ - shapeInsets.getBottom());
+
+ // the modification flag must initially be false
+ ((KShapeLayoutImpl) shapeLayout).resetModificationFlag();
+
+ }
+
+ /**
+ * Determines whether the given shape is a port.
+ *
+ * @param shape the shape to be investigated
+ * @return true if the {@code shape} is a port else false
+ *
+ * @author jayant
+ */
+ protected abstract boolean isPort(Shape shape);
+
+ /**
+ * Determines whether the given shape is a Top Level Bounding Box or not.
+ *
+ * @param shape the shape to be investigated
+ * @return true if the {@code shape} is the Top Level Bounding Box
+ *
+ * @author jayant
+ */
+ protected abstract boolean isTopLevelBoundingBox(Shape shape);
+
+}
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceLayoutCommand.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceLayoutCommand.java
new file mode 100644
index 000000000..c09dabf46
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/ETriceLayoutCommand.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * This program and the accompanying materials
+ * are 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:
+ * Jayant Gupta (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.ui.layout;
+
+import java.util.List;
+
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.graphiti.features.IFeatureProvider;
+import org.eclipse.graphiti.features.context.impl.LayoutContext;
+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.ContainerShape;
+import org.eclipse.graphiti.mm.pictograms.FreeFormConnection;
+import org.eclipse.graphiti.mm.pictograms.PictogramElement;
+import org.eclipse.graphiti.services.Graphiti;
+
+import de.cau.cs.kieler.core.kgraph.KEdge;
+import de.cau.cs.kieler.core.kgraph.KGraphElement;
+import de.cau.cs.kieler.core.kgraph.KNode;
+import de.cau.cs.kieler.core.kgraph.KPort;
+import de.cau.cs.kieler.core.math.KVector;
+import de.cau.cs.kieler.core.math.KVectorChain;
+import de.cau.cs.kieler.kiml.graphiti.GraphitiLayoutCommand;
+import de.cau.cs.kieler.kiml.klayoutdata.KInsets;
+import de.cau.cs.kieler.kiml.klayoutdata.KShapeLayout;
+
+/**
+ * A command for applying the result of automatic layout to an eTrice
+ * editor(Graphiti) diagram.
+ *
+ * @author jayant
+ */
+public class ETriceLayoutCommand extends GraphitiLayoutCommand {
+
+ public ETriceLayoutCommand(TransactionalEditingDomain domain,
+ IFeatureProvider thefeatureProvider) {
+ super(domain, thefeatureProvider);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected void applyPortLayout(KPort kport, PictogramElement pelem) {
+
+ ContainerShape shape = (ContainerShape) ((Anchor) pelem).getParent();
+
+ setCalculatedPositionAndSize(kport, kport.getNode(), shape);
+ };
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected void applyNodeLayout(KNode knode, PictogramElement pelem) {
+
+ setCalculatedPositionAndSize(knode, knode.getParent(),
+ (ContainerShape) pelem);
+
+ };
+
+ /**
+ * {@inheritDoc}
+ *
+ */
+ /*
+ * The code used in this function has been taken from
+ * GraphitilayoutCommand.applyEdgeLayout() method. (Removing some unwanted
+ * code)
+ */
+ @Override
+ protected void applyEdgeLayout(final KEdge kedge,
+ final PictogramElement pelem) {
+ // create bend points for the edge
+ KVectorChain bendPoints = getBendPoints(kedge);
+
+ if (pelem instanceof FreeFormConnection) {
+ FreeFormConnection connection = (FreeFormConnection) pelem;
+ List<Point> pointList = connection.getBendpoints();
+ // add the bend points to the connection, reusing existing points
+ for (int i = 0; i < bendPoints.size(); i++) {
+ KVector kpoint = bendPoints.get(i);
+ if (i >= pointList.size()) {
+ Point point = Graphiti.getGaService().createPoint(
+ (int) Math.round(kpoint.x),
+ (int) Math.round(kpoint.y));
+ pointList.add(point);
+ } else {
+ Point point = pointList.get(i);
+ point.setX((int) Math.round(kpoint.x));
+ point.setY((int) Math.round(kpoint.y));
+ }
+ }
+ while (pointList.size() > bendPoints.size()) {
+ pointList.remove(pointList.size() - 1);
+ }
+ }
+ }
+
+ /**
+ * Sets the calculated position and size from a KGraph Model-Element (Node or
+ * Port) back to the corresponding diagram shape.
+ *
+ * @param kelem
+ * the KGraph Model Element (Node/Port)
+ * @param parentNode
+ * for nodes : the parent node , for ports : the containing node
+ * @param shape
+ * the corresponding pictogram element for Node/Port
+ *
+ * @author jayant
+ */
+ /*
+ * This function derives its code majorly from
+ * GraphitilayoutCommand.applyNodeLayout() method
+ */
+ private void setCalculatedPositionAndSize(final KGraphElement kelem,
+ KNode parentNode, final ContainerShape shape) {
+
+ KShapeLayout shapeLayout = kelem.getData(KShapeLayout.class);
+ float xpos = shapeLayout.getXpos();
+ float ypos = shapeLayout.getYpos();
+
+ if (parentNode != null) {
+ KInsets parentInsets = parentNode.getData(KShapeLayout.class)
+ .getProperty(INVIS_INSETS);
+ if (parentInsets != null) {
+ xpos += parentInsets.getLeft();
+ ypos += parentInsets.getRight();
+ }
+ }
+
+ float width = shapeLayout.getWidth();
+ float height = shapeLayout.getHeight();
+
+ KInsets nodeInsets = shapeLayout.getProperty(INVIS_INSETS);
+ if (nodeInsets != null) {
+ xpos -= nodeInsets.getLeft();
+ ypos -= nodeInsets.getTop();
+ width += nodeInsets.getLeft() + nodeInsets.getRight();
+ height += nodeInsets.getTop() + nodeInsets.getBottom();
+ }
+
+ GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
+
+ ga.setX(Math.round(xpos));
+ ga.setY(Math.round(ypos));
+ ga.setWidth(Math.round(width));
+ ga.setHeight(Math.round(height));
+
+ featureProvider.layoutIfPossible(new LayoutContext(shape));
+ }
+}
diff --git a/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureDiagramLayoutmanager.java b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureDiagramLayoutmanager.java
new file mode 100644
index 000000000..5dd544f9d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.ui.layout/src/org/eclipse/etrice/ui/layout/StructureDiagramLayoutmanager.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * This program and the accompanying materials
+ * are 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:
+ * Jayant Gupta (initial contribution)
+ *
+ *******************************************************************************/
+package org.eclipse.etrice.ui.layout;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.etrice.core.room.ActorClass;
+import org.eclipse.etrice.core.room.InterfaceItem;
+import org.eclipse.etrice.core.room.SAPoint;
+import org.eclipse.etrice.core.room.SPPoint;
+import org.eclipse.etrice.ui.structure.editor.StructureEditor;
+import org.eclipse.etrice.ui.structure.support.ActorContainerRefSupport;
+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.ui.internal.parts.IPictogramElementEditPart;
+
+import de.cau.cs.kieler.core.kgraph.KNode;
+import de.cau.cs.kieler.kiml.LayoutContext;
+import de.cau.cs.kieler.kiml.config.VolatileLayoutConfig;
+import de.cau.cs.kieler.kiml.graphiti.KimlGraphitiUtil;
+import de.cau.cs.kieler.kiml.options.LayoutOptions;
+import de.cau.cs.kieler.kiml.ui.diagram.LayoutMapping;
+import de.cau.cs.kieler.kiml.util.KimlUtil;
+
+/**
+ * Layout Manager implementation for eTrice Structure Editor.
+ *
+ * @author jayant
+ */
+@SuppressWarnings("restriction")
+public class StructureDiagramLayoutmanager extends ETriceDiagramLayoutManager {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ public boolean supports(final Object object) {
+
+ return object instanceof StructureEditor
+ || object instanceof IPictogramElementEditPart
+ || object instanceof PictogramElement;
+
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected void buildLayoutGraphForBoundingBox(
+ LayoutMapping<PictogramElement> mapping, Diagram diagram,
+ KNode diagramNode, boolean onlyVisible) {
+
+ for (Shape boundingBox : ((Diagram) diagram).getChildren()) {
+ if (boundingBox.isVisible()) {
+ buildAllLevels(mapping, boundingBox, diagramNode);
+ break;
+ }
+ }
+ }
+
+ /** the fixed minimal height of nodes. */
+ public static final float MIN_HEIGHT = ActorContainerRefSupport.DEFAULT_SIZE_Y;
+ /** the fixed minimal width of shapes. */
+ public static final float MIN_WIDHT = ActorContainerRefSupport.DEFAULT_SIZE_X;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ protected KNode createNode(final LayoutMapping<PictogramElement> mapping,
+ final KNode parentNode, final Shape shape) {
+ KNode node = KimlUtil.createInitializedNode();
+ node.setParent(parentNode);
+
+ setCurrentPositionAndSize(mapping, parentNode, node, shape);
+
+ VolatileLayoutConfig staticConfig = mapping
+ .getProperty(KimlGraphitiUtil.STATIC_CONFIG);
+ // FIXME find a way to specify the minimal size dynamically
+
+ staticConfig.setValue(LayoutOptions.MIN_WIDTH, node,
+ LayoutContext.GRAPH_ELEM, MIN_WIDHT);
+ staticConfig.setValue(LayoutOptions.MIN_HEIGHT, node,
+ LayoutContext.GRAPH_ELEM, MIN_HEIGHT);
+
+ mapping.getGraphMap().put(node, shape);
+
+ return node;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected boolean isPort(Shape shape) {
+ EObject modelObject = shape.getLink().getBusinessObjects().get(0);
+ if (modelObject instanceof InterfaceItem
+ || modelObject instanceof SPPoint
+ || modelObject instanceof SAPoint)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @author jayant
+ */
+ @Override
+ protected boolean isTopLevelBoundingBox(Shape shape) {
+ EObject modelObject = shape.getLink().getBusinessObjects().get(0);
+ if (modelObject instanceof ActorClass)
+ return true;
+
+ return false;
+ }
+
+}

Back to the top