| /****************************************************************************** |
| * Copyright (c) 2002, 2008 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.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.draw2d.FigureCanvas; |
| import org.eclipse.draw2d.PositionConstants; |
| import org.eclipse.draw2d.Viewport; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.gef.EditPart; |
| import org.eclipse.gef.Request; |
| import org.eclipse.gef.SharedCursors; |
| import org.eclipse.gef.commands.Command; |
| import org.eclipse.gef.commands.CompoundCommand; |
| import org.eclipse.gef.requests.ChangeBoundsRequest; |
| import org.eclipse.gef.tools.DragEditPartsTracker; |
| import org.eclipse.gef.tools.ToolUtilities; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; |
| import org.eclipse.gmf.runtime.diagram.ui.internal.ruler.SnapToHelperUtil; |
| import org.eclipse.gmf.runtime.diagram.ui.requests.DuplicateRequest; |
| import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants; |
| import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil; |
| import org.eclipse.swt.events.KeyEvent; |
| import org.eclipse.swt.graphics.Cursor; |
| import org.eclipse.swt.widgets.Control; |
| |
| /** |
| * A dervied DragEditPartsTRacker that sends REQ_DRAG instead of REQ_ORPHAN |
| * and REQ_DROP instead of REQ_ADD |
| * |
| * @author melaasar |
| */ |
| public class DragEditPartsTrackerEx extends DragEditPartsTracker { |
| |
| /** |
| * @param sourceEditPart |
| */ |
| public DragEditPartsTrackerEx(EditPart sourceEditPart) { |
| super(sourceEditPart); |
| } |
| |
| /** |
| * @see org.eclipse.gef.tools.AbstractTool#getCommand() |
| */ |
| protected Command getCommand() { |
| if (!isMove()) { |
| CompoundCommand command = new CompoundCommand(); |
| addSourceCommands(false, command); |
| if (getTargetEditPart()!=null){ |
| command.add(getTargetEditPart().getCommand(getTargetRequest())); |
| if (command.canExecute()) |
| return command; |
| } |
| |
| |
| } |
| CompoundCommand command = new CompoundCommand(); |
| addSourceCommands(true, command); |
| return command; |
| } |
| |
| /** |
| * Collects the move/drag commands from the operation set |
| * @param isMove |
| * @param command |
| */ |
| protected void addSourceCommands(boolean isMove, CompoundCommand command) { |
| Request request = getTargetRequest(); |
| |
| if (isCloneActive()) { |
| |
| // do not use operation set in this case as connections will get |
| // filtered out |
| List editparts = ToolUtilities |
| .getSelectionWithoutDependants(getCurrentViewer()); |
| |
| DuplicateRequest duplicateRequest = new DuplicateRequest(); |
| duplicateRequest.setEditParts(editparts); |
| duplicateRequest.setExtendedData(request.getExtendedData()); |
| if (request instanceof ChangeBoundsRequest) { |
| Point delta = ((ChangeBoundsRequest) request).getMoveDelta(); |
| MapModeUtil.getMapMode( |
| ((IGraphicalEditPart) getTargetEditPart()).getFigure()) |
| .DPtoLP(delta); |
| |
| duplicateRequest.setOffset(delta); |
| } |
| command.add(getTargetEditPart().getCommand(duplicateRequest)); |
| } else { |
| request.setType(isMove ? REQ_MOVE |
| : RequestConstants.REQ_DRAG); |
| Iterator iter = getOperationSet().iterator(); |
| while (iter.hasNext()) { |
| EditPart editPart = (EditPart) iter.next(); |
| command.add(editPart.getCommand(request)); |
| } |
| } |
| |
| request.setType(RequestConstants.REQ_DROP); |
| } |
| |
| /** |
| * @see org.eclipse.gef.tools.AbstractTool#getCommandName() |
| */ |
| protected String getCommandName() { |
| if (!isMove()) |
| return RequestConstants.REQ_DROP; |
| return super.getCommandName(); |
| } |
| |
| /** |
| * If the source is not in the operation set, it is not a move |
| * @see org.eclipse.gef.tool s.DragEditPartsTracker#isMove() |
| */ |
| protected boolean isMove() { |
| for (int i = 0 ; i < getOperationSet().size(); i++){ |
| if (getOperationSet().get(i).equals(getSourceEditPart())){ |
| return super.isMove(); |
| } |
| //additional case for GroupEditPart, check the children |
| //this is for snap to geometry |
| if (getOperationSet().get(i) instanceof GroupEditPart){ |
| GroupEditPart currPart = (GroupEditPart)getOperationSet().get(i); |
| for (int j = 0 ; j < currPart.getChildren().size() ; j++){ |
| if (currPart.getChildren().get(j).equals(getSourceEditPart())){ |
| return super.isMove(); |
| } |
| } |
| } |
| } |
| return false; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.gef.tools.AbstractTool#executeCurrentCommand() |
| */ |
| protected void executeCurrentCommand() { |
| super.executeCurrentCommand(); |
| if (isActive()) { |
| if (getOperationSet().size() > 0) { |
| if (getOperationSet().get(0) instanceof IGraphicalEditPart) { |
| IGraphicalEditPart editpart = (IGraphicalEditPart) getOperationSet() |
| .get(0); |
| if ((editpart.getFigure() == null) |
| || (editpart.getFigure().getParent() == null) |
| || (editpart.getFigure().getParent().getLayoutManager() == null)) |
| return; |
| editpart.getFigure().getParent().getLayoutManager().layout( |
| editpart.getFigure().getParent()); |
| reveal(editpart); |
| } |
| } |
| } |
| } |
| |
| /** |
| * @param editpart |
| */ |
| protected void reveal(EditPart editpart){ |
| editpart.getViewer().reveal(editpart); |
| } |
| |
| protected boolean handleDragInProgress() { |
| boolean returnValue = super.handleDragInProgress(); |
| if (isInState(STATE_DRAG_IN_PROGRESS) |
| || isInState(STATE_ACCESSIBLE_DRAG_IN_PROGRESS)) { |
| |
| // Expose the diagram as the user scrolls in the area handled by the |
| // autoexpose helper. |
| updateAutoexposeHelper(); |
| } |
| return returnValue; |
| } |
| |
| protected Cursor calculateCursor() { |
| if (isInState(STATE_DRAG_IN_PROGRESS) |
| || isInState(STATE_ACCESSIBLE_DRAG_IN_PROGRESS)) { |
| |
| // Give some feedback so the user knows the area where autoscrolling |
| // will occur. |
| if (getAutoexposeHelper() != null) { |
| return SharedCursors.HAND; |
| } else { |
| |
| // Give some feedback so the user knows that they can't drag |
| // outside the viewport. |
| Control control = getCurrentViewer().getControl(); |
| if (control instanceof FigureCanvas) { |
| Viewport viewport = ((FigureCanvas) control).getViewport(); |
| Rectangle rect = Rectangle.SINGLETON; |
| viewport.getClientArea(rect); |
| viewport.translateToParent(rect); |
| viewport.translateToAbsolute(rect); |
| |
| if (!rect.contains(getLocation())) { |
| return getDisabledCursor(); |
| } |
| } |
| } |
| } |
| return super.calculateCursor(); |
| } |
| |
| protected boolean handleButtonDown(int button) { |
| |
| // If the group is selected, and the user clicks on a shape, defer the |
| // selection of the shape until the mouse button is released instead of |
| // selecting on mouse down because if the user does a drag they will |
| // move the entire group and not the shape. |
| if (button == 1 |
| && getSourceEditPart().getParent() instanceof GroupEditPart |
| && getSourceEditPart().getParent().getSelected() != EditPart.SELECTED_NONE) { |
| |
| stateTransition(STATE_INITIAL, STATE_DRAG); |
| return true; |
| } |
| |
| return super.handleButtonDown(button); |
| } |
| |
| protected boolean handleDoubleClick(int button) { |
| // If the user double-clicks a shape in a group and the shape is not |
| // selected, select the shape. |
| if (getSourceEditPart().getParent() instanceof GroupEditPart |
| && getSourceEditPart().getSelected() == EditPart.SELECTED_NONE) { |
| performSelection(); |
| return true; |
| } else { |
| return super.handleDoubleClick(button); |
| } |
| } |
| |
| protected void performSelection() { |
| super.performSelection(); |
| |
| // If the new selection is a child of a group, we want to deselect the group. |
| if (getSourceEditPart().getParent() instanceof GroupEditPart |
| && getSourceEditPart().getParent().getSelected() != EditPart.SELECTED_NONE) { |
| getCurrentViewer().deselect(getSourceEditPart().getParent()); |
| } |
| } |
| |
| /** |
| * Overridden to add extended data to the request to restrict snapping to |
| * specific directions based on the move delta. |
| */ |
| protected void snapPoint(ChangeBoundsRequest request) { |
| Point moveDelta = request.getMoveDelta(); |
| if (getState() == STATE_ACCESSIBLE_DRAG_IN_PROGRESS) { |
| int restrictedDirection = 0; |
| |
| if (moveDelta.x > 0) { |
| restrictedDirection = restrictedDirection |
| | PositionConstants.EAST; |
| } else if (moveDelta.x < 0) { |
| restrictedDirection = restrictedDirection |
| | PositionConstants.WEST; |
| } |
| |
| if (moveDelta.y > 0) { |
| restrictedDirection = restrictedDirection |
| | PositionConstants.SOUTH; |
| } else if (moveDelta.y < 0) { |
| restrictedDirection = restrictedDirection |
| | PositionConstants.NORTH; |
| } |
| |
| request.getExtendedData().put(SnapToHelperUtil.RESTRICTED_DIRECTIONS, |
| restrictedDirection); |
| } |
| |
| super.snapPoint(request); |
| } |
| |
| protected boolean handleKeyDown(KeyEvent e) { |
| if (acceptArrowKey(e)) { |
| if (isInState(STATE_INITIAL)) { |
| IGraphicalEditPart ep = (IGraphicalEditPart) getSourceEditPart(); |
| if (ep != null) { |
| Point location = ep.getFigure().getBounds().getCenter(); |
| ep.getFigure().translateToAbsolute(location); |
| placeMouseInViewer(location); |
| getCurrentInput().setMouseLocation(location.x, location.y); |
| } |
| } |
| } |
| return super.handleKeyDown(e); |
| } |
| |
| } |