It has been around three months since the last release, June 22nd to be exact. Since then I have made some small changes along the way, but didn’t publish them because they haven’t been in the shape that I wanted them to be for a release, but still good and helpful enough for me to use them on a daily basis. The biggest new feature is an editor. Second comes the translation and around them gather a few improvements regarding usability.
Visit the GitHub page to download the latest version.
High-Level Features
Let’s start with the editor. My typical use case is that I have to fix items of the current day either because I totally forgot to diligently click the “Start” and “Stop” buttons or because I wasn’t at my desk at all, attending a meeting or talking to colleagues about issues in the software. However, the editor is not limited to the currently active day. You can choose from a list of all the days you have ever recorded.
The editor follows a wizard style approach and consists of two pages between which you can jump back and forth as much as you like. The first shows a list of days from which you select one to edit and the second page is the editor itself. To make it easy for my use case the list is sorted in descending order, meaning that the most recent day is listed at the top. If all you care about is the current day and you live on the keyboard then starting from the main window you hit Ctrl-E to open the editor and Enter to select the current day and move right to the edit page.
On the left side of the window you’ll see the list of tasks for the selected day and on the right side there are the recorded working times. As shown in the picture you can rename a task inline (F2, as expected) or add (Ctrl-A, Ctrl-T) or remove (Ctrl-R, Ctrl-T) tasks. The same is true for timstamps, Ctrl-A, Ctrl-D adds a “datetime” and Ctrl-R, Ctrl-D removes a “datetime”. Adding a new working time means that a new line without values is inserted. Removing a timestamp means… Well, it depends on your selection. You can select arbitrary items and remove them and the following rules apply:
- If only one cell of a row is selected then the value is removed.
- If only one cell of a row is selected and the other cell is empty then the selected value and the complete row are removed.
- If both cells of a row are selected then both values and the row are removed.
Multi-select also applies to the list of tasks and works as you’d expect. The selected tasks are removed and with them the recorded timestamps. Be careful though, every action has immediate effect on the underlying data model. If you remove tasks then they are gone. Closing the wizard by hitting the Escape key won’t help you.
This is the result of making it easy for me to implement since I don’t have to record the changes and then apply them later on and it also facilitates moving back and forth between the select-a-day-page and the edit-tasks-page.
The next feature isn’t really anything that provides a real tangible benefit like the editor does. But it was enough work to be called a feature and that is a translated user interface.
The main windows contains a new menu option called “Language” and lists the currently supported languages. At the moment there are only two, my native language German and English (with US flavor whenever there are distinctions, e.g. date formats). Selecting a language immediately translates the user interface, you don’t have to restart the application.
Among the small improvements the biggest one is probably the input of the tasks. After you click the “Start” or “Stop” button the application shows an edit field which now automatically receives the focus. This way you can type away immediately and don’t have to move the cursor into the edit field. The second part is that this edit field now recognizes the Enter key and when detected it presses the “Select Task” key for you. That makes entering tasks much faster. Along those lines of minor changes are a few keyboard shortcuts on the buttons that somehow got lost in a previous release.
Technical Stuff
The editor, the language and the small improvements to keyboard shortcuts that make navigation faster are not a big deal. In theory it means to only slap a few lists and edit buttons into a dialog, implement Qt’s model paradigm and call it a day. But, for the editor to work correctly the underlying model had to be changed. Completely. From a database perspective a workday consists of three XML tags:
- The itself.
- A list of items with as parent.
- A list of items with as parent.
The references a “real task” (the text you enter when you start or stop a task) through an attribute “id” and the nodes have attributes “start” and “stop” (do I need to explain?).
In the previous version this workday-task-time relationship was modeled using two classes. The task and time had been fused into one and the workday had a list of those amalgamations. In addition, the workday was responsible of creating the XML nodes for task and time. This is by no means a reasonable approach if you want to implement arbitrary editing capabilities – which wasn’t the plan to begin with. I realized that an editor was necessary only after a few weeks of using the application productively. Until the very first simple implementation (based on the old model) I edited the XML file directly.
What was already there was the immediate feedback after a change. The existing model was already directly linked to the XML database by having the QDomNode stored in every instance of the model classes. I certainly wanted to keep that. What I ended up doing was to model the application’s data model based on the real world, which meant having three classes for three different DOM nodes. Every class still has its QDomNode and reads its values and attributes and children directly from that node and of course also writes to that node. There are no intermediary member variables. Now it was easy to have a one-to-many relationship between workday and task and also task and time.
That change also meant that most of the code that deals with these classes, e.g. finding an active day and task on startup, had to be changed to fit the new model. Only after that was finished and proved to work as reliable as before I moved on to finally implement the editor as it now is.
For the time being this is probably the last version of WorkTracker (unless I discover bugs that really have to be fixed). I’m going to move on to other things, C# to be exact, to try and do and learn something different. That doesn’t mean I’m abandoning WorkTracker, which I’m not. It is mature enough to be put aside for some time and that’s what I am doing. I’m still planning on adding global hotkeys at some point, just not right away. I need something different now.