简体   繁体   中英

Eclipse RCP menu

I am building an eclipse RCP application, and I have one question :

In plugin.xml file, i declared a menu with 5 commands. In summary, it is like this :

Menu A
 subMenu A1
 subMenu A2

what I want is to tell to eclipse to evaluate if submenus must be visible only when the the cursor mouse hovers over Main menu item, ie Menu A. How can I do this?

Thanks in advance

<extension
         point="org.eclipse.ui.menus">
      <menuContribution
            allPopups="false"
            locationURI="popup:com.x.sat.ui.views.ProjectsView?after=com.x.sat.ui.commands.closeproject">
         <menu
               icon="icons/repository_rep.gif"
               id="com.x.sat.ui.sgc"
               label="Gestion de Configuration">
            <command
                  commandId="com.x.sat.sgc.ui.addProject"
                  label="Partager le projet"
                  style="push">
               <visibleWhen
                     checkEnabled="false">
                  <reference
                        definitionId="satProjetOrSatModelProjectSelected">
                  </reference>
               </visibleWhen>
            </command>
            <command
                  commandId="com.x.sat.sgc.ui.synchronize"
                  label="Synchroniser avec le dépôt ..."
                  style="push">
               <visibleWhen
                     checkEnabled="false">
                  <reference
                        definitionId="synchronizeObject">
                  </reference>
               </visibleWhen>
            </command>
            <command
                  commandId="com.x.sat.sgc.ui.browseRepository"
                  label="Parcourir le dépôt...."
                  style="push">
            </command>
            <command
                  commandId="com.x.sat.sgc.ui.compare"
                  label="Comparer..."
                  style="push">
            </command>
            <command
                  commandId="com.x.sat.sgc.ui.disconnect"
                  label="Déconnecter le projet ..."
                  style="push">
            </command>
         </menu>
      </menuContribution>
   </extension>

I doubt that you can get this to run using plugin.xml and visiblewhen . Since you know the MenuItem that you want to listen to, you can add an ArmListener instead. It will listen to the MenuItem and you can implement the visibleWhen commands inside or call some other method that triggers your Items.

    ArmListener armListener = new ArmListener() {
    @Override
    public void widgetArmed(ArmEvent e) {
        System.out.println(e);
    }
    };

and call it:

Menu systemMenu = display.getSystemMenu();
    if (systemMenu != null) {
        MenuItem sysItem = getItem(systemMenu, SWT.ID_QUIT);
        sysItem.addArmListener(armListener);
    }

A full example if the usage can be found in this SWT Snippet

edit: for a popup menu you can do

final Menu tableMenu = new Menu(shell, SWT.POP_UP);
MenuItem item = new MenuItem(tableMenu, SWT.PUSH);
item.setText("Hover Me");
item.addArmListener(armListener);

I did something similar in the past but not sure that the trick matches Eclipse state-of-art; I used a dynamic element into my menu declaration and a sourceProvider from org.eclipse.ui.services extension point.

I guess it should also been applicable to your popup menu.

The class linked to the dynamic element extends CompoundContributionItem and override the getContributionItems() method in order to update the sourceProvider variable state... here is the trick not really clean to my mind but it works...

@Override
protected IContributionItem[] getContributionItems() {
    SourceProvider.getInstance().updateState();
    return new IContributionItem[0];
}

SourceProvider sample:

public class SourceProvider extends AbstractSourceProvider {

    private static String ID = "fr.jln.stackoverflow.services.SourceProvider";
    private static String VAR = "fr.jln.stackoverflow.variable1";

    private static final String VAL_TRUE = "TRUE";
    private static final String VAL_FALSE = "FALSE";

    public static SourceProvider getInstance() {
        ISourceProviderService ser = (ISourceProviderService) PlatformUI.getWorkbench().getService(ISourceProviderService.class);
        return (SourceProvider) ser.getSourceProvider(ID);
    }

    boolean state = false;

    public SourceProvider() {}

    @Override
    public Map<?, ?> getCurrentState() {
        String value = null;
        Map<String, String> map = new HashMap<String, String>(1);

        // fake variable (my id)
        map.put(ID, VAL_TRUE);

        // var state
        value = state ? VAL_TRUE : VAL_FALSE;
        map.put(VAR, value);

        return map;
    }

    @Override
    public String[] getProvidedSourceNames() {
        return new String[] { ID, VAR };
    }

    public void updateState() {
        Calendar cal = Calendar.getInstance();
        int min = cal.get(Calendar.MINUTE);
        state = (min % 2 == 0);
        fireSourceChanged(ISources.WORKBENCH, VAR, state?VAL_TRUE:VAL_FALSE);
    }

    @Override
    public void dispose() {}
}

plugin.xml:

   <extension
         point="org.eclipse.ui.menus">
      <menuContribution
            allPopups="false"
            locationURI="menu:org.eclipse.ui.main.menu?after=additions">
         <menu
               label="StackOverflow">
            <command
                  commandId="fr.jln.stackoverflow.command1"
                  label="Command 1"
                  style="push">
               <visibleWhen
                     checkEnabled="false">
                  <with
                        variable="fr.jln.stackoverflow.variable1">
                     <equals
                           value="TRUE">
                     </equals>
                  </with>
               </visibleWhen>
            </command>
            <command
                  commandId="fr.jln.stackoverflow.command2"
                  label="Command 2"
                  style="push">
               <visibleWhen
                     checkEnabled="false">
                  <with
                        variable="fr.jln.stackoverflow.variable1">
                     <equals
                           value="FALSE">
                     </equals>
                  </with>
               </visibleWhen>
            </command>
            <dynamic
                  class="ContributionItem"
                  id="fr.jln.stackoverflow.dynamic1">
            </dynamic>
         </menu>
      </menuContribution>
   </extension>
   <extension
         point="org.eclipse.ui.services">
      <sourceProvider
            provider="SourceProvider">
         <variable
               name="fr.jln.stackoverflow.variable1"
               priorityLevel="workbench">
         </variable>
      </sourceProvider>
   </extension>

With this sample, at the result you should have a menu containing 2 items, on which 1 is masked depending on the time...

Note: some ids can appear quite strange, but sources are extracted from my company plugin

Hope this could help...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM