| /******************************************************************************* |
| * <copyright> |
| * |
| * Copyright (c) 2005, 2012 SAP AG. |
| * 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: |
| * SAP AG - initial API, implementation and documentation |
| * mwenz - Bug 323155 - Check usage scenarios for DefaultPrintFeature and |
| * DefaultSaveImageFeature |
| * mwenz - Bug 339525 - Enrich paste context with location information |
| * Bug 336488 - DiagramEditor API |
| * Benjamin Schmeling - mwenz - Bug 367483 - Support composite connections |
| * cbrand - Bug 377783 - Dump for figures in connection layer needed |
| * fvelasco - Bug 396247 - ImageDescriptor changes |
| * pjpaulin - Bug 352120 - Add certain menu options only if local transaction |
| * pjpaulin - Bug 352120 - Now uses IDiagramContainerUI interface |
| * |
| * </copyright> |
| * |
| *******************************************************************************/ |
| package org.eclipse.graphiti.ui.editor; |
| |
| import java.util.List; |
| |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.gef.ContextMenuProvider; |
| import org.eclipse.gef.EditPartViewer; |
| import org.eclipse.gef.ui.actions.ActionRegistry; |
| import org.eclipse.gef.ui.actions.GEFActionConstants; |
| import org.eclipse.graphiti.datatypes.ILocation; |
| import org.eclipse.graphiti.features.IFeature; |
| import org.eclipse.graphiti.features.IFeatureProvider; |
| import org.eclipse.graphiti.features.IPrintFeature; |
| import org.eclipse.graphiti.features.context.ICustomContext; |
| import org.eclipse.graphiti.features.context.impl.CustomContext; |
| import org.eclipse.graphiti.features.custom.ICustomFeature; |
| import org.eclipse.graphiti.internal.pref.GFPreferences; |
| import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; |
| import org.eclipse.graphiti.mm.pictograms.CompositeConnection; |
| import org.eclipse.graphiti.mm.pictograms.Connection; |
| import org.eclipse.graphiti.mm.pictograms.Diagram; |
| import org.eclipse.graphiti.mm.pictograms.PictogramElement; |
| import org.eclipse.graphiti.mm.pictograms.Shape; |
| import org.eclipse.graphiti.services.Graphiti; |
| import org.eclipse.graphiti.tb.ContextMenuEntry; |
| import org.eclipse.graphiti.tb.IContextMenuEntry; |
| import org.eclipse.graphiti.tb.IToolBehaviorProvider; |
| import org.eclipse.graphiti.ui.internal.Messages; |
| import org.eclipse.graphiti.ui.internal.action.CustomAction; |
| import org.eclipse.graphiti.ui.internal.action.DeleteAction; |
| import org.eclipse.graphiti.ui.internal.action.IAvailable; |
| import org.eclipse.graphiti.ui.internal.action.RemoveAction; |
| import org.eclipse.graphiti.ui.internal.action.SaveImageAction; |
| import org.eclipse.graphiti.ui.internal.action.UpdateAction; |
| import org.eclipse.graphiti.ui.internal.feature.DebugFeature; |
| import org.eclipse.graphiti.ui.internal.parts.CompositeConnectionEditPart; |
| import org.eclipse.graphiti.ui.platform.IConfigurationProvider; |
| import org.eclipse.graphiti.ui.services.GraphitiUi; |
| import org.eclipse.graphiti.util.ILocationInfo; |
| import org.eclipse.jface.action.ActionContributionItem; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IContributionItem; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.ui.actions.ActionFactory; |
| |
| /** |
| * Provides a standard-context-menu and adds it to the given EditPartViewer. |
| * Another feature is, that it can set the menu-location to all Actions. |
| * <p> |
| * Some of the standard-menu-items are: undo/redo, delete, copy/paste, |
| * alignment, zooming. |
| * |
| */ |
| public class DiagramEditorContextMenuProvider extends ContextMenuProvider { |
| |
| private final ActionRegistry actionRegistry; |
| |
| private final IConfigurationProvider configurationProvider; |
| |
| /** |
| * Creates a new DiagramEditorContextMenuProvider. |
| * |
| * @param viewer |
| * The EditPartViewer, for which the context-menu shall be |
| * displayed. |
| * @param registry |
| * The action-registry, which contains the actions corresponding |
| * to the menu-items. |
| * @param configurationProvider |
| * the configuration provider |
| * @since 0.10 |
| */ |
| public DiagramEditorContextMenuProvider(EditPartViewer viewer, ActionRegistry registry, |
| IConfigurationProvider configurationProvider) { |
| super(viewer); |
| if (registry == null) { |
| throw new IllegalArgumentException("Argument registry must not be null"); //$NON-NLS-1$ |
| } |
| this.actionRegistry = registry; |
| if (configurationProvider == null) { |
| throw new IllegalArgumentException("Argument configurationProvider must not be null"); //$NON-NLS-1$ |
| } |
| this.configurationProvider = configurationProvider; |
| } |
| |
| /** |
| * Adds the Actions to the given IMenuManager, which is displayed as a |
| * context-menu. |
| * |
| * @param manager |
| * the manager |
| * @see ContextMenuProvider#buildContextMenu(IMenuManager) |
| */ |
| @Override |
| public void buildContextMenu(IMenuManager manager) { |
| GEFActionConstants.addStandardActionGroups(manager); |
| |
| addDefaultMenuGroupUndo(manager); |
| addDefaultMenuGroupSave(manager); |
| addDefaultMenuGroupEdit(manager); |
| addDefaultMenuGroupPrint(manager); |
| addDefaultMenuGroupRest(manager); |
| } |
| |
| // ====================== add default menu-groups ========================= |
| |
| /** |
| * Adds the default menu group undo. |
| * |
| * @param manager |
| * the manager |
| */ |
| protected void addDefaultMenuGroupUndo(IMenuManager manager) { |
| addActionToMenu(manager, ActionFactory.UNDO.getId(), GEFActionConstants.GROUP_UNDO); |
| addActionToMenu(manager, ActionFactory.REDO.getId(), GEFActionConstants.GROUP_UNDO); |
| } |
| |
| /** |
| * Adds the default menu group save. |
| * |
| * @param manager |
| * the manager |
| */ |
| protected void addDefaultMenuGroupSave(IMenuManager manager) { |
| addActionToMenu(manager, SaveImageAction.ACTION_ID, GEFActionConstants.GROUP_SAVE); |
| } |
| |
| /** |
| * Adds the default menu group edit. |
| * |
| * @param manager |
| * the manager |
| */ |
| protected void addDefaultMenuGroupEdit(IMenuManager manager) { |
| addActionToMenuIfAvailable(manager, ActionFactory.COPY.getId(), GEFActionConstants.GROUP_EDIT); |
| addActionToMenuIfAvailable(manager, ActionFactory.PASTE.getId(), GEFActionConstants.GROUP_EDIT); |
| } |
| |
| /** |
| * Adds the default menu group print. |
| * |
| * @param manager |
| * the manager |
| */ |
| protected void addDefaultMenuGroupPrint(IMenuManager manager) { |
| IFeatureProvider fp = configurationProvider.getDiagramTypeProvider().getFeatureProvider(); |
| if (fp != null) { |
| IPrintFeature pf = fp.getPrintFeature(); |
| |
| if (pf != null) { |
| addActionToMenu(manager, ActionFactory.PRINT.getId(), GEFActionConstants.GROUP_PRINT); |
| } |
| } |
| } |
| |
| /** |
| * Adds the default menu group rest. |
| * |
| * @param manager |
| * the manager |
| */ |
| protected void addDefaultMenuGroupRest(IMenuManager manager) { |
| addAlignmentSubMenu(manager, GEFActionConstants.GROUP_REST); |
| |
| addActionToMenuIfAvailable(manager, UpdateAction.ACTION_ID, GEFActionConstants.GROUP_REST); |
| addActionToMenuIfAvailable(manager, RemoveAction.ACTION_ID, GEFActionConstants.GROUP_REST); |
| addActionToMenuIfAvailable(manager, DeleteAction.ACTION_ID, GEFActionConstants.GROUP_REST); |
| |
| PictogramElement pes[] = getEditor().getSelectedPictogramElements(); |
| ICustomContext context = new CustomContext(pes); |
| |
| boolean diagramSelected = false; |
| if (pes.length == 1) { |
| extendCustomContext(pes[0], (CustomContext) context); |
| if (pes[0] instanceof Diagram) { |
| diagramSelected = true; |
| } |
| } |
| |
| IToolBehaviorProvider tb = configurationProvider.getDiagramTypeProvider().getCurrentToolBehaviorProvider(); |
| |
| IContextMenuEntry[] contextMenuEntries = tb.getContextMenu(context); |
| |
| if (GFPreferences.getInstance().areDebugActionsActive()) { |
| IFeatureProvider fp = configurationProvider.getDiagramTypeProvider().getFeatureProvider(); |
| ContextMenuEntry debugEntry = new ContextMenuEntry(null, context); |
| debugEntry.setText("Debug"); //$NON-NLS-1$ |
| debugEntry.setSubmenu(true); |
| debugEntry.add(new ContextMenuEntry(new DebugFeature(fp, DebugFeature.TYPE_DUMP_FIGURE_DATA), context)); |
| if (diagramSelected) { |
| debugEntry.add(new ContextMenuEntry(new DebugFeature(fp, |
| DebugFeature.TYPE_DUMP_FIGURE_INCL_CONNECTION_DATA), context)); |
| } |
| debugEntry.add(new ContextMenuEntry(new DebugFeature(fp, DebugFeature.TYPE_DUMP_PICTOGRAM_DATA), context)); |
| debugEntry.add(new ContextMenuEntry(new DebugFeature(fp, DebugFeature.TYPE_DUMP_EDIT_PART_DATA), context)); |
| debugEntry.add(new ContextMenuEntry(new DebugFeature(fp, DebugFeature.TYPE_DUMP_ALL), context)); |
| debugEntry.add(new ContextMenuEntry(new DebugFeature(fp, DebugFeature.TYPE_REFRESH), context)); |
| IContextMenuEntry[] contextMenuEntries2 = new IContextMenuEntry[contextMenuEntries.length + 1]; |
| System.arraycopy(contextMenuEntries, 0, contextMenuEntries2, 0, contextMenuEntries.length); |
| contextMenuEntries2[contextMenuEntries2.length - 1] = debugEntry; |
| contextMenuEntries = contextMenuEntries2; |
| } |
| |
| addEntries(manager, contextMenuEntries, context, GEFActionConstants.GROUP_REST, null); |
| } |
| |
| private void addEntries(IMenuManager manager, IContextMenuEntry[] contextMenuEntries, ICustomContext context, String groupID, |
| String textParentEntry) { |
| |
| for (int i = 0; i < contextMenuEntries.length; i++) { |
| IContextMenuEntry cmEntry = contextMenuEntries[i]; |
| String text = cmEntry.getText(); |
| if (cmEntry.getChildren().length == 0) { |
| IFeature feature = cmEntry.getFeature(); |
| if (feature instanceof ICustomFeature && feature.isAvailable(context)) { |
| IAction action = new CustomAction((ICustomFeature) feature, context, |
| configurationProvider.getDiagramBehavior()); |
| if (textParentEntry != null) { |
| text = textParentEntry + " " + text; //$NON-NLS-1$ |
| } |
| action.setText(text); |
| action.setDescription(cmEntry.getDescription()); |
| ImageDescriptor image = GraphitiUi.getImageService().getImageDescriptorForId( |
| configurationProvider.getDiagramTypeProvider().getProviderId(), cmEntry.getIconId()); |
| action.setImageDescriptor(image); |
| appendContributionItem(manager, groupID, new ActionContributionItem(action)); |
| } |
| } else { |
| if (cmEntry.isSubmenu()) { |
| |
| MenuManager subMenu = new MenuManager(text); |
| addEntries(subMenu, cmEntry.getChildren(), context, null, null); |
| if (!subMenu.isEmpty()) { |
| appendContributionItem(manager, groupID, subMenu); |
| } |
| } else { |
| appendContributionItem(manager, groupID, new Separator()); |
| addEntries(manager, cmEntry.getChildren(), context, groupID, text); |
| appendContributionItem(manager, groupID, new Separator()); |
| } |
| } |
| } |
| } |
| |
| private void appendContributionItem(IMenuManager manager, String groupID, IContributionItem contributionItem) { |
| if (groupID != null) { |
| manager.appendToGroup(groupID, contributionItem); |
| } else { |
| manager.add(contributionItem); |
| } |
| } |
| |
| // ====================== add single menu-entries ========================= |
| |
| private void extendCustomContext(PictogramElement pe, CustomContext context) { |
| Point location = getEditor().getMouseLocation(); |
| int mX = location.x; |
| int mY = location.y; |
| context.setX(mX); |
| context.setY(mY); |
| |
| if (pe instanceof Shape && !(pe instanceof Diagram)) { |
| GraphicsAlgorithm ga = pe.getGraphicsAlgorithm(); |
| if (ga != null) { |
| ILocation relLocation = Graphiti.getPeService().getLocationRelativeToDiagram((Shape) pe); |
| int x = relLocation.getX(); |
| int y = relLocation.getY(); |
| int width = ga.getWidth(); |
| int height = ga.getHeight(); |
| |
| if (mX > x && mX < x + width && mY > y && mY < y + height) { |
| int relativeX = mX - x; |
| int relativeY = mY - y; |
| ILocationInfo locationInfo = Graphiti.getLayoutService().getLocationInfo((Shape) pe, relativeX, relativeY); |
| context.setInnerPictogramElement(locationInfo.getShape()); |
| context.setInnerGraphicsAlgorithm(locationInfo.getGraphicsAlgorithm()); |
| } |
| } |
| } else if (pe instanceof CompositeConnection) { |
| List<?> selectedEditParts = getViewer().getSelectedEditParts(); |
| for (Object object : selectedEditParts) { |
| if (object instanceof CompositeConnectionEditPart) { |
| // Retrieve child selection info from the edit part |
| CompositeConnectionEditPart compEditPart = (CompositeConnectionEditPart) object; |
| org.eclipse.graphiti.ui.internal.parts.ConnectionEditPart originallySelectedChildConnection = compEditPart |
| .getOriginallySelectedChild(); |
| if (originallySelectedChildConnection != null) { |
| // and provide the originally selection child connection |
| // as inner PE |
| Connection connectionPicto = (Connection) originallySelectedChildConnection.getModel(); |
| context.setInnerGraphicsAlgorithm(connectionPicto.getGraphicsAlgorithm()); |
| context.setInnerPictogramElement(connectionPicto); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Adds the alignment sub menu. |
| * |
| * @param manager |
| * the manager |
| * @param group |
| * the group |
| */ |
| protected void addAlignmentSubMenu(IMenuManager manager, String group) { |
| IAction action; |
| MenuManager alignmentSubMenu = new MenuManager(Messages.GraphicsContextMenuProvider_0_xmen); |
| |
| action = this.actionRegistry.getAction(GEFActionConstants.ALIGN_LEFT); |
| if (action != null && action.isEnabled()) { |
| alignmentSubMenu.add(action); |
| } |
| |
| action = this.actionRegistry.getAction(GEFActionConstants.ALIGN_CENTER); |
| if (action != null && action.isEnabled()) { |
| alignmentSubMenu.add(action); |
| } |
| |
| action = this.actionRegistry.getAction(GEFActionConstants.ALIGN_RIGHT); |
| if (action != null && action.isEnabled()) { |
| alignmentSubMenu.add(action); |
| } |
| |
| action = this.actionRegistry.getAction(GEFActionConstants.ALIGN_TOP); |
| if (action != null && action.isEnabled()) { |
| alignmentSubMenu.add(action); |
| } |
| |
| action = this.actionRegistry.getAction(GEFActionConstants.ALIGN_MIDDLE); |
| if (action != null && action.isEnabled()) { |
| alignmentSubMenu.add(action); |
| } |
| |
| action = this.actionRegistry.getAction(GEFActionConstants.ALIGN_BOTTOM); |
| if (action != null && action.isEnabled()) { |
| alignmentSubMenu.add(action); |
| } |
| |
| action = this.actionRegistry.getAction(GEFActionConstants.MATCH_WIDTH); |
| if (action != null && action.isEnabled()) { |
| alignmentSubMenu.add(action); |
| } |
| |
| action = this.actionRegistry.getAction(GEFActionConstants.MATCH_HEIGHT); |
| if (action != null && action.isEnabled()) { |
| alignmentSubMenu.add(action); |
| } |
| |
| if (!alignmentSubMenu.isEmpty()) { |
| manager.appendToGroup(group, alignmentSubMenu); |
| } |
| } |
| |
| /** |
| * Adds the action to menu. |
| * |
| * @param manager |
| * the manager |
| * @param actionId |
| * the action id |
| * @param menuGroup |
| * the menu group |
| */ |
| protected void addActionToMenu(IMenuManager manager, String actionId, String menuGroup) { |
| IAction action; |
| action = this.actionRegistry.getAction(actionId); |
| if (action != null && action.isEnabled()) { |
| manager.appendToGroup(menuGroup, action); |
| } |
| } |
| |
| /** |
| * Adds the action to menu if available. |
| * |
| * @param manager |
| * the manager |
| * @param actionId |
| * the action id |
| * @param menuGroup |
| * the menu group |
| */ |
| protected void addActionToMenuIfAvailable(IMenuManager manager, String actionId, String menuGroup) { |
| IAction action = this.actionRegistry.getAction(actionId); |
| if (action instanceof IAvailable) { |
| if (((IAvailable) action).isAvailable()) { |
| manager.appendToGroup(menuGroup, action); |
| // For Update Actions we have to trigger a refresh of the |
| // enablement, also if no selection change occurred: |
| //e.g. update was triggered, then update has to be disabled. |
| if (action instanceof UpdateAction) { |
| UpdateAction updateAction = (UpdateAction) action; |
| updateAction.setEnabled(updateAction.isEnabled()); |
| } |
| } |
| } |
| } |
| |
| @Override |
| protected boolean allowItem(IContributionItem itemToAdd) { |
| boolean ret = super.allowItem(itemToAdd); |
| if (ret) { |
| String itemId = itemToAdd.getId(); |
| if (itemId != null) { |
| if (itemId.startsWith("org.eclipse.debug.ui.contextualLaunch.")) { //$NON-NLS-1$ |
| return false; |
| } |
| } |
| } |
| return ret; |
| } |
| |
| private DiagramBehavior getEditor() { |
| return configurationProvider.getDiagramBehavior(); |
| } |
| } |