Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Menu Contributions/Problems View Example"

 
Line 138: Line 138:
 
Using the ProblemView site to access the IHandlerService handles the <activeWhen/> clause for us, and our programmatic handler would manage its own enablement state.
 
Using the ProblemView site to access the IHandlerService handles the <activeWhen/> clause for us, and our programmatic handler would manage its own enablement state.
  
=== Expression Sidebar  ===
 
 
You can see that the <activeWhen/>, <enabledWhen/>, and probably the <visibleWhen/> are likely to be replicated over and over again.  A possible option is some kind of expression template markup ... either in its own extension or supported by our UI extensions that can use core expressions.
 
 
Here's an example of using expression templates in its own extension point.
 
 
  <extension point="org.eclipse.core.expression.templates">
 
    <expression id="isPartActive">
 
      <parameter id="partId" />
 
      <with variable="activePartId">
 
        <equals value="$partId" />
 
      </with>
 
    </expression>
 
    <expression id="isActionSetActive">
 
      <parameter id="actionSetId" />
 
      <with variable="activeContexts">
 
        <iterator operator="or">
 
          <equals value="$actionSetId" />
 
        </iterator>
 
      </with>
 
    </expression>
 
    <expression id="isContextActive">
 
      <parameter id="contextId" />
 
      <with variable="activeContexts">
 
        <iterator operator="or">
 
          <equals value="$contextId" />
 
        </iterator>
 
      </with>
 
    </expression>
 
    <expression id="isSelectionAvailable">
 
      <not>
 
        <count value="0" />
 
      </not>
 
    </expression>
 
  </extension>
 
 
 
This could be used to simplify the handler definitions:
 
 
  <extension point="org.eclipse.ui.handlers">
 
    <handler commandId="org.eclipse.ui.edit.copy"
 
            class="org.eclipse.ui.views.markers.internal.CopyMarkerHandler">
 
      <enabledWhen>
 
        <evaluate ref="isSelectionAvailable" />
 
      </enabledWhen>
 
      <activeWhen>
 
        <evaluate ref="isPartActive">
 
          <parameter id="partId" value="org.eclipse.ui.views.ProblemView" />
 
        </evaluate>
 
      </activeWhen>
 
    </handler>
 
  </extension>
 
 
 
If we allow recursive template definitions, that would allow you to specify the concrete expression once and then reference it throughout your view.
 
 
  <extension point="org.eclipse.core.expression.templates">
 
    <expression id="isProblemViewActive">
 
      <evaluate ref="isPartActive">
 
        <parameter id="partId" value="org.eclipse.ui.views.ProblemView" />
 
      </evaluate>
 
    </expression>
 
  </extension>
 
  <extension point="org.eclipse.ui.handlers">
 
    <handler commandId="org.eclipse.ui.edit.copy"
 
            class="org.eclipse.ui.views.markers.internal.CopyMarkerHandler">
 
      <enabledWhen>
 
        <evaluate ref="isSelectionAvailable" />
 
      </enabledWhen>
 
      <activeWhen>
 
        <evaluate ref="isProblemViewActive" />
 
      </activeWhen>
 
    </handler>
 
  </extension>
 
 
 
This reduces the handler definition even more.
 
 
 
A similar option to reuse expressions as much as possible without turning them into their own procedural language would be to allow global definitions and then reuse them.  No parameters and no expression composition:
 
 
  <extension point="org.eclipse.core.expression.templates">
 
    <expression id="isProblemViewActive">
 
      <with variable="activePartId">
 
        <equals value="org.eclipse.ui.views.ProblemView" />
 
      </with>
 
    </expression>
 
    <expression id="isSelectionAvailable">
 
      <not>
 
        <count value="0" />
 
      </not>
 
    </expression>
 
  </extension>
 
  <extension point="org.eclipse.ui.handlers">
 
    <handler commandId="org.eclipse.ui.edit.copy"
 
            class="org.eclipse.ui.views.markers.internal.CopyMarkerHandler">
 
      <enabledWhen ref="isSelectionAvailable" />
 
      <activeWhen ref="isProblemViewActive" />
 
    </handler>
 
  </extension>
 
 
