Quellcode durchsuchen

place regions for extracted sub diagrams beside each other

also fixed a bug when state text expression editpart was selected when
executing proposal provider.
andreas muelder vor 7 Jahren
Ursprung
Commit
36455e0ba5

+ 364 - 323
plugins/org.yakindu.sct.refactoring/src/org/yakindu/sct/refactoring/refactor/impl/ExtractSubdiagramRefactoring.java

@@ -1,323 +1,364 @@
-/**
- * Copyright (c) 2013 committers of YAKINDU and others.
- * All rights reserved. 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:
- * 	committers of YAKINDU - initial API and implementation
- * 
- */
-package org.yakindu.sct.refactoring.refactor.impl;
-
-import static org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil.createInlineStyle;
-import static org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil.getInlineStyle;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-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.util.EcoreUtil;
-import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
-import org.eclipse.gmf.runtime.diagram.core.services.ViewService;
-import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
-import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
-import org.eclipse.gmf.runtime.notation.Bounds;
-import org.eclipse.gmf.runtime.notation.Diagram;
-import org.eclipse.gmf.runtime.notation.Edge;
-import org.eclipse.gmf.runtime.notation.Node;
-import org.eclipse.gmf.runtime.notation.Style;
-import org.eclipse.gmf.runtime.notation.View;
-import org.yakindu.sct.model.sgraph.Entry;
-import org.yakindu.sct.model.sgraph.Exit;
-import org.yakindu.sct.model.sgraph.ReactionProperty;
-import org.yakindu.sct.model.sgraph.Region;
-import org.yakindu.sct.model.sgraph.SGraphFactory;
-import org.yakindu.sct.model.sgraph.State;
-import org.yakindu.sct.model.sgraph.Statechart;
-import org.yakindu.sct.model.sgraph.Transition;
-import org.yakindu.sct.model.sgraph.Vertex;
-import org.yakindu.sct.model.stext.stext.EntryPointSpec;
-import org.yakindu.sct.model.stext.stext.ExitPointSpec;
-import org.yakindu.sct.model.stext.stext.StextFactory;
-import org.yakindu.sct.refactoring.refactor.AbstractRefactoring;
-import org.yakindu.sct.ui.editor.DiagramActivator;
-import org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor;
-import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil;
-import org.yakindu.sct.ui.editor.providers.SemanticHints;
-
-/**
- * 
- * @author andreas muelder - Initial contribution and API
- * 
- */
-public class ExtractSubdiagramRefactoring extends AbstractRefactoring<View> {
-
-	protected PreferencesHint preferencesHint = DiagramActivator.DIAGRAM_PREFERENCES_HINT;
-	private Diagram subdiagram;
-
-	@Override
-	public boolean isExecutable() {
-		EObject element = getContextObject().getElement();
-		if (!(element instanceof State)) {
-			return false;
-		}
-		State state = (State) element;
-		BooleanValueStyle inlineStyle = getInlineStyle(getContextObject());
-		return super.isExecutable() && state.isComposite() && (inlineStyle == null || inlineStyle.isBooleanValue());
-	}
-
-	@Override
-	protected void internalExecute() {
-		setNotationStyle();
-		subdiagram = createSubdiagram();
-		createEntryExitPoints(subdiagram);
-		setPreferredSize();
-	}
-
-	@Override
-	protected boolean internalDoUndo() {
-		// close the sub diagram before undo will delete it
-		return DiagramPartitioningUtil.closeSubdiagramEditors((State) subdiagram.getElement());
-	}
-
-	@SuppressWarnings("unchecked")
-	protected void createEntryExitPoints(Diagram subdiagram) {
-		TreeIterator<EObject> eAllContents = subdiagram.eAllContents();
-		List<Edge> entryPointsToCreate = new ArrayList<Edge>();
-		List<Edge> exitPointstoCreate = new ArrayList<Edge>();
-		while (eAllContents.hasNext()) {
-			EObject next = eAllContents.next();
-			if (next instanceof View) {
-				EList<Edge> targetEdges = ((View) next).getTargetEdges();
-				for (Edge edge : targetEdges) {
-					if (!EcoreUtil.isAncestor(subdiagram, edge.getSource()))
-						entryPointsToCreate.add(edge);
-				}
-				EList<Edge> sourceEdges = ((View) next).getSourceEdges();
-				for (Edge edge : sourceEdges) {
-					if (!EcoreUtil.isAncestor(subdiagram, edge.getTarget()))
-						exitPointstoCreate.add(edge);
-				}
-			}
-		}
-		for (Edge edge : entryPointsToCreate) {
-			createEntryPoint(edge, subdiagram);
-		}
-		for (Edge edge : exitPointstoCreate) {
-			createExitPoint(edge, subdiagram);
-		}
-	}
-
-	protected void createEntryPoint(Edge edge, Diagram subdiagram) {
-		Transition transition = (Transition) edge.getElement();
-		Region entryPointContainer = getEntryPointContainer(transition);
-		Entry entryPoint = createSemanticEntryPoint(transition);
-
-		// re-wire old transition to targeting the selected state
-		transition.setTarget((State) subdiagram.getElement());
-		View oldTarget = edge.getTarget();
-		edge.setTarget(getContextObject());
-
-		// create node for entry point
-		View entryPointContainerView = helper.getViewForSemanticElement(entryPointContainer, subdiagram);
-		View entryPointRegionCompartment = ViewUtil.getChildBySemanticHint(entryPointContainerView,
-				SemanticHints.REGION_COMPARTMENT);
-		Node entryNode = ViewService.createNode(entryPointRegionCompartment, entryPoint, SemanticHints.ENTRY,
-				preferencesHint);
-		ViewService.createEdge(entryNode, oldTarget, entryPoint.getOutgoingTransitions().get(0),
-				SemanticHints.TRANSITION, preferencesHint);
-
-		addEntryPointSpec(transition, entryPoint);
-	}
-
-	private void addEntryPointSpec(Transition transition, Entry entryPoint) {
-		EList<ReactionProperty> properties = transition.getProperties();
-		EntryPointSpec entryPointSpec = StextFactory.eINSTANCE.createEntryPointSpec();
-		// A transition can only have one entry point so alter the existing
-		for (ReactionProperty reactionProperty : properties) {
-			if (reactionProperty instanceof EntryPointSpec) {
-				entryPointSpec = (EntryPointSpec) reactionProperty;
-			}
-		}
-		entryPointSpec.setEntrypoint(entryPoint.getName());
-		properties.add(entryPointSpec);
-	}
-
-	private void addExitPointSpec(Transition transition, Exit exitPoint) {
-		EList<ReactionProperty> properties = transition.getProperties();
-		ExitPointSpec exitPointSpec = StextFactory.eINSTANCE.createExitPointSpec();
-		// A transition can only have one exit point so alter the existing
-		for (ReactionProperty reactionProperty : properties) {
-			if (reactionProperty instanceof ExitPointSpec) {
-				exitPointSpec = (ExitPointSpec) reactionProperty;
-			}
-		}
-		exitPointSpec.setExitpoint(exitPoint.getName());
-		properties.add(exitPointSpec);
-	}
-
-	protected String getEntryPointName(Transition transition) {
-		StringBuilder stringBuilder = new StringBuilder();
-		stringBuilder.append("entry_");
-		stringBuilder.append(transition.getTarget().getName());
-		int index = transition.getSource().getOutgoingTransitions().indexOf(transition);
-		stringBuilder.append(index);
-		return asIdentifier(stringBuilder.toString());
-	}
-
-	protected String getExitPointName(Transition transition) {
-		StringBuilder stringBuilder = new StringBuilder();
-		stringBuilder.append("exit_");
-		stringBuilder.append(transition.getSource().getName());
-		int index = transition.getSource().getOutgoingTransitions().indexOf(transition);
-		stringBuilder.append(index);
-		return asIdentifier(stringBuilder.toString());
-	}
-
-	protected Entry createSemanticEntryPoint(Transition transition) {
-		Region entryPointTarget = getEntryPointContainer(transition);
-		String name = getEntryPointName(transition);
-		Entry entryPoint = null;
-		Iterator<Vertex> iterator = entryPointTarget.getVertices().iterator();
-		while (iterator.hasNext()) {
-			Vertex next = iterator.next();
-			if (next instanceof Entry) {
-				Entry current = (Entry) next;
-				if (name.equals(current.getName())) {
-					// Do nothing, there already exists an entry point
-					return current;
-				}
-			}
-		}
-		entryPoint = SGraphFactory.eINSTANCE.createEntry();
-		entryPoint.setName(name);
-		entryPointTarget.getVertices().add(entryPoint);
-		Transition entryPointTransition = SGraphFactory.eINSTANCE.createTransition();
-		entryPointTransition.setSource(entryPoint);
-		entryPointTransition.setTarget(transition.getTarget());
-
-		return entryPoint;
-	}
-
-	private Exit createSemanticExitPoint(Transition transition) {
-		Region exitPointContainer = getExitPointContainer(transition);
-		String name = getExitPointName(transition);
-
-		Exit exitPoint = null;
-		Iterator<Vertex> iterator = exitPointContainer.getVertices().iterator();
-		while (iterator.hasNext()) {
-			Vertex next = iterator.next();
-			if (next instanceof Exit) {
-				Exit current = (Exit) next;
-				if (name.equals(current.getName())) {
-					// Do nothing, there already exists an entry point
-					return current;
-				}
-			}
-		}
-
-		exitPoint = SGraphFactory.eINSTANCE.createExit();
-		exitPoint.setName(name);
-		exitPointContainer.getVertices().add(exitPoint);
-
-		return exitPoint;
-	}
-
-	private Region getEntryPointContainer(Transition transition) {
-		// entry point container is the subdiagram's state's region which
-		// contains the transition target
-		EObject firstParentRegion = transition.getTarget().getParentRegion();
-		return getOutermostParentRegion(firstParentRegion);
-	}
-
-	private Region getExitPointContainer(Transition transition) {
-		// exit point container is the subdiagram's state's region which
-		// contains the transition source
-		EObject firstParentRegion = transition.getSource().getParentRegion();
-		return getOutermostParentRegion(firstParentRegion);
-	}
-
-	private Region getOutermostParentRegion(EObject element) {
-		while (!(element.eContainer() instanceof Statechart)) {
-			EObject container = element.eContainer();
-			if (container instanceof State) {
-				State parentState = (State) container;
-				if (parentState.equals(subdiagram.getElement())) {
-					return (Region) element;
-				}
-				element = parentState.getParentRegion();
-			} else {
-				element = element.eContainer();
-			}
-		}
-		return null;
-	}
-
-	protected void createExitPoint(Edge edge, Diagram subdiagram) {
-		Transition transition = (Transition) edge.getElement();
-		// create semantic exit point
-		Region exitPointContainer = getExitPointContainer(transition);
-		Exit exitPoint = createSemanticExitPoint(transition);
-
-		// create node for exit point
-		View exitPointContainerView = helper.getViewForSemanticElement(exitPointContainer, subdiagram);
-		View exitPointRegionCompartment = ViewUtil.getChildBySemanticHint(exitPointContainerView,
-				SemanticHints.REGION_COMPARTMENT);
-		Node exitNode = ViewService.createNode(exitPointRegionCompartment, exitPoint, SemanticHints.EXIT,
-				preferencesHint);
-
-		// re-wire existing transition to new exit point
-		Vertex oldTransitionTarget = transition.getTarget();
-		transition.setTarget(exitPoint);
-		View oldEdgeTarget = edge.getTarget();
-		edge.setTarget(exitNode);
-
-		// create transition from selected state to former transition target
-		Transition exitPointTransition = SGraphFactory.eINSTANCE.createTransition();
-		exitPointTransition.setSource((State) subdiagram.getElement());
-		exitPointTransition.setTarget(oldTransitionTarget);
-		ViewService.createEdge(getContextObject(), oldEdgeTarget, exitPointTransition, SemanticHints.TRANSITION,
-				preferencesHint);
-
-		addExitPointSpec(exitPointTransition, exitPoint);
-	}
-
-	/**
-	 * Sets the GMF inline {@link Style} to true
-	 */
-	@SuppressWarnings("unchecked")
-	protected void setNotationStyle() {
-		BooleanValueStyle inlineStyle = getInlineStyle(getContextObject());
-		if (inlineStyle == null) {
-			inlineStyle = createInlineStyle();
-			getContextObject().getStyles().add(inlineStyle);
-		}
-		inlineStyle.setBooleanValue(false);
-	}
-
-	/**
-	 * Creates a new {@link Diagram} and copies child elements
-	 */
-	protected Diagram createSubdiagram() {
-		View contextView = getContextObject();
-		State contextElement = (State) contextView.getElement();
-		Diagram subdiagram = ViewService.createDiagram(contextElement, StatechartDiagramEditor.ID, preferencesHint);
-		View figureCompartment = ViewUtil.getChildBySemanticHint(contextView, SemanticHints.STATE_FIGURE_COMPARTMENT);
-		getResource().getContents().add(subdiagram);
-		while (figureCompartment.getChildren().size() > 0) {
-			subdiagram.insertChild((View) figureCompartment.getChildren().get(0));
-		}
-		return subdiagram;
-	}
-
-	protected void setPreferredSize() {
-		Node node = (Node) getContextObject();
-		Bounds bounds = (Bounds) node.getLayoutConstraint();
-		bounds.setWidth(-1);
-		bounds.setHeight(-1);
-	}
-}
+/**
+ * Copyright (c) 2013 committers of YAKINDU and others.
+ * All rights reserved. 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:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.refactoring.refactor.impl;
+
+import static org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil.createInlineStyle;
+import static org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil.getInlineStyle;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.draw2d.geometry.Rectangle;
+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.util.EcoreUtil;
+import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
+import org.eclipse.gmf.runtime.diagram.core.services.ViewService;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramGraphicalViewer;
+import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
+import org.eclipse.gmf.runtime.notation.Bounds;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.Edge;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.gmf.runtime.notation.Style;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.ui.IEditorPart;
+import org.yakindu.base.xtext.utils.jface.viewers.util.ActiveEditorTracker;
+import org.yakindu.sct.model.sgraph.Entry;
+import org.yakindu.sct.model.sgraph.Exit;
+import org.yakindu.sct.model.sgraph.ReactionProperty;
+import org.yakindu.sct.model.sgraph.Region;
+import org.yakindu.sct.model.sgraph.SGraphFactory;
+import org.yakindu.sct.model.sgraph.State;
+import org.yakindu.sct.model.sgraph.Statechart;
+import org.yakindu.sct.model.sgraph.Transition;
+import org.yakindu.sct.model.sgraph.Vertex;
+import org.yakindu.sct.model.stext.stext.EntryPointSpec;
+import org.yakindu.sct.model.stext.stext.ExitPointSpec;
+import org.yakindu.sct.model.stext.stext.StextFactory;
+import org.yakindu.sct.refactoring.refactor.AbstractRefactoring;
+import org.yakindu.sct.ui.editor.DiagramActivator;
+import org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor;
+import org.yakindu.sct.ui.editor.factories.StateViewFactory;
+import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil;
+import org.yakindu.sct.ui.editor.providers.SemanticHints;
+import org.yakindu.sct.ui.editor.utils.GMFNotationUtil;
+
+/**
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public class ExtractSubdiagramRefactoring extends AbstractRefactoring<View> {
+
+	protected PreferencesHint preferencesHint = DiagramActivator.DIAGRAM_PREFERENCES_HINT;
+	private Diagram subdiagram;
+
+	@Override
+	public boolean isExecutable() {
+		EObject element = getContextObject().getElement();
+		if (!(element instanceof State)) {
+			return false;
+		}
+		State state = (State) element;
+		BooleanValueStyle inlineStyle = getInlineStyle(getContextObject());
+		return super.isExecutable() && state.isComposite() && (inlineStyle == null || inlineStyle.isBooleanValue());
+	}
+
+	@Override
+	protected void internalExecute() {
+		setNotationStyle();
+		subdiagram = createSubdiagram();
+		createEntryExitPoints(subdiagram);
+		setPreferredSize();
+	}
+
+	@Override
+	protected boolean internalDoUndo() {
+		// close the sub diagram before undo will delete it
+		return DiagramPartitioningUtil.closeSubdiagramEditors((State) subdiagram.getElement());
+	}
+
+	@SuppressWarnings("unchecked")
+	protected void createEntryExitPoints(Diagram subdiagram) {
+		TreeIterator<EObject> eAllContents = subdiagram.eAllContents();
+		List<Edge> entryPointsToCreate = new ArrayList<Edge>();
+		List<Edge> exitPointstoCreate = new ArrayList<Edge>();
+		while (eAllContents.hasNext()) {
+			EObject next = eAllContents.next();
+			if (next instanceof View) {
+				EList<Edge> targetEdges = ((View) next).getTargetEdges();
+				for (Edge edge : targetEdges) {
+					if (!EcoreUtil.isAncestor(subdiagram, edge.getSource()))
+						entryPointsToCreate.add(edge);
+				}
+				EList<Edge> sourceEdges = ((View) next).getSourceEdges();
+				for (Edge edge : sourceEdges) {
+					if (!EcoreUtil.isAncestor(subdiagram, edge.getTarget()))
+						exitPointstoCreate.add(edge);
+				}
+			}
+		}
+		for (Edge edge : entryPointsToCreate) {
+			createEntryPoint(edge, subdiagram);
+		}
+		for (Edge edge : exitPointstoCreate) {
+			createExitPoint(edge, subdiagram);
+		}
+	}
+
+	protected void createEntryPoint(Edge edge, Diagram subdiagram) {
+		Transition transition = (Transition) edge.getElement();
+		Region entryPointContainer = getEntryPointContainer(transition);
+		Entry entryPoint = createSemanticEntryPoint(transition);
+
+		// re-wire old transition to targeting the selected state
+		transition.setTarget((State) subdiagram.getElement());
+		View oldTarget = edge.getTarget();
+		edge.setTarget(getContextObject());
+
+		// create node for entry point
+		View entryPointContainerView = helper.getViewForSemanticElement(entryPointContainer, subdiagram);
+		View entryPointRegionCompartment = ViewUtil.getChildBySemanticHint(entryPointContainerView,
+				SemanticHints.REGION_COMPARTMENT);
+		Node entryNode = ViewService.createNode(entryPointRegionCompartment, entryPoint, SemanticHints.ENTRY,
+				preferencesHint);
+		ViewService.createEdge(entryNode, oldTarget, entryPoint.getOutgoingTransitions().get(0),
+				SemanticHints.TRANSITION, preferencesHint);
+
+		addEntryPointSpec(transition, entryPoint);
+	}
+
+	private void addEntryPointSpec(Transition transition, Entry entryPoint) {
+		EList<ReactionProperty> properties = transition.getProperties();
+		EntryPointSpec entryPointSpec = StextFactory.eINSTANCE.createEntryPointSpec();
+		// A transition can only have one entry point so alter the existing
+		for (ReactionProperty reactionProperty : properties) {
+			if (reactionProperty instanceof EntryPointSpec) {
+				entryPointSpec = (EntryPointSpec) reactionProperty;
+			}
+		}
+		entryPointSpec.setEntrypoint(entryPoint.getName());
+		properties.add(entryPointSpec);
+	}
+
+	private void addExitPointSpec(Transition transition, Exit exitPoint) {
+		EList<ReactionProperty> properties = transition.getProperties();
+		ExitPointSpec exitPointSpec = StextFactory.eINSTANCE.createExitPointSpec();
+		// A transition can only have one exit point so alter the existing
+		for (ReactionProperty reactionProperty : properties) {
+			if (reactionProperty instanceof ExitPointSpec) {
+				exitPointSpec = (ExitPointSpec) reactionProperty;
+			}
+		}
+		exitPointSpec.setExitpoint(exitPoint.getName());
+		properties.add(exitPointSpec);
+	}
+
+	protected String getEntryPointName(Transition transition) {
+		StringBuilder stringBuilder = new StringBuilder();
+		stringBuilder.append("entry_");
+		stringBuilder.append(transition.getTarget().getName());
+		int index = transition.getSource().getOutgoingTransitions().indexOf(transition);
+		stringBuilder.append(index);
+		return asIdentifier(stringBuilder.toString());
+	}
+
+	protected String getExitPointName(Transition transition) {
+		StringBuilder stringBuilder = new StringBuilder();
+		stringBuilder.append("exit_");
+		stringBuilder.append(transition.getSource().getName());
+		int index = transition.getSource().getOutgoingTransitions().indexOf(transition);
+		stringBuilder.append(index);
+		return asIdentifier(stringBuilder.toString());
+	}
+
+	protected Entry createSemanticEntryPoint(Transition transition) {
+		Region entryPointTarget = getEntryPointContainer(transition);
+		String name = getEntryPointName(transition);
+		Entry entryPoint = null;
+		Iterator<Vertex> iterator = entryPointTarget.getVertices().iterator();
+		while (iterator.hasNext()) {
+			Vertex next = iterator.next();
+			if (next instanceof Entry) {
+				Entry current = (Entry) next;
+				if (name.equals(current.getName())) {
+					// Do nothing, there already exists an entry point
+					return current;
+				}
+			}
+		}
+		entryPoint = SGraphFactory.eINSTANCE.createEntry();
+		entryPoint.setName(name);
+		entryPointTarget.getVertices().add(entryPoint);
+		Transition entryPointTransition = SGraphFactory.eINSTANCE.createTransition();
+		entryPointTransition.setSource(entryPoint);
+		entryPointTransition.setTarget(transition.getTarget());
+
+		return entryPoint;
+	}
+
+	private Exit createSemanticExitPoint(Transition transition) {
+		Region exitPointContainer = getExitPointContainer(transition);
+		String name = getExitPointName(transition);
+
+		Exit exitPoint = null;
+		Iterator<Vertex> iterator = exitPointContainer.getVertices().iterator();
+		while (iterator.hasNext()) {
+			Vertex next = iterator.next();
+			if (next instanceof Exit) {
+				Exit current = (Exit) next;
+				if (name.equals(current.getName())) {
+					// Do nothing, there already exists an entry point
+					return current;
+				}
+			}
+		}
+
+		exitPoint = SGraphFactory.eINSTANCE.createExit();
+		exitPoint.setName(name);
+		exitPointContainer.getVertices().add(exitPoint);
+
+		return exitPoint;
+	}
+
+	private Region getEntryPointContainer(Transition transition) {
+		// entry point container is the subdiagram's state's region which
+		// contains the transition target
+		EObject firstParentRegion = transition.getTarget().getParentRegion();
+		return getOutermostParentRegion(firstParentRegion);
+	}
+
+	private Region getExitPointContainer(Transition transition) {
+		// exit point container is the subdiagram's state's region which
+		// contains the transition source
+		EObject firstParentRegion = transition.getSource().getParentRegion();
+		return getOutermostParentRegion(firstParentRegion);
+	}
+
+	private Region getOutermostParentRegion(EObject element) {
+		while (!(element.eContainer() instanceof Statechart)) {
+			EObject container = element.eContainer();
+			if (container instanceof State) {
+				State parentState = (State) container;
+				if (parentState.equals(subdiagram.getElement())) {
+					return (Region) element;
+				}
+				element = parentState.getParentRegion();
+			} else {
+				element = element.eContainer();
+			}
+		}
+		return null;
+	}
+
+	protected void createExitPoint(Edge edge, Diagram subdiagram) {
+		Transition transition = (Transition) edge.getElement();
+		// create semantic exit point
+		Region exitPointContainer = getExitPointContainer(transition);
+		Exit exitPoint = createSemanticExitPoint(transition);
+
+		// create node for exit point
+		View exitPointContainerView = helper.getViewForSemanticElement(exitPointContainer, subdiagram);
+		View exitPointRegionCompartment = ViewUtil.getChildBySemanticHint(exitPointContainerView,
+				SemanticHints.REGION_COMPARTMENT);
+		Node exitNode = ViewService.createNode(exitPointRegionCompartment, exitPoint, SemanticHints.EXIT,
+				preferencesHint);
+
+		// re-wire existing transition to new exit point
+		Vertex oldTransitionTarget = transition.getTarget();
+		transition.setTarget(exitPoint);
+		View oldEdgeTarget = edge.getTarget();
+		edge.setTarget(exitNode);
+
+		// create transition from selected state to former transition target
+		Transition exitPointTransition = SGraphFactory.eINSTANCE.createTransition();
+		exitPointTransition.setSource((State) subdiagram.getElement());
+		exitPointTransition.setTarget(oldTransitionTarget);
+		ViewService.createEdge(getContextObject(), oldEdgeTarget, exitPointTransition, SemanticHints.TRANSITION,
+				preferencesHint);
+
+		addExitPointSpec(exitPointTransition, exitPoint);
+	}
+
+	/**
+	 * Sets the GMF inline {@link Style} to true
+	 */
+	@SuppressWarnings("unchecked")
+	protected void setNotationStyle() {
+		BooleanValueStyle inlineStyle = getInlineStyle(getContextObject());
+		if (inlineStyle == null) {
+			inlineStyle = createInlineStyle();
+			getContextObject().getStyles().add(inlineStyle);
+		}
+		inlineStyle.setBooleanValue(false);
+	}
+
+	/**
+	 * Creates a new {@link Diagram} and copies child elements
+	 */
+	protected Diagram createSubdiagram() {
+		View contextView = getContextObject();
+		State contextElement = (State) contextView.getElement();
+		Diagram subdiagram = ViewService.createDiagram(contextElement, StatechartDiagramEditor.ID, preferencesHint);
+		View figureCompartment = ViewUtil.getChildBySemanticHint(contextView, SemanticHints.STATE_FIGURE_COMPARTMENT);
+		getResource().getContents().add(subdiagram);
+
+		boolean isHorizontal = isHorizontal(figureCompartment);
+		int offset = 0;
+		while (figureCompartment.getChildren().size() > 0) {
+			Node child = (Node) figureCompartment.getChildren().get(0);
+			Rectangle actualBounds = getActualBounds(child);
+			if (actualBounds != Rectangle.SINGLETON) {
+				Bounds modelBounds = (Bounds) child.getLayoutConstraint();
+				modelBounds.setWidth(actualBounds.width());
+				modelBounds.setHeight(actualBounds.height());
+				if (isHorizontal) {
+					modelBounds.setX(offset);
+					offset += actualBounds.width();
+				} else {
+					modelBounds.setY(offset);
+					offset += actualBounds.height();
+				}
+			}
+
+			subdiagram.insertChild(child);
+		}
+		return subdiagram;
+	}
+
+	protected boolean isHorizontal(View child) {
+		BooleanValueStyle style = GMFNotationUtil.getBooleanValueStyle((View) child.eContainer(),
+				StateViewFactory.ALIGNMENT_ORIENTATION);
+		return (style != null) ? style.isBooleanValue() : true;
+	}
+
+	protected Rectangle getActualBounds(Node child) {
+		IEditorPart lastActiveEditor = ActiveEditorTracker.getLastActiveEditor();
+		if (lastActiveEditor instanceof StatechartDiagramEditor) {
+			IDiagramGraphicalViewer viewer = ((StatechartDiagramEditor) lastActiveEditor).getDiagramGraphicalViewer();
+			IGraphicalEditPart editPart = (IGraphicalEditPart) viewer.getEditPartRegistry().get(child);
+			return editPart.getFigure().getBounds();
+		}
+		return Rectangle.SINGLETON;
+	}
+
+	protected void setPreferredSize() {
+		Node node = (Node) getContextObject();
+		Bounds bounds = (Bounds) node.getLayoutConstraint();
+		bounds.setWidth(-1);
+		bounds.setHeight(-1);
+	}
+}

