Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Manage Decorators On Papyrus

Revision as of 03:50, 20 October 2015 by Celine.Janssens.all4tec.net (Talk | contribs) (Introduction)

Contents

Introduction

To manage decorator on Edit Part two solutions are are provided by Papyrus:

  • Decoration Service Framework
  • Shape Service Framework

The purpose of this documentation is to give the minimum information to deploy your own decorator for Papyrus elements as EditPart.

...TODO differences...

shape=svg
shape= if already using an svg file as shape of the edit part, using of shape provider can be problematic. decoration=icons
shape: shapeCompartment+position
decoration:top-right
decoration:top-right
... ...

Decoration Service Framework

Architecture

The decoration service architecture have already been describe on a document (here). You will find here a description of mains Interfaces or classes to be implemented or to be called in order to use the framework and adds specific decoration.

DecorationService

DecorationService.jpg

Decoration service permits to manage decoration on EObject. Decoration are adds throw this service. It provide listener to observe changes. This service can be get with:

DecorationService decorationService = ServiceUtilsForEditPart.getInstance().getService(DecorationService.class, editPart);

Main methods

addDecorations(IPapyrusMarker marker, EObject element)

Add a new Decoration to a decorations Map with an IPapyrusMarker associated to an element.

addDecoration(String id, String type, EObject element, ImageDescriptor decorationImageForGE, ImageDescriptor decorationImageForME, PreferedPosition position, String message, int priority)

Add a new decoration without passing by a marker.

removeDecoration(String id)

Remove a decoration from the decorations Map,

getDecorations(EObject element):List<IPapyrusDecoration>

Return an Interface of decoration (IDecoration) for the element

IPapyrusMarker

IPapyrusMarker.jpg

IPapyrusMarker provide a protocol for markers that annotate elements with information, often used for problems. It is an analogue of the Eclipse IMarker API for resources in the workspace. To be implemented to create its own marker used for custom decoration.

Main methods

getType():String

Return the type of the concret Papyrus marker. Is also used to link a decorator to the marker(see Decoration Image Extension Point).

exist():Boolean

Return true if the marker exists on the view.

IDecorationSpecificFunctions

IDecorationSpecificFunctions.jpg

This interface allows to access a set of functions that depend on the decorator type. The objective is that plug-ins for a specific decoration type can implement this interface (via an extension point) to provide the information that depends on the decoration type, notably the used icons, their position, the way how messages are calculated and how decoration might propagate from children to parents. To be implemented to create its own decoration. Is related to a marker throw decorationImage extension point.

Main methods

getImageDescriptorForGE(IPapyrusMarker marker):ImageDescriptor

Get the image descriptor for a graphical editor.

getImageDescriptorForME(IPapyrusMarker marker):ImageDescriptor

Get the image descriptor for model explorer. May be identical to the image for a graphical editor.

getPreferedPosition(IPapyrusMarker marker):PreferedPosition

Return the preferred position for markers within the model explorer.

getMessage(IPapyrusMarker marker):String

Return a textual information for the marker (used for fixed messages that do not need to be stored in each marker).

getPriority(IPapyrusMarker marker):int

Return the priority of a decoration. This enables to select a marker with a high priority, if multiple markers for the same model element and the same position exist.

supportsMarkerPropagation():MarkChildren

Does the decoration type support a propagation from child to parent, e.g. in case of a problem marker parents (package) might be marked as containing warnings or errors.

markerPropagation(EList<IPapyrusDecoration> childDecorations):IPapyrusDecoration

Calculate a propagated marker for the parent, given the set of child decorations. Return the calculated decoration for the parent depending on a set of decorations on children.

Decoration Image Extension Point

Provide an ImageDescription for a decoration marker. It permits to link a IDecorationSpecificFunction class to a Papyrus marker throw is type.

Identifier:

org.eclipse.papyrus.infra.services.decoration.decorationImage

DecorationExtensionPoint.jpg

Shape Service Framework

The shape service framework permits to be display svg document on the symbol compartment or in a chosen position on the edit part.

Architecture

AbstractShapeProvider

The framework provide a simple abstract provider class in order to add svg shape to edit parts. Only few methods have to be implemented.

AbstractShapeProvider.jpg

Main methods

getShapes(EObject view):List<RenderedImage>

Returns the list of shapes proposed by this provider or null if no shapes have to be displayed by this provider.

getSVGDocument(EObject view):List<SVGDocument>

Return the list of SVG DOCUMENT or null if no shapes have to be displayed by this provider.

providesShapes(EObject view):Boolean

Returns true if the provider can display shapes. This methods allows to compute if shapes can be displayed instead of computing the whole list of shapes to be displayed.

ShapeProvider Extension Point

To be load, implemented shape providers have to be linked throw a specific extension point.

ShapeProviderExtensionPoint.jpg

Appearence tab

To display the shape on the edit parts and to choose the position visibility and the position, attributes have to be set on the appearance tab of the properties view.

AppearenceTab.jpg

Application Example

This part will provide a simple example using decorator service. This example will permit to display decoration on edit part according to the conditions describe just before.

Context

The allocation profile used will be the SysML Profile. An allocation table is used, where it allocates the call behavior on nodes. Nodes can be stereotyped with NodeA and NodeB stereotypes. Depending on the node on which the callbehavior is allocated, the decorator in callbehavior the activity diagram should change.

Example

With this profile:

ExampleProfile.jpg

Applied on these two nodes:

NodesStereotyped.jpg

And with this allocation Table:

AllocationTable.jpg

The expected result is:

DiagramExample.jpg

Implementation architecture

