### Eclipse Workspace Patch 1.0 #P org.eclipse.gmf.runtime.diagram.ui Index: src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ContainerEditPolicy.java =================================================================== RCS file: /cvsroot/modeling/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ContainerEditPolicy.java,v retrieving revision 1.20 diff -u -r1.20 ContainerEditPolicy.java --- src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ContainerEditPolicy.java 2 Nov 2007 21:03:36 -0000 1.20 +++ src/org/eclipse/gmf/runtime/diagram/ui/editpolicies/ContainerEditPolicy.java 19 Nov 2007 21:25:04 -0000 @@ -30,6 +30,7 @@ import org.eclipse.gef.EditPart; import org.eclipse.gef.Request; import org.eclipse.gef.commands.Command; +import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gef.requests.CreateRequest; import org.eclipse.gef.requests.GroupRequest; import org.eclipse.gmf.runtime.common.core.command.CommandResult; @@ -52,11 +53,15 @@ import org.eclipse.gmf.runtime.diagram.ui.internal.commands.DuplicateViewsCommand; import org.eclipse.gmf.runtime.diagram.ui.internal.commands.PasteCommand; import org.eclipse.gmf.runtime.diagram.ui.internal.commands.RefreshEditPartCommand; +import org.eclipse.gmf.runtime.diagram.ui.internal.commands.SnapCommand; import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.ISurfaceEditPart; +import org.eclipse.gmf.runtime.diagram.ui.internal.properties.WorkspaceViewerProperties; import org.eclipse.gmf.runtime.diagram.ui.internal.requests.PasteViewRequest; import org.eclipse.gmf.runtime.diagram.ui.internal.services.layout.IInternalLayoutRunnable; import org.eclipse.gmf.runtime.diagram.ui.internal.services.layout.LayoutNode; import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages; +import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer; +import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart; import org.eclipse.gmf.runtime.diagram.ui.requests.ArrangeRequest; import org.eclipse.gmf.runtime.diagram.ui.requests.DuplicateRequest; import org.eclipse.gmf.runtime.diagram.ui.requests.EditCommandRequestWrapper; @@ -72,6 +77,9 @@ import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.Node; import org.eclipse.gmf.runtime.notation.View; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; /** * the container edit policy @@ -275,7 +283,8 @@ if ( (ActionIds.ACTION_ARRANGE_ALL.equals(request.getType())) || (ActionIds.ACTION_TOOLBAR_ARRANGE_ALL.equals(request.getType()))) { - editparts = ((IGraphicalEditPart)getHost()).getChildren(); + editparts = ((IGraphicalEditPart)getHost()).getChildren(); + request.setPartsToArrange(editparts); } if ( (ActionIds.ACTION_ARRANGE_SELECTION.equals(request.getType())) || (ActionIds.ACTION_TOOLBAR_ARRANGE_SELECTION.equals(request.getType()))) { @@ -305,23 +314,42 @@ hints.add(getHost()); IAdaptable layoutHint = new ObjectAdapter(hints); final Runnable layoutRun = layoutNodes(nodes, offsetFromBoundingBox, layoutHint); + + boolean isSnap = true; + IWorkbenchPart activePart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart(); + if (activePart != null){ + IDiagramWorkbenchPart editor = (IDiagramWorkbenchPart) activePart; + if (editor != null){ + DiagramGraphicalViewer viewer = (DiagramGraphicalViewer) editor.getDiagramGraphicalViewer(); + IPreferenceStore preferenceStore = viewer.getWorkspaceViewerPreferenceStore(); + isSnap = preferenceStore.getBoolean(WorkspaceViewerProperties.SNAPTOGRID); + } + } + + //the snapCommand still invokes proper calculations if snap to grid is turned off, this additional check + //is intended to make the code more appear more logical + + CompoundCommand cmd = new CompoundCommand(); if (layoutRun instanceof IInternalLayoutRunnable) { - return ((IInternalLayoutRunnable)layoutRun).getCommand(); + cmd.add(((IInternalLayoutRunnable) layoutRun).getCommand()); } else { TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()) - .getEditingDomain(); - - return new ICommandProxy(new AbstractTransactionalCommand(editingDomain, "", null) {//$NON-NLS-1$ + .getEditingDomain(); + cmd.add(new ICommandProxy(new AbstractTransactionalCommand(editingDomain, "", null) {//$NON-NLS-1$ protected CommandResult doExecuteWithResult( IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException { layoutRun.run(); return CommandResult.newOKCommandResult(); } - }); + })); + } + if (isSnap) { + cmd.add(getSnapCommand(request)); } + return cmd; } /** @@ -433,6 +461,24 @@ return new Point(offset, offset); } + private Command getSnapCommand(Request request){ + + List editparts = null; + if (request instanceof GroupRequest){ + editparts = ((GroupRequest)request).getEditParts(); + } + else if (request instanceof ArrangeRequest){ + editparts = ((ArrangeRequest)request).getPartsToArrange(); + } + + TransactionalEditingDomain editingDomain = ((IGraphicalEditPart) getHost()) + .getEditingDomain(); + if (editparts != null){ + return new ICommandProxy(new SnapCommand(editingDomain, editparts)); + } + return null; + } + /** * @see org.eclipse.gef.EditPolicy#getCommand(Request) */ @@ -440,8 +486,12 @@ if (request instanceof ArrangeRequest) { return getArrangeCommand((ArrangeRequest)request); + } + + if (RequestConstants.REQ_SNAP_TO_GRID.equals(request.getType())){ + return getSnapCommand(request); } - + if (RequestConstants.REQ_REFRESH.equals(request.getType())) { IGraphicalEditPart containerEP = (IGraphicalEditPart) getHost(); @@ -503,12 +553,13 @@ ActionIds.ACTION_ARRANGE_ALL.equals(request.getType()) || ActionIds.ACTION_TOOLBAR_ARRANGE_ALL.equals(request.getType()) || ActionIds.ACTION_ARRANGE_SELECTION.equals(request.getType()) - || ActionIds.ACTION_TOOLBAR_ARRANGE_SELECTION.equals(request.getType()) + || ActionIds.ACTION_TOOLBAR_ARRANGE_SELECTION.equals(request.getType()) || RequestConstants.REQ_ARRANGE_RADIAL.equals(request.getType()) || RequestConstants.REQ_ARRANGE_DEFERRED.equals(request.getType()) || RequestConstants.REQ_REFRESH.equals(request.getType()) || RequestConstants.REQ_PASTE.equals(request.getType()) || RequestConstants.REQ_DUPLICATE.equals(request.getType()) + || RequestConstants.REQ_SNAP_TO_GRID.equals(request.getType()) || ZOrderRequest.REQ_BRING_TO_FRONT.equals(request.getType()) || ZOrderRequest.REQ_BRING_FORWARD.equals(request.getType()) || ZOrderRequest.REQ_SEND_TO_BACK.equals(request.getType()) Index: src/org/eclipse/gmf/runtime/diagram/ui/l10n/DiagramUIMessages.java =================================================================== RCS file: /cvsroot/modeling/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/l10n/DiagramUIMessages.java,v retrieving revision 1.6 diff -u -r1.6 DiagramUIMessages.java --- src/org/eclipse/gmf/runtime/diagram/ui/l10n/DiagramUIMessages.java 31 Jul 2007 18:31:05 -0000 1.6 +++ src/org/eclipse/gmf/runtime/diagram/ui/l10n/DiagramUIMessages.java 19 Nov 2007 21:25:04 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2006 IBM Corporation and others. + * Copyright (c) 2000, 2007 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 @@ -232,6 +232,7 @@ public static String Command_ChangeViewProperty_ChangePropertyPattern; public static String Commands_CreateCommand_Connection_Label; public static String Command_Deferred_Layout; + public static String SnapCommand_Label; public static String Commands_SetConnectionEndsCommand_Target; public static String Commands_SetConnectionEndsCommand_Source; public static String Commands_DestroyElement; Index: src/org/eclipse/gmf/runtime/diagram/ui/l10n/DiagramUIMessages.properties =================================================================== RCS file: /cvsroot/modeling/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/l10n/DiagramUIMessages.properties,v retrieving revision 1.7 diff -u -r1.7 DiagramUIMessages.properties --- src/org/eclipse/gmf/runtime/diagram/ui/l10n/DiagramUIMessages.properties 31 Jul 2007 18:31:05 -0000 1.7 +++ src/org/eclipse/gmf/runtime/diagram/ui/l10n/DiagramUIMessages.properties 19 Nov 2007 21:25:04 -0000 @@ -313,6 +313,7 @@ Command_CreateDiagramLink=Create Diagram Link CreateCommand_Label=Create View SetLocationCommand_Label_Resize=Set Location or Size +SnapCommand_Label = Snap To Grid Command_ChangeViewProperty_ChangePropertyPattern=Change {0} Commands_CreateCommand_Connection_Label=Create Connector Command_Deferred_Layout=Deferred Layout Index: src/org/eclipse/gmf/runtime/diagram/ui/requests/RequestConstants.java =================================================================== RCS file: /cvsroot/modeling/org.eclipse.gmf/plugins/org.eclipse.gmf.runtime.diagram.ui/src/org/eclipse/gmf/runtime/diagram/ui/requests/RequestConstants.java,v retrieving revision 1.7 diff -u -r1.7 RequestConstants.java --- src/org/eclipse/gmf/runtime/diagram/ui/requests/RequestConstants.java 24 Apr 2006 17:10:40 -0000 1.7 +++ src/org/eclipse/gmf/runtime/diagram/ui/requests/RequestConstants.java 19 Nov 2007 21:25:04 -0000 @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright (c) 2002, 2004, 2006 IBM Corporation and others. + * Copyright (c) 2002, 2004, 2007 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 @@ -143,7 +143,7 @@ public static final String REQ_CHILD_PROPERTY_CHANGE = "child_property_change"; //$NON-NLS-1$ /** - * constant for show all compartments request + * constant for show all compartments request */ public static final String REQ_SHOW_ALL_COMPARTMENTS = "show_all_compartments"; //$NON-NLS-1$ @@ -151,5 +151,10 @@ * constant key for extended data in the DirectEditRequest for the initial character */ public static final String REQ_DIRECTEDIT_EXTENDEDDATA_INITIAL_CHAR = "directedit_extendeddata_initial_char"; //$NON-NLS-1$ + + /** + * constant key for snapping editpart to grid request + */ + public static final String REQ_SNAP_TO_GRID = "snap_to_grid"; //$NON-NLS-1$ } Index: src/org/eclipse/gmf/runtime/diagram/ui/internal/commands/SnapCommand.java =================================================================== RCS file: src/org/eclipse/gmf/runtime/diagram/ui/internal/commands/SnapCommand.java diff -N src/org/eclipse/gmf/runtime/diagram/ui/internal/commands/SnapCommand.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/gmf/runtime/diagram/ui/internal/commands/SnapCommand.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,156 @@ +/****************************************************************************** + * Copyright (c) 2002, 2007 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.internal.commands; + +import java.util.Iterator; +import java.util.List; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PrecisionPoint; +import org.eclipse.draw2d.geometry.PrecisionRectangle; + +import org.eclipse.emf.transaction.TransactionalEditingDomain; + +import org.eclipse.gef.SnapToHelper; +import org.eclipse.gef.commands.CompoundCommand; +import org.eclipse.gef.handles.HandleBounds; +import org.eclipse.gef.requests.ChangeBoundsRequest; +import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants; +import org.eclipse.gmf.runtime.common.core.command.CommandResult; +import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramRootEditPart; +import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart; +import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; +import org.eclipse.gmf.runtime.diagram.ui.l10n.DiagramUIMessages; +import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode; +import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; +import org.eclipse.gmf.runtime.notation.Bounds; +import org.eclipse.gmf.runtime.notation.LayoutConstraint; +import org.eclipse.gmf.runtime.notation.Node; +import org.eclipse.gmf.runtime.notation.View; + +/** + * This command is used to snap edit parts on a diagram, where the edit parts are + * passed in as the parameter. + * + * @author cli + */ +public class SnapCommand extends AbstractTransactionalCommand { + + /** the edit parts requested to be snapped to grid */ + protected List editparts; + + /** + * Constructor for SnapCommand. + * + * @param editingDomain + * the editing domain through which model changes are made + * @param editparts + * the list containing the edit parts that need to be snapped + */ + public SnapCommand(TransactionalEditingDomain editingDomain, List editparts) { + + super(editingDomain, DiagramUIMessages.SnapToGrid_textLabel, null); + this.editparts = editparts; + + } + + public List getAffectedFiles() { + if (editparts != null) { + // we only need the first child since all the edit parts being + // snapped originate from the same diagram + IGraphicalEditPart parent = (IGraphicalEditPart) editparts.get(0); + View view = (View) parent.getParent().getModel(); + return getWorkspaceFiles(view); + } + return super.getAffectedFiles(); + } + + /** + * Executes a snap command for all the desired edit parts. + * + */ + protected CommandResult doExecuteWithResult( + IProgressMonitor progressMonitor, IAdaptable info) + throws ExecutionException { + + CompoundCommand snapCommand = new CompoundCommand(); + + for (Iterator iter = editparts.iterator(); iter.hasNext();) { + IGraphicalEditPart newEditPart = (GraphicalEditPart) iter.next(); + IMapMode mapMode = ((DiagramRootEditPart) newEditPart.getRoot()).getMapMode(); + + if (newEditPart.getModel() instanceof Node) { + + LayoutConstraint constraint = ((Node) newEditPart.getModel()).getLayoutConstraint(); + if (constraint instanceof Bounds) { + + Bounds bounds = (Bounds) constraint; + ChangeBoundsRequest request = new ChangeBoundsRequest(RequestConstants.REQ_MOVE); + request.setEditParts(newEditPart); + + // translate all coordinates to device units as a standard if necessary + // this is done since moveDelta uses device units + + int xDiff = mapMode.LPtoDP(bounds.getX()) + - mapMode.LPtoDP(newEditPart.getFigure().getBounds().x); + int yDiff = mapMode.LPtoDP(bounds.getY()) + - mapMode.LPtoDP(newEditPart.getFigure().getBounds().y); + + // In the case that the figure bounds and model's layout constant are the same, + // xDiff and yDiff will evaluate to zero, but snapToHelper will still locate the closest + // NorthWest snap locations. In the case that they're not, we assume the figure's bounds + // have not been updated, so the moveDelta value will simulate a drag to the new location + // In both situations we base the resulting snap location off the figure's bounds + + // snapToGrid logic taken from DragEditPartsTracker.java + Point moveDelta = new Point(xDiff, yDiff); + request.getExtendedData().clear(); + request.setMoveDelta(moveDelta); + + PrecisionRectangle figureBounds = null; + IFigure figure = newEditPart.getFigure(); + if (figure instanceof HandleBounds) { + figureBounds = new PrecisionRectangle( + ((HandleBounds) figure).getHandleBounds()); + } else { + figureBounds = new PrecisionRectangle(figure.getBounds()); + } + + figure.translateToAbsolute(figureBounds); + + SnapToHelper snapToHelper = (SnapToHelper) newEditPart.getAdapter(SnapToHelper.class); + PrecisionRectangle baseRect = new PrecisionRectangle(figureBounds); + baseRect.translate(moveDelta); + + PrecisionPoint preciseDelta = new PrecisionPoint(moveDelta); + if (snapToHelper != null) { + snapToHelper.snapPoint(request, + PositionConstants.HORIZONTAL | PositionConstants.VERTICAL, + new PrecisionRectangle[] { baseRect }, preciseDelta); + request.setMoveDelta(preciseDelta); + } + + snapCommand.add(newEditPart.getCommand(request)); + } + } + } + + if (snapCommand != null && snapCommand.canExecute()) { + snapCommand.execute(); + } + return CommandResult.newOKCommandResult(); + } +}