KDEPIM sprint – KDirModel + friends and QML Calendar

Hi,

Last week we had one hell of a wonderful KDEPIM spring with about 30 people attending. It was my second sprint, and it’s certainly something i will keep attending.

So, what did i do during the sprint? The first day was spend entirely on my pet project of improving the entire file browsing stack in kdelibs. That means:

  • KFileItem
  • KDirModel
  • KDirLister

I’m doing this because the current stack doesn’t scale very well. It works fine for the every day usage, but begins to show it’s limitations when you use massive folders (100.000 till 1 million entries). I know that optimizing for this is “crazy”, but it’s also fun and seems to work really well thus far. The intention here is to have a rewritten stack that is as good as the current stack, but does scale well. Even with millions of files in one folder. However stupid that might be. I’ve rewritten all of the above classes since i wasn’t about to keep backwards compatibility. And rewriting them has the benefit that i can change the structure however i want to do that. The new names are:

  • KDirectoryEntry
  • KDirectory (contains a list of KDirectoryEntry objects for each entry)
  • DirModel (is going to be KDirModelV2)
  • KDirListerV2

KDirectory and KDirectoryEntry vs KFileItem. In terms of memory usage KFileItem was horrible. It was having one full UDSEntry and at least one KUrl. All sucking up memory that really could be used more effectively. I’ve taken a different approach here. KDirectoryEntry (the KFileItem replacement) is not storing a UDSEntry or a KUrl/QUrl anymore. It’s only storing:
QString with only the file name (not the full url)
mode_t with the details that tell what kind of entry this is (file, folder, symlink…)
bool that tells me if i have more information available like file size, permissions and a bunch of other details
FullStatData* pointer that contains the actual detailed data.

The “FullStatData*” pointer is filled based on lazy loading. It’s only filled when the data is actually needed. So that means the KDirectoryEntry object is very small compared to KFileItem and only loads additional data when it’s actually required to see that data. Even when that data is loaded, the memory footprint is massively lower then what you would see if you where using KFileItem. Some numbers will follow later in this post.

KDirectory is a glorified container class. It contains a list of KDirectoryEntry objects and is being spammed by KDirListerV2 with new entries.

KDirListerV2 is the real big dragon in this picture. What KDirListerV2 is basically doing is create a new KDirectory object for every new directory it wants to index. Then it attaches some signals from KIO::listDir and KDirWatch. Besides that it also contains logic to get a KDirectory object based on an “int index” and some logic to get that index. It’s based on int indexes because that makes it very easy to use it in a QAbstractItemModel. Besides KDirWatch (it seems to mark everything as dirty -_-) it works fairly well. No issues thus far anyway.

KDirModelV2 (DirModel) is the real head breaking part of the code. Playing with the QModelIndex, parent and index functions is just pure pain. Just a difficult part in this pet project, but one i will probably get working at some point in time.

Now for a few numbers.
If you would put a KDirModel (with a KDirLister) on a folder with 100.000 entries then you would be using about ~700MB of memory. If you do the exact same thing using KDirModelV2 (with KDirListerV2) then you are only using ~160MB of memory. That’s quite a big improvement. Even more curious is the place where the memory is being used. It “seems” like most of the 160MB is being used in the part that building up the actual UDSEntry list and the part that’s receiving the raw blob data from the respective KIO slave. That’s the only part i haven’t touched! In terms of speed it’s filling the list very rapidly. I haven’t done any numeric benchmarks in that area yet, but visually it certainly seem as fast (or faster) then the current KDirModel + KDirLister approach.

That’s it for that “little” pet project.

QML Calendar
Now this is where the other 2 sprint days where spend. In my last sprint i was already working on the QML Calendar and it was progressing nicely. However, i had a bit of a knowledge gap in how to use QModelIndex and Qt’s models. I’ve been trying very hard to fill that gap in (mainly with the pet project above). At this sprint it was time to take it to the next level. Previously i was trying to access the calendar data through C++ and making it available through C++ in QML. That was working but is not really the way to go forward since other applications could very well benefit of the same things as well.

So we needed QML components! Since John Layt is also having some calendar related wishes it was time to just sit together with a group and discuss each others calendar needs. Tobias, John, Kevin, Andreas, a few others and me sat together during lunch and drafted up an QML Calendar API. I worked that out with Tobias in this wiki page: Calendar API QML. This API consists of two QML components:

  • CalendarData
  • Calendar

The CalendarData component is providing exactly what it’s name implies. “Calendar Data”. You simply put in a date range from which you want to receive data and the types (Events, Holidays.. or nothing which will fetch all types). You then get a model back with a bunch of properties. This properties part is still one of the parts that i have to finish. So what this component allows you to do is – for example – show all todo items for tomorrow. Or all event entries for this month. It’s that easy and that powerful.

The Calendar component is a different beast. That component is meant to show a month overview. All you do is say when to start the overview and which data it should contain. The model will do the rest. A very important thing to remember here is that this component (both components) are just data components. They provide models and won’t show anything. If you combine the two components you can implement the current plasma clock calendar popup in pure QML without a single line of C++. And that is actually my current testcase. A full calendar clock popup applet (what’s the real name of that thing anyway?) in plain QML. Below is a screenshot of how it currently looks. An obvious note: heavily work in progress!

qml_calendar_popup

Just to explain what you see in terms of components. The left part of that image (the actual calendar) is the “Calendar” component from the above mentioned wiki link. The previous and next buttons actually work and are tied to the previous() and next() function in the Calendar component. The colored 4, 5, 6 and 13 are actually colored from actual akonadi calendar data. This is real stuff! I didn’t just give those specific cells the purple color. All cells with any event in them are colored purple.

The right part you see here is the CalendarData component. When you hover a date the data on the right is filled in. This is even more work in progress as you can see.

While this is already very awesome and already allows the clock popup to be fully rewritten in pure QML, this is only the beginning. The idea (John’s idea to be honest) here is to be able to modify and add actual calendar data through QML. Those bits haven’t been written yet, they haven’t even been discussed in depth yet, but the end goal here should be a more interactive calendar where you can just pick a date and add an event as you wish straight from the popup applet. Now that is really tapping into the power of QML and Akonadi.

