All posts by Dominik

Dominik is a PhD student at the Control Theory and Robotics Lab, TU Darmstadt, as part of the Research Training Group GKMM (GRK1362). My research focuses on state estimation in distributed systems. As hobby, I contribute to the KDE project and work on the Kate application and editor component.

Kate in 4.11

Another release cycle gone, and the KDE Software Compilation 4.11 is out in the open (well, for quite some time already), and with that it is time to talk about what changed in Kate the last half year since the 4.10 release. Besides the usual bug fixing (~50 bugs since 4.10), the following sections present some major improvements and features of Kate in 4.11.

Python Plugins

Since KDE 4.10, Kate features the Python »Pâté« plugin. This plugin basically wraps the API of all Kate application interfaces. Therewith, together with the Python KDE (PyKDE) bindings you can develop full-featured Kate plugins in Python. Being relatively new, there are quite some Python plugins available already now (see this blog, this blog, or this blog).

@Python community: You can interpret this as an invitation for writing lots of cool addons for the Kate text editor in python. All contributions are usually very much welcome!

Vi Input Mode

Enabling the vi input mode turns Kate into a full-fleged vim compatible editor: modal editing exactly like in vim. This mode is especially suited for vim users who want a fully KDE integrated text editor with all the beloved vim features. Started as GSoC project in 2010, the vi input mode evolved over the years to become a very mature alternative to vim itself. However, there is always room for improvements. The good news is, that Kate Part’s vi input mode gained a lot of attention thanks to Simon, mostly in the form of small “papercuts” that fixed small bugs and annoyances and made behaviour more compatible with Vim, including:

  • Yank highlighting, which helps you to see what text you just yanked;
  • “Yank to clipboard” (courtesy of Fabian Kosmale!);
  • The “last edit” markers, “.”, “[" and "]“;
  • Recursive vs non-recursive mappings, for if you want to e.g. map “j” to “gj” …
  • … plus plenty of fixes to gj and gk;
  • and countless other small tweaks to things like the “inner block” text object; cursor position after paste; fixes to ctrl-a/x (add to/ subtract from number under cursor); making more motions available in Visual Mode and more motions counted, etc!

