/****************************************************************************** * Copyright (c) 2003, 2009 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.editpolicies; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.draw2d.FigureListener; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Point; import org.eclipse.gef.LayerConstants; import org.eclipse.gef.Tool; import org.eclipse.gef.tools.SelectionTool; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.handles.ConnectionHandle; import org.eclipse.gmf.runtime.diagram.ui.handles.ConnectionHandleLocator; import org.eclipse.gmf.runtime.diagram.ui.handles.ConnectionHandle.HandleDirection; import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages; import org.eclipse.gmf.runtime.diagram.ui.preferences.IPreferenceConstants; import org.eclipse.gmf.runtime.emf.ui.services.modelingassistant.ModelingAssistantService; /** * This editpolicy is responsible for adding the connection handles to a shape. * * @author cmahoney */ public class ConnectionHandleEditPolicy extends DiagramAssistantEditPolicy { /** * Listens to the owner figure being moved so the handles can be removed * when this occurs. */ private class OwnerMovedListener implements FigureListener { /** * @see org.eclipse.draw2d.FigureListener#figureMoved(org.eclipse.draw2d.IFigure) */ public void figureMoved(IFigure source) { hideDiagramAssistant(); } } /** listener for owner shape movement */ private OwnerMovedListener ownerMovedListener = new OwnerMovedListener(); /** list of connection handles currently being displayed */ private List handles = null; /* (non-Javadoc) * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.DiagramAssistantEditPolicy#isDiagramAssistant(java.lang.Object) */ protected boolean isDiagramAssistant(Object object) { return object instanceof ConnectionHandle; } /** * Gets the two connection handle figures to be added to this shape if they * support user gestures. * @return a list of <code>ConnectionHandle</code> objects */ protected List getHandleFigures() { List list = new ArrayList(2); String tooltip; tooltip = buildTooltip(HandleDirection.INCOMING); if (tooltip != null) { list.add(new ConnectionHandle((IGraphicalEditPart) getHost(), HandleDirection.INCOMING, tooltip)); } tooltip = buildTooltip(HandleDirection.OUTGOING); if (tooltip != null) { list.add(new ConnectionHandle((IGraphicalEditPart) getHost(), HandleDirection.OUTGOING, tooltip)); } return list; } /** * Builds the applicable tooltip string based on whether the Modeling * Assistant Service supports handle gestures on this element. If no * gestures are supported, the tooltip returned will be null. * * @param direction * the handle direction. * @return tooltip the tooltip string; if null, the handle should be not be * displayed */ protected String buildTooltip(HandleDirection direction) { ModelingAssistantService service = ModelingAssistantService .getInstance(); boolean supportsCreation = (direction == HandleDirection.OUTGOING) ? !service .getRelTypesOnSource(getHost()).isEmpty() : !service.getRelTypesOnTarget(getHost()).isEmpty(); boolean supportsSRE = (direction == HandleDirection.OUTGOING) ? !service .getRelTypesForSREOnSource(getHost()).isEmpty() : !service.getRelTypesForSREOnTarget(getHost()).isEmpty(); if (supportsSRE) { if (supportsCreation) { return DiagramUIMessages.ConnectionHandle_ToolTip_ShowRelatedElementsAndCreateRelationship; } else { return DiagramUIMessages.ConnectionHandle_ToolTip_ShowRelatedElementsOnly; } } else if (supportsCreation) { return DiagramUIMessages.ConnectionHandle_ToolTip_CreateRelationshipOnly; } return null; } public void activate() { super.activate(); ((IGraphicalEditPart) getHost()).getFigure().addFigureListener( ownerMovedListener); } public void deactivate() { ((IGraphicalEditPart) getHost()).getFigure().removeFigureListener( ownerMovedListener); super.deactivate(); } protected void showDiagramAssistant(Point referencePoint) { if (referencePoint == null) { referencePoint = getHostFigure().getBounds().getRight(); } handles = getHandleFigures(); if (handles == null) { return; } ConnectionHandleLocator locator = getConnectionHandleLocator(referencePoint); IFigure layer = getLayer(LayerConstants.HANDLE_LAYER); for (Iterator iter = handles.iterator(); iter.hasNext();) { ConnectionHandle handle = (ConnectionHandle) iter.next(); handle.setLocator(locator); locator.addHandle(handle); handle.addMouseMotionListener(this); layer.add(handle); // Register this figure with it's host editpart so mouse events // will be propagated to it's host. getHost().getViewer().getVisualPartMap().put(handle, getHost()); } if(!shouldAvoidHidingDiagramAssistant()) { // dismiss the handles after a delay hideDiagramAssistantAfterDelay(getDisappearanceDelay()); } } /* * (non-Javadoc) * * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.DiagramAssistantEditPolicy#getPreferenceName() */ String getPreferenceName() { return IPreferenceConstants.PREF_SHOW_CONNECTION_HANDLES; } /** * Removes the connection handles. */ protected void hideDiagramAssistant() { if (handles == null) { return; } IFigure layer = getLayer(LayerConstants.HANDLE_LAYER); for (Iterator iter = handles.iterator(); iter.hasNext();) { IFigure handle = (IFigure) iter.next(); handle.removeMouseMotionListener(this); layer.remove(handle); getHost().getViewer().getVisualPartMap().remove(handle); } handles = null; } private boolean isSelectionToolActive() { // getViewer calls getParent so check for null if(getHost().getParent() != null) { Tool theTool = getHost().getViewer().getEditDomain().getActiveTool(); if((theTool != null) && theTool instanceof SelectionTool) { return true; } } return false; } /* (non-Javadoc) * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.DiagramAssistantEditPolicy#shouldShowDiagramAssistant() */ protected boolean shouldShowDiagramAssistant(){ if (!super.shouldShowDiagramAssistant()) { return false; } if (handles != null || !isSelectionToolActive()) { return false; } return true; } /** * get the connection handle locator using the host and the passed reference * point * * @param referencePoint * @return <code>ConnectionHandleLocator</code> */ protected ConnectionHandleLocator getConnectionHandleLocator(Point referencePoint){ return new ConnectionHandleLocator(getHostFigure(), referencePoint); } /* (non-Javadoc) * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.DiagramAssistantEditPolicy#isDiagramAssistantShowing() */ protected boolean isDiagramAssistantShowing() { return handles != null; } protected String getDiagramAssistantID() { return ConnectionHandleEditPolicy.class.getName(); } /** * Add a connection handle to the edit policy. * * @param aHandle the connection handle. * @since 1.2 */ public void addHandle(ConnectionHandle aHandle ) { handles.add(aHandle); } }