For the components as they are currently described in the wiki. I aim to have them in KDE 4.11 under the “org.kde.pim.calendar” namespace. I’m also planning to have the calendar popup re-implemented in QML for KDE 4.11. I aim for those, but it could very easily end up being 4.12.

That’s it for my very lengthy blog post. I hope to post some more updates in the coming days regarding my “file browsing stack” rewrite since there is a lot more going on in that area.

Cheers,
Mark

* fixed the API link. The PIM Sprint photo is nice, but the API is the intention here ;)

QClipboard wrapper for QML

Hi,

It’s not the first Qt class that i’m making usable in QML and will certainly not be the last one. Even better would be singleton components because you really don’t want two of these components in one application, something that is possible in Qt5 if i’m correct.

Note: It has been suggested that i make this as a plasma service. I do wonder, what’s the benefit over a component? And how to even make a service? Making this wrapper class is really easy, is it even easier with services? Making this wrapper was really easy and only took a few hours.

Without further delay, here is the “Clipboard” QML component free for you to use however you like.
clipboard.h

And the clipboard.cpp file:

You obviously have to register the class in QML as well. Look in my other posts if you don’t know how to do that.

Now using this class needs a bit of documentation. First, you have to add it to QML which is as simple as adding:

Lets say you want to paste the content of the clipboard. For that i take my Shortcut element as example, look at the following code:

