/******************************************************************************* * Copyright (c) 2000, 2005 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.gef.editpolicies; import org.eclipse.draw2d.Connection; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.ConnectionLayer; import org.eclipse.draw2d.ConnectionRouter; import org.eclipse.draw2d.PolylineConnection; import org.eclipse.draw2d.geometry.Point; import org.eclipse.gef.EditPart; import org.eclipse.gef.LayerConstants; import org.eclipse.gef.NodeEditPart; import org.eclipse.gef.Request; import org.eclipse.gef.commands.Command; import org.eclipse.gef.requests.CreateConnectionRequest; import org.eclipse.gef.requests.DropRequest; import org.eclipse.gef.requests.ReconnectRequest; /** * A GraphicalNodeEditPolicy is responsible for creating and reconnecting connections * graphically. * * Created on :Nov 11, 2002 * @author hudsonr * @since 2.0 */ public abstract class GraphicalNodeEditPolicy extends GraphicalEditPolicy { /** * the current FeedbackHelper */ protected FeedbackHelper feedbackHelper; /** * The connection feedback displayed during creates */ protected Connection connectionFeedback; /** * Returns a connection to be used as feeback during creates. * @param req the operation being performed * @return a connection to use as feedback */ protected Connection createDummyConnection(Request req) { return new PolylineConnection(); } /** * @see org.eclipse.gef.EditPolicy#deactivate() */ public void deactivate() { if (connectionFeedback != null) { removeFeedback(connectionFeedback); feedbackHelper = null; connectionFeedback = null; } super.deactivate(); } /** * Erases connection feedback if necessary. Frees unused fields. * @param request the CreateConnectionRequest */ protected void eraseCreationFeedback(CreateConnectionRequest request) { if (connectionFeedback != null) { removeFeedback(connectionFeedback); feedbackHelper = null; connectionFeedback = null; } } /** * Calls {@link #eraseCreationFeedback(CreateConnectionRequest)} when appropriate. * @see org.eclipse.gef.EditPolicy#eraseSourceFeedback(Request) */ public void eraseSourceFeedback(Request request) { if (REQ_CONNECTION_END.equals(request.getType())) eraseCreationFeedback((CreateConnectionRequest)request); } /** * Override to erase target feedback. Does nothing by default. * @param request the DropRequest */ protected void eraseTargetConnectionFeedback(DropRequest request) { } /** * Calls {@link #eraseTargetConnectionFeedback(DropRequest)} when appropriate. * @see org.eclipse.gef.EditPolicy#eraseTargetFeedback(Request) */ public void eraseTargetFeedback(Request request) { if (REQ_CONNECTION_START.equals(request.getType()) || REQ_CONNECTION_END.equals(request.getType()) || REQ_RECONNECT_SOURCE.equals(request.getType()) || REQ_RECONNECT_TARGET.equals(request.getType())) eraseTargetConnectionFeedback((DropRequest) request); } /** * Factors the request into one of four abstract methods. Subclasses must implement these * methods. * @see org.eclipse.gef.EditPolicy#getCommand(Request) */ public Command getCommand(Request request) { if (REQ_CONNECTION_START.equals(request.getType())) return getConnectionCreateCommand((CreateConnectionRequest)request); if (REQ_CONNECTION_END.equals(request.getType())) return getConnectionCompleteCommand((CreateConnectionRequest)request); if (REQ_RECONNECT_TARGET.equals(request.getType())) return getReconnectTargetCommand((ReconnectRequest)request); if (REQ_RECONNECT_SOURCE.equals(request.getType())) return getReconnectSourceCommand((ReconnectRequest)request); return null; } /** * Returns the Command that will create the connection. This is second part of creation. * {@link CreateConnectionRequest#getStartCommand()} is used here to obtain the * contribution from the EditPart from which the User started the <i>creation</i>. * @param request the CreateConnectionRequest * @return the complete command to create a connection */ protected abstract Command getConnectionCompleteCommand(CreateConnectionRequest request); /** * Returns the Command that represents the first half of creating a connection. This * Command will be passed to the target node EditPart. The target node may do anything * necessary to create a Command that represents the entire creation. * @param request the CreateConnectionRequest * @see #getConnectionCompleteCommand(CreateConnectionRequest) * @return a Command representing half of a connection creation */ protected abstract Command getConnectionCreateCommand(CreateConnectionRequest request); /** * Returns the ConnectionRouter for the creation feedback's connection. * @param request the create request * @return a connection router * @since 3.2 */ protected ConnectionRouter getDummyConnectionRouter(CreateConnectionRequest request) { return ((ConnectionLayer) getLayer(LayerConstants.CONNECTION_LAYER)) .getConnectionRouter(); } /** * Returns the FeedbackHelper that is ready to use. The feedback helper must be configured * with the connection that will be used to display feedback, and that connection must be * added to the appropriate layer in the diagram. * @param request the CreateConnectionRequest * @return a FeedbackHelper */ protected FeedbackHelper getFeedbackHelper(CreateConnectionRequest request) { if (feedbackHelper == null) { feedbackHelper = new FeedbackHelper(); Point p = request.getLocation(); connectionFeedback = createDummyConnection(request); connectionFeedback.setConnectionRouter(getDummyConnectionRouter(request)); connectionFeedback.setSourceAnchor(getSourceConnectionAnchor(request)); feedbackHelper.setConnection(connectionFeedback); addFeedback(connectionFeedback); feedbackHelper.update(null, p); } return feedbackHelper; } /** * Returns the <code>Command</code> to reconnect a connection's <i>target</i> end to the * host. * @param request the ReconnectRequest * @return a Command */ protected abstract Command getReconnectTargetCommand(ReconnectRequest request); /** * Returns the <code>Command</code> to reconnect a connection's <i>source</i> end to the * host. * @param request the ReconnectRequest * @return a Command */ protected abstract Command getReconnectSourceCommand(ReconnectRequest request); /** * Called during the display of creation feedback to snap the feedback to the nearest * source ConnectionAnchor. * @param request CreateConnectionRequest * @return <code>null</code> or the nearest source ConnectionAnchor */ protected ConnectionAnchor getSourceConnectionAnchor(CreateConnectionRequest request) { EditPart source = request.getSourceEditPart(); return source instanceof NodeEditPart ? ((NodeEditPart) source).getSourceConnectionAnchor(request) : null; } /** * Called during the display of creation feedback to snap the feedback to the nearest * target ConnectionAnchor. * @param request CreateConnectionRequest * @return <code>null</code> or the nearest target ConnectionAnchor */ protected ConnectionAnchor getTargetConnectionAnchor(CreateConnectionRequest request) { EditPart target = request.getTargetEditPart(); return target instanceof NodeEditPart ? ((NodeEditPart) target).getTargetConnectionAnchor(request) : null; } /** * Returns the <i>host</i> for the appropriate <code>Requests</code>. Returns * <code>null</code> otherwise. * @see org.eclipse.gef.EditPolicy#getTargetEditPart(Request) */ public EditPart getTargetEditPart(Request request) { if (REQ_CONNECTION_START.equals(request.getType()) || REQ_CONNECTION_END.equals(request.getType()) || REQ_RECONNECT_SOURCE.equals(request.getType()) || REQ_RECONNECT_TARGET.equals(request.getType())) return getHost(); return null; } /** * Shows feedback during a creation. * @param request CreateConnectionRequest */ protected void showCreationFeedback(CreateConnectionRequest request) { FeedbackHelper helper = getFeedbackHelper(request); Point p = new Point(request.getLocation()); helper.update(getTargetConnectionAnchor(request), p); } /** * calls {@link #showCreationFeedback(CreateConnectionRequest)} when appropriate. * @see org.eclipse.gef.EditPolicy#showSourceFeedback(Request) */ public void showSourceFeedback(Request request) { if (REQ_CONNECTION_END.equals(request.getType())) showCreationFeedback((CreateConnectionRequest)request); } /** * Override to show target connection feedback. Does nothing by default. * @param request the DropRequest */ protected void showTargetConnectionFeedback(DropRequest request) { } /** * Calls {@link #showTargetConnectionFeedback(DropRequest)} when appropriate. * @see org.eclipse.gef.EditPolicy#showTargetFeedback(Request) */ public void showTargetFeedback(Request request) { if (REQ_CONNECTION_START.equals(request.getType()) || REQ_CONNECTION_END.equals(request.getType()) || REQ_RECONNECT_SOURCE.equals(request.getType()) || REQ_RECONNECT_TARGET.equals(request.getType())) showTargetConnectionFeedback((DropRequest) request); } }