This week I’ll present you part of the technologies used in the brand new Konqueror bookmarks system. I’ll explaining how they work and how I’m going to use them, thereby showing part of the design of the new bookmarks model at the same time. Finally, I’ll also show you what’s the current development state and what I plan to do for next week.
Nepomuk is where I will store Konqueror bookmarks. It’s very easy to do so. In my code, I only need the following code to create a bookmark in Nepomuk and put it in a bookmark folder:
kdeBookmark.addTitle("KDE main site");
That’s it! This line of code will create the bookmark in the Nepomuk database if it wasn’t already there, set the title of the bookmark, and it will add the bookmark to the Konqueror’s root bookmark folder. After executing that code, if I can search in Krunner for kde.org, and the Nepomuk runner will find the bookmark. And any application who wishes to list the bookmarks in the root bookmark folder can do so with the following bit of code:
QList bookmarks = folder.containsBookmarks();
UHm..what if I wanted to remove a bookmark from Nepomuk? I can do so every easily too by just calling to bookmark.remove();. It also allows me to attach a lot more information related to a bookmark of course. All kinds of resources and properties can be attached to a Nepomuk bookmark: tag, creation time, whatever. All in all, Nepomuk stand for an easy to use semantic database.
Akonadi is a convenient way to access data stored elsewhere. It isn’t designed to store the data itself, because it’s a middle layer between the application and the data. It gives power to the develop by providing an abstraction layer in which all the data is represented by collections and items in a tree similar to the concept of dirs and files in a filesystem.
A Collection is made up of other subcollections and items. And of course, there is a root collection to rule them all, master of the puppets. To clasify the data, both collections and items have one or more mimetypes attached to them. For example, a collection has the mimetype Collection::mimetype(), but it can also have the mimetype “application/x-vnd.kde.konqbookmark” which is the one I’m using right now for Konqueror bookmarks.
Now a bit more talk about the items. You guessed it, the items can have some data attached to them, but how? Using payloads. A payload is a supported Akonadi class that stores some data. It could be an email, or in my case, a bookmark. I don’t use directly Nepomuk::Bookmark (but I could if I wanted), but a wrapper class that I called KonqBookmark.
When one application request the KonqBookmark payload of a bookmark item, that data needs to go from the akonadi server process to the application process. This is done serializing the data in the server and deserializing it in the other side. As KonqBookmark is not a natively supported class by akonadi, I have to give Akonadi a class that serializes it, and then it works.
An application connected to Akonadi can add new items to a Collection, modify them, delete them. Same with collections: they can be addd/modified/removed. Imagine I’ve got two instances running of my bookmarks editor. If I remove in instance 1 a boomark item via Akonadi, Akonadi itself updates instance 2 of the bookmark editor and shows there that item is gone. Without me needing to do anything! No need to sync via d-bus, etc. It’s like magic, but one that really works.
So far, we’ve got Collections and items in the Akonadi server.. but how? where do they come from? They come from Akonadi agents, concretely from an Akonadi resource. An Akonadi resource provides a set of collections and their items. I’ve created the Konqueror bookmarks resource that adds some collections of bookmarks to Akonadi. But you could add for example a new bookmarks resource different from mine using the same mimetype as me, and provide access to a del.ici.us collections. You just need to code for the resource the part in which you access to the del.ici.us bookmarks and create the correspondent collections and items in Akonadi.
Akonadi is a middle layer, it doesn’t really stores the data. Thus, the bookmarks resource I’m developing stores the data in Nepomuk, as I explained earlier. If you create a del.ici.us resource as I said in the previous paragraph, you could access your del.ici.us bookmarks but they wouldn’t be the same as those stored in nepomuk. A new kind of akonadi agent comes to the rescue: Akonadi feeders. You could create a del.ici.us feeder instead for konqueror bookmarks, and then when a new Konqueror bookmark is added, it would also be feeded to del.ici.us, etc.
And what if I’ve added a bookmark when I was offline? what happens there? Akonadi then caches the bookmark, and it would be added to del.ici.us when you connect to Internet. This is transparent to the del.ici.us feeder: it only needs to have a function to add bookmarks to del.ici.us, and Akonadi will simply call it when it’s appropiate. Again, it’s like magic.
So far, I’ve got an Akonadi resource which can list bookmarks in the Nepomuk database, add new bookmarks, modify them, remove them. The bookmark items use a KonqBookmark class payload, which is supported by Akonadi as payload because I’ve also implemented a KonqBookmark serializer/deserializer.
I’ve created a sample application using this resource, a bookmarks editor, which you can see in the screenshot below (I promised you would get one this time😉. This bookmarks organizer shows you the bookmark folders and bookmarks as usual, using two views: a tree of bookmark folders and a listing of bookmarks.
The application itself is very simple, because it uses model-view & delegate classes for displaying and editing bookmarks and bookmark folders. Some of these classes are provided by Akonadi (the model for Bookmarks collection for example), and I developed the other classes, like the model and delegate for Konqueror bookmarks.
I’m developing all this in the most reusable way so that other web browser that wish to share with Konqueror the bookmarks system can do it very easily. I remind all those curious people that the code is available in github.
Next week, I plan to improve both the editor and the resource. I also want to start playing with Akonadi virtual collections for doing searches in the bookmarks too, and maybe I start doing some tests with Kcompletion stuff for the new location bar. Have a nice day!