Something that works is good, but something that works great is better. These past days, I fixed many bugs and imperfections of the new Nepomuk Query Parser and the Query Builder widget. I will summarize theses fixes shortly, then will come the screenshots.

Syntax-highlighting, one more time

Before my holidays, I implemented the Query Builder widget as a syntax-highlighted QPlainTextEdit . This was easy and fun, and the result looked quite nice. You can find the whole story here.

After that, I decided to rewrite the implementation from scratch to give it a different look. I wanted to have boxes around parsed terms, with a small cross to remove them. After some days, the widget looked like that:

This widget was really nice, but its implementation did not seem very clean. Furthermore, the widget was made of a complex tree of line edits, buttons and widgets responsible for drawing the boxes. Handling the cursor position (and the text itself) was a bit hackish, and some things did not work well (you were unable to select all the text of the widget, for instance, and focus handling was a bit special).

On Sunday, I thought of a new implementation that has the simplicity of the syntax-highlighted QPlainTextEdit , with the look of the complex widget tree.

At the start of the day, I wanted to use a QTextEdit with a custom style sheet and custom HTML. My plan was to use the HTML renderer of Qt to draw the boxes around the parsed terms, and to use the Unicode "×" character to provide the cross. I wanted to implement the closing cross using a custom mousePressEvent method and something like characterAtMousePosition() == '×' .

Finally, I discovered that the HTML engine of Qt does not support rounded corners (and does not seem to support border colors at all). So, I decided to do all the drawing myself, in a paintEvent method. I tried to subclass QLineEdit , but this class does not allow me to map a character position to a x coordinate. Finally, I used QPlainTextEdit , because QTextDocument allows me to map a character position to a x coordinate:

1 2 QTextLine line = document () -> findBlock ( 0 ). layout () -> lineAt ( 0 ); int x_pos = line . cursorToX ( char_index );

Using this, I'm able to easily draw boxes around terms, and this is fast. The only problem is that there is no crosses. I first wanted to add " ×" after each box, but this would have required to change the positions of the boxes. If a box spans characters 2 to 6 without a cross, it needs to be extended to character 8 with a space and a cross at its end. Furthermore, the following boxes need to be adjusted 2 characters to the right. This would have been too complicated for a feature not really needed.

With the third version of the query builder in place, I was able to fix many bugs. Text selection now works correctly and as expected, and the auto-completion widget was enhanced. It preselects completions based on what the user types (if I type "tagged as Im" and I have a tag named "Important", it will be pre-selected), and many little details like size hints are now saner.

Playing with Dolphin

Yesterday, I wrote a small patch for Dolphin to integrate the query builder in it. When Dolphin is built with Nepomuk enabled, you can enter user queries with the help of the query builder widget. The result is quite nice and I hope that this patch will be merged in the next KDE release. I don't post it yet on Reviewboard because the API of the query builder is not yet fixed.

The next steps are now to integrate the query builder in more applications (maybe Plasma Active), and to fix even more bugs. I also have to document the public API of my code.