=== Another Alternative: Specify Context at Extension Level ===
 
 
 
Since <code>enabledWhen</code> and <code>activeWhen</code> specify context and the simple way to specify context in XML is enclosure, how about scoping context to the extension point rather than the handler:
 
 
  <extension point="org.eclipse.ui.handlers">
 
      <enabledWhen>  <!-- context of all  handlers in this extension -->
 
        <not>
 
          <count value="0" />
 
        </not>
 
      </enabledWhen>
 
      <activeWhen>
 
        <with variable="activePartId">
 
          <equals value="org.eclipse.ui.views.ProblemView" />
 
        </with>
 
      </activeWhen>
 
      <handler commandId="org.eclipse.ui.edit.copy"
 
            class="org.eclipse.ui.views.markers.internal.CopyMarkerHandler" />
 
      <handler commandId="org.eclipse.ui.edit.paste"
 
            class="org.eclipse.ui.views.markers.internal.PasteMarkerHandler" />
 
      <handler commandId="org.eclipse.ui.edit.delete"
 
            class="org.eclipse.ui.views.markers.internal.RemoveMarkerHandler" />
 
      <handler commandId="org.eclipse.jdt.ui.edit.text.java.correction.assist.proposals"
 
            class="org.eclipse.ui.views.markers.internal.ResolveMarkerHandler" />
 
      <handler commandId="org.eclipse.ui.edit.selectAll"
 
            class="org.eclipse.ui.views.markers.internal.SelectAllMarkersHandler" />
 
      <handler commandId="org.eclipse.ui.file.properties"
 
            class="org.eclipse.ui.views.markers.internal.ProblemPropertiesHandler" />
 
  </extension>
 
 
This gives compact markup without inventing a new language.  Elements nested in the handler element could override the extension-wide settings.
 
  
 
== Menus ==
 
== Menus ==
Line 363: Line 231:
 
   </extension>
 
   </extension>
  
 
Some constraints on the system:
 
 
# Identifiers (id) for <menu/> elements must be globally unique.
 
# Identifiers (id) for <command/> elements must be globally unique if they are specified.
 
# You can reference a <menu/> by id.
 
# If you are just creating menu items for your commands, you can leave them with only a command id.  You don't have to specify an item id.
 
# You can reference an <command/> for placement options (after, before, etc) by id.
 
# <separator/> ids only have to be unique within that menu level.  This is changed to name instead of id in '''3.3M5'''.
 
# You can provide an <command/> label attribute.  If none is provided, it will take the command name.
 
# In this design the item contains most of the same rendering information that <action/> did.
 
# <menu/> and <command/> can have <visibleWhen/> clauses.  If a menu's <visibleWhen/> evaluates to false, we will never ask the items contained in that menu.
 
# All of the display-able attributes are translatable.
 
# The mnemonic is specified as you place your <command/> elements in their respective menus, since it is possible that the same command might need a different mnemonic depending on which menu it is placed.  Also, when defaulting to command names they don't contain any mnemonic information.
 
 
=== Menu URIs ===
 
 
For location placement we need a path and placement modifier, and to specify how the paths are built.  First pass we are going to look at URIs. 
 
 
* <scheme>:<menu-id>[?<placement-modifier>]
 
 
scheme is about how to interpret the URI path.  For example, <code>menu</code>, <code>toolbar</code>, <code>popup</code>, <code>status</code> (although status may be deprecated).
 
 
 
