diff options
author | Remi Schnekenburger | 2016-04-28 21:12:30 +0000 |
---|---|---|
committer | Gerrit Code Review @ Eclipse.org | 2016-05-20 16:19:36 +0000 |
commit | aea7ae97401e60b919cc0a824b8bdf12a40fb25a (patch) | |
tree | 958ecc24fa9584316adc16c351c3c43bbca0b5a1 /plugins | |
parent | c1d2ca47d0d4facc38baaf798714ac6f7000103c (diff) | |
download | org.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')
10 files changed, 1279 insertions, 925 deletions
diff --git a/plugins/doc/org.eclipse.papyrus.infra.gmfdiag.css.doc/resource/css.mediawiki b/plugins/doc/org.eclipse.papyrus.infra.gmfdiag.css.doc/resource/css.mediawiki index 3a732f6d2d2..a04b0bd8d56 100644 --- a/plugins/doc/org.eclipse.papyrus.infra.gmfdiag.css.doc/resource/css.mediawiki +++ b/plugins/doc/org.eclipse.papyrus.infra.gmfdiag.css.doc/resource/css.mediawiki @@ -315,7 +315,7 @@ The following properties can be used to bypass the standard UML notation. They c |- | displayName || boolean || true || Shapes || If set to false, the name of the Shape will be hidden |- -| displayTag || boolean || true || Shapes, connectors || If set to false, the tags (e.g. « component ») of the element will be hidden +| displayTag || boolean || true || Shapes, connectors || If set to false, the tags (e.g. « component ») of the element will be hidden |- | maintainSymbolRatio || boolean || true || Shapes || If the shape is represented with a Symbol, specifies whether the ratio should be maintained or not. If the Symbol is displayed in a compartment, it is usually a good idea to maintain the ratio. If the symbol is the only representation (e.g. when the name, border and compartments are hidden), it is recommended to not maintain the ratio |- @@ -381,13 +381,13 @@ The following properties can be used to bypass the standard UML notation. They c |- |lineLength ||int ||-1 ||Compartment ||Set the top line length of the compartment. By default the length is set to the width of the compartment. |- -|lineLengthRatio ||String ||“1.0” ||Compartment ||Set the top line length ratio of the compartment. +|lineLengthRatio ||String ||“1.0â€� ||Compartment ||Set the top line length ratio of the compartment. |- -|linePosition ||String ||“center” ||Compartment ||Set the compartment top line position.Can be left, center, right. +|linePosition ||String ||“centerâ€� ||Compartment ||Set the compartment top line position.Can be left, center, right. |- |displayHeader ||Boolean ||true ||Shape ||Set to true to add a header. |- -|portPosition ||String ||“onLine” ||Affixed Shape ||Set the position of the port. Can be “inside”, “ouside” or “onLine”. +|portPosition ||String ||“onLineâ€� ||Affixed Shape ||Set the position of the port. Can be “insideâ€�, “ousideâ€� or “onLineâ€�. |- |isPackage ||Boolean ||false ||Shapes ||Set if the shape have to be displayed as a package. |- @@ -403,6 +403,18 @@ The following properties can be used to bypass the standard UML notation. They c |- |bottomMarginLabel ||integer ||0 ||Labels ||Define the bottom margin of the label in pixel. This is the space between the text box and his container |- +|shapeStereotype ||boolean ||true ||Shapes ||true if shapes provided by stereotypes should be included in the list of visible shapes in the symbol compartment +|- +|shapeTypedElement ||boolean ||true ||Shapes ||true if shapes provided by TypeSymbolDefinition stereotype should be included in the list of visible shapes in the symbol compartment +|- +|shapeStyle ||boolean ||true ||Shapes ||true if shapes provided by property svgFile should be included in the list of visible shapes in the symbol compartment +|- +|shapeDecorationStereotype ||boolean ||true ||Shapes ||true if shapes provided by stereotypes should be included in the list of visible shapes as decorations +|- +|shapeDecorationTypedElement ||boolean ||true ||Shapes ||true if shapes provided by TypeSymbolDefinition stereotype should be included in the list of visible shapes as decorations +|- +|shapeDecorationStyle ||boolean ||true ||Shapes ||true if shapes provided by property svgFile should be included in the list of visible shapes as decorations +|- |} Other properties address presentation aspects that relate not so much to visual style as to content of the diagram: 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"; } diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.symbols/src/org/eclipse/papyrus/uml/diagram/symbols/provider/StereotypedElementShapeProvider.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.symbols/src/org/eclipse/papyrus/uml/diagram/symbols/provider/StereotypedElementShapeProvider.java index f28c5b42c7f..3ea2b95fa41 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.symbols/src/org/eclipse/papyrus/uml/diagram/symbols/provider/StereotypedElementShapeProvider.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.symbols/src/org/eclipse/papyrus/uml/diagram/symbols/provider/StereotypedElementShapeProvider.java @@ -1,231 +1,298 @@ -/*****************************************************************************
- * Copyright (c) 2012-2013 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.uml.diagram.symbols.provider;
-
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.emf.common.notify.Notification;
-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.draw2d.ui.render.factory.RenderedImageFactory;
-import org.eclipse.gmf.runtime.notation.View;
-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.service.shape.ShapeService;
-import org.eclipse.papyrus.uml.diagram.common.stereotype.display.helper.StereotypeDisplayUtil;
-import org.eclipse.papyrus.uml.diagram.symbols.Activator;
-import org.eclipse.papyrus.uml.tools.utils.ElementUtil;
-import org.eclipse.uml2.uml.Element;
-import org.eclipse.uml2.uml.Stereotype;
-import org.w3c.dom.svg.SVGDocument;
-
-/**
- * This provider is linked to the {@link ShapeService}. It returns the shapes for a given element corresponding to the stereotypes applied on the
- * business element.
- */
-public class StereotypedElementShapeProvider extends AbstractShapeProvider {
-
- private static final String SHAPE_CONSTANT = "shape";
-
- /**
- * {@inheritDoc}
- */
- @Override
- public List<RenderedImage> getShapes(EObject view) {
- if (!(view instanceof View)) {
- return null;
- }
- EObject element = ((View) view).getElement();
- if (element instanceof Element) {
- List<RenderedImage> images = new ArrayList<RenderedImage>();
- // it has already been checked that
-
- Iterator<Stereotype> appliedStereotypes = ((Element) element).getAppliedStereotypes().iterator();
- while (appliedStereotypes.hasNext()) {
- try {
- Stereotype appliedStereotype = appliedStereotypes.next();
- View stereotypeLabel = StereotypeDisplayUtil.getInstance().getStereotypeLabel(((View) view), appliedStereotype);
- if (stereotypeLabel != null && stereotypeLabel.isVisible()) {
- org.eclipse.uml2.uml.Image icon = ElementUtil.getStereotypeImage(((Element) element), appliedStereotype, SHAPE_CONSTANT);
- if (icon != null) {
- if (!"".equals(icon.getLocation()) && icon.getLocation() != null) {
- SVGDocument document = getSVGDocument(icon.getLocation());
- if (document != null) {
- images.add(renderSVGDocument(view, document));
- } else {
- URL url = new URL(icon.getLocation());
- images.add(RenderedImageFactory.getInstance(url));
- }
- }
- }
- }
- } catch (Exception ex) {
- Activator.log.error(ex);
- continue;
- }
- }
-
- return images;
- }
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean providesShapes(EObject view) {
- if (!(view instanceof View)) {
- return false;
- }
-
- EObject element = ((View) view).getElement();
- if (element instanceof Element) {
-
- // This is an element. does it have stereotypes ? If yes, do the stereotypes have shapes associated ?
- Iterator<Stereotype> appliedStereotypes = ((Element) element).getAppliedStereotypes().iterator();
- while (appliedStereotypes.hasNext()) {
-
- Stereotype appliedStereotype = appliedStereotypes.next();
- View stereotypeLabel = StereotypeDisplayUtil.getInstance().getStereotypeLabel(((View) view), appliedStereotype);
- if (stereotypeLabel != null && stereotypeLabel.isVisible()) {
- org.eclipse.uml2.uml.Image icon = ElementUtil.getStereotypeImage(((Element) element), appliedStereotype, SHAPE_CONSTANT);
-
- if (icon != null) {
- if (icon.getLocation() != "" && icon.getLocation() != null) {
- return true;
- }
- }
- }
- }
-
-
- }
-
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- */
- @Override
- public List<SVGDocument> getSVGDocument(EObject view) {
- if (!(view instanceof View)) {
- return null;
- }
- EObject element = ((View) view).getElement();
- if (element instanceof Element) {
- List<SVGDocument> images = new ArrayList<SVGDocument>();
- // it has already been checked that
- Iterator<Stereotype> appliedStereotypes = ((Element) element).getAppliedStereotypes().iterator();
- while (appliedStereotypes.hasNext()) {
-
- Stereotype appliedStereotype = appliedStereotypes.next();
- View stereotypeLabel = StereotypeDisplayUtil.getInstance().getStereotypeLabel(((View) view), appliedStereotype);
- if (stereotypeLabel != null && stereotypeLabel.isVisible()) {
- org.eclipse.uml2.uml.Image icon = ElementUtil.getStereotypeImage(((Element) element), appliedStereotype, SHAPE_CONSTANT);
- if (icon != null) {
- if (icon.getLocation() != "" && icon.getLocation() != null) {
- SVGDocument document = getSVGDocument(icon.getLocation());
- if (document != null) {
- images.add(document);
- }
- }
- }
- }
- }
- return images;
- }
-
- return null;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ProviderNotificationManager createProviderNotificationManager(DiagramEventBroker diagramEventBroker, EObject view, NotificationListener listener) {
- // retrieve semantic element from the view and add a notification listener on the Type feature if the semantic element is a TypedElement
- if (view == null || !(view instanceof View)) {
- return null;
- }
-
- StereotypedElementShapeProviderNotificationManager notificationManager = new StereotypedElementShapeProviderNotificationManager(diagramEventBroker, view, listener);
- return notificationManager;
- }
-
- /**
- * Notification Manager for the {@link StereotypedElementShapeProvider}.
- */
- public class StereotypedElementShapeProviderNotificationManager extends ProviderNotificationManager implements NotificationListener {
-
- /**
- * Creates a new StereotypedElementShapeProviderNotificationManager.
- *
- * @param diagramEventBroker
- * event broker specific to the diargam displaying the shapes.
- * @param view
- * the view from which all elements to listen will be computed.
- * @param listener
- * the listener to which notifications will be forwarded.
- */
- public StereotypedElementShapeProviderNotificationManager(DiagramEventBroker diagramEventBroker, EObject view, NotificationListener listener) {
- super(diagramEventBroker, view, listener);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected void registerListeners() {
- if (view == null || !(view instanceof View)) {
- return;
- }
- diagramEventBroker.addNotificationListener(view, this);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void dispose() {
- if (view == null || !(view instanceof View)) {
- return;
- }
- diagramEventBroker.removeNotificationListener(view, this);
- super.dispose();
- }
-
- /**
- * @see org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener#notifyChanged(org.eclipse.emf.common.notify.Notification)
- *
- * @param notification
- */
- @Override
- public void notifyChanged(Notification notification) {
- // TODO
-
- }
-
-
-
- }
-
-}
+/***************************************************************************** + * Copyright (c) 2012-2013 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.uml.diagram.symbols.provider; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.emf.common.notify.Notification; +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.draw2d.ui.render.factory.RenderedImageFactory; +import org.eclipse.gmf.runtime.notation.View; +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.service.shape.ShapeService; +import org.eclipse.papyrus.uml.diagram.common.stereotype.display.helper.StereotypeDisplayUtil; +import org.eclipse.papyrus.uml.diagram.symbols.Activator; +import org.eclipse.papyrus.uml.tools.utils.ElementUtil; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Stereotype; +import org.w3c.dom.svg.SVGDocument; + +/** + * This provider is linked to the {@link ShapeService}. It returns the shapes for a given element corresponding to the stereotypes applied on the + * business element. + */ +public class StereotypedElementShapeProvider extends AbstractShapeProvider { + + private static final String SHAPE_CONSTANT = "shape"; + + /** name of the CSS property that manages the enablement of that provider */ + protected static final String SHAPE_STEREOTYPE_PROPERTY = "shapeStereotype"; + + /** name of the CSS property that manages the enablement of that provider for decoration */ + protected static final String SHAPE_DECORATION_STEREOTYPE_PROPERTY = "shapeDecorationStereotype"; + + /** + * {@inheritDoc} + */ + @Override + public List<RenderedImage> getShapes(EObject view) { + if (!(view instanceof View)) { + return null; + } + View v = (View) view; + // check the css property for the status (enable or not) of that provider + if (!isShapeStereotypeEnable(v)) { + return null; + } + + return doGetShapes(v); + } + + protected List<RenderedImage> doGetShapes(View view) { + EObject element = view.getElement(); + if (element instanceof Element) { + List<RenderedImage> images = new ArrayList<RenderedImage>(); + // it has already been checked that + + Iterator<Stereotype> appliedStereotypes = ((Element) element).getAppliedStereotypes().iterator(); + while (appliedStereotypes.hasNext()) { + try { + Stereotype appliedStereotype = appliedStereotypes.next(); + View stereotypeLabel = StereotypeDisplayUtil.getInstance().getStereotypeLabel(view, appliedStereotype); + if (stereotypeLabel != null && stereotypeLabel.isVisible()) { + org.eclipse.uml2.uml.Image icon = ElementUtil.getStereotypeImage(((Element) element), appliedStereotype, SHAPE_CONSTANT); + if (icon != null) { + if (icon.getLocation() != null && !("".equals(icon.getLocation()))) { + SVGDocument document = getSVGDocument(icon.getLocation()); + if (document != null) { + images.add(renderSVGDocument(view, document)); + } else { + URL url = new URL(icon.getLocation()); + images.add(RenderedImageFactory.getInstance(url)); + } + } + } + } + } catch (Exception ex) { + Activator.log.error(ex); + continue; + } + } + + return images; + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public List<RenderedImage> getShapesForDecoration(EObject view) { + if (!(view instanceof View)) { + return null; + } + View v = (View) view; + // check the css property for the status (enable or not) of that provider + if (!isShapeDecorationStereotypeEnable(v)) { + return null; + } + + return doGetShapesForDecoration(v); + } + + protected List<RenderedImage> doGetShapesForDecoration(View view) { + return doGetShapes(view); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean providesShapes(EObject view) { + if (!(view instanceof View)) { + return false; + } + + View v = (View) view; + if (!isShapeStereotypeEnable(v)) { + return false; + } + + EObject element = v.getElement(); + if (element instanceof Element) { + // This is an element. does it have stereotypes ? If yes, do the stereotypes have shapes associated ? + Iterator<Stereotype> appliedStereotypes = ((Element) element).getAppliedStereotypes().iterator(); + while (appliedStereotypes.hasNext()) { + + Stereotype appliedStereotype = appliedStereotypes.next(); + View stereotypeLabel = StereotypeDisplayUtil.getInstance().getStereotypeLabel(v, appliedStereotype); + if (stereotypeLabel != null && stereotypeLabel.isVisible()) { + org.eclipse.uml2.uml.Image icon = ElementUtil.getStereotypeImage(((Element) element), appliedStereotype, SHAPE_CONSTANT); + + if (icon != null) { + if (!"".equals(icon.getLocation()) && icon.getLocation() != null) { + return true; + } + } + } + } + } + return false; + } + + /** + * Returns <code>false</code> if the given view specifically removes the support for shapes by stereotypes. + * + * @param view + * the view to check style + * @return <code>false</code> if the given view specifically removes the support for shapes by stereotypes, otherwise <code>true</code>. + */ + private boolean isShapeStereotypeEnable(View view) { + return NotationUtils.getBooleanValue(view, SHAPE_STEREOTYPE_PROPERTY, true); + } + + /** + * Returns <code>false</code> if the given view specifically removes the support for shapes as decoration by stereotypes. + * + * @param view + * the view to check style + * @return <code>false</code> if the given view specifically removes the support for shapes as decoration by stereotypes, otherwise <code>true</code>. + */ + private boolean isShapeDecorationStereotypeEnable(View view) { + return NotationUtils.getBooleanValue(view, SHAPE_DECORATION_STEREOTYPE_PROPERTY, true); + } + + /** + * {@inheritDoc} + * + */ + @Override + public List<SVGDocument> getSVGDocument(EObject view) { + if (!(view instanceof View)) { + return null; + } + + View v = (View) view; + if (!isShapeStereotypeEnable(v)) { + return null; + } + + EObject element = v.getElement(); + if (element instanceof Element) { + List<SVGDocument> images = new ArrayList<SVGDocument>(); + // it has already been checked that + Iterator<Stereotype> appliedStereotypes = ((Element) element).getAppliedStereotypes().iterator(); + while (appliedStereotypes.hasNext()) { + + Stereotype appliedStereotype = appliedStereotypes.next(); + View stereotypeLabel = StereotypeDisplayUtil.getInstance().getStereotypeLabel(v, appliedStereotype); + if (stereotypeLabel != null && stereotypeLabel.isVisible()) { + org.eclipse.uml2.uml.Image icon = ElementUtil.getStereotypeImage(((Element) element), appliedStereotype, SHAPE_CONSTANT); + if (icon != null) { + if (icon.getLocation() != null && !("".equals(icon.getLocation()))) { + SVGDocument document = getSVGDocument(icon.getLocation()); + if (document != null) { + images.add(document); + } + } + } + } + } + return images; + } + + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public ProviderNotificationManager createProviderNotificationManager(DiagramEventBroker diagramEventBroker, EObject view, NotificationListener listener) { + // retrieve semantic element from the view and add a notification listener on the Type feature if the semantic element is a TypedElement + if (view == null || !(view instanceof View)) { + return null; + } + + StereotypedElementShapeProviderNotificationManager notificationManager = new StereotypedElementShapeProviderNotificationManager(diagramEventBroker, view, listener); + return notificationManager; + } + + /** + * Notification Manager for the {@link StereotypedElementShapeProvider}. + */ + public class StereotypedElementShapeProviderNotificationManager extends ProviderNotificationManager implements NotificationListener { + + /** + * Creates a new StereotypedElementShapeProviderNotificationManager. + * + * @param diagramEventBroker + * event broker specific to the diargam displaying the shapes. + * @param view + * the view from which all elements to listen will be computed. + * @param listener + * the listener to which notifications will be forwarded. + */ + public StereotypedElementShapeProviderNotificationManager(DiagramEventBroker diagramEventBroker, EObject view, NotificationListener listener) { + super(diagramEventBroker, view, listener); + } + + /** + * {@inheritDoc} + */ + @Override + protected void registerListeners() { + if (view == null || !(view instanceof View)) { + return; + } + diagramEventBroker.addNotificationListener(view, this); + } + + /** + * {@inheritDoc} + */ + @Override + public void dispose() { + if (view == null || !(view instanceof View)) { + return; + } + diagramEventBroker.removeNotificationListener(view, this); + super.dispose(); + } + + /** + * @see org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener#notifyChanged(org.eclipse.emf.common.notify.Notification) + * + * @param notification + */ + @Override + public void notifyChanged(Notification notification) { + // TODO + + } + + + + } + +} diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.symbols/src/org/eclipse/papyrus/uml/diagram/symbols/provider/TypedElementShapeProvider.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.symbols/src/org/eclipse/papyrus/uml/diagram/symbols/provider/TypedElementShapeProvider.java index e34d5a02626..cb764df4820 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.symbols/src/org/eclipse/papyrus/uml/diagram/symbols/provider/TypedElementShapeProvider.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.symbols/src/org/eclipse/papyrus/uml/diagram/symbols/provider/TypedElementShapeProvider.java @@ -31,6 +31,7 @@ import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener; import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage; import org.eclipse.gmf.runtime.draw2d.ui.render.factory.RenderedImageFactory; import org.eclipse.gmf.runtime.notation.View; +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.service.shape.ShapeService; @@ -50,11 +51,29 @@ import org.w3c.dom.svg.SVGDocument; */ public class TypedElementShapeProvider extends AbstractShapeProvider { + /** name of the CSS property that manages the enablement of that provider */ + protected static final String SHAPE_TYPED_ELEMENT_PROPERTY = "shapeTypedElement"; + + /** name of the CSS property that manages the enablement of that provider as decoration */ + protected static final String SHAPE_DECORATION_TYPED_ELEMENT_PROPERTY = "shapeDecorationTypedElement"; + /** * {@inheritDoc} */ @Override public List<RenderedImage> getShapes(EObject view) { + if (!(view instanceof View)) { + return null; + } + View v = (View) view; + // check the css property for the status (enable or not) of that provider + if (!isShapeTypedElementEnable(v)) { + return null; + } + return doGetShapes(v); + } + + protected List<RenderedImage> doGetShapes(View view) { Type type = getType(view); String path = getSymbolPath(type); if (path != null && path.length() > 0) { @@ -99,11 +118,62 @@ public class TypedElementShapeProvider extends AbstractShapeProvider { } /** + * Returns <code>false</code> if the given view specifically removes the support for shapes by type. + * + * @param view + * the view to check style + * @return <code>false</code> if the given view specifically removes the support for shapes by type, otherwise <code>true</code>. + */ + private boolean isShapeTypedElementEnable(View view) { + return NotationUtils.getBooleanValue(view, SHAPE_TYPED_ELEMENT_PROPERTY, true); + } + + /** + * {@inheritDoc} + */ + @Override + public List<RenderedImage> getShapesForDecoration(EObject view) { + if (!(view instanceof View)) { + return null; + } + View v = (View) view; + // check the css property for the status (enable or not) of that provider + if (!isShapeDecorationTypedElementEnable(v)) { + return null; + } + return doGetShapesForDecoration(v); + } + + protected List<RenderedImage> doGetShapesForDecoration(View view) { + return doGetShapes(view); + } + + /** + * Returns <code>false</code> if the given view specifically removes the support for shapes decoration by type. + * + * @param view + * the view to check style + * @return <code>false</code> if the given view specifically removes the support for shapes decoration by type, otherwise <code>true</code>. + */ + private boolean isShapeDecorationTypedElementEnable(View view) { + return NotationUtils.getBooleanValue(view, SHAPE_DECORATION_TYPED_ELEMENT_PROPERTY, true); + } + + /** * {@inheritDoc} */ @Override public List<SVGDocument> getSVGDocument(EObject view) { - Type type = getType(view); + if (!(view instanceof View)) { + return null; + } + View v = (View) view; + // check the css property for the status (enable or not) of that provider + if (!isShapeTypedElementEnable(v)) { + return null; + } + + Type type = getType(v); String path = getSymbolPath(type); if (path != null && path.length() > 0) { try { @@ -134,6 +204,15 @@ public class TypedElementShapeProvider extends AbstractShapeProvider { */ @Override public boolean providesShapes(EObject view) { + if (!(view instanceof View)) { + return false; + } + View v = (View) view; + // check the css property for the status (enable or not) of that provider + if (!isShapeTypedElementEnable(v)) { + return false; + } + Type type = getType(view); String path = getSymbolPath(type); if (path != null && path.length() > 0) { |