Mark's KDE blog

It’s that TIME again!

Twice a year i’m welcomed by a change in my time. Yes, it’s the stupid Daylight Saving Time. Or rather, it stops and kicks back in at the end of march.

In other terms: Summer time and Winter time. Why we – all of Europe – still even have this time weirdness is beyond me. I would kick summer time out and stay with winter time all year.

Since we don’t have one time yet, i’m stuck to fixing my clock twice a year. This time i saved the commands to do just that and share them with you.

All the commands below should be executed as root user!

First you need to sync your time using this command (you might need to install ntp or ntpdate):
ntpdate pool.ntp.org

This synchronizes your time. However, your hardware clock can still be wrong. Sync your new time to the hardware clock:
hwclock –systohc –localtime

That’s it.
Your time should work properly now. Both on linux and windows.

Natural string sorting, an in depth analysis

Hi KDE folks,

Update: content updated! The blog post has been updated all over the place with proper timings.

Yes, a blog post about natural string sorting was bound to happen. Given that I’ve been playing with that for quite a long time. This post is all about the performance of sorting strings in a way consider natural, but machines don’t.

What does a natural order look like? Here is a small example.
0.txt
1.txt
3.txt

8.txt
9.txt
10.txt
11.txt

You get the point. That is a natural sort order for people. Computers on the other hand don’t think so. When they sort a string they look at each individual character. Looking at numbers in that way causes computers to sort the same example as:

0.txt
1.txt
10.txt
11.txt
3.txt

8.txt
9.txt

See the issue at “10.txt” and “11.txt”. Well, that is caused by looking at individual characters for sorting. How exactly that issue is solved on a technical area is beyond this blog post. If you want, you can investigate the KDE function: KStringHandler::naturalCompare.

Currently in KDE SC 4.xx, more specifically in Dolphin, natural sorting is done using this very nifty function. It works just fine and has been doing so for many years. But it has a downside: it’s not really fast. Usually you don’t bother too much about that since you don’t often sort, right? Well, partly. In KDE’s Dolphin you get sorted results by default. This in turn means that you will notice any slowdowns if the sorting takes more then 100ms (0.1 second). That in turn also depends on the person. I had reported this issue in the Dolphin camp quite a while ago and they “solved” it by implementing a sorting algorithm that runs on multiple cores thus is usually done faster. The KStringHandler::naturalCompare function is still used, just on more cores :)

All this isn’t new. Dolphin developers have done really awesome work in speeding this up and it’s been implemented in dolphin since a couple releases (KDE Applications 4.11?).

This still leaves us with a – in my opinion – slow KStringHandler::naturalCompare. Isn’t there anything we can do to speed it up? Till Qt version 5.1 there was nothing we could do about it. Starting with Qt 5.2 we have two awesome new classes:
QCollator
QCollatorSortKey

QCollator can be seen as a class that you create that sets the rules for comparing strings. So we want for instance numbers to be sorted in a way we like them (10 after 9, not 1). That class allows us to set those rules. Then we can call QCollator::compare with the strings to compare and they would be checked to those rules.

QCollatorSortKey is a bit different. You can ask QCollator (by calling “sortKey(your string)”) to give a pre-computed key that obeys the rules set in QCollator. When you want to compare two string you would then compare the QCollatorSortKey objects for those strings. It adds a bit of extra bookkeeping so you need to wonder if the extra bookkeeping is worth using it. QCollator::compare is very easy after all.

To know for sure i started benchmarking those 3 options:
– Sorting using KStringHandler::naturalCompare
– Sorting using QCollator::compare
– Sorting using QCollatorSortKey

This chart shows the benchmarking results i gathered with those 4 different methods in Qt build with -developer-build, aka debug + something else. Shorter is better.
sorting_benchmark

 

The following chart is gathered with Qt build in release mode and debug symbols added. That’s about the mode you would have (minus the debug symbols) when you install Qt from your distribution.

sorting_revised

A special note for QCollatorSortKey. It is benchmarked with the overhead time of calling QCollator::sortKey and adding additional bookmarking data. In other terms, the timings for QCollatorSortKey are including all overhead! If i where to remove the overhead and just measure the actual sorting time then all it’s timings are cut in half.

Before i started benchmarking i had some ideas about which one would be faster. I was expecting QCollatorSortKey to be the fastest so no surprise for me there. It’s the other two where i’m really surprised.