On this example, we have used 2 markers and one decoration specific function for each marker. The association between markers and decoration are done thanks to a specific extension point. An Edit policy is used to add markers to the decoration Service according to the model context. The edit policy is install to the right edit parts throw an edit policy provider, which is load by extension point.

ExampleArchitecture.jpg

The markers

For each type of stereotype NodeA and nodeB, a marker have been implemented with a specific markerType:

public class NodeAMarker implements IPapyrusMarker {
	public static final String MARKER_TYPE = "org.eclipse.papyrus.infra.services.decoration.example.NodeA"; //$NON-NLS-1$
	public static final String NODE_A_STEREOTYPE = "DecorationExampleProfile::NodeA";//$NON-NLS-1$
	protected View notationElement;
	public NodeAMarker(final View notationElement) {
		this.notationElement = notationElement;
	}
	@Override
	public boolean exists() {
		return ExampleUtils.isAllocatedTo((CallBehaviorAction) notationElement, NODE_A_STEREOTYPE);
	}
	@Override
	public String getType() throws CoreException {
		return MARKER_TYPE;
	}
	@Override
	public String getTypeLabel() throws CoreException {
		return "Node A marker example";
	}
	...


The NodeDecoration EditPolicy

These markers are add to the DecorationService thanks to a editPolicy applied to the CallBehavoir edit part.

The DecorationService is call in the Activate() method:

	@Override
	public void activate() {
		super.activate();
		// TODO install listener
		try {
			decorationService = ServiceUtilsForEditPart.getInstance().getService(DecorationService.class, getHost());
			refresh();
		} catch (final ServiceException ex) {
			// Ignored; do nothing
		}
	}

The refresh method adds or removes markers according to the allocated element on the UML element of the edit part:

	@Override
	public void refresh() {
		...
		// If the marker already set for nodeA have to be changed.
		if (ExampleUtils.isAllocatedTo((CallBehaviorAction) view.getElement(), NodeAMarker.NODE_A_STEREOTYPE) != isNodeAMarked) {
			isNodeAMarked = !isNodeAMarked;
			if (isNodeAMarked) {
				decorationService.addDecoration(getMarkerA(), getView());
			} else {
				decorationService.removeDecoration(getMarkerA().toString());
			}
			getHost().refresh();
		}
		// If the marker for nodeB already set have to be changed
		if (ExampleUtils.isAllocatedTo((CallBehaviorAction) view.getElement(), NodeBMarker.NODE_B_STEREOTYPE) != isNodeBMarked) {
			isNodeBMarked = !isNodeBMarked;
			if (isNodeBMarked) {
				decorationService.addDecoration(getMarkerB(), getView());
			} else {
				decorationService.removeDecoration(getMarkerB().toString());
			}
			getHost().refresh();
		}
	}

The CustomEditPolicy Provider

An edit policy provider is use to install the NodeDecorationEditPolicy to the right edit parts.

public class CustomEditPolicyProvider implements IEditPolicyProvider {
	protected String diagramType = org.eclipse.papyrus.uml.diagram.activity.edit.parts.ActivityDiagramEditPart.MODEL_ID;
	@Override
	public void addProviderChangeListener(final IProviderChangeListener listener) {
	}
	@Override
	public boolean provides(final IOperation operation) {
		boolean provide = false;
		String currentDiagramType;
		// get the element
		final EObject referenceElement = ((View) ((CreateEditPoliciesOperation) operation).getEditPart().getModel()).getElement();
		// Test if it's a creation operation and the element is a CallBehavoirActino
		if ((operation instanceof CreateEditPoliciesOperation) && (referenceElement instanceof CallBehaviorAction)) {
			// Get The current diagram type
			currentDiagramType = ((View) ((CreateEditPoliciesOperation) operation).getEditPart().getModel()).getDiagram().getType();
			// Test if we are on an Activity Diagram
			if ((diagramType != null) && (diagramType.equals(currentDiagramType))) {
				provide = true;
			} else {
				provide = false;
			}
		}
		return provide;
	}
	@Override
	public void removeProviderChangeListener(final IProviderChangeListener listener) {
	}
	@Override
	public void createEditPolicies(final EditPart editPart) {
		editPart.installEditPolicy(NodeDecoratorEditPolicy.EDIT_POLICY_ROLE, new NodeDecoratorEditPolicy());
	}
}

This edit policy provider is installed with the editpolicyProviders extension point:

EditPolicyProviderExtension.jpg

The Decoration Specific Function

The decoration specific function specify the decoration to be applied on a marked element. It's define the image, the position, the context message of the decoration etc...

public class NodeADecoration implements IDecorationSpecificFunctions {
	@Override
	public MarkChildren supportsMarkerPropagation() {
		// This marker should not be propagated
		return null;
	}
	@Override
	public ImageDescriptor getImageDescriptorForGE(final IPapyrusMarker marker) {
		return org.eclipse.papyrus.infra.widgets.Activator.getDefault().getImageDescriptor(Activator.ID, "icons/NodeA.gif"); //$NON-NLS-1$
	}
	@Override
	public PreferedPosition getPreferedPosition(final IPapyrusMarker marker) {
		return PreferedPosition.NORTH_EAST;
	}
	@Override
	public String getMessage(final IPapyrusMarker marker) {
		return "Node A decoration example";
	}
	@Override
	public int getPriority(final IPapyrusMarker marker) {
		return 0;
	}
}

To associate decoration specific function to a marker, an extension point are used. In the image below the decoration NodeAdecoration is linked to the marker type define on the marker NodeAMarker.MARKER_TYPE

SpecificFunctionExtension.jpg

Sources

The plugin of this example can be retrieve in the Papyrus git code repository here.

Back to the top