Community
Participate
Working Groups
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.
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.
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.
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.
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.
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?
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!
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.
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.
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."
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?
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).
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?
Reassigning to Platform-UI-Inbox (I left IBM 18 months ago..)
Moving Dougs bugs
Assigning to component owner PW
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.