Package org.cishell.reference.gui.menumanager.menu

Source Code of org.cishell.reference.gui.menumanager.menu.MenuAdapter

/* ****************************************************************************
* CIShell: Cyberinfrastructure Shell, An Algorithm Integration Framework.
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Apache License v2.0 which accompanies
* this distribution, and is available at:
* http://www.apache.org/licenses/LICENSE-2.0.html
*
* Created on Jun 16, 2006 at Indiana University.
*
* Contributors:
*     Indiana University -
* ***************************************************************************/
package org.cishell.reference.gui.menumanager.menu;

import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.cishell.framework.CIShellContext;
import org.cishell.framework.algorithm.AlgorithmFactory;
import org.cishell.framework.algorithm.AlgorithmProperty;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
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.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.log.LogService;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


public class MenuAdapter implements AlgorithmProperty {
  public static final String DEFAULT_MENU_FILE_NAME = "default_menu.xml";

  // Tags in DEFAULT_MENU_FILE_NAME.
    public static final String TAG_TOP_MENU = "top_menu";
    public static final String TAG_MENU = "menu";   
    public static final String TYPE_ATTRIBUTE = "type";
    public static final String NAME_ATTRIBUTE = "name";
    public static final String PID_ATTRIBUTE = "pid";
    public static final String PRESERVED_GROUP = "group";
    public static final String PRESERVED_BREAK = "break";
    public static final String PRESERVED_EXIT = "Exit";
    public static final String PRESERVED_SERVICE_PID = "service.pid";
    public static final String PRESERVED = "preserved";

    public static final String HELP_DESK_EMAIL_ADDRESS = "nwb-helpdesk@googlegroups.com";

    private String toolName;
    private String toolTicketURL;
    private IMenuManager menuManager;
    private Shell shell;
    private BundleContext bundleContext;
    private CIShellContext ciShellContext;
    private Map<String, Action> algorithmsToActions;
    private Map<Action, IMenuManager> actionsToMenuManagers;
    private ContextListener contextListener;
    private IWorkbenchWindow workbenchWindow;
    private LogService logger;
    /*
     * This map holds a pid as a key and the corresponding ServiceReference as a value.
     * It is built when preprocessServiceBundles() is invoked.
     * Then the entries are gradually removed when the pids are specified in
     *  DEFAULT_MENU_FILE_NAME.
     * If any entries are left, in processLeftServiceBundles(), those plug-ins that have specified
     *  the menu_path and label but are not listed in DEFAULT_MENU_FILE_NAME will be added on to
     *  the menu.
     */
    private Map<String, ServiceReference> pidsToServiceReferences;
    /*
     * This is the exactly same copy of pidsToServiceReferences.
     * Since some plug-ins could display on menu more than once, it provides a map between a pid
     *  and a serviceReference while in pidsToServiceReferences that pid has been removed.
     */
    private Map<String, ServiceReference> pidsToServiceReferencesCopy;
    private Document documentObjectModel;

    private Runnable updateAction = new Runnable() {
        public void run() {
            MenuAdapter.this.menuManager.updateAll(true);
        }
    };

    private Runnable stopAction = new Runnable() {
        public void run() {
            String[] algorithmKeys =
              MenuAdapter.this.algorithmsToActions.keySet().toArray(new String[]{});
           
            for (int ii = 0; ii < algorithmKeys.length; ii++) {
                Action item = MenuAdapter.this.algorithmsToActions.get(algorithmKeys[ii]);
                IMenuManager targetMenu = MenuAdapter.this.actionsToMenuManagers.get(item);
               
                targetMenu.remove(item.getId());
                MenuAdapter.this.algorithmsToActions.remove(algorithmKeys[ii]);
                MenuAdapter.this.actionsToMenuManagers.remove(item);
            }
        }       
    };