For <code>menu:</code> valid root ids will be any viewId for that view's menu, and <b>org.eclipse.ui.main.menu</b> for the main menu.  Then specify the id of the menu this contribution applies to.  The placement modifier helps position the menu contribution.  ex: after=<id>, where <id> can be a separator name, menu id, or item id.  An example of a path: <code>menu:org.eclipse.search.menu?after=contextMenuActionsGroup</code>
 
 
Since menu ids must be unique, you can specify your menu location relative to an existing id: <code>menu:org.eclipse.search.menu?after=contextMenuActionsGroup</code>
 
 
For <code>toolbar:</code> valid root ids will be any viewId for that view's toolbar, <b>org.eclipse.ui.main.toolbar</b> for the main toolbar, and any toolbar id that is contained in the main toolbar.  Toolbars can support <b>invisible</b> separators.  Toolbars in the main toolbar (technically a coolbar) can have ids as well as separators, but only one level.  For example: <code>toolbar:org.eclipse.ui.edit.text.actionSet.presentation?after=Presentation</code>
 
 
In this example, <b>Presentation</b> is an invisible separator in the <b>org.eclipse.ui.edit.text.actionSet.presentation</b> toolbar.
 
 
The use of <b>org.eclipse.ui.main.toolbar</b> might change if all "main" toolbars have ids anyway, so the only options for interpretting the toolbar root is 1) the view toolbar or 2) an IDed main toolbar.
 
 
 
For <code>popup:</code> valid root ids are any registered context id (which defaults to the part id if no context menu id was given at registration time) and <b>org.eclipse.ui.popup.any</b> for all registered context menus.  For example, to add to the default Text Editor context menu: <code>popup:#TextEditorContext?after=additions</code>
 
 
Popup submenus are treated like menu submenus, except the form continues to be <code>popup:submenuId</code>.
 
 
There will be constants defined for the ids that the eclipse workbench provides.
 
 
=== Menu - JSR198 ===
 
 
'''Note:''' for novelty purposes only.
 
 
For comparison, there is a JSR describing how IDEs can contribute menus.  Below is a sample for 2 items:
 
 
* org.eclipse.ui.views.problems.sorting.item from menu:org.eclipse.ui.views.ProblemView
 
* org.eclipse.ui.views.problems.resolveMarker.item from popup:org.eclipse.ui.views.ProblemView
 
 
  <menu-hook>
 
    <actions>
 
      <action id="org.eclipse.ui.views.problems.sorting.item">
 
        <label>Sorting...</label>
 
        <mnemonic>S</mnemonic>
 
        <tooltip>Change the Sort order</tooltip>
 
        <invoke-class>org.eclipse.ui.views.problems.sorting</invoke-class>
 
      </action>
 
      <action id="org.eclipse.ui.views.problems.resolveMarker.item">
 
        <label>Quick Fix</label>
 
        <mnemonic>Q</mnemonic>
 
        <iconpath>$nl$/icons/full/elcl16/smartmode_co.gif</iconpath>
 
        <invoke-class>org.eclipse.jdt.ui.edit.text.java.correction.assist.proposals</invoke-class>
 
        <update-class>org.eclipse.jdt.ui.edit.text.java.correction.assist.proposals</update-class>
 
      </action>
 
    </actions>
 
    <menus>
 
      <menubar id="org.eclipse.ui.views.ProblemView">
 
        <menu id="org.eclipse.ui.views.ProblemView">
 
          <section id="problem.view.section">
 
            <command action-ref="org.eclipse.ui.views.problems.sorting.item" />
 
            <menu id="org.eclipse.ui.views.problems.groupBy.menu">
 
              <label>Group By</label>
 
              <mnemonic>G</mnemonic>
 
            </menu>
 
          </section>
 
        </menu>
 
      </menubar>
 
      <popup id="org.eclipse.ui.views.ProblemView">
 
        <section id="group.resolve">
 
          <command action-ref="org.eclipse.ui.views.problems.resolveMarker.item" />
 
        </section>
 
      </popup>
 
    </menus>
 
  </menu-hook>
 
 
Some thoughts:
 
 
* the actions can only specify one icon
 
* the actions can't *quite* link to our commands
 
* the menus can't specify dynamic submenus
 
 
=== Menu - XUL ===
 
 
'''Note:''' for novelty purposes only.
 
 
 
