Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » visibleWhen expression is not always evaluated when a custom source changes
visibleWhen expression is not always evaluated when a custom source changes [message #326061] Thu, 06 March 2008 17:22 Go to next message
Ryan Norris is currently offline Ryan NorrisFriend
Messages: 18
Registered: July 2009
Junior Member
I'm using Eclipse 3.4M5. I have a visibleWhen expression defined for a
toolbar contribution to a view and the expression only gets evaluated
when the view is the active view. The expression uses a <with> tag that
checks a custom source provider's property. This property can change
independently of the active part. Is this a bug or is there a way to
have the expression always evaluated when the source provider changes?

It appears that the postingChanges property on the EvaluationReference
object is false when the view is not active and as a result the
expression doesn't get evaluated (in
EvaluationAuthority.refsWithSameExpression()) after the source provider
fires a source changed event.

I created a test case using a test plug-in and the Eclipse IDE where I
have a source provider that exposes a custom source name called
"customsource.visible". The values are true or false. I put an action
on the main menu that toggles the property. I then added an action to
the Package Explorer. This action should only be visible when
customsource.visible=true. If Package Explorer is the active part this
works. If it is not the active part it doesn't work.

Here's the xml for the menu contribution:

<menuContribution

locationURI="toolbar:org.eclipse.jdt.ui.PackageExplorer?after=additions ">
<command
commandId="com.sas.csp.test"
id="com.sas.csp.test.toolitem"
label="Test Action"
style="push"
tooltip="Test Action">
<visibleWhen
checkEnabled="false">
<with
variable="customsource.visible">
<equals
value="true">
</equals>
</with>
</visibleWhen>
</command>
</menuContribution>

Here's the definition of the custom source provider:

public class CustomSourceProvider extends AbstractSourceProvider {

public static final String CUSTOM_SOURCE = "customsource.visible";

private boolean _on;

public void dispose() {
// empty
}

public Map<String, Boolean> getCurrentState() {
Map<String, Boolean> map = new HashMap<String, Boolean>(1);
map.put(CUSTOM_SOURCE, _on);
return map;
}

public void toggle() {
_on = !_on;
fireSourceChanged(ISources.WORKBENCH, getCurrentState());
}

public String[] getProvidedSourceNames() {
return new String[] { CUSTOM_SOURCE };
}
}

Here's how I register the source provider in the activator's start():

IEvaluationService service =
(IEvaluationService)PlatformUI.getWorkbench().getService(IEv aluationService.class);
service.addSourceProvider(getCustomSourceProvider());

