As C.Boemann already said, we met at my place for two days in order to fix some serious issues we had with the undo/redo framework in Calligra Words (and Stage for that matter).
The undo/redo framework is something I wrote when I first started contributing to KOffice about 3 years ago. I have to say that I was not really looking forward having to jump into this stuff again. I am not such a masochist and the memories I have of writing this are not ones of an easy glide.
To summarise a bit (more detailed description bellow for the hard hearted): we use Qt Scribe framework for our document. When an edition is done on a QTextDocument, it emits a signal telling that an undo/redo action was added on the QTextDocument internal undoStack. The application listens to this signal and can create an undo action on its stack to match QTextDocument's internal one.
So we sat with Boemann thinking how to solve that problem. In the end we only needed to add, instead of a single head command member in the framework, a stack of head commands.
Overall, I had a really good time coding with C.Boemann, who is not only a very talented coder but also somebody I really appreciate. It is amazing to see what we achieved in those just two days.
A bit more details:
As I said, we use QTextDocuments to hold the data of one text frame (text shapes). This document is edited through a specific handler: a KoTextEditor. This editor is not only responsible for editing the QTextDocument but also to listen to the QTextDocument's undoCommandAdded signal and keep our application's stack in sync.
In addition to this, there are two special cases in editing QTextDocument: inserting text and deleting text. These two actions only trigger a signal on the first edit. Any subsequent compatible edit is "merged" into the original edit command and will not trigger a signal. Inserting text and deleting are therefore open ended actions, as far as our framework is concerned.
In order to handle this, a sort of state machine is used. The KoTextEditor can be in a NoOp, KeyPress, Delete, Format or Custom state. Furthermore, for each signal received from the QTextDocument, we create a "dummy" UndoTextCommand, whose sole purpose is to call QTextDocument::undo or QTextDocument::redo. These commands need to be parented to a command which we push on our application's stack. This head command will call undo or redo on all its children when the user press undo or redo in the application.
I will not enter into more details here, if you are interested in the whole gory logic of this, you can look at the code in calligra/libs/kotext/KoTextEditor_undo.cpp (which for now lies in the text_undo_munichsprint git branch). The code has now been pretty well documented, something I had not done before.
That's it for today. Once again, I ask from as much of you to try our next test release, specifically the undo/redo framework, so that we can ensure that we release a really good stable Calligra Words.