For comparison, with Mozilla everywhere there is the probability eclipse will include xulrunner.  Menu definitions that are consistent with XUL look like:
 
 
  <keyset>
 
    <key id="paste-key" modifiers="accel" key="V" />
 
  </keyset>
 
  <menubar id="org.eclipse.ui.views.ProblemView">
 
    <menupopup id="org.eclipse.ui.views.ProblemView">
 
      <menuitem id="org.eclipse.ui.views.problems.sorting.item"
 
                accesskey="S"
 
                key="paste-key"
 
                label="Sorting..."
 
                oncommand="invokeCommand('org.eclipse.ui.views.problems.sorting')" />
 
      <menu id="org.eclipse.ui.views.problems.groupBy.menu"
 
            label="Group By"
 
            accesskey="G">
 
        <menupopup id="groupby.popup">
 
          <!-- this is where submenu items would go -->
 
        </menupopup>
 
      </menu>
 
    </menupopup>
 
  </menubar>
 
 
 
XUL supports everything as a flavour of a DOM, and javascripting can drive your buttons to perform commands.  I suspect the scripting would allow you to dynamically update menus (dynamic menus) on popup, depending on what events the DOM would report to you.
 
  
 
== Menus API ==
 
== Menus API ==
Line 587: Line 334:
  
 
The <code>AbstractContributionFactory</code> creates new contribution items every time <code>createContributionItems(List)</code> is called.  The factory location tells the framework where to insert the contributions when populating <code>ContributionManager</code>s.
 
The <code>AbstractContributionFactory</code> creates new contribution items every time <code>createContributionItems(List)</code> is called.  The factory location tells the framework where to insert the contributions when populating <code>ContributionManager</code>s.
 
You add your IContributionItems in the list.  Supported contributions include:
 
*MenuManagers
 
*Separators
 
*GroupMarkers
 
*CommandContributionItems
 
*CompoundContributionItems
 
*ControlContributions
 
 
If you need to reference an Item at some time you will need to create it with an id, which must be unique.
 
 
Menus cannot be re-used, and so they have an intrinsic id value.  Separators are unique within one menu level, so they also contain their name.
 

Revision as of 11:09, 28 February 2007

Add ProblemView menus

Add the Problems view menus. The Problems view has one toolbar action and in the view menu, 3 actions and 2 dynamic submenus. It also has a dynamic menu and another bunch of actions in its context menu.

Commands

First define commands that are specific to the view. Since these are view commands, we can specify a default handler ... we're unlikely to replace it.

  <extension point="org.eclipse.ui.commands">
     <category id="org.eclipse.ui.views.problems"
               name="%ProblemView.category.name">
     </category>
     <command categoryId="org.eclipse.ui.views.problems"
              defaultHandler="org.eclipse.ui.views.markers.internal.TableSortHandler"
              description="%ProblemView.Sorting.description"
              id="org.eclipse.ui.views.problems.sorting"
              name="%ProblemView.Sorting.name">
     </command>
     <!-- the view preference command would probably be defined once
     with the other preference contributions -->
     <command categoryId="org.eclipse.ui.views.problems"
              defaultHandler="org.eclipse.ui.preferences.ViewPreferencesHandler"
              description="%ViewPreferences.description"
              id="org.eclipse.ui.preferences.viewPreferences"
              name="%ViewPreferences.name">
        <commandParameter id="markerEnablementName"
                          name="%ViewPreferences.markerEnablementName.name"
                          optional="false" />
        <commandParameter id="markerLimitName"
                          name="%ViewPreferences.markerLimitName.name"
                          optional="false" />
     </command>
     <command categoryId="org.eclipse.ui.views.problems"
              defaultHandler="org.eclipse.ui.views.markers.internal.FiltersHandler"
              description="%ProblemView.ConfigureFilters.description"
              id="org.eclipse.ui.views.problems.configureFilters"
              name="%ProblemView.ConfigureFilters.name">
     </command>
     <command categoryId="org.eclipse.ui.views.problems"
              defaultHandler="org.eclipse.ui.views.markers.internal.OpenMarkerHandler"
              description="%ProblemView.GoTo.description"
              id="org.eclipse.ui.views.problems.goTo"
              name="%ProblemView.GoTo.name" />
  </extension>

Handlers

