| /** |
| * Copyright (c) 2009 Sierra Wireless 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: |
| * Sierra Wireless - initial API and implementation |
| * |
| * $Id: CreateElementDropDownAction.java,v 1.2 2009/12/09 09:15:38 bcabe Exp $ |
| */ |
| package org.eclipse.pde.emfforms.editor.actions; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.edit.domain.EditingDomain; |
| import org.eclipse.jface.action.*; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.viewers.*; |
| import org.eclipse.pde.emfforms.editor.*; |
| import org.eclipse.pde.emfforms.internal.Activator; |
| import org.eclipse.pde.emfforms.internal.editor.IEmfFormsImages; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.widgets.*; |
| |
| public class CreateElementDropDownAction extends Action implements IMenuCreator { |
| |
| private EmfMasterDetailBlock masterDetailBlock; |
| |
| private Menu fMenu; |
| |
| /** The create child actions. */ |
| private Collection<IAction> createChildActions; |
| |
| /** The create sibling actions */ |
| protected Collection<IAction> createSiblingActions; |
| |
| public CreateElementDropDownAction(EmfMasterDetailBlock masterDetailBlck) { |
| masterDetailBlock = masterDetailBlck; |
| fMenu = null; |
| setToolTipText("Create a new child/sibling element"); |
| setImageDescriptor(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource(IEmfFormsImages.ADD_TOOLBAR_BUTTON))); |
| setMenuCreator(this); |
| } |
| |
| public void dispose() { |
| // action is reused, can be called several times. |
| if (fMenu != null) { |
| fMenu.dispose(); |
| fMenu = null; |
| } |
| } |
| |
| public Menu getMenu(Menu parent) { |
| return null; |
| } |
| |
| public Menu getMenu(Control parent) { |
| if (fMenu != null) { |
| fMenu.dispose(); |
| } |
| fMenu = new Menu(parent); |
| |
| updateActions(); |
| |
| // Add all CreateChild actions for the current selection |
| IAction titleCreateChildAction = new Action(createChildActions.isEmpty() ? "(no new child)" : "-- New Child --") {}; |
| titleCreateChildAction.setEnabled(false); |
| new ActionContributionItem(titleCreateChildAction).fill(fMenu, -1); |
| |
| for (IAction createChildAction : createChildActions) { |
| addActionToMenu(fMenu, createChildAction); |
| } |
| |
| // Add a separator |
| new MenuItem(fMenu, SWT.SEPARATOR); |
| |
| // Add all CreateSibling actions for the current selection |
| IAction titleCreateSiblingAction = new Action(createSiblingActions.isEmpty() ? "(no new sibling)" : "-- New Sibling --") {}; |
| titleCreateSiblingAction.setEnabled(false); |
| new ActionContributionItem(titleCreateSiblingAction).fill(fMenu, -1); |
| for (IAction createSiblingAction : createSiblingActions) { |
| addActionToMenu(fMenu, createSiblingAction); |
| } |
| |
| return fMenu; |
| } |
| |
| private void addActionToMenu(Menu parent, IAction action) { |
| ActionContributionItem item = new ActionContributionItem(action); |
| item.fill(parent, -1); |
| } |
| |
| private void updateActions() { |
| Collection<?> newChildDescriptors = null; |
| Collection<?> newSiblingDescriptors = null; |
| |
| // Query the new selection for appropriate new child/sibling descriptors |
| ISelection selection = getCurrentSelection(); |
| |
| if (selection instanceof IStructuredSelection && ((IStructuredSelection) selection).size() == 1) { |
| Object object = ((IStructuredSelection) selection).getFirstElement(); |
| |
| EditingDomain domain = masterDetailBlock.getEditor().getEditingDomain(); |
| newChildDescriptors = domain.getNewChildDescriptors(object, null); |
| newSiblingDescriptors = domain.getNewChildDescriptors(null, object); |
| |
| // Generate actions for selection |
| createChildActions = ((EmfActionBarContributor) masterDetailBlock.getEditor().getActionBarContributor()).generateCreateChildActions(newChildDescriptors, selection); |
| createSiblingActions = ((EmfActionBarContributor) masterDetailBlock.getEditor().getActionBarContributor()).generateCreateSiblingActions(newSiblingDescriptors, selection); |
| } |
| } |
| |
| /** |
| * Get the currentSelection from the {@link TreeViewer} widget.<br/> |
| * Default implementation first attempts to retrieve the selection from the {@link TreeViewer}, |
| * but if the selection is empty, we compute a selection from the viewer input, or if none input |
| * has been set, a call to the <code>getRootElement()</code> method is done. |
| * Subclasses may override this method in order to provide their own selection. |
| * |
| * @return ISelection The {@link TreeViewer} selection to be used to compute Child/Sibling actions |
| */ |
| protected ISelection getCurrentSelection() { |
| ISelection selection = masterDetailBlock.getTreeViewer().getSelection(); |
| if (selection.isEmpty()) { |
| if (masterDetailBlock.getTreeViewer().getInput() != null) { |
| selection = new StructuredSelection(masterDetailBlock.getTreeViewer().getInput()); |
| } else { |
| selection = getRootElement(); |
| } |
| } |
| return selection; |
| } |
| |
| /** |
| * In case the {@link TreeViewer}'s input has not been initialized, return the selection from which Child/Sibling actions should be computed. |
| * Default implementation returns a new selection based on the {@link EmfFormEditor} {@link EObject} currently edited. |
| * |
| * @return ISelection The {@link TreeViewer} selection to be used to compute Child/Sibling actions |
| */ |
| protected IStructuredSelection getRootElement() { |
| return new StructuredSelection(masterDetailBlock.getEditor().getCurrentEObject()); |
| } |
| |
| @Override |
| public void runWithEvent(Event event) { |
| ToolItem toolItem = (ToolItem) event.widget; |
| |
| // Update the menu |
| getMenu(toolItem.getParent()); |
| |
| Collection<IAction> allEnabledActions = getAllEnabledActions(); |
| if (allEnabledActions.isEmpty()) { |
| // 1. None enabled action to execute - Just exit |
| return; |
| } else if (allEnabledActions.size() == 1) { |
| // 2. A single action to execute - Run it and exit |
| allEnabledActions.iterator().next().run(); |
| return; |
| } else { |
| // 3. Several actions are enabled - Show the menu |
| Point point = toolItem.getParent().toDisplay(new Point(event.x, event.y)); |
| // Position the menu below the drop down item. Need to translate the menu 20 pixels to the bottom for the same rendering as it was created from the DOWN_ARROW area |
| fMenu.setLocation(point.x, point.y + 20); |
| fMenu.setVisible(true); |
| return; // we don't fire the action |
| } |
| } |
| |
| private Collection<IAction> getAllEnabledActions() { |
| Collection<IAction> allEnabledActions = new ArrayList<IAction>(); |
| |
| for (IAction createChildAction : createChildActions) { |
| if (createChildAction.isEnabled()) { |
| allEnabledActions.add(createChildAction); |
| } |
| } |
| for (IAction createSiblingAction : createSiblingActions) { |
| if (createSiblingAction.isEnabled()) { |
| allEnabledActions.add(createSiblingAction); |
| } |
| } |
| return allEnabledActions; |
| } |
| } |