Bug 27539 - [MPE] [Text Editor] Text editor should not register global actions with the keybinding service
Summary: [MPE] [Text Editor] Text editor should not register global actions with the k...
Status: VERIFIED DUPLICATE of bug 37612
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 2.1   Edit
Hardware: PC All
: P1 normal (vote)
Target Milestone: 3.0 M8   Edit
Assignee: Douglas Pollock CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 29283 29294 29360
  Show dependency tree
 
Reported: 2002-12-02 16:52 EST by Karen Williamson CLA
Modified: 2004-03-25 17:35 EST (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Karen Williamson CLA 2002-12-02 16:52:51 EST
This may be a regression of bug 25806, but the behaviour is very odd so I 
believe it warrants a separate PR.

build no: I20021127

The edit accelerators ctrl-a, ctrl-c, ctrl-v are not working correctly in the 
description editor of both the Definition and Documentation pages of the Schema 
Editor.  

The quirky part of this bahaviour is that if you never look at the source page, 
the accelerators work properly, but once you flip to the source page and then 
back to the GUI, the accelerators are broken.

steps to reproduce problem with ctrl-A: 
1. Open a new schema editor with the Definition page visible.
2. Click on the description editor and hit ctrl-a

  RESULT:  contents of description editor are highlighted as expected

3. Click on the source tab to bring up the source page
4. Click on the Definition tab to being back the definition page
5. Click on the description editor and hit ctrl-a.

  RESULT: contents of description editor are *not* highlighted.

In fact, if you click on the source tab, you'll find the contents of the source 
page are highlighted instead.

Similar behaviour was found with ctrl-c and ctrl-v; once the source page has 
been viewed, these accelerators only work on the source page, not on the 
decription editor.  Performing the action from the edit or context menu works 
properly.

So even while the user in looking at the GUI, ctrl-c will copy whatever is 
highlighted on the cource page, and ctrl-v will paste clipboard contents to the 
source page.  Since this happens while the user is on the GUI, all they see is 
nothing happening, while their source file is being modified.
Comment 1 Dejan Glozic CLA 2002-12-03 10:32:29 EST
I beleive this is a key bindings problem. If you execute the same actions from 
the 'Edit' menu, the correct behaviour can be observed. It is only the keyboard 
accelerator for the action that is not passed to the right action.

When pages are switched, PDE updates the global action handlers using:

		IActionBars.setGlobalActionHandler()

When source page is switched, we call this method to link global actions with 
action handlers in the source page. When GUI pages are selected, we redirect 
global actions to GUI action handlers, that simply delegate the global action 
execution to the current GUI page/current section. This mechanism is working 
well when executing actions from the menu, but for some reason keyboard 
mappings are not updated at the same time.
Comment 2 Chris McLaren CLA 2003-01-07 17:10:02 EST
on the first press of Ctrl+A on the description page, the action that the key 
binding service invokes is an instance of PDEEditorContributor$GlobalAction 
with the id parameter "selectAll". moving to the source page, back to the 
description page, deselecting with the mouse, and pressing Ctrl+A once again, 
the action is an instance of org.eclipse.ui.texteditor.TextOperationAction.

the implementation of KeyBindingService checks for any actions explicitly 
registered with it, if not, it reverts to its parent, WWinKeyBindingService, 
for other handlers - this is where the global action handlers are found.

when the text editor component is created for the source page (lazy creation 
seems to be at work here), the text editor registers all of its actions, 
including global actions, with the key binding service and never unregisters 
them with the keybinding service. (for instance, when the source page closes). 

returning to the description page, the menu item correctly identifies the 
global action handler for select all in PDE, but the key binding service sitll 
finds an explicit registration for the text editor to receive select all.

because of the built in association between global actions and WWinKeyBinding 
service, there seems to be no need for Kai to register global actions with the 
key binding service directly, or at least they should be unregistered from the 
key binding service when the text editor loses focus, etc.

as a quick hack, i changed 
AbstractTextEditor$ActivationCodeTrigger.registerActionForKeyActivation to 
reject actions with the action definition id 
ITextEditorActionDefinitionIds.SELECT_ALL and everything worked correctly.

passing to Kai to fix, and adding you on the CC: since our coop student, the 
reporter of this bug, has left OTI.


Comment 3 Dejan Glozic CLA 2003-01-23 17:29:36 EST
This affects all PDE editors, but is particularly visible in schema editor 
where users frequently toggle between source and form pages. Once they switch 
to the source page for the first time, they loose the form page key bindings, 
and open defects against PDE about global commands not working.

I am rising the severity for this defect.
Comment 4 Kai-Uwe Maetzel CLA 2003-02-04 09:57:49 EST
It seems to me that a change in the text editor area is not appropriate to 
solve this problem. It’s looking like an architectural issue. Here is why I 
think so. I am using the PDE schema editor as one example.

A text editor is an editor part. It assumes to live in a well-defined context. 
Part of this context is the editor site providing several services to the 
editor. For example, the editor can register its context menu with its site. 
Also, the editor can register its actions with the site’s key binding service. 
It is part of the definition of the editor’s context that after having 
registered its actions, the editor is freed from further management. This means 
that the editor does not have to track its activation status in order to bind 
its actions to retarget menu bar or tool bar actions.

The PDE schema editor is a multi-page editor. It uses the text editor 
(AbstractTextEditor) as the content of one of its pages. Thus, it is the multi-
pages editor’s responsibility to create the context for the embedded text 
editor. Since the multi-page editor already provides several pieces of the 
infrastructure including a multi-page editor site this should be possible 
without requesting additional API from the embedded editor.

Following Chris’ proposal to not register actions with the key binding service 
would not be sufficient it seems. It would still be the schema editor’s 
responsibility to track activation/deactivation and to force the embedded 
editor to set or remove its actions as global action handlers. This would 
require new API on text editors that would then be available for everybody. New 
API could be avoided by making activation tracking the embedded editor’s task. 
But doing so (probably based on widget focus) is not optimal for three reasons: 
It would contradict the assumption described above. It would contradict the 
architectural model of editors in which the editor contributor tracks the 
active editor. It would introduce the “same” functionality at two different 
layers (workbench and text editor) and which for all single page editors would 
be executed twice on each activation change.

Moving to Platform UI.
Comment 5 Dejan Glozic CLA 2003-02-04 12:14:08 EST
Please note that PDE is NOT using multi-page editor provided by platform UI 
(historic reasons - we will rework our editors in 2.2 and switch then).

Assuming that we are willing to do what is required in PDE, what would that be? 
We already have our sub-managers that track page switching, and register global 
action handlers for form or source pages on switching. I think that this part 
is not a problem - the switching works fine. However, since text editor 
registers key binding service explicitly, it does not let it go on switching. 
What is it that we need to do reset the key binding service set explicitly by 
the text editor in the source page?
Comment 6 Nick Edgar CLA 2003-02-10 12:09:47 EST
If we changed the text editor to not register its global action handlers in the 
keybinding service, then this would solve the problem for the global actions 
(cut, copy, paste, undo, redo, select all, etc).
This would be an expedient solution for 2.1, but it goes against how we would 
like to do this in the future, where we would like to have a single command 
service rather than both a global action service and a keybinding service.

As Kai points out, though, this does not solve the problem in general.  Other 
actions registered by the text editor with the keybinding service (e.g. 
prev/next line) would not get reassigned when switching pages.

To fix this properly, in the part site provided to the nested editor, you need 
to provide a "virtual" key binding service.  The multipage editor then must 
update the real keybinding service for the active page (removing bindings for 
the previously active page, and adding ones for the newly active page).

This needs to be fixed up in MultiPageEditorSite as well, but it's unlikely 
we'll get to this for 2.1.
Comment 7 Dejan Glozic CLA 2003-02-10 13:01:05 EST
Can you point us at the code we need to mimic in order to get the key binding 
switching in our multi-page editor?
Comment 8 Dejan Glozic CLA 2003-02-10 15:43:57 EST
Here is a quick and evil fix provided by Nick Dr. Evel Edgar:

When we create an initialize source page, we immediately turn around and 
unregister actions registered with the key binding service that we care about 
(cliboard, select all, undo/redo etc.). These are the same actions we actively 
manage as global action handlers. 

Since these actions are unregisted, from the service, they default mechanism 
(global actions) are now handling them. Text editor still receives all the 
commands from the user, only that they arrive to it through the global action 
accelerators, not the key binding service.

I tested this on couple of our editors and all seems to work well without any 
loss of function in the source page.

I will move this defect to 'Later' to be reactivated in 2.2 as we rehost PDE 
editors to multi-page editor support from the platform.
Comment 9 Douglas Pollock CLA 2003-09-22 11:26:03 EDT
Can anyone advise as to the status of this bug?  In particular, PDE's rehosting
of editors in 2.2.  platform-ui is approaching the editor switching problem for
3.0.  See Bug 37612.
Comment 10 Nick Edgar CLA 2003-10-07 23:27:57 EDT
Reopening.
Text and other teams need recommendations from us on how to do this properly.

Nesting of services is a general problem.  I see two possible paths:
1) Keep the current model whereby a part's site provides services, but extend 
it so that:
  (a) set of services is extensible without requiring changes to the site API 
