/***************************************************************************** * Copyright (c) 2011 CEA LIST. * * 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: * * CEA LIST - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.infra.gmfdiag.common.commands; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.gef.commands.Command; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.diagram.ui.commands.CommandUtilities; import org.eclipse.gmf.runtime.diagram.ui.commands.PopupMenuCommand; import org.eclipse.gmf.runtime.diagram.ui.menus.PopupMenu; import org.eclipse.gmf.runtime.diagram.ui.menus.PopupMenu.CascadingMenu; import org.eclipse.papyrus.infra.gmfdiag.common.Activator; import org.eclipse.swt.widgets.Shell; /** * This class opens a dialog to select and execute a command in a given list. */ public class SelectAndExecuteCommand extends PopupMenuCommand { /** Selected command kept here for undo / re-do purpose */ private Command _selectedCmd; /** An object to handle the selection of a default command. May be null. */ private DefaultActionHandler defaultHandler; /** * The default label provider for the the menu items (Commands) used in this command. */ static public class CommandLabelProvider extends org.eclipse.jface.viewers.LabelProvider { /** * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) */ @Override public String getText(Object object) { String text = super.getText(object); if(object instanceof Command) { String commandLabel = ((Command)object).getLabel(); if(commandLabel != null) { text = commandLabel; } } return text; } } /** * * Constructor. * * @param label * the command label * @param parentShell * the parent shell * @param content * the list of available commands proposed for user selection * (List<org.eclipse.gef.commands.Command> expected here) */ public SelectAndExecuteCommand(String label, Shell parentShell, List<Command> content) { this(label, parentShell, content, null); } /** * * Constructor. * * @param label * the command label * @param parentShell * the parent shell * @param content * the list of available commands proposed for user selection * (List<org.eclipse.gef.commands.Command> expected here) * @param handler * an object to handle the "default action" case */ public SelectAndExecuteCommand(String label, Shell parentShell, List<Command> content, DefaultActionHandler handler) { super(label, parentShell); this.defaultHandler = handler; createPopupMenu(content); } /** * Adds a submenu to the popup menu, to handle the "Select default" case * * @param menu */ protected void createPopupMenu(List<Command> content) { PopupMenu popupMenu; if(defaultHandler != null) { //Contains a list of commands + a Default item List<Object> menuContents = new LinkedList<Object>(content); PopupMenu submenu = new PopupMenu(convertToDefault(content), new CommandLabelProvider()); CascadingMenu cascadingMenu = new CascadingMenu(defaultHandler.getLabel(), submenu); menuContents.add(cascadingMenu); popupMenu = new PopupMenu(menuContents, new CommandLabelProvider()); } else { popupMenu = new PopupMenu(content, new CommandLabelProvider()); } setPopupMenu(popupMenu); } /** * Adds a "Set as default" behavior to a list of commands * * @param commands * @return */ protected List<Command> convertToDefault(List<Command> commands) { List<Command> result = new ArrayList<Command>(commands.size()); for(Command command : commands) { final Command commandToExecute = command; CompoundCommand compound = new CompoundCommand(commandToExecute.getLabel()); compound.add(commandToExecute); compound.add(new Command("Set default drop behavior") { @Override public void execute() { defaultHandler.defaultActionSelected(commandToExecute); } }); result.add(compound); } return result; } @Override protected CommandResult doExecuteWithResult(IProgressMonitor progressMonitor, org.eclipse.core.runtime.IAdaptable info) throws ExecutionException { CommandResult cmdResult = super.doExecuteWithResult(progressMonitor, info); if(!cmdResult.getStatus().isOK()) { if(cmdResult.getStatus().getSeverity() != IStatus.CANCEL) { Activator.log.error(cmdResult.getStatus().getException()); } return cmdResult; } Object returnValue = cmdResult.getReturnValue(); if(returnValue instanceof List<?>) { _selectedCmd = (Command)((List<?>)returnValue).get(((List<?>)returnValue).size() - 1); //Returns the last command } else { _selectedCmd = (Command)cmdResult.getReturnValue(); } Assert.isTrue(_selectedCmd != null && _selectedCmd.canExecute()); _selectedCmd.execute(); return CommandResult.newOKCommandResult(); } @Override protected CommandResult doUndoWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException { if(_selectedCmd != null && _selectedCmd.canUndo()) { _selectedCmd.undo(); } return super.doUndoWithResult(progressMonitor, info); } @Override protected CommandResult doRedoWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException { if(_selectedCmd != null && CommandUtilities.canRedo(_selectedCmd)) { _selectedCmd.redo(); } return super.doRedoWithResult(progressMonitor, info); } }