Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemi Schnekenburger2016-04-28 21:12:30 +0000
committerGerrit Code Review @ Eclipse.org2016-05-20 16:19:36 +0000
commitaea7ae97401e60b919cc0a824b8bdf12a40fb25a (patch)
tree958ecc24fa9584316adc16c351c3c43bbca0b5a1 /plugins/infra/gmfdiag
parentc1d2ca47d0d4facc38baaf798714ac6f7000103c (diff)
downloadorg.eclipse.papyrus-aea7ae97401e60b919cc0a824b8bdf12a40fb25a.tar.gz
org.eclipse.papyrus-aea7ae97401e60b919cc0a824b8bdf12a40fb25a.tar.xz
org.eclipse.papyrus-aea7ae97401e60b919cc0a824b8bdf12a40fb25a.zip
Bug 492697: [UseCase Diagram] User should be able to change the
representation of an Actor with the TypeSymbolDefinition stereotype https://bugs.eclipse.org/bugs/show_bug.cgi?id=492697 Change-Id: I9178d26555a141ed22990a48f4ad8aa279735969 Signed-off-by: Remi Schnekenburger <remi.schnekenburger@cea.fr>
Diffstat (limited to 'plugins/infra/gmfdiag')
-rw-r--r--plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css3.xtext.ui/src/org/eclipse/papyrus/infra/gmfdiag/css3/ui/contentassist/CustomCSSProposalProvider.java9
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/ShapeDecorator.java908
-rwxr-xr-xplugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/StyleBasedShapeProvider.java361
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/GetShapeDecorationsForViewOperation.java60
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/IShapeProvider.java184
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/ShapeService.java46
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/NamedStyleProperties.java6
7 files changed, 885 insertions, 689 deletions
diff --git a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css3.xtext.ui/src/org/eclipse/papyrus/infra/gmfdiag/css3/ui/contentassist/CustomCSSProposalProvider.java b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css3.xtext.ui/src/org/eclipse/papyrus/infra/gmfdiag/css3/ui/contentassist/CustomCSSProposalProvider.java
index f9fcadfccb6..a8c8215c6fc 100644
--- a/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css3.xtext.ui/src/org/eclipse/papyrus/infra/gmfdiag/css3/ui/contentassist/CustomCSSProposalProvider.java
+++ b/plugins/infra/gmfdiag/css/org.eclipse.papyrus.infra.gmfdiag.css3.xtext.ui/src/org/eclipse/papyrus/infra/gmfdiag/css3/ui/contentassist/CustomCSSProposalProvider.java
@@ -270,7 +270,14 @@ public class CustomCSSProposalProvider extends AbstractCSSProposalProvider {
NamedStyleProperties.USE_ORIGINAL_COLORS,
NamedStyleProperties.WRAP_NAME,
NamedStyleProperties.NAME_BACKGROUND_COLOR,
- NamedStyleProperties.IS_PORT_RESIZABLE
+ NamedStyleProperties.IS_PORT_RESIZABLE,
+ /* shape provider properties */
+ "shapeStereotype",
+ "shapeDecorationStereotype",
+ NamedStyleProperties.SHAPE_STYLE_PROPERTY,
+ NamedStyleProperties.SHAPE_DECORATION_STYLE_PROPERTY,
+ "shapeTypedElement",
+ "shapeDecorationTypedElement"
};
return Arrays.asList(properties);
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/ShapeDecorator.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/ShapeDecorator.java
index f6ee73bc8ca..ce53c1d19ba 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/ShapeDecorator.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/ShapeDecorator.java
@@ -1,454 +1,454 @@
-/*****************************************************************************
- * Copyright (c) 2012 CEA LIST.
- *
- * 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:
- * CEA LIST - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.gmfdiag.common.providers;
-
-import java.util.List;
-
-import org.eclipse.core.databinding.observable.ChangeEvent;
-import org.eclipse.core.databinding.observable.IChangeListener;
-import org.eclipse.draw2d.Figure;
-import org.eclipse.draw2d.IFigure;
-import org.eclipse.draw2d.Locator;
-import org.eclipse.draw2d.PositionConstants;
-import org.eclipse.draw2d.geometry.PrecisionRectangle;
-import org.eclipse.draw2d.geometry.Rectangle;
-import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.gef.EditPart;
-import org.eclipse.gef.EditPolicy;
-import org.eclipse.gef.handles.HandleBounds;
-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.IGraphicalEditPart;
-import org.eclipse.gmf.runtime.diagram.ui.editpolicies.XYLayoutEditPolicy;
-import org.eclipse.gmf.runtime.diagram.ui.services.decorator.AbstractDecorator;
-import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorTarget;
-import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorTarget.Direction;
-import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
-import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
-import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage;
-import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
-import org.eclipse.gmf.runtime.notation.DescriptionStyle;
-import org.eclipse.gmf.runtime.notation.Diagram;
-import org.eclipse.gmf.runtime.notation.IntValueStyle;
-import org.eclipse.gmf.runtime.notation.Node;
-import org.eclipse.gmf.runtime.notation.NotationPackage;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.papyrus.infra.gmfdiag.common.databinding.custom.CustomBooleanStyleObservableValue;
-import org.eclipse.papyrus.infra.gmfdiag.common.databinding.custom.CustomIntStyleObservableValue;
-import org.eclipse.papyrus.infra.gmfdiag.common.figure.node.BorderedScalableImageFigure;
-import org.eclipse.papyrus.infra.gmfdiag.common.figure.node.ShapeFlowLayout;
-import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.NotificationManager;
-import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.ShapeService;
-import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil;
-import org.eclipse.papyrus.infra.gmfdiag.common.utils.Util;
-
-/**
- *
- * The decorator to represent shapes for a given view. This decorator adds a set of small
- * images provided by the {@link ShapeService}.
- * 3 positions are defined for the decoration :
- * <ul>
- * <li>if the representation is an affixed child node : in {@link PositionConstants#NORTH_WEST} or {@link PositionConstants#SOUTH_EAST} following its position/parent and margin =1</li>
- * <li>else if the element is in a compartment list : {@link PositionConstants#EAST} and margin =-1</li>
- * <li>else {@link PositionConstants#SOUTH_EAST} and margin = -1</li>
- * </ul>
- */
-public class ShapeDecorator extends AbstractDecorator implements NotificationListener, IChangeListener {
-
- protected NotificationManager notificationManager;
-
- /** default vertical margin */
- protected static final int MARGIN_HEIGHT = 4;
-
- /** default horizontal margin */
- protected static final int MARGIN_WIDTH = 4;
-
- /** default image height */
- protected static final int IMAGE_WIDTH = 36; // 32
-
- /** default image width */
- protected static final int IMAGE_HEIGHT = 36; // 32
-
- /** name of the boolean style to manage visibility of the figure */
- public static final String SHAPE_DECORATOR_VISIBILITY = "shapeVisibility";
-
- /** name of the boolean style to manage direction of the decoration in the figure */
- public static final String SHAPE_DECORATOR_DIRECTION = "shapeDirection";
-
- /** listener on the custom style for visibility */
- protected CustomBooleanStyleObservableValue visibilityObservable;
-
- /** listener on the custom style for position */
- private CustomIntStyleObservableValue positionObservable;
-
- /** Store the view to be able to remove listeners in deactivate() */
- protected View view;
-
- /**
- * Creates a new <code>ShapeDecorator</code> for the decorator target
- * passed in.
- *
- * @param decoratorTarget
- * the object to be decorated
- */
- public ShapeDecorator(IDecoratorTarget decoratorTarget) {
- super(decoratorTarget);
- }
-
- /**
- * getDecoratorTargetClassifier Utility method to determine if the
- * decoratorTarget is a supported type for this decorator and return the
- * associated Classifier element.
- *
- * @param decoratorTarget
- * IDecoratorTarget to check and return valid Classifier target.
- * @return node Node if IDecoratorTarget can be supported, null otherwise.
- */
- static public View getDecoratorTargetNode(IDecoratorTarget decoratorTarget) {
- View node = decoratorTarget.getAdapter(View.class);
- return getDecorableNode(node);
- }
-
- static public Node getDecorableNode(View node) {
- if (node != null && !(node instanceof Diagram)) {
- DescriptionStyle descStyle = (DescriptionStyle) node.getStyle(NotationPackage.eINSTANCE.getDescriptionStyle());
- if (descStyle != null) {
- return (Node) node;
- }
- }
- return null;
- }
-
- static public boolean isDecorable(View node) {
- return getDecorableNode(node) != null;
- }
-
- /**
- * Creates the appropriate review decoration if all the criteria is
- * satisfied by the view passed in.
- */
-
- @Override
- public void refresh() {
- removeDecoration();
-
- View node = getDecoratorTargetNode(getDecoratorTarget());
- IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class);
-
- // should check if the shapes decorations are asked to be drawn
-
- if (node != null) {
- DescriptionStyle descStyle = getDescriptionStyle(node);
-
- if (descStyle != null && isDecorationVisible(node)) {
- // look for the custom style shape_visibility
- boolean hasShapes = ShapeService.getInstance().hasShapeToDisplay(node);
- if (hasShapes) {
- List<RenderedImage> shapesToDisplay = ShapeService.getInstance().getShapesToDisplay(node);
- if (!shapesToDisplay.isEmpty()) {
- IFigure figure = new Figure();
- // figure.setBorder(new LineBorder(1));
- IMapMode mm = MapModeUtil.getMapMode(((IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class)).getFigure());
- figure.setSize(mm.DPtoLP(shapesToDisplay.size() * IMAGE_WIDTH), mm.DPtoLP(IMAGE_HEIGHT));
- figure.setLayoutManager(new ShapeFlowLayout());
-
- for (RenderedImage image : shapesToDisplay) {
- BorderedScalableImageFigure subFigure = new BorderedScalableImageFigure(image, false, true, true);
- figure.add(subFigure);
- }
-
- if (isInCompartmentList(node) && !Util.isAffixedChildNode(gep)) {
- setDecoration(getDecoratorTarget().addShapeDecoration(figure, getDirection(node), -1, false));
- } else {
- Locator locator = new OverlayLocator(gep.getFigure(), getDirection(node));
- setDecoration(getDecoratorTarget().addDecoration(figure, locator, false));
- }
- }
- }
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void notifyChanged(Notification notification) {
- refresh();
- }
-
- /**
- * Returns the direction to set the decorator for the node
- *
- * @param node
- * the node
- * @return the direction to set the decorator for the node direction can be
- * :
- * <ul>
- * <li>{@link PositionConstants#NORTH_WEST} or {@link PositionConstants#SOUTH_EAST}</li> if the node is an Affixed Child Node
- * <li>{@link PositionConstants#EAST}</li> if the node is in a compartment list
- * <li>{@link PositionConstants#SOUTH_EAST}</li> in other cases
- * </ul>
- */
- protected Direction getDirection(View node) {
- IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class);
- assert gep != null;
- if (gep.getParent() != null) {
- if (isInCompartmentList(node) && !Util.isAffixedChildNode(gep)) {
- return IDecoratorTarget.Direction.EAST;
- }
- }
-
- // get the custom style for the direction
- IntValueStyle directionStyle = (IntValueStyle) node.getNamedStyle(NotationPackage.eINSTANCE.getIntValueStyle(), SHAPE_DECORATOR_DIRECTION);
- if (directionStyle != null) {
- int direction = directionStyle.getIntValue();
- switch (direction) {
- case 0: // NORTH WEST
- return IDecoratorTarget.Direction.NORTH_WEST;
- case 1: // NORTH
- return IDecoratorTarget.Direction.NORTH;
- case 2: // NORTH EAST
- return IDecoratorTarget.Direction.NORTH_EAST;
- case 3: // WEST
- return IDecoratorTarget.Direction.WEST;
- case 4: // CENTER
- return IDecoratorTarget.Direction.CENTER;
- case 5: // EAST
- return IDecoratorTarget.Direction.EAST;
- case 6: // SOUTH WEST
- return IDecoratorTarget.Direction.SOUTH_WEST;
- case 7: // SOUTH
- return IDecoratorTarget.Direction.SOUTH;
- case 8: // SOUTH EAST
- return IDecoratorTarget.Direction.SOUTH_EAST;
- default:
- return IDecoratorTarget.Direction.NORTH_WEST;
- }
- }
-
- return IDecoratorTarget.Direction.NORTH_WEST;
- }
-
- /**
- * Returns <code>true</code> if the decorations should be visible
- *
- * @param node
- * the node to test
- * @return <code>true</code> if the decoration should be displayed
- */
- protected boolean isDecorationVisible(View node) {
- BooleanValueStyle visibilityStyle = (BooleanValueStyle) node.getNamedStyle(NotationPackage.eINSTANCE.getBooleanValueStyle(), SHAPE_DECORATOR_VISIBILITY);
- if (visibilityStyle != null) {
- return visibilityStyle.isBooleanValue();
- }
-
- // FIXME return the value in the preferences
- return false;
- }
-
- /**
- * Tests if the compartment is a compartment list
- *
- * @param node
- * the node on which we want add an Overlay
- * @return <code>true</code> if the compartment is managed by an {@link XYLayoutEditPolicy}
- */
- protected boolean isInCompartmentList(View node) {
- IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class);
- if (gep != null && gep.getRoot() != null) {
- EObject container = node.eContainer();
- if (container instanceof View) {
- EditPart EP = DiagramEditPartsUtil.getEditPartFromView((View) container, gep);
- EditPolicy editPolicy = EP.getEditPolicy(EditPolicy.LAYOUT_ROLE);
- if (!(editPolicy instanceof XYLayoutEditPolicy)) { // we are in a compartment list
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * getDescriptionStyle Accessor to retrieve the description style from a
- * Node.
- *
- * @param node
- * Node to retrieve the description style from.
- * @return DescriptionStyle style object
- */
- protected DescriptionStyle getDescriptionStyle(View node) {
- return (DescriptionStyle) node.getStyle(NotationPackage.eINSTANCE.getDescriptionStyle());
- }
-
- /**
- * Adds listeners on
- * <ul>
- * <li>Affixed Child Node</li>
- * <li>graphical parent, when its a Property (we add the listener on its Type)</li>
- * </ul>
- */
- @Override
- public void activate() {
- view = getView();
- if (view == null) {
- return;
- }
- // listens for modifications on the container of the compartment, i.e. the figure that handle stereotype management (ClassifierView for example)
- notificationManager = ShapeService.getInstance().createNotificationManager(getDiagramEventBroker(), view, this);
-
- TransactionalEditingDomain domain = getTransactionalEditingDomain((IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class));
-
- if (domain != null) {
- visibilityObservable = new CustomBooleanStyleObservableValue(view, domain, SHAPE_DECORATOR_VISIBILITY);
- visibilityObservable.addChangeListener(this);
-
- positionObservable = new CustomIntStyleObservableValue(view, domain, SHAPE_DECORATOR_DIRECTION);
- positionObservable.addChangeListener(this);
- }
- }
-
- /**
- * Removes the listeners and the decorations
- */
- @Override
- public void deactivate() {
- // retrieve the view and the element managed by the edit part
- if (view == null) {
- return;
- }
- notificationManager.dispose();
- notificationManager = null;
-
- if (visibilityObservable != null) {
- visibilityObservable.dispose();
- visibilityObservable = null;
- }
- if (positionObservable != null) {
- positionObservable.dispose();
- positionObservable = null;
- }
- super.deactivate();
- }
-
- protected View getView() {
- IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class);
- if (gep == null) {
- return null;
- }
- View view = ((View) gep.getModel());
- return view;
- }
-
- protected TransactionalEditingDomain getTransactionalEditingDomain(IGraphicalEditPart editPart) {
- if (editPart != null) {
- return editPart.getEditingDomain();
- }
- return null;
- }
-
- /**
- * Gets the diagram event broker from the editing domain.
- *
- * @return the diagram event broker
- */
- protected DiagramEventBroker getDiagramEventBroker() {
- IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class);
- TransactionalEditingDomain editingDomain = getTransactionalEditingDomain(gep);
- if (editingDomain != null) {
- return DiagramEventBroker.getInstance(editingDomain);
- }
- return null;
- }
-
- public class OverlayLocator implements Locator {
-
- /** the reference figure */
- private IFigure reference;
-
- /** the Overlay Position */
- private Direction position = null;
-
- /**
- *
- * Constructor.
- *
- * @param reference
- * the reference figure
- * @param position
- * the overlay position
- */
- public OverlayLocator(IFigure reference, IDecoratorTarget.Direction position) {
- assert reference != null;
- this.reference = reference;
- this.position = position;
- }
-
- /**
- *
- * @see org.eclipse.draw2d.Locator#relocate(org.eclipse.draw2d.IFigure)
- *
- * @param target
- * the overlay figure to locate
- */
- @Override
- public void relocate(IFigure target) {
- Rectangle bounds = reference instanceof HandleBounds ? new PrecisionRectangle(((HandleBounds) reference).getHandleBounds()) : new PrecisionRectangle(reference.getBounds());
-
- reference.translateToAbsolute(bounds);
- target.translateToRelative(bounds);
-
- int width = IMAGE_WIDTH;
- int height = IMAGE_HEIGHT;
- // retrieve the lisf of scalable figures => children of the child.
- if (target.getChildren().size() == 1) {
- IFigure parentFigure = (IFigure) target.getChildren().get(0);
- if (parentFigure.getChildren().size() > 1) {
- width = parentFigure.getChildren().size() * IMAGE_WIDTH + (parentFigure.getChildren().size() - 1) * MARGIN_WIDTH /* margin inside */;
- }
- }
-
- if (Direction.NORTH_WEST.equals(this.position)) {
- target.setLocation(bounds.getTopLeft().getTranslated(MARGIN_WIDTH, MARGIN_HEIGHT));
- } else if (Direction.NORTH.equals(this.position)) {
- target.setLocation(bounds.getTop().getTranslated(-width / 2, MARGIN_HEIGHT));
- } else if (Direction.NORTH_EAST.equals(this.position)) {
- target.setLocation(bounds.getTopRight().getTranslated(-MARGIN_WIDTH - width, MARGIN_HEIGHT));
- } else if (Direction.SOUTH_WEST.equals(this.position)) {
- target.setLocation(bounds.getBottomLeft().getTranslated(MARGIN_WIDTH, -MARGIN_HEIGHT - height));
- } else if (Direction.SOUTH.equals(this.position)) {
- target.setLocation(bounds.getBottom().getTranslated(-width / 2, -MARGIN_HEIGHT - height));
- } else if (Direction.SOUTH_EAST.equals(this.position)) {
- target.setLocation(bounds.getBottomRight().getTranslated(-MARGIN_WIDTH - width, -MARGIN_HEIGHT - height));
- } else if (Direction.WEST.equals(this.position)) {
- target.setLocation(bounds.getLeft().getTranslated(MARGIN_WIDTH, -height / 2));
- } else if (Direction.EAST.equals(this.position)) {
- target.setLocation(bounds.getRight().getTranslated(-MARGIN_WIDTH - width, -height / 2));
- } else if (Direction.CENTER.equals(this.position)) {
- target.setLocation(bounds.getCenter().getTranslated(-width / 2, -height / 2));
- }
-
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleChange(ChangeEvent event) {
- refresh();
-
- }
-}
+/*****************************************************************************
+ * Copyright (c) 2012 CEA LIST.
+ *
+ * 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.common.providers;
+
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.ChangeEvent;
+import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.draw2d.Figure;
+import org.eclipse.draw2d.IFigure;
+import org.eclipse.draw2d.Locator;
+import org.eclipse.draw2d.PositionConstants;
+import org.eclipse.draw2d.geometry.PrecisionRectangle;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPolicy;
+import org.eclipse.gef.handles.HandleBounds;
+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.IGraphicalEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.editpolicies.XYLayoutEditPolicy;
+import org.eclipse.gmf.runtime.diagram.ui.services.decorator.AbstractDecorator;
+import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorTarget;
+import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorTarget.Direction;
+import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
+import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
+import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage;
+import org.eclipse.gmf.runtime.notation.BooleanValueStyle;
+import org.eclipse.gmf.runtime.notation.DescriptionStyle;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.IntValueStyle;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.infra.gmfdiag.common.databinding.custom.CustomBooleanStyleObservableValue;
+import org.eclipse.papyrus.infra.gmfdiag.common.databinding.custom.CustomIntStyleObservableValue;
+import org.eclipse.papyrus.infra.gmfdiag.common.figure.node.BorderedScalableImageFigure;
+import org.eclipse.papyrus.infra.gmfdiag.common.figure.node.ShapeFlowLayout;
+import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.NotificationManager;
+import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.ShapeService;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramEditPartsUtil;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.Util;
+
+/**
+ *
+ * The decorator to represent shapes for a given view. This decorator adds a set of small
+ * images provided by the {@link ShapeService}.
+ * 3 positions are defined for the decoration :
+ * <ul>
+ * <li>if the representation is an affixed child node : in {@link PositionConstants#NORTH_WEST} or {@link PositionConstants#SOUTH_EAST} following its position/parent and margin =1</li>
+ * <li>else if the element is in a compartment list : {@link PositionConstants#EAST} and margin =-1</li>
+ * <li>else {@link PositionConstants#SOUTH_EAST} and margin = -1</li>
+ * </ul>
+ */
+public class ShapeDecorator extends AbstractDecorator implements NotificationListener, IChangeListener {
+
+ protected NotificationManager notificationManager;
+
+ /** default vertical margin */
+ protected static final int MARGIN_HEIGHT = 4;
+
+ /** default horizontal margin */
+ protected static final int MARGIN_WIDTH = 4;
+
+ /** default image height */
+ protected static final int IMAGE_WIDTH = 36; // 32
+
+ /** default image width */
+ protected static final int IMAGE_HEIGHT = 36; // 32
+
+ /** name of the boolean style to manage visibility of the figure */
+ public static final String SHAPE_DECORATOR_VISIBILITY = "shapeVisibility";
+
+ /** name of the boolean style to manage direction of the decoration in the figure */
+ public static final String SHAPE_DECORATOR_DIRECTION = "shapeDirection";
+
+ /** listener on the custom style for visibility */
+ protected CustomBooleanStyleObservableValue visibilityObservable;
+
+ /** listener on the custom style for position */
+ private CustomIntStyleObservableValue positionObservable;
+
+ /** Store the view to be able to remove listeners in deactivate() */
+ protected View view;
+
+ /**
+ * Creates a new <code>ShapeDecorator</code> for the decorator target
+ * passed in.
+ *
+ * @param decoratorTarget
+ * the object to be decorated
+ */
+ public ShapeDecorator(IDecoratorTarget decoratorTarget) {
+ super(decoratorTarget);
+ }
+
+ /**
+ * getDecoratorTargetClassifier Utility method to determine if the
+ * decoratorTarget is a supported type for this decorator and return the
+ * associated Classifier element.
+ *
+ * @param decoratorTarget
+ * IDecoratorTarget to check and return valid Classifier target.
+ * @return node Node if IDecoratorTarget can be supported, null otherwise.
+ */
+ static public View getDecoratorTargetNode(IDecoratorTarget decoratorTarget) {
+ View node = decoratorTarget.getAdapter(View.class);
+ return getDecorableNode(node);
+ }
+
+ static public Node getDecorableNode(View node) {
+ if (node != null && !(node instanceof Diagram)) {
+ DescriptionStyle descStyle = (DescriptionStyle) node.getStyle(NotationPackage.eINSTANCE.getDescriptionStyle());
+ if (descStyle != null) {
+ return (Node) node;
+ }
+ }
+ return null;
+ }
+
+ static public boolean isDecorable(View node) {
+ return getDecorableNode(node) != null;
+ }
+
+ /**
+ * Creates the appropriate review decoration if all the criteria is
+ * satisfied by the view passed in.
+ */
+
+ @Override
+ public void refresh() {
+ removeDecoration();
+
+ View node = getDecoratorTargetNode(getDecoratorTarget());
+ IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class);
+
+ // should check if the shapes decorations are asked to be drawn
+
+ if (node != null) {
+ DescriptionStyle descStyle = getDescriptionStyle(node);
+
+ if (descStyle != null && isDecorationVisible(node)) {
+ // look for the custom style shape_visibility
+ boolean hasShapes = ShapeService.getInstance().hasShapeToDisplay(node);
+ if (hasShapes) {
+ List<RenderedImage> shapesToDisplay = ShapeService.getInstance().getShapeDecorationsToDisplay(node);
+ if (!shapesToDisplay.isEmpty()) {
+ IFigure figure = new Figure();
+ // figure.setBorder(new LineBorder(1));
+ IMapMode mm = MapModeUtil.getMapMode(((IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class)).getFigure());
+ figure.setSize(mm.DPtoLP(shapesToDisplay.size() * IMAGE_WIDTH), mm.DPtoLP(IMAGE_HEIGHT));
+ figure.setLayoutManager(new ShapeFlowLayout());
+
+ for (RenderedImage image : shapesToDisplay) {
+ BorderedScalableImageFigure subFigure = new BorderedScalableImageFigure(image, false, true, true);
+ figure.add(subFigure);
+ }
+
+ if (isInCompartmentList(node) && !Util.isAffixedChildNode(gep)) {
+ setDecoration(getDecoratorTarget().addShapeDecoration(figure, getDirection(node), -1, false));
+ } else {
+ Locator locator = new OverlayLocator(gep.getFigure(), getDirection(node));
+ setDecoration(getDecoratorTarget().addDecoration(figure, locator, false));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void notifyChanged(Notification notification) {
+ refresh();
+ }
+
+ /**
+ * Returns the direction to set the decorator for the node
+ *
+ * @param node
+ * the node
+ * @return the direction to set the decorator for the node direction can be
+ * :
+ * <ul>
+ * <li>{@link PositionConstants#NORTH_WEST} or {@link PositionConstants#SOUTH_EAST}</li> if the node is an Affixed Child Node
+ * <li>{@link PositionConstants#EAST}</li> if the node is in a compartment list
+ * <li>{@link PositionConstants#SOUTH_EAST}</li> in other cases
+ * </ul>
+ */
+ protected Direction getDirection(View node) {
+ IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class);
+ assert gep != null;
+ if (gep.getParent() != null) {
+ if (isInCompartmentList(node) && !Util.isAffixedChildNode(gep)) {
+ return IDecoratorTarget.Direction.EAST;
+ }
+ }
+
+ // get the custom style for the direction
+ IntValueStyle directionStyle = (IntValueStyle) node.getNamedStyle(NotationPackage.eINSTANCE.getIntValueStyle(), SHAPE_DECORATOR_DIRECTION);
+ if (directionStyle != null) {
+ int direction = directionStyle.getIntValue();
+ switch (direction) {
+ case 0: // NORTH WEST
+ return IDecoratorTarget.Direction.NORTH_WEST;
+ case 1: // NORTH
+ return IDecoratorTarget.Direction.NORTH;
+ case 2: // NORTH EAST
+ return IDecoratorTarget.Direction.NORTH_EAST;
+ case 3: // WEST
+ return IDecoratorTarget.Direction.WEST;
+ case 4: // CENTER
+ return IDecoratorTarget.Direction.CENTER;
+ case 5: // EAST
+ return IDecoratorTarget.Direction.EAST;
+ case 6: // SOUTH WEST
+ return IDecoratorTarget.Direction.SOUTH_WEST;
+ case 7: // SOUTH
+ return IDecoratorTarget.Direction.SOUTH;
+ case 8: // SOUTH EAST
+ return IDecoratorTarget.Direction.SOUTH_EAST;
+ default:
+ return IDecoratorTarget.Direction.NORTH_WEST;
+ }
+ }
+
+ return IDecoratorTarget.Direction.NORTH_WEST;
+ }
+
+ /**
+ * Returns <code>true</code> if the decorations should be visible
+ *
+ * @param node
+ * the node to test
+ * @return <code>true</code> if the decoration should be displayed
+ */
+ protected boolean isDecorationVisible(View node) {
+ BooleanValueStyle visibilityStyle = (BooleanValueStyle) node.getNamedStyle(NotationPackage.eINSTANCE.getBooleanValueStyle(), SHAPE_DECORATOR_VISIBILITY);
+ if (visibilityStyle != null) {
+ return visibilityStyle.isBooleanValue();
+ }
+
+ // FIXME return the value in the preferences
+ return false;
+ }
+
+ /**
+ * Tests if the compartment is a compartment list
+ *
+ * @param node
+ * the node on which we want add an Overlay
+ * @return <code>true</code> if the compartment is managed by an {@link XYLayoutEditPolicy}
+ */
+ protected boolean isInCompartmentList(View node) {
+ IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class);
+ if (gep != null && gep.getRoot() != null) {
+ EObject container = node.eContainer();
+ if (container instanceof View) {
+ EditPart EP = DiagramEditPartsUtil.getEditPartFromView((View) container, gep);
+ EditPolicy editPolicy = EP.getEditPolicy(EditPolicy.LAYOUT_ROLE);
+ if (!(editPolicy instanceof XYLayoutEditPolicy)) { // we are in a compartment list
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * getDescriptionStyle Accessor to retrieve the description style from a
+ * Node.
+ *
+ * @param node
+ * Node to retrieve the description style from.
+ * @return DescriptionStyle style object
+ */
+ protected DescriptionStyle getDescriptionStyle(View node) {
+ return (DescriptionStyle) node.getStyle(NotationPackage.eINSTANCE.getDescriptionStyle());
+ }
+
+ /**
+ * Adds listeners on
+ * <ul>
+ * <li>Affixed Child Node</li>
+ * <li>graphical parent, when its a Property (we add the listener on its Type)</li>
+ * </ul>
+ */
+ @Override
+ public void activate() {
+ view = getView();
+ if (view == null) {
+ return;
+ }
+ // listens for modifications on the container of the compartment, i.e. the figure that handle stereotype management (ClassifierView for example)
+ notificationManager = ShapeService.getInstance().createNotificationManager(getDiagramEventBroker(), view, this);
+
+ TransactionalEditingDomain domain = getTransactionalEditingDomain((IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class));
+
+ if (domain != null) {
+ visibilityObservable = new CustomBooleanStyleObservableValue(view, domain, SHAPE_DECORATOR_VISIBILITY);
+ visibilityObservable.addChangeListener(this);
+
+ positionObservable = new CustomIntStyleObservableValue(view, domain, SHAPE_DECORATOR_DIRECTION);
+ positionObservable.addChangeListener(this);
+ }
+ }
+
+ /**
+ * Removes the listeners and the decorations
+ */
+ @Override
+ public void deactivate() {
+ // retrieve the view and the element managed by the edit part
+ if (view == null) {
+ return;
+ }
+ notificationManager.dispose();
+ notificationManager = null;
+
+ if (visibilityObservable != null) {
+ visibilityObservable.dispose();
+ visibilityObservable = null;
+ }
+ if (positionObservable != null) {
+ positionObservable.dispose();
+ positionObservable = null;
+ }
+ super.deactivate();
+ }
+
+ protected View getView() {
+ IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class);
+ if (gep == null) {
+ return null;
+ }
+ View view = ((View) gep.getModel());
+ return view;
+ }
+
+ protected TransactionalEditingDomain getTransactionalEditingDomain(IGraphicalEditPart editPart) {
+ if (editPart != null) {
+ return editPart.getEditingDomain();
+ }
+ return null;
+ }
+
+ /**
+ * Gets the diagram event broker from the editing domain.
+ *
+ * @return the diagram event broker
+ */
+ protected DiagramEventBroker getDiagramEventBroker() {
+ IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class);
+ TransactionalEditingDomain editingDomain = getTransactionalEditingDomain(gep);
+ if (editingDomain != null) {
+ return DiagramEventBroker.getInstance(editingDomain);
+ }
+ return null;
+ }
+
+ public class OverlayLocator implements Locator {
+
+ /** the reference figure */
+ private IFigure reference;
+
+ /** the Overlay Position */
+ private Direction position = null;
+
+ /**
+ *
+ * Constructor.
+ *
+ * @param reference
+ * the reference figure
+ * @param position
+ * the overlay position
+ */
+ public OverlayLocator(IFigure reference, IDecoratorTarget.Direction position) {
+ assert reference != null;
+ this.reference = reference;
+ this.position = position;
+ }
+
+ /**
+ *
+ * @see org.eclipse.draw2d.Locator#relocate(org.eclipse.draw2d.IFigure)
+ *
+ * @param target
+ * the overlay figure to locate
+ */
+ @Override
+ public void relocate(IFigure target) {
+ Rectangle bounds = reference instanceof HandleBounds ? new PrecisionRectangle(((HandleBounds) reference).getHandleBounds()) : new PrecisionRectangle(reference.getBounds());
+
+ reference.translateToAbsolute(bounds);
+ target.translateToRelative(bounds);
+
+ int width = IMAGE_WIDTH;
+ int height = IMAGE_HEIGHT;
+ // retrieve the lisf of scalable figures => children of the child.
+ if (target.getChildren().size() == 1) {
+ IFigure parentFigure = (IFigure) target.getChildren().get(0);
+ if (parentFigure.getChildren().size() > 1) {
+ width = parentFigure.getChildren().size() * IMAGE_WIDTH + (parentFigure.getChildren().size() - 1) * MARGIN_WIDTH /* margin inside */;
+ }
+ }
+
+ if (Direction.NORTH_WEST.equals(this.position)) {
+ target.setLocation(bounds.getTopLeft().getTranslated(MARGIN_WIDTH, MARGIN_HEIGHT));
+ } else if (Direction.NORTH.equals(this.position)) {
+ target.setLocation(bounds.getTop().getTranslated(-width / 2, MARGIN_HEIGHT));
+ } else if (Direction.NORTH_EAST.equals(this.position)) {
+ target.setLocation(bounds.getTopRight().getTranslated(-MARGIN_WIDTH - width, MARGIN_HEIGHT));
+ } else if (Direction.SOUTH_WEST.equals(this.position)) {
+ target.setLocation(bounds.getBottomLeft().getTranslated(MARGIN_WIDTH, -MARGIN_HEIGHT - height));
+ } else if (Direction.SOUTH.equals(this.position)) {
+ target.setLocation(bounds.getBottom().getTranslated(-width / 2, -MARGIN_HEIGHT - height));
+ } else if (Direction.SOUTH_EAST.equals(this.position)) {
+ target.setLocation(bounds.getBottomRight().getTranslated(-MARGIN_WIDTH - width, -MARGIN_HEIGHT - height));
+ } else if (Direction.WEST.equals(this.position)) {
+ target.setLocation(bounds.getLeft().getTranslated(MARGIN_WIDTH, -height / 2));
+ } else if (Direction.EAST.equals(this.position)) {
+ target.setLocation(bounds.getRight().getTranslated(-MARGIN_WIDTH - width, -height / 2));
+ } else if (Direction.CENTER.equals(this.position)) {
+ target.setLocation(bounds.getCenter().getTranslated(-width / 2, -height / 2));
+ }
+
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleChange(ChangeEvent event) {
+ refresh();
+
+ }
+}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/StyleBasedShapeProvider.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/StyleBasedShapeProvider.java
index 1420664093d..ed8fad227ee 100755
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/StyleBasedShapeProvider.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/StyleBasedShapeProvider.java
@@ -1,147 +1,214 @@
-/*****************************************************************************
- * Copyright (c) 2014 CEA LIST.
- *
- * 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:
- * CEA LIST - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.gmfdiag.common.providers;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker;
-import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener;
-import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage;
-import org.eclipse.gmf.runtime.notation.NotationPackage;
-import org.eclipse.gmf.runtime.notation.StringValueStyle;
-import org.eclipse.gmf.runtime.notation.View;
-import org.eclipse.papyrus.infra.gmfdiag.common.Activator;
-import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.AbstractShapeProvider;
-import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.ProviderNotificationManager;
-import org.w3c.dom.svg.SVGDocument;
-
-/**
- * Shape provider based on the applied style
- *
- * @author Laurent Wouters
- */
-public class StyleBasedShapeProvider extends AbstractShapeProvider {
-
- protected static final String STYLE_PROPERTY = "svgFile";
-
- private ProviderNotificationManager manager;
-
- private List<SVGDocument> listEmptySVG;
- private List<RenderedImage> listEmptyRendered;
- private List<SVGDocument> listSingletonSVG;
- private List<RenderedImage> listSingletonRendered;
-
- public StyleBasedShapeProvider() {
- listEmptySVG = new ArrayList<SVGDocument>(0);
- listEmptyRendered = new ArrayList<RenderedImage>(0);
- listSingletonSVG = new ArrayList<SVGDocument>(1);
- listSingletonSVG.add(null);
- listSingletonRendered = new ArrayList<RenderedImage>(1);
- listSingletonRendered.add(null);
- }
-
- /**
- * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#getShapes(org.eclipse.emf.ecore.EObject)
- */
- @Override
- public List<RenderedImage> getShapes(EObject view) {
- if (!(view instanceof View)) {
- return listEmptyRendered;
- }
- View v = (View) view;
- String svgFile = extract((StringValueStyle) v.getNamedStyle(NotationPackage.eINSTANCE.getStringValueStyle(), STYLE_PROPERTY));
- if (svgFile == null) {
- return listEmptyRendered;
- }
- SVGDocument svg = getSVGDocument(view, svgFile);
- if (svg == null){
- Activator.log.warn("Invalid SVG File path: "+svgFile);
- return null;
- }
- RenderedImage img = null;
- try {
- img = renderSVGDocument(view, svg);
- } catch (IOException e) {
- Activator.log.error("Failed to render the svg file: " + svgFile, e);
- }
- listSingletonRendered.set(0, img);
- return listSingletonRendered;
- }
-
- /**
- * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#getSVGDocument(org.eclipse.emf.ecore.EObject)
- */
- @Override
- public List<SVGDocument> getSVGDocument(EObject view) {
- if (!(view instanceof View)) {
- return listEmptySVG;
- }
- View v = (View) view;
- String svgFile = extract((StringValueStyle) v.getNamedStyle(NotationPackage.eINSTANCE.getStringValueStyle(), STYLE_PROPERTY));
- if (svgFile == null) {
- return listEmptySVG;
- }
- SVGDocument svg = getSVGDocument(view, svgFile);
- listSingletonSVG.set(0, svg);
- return listSingletonSVG;
- }
-
- /**
- * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#providesShapes(org.eclipse.emf.ecore.EObject)
- */
- @Override
- public boolean providesShapes(EObject view) {
- if (!(view instanceof View)) {
- return false;
- }
- View v = (View) view;
- String svgFile = extract((StringValueStyle) v.getNamedStyle(NotationPackage.eINSTANCE.getStringValueStyle(), STYLE_PROPERTY));
- return (svgFile != null);
- }
-
- /**
- * Extracts the primitive value from the given style
- *
- * @param style
- * The style
- * @return The primitive value
- */
- private String extract(StringValueStyle style) {
- if (style == null || style.getStringValue() == null || style.getStringValue().isEmpty()) {
- return null;
- }
- return style.getStringValue();
- }
-
- /**
- * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#createProviderNotificationManager(org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker, org.eclipse.emf.ecore.EObject,
- * org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener)
- */
- @Override
- public ProviderNotificationManager createProviderNotificationManager(DiagramEventBroker diagramEventBroker, EObject view, NotificationListener notificationListener) {
- if (manager != null) {
- return manager;
- }
- manager = new ProviderNotificationManager(diagramEventBroker, view, notificationListener) {
- @Override
- protected void registerListeners() {
-
- }
- };
- return manager;
- }
-}
+/*****************************************************************************
+ * Copyright (c) 2014 CEA LIST.
+ *
+ * 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.common.providers;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker;
+import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener;
+import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.StringValueStyle;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.infra.gmfdiag.common.Activator;
+import org.eclipse.papyrus.infra.gmfdiag.common.model.NotationUtils;
+import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.AbstractShapeProvider;
+import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.ProviderNotificationManager;
+import org.eclipse.papyrus.infra.gmfdiag.common.utils.NamedStyleProperties;
+import org.w3c.dom.svg.SVGDocument;
+
+/**
+ * Shape provider based on the applied style
+ *
+ * @author Laurent Wouters
+ */
+public class StyleBasedShapeProvider extends AbstractShapeProvider {
+
+ protected static final String STYLE_PROPERTY = "svgFile";
+
+ private ProviderNotificationManager manager;
+
+ private List<SVGDocument> listEmptySVG;
+ private List<RenderedImage> listEmptyRendered;
+ private List<SVGDocument> listSingletonSVG;
+ private List<RenderedImage> listSingletonRendered;
+
+ public StyleBasedShapeProvider() {
+ listEmptySVG = new ArrayList<SVGDocument>(0);
+ listEmptyRendered = new ArrayList<RenderedImage>(0);
+ listSingletonSVG = new ArrayList<SVGDocument>(1);
+ listSingletonSVG.add(null);
+ listSingletonRendered = new ArrayList<RenderedImage>(1);
+ listSingletonRendered.add(null);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#getShapes(org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ public List<RenderedImage> getShapes(EObject view) {
+ if (!(view instanceof View)) {
+ return listEmptyRendered;
+ }
+ View v = (View) view;
+
+ if (!isShapeStyleEnable(v)) {
+ return listEmptyRendered;
+ }
+
+ return doGetShapes(v);
+ }
+
+ protected List<RenderedImage> doGetShapes(View view) {
+ String svgFile = extract((StringValueStyle) view.getNamedStyle(NotationPackage.eINSTANCE.getStringValueStyle(), STYLE_PROPERTY));
+ if (svgFile == null) {
+ return listEmptyRendered;
+ }
+ SVGDocument svg = getSVGDocument(view, svgFile);
+ if (svg == null) {
+ Activator.log.warn("Invalid SVG File path: " + svgFile);
+ return null;
+ }
+ RenderedImage img = null;
+ try {
+ img = renderSVGDocument(view, svg);
+ } catch (IOException e) {
+ Activator.log.error("Failed to render the svg file: " + svgFile, e);
+ }
+ listSingletonRendered.set(0, img);
+ return listSingletonRendered;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#getShapesForDecoration(org.eclipse.emf.ecore.EObject)
+ *
+ * @param view
+ * @return
+ */
+ @Override
+ public List<RenderedImage> getShapesForDecoration(EObject view) {
+ if (!(view instanceof View)) {
+ return listEmptyRendered;
+ }
+ View v = (View) view;
+
+ if (!isShapeDecorationStyleEnable(v)) {
+ return listEmptyRendered;
+ }
+
+ return doGetShapesForDecoration(v);
+ }
+
+ protected List<RenderedImage> doGetShapesForDecoration(View view) {
+ return doGetShapes(view);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#getSVGDocument(org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ public List<SVGDocument> getSVGDocument(EObject view) {
+ if (!(view instanceof View)) {
+ return listEmptySVG;
+ }
+ View v = (View) view;
+
+ if (!isShapeStyleEnable(v)) {
+ return listEmptySVG;
+ }
+
+ String svgFile = extract((StringValueStyle) v.getNamedStyle(NotationPackage.eINSTANCE.getStringValueStyle(), STYLE_PROPERTY));
+ if (svgFile == null) {
+ return listEmptySVG;
+ }
+ SVGDocument svg = getSVGDocument(view, svgFile);
+ listSingletonSVG.set(0, svg);
+ return listSingletonSVG;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#providesShapes(org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ public boolean providesShapes(EObject view) {
+ if (!(view instanceof View)) {
+ return false;
+ }
+ View v = (View) view;
+
+ if (!isShapeStyleEnable(v)) {
+ return false;
+ }
+
+ String svgFile = extract((StringValueStyle) v.getNamedStyle(NotationPackage.eINSTANCE.getStringValueStyle(), STYLE_PROPERTY));
+ return (svgFile != null);
+ }
+
+ /**
+ * Returns <code>false</code> if the given view specifically removes the support for css-defined shapes.
+ *
+ * @param view
+ * the view to check style
+ * @return <code>false</code> if the given view specifically removes the support for css-defined shapes, otherwise <code>true</code>.
+ */
+ private boolean isShapeStyleEnable(View view) {
+ return NotationUtils.getBooleanValue(view, NamedStyleProperties.SHAPE_STYLE_PROPERTY, true);
+ }
+
+ /**
+ * Returns <code>false</code> if the given view specifically removes the support for css-defined shapes.
+ *
+ * @param view
+ * the view to check style
+ * @return <code>false</code> if the given view specifically removes the support for css-defined shapes, otherwise <code>true</code>.
+ */
+ private boolean isShapeDecorationStyleEnable(View view) {
+ return NotationUtils.getBooleanValue(view, NamedStyleProperties.SHAPE_DECORATION_STYLE_PROPERTY, true);
+ }
+
+ /**
+ * Extracts the primitive value from the given style
+ *
+ * @param style
+ * The style
+ * @return The primitive value
+ */
+ private String extract(StringValueStyle style) {
+ if (style == null || style.getStringValue() == null || style.getStringValue().isEmpty()) {
+ return null;
+ }
+ return style.getStringValue();
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#createProviderNotificationManager(org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker, org.eclipse.emf.ecore.EObject,
+ * org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener)
+ */
+ @Override
+ public ProviderNotificationManager createProviderNotificationManager(DiagramEventBroker diagramEventBroker, EObject view, NotificationListener notificationListener) {
+ if (manager != null) {
+ return manager;
+ }
+ manager = new ProviderNotificationManager(diagramEventBroker, view, notificationListener) {
+ @Override
+ protected void registerListeners() {
+
+ }
+ };
+ return manager;
+ }
+
+}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/GetShapeDecorationsForViewOperation.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/GetShapeDecorationsForViewOperation.java
new file mode 100644
index 00000000000..5f374872410
--- /dev/null
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/GetShapeDecorationsForViewOperation.java
@@ -0,0 +1,60 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * 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:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.common.service.shape;
+
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage;
+
+/**
+ * Operation to find a list of shapes for decoration, given a view
+ */
+public class GetShapeDecorationsForViewOperation implements IOperation, IShapeProviderOperation {
+
+ /** View from which shape has to be retrieved */
+ private final EObject view;
+
+ /**
+ * Creates a new GetShapeProvidersForViewOperation.
+ *
+ * @param view
+ * the EObject for which shapes has to be found
+ */
+ protected GetShapeDecorationsForViewOperation(EObject view) {
+ assert null != view : "GetShapeDecorationsForViewOperation constructor received NULL as argument"; //$NON-NLS-1$
+ this.view = view;
+ }
+
+ /**
+ * @{inheritDoc
+ */
+ @Override
+ public List<RenderedImage> execute(IProvider provider) {
+ if (!(provider instanceof IShapeProvider)) {
+ return null;
+ }
+ IShapeProvider shapeProvider = (IShapeProvider) provider;
+ return shapeProvider.getShapesForDecoration(getView());
+ }
+
+ /**
+ * Returns the view for which this operation is looking for shapes
+ *
+ * @return the view for which this operation is looking for shapes
+ */
+ protected EObject getView() {
+ return view;
+ }
+}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/IShapeProvider.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/IShapeProvider.java
index 952e2a7c42b..5139e00d232 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/IShapeProvider.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/IShapeProvider.java
@@ -1,87 +1,97 @@
-/*****************************************************************************
- * Copyright (c) 2011 CEA LIST.
- *
- * 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:
- *
- * CEA LIST - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.gmfdiag.common.service.shape;
-
-import java.util.List;
-
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.gmf.runtime.common.core.service.IProvider;
-import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker;
-import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener;
-import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage;
-import org.w3c.dom.svg.SVGDocument;
-
-/**
- * Interface implemented by all providers to the {@link ShapeService}
- */
-public interface IShapeProvider extends IProvider {
-
- /**
- * Sets the configuration for this provider, given the configuration element
- *
- * @param element
- * configuration element coming from plugin.xml file
- */
- void setConfiguration(IConfigurationElement element);
-
- /**
- * Returns the unique identifier of this provider
- *
- * @return the unique identifier of this provider
- */
- String getId();
-
- /**
- * Returns the list of shapes proposed by this provider
- *
- * @param view
- * the view for which shapes are looked for
- * @return the list of shapes or <code>null</code> if no shapes have to be displayed by this provider
- */
- List<RenderedImage> getShapes(EObject view);
-
- /**
- * Returns the list of SVG Documents proposed by this provider
- *
- * @param view
- * the view for which shapes are looked for
- * @return the list of SVG DOCUMENT or <code>null</code> if no shapes have to be displayed by this provider
- */
- List<SVGDocument> getSVGDocument(EObject view);
-
- /**
- * Returns <code>true</code> 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.
- *
- * @param view
- * the view that can display shapes
- * @return <code>true</code> if this provider can provide shapes for this view.
- */
- boolean providesShapes(EObject view);
-
- /**
- * Adds notification listeners to the diagram event broker for the given view
- *
- * @param diagramEventBroker
- * diagram event broker that dispatches the notifications to interested elements
- * @param view
- * view from which objects to listen are retrieved
- * @param notificationListener
- * notification listener that will react to the modification of shapes
- * @return the result of the creation
- */
- ProviderNotificationManager createProviderNotificationManager(DiagramEventBroker diagramEventBroker, EObject view, NotificationListener notificationListener);
-
-}
+/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ * 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:
+ *
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.common.service.shape;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker;
+import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener;
+import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage;
+import org.w3c.dom.svg.SVGDocument;
+
+/**
+ * Interface implemented by all providers to the {@link ShapeService}
+ */
+public interface IShapeProvider extends IProvider {
+
+ /**
+ * Sets the configuration for this provider, given the configuration element
+ *
+ * @param element
+ * configuration element coming from plugin.xml file
+ */
+ void setConfiguration(IConfigurationElement element);
+
+ /**
+ * Returns the unique identifier of this provider
+ *
+ * @return the unique identifier of this provider
+ */
+ String getId();
+
+ /**
+ * Returns the list of shapes proposed by this provider
+ *
+ * @param view
+ * the view for which shapes are looked for
+ * @return the list of shapes or <code>null</code> if no shapes have to be displayed by this provider
+ */
+ List<RenderedImage> getShapes(EObject view);
+
+ /**
+ * Returns the list of shapes proposed by this provider specific for decoration
+ *
+ * @param view
+ * the view for which shapes are looked for
+ * @return the list of shapes displayed as decoration or <code>null</code> if no shapes have to be displayed by this provider
+ */
+ List<RenderedImage> getShapesForDecoration(EObject view);
+
+
+ /**
+ * Returns the list of SVG Documents proposed by this provider
+ *
+ * @param view
+ * the view for which shapes are looked for
+ * @return the list of SVG DOCUMENT or <code>null</code> if no shapes have to be displayed by this provider
+ */
+ List<SVGDocument> getSVGDocument(EObject view);
+
+ /**
+ * Returns <code>true</code> 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.
+ *
+ * @param view
+ * the view that can display shapes
+ * @return <code>true</code> if this provider can provide shapes for this view.
+ */
+ boolean providesShapes(EObject view);
+
+ /**
+ * Adds notification listeners to the diagram event broker for the given view
+ *
+ * @param diagramEventBroker
+ * diagram event broker that dispatches the notifications to interested elements
+ * @param view
+ * view from which objects to listen are retrieved
+ * @param notificationListener
+ * notification listener that will react to the modification of shapes
+ * @return the result of the creation
+ */
+ ProviderNotificationManager createProviderNotificationManager(DiagramEventBroker diagramEventBroker, EObject view, NotificationListener notificationListener);
+
+}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/ShapeService.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/ShapeService.java
index 06bb5b64f7a..3889f666124 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/ShapeService.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/ShapeService.java
@@ -45,6 +45,11 @@ public class ShapeService extends org.eclipse.gmf.runtime.common.core.service.Se
*/
private static final String MAX_NUMBER_OF_SYMBOL = "maxNumberOfSymbol";
+ /**
+ *
+ */
+ private static final String MAX_NUMBER_OF_SYMBOL_DECORATION = "maxNumberOfSymbolDecoration";
+
/** singleton instance */
private static ShapeService instance;
@@ -67,6 +72,17 @@ public class ShapeService extends org.eclipse.gmf.runtime.common.core.service.Se
}
/**
+ * Checks if the given element can display shapes as decoration.
+ *
+ * @return <code>true</code> if one or several decorations should be displayed
+ */
+ public boolean hasShapeDecorationToDisplay(EObject view) {
+ @SuppressWarnings("unchecked")
+ List<RenderedImage> images = execute(ExecutionStrategy.REVERSE, new GetShapeDecorationsForViewOperation(view));
+ return images != null && images.size() > 0;
+ }
+
+ /**
* Returns the shape to be displayed
*
* @param view
@@ -87,6 +103,28 @@ public class ShapeService extends org.eclipse.gmf.runtime.common.core.service.Se
return images.subList(0, Math.min(nbImagesToDisplay, images.size()));
}
+
+ /**
+ * Returns the shape to be displayed
+ *
+ * @param view
+ * the EObject for which the shape is computed
+ * @return the shape to be displayed
+ */
+ public List<RenderedImage> getShapeDecorationsToDisplay(EObject view) {
+ @SuppressWarnings("unchecked")
+ List<List<RenderedImage>> listOfListOfImages = execute(ExecutionStrategy.FORWARD, new GetShapeDecorationsForViewOperation(view));
+ List<RenderedImage> images = new ArrayList<RenderedImage>();
+ for (List<RenderedImage> listOfImages : listOfListOfImages) {
+ if (listOfImages != null && !listOfImages.isEmpty()) {
+ images.addAll(listOfImages);
+ }
+ }
+ // Get the number of images to display
+ int nbImagesToDisplay = NotationUtils.getIntValue((View) view, MAX_NUMBER_OF_SYMBOL_DECORATION, getDefaultMaxNumberOfSymbolDecoration());
+
+ return images.subList(0, Math.min(nbImagesToDisplay, images.size()));
+ }
/**
* Returns the shape to be displayed
@@ -132,6 +170,14 @@ public class ShapeService extends org.eclipse.gmf.runtime.common.core.service.Se
}
/**
+ * @return
+ */
+ private int getDefaultMaxNumberOfSymbolDecoration() {
+ return 10;
+ }
+
+
+ /**
* Ask all the shape providers to add their required notification listeners to the diagram event broker.
*
* @param diagramEventBroker
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/NamedStyleProperties.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/NamedStyleProperties.java
index e2972da87a0..4d7e468eca7 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/NamedStyleProperties.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/utils/NamedStyleProperties.java
@@ -12,6 +12,7 @@
*****************************************************************************/
package org.eclipse.papyrus.infra.gmfdiag.common.utils;
+import org.eclipse.papyrus.infra.gmfdiag.common.providers.StyleBasedShapeProvider;
/**
* Contains constants for specific NamedStyle, used to customize figure.
@@ -167,4 +168,9 @@ public interface NamedStyleProperties {
/* Label used to identify the forced CSS values */
public static final String CSS_FORCE_VALUE = "PapyrusCSSForceValue"; // $NON-NLS-1$
+ /** name of the CSS property that manages the enablement of the {@link StyleBasedShapeProvider} */
+ public static final String SHAPE_STYLE_PROPERTY = "shapeStyle";
+
+ /** name of the CSS property that manages the enablement of the {@link StyleBasedShapeProvider} for decoration */
+ public static final String SHAPE_DECORATION_STYLE_PROPERTY = "shapeDecorationStyle";
}

Back to the top