Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Rich Client Platform (RCP) » org.eclipse.ui.menus menuContribution: how to make <activeWhen> test the state of the selectio
org.eclipse.ui.menus menuContribution: how to make <activeWhen> test the state of the selectio [message #528782] Wed, 21 April 2010 18:06 Go to next message
Mike Norman is currently offline Mike NormanFriend
Messages: 35
Registered: July 2009
Member
I have built a TreeViewer and hooked up some commands and menuContributions to the viewer's popup menu:

     <menuContribution
           locationURI="popup:org.eclipse.ui.popup.any?after=additions">
        <command
              commandId="ca.carleton.tim.ksat.client.command.ConnectToDatabase"
              label="Connect to Database"
              style="push">
               <visibleWhen
                     checkEnabled="false">
                 <with
                   variable="activeMenuSelection">
                   <iterate operator="and" ifEmpty="false">
                      <adapt
                            type="ca.carleton.tim.ksat.client.AnalysisDatabase">
                      </adapt>
                    </iterate>
                 </with>
               </visibleWhen>
        </command>
     </menuContribution>


This allows me to select the 'Database' node and have a menu-item 'Connect to Database' popup.

What I would really like is to popup a menu with 2 commands - 'Connect' and 'Disconnect' with one or the other grey'd out depending on the result of:

IStructuredSelection selection = (IStructuredSelection)HandlerUtil.getActiveMenuSelection(event);
AnalysisDatabase database = (AnalysisDatabase)selection.getFirstElement();
database.isConnected();


Is this possible to specify in the plugin.xml, or does this have to be done in code - and if so, how does one popup two menu items, one enabled the other grey'd out, based on the answer to isConnected() ???

Thanks in advance,
Mike Norman
Re: org.eclipse.ui.menus menuContribution: how to make <activeWhen> test the state of the sele [message #528787 is a reply to message #528782] Wed, 21 April 2010 18:25 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

You would have to write a subclass of PropertyTester and contribute it
using an extension point (probably
org.eclipse.core.expressions.propertyTesters).

Then you could use it in an enabledWhen on your handler (similar to your
visibleWhen).

<adapt type="ca.carleton.tim.ksat.client.AnalysisDatabase">
<test property="my.property.namespace.isConnected"/>
</adapt>

See http://wiki.eclipse.org/Command_Core_Expressions for some other
examples of property testers.

PW


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: org.eclipse.ui.menus menuContribution: how to make <activeWhen> test the state of the sele [message #529364 is a reply to message #528787] Sat, 24 April 2010 01:31 Go to previous messageGo to next message
Mike Norman is currently offline Mike NormanFriend
Messages: 35
Registered: July 2009
Member
Ok, I got it mostly working now. For anyone who might be interested, I'll go thru it step-by-step

The menuContribution I described before shows the conditions under which the 'Disconnect from Database' popup-menu will be displayed. The original condition basically just said 'the selection has to be of type AnalysisDatabase' - to make it only popup when the database is connected, we need a couple of things:

Extensions
- org.eclipse.core.expressions.propertyTesters
- org.eclipse.core.expressions.definitions
- org.eclipse.ui.handlers
- org.eclipse.ui.menus (already used)
- org.eclipse.ui.commands (already used)

step 1 - define a propertyTester:

<extension
  point="org.eclipse.core.expressions.propertyTesters">
  <propertyTester
    class="ca.carleton.tim.ksat.client.DbConnectionTester"
    id="ca.carleton.tim.ksat.client.propertyTester.DbConnectionTester"
    namespace="ca.carleton.tim.ksat.client"
    properties="isConnected,isDisconnected"
    type="ca.carleton.tim.ksat.client.AnalysisDatabase">
  </propertyTester>


The class DbConnectionTester extends org.eclipse.core.expressions.PropertyTester and has a single overridden method that has all the 'smarts':

@Override
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
	AnalysisDatabase database = (AnalysisDatabase)receiver;
	if ("isConnected".equals(property)) {
		return database.isConnected();
	}
	else if ("isDisconnected".equals(property)) {
		return !database.isConnected();
	}
	return false;
}


The receiver is the selection from the TreeViewer when the right-clink menu is pop'd up; the property string indicates if the test is for the 'connected' state
or the 'disconnected' state. Going back to the extension point above, the combination of the namespace and one of the properties from the list allows us to use
the class to test 2 different things - true if isConnected or true if !isConnected:
ca.carleton.tim.ksat.client.isConnected
ca.carleton.tim.ksat.client.isDisconnected

step 2 - create the command:
<extension
  point="org.eclipse.ui.commands">
    <command
      id="ca.carleton.tim.ksat.client.command.DisconnectFromDatabase"
      name="DisconnectFromDatabase">
    </command>
(... other commands)

Previously, I had specified a 'Default Handler' with the command, but for some reason that didn't work.

step 3 - create a handler for the command:

<extension
  point="org.eclipse.ui.handlers">
    <handler
      class="ca.carleton.tim.ksat.client.DisconnectFromDatabaseHandler"
      commandId="ca.carleton.tim.ksat.client.command.DisconnectFromDatabase">
      <activeWhen>
        <reference
          definitionId="isConnectedDatabase">
        </reference>
      </activeWhen>
    </handler>


Originally the menuContribution had the conditions, but I abstracted that out into a definition that can be re-used:

step 4 - create a definition for 'isConnectedDatabase'
<extension
  point="org.eclipse.core.expressions.definitions">
  <definition
    id="isConnectedDatabase">
    <with variable="selection">
      <iterate
        ifEmpty="false"
        operator="and">
        <adapt
          type="ca.carleton.tim.ksat.client.AnalysisDatabase">
        </adapt>
        <test
          forcePluginActivation="true"
          property="ca.carleton.tim.ksat.client.isConnected">
        </test>
      </iterate>
    </with>
  </definition>


Finally,

step 5 - the new-&-improved menuContribution

<menuContribution
  locationURI="popup:org.eclipse.ui.popup.any?after=additions">
  <command
    commandId="ca.carleton.tim.ksat.client.command.DisconnectFromDatabase"
    label="Disconnect from Database"
    style="push">
    <visibleWhen
      checkEnabled="false">
      <reference
        definitionId="isConnectedDatabase">
      </reference>
    </visibleWhen>
  </command>
</menuContribution>


It turns out, there are a number of operations that make sense with the database is connected: disconnect, createNewAnalysis (the child node underneath the database); conversely, only certain operations make sense when the database is disconnected: connect, edit DB properties, remove database.
The <reference> element allows the properties to be re-used across different handlers and menuContributions.

My current issue is refreshing the TreeViewer upon connect/disconnect, the properties aren't being evaluated correctly - anyone know how to force the properties to be re-calculated?
Re: org.eclipse.ui.menus menuContribution: how to make <activeWhen> test the state of the sele [message #529593 is a reply to message #529364] Mon, 26 April 2010 13:29 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Mike Norman wrote:
>
> My current issue is refreshing the TreeViewer upon connect/disconnect,
> the properties aren't being evaluated correctly - anyone know how to
> force the properties to be re-calculated?

Variables that come from source providers (selection, activePart, etc)
are event driven and get recalculated. Properties aren't (since a
property tester is just a method call). But you can request that a
property be re-evaluated if you know it has changed:

org.eclipse.ui.services.IEvaluationService.requestEvaluation (String)

PW

--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: org.eclipse.ui.menus menuContribution: how to make <activeWhen> test the state of the sele [message #529599 is a reply to message #529593] Mon, 26 April 2010 14:05 Go to previous message
Mike Norman is currently offline Mike NormanFriend
Messages: 35
Registered: July 2009
Member
Thanks Paul, I (sorta) figured it out.

Perhaps I was trying to be too clever, but I create 2 properties:
isConnected and isDisconnected and hooked them up to
my custom PropertiesTester (and used them across a bunch
of definitions and command-handlers).

When I asked the IEvaluationService to re-calculate them,
something didn't quite go right.

So, I reduced things to a single property 'isConnected' and in
my definition added a boolean condition:

<definition
      id="isDisconnectedDatabase">
      <with variable="selection">
         <iterate
               ifEmpty="false"
               operator="and">
            <adapt
                  type="ca.carleton.tim.ksat.client.AnalysisDatabase">
            </adapt>
            <not>
                <test
                      forcePluginActivation="true"
                      property="ca.carleton.tim.ksat.client.isConnected">
                </test>
            </not>
         </iterate>
      </with>
</definition>


After that, all my 'conditional' menus are working.
Previous Topic:How to reinitialize Equinox?
Next Topic:Fail to show splash screen when launch with JNLP
Goto Forum:
  


Current Time: Tue Apr 23 06:37:23 GMT 2024

Powered by FUDForum. Page generated in 0.03314 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top