This happens to be an example for CTRL+V (pasting). clip.paste is where the magic happens. All you have to do is provide a location (with the protocol in front of it like “file://”). Then the files that are on the clipboard will be put on that location.

If you want to copy/cut files you have to go through some more trouble. This “trouble” is there because QML doesn’t properly allow arrays to be filled after they have been defined in “property variant someArray”. This has been resolved in Qt 5 where “property var someArray” works just as you would expect from a javascript array.

So, in the above Clipboard QML component you have one function to fill the url: clip.addUrl(file:///your/url/to/anything/). If you have multiple urls you have to add them all – one by one.
clip.addUrl(file:///your/url/to/anything/one)
clip.addUrl(file:///your/url/to/anything/two)
clip.addUrl(file:///your/url/to/anything/three)

Another function you have is clip.urlList() which just spits out your url list. There is no remove/clear/anything else for the url container.
Once you’re done adding url entries you call clip.cut() or clip.copy(), depending on what you want to do. After that point the files (urls actually) will have been placed on the clipboard and the url list will be cleared ready for the next job.

That’s about all there is to know for this wrapper.

Idea: feature based shortcuts outside the main application

Hi,

I wasn’t quite sure how to name this subject so sorry for the slightly vague title.

The case is as follows. I’m right now developing an application in QML for KDE (like the QML Calendar) and i’m finding myself in the position where i need to define application wide shortcuts for certain features/events. Hence the recent posts about application wide shortcuts in QML. Obviously defining the shortcuts inside the application would work (and is currently working just fine) but i was wondering if it can be done differently and perhaps better.

That’s when i got the following idea. Why don’t we – KDE – completely remove all shortcuts from the applications and instead let the applications register their features that could benefit from a shortcut in some global KDE wide “feature to shortcut” manager? In other terms: “apps don’t register shortcuts, but register the features where the user can assign a shortcut to”. Still vague? Here is a more practical example. In this case i’m taking Dolphin as the example since we all know that application.

Lets say that dolphin has no shortcuts in it’s application but rather registers the following features:

  • reload
  • back
  • forward
  • home

Then in KDE there has to be an app that does feature to shortcut translation like so (actually exists and is called Shortcut Manager):

  • refresh
    • F5
  • back
    • Mouse back button
    • backspace
    • alt + left arrow
  • forward
    • Mouse forward button
    • alt + right arrow
  • home
    • home button (some keyboards have that..)

This is how it would look in QML for an app to register the refresh feature and how to use it:

The syntax is roughly the same as my earlier Shortcut {…} component.

So you might think: “why not use a shortcut directly?” and perhaps you even wonder why i’m making this suggestion at all. There are a couple reasons for that.

  1. If the shortcuts are managed from one single point then applications themselves don’t have to bother managing them thus less to worry about.
  2. The most important point is unification. Right now the shortcuts in KDE applications are wildly different between apps. Just look at opening a tab in Konsole and in Dolphin for example. If the shortcuts are all managed from one central place (and  if apps actually obey that) then you will see a perfectly unified shortcut handling throughout KDE apps. CTRL+T will be a new tab in every app then.
  3. It will become a lot easier for users to change default shortcuts since it’s all in one place! So if a user wants to have the refresh feature done by the F12 key rather then the F5 key then it’s just a simple matter of changing it once in the shortcut manager and all apps will obey to the new shortcut.

KDE, as one of the very few desktop environments, has a full featured shortcut manager. Shortcuts can already be managed through the existing KDE Shortcut Manager and the above idea might in fact already be possible to implement (not 100% sure yet).

One downside of all of this is when an application is not developed for KDE specifically but rather Qt only. In that case this suggestion won’t work so there it might be wise to have a fallback mechanism in the above qml that looks like this:

in which case the “FeatureRegistration” component would just be a Shortcut {} component.

What’s your opinion about this idea? Is it worth a try to get in KDE and get all current and future apps in line by using this mechanism? Note: if this is done then the FeatureRegistration will obviously also be a C++ class so that non QML apps can use it as well.

I kinda like this idea. Specially because it could finally tackle the very annoying issue of shortcuts not being unified between applications and it gives developers a very easy way to use shortcuts in a unified manner.

Cheers,
Mark

Update

It might be important to add a small update here. The CTRL+C shortcut is a very interesting one (among a bunch of others). Inside a application that CTRL+C might mean completely different things. For example in dolphin that will copy a file, but in konsole it will abort a running application. So lets think that the Shortcut Manager has this:

  • copy
    • CTRL+C
  • quit_running_app
    • CTRL+C

Now it’s not the shortcut manager that decides CTRL+C will quit your running application with CTRL+C or act as copy command. That’s up to you to decide. This is how it would look in QML for Konsole:

And for dolphin:

I hope that clears up a little confusion. Note that in this case i took strings as “feature” value. If one wants to add a custom shortcut that isn’t registered in the shortcut manager application then just defining the “fallbackShortcut” to whatever key combination the user wants should work as well.

Application wide shortcuts in QML (this time without QShortcut)

Hi,

In my previous post i was using QShortcut to get application wide shortcuts. I didn’t like that route because it depends on QWidget, but i didn’t see any other option back then. After a little bit of discussion on how to get the same stuff working without QShortcut (thus no QWidget dependency) i started trying the same using Qt’s event filter system. That turned out to work rather nice! Because there is no more need for QWidget, the somewhat ugly trick to put the QWidget based mainwindow in a global class isn’t needed anymore. The C++ side looks as follows:

shortcut.cpp

And the header, shortcut.h:

Making it available in QML is done the same way as in the previous post:

The reason that this works is because of the re-implemented eventFilter function. That filter listens for key events and if it finds one (and if that one matches the one we registered) then a signal is emitted to indicate the application that the registered key has been pressed. It’s really that simple. The filter is registered in the class constructor through qApp->installEventFilter(this); That’s all i needed to do to get is working.

In QML it still looks as simple as this:

Right now this is not part of any KDE QML imports, but i do want to try and get this specific component in QML. It will help other applications as well if they happen to need this functionality.

Cheers,
Mark

Update
Updated the code to reflect all the suggestions from the comments. The QML side still works exactly the same, but has an additional signal that will let you know when the key has been changed. Changed! not triggered! That is still a separate signal. Also added a bool: m_keypressAlreadySend in an attempt to prevent double signals which was happening all the time.

Application wide shortcuts using QShortcut in QML!

If you know QML and have worked with it for some thime then you probably say: not possible. QShortcut requires a QWidget thus you cannot use it in QML.

The simple answer is indeed: not possible. The more complex answer is interesting. Yes, it is possible by using a nasty trick! However, it’s only possible if you expose your custom QML “QShortcut” through your main application since you need the widget of your main window. You cannot do the trick that follows in a plain C++ plugin to add some QML components.

So, how did i do this? We obviously need a QWidget in every QShortcut instance so to get that i made a global static singleton class in which i get/set my main window. I set it in the application context and get it in the “QSortcut for QML” context. It looks somewhat like this:

Util.h

That gives you the singleton. Now in the applications main context you have to set it’s main QWidget window. In the case that you are making a QML application you likely have a main that looks somewhat like this:

Note the line i added with: “Util::instance()->setMainWindow(&viewer);”. This works because the viewer object is (deep down the stack) inheriting from QWidget.

That’s all you need to add to your main for now (besides obviously the header for your Util class). Next up is creating the actual QShortcut component for QML. I’m using QShortcut here and not KShortcut. Please do note that KShortcut and QShortcut are completely different! A KShortcut just sets a primary and alternate shortcut which you can then set in a KAction. You can;y set a shortcut and listen for it which you can do in QShortcut. They are just two different beasts which you should not mix up.

QShortcut in QML. I named mine “Shortcut” and the code for it looks as follows (shortcut.h):

As you can see, a very simple clean component. Only a key can be set and a signal for when that key is activated (pressed).
And the source looks like this (shortcut.cpp, this is where the magic happens in one line):

Now the most important line here is the first line (m_shortcut ….). There i’m creating a QShortcut object in which i’m setting my main QWidget (the one i had set in the main file). Without that (little nasty) trick it doesn’t work. I really wish there was a nice way to add application shortcuts in QML, but apparently nobody has ever needed that before because there is just nothing out there that i can find. Yes, QML has the Keys{ … } stuff, but it’s not application wide.

Now all you need to do is expose this “Shortcut” class to QML so you can use it. Open you main.cpp again and simply add it as follows:

You obviously have to include “shortcut.h” in here as well. Now pay attention to the text: “Project” since that will be your import line. In QML to use this Shortcut it looks like this:

And that’s it. It’s that easy and clean! This does come with some notes you should be aware of. Since these shortcuts are application wide you should NOT add a shortcut inside a listview or so. Just make sure you only add them once for your own sake. Another limitation is that you can only set one key as shortcut. You can’t add a modifier or more keys. So a shortcut like CTRL + A isn’t possible in the current code. This however is just something you’d have to implement to make it available. It’s not difficult and the functionality is already there in QShortcut. You just have to make it available in QML. And that exact part is a bit tricky of you want multiple keys to act as one shortcut. Or you could just expose the string based shortcut and you’re done ^_-

That’s it for this hopefully helpful post about application wide shortcuts in QML applications. I hope this comes in handy for those that need it but don’t know how to get there.

Cheers,
Mark

Using Fonts Awesome in QML

Hi,

Today i read this post on the planet and it made me think: “can’t we use that already? It’s just a font..”.

It actually is quite easy to get it working. All you need is QML and the ttf font. This is what you need in QML:

And that’s it. That allows you to use the quite nice monochrome icons. You obviously need to change the location to wherever you downloaded fontawesome-webfont.ttf. Which you can be found in the download package from FontsAwesome.

There are a few things to know here. First, take a look at the available icons. You can’t use the names described in that page. But you can use their unicode key which you can find here. Now if you see an icon that you, for example the “icon-ok”, you type on this page (just using CTRL + F). There you will see that the unicode key for “icon-ok” is: “\f00c“. Putting exactly that in QML won’t work. Unicode keys have to be prefixed with “\u” so in this case you simply add a “u” after the slash and you’re done. The results is: ”\uf00c“.

That’s it. Easy right :)

Cheers,
Mark

Update

Somehow the “FontAwesome.ttf” in the root of the download package from their site isn’t working with the way i described above. You need to use the “fontsawesome-webfont.ttf” which you can find in the “font” folder of that same package.

Update 2

Since some people don’t like putting in unicode values in the text value, which i can perfectly understand, i made a translation array. Save the following as “fontawesome.js”

Now in QML you can use it as follows:

In my case i named the array “fontawesome.js” which i then include in QML as “FontAwesome”. Then in the text part you can use it with FontAresome.Icon.<the icon you want>.

When naming all the icons i went for camelcase with the first char as capital as well. I couldn’t do “icon-ok” because a “-” isn’t allowed in variable names in javascript. Good luck using it!

Add a custom QStringListModel to QML without using setContextProperty.

Hi,

Easy huh? Heh! Not really. It took me quite a lot of trial and error just to figure out that i can’t get it working without setContextProperty. Though i didn’t leave there. I opened a topic about this on the Qt interest mailing list. The example code is as follows:

pathmodel.h

class PathModel : public QStringListModel
{
public:
explicit PathModel(QObject *parent = 0);
};

Then i made a custom “utils” class where i just make some random functionality available. Like so:

util.h
class Util : public QObject
{
Q_OBJECT
public:
….
Q_INVOKABLE PathModel* pathModel();
Q_INVOKABLE QString testString() { return “some_test_text”; }
….
};

Then i have the main file where i create the QML context and load a QML file. Just the default stuff when you make a QML application through QtCreator. It looks like this:

Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));

QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String(“qml/Porpoise/main.qml”));
viewer.showExpanded();

return app->exec();
}

