/*******************************************************************************
* 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);
}
}