blob: 9ebabea8d73e8c7647a76d6b3701f9e37fd55d09 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2004, 2006 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.tools;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gef.tools.TargetingTool;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramCommandStack;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Display;
/**
* Abstract class for popup bar tools. This is the tool used for the Add
* commands associated with the popup bars. The creation tools for popup bars
* also need to impl DragTracker since the SelectionTool calls
* Handle.getDragTracker during mouseDown.
*
* @author affrantz
*/
public abstract class AbstractPopupBarTool
extends TargetingTool
implements DragTracker {
private EditPart myHostEditPart = null;
/** the requested element kind */
private IElementType myElementType = null;
/** the create request to be used (optional) */
private CreateRequest myRequest = null;
/**
* @param epHost
* the host editpart
* @param elementType
* the element type to be created
*/
public AbstractPopupBarTool(EditPart epHost, IElementType elementType) {
myElementType = elementType;
myHostEditPart = epHost;
lockTargetEditPart(epHost);
}
/**
* @param epHost
* the host editpart
* @param theRequest
* the create request to be used
*/
public AbstractPopupBarTool(EditPart epHost, CreateRequest theRequest) {
myHostEditPart = epHost;
myRequest = theRequest;
lockTargetEditPart(epHost);
}
/**
* @see org.eclipse.gef.tools.TargetingTool#createTargetRequest()
*/
abstract protected Request createTargetRequest();
/**
* @see org.eclipse.gef.tools.TargetingTool#getCommand()
*/
abstract protected Command getCommand();
/**
* Test to see if the tool's associated cmd is available to be run
*/
public boolean isCommandEnabled() {
Command cmd = this.getCommand();
if (cmd == null) {
return false;
}
return cmd.canExecute();
}
/**
* @see org.eclipse.gef.DragTracker#commitDrag()
*/
public void commitDrag() {
// NULL implementation
}
protected boolean handleButtonDown(int button) {
// push the cmd that will be used by performCreation
setCurrentCommand(getCommand());
return super.handleButtonDown(button);
}
/**
*
* @see org.eclipse.gef.tools.AbstractTool#handleButtonUp(int)
*/
protected boolean handleButtonUp(int button) {
performCreation(button);
return true;
}
/**
* @see org.eclipse.gef.tools.AbstractTool#performCreation(int)
* @param button
*/
private void performCreation(int button) {
EditPartViewer viewer = getCurrentViewer();
Command c = getCurrentCommand();
executeCurrentCommand();
List editparts = new ArrayList(1);
Collection newObjects = DiagramCommandStack.getReturnValues(c);
for (Iterator i = newObjects.iterator(); i.hasNext();) {
Object o = i.next();
EditPart editpart = null;
if (o instanceof IAdaptable) {
IAdaptable adapter = (IAdaptable) o;
View view = (View) adapter.getAdapter(View.class);
if (view != null)
editpart = (EditPart) viewer.getEditPartRegistry()
.get(view);
} else if (o instanceof EObject) {
IGraphicalEditPart host = (IGraphicalEditPart) myHostEditPart;
editpart = host.findEditPart(host, (EObject) o);
}
if (editpart != null)
editparts.add(editpart);
}
selectAddedObject(viewer, editparts);
}
/**
* Finds the newly created editpart associated with the element that has
* been added and then selects the editpart and requests direct editing
*
*/
protected void selectAddedObject(final EditPartViewer viewer,
final List editparts) {
if (editparts.isEmpty())
return;
// Don't change the selection unless at least one editpart is
// selectable.
boolean selectable = false;
for (Iterator iter = editparts.iterator(); iter.hasNext();) {
EditPart editpart = (EditPart) iter.next();
if (editpart.isSelectable()) {
selectable = true;
break;
}
}
if (selectable) {
// automatically put the first shape into edit-mode
Display.getCurrent().asyncExec(new Runnable() {
public void run() {
viewer.setSelection(new StructuredSelection(editparts));
EditPart editpart = (EditPart) editparts.get(0);
editpart.performRequest(new Request(
RequestConstants.REQ_DIRECT_EDIT));
}
});
}
}
/**
* HACK in order to lock the editpart for the duration that this tool is
* active and avoid updateTargetUnderMouse, getting called we need to
* override this method to perform a NOP
*
* @see org.eclipse.gef.tools.TargetingTool#unlockTargetEditPart()
*/
protected void unlockTargetEditPart() {
// NULL implementation
}
protected IElementType getElementType() {
return myElementType;
}
protected void setElementKind(IElementType elementType) {
myElementType = elementType;
}
/**
* @see org.eclipse.gef.tools.AbstractTool#getCommandName()
*/
protected String getCommandName() {
return REQ_CREATE;
}
/**
* @see org.eclipse.gef.tools.AbstractTool#getDebugName()
*/
protected String getDebugName() {
return "Popup Bar Creation Tool"; //$NON-NLS-1$
}
protected EditPart getHost() {
return myHostEditPart;
}
/**
* Gets the preferences hint that is to be used to find the appropriate
* preference store from which to retrieve diagram preference values. The
* preference hint is mapped to a preference store in the preference
* registry <@link DiagramPreferencesRegistry>.
*
* @return the preferences hint
*/
protected PreferencesHint getPreferencesHint() {
PreferencesHint preferencesHint = null;
if (myHostEditPart != null) {
preferencesHint = ((IGraphicalEditPart) myHostEditPart)
.getDiagramPreferencesHint();
}
return preferencesHint;
}
/**
* Gets the the create request to be used if one was specified in the constructor.
* @return Returns the create request.
*/
protected CreateRequest getCreateRequest() {
return myRequest;
}
}