(perhaps by having the site implement IAdaptable), and 
  (b) services know how to nest themselves, through a generic API (e.g. 
INestableService.getNestedService()).

2) Reverse the flow of control so that the workbench calls in to the part, 
rather than the part reaching out to its site, and allow the part to delegate 
to nested parts (a la chain-of-responsibility pattern).

Details to be worked out <g>.
Comment 11 Douglas Pollock CLA 2003-10-08 10:32:33 EDT
What's left of this bug is now represented by Bug 37612.

*** This bug has been marked as a duplicate of 37612 ***
Comment 12 Douglas Pollock CLA 2004-02-26 16:56:44 EST
As a note, MultiPageEditorPart and MultiPageEditorSite now support nested key 
binding services.  This means that it should support switching of contexts and 
handlers based on the currently active page. 
Comment 13 Dejan Glozic CLA 2004-02-26 16:59:21 EST
This is very timely, because Eclipse Forms have this support for multi-page 
form editor (meaning we can delete classes :-). Can you give us some pointers 
of what needs to be done to use this?
Comment 14 Douglas Pollock CLA 2004-02-26 23:35:07 EST
The long answer you didn't really want, but you'll get anyway.... 
 
I have currently hacked this together using the old KeyBindingService.  I will 
describe this method first, since it is something we can guarantee support for 
(its going into 2.1.3).  The new API Chris has put together is much more 
succinct, but is probably still too new for use.  (Plus, you'd probably want to 
make a helper class to handle the switching anyway.) 
 
