code: /*--------------------------------------------------------------*
    Copyright (C) 2006-2015 OpenSim Ltd.
  
    This file is distributed WITHOUT ANY WARRANTY. See the file
    'License' for details on this and other legal matters.
  *--------------------------------------------------------------*/
  
  package org.omnetpp.ned.editor.graph.actions;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import org.eclipse.draw2d.PositionConstants;
  import org.eclipse.gef.ui.actions.ActionRegistry;
  import org.eclipse.gef.ui.actions.AlignmentRetargetAction;
  import org.eclipse.gef.ui.actions.GEFActionConstants;
  import org.eclipse.gef.ui.actions.MatchHeightRetargetAction;
  import org.eclipse.gef.ui.actions.MatchWidthRetargetAction;
  import org.eclipse.gef.ui.actions.RedoRetargetAction;
  import org.eclipse.gef.ui.actions.UndoRetargetAction;
  import org.eclipse.gef.ui.actions.ZoomInRetargetAction;
  import org.eclipse.gef.ui.actions.ZoomOutRetargetAction;
  import org.eclipse.jface.action.IAction;
  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.ui.IActionBars;
  import org.eclipse.ui.IEditorPart;
  import org.eclipse.ui.IWorkbenchActionConstants;
  import org.eclipse.ui.actions.ActionFactory;
  import org.eclipse.ui.actions.RetargetAction;
  import org.eclipse.ui.part.EditorActionBarContributor;
  
  /**
   * Adds Graphical NED editor actions to the action bar.
   * It is a copy of the original GEF ActionBarContributor because of the NPE issue if a non-GEF editor
   * gets activated. Once it is fixed in GEF their class can be derived from ActionBarContributor
   *
   * @author rhornig
   */
  public class GNedActionBarContributor extends EditorActionBarContributor {
  
      private ActionRegistry registry = new ActionRegistry();
  
      /**
       * Contains the {@link RetargetAction}s that are registered as global action handlers.  We
       * need to hold on to these so that we can remove them as PartListeners in dispose().
       */
      private List<RetargetAction> retargetActions = new ArrayList<RetargetAction>();
      private final List<String> globalActionKeys = new ArrayList<String>();
  
      /**
       * Adds the given action to the action registry.
       *
       * @param action the action to add
       */
      protected void addAction(IAction action) {
          getActionRegistry().registerAction(action);
      }
  
      /**
       * Indicates the existence of a global action identified by the specified key. This global
       * action is defined outside the scope of this contributor, such as the Workbench's undo
       * action, or an action provided by a workbench ActionSet. The list of global action keys
       * is used whenever the active editor is changed ({@link #setActiveEditor(IEditorPart)}).
       * Keys provided here will result in corresponding actions being obtained from the active
       * editor's <code>ActionRegistry</code>, and those actions will be registered with the
       * ActionBars for this contributor. The editor's action handler and the global action must
       * have the same key.
       *
       * @param key the key identifying the global action
       */
      protected void addGlobalActionKey(String key) {
          globalActionKeys.add(key);
      }
  
      /**
       * Adds the specified RetargetAction to this contributors <code>ActionRegistry</code>. The
       * RetargetAction is also added as a <code>IPartListener</code> of the contributor's page.
       * Also, the retarget action's ID is flagged as a global action key, by calling {@link
       * #addGlobalActionKey(String)}.
       *
       * @param action the retarget action being added
       */
      protected void addRetargetAction(RetargetAction action) {
          addAction(action);
          retargetActions.add(action);
          getPage().addPartListener(action);
          addGlobalActionKey(action.getId());
      }
  
  
      /**
       * Disposes the contributor. Removes all {@link RetargetAction}s that were {@link
       * org.eclipse.ui.IPartListener}s on the {@link org.eclipse.ui.IWorkbenchPage} and
       * disposes them. Also disposes the action registry.
       * <P>
       * Subclasses may extend this method to perform additional cleanup.
       * @see org.eclipse.ui.part.EditorActionBarContributor#dispose()
       */
      @Override
      public void dispose() {
          for (RetargetAction action : retargetActions ) {
              getPage().removePartListener(action);
              action.dispose();
          }
          registry.dispose();
          retargetActions = null;
          registry = null;
      }
  
      /**
       * Retrieves an action from the action registry using the given ID,
       * or null if not found.
       */
      protected IAction getAction(String id) {
          return getActionRegistry().getAction(id);
      }
  
      /**
       * Returns this contributor's ActionRegsitry.
       */
      protected ActionRegistry getActionRegistry() {
          return registry;
      }
  
      /* (non-Javadoc)
       * @see EditorActionBarContributor#init(IActionBars)
       */
      @Override
      public void init(IActionBars bars) {
          buildActions();
          declareGlobalActionKeys();
          super.init(bars);
      }
  
      /* (non-Javadoc)
       * @see org.eclipse.ui.IEditorActionBarContributor#setActiveEditor(IEditorPart)
       */
      @Override
      public void setActiveEditor(IEditorPart editor) {
          ActionRegistry registry = (ActionRegistry)editor.getAdapter(ActionRegistry.class);
          IActionBars bars = getActionBars();
          for (int i = 0; i < globalActionKeys.size(); i++) {
              String id = globalActionKeys.get(i);
              // XXX fix for the NPE if non GEF editor is activated (in that case the global
              // actions should be removed)
              IAction action = registry == null ? null : registry.getAction(id);
              // end fix
              bars.setGlobalActionHandler(id, action);
          }
      }
  
      /* (non-Javadoc)
       * @see org.eclipse.gef.ui.actions.ActionBarContributor#buildActions()
       */
      protected void buildActions() {
          addRetargetAction(new UndoRetargetAction());
          addRetargetAction(new RedoRetargetAction());
  
          RetargetAction retAction;
          addRetargetAction(retAction = new RetargetAction(TogglePinAction.ID, TogglePinAction.MENUNAME, IAction.AS_CHECK_BOX));
          retAction.setToolTipText(TogglePinAction.TOOLTIP);
          retAction.setImageDescriptor(TogglePinAction.IMAGE);
          addRetargetAction(retAction = new RetargetAction(RelayoutAction.ID, RelayoutAction.MENUNAME));
          retAction.setToolTipText(RelayoutAction.TOOLTIP);
          retAction.setImageDescriptor(RelayoutAction.IMAGE);
  
          addRetargetAction(new AlignmentRetargetAction(PositionConstants.LEFT));
          addRetargetAction(new AlignmentRetargetAction(PositionConstants.CENTER));
          addRetargetAction(new AlignmentRetargetAction(PositionConstants.RIGHT));
          addRetargetAction(new AlignmentRetargetAction(PositionConstants.TOP));
          addRetargetAction(new AlignmentRetargetAction(PositionConstants.MIDDLE));
          addRetargetAction(new AlignmentRetargetAction(PositionConstants.BOTTOM));
  
          addRetargetAction(new ZoomInRetargetAction());
          addRetargetAction(new ZoomOutRetargetAction());
  
          addRetargetAction(new MatchWidthRetargetAction());
          addRetargetAction(new MatchHeightRetargetAction());
  
          addRetargetAction(retAction = new RetargetAction(ToggleSnapToGeometryAction.ID, ToggleSnapToGeometryAction.MENUNAME,
                  IAction.AS_CHECK_BOX));
          retAction.setToolTipText(ToggleSnapToGeometryAction.TOOLTIP);
          retAction.setImageDescriptor(ToggleSnapToGeometryAction.IMAGE);
  
      }
  
      /* (non-Javadoc)
       * @see org.eclipse.gef.ui.actions.ActionBarContributor#declareGlobalActionKeys()
       */
      protected void declareGlobalActionKeys() {
          addGlobalActionKey(ActionFactory.PRINT.getId());
          addGlobalActionKey(ActionFactory.SELECT_ALL.getId());
          addGlobalActionKey(ActionFactory.DELETE.getId());
          addGlobalActionKey(ActionFactory.CUT.getId());
          addGlobalActionKey(ActionFactory.COPY.getId());
          addGlobalActionKey(ActionFactory.PASTE.getId());
      }
  
      /* (non-Javadoc)
       * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToToolBar(IToolBarManager)
       */
      @Override
      public void contributeToToolBar(IToolBarManager tbm) {
          tbm.add(getAction(ActionFactory.UNDO.getId()));
          tbm.add(getAction(ActionFactory.REDO.getId()));
  
          tbm.add(new Separator());
          tbm.add(getAction(TogglePinAction.ID));
          tbm.add(getAction(RelayoutAction.ID));
  
      }
  
      /* (non-Javadoc)
       * @see org.eclipse.ui.part.EditorActionBarContributor#contributeToMenu(IMenuManager)
       */
      @Override
      public void contributeToMenu(IMenuManager menubar) {
  
          MenuManager viewMenu = new MenuManager("&View");
          viewMenu.add(getAction(GEFActionConstants.ZOOM_IN));
          viewMenu.add(getAction(GEFActionConstants.ZOOM_OUT));
          viewMenu.add(new Separator());
          viewMenu.add(getAction(ToggleSnapToGeometryAction.ID));
          viewMenu.add(new Separator());
          viewMenu.add(getAction(GEFActionConstants.ALIGN_LEFT));
          viewMenu.add(getAction(GEFActionConstants.ALIGN_CENTER));
          viewMenu.add(getAction(GEFActionConstants.ALIGN_RIGHT));
          viewMenu.add(new Separator());
          viewMenu.add(getAction(GEFActionConstants.ALIGN_TOP));
          viewMenu.add(getAction(GEFActionConstants.ALIGN_MIDDLE));
          viewMenu.add(getAction(GEFActionConstants.ALIGN_BOTTOM));
          viewMenu.add(new Separator());
          viewMenu.add(getAction(GEFActionConstants.MATCH_WIDTH));
          viewMenu.add(getAction(GEFActionConstants.MATCH_HEIGHT));
  
          // adds a VIEW menu to the main toolbar
          menubar.insertAfter(IWorkbenchActionConstants.M_EDIT, viewMenu);
      }
  
  }
  