Search code examples
javaeclipseeclipse-plugineclipse-indigoeclipse-pde

Eclipse plugin : disable/enable dynamically an action from main menubar


EDIT : SOLVED

Background

I have implemented a eclipse plugin (on indigo, 3.7.2) that provide a new icon in the bar menu.

This new action is fully initialized few seconds after eclipse startup (some configuration files are loaded from my maven repository).

I'm trying to disable this action until my activator finish initalization.

What I'm looking for

Before initialization

Disabled

After initialization

Enabled

What I've already done

I added an enablement test on my action. My action will be enabled only if my plugin is activated.

<extension
     point="org.eclipse.ui.actionSets">
  <actionSet
        label="Action Set"
        visible="true"
        id="com.eclipse.plugins.extarcheytpe.actionSet">
     <action
           class="com.eclipse.plugins.extarchetype.actions.ShortcutsAction"
           icon="src/main/resources/icons/generic_box_16x16.png"
           id="com.eclipse.plugins.extarcheytpe.actions.ShortcutsAction"
           label="Shortcuts List"
           style="pulldown"
           toolbarPath="Shortcuts"
           tooltip="Shortcuts">
        <enablement>
           <pluginState
                 id="com.eclipse.plugins.extarchetype"
                 value="activated">
           </pluginState>
        </enablement>
     </action>
  </actionSet>
</extension>

[...]

<extension
      point="org.eclipse.ui.startup">
   <startup
          class="com.eclipse.plugins.extarchetype.Startup">
   </startup>
</extension>

I defined a startup class, where ignite() method initialize my plugin configuration :

public class Startup implements org.eclipse.ui.IStartup{

    @Override
    public void earlyStartup() {
            try {
                Activator.getDefault().ignite();
                Activator.getDefault().setChanged();
                Activator.getDefault().notifyObservers();
            } catch (Exception e) {
                e.printStackTrace();
            }       
    }

}

I implemented an observing design pattern between my action and my activator (to notify the initialization end).

public class ShortcutsAction extends Action implements
        IWorkbenchWindowPulldownDelegate, IMenuCreator, IObserver {

    private IAction action;
    private Menu menu;
    public boolean enabled = false;

    public ShortcutsAction() {
        super();
        Activator.getDefault().addObserver(this);
    }

    @Override
    public void selectionChanged(IAction action, ISelection selection) {
        // Change action object instance at first selection
        if (action != this.action) {
            this.action = action;
        }
        // If property enabled is true, enable this action
        if (enabled) {
            action.setEnabled(true);
        } else {
            action.setEnabled(false);
        }
    }

    [...]

    @Override
    public void update(IObservable obs, Object obj) {
        this.enabled = true;
        ConsoleHandler.logInfo("Shortcut enabled");
        action.setEnabled(true);
    }
}

Conclusion

I got what I was looking for :

  1. At loading, my action is disabled
  2. Since my plugin is initialized, my action is enabled

Thank you.


Solution

  • <objectState> and <objectClass> test the state and class of the currently selected objects not the action handler class.

    I think you would have to use <systemProperty> to check a property that you set. Or use the selectionChanged method to enable the IAction.

    The selectionChanged method is part of the IActionDelegate interface that you are indirectly implementing with IWorkbenchWindowPulldownDelegate:

    public void selectionChanged(IAction action, ISelection selection)
    

    The action parameter is the actual action, call action.setEnabled(true) to enable the action.