    public MenuAdapter(
        String toolName,
        String toolTicketURL,
        IMenuManager menuManager,
        Shell shell,
            BundleContext bundleContext,
            CIShellContext ciShellContext,
            IWorkbenchWindow workbenchWindow) {
      this.toolName = toolName;
      this.toolTicketURL = toolTicketURL;
        this.menuManager = menuManager;
        this.shell = shell;
        this.bundleContext = bundleContext;
        this.ciShellContext = ciShellContext;
        this.workbenchWindow = workbenchWindow;
        this.algorithmsToActions = new HashMap<String, Action>();
        this.actionsToMenuManagers = new HashMap<Action, IMenuManager>();
        this.pidsToServiceReferences = new HashMap<String, ServiceReference>();
        this.pidsToServiceReferencesCopy = new HashMap<String, ServiceReference>();
        this.logger = (LogService) this.ciShellContext.getService(LogService.class.getName());

        /*
       * The intention of this clearShortcuts was to programmatically clear all of the
       *  bound shortcuts, so any found in our own plugins wouldn't have conflicts.
       * Doing this doesn't immediately seem very possible, though there may be some promise in
       *  "redirecting" the actions taken by the shortcuts.
       * (See: http://dev.eclipse.org/newslists/news.eclipse.platform/msg79882.html )
       * As a note, the keyboard shortcuts are actually called accelerator key codes, and the
       *  machinery that makes them work is very deeply ingrained in Eclipse.
       * The difficulties I faced with trying to clear already-bound shortcuts has led me to
       *  suspect three possible things:
       *   We may be "abusing" Eclipse by using it as the foundation for our own applications.
       *   There may be a way to customize/configure (or interface with) the culprit plugin
       *    that's binding the shortcuts before us (org.eclipse.ui.workbench).  This seems to be
       *    highly-likely, and more research on the matter can probably be justified at
       *    some point.
       *   The intended way TO work around the shortcuts already being bound is to redirect the
       *    actions taken by them, as mentioned above.
       * Either way, to get these shortcuts working, I'm just going to use non-standard key
       *  combinations.
       */
        //clearShortcuts();

        /*
         * Appears to add a context listener which updates the menu item whenever a corresponding
         *  change occurs in the bundle (registers, unregisters, etc...).
         */
        String filter = "(" + Constants.OBJECTCLASS + "=" + AlgorithmFactory.class.getName() + ")";
        this.contextListener = new ContextListener();

        try {
            bundleContext.addServiceListener(this.contextListener, filter);
            preprocessServiceBundles();
            String applicationLocation = System.getProperty("osgi.configuration.area");
        
            /*
             * Comments below refer to problems with earlier versions of this document.
             * Keeping these around for now, as well as the system.out.printlns, until we are sure
             *  that the current fix works.
             */
           
            /*
             * This is a temporary fix. A bit complex to explain the observation I got so far.
             * On Windows XP,
             *  app_location =
             *   file:/C:/Documents and Settings/huangb/Desktop/nwb-sept4/nwb/configuration/
             * If I didn't trim "file:/", on some windows machines
             *  new File(fileFullpath).exists()
             *  will return false, and initializaMenu() will be invoked.
             * When initializaMenu() is invoked, not all required top menus will show up.
             * So either Bruce code or Tim's fix has some problems. Can not append top menu such as
             *  Tools-->Scheduler if Tools is not specified in the XML.
             * If pass trimmed file path
             *  C:/Documents and Settings/huangb/Desktop/nwb-sept4/nwb/configuration/
             *  to createMenuFromXML, on some machines,
             *  URL = C:/Documents and Settings/huangb/Desktop/nwb-sept4/nwb/configuration/
             *  is a bad one, and can not create a document builder instance and the
             *  DOM representation of the XML file.
             *
             * This piece of code needs to be reviewed and refactored!!!
       */
           
            /*
             * Better to use System.err, since it prints the stream immediately instead of storing
             *  it in a buffer which might be lost if there is a crash.
             */
            String fileFullPath = applicationLocation + DEFAULT_MENU_FILE_NAME;
            URL configurationDirectoryURL = new URL(fileFullPath);

            try {
              configurationDirectoryURL.getContent();
              //System.out.println(">>>config.ini Exists!");
              createMenuFromXML(fileFullPath);
              processLeftServiceBundles()
            } catch (IOException ioException) {
              ioException.printStackTrace();
              //System.err.println("config.ini does not exist... Reverting to backup plan");
              initializeMenu();
            }

            Display.getDefault().asyncExec(this.updateAction);
        } catch (InvalidSyntaxException invalidSyntaxException) {
          // TODO: Improve this error message.  "Invalid Syntax" is terrible!
            this.logger.log(LogService.LOG_DEBUG, "Invalid Syntax", invalidSyntaxException);
        } catch (Throwable exception) {
          /*
           * TODO: Improve this.
           * Should catch absolutely everything catchable. Will hopefully reveal the error coming
           *  out of the URI constructor.
           * No time to test today, just commiting this for testing later.
           */
          exception.printStackTrace();
        }
    }
       
