/******************************************************************************* * 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 * Exadel, Inc. * Red Hat, Inc. *******************************************************************************/package org.jboss.tools.common.gef.alignment.xpl; import java.util.List; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.draw2d.geometry.PrecisionDimension; import org.eclipse.draw2d.geometry.PrecisionRectangle; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.RequestConstants; import org.eclipse.gef.commands.Command; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gef.internal.GEFMessages; import org.eclipse.gef.internal.InternalImages; import org.eclipse.gef.requests.ChangeBoundsRequest; import org.eclipse.gef.ui.actions.GEFActionConstants; import org.eclipse.gef.ui.actions.SelectionAction; import org.jboss.tools.common.gef.action.IDiagramSelectionProvider; /** * An action that matches the width of all selected EditPart's Figures to the * width of the Primary Selection EditPart's Figure. */ public abstract class DefaultMatchWidthAction extends SelectionAction { /** * Constructs a <code>MatchWidthAction</code> and associates it with the given * part. * * @param part * The workbench part associated with this MatchWidthAction */ public DefaultMatchWidthAction(IWorkbenchPart part) { super(part); setText(GEFMessages.MatchWidthAction_Label); setHoverImageDescriptor(InternalImages.DESC_MATCH_WIDTH); setDisabledImageDescriptor(InternalImages.DESC_MATCH_WIDTH_DIS); setToolTipText(GEFMessages.MatchWidthAction_Tooltip); setId(GEFActionConstants.MATCH_WIDTH); } /** * @see org.eclipse.gef.ui.actions.WorkbenchPartAction#calculateEnabled() */ protected boolean calculateEnabled() { Command cmd = createMatchSizeCommand(getSelectedObjects()); if (cmd == null) return false; return cmd.canExecute(); } /** * Create a command to resize the selected objects. * * @param objects * The objects to be resized. * @return The command to resize the selected objects. */ private Command createMatchSizeCommand(List objects) { if (objects.isEmpty()) return null; if (!(objects.get(0) instanceof GraphicalEditPart)) return null; GraphicalEditPart primarySelection = getPrimarySelectionEditPart(getSelectedObjects()); if (primarySelection == null) return null; GraphicalEditPart part = null; ChangeBoundsRequest request = null; PrecisionDimension preciseDimension = null; PrecisionRectangle precisePartBounds = null; Command cmd = null; CompoundCommand command = new CompoundCommand(); PrecisionRectangle precisePrimaryBounds = new PrecisionRectangle(primarySelection .getFigure().getBounds().getCopy()); primarySelection.getFigure().translateToAbsolute(precisePrimaryBounds); for (int i = 0; i < objects.size(); i++) { part = (GraphicalEditPart)objects.get(i); if (!part.equals(primarySelection)) { request = new ChangeBoundsRequest(RequestConstants.REQ_RESIZE); precisePartBounds = new PrecisionRectangle(part.getFigure().getBounds().getCopy()); part.getFigure().translateToAbsolute(precisePartBounds); preciseDimension = new PrecisionDimension(); preciseDimension.preciseWidth = getPreciseWidthDelta(precisePartBounds, precisePrimaryBounds); preciseDimension.preciseHeight = getPreciseHeightDelta(precisePartBounds, precisePrimaryBounds); preciseDimension.updateInts(); request.setSizeDelta(preciseDimension); cmd = part.getCommand(request); if (cmd != null) command.add(cmd); } } return command; } /** * Returns the height delta between the two bounds. Separated into a method so * that it can be overriden to return 0 in the case of a width-only action. * * @param precisePartBounds * the precise bounds of the EditPart's Figure to be matched * @param precisePrimaryBounds * the precise bounds of the Primary Selection EditPart's Figure * @return the delta between the two heights to be used in the Request. */ protected double getPreciseHeightDelta(PrecisionRectangle precisePartBounds, PrecisionRectangle precisePrimaryBounds) { return precisePrimaryBounds.preciseHeight - precisePartBounds.preciseHeight; } private GraphicalEditPart getPrimarySelectionEditPart(List editParts) { GraphicalEditPart part = null; for (int i = 0; i < editParts.size(); i++) { part = (GraphicalEditPart)editParts.get(i); if (part.getSelected() == EditPart.SELECTED_PRIMARY) return part; } return null; } /** * Returns the width delta between the two bounds. Separated into a method so * that it can be overriden to return 0 in the case of a height-only action. * * @param precisePartBounds * the precise bounds of the EditPart's Figure to be matched * @param precisePrimaryBounds * the precise bounds of the Primary Selection EditPart's Figure * @return the delta between the two widths to be used in the Request. */ protected double getPreciseWidthDelta(PrecisionRectangle precisePartBounds, PrecisionRectangle precisePrimaryBounds) { return precisePrimaryBounds.preciseWidth - precisePartBounds.preciseWidth; } /** * Executes this action, cycling through the selected EditParts in the Action's * viewer, and matching the size of the selected EditPart's Figures to that of * the Primary Selection's Figure. */ public void run() { execute(createMatchSizeCommand(getSelectedObjects())); } public abstract void update(); }