blob: dd3d213d5218556ce101deb08b845da82ee1d032 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2006 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.internal.actions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.gmf.runtime.common.ui.action.AbstractContributionItem;
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.parts.DiagramCommandStack;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramEditDomain;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramGraphicalViewer;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
/**
* @author melaasar
*
* An abstract implementation of a custom toolbar contribution item for a diagram
* engine-based part
*
*/
public abstract class CustomContributionItem
extends AbstractContributionItem {
/** the target request */
private Request targetRequest;
/** the cached operation set */
private List _operationSet = Collections.EMPTY_LIST;
/**
* Constructs a new custom contribution item
*
* @param workbenchPage The workbench page
* @param id The item's id
*/
public CustomContributionItem(
IWorkbenchPage workbenchPage,
String id) {
super(workbenchPage, id);
}
/**
* @see org.eclipse.jface.action.IContributionItem#dispose()
*/
public void dispose() {
targetRequest = null;
_operationSet = null;
super.dispose();
}
protected void doRun(IProgressMonitor progressMonitor) {
updateTargetRequest();
execute(getCommand(), progressMonitor);
}
public void refresh() {
_operationSet = null; // invalidate the cached set
updateTargetRequest();
super.refresh();
}
protected boolean calculateEnabled() {
Command command = getCommand();
return command != null && command.canExecute();
}
/**
* Executes the given {@link Command}.
* @param command the command to execute
* @param progressMonitor the progress monitor
*/
protected final void execute(
Command command,
IProgressMonitor progressMonitor) {
if (command == null || !command.canExecute())
return;
if (getDiagramCommandStack() != null)
getDiagramCommandStack().execute(command, progressMonitor);
}
/**
* gets the part's diagram command stack.
* @return the <code>DiagramCommandStack</code>
*/
protected DiagramCommandStack getDiagramCommandStack() {
Object stack = getWorkbenchPart().getAdapter(CommandStack.class);
return (stack instanceof DiagramCommandStack)
? (DiagramCommandStack) stack
: null;
}
/**
* Gets a command to execute on the operation set based on the target request
*
* @return a command to execute
*/
protected Command getCommand() {
return getCommand(getTargetRequest());
}
/**
* Gets a command to execute on the operation set based on a given request
* @param request the request
* @return a command to execute
*/
protected Command getCommand(Request request) {
List operationSet = getOperationSet();
Iterator editParts = operationSet.iterator();
CompoundCommand command = new CompoundCommand(getCommandLabel());
while (editParts.hasNext()) {
EditPart editPart = (EditPart) editParts.next();
Command curCommand = editPart.getCommand(request);
if (curCommand != null) {
command.add(curCommand);
}
}
return command.isEmpty()
|| command.size() != operationSet.size()
? UnexecutableCommand.INSTANCE
: (Command) command;
}
/**
* Gets an optional label for the action's executed command
*
* @return An optional label for the action's executed command
*/
protected String getCommandLabel() {
return null;
}
/**
* Gets a request to be addressed to the operation set
*
* @return a target request
*/
protected Request getTargetRequest() {
if (targetRequest == null)
targetRequest = createTargetRequest();
return targetRequest;
}
/**
* Creates a new target request
*
* @return the new target request
*/
protected abstract Request createTargetRequest();
/**
* updates the target request.
* Clients should call this method whenever the request
* is expected to be changed
*/
protected void updateTargetRequest() {
// no def impl
}
/**
* A utility method to return a list of objects in the current structured selection
*
* @return A list of objects in the current structure selection
*/
protected List getSelectedObjects() {
return getStructuredSelection().toList();
}
/**
* Return the list of editparts considered the operation set after caching them
*
* @return A list of editparts conidered the operation set
*/
protected final List getOperationSet() {
if (_operationSet == null) {
_operationSet = createOperationSet();
if (_operationSet == null)
_operationSet = Collections.EMPTY_LIST;
}
return _operationSet;
}
/**
* Filters the selected objects and returns only editparts that understands the request
* @return a list of editparts selected.
*
*/
protected List createOperationSet() {
List selection = getSelectedObjects();
if (selection.isEmpty() || !(selection.get(0) instanceof IGraphicalEditPart))
return Collections.EMPTY_LIST;
Iterator selectedEPs = selection.iterator();
List targetedEPs = new ArrayList();
while (selectedEPs.hasNext()) {
EditPart selectedEP = (EditPart) selectedEPs.next();
targetedEPs.addAll(getTargetEditParts(selectedEP));
}
return targetedEPs.isEmpty() ? Collections.EMPTY_LIST : targetedEPs;
}
/**
* Given an editpart, returns a list of target editparts to the current request
* If no targets could be found, an empty list is returned
*
* @param editpart The given editpart
* @return a list of target editparts, or Empty list if none
*/
protected List getTargetEditParts(EditPart editpart) {
EditPart targetEP = editpart.getTargetEditPart(getTargetRequest());
return (targetEP == null)
? Collections.EMPTY_LIST
: Collections.singletonList(targetEP);
}
/**
* A utility method to get the <code>IDiagramEditDomain</code> from the
* current part if it adapts to it
*
* @return The diagram edit domain adapter if it exists; <code>null</code> otherwise
*/
protected IDiagramEditDomain getDiagramEditDomain() {
return (IDiagramEditDomain) getWorkbenchPart().getAdapter(
IDiagramEditDomain.class);
}
/**
* A utility method to return the active part if it implements the
* <code>IDiagramWorkbenchPart</code> interface
*
* @return The current part if it implements <code>IDiagramWorkbenchPart</code>; <code>null</code> otherwise
*/
protected IDiagramWorkbenchPart getDiagramWorkbenchPart() {
return getWorkbenchPart() instanceof IDiagramWorkbenchPart
? (IDiagramWorkbenchPart) getWorkbenchPart()
: null;
}
/**
* A utility method to return the active <code>DiagramEditPart</code>
* if the current part implements <code>IDiagramWorkbenchPart</code>
*
* @return The current diagram if the parts implements
* <code>IDiagramWorkbenchPart</code>; <code>null</code> otherwise
*/
protected DiagramEditPart getDiagramEditPart() {
IDiagramWorkbenchPart editor = getDiagramWorkbenchPart();
return editor != null ? editor.getDiagramEditPart() : null;
}
/**
* A utility method to return the active <code>DiagramEditPart</code>
* if the current part implements <code>IDiagramWorkbenchPart</code>
*
* @return The current diagram if the parts implements
* <code>IDiagramWorkbenchPart</code>; <code>null</code> otherwise
*/
protected IDiagramGraphicalViewer getDiagramGraphicalViewer() {
IDiagramWorkbenchPart part = getDiagramWorkbenchPart();
return part != null ? part.getDiagramGraphicalViewer() : null;
}
/**
* Filters the given list of EditParts so that the list only contains the EditParts that
* matches the given condition when called on the given editpart).
* @param list the list of edit parts to filter
* @param condition the condition
* @return a modified list containing those editparts that matched the condition
*/
protected List filterEditPartsMatching(
List list,
EditPartViewer.Conditional condition) {
List matchList = new ArrayList();
Iterator iter = list.iterator();
while (iter.hasNext()) {
EditPart ep = (EditPart) iter.next();
if (condition.evaluate(ep))
matchList.add(ep);
}
return matchList;
}
}