Home > Eclipse development, Refactoring, Software Development, Testing > Writing an Eclipse Plug-in (Part 24): Common Navigator: Configuring the submenus (Presentation…again)

Writing an Eclipse Plug-in (Part 24): Common Navigator: Configuring the submenus (Presentation…again)


When we last left our erstwhile travelers (that would be all of you) they were surfing the quantum wave on their way to a future refactoring of their past to allow them to simultaneously feel proud of their work and embarrassed that they were following some guy who is making it all up as he goes along causing them to need refactoring in the first place.

Hey. Refactoring happens. All the time. Just ask evolution (only don’t mention the alligators).

What I will post about is adding behavior to our menu items. After having added 4 (count ‘em) new menu items it is time to make them actually do something. What should they do? Well, they are going to add elements into their respective XML files (and respectively) while looking like they are adding items into their respective category nodes in the navigator.

That would appear to entail a few things:

  • Display the proper menu item based on the node/project selected
    • If right clicking on Schema then display Table, View and Filter
    • If right clicking on Stored Procedures then display Stored Procedure

Regardless of which node is selected:

  • Make sure the XML file in question exists to begin with
  • Update the appropriate elements
  • Update the Custom Navigator model

Finally:

  • In the navigator: open the node that contains the new element
  • Remove the ability to create the actual XML file from the New Wizard
  • New Wizard: Add the appropriate New Wizard based on whether a Project, Schema or Stored Procedures node, or any of their children, is selected

We won’t be doing those last 2 in this post. All we are going to do is straighten out the popup behavior. I want to do more, but these posts are getting rather long, its Sunday and I really want to get some reading in before I go to work tomorrow.

What (are we doing?)

The things we need to do (in this and the next few posts) are:
1. Display the proper popup depending on the node right-clicked by the user
2. Check for the existence of a particular file type (schema or stored procedure file)
3. Add a new entry into the file based on the element type selected
4. Display the new entry in the navigator

Sounds reasonable so far. We can test the second two and ignore the last (what? Ignore it? Yes…remember: don’t test the platform). However, depending on how involved the model code is we might want to test that the model code is handling the non-trivial handling of the XML files properly. I am not sure. We’ll figure that out. But not today.

How (are we doing it?)

Display the proper menu item based on the node/project selected

  • If right clicking on Schema then display Table, View and Filter
  • If right clicking on Stored Procedures then display Stored Procedure

In order to restrict the Schema Table menu we have to go back to customnavigator plugin.xml –> Extensions –> org.eclipse.ui.handlers –> (handler) [the one for Schema Table] –> (enabledWhen) –> selection (with) –> false (iterate) –> customnavigator.navigator.ICustomProjectElement.
Do the following:

  1. Delete the false (iterate) node.
  2. selection (with) –> New –> iterate
  3. (iterate) –> New –> or
  4. (or) –> New –> instanceof
  5. Value: customnavigator.navigator.CustomProjectParent
  6. (or) –> New –> instanceof
  7. Value: customnavigator.navigator.CustomProjectSchema

Repeat the previous steps for Schema View and Schema Filter.

Save plugin.xml and start the runtime workbench to check your work.