The above helps understanding the context. In the above you can already see that i want to send the Util class to QML. I do that like
so:

Util util;
viewer.rootContext()->setContextProperty(“Util”, &util);

Now in QML i call:
Util.testString()
Reply: “some_test_text”

That is es expected. Nothing wrong.

Now if i call:
Util.pathModel()
Reply: undefined

That surprised me. undefined wasn’t what i was expecting. The solution to get this example working was very kindly provided by Robert Voinea. His exact words:

For QObject-derived classes their properties are exposed to QML and used through the QObject interface.

Also with an example. All that was needed was adding (in util.h below Q_OBJECT):

Q_PROPERTY(QObject* pathModel READ pathModel CONSTANT)

And obviously removing Q_INVOKABLE from the pathModel function.
Then calling it in QML like so:

Util.pathModel <– no “()”
Reply: PathModel(….)

That works like a charm. Using it right now. I am really amazed that this kind of vital information is not easy to find in the Qt documentation.

Oh well, just posting this in here because it will probably save some other folks a lot of time figuring out the same.

Cheers,
Mark

The KDE PIM meeting, just awesome!

Hi,

Last weekend from friday 12th till sunday 15th i attended the KDE PIM meeting in Berlin. I never had attended to any KDE meeting yet and i never went to a place that far away. I went there with a main focus on learning a lot about Akonadi, how it works and what it’s goal actually is. Obviously also to meet the people behind akonadi and just to socialize a bit with people that share a common interest: KDE.

When i arrived in Berlin (Thursday evening) i received a warm welcome from Jos Poortvliet and his wife Camila. They generously allowed me to stay at their house during the kde pim meeting days. On the evening/night before the first meeting day Jos and I had a long discussion about various KDE subjects. Conversations like that are really awesome and that alone is already worth attending a meeting like this! The evening ended with a little code hacking in QML Calendar by hacking up a quick way to tie all my – thus far separate - components in a nice overview. Screenshots of that are below.

The sprint: Day 1

