Refactoring of Writer's usage of the Drawing layer
CURRENTLY UNDER CONSTRUCTION BY OD
The refactoring of the Writer's usage of the Drawing Layer is to create and maintain different Draw models for the Writer's model of Drawing objects and for the Writer's view(s) of Drawing objects. Thus The purpose of this refactoring is to
- improve the maintainability of the Writer's code regarding its usage of the Drawing layer,
- prepare the replacement of the Writer's implementation for graphic objects and embedded object by the corresponding implementation of the Drawing layer,
- get rid of special code in the Drawing layer, which only serves the Writer's needs for Drawing objects,
- solve certain issues regarding Drawing objects in repeated areas of a text document (Note: such repeated areas are page header, page footer and table headers), and
- "pre-prepare" the introduction of multiple different views on a certain text document.
- Develop general idea about the refactoring and its high-level implementation details – the big picture.
- Evaluate Drawing Layer functionality regarding the refactoring.
- Identify issues in Drawing Layer functionality, which needs to be solved in order to support the proposed refactoring.
- Identify certain implementation constraints which
- simplify the refactoring and/or the new code,
- allow the removable of former inappropriate code/solutions, and
- assure a good performance of the new code.
- The load/save performance shall not be affected by the refactoring. The editing performance is affected by the refactoring, but its effect shall be as low as possible.
- Note: It is needed to find a balanced way between the above three goals – e.g. not everything, which simplifies the new code would be good for the performance.
- Evaluate consequences of the refactoring to other functionalities regarding Drawing objects in Writer.
- ODF import/export
- Writer's implementation of the Drawing objects' UNO-API
- Identify known issues, which shall be solved by the proposed refactoring.
- Define testing/QA issues
- test plan(s) for end user tests
- API tests
- UNIT tests
- Get overview of the implementation details.
- Design and implementation of the new/changed architecture of the Writer's usage of the Drawing Layer
- New Classes/Interfaces
- Classes/Interfaces, which are reused, but are adjusted
- Classes/Interfaces, which are removed
- Relationships between the Classes/Interfaces, which implement the new Writer's usage of the Drawing Layer
The Big picture of the refactoring
The general idea of the refactoring is to use the Drawing layer in such a way that the model and the views of Drawing objects from the perspective of the Writer are separated. This new usage shall be transparent for the Drawing layer - no special code should be included into the Drawing layer to reflect this separation.
The solution to make this idea happen is to create different Draw models for different purposes. One Draw model for the intrinsic model of Drawing objects - called simply Draw model in the following. One Draw model for each Writer view for the view of Drawing objects - called Draw view model in the following.
Current state of the art
Currently the Writer holds one Draw model with one Draw page for the model and the view of Drawing objects. This causes certain special code to reflect Writer's specifics regarding Drawing objects:
- As invisible marked layers in the Draw page.
- Certain Drawing objects are not visible in any view, because they are located inside a hidden area (hidden section, hidden paragraph) or inside a page header/footer of a page style, which is not applied to any visible text document page. But, these Drawing objects belong to the model. Thus, they have to be on a Draw page in the Draw model -> invisible marked layers.
- Virtual Drawing objects
- Drawing objects in repeated areas (page header/footer and table header) have to be shown more than once inside a certain view. Because each Drawing object shall be only once in the Draw model, virtual Drawing objects are introduced - class <SdrVirtObj>. These are referencing the intrinsic Drawing object. Drawing objects of type control are not working with this mechanism. There are also some effects (e.g. text animation), which does not work with this mechanism.
- Note: The current usage of class <SdrVirtObj> by inheriting certain classes causes a lot of implementation effort. It is error-prone and complicated. It lacks certain features (controls not supported, no support for certain effects). It is also hard to maintain.
- Special call back mechanism from Drawing layer to Writer on Drawing object changes
- Due to former needs a special call back mechanism from the Drawing layer to the Writer is implemented. In this call back mechanism further information - namely the bounding rectangle of the Drawing object before the change has been applied to the Drawing object - is passed to the Writer. This special call back mechanism can be removed nowadays. But unfortunately during the implementation of changes and enhancements to Drawing objects in Writer made in the past (mostly done by myself - email@example.com) this call back mechanism is not put into question.
The current state of the art also causes some problems with Drawing objects in the preparation work for multiple different views and for probably new views of a text document - cws swrefactor071015.
Solution/Refactoring in detail
The details of the refactoring are:
- The Writer model holds a Draw model. This Draw model represents the model of the Drawing objects, which are contained in a text document. Thus, this Draw model is used for load/save and the UNO-API. The Drawing objects in this Draw model will be called Drawing model objects in the following.
- The Writer model is more or less represented by the <SwDoc> instance.
- Each Writer layout holds its own Draw model for the visualization of the Drawing objects. Such a Draw model will be called Draw view model is the following. The Drawing objects of a Draw view model are clones of the corresponding Drawing model objects. These clones will be called Drawing view objects in the following. For each visualization a new clone is created. For the Drawing layer these clones are independent from each other - there will be no functionality restrictions as they are currently with virtual Drawing objects.
- A Writer layout is more or less represented by the tree of <SwFrm> instances with a <SwRootFrm> instance as its root.
- Note: Currently, only one Writer layout exists and it is shared between the existing Writer views (reason for the current restrictions between the existing views of a text document). Thus, after the refactoring there will be only one Draw view model. But, this solution will allow to continue the preparation work for multiple different views of a text document without having problems with Drawing objects (the goal of this preparation work is to give each Writer view its own Writer layout).
- The Writer will take care of the relationship between the Drawing model objects and its corresponding Drawing view objects.
- The Writer layout algorithm will create the Drawing view objects from the Drawing model objects.
- A certain instance of the Writer layout for each Drawing model object will hold the relations to the corresponding Drawing view objects.
- A certain instance of the Writer model will listen to the Draw model for changes on Drawing model objects and will assure a propagation of the changes to existing Drawing view objects.
- A certain instance of the Writer layout will listen to the Draw view models for changes on Drawing view objects and will assure a propagation of the changes to the Drawing model object and the other existing Drawing view objects.
- No special handling for undo/redo actions seems to be necessary. A certain undo action is recorded for the Drawing object, at which the action has taken place. On undo/redo the reverse action is applied to this Drawing object and via the above listening mechanism the other Drawing objects are notified.
Drawing layer functionality and issues
For the refactoring the following functions are needed:
- Clone Drawing objects
- Needed when a Drawing view object is created from the Drawing model object.
- Assignment of Drawing objects to each other
- Needed to propagate the changes on one Drawing object to the other related ones.
- Listening to Drawing object's changes
- Being notified, when changes are applied to a certain Drawing object in order to coordinate the propagation to the other related ones.
All functions are available at the Drawing layer. No serious issues regarding these functions are currently known.
- Treat every Drawing object type the same
- simplify code
- Get rid of class <SdrVirtObj> - instead use "real" Drawing objects
- simplify code
- special Drawing object type of Drawing layer for Writer, not needed any more
- Get rid of class <SdrObjUserCall> - instead use implemented listener-concept
- simplify code
- special notification mechanism of Drawing layer for Writer, not needed any more
- Special treatment of embedded objects regarding cloning
- clone of embedded object for visualization should be a graphic object with the replacement graphic of the embedded object as its content.
- this approach is in use for the full drag support of embedded objects, because it reveals that cloning embedded objects is too expensive.
- causes special treatment of graphic objects as visualization objects for embedded objects
- propagation of changes
- context menu
- tool bars
- clipboard handling
- Evaluate, if special treatment of control objects regarding cloning is needed
- Try to avoid the introduction of code into the Drawing layer to support new Writer's usage of the Drawing layer
- 1. and 4. somehow contradicts each other. Thus, assure in the implementation that the special treatment of embedded objects is implemented via a wrapper in the Writer code or via a corresponding virtual method in the Draw code.
- Note: second solution (new virtual method) contradicts with 6. But, would support a similar Drawing layer usage from the other applications.
- 4. would probably cause a new class in the <SdrObject> class hierarchy in order to identify the graphic objects, which are visualizations of embedded objects.
- Note: this would contradict with 6. But, would support a similar Drawing layer usage from the other applications.
Affected Drawing object functionalities
Issues fixed by the refactoring
|firstname.lastname@example.org||support form controls in page header/footer||P3||OOo Later|
|email@example.com||Anchor control to header's paragraph, OpenOffice will crash||P2||OOo 3.x|
|firstname.lastname@example.org||Drawing object copied via CTRL+drag is not visible||P3||OOo 3.x|
|email@example.com||Pictures flicker on top of document when opening||P3||OOo 3.x|
|firstname.lastname@example.org||Invisible object after pasting during "edit group"||P3||OOo 3.x|
|email@example.com||animated text in drawing objects in page header/footer only in one page header/footer||P3||OOo Later|
|firstname.lastname@example.org||"edit group" for page header/footer anchored drawing object group only in one group possible||P3||OOo Later|