Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Rich Client Platform (RCP) » Contextual menu / selection provider / forms UI problems
Contextual menu / selection provider / forms UI problems [message #682582] Sat, 11 June 2011 10:41 Go to next message
Christophe Fondacci is currently offline Christophe Fondacci
Messages: 95
Registered: July 2009
Location: Paris
Member
Hi,

I am used to add context menus to views and editors where there is generally one and only one selection provider to register, but now I am trying to add a context menu in a form page.

Since I got the same kind of need, I did the same kind of implementation as I did before :
* The form page uses the master/details pattern
* The master block is composed of a TableViewer which handles the list of master items
* Since I want context menu on elements from this table, here is the code I added :
MenuManager contextMenu = new MenuManager();
contextMenu.setRemoveAllWhenShown(true);

// this is to work around complaints about missing standard groups.
contextMenu.addMenuListener(new IMenuListener() {

	public void menuAboutToShow(IMenuManager manager) {
		manager.add(new GroupMarker("editions"));
		manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
		manager.add(new GroupMarker("version")); //$NON-NLS-1$
		manager.add(new GroupMarker("sql"));
		manager.add(new GroupMarker("actions"));
	}
});

IWorkbenchPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
		.getActivePart();
part.getSite().registerContextMenu("typedListBlock_" + contentProvider.toString(),
		contextMenu, viewer);
Menu menu = contextMenu.createContextMenu(viewer.getTable());
viewer.getTable().setMenu(menu);


Now when I right click on an element from the viewer, I do get a context menu, but which is filled with only one menu item (I cannot understand why this one is displayed and not the others). If I right click on the exact same item from another view with context menu enabled and same registered group markers, I have a lot more items injected in the menu.

Since I got one item in the menu, I tried clicking on it to see what was going on in the handler of the executed command :
In the handler it appears that the selection is always empty so it is as if there is something going wrong with the selection provider but I cannot understand what.

I think I am doing something wrong since I do not register a selection provider to the active site as I do when coding menu registration in a view. But I think in my situation that the form editor already registers a global selection provider but how could I inform that selection provider to delegate to the TableView for providing selection when it is focused.

I am properly doing this in the code of my master part which I thought would do this :
viewer.addSelectionChangedListener(new ISelectionChangedListener() {

	public void selectionChanged(SelectionChangedEvent event) {
		managedForm.fireSelectionChanged(spart, event.getSelection());
	}
});


I am a bit lost and any help would be highly appreciated Wink
Thank you,
Christophe,
http://www.nextep-softwares.com
Re: Contextual menu / selection provider / forms UI problems [message #682981 is a reply to message #682582] Sun, 12 June 2011 13:33 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

2 suggestions:

IWorkbenchPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
		.getActivePart();


You would presumably pass in the part or part site that you are creating your form master details block. Since it is possible to create a part while another part is still active, that might cause a problem.

The other suggestion I have is for use with commands/handlers. When you open a context menu that is registered with a part site, the framework does 2 things. It sets activeMenuIds to the collection of IDs that represent that context menu. That might be the part id, or might be one or more IDs that are used when registering the menu. That can be used as part of a locationURI when targetting specific menus.

The framework also sets the activeMenuSelection to the selection returned by your viewer. For legacy reasons, this is not the same as the "selection" variable that is set if your viewer is used as the main provider for your part: getSite().setSelectionProvider(viewer); That means that commands that depend on a visibleWhen and use the "selection" variable won't be triggered by this kind of activeMenuSelection.

PW


Re: Contextual menu / selection provider / forms UI problems [message #684829 is a reply to message #682981] Thu, 16 June 2011 06:00 Go to previous messageGo to next message
Christophe Fondacci is currently offline Christophe Fondacci
Messages: 95
Registered: July 2009
Location: Paris
Member
Hi Paul and thank you very much for your help,

I investigated both leads :

1. I now pass the site of the page on which my MasterDetailsBlock is created all way long to the menu registration so that the menu is no longer registrated under the "active" site but under the page site.
=> No effect, but I totally agree this is much safer

2. I am not sure to understand well what you said and the implications it might have but this is definitly the area where the problem reside :
* If I remove the visibleWhen clause of one of my menu contribution, the menu item gets properly injected in my menu.

That would mean that the selection that the framework is considering is not the good one since it makes the visibleWhen clause to return false.

A few clarifications :
I do register my viewer as the selection provider of the site of the page :
site.setSelectionProvider(viewer);
site.registerContextMenu("typedListBlock_" + contentProvider.toString(), contextMenu, viewer);


I don't really understand the difference you underlined between activeMenuSelection and selection variable. As mentioned in the 2 lines of code above, the same selection provider is used for site selection registration and context menu registration so I don't really understand how could the "selection" context be different.
I tried to digg into the menu activation code, but I cannot find out how I could see where the selection is retrieved (I mean the selection against which the visibleWhen expressions will be computed and, if different, the selection that is passed to the handler). Could you point any location where I could add a breakpoint and analyze what selection provider is used to push the selection to the menu activation layer ?

Another clarification :
The only reason why one menu item appears in my menu is that the "ifEmpty" attribute of the "iterate" expression was not explicitly defined, resulting in a success on empty selection. If I switch this to ifEmpty=false for this item, I now have no menu. That mean that the selection used to compute visibility is always empty but I cannot understand why since I registered my viewer as the selection provider of the page site and I also passed it in the registerContextMenu method call...



Thank you very much !
Christophe.
http://www.nextep-softwares.com

Re: Contextual menu / selection provider / forms UI problems [message #684862 is a reply to message #684829] Thu, 16 June 2011 07:16 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

If you also did a getSite().setSelectionProvider(viewer), then yes for all intents and purposes selection and activeMenuSelection should be the same thing.

Could you post one of your menuContributions including locationURI and the visibleWhen?

PW


Re: Contextual menu / selection provider / forms UI problems [message #684866 is a reply to message #684862] Thu, 16 June 2011 07:28 Go to previous messageGo to next message
Christophe Fondacci is currently offline Christophe Fondacci
Messages: 95
Registered: July 2009
Location: Paris
Member
Sure, here it is :
      <menuContribution
            locationURI="popup:org.eclipse.ui.popup.any?before=editions">
         <command
               commandId="com.neXtep.designer.ui.editTypedItem"
               icon="resource/EditTiny.ico"
               style="push">
            <visibleWhen
                  checkEnabled="false">
               <iterate
                     ifEmpty="false"
                     operator="and">
                  <and>
                     <instanceof
                           value="com.nextep.datadesigner.model.ITypedObject">
                     </instanceof>
                     <not>
                        <instanceof
                              value="com.nextep.datadesigner.model.IReference">
                        </instanceof>
                     </not>
                     <not>
                        <test
                              property="com.neXtep.designer.ui.typeId"
                              value="TARGET_SET">
                        </test>
                     </not>
                  </and>
               </iterate>
            </visibleWhen>
         </command>
      </menuContribution>


Christophe
http://www.nextep-softwares.com
Re: Contextual menu / selection provider / forms UI problems [message #685539 is a reply to message #684866] Fri, 17 June 2011 13:56 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Is this a typo in your property?

                        <test
                              property="com.neXtep.designer.ui.typeId"
                              value="TARGET_SET">
                        </test>


com.neXtep...

PW


Re: Contextual menu / selection provider / forms UI problems [message #685892 is a reply to message #685539] Mon, 20 June 2011 10:34 Go to previous messageGo to next message
Christophe Fondacci is currently offline Christophe Fondacci
Messages: 95
Registered: July 2009
Location: Paris
Member
No this is not a typo the X is uppercased.
It refers to a property tester which declares a namespace "com.neXtep.designer.ui" and a "typeId" properties. This is to stay consistent with our plugin naming convention which are all declared as "com.neXtep.designer.*".

Do you think this could be a problem ? Because I never had any problem with this anywhere else. And I think I got other menu contributions which are not using the <test> part and which are not getting injected in the menu either.

Christophe.

Re: Contextual menu / selection provider / forms UI problems [message #686000 is a reply to message #685892] Tue, 21 June 2011 07:00 Go to previous messageGo to next message
Paul Webster is currently offline Paul Webster
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

What is the type of that property tester? Do the selection elements have to adapt to their types, or are they already those types?

Your expression looks reasonable:

for all selected elements:
  (X instanceof com.nextep.datadesigner.model.ITypedObject)
  && !(X instanceof com.nextep.datadesigner.model.IReference)
  && !(test X for com.neXtep.designer.ui.typeId/TARGET_SET)



PW


Re: Contextual menu / selection provider / forms UI problems [message #693759 is a reply to message #686000] Thu, 07 July 2011 03:15 Go to previous messageGo to next message
Christophe Fondacci is currently offline Christophe Fondacci
Messages: 95
Registered: July 2009
Location: Paris
Member
Sorry Paul, I did not receive a notification of your last answer...

Elements natively implement the tested interfaces, they do not need to be adapted. But indeed it could be a good practice to always use "adapt" instead of "instanceof"... is it something you recommend ?

My property tester extends org.eclipse.core.expressions.PropertyTester


I digged a little more on this problem :
* It seems to be selection related : a view reacting on my selection is not properly refreshed when elements are selected
* If I click on another view or editor (= I loose the focus on my editor) and if I go back in the editor, selection now works properly and manus are displayed properly (weird isn't it ?)

After some debugging it seems that at some point, the FormEditor global selection provider (FormEditorSelectionProvider) expects that every page (that is to say every child editor) of the MultiPageEditorPart (the base class of the FormEditor) has its own editor site. Here is the piece of code incriminated :
public ISelection getSelection() {
	IEditorPart activeEditor = ((FormEditor) getMultiPageEditor()).getActiveEditor();
	if (activeEditor != null) {
		ISelectionProvider selectionProvider = activeEditor.getSite()
				.getSelectionProvider();
		if (selectionProvider != null)
			return selectionProvider.getSelection();
	}
	...
}


It seems to make sense. BUT : When I debug my editor page creation, I can see that the site of the child editor IS THE SAME as the site of the main multi page editor.
when I try to register my viewer as the selection provider of my child editor's site, it actually replaces the FormEditorSelectionProvider of the main mutli page editor...

Today I will try to implement a global selection provider that will not be based on site's selection provider to see whether it fixes the problem.

The weird thing is that if there is such problem I think it would have been detected much earlier and caused much more problems. Indeed, every menu and selections from PDE editors work well so I don't know what is going on. Maybe I don't create my editor pages properly... But I can see that the FormEditor.registerPage() method does pass the main editor site to child pages :
if (page instanceof IFormPage) {
	IFormPage fpage = (IFormPage) page;
	if (fpage.isEditor() == false)
		fpage.init(getEditorSite(), getEditorInput());
}


While the MultiPageEditorPart.addPage(int, IEditorPart, IEditorInput) does create a new site for child editors...

I think I'm getting closer, but I am still lost Sad

Christophe.
http://www.nextep-softwares.com
Re: Contextual menu / selection provider / forms UI problems [message #693906 is a reply to message #693759] Thu, 07 July 2011 09:19 Go to previous messageGo to next message
Christophe Fondacci is currently offline Christophe Fondacci
Messages: 95
Registered: July 2009
Location: Paris
Member
I confirm, when I implement my own global selection provider and handles selection between my parts, everything works fine.

Here is my global selection provider which I set into my form editor's site :

Interface definition :
public interface IGlobalSelectionProvider extends ISelectionProvider {

	/**
	 * Registers the selection provider for a workbench part. When this part is shown in a
	 * multi-page editor context, the global selection provider will use the associated registered
	 * selection provider to provide the selection to the workbench.
	 * 
	 * @param pageEditor the {@link IWorkbenchPart} for which the selection provider should be
	 *        registered
	 * @param provider the corresponding part's inner {@link ISelectionProvider}
	 */
	void registerSelectionProvider(IWorkbenchPart pageEditor, ISelectionProvider provider);
}


The registerSelectionProvider method is called by every "FormPage" (but that will work with simple "page" editors of a MultiPageEditorPart, although I don't know if there is the same problem) to register its associated selection provider.

Then the GlobalSelectionProvider implementation which handles the mediation between every selection providers of every pages of the FormEditor :
public class GlobalSelectionProvider implements IGlobalSelectionProvider, ISelectionChangedListener {

	private static final Log LOGGER = LogFactory.getLog(GlobalSelectionProvider.class);
	private Collection<ISelectionChangedListener> listeners = new ArrayList<ISelectionChangedListener>();
	private Map<IWorkbenchPart, ISelectionProvider> providersPageMap = new HashMap<IWorkbenchPart, ISelectionProvider>();
	private ISelection globalSelection = StructuredSelection.EMPTY;

	@Override
	public void addSelectionChangedListener(ISelectionChangedListener listener) {
		listeners.add(listener);
	}

	@Override
	public ISelection getSelection() {
		final IEditorPart editor = CoreUiPlugin.getDefault().getWorkbench()
				.getActiveWorkbenchWindow().getActivePage().getActiveEditor();
		if (editor != null) {
			if (editor instanceof FormEditor) {
				final IFormPage activePage = ((FormEditor) editor).getActivePageInstance();
				final ISelectionProvider activeProvider = providersPageMap.get(activePage);
				if (activeProvider != null) {
					return activeProvider.getSelection();
				}
			}
		}
		return globalSelection;
	}

	@Override
	public void removeSelectionChangedListener(ISelectionChangedListener listener) {
		listeners.remove(listener);
	}

	@Override
	public void setSelection(ISelection selection) {
		final IEditorPart editor = CoreUiPlugin.getDefault().getWorkbench()
				.getActiveWorkbenchWindow().getActivePage().getActiveEditor();
		if (editor != null) {
			if (editor instanceof FormEditor) {
				final IEditorPart activePage = ((FormEditor) editor).getActiveEditor();
				final ISelectionProvider activeProvider = providersPageMap.get(activePage);
				if (activeProvider != null) {
					activeProvider.setSelection(selection);
				} else {
					this.globalSelection = selection;
				}
			}
		}
	}

	@Override
	public void registerSelectionProvider(IWorkbenchPart pageEditor, ISelectionProvider provider) {
		if (providersPageMap.get(pageEditor) == null) {
			provider.addSelectionChangedListener(this);
			providersPageMap.put(pageEditor, provider);
		} else {
			LOGGER.warn(MessageFormat
					.format("Ignoring registration of delegate selection provider ''{0}'' for part ''{1}''", //$NON-NLS-1$
					provider, pageEditor));
		}
	}

	@Override
	public void selectionChanged(SelectionChangedEvent event) {
		for (ISelectionChangedListener listener : listeners) {
			listener.selectionChanged(event);
		}
	}
}


Hope this can help. If anybody knows a way to make the native FormEditor selection provider to work properly I would love to know what I was doing wrong.
Christophe.
http://www.nextep-softwares.com
Re: Contextual menu / selection provider / forms UI problems [message #1250888 is a reply to message #693906] Wed, 19 February 2014 12:55 Go to previous message
Bruce Mokhtari is currently offline Bruce Mokhtari
Messages: 1
Registered: February 2014
Junior Member
Hi Christophe,

I'm facing the exact same problem with FormEditor. Did you by any change figure out a better way to some this problem?

Previous Topic:App error please
Next Topic:Custom filename validation after copy paste into same directory
Goto Forum:
  


Current Time: Wed Jul 23 22:24:39 EDT 2014

Powered by FUDForum. Page generated in 0.03334 seconds