Day one of something that you’ve never done before is always special. The initial plan here was for Jos, Camila and me to go to the meeting together. As you can read between the lines, that didn’t happen. Lets just say that Jos doesn’t like needles which “somehow” resulted me in going alone ^_- I leave that up to him to blog about if he wants to. Traveling to KDAB (where the meeting was taking place) was spacial. I actually took the wrong train the first time. I had to take the S-Bahn too some other station to take the U-Bahn. While i did take the S-Bahn, the number wasn’t 41, it was 8. That issue was easily resolved by getting out on the next station and waiting for number 41. After that the trip went fine and i ended up at KDAB (after asking a few people where “Tempelhofer Ufer 11″ was. You’d be amazed to know that even the locals didn’t know where exactly it was. When i saw the street signs it was just a matter of following the numbers.

Once I arrived at KDAB I finally saw the people behind the IRC names that i had “known” for some time but never saw in person. There they where all sitting: volker, jlayt, krake, afiestas, amantia and a lot more.  Time to shake hands, connect my crappy notebook and start hacking on the thing i wanted to develop further: QML Calendar. Note: I was the only “new” one in there that nobody had ever seen. Fresh blood!

After a little while the actual “knowledge transfer” started. András Mantia, Volker Krause and Kevin Krammer started talking about Akonadi. Men those guys really do know a lot about Akonadi and KDE as a whole. That talk (along with part 2 on day 2) is one of the reasons why you would want to go to a sprint like this. You just don’t get a better explanation like that on paper or even on a video. They really went in deep and told us the details how it was designed, what it’s intended usage is and why it was designed the way it is. And i must say, it’s massive! A lot of information to absorb and those folks really thought it out well. If you want to learn more about any KDE technology you should certainly attend a sprint in which that technology belongs. The guys (and girls) that are also attending are more then happy to share their knowledge when you ask them face to face. Writing it down in mails, wiki pages or things like that just won’t give you as much detail as the live version.

After this talk it was time too let it sink in, grab a coffee and chat with the fellow attendees. The last part of the day was spend restructuring the calendar day view – yet again – to make it reusable for the week view. It wasn’t something i was looking forward to since i had recreated that exact part already about 4 times already (trial and error approach). Yet I’m very happy with the final results. It looks a lot cleaner now and adding the week overview became a no-brainer. I gained complete flexibility there as in how much days i want to show in a week. Something that was rather difficult before.

The sprint: Day 2

The second day had part 2 of the Akonadi system in the morning. Like the first day it was another amazing talk about the Akonadi internals. There was also a big discussion about database backends. Akonadi is mainly used with MySQL and does that job well. Though it has high memory consumption. There where questions about PostgreSQL and SQLite (both also supported by Akonadi) and I’ve been meaning to ask if NoSQL was ever considered. Sadly i completely forgot to ask that since i was a bit overwhelmed by the massive amount of interesting information. NoSQL is probably a stupid idea, but i do keep wondering that. So if someone would like to comment one that?

Then lunch came. I don’t find it useful to talk about food in a blog post, but this one is an exception. When i am in germany i always try out different kinds of meals. The same this time. We went for lunch, got a menu card and as usual i couldn’t pick one. It all seemed nice. So i simply tried the middle one which was something with goat cheese, potatoes and green beans(?) with rhubarb juice as a drink. In my memory rhubarb tasted nice with a lot of sugar and that’s how you where supposed to eat it. This drink was absolutely horrible! Gladly Chani was sitting at the same table and finished my drink. As for the food, I’ve never ever had something that stinking and distasteful ever! My food choice for that day where kinda poor. Oh well, that evening we all ordered pizza and i took a safe choice of a tune fish pizza.

After the (not so nice) lunch we all went back and started hacking again. Each on our own projects. At that point i was figuring out QML with re-parenting. What i wanted to do was move an event from one day to another. Something that is quite common in a calendar to do, but quite hard in QML to get implemented. Specially if you generate everything dynamically. I did get it working rather quickly but had the amazingly frustrating issue that i could only move it once! That turned out to take the rest of the day. Guess what, the fix was – as usual with issues that take long – a simple one liner. I was using a state machine and was setting it to one state but never resetting it’s state. That resulted in the event being able to execute exactly once! Once i figured that out i fixed it and events could be moved across days as well. Yay!

On this day I’ve also had a nice long discussion with John Layt. John is working on ICU support for Qt and is doing an amazing job there – all alone! However, he is also planning on changing the calendar part of the clock applet in KDE to make it more functional. That part obviously gets close to my calendar intentions so the question became if my components – that already look rather nice – are somehow possible to use in there. Since he also wants to use QML for it. Right now that idea is impossible because my components are not stored in a KDE central import position like org.kde.plasma.<folder> are. So here my suggestion was to make my calendar components available under org.kde.calendar. Or perhaps “org.kde.icalendar” to clarify that all the components required to make an calendar based on the icalendar specification can be found in there. That should only have basic components that are icalendar related. So it should have the following for calendar purposes:

  • Day view
  • Month view
  • Year view
  • Events view

And perhaps a few basic filter settings so that you can show the events from a certain calendar. Based on those components you could even make an entire calendar application completely in QML since those components would have the C++ interfacing stuff. This is  a very interesting progressing of what i was doing already and i’m intending to follow this path. That would mean that QML Calendar is really going to be a QML only application. I guess even the first QML only desktop application for KDE.

The sprint: Day 3

There where no events scheduled for day 3. It was just a day full of talking with mainly Georg from kdab. He seemed  quite interested in my calendar attempt and offered to bring me in touch with a usability expert. That link has been made by now, but there isn’t much for him at the moment to help with since there is nearly no user interaction – yet! For now i’m just going to continue developing the calendar application and get back on the usability expert once i have actually something for him to give a usability voice over. Most of this day was just spend talking, waiting in line (for about 1 1/2 hour!) for a kebab store which made very nice kebab and was worth the wait. It’s just in the last ~ 20 minuts of the sprint that i actually wanted to use Akonadi. My project is still a QtCreator project with QMake. Why do i tell that? Well, when i tried to use akonadi in there i ran into a segmentation fault! That one is reported now. So i had to go through some hoops to compile a QMake project under kdevelop. Then something amayzing happened:

Note: Just merely entering this code in QtCreator (2.5.x till at least 2.6.0 RC) will make it crash instantly! Assuming you also added the right includepath for kdepimlibs.

You see how small that code is? That is all you need to show all your calendar events from Akonadi! Isn’t that amazing? I think this is just a stunningly easy way to use Akonadi. This really makes the use of quite complicated KDE technologies very easy for the app developer. As of right now it looks like that will be possible to use in KDE 4.10 in terms of API since the above part is still living in a calendaring branch.

QML Calendar results

Here are the images of how the QML Calendar project looks like at this moment:

This is the day overview. The red area is going to contain the upcoming events. I don’t have anything for that part yet thus i made it red :)

The week overview. Right now it shows 7 days, but as you can see. Also not finished yet since the days themselves are missing.

The month overview didn’t get any love.

The year overview also didn’t get any love.

In the images you also see a row of buttons to change between view. That’s new as well, but still a bit ugly. The components for those buttons are the plasma component ones, i also tested the Qt Desktop components, but to be honest, both component sets simply don’t look nice in a layout like this. I don’t know how i’m going to resolve that issue, but i’m very much leaning towards making real QML Desktop components with the desktop as their intended usecase. Right now that doesn’t exist yet. Not in Qt nor KDE.

Attending sprints

This was my first sprint ever and my first time in Berlin (not that I’ve seen much of it). I have to say that i really liked it. The people are very nice, very helpful and everyone is working on such nice projects for KDE. Like Kevin who is working on a cool looking plasmoid for easy Akonadi control. John Layt is working on ICU and has a very interesting idea on how to improve the calendar that you see in the clock applet. And our photographer (forgot his name, sorry) Martin is working on a very nice QML social plasmoid. Besides that there has been a lot of work done in those few days in fixing bugs in all of Akonadi and improving KMail. More about that can be read in the sprint notes. For me personally it was a very good thing to attend the sprint and i can’t wait for the next one to start in Osnabrück. More people are always welcome, so please do attend if you have the time for it.

I hope you enjoyed reading my blog. It took me quite a while to make such a long one :)

Cheers,
Mark

QML: drag, drop and resize dynamic element – Followup

Hi,

Over a week ago i made this post. Back then i was happy with the results of my QML. However, someone a little bit smarter in QML came by and decided to improve my version. Thanks, Luís Gabriel. That really helped me.

However, it had a small issue. The resize handle was displayed “above” the content. Whereas i wanted it “on top” of the content. That’s minor and i fixed that. So here is the final QML code for that stuff. (actually just making this blog post so that the code snippet doesn’t get lost).

For my usecase it still has a few issues (as in the height of the content should never go below a certain size) but to keep it a simple example the above will do fine.

Cheers,
Mark

QML: drag, drop and resize dynamic element