I was expecting QCollator::compare to beat KStringHandler::naturalCompare since the former is going to replace the later in a KDE Frameworks world. I wasn’t expecting QCollator::compare to be this much slower, rather my expectation was it to be somewhat faster then what we had. Apparently KStringHandler::naturalCompare still has a big reason to be used when looking at the performance numbers.

Another thing i wasn’t expecting was QCollatorSortKey to _always_ be faster then the other two alternatives. I was under the impression that for a few compares QCollator::compare was faster. The documentation even says so, but these benchmarking results clearly show that QCollatorSortKey is just faster (again, with all overhead included!).

Based on the chart we can draw some conclusions.
1. KStringHandler::naturalCompare is far superior to QCollator::compare when it comes to performance.
2. QCollatorSortKey beats everyone.
3. If you never have more then 100 items to sort then it really doesn’t matter which one you take. All 3 options complete the sorting very fast. If this is your case then i would go for ease of coding and go for QCollator::compare. I completely revise this stance based on the new performance numbers. You should consider using KStringHandler::naturalCompare when you need a simple natural string compare method. If you have more time then you should go for QCollatorSortKey. I cannot make up any reason anymore to use QCollator::compare. It’s just not as performant as the alternatives.
4. Do you want your sorting to still be fast with insanely high numbers of items to sort? Go for QCollatorSortKey. For file browsers (hello Dolphin and Accretion) i would always go for QCollatorSortKey.

If you want to repeat these results, here is the code i used. It needs C++11 since i use some C++11 features.

Next up is investigating if this is the most performance we can drag out of QCollatorSortKey. More performance there would mean patches against Qt. So where is the time being spend when we sort in QCollatorSortKey? Surely in std::sort comparing the internal bytes, right? Aka, not much more we can optimize.

To profile this we add a header in the above source file:
#include <valgrind/callgrind.h>

Then we set points from where we want to have profiling. You can replace your doSort function with this one:

Then compile it (obviously in release mode with debug symbols) and run the executable through valgrind with a command like this:
valgrind –tool=callgrind –instr-atstart=no <executable>

This gives you a file named callgrind.out.<somenumber> You should open kcachegrind with that to read it. I don’t know how others do this, but in this case i’m looking at the actual sort function and the sortKey function cost. For both in the deepest level till the line you find the function that Qt is calling that isn’t defined in Qt.
For the actual sorting that is the line:
__memcmp_sse4_1 (at a cost of 5,79% of the total execution time)

For the sortKey that is the function call:
ucol_getSortKey_53 (at a cost of 27,10% of the total execution time)

+ 0,5% of the total running time create our new vector with the sorted strings.

Note: when i say “total running time” i mean the time that is instrumented by valgrind. This is not the total execution time when you start the app.

Now we immediately have a good idea of the performance we get and the actual costs.
Actual costs: 5,79% + 27,10% + 0,5% = 33,39%
Which means that 66,61% is spend in overhead, Checks and whatever else is going on.

First, lets look at the 5,7% of the memcmp.
QCollatorSortKey_profiling

Look at the image. Within the qstrcmp we have 4 things using cpu:
20.5%, QByteArray::constData()
5,79%, __memcmp_sse4_1
3,49%, QByteArray::length()
2,84%, qMin

Remember, every single function that is being called in __memcmp_sse4_1 is called in O(n log n) time. That is a LOT more then O(n). If we just reduce the function calls there we can easily save 20% of the total running cost thus that alone making our sorting 20% faster. The issue is that this function (qstrcmp which calls __memcmp_sse4_1) isn’t wrong at all. It’s just fine for one QByteArray. However, when we have a big list of QByteArray objects then it becomes faster to maintain bookkeeping of the length of all items and the data pointer to them. Which would completely throw away the calls to constData and length at a cost of accessing an array where that same data is stored. It will be faster, but for Qt it’s not worth it. It’s too specific. For us it would be worth it.

Update the above was done with a Qt build that was compiled with “-developer-build”. I was expecting that to be equal to “release with debug symbols”, but it’s equal to “debug with some more” thus giving me a wrong picture when benchmarking and profiling. I let the above in this post because it was the reason for me to try a different approach. However, in -release mode you don’t see any calls to ::constData anymore. It’s a free function call (0 cost) along with other calls that became free in release mode. That’s why in the charts above (the one for the release build) the timings for QCollatorSortKey are down quite significantly between debug and release. However, the above does show potential data locality improvements that can be made. A general rule of thumb when optimising for high speed is to have data as close together as possible.

