/******************************************************************************* * Copyright (c) 2004, 2005 Sybase, Inc. 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: * Sybase, Inc. - initial API and implementation *******************************************************************************/ package org.eclipse.jst.jsf.facesconfig.ui.pageflow.action; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.PrecisionRectangle; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.gef.EditPart; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.Request; import org.eclipse.gef.RequestConstants; import org.eclipse.gef.commands.Command; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gef.requests.AlignmentRequest; import org.eclipse.gef.tools.ToolUtilities; import org.eclipse.gef.ui.actions.GEFActionConstants; import org.eclipse.gef.ui.actions.SelectionAction; import org.eclipse.jst.jsf.facesconfig.ui.EditorMessages; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; /** * An improved alignment action to align the selected parts in different action. * * @author xgzhang * @version original version is from GEF */ public final class AlignmentAction extends SelectionAction { /** * Indicates that the bottom edges should be aligned. */ public static final String ID_ALIGN_BOTTOM = GEFActionConstants.ALIGN_BOTTOM; /** * Indicates that the horizontal centers should be aligned. */ public static final String ID_ALIGN_CENTER = GEFActionConstants.ALIGN_CENTER; /** * Indicates that the left edges should be aligned. */ public static final String ID_ALIGN_LEFT = GEFActionConstants.ALIGN_LEFT; /** * Indicates that the vertical midpoints should be aligned. */ public static final String ID_ALIGN_MIDDLE = GEFActionConstants.ALIGN_MIDDLE; /** * Indicates that the right edges should be aligned. */ public static final String ID_ALIGN_RIGHT = GEFActionConstants.ALIGN_RIGHT; /** * Indicates that the top edges should be aligned. */ public static final String ID_ALIGN_TOP = GEFActionConstants.ALIGN_TOP; private int alignment; private List operationSet; /** * @deprecated use AlignmentAction(IWorkbenchPart, int align) * @param editor * the editor * @param align * the alignment ID */ public AlignmentAction(IEditorPart editor, int align) { this((IWorkbenchPart) editor, align); } /** * Constructs an AlignmentAction with the given part and alignment ID. The * alignment ID must by one of: * <UL> * <LI>GEFActionConstants.ALIGN_LEFT * <LI>GEFActionConstants.ALIGN_RIGHT * <LI>GEFActionConstants.ALIGN_CENTER * <LI>GEFActionConstants.ALIGN_TOP * <LI>GEFActionConstants.ALIGN_BOTTOM * <LI>GEFActionConstants.ALIGN_MIDDLE * </UL> * * @param part * the workbench part used to obtain context * @param align * the aligment ID. */ public AlignmentAction(IWorkbenchPart part, int align) { super(part); alignment = align; initUI(); } /** * Returns the alignment rectangle to which all selected parts should be * aligned. * * @param request * the alignment Request * @return the alignment rectangle */ protected Rectangle calculateAlignmentRectangle(Request request) { List editparts = getOperationSet(request); if (editparts == null || editparts.isEmpty()) { return null; } GraphicalEditPart part = null; if (alignment == PositionConstants.MIDDLE || alignment == PositionConstants.CENTER) { part = (GraphicalEditPart) editparts.get(editparts.size() - 1); } else { part = getFitnessPart(editparts); } Rectangle rect = new PrecisionRectangle(part.getFigure().getBounds()); part.getFigure().translateToAbsolute(rect); return rect; } /** * get the Fitness part in the four kinds of alignment directions * * @param editparts */ private GraphicalEditPart getFitnessPart(List editparts) { if (alignment == PositionConstants.MIDDLE || alignment == PositionConstants.CENTER) { return null; } int positionComparor = Integer.MAX_VALUE; if (alignment == PositionConstants.LEFT || alignment == PositionConstants.TOP) { positionComparor = Integer.MAX_VALUE; } else if (alignment == PositionConstants.RIGHT || alignment == PositionConstants.BOTTOM) { positionComparor = Integer.MIN_VALUE; } GraphicalEditPart fitnessPart = null; for (Iterator iter = editparts.iterator(); iter.hasNext();) { GraphicalEditPart part = (GraphicalEditPart) iter.next(); Rectangle rectPart = part.getFigure().getBounds(); switch (alignment) { case PositionConstants.LEFT: if (rectPart.getLeft().x < positionComparor) { fitnessPart = part; positionComparor = rectPart.getLeft().x; } break; case PositionConstants.RIGHT: if (rectPart.getRight().x > positionComparor) { fitnessPart = part; positionComparor = rectPart.getRight().x; } break; case PositionConstants.TOP: if (rectPart.getTop().y < positionComparor) { fitnessPart = part; positionComparor = rectPart.getTop().y; } break; case PositionConstants.BOTTOM: if (rectPart.getBottom().y > positionComparor) { fitnessPart = part; positionComparor = rectPart.getBottom().y; } break; } } return fitnessPart; } /** * @see org.eclipse.gef.ui.actions.WorkbenchPartAction#calculateEnabled() */ protected boolean calculateEnabled() { operationSet = null; Command cmd = createAlignmentCommand(); if (cmd == null) { return false; } return cmd.canExecute(); } private Command createAlignmentCommand() { AlignmentRequest request = new AlignmentRequest( RequestConstants.REQ_ALIGN); request.setAlignmentRectangle(calculateAlignmentRectangle(request)); request.setAlignment(alignment); List editparts = getOperationSet(request); if (editparts.size() < 2) { return null; } CompoundCommand command = new CompoundCommand(); command.setDebugLabel(getText()); for (int i = 0; i < editparts.size(); i++) { EditPart editpart = (EditPart) editparts.get(i); command.add(editpart.getCommand(request)); } return command; } /** * @see org.eclipse.gef.Disposable#dispose() */ public void dispose() { operationSet = Collections.EMPTY_LIST; super.dispose(); } /** * Returns the list of editparts which will participate in alignment. * * @param request * the alignment request * @return the list of parts which will be aligned */ protected List getOperationSet(Request request) { if (operationSet != null) { return operationSet; } List editparts = new ArrayList(getSelectedObjects()); if (editparts.isEmpty() || !(editparts.get(0) instanceof GraphicalEditPart)) { return Collections.EMPTY_LIST; } Object primary = editparts.get(editparts.size() - 1); editparts = ToolUtilities.getSelectionWithoutDependants(editparts); ToolUtilities.filterEditPartsUnderstanding(editparts, request); if (editparts.size() < 2 || !editparts.contains(primary)) { return Collections.EMPTY_LIST; } EditPart parent = ((EditPart) editparts.get(0)).getParent(); for (int i = 1; i < editparts.size(); i++) { EditPart part = (EditPart) editparts.get(i); if (part.getParent() != parent) { return Collections.EMPTY_LIST; } } return editparts; } /** * Initializes the actions UI presentation. */ protected void initUI() { switch (alignment) { case PositionConstants.LEFT: setId(GEFActionConstants.ALIGN_LEFT); setText(EditorMessages.AlignmentAction_AlignLeftAction_Label); setToolTipText(EditorMessages.AlignmentAction_AlignLeftAction_Tooltip); setImageDescriptor(InternalImages.DESC_HORZ_ALIGN_LEFT); setDisabledImageDescriptor(InternalImages.DESC_HORZ_ALIGN_LEFT_DIS); break; case PositionConstants.RIGHT: setId(GEFActionConstants.ALIGN_RIGHT); setText(EditorMessages.AlignmentAction_AlignRightAction_Label); setToolTipText(EditorMessages.AlignmentAction_AlignRightAction_Tooltip); setImageDescriptor(InternalImages.DESC_HORZ_ALIGN_RIGHT); setDisabledImageDescriptor(InternalImages.DESC_HORZ_ALIGN_RIGHT_DIS); break; case PositionConstants.TOP: setId(GEFActionConstants.ALIGN_TOP); setText(EditorMessages.AlignmentAction_AlignTopAction_Label); setToolTipText(EditorMessages.AlignmentAction_AlignTopAction_Tooltip); setImageDescriptor(InternalImages.DESC_VERT_ALIGN_TOP); setDisabledImageDescriptor(InternalImages.DESC_VERT_ALIGN_TOP_DIS); break; case PositionConstants.BOTTOM: setId(GEFActionConstants.ALIGN_BOTTOM); setText(EditorMessages.AlignmentAction_AlignBottomAction_Label); setToolTipText(EditorMessages.AlignmentAction_AlignBottomAction_Tooltip); setImageDescriptor(InternalImages.DESC_VERT_ALIGN_BOTTOM); setDisabledImageDescriptor(InternalImages.DESC_VERT_ALIGN_BOTTOM_DIS); break; case PositionConstants.CENTER: setId(GEFActionConstants.ALIGN_CENTER); setText(EditorMessages.AlignmentAction_AlignCenterAction_Label); setToolTipText(EditorMessages.AlignmentAction_AlignCenterAction_Tooltip); setImageDescriptor(InternalImages.DESC_HORZ_ALIGN_CENTER); setDisabledImageDescriptor(InternalImages.DESC_HORZ_ALIGN_CENTER_DIS); break; case PositionConstants.MIDDLE: setId(GEFActionConstants.ALIGN_MIDDLE); setText(EditorMessages.AlignmentAction_AlignMiddleAction_Label); setToolTipText(EditorMessages.AlignmentAction_AlignMiddleAction_Tooltip); setImageDescriptor(InternalImages.DESC_VERT_ALIGN_MIDDLE); setDisabledImageDescriptor(InternalImages.DESC_VERT_ALIGN_MIDDLE_DIS); break; } } /** * @see org.eclipse.jface.action.IAction#run() */ public void run() { operationSet = null; execute(createAlignmentCommand()); } }