    /*
     * This method scans all service bundles. If a bundle specifies  menu_path and label,
     *  get service.pid of this bundle (key), let the service reference as the value, and put
     *  key/value pair  to pidsToServiceReferences for further processing.
     */
    private void preprocessServiceBundles() throws InvalidSyntaxException {
        ServiceReference[] serviceReferences =
          this.bundleContext.getAllServiceReferences(AlgorithmFactory.class.getName(), null);

        if (serviceReferences != null){
          for (int ii = 0; ii < serviceReferences.length; ii++) {
            String path = (String)serviceReferences[ii].getProperty(MENU_PATH);

            if (path == null) {
              continue;
            } else {      
              String pid = (String)serviceReferences[ii].getProperty(PRESERVED_SERVICE_PID);
              this.pidsToServiceReferences.put(pid.toLowerCase().trim(), serviceReferences[ii]);
              this.pidsToServiceReferencesCopy.put(
                pid.toLowerCase().trim(), serviceReferences[ii]);
            }
          }
        }
    }
    /*
     * Parse DEFAULT_MENU_FILE_NAME file.
     * For each menu node, get the value of the attribute pid.
     * Check if the pid exists in pidsToServiceReferences.
     * If so, get the action and add to the parent menu.
     * If not, ignore this menu.
     * At the end of each top menu or subgroup menu or before help menu,  add "additions" so that
     *  new algorithms can be added on later.
     *
     * What is the reasonable logic?
     * If a plug-in has been specified in the DEFAULT_MENU_FILE_NAME, always use that menu layout
     * If a plug-in specified in the DEFAULT_MENU_FILE_NAME, use the menu_path specified in the
     *  properties file.
     * If a plug-in specifies a label in the properties file, always use it.
     */
    private void createMenuFromXML(String menuFilePath) throws InvalidSyntaxException{
      parseXMLFile(menuFilePath);     
      // Get the root elememt.
    Element documentElement = this.documentObjectModel.getDocumentElement();
     
    // Get a nodelist of the top menu elements.
    NodeList topMenuList = documentElement.getElementsByTagName(TAG_TOP_MENU);

    if ((topMenuList != null) && (topMenuList.getLength() > 0)) {
      for (int ii = 0; ii < topMenuList.getLength(); ii++) {       
        Element element = (Element)topMenuList.item(ii);
        processTopMenu(element);       
      }
    }     
    } 
   
    private void processTopMenu(Element topMenuNode) {
      /* 
       * The File and Help menus are created in ApplicationActionBarAdvisor.java.
       * This function now parses the XML file and appends the new menus/menu items to the
       *  correct group.
       * We first check to see if the menu already exists in our MenuBar.
       * If it does, we modify the already existing menu. If not, then we create a new Menu.
       *
       * Additional code at: org.cishell.reference.gui.workspace.ApplicationActionBarAdvisor.java
       */
     
      String topMenuName = topMenuNode.getAttribute(NAME_ATTRIBUTE);
      MenuManager topMenuBar = (MenuManager)this.menuManager.findUsingPath(topMenuName);

      if (topMenuBar == null) {
        topMenuBar = new MenuManager(topMenuName, topMenuName.toLowerCase());
        this.menuManager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, topMenuBar);
      }
     