An even more ideal approach would be for Qt to have a sortKey function that fills a buffer that we provide it. We then maintain everything ourselves which allows for far easier optimisations then to hack in the Qt code. Another big advantage of that approach is that we control the data locality.

As a proof of concept i implemented that ideal approach in Qt. I fear that it won’t be accepted upstream, but i can always try. The diff:

I used the new function in my benchmark and the results are simply stunning as the following graph shows (shorter bars is better). Taken with Qt build in release mode. (+typo of optimized..)

sorting_revised_colkey_optimized

As you can see in the chart, the speedup in the optimised version is always faster, but you won’t notice that if you sort less then 5000 items. Interesting though is the increased performance improvement in the higher sorting numbers. The optimised sorting is about 80% faster then the non optimised version. I’m guessing this is due to data locality which in turn causes for more efficient usage of the CPU cache. And let me stress it again, this is a timing including all bookkeeping overhead! If i would just measure the sorting speed then the 500.000 sort takes just 180 milliseconds aka 0,18 seconds. The vast majority of the time spend right now is in creating the sortKey with roughly 65%. I can probably find faster ways there as well, but i don’t really want to fiddle with ICU internals :)

There you have it, an in depth analysis of how to do natural string sorting. You now know your options and which one is the fastest.

I hope you liked this insanely long blog post. It took me quite some hours to write it.

Cheers,
Mark

PIM Sprint, Calendar progress and Akonadi

Hi,

First of all, a nice picture of all the people attending the the spring 2014 pim sprint.
pim_group_picture_spring_2014

There will be a dot story later outlining what all happened during this sprint. For this blog post i’m merely focusing on what i did.

Optimize akonadi to be faster overall

Yeah, lets start with Akonadi..
tl;dr : I failed at optimizing anything.

The longer story is more interesting though.
While i wasn’t able to profile akonadi and fix or change hot code paths to be either faster or called less often (or both), i was able to identify one massive hot spot in Akonadi.

I will leave the technical details out because they aren’t quite clear to me*, but my (fairly simple) profiling does show me one massive bottleneck that could potentially speed up things quite significantly**. That is quite clear in the following picture:
akonadi_profiling

What you see here is the start of akonadi when it only has one maildir folder (a dump from the kernel mailing list) of about 80.000 mails. The most time is – obviously – being spend in libmysql, but there is also a lof of time that is being spend in creating QSqlQuery objects and query strings. In fact, much of the malloc calls that you see in the screenshot are caused by QString. What you also see is 6.2 million calls to QSqlQuery::value(int). Which is imho way to much for a maildir folder with just 80.000 mails. Mind you, i have nothing else setup so that maildir is all there is.

6.200.000 / 80.000 = 77,5 calls to QSqlQuery::value(int) which is just insane. Next up is further investigate why this is happening and see if there is a way to reduce this significantly. The most calls i would expect to QSqlQuery::value(int) is 10 per mail so that would be ~800.000 calls to QSqlQuery::value(int). Add to that that each mail has 3 akonadi database entries which would raise the theoretical maximum to 2.400.000 max for QSqlQuery::value(int).

Other then that i can’t figure out why it has so many more calls. I am still researching this issue and hope to find some reason why it’s this high. There is most certainly room for optimization here once i know how to handle this code. Right now i just know too little about this part to make a sane conclusion or even go as far as posting a patch. To be continued at some later point.

* disclaimer: i’m tempted to just ignore akonadi and leave that to the people who really know what they’re doing in there. I’m more at home in “using” akonadi classes instead of optimizing the gazillion files behind them.
** This is a profile of akonadiserver which is already quite fast. There is much to win in optimizing it, but it doesn’t have to be optimized.

Finally find a way to draw multiday events in QML (calendar stuff)

During the last PIM sprint it became painfully clear that QML is just not fit for handling multiday events as you know them in KOrganier, Mac Mail and some other mail applications. I gave up the pure QML approach at that time to revise it later (this sprint).

