public final Image addDecoration( IPapyrusDecoration pDecoration, int percentageFromSource, int margin, boolean isVolatile) { // use image registry, see bug 401056 Image image = Activator.getPluginIconImage(Activator.ID, pDecoration.getDecorationImageForGE()); IDecoration decoration = createDecorationImage(decoratorTarget, image, percentageFromSource, margin, isVolatile); if (decoration != null) { decorations.add(decoration); String message = pDecoration.getMessage(); Label toolTip = getToolTip(message); if (decoration instanceof Decoration) { ((Decoration) decoration).setToolTip(toolTip); } return image; } else { return null; } }
/** * The decorator to represent inherited element This decorator adds a small image ( the * generalization icon) next to the UML Element which are inherited. 3 positions are defined for the * decoration : * * <ul> * <li>if the UML Element is represented like an affixed child node : in {@link * PositionConstants#NORTH_WEST} or {@link PositionConstants#SOUTH_EAST} following its * position/parent and margin =1 * <li>else if the element is in a compartment list : {@link PositionConstants#EAST} and margin * =-1 * <li>else {@link PositionConstants#SOUTH_EAST} and margin = -1 * </ul> */ public class InheritedDecorator implements IDecorator { /** the object to be decorated */ private IDecoratorTarget decoratorTarget; /** the decoration being displayed */ private IDecoration decoration; /** the plugin where owning the icons for the UML Element */ public static final String pluginID = "org.eclipse.papyrus.uml.diagram.common"; // $NON-NLS-1$ /** the image path */ public static final String imagePath = "/icons/hyperlink_13x13.gif"; // $NON-NLS-1$ /** the image used added to represent an inherited element */ private static final Image ICON_HYPERLINK = Activator.getPluginIconImage(pluginID, imagePath); /** * Creates a new <code>AbstractDecorator</code> for the decorator target passed in. * * @param decoratorTarget the object to be decorated */ public InheritedDecorator(IDecoratorTarget decoratorTarget) { this.decoratorTarget = decoratorTarget; } /** * Gets the object to be decorated. * * @return Returns the object to be decorated */ protected IDecoratorTarget getDecoratorTarget() { return decoratorTarget; } /** @return Returns the decoration. */ public IDecoration getDecoration() { return decoration; } /** @param decoration The decoration to set. */ public void setDecoration(IDecoration decoration) { this.decoration = decoration; } /** Removes the decoration if it exists and sets it to null. */ protected void removeDecoration() { if (decoration != null) { decoratorTarget.removeDecoration(decoration); decoration = null; } } /** * 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. */ public static Node getDecoratorTargetNode(IDecoratorTarget decoratorTarget) { DescriptionStyle descStyle = null; View node = (View) decoratorTarget.getAdapter(View.class); if (node != null && !(node instanceof Diagram)) { descStyle = (DescriptionStyle) node.getStyle(NotationPackage.eINSTANCE.getDescriptionStyle()); if (descStyle != null) { return (Node) node; } } return null; } /** * Creates the appropriate review decoration if all the criteria is satisfied by the view passed * in. */ public void refresh() { removeDecoration(); Node node = getDecoratorTargetNode(getDecoratorTarget()); IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class); if (node != null) { DescriptionStyle descStyle = getDescriptionStyle(node); if (descStyle != null) { if (isInherited(node)) { // if(Util.isAffixedChildNode(gep)) { // setDecoration(getDecoratorTarget().addDecoration(figure, // locator, false)); // } else { // setDecoration(getDecoratorTarget().addShapeDecoration(figure, // getDirection(node), -1, false)); // } if (gep != null && gep.getRoot() != null) { // if the gep has // no parent, we // can't test if // the container // is a // compartment // list // (because, we // call the // method // DiagramEditPartsUtil.getEditPartFromView((View)container, // gep); IFigure figure = getFigure(ICON_HYPERLINK); 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)); } } } } } } /** * Returns a figure corresponding to this image * * @param image a image * @return a figure corresponding to this image */ public IFigure getFigure(Image image) { IMapMode mm = MapModeUtil.getMapMode( ((IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class)) .getFigure()); ImageFigure fig = new ImageFigure(); fig.setImage(image); fig.setSize(mm.DPtoLP(image.getBounds().width), mm.DPtoLP(image.getBounds().height)); return fig; } /** * 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} if the * node is an Affixed Child Node * <li>{@link PositionConstants#EAST} if the node is in a compartment list * <li>{@link PositionConstants#SOUTH_EAST} in other cases * </ul> */ protected Direction getDirection(Node node) { IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class); assert gep != null; // test if its an affixed ChildNode // if(Util.isAffixedChildNode(gep)) { // // IBorderItemLocator loc = // ((BorderNamedElementEditPart)gep).getBorderItemLocator(); // int location = loc.getCurrentSideOfParent(); // if(PositionConstants.NONE == location) { //sometimes // getBorderItemLocator doesn't work correctly! // location = PositionConstants.NORTH_WEST; // } // switch(location) { // case PositionConstants.NORTH: // case PositionConstants.NORTH_WEST: // case PositionConstants.WEST: // case PositionConstants.SOUTH_WEST: // // return IDecoratorTarget.Direction.NORTH_WEST; // default: // return IDecoratorTarget.Direction.SOUTH_EAST; // } // } if (gep.getParent() != null) { if (isInCompartmentList(node) && !Util.isAffixedChildNode(gep)) { return IDecoratorTarget.Direction.EAST; } } return IDecoratorTarget.Direction.SOUTH_WEST; } /** * 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(Node 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; } /** * Tests if the node is an inherited element * * @param node a node * @return <code>true</code> if the node is an inherited element <code>false</code> if not */ protected boolean isInherited(Node node) { EObject element = node.getElement(); if (element instanceof Element) { EObject container = node.eContainer(); EObject graphicalParent = null; if (container instanceof DecorationNode) { graphicalParent = ((DecorationNode) container).getElement(); } else if (container instanceof View) { graphicalParent = ((View) container).getElement(); } if (graphicalParent instanceof Property || graphicalParent instanceof Classifier) { Classifier classifier = null; if (graphicalParent instanceof Property) { Type type = ((Property) graphicalParent).getType(); if (type instanceof Classifier) { classifier = (Classifier) type; } } else { classifier = (Classifier) graphicalParent; } if (classifier != null) { EList<NamedElement> inheritedMembers = classifier.getInheritedMembers(); return inheritedMembers.contains(element); } } } 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(Node node) { return (DescriptionStyle) node.getStyle(NotationPackage.eINSTANCE.getDescriptionStyle()); } /** A listener used to listen the change of location and type (for Property) */ private NotificationListener notificationListener = new NotificationListener() { /** * @see * org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener#notifyChanged(org.eclipse.emf.common.notify.Notification) * @param notification */ public void notifyChanged(Notification notification) { if (notification.getEventType() == Notification.REMOVE) { if (notification.getNotifier() instanceof Classifier) { IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class); assert gep != null; // we remove the listener on the container (because it's // changing DiagramEventBroker.getInstance(gep.getEditingDomain()) .removeNotificationListener( (EObject) notification.getNotifier(), notificationListener); } } // we update the listeners It's useful when an Element with overlay // changes of parent deactivate(); activate(); refresh(); } }; /** * Adds listeners on * * <ul> * <li>Affixed Child Node * <li>graphical parent, when its a {@link Property} (we add the listener on its Type) * </ul> */ public void activate() { IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class); assert gep != null; View view = ((View) gep.getModel()); if (view instanceof Node) { // the location of the decorator can change if it's an Affixed Child // Node if (isInherited((Node) view) && Util.isAffixedChildNode(gep)) { DiagramEventBroker.getInstance(gep.getEditingDomain()) .addNotificationListener(gep.getNotationView(), notificationListener); } } // if the graphical parent is a Property, we add a listener on the type // of the property, to refresh the decoration EObject parent = view.eContainer(); if (parent instanceof DecorationNode) { parent = parent.eContainer(); } if (parent instanceof View) { EObject el = ((View) parent).getElement(); if (el instanceof Property) { DiagramEventBroker.getInstance(gep.getEditingDomain()) .addNotificationListener( el, UMLPackage.eINSTANCE.getTypedElement_Type(), notificationListener); } } /* * We listen the changes on the UML parent, in order to know if the * element is changing of parent Adding a listener using the following * EReference doesn't work UMLPackage.eINSTANCE.getElement_Owner(); * UMLPackage.eINSTANCE.getProperty_Class(); * UMLPackage.eINSTANCE.getNamedElement_Namespace(); that's why we * listen the parent */ if (view.getElement() instanceof Element) { Element semanticElement = (Element) view.getElement(); /* * We need add a listener only if the element is an element which * can be inherited, like Property, Operation, Signal, Classifier... */ if (semanticElement != null && canBeInherited(semanticElement)) { // we listen if the container of the element changes! if (semanticElement.eContainer() != null) { DiagramEventBroker.getInstance(gep.getEditingDomain()) .addNotificationListener(semanticElement.eContainer(), notificationListener); } } } } /** * Tests if the element can be inherited * * @param semanticElement the element to test * @return <code>true</code> if the element can be inherited */ protected boolean canBeInherited(Element semanticElement) { /* * maybe we could replace these tests by RedefinableElement? or not? */ if (semanticElement instanceof Classifier) { return true; } else if (semanticElement instanceof Property) { return true; } else if (semanticElement instanceof Operation) { return true; } return false; } /** Removes the listeners and the decorations */ public void deactivate() { removeDecoration(); IGraphicalEditPart gep = (IGraphicalEditPart) getDecoratorTarget().getAdapter(IGraphicalEditPart.class); assert gep != null; DiagramEventBroker.getInstance(gep.getEditingDomain()) .removeNotificationListener(gep.getNotationView(), notificationListener); View view = ((View) gep.getModel()); if (view instanceof Node) { // the location of the decorator can change if it's an Affixed Child // Node if (isInherited((Node) view) && Util.isAffixedChildNode(gep)) { DiagramEventBroker.getInstance(gep.getEditingDomain()) .removeNotificationListener(gep.getNotationView(), notificationListener); } } EObject parent = view.eContainer(); if (parent instanceof View) { EObject el = ((View) parent).getElement(); if (el instanceof Property) { DiagramEventBroker.getInstance(gep.getEditingDomain()) .removeNotificationListener( el, UMLPackage.eINSTANCE.getTypedElement_Type(), notificationListener); } } if (view.getElement() instanceof Element) { Element semanticElement = (Element) view.getElement(); if (semanticElement != null) { if (semanticElement.eContainer() != null) { DiagramEventBroker.getInstance(gep.getEditingDomain()) .addNotificationListener(semanticElement.eContainer(), notificationListener); } } } } }