|
One of the most visible cues of good integration
between editors and views is synchronized selection: the selected
Java method in the Outline view should reflect the caret position in
the Java Editor, the Properties view should show properties for the
DOM Element selected in the Outline view, the selected objects on a
mutli-page editor's Design page should always be the same as on its
Source page, etc. Rather than introduce and maintain our own
mechanism for achieving this, the StructuredTextEditor
exposes its selection handling using standard Eclipse platform APIs.
|
Selection notification in
text editors |
|
In text editors, the editor sets a ISelectionProvider
into its IEditorSite . The ISelectionProvider
sends ITextSelection objects from the source viewer to
its listeners and knows how to accept an ITextSelection
and apply it to the SourceViewer . The workbench ISelectionService
becomes a listener of the ISelectionProvider and any
changes sent to the ISelectionService are forwarded to
everyone listening to the service--most views, for example.
The flow of selection notification from the editor's source viewer
changes looks like this:
|
selection changes in the source viewer |
|
|
-> editor's ISelectionProvider
receives selection changed and notifies its listeners |
|
|
|
-> ISelectionService receives
selection changed and notifies its listeners |
|
|
|
|
-> listeners react (views update) |
The flow of setting selection into the editor looks like this:
|
selection created |
|
|
-> editor's ISelectionProvider
receives setSelection() message and updates the source
viewer's selected text |
|
|
In the past, the StructuredTextEditor
didn't affect any of this. As part of the changes for bug 109441
, StructuredTextEditor provides an ISelectionProvider
that creates a single selection object implementing both ITextSelection
and IStructuredSelection . Listeners that can only
handle one of those types of selection can still function because
this unified selection is provided in every selection changed event
and as the result of ISelectionProvider.getSelection() .
The ISelectionProvider also accepts both kinds of
selection for ISelectionProvider.setSelection(ISelection) ,
passing text selections straight through to the source viewer. The
actual ISelectionProvider implementation being used is org.eclipse.wst.sse.ui.StructuredTextEditor.StructuredSelectionProvider
.
|
|
The MultiPageEditorPart connects its own selection
provider (2) to the selection service. That selection provider (2) is
notified of selection changes by the selection providers (1) of all
of its connected pages and forwards any notifications to the
selection service. In Eclipse 3.1, this is done for plain selection
notification only, not for post selection. Source viewers send cursor
movements using post selection notification, and when using the base
selection APIs, updating selection in views like the outline will
rely on post selection notification coming from the source viewer
through the MultiPageEditorPart and the selection
service. Eclipse bug 108324
has been opened to address this for Eclipse 3.2. org.eclipse.wst.common.ui.provisional.editors.PostSelectionMultiPageEditorPart
has been provided as a temporary workaround.
|
|
- Synchronizing selection from an editor to a view:
- To synchronize selection from an editor to a view, the view
should register itself as a listener of the ISelectionService when
it is initialized. It will then automatically recieve notification
about selection changes and the workbench part that originated them.
Pages in a
PageBookView should check their visibility
before handling any selection change notifications as they'll
receive notification from every workbench part. The PageBook
will ensure that the page is only visible when the correct workbench
part is active.
- Synchronizing selection from a view to an editor:
- It's rare for an editor to want just any view to control it, so
this is also left as a task for the editor part itself. SSE's
ConfigurableContentOutlinePage
allows anyone to add an IDoubleClickListener to it, and
multi-page editors built around the StructuredTextEditors
would be expected to do so (StructuredTextEditor
already does this if it creates the page) to respond to double-click
events within the outline.
- How to synchronize selection from one view to another view:
- The first view is set up to provide selection notification to
the selection service. The second view can then be driven from the
first view's selection just as it would by an editor's selection.
For a concrete example, when editing HTML, the
StructuredTextEditor
will provide its IStructuredSelection using DOM nodes.
It's Outline provides IStructuredSelection using the
same DOM nodes. The SSE Property Sheet can't tell the difference,
and since it's only ever showing the properties of nodes supplied
through the selection (which is now always an IStructuredSelection ),
it doesn't even need an IStructuredModel to be set on
it--the node is supplied by the active part, whether it's the
editor, outline, or otherwise.
- Synchronizing selection within a Multi-Page Editor:
- Currently, the main multi-page editor class must synchronize the
selection between its pages by itself. For reference,
ITextEditor
returns an ISelectionProvider as part of its interface
and the SSE IDesignViewer has been changed to do so as
well. The provided XMLMultiPageEditorPart synchronizes
using these interfaces and relies on the source viewer to notify the
selection service.
- Avoiding selection notification loops:
- Setting the selection into a viewer causes it to also fire
selection notifications, so if two viewers are synchronizing
selection based on post selection notification, they might end up
looping endlessly notifying each other when selection is applied to
their Controls. The selection objects themselves will be different
as each viewer will be generating a fresh selection event and
selection from the underlying
Control . The recommended
solution for this problem is to make sure that a part never updates
its selection from outside notification when it is the active part,
nor when it is sending selection (or post selection) notification
itself.
- Listening to the selection service
- Editors should not just be a listener of the selection service
since selection changes in every part (including some listening for
changes in that same editor) would be received.
- How to get selected "nodes" and text from a
StructuredTextEditor:
- The
StructuredTextEditor 's selection provider
returns an ITextSelection & IStructuredSelection
combination when ISelectionProvider.getSelection() is
called. Casting to an IStructuredSelection will give
you the selected IndexedNodes for the current text
selection. Casting to an ITextSelection will give the
current text selection, just as you would receive from other text
editors.
Caution: IStructuredSelection does not provide explicit
typing for its selected objects (NodeSelectionChangedEvent
didn't, either).
- How to manage double-click:
- As of now, we haven't provided a unified way to do this, and
we're currently not planning to. Like selection, double-click does
different things in different places. The
XMLMultiPageEditorPart
won't handle double-click from its design page to its source page
properly in 1.0M8, that will be released early in 1.0M9 development.
|
|
org.eclipse.wst.sse.ui.internal.ViewerSelectionManager
- deprecated
org.eclipse.wst.sse.ui.internal.CaretMediator -
deprecated
org.eclipse.wst.sse.ui.internal.view.events -
entire package deprecated
- The selection range shown on the left of the source editor are
not the same for XML languages as they were before. Code in
org.eclipse.wst.sse.ui used to take advantage of the
org.w3c.Node
interfaces being in the JRE to base the selection range on a parent
Element if a Text node was the selected
node. This made assumptions about the nature of the IndexedNodes
of an IStructuredModel that shouldn't be known in the
core SSE UI plugin. When the caret is within a Text
node you will now see a selection range reflecting the Text
Node itself.
|