| /******************************************************************************* |
| * Copyright (c) 2000, 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.gef.tools; |
| |
| import java.util.List; |
| |
| import org.eclipse.swt.graphics.Cursor; |
| |
| import org.eclipse.draw2d.rap.swt.SWT; |
| |
| 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.requests.DirectEditRequest; |
| import org.eclipse.gef.requests.SelectionRequest; |
| |
| /** |
| * DragTracker used to select, edit, and open {@link org.eclipse.gef.EditPart |
| * EditParts}. |
| */ |
| public class SelectEditPartTracker extends TargetingTool implements DragTracker { |
| |
| /** Flag to indicate selection has been performed. */ |
| protected static final int FLAG_SELECTION_PERFORMED = TargetingTool.MAX_FLAG << 1; |
| private static final int FLAG_ENABLE_DIRECT_EDIT = TargetingTool.MAX_FLAG << 2; |
| /** Max flag */ |
| protected static final int MAX_FLAG = FLAG_ENABLE_DIRECT_EDIT; |
| |
| private EditPart editpart; |
| |
| /** |
| * Constructs a new SelectEditPartTracker with the given edit part as the |
| * source. |
| * |
| * @param owner |
| * the source edit part |
| */ |
| public SelectEditPartTracker(EditPart owner) { |
| setSourceEditPart(owner); |
| } |
| |
| /** |
| * @see org.eclipse.gef.tools.AbstractTool#calculateCursor() |
| */ |
| protected Cursor calculateCursor() { |
| if (isInState(STATE_INITIAL | STATE_DRAG | STATE_ACCESSIBLE_DRAG)) |
| return getDefaultCursor(); |
| return super.calculateCursor(); |
| } |
| |
| /** |
| * @see org.eclipse.gef.tools.AbstractTool#getCommandName() |
| */ |
| protected String getCommandName() { |
| return "Select Tracker";//$NON-NLS-1$ |
| } |
| |
| /** |
| * @see org.eclipse.gef.tools.AbstractTool#getDebugName() |
| */ |
| protected String getDebugName() { |
| return "Select Tracker";//$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns the source edit part. |
| * |
| * @return the source edit part |
| */ |
| protected EditPart getSourceEditPart() { |
| return editpart; |
| } |
| |
| /** |
| * Performs a conditional selection if needed (if right or left mouse button |
| * have been pressed) and goes into the drag state. If any other button has |
| * been pressed, the tool goes into the invalid state. |
| * |
| * @see org.eclipse.gef.tools.AbstractTool#handleButtonDown(int) |
| */ |
| protected boolean handleButtonDown(int button) { |
| if ((button == 3 || button == 1) && isInState(STATE_INITIAL)) |
| performConditionalSelection(); |
| |
| if (button != 1) { |
| setState(STATE_INVALID); |
| if (button == 3) |
| setState(STATE_TERMINAL); |
| handleInvalidInput(); |
| } else |
| stateTransition(STATE_INITIAL, STATE_DRAG); |
| return true; |
| } |
| |
| /** |
| * If in the drag state, the tool selects the source edit part. If the edit |
| * part was already selected, {@link #performDirectEdit()} is called. If the |
| * edit part is newly selected and not completely visible, |
| * {@link EditPartViewer#reveal(EditPart)} is called to show the selected |
| * edit part. |
| * |
| * @see org.eclipse.gef.tools.AbstractTool#handleButtonUp(int) |
| */ |
| protected boolean handleButtonUp(int button) { |
| if (isInState(STATE_DRAG)) { |
| performSelection(); |
| if (getFlag(FLAG_ENABLE_DIRECT_EDIT)) |
| performDirectEdit(); |
| if (button == 1 |
| && getSourceEditPart().getSelected() != EditPart.SELECTED_NONE) |
| getCurrentViewer().reveal(getSourceEditPart()); |
| setState(STATE_TERMINAL); |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Calls {@link #performOpen()} if the double click was with mouse button 1. |
| * |
| * @see org.eclipse.gef.tools.AbstractTool#handleDoubleClick(int) |
| */ |
| protected boolean handleDoubleClick(int button) { |
| setFlag(FLAG_ENABLE_DIRECT_EDIT, false); |
| if (button == 1) { |
| // Prevent selection from happening later on mouse up |
| setFlag(FLAG_SELECTION_PERFORMED, true); |
| performOpen(); |
| } |
| return true; |
| } |
| |
| /** |
| * @see org.eclipse.gef.tools.AbstractTool#handleDragStarted() |
| */ |
| protected boolean handleDragStarted() { |
| return stateTransition(STATE_DRAG, STATE_DRAG_IN_PROGRESS); |
| } |
| |
| /** |
| * Returns <code>true</code> if selection has already occured. |
| * |
| * @return <code>true</code> if selection has occured |
| */ |
| protected boolean hasSelectionOccurred() { |
| return getFlag(FLAG_SELECTION_PERFORMED); |
| } |
| |
| /** |
| * Calls {@link #performSelection()} if the source is not selected. If the |
| * source is selected and there are no modifier keys pressed (i.e. the user |
| * isn't selecting multiple edit parts or deselecting edit parts), sets the |
| * direct edit flag so that when the mouse is released, a direct edit will |
| * be performed. |
| */ |
| protected void performConditionalSelection() { |
| if (getSourceEditPart().getSelected() == EditPart.SELECTED_NONE) |
| performSelection(); |
| else if (getCurrentInput().getModifiers() == 0) |
| setFlag(FLAG_ENABLE_DIRECT_EDIT, true); |
| } |
| |
| /** |
| * Creates a {@link DirectEditRequest} and sends it to a |
| * DelayedDirectEditHelper to allow the user to directly edit the edit part. |
| */ |
| protected void performDirectEdit() { |
| DirectEditRequest req = new DirectEditRequest(); |
| req.setLocation(getCurrentInput().getMouseLocation()); |
| new DelayedDirectEditHelper(getSourceEditPart().getViewer(), req, |
| getSourceEditPart()); |
| } |
| |
| /** |
| * Creates a {@link SelectionRequest} and sends it to the source edit part |
| * via {@link EditPart#performRequest(Request)}. Possible uses are to open |
| * the selected item in another editor or replace the current editor's |
| * contents based on the selected item. |
| */ |
| protected void performOpen() { |
| SelectionRequest request = new SelectionRequest(); |
| request.setLocation(getLocation()); |
| request.setModifiers(getCurrentInput().getModifiers()); |
| request.setType(RequestConstants.REQ_OPEN); |
| getSourceEditPart().performRequest(request); |
| } |
| |
| /** |
| * Performs the appropriate selection action based on the selection state of |
| * the source and the modifiers (CTRL and SHIFT). If no modifier key is |
| * pressed, the source will be set as the only selection. If the CTRL key is |
| * pressed and the edit part is already selected, it will be deselected. If |
| * the CTRL key is pressed and the edit part is not selected, it will be |
| * appended to the selection set. If the SHIFT key is pressed, the source |
| * will be appended to the selection. |
| */ |
| protected void performSelection() { |
| if (hasSelectionOccurred()) |
| return; |
| setFlag(FLAG_SELECTION_PERFORMED, true); |
| EditPartViewer viewer = getCurrentViewer(); |
| List selectedObjects = viewer.getSelectedEditParts(); |
| |
| if (getCurrentInput().isModKeyDown(SWT.MOD1)) { |
| if (selectedObjects.contains(getSourceEditPart())) |
| viewer.deselect(getSourceEditPart()); |
| else |
| viewer.appendSelection(getSourceEditPart()); |
| } else if (getCurrentInput().isShiftKeyDown()) |
| viewer.appendSelection(getSourceEditPart()); |
| else |
| viewer.select(getSourceEditPart()); |
| } |
| |
| /** |
| * @see org.eclipse.gef.tools.AbstractTool#resetFlags() |
| */ |
| protected void resetFlags() { |
| super.resetFlags(); |
| setFlag(FLAG_SELECTION_PERFORMED, false); |
| setFlag(FLAG_ENABLE_DIRECT_EDIT, false); |
| } |
| |
| /** |
| * Sets the source edit part. |
| * |
| * @param part |
| * the source edit part |
| */ |
| protected void setSourceEditPart(EditPart part) { |
| this.editpart = part; |
| } |
| |
| } |