Hi,

This is not a KDE post, but might help those that are converting KDE plasmoids from C++ to QML.

As i mentioned before, i had a lot of issues making dynamically added elements resizable and drag/droppable. So i started a new QML project to figure out exactly that. It turns out to be quite a challenge and certainly not straightforward. First an image of how it looks.

As you can see, it’s a very basic image. The functionality is as follows. The red rectangle can be used to resize the blue rectangle (vertically only). The red one will turn orange once you start resizing. The blue rectangle will then obviously change in size. By clicking the blue rectangle you can drag it around and drop it anywhere you want. Below is the code and after the code i will share the tricks i had to apply to even get this working.

In order to get this working i had to do some tricks. For instance, you can’t resize a QML element downwards by default so you have to anchor it to something that stays at a certain position, anchor to that item and resizing works both up and down. The way to get that working is a bit tricky. In the code above i’m defining an item with the “positionAnchorHook” id. It’s just an empty item with no size at all yet that item is very important.

Now the thing that happens once you press a red rectangle is the following:

  • First i’m anchoring the “positionAnchorHook” to the bottom of the blue rectangle. That’s just to position the “positionAnchorHook” at the same location as the rectangle. I might as well use X and Y in this case.
  • Right after they are anchored i reset the anchor points of “positionAnchorHook” so that it simply stays where i placed them regardless of what i do next. So what i basically did (with a detour) is setting the X and Y position… While typing this i’m considering of changing it in the code :p
Once you drag the pressed red rectangle (which will become orange) the following happens:
  • Now the bottom of the red rectangle is anchored to the “positionAnchorHook”. Doing this allows me to resize the element up and down till the “positionAnchorHook” y position. If i drop below that position i have the change the anchoring.
  • The height is being calculated based on the “positionAnchorHook” y position and the current mouse y position.
  • I’m also adding the mouse position from where you click in the red rectangle in order to avoid a height jump. (difficult to explain).

At first i was trying to simply use dragging of the red rectangle and binding the blue rectangle to that, but that didn’t really work out nicely.

Dragging the entire blue rectangle does work nicely. You also might notice the listmodel.. That’s done intentionally because that mimics the situation i had in my QML Calendar application.

So there you have it. Dragging/dropping and (vertically only) resizing in QML. It’s quite tricky to figure out how it should all work, so therefore i share the basic version in this blog post.

I hope this saves some others hours if not days of figuring out this stuff. It took me quite some time. I did this because i couldn’t continue my QML Calendar because of those issues. Now that they are fixed i can finally take some steps in there.

Cheers,
Mark

What will QML Calendar have? Progress update, QML issue.

Hi,

In previous posts i completely ignored all things other then the Calendar part, but this app will do a lot more then just calendar stuff. In that regards the name might need to be changed?

QML Calendar will actually use all (or as much as possible) of the KDE KCalCore library. Or in a more abstract manner, QML Calendar will be able to use all of the iCalendar core “objects“. To sum that up:

To-Do

I don’t have any designs ready for adding to-do entries. They probably will be visible in the calendar as well. In time, this will get more clearly defined.

Calendar

This is the one that you’ve probably all seen by now.

Journal

A journal is just attached to any other event (todo, calendar …) that adds the possibility for you to make a longer description. This will obviously be added.

Alarm

Perhaps a bit unknown, but the iCalendar spec also talks about alarms. KCalCore has support for it and i will add it in. The only issue here is that i don’t quite know how to integrate alarms in this application without taking over functionality from KAlarm. On the other hand, it might be time to drop apps that are – in terms of spec – defined in one spec, but in terms of apps divided over multiple apps. So that would mean the QML Calendar is going to take over functionality from KAlarm and also replace that app. This is all unknown and just pure speculation. All i do know for now is that QML Calendar will have the ability to set an alarm like the spec describes. How it will be visually implemented (IF it will be visually implemented) is unknown. More on this as the app is being developed.

Progress Update, QML issue.

There hasn’t been a lot of updated in the public git repository (please note that it’s all highly WIP code! Even proof of concept!), but i am working hard on getting more stuff working. I am however hitting very annoying and hard to fix/workaround QML limitations! I hope that some people on planetkde have some suggestions for me here.

What i’m working on right now is making entered events resizable. In reality that means making an event take longer or shorter. This task alone has a few very difficult QML issues to resolve. One is making resize handles. In QML 2 i could simply use the cursorShape property on 2 new mousearea’s (on anchored to the bottom of the event, one anchored to the top) and that would be it for the visual part. In QML 1 that property simply does not exist so i had to make it through C++. While it’s annoying, it’s fairly easy to do and not an issue anymore. Just a pain to see something that useful in QML 2 while i can’t use it in QML 1. Right now i’m planning to make QML Calendar in QML 1 so that it can be used for KDE 4.x. In time it will be ported to QML 2.

The issue i have right now where i haven’t found a solution yet is when actually increasing/decreasing the height of an event. In a treeview the structure would probably look as follows:
|- root
|- – … lots of stuff
|- – - Flickable — This is where all events in a day are contained.
|- – - – Column — This is where the list for the events is being drawn, NOT the events themselves!
|- – - – Repeater — This is actually putting the events on the right places. This is done dynamically! That’s important to know because they don’t have an ID!
|- – - – …
|- – - – Event .. No ID!
|- – - – - Top mousearea (handle for resizing the event)
|- – - – - Bottom mousearea (handle for resizing the event)
|- – - – …
|- – - – MouseArea — Yes, at the same level of the column with the width/height of the flickable content

Now you see the rough structure that is in place. The actual issue is – as always – with the overlapping mouseareas! The way this works is that i need 2 mouseareas to work. The last MouseArea for the position and the top/bottom one for the pressed state. The last MouseArea has the full width/height of a complete day so i can directly use it’s y position to calculate where something needs to be placed. That works like a charm and nothing is wrong there. The issue is with resizing. If i want to resize the event i need to listen to the top/bottom mousearea which then changes the cursor to a resize shape. That also works, but in order to get that working i have to temporary disable the last mousearea as long as i’m hovering the top/bottom one thus i lose the real positions that i need to use to calculate where the event should be placed (or be resized to). That’s the conflicting issue i have right now where i don’t know any solution yet.

