Browse Source

Improve ErrorMarker navigation (#1914)

* Add EObject field to SCTIssue

* Add descriptors for marker reason

* Add issue reason information to IMarkers

* Add getFeature()

* Improve marker classification

* Improve marker user data architecture

* Cleanup

* removed dead code
Rene Beckmann 7 years ago
parent
commit
7ba872c48b

+ 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);
+	}
+}

+ 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

+ 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;
+	}
 }