Bug 35404 - [Contributions] state: Can't programmatically set initial checked state
Summary: [Contributions] state: Can't programmatically set initial checked state
Status: ASSIGNED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 2.1   Edit
Hardware: PC Windows 2000
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Platform UI Triaged CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-03-20 15:38 EST by Jan Joseph Kratky CLA
Modified: 2019-09-06 16:04 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Joseph Kratky CLA 2003-03-20 15:38:15 EST
I'm trying to do something that I thought would be simple, but it
doesn't seem to be. I have an org.eclipse.ui.actionSets extension that I
want to be manifested as a checkbox-menu-item. To do this, apparently, I
have to add a "true" or "false" value to the state attribute of the
action element in my plugin.xml.

However, I really want to be able to control, *dynamically*, whether or
not the menu item is checked when it's first shown. That is, I have a
persisted property that tells me whether or not the checkbox was checked
when the workbench was last shut down, and I want to restore the menu
item to that state.

IWorkbenchWindowActionDelegate does not give the ability to
do this - I don't get a reference to the IAction object until the menu
item actually is selected.

Some notes I took while trying to find a workaround (never did find one) with 
IWorkbenchWindowPulldownDelegate2:

1) There seems to be no way to make my action manifest itself as a
checkbox-menu-item without specifying a "state" attribute. I tried
overriding the Action's getStyle() method, but it never gets called.

2) When I do provide a "state" attribute ("true" or "false"), that is
how the menu item's check shows up. Any calls to Action.setChecked()
that I insert, for example, in delegate's constructor, or in the
constructor of my Action, have no effect. So, for example, if I insert
'state="false"' in my plugin.xml, no call to Action.setChecked(true)
will cause the menu item to be displayed as checked the first time it is
shown.

Perhaps the 'state' attribute should be able to take a 3rd value in addition 
to 'true' and 'false' that indicates that the initial state will be under 
programmatic control. Or maybe it's OK with the 2 that exist, but there should 
exist some way to programmatically override the value given in the plugin 
descriptor.

See the 'Initial selection of an actionSet' thread (~3/5/03) in the 
eclipse.tools newsgroup for more details, and some context on the workarounds I 
attempted.
Comment 1 Nick Edgar CLA 2003-03-20 16:17:58 EST
It's possible that your action delegate class has not yet been loaded.  They 
are lazily loaded when the action is first run.  Action delegates are also 
loaded when the plugin that contributes them is activated.

If that's not the case, try implementing IActionDelegate2, in addition to 
IWorkbenchWindowActionDelegate.  

You mentioned IWorkbenchWindowPulldownDelegate2.  That is not the interface to 
use for check box actions, but pulldowns also support IActionDelegate2.
Comment 2 Simon Arsenault CLA 2003-03-20 17:38:10 EST
Can you also provide a simple test plugin to show up this problem. In your 
point #2 above, you say "in delegate's constructor, or in the constructor of my 
Action, have no effect". What do you mean by "in the constructor of my Action"? 
You only need to provide an action delegate.
Comment 3 Jan Joseph Kratky CLA 2003-03-20 17:56:48 EST
That's a reference to my failed attempt to use 
IWorkbenchWindowPulldownDelegate2, as was suggested to me on the newsgroup (the 
sample code that served as my basis for that attempt is posted in that thread).

I'll have to try Nick's suggestion of using IActionDelegate2.
Comment 4 Jan Joseph Kratky CLA 2003-03-20 20:46:17 EST
As I feared when I saw that it was yet another delegate, implementing 
IActionDelegate2 does not help. The delegate, following the pattern of all the 
delegates, is not even constructed until the menu item is actually selected, so 
I have no Action to which I can programmatically set a checked state.

The IWorkbenchWindowPulldownDelegate2 still seems like the closest I have 
gotten. Using that delegate, I construct my own MenuItem and Action. But, as I 
mentioned, that action does not respond to my attempts to set its initial state.
Comment 5 Simon Arsenault CLA 2003-03-21 09:23:46 EST
Before your delegate is loaded, the initial state of the toggle menu item is 
control by the value of the state attribute in the plugin.xml file. There is no 
support nor API to set the initial toggle state via other means. Going the 
IWorkbenchPulldownDelegate route will not work.

Can you describe your use case for this? Having a "real world" example would 
help us understand what support we could add to help with this. If there was a 
mechanism via the plugin.xml to specify the state depends on some persisted 
property, would that be sufficient? Or would the delegate need to be loaded 
when the action is initially set to true or false?
Comment 6 Jan Joseph Kratky CLA 2003-03-21 09:40:11 EST
The use case is: I have a checkbox menu item actionSet contribution. A 
persistent property keeps track of the last checked state of the menu item. On 
workbench startup, I wish to restore the menu item's checked state to the state 
it had when the workbench was last shut down.

So the answer to your question, "If there was a 
mechanism via the plugin.xml to specify the state depends on some persisted 
property, would that be sufficient?" is yes!

Comment 7 Simon Arsenault CLA 2003-03-21 10:49:56 EST
Just to clarify one more thing... And it would be ok that the delegate may not 
be loaded at the time? Lets look at two "types" of toggle actions.

