views:

3448

answers:

5

In my eclipse RCP 3.3 application, I would like to enable or disable a 'save' toolbar button according to current editor dirty flag.

I'm trying to use the <enabledWhen> tag but I can't make it work.

Here's the portion of code in plugin.xml :

<command
 commandId="org.acme.command.save"
 icon="icons/save.png"
 id="org.acme.command.save"
 style="push">
 <enabledWhen>
    <instanceof value="activeEditor"/>
     <test property="dirty" value="true"/>
 </enabledWhen>
</command>

Do you have any idea how that is supposed to work ?

A: 

I am not sure it can be entirely declarative.

saveAction = ActionFactory.SAVE.create(PlatformUI.getWorkbench().getActiveWorkbenchWindow());
configurer.registerGlobalAction(saveAction);

Ca you check if the following thread can help you ?
In the case of the Save Action, it may be a Retargetable action.

VonC
Thanks for your answer. However, I would like to use the declarative way (by the way, I also tried with a PropertyTester without luck for now). The thread wasn't helpful for my specific problem.
paulgreg
A: 

try this:

org.eclipse.core.variables.dynamicVariables
-(variable) [here you should implement resolver class to return active editor]

org.eclipse.core.expressions.definitions
-(definition)
--(with) [reference here your variable]
---(test) [test if dirty]

org.eclipse.ui.commands !mistake: not commands, but handlers
-(handler)
--(enabledWhen)
---(reference) [reference your definition here]

**(updated)**
org.eclipse.core.properties.propertyTesters
-(propertyTester)

I'm not sure if it will work, but there is a chance...

Imaskar
found, that there is predefined variable for active editor- "activeEditor", so step 1 is not needed.
Imaskar
Thanks. I've just tried that but doesn't seem to work...
paulgreg
By the way, even if I haven't found my answer there, that URL is useful for eclipse core expressions (http://wiki.eclipse.org/Command_Core_Expressions).
paulgreg
found, that the properties are evaluated by property testers and don't check the real object's properties themselves.2nd is that there is no standard property for dirtiness of IEditorPartso, you needorg.eclipse.core.properties.propertyTesters ext.point and your own tester
Imaskar
and also, the property will not be re-evaluated when editor becomes dirty (only when activeEditor is changed).to resolve this you need org.eclipse.ui.services.IEvaluationService.requestEvaluation(String) at the appropriate time to request a re-evaluation.so it's going to java anyway
Imaskar
Arg... Ok, so there's no way to make it work this way. Thanks a lot for your answer !
paulgreg
sorry, no more ideas...
Imaskar
+2  A: 

Support for the 'Save' and 'Save All' actions is provided by the workbench so you don't need to implement it yourself as you are trying to do.

The recommended way is to add the support in your class that extends ActionBarAdvisor. The exact code will depend on the structure of the class, but the bits of code you will need are as follows.

in your field declarations:

private IWorkbenchAction saveAction;
private IWorkbenchAction saveAllAction;

in your makeActions method:

    saveAction = ActionFactory.SAVE.create(window);
    register(saveAction);

    saveAllAction = ActionFactory.SAVE_ALL.create(window);
    register(saveAllAction);

in your fillActionBars method:

    IToolBarManager saveToolbar = new ToolBarManager(SWT.FLAT | SWT.RIGHT);
    saveToolbar.add(saveAction);
    saveToolbar.add(saveAllAction);
    coolBar.add(new ToolBarContributionItem(saveToolbar, "save"));

The workbench will take care of the enabling and disabling for you.

If you do want to implement your own code to do this for whatever reason then the approach you are taking will work. You will need to correct the XML (for example, the instanceof element is checking that the selected object is an instance of a class called 'activeEditor', which is probably not what was intended).

Thanks. I would like to use the XML declarative way but it seems that it is no way. So your code might be useful.
paulgreg
A: 

A brilliant colleague of mine just found the answer for eclipse >= 3.3 :

Here's how to define the command in the plugin.xml :

  <command
        commandId="com.acme.bo.command.done"
        id="com.acme.bo.menu.done"
        label="Command to do">
     <visibleWhen>
        <with variable="activeMenuSelection">
           <iterate>
              <adapt type="com.acme.bo.model.Pojo"></adapt>
              <test
                    args="valueThatYouWantToPassTest"
                    property="com.acme.namespace.testedProperty"
                    value="something">
              </test>
           </iterate>
        </with>
     </visibleWhen>
  </command>

Then, you have to define the propertyTester, again in plugin.xml :

 <extension
       point="org.eclipse.core.expressions.propertyTesters">
    <propertyTester
          class="com.acme.namespace.tester.YourPropertyTester"
          id="com.acme.namespace.tester.testedPropertyTester"
          namespace="com.acme.namespace"
          properties="testedProperty"
          type="com.acme.bo.model.Pojo">
    </propertyTester>
 </extension>

And here is YourPropertyTester class which do the test :

package com.acme.namespace.tester;

import org.eclipse.core.expressions.PropertyTester;

import com.acme.bo.model.Pojo;

public class YourPropertyTester extends PropertyTester {

   @Override
   public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
      if (receiver == null || !(receiver instanceof Pojo))
         return false;

      Pojo pojo = (Pojo) receiver;
      if (args != null) {
         for (Object object : args) {
            if (pojo.getYourProperty().contains((String)object))
               return true;
         }
      }
      return false;
   }
}
paulgreg
A: 

If you encounter problems with property tester activation be aware that your property tester implementation must be located in the same plugin in which it contributes to org.eclipse.core.expressions.propertyTesters extension point.

bartos