Archive for January, 2010

Flight of the Pechvogel

January 29, 2010

On Wednesday afternoon I boarded a Greyhound bus in Las Vegas, and by Thursday morning I was at the airport in San Diego to fly home to Berlin by Friday evening. It’s 8 am by my frame of reference, and I didn’t sleep on the plane because of the old guy beside me who looked so uncomfortable in his chair I thought he might collapse.

Of course, just like last time, my luggage didn’t get as far as I did. There must be some way to measure the hysteresis of my luggage–self movements. Or something, I’m very tired and I have to stay up until nighttime. But at least I learned a new German word.

There was a lot of interesting content at CampKDE which will be shared with the world in due course. Aside from the talks, it was very cool to meet KDE people I’d never met before and some that I’ve met a few times now. This side of the pond had a good turnout, but it was mostly North Americans attending. The trainings in CMake, Qt and QtEmbedded were very useful to attend too.

I should be back to the usual interesting blog posts about kde pim, more ModelView stuff and Grantlee in the next week now that I’m out of the land of distraction.

Advertisements

Getting (mostly) to CampKDE

January 15, 2010

A guy walks to the checkin desk of his airline with a lot of luggage:

Flyer: Hi there. I’d like you to send my suitcase to Beijing, my rucksack to Washington, my surfboard to Berlin, and I’m flying to San Diego.
Airline: Uh, I’m sorry sir I don’t think we can do that.
Flyer: Well you did it before without me even asking you to…

In fairness I had only one checked in bag on my flights, but it got lost somewhere through my cancelled and delayed connections. Hopefully it will turn up in the next day or two, or it could shaft my plans for after the event.

Right now though, they’re playing Moondance by Van Morrison in the lobby. The day is looking up. 🙂 Time to debug my presentation methinks.

Testing proxy models gets easier. Again.

January 6, 2010

I just pushed a few commits to the tests section of kdelibs which make it easier to test proxy models.

I have written before about testing of proxy models, but things have progressed greatly since then. Aside from creating a unit test suite, I also created a small application for testing proxy models, imaginatively called proxymodeltestapp.

The idea was to have a visual indication of whether the proxy models used in Akonadi were working properly. Those proxies are all implemented generically so that they can be used with any model, in this case DynamicTreeModel which I wrote about before. Having full control over the contents of the DynamicTreeModel by using various commands meant that I could tackle various bugs in the proxies as they came up by recreating models and scenarios in the proxymodeltestapp, such as “starting with a complex tree, we move these items from here to there. Then the application crashes.”. Having a way to reproduce those scenarios in a Short, Self Contained, Correct, Example, away from the additional Akonadi and application code has proved very useful. There is even a widget to drive the DynamicTreeModel in the same way as it is driven in unit tests. Again, having a visual representation of what is going on and how the proxy should react takes some of the pain out of writing and fixing unit tests for the proxies.

It’s all in the interpretation

The first of todays interesting commits adds an interpreter to DynamicTreeModel. The two most annoying parts of writing tests for proxy models are setting up an initial condition, and inserting some new rows, some of which have child items themselves. Both issues have the same root cause: The DynamicTreeModel did not have any easy to use command to insert a tree or sub-tree into the model. The old solution was to define some fragments in a ModelInsertWithDescendantsCommand (catchy name as always), and when the command was executed, the fragments would be inserted at once, creating a new subtree. This kind of worked, but the code was difficult to read and implement, both counter-productive to unit testing.

The new interpretation method looks something like this:

insertCommand->interpret(
  "- 1"
  "- 2"
  "- - 3"
  "- 4"
  "- 5"
  "- - 6"
  "- - - 7"
  "- 8"
);
insertCommand->doCommand();

which will of insert 5 new rows in the model, some of which have children. Much better for writing unit tests. The parsing logic is very simple, and each of the items in the tree does not need to be a sequential number. They can all be the same number, letter or series of gibberish if it makes it easier. There’s even a #define to dump a nice numerical tree to stdout if you want to create a readable version from a gibberish version.

Simultaneous interpretation

Of course the interpret feature is not limited to writing unit tests. Through the use of the new DynamicTreeWidget, proxymodeltestapp can be used to quickly create a model for testing purposes without recompliling or even restarting the application.

DynamicTreeWidget View and Edit tabs

On the left is the “View” tab of the DynamicTreeWidget, which contains the DynamicTreeModel in a QTreeView. By clicking on the “Edit” tab, we get an editable textual representation of the tree. We can move, add and remove items in the text view, and when we switch back, the “View” tab is already updated with the new edited version. We can also use separate controls in the DynamicTreeWidget to insert or remove items in the model, or move them with drag and drop, and the text version is instantly updated. This is a very simple way to create and manipulate the model for proxy (or view) testing purposes and allowed the removal of a lot of code in the test app.

Scriptable descendants

The last interesting commit for today (there will be plenty more days) combines a new proxy model with QtScript. I haven’t written about the KReparentingProxyModel before because it will hopefully be part of kdelibs 4.5, but not 4.4. The idea is to define in a proxied model a completely different structure than is present in the source model. It could be used for example to turn a list of emails into a threaded tree of emails in KMail, or a list of todo tasks into a tree of tasks and subtasks in KTimeTracker. It could be used to flatten a tree into a list for use in a combobox or similar widget, or to turn a particular tree into another tree of a different structure for a reason I can’t imagine. On the whole, it should be useful for Akonadi when fully working.

There is only one method in the API:

virtual bool isDescendantOf(const QModelIndex &ancestor, const QModelIndex &descendant);

Consumers of the class reimplement that method to return whether descendant should be a descendant of ascendant in the proxy model in much the same way that you might implement QSortFilterProxyModel::lessThan. By using a little bit of QtScript magic, I can define the structure in a proxy at runtime in the proxymodeltestapp.

Scripted reparenting proxy model 1

Scripted reparenting proxy model 2

Scripted reparenting proxy model 3

Nice, no?