      // Second process submenu.
      processSubMenu(topMenuNode, topMenuBar);
    }
   
    /*
     * Recursively process sub menu and group menu.
     */
    private void processSubMenu(Element menuNode, MenuManager parentMenuBar){
      NodeList subMenuList =  menuNode.getElementsByTagName(TAG_MENU);

      if ((subMenuList != null) && (subMenuList.getLength() > 0)) {
        for (int ii = 0; ii < subMenuList.getLength(); ii++) {     
        Element element = (Element)subMenuList.item(ii);
       
        /*
         * Only process direct children nodes and drop all grand or grand of grand
         *  children nodes.
         * TODO: Why?
         */
        if (!element.getParentNode().equals(menuNode)) {
          continue;
        }

        String menuType = element.getAttribute(TYPE_ATTRIBUTE);
        String algorithmPID = element.getAttribute(PID_ATTRIBUTE);

        if (((menuType == null) || (menuType.length() == 0)) && (algorithmPID != null)) {
          processAMenuNode(element, parentMenuBar);
        } else if (menuType.equalsIgnoreCase(PRESERVED_GROUP)) {
          String groupName = element.getAttribute(NAME_ATTRIBUTE);
          MenuManager groupMenuBar = new MenuManager(groupName, groupName.toLowerCase());
          parentMenuBar.add(groupMenuBar);
          processSubMenu(element, groupMenuBar);         
        }       
        else if (menuType.equalsIgnoreCase(PRESERVED_BREAK)){ 
          /*
           * It seems that the framework automatically takes care of issues such as
           *  double separators and a separator at the top or bottom.
           */         
          parentMenuBar.add(new Separator());
        }
        else if (menuType.equalsIgnoreCase(PRESERVED)){
          String menuName = element.getAttribute(NAME_ATTRIBUTE);
          if(menuName.equalsIgnoreCase(PRESERVED_EXIT) ){
            //allow to add more menu before "File/Exit" 
            if(parentMenuBar.getId().equalsIgnoreCase(IWorkbenchActionConstants.M_FILE)){
            parentMenuBar.add(new GroupMarker(START_GROUP));
            parentMenuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
            parentMenuBar.add(new GroupMarker(END_GROUP));
            }
            IWorkbenchAction exitAction = ActionFactory.QUIT.create(workbenchWindow);
            parentMenuBar.add(new Separator());
            parentMenuBar.add(exitAction);           
          }
        }
      }
      //allow to append new submenu(s) at the bottom under each top menu
      //except "File" and "Help"
      if(!parentMenuBar.getId().equalsIgnoreCase(IWorkbenchActionConstants.M_FILE)&&
         !parentMenuBar.getId().equalsIgnoreCase(IWorkbenchActionConstants.M_HELP))     
      {     
        parentMenuBar.add(new GroupMarker(START_GROUP));
        parentMenuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
        parentMenuBar.add(new GroupMarker(END_GROUP));
      }
      }
    }

    /*
     * TODO: Better name?
     * Process a menu (algorithm). 
     */
    private void processAMenuNode(Element menuNode, MenuManager parentMenuBar) {
     String menuName = menuNode.getAttribute(NAME_ATTRIBUTE);
    String pid = menuNode.getAttribute(PID_ATTRIBUTE);

    if ((pid == null) || (pid.length() == 0)) {
      /*
       * TODO: Check if the name is one of the preserved one, and add the default action if
       *  it is?
       */
    } else {
      // Check if the PID has registered in pidsToServiceReferences.
      if (this.pidsToServiceReferencesCopy.containsKey(pid.toLowerCase().trim())){
        ServiceReference serviceReference =
          this.pidsToServiceReferencesCopy.get(pid.toLowerCase().trim());
        this.pidsToServiceReferences.remove(pid.toLowerCase().trim());
          AlgorithmAction action =
            new AlgorithmAction(serviceReference, this.bundleContext, this.ciShellContext);
          String menuLabel = (String)serviceReference.getProperty(LABEL);

          if ((menuName!= null) && (menuName.trim().length() > 0)) {
            // Use the name specified in the XML to overwrite the label.
            action.setText(menuName);
            action.setId(getItemID(serviceReference));
            parentMenuBar.add(action);
            handleActionAccelerator(action, parentMenuBar, serviceReference);
          } else {
            if ((menuLabel != null) && (menuLabel.trim().length() > 0)) {
              action.setText(menuLabel);
              action.setId(getItemID(serviceReference));
              parentMenuBar.add(action);
              handleActionAccelerator(action, parentMenuBar, serviceReference);
            } else {
              /*
               * TODO: This is a problem: No label is specified in the plug-in's
               *  properties file and no name is specified in the XML file.
               */
            }
          }
       
      } else {
        String algorithmNotFoundFormat =
          "Oops!  %s tried to place an algorithm with the id '%s' " +
          "on the menu, but the algorithm could not be found.";
        String algorithmNotFoundMessage =
          String.format(algorithmNotFoundFormat, this.toolName, pid);
//        String algorithmNotFoundMessage =
//          "Oops! Network Workbench tried to place an algorithm with the id '" +
//          pid +
//          "' on the menu, but the algorithm could not be found.";
        String contactInformationFormat =
          "If you see this error, please contact %s, " +
          "or post a ticket on our bug tracker at: %s .";
        String contactInformationMessage = String.format(
          contactInformationFormat, HELP_DESK_EMAIL_ADDRESS, this.toolTicketURL);
//        String contactInformationMessage =
//          "If you see this error, please contact nwb-helpdesk@googlegroups.com, or " +
//          "post a ticket on our bug tracker at: " +
//          "http://cns-trac.slis.indiana.edu/trac/nwb .";
        this.logger.log(LogService.LOG_DEBUG, algorithmNotFoundMessage);
        this.logger.log(LogService.LOG_DEBUG, contactInformationMessage);
      }
    }
    }   
   
    private void parseXMLFile(String menuFilePath){
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setCoalescing(true);

    try {
      DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
       
          this.documentObjectModel = documentBuilder.parse(menuFilePath)

    } catch(ParserConfigurationException parserConfigurationException) {
      parserConfigurationException.printStackTrace();
    } catch(SAXException saxException) {
      saxException.printStackTrace();
    } catch(IOException ioException) {
      ioException.printStackTrace();
    }
  }
   
    /*
     * Handle some service bundles that have specified the menu_path and label
     * but not specified in the DEFAULT_MENU_FILE_NAME
     */
    private void processLeftServiceBundles() {
      if (!this.pidsToServiceReferences.isEmpty()){
        for (String key : this.pidsToServiceReferences.keySet()) {
          ServiceReference serviceReference = this.pidsToServiceReferences.get(key);
          makeMenuItem(serviceReference);
        }
//        Object[] keys = this.pidsToServiceReferences.keySet().toArray();
//
//        for (int ii = 0; ii < keys.length; ii++) {
//          ServiceReference serviceReference =
//            (ServiceReference)this.pidsToServiceReferences.get((String)keys[ii]);
//          makeMenuItem(serviceReference);
//        }       
      }       
    }

    private void initializeMenu() throws InvalidSyntaxException {  
        ServiceReference[] serviceReferences = this.bundleContext.getAllServiceReferences(
          AlgorithmFactory.class.getName(), null);
    
     if (serviceReferences != null) {
            for (int ii = 0; ii < serviceReferences.length; ii++) {
                makeMenuItem(serviceReferences[ii]);
            }
        }
    }

    private class ContextListener implements ServiceListener {
        public void serviceChanged(ServiceEvent event) {
            switch (event.getType()) {
            case ServiceEvent.REGISTERED:
                makeMenuItem(event.getServiceReference());

                break;
            case ServiceEvent.UNREGISTERING:
                removeMenuItem(event.getServiceReference());

                break;
            case ServiceEvent.MODIFIED:
                updateMenuItem(event.getServiceReference());

                break;
            }
        }
    }
   
    private void makeMenuItem(ServiceReference serviceReference) {
        String path = (String) serviceReference.getProperty(MENU_PATH);
        String[] items = null;

        if (path != null) {
          items = path.split("/");
        }

        IMenuManager menu = null;

        if ((items != null) && (items.length > 1)) {
            AlgorithmAction action =
              new AlgorithmAction(serviceReference, this.bundleContext, this.ciShellContext);
            action.setId(getItemID(serviceReference));
           
            IMenuManager targetMenu = this.menuManager;
            String group = items[items.length - 1];
           
            for (int ii = 0; ii < items.length - 1; ii++) {
                menu = targetMenu.findMenuUsingPath(items[ii]);
                if ((menu == null) && (items[ii] != null)) {
                    menu = targetMenu.findMenuUsingPath(items[ii].toLowerCase());                 
                }
               
                if (menu == null) {                 
                    menu = createMenu(items[ii], items[ii]);
                    targetMenu.appendToGroup(ADDITIONS_GROUP, menu);
                }
               
                targetMenu = menu;
            }
           
            group = items[items.length - 1];
            IContributionItem groupItem = targetMenu.find(group);
           
            if (groupItem == null) {
                groupItem = new GroupMarker(group);
                targetMenu.appendToGroup(ADDITIONS_GROUP, groupItem);
            }
           
            targetMenu.appendToGroup(group, action);
            handleActionAccelerator(action, targetMenu, serviceReference);
            targetMenu.appendToGroup(group, new Separator());
            algorithmsToActions.put(getItemID(serviceReference), action);
            actionsToMenuManagers.put(action, targetMenu);
           
            Display.getDefault().asyncExec(this.updateAction);
        } else {
            this.logger.log(
              LogService.LOG_DEBUG,
              "Bad menu path for Algorithm: " + serviceReference.getProperty(LABEL));
        }
    }
   
    private String getItemID(ServiceReference serviceReference) {
      return
        serviceReference.getProperty("PID:" + Constants.SERVICE_PID) +
        "-SID:" +
        serviceReference.getProperty(Constants.SERVICE_ID);
    }

    private MenuManager createMenu(String name, String id){
        MenuManager menu = new MenuManager(name, id);
        menu.add(new GroupMarker(START_GROUP));
        menu.add(new GroupMarker(ADDITIONS_GROUP));
        menu.add(new GroupMarker(END_GROUP));

        return menu;
    }

    private void updateMenuItem(ServiceReference serviceReference) {
        Action item = (Action)this.algorithmsToActions.get(getItemID(serviceReference));
       
        if (item != null) {
          this.logger.log(
            LogService.LOG_DEBUG, "updateMenuItem for " + getItemID(serviceReference));
            item.setText("" + serviceReference.getProperty(LABEL));
        }
    }
   
    private void removeMenuItem(ServiceReference serviceReference) {
        String path = (String)serviceReference.getProperty(MENU_PATH);
        final Action item = this.algorithmsToActions.get(getItemID(serviceReference));
       
        if ((path != null) && (item != null)) {
            int index = path.lastIndexOf('/');

            if (index != -1) {
                path = path.substring(0, index);
                final IMenuManager targetMenu = this.menuManager.findMenuUsingPath(path);

                if (targetMenu != null) {
                  if (!this.shell.isDisposed()) {
                    this.shell.getDisplay().syncExec(new Runnable() {
                      public void run() {
                        targetMenu.remove(item.getId());
                      }
                    });
                    }

                    this.algorithmsToActions.remove(getItemID(serviceReference));
                    this.actionsToMenuManagers.remove(item);
                }
            }  
        }
    }

    public void stop() {
        this.bundleContext.removeServiceListener(this.contextListener);
       
        if (!this.shell.isDisposed()) {
            this.shell.getDisplay().syncExec(this.stopAction);
        }
    }

    //private void clearShortcuts() {
      /*IWorkbench workbench = this.window.getWorkbench();
      IBindingService bindingService =
        (IBindingService)workbench.getService(IBindingService.class);
      Binding[] bindings = bindingService.getBindings();
      IHandlerService handlerService =
        (IHandlerService)workbench.getService(IHandlerService.class);*/
      //getLog().log(LogService.LOG_WARNING, "handlerService: " + handlerService);
      //for (int ii = 0; ii < bindings.length; ii++) {
        // getLog().log(LogService.LOG_INFO, "Binding[" + ii + "]: " + bindings[ii]);
        /*String bindingInfo =
          "\tcontextID: " + bindings[ii].getContextId() + "\n" +
          "\tparameterized command: " + bindings[ii].getParameterizedCommand() + "\n" +
          "\ttrigger sequence: " + bindings[ii].getTriggerSequence().format();
        getLog().log(LogService.LOG_INFO, "Binding:\n" + bindingInfo);*/
       
        /*KeyBinding(
          bindings[ii].getTriggerSequence(),
          null,
          bindings[ii].getSchemeId(),
          bindings[ii].getContextId(),
          null,
          null,
          null,
          Binding.SYSTEM);*/
      //}
    //}

    private void handleActionAccelerator(
        Action action, IMenuManager parentMenuBar, ServiceReference serviceReference) {
      action.setAccelerator(determineActionAcceleratorKeyCode(serviceReference, action));
    }

    private static int determineActionAcceleratorKeyCode(
        ServiceReference serviceReference, Action action) {
      String shortcutString = (String)serviceReference.getProperty(SHORTCUT);

        if (shortcutString != null) {
          return Action.convertAccelerator(shortcutString);
        } else {
          return 0;
        }
    }

    /*
     * printElementAttributes takes in a xml document, gets the nodes, then prints the attributes.
     * Copied from Java Tutorial on XML Parsing by Tim Kelley for debugging purposes.
     */
    static void printElementAttributes(Document doc)
    {
       NodeList nl = doc.getElementsByTagName("*");
       Element e;
       Node n;
       NamedNodeMap nnm;
    
       String attrname;
       String attrval;
       int i, len;
    
       len = nl.getLength();

       for (int j=0; j < len; j++)
       {
          e = (Element)nl.item(j);
          System.err.println(e.getTagName() + ":");
          nnm = e.getAttributes();
    
          if (nnm != null)
          {
             for (i=0; i<nnm.getLength(); i++)
             {
                n = nnm.item(i);
                attrname = n.getNodeName();
                attrval = n.getNodeValue();
                System.err.print(" " + attrname + " = " + attrval);
             }
          }
          System.err.println();
       }
    }
}
TOP

Related Classes of org.cishell.reference.gui.menumanager.menu.MenuAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.