So what i need to have is the mouse y position of the last MouseArea while i’m hovering/listening to the top/bottom mousearea. I can’t use the y position from the top/bottom mousearea since they are relative to their parent and only as high as i make them, which is 5px right now. Also, i don’t seem to have any way of translating the position of that relative mousearea to the last MouseArea. I thought of defining a list of Y positions where resize handles are positioned and checking against that list in the last MouseArea. That would probably work and prevent the sub mouseareas, but would be very easy to contain an error and difficult to make and maintain therefore i didn’t even bother trying that out yet.

Be careful with making suggestions, anything that requires an ID is impossible to use because the events are placed dynamically and thus don’t have an ID. Not my choice, but a QML choice. I rather had ID’s since that would make things a lot less complicated. If you have a suggestion, please do share :)

Cheers
Mark

Questions, Answers and Suggestions about QML Calendar

Hi,

I was expecting positive feedback based on my QML Calendar, but i wasn’t expecting it to be this positive! I guess this is really a subject where users and developers can’t wait till there is a new and modern Calendar. Even though i only have about 11 comments on that post, there are a lot of questions/suggestions in there. I will try to answer them all in this post.

You should definitely come to the next osnabrueck pim meeting ( early 2013 probably ) so we can discuss how to integrate this into kdepim.

Yes, i’d like to be there but there is a “little” issue with the time. I’m expecting to work on the QML Calendar full time starting today! I’m only expecting this endeavour to take ~4 months with some beta releases in between. So 2013 might be a bit late to discuss how it should be implemented if i’m expecting it to be fully working and released by that time.

That all sounds really great. You should try to get hired by Blue Systems.
As for the QML Kontact applications Marco Martin demonstrated a year ago that it’s possible to make a single QML app fit various formfactors. I do not know the details but if even QML code could be shared with the Kontact Touch apps for Plasma Active, it’ll be great. Though even further, maybe the Plasma Desktop Calendar widget could even be the smartphone formfactor QML of QML-KOrganizer.

I’m all open for the Blue Systems suggestion. Though i think it’s best for me to just make this app and continue from there on. As for the multiple form factors. That’s a bit uncertain. As i said earlier, i’m aiming this app for the desktop and desktop alone, i certainly have no intentions to get it working on a mobile device but on the other hand i do want to make it as easy as possible for others to port it to a mobile device. Since i’m – obviously – using QML, porting might be very simple. Right now the application exists of a couple custom QML elements for the day overview, month and year. Those elements can be easily tweaked for mobile devices so a lot of the current GUI can already be reused. Again, i’m focusing on the Desktop now. If others want to make a mobile version i’d certainly encourage that!

Quote: “The reasoning behind that is that if Akonadi ever becomes a framework on it’s own (so only depending on Qt)”

That’s already the case, Akonadi only depends on Qt (QtCore iirc).

Awesome job ! the QML Calendar look hot and your plan look even hotter (to replace current views in Kontact app’s).

Àlex Fiestas wrote that very interesting comment. This means that Akonadi only needs Qt to work thus it would be very interesting for me to make this Calendar only dependent on Akonadi (and Qt). Even though i want it to be a KOrganizer replacement. I’il probably blog about this when i know more.

Wrt the QML calendar: I’d so love to have a better kontact app. It deserves it :)

and

Hi Mark, will it be integrated with Kontact?

First the Calendar, that’s my goal for now. If that turns out nicely and i can somehow get the money to continue working on this then all other Kontact apps are subject of being rewritten. Kontact itself would probably be the last one. For now the QML Calendar will just be standalone. I don’t know about the integration with Kontact. Yes, if i end up rewriting all of Kontact. Probably No if it stays with the Calendar.

Absolutely amazing work! Are you planning on replacing KOrganizer completely? I also mean in terms of integration within the Kontact suite? I think as long as it still integrates with Kontact and KMail :)

Very nice work… and btw: I’m all in for a kickstarter project :)

For your first question, Yes! Without a doubt if it’s up to me. But remember, i’m not the maintainer of Kontact or KOrganizer so i don’t have anything to say about a replacement. However, people that do have anything to say like this so feel free to draw your conclusions :) For the Kontact question, read above. Kickstarter would actually be my last option. I prefer other options first.

 

That’s it for now. More in the coming days.

 

Cheers,
Mark

Introduction and announcing QML Calendar!

Introduction

Hi planetkde, i’m Mark. In the KDE world probably better known as “markg85″. I’ve been using KDE for years now and have occasionally been contributing by means of fixing bugs. Specifically for Dolphin related bugs even though they – 99% of the time – end up being issues that had to be fixed in kdelibs.

I have been working on the following parts which have been commited to KDE and are in it for a while now:

Fixing blur behind tooltips

The fix for this was fairly easy, the issue here is that there are a various tooltip implementations in KDE. I made fixes for Dolphin and System Settings. This did made me realize that the tooltip shape in KDE was something that could be improved. More on that further down in this blog. (Will be visible in KDE 4.9) An older one is the KMix OSD widget. That got fixed a while ago and is visible in KDE since 4.8.

Various improvements for Plasma Components (QML)

When the Plasma Components where just put in git, i simply had to test them out. That immediately gave me some issues with using system icons. Along with a better looking Button. Nothing big in here. (Visible since KDE 4.8)

Dolphin bugs, or so i though.

Invalid Protocol for ftp

This was my very first contribution to KDE. At that point i’ve only had a few months of C++ experience. I certainly was not happy to look into kdelibs or other deeply hidden KDE places. This issue did exactly that. It showed me a bunch of odd corners in KDE. The issue here was that there was an invalid protocol error for accessing ftp while it worked just fine when using ftp://ftp… So in my mind it should be a very easy fix. Looking back at it, it is indeed easy, but only if you know the internal working of KUriFilter and the different filters that are out there.