Thanks in advance for any help,
-Ryan
Re: visibleWhen expression is not always evaluated when a custom source changes [message #326080 is a reply to message #326061] Fri, 07 March 2008 00:30 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Ryan Norris wrote:
> I'm using Eclipse 3.4M5. I have a visibleWhen expression defined for a
> toolbar contribution to a view and the expression only gets evaluated
> when the view is the active view. The expression uses a <with> tag that
> checks a custom source provider's property. This property can change
> independently of the active part. Is this a bug or is there a way to
> have the expression always evaluated when the source provider changes?

This is a feature. A view's toolbar visibleWhens are only re-evaluated
when the view is active. It works at the window level, a window's
toolbar visibleWhens are only re-evaluated when that window is active.
Otherwise changing the global state (which is what a source is) would
cause "uninteresting" components like views your not working on,
secondary windows that are not active, etc to have their toolbar flickering.

If you're interested in the actual cause, check out
org.eclipse.ui.internal.menus.WorkbenchMenuService.registerV isibleWhen(IContributionItem,
Expression, Expression, String) for its use and
org.eclipse.ui.internal.menus.MenuServiceFactory which is creating the
SlaveMenuService for each part with the ActivePartExpression()

>
> Here's the definition of the custom source provider:
>
> public class CustomSourceProvider extends AbstractSourceProvider {
> }
>
> Here's how I register the source provider in the activator's start():
>
> IEvaluationService service =
> (IEvaluationService)PlatformUI.getWorkbench().getService(IEv aluationService.class);
>
> service.addSourceProvider(getCustomSourceProvider());

In 3.4M6 it will be easier to add your own custom source provider using
the org.eclipse.ui.services extension point, as even the handlers
activeWhen expressions will honour it.

PW



--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse. platform.doc.isv/guide/workbench.htm


Re: visibleWhen expression is not always evaluated when a custom source changes [message #326534 is a reply to message #326080] Sun, 23 March 2008 04:46 Go to previous messageGo to next message
Ryan Norris is currently offline Ryan NorrisFriend
Messages: 18
Registered: July 2009
Junior Member
Paul,

Thanks very much for the response. I've included some comments and
questions below.

-Ryan

Paul Webster wrote:

> This is a feature. A view's toolbar visibleWhens are only re-evaluated
> when the view is active. It works at the window level, a window's
> toolbar visibleWhens are only re-evaluated when that window is active.
> Otherwise changing the global state (which is what a source is) would
> cause "uninteresting" components like views your not working on,
> secondary windows that are not active, etc to have their toolbar
> flickering.
>


I'm trying to detect a change in the global state of my application in
all of my views. Perhaps I should describe the design of my application
to illustrate what I'm trying to do...

The application that I work on is an object manager type application.
That is, it contains views for viewing and managing various objects in
our system (each object type has its own view, which contains either a
table or a tree table...6 views total). We have a root object which
contains or has relationships with various other objects. Of the owned
or related objects, each has its own view for displaying and managing
them. The root object has a property which controls which behaviors are
available on the subordinate objects (type 1 allows more behavior, type
2 allows less). When the user enters the application they "open" one of
the available root objects. All views are then filtered based on this
root object. The user can then choose to change the "open" root object.

If the user changes the open object from type 1 to type 2, any open
views need to adapt to either allow or restrict the behaviors based on
this change.


In my previous post, I described a source provider. I created a source
provider that fires a change whenever the open object changes (the
global state for my application). I would like for the actions
contributed to the local menus, local tool bars and context menus of the
views in my application to have their visibleWhen conditions
re-evaluated when this event occurs. For example, if the open object is
type 1 several actions should appear on the action bars and if the open
object is type 2 they should disappear. As described in the previous
post I can only get this to occur for the active view whenever of the
change takes place.

I understand that in general it may not be a good idea for all views to
react to a global change especially for larger open applications like
the Eclipse IDE, however, this is the behavior I would like in my more
closed application.

Can you suggest a way for me to get this behavior to occur? Is there
another way of designing my views or for contributing such that I can
have actions appear and disappear in this manner?

Should I request a new feature? If so I suspect it wouldn't be
something that would or could be completed for 3.4 which is what I will
be shipping with. Perhaps views could register as interested parties
for source changes to enable re-evaluation of only a subset of
non-active views?
Re: visibleWhen expression is not always evaluated when a custom source changes [message #326611 is a reply to message #326534] Wed, 26 March 2008 14:31 Go to previous message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Ryan Norris wrote:

> Can you suggest a way for me to get this behavior to occur? Is there
> another way of designing my views or for contributing such that I can
> have actions appear and disappear in this manner?

There aren't any easy ways, that I can think of. The "guy" causing your
problems is in org.eclipse.ui.internal.ViewReference.createPartHelper()
....
IMenuService menuService
= (IMenuService) site.getService(IMenuService.class);

This restricts your view toolbar and menu to your site (active view).

You can't control the items added to your view location URI, but you
could use add them via a secondary ID that you control.

i.e. in your createPartControl(*):
IMenuService menuService = PlatformUI.getWorkbench()
.getService(IMenuService.class);
if (getViewSite().getActionBars().getToolBarManager() instanceof
ContributionManager) {
menuService.populateContributionManager(
(ContributionManager) site.getActionBars().getToolBarManager(),
"toolbar:my.view.id.special.toolbar");
}

Because this is the global menu service, it wouldn't have the "active
view" restriction on it.

And of course, read the javadoc and make sure you release it (using the
same menu service) in your dispose() method:
IMenuService menuService = PlatformUI.getWorkbench()
.getService(IMenuService.class);
// ... etc

As an aside, it's a service best practice to get the services you when
you need them, as opposed to storing them in a field.

>
> Should I request a new feature? If so I suspect it wouldn't be
> something that would or could be completed for 3.4 which is what I will
> be shipping with. Perhaps views could register as interested parties
> for source changes to enable re-evaluation of only a subset of
> non-active views?

You can of course file a new feature ... I'd be looking for some
suggestions on a simple way to implement this kind of control, however.

PW


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse. platform.doc.isv/guide/workbench.htm


Previous Topic:Editors and perspectives
Next Topic:Using IHandlerService in modal dialog
Goto Forum:
  


Current Time: Wed Jan 15 09:35:12 GMT 2025

Powered by FUDForum. Page generated in 0.03393 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top