blob: cde98c4eefdf9cf6c47de02a43661f39f81ff159 [file] [log] [blame]
/******************************************************************************
* 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", e); //$NON-NLS-1$
}
}
}
/**
* 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));
}
}