One fairly major change is the introduction of an experimental Emulated Vim Command Bar. This, as you will probably have guessed, is a replacement for the current Search dialog that behaves more like Vim’s, allowing one to e.g. insert the contents of registers via ctrl-r; dismiss via ctrl-c/ ctrl-[ as well as ESC; work properly with both forward (“/”) and backward (“?”) incremental searches; use smart case for case-sensitivity; allow the use of Vim-style regex’s etc. As an extension to Vim, I’ve also added the ability to auto-complete words from the document via ctrl-space: not that useful for searching, but very useful for when you want to do a search+replace command (command mode (“:”) did not make it into 4.11, alas).

In 4.11, it is disabled by default as it is not yet ready for primetime, but may be enabled by setting the hidden config option “Vi Input Mode Emulate Command Bar” to “true”. It is much more powerful and featureful in current master (see the blog here!) and will likely be the default in 4.12.

New Text Folding

Back in KDE SC 4.8, Kate got a new code folding implementation as part of the yearly GSoC project. Compared to the previous implementation, the amount of bugs indeed reduced, but during the 4.9 and 4.10 release it became apparent, that the code folding was still not where it should be. Maybe writing a good code folding implementation was also a bit too much in terms of a newby developer in a GSoC project.

So Christoph sat down and wrote it completely new from scratch, this time very clean and simple. And as a new feature, the text folding is now per view, so the folded parts can be different in each view of a document. And as another feature for those who do not use text folding at all: Not using text folding means you have zero overhead, no matter how large the file. Besides that, code folding in Python works now better than ever before, in fact, it should be bug-free.

Passive Notifications & KTextEditor Interfaces

Passive notifications are meant to provide a non-intrusive way showing notifications (replacing KPassivePopup). Used e.g. by the data recovery, these notifications were also introduced for the search & replace feature (most of this is already available in KDE SC 4.10.3). In KDE SC 4.11, the interface for showing these passive notifications got officially included into the KTextEditor interfaces, meaning that applications like Kile or KDevelop can show notifications as well. (Issues in KDE 4.11.0 should be fixed for 4.11.1).

Next to the KTextEditor::MessageInterface, Kate has a so-called TextHintInterface since year 2003, but it seems its implementation never got finished. For 4.11, Sven Brauch stepped up and finally fixed the text hint interface. So showing tool tips for text under the mouse (section Text tooltips) is as easy as it was never before:

Saving Files

When saving files, Kate uses the class KSaveFile (in Qt5 available as QSaveFile thanks to David Faure). In short, to avoid data loss, KSaveFile saves the file to a temporary file in the same directory as the target file, and on successful write finally moves the temporary file to the target filename. If the folder of the file does not allow creating new files, KSaveFile automatically falls back to writing the file directly. In this case, data loss could happen if e.g. the system crashes in this moment, but saving the file would otherwise be not possible at all.

What Comes Next?

Announced just a few days ago, the KDE community prepares for KDE Frameworks 5 and much more: The KDE libraries and the KDE Plasma Workspace are now in long term support mode, meaning that bugs will get fixed for another two years. That means that the KTextEditor interfaces are frozen as well, there will not be any feature updates at all in the KTextEditor interfaces itself. Since Kate Part and the Kate Application are developed outside of kdelibs, Kate Part and Kate will most certainly see another feature release. Especially, since there are already a lot of improvements for the vi input mode in the pipe for Kate in KDE SC 4.12.

After that, we plan to port Kate to Qt5 and the new frameworks 5 libraries. We already added a lot of “KDE 5″ todo-markers to the Kate source code, meaning that we will probably work on a 5 port rather sooner than later. We will address this schedule in a separate post later this year, so stay tuned!

QUndoStack versus Kate’s Undo System

I’m currently using QUndoStack in a project of mine. A QUndoStack contains a list of QUndoCommands which then can be executed with QUndoStack::undo() and QUndoStack:.redo().

Now I thought when deleting an instance of the class Node, I can just hock the creation of the respective UndoDeleteNode class (derived from QUndoCommand) into the destructor, like this:

class Node {
public:
  // ...
  ~Node() {
    undoStack()->push(new UndoDeleteNode(this));
  }
};

class UndoDeleteNode : public QUndoCommand {
public:
  // ...
  void undo() {
    // create node again
  }
  void redo() {
    // delete node again
  }
};

Now the problem with this code is, that executing UndoDeleteNode::redo() will delete the node through the undo/redo system. In this case, the destructor ~Node() will create another UndoDeleteNode item. So what I was looking for a way to only create the undo item when the undo/redo system is not active, i.e.:

class Node {
public:
  // ...
  ~Node() {
    if (!undoStack()->undoOrRedoRunning()) {
      undoStack()->push(new UndoDeleteNode(this));
    } 
  }
};

I found QUndoStack::isActive(), but isActive() does something completely different. In fact, it looks as if there is no way to tell that the QUndoStack is currently operating. This finally also gets clear by reading the API docs of QUndoStack::push(QUndoCommand* cmd):

[...] Executes cmd by calling its redo() function. [...]

In other words, each QUndoCommand you push on the stack is executed immediately. This obviously is a design decision: Following this paradigm, you should not just call “delete node;” Instead, you should simply create a UndoDeleteNode() instance and push it to the stack. The undo command is then immediately executed by calling redo().

This design has the advantage that developers are forced to go this route. Following this paradigm, you very easily get macro support, since all actions are undo/redo items. This is cool.

However, what I dislike about this approach is the fact that it seems you loose the nice API to simply delete the node. You cannot write “delete node;”. Instead, you have to have some helper class such as a Document, that provides a Document::deleteNode(Node* node) function. This function then just creates a new UndoDeleteNode and pushes it to the stack.

Is this how the QUndoStack is supposed to be used? Does it imply that the destructor should be protected, and UndoDeleteNode must be a friend class of Node, to avoid other classes from just calling delete Node?

In Kate, we indeed go the other way: We have a KateUndoManager::isActive(), which indicates whether the edit actions should be tracked by the undo manager or not…

I’m not yet convinced that the approach of QUndoStack is ultimately cool. To me it looks like I’m forced into some design decision I didn’t want to take. Maybe I’m missing something?

Akademy 2013

So Akademy 2013 is nearing and this time it takes place at Bilbao, Spain. As it happens, Bilbao is located quite near to the beach as well as very close to the mountains. So I stumbled over a page with several hiking trails starting in Bilbao ranging from easy to hard. For instance, this route starts in a nearby village and then goes from about 65 meters in height up to 1000 (this is the point where you stop to hack on KDE, of course), and then down to 30 in Bilbao again. Anyone? :-)

