Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » [commands] Help with handler enabledWhen
[commands] Help with handler enabledWhen [message #482794] Thu, 27 August 2009 22:12 Go to next message
Will Horn is currently offline Will Horn
Messages: 265
Registered: July 2009
Senior Member
I have a view toolbar contribution and I need to tie the button's enablement
to a property of the view. I created a property tester for the view, but I
don't know how to set the view as the active variable in a enabledWhen
element.

"with(activePart)" only works when the view is active.

I also tried changing the property tester's type to IWorkbenchWindow, and
then used "with(activeWorkbenchWindow)". This got me slightly farther, but
I still have problems when when a dialog is popped up (since I guess the
workbench window is not active). This is also a hack because the property
is not related to IWorkbenchWindow.

I saw enabledWhen's documentation mentions a "resolve" element, but I could
not find any examples or further information.

What I really want to do is create a handler that is active when my view is
open, and enabled when my view's "ready" property is "true". Any
suggestions?

Thanks,
Will
Re: [commands] Help with handler enabledWhen [message #482885 is a reply to message #482794] Fri, 28 August 2009 09:02 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Will Horn wrote on Thu, 27 August 2009 22:12
I

What I really want to do is create a handler that is active when my view is
open, and enabled when my view's "ready" property is "true". Any
suggestions?

Thanks,
Will


I believe you need to activate your handler programmatically to achieve this. in your createPartControl(*) get the IHandlerService from your workbench window and then activate your handler. It will be active as long as your workbench window is active. Make sure your view dispose() deactivates the handler with the saved IHandlerActivation.

Then you can tie your enabled state to your view property.

You would still potentially see the behaviour when a dialog is popped up. But if you go up to the workbench level to get the IHandlerService to activate your handler, you could never have multiple windows with that view in them.

PW


Re: [commands] Help with handler enabledWhen [message #482967 is a reply to message #482885] Fri, 28 August 2009 14:18 Go to previous messageGo to next message
Will Horn is currently offline Will Horn
Messages: 265
Registered: July 2009
Senior Member
"Paul Webster" <pwebster@ca.ibm.com> wrote in message
news:h78kh0$dva$1@build.eclipse.org...
> I believe you need to activate your handler programmatically to achieve
> this. in your createPartControl(*) get the IHandlerService from your
> workbench window and then activate your handler. It will be active as
> long as your workbench window is active. Make sure your view dispose()
> deactivates the handler with the saved IHandlerActivation.

Thanks, Paul for the helpful reply as usual. One additional design goal
here that I didn't state explicitly is that the view itself not be aware of
the toolbar contribution that is coming from a different optional plugin.

But going the programmatic route, I removed the activeWhen and enabledWhen
XML from my handler and implemented the methods in the AbstractHandler
subclass. Unfortunately, I am finding that this class is not instantiated
until the first time I click the toolbar button. I tried making it the
default handler for the command and get the same behavior. Is there a way
to make the framework more eagerly create the handler and ask it isEnabled?
Waiting for the user to click it defeats the purpose of enablement :o)

-Will
Re: [commands] Help with handler enabledWhen [message #482969 is a reply to message #482967] Fri, 28 August 2009 14:38 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

A contribution from a different plugin changes the game, unfortunately, since you only have the declarative support at your disposal.

If you use o.e.ui.handlers to associate your handler to the command and you don't include an activeWhen clause, then that handler will be the default handler. You can then concentrate on the enabledWhen.

Use a context to denote your active case:
<enabledWhen>
<with variable="activeContexts">
<iterate operator="or">
<equals value="your.view.has.property.mode"/>
</iterate>
</with>
</enabledWhen>

Have your view activate the your.view.has.property.mode context when appropriate, and de-activated it when not. Of course this only works if you can change the main view.

PW


Re: [commands] Help with handler enabledWhen [message #482972 is a reply to message #482967] Fri, 28 August 2009 14:37 Go to previous messageGo to next message
Will Horn is currently offline Will Horn
Messages: 265
Registered: July 2009
Senior Member
"Will Horn" <will.horn@gmail.com> wrote in message
news:h79721$74q$1@build.eclipse.org...
> Unfortunately, I am finding that this class is not instantiated until the
> first time I click the toolbar button.
I responded too hastily here. The reason it is lazily instantiated is
because it is defined in the XML. I needed to make it 100% programmatic.
Re: [commands] Help with handler enabledWhen [message #482989 is a reply to message #482969] Fri, 28 August 2009 18:04 Go to previous messageGo to next message
Will Horn is currently offline Will Horn
Messages: 265
Registered: July 2009
Senior Member
Yes, that works! All my other workarounds were looking very messy. I have
never used a context, but this is good example.

One thing that still tripped me up was that I had to get the IContextService
from the workbench instead of my view site for it to be exposed to the
handler's enablement expression. After thinking about it, this makes sense
since it is a global command handler.

I am very grateful for Paul's solution, but I think it still qualifies as
workaround. Fortunately, at this point I only have a single instance of my
view, but what if there were more than one? When you contribute a button to
a view's toolbar, it is very likely that the button is tied to that single
view instance. It's enablement state should not have to be tied to a global
property.

For example, the Eclipse Console view has a "Clear Console" button. It
doesn't seem like such a button could be contributed by a third party plugin
through the commands framework. Only one handler can be active at a time
(and thus only one handler can be enabled), but I may have two console views
both showing different text that can be cleared. I'd want both buttons to
be enabled at the same time even though their handlers are different. At
other times, one would be enabled and one would be disabled. Sometimes both
would be disabled.

This issue is specifically about toolbars. A toolbar button should be
enabled if can be run as soon as you click it, that is, as soon as the view
(or maybe window) is activated. To me this means the button's enablement
state should be the result of evaluating the enabledWhen expression *as if*
the view were the activePart. I'm not saying the handler should be
activated - it is clear to me that there should only be one handler active
at a time (for keyboard shortcuts, etc.), but I think toolbar contributions
need a way to decouple their enablement from the handler's activation.

The following XML for the handler (what I had originally) is intuitive and
works perfect once the view has focus:

<activeWhen>
<with
variable="activePartId">
<equals
value="org.example.view">
</equals>
</with>
</activeWhen>
<enabledWhen>
<with
variable="activePart">
<test
property="org.example.view.enabled"
value="true">
</test>
</with>
</enabledWhen>

Would there be a way make the toolbar button enablement more intelligent so
that even when the view loses focus, it can compute properly?

-Will

"Paul Webster" <pwebster@ca.ibm.com> wrote in message
news:h7986g$jrn$1@build.eclipse.org...
>A contribution from a different plugin changes the game, unfortunately,
>since you only have the declarative support at your disposal.
>
> If you use o.e.ui.handlers to associate your handler to the command and
> you don't include an activeWhen clause, then that handler will be the
> default handler. You can then concentrate on the enabledWhen.
>
> Use a context to denote your active case:
> <enabledWhen>
> <with variable="activeContexts">
> <iterate operator="or">
> <equals value="your.view.has.property.mode"/>
> </iterate>
> </with>
> </enabledWhen>
>
> Have your view activate the your.view.has.property.mode context when
> appropriate, and de-activated it when not. Of course this only works if
> you can change the main view.
>
> PW
>
Re: [commands] Help with handler enabledWhen [message #483186 is a reply to message #482989] Mon, 31 August 2009 10:00 Go to previous message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Will Horn wrote on Fri, 28 August 2009 18:04
I am very grateful for Paul's solution, but I think it still qualifies as
workaround. Fortunately, at this point I only have a single instance of my
view, but what if there were more than one? When you contribute a button to
a view's toolbar, it is very likely that the button is tied to that single
view instance. It's enablement state should not have to be tied to a global
property.

[... snip ...]


Would there be a way make the toolbar button enablement more intelligent so
that even when the view loses focus, it can compute properly?




This is one of the design constraints of commands in 3.x. There is a Global Application State. It works well for eclipse main usecases, but does the wrong in the "this is really a local command+state" problem, as in your multi-instance view example (where the command state is dependent on its own view instance). It's not limited to views, we had to do special processing on window toolbars to support the 2 workbench window usecase (so as not to flash the inactive window toolbar to no purpose).

In e4 (for eclipse 4.0) we are working on a hierarchy of contexts (In 3.x the IEvaluationContext that stores variables) that can support a better general lookup strategy as well as control of the lookup strategy as specific points in the hierarchy (for hierarchy, think workbench->workbench window->active part).

So when the command in view 1 computes its enabled state, it sees the world from view 1 and when the same command which is also visible but in inactive view 2 computes its enabled state, it sees the world from view 2.

PW


Previous Topic:Using JNDI in Eclipse
Next Topic:Moving a newly created Instance of a ViewPart
Goto Forum:
  


Current Time: Sat Aug 30 02:31:38 EDT 2014

Powered by FUDForum. Page generated in 0.01904 seconds