Java tutorial
/****************************************************************************** * Copyright (c) 2002, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation ****************************************************************************/ package org.eclipse.gmf.runtime.diagram.ui.editparts; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IAdapterFactory; import org.eclipse.core.runtime.Platform; import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.ConnectionLayer; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.PolygonDecoration; import org.eclipse.draw2d.PolylineDecoration; import org.eclipse.draw2d.RelativeBendpoint; import org.eclipse.draw2d.RotatableDecoration; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.transaction.RunnableWithResult; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.emf.transaction.util.TransactionUtil; import org.eclipse.gef.AccessibleEditPart; import org.eclipse.gef.DragTracker; import org.eclipse.gef.EditDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPartViewer; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.LayerConstants; import org.eclipse.gef.Request; import org.eclipse.gef.RequestConstants; import org.eclipse.gef.RootEditPart; import org.eclipse.gef.SnapToHelper; import org.eclipse.gef.commands.Command; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gef.commands.UnexecutableCommand; import org.eclipse.gef.editparts.AbstractConnectionEditPart; import org.eclipse.gef.editpolicies.SnapFeedbackPolicy; import org.eclipse.gef.requests.CreateConnectionRequest; import org.eclipse.gef.requests.DropRequest; import org.eclipse.gef.requests.GroupRequest; import org.eclipse.gef.requests.ReconnectRequest; import org.eclipse.gef.requests.TargetRequest; import org.eclipse.gmf.runtime.common.core.util.Log; import org.eclipse.gmf.runtime.common.core.util.Trace; import org.eclipse.gmf.runtime.common.ui.services.action.filter.ActionFilterService; import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker; import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener; import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint; import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ConnectionBendpointEditPolicy; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ConnectionLabelsEditPolicy; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.DecorationEditPolicy; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.PropertyHandlerEditPolicy; import org.eclipse.gmf.runtime.diagram.ui.editpolicies.SemanticEditPolicy; import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIDebugOptions; import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIPlugin; import org.eclipse.gmf.runtime.diagram.ui.internal.DiagramUIStatusCodes; import org.eclipse.gmf.runtime.diagram.ui.internal.commands.ToggleCanonicalModeCommand; import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.IContainedEditPart; import org.eclipse.gmf.runtime.diagram.ui.internal.editpolicies.ConnectionEditPolicy; import org.eclipse.gmf.runtime.diagram.ui.internal.editpolicies.ConnectionLineSegEditPolicy; import org.eclipse.gmf.runtime.diagram.ui.internal.editpolicies.TreeConnectionBendpointEditPolicy; import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties; import org.eclipse.gmf.runtime.diagram.ui.internal.ruler.SnapToHelperUtil; import org.eclipse.gmf.runtime.diagram.ui.internal.services.editpolicy.EditPolicyService; import org.eclipse.gmf.runtime.diagram.ui.internal.type.NotationTypeUtil; import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramColorRegistry; import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages; import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer; import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramEditDomain; import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramGraphicalViewer; import org.eclipse.gmf.runtime.diagram.ui.preferences.IPreferenceConstants; import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewRequest; import org.eclipse.gmf.runtime.diagram.ui.requests.EditCommandRequestWrapper; import org.eclipse.gmf.runtime.diagram.ui.services.editpart.EditPartService; import org.eclipse.gmf.runtime.diagram.ui.util.EditPartUtil; import org.eclipse.gmf.runtime.draw2d.ui.figures.FigureUtilities; import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx; import org.eclipse.gmf.runtime.draw2d.ui.internal.figures.ConnectionLayerEx; import org.eclipse.gmf.runtime.draw2d.ui.internal.routers.ForestRouter; import org.eclipse.gmf.runtime.draw2d.ui.internal.routers.OrthogonalRouter; import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode; import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil; import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil; import org.eclipse.gmf.runtime.gef.ui.internal.editpolicies.GraphicalEditPolicyEx; import org.eclipse.gmf.runtime.gef.ui.internal.l10n.Cursors; import org.eclipse.gmf.runtime.gef.ui.internal.tools.SelectConnectionEditPartTracker; import org.eclipse.gmf.runtime.notation.ArrowStyle; import org.eclipse.gmf.runtime.notation.ArrowType; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.FontStyle; import org.eclipse.gmf.runtime.notation.JumpLinkStatus; import org.eclipse.gmf.runtime.notation.JumpLinkType; import org.eclipse.gmf.runtime.notation.LineStyle; import org.eclipse.gmf.runtime.notation.LineType; import org.eclipse.gmf.runtime.notation.LineTypeStyle; import org.eclipse.gmf.runtime.notation.NotationPackage; import org.eclipse.gmf.runtime.notation.RelativeBendpoints; import org.eclipse.gmf.runtime.notation.Routing; import org.eclipse.gmf.runtime.notation.RoutingStyle; import org.eclipse.gmf.runtime.notation.Smoothness; import org.eclipse.gmf.runtime.notation.View; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.resource.DeviceResourceException; import org.eclipse.jface.resource.FontDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.ResourceManager; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.accessibility.AccessibleEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.ui.IActionFilter; /** * the base edit part that controls <code>Edge</code> views, it is the basic * controller for the connection's view * * @author mmostafa */ abstract public class ConnectionEditPart extends AbstractConnectionEditPart implements IGraphicalEditPart, PropertyChangeListener, IContainedEditPart, IPrimaryEditPart, NotificationListener { /** A map of listener filters ids to filter data */ private Map listenerFilters; /** Used for registering and unregistering the edit part */ private String elementGuid; /** * Flag to indicate if the edit part is in edit mode */ private boolean isEditable = true; /** Used for accessibility. */ protected AccessibleEditPart accessibleEP; /** * Cache the editing domain after it is retrieved. */ private TransactionalEditingDomain editingDomain; /** * Cache the font data when a font is created so that it can be * disposed later. */ private FontData cachedFontData; /** * Cache the answer to whether or not this is a semantic connection after it * is retrieved. */ private Boolean semanticConnection; /** counter that tracs the recursive depth of the getCommand() method. */ private static volatile int GETCOMMAND_RECURSIVE_COUNT = 0; /** A list of editparts who's canonical editpolicies are to be temporarily disabled. */ private static Set _disableCanonicalEditPolicyList = new HashSet(); /** * gets a property change command for the passed property, using both of the * old and new values * * @param property * the property associated with the command * @param oldValue * the old value associated with the command * @param newValue * the new value associated with the command * @return a command */ protected Command getPropertyChangeCommand(Object property, Object oldValue, Object newValue) { // by default return null, which means there is no special command to // change the property return null; } protected void addChild(EditPart child, int index) { super.addChild(child, index); if (child instanceof GraphicalEditPart) { GraphicalEditPart gEP = (GraphicalEditPart) child; boolean editMode = isEditModeEnabled(); if (editMode != gEP.isEditModeEnabled()) { if (editMode) gEP.enableEditMode(); else gEP.disableEditMode(); } } } /** * Register the adapters for the standard properties. */ static { registerAdapters(); } /* * (non-Javadoc) * * @see org.eclipse.gef.EditPart#activate() */ public void activate() { if (isActive()) { return; } addNotationalListeners(); EObject semanticProxy = ((View) getModel()).getElement(); EObject semanticElement = EMFCoreUtil.resolve(getEditingDomain(), semanticProxy); if (semanticElement != null) addSemanticListeners(); else if (semanticProxy != null) { addListenerFilter("SemanticProxy", this, semanticProxy); //$NON-NLS-1$ } super.activate(); } /** * Adds a listener filter by adding the given listener to a passed notifier * * @param filterId * A unique filter id (within the same editpart instance) * @param listener * A listener instance * @param notifier * An element notifer to add the listener to */ protected void addListenerFilter(String filterId, NotificationListener listener, EObject element) { if (element == null) return; assert filterId != null; assert listener != null; if (listenerFilters == null) listenerFilters = new HashMap(); getDiagramEventBroker().addNotificationListener(element, listener); listenerFilters.put(filterId, new Object[] { element, listener }); } /** * Adds a listener filter by adding the given listener to a passed notifier * * @param filterId * A unique filter id (within the same editpart instance) * @param listener * A listener instance * @param notifier * An element notifer to add the listener to */ protected void addListenerFilter(String filterId, NotificationListener listener, EObject element, EStructuralFeature feature) { if (element == null) return; assert filterId != null; assert listener != null; if (listenerFilters == null) listenerFilters = new HashMap(); getDiagramEventBroker().addNotificationListener(element, feature, listener); listenerFilters.put(filterId, new Object[] { element, feature, listener }); } /* * (non-Javadoc) * * @see org.eclipse.gef.editparts.AbstractEditPart#createChild(java.lang.Object) */ final protected EditPart createChild(Object model) { return EditPartService.getInstance().createGraphicEditPart((View) model); } /* * (non-Javadoc) * * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createConnection(java.lang.Object) */ final protected org.eclipse.gef.ConnectionEditPart createConnection(Object connectionView) { return (org.eclipse.gef.ConnectionEditPart) createChild(connectionView); } /** * Overridden to support editpolicies installed programmatically and via the * <code>EditPolicyService</code>. Subclasses should override * <code>createDefaultEditPolicies()</code>. * * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies() */ final protected void createEditPolicies() { createDefaultEditPolicies(); EditPolicyService.getInstance().createEditPolicies(this); } /** * Should be overridden to install editpolicies programmatically. * * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies() */ protected void createDefaultEditPolicies() { installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE, new SemanticEditPolicy()); installEditPolicy(EditPolicyRoles.PROPERTY_HANDLER_ROLE, new PropertyHandlerEditPolicy()); installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE, new org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy()); installEditPolicy(EditPolicy.CONNECTION_ROLE, new ConnectionEditPolicy()); installBendpointEditPolicy(); installEditPolicy(EditPolicyRoles.DECORATION_ROLE, new DecorationEditPolicy()); installEditPolicy(EditPolicyRoles.CONNECTION_LABELS_ROLE, new ConnectionLabelsEditPolicy()); installEditPolicy(EditPolicyRoles.SNAP_FEEDBACK_ROLE, new SnapFeedbackPolicy()); } /* * (non-Javadoc) * * @see org.eclipse.gef.EditPart#deactivate() */ public void deactivate() { if (!isActive()) { return; } boolean wasActive = isActive(); super.deactivate(); if (listenerFilters != null && wasActive != isActive()) { for (Iterator i = listenerFilters.keySet().iterator(); i.hasNext();) { Object[] obj = (Object[]) listenerFilters.get(i.next()); if (obj.length > 2) { getDiagramEventBroker().removeNotificationListener((EObject) obj[0], (EStructuralFeature) obj[1], (NotificationListener) obj[2]); } else { getDiagramEventBroker().removeNotificationListener((EObject) obj[0], (NotificationListener) obj[1]); } } } getConnectionFigure().getConnectionRouter().remove(getConnectionFigure()); } public void removeNotify() { super.removeNotify(); if (cachedFontData != null) { getResourceManager().destroyFont(FontDescriptor.createFrom(cachedFontData)); cachedFontData = null; } } /** * executes the passed command * * @param command * the command to execute */ protected void executeCommand(Command command) { getEditDomain().getCommandStack().execute(command); } /** * a function that registers this provider with the Eclipse AdapterManager * as an IView and an IActionFilter adapter factory for the * IGraphicalEditPart nodes * */ static private void registerAdapters() { Platform.getAdapterManager().registerAdapters(new IAdapterFactory() { /** * @see org.eclipse.core.runtime.IAdapterFactory */ public Object getAdapter(Object adaptableObject, Class adapterType) { IGraphicalEditPart gep = (IGraphicalEditPart) adaptableObject; if (adapterType == IActionFilter.class) { return ActionFilterService.getInstance(); } else if (adapterType == View.class) { return gep.getModel(); } return null; } /** * @see org.eclipse.core.runtime.IAdapterFactory */ public Class[] getAdapterList() { return new Class[] { IActionFilter.class, View.class }; } }, IGraphicalEditPart.class); } /* * (non-Javadoc) * * @see org.eclipse.gef.editparts.AbstractEditPart#getAccessibleEditPart() */ protected AccessibleEditPart getAccessibleEditPart() { if (accessibleEP == null) { accessibleEP = new AccessibleGraphicalEditPart() { private String getSemanticName() { EObject semanticElement = resolveSemanticElement(); if (semanticElement != null) { String name = semanticElement.getClass().getName(); int startIndex = name.lastIndexOf('.') + 1; int endIndex = name.lastIndexOf("Impl"); //$NON-NLS-1$ return name.substring(startIndex, endIndex); } return DiagramUIMessages.Accessible_Connection_Label; } public void getName(AccessibleEvent e) { EditPart sourceEP = getSource(); EditPart targetEP = getTarget(); // Get the Connection Name String connectionName = getSemanticName(); // Get the Source Name String sourceName = null; if (sourceEP != null) { AccessibleEditPart aEP = (AccessibleEditPart) sourceEP.getAdapter(AccessibleEditPart.class); AccessibleEvent event = new AccessibleEvent(this); aEP.getName(event); sourceName = event.result; } // Get the Target Name String targetName = null; if (targetEP != null) { AccessibleEditPart aEP = (AccessibleEditPart) targetEP.getAdapter(AccessibleEditPart.class); AccessibleEvent event = new AccessibleEvent(this); aEP.getName(event); targetName = event.result; } if (sourceName != null && targetName != null) { e.result = NLS.bind(DiagramUIMessages.Accessible_Connection_From_Source_To_Target, new Object[] { connectionName, sourceName, targetName }); } else if (sourceName != null) { e.result = NLS.bind(DiagramUIMessages.Accessible_Connection_From_Source, new Object[] { connectionName, sourceName }); } else if (targetName != null) { e.result = NLS.bind(DiagramUIMessages.Accessible_Connection_To_Target, new Object[] { connectionName, targetName }); } else { e.result = connectionName; } } }; } return accessibleEP; } /** * Adds the ability to adapt to this editpart's view class. */ public Object getAdapter(Class key) { Object adapter = Platform.getAdapterManager().getAdapter(this, key); if (adapter != null) { return adapter; } if (key == SnapToHelper.class) { return SnapToHelperUtil.getSnapHelper((org.eclipse.gef.GraphicalEditPart) this.getSource()); } Object model = getModel(); if (View.class.isAssignableFrom(key) && key.isInstance(model)) { return model; } if (model != null && model instanceof View) { // Adapt to semantic element EObject semanticObject = ViewUtil.resolveSemanticElement((View) model); if (key.isInstance(semanticObject)) { return semanticObject; } else if (key.isInstance(model)) { return model; } } return super.getAdapter(key); } /** * Method getChildBySemanticHint. * * @param semanticHint * @return IGraphicalEditPart */ public IGraphicalEditPart getChildBySemanticHint(String semanticHint) { if (getModel() != null) { View view = ViewUtil.getChildBySemanticHint((View) getModel(), semanticHint); if (view != null) return (IGraphicalEditPart) getViewer().getEditPartRegistry().get(view); } return null; } /* * (non-Javadoc) * * @see org.eclipse.gef.EditPart#getCommand(org.eclipse.gef.Request) */ public Command getCommand(Request _request) { if (!isEditModeEnabled()) { return UnexecutableCommand.INSTANCE; } Command cmd = null; try { GETCOMMAND_RECURSIVE_COUNT++; final Request request = _request; try { cmd = (Command) getEditingDomain().runExclusive(new RunnableWithResult.Impl() { public void run() { setResult(ConnectionEditPart.super.getCommand(request)); } }); } catch (InterruptedException e) { Trace.catching(DiagramUIPlugin.getInstance(), DiagramUIDebugOptions.EXCEPTIONS_CATCHING, getClass(), "getCommand", e); //$NON-NLS-1$ Log.error(DiagramUIPlugin.getInstance(), DiagramUIStatusCodes.IGNORED_EXCEPTION_WARNING, "getCommand", e); //$NON-NLS-1$ } if (cmd != null) { _disableCanonicalEditPolicyList.addAll(disableCanonicalFor(_request)); } GETCOMMAND_RECURSIVE_COUNT--; if (GETCOMMAND_RECURSIVE_COUNT == 0) { if (cmd != null && !_disableCanonicalEditPolicyList.isEmpty()) { CompoundCommand cc = new CompoundCommand(); cc.setLabel(cmd.getLabel()); ToggleCanonicalModeCommand tcmd = ToggleCanonicalModeCommand .getToggleCanonicalModeCommand(_disableCanonicalEditPolicyList, false); cc.add(tcmd); cc.add(cmd); ToggleCanonicalModeCommand tcmd2 = ToggleCanonicalModeCommand .getToggleCanonicalModeCommand(tcmd, true); if (tcmd2 != null) { tcmd2.setDomain(getEditingDomain()); } cc.add(tcmd2); _disableCanonicalEditPolicyList.clear(); return cc.unwrap(); } } } catch (RuntimeException t) { GETCOMMAND_RECURSIVE_COUNT = 0; throw t; } return cmd; } /** * Return a list of editparts who's canonical editpolicies should be disabled * prior to executing the commands associated to the supplied request. * This implementation will return the editpart honoring a <code>SemanticWrapperRequest</code> * and a <code>CreateConnectionViewRequest</code>'s source and target editparts. * * @param request a request that has returned a command. * @return list of editparts. */ protected Collection disableCanonicalFor(final Request request) { // // not the most generic of solution; however, it will have to do for now... // // Alternate solutions // 1. common request interface on all the requests // IRequest#getAffectedEditParts // // 2. Traverse down the command and collect of the ICommand#getAffectedObjects() // -- this requires that all our commands properly set this value. Set hosts = new HashSet(); if ((request instanceof EditCommandRequestWrapper) || request instanceof TargetRequest || request instanceof DropRequest) { hosts.add(this); hosts.add(getParent()); } if ((request instanceof ReconnectRequest)) { ReconnectRequest reconnect = (ReconnectRequest) request; hosts.add(this); hosts.add(getParent()); if (reconnect.getTarget() != null) { EditPart target = reconnect.getTarget(); addEditPartAndParent(hosts, target); } if (reconnect.getConnectionEditPart() != null) { org.eclipse.gef.ConnectionEditPart connectionEditPart = reconnect.getConnectionEditPart(); if (connectionEditPart.getSource() != null) { EditPart srcEP = connectionEditPart.getSource(); addEditPartAndParent(hosts, srcEP); } if (connectionEditPart.getTarget() != null) { EditPart trgEP = connectionEditPart.getTarget(); addEditPartAndParent(hosts, trgEP); } } } if ((request instanceof CreateConnectionRequest)) { CreateConnectionRequest ccvr = (CreateConnectionRequest) request; hosts.add(this); hosts.add(getParent()); if (ccvr.getSourceEditPart() != null) { hosts.add(ccvr.getSourceEditPart()); hosts.add(ccvr.getSourceEditPart().getParent()); } if (ccvr.getTargetEditPart() != null) { hosts.add(ccvr.getTargetEditPart()); hosts.add(ccvr.getTargetEditPart().getParent()); } } if ((request instanceof GroupRequest)) { List parts = ((GroupRequest) request).getEditParts(); hosts.add(this); hosts.add(getParent()); Iterator editparts = parts == null ? Collections.EMPTY_LIST.iterator() : parts.iterator(); while (editparts.hasNext()) { EditPart ep = (EditPart) editparts.next(); addEditPartAndParent(hosts, ep); } } ///////////////////////////////////////////////////////////// // This following behavior is specific to BorderItemEditPart and // AbstractBorderItemEditPart, but we do not want to allow clients to // override this method so we do not want to make it protected. if (this instanceof IBorderItemEditPart) { if ((request instanceof CreateConnectionViewRequest)) { CreateConnectionViewRequest ccvr = (CreateConnectionViewRequest) request; if (ccvr.getSourceEditPart() instanceof IBorderItemEditPart) { hosts.add(ccvr.getSourceEditPart().getParent().getParent()); } if (ccvr.getTargetEditPart() instanceof IBorderItemEditPart) { hosts.add(ccvr.getTargetEditPart().getParent().getParent()); } } } ///////////////////////////////////////////////////////////// return hosts; } private void addEditPartAndParent(Set hosts, EditPart editPart) { hosts.add(editPart); hosts.add(editPart.getParent()); } /** * Convenience method returning the editpart's Diagram, the Diagam that owns * the edit part * * @return the diagram */ protected Diagram getDiagramView() { return ((View) getRoot().getContents().getModel()).getDiagram(); } /* * (non-Javadoc) * * @see org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart#getPrimaryView() */ public View getPrimaryView() { if (this instanceof IPrimaryEditPart && getModel() instanceof View) { return (View) getModel(); } else { for (EditPart ep = getParent(); ep != null; ep = ep.getParent()) { if (ep instanceof IGraphicalEditPart && ep.getModel() instanceof View) { return ((IGraphicalEditPart) ep).getPrimaryView(); } } } return null; } /** * Convenience method returning the editpart's edit domain. Same as calling * <code>getRoot().getViewer().getEditDomain()</code> * * @return the edit domain */ protected EditDomain getEditDomain() { return getRoot().getViewer().getEditDomain(); } /* * (non-Javadoc) * * @see org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart#getDiagramEditDomain() */ public IDiagramEditDomain getDiagramEditDomain() { return (IDiagramEditDomain) getEditDomain(); } /** * Return this editpart's view (model) children. * * @return list of views. */ protected List getModelChildren() { return new ArrayList(((View) getModel()).getChildren()); } /** * Convenience method to retreive the value for the supplied value from the * editpart's associated view element. Same as calling * <code> ViewUtil.getStructuralFeatureValue(getNotationView(),feature)</code>. */ public Object getStructuralFeatureValue(EStructuralFeature feature) { return ViewUtil.getStructuralFeatureValue((View) getModel(), feature); } /** * try to resolve the semantic element and Return the resolven element; if * the element is unresolvable or null it will return null * * @return non proxy EObject or NULL */ public EObject resolveSemanticElement() { EObject eObj = ((View) getModel()).getElement(); if (eObj == null) { return null; } if (!eObj.eIsProxy()) { return eObj; } try { return (EObject) getEditingDomain().runExclusive(new RunnableWithResult.Impl() { public void run() { setResult(ViewUtil.resolveSemanticElement((View) getModel())); } }); } catch (InterruptedException e) { Trace.catching(DiagramUIPlugin.getInstance(), DiagramUIDebugOptions.EXCEPTIONS_CATCHING, getClass(), "resolveSemanticElement", e); //$NON-NLS-1$ Log.error(DiagramUIPlugin.getInstance(), DiagramUIStatusCodes.IGNORED_EXCEPTION_WARNING, "resolveSemanticElement", e); //$NON-NLS-1$ return null; } } /** * Walks up the editpart hierarchy to find and return the * <code>TopGraphicEditPart</code> instance. */ public TopGraphicEditPart getTopGraphicEditPart() { EditPart editPart = this; while (editPart instanceof IGraphicalEditPart) { if (editPart instanceof TopGraphicEditPart) return (TopGraphicEditPart) editPart; editPart = editPart.getParent(); } return null; } /** * Return the editpart's associated Notation View. * * @return <code>View</code>, the associated view or null if there is no * associated Notation View */ public View getNotationView() { Object model = getModel(); if (model instanceof View) return (View) model; return null; } /** * Handles the passed property changed event only if the editpart's view is * not deleted */ public final void propertyChange(PropertyChangeEvent event) { if (isActive()) handlePropertyChangeEvent(event); } /** * Handles the property changed event. Clients should override to respond to * the specific notification events they are interested. * * Note: This method may get called on a non-UI thread. Clients should * either ensure that their code is thread safe and/or doesn't make * unsupported calls (i.e. Display.getCurrent() ) assuming they are on the * main thread. Alternatively if this is not possible, then the client can * wrap their handler within the Display.synchExec runnable to ensure * synchronization and subsequent execution on the main thread. * * @param event * the <code>Notification</code> object that is the property * changed event */ protected void handlePropertyChangeEvent(PropertyChangeEvent event) { if (event.getPropertyName().equals(Connection.PROPERTY_CONNECTION_ROUTER)) { installRouter(); } } /** * Method reactivateSemanticModel. This method reactivates the edit part's * emantic model by: 1- removing semantic listeners 2- adding semantic * listeners if the semantic reference is resolvable 3- Refreshing it * * This method is called in response to IView's Properties.ID_SEMANTICREF * property change event However, it will only work under the following * assumptions: 1- The old and new semantic models are compatible in their * kind 2- The deltas between old and new semantic models do not affect * notation 3- Connections are not refereshed since they are maintained by * the diagram */ public void reactivateSemanticModel() { removeSemanticListeners(); if (resolveSemanticElement() != null) addSemanticListeners(); refresh(); } /** Finds an editpart given a starting editpart and an EObject */ public EditPart findEditPart(EditPart epBegin, EObject theElement) { if (theElement == null) { return null; } EditPart epStart = null; if (epBegin == null) { epStart = this; } else { epStart = epBegin; } final View view = (View) ((IAdaptable) epStart).getAdapter(View.class); if (view != null) { EObject el = ViewUtil.resolveSemanticElement(view); if ((el != null) && el.equals(theElement)) { return epStart; } } ListIterator childLI = epStart.getChildren().listIterator(); while (childLI.hasNext()) { EditPart epChild = (EditPart) childLI.next(); EditPart elementEP = findEditPart(epChild, theElement); if (elementEP != null) { return elementEP; } } return null; } /** * Refresh the editpart's figure foreground colour. */ protected void refreshForegroundColor() { LineStyle style = (LineStyle) getPrimaryView().getStyle(NotationPackage.Literals.LINE_STYLE); if (style != null) setForegroundColor(DiagramColorRegistry.getInstance().getColor(Integer.valueOf(style.getLineColor()))); } /** * Refresh the editpart's figure visibility. */ protected void refreshVisibility() { setVisibility(((View) getModel()).isVisible()); } /** * Removes a listener previously added with the given id * * @param filterId * the filiter ID */ protected void removeListenerFilter(String filterId) { if (listenerFilters == null) return; Object[] objects = (Object[]) listenerFilters.get(filterId); if (objects == null) { return; } if (objects.length > 2) { getDiagramEventBroker().removeNotificationListener((EObject) objects[0], (EStructuralFeature) objects[1], (NotificationListener) objects[2]); } else { getDiagramEventBroker().removeNotificationListener((EObject) objects[0], (NotificationListener) objects[1]); } listenerFilters.remove(filterId); } /** * sets the forefround color of the editpart's figure * * @param color * the color */ protected void setForegroundColor(Color color) { getFigure().setForegroundColor(color); } /** * Sets the passed feature if possible on this editpart's view to the passed * value. * * @param feature * the feature to use * @param value * the value of the property being set */ public void setStructuralFeatureValue(EStructuralFeature feature, Object value) { ViewUtil.setStructuralFeatureValue((View) getModel(), feature, value); } /** * sets the edit part's visibility * * @param vis * the new visibilty value */ protected void setVisibility(boolean vis) { if (!vis && getSelected() != SELECTED_NONE) getViewer().deselect(this); getFigure().setVisible(vis); getFigure().revalidate(); } /** * This method adds all listeners to the notational world (views, figures, * editpart...etc) Override this method to add more notational listeners * down the hierarchy */ protected void addNotationalListeners() { addListenerFilter("View", this, (View) getModel());//$NON-NLS-1$ getFigure().addPropertyChangeListener(Connection.PROPERTY_CONNECTION_ROUTER, this); } /** * This method adds all listeners to the semantic element behind this * EditPart Override this method to add more semantic listeners down the * hierarchy This method is called only if the semantic element is * resolvable */ protected void addSemanticListeners() { addListenerFilter("SemanticModel", //$NON-NLS-1$ this, resolveSemanticElement()); } /** * This method removes all listeners to the notational world (views, * figures, editpart...etc) Override this method to remove notational * listeners down the hierarchy */ protected void removeNotationalListeners() { getFigure().removePropertyChangeListener(Connection.PROPERTY_CONNECTION_ROUTER, this); removeListenerFilter("View");//$NON-NLS-1$ } /** * This method removes all listeners to the semantic element behind this * EditPart Override this method to remove semantic listeners down the * hierarchy */ protected void removeSemanticListeners() { removeListenerFilter("SemanticModel");//$NON-NLS-1$ } /** * @see org.eclipse.gef.EditPart#addNotify() */ public void addNotify() { super.addNotify(); installRouter(); } /** * a static array of appearance property ids applicable to the connections */ protected static final String[] appearanceProperties = new String[] { Properties.ID_FONTNAME, Properties.ID_FONTSIZE, Properties.ID_FONTBOLD, Properties.ID_FONTITALIC, Properties.ID_FONTCOLOR, Properties.ID_LINECOLOR }; /** * construcotr * * @param view , * the view the edit part will own */ public ConnectionEditPart(View view) { setModel(view); } /** * Method createConnectionFigure. * * @return a <code>Connection</code> figure */ abstract protected Connection createConnectionFigure(); final protected IFigure createFigure() { return createConnectionFigure(); } /* * (non-Javadoc) * * @see org.eclipse.gef.EditPart#refresh() */ public void refresh() { if (getSource() != null && getTarget() != null) { try { getEditingDomain().runExclusive(new Runnable() { public void run() { ConnectionEditPart.super.refresh(); EditPolicyIterator i = getEditPolicyIterator(); while (i.hasNext()) { EditPolicy policy = i.next(); if (policy instanceof GraphicalEditPolicyEx) { ((GraphicalEditPolicyEx) policy).refresh(); } } } }); } catch (InterruptedException e) { Trace.catching(DiagramUIPlugin.getInstance(), DiagramUIDebugOptions.EXCEPTIONS_CATCHING, getClass(), "refresh", e); //$NON-NLS-1$ Log.error(DiagramUIPlugin.getInstance(), DiagramUIStatusCodes.IGNORED_EXCEPTION_WARNING, "refresh", //$NON-NLS-1$ e); } } } /** * utility method to get the <code>Edge</code> view * * @return the <code>Edge</code> */ protected Edge getEdge() { return (Edge) getModel(); } /* * @see AbstractEditPart#getDragTracker(Request) */ public DragTracker getDragTracker(Request req) { return new SelectConnectionEditPartTracker(this); } /** * give access to the source of the edit part's Edge * * @return the source */ protected Object getModelSource() { return getEdge().getSource(); } /** * give access to the target of the edit part's Edge * * @return the target */ protected Object getModelTarget() { return getEdge().getTarget(); } /** * installes a router on the edit part, depending on the * <code>RoutingStyle</code> */ protected void installRouter() { ConnectionLayer cLayer = (ConnectionLayer) getLayer(LayerConstants.CONNECTION_LAYER); RoutingStyle style = (RoutingStyle) ((View) getModel()).getStyle(NotationPackage.Literals.ROUTING_STYLE); if (style != null && cLayer instanceof ConnectionLayerEx) { ConnectionLayerEx cLayerEx = (ConnectionLayerEx) cLayer; Routing routing = style.getRouting(); if (Routing.MANUAL_LITERAL == routing) { getConnectionFigure().setConnectionRouter(cLayerEx.getObliqueRouter()); } else if (Routing.RECTILINEAR_LITERAL == routing) { getConnectionFigure().setConnectionRouter(cLayerEx.getRectilinearRouter()); } else if (Routing.TREE_LITERAL == routing) { getConnectionFigure().setConnectionRouter(cLayerEx.getTreeRouter()); } } refreshRouterChange(); } /** * refresh the pendpoints owned by the EditPart's <code>Edge</code> */ protected void refreshBendpoints() { RelativeBendpoints bendpoints = (RelativeBendpoints) getEdge().getBendpoints(); List modelConstraint = bendpoints.getPoints(); List figureConstraint = new ArrayList(); for (int i = 0; i < modelConstraint.size(); i++) { org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint wbp = (org.eclipse.gmf.runtime.notation.datatype.RelativeBendpoint) modelConstraint .get(i); RelativeBendpoint rbp = new RelativeBendpoint(getConnectionFigure()); rbp.setRelativeDimensions(new Dimension(wbp.getSourceX(), wbp.getSourceY()), new Dimension(wbp.getTargetX(), wbp.getTargetY())); if (modelConstraint.size() == 1) { rbp.setWeight(0.5f); } else { rbp.setWeight(i / ((float) modelConstraint.size() - 1)); } figureConstraint.add(rbp); } getConnectionFigure().setRoutingConstraint(figureConstraint); } private void installBendpointEditPolicy() { if (getConnectionFigure().getConnectionRouter() instanceof ForestRouter) { installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE, new TreeConnectionBendpointEditPolicy()); } else if (getConnectionFigure().getConnectionRouter() instanceof OrthogonalRouter) { installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE, new ConnectionLineSegEditPolicy()); } else { installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE, new ConnectionBendpointEditPolicy()); } EditPartUtil.synchronizeRunnableToMainThread(this, new Runnable() { public void run() { if (getConnectionFigure().getConnectionRouter() instanceof ForestRouter) { getConnectionFigure().setCursor(Cursors.CURSOR_SEG_MOVE); } else if (getConnectionFigure().getConnectionRouter() instanceof OrthogonalRouter) { getConnectionFigure().setCursor(Cursors.CURSOR_SEG_MOVE); } else { getConnectionFigure().setCursor(Cursors.CURSOR_SEG_ADD); } }; }); } /** * Method refreshRouterChange. */ protected void refreshRouterChange() { refreshBendpoints(); installBendpointEditPolicy(); } /** * Method refreshSmoothness. */ protected void refreshSmoothness() { Connection connection = getConnectionFigure(); if (!(connection instanceof PolylineConnectionEx)) return; PolylineConnectionEx poly = (PolylineConnectionEx) connection; RoutingStyle style = (RoutingStyle) ((View) getModel()).getStyle(NotationPackage.Literals.ROUTING_STYLE); if (style != null) { Smoothness smoothness = style.getSmoothness(); if (Smoothness.LESS_LITERAL == smoothness) { poly.setSmoothness(PolylineConnectionEx.SMOOTH_LESS); } else if (Smoothness.NORMAL_LITERAL == smoothness) { poly.setSmoothness(PolylineConnectionEx.SMOOTH_NORMAL); } else if (Smoothness.MORE_LITERAL == smoothness) { poly.setSmoothness(PolylineConnectionEx.SMOOTH_MORE); } else if (Smoothness.NONE_LITERAL == smoothness) { poly.setSmoothness(PolylineConnectionEx.SMOOTH_NONE); } } } /** * Refreshes raduis for rounding bendpoints in rectilinear routing (radius * smaller than 1 indicates that bendpoints should not be rounded). * * @since 1.2 */ protected void refreshRoundedBendpoints() { Connection connection = getConnectionFigure(); if (!(connection instanceof PolylineConnectionEx)) return; RoutingStyle style = (RoutingStyle) ((View) getModel()).getStyle(NotationPackage.Literals.ROUTING_STYLE); if (style != null) { PolylineConnectionEx poly = (PolylineConnectionEx) connection; poly.setRoundedBendpointsRadius(style.getRoundedBendpointsRadius()); } } /** * Method refreshJumplinks. */ protected void refreshJumplinks() { Connection connection = getConnectionFigure(); if (!(connection instanceof PolylineConnectionEx)) return; PolylineConnectionEx poly = (PolylineConnectionEx) connection; RoutingStyle style = (RoutingStyle) ((View) getModel()).getStyle(NotationPackage.Literals.ROUTING_STYLE); JumpLinkStatus status = JumpLinkStatus.NONE_LITERAL; JumpLinkType type = JumpLinkType.SEMICIRCLE_LITERAL; boolean reverse = false; if (style != null) { status = style.getJumpLinkStatus(); type = style.getJumpLinkType(); reverse = style.isJumpLinksReverse(); } int jumpType = 0; if (JumpLinkStatus.BELOW_LITERAL == status) { jumpType = PolylineConnectionEx.JUMPLINK_FLAG_BELOW; } else if (JumpLinkStatus.ABOVE_LITERAL == status) { jumpType = PolylineConnectionEx.JUMPLINK_FLAG_ABOVE; } else if (JumpLinkStatus.ALL_LITERAL == status) { jumpType = PolylineConnectionEx.JUMPLINK_FLAG_ALL; } boolean bCurved = type.equals(JumpLinkType.SEMICIRCLE_LITERAL); boolean bAngleIn = !type.equals(JumpLinkType.SQUARE_LITERAL); boolean bOnBottom = reverse; poly.setJumpLinks(jumpType != 0); poly.setJumpLinksStyles(jumpType, bCurved, bAngleIn, bOnBottom); } /** * Method refreshRoutingStyles. */ protected void refreshRoutingStyles() { Connection connection = getConnectionFigure(); if (!(connection instanceof PolylineConnectionEx)) return; PolylineConnectionEx poly = (PolylineConnectionEx) connection; RoutingStyle style = (RoutingStyle) ((View) getModel()).getStyle(NotationPackage.Literals.ROUTING_STYLE); if (style != null) { boolean closestDistance = style.isClosestDistance(); boolean avoidObstruction = style.isAvoidObstructions(); poly.setRoutingStyles(closestDistance, avoidObstruction); if (avoidObstruction) installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE, null); else installBendpointEditPolicy(); } } /* * (non-Javadoc) * * @see org.eclipse.gef.editparts.AbstractEditPart#refreshVisuals() */ protected void refreshVisuals() { super.refreshVisuals(); refreshVisibility(); refreshForegroundColor(); refreshRoutingStyles(); refreshSmoothness(); refreshRoundedBendpoints(); refreshJumplinks(); refreshBendpoints(); refreshFont(); } /** * Refresh the editpart's figure font. */ protected void refreshFont() { FontStyle style = (FontStyle) getPrimaryView().getStyle(NotationPackage.Literals.FONT_STYLE); if (style != null) { setFont(new FontData(style.getFontName(), style.getFontHeight(), (style.isBold() ? SWT.BOLD : SWT.NORMAL) | (style.isItalic() ? SWT.ITALIC : SWT.NORMAL))); } } /** * Sets the font to the label. This method could be overriden to change the * font data of the font overrides typically look like this: super.setFont( * new FontData( fontData.getName(), fontData.getHeight(), * fontData.getStyle() <| &> SWT.????)); * * @param fontData * the font data */ protected void setFont(FontData fontData) { if (cachedFontData != null && cachedFontData.equals(fontData)) { // the font was previously set and has not changed; do nothing. return; } try { Font newFont = getResourceManager().createFont(FontDescriptor.createFrom(fontData)); getFigure().setFont(newFont); getFigure().repaint(); if (cachedFontData != null) { getResourceManager().destroyFont(FontDescriptor.createFrom(cachedFontData)); } cachedFontData = fontData; } catch (DeviceResourceException e) { Trace.catching(DiagramUIPlugin.getInstance(), DiagramUIDebugOptions.EXCEPTIONS_CATCHING, getClass(), "setFont", e); //$NON-NLS-1$ Log.error(DiagramUIPlugin.getInstance(), DiagramUIStatusCodes.IGNORED_EXCEPTION_WARNING, "setFont", e); //$NON-NLS-1$ } } /** * Returns an array of the appearance property ids applicable to the * receiver. Fro this type it is Properties.ID_FONT, * Properties.ID_FONTCOLOR, Properties.ID_LINECOLOR * * @return - an array of the appearane property ids applicable to the * receiver */ protected String[] getAppearancePropertyIDs() { return appearanceProperties; } /** * Perform a request by executing a command from the target editpart of the * request For the Direct_Edit request, we need to show up an editor first * * @see org.eclipse.gef.EditPart#performRequest(org.eclipse.gef.Request) */ public void performRequest(Request request) { if (!isEditModeEnabled()) { return; } if (RequestConstants.REQ_DIRECT_EDIT == request.getType()) { performDirectEditRequest(request); } else { EditPart targetEditPart = getTargetEditPart(request); if (targetEditPart != null) { Command command = targetEditPart.getCommand(request); if (command != null) { getDiagramEditDomain().getDiagramCommandStack().execute(command); return; } } } } /** * Performs a direct edit request (usually by showing some type of editor) * * @param request * the direct edit request */ protected void performDirectEditRequest(Request request) { try { EditPart primaryChildEditPart = (EditPart) getEditingDomain() .runExclusive(new RunnableWithResult.Impl() { public void run() { setResult(getPrimaryChildEditPart()); } }); if (primaryChildEditPart != null) { primaryChildEditPart.performRequest(request); } } catch (InterruptedException e) { Trace.catching(DiagramUIPlugin.getInstance(), DiagramUIDebugOptions.EXCEPTIONS_CATCHING, getClass(), "performDirectEditRequest", e); //$NON-NLS-1$ Log.error(DiagramUIPlugin.getInstance(), DiagramUIStatusCodes.IGNORED_EXCEPTION_WARNING, "performDirectEditRequest", e); //$NON-NLS-1$ } } /** * @see org.eclipse.gef.EditPart#understandsRequest(org.eclipse.gef.Request) */ public boolean understandsRequest(Request req) { return RequestConstants.REQ_DIRECT_EDIT == req.getType() || super.understandsRequest(req); } /** Adds a [ref, editpart] mapping to the EditPartForElement map. */ protected void registerModel() { super.registerModel(); // Save the elements Guid to use during unregister EObject ref = ((View) getModel()).getElement(); if (ref == null) { return; } elementGuid = EMFCoreUtil.getProxyID(ref); ((IDiagramGraphicalViewer) getViewer()).registerEditPartForElement(elementGuid, this); } /** Remove this editpart from the EditPartForElement map. */ protected void unregisterModel() { super.unregisterModel(); ((IDiagramGraphicalViewer) getViewer()).unregisterEditPartForElement(elementGuid, this); } /** * Handles the case where the semantic reference has changed. */ protected final void handleMajorSemanticChange() { if (getSource() instanceof GraphicalEditPart && getTarget() instanceof GraphicalEditPart) { ((GraphicalEditPart) getSource()).refreshSourceConnection(this); ((GraphicalEditPart) getTarget()).refreshTargetConnection(this); } } /** * Refreshes a child editpart by removing it and refreshing children * * @param child */ final void refreshChild(GraphicalEditPart child) { removeChild(child); refreshChildren(); } /** * check if there is a canonical edit policy installed on the edit part or * not * * @return <tt>true</tt> if a canonical editpolicy has been installed on * this editpart; otherwise <tt>false</tt> */ public final boolean isCanonical() { return getEditPolicy(EditPolicyRoles.CANONICAL_ROLE) != null; } /** * checks if the edit part's figure is visible or not * * @return <tt>true</tt> if the editpart's figure is visible; * <tt>false</tt> otherwise. */ public boolean isSelectable() { return getFigure().isVisible(); } /* * @see org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart#disableEditMode() */ public void disableEditMode() { if (isEditable == false) { return; } List l = getSourceConnections(); int size = l.size(); for (int i = 0; i < size; i++) { Object obj = l.get(i); if (obj instanceof IEditableEditPart) { ((IEditableEditPart) obj).disableEditMode(); } } List c = getChildren(); size = c.size(); for (int i = 0; i < size; i++) { Object obj = c.get(i); if (obj instanceof IEditableEditPart) { ((IEditableEditPart) obj).disableEditMode(); } } isEditable = false; } /* * @see org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart#enableEditMode() */ public void enableEditMode() { if (isEditable) { return; } isEditable = true; List c = getChildren(); int size = c.size(); for (int i = 0; i < size; i++) { Object obj = c.get(i); if (obj instanceof IEditableEditPart) { ((IEditableEditPart) obj).enableEditMode(); } } List l = getSourceConnections(); size = l.size(); for (int i = 0; i < size; i++) { Object obj = l.get(i); if (obj instanceof IEditableEditPart) { ((IEditableEditPart) obj).enableEditMode(); } } } /* * @see org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart#isEditModeEnabled() */ public boolean isEditModeEnabled() { // protect against deadlock - don't allow any action while write // transaction // is active on another thread if (EditPartUtil.isWriteTransactionInProgress(this, true, true)) return false; return isEditable; } /* * @see org.eclipse.gef.EditPart#showSourceFeedback(org.eclipse.gef.Request) */ public void showSourceFeedback(Request request) { if (!isEditModeEnabled()) { return; } super.showSourceFeedback(request); } /* * @see org.eclipse.gef.EditPart#showTargetFeedback(org.eclipse.gef.Request) */ public void showTargetFeedback(Request request) { if (!isEditModeEnabled()) { return; } super.showTargetFeedback(request); } /* * @see org.eclipse.gef.EditPart#eraseSourceFeedback(org.eclipse.gef.Request) */ public void eraseSourceFeedback(Request request) { if (!isEditModeEnabled()) { return; } super.eraseSourceFeedback(request); } /* * @see org.eclipse.gef.EditPart#eraseTargetFeedback(org.eclipse.gef.Request) */ public void eraseTargetFeedback(Request request) { if (!isEditModeEnabled()) { return; } super.eraseTargetFeedback(request); } /** * this method will return the primary child EditPart inside this edit part * * @return the primary child view inside this edit part */ public EditPart getPrimaryChildEditPart() { if (getChildren().size() > 0) return (EditPart) getChildren().get(0); return null; } /* * (non-Javadoc) * * @see org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart#getDiagramPreferencesHint() */ public PreferencesHint getDiagramPreferencesHint() { RootEditPart root = getRoot(); if (root instanceof IDiagramPreferenceSupport) { return ((IDiagramPreferenceSupport) root).getPreferencesHint(); } return PreferencesHint.USE_DEFAULTS; } /* * (non-Javadoc) * * @see org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener#notifyChanged(org.eclipse.emf.common.notify.Notification) */ public void notifyChanged(Notification notification) { if (isActive()) { handleNotificationEvent(notification); } } /** * Handles the property changed event * * @param event * the property changed event */ protected void handleNotificationEvent(Notification event) { Object feature = event.getFeature(); if (NotationPackage.Literals.VIEW__PERSISTED_CHILDREN.equals(feature) || NotationPackage.Literals.VIEW__TRANSIENT_CHILDREN.equals(feature)) { refreshChildren(); } else if (NotationPackage.Literals.VIEW__VISIBLE.equals(feature)) { Object notifier = event.getNotifier(); if (notifier == getModel()) setVisibility(((Boolean) event.getNewValue()).booleanValue()); // Reactivating in response to semantic model reference change // However, we need to verify that the event belongs to this // editpart's view } else if (NotationPackage.Literals.ROUTING_STYLE__ROUTING.equals(feature)) { installRouter(); } else if (NotationPackage.Literals.ROUTING_STYLE__SMOOTHNESS.equals(feature) || NotationPackage.Literals.ROUTING_STYLE__AVOID_OBSTRUCTIONS.equals(feature) || NotationPackage.Literals.ROUTING_STYLE__CLOSEST_DISTANCE.equals(feature) || NotationPackage.Literals.ROUTING_STYLE__JUMP_LINK_STATUS.equals(feature) || NotationPackage.Literals.ROUTING_STYLE__JUMP_LINK_TYPE.equals(feature) || NotationPackage.Literals.ROUTING_STYLE__JUMP_LINKS_REVERSE.equals(feature) || NotationPackage.Literals.ROUNDED_CORNERS_STYLE__ROUNDED_BENDPOINTS_RADIUS.equals(feature)) { refreshVisuals(); } else if (NotationPackage.Literals.LINE_STYLE__LINE_COLOR.equals(feature)) { Integer c = (Integer) event.getNewValue(); setForegroundColor(DiagramColorRegistry.getInstance().getColor(c)); } else if (NotationPackage.Literals.RELATIVE_BENDPOINTS__POINTS.equals(feature)) { refreshBendpoints(); } else if (event.getFeature() == NotationPackage.Literals.VIEW__ELEMENT && ((EObject) event.getNotifier()) == getNotationView()) { handleMajorSemanticChange(); } else if (event.getEventType() == EventType.UNRESOLVE && event.getNotifier() == ((View) getModel()).getElement()) handleMajorSemanticChange(); } /** * @return <code>IMapMode</code> that allows for the coordinate mapping * from device to logical units. */ protected IMapMode getMapMode() { RootEditPart root = getRoot(); if (root instanceof DiagramRootEditPart) { DiagramRootEditPart dgrmRoot = (DiagramRootEditPart) root; return dgrmRoot.getMapMode(); } return MapModeUtil.getMapMode(); } /** * Derives my editing domain from my diagram element. Subclasses may * override. */ public TransactionalEditingDomain getEditingDomain() { if (editingDomain == null) { // try to get the editing domain for the model editingDomain = TransactionUtil.getEditingDomain(getModel()); if (editingDomain == null) { // try to get the editing domain from the diagram view editingDomain = TransactionUtil.getEditingDomain(getDiagramView()); } } return editingDomain; } /** * Gets the diagram event broker from the editing domain. * * @return the diagram event broker */ private DiagramEventBroker getDiagramEventBroker() { TransactionalEditingDomain theEditingDomain = getEditingDomain(); if (theEditingDomain != null) { return DiagramEventBroker.getInstance(theEditingDomain); } return null; } public Object getPreferredValue(EStructuralFeature feature) { Object preferenceStore = getDiagramPreferencesHint().getPreferenceStore(); if (preferenceStore instanceof IPreferenceStore) { if (feature == NotationPackage.eINSTANCE.getLineStyle_LineColor()) { return FigureUtilities.RGBToInteger(PreferenceConverter.getColor((IPreferenceStore) preferenceStore, IPreferenceConstants.PREF_LINE_COLOR)); } else if (feature == NotationPackage.eINSTANCE.getFontStyle_FontColor()) { return FigureUtilities.RGBToInteger(PreferenceConverter.getColor((IPreferenceStore) preferenceStore, IPreferenceConstants.PREF_FONT_COLOR)); } } return getStructuralFeatureValue(feature); } /** * Gets the resource manager to remember the resources allocated for this * graphical viewer. All resources will be disposed when the graphical * viewer is closed if they have not already been disposed. * * @return the resource manager */ protected ResourceManager getResourceManager() { EditPartViewer viewer = getViewer(); if (viewer instanceof DiagramGraphicalViewer) { return ((DiagramGraphicalViewer) viewer).getResourceManager(); } return JFaceResources.getResources(); } /** * Answers whether or not this connection represents a part of the semantic * model. * * @return <code>true</code> if this connection has semantic meaning, * <code>false</code> otherwise. */ public boolean isSemanticConnection() { if (semanticConnection == null) { if (getEdge() != null && (getEdge().getElement() != null || !NotationTypeUtil.hasNotationType(getEdge()))) { semanticConnection = Boolean.TRUE; } else { semanticConnection = Boolean.FALSE; } } return semanticConnection.booleanValue(); } /** * Clear the semantic connection value when the model changes. */ public void setModel(Object model) { super.setModel(model); semanticConnection = null; } /** * Set the line width of the connection. Clients need to override if they * support line width. * * @param width * the line width. */ protected void setLineWidth(int width) { /* not implemented */ } /** * Get the line width of the connection. * * @return width * the line width. */ protected int getLineWidth() { /* a default of -1 means the diagram does not implement line width */ int lineWidth = -1; LineStyle style = (LineStyle) getPrimaryView().getStyle(NotationPackage.eINSTANCE.getLineStyle()); if (style != null) { lineWidth = style.getLineWidth(); } return lineWidth; } /** * Set the line type of the connection. Clients need to override if they * support line type. * * @param lineType * the line type. */ protected void setLineType(int lineType) { /* not implemented */ } /** * Get the line type of the connection. * * @return the line type. */ protected int getLineType() { // default to Graphics.LINE_SOLID. int lineType = Graphics.LINE_SOLID; LineTypeStyle style = (LineTypeStyle) getPrimaryView() .getStyle(NotationPackage.eINSTANCE.getLineTypeStyle()); if (style != null) { if (style.getLineType() == LineType.SOLID_LITERAL) { lineType = Graphics.LINE_SOLID; } else if (style.getLineType() == LineType.DASH_LITERAL) { lineType = Graphics.LINE_DASH; } else if (style.getLineType() == LineType.DOT_LITERAL) { lineType = Graphics.LINE_DOT; } else if (style.getLineType() == LineType.DASH_DOT_LITERAL) { lineType = Graphics.LINE_DASHDOT; } else if (style.getLineType() == LineType.DASH_DOT_DOT_LITERAL) { lineType = Graphics.LINE_DASHDOTDOT; } } return lineType; } /** * Set the arrow decoration on the connection source end. Clients need to override if they * support arrow decorations. * * @param arrowDecoration * the arrow decoration. */ protected void setArrowSource(RotatableDecoration arrowDecoration) { /* not implemented */ } /** * Set the arrow decoration on the connection target end. Clients need to override if they * support arrow decorations. * * @param arrowDecoration * the arrow type. */ protected void setArrowTarget(RotatableDecoration arrowDecoration) { /* not implemented */ } /** * Get the arrow decoration for the arrow type. * * @param arrowType * the arrow type. */ protected RotatableDecoration getArrowDecoration(int arrowType) { RotatableDecoration decoration = null; int width = getLineWidth(); if (width < 0) { width = 1; } if (arrowType == ArrowType.OPEN_ARROW) { IMapMode mm = getMapMode(); decoration = new PolylineDecoration(); ((PolylineDecoration) decoration).setScale(mm.DPtoLP(11 + width), mm.DPtoLP(6 + width)); ((PolylineDecoration) decoration).setTemplate(PolylineDecoration.TRIANGLE_TIP); ((PolylineDecoration) decoration).setLineWidth(mm.DPtoLP(width)); } else if (arrowType == ArrowType.SOLID_ARROW) { IMapMode mm = getMapMode(); decoration = new PolygonDecoration(); ((PolygonDecoration) decoration).setScale(mm.DPtoLP(11 + width), mm.DPtoLP(6 + width)); ((PolygonDecoration) decoration).setTemplate(PolygonDecoration.TRIANGLE_TIP); ((PolygonDecoration) decoration).setLineWidth(mm.DPtoLP(width)); ((PolygonDecoration) decoration).setFill(true); } return decoration; } /** * Refreshes the line type property. */ protected void refreshLineWidth() { setLineWidth(getLineWidth()); } /** * Refreshes the line type property. */ protected void refreshLineType() { setLineType(getLineType()); } /** * Refreshes the arrow decoration on the source end property. */ protected void refreshArrowSource() { // default to no decoration. int arrowType = ArrowType.NONE; ArrowStyle style = (ArrowStyle) getPrimaryView().getStyle(NotationPackage.eINSTANCE.getArrowStyle()); if (style != null) { arrowType = style.getArrowSource().getValue(); } setArrowSource(getArrowDecoration(arrowType)); } /** * Refreshes the arrow decoration on the target end property. */ protected void refreshArrowTarget() { // default to no decoration. int arrowType = ArrowType.NONE; ArrowStyle style = (ArrowStyle) getPrimaryView().getStyle(NotationPackage.eINSTANCE.getArrowStyle()); if (style != null) { arrowType = style.getArrowTarget().getValue(); } setArrowTarget(getArrowDecoration(arrowType)); } }