Hey all,
I have been playing a bit with an implementation for Calc table style
support including OOXML support. I'm not too happy with some of my design
decisions so wanted to see what other people think before I spend any more
time on this.
The code can be found in the branch feature/calc-table-styles
Attached are two screenshots showing a comparison between the MSO Excel
rendering of my test document and the current Calc rendering.
Note that this also includes a number of related database range
improvements, including a small sidebar section with database range/table
style properties, a handle to change the size of database ranges when they
are selected and a script to generate the OOXML default style information
in a way that we can use them easily from code.
My current code has the following limitations that I'd like to fix before
this would be ready to merge:
- font formatting is not implemented at all. Font handling is a lot more
complicated than background and border handling
- border handling is per cell right now but it should be based on the
property that provides the border definition, e.g. if the border definition
comes from row striping the left border only applies to the left edge of
the table and not each cell in the corresponding row.
- The dxf handling for vertical and horizontal border definitions got
added already but not the rendering part
- unit tests are completely missing
- link between table style and DB goes through the name instead of a
reference to the actual table definition
- The autoformat feature should be removed and folded into the table
style implementation which would also provide a UI for modifying table
styles.
- merged cells are not handled at all right now
- some UNO interfaces to interact with this feature
Additionally, I might fix the following database range related issues
before merging if I continue with the current design:
- the subtotal row does not move when the database range gets expanded
- the filter buttons can disappear when in tables without headers. MSO
does not allow filter buttons on rows without headers but Calc supports
this. As soon as the filter buttons disappear you can not remove the filter
without using the show hidden rows feature. If you use the feature the
filter settings and the document behavior are no longer in sync.
- the ability to change the database range name and automatically adapt
all the formulas referencing the range. We have an UNO API to change the
name but it breaks all structured references
Now to the part that I'm not happy with and why I think someone else might
want to have a second look at the ideas behind this change:
- Storing the table style information purely on the ScDBData makes some
operations quite easy but at the same time makes the code in
ScDocument::FillInfo a lot more complicated. At the same time I have not
come up with a design that would allow us to avoid the position dependent
property lookup during FillInfo. We could store a reference to the table
style in the ScPatternAttr but then we need to keep the ScDBData range and
the ScPatternAttr in sync. In my mind the table style information is not a
cell attribute until the rendering stage.
- Adding font handling is going to be painful as the font lookup is
delayed until the actual drawing
- My current idea would be to store a reference to the table style
and a struct storing the style lookup information, e.g. this
cell looks at
first column stripe, second row stripe and whole table item
sets. This way
the information only needs to be computed once and the lookup for all the
font properties can be done reasonably quickly.
- Potentially this could also be done by combining the handling of
conditional formatting and table styles. In theory a slightly cleaner
approach would be to have a list of SfxItemSet instances that are checked
in order until an explicitly set item was found. That way there
is no need
to encode application layer information into the rendering code.
- The fix for the border drawing issue mentioned above requires the
dynamic generation of new border items that can be passed through
ScDocument::FillInfo to the rendering code or a rework of the border
rendering.
I'd appreciate feedback from some other Calc developers about the design
and whether it is worth continuing with this design.
Cheers,
Markus