I’ve had the suggestion – quite a few times – to just align rectangles for multiday events in QML. While that is certainly a possibility, it’s not my preferred way of creating it. If you do it in pure QML then you need a _lot_ of javascript glue code to make it work. That in turn will make it more difficult to maintain (since you have lots of code) and will likely be hunting you back later on in terms of performance and scalability. But if you really are interested in how something like that is done in pure QML, then please look at the great length this QingfengCalendar has gone through to make it work. So it can be done.

I’m going for the C++ approach in sending QRect objects to QML which it would read and use in a repeater to place and position Rectangle{} objects. That seems like the easiest approach which is fairly simple from the C++ side. But how do i do that? Well, that’s a question i didn’t know how to answer. That’s where i’ve had some wonderful help of Sergio Martins.

Basically it boils down to this structure:
“CalendarEvents” class
– contains all the events within a given date range.

“EventRectangles” which has a CalendarEvents models as it’s source.
– This class would translate events to QRect objects and an ID to go back to the initial event as it was known in “CalendarEvents”.
– So for an event that is spread over X number of days, you would get an X number of QRect objects.

Implementing this is not that difficult but it requires some time to get it right since you need to re-implement some functions and play with Qt’s very annoying QModelIndex stuff. This class (EventRectangles) then listens to all Additions, insertions and updates that it reveives from the CalendarEvents source model and applies that to the rectangle objects. QML is then simply drawing the rectangles.

I have a very crude prototype of it working, but i need to work on it a bit more to get it working properly.

So that’s a nice bit of progression for this sprint. Not as much as i’d like, but good enough.

On to the frameworks sprint which starts in 20 days. I’m really looking forward to that sprint. Showcasing the current progress of Accretion, discussion my changes for KIO in terms of new classes for file/folder listing and probably more tons of fun stuff.

Cheers,
Mark

PIM Spring Sprint – just 9 more days to sign up

Hi,

You know those cool PIM sprints? The next one is starting at March 28 and ends at the 31st. You can still join this awesome sprint!

If you want to get a refund for your expenses then you have to register on the sprint page [1] within the next 9 days. If you don’t care about that then you can ignore this reminder.

The current list of people attending is a bit low (just 8). I hope the number goes up to about 15.

See you there,
Mark

[1] https://sprints.kde.org/sprint/206

PIM Spring Sprint – March 28 till 31 in Barcelona!

Hi Pim people,

The next PIM sprint is final. Both in date and location.

Date:
28 – 31 March

Location:
Barcelona

The duration of this sprint is slightly different. Usual PIM sprints
are 3 days where people arrive on day 1 and leave on day 3. Leaving an
effective 1 day where everyone is present. This time the sprint is
planned for 4 days with the intention of having 2 full days with
everyone present.

You can find the sprint page here [1]. Please register yourself on
that page if you plan to join.
If you want to reimburse your travel and/or hotel expenses then you
should fill those in before February 28. KDE e.V. will then decide if
your reimbursement is approved.

I’d also like to encourage anyone attending to take a few minutes and
add your points, meeting subject, projects or other related things to
the wiki [2].

I will send one or two reminders before Feb 28 on this list and on planet kde.

Cheers,
Mark

[1] https://sprints.kde.org/sprint/206
[2] http://community.kde.org/KDE_PIM/Meetings/PIM_Spring_2014_meeting

Finally! Shortcuts with mouse support!

Hi,

A while ago there was stuff going on in Qt to extend the current QKeySequence class to include mouse support as well. That would make it trivial for you as a user to create a shortcut like “Ctrl+LeftButton” (LeftButton would be the left mouse button). Sadly, that didn’t happen due to numerous difficulties.

But i was still left with the issue that i want to have shortcuts with potential mouse support so i decided to tidy up a class – named Shortcut – i already had for shortcuts in QML [1, 2] and extend it to have support for keyboard keys + mouse buttons. You can find the code in my “kdirchainrebuild” gitorious repo [1, 2].

If you expose this class to QML then you can use shortcuts on an application wide basis with code like the following snippet:

In that snippet you already see mouse and keyboards keys/buttons. Not mixed though.
The “keys” property binds to a QStringList and can be either a single string or a javascript array of strings. This also allows for multiple keys that have the same action. The above snippet specifically binds the keys:
– (mouse) BackButton
– (keyboard) Alt+Left
– (keyboard) Backspace

which in my case are all used for going back (previous page) in Accretion.
The activated signal (onActivated slot) will then be emitted once (one of the) shortcut sequences has been triggered.