We can also use a number of global commands, like copy, paste, delete, quick fix, and properties. For these, we just need to define our handlers. We need to add them with <activeWhen/> clauses to restrict them to being active when the view is active.

  <extension point="org.eclipse.ui.handlers">
     <handler commandId="org.eclipse.ui.edit.copy"
              class="org.eclipse.ui.views.markers.internal.CopyMarkerHandler">
        <enabledWhen>
           <not>
              <count value="0" />
           </not>
        </enabledWhen>
        <activeWhen>
           <with variable="activePartId">
              <equals value="org.eclipse.ui.views.ProblemView" />
           </with>
        </activeWhen>
     </handler>
     <handler commandId="org.eclipse.ui.edit.paste"
              class="org.eclipse.ui.views.markers.internal.PasteMarkerHandler">
        <enabledWhen>
           <not>
              <count value="0" />
           </not>
        </enabledWhen>
        <activeWhen>
           <with variable="activePartId">
              <equals value="org.eclipse.ui.views.ProblemView" />
           </with>
        </activeWhen>
     </handler>
     <handler commandId="org.eclipse.ui.edit.delete"
              class="org.eclipse.ui.views.markers.internal.RemoveMarkerHandler">
        <enabledWhen>
           <not>
              <count value="0" />
           </not>
        </enabledWhen>
        <activeWhen>
           <with variable="activePartId">
              <equals value="org.eclipse.ui.views.ProblemView" />
           </with>
        </activeWhen>
     </handler>
     <handler commandId="org.eclipse.ui.edit.selectAll"
              class="org.eclipse.ui.views.markers.internal.SelectAllMarkersHandler">
        <enabledWhen>
           <not>
              <count value="0" />
           </not>
        </enabledWhen>
        <activeWhen>
           <with variable="activePartId">
              <equals value="org.eclipse.ui.views.ProblemView" />
           </with>
        </activeWhen>
     </handler>
     <handler commandId="org.eclipse.jdt.ui.edit.text.java.correction.assist.proposals"
              class="org.eclipse.ui.views.markers.internal.ResolveMarkerHandler">
        <enabledWhen>
           <not>
              <count value="0" />
           </not>
        </enabledWhen>
        <activeWhen>
           <with variable="activePartId">
              <equals value="org.eclipse.ui.views.ProblemView" />
           </with>
        </activeWhen>
     </handler>
     <handler commandId="org.eclipse.ui.file.properties"
              class="org.eclipse.ui.views.markers.internal.ProblemPropertiesHandler">
        <enabledWhen>
           <not>
              <count value="0" />
           </not>
        </enabledWhen>
        <activeWhen>
           <with variable="activePartId">
              <equals value="org.eclipse.ui.views.ProblemView" />
           </with>
        </activeWhen>
     </handler>
  </extension>


Or we can programmatically activate them through the IHandlerService which we would retrieve from the ProblemView site.

IHandlerService handlerServ = (IHandlerService)getSite().getService(IHandlerService.class);
copy = new CopyMarkerHandler();
handlerServ.activateHandler("org.eclipse.ui.edit.copy", copy);

Using the ProblemView site to access the IHandlerService handles the <activeWhen/> clause for us, and our programmatic handler would manage its own enablement state.


Menus