Make “\\” usable for accessing a samba network (alias for smb://)

Once i used KUirFilter i was wondering why \\servername\ wasn’t working while smb://servername/ was. Where the above issue was a missing filter, this issue was inside the implementation of the KUrlNavigator class where KUrlNavigator::uncommittedUrl wasn’t returning what it should return. I actually took the credit here while i’ve had a lot of help from David Faure to get this one figured out. After fixing this it turned out that there was already a filter for \\ in place. It just never worked. After this fix it all started working.

Only Nepomuk had a caption in Dolphin

This was the first issue that actually did end up being in Dolphin. The issue was that there was no caption for anything besides nepomuk. That was a bit inconsistent so either the caption for nepomuk had to go or the rest should get a caption. That turned out to be quite a nice fix. Right now, if you browse to anything in dolphin, you see that in the title bar.

Others

There are some other fixes i brought in, but thus far the total can still be counted on just 2 hands. Just search for “markg” on git.reviewboard.kde.org and svn.reviewboard.kde.org if you want to see the rest.

It’s only up till a few months ago that i’ve really become active in participating in KDE and am really trying to improve things. I occasionally look through existing review requests and provide my help if i happen to know something. That has also happened a fe times in the mailing lists. Also, I’ve taken on a few big issues in KDE, but each time i try that there seems to be some blocking issue on the road that prevents me to continue. The following also quite big issues but are currently laying dormant on my computer.

QML Tooltips

As i said earlier, the current tooltip shape is a bit… undesirable. There needs to be a tooltip unification where all applications use the same tooltip classes. You might thing that Plasma::TooltipManager is taking on that job, but apparently that is to limiting for Dolphin and System settings to use. I took the job on me to make that class usable for all current KDE applications and make the tooltips themselves in QML. So fat so good, i’ve got tooltips working in QML and they seem to look just fine. However, while using QML i need to have the tooltips as toplevel widgets without decorations. At first i tried using the PlasmaComponents.Dialog element. That works, but has some quirks that prevent me from further using it. So in the end this boils down to making my own tooltip top level widget which is where i am now. It’s lying dormant a bit because i’m working on something else at the moment. To be continued.

More then 2 shortcuts (KAction/QAction)

This one seemed so easy when reading the bug report. Simply adding another shortcut to go back in Dolphin. Yet here we hit a limitation – actually a design flaw – in KAction. KAction can only be used with 2 actions bound to it. Using QAction is not possible. This issue turns out to be an issue that has to be resolved in either KDE Frameworks 5 or in Qt 5.1. The latter means that some KAction specifics merge back in QAction which then becomes usable and KAction can be dropped (optimistic view). I am going to try to get this in Qt 5.1, but that really depends on a lot of things. To be continued.

Improving performance in KSharedDataCache

By now it’s about half a year ago when i started this review request. I haven’t really had the time to get back on it, get it working again and apply the critics from the latest review. Once this review is – finally – done, the performance of KSharedDataCache should be a lot better. Right now i’m also thinking of including MurmurHash3_x64_128 since it’s a _lot_ faster and only the first 64 bits need to be used as key for the hash table. To be continued.

Introduction: QML Calendar

This is what i’ve been working on for the last ~2 months. Making a whole new Calendar application, meant to replace KOrganizer. QML Calendar is meant to use todays Qt techniques (with emphasis on QML), looks modern and appealing to new and existing users and is a Desktop Application, not a website. This application will obviously use KDE’s awesome PIM framework – Akonadi – for fetching and storing Calendar events. I’m not quite sure yet if I want to make this application deeply dependent on KDE or only on Akonadi. The reasoning behind that is that if Akonadi ever becomes a framework on it’s own (so only depending on Qt) then that means that this calendar can be used everywhere where Qt can be used. Also, in that respect i’m not quite sure yet which widgets to use. Qt Desktop components (integrates with KDE’s Oxygen, Gnome, Windows and whatever else is implemented), Plasma Components (KDE only) or my own components to fit the calendar style.. though that would make it inconsistent with other KDE apps. Difficult choices.

In terms of features this Calendar should be on par with KOrganizer, but in terms of usability, looks and feel it should be the better one. Also the new application has a much smaller codebase then KOrganizer has and is much more maintainable due to all of the graphics being done in QML. C++ is only used to fetch the data, prepare it and send it to QML (or send it from QML to C++ to store it in Akonadi).

Here are the first screenshots of this QML Calendar application. The red line is placed at the current time (when i took the screenshot) and actually updates it’s own position once every minute. The areas marked in grey are fetched from C++, but in a very crude “proof of concept” manner (dumping some start and end times in a model) just to get the principle working. Next would be to do the same only with events fetched from Akonadi. Please do note that these are just the screenshots of the separate calendar parts, i still need to make a nice look around this. This is the day overview:

This is the month overview. In here (not visible yet) you should also see your events for that month and as much as fit in the each day. If there are more events then fit in a day it will be a drop down arrow or something else indicating that there are more events in that day then there are visible.

This is the year overview. What’s also not visible in here is that events will be shown in here as well only a little bit differently. Here i will use a color coding from yellow till red. If the background of a day is yellow it means that there is just one or perhaps 2 events in that day. The color will bo more red if there are more events. If you have about 7 events for a day it will be red. Everything higher then that amount of events will just be red.

It’s my goal – as said – to replace KOrganizer with this calendar once it’s done. I don’t want to stop there though. I would like to replace all of KOntact applications (except KMail) with modern applications that meet todays standards. Both in usability, features, design and ease of maintainability for the developers. If that is going to happen i definitely need some kind of sponsorship, donations or perhaps even kickstarter. Taking on something that big must be done in a full time fashion. Just doing that for a few hours a week is not going anywhere fast. For now it stays with the QML Calendar.

At the rate i’m currently working on the calendar i’d estimate it to be done in about 3 – 5 months. The most difficult thus was was having the day view working. It might not seem like much, but placing the day view in a Flickable with a MouseArea on top of it where you can select rows to make a new event is really really really difficult to get working.

Conclusion

So there you have it, what i’ve been doing in KDE for the recent years, what i’m going to do in the coming months and what i’m doing right now. I will post a lot more on planetkde from now on.

Cheers,
Mark