So there you have it. More advanced shortcut handling in a quite small package. Ready for you to use in QML and C++. I kinda hope that this class will find it’s way into plasma desktop 2 for the shortcut handling since that will both allow for more then 2 shortcuts per action and having shortcuts that include mouse buttons.

I do have some possible features where i’m not quite sure if i want to have them in this class or in a more advanced version.
– A flag field allowing you to tell which signals should be emitted. Right now the “activated” signal is emitted once the sequence is “pressed” but there could be value in having a signal for the “release” as well.
– The internal hash for mouse buttons could be made more memory efficient sine this will be one instance per shortcut object.
– I am using a QKeySequence internally because that is the only way i could get this working. It would be ideal if i can get the actual keys from QKeySequence as they are in the Qt::Key enum. This likely requires a change in Qt upstream (in QKeySequence) which isn’t really worth it.

I don’t know if/when i will implement any of the above. For now it works very well as it is :)

Cheers,
Mark

[1] https://gitorious.org/kdirchainrebuild/master/source/utils/shortcut.cpp
[2] https://gitorious.org/kdirchainrebuild/master/source/utils/shortcut.h

Introducing: Accretion! A file browser in QML for the Desktop.

Hi,

I’ve been trying very hard to get this in a shape where i can really show off screenshots. And before the next pim sprint (which starts in just 2 days!). What you’re about to read is from a project that is highly work in progress! It is by no means anywhere near alpha quality. Also the design is not final by any means. The stuff you see in screenshots below is the intended direction, but even here there is a lot still missing.

So far for the little disclaimer.

Accretion, the name

Accretion has a meaning. In astrophysics the meaning is:

The first and most common is the growth of a massive object by gravitationally attracting more matter, typically gaseous matter in an accretion disk.[1] Accretion disks are common around smaller stars or stellar remnants in a close binary or black holes in the centers of spiral galaxies. Some dynamics in the disk are necessary to allow orbiting gas to lose angular momentum and fall onto the central massive object. Occasionally, this can result in stellar surface fusion. (See: Bondi accretion)

The second process is somewhat analogous to the one in atmospheric science. In the nebular theory, accretion refers to the collision and sticking of cooled microscopic dust and ice particles electrostatically, in protoplanetary disks and gas giant protoplanet systems, eventually leading to planetesimals which gravitationally accrete more small particles and other planetesimals.[citation needed]

I picked this name because it seemed very fitting for this project. The rationale behind it is that this project really consists of a lot of different components/classes across languages. Each individual component on it’s own is not doing much, but when you bring them all together – with some glue – you can end up with some really nice applications. That’s why i took this name. It combines KIO, my custom KIO classes (will blog about that soon), exposure of the before in QML, creating custom QML components. Even some javascript though i try to keep that at a bare minimum where possible.

Previously the same project was going be the name: “Porpoise”. That was a small hint at Dolphin since a “Porpose” is a different kind of “Dolphin”. However, that name didn’t really sound right. It looks a lot like “Purpose” and just didn’t work out.

Screenshots!

First is the current default view. The red like row is what you see when you hover any part of a row. This is obviously way different then a default icon view mode that you’re used to. There are a couple of reasons for that which you will find below in the “View plugins” section.

folders_with_hover

This is where things get – technically – very complicated. What you see below is the same view as above only grouped by mime type. Technically each individual group is a QSortFilterProxyModel and that is what made it very complicated. To give you an QML idea, this is a ListView inside a ListView. For more details you’d have to look at the code. Anyway, because every group is a model on it’s own it adds the quite big benefit that you can – if you want – create completely different layouts per group view. So for instance one part can be a detailed list view like you see in the screenshots. Other groups can very well be an icon view or something completely different. You have complete freedom here. If it’s possible in QML then a group can make use of it. Or any view for that matter.

grouping_per_group_order

As i just said, each group can have it’s own layout. But you can also sort each individual group the way you want. I actually implemented this feature because i missed it in Dolphin. What you see below is one group (the one with 6 items) is not sorted. The group below with 10 items is sorted in ascending order based on filesize. But you can click any column name and sort by name or time as well. That is another advantage of using QSortFilterProxyModel, it comes with sorting capabilities for nearly all possible data types that you could use. One note though for natural name sorting. Qt 5.2 includes QCollation which allows for fairly simple natural sorting. That is sadly not taken into account in QSortFilterProxyModel so i have to add that in a subclass. Right now it’s not in yet.

