- 1 General architecture of views
- 2 Options for a split view
- 2.1 (1) Add a task window that embeds the Frame windows
- 2.2 (2) Several Frames share the same Frame Window
- 2.3 (3) Several Controller objects attached to the same Frame object can exist
- 2.4 (4) Changes in sfx2 below the Controller level
- 2.5 (5) Changes on SfxViewShell level or below
- 2.6 Comparison and Conclusion
General architecture of views
A View in OOo consists of several parts
- a Frame object (UNO service com::sun::star::frame::Frame) that owns a Window. In case of regular document views it's a SystemWindow (frame window);
- a Controller object (UNO service com::sun::star::frame::Controller) that works on a window that is provided by its implementation (controller window);
- a LayoutManager that places GUI elements (currently only toolbar and status bar) between these two windows. The screen space occupied by these tools is called "border space", it defines the difference in size between the two windows.
All OOo applications are based on the sfx2 class library that provides some generic parts of the view implementation. Together with the application specific parts the following architecture is created:
- the implementation of the window that is provided by the Controller object
- an SfxFrame object that works on this window (SfxFrame window = Controller window);
- an SfxViewFrame object that creates a child window of the SfxFrame's window (SfxViewFrame window);
- an SfxWorkWindow object that - in the same way as the LayoutManager object - places GUI elements (side panes, docked windows etc.) between these two windows, again creating a border space; it's not a window by itself but uses the SfxFrame window
- an SfxViewShell object that provides another window that is placed into the window of the SfxViewFrame. Both implementations are application specific, the sfx2 provides the base class SfxViewShell that implements all the communication with the SfxViewFrame, SfxFrame and Controller and Frame objects;
- the application specific window (often called the "edit window") contains some more tools (scrollbars, rulers etc.) and a document view
Options for a split view
OOo is able to have more than one view per document in most cases (the exception is Writer that can create more than one view only if all of them use the same layout). All views will have their own full view architecture as explained above. In a split view two or more views shall be placed in a common window. Any of the windows mentioned in the architecture description could be used for that as the document view is placed into the innermost window. So views can share one of these windows, either directly or by sharing the objects "above" the objects owning the windows:
(1) Add a task window that embeds the Frame windows
Each time a new top level Frame object including its windows is created, we create a "task window" and create the Frame window as its child window. A split view would create more Frame objects with their own Frame windows inside the task window. This would require to implement a new TaskCreator service and some changes mainly in the Frame and LayoutManager class. It took only a few days of work to implement a prototype for that some time ago. The biggest advantage of this approach is that changes only happen in a very limited, well separated and well-arranged code. No change at all will be necessary in the application's (sw,sd,sc) code. Another advantage is that a split view created that way can also take views from different documents, even from different applications. Disadvantage: without re-implementing large parts of the layout manager, toolbars etc. can't be shared. So even if two views require the same UI tools, switching between them will let the toolbars flicker. Another disadvantage could be that code relying on container windows of top level frames being a system window will break. This code is wrong (as it relies on an undocumented feature) thout nevertheless it might exist. To fix possible problems, we had to check all code using XFrame::getContainerWindow. Not a big deal.
This approach has the same advantages as the first one, but doesn't have its disadvantage. OTOH it touches a very sensitive area. Frames currently own their window and control its life time. Without that additional means had to be implemented for this life time control. We also had to re-implement the LayoutManager to make it aware of the fact that it does not contain one internal windows but several of them. All in all no deciding improvement to the first option, but a considerable behavioral change of the UNO API implementation.
(3) Several Controller objects attached to the same Frame object can exist
This would require to add an interface to the Frame object containing a new "setComponent" method that does not dispose a Controller when a new Controller is attached to the Frame. A new object would be required that manages the existing Controllers as the Frame will only dispose the current one in case it is closed. The biggest advantage of this approach is that it can avoid the toolbar flicker with some effort and also does not change the window hierarchy. The disadvantage is that it goes against the current idea of our Framework API and it creates the situation that XFrame::getController and XController::GetFrame is not symmetric anymore. This could create some subtle, not so obvious problems.
(4) Changes in sfx2 below the Controller level
By sharing a Controller between the views we avoid the problems mentioned in the last section, but we keep its advantages. There are several options to implement that, the best seems to be that the SfxFrame will no longer have a 1:1 relationship with an SfxViewFrame and that its Window will become a Container for several SfxViewFrame windows. It seems that the implementation can be carried out in sfx2 to a large extent, only a few changes will be necessary in application code (mainly some method renaming). No code changes at all are expected in code "outside", e.g. the Framework module. As all SfxViewFrame objects belong to the same Controller object, this approach would not allow to mix views of different documents, though the SFX code alone would allow to do so. A split view implemented this way would appear as a single view on the framework API level.
(5) Changes on SfxViewShell level or below
All changes in SfxViewShell or "below" will have the disadvantage that a split view never can contain views to different documents. An attempt to implement split views on layout level adds new disadvantages: the split view parts can't be scrolled independently without huge code changes and in Writer we hit the single layout problem even for the print layout. We also had to implement the split view in application specific code, means: for each application we would have a specific implementation.
Comparison and Conclusion
The options (1), (3) and (4) seem to be the best choices. Option (4) would exclude Base from this feature, but that probably isn't a problem. It also would not allow to put views of different documents together. It's unclear how severe that features loss is. More in depth analysis is required to find out about some more not so obvious problems and disadvantages. Some remarks:
- Having a prototype for (1) already is a big Plus. It still lacks the reimplementation of the Layoutmanager. The prototype shows that this implementation basically can work.
- Without the prototype Options (3) and (4) are a more risky choice. We might discover big problems in the implementation that we currently don't forsee.
- Working on option (4) might be preferable for developers not so familiar with UNO development
- Option (1) is not ready for prime time before the DockingWindow rework is finished, as otherwise each view would have its own docked windows
- All options would require additional UI elements to close single views via mouse, as the Window Closer always will close all views at once.