GSoC 2011 Tables Weekly Reports

This is a collection of weekly reports from my work with implementing tables in Scribus as part of Google Summer of Code 2011. They are kept here for future reference and can possibly be used for future design documentation. The reports are in chronological order.

= Report #1 = This report was sent to the scribus-dev mailing list on Sunday June 5, 2011. Here is a link to the mail.

Work Report

 * Added a skeleton of a table style. This was way back in April, just to see what work is involved in creating a new type of style. The style is the most basic one imaginable. At the moment I think it has a single property for background color and styles can be managed in the SM. Also, it doesn't do inheritance yet, though that should be relatively easy to fix.
 * Added class PageItem_Table, a new page item for tables. The class represents a grid of table cells by keeping a few lists with row / column geometries.
 * Added ability to insert a new PageItem_Table from toolbar or Insert menu followed by mouse dragging. Just like the current "tables".
 * Added API to PageItem_Table for the basic table operations
 * insert and remove rows and columns,
 * resize rows and column.
 * Added support for merging cells to PageItem_Table as well as an accompanying helper class CellArea used when keeping track of areas of merged cells. The CellArea class also comes with what I think is the very first unit tests in Scribus. The tests are in tests/ and can be runned using `make test'. In the future, feel free to add more unit tests here if you think there are classes in Scribus that that are easy to unit test and could benefit from it.
 * Added some rudimentary painting to PageItem_Table, just to be able to see the cells. Still a long way to go for proper table / cell painting, which is kind of non-trivial.
 * As scriptability allows me to experiment with tables before any UI is done, I've added the following new scripting methods. These have been added to the old scripter, but should be easy enough to port to ScripterNG later on.
 * createTable(x, y, width, height, numRows, numColumns, ["name"])
 * getTableRows(["name"])
 * getTableColumns(["name"])
 * insertTableRows(index, numRows, ["name"])
 * removeTableRows(index, numRows, ["name"])
 * getTableRowHeight(row, ["name"])
 * setTableRowHeight(row, height, ["name"])
 * insertTableColumns(index, numColumns, ["name"])
 * removeTableColumns(index, numColumns, ["name"])
 * getTableColumnWidth(column, ["name"])
 * setTableColumnWidth(column, width, ["name"])
 * mergeTableCells(row, column, numRows, numColumns, ["name"])

Project Status
The goal in the schedule for this first week was simply "Data structures for tables". Intentionally a quite moderate goal, as I didn't know how long it would take to get up to speed. So unsurprisingly, I think I'm a little ahead of schedule. Worth noting though is that the tables are currently only skeletal in their nature; they hold no content and are simply a grid of empty cells. This is all according to plan though, and integration with text frames is scheduled for later.

Problems / Questions
Only have one quite specific question at the moment (though more will come for sure):


 * How do I set a clipping rectangle on the painter when painting an item in PageItem::DrawObj_Item(...) ? Some method call to set the clipping path followed by a call to setClipPath on the painter? I looked a bit at the other items but haven't quite figured it out yet. So if someone knows off-hand how to do it that would be great.

Next Week
The goals for next week according to the schedule is


 * Basic table layout with fixed column widths and mock content in cells.
 * Insertion/removal of rows/columns.
 * Basic drawing of table.

but as at least some of this has already been done, I think I'll start looking at other things as well. Ideas include


 * Cell borders / padding.
 * Add splitCells(int, int, int, int), symmetric to the current mergeCells(int, int, int, int).
 * Painting of table / cells.
 * Table and cell styles.
 * Start looking at UI:
 * Editing through Property Palette.
 * Canvas mode for editing and selecting cells / rows / columns.
 * Start looking at saving / loading (probably a bit premature).

Lots of things to pick and choose from, and if you have thoughts on which direction to go in first, I'm idle ears. Otherwise I'll just pick what feels most natural and go with it.

I don't think I want to start looking at integration of text frames just yet as I have a feeling that is going to be one of the toughest parts of the project. Besides, there are plenty of things to do before that can be done orthogonally to the integration of text frames. I'd like to have quite robust support for the other things before starting to crack that nut. Keep my back clear and don't spread myself too thin so to speak. So I think I'll stick to my schedule when it comes to this and not stick my head in that beehive until week 4 ;)

= Report #2 = This report was sent to the scribus-dev mailing list on Sunday June 12, 2011. Here is a link to the mail.

Work Report

 * Fixed 4 small bugs in the scripting methods.
 * Added a poor mans unit testing "framework" in the form a script (tests/script/test_tables.py) that automatically runs a set of test methods that exercises the table functionality and reports any regressions. The script gives output of the form

Running table tests... 1/8: test_construction............. Passed 2/8: test_insert_columns........... Passed 3/8: test_insert_rows.............. Passed 4/8: test_merge_cells.............. Passed 5/8: test_remove_columns........... Passed 6/8: test_remove_rows.............. Passed 7/8: test_set_column_width......... Passed 8/8: test_set_row_height........... Passed 100% passed, 0 tests failed out of 8


 * Added CellStyle, a new type of style for table cells. Currently it's as simple as the table style. New styles of this type can be managed in the SM. Also made sure that table/cell styles are shown below the other styles in the SM.
 * Fixed the drawing problem in DrawObj_Post we were talking about.
 * Added a new class TableCell for representing table cells.
 * Moved some adjustment code for areas of merged cells from PageItem_Table into CellArea, thereby simplifying the code in PageItem_Table a little. This made it possible to unit test the code properly and made me find a couple of bugs that I've now fixed. The code will probably also come in handy when doing selections of cell areas later on.
 * Fixed a (silly) bug when inserting a row/column before the first row/column of a table.
 * (Somewhere around here made my 100:th commit, yay :)
 * Changed TableCell into an explicitly shared class using QExplicitlySharedDataPointer for its data. This makes it possible for the table to easily invalidate cells that have been returned by cellAt(int, int) when rows are removed or cells merged. It also frees me from the burden of working with bare pointers to TableCells, minimizing the risk of dangling pointers.
 * Various small cleanups to the table code.

In addition to the work listed above, this week I've also done quite a bit of thinking about the painting of the tables and about their internal representation. I guess like most programmers, I find that if I make a long and hard thinking about the code before writing it, it will almost write itself, whereas if I just go ahead and start coding, it's easy to code yourself into some nasty corners. As I will have limited time after the summer, I want the code to be hackable/maintainable and clear.

Project Status
The past week has seen a little bit less work from me than the last I think. This is mostly because I had that dreaded trailing exam to take care of on the Thursday. This is now taken care of and GSoC can have my undivided attention. On the schedule for the past week was as I mentioned in my last report


 * Basic table layout with fixed column widths and mock content in cells.
 * Insertion/removal of rows/columns.
 * Basic drawing of table.

All three items are done, except I've actually removed some of the first painting code I wrote as I'm currently working on proper painting (more about this in Next Week below).

Problems / Questions
No specific questions this time. You promptly replied to me regarding that painting issue I had with DrawObj_Post(...). Thanks for that. I've added a TODO at the fix in the code about this needing some further investigation.

I do however have one non-code-related concern which turned up while writing this report; I noticed that after malex did the updating of my gsoc11tables Git repo from your internal SVN, some of my old commits started showing up twice in `git log'. As an example, my very first commit "Add a (very) rough first prototype of a table style." is now visible as both