grouping_random_suborder

That’s it for the screenshots.

Model/View abstraction

Some people do “loose” model/view abstraction. As in they might do pre-calculated stuff in the model and expose that to the view to use it directly. I don’t. I try to make everything as abstract as possible and any data that is going to be used in a view will be made available in it’s most rawest form. So for example QDateTime objects and filesizes. Both are exposed to QML as they are. The filesize in bytes. QML – or rather a javascript function – will then convert that human unfriendly size to something humans like more. You can see the result of that specific part in the screenshots above. The same holds true for date stamps although i didn’t made them “human friendly” yet. Remember, this is all heavily work in process!

I try to follow the above principle for every single thing i make. If it doesn’t have a direct need in a class/component it shouldn’t be there.

View plugins

By “View plugins” i mean simple files or packages that can be used as a view like you see in the screenshots above. The model and view are completely separated and that allows for custom views to be written very easily. All views have the same access to model data as the default views has. You can do whatever your fantasy (and QML) allows you to. The view you see in the screenshot is inspired by these awesome mockups. I quite frankly find that one of the only awesome flat ui designs that exist. All current popular operating systems (mobile and desktop) that have a flat UI design are – imho – extremely ugly. The Accretion file browser is – initially – going to have a design inspired by those mockups. However, even that is done in a very easily adjustable way. All style related settings are defined in one big javascript file.

Relation to Dolphin?

Dolphin is actually what inspired me to make this. The way i see it, QML is the (long term) future for the Linux desktop or certainly for KDE when it comes to graphical user interfaces. Dolphin is currently too big to rewrite or to adjust to make a QML frontend. The fact that dolphin has it’s own model/view implementation also makes it near impossible to port dolphin to QML at all.

Before anyone starts to get any ideas for this as a dolphin replacement. That won’t happen or at least not anytime soon. There is a ton of stuff to add to this before it even becomes usable.

Future development

I started this project about a year ago. Not the GUI side, but the C++ side. It’s far from done and needs a lot of time to get where i consider it “working just fine”. Right now it even lacks basic functionality like:

  1. Right mouse button
  2. Settings (even though the icon is there)
  3. Click to open files. Folders work.
  4. Bookmarks
  5. tons more

Besides the obvious i also want to implement some more exotic features that should make it very easy for others to develop plugins for it. Perhaps even to build a community around it.

One of those more exotic features is this. Views themselves are plugins, but i also want to have “View entry” plugins. By that i mean plugins that can modify how an entry looks based on it’s data. This should allow for plugins like svn and git. But it should also be flexible enough to – for instance – transform Accretion to an image viewer for image files with the right plugins installed. How that should be done in a technical abstract way, i don’t know.

Intended platforms

Right now: Linux with KDE is the intended target. In the longer run it should work on Mac and Windows as well. Don’t pin me on it though.

Source

If you want to try this out for yourself then you need to follow a few requirements.

  1. Qt 5.2
  2. KF5
  3. KDirchainRebuild

Once you have those 3, you should get the Accretion source from here. I am not going to support or help you getting this up and running. Much of the above changes on a daily basis anyway.

That’s it for my lengthy post. I hope you like this project, i certainly do!

Next blog: KDirchainRebuild.

Cheers,
Mark

Frameworks porting notice: kDebug and qDebug need to go to qCDebug.

Hi all,

After today’ frameworks meeting we (mostly David Faure and Kai Koehne)
discussed the categorized debugging support that is new in Qt 5.2.

I’ve written a detailed wiki page to layout the current status of
categorized debugging in Qt 5.2 and what we still need (and is coming)
in Qt 5.3. You can find that here [1].

For everyone. If you start a new port then please port the
kDebug/qDebug lines to qCDebug and set a category that makes sense.
Using numbers for the category string is not appreciated! Usually a
category is just the name of the application, library or even the
class if you go very detailed. The wiki [1] also contains an example
for that.

Also, by default when porting to a qCDebug line with a category you
won’t see log output because custom categories have everything
disabled by default. The wiki [1] tells you how to enable it.

Do you spot anything wrong on the wiki link mentioned a couple times
now? Feel free to change it, it’s a wiki after all :)

Cheers,
Mark

[1] http://community.kde.org/Frameworks/Porting_To_qCDebug

QML Calendar – KOrganizer replacement – The status thus far.

