[commands] Counterpart of activateHandler for dynamic menus? [message #655724] |
Tue, 22 February 2011 08:14  |
Eclipse User |
|
|
|
The IHandlerService allows for programmatic creation and activation
of command handlers which is a Good Thing(TM) in some scenarios.
Similarly, sometimes one needs programmatically created menus,
especially if these are dynamic ones. The idiomatic way to realize this
is to create an AbstractContributionFactory instance and use the
IMenuService for the provision of this "service". But there is one
disadvantage of the latter approach: I'm required to provide the
location URI via program code as well. This is very unfortunate, because
this does not allow for a proper separation of the "spacial" declaration
of functionality (usually done via the extension point
org.eclipse.ui.menus where the placement of the contribution is
configured) and the provision of the functionality, i.e. the actual
dynamic creation of the contribution items, which typically needs the
programmatically provided context data.
Does there already exist some support for declarative menu declarations
that are fed by programmatically created contribution items? Note that
in my use-case it would *not* be sufficient to provide the context data
via plugin declaration: This needs to be done within an internal part
within my view (actually at the same point where I would use the
IHandlerService to activate programmatic handlers).
I'm aware that I could define my own osgi or Eclipse UI service to
communicate between the menu creation and the view state, but I would
prefer to use existing architecture, if possible (I consider
SourceProviders as equivalent to UI services in this context).
Thanks & Greetings from Bremen
Daniel Krügler
|
|
|
|
|
|
Re: [commands] Counterpart of activateHandler for dynamic menus? [message #655807 is a reply to message #655806] |
Tue, 22 February 2011 11:47  |
Eclipse User |
|
|
|
On 2011-02-22 17:35, Paul Webster wrote:
> On 02/22/2011 10:52 AM, Daniel Krügler wrote:
>> The problem with this approach is, that the CompoundContributionItem
>> derivative will be constructed by the extension point registry and thus
>> it is impossible to inject the state from the local context where this
>> would be necessary. Compare it with the CollapseAllHandler: We need
>> to call IHandlerService.activateHandler at the local context where we
>> know about the Viewer, therefore we can invoke this functiona
>> programmatically within our hook-contextmenu function of a view-part. I
>> need exactly the same thing for menus, but see no way for this unless I
>> provide my own service-oriented machinery.
>
> Bridging local context to menus is not an easy thing.
>
> But the mechanism I've seen used is:
>
> class MyDynamicContribution extends CompoundContributionItem implements
> IWorkbenchContribution {
>
>
> public void initialize(IServiceLocator serviceLocator) {
> locator = serviceLocator;
> }
>
> }
>
> Then in getContributionItems() you can use the locator to get standard
> services, like the IPageService or the IEvaluationService (which gives
> you access to the system state, including your view as the active part).
Thanks for your - as usual - excellent suggestions. I agree that I could
follow this approach, but I would prefer not to :-) Let me explain why:
Only the view internals know about the details of constructing the
contribution items, and I would prefer not to give public access to it.
I think now that I will provide my own service, let's name it
IContributionFactory, which allows me to register a contribution item
factory by ID. In the view part, I will use this service and will
register a local implementation via some unique id (similar to
IHandlerService.activateHandler) and will unregister this in the dispose
function (were I will invoke my IHandlerService.deactivateHandler
functions as well). I will use a reusable CompoundContributionItem
similar to as you suggest which will also implement
IExecutableExtension. This allow me to use the <dynamic>
element via the : notation to define the org.eclipse.ui.menus in the
plugin.xml referring to this reusable CompoundContributionItem. The
implementation of this will also implement IWorkbenchContribution (as
you suggested) to have a service locator handy. By reading the
associated ID from IExecutableExtension it will use the service locator
to get my IContributionFactory service where I have a function that
takes the ID and which returns me the contribution items, voilà!
Thanks again,
- Daniel
|
|
|
Powered by
FUDForum. Page generated in 0.24915 seconds