1 - The toggle action represent only a state which is used by other actions. 
For example, say there was a toggle action "Verbose". Turning it on/off did not 
cause anything to happen. But when the action "Package for runtime" was called, 
it checked the state of the "Verbose" action and wrote more things to the 
console if on.

2 - The toggle action represents a running process. For example, say there was 
a toggle action "New item alert". Turning it on caused a background process to 
run looking for new items and notifying the user when found. Turning it off, no 
background process would be running.

So in case 1, the workbench could set the initial state of the toggle button 
from a persisted property (or better yet, could just remember it betwee 
shutdown/startup of Eclipse). It would not matter whether the delegate it 
loaded or not.

But in case 2, the delegate would need to be loaded if the state was set to 
true, otherwise, the background process would not be running as expected by the 
user.

For your action, which type would best describe it - 1 or 2? Or is there 
another type?

Sorry for all the questions. We just want to fully understand as many of the 
use cases for this so we can determine what solution would be best and still 
only load plugins as late as possible.
Comment 8 Jan Joseph Kratky CLA 2003-03-21 11:44:59 EST
Your scenario #2 really describes what I am trying to do, but I don't think the 
solution you propose for #1 would still be sufficient. 

My plug-in has a subsystem that must be launched if my persistent property is 
set to true. However, I must launch that subsystem on a background thread at 
the time my plug-in starts up. The startup wouldn't wait for the first time the 
menu item is shown.

In general, I think the checked state of the menu item would reflect a state of 
affairs that is independent of whether the user has looked at the menu item 
yet, and therefore, up-front construction of the delegate wouldn't be necessary.

I am assuming that you are talking about constructing the delegate when the 
menu item is shown. I may be misunderstanding, and you may be talking about 
constructing the delegate on plug-in startup. That would perhaps make for 
cleaner code, as I can simply detect the state change in the menu item on 
startup and start my subsystem as needed, in lieu of having an independent read 
of the persistent property. But there are good reasons for not going down that 
route: 1) it probably would have a negative impact on workbench startup time. 
2) (this is just a more obscure gut feeling I have, and I apologize if it 
doesn't make much sense) i don't think it wouldn't encourage good (MVC) design 
on the part of the coder contributing to the actionSet, as the menu item itself 
would somehow become a mix of all three MVC elements.

Of course, there may be other users out there who could come up with a 
different scenario. Perhaps they would want to perform some calculation to 
determine the initial checked state. How would you design for that? Sounds like 
you would need to ask users to supply in their extension a class that handles 
this, and you would have to check a method in that class (which will of course 
implement some interface you supplied) to establish the state. This is not what 
I am asking for, but I guess I could see the scenario arise.
Comment 9 Jan Joseph Kratky CLA 2003-03-21 12:49:05 EST
Sorry Simon, typed too fast. In the second sentence of my previous comments, I 
of course meant to say "I *do* think the solution you propose for #1 would 
still be sufficient."
Comment 10 Simon Arsenault CLA 2003-03-21 15:12:16 EST
So you would be ok with the following scenario...
- User starts up Eclipse first time
- Turns on your toggle action, which causes your delegate (& plug-in) to load
- Your delegate launches the background process
- User exits Eclipse
- User restarts Eclipse

Now at this point, lets assume the workbench was able to remember your action 
being in the "on" toggle state and restores it that way. Lets also assume that 
your plugin was not started (workbench lazy loads a plug-in - that is only when 
the user does something that requires that plug-in's code, like running an 
action, showing a view/editor, etc).

So your action would be in the "on" toggle state, but yet no background process 
would be running since your delegate is not loaded because your plugin is not 
loaded. Is that acceptable? Or would you require that if the action is restored 
in the "on" toggle state, that the delegate be loaded (and therefore the plug-
in also), and call "run" on the delegate?
Comment 11 Jan Joseph Kratky CLA 2003-03-21 15:27:03 EST
In my particular case, I need to force plug-in load at startup anyway, so I 
take the extreme but necessary step of extending org.eclipse.ui startup. So 
your first proposal would be acceptable to me.

But I can anticipate someone wanting the behavior in your second proposal. In 
fact, I referred someone from the eclipse.tools newsgroup to this bug; he may 
have a different opinion on this (see today's post by Christian Lemer).
Comment 12 Christian LEMER CLA 2003-03-24 04:34:35 EST
Our problem may be related but could be solved (maybe) in another way. Our problem is also related to the access to the IAction, but we were able to solve the initial status with the XML rules.Our problem is that the status could only be modified during the run or the selectionChanged. Unfortunately, in our case, the connection status could be changed in other situations... Should we fire a fake selectionChanged in some way?
Comment 13 Chris McLaren CLA 2005-12-12 16:57:31 EST
Reassigning to Platform-UI-Inbox (I left IBM 18 months ago..)
Comment 14 Michael Van Meekeren CLA 2006-04-21 13:56:38 EDT
Moving Dougs bugs
Comment 15 Paul Webster CLA 2007-04-05 19:02:09 EDT
Assigning to component owner
PW
Comment 16 Eclipse Webmaster CLA 2019-09-06 16:04:44 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.