+ 1 - 1
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/modifications/StateTemplatesModification.java

@@ -45,7 +45,7 @@ public abstract class StateTemplatesModification extends AbstractSemanticModific
 
 
 	@Override
 	@Override
 	protected boolean check(EObject semanticObject, View view) {
 	protected boolean check(EObject semanticObject, View view) {
-		return semanticObject instanceof State;
+		return semanticObject instanceof State && view.getType() == SemanticHints.STATE;
 	}
 	}
 
 
 
 

+ 1 - 1
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/proposals/ContentProposalHandler.java

@@ -77,7 +77,7 @@ public class ContentProposalHandler implements IContentProposalProvider {
 	}
 	}
 
 
 	protected void initProposalProvidersOnDemand() {
 	protected void initProposalProvidersOnDemand() {
-		if (proposalProviders == null) {
+		if (proposalProviders == null && getSelectedView() != null) {
 			IDomain domain = DomainRegistry.getDomain(getSelectedView().getElement());
 			IDomain domain = DomainRegistry.getDomain(getSelectedView().getElement());
 			Injector injector = domain.getInjector(IDomain.FEATURE_EDITOR);
 			Injector injector = domain.getInjector(IDomain.FEATURE_EDITOR);
 			injector.injectMembers(this);
 			injector.injectMembers(this);