PS: Maybe there are any locals who know the place around and can recommend a hiking track?

 

How to convert pdf to svg

In a project I’m currently working on I need to display the result of TeX code. So I thought it would be nice and accurate to compile the TeX code to produce a pdf, and then use libpoppler-qt4 to draw the pdf. This works in principal, but there is a licensing problem: libpoppler is GPL, and I want to use it in a LGPL library.

So I searched the net and found dvipng, which converts a dvi file to png. It even supports transparent backgrounds. So I could convert the dvi file to png through QProcess+dvipng, and then display the png file. This works, but whenever you scale the canvas the result looks ugly since png is not a vector graphic.

Next, I found pdf2svg that converts a pdf file into the scalable vector graphics format svg. In theory, I then can use QSvgRenderer to load and render the SVG on-the-fly using QSvgRenderer::render(QPainter*, …). So I first tested to convert the pdf to svg with this tool and then view it in InkScape. The result was perfect: InkScape renders the svg file exactly like Okular renders the pdf file:

So I looked into the source code of pdf2svg and saw that it uses libpoppler with Cairo. This reflects an additional dependency on cairo, so I went ahead and converted the cairo based code to Qt, using libpopper-qt4. The code basically boils down to:

// create poppler pdf document
Poppler::Document *document = Poppler::Document::load(args[1]);
document->setRenderBackend(Poppler::Document::ArthurBackend);
document->setRenderHint(Poppler::Document::Antialiasing, true);
document->setRenderHint(Poppler::Document::TextAntialiasing, true);
document->setRenderHint(Poppler::Document::TextHinting, true);
document->setRenderHint(Poppler::Document::TextSlightHinting, true);
document->setPaperColor(Qt::transparent);
// prepare QSvgGenerator as QPaintDevice
QSvgGenerator svgGenerator;
svgGenerator.setResolution(72); // resolution in dpi
svgGenerator.setFileName("out.svg");
svgGenerator.setSize(document->page(0)->pageSize());

// perform painting
QPainter painter(&svgGenerator);
document->page(0)->renderToPainter(&painter);
painter.end();

This code does indeed generate the svg code for the pdf file. However, the result is surprisingly ugly and wrong:

First, the pen seems too thick, and second the character ‘d’ is wrong on the left. I’ve tried changing the resolution (setResolution()) and also the page size (setSize()) of QSvgGenerator, always getting the same result. Searching the net reveals that QSvgGenerator seems to have quite some glitches with respect to WYSIWYG rendering. I tried to use QSvgGenerator before in 2009 and came out with unusable results. Maybe I’m missing something?

Update 1: It’s not QSvgGenerator that is to blame here. It’s indeed the Arthur backend of libpoppler. I send a patch to the poppler developers that fixes the issue with too bold glyphs. The pahts are still too inaccurate, though.

Update2: Using dvisvgm with the option –no-fonts results in an SVG file that QSvgRenderer renders correctly. So this is the current solution to get a TeX document rendered via SVG in Qt.