Then we would define the ProblemView menu structures. We are using 3 roots: the view menu, the view toolbar, and the view context menu. This is an example of an "in-place" menu definition. The <menuContribution/> location attribute is a URI that defines the starting point for inserting the menu elements. The XML hierarchy mirrors the menu hierarchy, in that you can define items and menus within the body of other menus.

  <extension point="org.eclipse.ui.menus">
     <menuContribution locationURI="menu:org.eclipse.ui.views.ProblemView">
        <command commandId="org.eclipse.ui.views.problems.sorting"
                 label="%ProblemView.Sorting.name"
                 mnemonic="%ProblemView.Sorting.mnemonic"
                 style="push"
                 tooltip="%ProblemView.Sorting.tooltip">
        </command>
        <menu id="org.eclipse.ui.views.problems.groupBy.menu"
              label="%ProblemView.GroupBy.label"
              mnemonic="%ProblemView.GroupBy.mnemonic">
           <dynamic class="org.eclipse.ui.views.markers.internal.GroupByItems"
                    id="org.eclipse.ui.views.problems.groupBy.items">
           </dynamic>
        </menu>
        <separator name="group.filter" visible="true" />
        <menu id="org.eclipse.ui.views.problems.filters.menu"
              label="%ProblemView.Filters.label"
              mnemonic="%ProblemView.Filters.mnemonic">
           <dynamic class="org.eclipse.ui.views.markers.internal.FilterItems"
                    id="org.eclipse.ui.views.problems.filters.items" />
        </menu>
        <command commandId="org.eclipse.ui.views.problems.configureFilters"
                 icon="$nl$/elcl16/filter_ps.gif"
                 label="%ProblemView.ConfigureFilters.name"
                 mnemonic="%ProblemView.ConfigureFilters.mnemonic"
                 tooltip="%ProblemView.ConfigureFilters.tooltip" />
        <command commandId="org.eclipse.ui.preferences.viewPreferences"
                 label="%ViewPreferences.name"
                 mnemonic="%ViewPreferences.mnemonic">
           <parameter name="markerEnablementName" value="LIMIT_PROBLEMS" />
           <parameter name="markerLimitName" value="PROBLEMS_LIMIT" />
        </command>
     </menuContribution>
     <menuContribution locationURI="toolbar:org.eclipse.ui.views.ProblemView">
        <command commandId="org.eclipse.ui.views.problems.configureFilters"
                 icon="$nl$/elcl16/filter_ps.gif"
                 tooltip="%ProblemView.ConfigureFilters.tooltip" />
     </menuContribution>
     <menuContribution locationURI="popup:org.eclipse.ui.views.ProblemView">
        <command commandId="org.eclipse.ui.views.problems.goTo"
                 mnemonic="%ProblemView.GoTo.mnemonic"
                 icon="$nl$/elcl16/gotoobj_tsk.gif"
                 disabledIcon="$nl$/dlcl16/gotoobj_tsk.gif"
                 tooltip="%ProblemView.GoTo.tooltip" />
        <separator name="group.showIn" visible="true" />
        <menu id="org.eclipse.ui.views.problems.showIn.menu"
              label="%ProblemView.ShowIn.label"
              mnemonic="%ProblemView.ShowIn.mnemonic">
           <dynamic class="org.eclipse.ui.actions.ShowInContributions"
                    id="org.eclipse.ui.views.problems.showIn.items" />
        </menu>
        <separator name="group.edit" visible="true" />
        <command commandId="org.eclipse.ui.edit.copy"
                 mnemonic="%ProblemView.copy.mnemonic"
                 icon="$nl$/icons/full/etool16/copy_edit.gif"
                 disabledIcon="$nl$/icons/full/dtool16/copy_edit.gif" />
        <command commandId="org.eclipse.ui.edit.paste"
                 mnemonic="%ProblemView.paste.mnemonic"
                 icon="$nl$/icons/full/etool16/paste_edit.gif"
                 disabledIcon="$nl$/icons/full/dtool16/paste_edit.gif" />
        <command commandId="org.eclipse.ui.edit.delete"
                 mnemonic="%ProblemView.delete.mnemonic"
                 icon="$nl$/icons/full/etool16/delete_edit.gif"
                 disabledIcon="$nl$/icons/full/dtool16/delete_edit.gif">
           <visibleWhen>
              <not>
                 <with variable="activePartId">
                    <equals value="org.eclipse.ui.views.ProblemView" />
                 </with>
              </not>
           </visibleWhen>
        </command>
        <command commandId="org.eclipse.ui.edit.selectAll"
                 mnemonic="%ProblemView.selectAll.mnemonic" />
        <separator name="group.resolve" visible="true" />
        <command commandId="org.eclipse.jdt.ui.edit.text.java.correction.assist.proposals"
                 mnemonic="%ProblemView.Resolve.mnemonic"
                 icon="$nl$/icons/full/elcl16/smartmode_co.gif"
                 disabledIcon="$nl$/icons/full/dlcl16/smartmode_co.gif" />
        <separator name="additions" visible="false" />
        <separator name="group.properties" visible="true" />
        <command commandId="org.eclipse.ui.file.properties"
                 mnemonic="%ProblemView.Properties.mnemonic" />
     </menuContribution>
  </extension>


