blob: e108d8e553a729e8d8500df1026da77d0609920d [file] [log] [blame]
/*******************************************************************************
* 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());
}
}