浏览代码

Merge branch 'master' into misraNaming

Rene Beckmann 7 年之前
父节点
当前提交
6339625dc7
共有 39 个文件被更改,包括 1663 次插入1393 次删除
  1. 9 1
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/terminals/ExpressionsValueConverterService.java
  2. 48 0
      plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/terminals/FloatValueConverter.java
  3. 224 219
      plugins/org.yakindu.base.gmf.runtime/src/org/yakindu/base/gmf/runtime/editparts/TextAwareLabelEditPart.java
  4. 8 44
      plugins/org.yakindu.base.xtext.utils.jface/src/org/yakindu/base/xtext/utils/jface/viewers/StyledTextXtextAdapter.java
  5. 61 0
      plugins/org.yakindu.base.xtext.utils.jface/src/org/yakindu/base/xtext/utils/jface/viewers/XtextStyledTextSelectionProvider.java
  6. 2 1
      plugins/org.yakindu.sct.doc.user/image-tools/create_grammar_images.sh
  7. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_010_sctunit.png
  8. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_ifexpression.png
  9. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_loopstatement.png
  10. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_negativeverifystatement.png
  11. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_positiveverifystatement.png
  12. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_primaryexpression.png
  13. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_proceedunit.png
  14. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_returnstatement.png
  15. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_sctunitclass.png
  16. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_sctunitoperation.png
  17. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_sctunitvariabledefinition.png
  18. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_teststatement.png
  19. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_verifystatement.png
  20. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_030_assertion.png
  21. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_030_operation.png
  22. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_030_test_unit.png
  23. 二进制
      plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_outgoing_event_010.png
  24. 53 14
      plugins/org.yakindu.sct.doc.user/src/user-guide/sctunit.textile
  25. 13 1
      plugins/org.yakindu.sct.generator.genmodel.ui/src/org/yakindu/sct/generator/genmodel/ui/outline/SGenOutlineTreeProvider.java
  26. 2 3
      plugins/org.yakindu.sct.model.sgraph.ui/src/org/yakindu/sct/model/sgraph/ui/validation/ISctIssueCreator.java
  27. 5 4
      plugins/org.yakindu.sct.model.sgraph.ui/src/org/yakindu/sct/model/sgraph/ui/validation/SCTDiagnosticConverterImpl.java
  28. 14 4
      plugins/org.yakindu.sct.model.sgraph.ui/src/org/yakindu/sct/model/sgraph/ui/validation/SCTIssue.java
  29. 3 4
      plugins/org.yakindu.sct.model.sgraph.ui/src/org/yakindu/sct/model/sgraph/ui/validation/SCTMarkerCreator.java
  30. 2 3
      plugins/org.yakindu.sct.model.sgraph.ui/src/org/yakindu/sct/model/sgraph/ui/validation/SCTMarkerType.java
  31. 25 22
      plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/SGraphJavaValidator.java
  32. 19 13
      plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextNamesAreUniqueValidationHelper.java
  33. 1 1
      plugins/org.yakindu.sct.ui.editor/plugin.xml
  34. 43 0
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/definitionsection/ReleaseSelectionOnFocusGain.java
  35. 765 0
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/definitionsection/StatechartDefinitionSection.java
  36. 24 697
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/editor/StatechartDiagramEditor.java
  37. 2 68
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/partitioning/DiagramPartitioningEditor.java
  38. 280 281
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/partitioning/DiagramPartitioningUtil.java
  39. 60 13
      plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/providers/StatechartMarkerNavigationProvider.java

+ 9 - 1
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/terminals/ExpressionsValueConverterService.java

@@ -28,6 +28,7 @@ public class ExpressionsValueConverterService extends DefaultTerminalConverters
 	public static final String BOOL = "BOOL";
 	public static final String HEX = "HEX";
 	public static final String BINARY = "BINARY";
+	public static final String FLOAT = "FLOAT";
 	
 	@Inject
 	protected AbstractIDValueConverter idValueConverter;
@@ -44,6 +45,9 @@ public class ExpressionsValueConverterService extends DefaultTerminalConverters
 	@Inject
 	protected QIDValueConverter qidConverter;
 	
+	@Inject
+	protected FloatValueConverter floatConverter;
+	
 	@ValueConverter(rule = BOOL)
 	public IValueConverter<Boolean> BOOL() {
 		return boolConverter;
@@ -63,6 +67,10 @@ public class ExpressionsValueConverterService extends DefaultTerminalConverters
 	public IValueConverter<String> QID() {
 		return qidConverter;
 	}
-
+	
+	@ValueConverter(rule = FLOAT)
+	public IValueConverter<Float> FLOAT() {
+		return floatConverter;
+	}
 
 }

+ 48 - 0
plugins/org.yakindu.base.expressions/src/org/yakindu/base/expressions/terminals/FloatValueConverter.java

@@ -0,0 +1,48 @@
+/** 
+ * Copyright (c) 2018 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.base.expressions.terminals;
+
+import org.eclipse.xtext.conversion.ValueConverterException;
+import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.util.Strings;
+
+/**
+ * This float value converter provides float values with 'f' as suffix
+ * character.
+ * 
+ * @author robert rudi
+ *
+ */
+public class FloatValueConverter extends AbstractLexerBasedConverter<Float> {
+
+	protected static final String FLOAT_SUFFIX = "f";
+
+	@Override
+	public Float toValue(String string, INode node) throws ValueConverterException {
+		if (Strings.isEmpty(string))
+			throw new ValueConverterException("Couldn't convert empty string to float.", node, null);
+		try {
+			if (string.endsWith(FLOAT_SUFFIX))
+				return Float.parseFloat(string.substring(0, string.length() - 1));
+			else
+				return Float.parseFloat(string);
+		} catch (NumberFormatException e) {
+			throw new ValueConverterException("Couldn't convert '" + string + "' to float.", node, null);
+		}
+	}
+
+	@Override
+	protected String toEscapedString(Float value) {
+		return super.toEscapedString(value) + FLOAT_SUFFIX;
+	}
+
+}

+ 224 - 219
plugins/org.yakindu.base.gmf.runtime/src/org/yakindu/base/gmf/runtime/editparts/TextAwareLabelEditPart.java

@@ -1,219 +1,224 @@
-/**
- * Copyright (c) 2010 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.base.gmf.runtime.editparts;
-
-import static org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR;
-
-import org.eclipse.draw2d.IFigure;
-import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.ecore.EAttribute;
-import org.eclipse.gef.DragTracker;
-import org.eclipse.gef.EditPolicy;
-import org.eclipse.gef.Request;
-import org.eclipse.gef.requests.SelectionRequest;
-import org.eclipse.gef.tools.DirectEditManager;
-import org.eclipse.gmf.runtime.common.ui.services.parser.IParser;
-import org.eclipse.gmf.runtime.common.ui.services.parser.ParserOptions;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.CompartmentEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.ITextAwareEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.editpolicies.LabelDirectEditPolicy;
-import org.eclipse.gmf.runtime.diagram.ui.label.ILabelDelegate;
-import org.eclipse.gmf.runtime.diagram.ui.label.WrappingLabelDelegate;
-import org.eclipse.gmf.runtime.diagram.ui.tools.TextDirectEditManager;
-import org.eclipse.gmf.runtime.draw2d.ui.figures.WrappingLabel;
-import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
-import org.eclipse.gmf.runtime.notation.ShapeStyle;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
-import org.eclipse.jface.viewers.ICellEditorValidator;
-import org.eclipse.swt.graphics.Color;
-import org.yakindu.base.gmf.runtime.parsers.StringAttributeParser;
-import org.yakindu.base.xtext.utils.gmf.directedit.DoubleClickDirectEditDragTracker;
-import org.yakindu.base.xtext.utils.gmf.directedit.DoubleClickDirectEditDragTracker.IDoubleClickCallback;
-import org.yakindu.base.xtext.utils.gmf.figures.SyntaxColoringLabel;
-
-/**
- * This is a common abstract base class for all Label which are
- * {@link ITextAwareEditPart}.
- * 
- * * This edit part is only to be used for labels inside a figure! for external
- * labels, use {@link TextAwareExternalLabelEditPart}
- * 
- * 
- * @author andreas muelder
- * 
- */
-public abstract class TextAwareLabelEditPart extends CompartmentEditPart
-		implements ITextAwareEditPart {
-
-	private final DirectEditManager manager;
-
-	protected final EAttribute feature;
-
-	protected final String pluginId;
-
-	public TextAwareLabelEditPart(View view, EAttribute feature, String pluginId) {
-		super(view);
-		this.feature = feature;
-		this.pluginId = pluginId;
-		manager = createDirectEditManager();
-	}
-
-	protected void updateLabelText() {
-		getWrappingLabel().setText(getEditText());
-	}
-
-	@Override
-	public void activate() {
-		super.activate();
-		updateLabelText();
-	}
-
-	protected DirectEditManager createDirectEditManager() {
-		return new TextDirectEditManager(this);
-	}
-
-	@Override
-	public Object getAdapter(@SuppressWarnings("rawtypes") Class key) {
-		if (key.equals(ILabelDelegate.class)) {
-			WrappingLabel wrappingLabel = getWrappingLabel();
-			if (wrappingLabel == null)
-				return super.getAdapter(key);
-			return new WrappingLabelDelegate(wrappingLabel);
-		}
-		return super.getAdapter(key);
-	}
-
-	@Override
-	protected void createDefaultEditPolicies() {
-		super.createDefaultEditPolicies();
-		installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE,
-				new LabelDirectEditPolicy());
-		// TODO: Add a Feedback role
-	}
-
-	@Override
-	protected void refreshVisuals() {
-		super.refreshVisuals();
-		refreshFont();
-		refreshFontColor();
-	}
-
-	@Override
-	protected void setFontColor(Color color) {
-		getWrappingLabel().setForegroundColor(color);
-	}
-
-	public String getEditText() {
-		return getParser().getEditString(
-				new EObjectAdapter(resolveSemanticElement()), -1);
-	}
-
-	public void setLabelText(String text) {
-		updateLabelText();
-	}
-
-	protected WrappingLabel getWrappingLabel() {
-		return (WrappingLabel) getFigure();
-	}
-
-	@Override
-	protected IFigure createFigure() {
-		return new SyntaxColoringLabel();
-	}
-
-	public ICellEditorValidator getEditTextValidator() {
-		return null;
-	}
-
-	public ParserOptions getParserOptions() {
-		return ParserOptions.NONE;
-	}
-
-	public IParser getParser() {
-		return new StringAttributeParser(feature, pluginId);
-	}
-
-	public IContentAssistProcessor getCompletionProcessor() {
-		return null;
-	}
-	/**
-	 * Performs direct edit on double click
-	 */
-	@Override
-	public DragTracker getDragTracker(final Request request) {
-		if (request instanceof SelectionRequest
-				&& ((SelectionRequest) request).getLastButtonPressed() == 3)
-			return null;
-		IDoubleClickCallback callback = new IDoubleClickCallback() {
-
-			@Override
-			public void handleDoubleClick(int btn) {
-				performDirectEditRequest(request);
-			}
-		};
-		return new DoubleClickDirectEditDragTracker(this,
-				getTopGraphicEditPart(), callback);
-	}
-
-	@Override
-	protected void performDirectEditRequest(Request request) {
-		final Request theRequest = request;
-		try {
-			getEditingDomain().runExclusive(new Runnable() {
-
-				public void run() {
-					if (isActive()) {
-						if (theRequest.getExtendedData().get(
-								REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR) instanceof Character
-								&& manager instanceof TextDirectEditManager) {
-							Character initialChar = (Character) theRequest
-									.getExtendedData()
-									.get(REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR);
-
-							((TextDirectEditManager) manager).show(initialChar);
-
-						} else {
-							manager.show();
-						}
-					}
-				}
-			});
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-	}
-
-	// We want to get notified about changes to the primary view, the refresh
-	// the visuals when the parent Shape style changes.
-	@Override
-	protected void addNotationalListeners() {
-		super.addNotationalListeners();
-		addListenerFilter("parentview", this, getPrimaryView());
-	}
-
-	@Override
-	protected void removeNotationalListeners() {
-		super.removeNotationalListeners();
-		removeListenerFilter("parentview");
-	}
-
-	@Override
-	protected void handleNotificationEvent(Notification event) {
-		if (event.getFeature() == feature) {
-			updateLabelText();
-		}
-		if (event.getNotifier() instanceof ShapeStyle) {
-			refreshVisuals();
-		}
-		super.handleNotificationEvent(event);
-	}
-}
+/**
+ * Copyright (c) 2010 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.base.gmf.runtime.editparts;
+
+import static org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants.REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR;
+
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.gef.DragTracker;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gef.Request;
+import org.eclipse.gef.requests.SelectionRequest;
+import org.eclipse.gef.tools.DirectEditManager;
+import org.eclipse.gmf.runtime.common.ui.services.parser.IParser;
+import org.eclipse.gmf.runtime.common.ui.services.parser.ParserOptions;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.CompartmentEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.ITextAwareEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.LabelDirectEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.label.ILabelDelegate;
+import org.eclipse.gmf.runtime.diagram.ui.label.WrappingLabelDelegate;
+import org.eclipse.gmf.runtime.diagram.ui.tools.TextDirectEditManager;
+import org.eclipse.gmf.runtime.draw2d.ui.figures.WrappingLabel;
+import org.eclipse.gmf.runtime.emf.core.util.EObjectAdapter;
+import org.eclipse.gmf.runtime.notation.ShapeStyle;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.viewers.ICellEditorValidator;
+import org.eclipse.swt.graphics.Color;
+import org.yakindu.base.gmf.runtime.parsers.StringAttributeParser;
+import org.yakindu.base.xtext.utils.gmf.directedit.DoubleClickDirectEditDragTracker;
+import org.yakindu.base.xtext.utils.gmf.directedit.DoubleClickDirectEditDragTracker.IDoubleClickCallback;
+import org.yakindu.base.xtext.utils.gmf.figures.SyntaxColoringLabel;
+
+/**
+ * This is a common abstract base class for all Label which are
+ * {@link ITextAwareEditPart}.
+ *
+ * * This edit part is only to be used for labels inside a figure! for external
+ * labels, use {@link TextAwareExternalLabelEditPart}
+ *
+ *
+ * @author andreas muelder
+ *
+ */
+public abstract class TextAwareLabelEditPart extends CompartmentEditPart implements ITextAwareEditPart {
+
+	private final DirectEditManager manager;
+
+	protected final EAttribute feature;
+
+	protected final String pluginId;
+
+	public TextAwareLabelEditPart(View view, EAttribute feature, String pluginId) {
+		super(view);
+		this.feature = feature;
+		this.pluginId = pluginId;
+		manager = createDirectEditManager();
+	}
+
+	protected void updateLabelText() {
+		getWrappingLabel().setText(getEditText());
+	}
+
+	@Override
+	public void activate() {
+		super.activate();
+		updateLabelText();
+	}
+
+	protected DirectEditManager createDirectEditManager() {
+		return new TextDirectEditManager(this);
+	}
+
+	@Override
+	public Object getAdapter(@SuppressWarnings("rawtypes") Class key) {
+		if (key.equals(ILabelDelegate.class)) {
+			WrappingLabel wrappingLabel = getWrappingLabel();
+			if (wrappingLabel == null)
+				return super.getAdapter(key);
+			return new WrappingLabelDelegate(wrappingLabel);
+		}
+		return super.getAdapter(key);
+	}
+
+	@Override
+	protected void createDefaultEditPolicies() {
+		super.createDefaultEditPolicies();
+		installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new LabelDirectEditPolicy());
+		// TODO: Add a Feedback role
+	}
+
+	@Override
+	protected void refreshVisuals() {
+		super.refreshVisuals();
+		refreshFont();
+		refreshFontColor();
+	}
+
+	@Override
+	protected void setFontColor(Color color) {
+		getWrappingLabel().setForegroundColor(color);
+	}
+
+	@Override
+	public String getEditText() {
+		return getParser().getEditString(new EObjectAdapter(resolveSemanticElement()), -1);
+	}
+
+	@Override
+	public void setLabelText(String text) {
+		updateLabelText();
+	}
+
+	protected WrappingLabel getWrappingLabel() {
+		return (WrappingLabel) getFigure();
+	}
+
+	@Override
+	protected IFigure createFigure() {
+		return new SyntaxColoringLabel();
+	}
+
+	@Override
+	public ICellEditorValidator getEditTextValidator() {
+		return null;
+	}
+
+	@Override
+	public ParserOptions getParserOptions() {
+		return ParserOptions.NONE;
+	}
+
+	@Override
+	public IParser getParser() {
+		return new StringAttributeParser(feature, pluginId);
+	}
+
+	public EAttribute getFeature() {
+		return feature;
+	}
+
+	@Override
+	public IContentAssistProcessor getCompletionProcessor() {
+		return null;
+	}
+	/**
+	 * Performs direct edit on double click
+	 */
+	@Override
+	public DragTracker getDragTracker(final Request request) {
+		if (request instanceof SelectionRequest && ((SelectionRequest) request).getLastButtonPressed() == 3)
+			return null;
+		IDoubleClickCallback callback = new IDoubleClickCallback() {
+
+			@Override
+			public void handleDoubleClick(int btn) {
+				performDirectEditRequest(request);
+			}
+		};
+		return new DoubleClickDirectEditDragTracker(this, getTopGraphicEditPart(), callback);
+	}
+
+	@Override
+	protected void performDirectEditRequest(Request request) {
+		final Request theRequest = request;
+		try {
+			getEditingDomain().runExclusive(new Runnable() {
+
+				@Override
+				public void run() {
+					if (isActive()) {
+						if (theRequest.getExtendedData()
+								.get(REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR) instanceof Character
+								&& manager instanceof TextDirectEditManager) {
+							Character initialChar = (Character) theRequest.getExtendedData()
+									.get(REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR);
+
+							((TextDirectEditManager) manager).show(initialChar);
+
+						} else {
+							manager.show();
+						}
+					}
+				}
+			});
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+	}
+
+	// We want to get notified about changes to the primary view, the refresh
+	// the visuals when the parent Shape style changes.
+	@Override
+	protected void addNotationalListeners() {
+		super.addNotationalListeners();
+		addListenerFilter("parentview", this, getPrimaryView());
+	}
+
+	@Override
+	protected void removeNotationalListeners() {
+		super.removeNotationalListeners();
+		removeListenerFilter("parentview");
+	}
+
+	@Override
+	protected void handleNotificationEvent(Notification event) {
+		if (event.getFeature() == feature) {
+			updateLabelText();
+		}
+		if (event.getNotifier() instanceof ShapeStyle) {
+			refreshVisuals();
+		}
+		super.handleNotificationEvent(event);
+	}
+}