Menus API

We can contribute menu definitions through the IMenuService API.

The above example can be done for the view menus:

   public void addProblemsViewMenuContribution() {
       IMenuService menuService = (IMenuService) PlatformUI.getWorkbench()
               .getService(IMenuService.class);

       AbstractContributionFactory viewMenuAddition = new AbstractContributionFactory(
               "menu:org.eclipse.ui.views.ProblemView?after=additions") {
           public void createContributionItems(IMenuService menuService,
                   List additions) {
               CommandContributionItem item = new CommandContributionItem(
                       null, "org.eclipse.ui.views.problems.sorting", null,
                       null, null, null, "Sorting...", "S",
                       "Change the Sort order",
                       CommandContributionItem.STYLE_PUSH);
               additions.add(item);

               MenuManager submenu = new MenuManager("Group &By",
                       "org.eclipse.ui.views.problems.groupBy.menu");
               IContributionItem dynamicItem = new CompoundContributionItem(
                       "org.eclipse.ui.views.problems.groupBy.items") {
                   protected IContributionItem[] getContributionItems() {
                       // Here's where you would dynamically generate your list
                       IContributionItem[] list = new IContributionItem[2];
                       Map parms = new HashMap();
                       parms.put("groupBy", "Severity");
                       list[0] = new CommandContributionItem(null,
                               "org.eclipse.ui.views.problems.grouping",
                               parms, null, null, null, "Severity", null,
                               null, CommandContributionItem.STYLE_PUSH);

                       parms = new HashMap();
                       parms.put("groupBy", "None");
                       list[1] = new CommandContributionItem(null,
                               "org.eclipse.ui.views.problems.grouping",
                               parms, null, null, null, "None", null, null,
                               CommandContributionItem.STYLE_PUSH);
                       return list;
                   }
               };
               submenu.add(dynamicItem);

               additions.add(submenu);
               additions.add(new Separator("group.filter"));

               submenu = new MenuManager("&Filters",
                       "org.eclipse.ui.views.problems.filters.menu");
               dynamicItem = new CompoundContributionItem(
                       "org.eclipse.ui.views.problems.filters.items") {
                   protected IContributionItem[] getContributionItems() {
                       // Here's where you would dynamically generate your list
                       IContributionItem[] list = new IContributionItem[1];
                       Map parms = new HashMap();
                       parms.put("filter", "Default");
                       list[0] = new CommandContributionItem(null,
                               "org.eclipse.ui.views.problems.filters", parms,
                               null, null, null, "Default", null, null,
                               CommandContributionItem.STYLE_PUSH);
                       return list;
                   }
               };
               submenu.add(dynamicItem);

               additions.add(submenu);

               ImageDescriptor filterIcon = PlatformUI.getWorkbench()
                       .getSharedImages().getImageDescriptor(
                               "elcl16/filter_ps.gif");
               item = new CommandContributionItem(null,
                       "org.eclipse.ui.views.problems.configureFilters", null,
                       filterIcon, null, null, "Configure Filters...", "C",
                       "Configure the filters to be applied to this view",
                       CommandContributionItem.STYLE_PUSH);
               additions.add(item);

               Map parms = new HashMap();
               parms.put("markerEnablementName", "LIMIT_PROBLEMS");
               parms.put("markerLimitName", "PROBLEMS_LIMIT");
               item = new CommandContributionItem(null,
                       "org.eclipse.ui.preferences.viewPreferences", parms,
                       null, null, null, "Preference", "P",
                       "Open the preference dialog",
                       CommandContributionItem.STYLE_PUSH);
               additions.add(item);
           }

           public void releaseContributionItems(IMenuService menuService,
                   List items) {
               // for us this is a no-op
           }
       };
       menuService.addContributionFactory(viewMenuAddition);
   }



The AbstractContributionFactory creates new contribution items every time createContributionItems(List) is called. The factory location tells the framework where to insert the contributions when populating ContributionManagers.

Back to the top