blob: ca2485cb2cc5f1241bf0fa07449df7a494c0c7e5 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2007 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.gef.ConnectionEditPart;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.Request;
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.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart;
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.IPrimaryEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.editparts.ISurfaceEditPart;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.actions.ActionFactory;
/**
*
* @author melaasar
*
*/
public class SelectAllAction extends DiagramAction {
/** whether to select shapes */
private boolean selectShapes;
/** whether to select connections */
private boolean selectConnections;
/**
* @param partService
* @param selectShapes
* @param selectConnections
*/
private SelectAllAction(
IWorkbenchPage partService,
boolean selectShapes,
boolean selectConnections) {
super(partService);
this.selectShapes = selectShapes;
this.selectConnections = selectConnections;
}
protected Request createTargetRequest() {
return null;
}
/**
* The operation set is the shapes, connections or both on the diagrm edit part
*/
protected List createOperationSet() {
List selection = getSelectedObjects();
if (selection.isEmpty() || !(selection.get(0) instanceof IGraphicalEditPart))
return Collections.EMPTY_LIST;
List selectables = new ArrayList();
EditPart primaryEP = (EditPart) selection.get(selection.size() - 1);
List nodeEditParts = new ArrayList();
nodeEditParts.addAll(getSelectableNodes(primaryEP));
if (selectShapes)
selectables.addAll(nodeEditParts);
if (selectConnections)
selectables.addAll(addSelectableConnections(nodeEditParts));
return filterEditPartsMatching(selectables, getSelectionConditional());
}
/**
* Determines the candidate list of node editparts for selection
*
* @param editpart
* @return
*/
protected List getSelectableNodes(EditPart editpart) {
if (editpart == null) {
return Collections.EMPTY_LIST;
}
List retval = new ArrayList();
getSelectableNodesInside(editpart, true, retval);
return retval;
}
/**
* Determines the candidate list of node editparts for selection
*
* @param editpart
* @param topLevel <code>boolean</code> is this the initial entry point into the recursive method.
* @param retval <code>List</code> to modify
*/
private void getSelectableNodesInside(EditPart editpart, boolean topLevel, List retval) {
if ( editpart instanceof ISurfaceEditPart) {
getSelectableChildrenNodes(editpart, retval);
}
else if (editpart instanceof IPrimaryEditPart) {
if (topLevel) {
if (editpart instanceof ConnectionEditPart) {
ConnectionEditPart connection = (ConnectionEditPart) editpart;
EditPart source = connection.getSource();
EditPart target = connection.getTarget();
if (source != null && target != null) {
getSelectableNodesInside(source, true, retval);
if (target.getParent() != source.getParent())
getSelectableNodesInside(target, true, retval);
}
}
else
getSelectableNodesInside(editpart.getParent(), true, retval);
}
else {
if (editpart.isSelectable())
retval.add(editpart);
// Do not dig into groups -- just select the group, but not the
// shapes inside.
if (!(editpart instanceof GroupEditPart)) {
getSelectableChildrenNodes(editpart, retval);
}
}
}
}
private void getSelectableChildrenNodes(EditPart editpart, List retval) {
Iterator iter = editpart.getChildren().iterator();
while( iter.hasNext() ) {
EditPart child = (EditPart)iter.next();
getSelectableNodesInside(child, false, retval);
}
}
/**
* This method searches an edit part for a child that is a border item edit part
* @param parent part needed to search
* @param set to be modified of border item edit parts that are direct children of the parent
*/
private void getBorderItemEditParts(EditPart parent, Set retval) {
Iterator iter = parent.getChildren().iterator();
while(iter.hasNext()) {
EditPart child = (EditPart)iter.next();
if( child instanceof IBorderItemEditPart ) {
retval.add(child);
retval.addAll(child.getChildren());
}
getBorderItemEditParts(child, retval);
}
}
/**
* Determines the candidate list of connection edit for selection
* A connection is included if atleast the source or the target is
* included in the given list
*
* @param editparts
*/
protected List addSelectableConnections(List editparts) {
List selectableConnections = new ArrayList();
DiagramEditPart diagramEditPart = getDiagramEditPart();
Set connnectableEditParts = new HashSet(editparts);
ListIterator li = editparts.listIterator();
while (li.hasNext()) {
EditPart ep = (EditPart)li.next();
getBorderItemEditParts(ep, connnectableEditParts);
if (ep instanceof GroupEditPart) {
connnectableEditParts.addAll(((GroupEditPart)ep).getShapeChildren());
}
}
if (diagramEditPart != null) {
Iterator connections = diagramEditPart.getConnections().iterator();
while (connections.hasNext()) {
ConnectionEditPart connection =
(ConnectionEditPart) connections.next();
if (canSelectConnection(connection, connnectableEditParts))
selectableConnections.add(connection);
}
}
return selectableConnections;
}
/**
* Determines whether the given connection can be selected. First checks
* whether the source or target of the connection is in the given
* connetableEditPart list. If it isn't it checks recursively whether the source
* or target of the connection is another connection and if that connection's
* source or target is in the given connectableEditPart list. This is in
* response to Bugzilla #162083.
*
* @param connection connection to check
* @param connectableEditParts
*/
private boolean canSelectConnection(ConnectionEditPart connection, Set connectableEditParts)
{
EditPart connectionSource = connection.getSource();
EditPart connectionTarget = connection.getTarget();
boolean sourceHasSelectable = false;
boolean targetHasSelectable = false;
if (connectableEditParts.contains(connectionSource)
|| connectableEditParts.contains(connectionTarget))
return true;
if (connectionSource instanceof ConnectionEditPart)
sourceHasSelectable = canSelectConnection((ConnectionEditPart)connectionSource, connectableEditParts);
if (!sourceHasSelectable && connectionTarget instanceof ConnectionEditPart)
targetHasSelectable = canSelectConnection((ConnectionEditPart)connectionTarget, connectableEditParts);
return sourceHasSelectable || targetHasSelectable;
}
/**
* @return The Selection Conditional which tests if the editpart is selectable
*/
protected EditPartViewer.Conditional getSelectionConditional() {
return new EditPartViewer.Conditional() {
public boolean evaluate(EditPart editpart) {
return editpart.isSelectable();
}
};
}
/**
* Returns true if the operation set is not empty and only if the diagram is selected.
*/
protected boolean calculateEnabled() {
return !getOperationSet().isEmpty();
}
protected void doRun(IProgressMonitor progressMonitor) {
getDiagramGraphicalViewer().setSelection(
new StructuredSelection(getOperationSet()));
}
protected boolean isSelectionListener() {
return true;
}
protected boolean isOperationHistoryListener() {
//certain undo/redo actions can cause selection to change. see bugzilla#156261
return true;
}
/**
* Create the SelectAll action
*
* @return The SelectAll action
*/
public static SelectAllAction createSelectAllAction(IWorkbenchPage partService) {
SelectAllAction action = new SelectAllAction(partService, true, true);
action.setId(ActionFactory.SELECT_ALL.getId());
action.setText(DiagramUIActionsMessages.SelectAllAction_SelectAll);
action.setToolTipText(DiagramUIActionsMessages.SelectAllAction_SelectAll);
action.setImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTALL);
action.setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTALL_DISABLED);
return action;
}
/**
* Create the SelectAll toolbar action
*
* @return The SelectAll toobar action
*/
public static SelectAllAction createToolbarSelectAllAction(IWorkbenchPage partService) {
SelectAllAction action = new SelectAllAction(partService, true, true);
action.setId(ActionIds.ACTION_TOOLBAR_SELECT_ALL);
action.setText(DiagramUIActionsMessages.SelectAllAction_toolbar_SelectAll);
action.setToolTipText(DiagramUIActionsMessages.SelectAllAction_toolbar_SelectAll);
action.setImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTALL);
action.setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTALL_DISABLED);
return action;
}
/**
* Create the SelectAllShapes action
*
* @return The SelectAllShapes action
*/
public static SelectAllAction createSelectAllShapesAction(IWorkbenchPage partService) {
SelectAllAction action = new SelectAllAction(partService, true, false);
action.setId(ActionIds.ACTION_SELECT_ALL_SHAPES);
action.setText(DiagramUIActionsMessages.SelectAllAction_SelectShapes);
action.setToolTipText(DiagramUIActionsMessages.SelectAllAction_SelectShapes);
action.setImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTSHAPES);
action.setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTSHAPES_DISABLED);
return action;
}
/**
* Create the SelectAllShapes toolbar action
*
* @return The SelectAllShapes toolbar action
*/
public static SelectAllAction createToolbarSelectAllShapesAction(IWorkbenchPage partService) {
SelectAllAction action = new SelectAllAction(partService, true, false);
action.setId(ActionIds.ACTION_TOOLBAR_SELECT_ALL_SHAPES);
action.setText(DiagramUIActionsMessages.SelectAllAction_toolbar_SelectShapes);
action.setToolTipText(DiagramUIActionsMessages.SelectAllAction_toolbar_SelectShapes);
action.setImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTSHAPES);
action.setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTSHAPES_DISABLED);
return action;
}
/**
* Create the SelectAllConnections action
*
* @return The SelectAllConnections action
*/
public static SelectAllAction createSelectAllConnectionsAction(IWorkbenchPage partService) {
SelectAllAction action = new SelectAllAction(partService, false, true);
action.setId(ActionIds.ACTION_SELECT_ALL_CONNECTIONS);
action.setText(DiagramUIActionsMessages.SelectAllAction_SelectConnections);
action.setToolTipText(DiagramUIActionsMessages.SelectAllAction_SelectConnections);
action.setImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTCONNECTIONS);
action.setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTCONNECTIONS_DISABLED);
return action;
}
/**
* Create the SelectAllConnections toolbar action
*
* @return The SelectAllConnections toolbar action
*/
public static SelectAllAction createToolbarSelectAllConnectionsAction(IWorkbenchPage partService) {
SelectAllAction action = new SelectAllAction(partService, false, true);
action.setId(ActionIds.ACTION_TOOLBAR_SELECT_ALL_CONNECTIONS);
action.setText(DiagramUIActionsMessages.SelectAllAction_toolbar_SelectConnections);
action.setToolTipText(DiagramUIActionsMessages.SelectAllAction_toolbar_SelectConnections);
action.setImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTCONNECTIONS);
action.setDisabledImageDescriptor(DiagramUIActionsPluginImages.DESC_SELECTCONNECTIONS_DISABLED);
return action;
}
}