GSoC 2011 Tables Post GSoC Tasks
This is a list of tasks relating to tables that are up for grabs. Some of the tasks are small and relatively simple, some are more complex, and others are really complex. For each task I have written some thoughts and ideas on how to solve them.
Task Progress
Task | Difficulty | Status | Who |
Cell / Table Properties in Property Palette | Medium | In Progress | Elvis |
Cell Text Formatting | Medium | In Progress | Elvis |
Load / Save | Medium | In Progress | Elvis(?) - Craig |
Painting for Print Output | Medium | In Progress | Elvis |
Style Editing | Medium | In Progress | Elvis |
Cell Splitting | Easy(?) | TODO | TBD |
Cleanup of Resizing Code (Strategies) | Medium | TODO | TBD |
Extend Unit Testing Python Script | Easy | TODO | TBD |
Write C++ Unit Tests Where Possible | Easy | TODO | TBD |
Row / Columns Selection Canvas Gestures | Easy | TODO | TBD |
Optimize Table Painting | Hard | TODO | TBD |
Support Copy/Paste in Table Cells | Medium | TODO | TBD |
Import/Paste from CSV | Medium | TODO | TBD |
Import/Paste from ODS | Hard | TODO | TBD |
Painting Borders "Horizontal on Top" and "Vertical on Top" | Hard | TODO | TBD |
Odd/Even Row/Column Formatting in Table Style | Medium | TODO | TBD |
Extend Scripter API and Port to ScripterNG | Medium | TODO | TBD |
Adjust Table to Content | Hard | TODO | TBD |
Separate Border Model | Hard | TODO | TBD |
Breaking Tables over Multiple Frames | (Very!) Hard | TODO | TBD |
Task Descriptions
Urgent Tasks
Style Editing
Support for editing all the properties of table / cell styles should be added to the StyleManager. The work is quite straightforward, and similar to the work that needs to be done in the Properties Palette (see below).
Cell / Table Properties in Property Palette
The existing "Table" property palette should be made more robust and support all properties of the table. A combobox for selecting the table style, as well as a "Remove Direct Table Formatting" button should be added. A new "Cell" property palette should be added, supporting all properties of cells.
Cell Text Formatting
The existing "Text" property palette should be modified to support formatting of paragraphs and spans of selected text in tables. Modifications to the relevant slots in ScribusDoc is probably also necessary.
Load / Save
Loading saving of both tables and cells, as well as table style and cells styles have to be written. This requires modification of the scribus15format load/save plugin and the saxx(...) functions of the styles, and possibly other places as well.
Painting for Print Output
The table item is currently only painted on the canvas. The first step will be to add support for tables to PDFLibCore, to support output to PDF. Hopefully most code in the CollapsedTablePainter, which paints a table on the canvas, can be reused. The easiest way will probably be to create a CollapsedTablePainter::paintTablePDF(PageItem_Table* table, PDFLibCore*, QString& output) which will do the work, but then CollapsedTablePainter will have to be made a friend of PDFLibCore to be able to access its convenience functions for generating PS/PDF commands. I will have to look at it closer. After that, support for the other outputs needs to be added as well.
Small Tasks
Cleanup of Resizing Code (Strategies)
At the moment, the code in the the RowResize and ColumnResize canvas gesture for resizing the table overlay is pretty similar to the code in PageItem_Table that does the actual resizing of the table. Resizing is just a manipulation of a couple of lists of qreal. To avoid code duplication this code could be generalized into "resizing strategies" and put in e.g. tableutils.h/cpp to be shared.
Extend Unit Testing Python Script
This is pretty self-explanatory. The script scribus/tests/script/test_tables.py
currently tests some basic functionality of the table, but more tests could be added. Adding a test is as simple as adding a new method to the TableTests
class. Any added methods will be runned automatically when the script runs.
Write C++ Unit Tests Where Possible
There is not much, but there is some code that can be unit tested in an isolated manner without having to have a full Scribus application running. An example is the collapseBorders(...)
function in tableutils.h/cpp
. So adding unit tests for these in scribus/tests
would be a good idea.
General Improvements
Cell Splitting
Missing from GSoC Implementation
Row / Columns Selection Canvas Gestures
Currently, when hovering the top of a column or the left side of a row with the mouse, the cursor is changed to an arrow that indicates that the column/row can be selected. However, nothing happens when the user clicks or drags the mouse. What is needed is to add two new canvas gestures -- RowSelect and ColumnSelect. These gestures should be started when the user clicks these areas in the table editing canvas mode. By just clicking once, an entire row or column of cells should be selected. By click dragging, it should be possible to select a range of rows or columns. This task should be quite simple. It's just a matter of starting/stopping the gesture at the right time (see the switch/case
construct in the mousePressEvent
in canvasmode_edittable.cpp
), and then determining the range of rows/columns that should be selected.
Optimize Table Painting
The performance of the painting of the table is quite OK, but if we want to improve it, the absolutely best way to do it is to minimize the number of strokes that is performed. Since the borders of the table and its cells are painted in two passes, first vertical and then horizontal (which may overlap the vertical ones), it should be possible during the second pass to batch up the stroking of the horizontal borders if two subsequent borders are equal and have not been adjusted for joining. This could possibly speed up painting of homogeneous tables quite a bit.
Support Copy/Paste in Table Cells
Copy/Paste in table cells currently doesn't work. The entire table is copied/pasted. The code that handles text copying for regular text frames needs to be found, and be made aware of tables/cells and their text frames.
Import/Paste from CSV
If Boost is allowed in Scribus code, perhaps we can use Boost.Tokenizer's escaped_list_separator
which does quite robust parsing of a superset of CSV.
Import/Paste from ODS
This is probably a little trickier than import of CSV, but maybe we can contact the guys in Calligra, the office suite of KDE, to see what the state of their ODF parsing libraries is. I believe they have as a goal for third parties to be able to use their libraries, without depending on KDE libraries. I'm not sure if it's ready to be used straight away though. Will have to look it up.
Painting Borders "Horizontal on Top" and "Vertical on Top"
Borders of the table are currently always painted in a "best joins" fashion. If possible borders are always joined at intersections. There should be an option to paint the borders of a table either "Horizontal on Top" or "Vertical on Top", like there is in InDesign. This is much easier to do than the joining behavior, and I just haven't gotten around to it yet.
Odd/Even Row/Column Formatting in Table Style
Adobe InDesign has the ability to do conditional formatting of cells depending on whether they're in an odd or even row or column of the table. This is quite useful for some designs and saves the user some manual formatting. We should have this option as well.
Extend Scripter API and Port to ScripterNG
There is currently scripter methods for large parts of the tables functionality. These methods are however written for the "old" scripter, and needs to be ported/rewritten for the new scripter. This should be quite straightforward.
Complex / Long Term Task
Adjust Table to Content
Adjusting the height of a cell, a range of rows or all rows of the table to fit its text content (without overflowing) might be useful for some designers. So we might consider adding support for
- Adjusting the size of a single cell to its text content by right-clicking and picking "Adjust Cell to Text".
- Adjusting a range of rows to fit its text content by right-clicking and picking "Adjust Rows to Text".
- Adjusting all rows in a table to fit its text content by right-clicking and picking "Adjust Table to Text".
Implementation-wise, this would mean:
- Adding a function
adjustCellToContent(int row, int column)
toPageItem_Table
. This function would- Retrieve the cell at
row, column
. - Calculate
cell.maxTopBorderWidth()/2 + cell.topPadding() + [content height] + cell.bottomPadding() + cell.maxBottomBorderWidth()/2
. - Set the height of
row
to the calculated value.
- Retrieve the cell at
- Adding a function
adjustRowsToContent(int startRow, int endRow)
toPageItem_Table
. This function would- For each cell in
startRow
, perform steps 1.1 and 1.2 above and pick the maximum calculated height and set the height ofstartRow
to this value. - Repeat the step above for the rows
[startRow + 1...endRow]
.
- For each cell in
- Adding a function
adjustToContent()
. This function would simply doadjustRowsToContent(0, rows() - 1)
.
We might also consider a mode where typing in a cell would call adjustRowsToContent(...)
on each key stroke, giving a completely automatic adjustment of the table.
Separate Border Model
The border model currently implemented in Scribus is a variation of the CSS collapsing border model. Adjacent borders in the table are collapsed according to certain priority rules (found in TableUtils::collapseBorders(...)
). In the future we might also consider adding a "separate" border model, in which borders are always drawn separated. This would mean adding another subclass of TablePainter
, perhaps called SeparateTablePainter
and implementing the paintTable(...)
function, as well as adjusting the PageItem_Table::tableOrigin()
function to take this into account, plus any other places that currently assumes a collapsing border model. This is quite a complex task.
Breaking Tables over Multiple Frames
This one is definitely for the future. The idea is that tables would function similar to how linked text frames currently work, so the code in PageItem_Table
should probably be moved into a general Table
class, and the PageItem_Table
be made to only represent a section of the table. To allow content in a cell in one section of the table to flow into another section of the table, the text content of cells should be represented by a list of linked text frames instead of just a single text frame like it is now. On top of this comes all the logic of breaking the table correctly across these multiple table items. This is a very complex task, but it's definitely possible.