/****************************************************************************** * Copyright (c) 2004, 2008 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.commands; import java.util.List; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.common.core.util.ObjectAdapter; import org.eclipse.gmf.runtime.common.ui.dialogs.PopupDialog; import org.eclipse.gmf.runtime.diagram.ui.internal.commands.ElementTypeLabelProvider; import org.eclipse.gmf.runtime.diagram.ui.internal.l10n.InternalDiagramUIMessages; import org.eclipse.gmf.runtime.diagram.ui.menus.PopupMenu; import org.eclipse.gmf.runtime.emf.type.core.IElementType; import org.eclipse.gmf.runtime.emf.ui.dialogs.AbstractSelectElementDialog; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Shell; /** * <p> * A command that pops up a menu which can allow the user to select whether they * want to create a new type, select an existing element, or leave it * unspecified. * </p> * * <p> * The content can be customized, one or more of the above options are * permitted. The constants <code>UNSPECIFIED</code> and * <code>SELECT_EXISTING</code> can be used as the content of a menu item. * </p> * * <p> * The displayed strings can be customized with a custom label provider. * </p> * * <p> * The options are: * <li>Unspecified</li> * <li>Select Existing Element</li> * <li>Create New Type A</li> * <li>Create New Type B</li> * * <p> * If a "Select Existing" menu item is chosen, an additional dialog appears * allowing the user to choose an element. * * <p> * The <code>getResultAdapter()</code> method returns an adaptable to the * result. * </p> * * @author cmahoney */ public class CreateOrSelectElementCommand extends PopupMenuCommand { /** * Add this to the content list of the popup menu to add an 'unspecified' * option. */ public static final String UNSPECIFIED = InternalDiagramUIMessages.CreateOrSelectElementCommand_PopupMenu_UnspecifiedMenuItem_Text; /** * Add this to the content list of the popup menu to add a 'select existing' * option. */ public static final String SELECT_EXISTING = InternalDiagramUIMessages.CreateOrSelectElementCommand_PopupMenu_SelectExistingElementMenuItem_Text; /** * Add this to the content list of the popup menu to add a 'create without * binding' option. */ public static final String CREATE_WITHOUT_BINDING = InternalDiagramUIMessages.CreateOrSelectElementCommand_PopupMenu_CreateWithoutBindingMenuItem_Text; /** * The default label provider for the the menu items used in this command. * Adds the "Create new " text to the objects of type * <code>IElementType</code>. */ static public class LabelProvider extends ElementTypeLabelProvider { /** * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) */ public String getText(Object object) { String text = super.getText(object); if (object instanceof IElementType) { return NLS .bind( InternalDiagramUIMessages.CreateOrSelectElementCommand_PopupMenu_CreateMenuItem_Text, text); } return text; } } /** * The result to be returned from which the new element or type info can be * retrieved. */ private ObjectAdapter resultAdapter = new ObjectAdapter(); /** The dialog to be used if "Select Existing Element" is chosen */ private AbstractSelectElementDialog selectElementDialog; /** * Creates a new <code>CreateOrSelectElementCommand</code> that uses a * popup menu to prompt for the selection. * * @param parentShell * the parent shell * @param content * The list of items making up the content of the popup menu. * This can include element types (<code>IElementType</code>), * <code>UNSPECIFIED</code>, and <code>SELECT_EXISTING</code>. */ public CreateOrSelectElementCommand(Shell parentShell, List content) { this(parentShell, content, POPUP_MENU); } /** * Creates a new <code>CreateOrSelectElementCommand</code>. * * @param parentShell * the parent shell * @param content * The list of items making up the content of the popup menu. * This can include element types (<code>IElementType</code>), * <code>UNSPECIFIED</code>, and <code>SELECT_EXISTING</code>. * @param style * The kind of prompt to use for the selection. One of * {@link org.eclipse.gmf.runtime.diagram.ui.commands.PopupMenuCommand#POPUP_MENU} * or * {@link org.eclipse.gmf.runtime.diagram.ui.commands.PopupMenuCommand#POPUP_DIALOG} */ public CreateOrSelectElementCommand(Shell parentShell, List content, int style) { this(InternalDiagramUIMessages.CreateOrSelectElementCommand_Label, parentShell, content, style); } /** * Creates a new <code>CreateOrSelectElementCommand</code> that uses a * popup menu to prompt for the selection. * * @param label * the command label * @param parentShell * the parent shell * @param content * The list of items making up the content of the popup menu. * This can include element types (<code>IElementType</code>), * <code>UNSPECIFIED</code>, and <code>SELECT_EXISTING</code>. */ public CreateOrSelectElementCommand(String label, Shell parentShell, List content) { this(label, parentShell, content, POPUP_MENU); } /** * Creates a new <code>CreateOrSelectElementCommand</code>. * * @param label * the command label * @param parentShell * the parent shell * @param content * The list of items making up the content of the popup menu. * This can include element types (<code>IElementType</code>), * <code>UNSPECIFIED</code>, and <code>SELECT_EXISTING</code>. * @param style * The kind of prompt to use for the selection. One of * {@link org.eclipse.gmf.runtime.diagram.ui.commands.PopupMenuCommand#POPUP_MENU} * or * {@link org.eclipse.gmf.runtime.diagram.ui.commands.PopupMenuCommand#POPUP_DIALOG} */ public CreateOrSelectElementCommand(String label, Shell parentShell, List content, int style) { super(label, parentShell); if (style == POPUP_DIALOG) { setPopupDialog(new PopupDialog(parentShell, content, getLabelProvider())); } else { setPopupMenu(new PopupMenu(content, getLabelProvider())); } } /** * Creates a new <code>CreateOrSelectElementCommand</code>. * * @param parentShell * the parent shell * @param popupMenu * the popup menu */ public CreateOrSelectElementCommand(Shell parentShell, PopupMenu popupMenu) { super(InternalDiagramUIMessages.CreateOrSelectElementCommand_Label, parentShell, popupMenu); } /** * Pops up the dialog with the content provided. If the user selects 'select * existing', then the select elements dialog also appears. * * @see org.eclipse.gmf.runtime.common.core.sandbox.AbstractCommand2#doExecute(org.eclipse.core.runtime.IProgressMonitor) */ protected CommandResult doExecuteWithResult(IProgressMonitor progressMonitor, org.eclipse.core.runtime.IAdaptable info) throws ExecutionException { CommandResult cmdResult = super.doExecuteWithResult(progressMonitor, info); if (!cmdResult.getStatus().isOK()) { return cmdResult; } Object result = cmdResult.getReturnValue(); if (result != null) { if (result.equals(SELECT_EXISTING)) { AbstractSelectElementDialog dialog = getSelectElementDialog(); Assert.isNotNull(dialog); if (dialog.open() != Window.OK) { // user cancelled gesture return CommandResult.newCancelledCommandResult(); } List selectedElements = dialog.getSelectedElements(); if (selectedElements == null) { // user cancelled gesture progressMonitor.setCanceled(true); return CommandResult.newCancelledCommandResult(); } else if (dialog.isMultiSelectable()) { resultAdapter.setObject(selectedElements); return CommandResult.newOKCommandResult(selectedElements); } else { resultAdapter.setObject(selectedElements.get(0)); return CommandResult.newOKCommandResult(selectedElements.get(0)); } } else { resultAdapter.setObject(result); } } return cmdResult; } /** * Gets the selectElementDialog. * * @return Returns the selectElementDialog. */ protected AbstractSelectElementDialog getSelectElementDialog() { return selectElementDialog; } /** * Sets the selectElementDialog. * * @param dialog * The dialog to set. */ public void setSelectElementDialog(AbstractSelectElementDialog dialog) { this.selectElementDialog = dialog; } /** * Gets the resultAdapter. * * @return Returns the resultAdapter. */ public ObjectAdapter getResultAdapter() { return resultAdapter; } /** * Gets the label provider that is to be used to display each item in the * popup menu. * * @return the label provider */ protected ILabelProvider getLabelProvider() { return new LabelProvider(); } }