+ 8 - 44
plugins/org.yakindu.base.xtext.utils.jface/src/org/yakindu/base/xtext/utils/jface/viewers/StyledTextXtextAdapter.java

@@ -13,7 +13,6 @@ package org.yakindu.base.xtext.utils.jface.viewers;
 import java.util.List;
 
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jface.bindings.keys.KeyStroke;
 import org.eclipse.jface.fieldassist.ControlDecoration;
 import org.eclipse.jface.resource.ImageDescriptor;
@@ -22,10 +21,7 @@ import org.eclipse.jface.text.contentassist.IContentAssistant;
 import org.eclipse.jface.text.source.AnnotationModel;
 import org.eclipse.jface.text.source.ICharacterPairMatcher;
 import org.eclipse.jface.text.source.ISharedTextColors;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
 import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.jface.viewers.StructuredSelection;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.StyledText;
 import org.eclipse.swt.events.DisposeEvent;
@@ -44,9 +40,6 @@ import org.eclipse.ui.texteditor.AnnotationPreference;
 import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
 import org.eclipse.ui.texteditor.MarkerAnnotationPreferences;
 import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
-import org.eclipse.xtext.nodemodel.ICompositeNode;
-import org.eclipse.xtext.nodemodel.ILeafNode;
-import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
 import org.eclipse.xtext.parser.IParseResult;
 import org.eclipse.xtext.resource.XtextResource;
 import org.eclipse.xtext.ui.editor.XtextEditor;