Hi,

By now you probably know that i’m that “idiot” that tries to re-create KOrganizer in QML. You might wonder: “Why isn’t it done yet? You’re working on it for about a year now, right?”

Fair questions, but the answer is difficult.

About a year ago i had a working application, it just looked horrible and was made in a hacking fashion because it wasn’t at all certain if the needed data could be exposed from Anokadi to QML. No one really had done that before + the fact that QML was (and still is) very new made it extremely difficult to make something at all. I had to figure things out on my own in the QML world, asking questions was possible but not many people would be able to answer simply because i was playing in an area where knowledge is very sparse and there where just not many people into QML yet. So i wasn’t going anywhere fast and certainly not in an acceptable manner, code wise.

Then came the PIM sprint sprint, early 2013. My initial plan was to have the calendar working and released by that time. As just said, things where going nowhere so we had to come up with “some” grand plan to make calendar data from Akonadi usable for people in QML. The Akonadi structure was close to complete with the “calendaring” branch. During that PIM sprint we decided on a QML API for accessing PIM data. I had a lot of great help wrapping my mind around some odd proxy wrapping stuff to fetch the actual required data from Akonadi. By now that is known as “QML Calendar Components” and can be found here [1].

That PIM sprint was vital! I now had an easy way to fetch the data i want to have from Akonadi. Even though this is far from finished. Right now it still lacks:
– Todo events (easy to implement)
– Journal events (easy to implement)
– Update existing events through QML (started implementing it, editing some values is already possible)
– Create new events through QML (not implemented yet)

In fact, the components as they are there [1] right now is how Heena Mahour used them during the last GSoC. And quite successful i might say! She has rewritten the clock popup applet (the popup you see when you click the KDE clock) in QML using those components.

The fact that Heena was successful at creating that using “my” components means that a graphical KOrganizer replacement can now finally be written, or not?! As in representing the data, it’s a definitive yes! However, manipulating the data or adding new entries still remains a big hurdle left to tackle.

Then we still have QtQuick itself. When i made my first proof of concept – over a year ago – i could very easily conclude that QtQuick itself just wasn’t ready to draw the complicated features that a calendar needs. In this area things didn’t improve much. I will still have to do massive hacking to show an event in a ListView. However, things did improve greatly! It’s now very easy (without wrapper/glue) code to change your mouse pointer (resize handles come to mind) and to make proper use of the available space using the new QtQuick Layout components that are in Qt since 5.1. But that is it as well, it will be “less hacky” then a year ago, but still very hacky. I can’t really blame Qt for that. A calendar is an odd beast with non common elements. Don’t even bother asking about events that spawn multiple days. It’s extremely tricky to display that in a week view in QtQuick. It’s the most challenging issue i have at this moment for this project.

All of the above is the justification for the lack of finished “QML Calendar” application. However, things are changing quite rapidly at this moment. I started re-creating the calendar with Qt 5.1 (QtQuick 2.1) and it’s progressing very fast and nice. I’m not going to make promises, but i should have it working like a year ago only with the new calendar components and Qt 5.1. Stay tuned for more status updates since i plan on posting them more often from now on.

Regards,
Mark

[1] calendar_components

Update: a completely unrelated update. Some people asked me to do something about the comment box since it was sometimes impossible to reply at all. Turns out that the WYSIWYG comment box was done by Crayon – the syntax highlighter plugin – where i apparently screwed a setting up. That is fixed now and you have the plain old comment box back. Which is how i wanted it anyway.

Another reminder for the KDE PIM autumn sprint!

Hi,

By now you must be getting somewhat annoyed by the KDE pim sprint reminders. It’s all for a good cause :)

If you want to get a refund for your expenses then you have to register on the sprint page [1] before October 1st. If you don’t care about that then you can ignore the reminder part of this post.

The thing that amazes me in this sprint is the number of people that are going to attend. The sprint page lists 19 while writing this post and 2 more will be attending, but haven’t signed up on that page yet. That makes a total of 21. Hardly a small sprint for the “usual” small autumn edition! That’s awesome!

I’ll be there from Nov 14 – 19 (crappy flight dates from the Netherlands).

See you there,
Mark

[1] https://sprints.kde.org/sprint/158

Reminder: register from the KDE PIM autumn sprint!

Quote from Dan Vratil:

===============================================================

