diff options
Diffstat (limited to 'extraplugins/diagram-definition/org.eclipse.papyrus.dd.editor/src/org/eclipse/papyrus/dd/dg/editor/DGActionBarContributor.java')
-rw-r--r-- | extraplugins/diagram-definition/org.eclipse.papyrus.dd.editor/src/org/eclipse/papyrus/dd/dg/editor/DGActionBarContributor.java | 537 |
1 files changed, 537 insertions, 0 deletions
diff --git a/extraplugins/diagram-definition/org.eclipse.papyrus.dd.editor/src/org/eclipse/papyrus/dd/dg/editor/DGActionBarContributor.java b/extraplugins/diagram-definition/org.eclipse.papyrus.dd.editor/src/org/eclipse/papyrus/dd/dg/editor/DGActionBarContributor.java new file mode 100644 index 00000000000..66bc7095820 --- /dev/null +++ b/extraplugins/diagram-definition/org.eclipse.papyrus.dd.editor/src/org/eclipse/papyrus/dd/dg/editor/DGActionBarContributor.java @@ -0,0 +1,537 @@ +/** + * Copyright (c) 2014 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.dd.dg.editor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.StringTokenizer; + +import org.eclipse.emf.common.ui.viewer.IViewerProvider; +import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.edit.domain.IEditingDomainProvider; +import org.eclipse.emf.edit.ui.action.ControlAction; +import org.eclipse.emf.edit.ui.action.CreateChildAction; +import org.eclipse.emf.edit.ui.action.CreateSiblingAction; +import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor; +import org.eclipse.emf.edit.ui.action.LoadResourceAction; +import org.eclipse.emf.edit.ui.action.ValidateAction; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IContributionManager; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.action.SubContributionItem; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.papyrus.dd.editor.DDEditorPlugin; +import org.eclipse.papyrus.dd.editor.DDModelPage; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.actions.ActionFactory; + +/** + * This is the action bar contributor for the DG model editor. + */ +public class DGActionBarContributor extends EditingDomainActionBarContributor + implements ISelectionChangedListener { + + /** + * This keeps track of the active editor. + */ + protected IEditorPart activeEditorPart; + + /** + * This keeps track of the current selection provider. + */ + protected ISelectionProvider selectionProvider; + + /** + * This action opens the Properties view. + */ + protected IAction showPropertiesViewAction = new Action( + DDEditorPlugin.INSTANCE + .getString("_UI_ShowPropertiesView_menu_item")) { + + @Override + public void run() { + try { + getPage().showView("org.eclipse.ui.views.PropertySheet"); + } catch (PartInitException exception) { + DDEditorPlugin.INSTANCE.log(exception); + } + } + }; + + /** + * This action refreshes the viewer of the current editor if the editor + * implements {@link org.eclipse.emf.common.ui.viewer.IViewerProvider}. + */ + protected IAction refreshViewerAction = new Action( + DDEditorPlugin.INSTANCE.getString("_UI_RefreshViewer_menu_item")) { + + @Override + public boolean isEnabled() { + return activeEditorPart instanceof IViewerProvider; + } + + @Override + public void run() { + if (activeEditorPart instanceof IViewerProvider) { + Viewer viewer = ((IViewerProvider) activeEditorPart) + .getViewer(); + if (viewer != null) { + viewer.refresh(); + } + } + } + }; + + /** + * This will contain one + * {@link org.eclipse.emf.edit.ui.action.CreateChildAction} corresponding to + * each descriptor generated for the current selection by the item provider. + */ + protected Collection<IAction> createChildActions; + + /** + * This will contain a map of + * {@link org.eclipse.emf.edit.ui.action.CreateChildAction}s, keyed by + * sub-menu text. + */ + protected Map<String, Collection<IAction>> createChildSubmenuActions; + + /** + * This is the menu manager into which menu contribution items should be + * added for CreateChild actions. + */ + protected IMenuManager createChildMenuManager; + + /** + * This will contain one + * {@link org.eclipse.emf.edit.ui.action.CreateSiblingAction} corresponding + * to each descriptor generated for the current selection by the item + * provider. + */ + protected Collection<IAction> createSiblingActions; + + /** + * This will contain a map of + * {@link org.eclipse.emf.edit.ui.action.CreateSiblingAction}s, keyed by + * submenu text. + */ + protected Map<String, Collection<IAction>> createSiblingSubmenuActions; + + /** + * This is the menu manager into which menu contribution items should be + * added for CreateSibling actions. + */ + protected IMenuManager createSiblingMenuManager; + + /** + * This creates an instance of the contributor. + */ + public DGActionBarContributor() { + super(ADDITIONS_LAST_STYLE); + loadResourceAction = new LoadResourceAction(); + validateAction = new ValidateAction(); + controlAction = new ControlAction(); + } + + /** + * Override to handle the global actions for the model page only Otherwise, + * other controls (e.g., StyledText) are not handled property + */ + @Override + public void setActivePage(IEditorPart part) { + IActionBars actionBars = getActionBars(); + if (part instanceof DDModelPage) { + actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), + deleteAction); + actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), + cutAction); + actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), + copyAction); + actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), + pasteAction); + } else { + actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), + null); + actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), null); + actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), null); + actionBars + .setGlobalActionHandler(ActionFactory.PASTE.getId(), null); + } + } + + /** + * This adds Separators for editor additions to the tool bar. + */ + @Override + public void contributeToToolBar(IToolBarManager toolBarManager) { + toolBarManager.add(new Separator("dg-settings")); + toolBarManager.add(new Separator("dg-additions")); + } + + /** + * This adds to the menu bar a menu and some separators for editor + * additions, as well as the sub-menus for object creation items. + */ + @Override + public void contributeToMenu(IMenuManager menuManager) { + super.contributeToMenu(menuManager); + + IMenuManager submenuManager = new MenuManager( + DDEditorPlugin.INSTANCE.getString("_UI_DGEditor_menu"), + "org.eclipse.papyrus.dd.dgMenuID"); + menuManager.insertAfter("additions", submenuManager); + submenuManager.add(new Separator("settings")); + submenuManager.add(new Separator("actions")); + submenuManager.add(new Separator("additions")); + submenuManager.add(new Separator("additions-end")); + + // Prepare for CreateChild item addition or removal. + createChildMenuManager = new MenuManager( + DDEditorPlugin.INSTANCE.getString("_UI_CreateChild_menu_item")); + submenuManager.insertBefore("additions", createChildMenuManager); + + // Prepare for CreateSibling item addition or removal. + createSiblingMenuManager = new MenuManager( + DDEditorPlugin.INSTANCE + .getString("_UI_CreateSibling_menu_item")); + submenuManager.insertBefore("additions", createSiblingMenuManager); + + // Force an update because Eclipse hides empty menus now. + submenuManager.addMenuListener(new IMenuListener() { + + @Override + public void menuAboutToShow(IMenuManager menuManager) { + menuManager.updateAll(true); + } + }); + + addGlobalActions(submenuManager); + } + + /** + * When the active editor changes, this remembers the change and registers + * with it as a selection provider. + */ + @Override + public void setActiveEditor(IEditorPart part) { + super.setActiveEditor(part); + activeEditorPart = part; + + // Switch to the new selection provider. + if (selectionProvider != null) { + selectionProvider.removeSelectionChangedListener(this); + } + if (part == null) { + selectionProvider = null; + } else { + selectionProvider = part.getSite().getSelectionProvider(); + selectionProvider.addSelectionChangedListener(this); + + // Fake a selection changed event to update the menus. + if (selectionProvider.getSelection() != null) { + selectionChanged(new SelectionChangedEvent(selectionProvider, + selectionProvider.getSelection())); + } + } + } + + /** + * This implements + * {@link org.eclipse.jface.viewers.ISelectionChangedListener}, handling + * {@link org.eclipse.jface.viewers.SelectionChangedEvent}s by querying for + * the children and siblings that can be added to the selected object and + * updating the menus accordingly. + */ + @Override + public void selectionChanged(SelectionChangedEvent event) { + // Remove any menu items for old selection. + if (createChildMenuManager != null) { + depopulateManager(createChildMenuManager, createChildSubmenuActions); + depopulateManager(createChildMenuManager, createChildActions); + } + if (createSiblingMenuManager != null) { + depopulateManager(createSiblingMenuManager, + createSiblingSubmenuActions); + depopulateManager(createSiblingMenuManager, createSiblingActions); + } + + // Query the new selection for appropriate new child/sibling descriptors + Collection<?> newChildDescriptors = null; + Collection<?> newSiblingDescriptors = null; + + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection + && ((IStructuredSelection) selection).size() == 1) { + Object object = ((IStructuredSelection) selection) + .getFirstElement(); + + EditingDomain domain = ((IEditingDomainProvider) activeEditorPart) + .getEditingDomain(); + + newChildDescriptors = domain.getNewChildDescriptors(object, null); + newSiblingDescriptors = domain.getNewChildDescriptors(null, object); + } + + // Generate actions for selection; populate and redraw the menus. + createChildActions = generateCreateChildActions(newChildDescriptors, + selection); + createChildSubmenuActions = extractSubmenuActions(createChildActions); + createSiblingActions = generateCreateSiblingActions( + newSiblingDescriptors, selection); + createSiblingSubmenuActions = extractSubmenuActions(createSiblingActions); + + if (createChildMenuManager != null) { + populateManager(createChildMenuManager, createChildSubmenuActions, + null); + populateManager(createChildMenuManager, createChildActions, null); + createChildMenuManager.update(true); + } + if (createSiblingMenuManager != null) { + populateManager(createSiblingMenuManager, + createSiblingSubmenuActions, null); + populateManager(createSiblingMenuManager, createSiblingActions, + null); + createSiblingMenuManager.update(true); + } + } + + /** + * This generates a {@link org.eclipse.emf.edit.ui.action.CreateChildAction} + * for each object in <code>descriptors</code>, and returns the collection + * of these actions. + */ + protected Collection<IAction> generateCreateChildActions( + Collection<?> descriptors, ISelection selection) { + Collection<IAction> actions = new ArrayList<IAction>(); + if (descriptors != null) { + for (Object descriptor : descriptors) { + actions.add(new CreateChildAction(activeEditorPart, selection, + descriptor)); + } + } + return actions; + } + + /** + * This generates a + * {@link org.eclipse.emf.edit.ui.action.CreateSiblingAction} for each + * object in <code>descriptors</code>, and returns the collection of these + * actions. + */ + protected Collection<IAction> generateCreateSiblingActions( + Collection<?> descriptors, ISelection selection) { + Collection<IAction> actions = new ArrayList<IAction>(); + if (descriptors != null) { + for (Object descriptor : descriptors) { + actions.add(new CreateSiblingAction(activeEditorPart, + selection, descriptor)); + } + } + return actions; + } + + /** + * This populates the specified <code>manager</code> with + * {@link org.eclipse.jface.action.ActionContributionItem}s based on the + * {@link org.eclipse.jface.action.IAction}s contained in the + * <code>actions</code> collection, by inserting them before the specified + * contribution item <code>contributionID</code>. If + * <code>contributionID</code> is <code>null</code>, they are simply added. + */ + protected void populateManager(IContributionManager manager, + Collection<? extends IAction> actions, String contributionID) { + if (actions != null) { + for (IAction action : actions) { + if (contributionID != null) { + manager.insertBefore(contributionID, action); + } else { + manager.add(action); + } + } + } + } + + /** + * This removes from the specified <code>manager</code> all + * {@link org.eclipse.jface.action.ActionContributionItem}s based on the + * {@link org.eclipse.jface.action.IAction}s contained in the + * <code>actions</code> collection. + */ + protected void depopulateManager(IContributionManager manager, + Collection<? extends IAction> actions) { + if (actions != null) { + IContributionItem[] items = manager.getItems(); + for (int i = 0; i < items.length; i++) { + // Look into SubContributionItems + IContributionItem contributionItem = items[i]; + while (contributionItem instanceof SubContributionItem) { + contributionItem = ((SubContributionItem) contributionItem) + .getInnerItem(); + } + + // Delete the ActionContributionItems with matching action. + if (contributionItem instanceof ActionContributionItem) { + IAction action = ((ActionContributionItem) contributionItem) + .getAction(); + if (actions.contains(action)) { + manager.remove(contributionItem); + } + } + } + } + } + + /** + * This extracts those actions in the <code>submenuActions</code> collection + * whose text is qualified and returns a map of these actions, keyed by + * submenu text. + */ + protected Map<String, Collection<IAction>> extractSubmenuActions( + Collection<IAction> createActions) { + Map<String, Collection<IAction>> createSubmenuActions = new LinkedHashMap<String, Collection<IAction>>(); + if (createActions != null) { + for (Iterator<IAction> actions = createActions.iterator(); actions + .hasNext();) { + IAction action = actions.next(); + StringTokenizer st = new StringTokenizer(action.getText(), "|"); + if (st.countTokens() == 2) { + String text = st.nextToken().trim(); + Collection<IAction> submenuActions = createSubmenuActions + .get(text); + if (submenuActions == null) { + createSubmenuActions.put(text, + submenuActions = new ArrayList<IAction>()); + } + action.setText(st.nextToken().trim()); + submenuActions.add(action); + actions.remove(); + } + } + } + return createSubmenuActions; + } + + /** + * This populates the specified <code>manager</code> with + * {@link org.eclipse.jface.action.MenuManager}s containing + * {@link org.eclipse.jface.action.ActionContributionItem}s based on the + * {@link org.eclipse.jface.action.IAction}s contained in the + * <code>submenuActions</code> collection, by inserting them before the + * specified contribution item <code>contributionID</code>. If + * <code>contributionID</code> is <code>null</code>, they are simply added. + */ + protected void populateManager(IContributionManager manager, + Map<String, Collection<IAction>> submenuActions, + String contributionID) { + if (submenuActions != null) { + for (Map.Entry<String, Collection<IAction>> entry : submenuActions + .entrySet()) { + MenuManager submenuManager = new MenuManager(entry.getKey()); + if (contributionID != null) { + manager.insertBefore(contributionID, submenuManager); + } else { + manager.add(submenuManager); + } + populateManager(submenuManager, entry.getValue(), null); + } + } + } + + /** + * This removes from the specified <code>manager</code> all + * {@link org.eclipse.jface.action.MenuManager}s and their + * {@link org.eclipse.jface.action.ActionContributionItem}s based on the + * {@link org.eclipse.jface.action.IAction}s contained in the + * <code>submenuActions</code> map. + */ + protected void depopulateManager(IContributionManager manager, + Map<String, Collection<IAction>> submenuActions) { + if (submenuActions != null) { + IContributionItem[] items = manager.getItems(); + for (int i = 0; i < items.length; i++) { + IContributionItem contributionItem = items[i]; + if (contributionItem instanceof MenuManager) { + MenuManager submenuManager = (MenuManager) contributionItem; + if (submenuActions + .containsKey(submenuManager.getMenuText())) { + depopulateManager(submenuManager, + submenuActions.get(contributionItem.toString())); + manager.remove(contributionItem); + } + } + } + } + } + + /** + * This populates the pop-up menu before it appears. + */ + @Override + public void menuAboutToShow(IMenuManager menuManager) { + super.menuAboutToShow(menuManager); + MenuManager submenuManager = null; + + submenuManager = new MenuManager( + DDEditorPlugin.INSTANCE.getString("_UI_CreateChild_menu_item")); + populateManager(submenuManager, createChildSubmenuActions, null); + populateManager(submenuManager, createChildActions, null); + menuManager.insertBefore("edit", submenuManager); + + submenuManager = new MenuManager( + DDEditorPlugin.INSTANCE + .getString("_UI_CreateSibling_menu_item")); + populateManager(submenuManager, createSiblingSubmenuActions, null); + populateManager(submenuManager, createSiblingActions, null); + menuManager.insertBefore("edit", submenuManager); + } + + /** + * This inserts global actions before the "additions-end" separator. + */ + @Override + protected void addGlobalActions(IMenuManager menuManager) { + menuManager.insertAfter("additions-end", new Separator("ui-actions")); + menuManager.insertAfter("ui-actions", showPropertiesViewAction); + + refreshViewerAction.setEnabled(refreshViewerAction.isEnabled()); + menuManager.insertAfter("ui-actions", refreshViewerAction); + + super.addGlobalActions(menuManager); + } + + /** + * This ensures that a delete action will clean up all references to deleted + * objects. + */ + @Override + protected boolean removeAllReferencesOnDelete() { + return true; + } + +} |