/****************************************************************************** * Copyright (c) 2002, 2010 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.actions.internal; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.draw2d.Animation; import org.eclipse.gef.ConnectionEditPart; 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.tools.ToolUtilities; import org.eclipse.gmf.runtime.diagram.ui.actions.ActionIds; import org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction; import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsMessages; import org.eclipse.gmf.runtime.diagram.ui.actions.internal.l10n.DiagramUIActionsPluginImages; import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeCompartmentEditPart; import org.eclipse.gmf.runtime.diagram.ui.preferences.IPreferenceConstants; import org.eclipse.gmf.runtime.diagram.ui.requests.ArrangeRequest; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.ui.IWorkbenchPage; /** * The Arrange Action: arranges a container editpart or a set of selected editparts * * @author melaasar */ public class ArrangeAction extends DiagramAction { private boolean selectionOnly; /** * @param workbenchPage */ protected ArrangeAction( IWorkbenchPage workbenchPage, boolean selectionOnly) { super(workbenchPage); this.selectionOnly = selectionOnly; } /* (non-Javadoc) * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#createTargetRequest() */ protected Request createTargetRequest() { return new ArrangeRequest(getId()); } /* (non-Javadoc) * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#updateTargetRequest() */ protected void updateTargetRequest() { ArrangeRequest request = (ArrangeRequest) getTargetRequest(); request.setPartsToArrange(getOperationSet()); } private boolean isArrangeAll() { return !selectionOnly; } protected Command getCommand() { List operationSet = getOperationSet(); if (operationSet.isEmpty()) { return null; } CompoundCommand arrangeCC = new CompoundCommand(getLabel()); if (isArrangeAll()) { for (Iterator iter = operationSet.iterator(); iter.hasNext();) { EditPart element = (EditPart) iter.next(); Command cmd = element.getCommand(getTargetRequest()); if (cmd != null) arrangeCC.add(cmd); } } else { EditPart targetEP = getTargetEditPartForArrangeSelection(operationSet); if (targetEP != null) { Command cmd = targetEP.getCommand(getTargetRequest()); if (cmd != null) arrangeCC.add(cmd); } } return arrangeCC; } private EditPart getTargetEditPartForArrangeSelection(List editparts) { if (editparts.size() == 1) { // If there is only one editpart selected, then the Arrange // Selected request gets sent to this editpart's target editpart to // allow clients to do as they wish. return ((EditPart) editparts.get(0)) .getTargetEditPart(getTargetRequest()); } else { // If there is more than one editpart selected, then the Arrange // Selected request gets sent to the common parent. EditPart parentEP = getSelectionParent(editparts); if (parentEP == null) return null; for (int i = 1; i < editparts.size(); i++) { EditPart part = (EditPart) editparts.get(i); if (part instanceof ConnectionEditPart) { continue; } // if there is no common parent, then Arrange Selected isn't // supported. if (part.getParent() != parentEP) return null; } return parentEP; } } /* * The operation set is the shapes, connections or both on the diagrm edit part * (non-Javadoc) * @see org.eclipse.gmf.runtime.diagram.ui.actions.DiagramAction#createOperationSet() */ protected List createOperationSet() { List selection = getSelectedObjects(); if (isArrangeAll()) { if (!selection.isEmpty()) { return createOperationSetForArrangeAll(selection); } if (getDiagramEditPart() != null) { return getDiagramEditPart().getChildren(); } return Collections.EMPTY_LIST; } else { // this is the case of Arrange Selection if (selection.isEmpty() || !(selection.get(0) instanceof IGraphicalEditPart)) return Collections.EMPTY_LIST; selection = ToolUtilities.getSelectionWithoutDependants(selection); return selection; } } /** * getSelectionParent Utility to return the logical parent of the selection * list * * @param editparts * List to parse for a common parent. * @return EditPart that is the parent or null if a common parent doesn't * exist. */ private EditPart getSelectionParent(List editparts) { ListIterator li = editparts.listIterator(); while (li.hasNext()) { Object obj = li.next(); if (!(obj instanceof ConnectionEditPart) && obj instanceof EditPart) { return ((EditPart)obj).getParent(); } } return null; } /* (non-Javadoc) * @see org.eclipse.gmf.runtime.common.ui.action.AbstractActionHandler#isSelectionListener() */ protected boolean isSelectionListener() { return true; } /** * Creates the Arrange All action * @param workbenchPage */ public static ArrangeAction createArrangeAllAction(IWorkbenchPage workbenchPage) { ArrangeAction action = new ArrangeAction(workbenchPage,false); action.setId(ActionIds.ACTION_ARRANGE_ALL); action.setText(DiagramUIActionsMessages.ArrangeAction_ArrangeAll_ActionLabelText); action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_ArrangeAll_ActionToolTipText); action .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL); action .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL_DISABLED); action .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL); return action; } /** * Creates the Arrange All action for the toolbar menu * @param workbenchPage */ public static ArrangeAction createToolbarArrangeAllAction(IWorkbenchPage workbenchPage) { ArrangeAction action = new ArrangeAction(workbenchPage, false); action.setId(ActionIds.ACTION_TOOLBAR_ARRANGE_ALL); action.setText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeAll_ActionLabelText); action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeAll_ActionToolTipText); action .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL); action .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL_DISABLED); action .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_ALL); return action; } /** * Creates the Arrange Selection Only action * @param workbenchPage */ public static ArrangeAction createArrangeSelectionAction(IWorkbenchPage workbenchPage) { ArrangeAction action = new ArrangeAction(workbenchPage, true); action.setId(ActionIds.ACTION_ARRANGE_SELECTION); action.setText(DiagramUIActionsMessages.ArrangeAction_ArrangeSelection_ActionLabelText); action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_ArrangeSelection_ActionToolTipText); action .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED); action .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED_DISABLED); action .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED); return action; } /** * Creates the Arrange Selection Only action for the toolbar menu * @param workbenchPage */ public static ArrangeAction createToolbarArrangeSelectionAction(IWorkbenchPage workbenchPage) { ArrangeAction action = new ArrangeAction(workbenchPage, true); action.setId(ActionIds.ACTION_TOOLBAR_ARRANGE_SELECTION); action.setText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeSelection_ActionLabelText); action.setToolTipText(DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeSelection_ActionToolTipText); action .setImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED); action .setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED_DISABLED); action .setHoverImageDescriptor(DiagramUIActionsPluginImages.DESC_ARRANGE_SELECTED); return action; } protected void doRun(IProgressMonitor progressMonitor) { IPreferenceStore preferenceStore = (IPreferenceStore) getDiagramEditPart().getDiagramPreferencesHint().getPreferenceStore(); boolean animatedLayout = preferenceStore.getBoolean( IPreferenceConstants.PREF_ENABLE_ANIMATED_LAYOUT); if (animatedLayout) Animation.markBegin(); super.doRun(progressMonitor); if (animatedLayout) { int durationInc = 800; int factor = 10; int size = 0; List operationSet = getOperationSet(); if (isArrangeAll()){ for (Iterator iter = operationSet.iterator(); iter.hasNext();) { IGraphicalEditPart element = (IGraphicalEditPart) iter.next(); size += element.getFigure().getChildren().size(); } } else if (operationSet != null && !operationSet.isEmpty()) { IGraphicalEditPart container = (IGraphicalEditPart)getSelectionParent(operationSet); size += container.getFigure().getChildren().size(); } int totalDuration = Math.min(durationInc * factor / 2, Math.max(durationInc, (size / factor) * durationInc)); Animation.run(totalDuration); } } /** * @param selection * @return */ private List createOperationSetForArrangeAll(List selection) { Set parentsSet = new HashSet(); for (Iterator iter = selection.iterator(); iter.hasNext();) { Object element = iter.next(); if (element instanceof ShapeCompartmentEditPart || element instanceof DiagramEditPart){ parentsSet.add(element); } else if (element instanceof EditPart){ EditPart gEditPart = (EditPart)element; EditPart parentEditPart = gEditPart.getParent(); if (parentEditPart instanceof ShapeCompartmentEditPart || parentEditPart instanceof DiagramEditPart){ if (!parentsSet.contains(parentEditPart)) parentsSet.add(parentEditPart); } } } if (parentsSet.isEmpty()) return Collections.EMPTY_LIST; List elements = new ArrayList(); elements.addAll(parentsSet); return elements; } public String getLabel() { return isArrangeAll() ? DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeAll_ActionLabelText : DiagramUIActionsMessages.ArrangeAction_toolbar_ArrangeSelection_ActionLabelText; } }