and

in the Git history or gsoc11tables. The second one is the one that turned up after the merging and it has malex as commiter and me as author (Git makes a difference between the two). I'm no Git expert, but think this may be due to the pushing of SVN changes into the Git repo is done using git-svn. Ideally we would have no such duplicates, but I'm not sure how to achieve it. So; malex, do you think you could look into this? If it's not possible then it's not possible, but it's kind of annoying when trying to work out the history of things when old commits show up as if they were new. Maybe ask someone really git-wizard person about it.

Next Week
On the menu for next week according to my initial schedule is


 * More advanced layout.
 * Variable column widths.

But as variable column width is already done, and I already have some of the more advanced table layout features such as row/column spanning working (which was actually not in my schedule until week 7), it seems I'm still a little bit ahead. So far, it seems that I've underestimated how much work I'd be able to get done during these first two/three weeks. That said, the work ahead is plenty and I may well have underestimated the work involved in some of the later items on the schedule, so this is a good thing.

My plan of action for next week is instead to start looking at one of the items for week 4 in the schedule: "Cell formatting properties such as border and padding". In fact, this is what I'm working on right now, making some changes to the internals of the table in preparation for this. I've had a look at the quite powerful styles for lines that Scribus has, and I think they will be useful for my work. There are some tricky but interesting problems when it comes to painting borders on a table, especially regarding the order/priority of which border to paint, but also when it comes to joining of borders that meet at a corner or crossing. During my GSoC for KOffice in 2009, me and Casper Boemann were working in tandem on the tables, and he was doing a lot of the painting work, so I'm very much looking forward to taking this on as it's new territory for me.