[Note: I don't have an Eclipse running right now, so my naming and typing maybe 
a little off.] 
 
I rewrote MultiPageEditorSite.getKeyBindingService.  You can see the changes in 
CVS.  Basically, it attempts to get a nested key binding service (associated 
with the multi-page editor site).  If it fails, then it falls back on the old 
key binding service (provided by the editor site).  In the dispose method on 
MultiPageEditorSite, I clean up after myself (important to remember!). 
 
The relevant API is: 
INestableKeyBindingService.getKeyBindingService(IWorkbenchSite) 
INestableKeyBindingService.removeKeyBindingService(IWorkbenchSite) 
 
In MultiPageEditorPart, I hacked the setFocus() methods to call: 
INestableKeyBindingService.activateKeyBindingService(IWorkbenchSite) 
when appropriate. 
 
A lot of the code is just checking to make sure that nothing is null or of the 
wrong type.  In practice, this should never really happen. 
 
 
Under the covers, this is calling into the IWorkbenchContextSupport and 
IWorkbenchCommandSupport code.  It creates HandlerSubmissions and 
EnabledSubmissions, handles the switching, and makes sure to "spoof" the 
IWorkbenchSite with something these classes can recognize.  (The problem here 
is that the workbench has no concept of nesting, per se, and so only reports 
the top-level site as being active.  This leads to confusion when the 
submissions are trying to sort out whether they are active or not.) 
Comment 15 Douglas Pollock CLA 2004-03-25 17:35:48 EST
Moving duplicate resolved (but not fixed) bugs to verified for M8.