Close the runtime workbench when you finish checking that everything is okay.

  • Extra credit: update the child leaf behavior to only display the appropriate popup menu
    1. Go to org.eclipse.ui.handlers –> (handler) [the one for Schema Table] –> (enabledWhen) –> selection (with) –> (iterate) –> (or) –> New –> instanceof
    2. Value: customnavigator.navigator.CustomProjectSchemaTables
    3. Go to org.eclipse.ui.handlers –> (handler) [the one for Schema View] –> (enabledWhen) –> selection (with) –> (iterate) –> (or) –> New –> instanceof
    4. Value: customnavigator.navigator.CustomProjectSchemaViews
    5. Go to org.eclipse.ui.handlers –> (handler) [the one for Schema Filter] –> (enabledWhen) –> selection (with) –> (iterate) –> (or) –> New –> instanceof
    6. Value: customnavigator.navigator.CustomProjectSchemaFilters

    Save the plugin.xml and check out the runtime workbench.

    Why (did we do it that way?)

    Okay! We are now at a point where we can move forward again. Maybe not a lot very far, but my expectations are low these days.

    Let’s see:
    Display the proper menu item based on the node/project selected (in this case, the Schema Table)

    • Right clicking on a Custom Project should display all of our items under New
    • If right clicking on Schema then display Table, View and Filter
    • If right clicking on Stored Procedures then display Stored Procedure

    Starting the runtime workbench shows that our New menu comes up as before. All the various menu items are available as usual. If you right-click on Schema you will notice that all the menu items are also still displayed including Stored Procedure. We only want to see New –> [Table | View | Filter] when right clicking on the Schema node. How to fix that?

    In order to restrict the Schema Table menu we have to go back to customnavigator plugin.xml –> Extensions –> org.eclipse.ui.handlers –> (handler) [the one for Schema Table] –> (enabledWhen) –> selection (with) –> false (iterate) –> customnavigator.navigator.ICustomProjectElement.

    When the Eclipse GUI framework opens the popup it checks to see if any of the handlers should be enabled or disabled based on the information found in the enabledWhen element of the handler. In this case the Schema Table menu item will only appear if the item being right-clicked by the mouse is an object of type customnavigator.navigator.ICustomProjectElement. That is apparently too generic. Let’s restrict it to just the Schema node by changing customnavigator.navigator.ICustomProjectElement to customnavigator.navigator.CustomProjectSchema.

    Save plugin.xml and start the runtime workbench. Test our new configuration by right-clicking on Stored Procedures. The Table menu item should be gone. Excellent! Good times.

    Before exiting the runtime workbench check that the Table node still appears when we right-click on the project. Oh, oh. The Table menu is gone!

    Of course it is. We just told Eclipse to only display Table when the selected node is Schema. We need to display Table when the selected node is Schema or the project.

    Do the following:

    1. Delete the false (iterate) node.
    2. selection (with) –> New –> iterate
    3. (iterate) –> New –> or
    4. (or) –> New –> instanceof
    5. Value: customnavigator.navigator.CustomProjectParent
    6. (or) –> New –> instanceof
    7. Value: customnavigator.navigator.CustomProjectSchema

    Start the runtime workbench. Check both the project node and the Schema node. The Table menu should be displayed on both (only showing the popup menu of the project node).

    Exit the runtime workbench.

    Repeat the previous steps for Schema View and Schema Filter.

    1. Delete the false (iterate) node.
    2. selection (with) –> New –> iterate
    3. (iterate) –> New –> or
    4. (or) –> New –> instanceof
    5. Value: customnavigator.navigator.CustomProjectParent
    6. (or) –> New –> instanceof
    7. Value: customnavigator.navigator.CustomProjectSchema

    Save plugin.xml and start the runtime workbench.

    Check that all of the menu items appear when you right-click on the project, check that the Schema choices appear when right-clicking on the Schema node (the Stored Procedure menu item is still there as we have not updated its handler to only appear based on a more specific object type), and check that the Stored Procedure choice appear when right-clicking on the Stored Procedures node.


    Exit the runtime workbench.

    There is bit of a side-effect going on in that last check: because the Stored Procedures node is not a Schema node the only item that appears, by default, is Stored Procedure. Let’s be explicit:

    1. Delete the false (iterate) node.
    2. selection (with) –> New –> iterate
    3. (iterate) –> New –> or
    4. (or) –> New –> instanceof
    5. Value: customnavigator.navigator.CustomProjectParent
    6. (or) –> New –> instanceof
    7. Value: customnavigator.navigator.CustomProjectStoredProcedures

    Save plugin.xml and start the runtime workbench. The results should appear the same as before only now the Schema sub-menu no longer displays the Stored Procedure item. Give yourself a +1 for being so anal.

  • Extra credit: when you right click on any of the Schema nodes (Table, View or Filter) the New menu should just display the menu item specific to that node (we don’t need to worry about doing this for Stored Procedures).

    1. Go to org.eclipse.ui.handlers –> (handler) [the one for Schema Table] –> (enabledWhen) –> selection (with) –> (iterate) –> (or) –> New –> instanceof
    2. Value: customnavigator.navigator.CustomProjectSchemaTables
    3. Go to org.eclipse.ui.handlers –> (handler) [the one for Schema View] –> (enabledWhen) –> selection (with) –> (iterate) –> (or) –> New –> instanceof
    4. Value: customnavigator.navigator.CustomProjectSchemaViews
    5. Go to org.eclipse.ui.handlers –> (handler) [the one for Schema Filter] –> (enabledWhen) –> selection (with) –> (iterate) –> (or) –> New –> instanceof
    6. Value: customnavigator.navigator.CustomProjectSchemaFilters

    Save the plugin.xml and check out the runtime workbench.

    Just a quick look at one of the three leaves:

    Cool, huh?

    What Just Happened?

    Once again, we performed a minimal amount of configuration to control the display of popups. No code this time…again.

    While I hoped that we would get to a point where we could finally add behavior to these popups that was not to be.

    So in case I publish this before September: have a great Labor Day (for those of you not in the US: that would be the first Monday in September)! Eat drink and be merry! More drinking! More merry-making (especially merry-making)!
    The cat disapproves. The platypus wants shrimp on the barby. I am not sure what the squirrel thinks.

    Code

    Download this post’s code from the Eclipse Kick Start site.
    plugin.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <?eclipse version="3.4"?>
    <plugin>
       <extension
             point="org.eclipse.ui.views">
          <category
                id="customnavigator.category"
                name="%category.name">
          </category>
          <view
                allowMultiple="false"
                category="customnavigator.category"
                class="org.eclipse.ui.navigator.CommonNavigator"
                icon="icons/navigator.png"
                id="customnavigator.navigator"
                name="%view.name">
          </view>
       </extension>
       <extension
             point="org.eclipse.ui.navigator.viewer">
          <viewer
                viewerId="customnavigator.navigator">
             <popupMenu
                   id="customnavigator.navigator#PopupMenu">
                <insertionPoint
                      name="group.new">
                </insertionPoint>
                <insertionPoint
                      name="group.build"
                      separator="true">
                </insertionPoint>
             </popupMenu>
          </viewer>
          <viewerContentBinding
                viewerId="customnavigator.navigator">
             <includes>
                <contentExtension
                      pattern="customnavigator.navigatorContent">
                </contentExtension>
             </includes>
          </viewerContentBinding>
          <viewerActionBinding
                viewerId="customnavigator.navigator">
             <includes>
                <actionExtension
                      pattern="customnavigator.popup.actionprovider.CustomNewAction">
                </actionExtension>
                <actionExtension
                      pattern="customnavigator.popup.actionprovider.CustomRefreshAction">
                </actionExtension>
             </includes>
          </viewerActionBinding>
       </extension>
       <extension
             point="org.eclipse.ui.navigator.navigatorContent">
          <navigatorContent
                activeByDefault="true"
                contentProvider="customnavigator.navigator.ContentProvider"
                id="customnavigator.navigatorContent"
                labelProvider="customnavigator.navigator.LabelProvider"
                name="%navigatorContent.name">
             <triggerPoints>
                <instanceof
                      value="org.eclipse.core.resources.IWorkspaceRoot">
                </instanceof>
             </triggerPoints>
             <commonSorter
                   class="customnavigator.sorter.SchemaCategorySorter"
                   id="customnavigator.sorter.schemacategorysorter">
                <parentExpression>
                   <or>
                      <instanceof
                            value="customnavigator.navigator.CustomProjectSchema">
                      </instanceof>
                   </or>
                </parentExpression>
             </commonSorter>
          </navigatorContent>
          <actionProvider
                class="customnavigator.popup.actionprovider.CustomNewActionProvider"
                id="customnavigator.popup.actionprovider.CustomNewAction">
             <enablement>
                <or>
                   <instanceof
                         value="customnavigator.navigator.ICustomProjectElement">
                   </instanceof>
                   <adapt
                         type="java.util.Collection">
                      <count
                            value="0">
                      </count>
                   </adapt>
                </or>
             </enablement>
          </actionProvider>
          <actionProvider
                class="customnavigator.popup.actionprovider.CustomRefreshActionProvider"
                id="customnavigator.popup.actionprovider.CustomRefreshAction">
             <enablement>
                <or>
                   <instanceof
                         value="customnavigator.navigator.ICustomProjectElement">
                   </instanceof>
                   <adapt
                         type="java.util.Collection">
                      <count
                            value="0">
                      </count>
                   </adapt>
                </or>
             </enablement>
          </actionProvider>
          <commonWizard
                type="new"
                wizardId="customplugin.wizard.new.custom">
             <enablement></enablement>
          </commonWizard>
       </extension>
       <extension
             point="org.eclipse.ui.commands">
          <command
                description="%command.schemaTable.description"
                id="customnavigator.newSchemaTable"
                name="%command.schemaTable.name">
          </command>
          <command
                description="%command.schemaView.description"
                id="customnavigator.newSchemaView"
                name="%command.schemaView.name">
          </command>
          <command
                description="%command.schemaFilter.description"
                id="customnavigator.newSchemaFilter"
                name="%command.schemaFilter.name">
          </command>
          <command
                description="%command.storedProcedure.description"
                id="customnavigator.newStoredProcedure"
                name="%command.storedProcedure.name">
          </command>
       </extension>
       <extension
             point="org.eclipse.ui.handlers">
          <handler
                class="customnavigator.handler.BogusHandler"
                commandId="customnavigator.newSchemaTable">
             <enabledWhen>
                <with
                      variable="selection">
                   <iterate>
                      <or>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectParent">
                         </instanceof>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectSchema">
                         </instanceof>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectSchemaTables">
                         </instanceof>
                      </or>
                   </iterate>
                </with>
             </enabledWhen>
          </handler>
          <handler
                class="customnavigator.handler.BogusHandler"
                commandId="customnavigator.newSchemaView">
             <enabledWhen>
                <with
                      variable="selection">
                   <iterate>
                      <or>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectParent">
                         </instanceof>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectSchema">
                         </instanceof>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectSchemaViews">
                         </instanceof>
                      </or>
                   </iterate>
                </with>
             </enabledWhen>
          </handler>
          <handler
                class="customnavigator.handler.BogusHandler"
                commandId="customnavigator.newSchemaFilter">
             <enabledWhen>
                <with
                      variable="selection">
                   <iterate>
                      <or>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectParent">
                         </instanceof>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectSchema">
                         </instanceof>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectSchemaFilters">
                         </instanceof>
                      </or>
                   </iterate>
                </with>
             </enabledWhen>
          </handler>
          <handler
                class="customnavigator.handler.BogusHandler"
                commandId="customnavigator.newStoredProcedure">
             <enabledWhen>
                <with
                      variable="selection">
                   <iterate>
                      <or>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectParent">
                         </instanceof>
                         <instanceof
                               value="customnavigator.navigator.CustomProjectStoredProcedures">
                         </instanceof>
                      </or>
                   </iterate>
                </with>
             </enabledWhen>
          </handler>
       </extension>
       <extension
             point="org.eclipse.ui.menus">
          <menuContribution
                allPopups="false"
                locationURI="popup:common.new.menu?after=additions">
             <command
                   commandId="customnavigator.newSchemaTable"
                   style="push">
                <visibleWhen
                      checkEnabled="true">
                </visibleWhen>
             </command>
             <command
                   commandId="customnavigator.newSchemaView"
                   style="push">
                <visibleWhen
                      checkEnabled="true">
                </visibleWhen>
             </command>
             <command
                   commandId="customnavigator.newSchemaFilter"
                   style="push">
                <visibleWhen
                      checkEnabled="true">
                </visibleWhen>
             </command>
             <command
                   commandId="customnavigator.newStoredProcedure"
                   style="push">
                <visibleWhen
                      checkEnabled="true">
                </visibleWhen>
             </command>
          </menuContribution>
       </extension>
       <extension
             point="org.eclipse.ui.commandImages">
          <image
                commandId="customnavigator.newSchemaTable"
                icon="icons/project-schema-tables.png">
          </image>
          <image
                commandId="customnavigator.newSchemaView"
                icon="icons/project-schema-views.png">
          </image>
          <image
                commandId="customnavigator.newSchemaFilter"
                icon="icons/project-schema-filters.png">
          </image>
          <image
                commandId="customnavigator.newStoredProcedure"
                icon="icons/project-stored-procedures.png">
          </image>
       </extension>
    
    </plugin>
    

    MANIFEST.MF

    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: %Bundle-Name
    Bundle-SymbolicName: customnavigator;singleton:=true
    Bundle-Version: 1.0.2.4
    Bundle-Activator: customnavigator.Activator
    Require-Bundle: org.eclipse.ui,
     org.eclipse.core.runtime,
     org.eclipse.core.resources,
     org.eclipse.ui.ide;bundle-version="3.6.0",
     org.eclipse.ui.navigator,
     customplugin;bundle-version="1.0.1"
    Bundle-ActivationPolicy: lazy
    Bundle-RequiredExecutionEnvironment: JavaSE-1.6
    Export-Package: customnavigator,
     customnavigator.navigator,
     customnavigator.popup.actionprovider,
     customnavigator.sorter
    
    About these ads
    1. October 23, 2010 at 12:19 am

      Very nicely made tutorial. This helped me when I was stuck in creating my own plugin. Thanks

    2. nm
      November 18, 2010 at 3:56 pm

      Hello,
      Firstly, these tutorials are extremely useful. Everything is explained so well and the steps are outlined in a progressive manner which makes it easier to understand the whys and the hows.
      Thank you so much for them.
      I was wondering under what license is your code distributed?

      • cvalcarcel
        November 21, 2010 at 1:09 pm

        The code is distributed under the Coder Beware license. Use it as long as you don’t blame me for anything that goes wrong. Ever. For anything. Not even for your relationships. Or badly prepared food. Or anything that may or may not have happened in an alternate time stream. Especially alternate time streams.

        • nm
          November 22, 2010 at 5:21 am

          Yes, I completely agree with the alternate time streams; you never know what to expect there.
          Does this license also apply for commercial use?

    3. João Peixoto
      July 11, 2011 at 5:47 pm

      Thank you so much for your Hidden Clause plugin series!
      I read them all so far and it was exactly what I was looking forward to.

      Will we see any editor related plugin entries soon? You’ve spent a considerable amount of time on the navigator part (and thank you for that) but I think editors would be a great next step.

      Keep up the good work and once again, thank you so much.

    4. Martin Röbert
      February 10, 2012 at 8:43 am

      I have to join the other posters: Thanks for all these great articles.

      Maybe it is possible to provide all these articles as one file for a better reading experience?

      Cheers,
      Martin

    5. Sarim Hussain
      February 13, 2012 at 1:00 am

      I have no errors while running my project in the runtime workbench but when I try to deploy it as a jar (using Export Wizards link), the jar file created does not work in other standard eclipse versions. I have tried putting the jars in pulgins folder of eclipse installations but to no avail. Can anyone please tell me what the issue might be all about?

    6. Martin Röbert
      February 13, 2012 at 9:14 am

      I would try to create a Feature for all plugins you need. Afterwards generate a P2/Eclipse repository; this’ll add all needed dependecies to your (vanilla) eclipse installation.

    7. mat
      July 26, 2012 at 9:13 am

      this is nice but the file created is not shown in the navigator. How we can extend this navigator to achieve this?

    1. No trackbacks yet.

    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s

    Follow

    Get every new post delivered to your Inbox.

    Join 3,182 other followers

    %d bloggers like this: