/** * Copyright (c) 2016 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.providers; import java.util.ArrayList; import java.util.List; import org.eclipse.emf.common.notify.Notification; import org.eclipse.gef.EditDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.editparts.AbstractConnectionEditPart; import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker; import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener; import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditDomain; import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecorator; import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorTarget; import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.ui.IEditorPart; import org.yakindu.base.gmf.runtime.decorators.AbstractDecoratorProvider; import org.yakindu.base.gmf.runtime.decorators.BaseDecorator; import org.yakindu.sct.model.sgraph.SGraphPackage; import org.yakindu.sct.model.sgraph.Transition; import org.yakindu.sct.model.sgraph.Vertex; import org.yakindu.sct.ui.editor.DiagramActivator; import org.yakindu.sct.ui.editor.editor.StatechartDiagramEditor; import org.yakindu.sct.ui.editor.editor.figures.PriorityFigure; import org.yakindu.sct.ui.editor.editparts.TransitionEditPart; import org.yakindu.sct.ui.editor.preferences.StatechartPreferenceConstants; /** * @author andreas muelder - Initial contribution and API */ public class TransitionPriorityDecorationProvider extends AbstractDecoratorProvider implements IPropertyChangeListener { private static final String PRIORITY_ID = TransitionPriorityDecorationProvider.class.getSimpleName(); private List<IDecorator> decorators; public TransitionPriorityDecorationProvider() { decorators = new ArrayList<>(); DiagramActivator.getDefault().getPreferenceStore().addPropertyChangeListener(this); } @Override public void createDecorators(IDecoratorTarget decoratorTarget) { EditPart editPart = (EditPart) decoratorTarget.getAdapter(EditPart.class); if (editPart instanceof GraphicalEditPart || editPart instanceof AbstractConnectionEditPart) { EditDomain ed = editPart.getViewer().getEditDomain(); if (!(ed instanceof DiagramEditDomain)) { return; } if (shouldInstall(((DiagramEditDomain) ed).getEditorPart()) && editPart instanceof TransitionEditPart) { IDecorator decorator = createStatusDecorator(decoratorTarget); decorators.add(decorator); decoratorTarget.installDecorator(getDecoratorKey(), decorator); } } } protected IDecorator createStatusDecorator(IDecoratorTarget decoratorTarget) { return new PriorityDecorator(decoratorTarget); } protected Object getDecoratorKey() { return PRIORITY_ID; } protected boolean shouldInstall(IEditorPart editorPart) { return (editorPart instanceof StatechartDiagramEditor); } public static class PriorityDecorator extends BaseDecorator { private Vertex owningElement; public PriorityDecorator(IDecoratorTarget decoratorTarget) { super(decoratorTarget); } protected NotificationListener transitionPriorityChangeListener = new NotificationListener() { public void notifyChanged(Notification notification) { if (notification.getFeatureID(Vertex.class) == SGraphPackage.VERTEX__OUTGOING_TRANSITIONS) refresh(); } }; @Override public void activate() { super.activate(); if (!(semanticElement instanceof Transition) || !(((Transition) semanticElement).eContainer() instanceof Vertex)) { return; } if (((Transition) semanticElement).eContainer() != null) { owningElement = (Vertex) ((Transition) semanticElement).eContainer(); DiagramEventBroker.getInstance(gep.getEditingDomain()).addNotificationListener(owningElement, transitionPriorityChangeListener); } } @Override public void deactivate() { if (!(semanticElement instanceof Transition)) { return; } if (owningElement != null) { DiagramEventBroker.getInstance(gep.getEditingDomain()).removeNotificationListener(owningElement, transitionPriorityChangeListener); owningElement = null; } super.deactivate(); } @Override public void refresh() { removeDecoration(); boolean showLabels = DiagramActivator.getDefault().getPreferenceStore() .getBoolean(StatechartPreferenceConstants.PREF_PRIORITY_LABELS); if (!showLabels) return; View view = (View) getDecoratorTarget().getAdapter(View.class); if (view == null || view.eResource() == null) { return; } EditPart editPart = (EditPart) getDecoratorTarget().getAdapter(EditPart.class); if (editPart == null || editPart.getViewer() == null) { return; } if (editPart instanceof TransitionEditPart && (needsDecoration((TransitionEditPart) editPart))) createDecorators((TransitionEditPart) editPart); } public boolean needsDecoration(TransitionEditPart editPart) { Transition transition = (Transition) editPart.resolveSemanticElement(); Vertex container = (Vertex) transition.eContainer(); return container.getOutgoingTransitions().size() > 1; } public void createDecorators(TransitionEditPart editPart) { PriorityFigure figure = new PriorityFigure(MapModeUtil.getMapMode(), getPriority(editPart)); figure.setSize(10, 10); setDecoration(getDecoratorTarget().addConnectionDecoration(figure, 5, false)); } public int getPriority(TransitionEditPart editPart) { Transition transition = ((Transition) editPart.resolveSemanticElement()); Vertex container = (Vertex) transition.eContainer(); int indexOf = container.getOutgoingTransitions().indexOf(transition); // visible priorities should start with 1 return indexOf + 1; } } @Override public void propertyChange(PropertyChangeEvent event) { if (StatechartPreferenceConstants.PREF_PRIORITY_LABELS.equals(event.getProperty())) { for (IDecorator decorator : decorators) { decorator.refresh(); } } } }