A friendly reminder that deadline for requesting travel and/or accommodation
sponsorship from e.V. is in 6 days, on October 1st, so please register on
sprints.kde.org if you haven’t done so yet.

Also if you want to have your accommodation arranged by organizers, please fill
it in sprints.kde.org until the same date, so that I can book the hotel as
soon as possible.

Looking forward to see you all

Cheers,
Dan

===============================================================

KDE PIM Autumn sprint, please register!

Hi folks,

The doodle results pointed very clearly at the middle of November as
the ideal time for the next PIM sprint. So that is official now.
November 15 – 17 is set.

Daniel Vrátil very generously offered the sprint to take place at the
RedHat office in Brno (Czech republic). I happily accepted that so
that’s where the sprint is going to take place.

The sprint page has been created [1] and everyone planning to join is
invited to subscribe on that page. If you want to be able to reimburse
[3] your traveling and hotel costs then you have to provide those
costs before October the 1st of 2013.

You are also invited to fill in the stuff you want to work on (or
discuss) at the sprint on this [2] wiki page.

I will post this on planetkde as well and will post reminders once
every 4 weeks.

Regards,
Mark

[1] https://sprints.kde.org/sprint/158
[2] http://community.kde.org/KDE_PIM/Meetings/PIM_Autumn_2013_meeting
[3] KDE e.V. will have to give an OK on the costs to reimburse.

PIM Autumn sprint searches for host in Germany

Hi,

The next PIM sprint, planned to take place somewhere in november, is still searching for organisations willing to host us.
The requirements are:

  • Host at least the number of people planning to attend (16 at this moment)
  • High preference for the weekend of November 15 till 17

More dates can be found here.

Besides this request we also have 2 very generous offers already:

  • In Spain at BlueSystems but that can only allow up to 15 people. There’s too little room for more.
  • In the Czech Republic at RedHat which can host as many people as want to attend.

While both offers are awesome, it does likely add quite a bit of additional traveling costs as most PIM hackers are living in Germany. Hence the preference for Germany and this post for searching hosts in Germany.

If you have a possible location that fits the requirements and is in Germany then please contact me. You can do so by commenting on this post, finding me on irc (markg85 in #akonadi and #kde-devel) or by sending me an email directly at markg85 at gmail dot com

I plan on finalizing both the weekend and the location for the sprint in this month so that leaves us only one more week at most. I don’t want to drag this out into September because that might be getting to close for some people to organize their own schedules in attending the sprint.

Regards,
Mark

Organizing the next KDE PIM sprint!

Hey folks,

It’s that time of the year again for a new PIM sprint. I’ve been there the last two times now and it’s just one amazing bunch of people coming together and making massive progression in what they like doing most.

This time it’s the first time i’m not only attending the sprint but am also organizing it! Quite scarry as well :)

If you want to attend the sprint then please fill in your availability in this doodle link and keep an eye on the pim-devel mailing list.

Regards,
Mark

QML Drag/drop support is about to become a lot better, accepting external drop events!

Hi,

Up until this very moment the QML drag/drop support is kinda limited. You can only use it within the app’s context. Not many know, but “Chris Meyer” is currently working on this issue and has already send a patch:

Add support for external drag and drop in Quick items.

Add startExternal and mimeData to Drag item to enable external drags.

Call startExternal to change from internal drag to external drag with
mimeData specified in the mimeData property as mime-type / data pairs.

Allow DropArea to receive and process external data.

Introduced new variable containsDrag to QQuickDropAreaPrivate. This
replaces mimeData which was previously being used to determine if a
drop operation was currently occurring. The problem was that mimeData
was being externally destructed.

Also introduced accessor methods for getting color, html, image, text,
and urls out of the drop. This facilitates dropping of external data of
those types onto a DropArea.

Task-number: QTBUG-27498

Change-Id: Icd172a5380e0f86d8011a164ce0a461ee5763cb5

It seems to be targeted for Qt 5.0.x so i guess this will end up in the next patch releases of both Qt 5.0.x and 5.1.x. So why am i posting this? This is – imho – the last remaining bit that prevented QML from being truly useful for desktop applications. With this in place along with all of the other awesome Qt 5.1.x goodies, QML is finally mature enough to really serve desktop applications without much (or any) additional hacks.

Oke, it still needs to have stock clipboard support, but that is already fairly simple to implement yourself.

Regards,
Mark

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