| org.eclipse.ui.menus menuContribution: how to make <activeWhen> test the state of the selectio [message #528782] |
Wed, 21 April 2010 14:06  |
Eclipse User |
|
|
|
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 #529364 is a reply to message #528787] |
Fri, 23 April 2010 21:31   |
Eclipse User |
|
|
|
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 #529599 is a reply to message #529593] |
Mon, 26 April 2010 10:05  |
Eclipse User |
|
|
|
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.
|
|
|
Powered by
FUDForum. Page generated in 0.05272 seconds