/******************************************************************************* * Copyright (c) 2000, 2010, 2012 IBM Corporation, Gerhardt Informatics Kft. 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 * Gerhardt Informatics Kft. - GEFGWT port *******************************************************************************/ package org.eclipse.gef.ui.actions; import java.util.List; 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.ui.IWorkbenchPart; /** * An action that matches the size of all selected EditPart's Figures to the * size of the Primary Selection EditPart's Figure. * * @since 3.7 */ public class MatchSizeAction extends SelectionAction { /** * Constructs a <code>MatchSizeAction</code> and associates it with the * given part. * * @param part * The workbench part associated with this MatchSizeAction */ public MatchSizeAction(IWorkbenchPart part) { super(part); setText(GEFMessages.MatchSizeAction_Label); setImageDescriptor(InternalImages.DESC_MATCH_SIZE); setDisabledImageDescriptor(InternalImages.DESC_MATCH_SIZE_DIS); setToolTipText(GEFMessages.MatchSizeAction_Tooltip); setId(GEFActionConstants.MATCH_SIZE); } /** * @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.setPreciseWidth(getPreciseWidthDelta( precisePartBounds, precisePrimaryBounds)); preciseDimension.setPreciseHeight(getPreciseHeightDelta( precisePartBounds, precisePrimaryBounds)); 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 overwritten 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())); } }