@@ -79,7 +72,7 @@ import com.google.inject.Provider;
  */
 @SuppressWarnings("restriction")
 public class StyledTextXtextAdapter {
-	
+
 	@Inject
 	private IPreferenceStoreAccess preferenceStoreAccess;
 	@Inject
@@ -189,7 +182,8 @@ public class StyledTextXtextAdapter {
 			if (this.site == null) {
 				site = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getSite();
 			}
-			XtextStyledTextSelectionProvider xtextStyledTextSelectionProvider = new XtextStyledTextSelectionProvider();
+			XtextStyledTextSelectionProvider xtextStyledTextSelectionProvider = new XtextStyledTextSelectionProvider(
+					this.styledText, getFakeResourceContext().getFakeResource());
 			ChangeSelectionProviderOnFocusGain listener = new ChangeSelectionProviderOnFocusGain(site,
 					xtextStyledTextSelectionProvider);
 			getStyledText().addFocusListener(listener);
@@ -197,7 +191,6 @@ public class StyledTextXtextAdapter {
 		} catch (NullPointerException ex) {
 			// Do nothing, not opened within editor context
 		}
-
 	}
 
 	private ControlDecoration createContentAssistDecoration(StyledText styledText) {
@@ -224,9 +217,8 @@ public class StyledTextXtextAdapter {
 	}
 
 	protected ValidationJob createValidationJob() {
-		return new ValidationJob(getValidator(), getXtextDocument(),
-				new AnnotationIssueProcessor(getXtextDocument(), getXtextSourceviewer().getAnnotationModel(), getResolutionProvider()),
-				CheckMode.FAST_ONLY);
+		return new ValidationJob(getValidator(), getXtextDocument(), new AnnotationIssueProcessor(getXtextDocument(),
+				getXtextSourceviewer().getAnnotationModel(), getResolutionProvider()), CheckMode.FAST_ONLY);
 	}
 
 	protected XtextFakeResourceContext createFakeResourceContext(Injector injector) {
@@ -234,7 +226,8 @@ public class StyledTextXtextAdapter {
 	}
 
 	protected XtextSourceViewer createXtextSourceViewer() {
-		final XtextSourceViewer result = new XtextSourceViewerEx(getStyledText(), getPreferenceStoreAccess().getPreferenceStore());
+		final XtextSourceViewer result = new XtextSourceViewerEx(getStyledText(),
+				getPreferenceStoreAccess().getPreferenceStore());
 		result.configure(getXtextSourceViewerConfiguration());
 		result.setDocument(getXtextDocument(), new AnnotationModel());
 		return result;
@@ -388,36 +381,7 @@ public class StyledTextXtextAdapter {
 		return this.xtextStyledTextHighlightingHelper;
 	}
 
-	protected class XtextStyledTextSelectionProvider implements ISelectionProvider {
-		
-		public void setSelection(ISelection selection) {
-		}
-
-		public void removeSelectionChangedListener(ISelectionChangedListener listener) {
-		}
-
-		public void addSelectionChangedListener(ISelectionChangedListener listener) {
-		}
-
-		public ISelection getSelection() {
-			if (getStyledText().isDisposed())
-				return StructuredSelection.EMPTY;
-			int offset = getStyledText().getCaretOffset() - 1;
-			XtextResource fakeResource = StyledTextXtextAdapter.this.getFakeResourceContext().getFakeResource();
-			IParseResult parseResult = fakeResource.getParseResult();
-			if (parseResult == null)
-				return StructuredSelection.EMPTY;
-			ICompositeNode rootNode = parseResult.getRootNode();
-			ILeafNode selectedNode = NodeModelUtils.findLeafNodeAtOffset(rootNode, offset);
-			final EObject selectedObject = NodeModelUtils.findActualSemanticObjectFor(selectedNode);
-			if (selectedObject == null) {
-				return StructuredSelection.EMPTY;
-			}
-			return new StructuredSelection(selectedObject);
-		}
-	}
-
-	protected class ChangeSelectionProviderOnFocusGain implements FocusListener, DisposeListener {
+	public static class ChangeSelectionProviderOnFocusGain implements FocusListener, DisposeListener {
 
 		protected ISelectionProvider selectionProviderOnFocusGain;
 		protected ISelectionProvider selectionProviderOnFocusLost;

+ 61 - 0
plugins/org.yakindu.base.xtext.utils.jface/src/org/yakindu/base/xtext/utils/jface/viewers/XtextStyledTextSelectionProvider.java

@@ -0,0 +1,61 @@
+/** 
+ * Copyright (c) 2018 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.base.xtext.utils.jface.viewers;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.xtext.nodemodel.ICompositeNode;
+import org.eclipse.xtext.nodemodel.ILeafNode;
+import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
+import org.eclipse.xtext.parser.IParseResult;
+import org.eclipse.xtext.resource.XtextResource;
+
+
+public class XtextStyledTextSelectionProvider implements ISelectionProvider {
+
+	private StyledText styledText;
+	private XtextResource xtextResource;
+
+	public XtextStyledTextSelectionProvider(StyledText styledText, XtextResource xtextResource) {
+		this.styledText = styledText;
+		this.xtextResource = xtextResource;
+	}
+
+	public void setSelection(ISelection selection) {
+	}
+
+	public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+	}
+
+	public void addSelectionChangedListener(ISelectionChangedListener listener) {
+	}
+
+	public ISelection getSelection() {
+		if (styledText.isDisposed())
+			return StructuredSelection.EMPTY;
+		int offset = styledText.getCaretOffset() - 1;
+		XtextResource fakeResource = xtextResource;
+		IParseResult parseResult = fakeResource.getParseResult();
+		if (parseResult == null)
+			return StructuredSelection.EMPTY;
+		ICompositeNode rootNode = parseResult.getRootNode();
+		ILeafNode selectedNode = NodeModelUtils.findLeafNodeAtOffset(rootNode, offset);
+		final EObject selectedObject = NodeModelUtils.findActualSemanticObjectFor(selectedNode);
+		if (selectedObject == null) {
+			return StructuredSelection.EMPTY;
+		}
+		return new StructuredSelection(selectedObject);
+	}
+}

+ 2 - 1
plugins/org.yakindu.sct.doc.user/image-tools/create_grammar_images.sh

@@ -192,7 +192,8 @@ create_grammar_image operation \
 # Assertion
 create_grammar_image assertion \
     assertionstatement \
-    verifystatement
+    positiveverifystatement \
+    negativeverifystatement
 
 # Process
 create_grammar_image proceed \

二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_010_sctunit.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_ifexpression.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_loopstatement.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_negativeverifystatement.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_positiveverifystatement.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_primaryexpression.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_proceedunit.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_returnstatement.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_sctunitclass.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_sctunitoperation.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_sctunitvariabledefinition.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_teststatement.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_020_verifystatement.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_030_assertion.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_030_operation.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_grammar_030_test_unit.png


二进制
plugins/org.yakindu.sct.doc.user/src/user-guide/images/sctunit_outgoing_event_010.png


+ 53 - 14
plugins/org.yakindu.sct.doc.user/src/user-guide/sctunit.textile

@@ -299,9 +299,9 @@ bc.
 
 ==</div>==
 
-p. The _header_ of an operation consists of an optional annotation, typically <code>&#x40;Test</code>, followed by the keyword @operation@, followed by the name of the operation, followed by a parenthesized list of parameters, optionally followed by a colon and a return type.
+p. The _header_ of an operation consists of an optional annotation, typically <code>&#x40;Test</code>, followed by the keyword @operation@, followed by the name of the operation, followed by a parenthesized list of parameters, optionally followed by a colon and a return type. If no return type is specified, it is inferred from the operation's "_return_ statement(s)":#sctunit_returning_an_operations_result.
 
-The _body_ of an operation is enclosed in braces (<code>{ … }</code>). It consists of a sequence of "statements":#sctunit_statements_and_expressions, which may be empty.
+The _body_ of an operation is enclosed in braces (<code>{ … }</code>). It consists of a sequence of "statements":#sctunit_statements_and_expressions, which may be empty. If the operation's header specifies a return type different from @void@, the operation must return a value of that type, using the "_return_ statement":#sctunit_returning_an_operations_result.
 
 Figure "&quot;Operation grammar&quot;":#sctunit_fig_operation_grammar summarizes the structure of an operation:
 
@@ -407,10 +407,57 @@ In the second variant of the _assert called_ statement the keyword @with@ follow
 
 ==<!-- End sctunit_keyword_called -->==
 
+h5. Asserting an outgoing event
+
+Finally, you can use the _assert_ statement to check whether the state machine has raised an outgoing event. To do so, the @assert@ keyword is followed by the name of the desired event. It is also possible to assert the opposite, i.e., that the event has _not_ been raised. In this case, insert the negation operator @!@ between @assert@ and the event name.
+
+Here's an example:
+
+==<div class="example">==
+
+The statechart below transitions from state *A* to state *B* on either the _e1_ or the _e2_ incoming event. However, on _e1_, the outgoing event _e3_ will be raised, while this is not the case on _e2_.
+
+p(#sctunit_fig_statechart_raising_an_outgoing_event). 
+!(small)images/sctunit_outgoing_event_010.png(Statechart raising an outgoing event)!
+
+p=. Statechart raising an outgoing event
+
+You can verify this behavior using the following SCTUnit test class. The statement
+* @assert e3@
+succeeds if the _e3_ event has been raised, while
+* @assert ! e3@
+succeeds if that event has _not_ been raised.
+
+bc.. 
+testclass outgoingEventTest for statechart raiseOutgoingEvent {
+
+    @Test
+    operation test_e1 () {
+        enter
+        raise e1
+        proceed 1 cycle
+        assert e3
+        exit
+    }
+
+    @Test
+    operation test_e2 () {
+        enter
+        raise e2
+        proceed 1 cycle
+        assert ! e3
+        exit
+    }
+}
+p. 
+
+==</div>==
+
+h5. Assertion grammar
+
 Figure "&quot;Assertion grammar&quot;":#sctunit_fig_assertion_grammar summarizes the structure of an assertion:
 
 p(#sctunit_fig_assertion_grammar). 
-
 !images/sctunit_grammar_030_assertion.png(Assertion grammar)!
 
 p=. Assertion grammar
@@ -432,7 +479,7 @@ The _enter_ statement's grammar is very simple, as figure "&quot;Enter grammar&q
 
 p(#sctunit_fig_enter_grammar). 
 
-!images/sctunit_grammar_020_enterexpression.png(Enter grammar)!
+!(tiny)images/sctunit_grammar_020_enterexpression.png(Enter grammar)!
 
 p=. Enter grammar
 
@@ -493,7 +540,7 @@ The _exit_ statement's grammar is very simple, as figure "&quot;Exit grammar&quo
 
 p(#sctunit_fig_exit_grammar). 
 
-!images/sctunit_grammar_020_exitexpression.png(Exit grammar)!
+!(tiny)images/sctunit_grammar_020_exitexpression.png(Exit grammar)!
 
 p=. Exit grammar
 
@@ -587,14 +634,6 @@ is fine in the statechart language, it is an error in the SCTUnit language. You
 
 bc. var sum: integer = 0
 
-Figure "&quot;Variable definition grammar&quot;":#sctunit_fig_variable_definition_grammar summarizes the structure of a _variable definition_:
-
-p(#sctunit_fig_variable_definition_grammar). 
-
-!images/sctunit_grammar_020_sctunitvariabledefinition.png(Variable definition grammar)!
-
-p=. Variable definition grammar
-
 ==<!-- End sctunit_keyword_var -->==
 
 
@@ -815,7 +854,7 @@ h4(#sctunit_returning_an_operations_result). Returning an operation's result
 
 ==<!-- Start sctunit_keyword_return -->==
 
-The _return_ statement terminates the execution of the current operation and returns the value of an expression to the caller. The type of the expression must match the operation's return type.
+The _return_ statement terminates the execution of the current operation. It either returns nothing or the value of an expression to the caller. If an expression is returned, its type must match the operation's return type. If the operation returns nothing, its return type must be _void_, either implicitly or explicitly.
 
 ==<div class="example">==
 

+ 13 - 1
plugins/org.yakindu.sct.generator.genmodel.ui/src/org/yakindu/sct/generator/genmodel/ui/outline/SGenOutlineTreeProvider.java

@@ -10,12 +10,24 @@
 */
 package org.yakindu.sct.generator.genmodel.ui.outline;
 
+import org.eclipse.xtext.ui.editor.outline.IOutlineNode;
 import org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider;
+import org.yakindu.base.base.NamedElement;
+import org.yakindu.sct.model.sgen.GeneratorEntry;
 
 /**
  * customization of the default outline structure
  * 
  */
 public class SGenOutlineTreeProvider extends DefaultOutlineTreeProvider {
-	
+
+	protected void _createNode(IOutlineNode parentNode, GeneratorEntry modelElement) {
+		String name = modelElement.getContentType();
+		if (modelElement.getElementRef() instanceof NamedElement) {
+			name = name + " " + ((NamedElement) modelElement.getElementRef()).getName();
+		}
+		createEObjectNode(parentNode, modelElement, imageDispatcher.invoke(modelElement), name,
+				isLeafDispatcher.invoke(modelElement));
+	}
+
 }

+ 2 - 3
plugins/org.yakindu.sct.model.sgraph.ui/src/org/yakindu/sct/model/sgraph/ui/validation/ISctIssueCreator.java

@@ -6,7 +6,7 @@
  * http://www.eclipse.org/legal/epl-v10.html
  * Contributors:
  * 	committers of YAKINDU - initial API and implementation
- * 
+ *
  */
 package org.yakindu.sct.model.sgraph.ui.validation;
 
@@ -21,8 +21,7 @@ import com.google.inject.ImplementedBy;
 @ImplementedBy(SctIssueCreator.class)
 public interface ISctIssueCreator {
 
-    SCTIssue createFromMarker(IMarker marker, String elementID);
+	SCTIssue createFromMarker(IMarker marker, String elementID);
 
 	SCTIssue create(Issue t, String uriFragment);
-    
 }

+ 5 - 4
plugins/org.yakindu.sct.model.sgraph.ui/src/org/yakindu/sct/model/sgraph/ui/validation/SCTDiagnosticConverterImpl.java

@@ -6,7 +6,7 @@
  * http://www.eclipse.org/legal/epl-v10.html
  * Contributors:
  * 	committers of YAKINDU - initial API and implementation
- * 
+ *
  */
 package org.yakindu.sct.model.sgraph.ui.validation;
 
@@ -22,18 +22,19 @@ import org.yakindu.sct.model.sgraph.SpecificationElement;
 import com.google.inject.Inject;
 
 /**
- * 
+ *
  * @author andreas muelder - Initial contribution and API
- * 
+ *
  */
 public class SCTDiagnosticConverterImpl extends DiagnosticConverterImpl {
 
 	@Inject
 	ISctIssueCreator issueCreator;
-	
+
 	@Override
 	public void convertValidatorDiagnostic(final Diagnostic diagnostic, final IAcceptor<Issue> acceptor) {
 		super.convertValidatorDiagnostic(diagnostic, new IAcceptor<Issue>() {
+			@Override
 			public void accept(Issue t) {
 				boolean notAccepted = true;
 				if (diagnostic.getData().get(0) instanceof EObject) {

+ 14 - 4
plugins/org.yakindu.sct.model.sgraph.ui/src/org/yakindu/sct/model/sgraph/ui/validation/SCTIssue.java

@@ -6,7 +6,7 @@
  * http://www.eclipse.org/legal/epl-v10.html
  * Contributors:
  * 	committers of YAKINDU - initial API and implementation
- * 
+ *
  */
 package org.yakindu.sct.model.sgraph.ui.validation;
 
@@ -17,9 +17,9 @@ import org.eclipse.xtext.validation.Issue;
 import org.eclipse.xtext.validation.Issue.IssueImpl;
 
 /**
- * 
+ *
  * @author andreas muelder - Initial contribution and API
- * 
+ *
  */
 public class SCTIssue extends IssueImpl {
 
@@ -36,46 +36,56 @@ public class SCTIssue extends IssueImpl {
 		return semanticURI;
 	}
 
+	@Override
 	public Severity getSeverity() {
 		return delegate.getSeverity();
 	}
 
+	@Override
 	public String getMessage() {
 		return delegate.getMessage();
 	}
 
+	@Override
 	public String getCode() {
 		return delegate.getCode();
 	}
 
+	@Override
 	public CheckType getType() {
 		return delegate.getType();
 	}
 
+	@Override
 	public URI getUriToProblem() {
 		return delegate.getUriToProblem();
 	}
 
+	@Override
 	public Integer getLineNumber() {
 		return delegate.getLineNumber();
 	}
 
+	@Override
 	public Integer getOffset() {
 		return delegate.getOffset();
 	}
 
+	@Override
 	public Integer getLength() {
 		return delegate.getLength();
 	}
 
+	@Override
 	public boolean isSyntaxError() {
 		return delegate.isSyntaxError();
 	}
 
+	@Override
 	public String[] getData() {
 		return delegate.getData();
 	}
-	
+
 	@Override
 	public int hashCode() {
 		final int prime = 31;

+ 3 - 4
plugins/org.yakindu.sct.model.sgraph.ui/src/org/yakindu/sct/model/sgraph/ui/validation/SCTMarkerCreator.java

@@ -6,7 +6,7 @@
  * http://www.eclipse.org/legal/epl-v10.html
  * Contributors:
  * 	committers of YAKINDU - initial API and implementation
- * 
+ *
  */
 package org.yakindu.sct.model.sgraph.ui.validation;
 
@@ -17,9 +17,9 @@ import org.eclipse.xtext.ui.editor.validation.MarkerCreator;
 import org.eclipse.xtext.validation.Issue;
 
 /**
- * 
+ *
  * @author andreas muelder - Initial contribution and API
- * 
+ *
  */
 public class SCTMarkerCreator extends MarkerCreator {
 
@@ -30,5 +30,4 @@ public class SCTMarkerCreator extends MarkerCreator {
 			marker.setAttribute(SCTMarkerType.SEMANTIC_ELEMENT_ID, ((SCTIssue) issue).getSemanticURI());
 		}
 	}
-
 }

+ 2 - 3
plugins/org.yakindu.sct.model.sgraph.ui/src/org/yakindu/sct/model/sgraph/ui/validation/SCTMarkerType.java

@@ -6,7 +6,7 @@
  * http://www.eclipse.org/legal/epl-v10.html
  * Contributors:
  * 	committers of YAKINDU - initial API and implementation
- * 
+ *
  */
 package org.yakindu.sct.model.sgraph.ui.validation;
 
@@ -19,7 +19,6 @@ public interface SCTMarkerType {
 	public final static String NORMAL_VALIDATION = "org.yakindu.sct.ui.editor.diagnostic.normal"; //$NON-NLS-1$
 	public final static String EXPENSIVE_VALIDATION = "org.yakindu.sct.ui.editor.diagnostic.expensive"; //$NON-NLS-1$
 	public static final String SCT_TASK_TYPE = "org.yakindu.sct.ui.editor.task"; //$NON-NLS-1$
-	
+
 	public static final String SEMANTIC_ELEMENT_ID = org.eclipse.gmf.runtime.common.core.resources.IMarker.ELEMENT_ID;
-			
 }

+ 25 - 22
plugins/org.yakindu.sct.model.sgraph/src/org/yakindu/sct/model/sgraph/validation/SGraphJavaValidator.java

@@ -49,10 +49,10 @@ import com.google.inject.Inject;
  * This validator is intended to be used by a compositeValidator (See
  * {@link org.eclipse.xtext.validation.ComposedChecks}) of another language
  * specific validator. It does not register itself as an EValidator.
- * 
+ *
  * This validator checks for common graphical constraints for all kinds of state
  * charts.
- * 
+ *
  * @author terfloth
  * @author muelder
  * @author bohl - migrated to xtext infrastruture
@@ -85,24 +85,23 @@ public class SGraphJavaValidator extends AbstractDeclarativeValidator {
 	public static final String ISSUE_INITIAL_ENTRY_WITH_TRANSITION_TO_CONTAINER = "Outgoing transitions from entries can only target to sibling or inner states.";
 	public static final String ISSUE_STATECHART_NAME_NO_IDENTIFIER = "%s is not a valid identifier!";
 
-	
 	@Check(CheckType.FAST)
 	public void vertexNotReachable(final Vertex vertex) {
 		if (!(vertex instanceof Entry)) {
 
-			final Set<Object> stateScopeSet = new HashSet<Object>();
+			final Set<Object> stateScopeSet = new HashSet<>();
 			for (EObject obj : EcoreUtil2.eAllContents(vertex)) {
 				stateScopeSet.add(obj);
 			}
 			stateScopeSet.add(vertex);
 
-			final List<Object> externalPredecessors = new ArrayList<Object>();
+			final List<Object> externalPredecessors = new ArrayList<>();
 
 			DFS dfs = new DFS() {
 
 				@Override
 				public Iterator<Object> getElementLinks(Object element) {
-					List<Object> elements = new ArrayList<Object>();
+					List<Object> elements = new ArrayList<>();
 
 					if (element instanceof org.yakindu.sct.model.sgraph.State) {
 						if (!stateScopeSet.contains(element)) {
@@ -155,7 +154,8 @@ public class SGraphJavaValidator extends AbstractDeclarativeValidator {
 	@Check(CheckType.FAST)
 	public void nameIsNotEmpty(org.yakindu.sct.model.sgraph.State state) {
 		if ((state.getName() == null || state.getName().trim().length() == 0) && !(state instanceof FinalState)) {
-			error(ISSUE_STATE_WITHOUT_NAME, state, null, -1);
+			error(ISSUE_STATE_WITHOUT_NAME, state, null, -1, ISSUE_STATE_WITHOUT_NAME,
+					BasePackage.Literals.NAMED_ELEMENT__NAME.getName());
 		}
 	}
 
@@ -213,7 +213,7 @@ public class SGraphJavaValidator extends AbstractDeclarativeValidator {
 
 	/**
 	 * Exit nodes in top level regions are not supported.
-	 * 
+	 *
 	 * @param exit
 	 */
 	@Check(CheckType.FAST)
@@ -229,7 +229,7 @@ public class SGraphJavaValidator extends AbstractDeclarativeValidator {
 			error(ISSUE_SYNCHRONIZATION_TRANSITION_OUTGOING, sync, null, -1);
 		}
 	}
-	
+
 	@Check(CheckType.FAST)
 	public void synchronizationTransitionCount(Synchronization sync) {
 		int in = sync.getIncomingTransitions().size();
@@ -259,7 +259,7 @@ public class SGraphJavaValidator extends AbstractDeclarativeValidator {
 	/**
 	 * Checks if all composite states that are siblings of a shallow history can
 	 * enter their regions.
-	 * 
+	 *
 	 * @param e
 	 */
 	@Check(CheckType.FAST)
@@ -268,7 +268,7 @@ public class SGraphJavaValidator extends AbstractDeclarativeValidator {
 		if (e.getKind() == EntryKind.SHALLOW_HISTORY) {
 
 			// get all regions off all sibling states
-			List<Region> regions = new ArrayList<Region>();
+			List<Region> regions = new ArrayList<>();
 			for (Vertex v : e.getParentRegion().getVertices()) {
 				if (v instanceof org.yakindu.sct.model.sgraph.State) {
 					org.yakindu.sct.model.sgraph.State state = (org.yakindu.sct.model.sgraph.State) v;
@@ -339,34 +339,35 @@ public class SGraphJavaValidator extends AbstractDeclarativeValidator {
 			error(ISSUE_SYNCHRONIZATION_TARGET_STATES_NOT_ORTHOGONAL, sync, null, -1);
 		}
 	}
-	
+
 	@Check
 	public void orthogonalSynchronizedTransition(Synchronization sync) {
 
 		List<Transition> incoming = sync.getIncomingTransitions();
-		List<List<EObject>> inAncestorsList = new ArrayList<List<EObject>>();
+		List<List<EObject>> inAncestorsList = new ArrayList<>();
 		for (Transition trans : incoming) {
 			inAncestorsList.add(collectAncestors(trans.getSource(), new ArrayList<EObject>()));
 		}
 
 		List<Transition> outgoing = sync.getOutgoingTransitions();
-		List<List<EObject>> outAncestorsList = new ArrayList<List<EObject>>();
+		List<List<EObject>> outAncestorsList = new ArrayList<>();
 		for (Transition trans : outgoing) {
 			outAncestorsList.add(collectAncestors(trans.getTarget(), new ArrayList<EObject>()));
 		}
 
-		Set<Transition> inOrthogonal = new HashSet<Transition>();
-		Set<Transition> outOrthogonal = new HashSet<Transition>();
-		
-		if(incoming.size() == 0 || outgoing.size() == 0) {
+		Set<Transition> inOrthogonal = new HashSet<>();
+		Set<Transition> outOrthogonal = new HashSet<>();
+
+		if (incoming.size() == 0 || outgoing.size() == 0) {
 			return;
 		}
 
 		for (int i = 0; i < incoming.size(); i++) {
 			for (int j = 0; j < outgoing.size(); j++) {
 
-				List<Vertex> states = new ArrayList<>(Arrays.asList(incoming.get(i).getSource(), outgoing.get(j).getTarget()));
-				
+				List<Vertex> states = new ArrayList<>(
+						Arrays.asList(incoming.get(i).getSource(), outgoing.get(j).getTarget()));
+
 				if (areOrthogonal(states)) {
 					inOrthogonal.add(incoming.get(i));
 					outOrthogonal.add(outgoing.get(j));
@@ -387,11 +388,12 @@ public class SGraphJavaValidator extends AbstractDeclarativeValidator {
 	@Check
 	public void checkStatechartNameIsIdentifier(Statechart statechart) {
 		if (!isValidJavaIdentifier(statechart.getName())) {
-			error(String.format(ISSUE_STATECHART_NAME_NO_IDENTIFIER, statechart.getName()), statechart, BasePackage.Literals.NAMED_ELEMENT__NAME, -1);
+			error(String.format(ISSUE_STATECHART_NAME_NO_IDENTIFIER, statechart.getName()), statechart,
+					BasePackage.Literals.NAMED_ELEMENT__NAME, -1);
 
 		}
 	}
-	
+
 	protected boolean isValidJavaIdentifier(String s) {
 		if (s == null || s.length() == 0) {
 			return false;
@@ -415,6 +417,7 @@ public class SGraphJavaValidator extends AbstractDeclarativeValidator {
 		return false;
 	}
 
+	@Override
 	@Inject
 	public void register(EValidatorRegistrar registrar) {
 		// Do not register because this validator is only a composite #398987

+ 19 - 13
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/validation/STextNamesAreUniqueValidationHelper.java

@@ -71,21 +71,24 @@ public class STextNamesAreUniqueValidationHelper extends NamesAreUniqueValidatio
 	protected void checkDescriptionForDuplicatedName(IEObjectDescription description,
 			ValidationMessageAcceptor acceptor) {
 		QualifiedName qName = description.getName();
-		IEObjectDescription put = nameMap.put(qName, description);
-		IEObjectDescription lowerCasePut = caseInsensitiveMap.put(qName.toLowerCase(), description);
-		IEObjectDescription lastElementPut = lastElementMap.put(qName.getLastSegment(), description);
-		if (put != null) {
-			EClass common = checkForCommonSuperClass(put, description);
-			if (common != null) {
-				duplicateFQN(description, put, common, acceptor);
+		IEObjectDescription existing = nameMap.put(qName, description);
+		IEObjectDescription existingLowerCase = caseInsensitiveMap.put(qName.toLowerCase(), description);
+    IEObjectDescription existingLastElement = lastElementMap.put(qName.getLastSegment(), description);
+		if (existing != null) {
+			EClass common = checkForCommonSuperClass(existing, description);
+			if (inSameResource(existing, description) && common != null) {
+				createDuplicateNameError(description, common, acceptor);
+				createDuplicateNameError(existing, common, acceptor);
 			}
-		} else if (lowerCasePut != null) {
-			if (lowerCasePut.getEClass().equals(description.getEClass())) {
-				duplicateCaseInsensitiveFQN(description, lowerCasePut, acceptor);
+		} else if (existingLowerCase != null) {
+			if (inSameResource(existingLowerCase, description)
+					&& existingLowerCase.getEClass().equals(description.getEClass())) {
+				createDuplicateNameWarning(description, description.getEClass(), acceptor);
+				createDuplicateNameWarning(existingLowerCase, description.getEClass(), acceptor);
 			}
 		}
-		if (lastElementPut != null) {
-			duplicateLastElement(description, lastElementPut, acceptor);
+		if (existingLastElement != null) {
+			duplicateLastElement(description, existingLastElement, acceptor);
 		}
 	}
 
@@ -105,6 +108,10 @@ public class STextNamesAreUniqueValidationHelper extends NamesAreUniqueValidatio
 		createDuplicateNameError(old, common, acceptor);
 	}
 
+	protected boolean inSameResource(IEObjectDescription one, IEObjectDescription two) {
+		return one.getEObjectOrProxy().eResource().equals(two.getEObjectOrProxy().eResource());
+	}
+
 	protected void createDuplicateNameWarning(IEObjectDescription description, EClass eClass,
 			ValidationMessageAcceptor acceptor) {
 		EObject object = description.getEObjectOrProxy();
@@ -120,7 +127,6 @@ public class STextNamesAreUniqueValidationHelper extends NamesAreUniqueValidatio
 	}
 
 	protected EClass checkForCommonSuperClass(IEObjectDescription one, IEObjectDescription two) {
-
 		List<EClass> flatOne = buildSuperClassList(one.getEClass());
 		List<EClass> flatTwo = buildSuperClassList(two.getEClass());
 

+ 1 - 1
plugins/org.yakindu.sct.ui.editor/plugin.xml

@@ -920,7 +920,7 @@
  <extension
        point="org.eclipse.ui.elementFactories">
     <factory
-          class="org.yakindu.sct.ui.editor.DiagramEditorInputFactory"
+          class="org.yakindu.sct.ui.editor.partitioning.DiagramEditorInputFactory"
           id="org.yakindu.sct.ui.editor.DiagramEditorInputFactory">
     </factory>
  </extension>

+ 43 - 0
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/definitionsection/ReleaseSelectionOnFocusGain.java

@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2018 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.ui.editor.definitionsection;
+
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.yakindu.base.xtext.utils.jface.viewers.StyledTextXtextAdapter;
+
+/**
+ * Extends {@link StyledTextXtextAdapter.ChangeSelectionProviderOnFocusGain} to
+ * be able to release selection of previous selection provider. This in needed
+ * to be able to perform keyboard shortcuts on the text in the statechart
+ * definition section without interacting with the elements of the diagram.
+ * 
+ * @author robert rudi - Initial contribution and API
+ */
+public class ReleaseSelectionOnFocusGain extends StyledTextXtextAdapter.ChangeSelectionProviderOnFocusGain {
+
+	public ReleaseSelectionOnFocusGain(IWorkbenchPartSite site, ISelectionProvider selectionProviderOnFocusGain) {
+		super(site, selectionProviderOnFocusGain);
+	}
+
+	public void focusGained(FocusEvent e) {
+		releaseSelection();
+		super.focusGained(e);
+	}
+
+	protected void releaseSelection() {
+		if (site != null && this.selectionProviderOnFocusGain != null
+				&& !site.getSelectionProvider().equals(selectionProviderOnFocusGain))
+			site.getSelectionProvider().setSelection(StructuredSelection.EMPTY);
+	}
+}

+ 765 - 0
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/definitionsection/StatechartDefinitionSection.java

@@ -0,0 +1,765 @@
+/**
+ * Copyright (c) 2018 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.ui.editor.definitionsection;
+
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.databinding.IEMFValueProperty;
+import org.eclipse.emf.databinding.edit.EMFEditProperties;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.command.AddCommand;
+import org.eclipse.emf.edit.command.SetCommand;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.resources.editor.parts.DiagramDocumentEditor;
+import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.databinding.swt.ISWTObservableValue;
+import org.eclipse.jface.databinding.swt.WidgetProperties;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ST;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseTrackListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IPersistableEditor;
+import org.eclipse.ui.IPersistableElement;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.XMLMemento;
+import org.eclipse.xtext.EcoreUtil2;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.ui.editor.embedded.EmbeddedEditor;
+import org.eclipse.xtext.ui.editor.embedded.EmbeddedEditorFactory;
+import org.eclipse.xtext.ui.editor.embedded.EmbeddedEditorModelAccess;
+import org.eclipse.xtext.ui.editor.embedded.IEditedResourceProvider;
+import org.yakindu.base.base.BasePackage;
+import org.yakindu.base.base.NamedElement;
+import org.yakindu.base.xtext.utils.jface.viewers.FilteringMenuManager;
+import org.yakindu.base.xtext.utils.jface.viewers.XtextStyledTextSelectionProvider;
+import org.yakindu.base.xtext.utils.jface.viewers.context.XtextFakeResourceContext;
+import org.yakindu.sct.domain.extension.DomainRegistry;
+import org.yakindu.sct.domain.extension.IDomain;
+import org.yakindu.sct.model.sgraph.SGraphPackage;
+import org.yakindu.sct.model.sgraph.Statechart;
+import org.yakindu.sct.model.sgraph.util.ContextElementAdapter;
+import org.yakindu.sct.model.sgraph.util.ContextElementAdapter.IContextElementProvider;
+import org.yakindu.sct.ui.editor.StatechartImages;
+import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil;
+import org.yakindu.sct.ui.editor.propertysheets.ValidatingEMFDatabindingContext;
+
+import com.google.inject.Injector;
+
+/**
+ * 
+ * @author robert rudi - Initial contribution and API
+ *
+ */
+@SuppressWarnings("restriction")
+public class StatechartDefinitionSection extends Composite
+		implements
+			IPersistableEditor,
+			IPersistableElement,
+			IContextElementProvider {
+
+	protected static final String INLINE_TOOLTIP = "Inline definition section";
+	protected static final String SHOW_SECTION_TOOLTIP = "Show definition section";
+	protected static final String HIDE_SECTION_TOOLTIP = "Hide definition section";
+
+	protected static final int SASH_WIDTH = 5;
+	protected static final int BORDERWIDTH = 2;
+	protected static final int MAXIMIZED_CONTROL_INDEX = 1;
+	protected static final String REGEX_NO_WORD_NO_WHITESPACE = "[^\\w[\\s+]]";
+	protected static final String MEM_EXPANDED = "DefinitionSectionIsExpanded";
+	protected static final String MEM_FIRST_WEIGHT = "FirstSashWeight";
+	protected static final String MEM_SECOND_WEIGHT = "SecondSashWeight";
+	protected static final int[] MIN_SIZE = {11, 21};
+	protected static final int[] DEFAULT_WEIGHTS = new int[]{2, 10};
+	protected int[] previousWidths = DEFAULT_WEIGHTS;
+	private boolean isSectionExpanded = true;
+
+	private MouseListener mouseListener;
+	private ResizeListener resizeListener;
+	private ModifyListener nameModificationListener;
+	private ReleaseSelectionOnFocusGain selectionProviderListener;
+
+	private Label switchControl;
+	private Composite labelComposite;
+	private CollapsedBorder collapsedBorder;
+	private InlineIcon inlineIcon;
+
+	private EmbeddedEditor embeddedEditor;
+	private XtextResource xtextResource;
+	private SashForm sash;
+	private DiagramDocumentEditor editorPart;
+
+	private static IMemento memento;
+
+	public StatechartDefinitionSection(Composite parent, int style, DiagramDocumentEditor editorPart) {
+		super(parent, style);
+		this.sash = (SashForm) parent;
+		this.editorPart = editorPart;
+		this.switchControl = createSwitchControl();
+		this.labelComposite = createDefinitionSectionComponents();
+		this.embeddedEditor = createSpecificationEditor();
+		registerResizeListener();
+		GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(this);
+	}
+
+	protected Label createSwitchControl() {
+		Label switchControl = new Label(this, SWT.PUSH);
+		switchControl.setToolTipText(isSectionExpanded ? HIDE_SECTION_TOOLTIP : SHOW_SECTION_TOOLTIP);
+		switchControl.setImage(isSectionExpanded ? StatechartImages.COLLAPSE.image() : StatechartImages.EXPAND.image());
+		switchControl.setCursor(new Cursor(getDisplay(), SWT.CURSOR_HAND));
+		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).indent(-1, -1).hint(MIN_SIZE[0], MIN_SIZE[1])
+				.applyTo(switchControl);
+		mouseListener = new MouseAdapter() {
+			@Override
+			public void mouseUp(MouseEvent e) {
+				toggleExpandState();
+			}
+		};
+		switchControl.addMouseListener(mouseListener);
+		return switchControl;
+	}
+
+	protected Composite createDefinitionSectionComponents() {
+		Composite labelComposite = new Composite(this, SWT.NONE);
+		GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(labelComposite);
+		GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(labelComposite);
+		createNameLabel(labelComposite);
+		createInlineIcon(labelComposite);
+		createSeparator(this);
+		createCollapsedBorder(this);
+		return labelComposite;
+	}
+
+	protected void createNameLabel(Composite labelComposite) {
+		Text nameLabel = new Text(labelComposite, SWT.SINGLE | SWT.NORMAL);
+		GridDataFactory.fillDefaults().indent(5, 1).grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(nameLabel);
+		nameLabel.setText(getStatechartName());
+		nameLabel.setEditable(isStatechart());
+		nameLabel.setBackground(ColorConstants.white);
+		nameModificationListener = new ModifyListener() {
+			@Override
+			public void modifyText(ModifyEvent e) {
+				if (getContextObject() instanceof Statechart) {
+					getSash().setRedraw(false);
+					TransactionalEditingDomain domain = getTransactionalEditingDomain();
+					SetCommand command = new SetCommand(domain, getContextObject(),
+							BasePackage.Literals.NAMED_ELEMENT__NAME, nameLabel.getText());
+					domain.getCommandStack().execute(command);
+					refresh(nameLabel.getParent());
+					getSash().setRedraw(true);
+				}
+			}
+		};
+		nameLabel.addModifyListener(nameModificationListener);
+	}
+
+	protected String getStatechartName() {
+		Statechart statechart = EcoreUtil2.getContainerOfType(getContextObject(), Statechart.class);
+		Assert.isNotNull(statechart);
+		return statechart.getName();
+	}
+
+	protected void createInlineIcon(Composite labelComposite) {
+		inlineIcon = new InlineIcon(labelComposite, SWT.FILL);
+	}
+
+	protected boolean isStatechart() {
+		return getContextObject() instanceof Statechart;
+	}
+
+	protected void createSeparator(Composite definitionSection) {
+		Label separator = new Label(definitionSection, SWT.SEPARATOR | SWT.HORIZONTAL);
+		GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(separator);
+	}
+
+	protected void createCollapsedBorder(Composite definitionSection) {
+		collapsedBorder = new CollapsedBorder(definitionSection, SWT.NONE);
+		refresh(definitionSection);
+	}
+
+	protected void refresh(Composite comp) {
+		comp.layout(false, true);
+		comp.redraw();
+		comp.update();
+	}
+
+	protected EmbeddedEditor createSpecificationEditor() {
+		EmbeddedEditor embeddedEditor = createEmbeddedEditor();
+		EmbeddedEditorModelAccess modelAccess = embeddedEditor.createPartialEditor();
+		modelAccess.updateModel(((Statechart) getContextObject()).getSpecification());
+		GridDataFactory.fillDefaults().grab(true, true).span(2, 1).applyTo(embeddedEditor.getViewer().getControl());
+		initializeEmbeddedEditorWidget(embeddedEditor);
+		return embeddedEditor;
+	}
+
+	protected EmbeddedEditor createEmbeddedEditor() {
+		Injector embeddedEditorInjector = getEmbeddedStatechartSpecificationInjector();
+		EmbeddedEditorFactory instance = embeddedEditorInjector.getInstance(EmbeddedEditorFactory.class);
+		IEditedResourceProvider provider = getXtextResourceProvider(embeddedEditorInjector);
+		return instance.newEditor(provider).showErrorAndWarningAnnotations().withParent(this);
+	}
+
+	protected Injector getEmbeddedStatechartSpecificationInjector() {
+		IDomain domain = DomainRegistry.getDomain(getContextObject());
+		return domain.getInjector(IDomain.FEATURE_EDITOR, Statechart.class.getName());
+	}
+
+	protected IEditedResourceProvider getXtextResourceProvider(Injector injector) {
+		return new IEditedResourceProvider() {
+
+			@Override
+			public XtextResource createResource() {
+				XtextFakeResourceContext resource = new XtextFakeResourceContext(injector);
+				xtextResource = resource.getFakeResource();
+				xtextResource.eAdapters().add(new ContextElementAdapter(StatechartDefinitionSection.this));
+				return xtextResource;
+			}
+		};
+	}
+
+	protected void initializeEmbeddedEditorWidget(EmbeddedEditor embeddedEditor) {
+		StyledText embeddedEditorWidget = embeddedEditor.getViewer().getTextWidget();
+		embeddedEditorWidget.setAlwaysShowScrollBars(false);
+		embeddedEditorWidget.setSelection(0);
+		embeddedEditorWidget.setKeyBinding(SWT.MOD1 | SWT.KEY_MASK & 'a', ST.SELECT_ALL);
+		initXtextSelectionProvider(embeddedEditorWidget);
+		initBinding(embeddedEditorWidget);
+		initContextMenu(embeddedEditorWidget);
+	}
+
+	protected void initXtextSelectionProvider(StyledText embeddedEditorWidget) {
+		try {
+			XtextStyledTextSelectionProvider styledTextSelectionProvider = new XtextStyledTextSelectionProvider(
+					embeddedEditorWidget, xtextResource);
+			ReleaseSelectionOnFocusGain selectionChangeListener = new ReleaseSelectionOnFocusGain(
+					this.editorPart.getSite(), styledTextSelectionProvider);
+			embeddedEditorWidget.addFocusListener(selectionChangeListener);
+			embeddedEditorWidget.addDisposeListener(selectionChangeListener);
+		} catch (NullPointerException e) {
+			// do nothing, not opened within editor context
+		}
+	}
+
+	@SuppressWarnings({"unchecked", "rawtypes"})
+	protected void initBinding(StyledText embeddedEditorWidget) {
+		IEMFValueProperty modelProperty = EMFEditProperties.value(getTransactionalEditingDomain(),
+				SGraphPackage.Literals.SPECIFICATION_ELEMENT__SPECIFICATION);
+		ISWTObservableValue uiProperty = WidgetProperties.text(new int[]{SWT.FocusOut, SWT.Modify})
+				.observe(embeddedEditorWidget);
+		IObservableValue modelPropertyObservable = modelProperty.observe(getContextObject());
+		ValidatingEMFDatabindingContext context = new ValidatingEMFDatabindingContext(
+				(IContextElementProvider) editorPart, editorPart.getSite().getShell());
+		context.bindValue(uiProperty, modelPropertyObservable, null, null);
+	}
+
+	protected void initContextMenu(Control control) {
+		MenuManager menuManager = new FilteringMenuManager();
+		Menu contextMenu = menuManager.createContextMenu(control);
+		control.setMenu(contextMenu);
+		IWorkbenchPartSite site = editorPart.getSite();
+		if (site != null)
+			site.registerContextMenu("org.yakindu.base.xtext.utils.jface.viewers.StyledTextXtextAdapterContextMenu",
+					menuManager, site.getSelectionProvider());
+	}
+
+	protected void registerResizeListener() {
+		resizeListener = new ResizeListener();
+		getSash().addControlListener(resizeListener);
+		embeddedEditor.getViewer().getTextWidget().addControlListener(resizeListener);
+	}
+
+	protected TransactionalEditingDomain getTransactionalEditingDomain() {
+		return (TransactionalEditingDomain) editorPart.getAdapter(TransactionalEditingDomain.class);
+	}
+
+	@Override
+	public EObject getContextObject() {
+		return (EObject) editorPart.getAdapter(EObject.class);
+	}
+
+	protected Diagram getDiagram() {
+		return (Diagram) editorPart.getAdapter(Diagram.class);
+	}
+
+	protected void updateInlineStyle() {
+		TransactionalEditingDomain domain = getTransactionalEditingDomain();
+		Diagram diagram = getDiagram();
+		BooleanValueStyle inlineStyle = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(diagram);
+		if (inlineStyle == null) {
+			inlineStyle = DiagramPartitioningUtil.createInlineDefinitionSectionStyle();
+			addInlineStyle(inlineStyle, domain);
+		}
+		setInlineStyleValue(inlineStyle, domain);
+	}
+
+	protected void setInlineStyleValue(BooleanValueStyle inlineStyle, TransactionalEditingDomain domain) {
+		SetCommand command = new SetCommand(domain, inlineStyle,
+				NotationPackage.Literals.BOOLEAN_VALUE_STYLE__BOOLEAN_VALUE, !inlineStyle.isBooleanValue());
+		domain.getCommandStack().execute(command);
+	}
+
+	protected void addInlineStyle(BooleanValueStyle inlineStyle, TransactionalEditingDomain domain) {
+		AddCommand command = new AddCommand(domain, (View) getDiagram(), NotationPackage.Literals.VIEW__STYLES,
+				inlineStyle);
+		domain.getCommandStack().execute(command);
+	}
+
+	public void toggleDefinitionSection() {
+		getSash().setMaximizedControl(!isInlined() ? null : getSash().getChildren()[MAXIMIZED_CONTROL_INDEX]);
+	}
+
+	protected boolean isInlined() {
+		BooleanValueStyle style = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(getDiagram());
+		return style != null ? style.isBooleanValue() : true;
+	}
+
+	protected void collapseDefinitionSection() {
+		int parentWidth = getSash().getBounds().width;
+		int switchControlWidth = getSwitchControlWidth();
+		int[] sashWidths = getCollapsedSashWidths(parentWidth, switchControlWidth);
+		layoutDefinitionSection(0, sashWidths, false, 1);
+	}
+
+	protected void expandDefinitionSection() {
+		layoutDefinitionSection(SASH_WIDTH, previousWidths, true, 2);
+	}
+
+	protected int getSwitchControlWidth() {
+		return switchControl.getBounds().width + BORDERWIDTH;
+	}
+
+	protected int[] getCollapsedSashWidths(int parentWidth, int switchControlWidth) {
+		int diff = parentWidth - switchControlWidth;
+		if (diff < 0) {
+			return DEFAULT_WEIGHTS;
+		}
+		return new int[]{switchControlWidth, (diff % 2 != 0) ? diff - (1 + BORDERWIDTH) : diff};
+	}
+
+	protected void layoutDefinitionSection(int sashWidth, int[] weights, boolean visible, int hSpan) {
+		getSash().setRedraw(false);
+		getSash().setSashWidth(sashWidth);
+		getSash().setWeights(weights);
+		embeddedEditor.getViewer().getControl().setVisible(visible);
+		labelComposite.setVisible(visible);
+		if (visible)
+			refreshSwitchControl(HIDE_SECTION_TOOLTIP, StatechartImages.COLLAPSE.image());
+		else
+			refreshSwitchControl(SHOW_SECTION_TOOLTIP, StatechartImages.EXPAND.image());
+		layoutCollapsedBorder(hSpan);
+		layoutEmbeddedEditor(hSpan);
+		refresh(getSash());
+		getSash().setRedraw(true);
+	}
+
+	protected void toggleExpandState() {
+		getSash().setRedraw(false);
+		isSectionExpanded = !isSectionExpanded;
+		if (isSectionExpanded) {
+			expandDefinitionSection();
+		} else {
+			collapseDefinitionSection();
+		}
+		getSash().setRedraw(true);
+	}
+
+	protected void layoutEmbeddedEditor(int hSpan) {
+		((GridData) embeddedEditor.getViewer().getControl().getLayoutData()).horizontalSpan = hSpan;
+	}
+
+	protected void layoutCollapsedBorder(int hSpan) {
+		((GridData) collapsedBorder.getLayoutData()).horizontalSpan = hSpan;
+	}
+
+	protected void refreshSwitchControl(String tooltipText, Image image) {
+		switchControl.setToolTipText(tooltipText);
+		switchControl.setImage(image);
+	}
+
+	@Override
+	public void dispose() {
+		saveState(memento);
+		disposeEmbeddedEditor();
+		super.dispose();
+	}
+
+	protected void disposeEmbeddedEditor() {
+		if (mouseListener != null && switchControl != null && !switchControl.isDisposed()) {
+			switchControl.removeMouseListener(mouseListener);
+			mouseListener = null;
+			switchControl.dispose();
+			switchControl = null;
+		}
+		if (inlineIcon != null && !inlineIcon.isDisposed())
+			inlineIcon.dispose();
+
+		if (collapsedBorder != null && !collapsedBorder.isDisposed())
+			collapsedBorder.dispose();
+
+		if (embeddedEditor != null) {
+			StyledText embeddedEditorWidget = embeddedEditor.getViewer().getTextWidget();
+			if (embeddedEditorWidget != null && !embeddedEditorWidget.isDisposed()) {
+				if (resizeListener != null) {
+					embeddedEditorWidget.removeControlListener(resizeListener);
+					getSash().removeControlListener(resizeListener);
+					resizeListener = null;
+				}
+				if (selectionProviderListener != null) {
+					embeddedEditorWidget.removeFocusListener(selectionProviderListener);
+					embeddedEditorWidget.removeDisposeListener(selectionProviderListener);
+					selectionProviderListener = null;
+				}
+				embeddedEditorWidget.dispose();
+				embeddedEditorWidget = null;
+				embeddedEditor = null;
+			}
+		}
+		nameModificationListener = null;
+	}
+
+	public SashForm getSash() {
+		return this.sash;
+	}
+
+	protected void refreshEditorContents() {
+		((List<?>) ((DiagramEditPart) editorPart.getAdapter(DiagramEditPart.class)).getChildren()).forEach(part -> {
+			if (part instanceof EditPart)
+				((EditPart) part).refresh();
+		});
+	}
+
+	@Override
+	public String getFactoryId() {
+		return editorPart.getEditorInput().getPersistable().getFactoryId();
+	}
+
+	public void restoreSashWidths() {
+		if (memento == null) {
+			saveState(memento);
+		}
+		restoreState(memento);
+	}
+
+	@Override
+	public void saveState(IMemento memento) {
+		if (memento == null) {
+			memento = XMLMemento.createWriteRoot(getFactoryId());
+		}
+		setMementoProperties(memento);
+		saveCurrentMemento(memento);
+	}
+
+	@Override
+	public void restoreState(IMemento memento) {
+		if (getSash() != null && memento != null) {
+			Boolean hasMemento = getExpandProperty(memento);
+			if (hasMemento != null) {
+				previousWidths = getWeightProperties(memento);
+				isSectionExpanded = hasMemento.booleanValue();
+				refreshEditorContents();
+				saveCurrentMemento(memento);
+			} else {
+				saveState(memento);
+			}
+			getSash().setWeights(previousWidths);
+		}
+	}
+
+	protected void saveCurrentMemento(IMemento memento) {
+		StatechartDefinitionSection.memento = memento;
+	}
+
+	protected void setMementoProperties(IMemento memento) {
+		String sectionProperty = getSectionProperty(getContextObject());
+		memento.putInteger(sectionProperty + MEM_FIRST_WEIGHT, previousWidths[0]);
+		memento.putInteger(sectionProperty + MEM_SECOND_WEIGHT, previousWidths[1]);
+		memento.putBoolean(sectionProperty + MEM_EXPANDED, isSectionExpanded);
+	}
+
+	protected String getSectionProperty(EObject element) {
+		return stripElementName(((NamedElement) element).getName());
+	}
+
+	protected String stripElementName(String name) {
+		if (name != null)
+			return name.replaceAll(REGEX_NO_WORD_NO_WHITESPACE, "");
+		return "";
+	}
+
+	protected Boolean getExpandProperty(IMemento memento) {
+		String expandProperty = getSectionProperty(getContextObject()) + MEM_EXPANDED;
+		return memento.getBoolean(expandProperty);
+	}
+
+	protected int[] getWeightProperties(IMemento memento) {
+		String sectionProperty = getSectionProperty(getContextObject());
+		Integer first = memento.getInteger(sectionProperty + MEM_FIRST_WEIGHT);
+		Integer second = memento.getInteger(sectionProperty + MEM_SECOND_WEIGHT);
+		if (first != null && second != null)
+			return new int[]{first, second};
+		return DEFAULT_WEIGHTS;
+	}
+
+	/**
+	 * @author robert rudi - Initial contribution and API
+	 * 
+	 */
+	protected class ResizeListener extends ControlAdapter {
+
+		private static final int DELAY = 150;
+		private Job resizeFinishedJob = new Job("Resizing...") {
+
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				Display.getDefault().asyncExec(new Runnable() {
+
+					@Override
+					public void run() {
+						if (isDisposed() || getSash().isDisposed())
+							return;
+						if (isSectionExpanded) {
+							// save current weights so the widths can later be restored
+							previousWidths = getSash().getWeights();
+							saveState(memento);
+						} else {
+							// keep sash collapsed
+							if (getBounds().width != getSwitchControlWidth()) {
+								collapseDefinitionSection();
+							}
+						}
+					}
+				});
+				return Status.OK_STATUS;
+			}
+		};
+
+		@Override
+		public void controlResized(ControlEvent e) {
+			handleControlChanged();
+		}
+
+		@Override
+		public void controlMoved(ControlEvent e) {
+			handleControlChanged();
+		}
+
+		protected void handleControlChanged() {
+			resizeFinishedJob.cancel();
+			resizeFinishedJob.schedule(DELAY);
+		}
+	}
+
+	/**
+	 * @author robert rudi - Initial contribution and API
+	 * 
+	 */
+	protected class InlineIcon extends Composite implements MouseListener, MouseTrackListener, PaintListener {
+
+		private Cursor handCursor = new Cursor(getDisplay(), SWT.CURSOR_HAND);
+		private boolean iconHasFocus = false;
+		private Label icon;
+
+		public InlineIcon(Composite parent, int style) {
+			super(parent, style);
+			GridLayoutFactory.fillDefaults().applyTo(this);
+			icon = new Label(this, style);
+			icon.setCursor(handCursor);
+			icon.setImage(StatechartImages.PIN.image());
+			icon.setToolTipText(INLINE_TOOLTIP);
+			icon.setEnabled(isStatechart());
+			icon.addMouseListener(this);
+			icon.addMouseTrackListener(this);
+			icon.addPaintListener(this);
+		}
+
+		@Override
+		public void mouseUp(MouseEvent e) {
+			updateInlineStyle();
+			toggleDefinitionSection();
+			refreshEditorContents();
+			saveState(memento);
+		}
+
+		@Override
+		public void mouseDoubleClick(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseDown(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseHover(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseEnter(MouseEvent e) {
+			iconHasFocus = true;
+			icon.redraw();
+		}
+
+		@Override
+		public void mouseExit(MouseEvent e) {
+			iconHasFocus = false;
+			icon.redraw();
+		}
+
+		@Override
+		public void paintControl(PaintEvent e) {
+			if (iconHasFocus) {
+				drawIconBorder(this.icon, e.gc);
+			}
+		}
+
+		protected void drawIconBorder(Label icon, GC gc) {
+			Rectangle rect = new Rectangle(0, 0, icon.getBounds().width - 1, icon.getBounds().height - 1);
+			Transform t = new Transform(getDisplay());
+			gc.setTransform(t);
+			t.dispose();
+			gc.setForeground(ColorConstants.lightGray);
+			gc.drawRectangle(0, 0, rect.width, rect.height);
+		}
+
+		@Override
+		public void dispose() {
+			icon.removeMouseListener(this);
+			icon.removeMouseTrackListener(this);
+			icon.removePaintListener(this);
+			handCursor.dispose();
+			icon.dispose();
+			super.dispose();
+		}
+
+	}
+
+	/**
+	 * @author robert rudi - Initial contribution and API
+	 * 
+	 */
+	protected class CollapsedBorder extends Canvas implements MouseListener, MouseTrackListener, PaintListener {
+
+		private String text;
+		float rotationAngle = -90f;
+		private Font font = new Font(getDisplay(), "Segoe UI", 8, SWT.NORMAL);
+		private Cursor arrowCursor = new Cursor(getDisplay(), SWT.CURSOR_ARROW);
+		private Cursor handCursor = new Cursor(getDisplay(), SWT.CURSOR_HAND);
+
+		public CollapsedBorder(Composite parent, int style) {
+			super(parent, style);
+			setText("Definition section", font);
+			GridDataFactory.fillDefaults().grab(false, false).span(2, 1).hint(0, parent.getBounds().height)
+					.applyTo(this);
+			addPaintListener(this);
+			addMouseListener(this);
+			addMouseTrackListener(this);
+		}
+
+		public void setText(String string, Font font) {
+			this.text = string;
+			setFont(font);
+			refresh(this);
+		}
+		@Override
+		public void paintControl(PaintEvent e) {
+			int w = e.width;
+			int h = e.height;
+			Transform tr = new Transform(e.display);
+			tr.translate(w / 2, h / 2);
+			tr.rotate(rotationAngle);
+			e.gc.setTransform(tr);
+			tr.dispose();
+			int drawHeight = -w + 2;
+			e.gc.drawString(isSectionExpanded ? "" : text, 0, drawHeight % 2 != 0 ? drawHeight + 1 : drawHeight - 1);
+		}
+
+		@Override
+		public void mouseUp(MouseEvent e) {
+			if (!isSectionExpanded)
+				toggleExpandState();
+			setCursor(arrowCursor);
+		}
+
+		@Override
+		public void mouseDown(MouseEvent e) {
+			if (mouseListener != null && !isSectionExpanded)
+				toggleExpandState();
+		}
+
+		@Override
+		public void mouseEnter(MouseEvent e) {
+			setCursor((!isSectionExpanded) ? handCursor : arrowCursor);
+			setToolTipText((!isSectionExpanded) ? SHOW_SECTION_TOOLTIP : null);
+		}
+
+		@Override
+		public void mouseExit(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseHover(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseDoubleClick(MouseEvent e) {
+		}
+
+		@Override
+		public void dispose() {
+			removePaintListener(this);
+			removeMouseListener(this);
+			removeMouseTrackListener(this);
+			handCursor.dispose();
+			arrowCursor.dispose();
+			font.dispose();
+			super.dispose();
+		}
+	}
+}

+ 24 - 697
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/editor/StatechartDiagramEditor.java

@@ -13,7 +13,6 @@ package org.yakindu.sct.ui.editor.editor;
 import java.util.ArrayList;
 import java.util.Optional;
 
-import org.eclipse.core.databinding.observable.value.IObservableValue;
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
@@ -21,14 +20,7 @@ import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.draw2d.ColorConstants;
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.emf.databinding.IEMFValueProperty;
-import org.eclipse.emf.databinding.edit.EMFEditProperties;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.edit.command.AddCommand;
-import org.eclipse.emf.edit.command.SetCommand;
 import org.eclipse.emf.transaction.TransactionalEditingDomain;
 import org.eclipse.emf.transaction.util.TransactionUtil;
 import org.eclipse.gef.KeyHandler;
@@ -39,84 +31,39 @@ import org.eclipse.gef.ui.actions.ZoomInAction;
 import org.eclipse.gef.ui.actions.ZoomOutAction;
 import org.eclipse.gmf.runtime.common.ui.services.marker.MarkerNavigationService;
 import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
 import org.eclipse.gmf.runtime.diagram.ui.internal.parts.DiagramGraphicalViewerKeyHandler;
-import org.eclipse.gmf.runtime.diagram.ui.resources.editor.parts.DiagramDocumentEditor;
 import org.eclipse.gmf.runtime.gef.ui.internal.editparts.AnimatableZoomManager;
-import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
-import org.eclipse.gmf.runtime.notation.NotationPackage;
-import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.gmf.runtime.notation.Diagram;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.databinding.swt.ISWTObservableValue;
-import org.eclipse.jface.databinding.swt.WidgetProperties;
 import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.layout.GridLayoutFactory;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.FocusAdapter;
-import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.KeyAdapter;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseTrackAdapter;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Cursor;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Transform;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Canvas;
 import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorReference;
 import org.eclipse.ui.IEditorSite;
 import org.eclipse.ui.IFileEditorInput;
-import org.eclipse.ui.IMemento;
-import org.eclipse.ui.IWorkbenchPartSite;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.XMLMemento;
 import org.eclipse.ui.help.IWorkbenchHelpSystem;
 import org.eclipse.ui.ide.IGotoMarker;
 import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
 import org.eclipse.xtext.EcoreUtil2;
 import org.eclipse.xtext.ui.XtextProjectHelper;
-import org.yakindu.base.base.BasePackage;
 import org.yakindu.base.base.DomainElement;
-import org.yakindu.base.base.NamedElement;
 import org.yakindu.base.xtext.utils.gmf.resource.DirtyStateListener;
-import org.yakindu.base.xtext.utils.jface.viewers.FilteringMenuManager;
-import org.yakindu.base.xtext.utils.jface.viewers.StyledTextXtextAdapter;
-import org.yakindu.base.xtext.utils.jface.viewers.util.ActiveEditorTracker;
 import org.yakindu.sct.domain.extension.DomainRegistry;
 import org.yakindu.sct.domain.extension.DomainStatus;
 import org.yakindu.sct.domain.extension.DomainStatus.Severity;
 import org.yakindu.sct.domain.extension.IDomain;
-import org.yakindu.sct.model.sgraph.SGraphPackage;
 import org.yakindu.sct.model.sgraph.Statechart;
-import org.yakindu.sct.model.sgraph.util.ContextElementAdapter;
 import org.yakindu.sct.model.sgraph.util.ContextElementAdapter.IContextElementProvider;
 import org.yakindu.sct.ui.editor.DiagramActivator;
-import org.yakindu.sct.ui.editor.StatechartImages;
+import org.yakindu.sct.ui.editor.definitionsection.StatechartDefinitionSection;
 import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningEditor;
 import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil;
-import org.yakindu.sct.ui.editor.propertysheets.ValidatingEMFDatabindingContext;
 import org.yakindu.sct.ui.editor.proposals.ContentProposalViewerKeyHandler;
 import org.yakindu.sct.ui.editor.providers.ISCTOutlineFactory;
 import org.yakindu.sct.ui.editor.utils.HelpContextIds;
@@ -137,41 +84,14 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 
 	public static final String ID = "org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor";
 
-	protected static final String CANNOT_INLINE_SECTION = "Cannot be inlined for subdiagrams";
-	protected static final String DEFINITION_SECTION = "definition section";
-	protected static final String INLINE_SECTION = "Inline " + DEFINITION_SECTION;
-	protected static final String SHOW_SECTION = "Show " + DEFINITION_SECTION;
-	protected static final String HIDE_SECTION = "Hide " + DEFINITION_SECTION;
-
-	private static final int EDITOR_HORIZONTAL_MARGIN = 10;
-	private static final int EDITOR_VERTICAL_MARGIN = 10;
 	protected static final int INITIAL_PALETTE_SIZE = 175;
-	protected static final int[] MIN_SIZE = {11, 21};
-	protected static final int BORDERWIDTH = 2;
-	protected static boolean iconHasFocus = false;
-	protected int[] previousWidths = DEFAULT_WEIGHTS;
-	private boolean isSectionExpanded = true;
 
 	private KeyHandler keyHandler;
 	private DirtyStateListener domainAdapter;
 	private LiveValidationListener validationListener;
 	private IValidationIssueStore issueStore;
-	private SelectionListener selectionListener;
-	private ResizeListener resizeListener;
-	private IconPaintListener iconPaintListener;
-	private IconMouseListener iconMouseListener;
-	private IconMouseTrackListener iconMouseTrackListener;
-	private NameModificationListener nameModificationListener;
-	private CollapsedBorderMouseTrackListener collapsedBorderMouseTrackListener;
-	private CollapsedBorderMouseListener collapsedBorderMouseListener;
-	private EmbeddedEditorFocusListener embeddedEditorFocusListener;
-	private EmbeddedEditorKeyListener embeddedEditorKeyListener;
-
-	private Label switchControl;
-	private Composite labelComposite;
-	private CollapsedBorder collapsedBorder;
 
-	private StyledText embeddedEditor;
+	private StatechartDefinitionSection definitionSection;
 
 	public StatechartDiagramEditor() {
 		super(true);
@@ -274,11 +194,6 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 		return injector;
 	}
 
-	protected Injector getEmbeddedStatechartSpecificationInjector() {
-		IDomain domain = DomainRegistry.getDomain(getContextObject());
-		return domain.getInjector(IDomain.FEATURE_EDITOR, Statechart.class.getName());
-	}
-
 	protected void checkXtextNature() {
 		IFileEditorInput editorInput = (IFileEditorInput) getEditorInput();
 		IProject project = editorInput.getFile().getProject();
@@ -444,15 +359,10 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 		return ID;
 	}
 
-	@Override
-	public String getFactoryId() {
-		return getEditorInput().getPersistable().getFactoryId();
-	}
-
 	@Override
 	public void dispose() {
-		saveState(getMemento());
-
+		if (definitionSection != null && !definitionSection.isDisposed())
+			definitionSection.dispose();
 		if (validationListener != null) {
 			validationListener.dispose();
 		}
@@ -463,46 +373,9 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 		getEditingDomain().removeResourceSetListener(domainAdapter);
 		if (domainAdapter != null)
 			domainAdapter.dispose();
-
-		disposeEmbeddedEditor();
-
 		super.dispose();
 	}
 
-	protected void disposeEmbeddedEditor() {
-		if (selectionListener != null && switchControl != null && !switchControl.isDisposed()) {
-			switchControl.removeMouseListener(selectionListener);
-			selectionListener = null;
-			switchControl.dispose();
-			switchControl = null;
-		}
-
-		if (embeddedEditor != null && !embeddedEditor.isDisposed()) {
-			if (resizeListener != null) {
-				embeddedEditor.removeControlListener(resizeListener);
-				getSash().removeControlListener(resizeListener);
-				resizeListener = null;
-			}
-			if (embeddedEditorKeyListener != null) {
-				embeddedEditor.removeKeyListener(embeddedEditorKeyListener);
-				embeddedEditorKeyListener = null;
-			}
-			if (embeddedEditorFocusListener != null) {
-				embeddedEditor.removeFocusListener(embeddedEditorFocusListener);
-				embeddedEditorFocusListener = null;
-			}
-			embeddedEditor.dispose();
-			embeddedEditor = null;
-		}
-
-		iconMouseListener = null;
-		iconMouseTrackListener = null;
-		iconPaintListener = null;
-		nameModificationListener = null;
-		collapsedBorderMouseTrackListener = null;
-		collapsedBorderMouseListener = null;
-	}
-
 	@Override
 	protected int getInitialPaletteSize() {
 		return INITIAL_PALETTE_SIZE;
@@ -514,170 +387,41 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 			return createOutline(type);
 		} else if (IValidationIssueStore.class.equals(type)) {
 			return issueStore;
-		} else if (DiagramPartitioningEditor.class.equals(type)) {
-			return super.getAdapter(type);
+		} else if (EObject.class.equals(type)) {
+			return this.getContextObject();
+		} else if (TransactionalEditingDomain.class.equals(type)) {
+			return getTransactionalEditingDomain();
+		} else if (Diagram.class.equals(type)) {
+			return getDiagram();
+		} else if (DiagramEditPart.class.equals(type)) {
+			return getDiagramEditPart();
 		}
 		return super.getAdapter(type);
 	}
 
 	@Override
 	protected void createTextEditor(Composite parent) {
-		if (getContextObject() instanceof Statechart) {
-			Composite definitionSection = new Composite(parent, SWT.BORDER);
-			GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(definitionSection);
-
-			switchControl = createSwitchControl(definitionSection);
-			createDefinitionSectionLabels(definitionSection);
-			embeddedEditor = createEmbeddedEditor(definitionSection);
-
-			selectionListener = new SelectionListener(embeddedEditor);
-			switchControl.addMouseListener(selectionListener);
-
-			resizeListener = new ResizeListener(definitionSection);
-
-			parent.addControlListener(resizeListener);
-			embeddedEditor.addControlListener(resizeListener);
+		if (isStatechart()) {
+			definitionSection = new StatechartDefinitionSection(parent, SWT.BORDER, this);
 		}
 	}
 
-	/*
-	 * Need hook into part creation lifecycle because the Xtext controls depends on
-	 * the selection provider of IWorkbenchPartSite, so the Xtext enabling cannot be
-	 * done before or while the part is created.
-	 * 
-	 * @see org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningEditor#
-	 * createPartControl(org.eclipse.swt.widgets.Composite)
-	 */
 	@Override
 	public void createPartControl(Composite parent) {
 		super.createPartControl(parent);
-		if (getContextObject() instanceof Statechart) {
-			toggleDefinitionSection();
-			restoreSashWidths(getSash(), getMemento());
-			enableXtext(embeddedEditor);
-		}
-	}
+		toggleDefinitionSection();
 
-	@SuppressWarnings({"unchecked", "rawtypes"})
-	protected void enableXtext(StyledText xtextControl) {
-		final StyledTextXtextAdapter xtextAdapter = createXtextAdapter();
-		xtextAdapter.adapt((StyledText) xtextControl);
-		initContextMenu(xtextControl);
-		IEMFValueProperty modelProperty = EMFEditProperties.value(getEditingDomain(),
-				SGraphPackage.Literals.SPECIFICATION_ELEMENT__SPECIFICATION);
-		ISWTObservableValue uiProperty = WidgetProperties.text(new int[]{SWT.FocusOut, SWT.Modify})
-				.observe(xtextControl);
-		IObservableValue modelPropertyObservable = modelProperty.observe(
-				EcoreUtil.getObjectByType(getDiagram().eResource().getContents(), SGraphPackage.Literals.STATECHART));
-		ValidatingEMFDatabindingContext context = new ValidatingEMFDatabindingContext(this, getSite().getShell());
-		context.bindValue(uiProperty, modelPropertyObservable, null, null);
 	}
 
-	protected StyledTextXtextAdapter createXtextAdapter() {
-		final StyledTextXtextAdapter xtextAdapter = new StyledTextXtextAdapter(
-				getEmbeddedStatechartSpecificationInjector(), getSite());
-		xtextAdapter.getFakeResourceContext().getFakeResource().eAdapters().add(new ContextElementAdapter(this));
-		return xtextAdapter;
-	}
-
-	protected StyledText createEmbeddedEditor(Composite definitionSection) {
-		StyledText textControl = new StyledText(definitionSection, SWT.MULTI | SWT.V_SCROLL | SWT.WRAP);
-		GridDataFactory.fillDefaults().grab(true, true).indent(EDITOR_HORIZONTAL_MARGIN, EDITOR_VERTICAL_MARGIN)
-				.span(2, 1).applyTo(textControl);
-
-		textControl.setAlwaysShowScrollBars(false);
-		textControl.setBackground(ColorConstants.white);
-		embeddedEditorKeyListener = new EmbeddedEditorKeyListener();
-		embeddedEditorFocusListener = new EmbeddedEditorFocusListener();
-		textControl.addKeyListener(embeddedEditorKeyListener);
-		textControl.addFocusListener(embeddedEditorFocusListener);
-		return textControl;
-	}
-
-	protected void createDefinitionSectionLabels(Composite definitionSection) {
-		labelComposite = new Composite(definitionSection, SWT.NONE);
-		GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(labelComposite);
-		GridDataFactory.fillDefaults().grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(labelComposite);
-		createNameLabel(labelComposite);
-		createInlineIcon(labelComposite);
-		createSeparator(definitionSection);
-		createCollapsedBorder(definitionSection);
-	}
-
-	protected void createInlineIcon(Composite labelComposite) {
-		Label icon = new Label(labelComposite, SWT.FILL);
-		icon.setImage(StatechartImages.PIN.image());
-		icon.setToolTipText(INLINE_SECTION);
-		icon.setEnabled(getContextObject() instanceof Statechart);
-		labelComposite.setToolTipText(getInlineTooltipText());
-		GridDataFactory.fillDefaults().applyTo(icon);
-		iconMouseListener = new IconMouseListener();
-		iconMouseTrackListener = new IconMouseTrackListener(icon);
-		iconPaintListener = new IconPaintListener(icon);
-		icon.addMouseListener(iconMouseListener);
-		icon.addMouseTrackListener(iconMouseTrackListener);
-		icon.addPaintListener(iconPaintListener);
-	}
-
-	protected String getInlineTooltipText() {
-		return (getContextObject() instanceof Statechart) ? INLINE_SECTION : CANNOT_INLINE_SECTION;
-	}
-
-	protected SetCommand setBooleanValueStyle(BooleanValueStyle inlineStyle, TransactionalEditingDomain domain) {
-		SetCommand command = new SetCommand(domain, inlineStyle,
-				NotationPackage.Literals.BOOLEAN_VALUE_STYLE__BOOLEAN_VALUE, !inlineStyle.isBooleanValue());
-		return command;
-	}
-
-	protected AddCommand addBooleanValueStyle(View view, BooleanValueStyle inlineStyle,
-			TransactionalEditingDomain domain) {
-		AddCommand command = new AddCommand(domain, view, NotationPackage.Literals.VIEW__STYLES, inlineStyle);
-		return command;
-	}
-
-	protected void createNameLabel(Composite labelComposite) {
-		Text nameLabel = new Text(labelComposite, SWT.SINGLE | SWT.NORMAL);
-		GridDataFactory.fillDefaults().indent(5, 1).grab(true, false).align(SWT.FILL, SWT.CENTER).applyTo(nameLabel);
-
-		nameLabel.setText(getStatechartName());
-		nameLabel.setEditable(getContextObject() instanceof Statechart);
-		nameLabel.setBackground(ColorConstants.white);
-		nameModificationListener = new NameModificationListener(nameLabel);
-		nameLabel.addModifyListener(nameModificationListener);
-	}
-
-	protected String getStatechartName() {
-		Statechart statechart = EcoreUtil2.getContainerOfType(getContextObject(), Statechart.class);
-		return statechart.getName();
-	}
-
-	protected void createSeparator(Composite definitionSection) {
-		Label separator = new Label(definitionSection, SWT.SEPARATOR | SWT.HORIZONTAL);
-		GridDataFactory.fillDefaults().span(2, 1).grab(true, false).applyTo(separator);
-	}
-
-	protected void createCollapsedBorder(Composite definitionSection) {
-		collapsedBorder = new CollapsedBorder(definitionSection, SWT.NONE);
-		collapsedBorder.setText("Definition section", new Font(getDisplay(), "Segoe UI", 8, SWT.NORMAL));
-		collapsedBorderMouseListener = new CollapsedBorderMouseListener(collapsedBorder);
-		collapsedBorderMouseTrackListener = new CollapsedBorderMouseTrackListener(collapsedBorder);
-		collapsedBorder.addMouseListener(collapsedBorderMouseListener);
-		collapsedBorder.addMouseTrackListener(collapsedBorderMouseTrackListener);
-
-		GridDataFactory.fillDefaults().grab(false, false).span(2, 1).hint(0, definitionSection.getBounds().height)
-				.applyTo(collapsedBorder);
-
-		refresh(definitionSection);
+	public void toggleDefinitionSection() {
+		if (definitionSection != null && !definitionSection.isDisposed() && isStatechart()) {
+			definitionSection.toggleDefinitionSection();
+			definitionSection.restoreSashWidths();
+		}
 	}
 
-	protected Label createSwitchControl(Composite definitionSection) {
-		Label switchControl = new Label(definitionSection, SWT.PUSH);
-		switchControl.setToolTipText(HIDE_SECTION);
-		switchControl.setImage(isSectionExpanded ? StatechartImages.COLLAPSE.image() : StatechartImages.EXPAND.image());
-		switchControl.setCursor(new Cursor(getDisplay(), SWT.CURSOR_HAND));
-		GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).indent(-1, 0).hint(MIN_SIZE[0], MIN_SIZE[1])
-				.applyTo(switchControl);
-		return switchControl;
+	protected boolean isStatechart() {
+		return getContextObject() instanceof Statechart;
 	}
 
 	@Override
@@ -688,424 +432,7 @@ public class StatechartDiagramEditor extends DiagramPartitioningEditor implement
 		return element;
 	}
 
-	protected void initContextMenu(Control control) {
-		MenuManager menuManager = new FilteringMenuManager();
-		Menu contextMenu = menuManager.createContextMenu(control);
-		control.setMenu(contextMenu);
-		IWorkbenchPartSite site = getSite();
-		if (site != null)
-			site.registerContextMenu("org.yakindu.base.xtext.utils.jface.viewers.StyledTextXtextAdapterContextMenu",
-					menuManager, site.getSelectionProvider());
-	}
-
-	protected void collapseDefinitionSection() {
-		int parentWidth = getSashWidth();
-		int switchControlWidth = getSwitchControlWidth();
-		int[] sashWidths = getCollapsedSashWidths(parentWidth, switchControlWidth);
-		if ((parentWidth - switchControlWidth) < 0 || (parentWidth < switchControlWidth)) {
-			sashWidths = DEFAULT_WEIGHTS;
-		}
-		layoutDefinitionSection(0, sashWidths, false, 1);
-	}
-
-	protected void expandDefinitionSection() {
-		layoutDefinitionSection(SASH_WIDTH, previousWidths, true, 2);
-	}
-
-	protected int getSashWidth() {
-		return getSash().getBounds().width;
-	}
-
-	protected int[] getCollapsedSashWidths(int parentWidth, int switchControlWidth) {
-		int diff = parentWidth - switchControlWidth;
-		return new int[]{switchControlWidth, (diff % 2 != 0) ? diff - (1 + BORDERWIDTH) : diff};
-	}
-
-	protected void layoutDefinitionSection(int sashWidth, int[] weights, boolean visible, int hSpan) {
-		getDisplay().asyncExec(() -> {
-			getSash().setRedraw(false);
-			getSash().setSashWidth(sashWidth);
-			getSash().setWeights(weights);
-			embeddedEditor.setVisible(visible);
-			labelComposite.setVisible(visible);
-			if (visible)
-				refreshSwitchControl(HIDE_SECTION, StatechartImages.COLLAPSE.image());
-			else
-				refreshSwitchControl(SHOW_SECTION, StatechartImages.EXPAND.image());
-			layoutCollapsedBorder(hSpan);
-			layoutEmbeddedEditor(hSpan);
-			refresh(getSash());
-			getSash().setRedraw(true);
-		});
-	}
-
-	protected void layoutEmbeddedEditor(int hSpan) {
-		((GridData) embeddedEditor.getLayoutData()).horizontalSpan = hSpan;
-	}
-
-	protected void layoutCollapsedBorder(int hSpan) {
-		((GridData) collapsedBorder.getLayoutData()).horizontalSpan = hSpan;
-	}
-
-	protected void refresh(Composite comp) {
-		comp.layout(false, true);
-		comp.redraw();
-		comp.update();
-	}
-
-	protected void refreshSwitchControl(String tooltipText, Image image) {
-		switchControl.setToolTipText(tooltipText);
-		switchControl.setImage(image);
-	}
-
-	@Override
-	protected boolean isDefinitionSectionInlined() {
-		BooleanValueStyle style = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(getDiagram());
-		return style != null ? style.isBooleanValue() : true;
-	}
-
-	@Override
-	public void saveState(IMemento memento) {
-		if (memento == null) {
-			memento = XMLMemento.createWriteRoot(getFactoryId());
-		}
-		memento.putInteger(FIRST_SASH_WEIGHT, previousWidths[0]);
-		memento.putInteger(SECOND_SASH_WEIGHT, previousWidths[1]);
-		setExpandState(memento);
-
-		super.setMemento(memento);
-	}
-
-	@Override
-	protected void setExpandState(IMemento memento) {
-		if (getContextObject() != null) {
-			if (getContextObject() instanceof NamedElement) {
-				NamedElement element = (NamedElement) getContextObject();
-				if (element != null)
-					memento.putBoolean(stripElementName(element.getName()) + MEM_EXPANDED, isSectionExpanded);
-			}
-		}
-	}
-
-	@Override
-	public void restoreState(IMemento memento) {
-		if (getSash() != null && memento != null) {
-			if (memento.getInteger(FIRST_SASH_WEIGHT) != null && memento.getInteger(SECOND_SASH_WEIGHT) != null) {
-				int[] weights = new int[]{memento.getInteger(FIRST_SASH_WEIGHT),
-						memento.getInteger(SECOND_SASH_WEIGHT)};
-				getSash().setWeights(weights);
-				previousWidths = weights;
-				isSectionExpanded = getExpandState(memento);
-			}
-		}
-		super.setMemento(memento);
-	}
-
-	protected boolean getExpandState(IMemento memento) {
-		Object expandState = null;
-		if (getContextObject() instanceof NamedElement) {
-			NamedElement element = (NamedElement) getContextObject();
-			if (element != null)
-				expandState = memento.getBoolean(stripElementName(element.getName()) + MEM_EXPANDED);
-		}
-		return expandState != null ? ((Boolean) expandState).booleanValue() : true;
-	}
-
 	protected TransactionalEditingDomain getTransactionalEditingDomain() {
 		return TransactionUtil.getEditingDomain(getDiagram());
 	}
-
-	protected String getStatechartSpecification() {
-		return ((Statechart) getContextObject()).getSpecification();
-	}
-
-	protected Display getDisplay() {
-		return Display.getCurrent() != null ? Display.getCurrent() : Display.getDefault();
-	}
-
-	protected int getSwitchControlWidth() {
-		return switchControl.getBounds().width + BORDERWIDTH;
-	}
-
-	/**
-	 * 
-	 * @author robert rudi - Initial contribution and API
-	 *
-	 */
-	public class EmbeddedEditorKeyListener extends KeyAdapter {
-		@Override
-		public void keyReleased(KeyEvent e) {
-			if (e.stateMask == SWT.CTRL && e.keyCode == 'a') {
-				embeddedEditor.selectAll();
-			}
-		}
-	}
-
-	/**
-	 * @author robert rudi - Initial contribution and API
-	 * 
-	 */
-	protected class EmbeddedEditorFocusListener extends FocusAdapter {
-
-		@Override
-		public void focusGained(FocusEvent e) {
-			// needed to be able to show the right property sheet in PropertiesView
-			((DiagramDocumentEditor) ActiveEditorTracker.getLastActiveEditor()).getDiagramGraphicalViewer()
-					.select(getDiagramEditPart());
-		}
-
-		@Override
-		public void focusLost(FocusEvent e) {
-			embeddedEditor.setSelection(0);
-		}
-	}
-
-	/**
-	 * @author robert rudi - Initial contribution and API
-	 * 
-	 */
-	protected class NameModificationListener implements ModifyListener {
-
-		private final Text nameLabel;
-
-		protected NameModificationListener(Text nameLabel) {
-			this.nameLabel = nameLabel;
-		}
-
-		@Override
-		public void modifyText(ModifyEvent e) {
-			if (getContextObject() instanceof Statechart) {
-				getSash().setRedraw(false);
-				TransactionalEditingDomain domain = getTransactionalEditingDomain();
-				SetCommand command = new SetCommand(domain, getContextObject(),
-						BasePackage.Literals.NAMED_ELEMENT__NAME, nameLabel.getText());
-				domain.getCommandStack().execute(command);
-				refresh(nameLabel.getParent());
-				getSash().setRedraw(true);
-			}
-		}
-	}
-
-	/**
-	 * @author robert rudi - Initial contribution and API
-	 * 
-	 */
-	protected class CollapsedBorderMouseListener extends MouseAdapter {
-		private final CollapsedBorder collapsedBorder;
-		protected CollapsedBorderMouseListener(CollapsedBorder collapsedBorder) {
-			this.collapsedBorder = collapsedBorder;
-		}
-		@Override
-		public void mouseUp(MouseEvent e) {
-			if (!isSectionExpanded)
-				selectionListener.handleSelection();
-			collapsedBorder.setCursor(new Cursor(getDisplay(), SWT.CURSOR_ARROW));
-		}
-	}
-
-	/**
-	 * @author robert rudi - Initial contribution and API
-	 * 
-	 */
-	protected class CollapsedBorderMouseTrackListener extends MouseTrackAdapter {
-		private final CollapsedBorder collapsedBorder;
-		protected CollapsedBorderMouseTrackListener(CollapsedBorder collapsedBorder) {
-			this.collapsedBorder = collapsedBorder;
-		}
-		@Override
-		public void mouseEnter(MouseEvent e) {
-			collapsedBorder
-					.setCursor(new Cursor(getDisplay(), (!isSectionExpanded) ? SWT.CURSOR_HAND : SWT.CURSOR_ARROW));
-			collapsedBorder.setToolTipText((!isSectionExpanded) ? SHOW_SECTION : null);
-		}
-	}
-
-	/**
-	 * @author robert rudi - Initial contribution and API
-	 * 
-	 */
-	protected class IconMouseListener extends MouseAdapter {
-
-		@Override
-		public void mouseUp(MouseEvent e) {
-			TransactionalEditingDomain domain = getTransactionalEditingDomain();
-			BooleanValueStyle inlineStyle = DiagramPartitioningUtil.getInlineDefinitionSectionStyle(getDiagram());
-			if (inlineStyle == null) {
-				inlineStyle = DiagramPartitioningUtil.createInlineDefinitionSectionStyle();
-				AddCommand command = addBooleanValueStyle(getDiagram(), inlineStyle, domain);
-				domain.getCommandStack().execute(command);
-			}
-			// set the new value for the boolean value style
-			SetCommand command = setBooleanValueStyle(inlineStyle, domain);
-			domain.getCommandStack().execute(command);
-
-			toggleDefinitionSection();
-			refreshDiagramEditPartChildren();
-		}
-	}
-
-	/**
-	 * @author robert rudi - Initial contribution and API
-	 * 
-	 */
-	protected class IconMouseTrackListener extends MouseTrackAdapter {
-		private final Label icon;
-
-		protected IconMouseTrackListener(Label icon) {
-			this.icon = icon;
-		}
-
-		@Override
-		public void mouseEnter(MouseEvent e) {
-			icon.setCursor(new Cursor(getDisplay(), SWT.CURSOR_HAND));
-			iconHasFocus = true;
-			refresh(icon.getParent());
-		}
-
-		@Override
-		public void mouseExit(MouseEvent e) {
-			iconHasFocus = false;
-			refresh(icon.getParent());
-		}
-	}
-
-	/**
-	 * @author robert rudi - Initial contribution and API
-	 * 
-	 */
-	protected class IconPaintListener implements PaintListener {
-		private final Label icon;
-
-		protected IconPaintListener(Label icon) {
-			this.icon = icon;
-		}
-
-		@Override
-		public void paintControl(PaintEvent e) {
-			if (iconHasFocus) {
-				drawIconBorder(icon, e.gc);
-			}
-		}
-
-		protected void drawIconBorder(Label icon, GC gc) {
-			Rectangle rect = new Rectangle(0, 0, icon.getBounds().width - 1, icon.getBounds().height - 1);
-			Transform t = new Transform(getDisplay());
-			gc.setTransform(t);
-			gc.setForeground(ColorConstants.lightGray);
-			gc.drawRectangle(0, 0, rect.width, rect.height);
-			refresh(icon.getParent());
-		}
-	}
-
-	/**
-	 * @author robert rudi - Initial contribution and API
-	 * 
-	 */
-	protected class ResizeListener extends ControlAdapter {
-
-		private final Composite definitionSection;
-
-		protected ResizeListener(Composite definitionSection) {
-			this.definitionSection = definitionSection;
-		}
-
-		@Override
-		public void controlResized(ControlEvent e) {
-			handleControlChanged();
-		}
-
-		@Override
-		public void controlMoved(ControlEvent e) {
-			handleControlChanged();
-		}
-
-		protected void handleControlChanged() {
-			if (isSectionExpanded) {
-				previousWidths = getSash().getWeights();// save current weights so the widths can later be restored
-			} else {
-				if (definitionSection.getBounds().width != getSwitchControlWidth()) {
-					collapseDefinitionSection(); // keep sash collapsed
-				}
-			}
-		}
-	}
-
-	/**
-	 * @author robert rudi - Initial contribution and API
-	 * 
-	 */
-	protected class SelectionListener extends MouseAdapter {
-
-		protected final StyledText xtextEditor;
-
-		protected SelectionListener(StyledText xtextEditor) {
-			this.xtextEditor = xtextEditor;
-		}
-
-		protected void handleSelection() {
-			getSash().setRedraw(false);
-			isSectionExpanded = !isSectionExpanded;
-			if (isSectionExpanded) {
-				xtextEditor.setVisible(true);
-				expandDefinitionSection();
-			} else {
-				xtextEditor.setVisible(false);
-				collapseDefinitionSection();
-			}
-			getSash().setRedraw(true);
-		}
-
-		@Override
-		public void mouseUp(MouseEvent e) {
-			handleSelection();
-		}
-	}
-
-	/**
-	 * @author robert rudi - Initial contribution and API
-	 * 
-	 */
-	protected class CollapsedBorder extends Canvas {
-
-		private String text;
-		float rotationAngle = -90f;
-
-		public CollapsedBorder(Composite parent, int style) {
-			super(parent, style);
-
-			this.addPaintListener(new PaintListener() {
-				public void paintControl(PaintEvent e) {
-					paint(e);
-				}
-			});
-			this.addListener(SWT.MouseDown, new Listener() {
-
-				@Override
-				public void handleEvent(Event event) {
-					if (selectionListener != null && !isSectionExpanded)
-						selectionListener.handleSelection();
-				}
-			});
-		}
-
-		public void setText(String string, Font font) {
-			this.text = string;
-			setFont(font);
-			refresh(this);
-		}
-
-		public void paint(PaintEvent e) {
-			Transform tr = null;
-			tr = new Transform(e.display);
-			int w = e.width;
-			int h = e.height;
-			tr.translate(w / 2, h / 2);
-			tr.rotate(rotationAngle);
-			e.gc.setTransform(tr);
-			int drawHeight = -w + 2;
-			e.gc.drawString(isSectionExpanded ? "" : text, 0, drawHeight % 2 != 0 ? drawHeight + 1 : drawHeight - 1);
-			update();
-		}
-	}
-
 }

+ 2 - 68
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/partitioning/DiagramPartitioningEditor.java

@@ -54,15 +54,11 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.ui.IEditorInput;
 import org.eclipse.ui.IEditorReference;
 import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.IMemento;
-import org.eclipse.ui.IPersistableEditor;
-import org.eclipse.ui.IPersistableElement;
 import org.eclipse.ui.IWorkbenchPage;
 import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.XMLMemento;
 import org.eclipse.ui.ide.FileStoreEditorInput;
 import org.eclipse.xtext.util.Arrays;
 import org.yakindu.base.base.BasePackage;
@@ -83,26 +79,16 @@ import org.yakindu.sct.ui.editor.StatechartImages;
 public abstract class DiagramPartitioningEditor extends DiagramDocumentEditor
 		implements
 			ISelectionChangedListener,
-			IEditingDomainProvider,
-			IPersistableEditor,
-			IPersistableElement {
+			IEditingDomainProvider
+			{
 
 	protected static final int SASH_WIDTH = 5;
-	private static final String REGEX_NO_WORD_NO_WHITESPACE = "[^\\w[\\s+]]";
-	protected static final String MEM_EXPANDED = "DefinitionSectionIsExpanded";
-	protected static final String FIRST_SASH_WEIGHT = "FirstSashControlWeight";
-	protected static final String SECOND_SASH_WEIGHT = "SecondSashControlWeight";
-	protected static final int[] DEFAULT_WEIGHTS = new int[]{2, 10};
-	protected static final int MAXIMIZED_CONTROL_INDEX = 1;
-
 	private DiagramPartitioningBreadcrumbViewer viewer;
 	private DiagramPartitioningDocumentProvider documentProvider;
 	private Adapter breadcrumbSynchronizer;
 
 	private SashForm sash;
 
-	private static IMemento memento;
-
 	protected abstract void createTextEditor(Composite parent);
 
 	protected abstract EObject getContextObject();
@@ -160,58 +146,6 @@ public abstract class DiagramPartitioningEditor extends DiagramDocumentEditor
 		return sash;
 	}
 
-	public void toggleDefinitionSection() {
-		sash.setMaximizedControl(!isDefinitionSectionInlined() ? null : sash.getChildren()[MAXIMIZED_CONTROL_INDEX]);
-	}	
-	
-	public void restoreSashWidths(SashForm sash, IMemento memento) {
-		if (memento == null) {
-			setDefaultSashWeights(sash);
-			memento = XMLMemento.createWriteRoot(getFactoryId());
-			memento.putInteger(FIRST_SASH_WEIGHT, DEFAULT_WEIGHTS[0]);
-			memento.putInteger(SECOND_SASH_WEIGHT, DEFAULT_WEIGHTS[1]);
-			setExpandState(memento);
-			setMemento(memento);
-		} else {
-			restoreState(memento);
-		}
-	}
-
-	protected abstract void setExpandState(IMemento memento);
-
-	protected String stripElementName(String name) {
-		if (name != null)
-			return name.replaceAll(REGEX_NO_WORD_NO_WHITESPACE, "");
-		return "";
-	}
-
-	public SashForm getSash() {
-		return sash;
-	}
-
-	protected void setDefaultSashWeights(SashForm sash) {
-		sash.setWeights(DEFAULT_WEIGHTS);
-	}
-
-	@Override
-	public abstract void restoreState(IMemento memento);
-
-	@Override
-	public abstract void saveState(IMemento memento);
-
-	public IMemento getMemento() {
-		return memento;
-	}
-
-	public void setMemento(IMemento memento) {
-		DiagramPartitioningEditor.memento = memento;
-	}
-
-	@Override
-	public abstract String getFactoryId();
-
-	protected abstract boolean isDefinitionSectionInlined();
-
 	@SuppressWarnings("restriction")
 	@Override
 	protected void sanityCheckState(IEditorInput input) {

+ 280 - 281
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/partitioning/DiagramPartitioningUtil.java

@@ -1,281 +1,280 @@
-/**
- * Copyright (c) 2012 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.ui.editor.partitioning;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.emf.common.util.TreeIterator;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.util.EcoreUtil;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gmf.runtime.diagram.ui.editparts.IPrimaryEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramEditorInput;
-import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
-import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
-import org.eclipse.gmf.runtime.notation.Diagram;
-import org.eclipse.gmf.runtime.notation.NotationFactory;
-import org.eclipse.gmf.runtime.notation.NotationPackage;
-import org.eclipse.gmf.runtime.notation.Style;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.ui.IEditorDescriptor;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IEditorReference;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.part.FileEditorInput;
-import org.yakindu.sct.model.sgraph.CompositeElement;
-import org.yakindu.sct.model.sgraph.State;
-import org.yakindu.sct.model.sgraph.Statechart;
-import org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor;
-import org.yakindu.sct.ui.editor.utils.GMFNotationUtil;
-
-/**
- * 
- * @author andreas muelder - Initial contribution and API
- * 
- */
-public class DiagramPartitioningUtil {
-
-	/** GMFs notation {@link Style} id **/
-	public static final String INLINE_STYLE = "isInline";
-	public static final String INLINE_DEFINITION_SECTION_STYLE = "inlineDefinitionSection";
-
-	private static final String DOMAIN_ID = "org.yakindu.sct.domain";
-
-	private DiagramPartitioningUtil() {
-	}
-
-	/**
-	 * returns the style for diagram inlining
-	 * 
-	 */
-	public static BooleanValueStyle getInlineStyle(View view) {
-		BooleanValueStyle result = GMFNotationUtil.getBooleanValueStyle(view, INLINE_STYLE);
-		return result;
-	}
-	
-	/**
-	 * returns the style for diagram inlining
-	 * 
-	 */
-	public static BooleanValueStyle getInlineDefinitionSectionStyle(View view) {
-		BooleanValueStyle result = GMFNotationUtil.getBooleanValueStyle(view, INLINE_DEFINITION_SECTION_STYLE);
-		return result;
-	}
-
-
-	/**
-	 * creates a new style for diagam inlining
-	 */
-	public static BooleanValueStyle createInlineStyle() {
-		BooleanValueStyle result = NotationFactory.eINSTANCE.createBooleanValueStyle();
-		result.setName(INLINE_STYLE);
-		result.setBooleanValue(true);
-		return result;
-	}
-	
-	/**
-	 * creates a new style for diagam inlining
-	 */
-	public static BooleanValueStyle createInlineDefinitionSectionStyle() {
-		BooleanValueStyle result = NotationFactory.eINSTANCE.createBooleanValueStyle();
-		result.setName(INLINE_DEFINITION_SECTION_STYLE);
-		result.setBooleanValue(true);
-		return result;
-	}
-
-	/**
-	 * Returns the Shared Editing Domain that is used for all Editors acting on the
-	 * same {@link IResource}
-	 * 
-	 * @return the {@link TransactionalEditingDomain}
-	 */
-	public static synchronized TransactionalEditingDomain getSharedDomain() {
-		return TransactionalEditingDomain.Registry.INSTANCE
-				.getEditingDomain(DOMAIN_ID);
-	}
-
-	/**
-	 * Returns the {@link Diagram} that contains a given semantic element.
-	 */
-	public static Diagram getDiagramContaining(EObject element) {
-		Assert.isNotNull(element);
-		Resource eResource = element.eResource();
-		Collection<Diagram> objects = EcoreUtil.getObjectsByType(eResource.getContents(),
-				NotationPackage.Literals.DIAGRAM);
-		for (Diagram diagram : objects) {
-			TreeIterator<EObject> eAllContents = diagram.eAllContents();
-			while (eAllContents.hasNext()) {
-				EObject next = eAllContents.next();
-				if (next instanceof View) {
-					if (EcoreUtil.equals(((View) next).getElement(), element)) {
-						return ((View) next).getDiagram();
-					}
-				}
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the Subdiagram for a given {@link State} or {@link Statechart}
-	 * 
-	 */
-	public static Diagram getSubDiagram(CompositeElement element) {
-		Assert.isNotNull(element);
-		Resource eResource = element.eResource();
-		Collection<Diagram> objects = EcoreUtil.getObjectsByType(eResource.getContents(),
-				NotationPackage.Literals.DIAGRAM);
-		for (Diagram diagram : objects) {
-			if (EcoreUtil.equals(diagram.getElement(), element))
-				return diagram;
-		}
-		return null;
-	}
-
-	/**
-	 * Opens the {@link StatechartDiagramEditor} for a fiven {@link IFile}
-	 * 
-	 */
-	public static IEditorPart openEditor(IFile file) {
-		try {
-			IEditorDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(file.getName());
-			final IWorkbenchPage wbPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-			return wbPage.openEditor(new FileEditorInput(file), desc.getId());
-		} catch (PartInitException e) {
-			e.printStackTrace();
-		}
-		return null;
-
-	}
-
-	/**
-	 * Opens a subdiagram for a given {@link Diagram}
-	 */
-	public static IEditorPart openEditor(Diagram diagramToOpen) {
-		IFile file = WorkspaceSynchronizer.getFile(diagramToOpen.eResource());
-		try {
-			IEditorDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(file.getName());
-			final IWorkbenchPage wbPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-			if (diagramToOpen.getElement() instanceof Statechart) {
-				return wbPage.openEditor(new FileEditorInput(file), desc.getId());
-			} else if (diagramToOpen.getElement() instanceof State) {
-				return wbPage.openEditor(new DiagramEditorInput(diagramToOpen), desc.getId());
-			}
-		} catch (PartInitException e) {
-			e.printStackTrace();
-		}
-		return null;
-	}
-	
-	
-	public static View findNotationView(EObject semanticElement) {
-		Collection<Diagram> objects = EcoreUtil.getObjectsByType(semanticElement.eResource().getContents(),
-				NotationPackage.Literals.DIAGRAM);
-		for (Diagram diagram : objects) {
-			TreeIterator<EObject> eAllContents = diagram.eAllContents();
-			while (eAllContents.hasNext()) {
-				EObject next = eAllContents.next();
-				if (next instanceof View) {
-					if (((View) next).getElement() == semanticElement) {
-						return ((View) next);
-					}
-				}
-			}
-		}
-		return null;
-	}
-	
-	public static void selectElementsInDiagram(IDiagramWorkbenchPart diagramPart, List<EditPart> editParts) {
-		diagramPart.getDiagramGraphicalViewer().deselectAll();
-
-		EditPart firstPrimary = null;
-		for (Iterator<EditPart> it = editParts.iterator(); it.hasNext();) {
-			EditPart nextPart = it.next();
-			diagramPart.getDiagramGraphicalViewer().appendSelection(nextPart);
-			if (firstPrimary == null && nextPart instanceof IPrimaryEditPart) {
-				firstPrimary = nextPart;
-			}
-		}
-		if (!editParts.isEmpty()) {
-			diagramPart.getDiagramGraphicalViewer()
-					.reveal(firstPrimary != null ? firstPrimary : (EditPart) editParts.get(0));
-		}
-	}
-
-	/**
-	 * Forces the user to close all opened editors for subdiagrams that are inlined.
-	 * 
-	 * @return true if all editors were closed, false otherwise
-	 */
-	public static boolean closeSubdiagramEditors(State state) {
-		Diagram diagram = DiagramPartitioningUtil.getSubDiagram(state);
-		if (diagram == null)
-			return true;
-		IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
-		IEditorReference[] refs = activePage.getEditorReferences();
-		for (IEditorReference ref : refs) {
-			try {
-				if (ref.getEditorInput() instanceof IDiagramEditorInput) {
-					IDiagramEditorInput diagramInput = (IDiagramEditorInput) ref.getEditorInput();
-					if (diagramInput.getDiagram().equals(diagram)) {
-						boolean close = MessageDialog.openQuestion(activePage.getActivePart().getSite().getShell(),
-								"Close subdiagram editor?",
-								"The subdiagram is still open in another editor. Do you want to close it?");
-						if (close) {
-							activePage.closeEditor(ref.getEditor(false), false);
-						}
-						return close;
-					}
-				}
-			} catch (PartInitException e) {
-				e.printStackTrace();
-			}
-		}
-		return true;
-	}
-
-	public static List<Diagram> getDiagramContainerHierachy(Diagram diagram) {
-		Assert.isNotNull(diagram);
-		List<Diagram> result = new ArrayList<Diagram>();
-		result.add(diagram);
-		while (diagram.getElement() instanceof State) {
-			diagram = DiagramPartitioningUtil.getDiagramContaining((State) diagram.getElement());
-			result.add(diagram);
-		}
-		Collections.reverse(result);
-		return result;
-	}
-
-	public static List<Diagram> getSubDiagramHierachy(Diagram diagram) {
-		Assert.isNotNull(diagram);
-		List<Diagram> result = new ArrayList<Diagram>();
-		result.add(diagram);
-		while (diagram.getElement() instanceof State) {
-			diagram = DiagramPartitioningUtil.getSubDiagram((CompositeElement) diagram.getElement());
-			result.add(diagram);
-		}
-		Collections.reverse(result);
-		return result;
-	}
-}
+/**
+ * Copyright (c) 2012 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.ui.editor.partitioning;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.IPrimaryEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramEditorInput;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
+import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.NotationFactory;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.Style;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
+import org.yakindu.sct.model.sgraph.CompositeElement;
+import org.yakindu.sct.model.sgraph.State;
+import org.yakindu.sct.model.sgraph.Statechart;
+import org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor;
+import org.yakindu.sct.ui.editor.utils.GMFNotationUtil;
+
+/**
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public class DiagramPartitioningUtil {
+
+	/** GMFs notation {@link Style} id **/
+	public static final String INLINE_STYLE = "isInline";
+	public static final String INLINE_DEFINITION_SECTION_STYLE = "inlineDefinitionSection";
+
+	private static final String DOMAIN_ID = "org.yakindu.sct.domain";
+
+	private DiagramPartitioningUtil() {
+	}
+
+	/**
+	 * returns the style for diagram inlining
+	 * 
+	 */
+	public static BooleanValueStyle getInlineStyle(View view) {
+		BooleanValueStyle result = GMFNotationUtil.getBooleanValueStyle(view, INLINE_STYLE);
+		return result;
+	}
+	
+	/**
+	 * returns the style for diagram inlining
+	 * 
+	 */
+	public static BooleanValueStyle getInlineDefinitionSectionStyle(View view) {
+		BooleanValueStyle result = GMFNotationUtil.getBooleanValueStyle(view, INLINE_DEFINITION_SECTION_STYLE);
+		return result;
+	}
+
+
+	/**
+	 * creates a new style for diagam inlining
+	 */
+	public static BooleanValueStyle createInlineStyle() {
+		BooleanValueStyle result = NotationFactory.eINSTANCE.createBooleanValueStyle();
+		result.setName(INLINE_STYLE);
+		result.setBooleanValue(true);
+		return result;
+	}
+	
+	/**
+	 * creates a new style for diagam inlining
+	 */
+	public static BooleanValueStyle createInlineDefinitionSectionStyle() {
+		BooleanValueStyle result = NotationFactory.eINSTANCE.createBooleanValueStyle();
+		result.setName(INLINE_DEFINITION_SECTION_STYLE);
+		result.setBooleanValue(false);
+		return result;
+	}
+
+	/**
+	 * Returns the Shared Editing Domain that is used for all Editors acting on the
+	 * same {@link IResource}
+	 * 
+	 * @return the {@link TransactionalEditingDomain}
+	 */
+	public static synchronized TransactionalEditingDomain getSharedDomain() {
+		return TransactionalEditingDomain.Registry.INSTANCE
+				.getEditingDomain(DOMAIN_ID);
+	}
+
+	/**
+	 * Returns the {@link Diagram} that contains a given semantic element.
+	 */
+	public static Diagram getDiagramContaining(EObject element) {
+		Assert.isNotNull(element);
+		Resource eResource = element.eResource();
+		Collection<Diagram> objects = EcoreUtil.getObjectsByType(eResource.getContents(),
+				NotationPackage.Literals.DIAGRAM);
+		for (Diagram diagram : objects) {
+			TreeIterator<EObject> eAllContents = diagram.eAllContents();
+			while (eAllContents.hasNext()) {
+				EObject next = eAllContents.next();
+				if (next instanceof View) {
+					if (EcoreUtil.equals(((View) next).getElement(), element)) {
+						return ((View) next).getDiagram();
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the Subdiagram for a given {@link State} or {@link Statechart}
+	 * 
+	 */
+	public static Diagram getSubDiagram(CompositeElement element) {
+		Assert.isNotNull(element);
+		Resource eResource = element.eResource();
+		Collection<Diagram> objects = EcoreUtil.getObjectsByType(eResource.getContents(),
+				NotationPackage.Literals.DIAGRAM);
+		for (Diagram diagram : objects) {
+			if (EcoreUtil.equals(diagram.getElement(), element))
+				return diagram;
+		}
+		return null;
+	}
+
+	/**
+	 * Opens the {@link StatechartDiagramEditor} for a fiven {@link IFile}
+	 * 
+	 */
+	public static void openEditor(IFile file) {
+		try {
+			IEditorDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(file.getName());
+			final IWorkbenchPage wbPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+			wbPage.openEditor(new FileEditorInput(file), desc.getId());
+		} catch (PartInitException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * Opens a subdiagram for a given {@link Diagram}
+	 */
+	public static IEditorPart openEditor(Diagram diagramToOpen) {
+		IFile file = WorkspaceSynchronizer.getFile(diagramToOpen.eResource());
+		try {
+			IEditorDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(file.getName());
+			final IWorkbenchPage wbPage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+			if (diagramToOpen.getElement() instanceof Statechart) {
+				return wbPage.openEditor(new FileEditorInput(file), desc.getId());
+			} else if (diagramToOpen.getElement() instanceof State) {
+				return wbPage.openEditor(new DiagramEditorInput(diagramToOpen), desc.getId());
+			}
+		} catch (PartInitException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+	
+	
+	public static View findNotationView(EObject semanticElement) {
+		Collection<Diagram> objects = EcoreUtil.getObjectsByType(semanticElement.eResource().getContents(),
+				NotationPackage.Literals.DIAGRAM);
+		for (Diagram diagram : objects) {
+			TreeIterator<EObject> eAllContents = diagram.eAllContents();
+			while (eAllContents.hasNext()) {
+				EObject next = eAllContents.next();
+				if (next instanceof View) {
+					if (((View) next).getElement() == semanticElement) {
+						return ((View) next);
+					}
+				}
+			}
+		}
+		return null;
+	}
+	
+	public static void selectElementsInDiagram(IDiagramWorkbenchPart diagramPart, List<EditPart> editParts) {
+		diagramPart.getDiagramGraphicalViewer().deselectAll();
+
+		EditPart firstPrimary = null;
+		for (Iterator<EditPart> it = editParts.iterator(); it.hasNext();) {
+			EditPart nextPart = it.next();
+			diagramPart.getDiagramGraphicalViewer().appendSelection(nextPart);
+			if (firstPrimary == null && nextPart instanceof IPrimaryEditPart) {
+				firstPrimary = nextPart;
+			}
+		}
+		if (!editParts.isEmpty()) {
+			diagramPart.getDiagramGraphicalViewer()
+					.reveal(firstPrimary != null ? firstPrimary : (EditPart) editParts.get(0));
+		}
+	}
+
+	/**
+	 * Forces the user to close all opened editors for subdiagrams that are inlined.
+	 * 
+	 * @return true if all editors were closed, false otherwise
+	 */
+	public static boolean closeSubdiagramEditors(State state) {
+		Diagram diagram = DiagramPartitioningUtil.getSubDiagram(state);
+		if (diagram == null)
+			return true;
+		IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+		IEditorReference[] refs = activePage.getEditorReferences();
+		for (IEditorReference ref : refs) {
+			try {
+				if (ref.getEditorInput() instanceof IDiagramEditorInput) {
+					IDiagramEditorInput diagramInput = (IDiagramEditorInput) ref.getEditorInput();
+					if (diagramInput.getDiagram().equals(diagram)) {
+						boolean close = MessageDialog.openQuestion(activePage.getActivePart().getSite().getShell(),
+								"Close subdiagram editor?",
+								"The subdiagram is still open in another editor. Do you want to close it?");
+						if (close) {
+							activePage.closeEditor(ref.getEditor(false), false);
+						}
+						return close;
+					}
+				}
+			} catch (PartInitException e) {
+				e.printStackTrace();
+			}
+		}
+		return true;
+	}
+
+	public static List<Diagram> getDiagramContainerHierachy(Diagram diagram) {
+		Assert.isNotNull(diagram);
+		List<Diagram> result = new ArrayList<Diagram>();
+		result.add(diagram);
+		while (diagram.getElement() instanceof State) {
+			diagram = DiagramPartitioningUtil.getDiagramContaining((State) diagram.getElement());
+			result.add(diagram);
+		}
+		Collections.reverse(result);
+		return result;
+	}
+
+	public static List<Diagram> getSubDiagramHierachy(Diagram diagram) {
+		Assert.isNotNull(diagram);
+		List<Diagram> result = new ArrayList<Diagram>();
+		result.add(diagram);
+		while (diagram.getElement() instanceof State) {
+			diagram = DiagramPartitioningUtil.getSubDiagram((CompositeElement) diagram.getElement());
+			result.add(diagram);
+		}
+		Collections.reverse(result);
+		return result;
+	}
+}

+ 60 - 13
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/providers/StatechartMarkerNavigationProvider.java

@@ -6,16 +6,18 @@
  * http://www.eclipse.org/legal/epl-v10.html
  * Contributors:
  * 	committers of YAKINDU - initial API and implementation
- * 
+ *
  */
 package org.yakindu.sct.ui.editor.providers;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
 import org.eclipse.core.resources.IMarker;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.ecore.EAttribute;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.gef.EditPart;
 import org.eclipse.gef.requests.DirectEditRequest;
@@ -25,15 +27,18 @@ import org.eclipse.gmf.runtime.emf.ui.providers.marker.AbstractModelMarkerNaviga
 import org.eclipse.gmf.runtime.notation.Diagram;
 import org.eclipse.gmf.runtime.notation.View;
 import org.eclipse.xtext.EcoreUtil2;
+import org.eclipse.xtext.util.Strings;
+import org.eclipse.xtext.validation.Issue;
+import org.yakindu.base.gmf.runtime.editparts.TextAwareLabelEditPart;
 import org.yakindu.base.xtext.utils.gmf.directedit.IXtextAwareEditPart;
 import org.yakindu.sct.model.sgraph.SGraphPackage;
 import org.yakindu.sct.model.sgraph.ui.validation.SCTMarkerType;
 import org.yakindu.sct.ui.editor.partitioning.DiagramPartitioningUtil;
 
 /**
- * 
+ *
  * @author andreas muelder
- * 
+ *
  */
 public class StatechartMarkerNavigationProvider extends AbstractModelMarkerNavigationProvider {
 
@@ -60,27 +65,69 @@ public class StatechartMarkerNavigationProvider extends AbstractModelMarkerNavig
 
 		EditPart targetEditPart = (EditPart) editPartRegistry.get(view);
 		if (targetEditPart != null) {
-			if(!targetEditPart.isSelectable()) return;
-			DiagramPartitioningUtil.selectElementsInDiagram(editor, Arrays.asList(new EditPart[] { targetEditPart }));
+			if (!targetEditPart.isSelectable())
+				return;
+			DiagramPartitioningUtil.selectElementsInDiagram(editor, Arrays.asList(new EditPart[]{targetEditPart}));
 		}
 
 		try {
 			if (marker.isSubtypeOf(SCTMarkerType.SUPERTYPE)) {
 				final DirectEditRequest request = new DirectEditRequest();
-				request.setDirectEditFeature(SGraphPackage.eINSTANCE.getSpecificationElement_Specification());
-				List<EObject> allNotationElements = EcoreUtil2.eAllContentsAsList(view);
-				for (EObject eObject : allNotationElements) {
-					if (eObject instanceof View) {
-						IGraphicalEditPart editPart = (IGraphicalEditPart) editPartRegistry.get(eObject);
-						if (editPart instanceof IXtextAwareEditPart) {
-							editPart.performRequest(request);
-						}
+				request.setDirectEditFeature(getEditFeature(targetElement, marker));
+				List<IGraphicalEditPart> allEditParts = getEditParts(editPartRegistry,
+						EcoreUtil2.eAllContentsAsList(view));
+
+				for (IGraphicalEditPart editPart : allEditParts) {
+					if (editPart instanceof IXtextAwareEditPart
+							|| (editPart instanceof TextAwareLabelEditPart) && ((TextAwareLabelEditPart) editPart)
+									.getFeature().equals(request.getDirectEditFeature())) {
+						editPart.performRequest(request);
+						break;
+					}
+				}
+			}
+		} catch (CoreException e) {
+			e.printStackTrace();
+		}
+	}
+
+	protected List<IGraphicalEditPart> getEditParts(Map<?, ?> editPartRegistry, Iterable<EObject> eObjects) {
+		List<IGraphicalEditPart> editParts = new ArrayList<>();
+		for (EObject e : eObjects) {
+			if (e instanceof View) {
+				editParts.add((IGraphicalEditPart) editPartRegistry.get(e));
+			}
+		}
+		return editParts;
+	}
+
+	protected EAttribute getEditFeature(EObject targetObject, IMarker marker) {
+		EAttribute defaultAttr = SGraphPackage.eINSTANCE.getSpecificationElement_Specification();
+		if (targetObject == null) {
+			return defaultAttr;
+		}
+		try {
+			String[] data = Strings.unpack((String) marker.getAttribute(Issue.DATA_KEY));
+			if (data != null) {
+				for (String string : data) {
+					EAttribute attribute = getEditFeature(targetObject, string);
+					if (attribute != null) {
+						return attribute;
 					}
 				}
 			}
 		} catch (CoreException e) {
 			e.printStackTrace();
 		}
+		return defaultAttr;
 	}
 
+	protected EAttribute getEditFeature(EObject targetObject, String featureName) {
+		for (EAttribute attribute : targetObject.eClass().getEAllAttributes()) {
+			if (attribute.getName().equals(featureName)) {
+				return attribute;
+			}
+		}
+		return null;
+	}
 }