» tagged pages
» logout

sorted by: recent | see : popular
Content Tagged with Qt + trolltech

Coding tip; pretty-printing enum values.

I’ve been in computers too long, whenever someone talks to me about error codes I think about the very old MacOs releases, or even longer ago the Amiga crash codes.
But I’m afraid you see them still, a dialog giving a very helpful “sorry, error 1234 happened”.

Now, anyone that is a coder knows how difficult it is to handle each and every error with a properly written error message. Preferrably one that actually makes sense to the user. And realistically speaking this tends not to happen. But before now the effect was typically to have useless messages like the above, or use some hacks that might get out of date on refactorings.
If you look at Qt there are several classes that have an error state; QNetworkReply is one of them. This error state is an enum and in C++ enums really are just integers.
In Qt we allow an enum to be more than just a set of integers using the Q_ENUMS macro. The direct benefit for you is that you can use introspection (/reflection) to get the string value of an enum.

So, no more excuses for just printing an integer error message, you can at least print the more readable enum value. Which means that technical people that don’t have the API docs for Qt handy can still figure out what went wrong.

Here is the code to do this;

QNetworkReply::NetworkError error;
error = fetchStuff();
if (error != QNetworkReply::NoError) {
    QString errorValue;
    QMetaObject meta = QNetworkReply::staticMetaObject;
    for (int i=0; i 

In Qt every class that has the Q_OBJECT macro will automatically have a static member “staticMetaObject” of the type QMetaObject. You can then find all sorts of cool things like the properties, signals, slots and indeed enums.

Happy hacking )

Trolltech: Trolltech Labs Blogs

Qtextended.org!

Along with the rebranding of Qtopia to Qt Extended, comes a new url - Qtextended.org! It will take place of qtopia.net (which should soon take you to qtextended.org)

You can use this new site for downloading Qt Extended open source releases, snapshot packages, SDK’s and flash image files. You can post your Qt Extended applications for download, as well.

There is a forum you can speak your mind, or you can even join the irc chat!

The new Qt Extended 4.4.1 release is there now, as well as a flash image for the Openmoko Freerunner. We are still working on getting an SDK for the Neo’s. Heck, there might even be some flash images for some Internet Tablets soon…

Qt Extended sports some new features, including dynamic rotation, webkit with an example browser, a GPS API named QtopiaWhereAbouts, GTalk chat and presence!

Trolltech: Trolltech Labs Blogs

Native file dialogs in GNOME

One of the few remaining complaints against Qt applications using QGtkStyle on GNOME have been about the file dialog. So far it certainly looked like a GTK+ dialog, but it was not exactly the same dialog that other applications had been using. While I’m not really in a position to comment on which dialog is the better one, this is what it currently looks like with QGtkStyle:

Gtk dialog with Qt

However, the policy on other platforms such as Windows and Mac OS X has been to use the native dialogs if possible. I recently applied some patches to support this for GTK+ as well. This is what you will see if you open forms in Designer now:

Gtk dialog with Qt

Note that since the KDE file dialog provides somewhat different functionality from the Qt one, KDE applications will still use the KDE file dialog. Feel free to try it out directly from the svn on my labs page and report whatever issues you might find here.

Trolltech: Trolltech Labs Blogs

Qt Extended

Well, now. The news is out, I can finally talk openly about this. Qtopia has been renamed Qt Extended!

There are new logos in the gui formerly known as Qtopia. Qtopia.net will be rebranded in the very near future, once the dust settles from the main web sites redesign.

Qt Software and Nokia are still committed to releasing Qt and Qt Extended under the GPL as open source, and will continue to do so. There will be an Openmoko Neo1973 and Freerunner SDK, as well as some really great devices in the future.

This all means that Qtopia^WQt Extended will use Qt! oh wait, it already does!

As a personal side note. I have now been working for Trolltech and been living in Australia for 5 years. There has been many changes in the organization and in Qt and Qtopia. Changes in my job from Qtopia Community Liasion to Software Engineer. There have also been great changes in my life as well. My 3 year old son has an Australian accent, but uses US English words such as ‘wrench’ not spanner (HA! much to the chagrin of his granddad) and to the dismay of his mother, ‘mom’.

Changes are a part of life and what make it exciting. The Open Source community has nothing to fear by this name change, or by Nokia buying Trolltech.

What is means is this: Qt Everywhere! Long live Qt! (Still pronounced as ‘kute’)

Trolltech: Trolltech Labs Blogs

Qt cuter than before: 4.4.3

Less than two weeks after the last release, we publish a new release of Qt: 4.4.3 is out. The reason for this, I mentioned then: Qt is now copyright Nokia Corporation. So we make a new release with the new copyright.

But… we wouldn’t waste your time with just legalese, would we?

No, we take this opportunity to launch our cool new website with our new brand:

Qt new logo

(which are are © 2008 Nokia Corporation and/or its subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation in Finland and/or other countries worldwide.)

The 4.4.3 version of Qt comes with the new logos.

We also got a pinball machine installed. Well, kinda. You be the judge:

Pinball

In other news, Qt has now switched to Git. Here are some pictures to prove:

Lars and Simon   Sysadmins
Lars and Simon asking sysadmins to turn Perforce support off   System administrators making Qt in Perforce read-only

Perforce has served us extremely well for 10 years. And it’s still better than many other solutions out there (including Subversion). But as we grow, we need to improve our tools. And like I explained before, we feel Git matches our model better.

Trolltech: Trolltech Labs Blogs

It’s getting cold

Today was the Autumn Equinox in the Northern Hemisphere (and Spring in the South). That means Summer is over and Autumn has started.

That means for us here in Oslo that we need to start to wear three layers of clothing when we go outside instead of just two (sweater over T-shirt), we can see the moist from our nose breathing, temperatures in the single-digit degrees (Celsius), etc. Pretty soon now we’ll set our clocks back one hour and the snow will come.

Interestingly, we’re also nearing feature freeze. The feature set for Qt 4.5 is coming together and the last features are being integrated this week. That’s why you won’t see Qt snapshots for the next week: we are adding code, cleaning up, and generally breaking Qt.

Also, like I said last week, we’re preparing Qt for the transition to Nokia. That means we have to change all of the copyright headers in Qt, reset the license texts, change the documentation, etc.

For those reasons, we prefer to finish our work before we publish it. We’ll bring snapshots back soon next week.

In the meantime, please enjoy the blogs about features being integrated.

Trolltech: Trolltech Labs Blogs

Sorry guys…

Sorry guys…

I know you have spent a lot of money on buying faster machines to get Qt to run fast enough for the software you are creating, but I’m now sad to inform you that Qt won’t make full use of these machines. In fact it will use your CPU a little bit less.

Jokes aside… We’ve been running a few optimizations internally, under the code name “Qt Falcon” (its going to make Qt fly!), and I wanted to share some of the current results. These things are not yet integrated into Qt Main, but they should be in place by the time Qt 4.5 goes Tech Preview.

Personally I sit on Windows for most of my daily work, so the benchmarks are from a Windows XP machine, and during the falcon initiative we did take the time to iron out a few things that has bothered us with the windows code paths along the way. Windows uses a software rendering engine, internally referred to as the “Raster Engine”. This is also the engine used for embedded and QImage drawing on X11 and Mac.

Lets start at the beginning, QPainter::begin(), a function that is called at the start of every single paint event in the history of Qt. When we originally designed the paint engines, we aimed at them being shared amongst different instances of the same subclass. e.g. all QWidget painting was done using a single paint engine. For this reason, we put most of the initialization logic into QPaintEngine::begin(), because the actual device changed all the time. With the introduction of the backingstore in 4.2 all widgets are actually being drawn to the same device so this begin() initialization started to make less sense, but the design stayed. With 4.5, we make raster engines be one per image and one per backingstore. The initialization is done outside of begin(), in the constructor if you can believe that.

On Windows, we also checked, in QRasterPaintEngine::begin(), if the system had switched its cleartype settings since the last time. This check was actually costing ~25% of the call to QPainter::begin() (ouch!). By listening for the system event when the users changes the settings instead of polling the value in the registry, we could kill those 25% and also support the feature that Qt switches cleartype when the user press “Apply” in the control panel, which we previously didn’t do.

A comparison of a plain QPainter::begin() / end() looks like this:

begin_end.png

The graph shows, in microseconds, the time to create a QPainter on a device and call end on it

We had a fair idea that save / restore was very costly when clipping was enabled in the 4.4. Part of the reason for this is that the communication between QPainter / QPaintEngine was done via a flat state update. A restore was performed by replaying the previous stack element, so if you consider the case of

p.setClipRect(rect1, Qt::ReplaceClip);
p.scale(2, 2);
p.setClipRect(rect2, Qt::IntersectClip);
p.rotate(10);
p.setClipRect(rect3, Qt::IntersectClip);
p.save();
p.drawStuff();
p.restore();

In the last line, restore(), QPainter would replay three clip operations to the underlying engine. Horrible you may think, and it is a piece of code that has been troubling me since I wrote it in the early 4.0 days. With Falcon, the engines can be made aware of QPainters stack, making it possible to cache the results on each level. That means that restore() becomes just a stack pop(). The results look like this:

save_restore.png

The graph shows, in microseconds, the time it takes to run save, followed by a state change, followed by restore

Another Windows thing that had bugged me for a while is the text drawing. Two separate things came together in QRasterPaintEngine::drawTextItem() as a bit of a mess. Again, I’m much to blame and the code has been troubling me for some time, but I didn’t have time to get back and fix these things. Until now, anyway… Point one, was that the only way to draw nice fonts on windows is using GDI, it does (in my opinion, I know people disagree ;) ) the nicest font rendering of all the systems, so using FreeType or another method would not be acceptable visually, as Qt would look worse than other apps on the platform. So we had to mix GDI and our own raster engine together to do clipping, textured / gradient text. The other point is that any pixel touched by GDI will have 0 as its alpha channel. The raster engine relies on premultiplied alpha so this basically destroys all rendering done afterwards. *sigh*

The solution to the two was to use GDI to render into a buffer and sample the values back into the raster engines buffer and at the same time patching the alpha channel. For cleartype this was even worse as the separate buffer first needed to be filled with the background (cleartype pixels depend on the background as well as the foreground). It ran “ok”, but it we were quite aware of that it could be done better. With Falcon, we introduce a mask-texture for each font engine, which generates the glyphs once using GDI. The approach supports both normal and cleartype text drawing and the cleartype approach even does the full RGB blend with Gamma correction (thanks to Samuel who spent an entire day with me to get the gamma correction of three-component alphablending proper). The speedups are quite noticeable. The results are measured in milliseconds:

text_windows.png

The graph shows, in milliseconds, the time it takes to draw the text “abcdefg” on a QPixmap using the default font with either cleartype or non-cleartype

We also removed some of the overhead of drawPixmap() on the raster engine. The problem was that there was a bit of set-up before we could get into the actual pixel-by-pixel blending. Instead of going through the generic rendering pipeline, we introduced a faster path for unclipped pixmaps (or pixmaps that fit inside a rectangular clip). I won’t bore you with the details, as this blog is already twice as long as I intended it to be. The results for 4.4 and Falcon fall together and become identically, speed wise, at around 200×200, but for the icon-size pixmap drawing, there is quite a visible difference.

draw_pixmap.png

The graph shows, in microseconds, how long time it takes to draw a QPixmap, solid or semi-transparent, at the specified sizes

What I’ve mentioned above, are a bunch of separate small things, and you may be thinking that how does this affect me in the real-world. You probably don’t do for-loops of begin/end() or save/restore. So I’ll finish up with some real-world examples. The numbers below are taken from a benchmark of a few widgets where we simply run “repaint()” a bunch of times. The QLabel numbers don’t have much relation to QComboBox etc, so don’t pay too much attention to that, but rather how each widget changes from 4.4 to Falcon.

overall.png

The graph shows, in milliseconds, how long repaint of a few widgets take

Now, much of the overall speedup here, probably over 50% of it is caused by some awesome work that Bjørn Erik has done in the backingstore. The rest is due to small things here and there, like the ones mentioned above.

There has been quite a bit of refactoring in the works here, and some work is still ahead of us, (like re-enabling GDI based glyph-generation of transformed text, which will be vector path based in the upcoming TP) but I hope that the changes we’ve made will benefit most users and that those that see problems with the new approaches let us know so we can look at those too.

Cheers!

Trolltech: Trolltech Labs Blogs

Cocoa News and Views

Hey!

We here at Qt Software are busy working on all sorts of stuff. Things are moving forward though. For example, I took the plunge and integrated the Cocoa port into the “main” branch over the weekend. It’s a massive undertaking to do a submit that touches many files and get everything working. In the end, it was only something in the UNIX print dialog that didn’t take (probably because of a bad merge from a while back).

Anyway, it’s in main now and should be part of the snapshots. Run configure -help to find out how to turn it on since its not the default.

Otherwise, I’m working on my presentations for DevDays. If you are looking for a chance to corner me and talk about the Cocoa port, you’d be hard pressed to find a better opportunity than at DevDays.

Back to the grind! -)

Trolltech: Trolltech Labs Blogs

Repeat after me: the release is not out until I blog about it

I said it before, and before. I hope you know the chant by now: Qt 4.4.2 is now released.

It’s almost weird to release 4.4.2, for two reasons: first, we’re so deep into Qt 4.5 work that it seems like the past when we go to 4.4 again. And second, because this release went smoothly, unlike 4.4.0 (really, really big release) and 4.4.1 (Summer got in the way).

I have to tell you, though: this is the last Qt release that Trolltech ASA will do…

(more…)

Trolltech: Trolltech Labs Blogs

XSL-T and Qt


A couple of weeks ago, I merged the development branch for XSL-T into our main line, heading for Qt 4.5. The idea is that Qt will carry an XSL-T 2.0 implementation with as usual being cross-platform, having solid documentation, and easy of use.

Using it is should straightforward. Either on the command line:

xmlpatterns yourStylesheet.xsl yourInputDocument -param myParam=myValue

Or using the C++ API[1]:

QXmlQuery myQuery(QXmlQuery::XSLT20);
myQuery.bindVariable("myParam", QVariant("myValue");
myQuery.setQuery("http://example.com/myStylesheet.xsl");
QFile out("outFile.xml");
out.open(QIODevice::WriteOnly);

myQuery.evaluateTo(&out);

See the documentation for the QXmlQuery class on the overloads available for setQuery() and evaluateTo(), for instance.

However, due to the beast XSL-T 2.0 is — I agree that it’s larger than XQuery — we’ve decided to do this according to the “release early release often” approach. The first, in Qt 4.5, will carry a subset, and subsequently be complemented in Qt 4.6. The current status is documented in the main page for the QtXmlPatterns module, which can be viewed in the documentation snapshot.

Therefore, while the current implementation probably falls short on more complex applications(such as Docbook XSL), it can run simpler things, users can plan ahead, and we trolls can receive feedback on what features/APIs that are missing, and what needs focus. So feel free to do that: send a mail to qt-bugs@trolltech.com, or say hello on IRC(FransE, on Free Node).

The code is accessible through the Qt snapshots.

What is XSL-T anyway?

XSL-T is a programming language for transforming XML into XML, HTML or text. Some implementations,  such as QtXmlPatterns or Saxon, provides mechanisms to map XML to other data sources and hence widens the scope of the language by letting the XML act as an abstract interface. Wikipedia has a good article on XSL-T. Version 2.0 of XSL-T extends the language heavily by putting a rigid type system and data model in the backbone, and adds many features that was a pain to miss when programming in XSL-T 1.0. XSL-T 2.0 use XPath 2.0, and shares the same large function library as XQuery.

1.

Over time, Java bindings through QtJambi and ECMAScript bindings through QtScript, will likely arrive.

Trolltech: Trolltech Labs Blogs

QGtkStyle now part of Qt

QGtkStyle made it’s way into the Qt snapshots this week, meaning it will become part of the Qt 4.5 release. Technical users can already compile and use it on their own desktop, but once Qt 4.5 is out it will simply replace Cleanlooks as the default application style Qt uses on GNOME desktops. While I haven’t blogged about it since the announcement back in May, a lot of fixes and improvements have gone into it since then and I’d like to thank everybody contributing bug reports, suggestions and patches to the project so far. Since the existing plugin based on Qt 4.4 seems rather popular and not everybody feel comfortable using an unstable version of Qt, I will continue to maintain it as a separate project and accept bug reports over at my google code page.

Clearlooks dialogglider theme

In other news, the nice folks over at the Qt4 Maemo garage have been adapting QGtkStyle to work nicely with the Maemo platform as was evidenced by lorn’s post last month. Samuel also blogged about using Freetype for subpixel filtering which should eventually take care of any differences in font rendering between Qt and GTK.

Trolltech: Trolltech Labs Blogs

Code portability

Today I was reminded of this great TV show that ran when I grew up; it was Hannibal saying “I love it when a plan comes together”.

In this show you often saw the various people on the team do completely separate and often just weird things and in the end you saw how the result could be combined to be a really cool thing. I felt a bit like that today because today Marijn blogged about a big milestone. He managed to get various applications from KOffice running natively on the Nokia n810, a Maemo device.

And this has been a team effort, for sure. The fact that you can use the exact same sourcecode to now run this office suite without code changes on Windows, Macintosh, Solaris, Linux and indeed an embedded device like the Maemo is because there has been an amazing framework we can depend on. Almost all of it available open source. As KOffice itself is as well.
Just for getting a mental picture here, we are talking about having the Linux Kernel, the window system, Qt naturally, KDELibs and last KOffice.

So today I would like to say Thank You to the people that regularly compile and fix issues on all of these platforms. This goes to the people working on Qt but much more really to the people doing the same for KDE and KOffice. You Rock!

Trolltech: Trolltech Labs Blogs

Subpixel antialiasing on X11

The last week I looked at some issues regarding Qt’s font rendering on X11, triggered by some bug reports comparing Qt 4’s font rendering to Qt 3’s and GTK’s font rendering, specifically when subpixel antialiasing is enabled. When rendering fonts with subpixel antialiasing Qt asks Freetype to render into an alpha mask that is three times wider than the desired glyph size (or taller in the case of a vertical LCD display). We then convert this alpha mask into an ARGB mask based on subpixel ordering and a smoothing filter. The smoothing filter is necessary to avoid color fringes; without it the glyphs would look like this:

Text without smoothing filter

With the default Qt 4 smoothing filter the fonts instead look like this (slight improvement, don’t you think?):

Text with smoothing filter

After doing some digging I found out that we changed the smoothing filter in the transition from Qt 3 to Qt 4 to use an interpixel as opposed to intrapixel filter. Interpixel means we do the smoothing on the subpixels directly, ignoring pixel boundaries, which is arguably more correct from a technical perspective. However, since Qt 4 was released, Freetype has added support for doing subpixel rendering and filtering itself, along with several settings for which filter to use. In Qt 4.5 we will use Freetype’s filtering if available, and thus honor the lcdfilter setting in font config. Note that the filtering we use in Qt 4.4 and earlier is pretty much the same as Freetype’s default filtering, but unlike before we now also support the other filtering settings. For Qt 4.5 we’ve also fixed an issue where we’d ignore the “slight” and “medium” hinting options in font config, leaving only “full” or “none” as the real options.

One of our goals was to make Qt 4 applications with QGtkStyle have the same font rendering as native GNOME applications, but apparently there’s a known issue in GNOME/Cairo/GTK that makes Cairo use the legacy filter as soon as medium or full hinting is enabled in the GNOME font settings dialog: https://bugs.launchpad.net/ubuntu/+source/fontconfig/+bug/200707

Gnome font settings dialog - hinting

As the legacy smoothing filter looks really ugly with certain fonts and/or slight hinting there is no way we want to use it by default in Qt, but if you really want Qt 4’s fonts to be rendered as in Qt 3, you can enable the legacy subpixel filtering as described on http://johan.kiviniemi.name/blag/2008/01/12/ubuntu-hardy-fonts/ (note it seems you might have to use the value “legacy” or “lcdlegacy” instead of “lcdfilterlegacy” depending on your system). Note that this can cause severe color fringes with certain fonts, while making other fonts crisper. This is how the font above looks with the legacy filter and full hinting:

Text with legacy smoothing filter

With the “slight” hinting option however it turns quite ugly (note the color fringes):

Text with legacy smoothing filter and slight hinting

To sum up, in Qt 4.5 we should honor more of the font config settings, including lcd filter and hinting style. However, unless you explicitly change the LCD filter or hinting style things should look basically the same as in Qt 4.4. By tweaking the LCD filter and hinting settings it should be possible to get Qt applications with QGtkStyle to look even closer to native on GNOME, though hopefully the configuration issues on GNOME will be fixed eventually and you won’t have to change anything to achieve this. We could of course try to mimic GNOME’s behavior in Qt, but as long as there are open issues regarding this in Gtk/Cairo it doesn’t make sense to change Qt’s behavior.

Note: all the screenshots in this article were taken on an LCD monitor with horizontal RGB subpixel ordering, and will probably look quite ugly on other display types.

Trolltech: Trolltech Labs Blogs

Workflow and switching to Git, part 2: The tools

In the first part of this blog, I discussed a bit the change process and the development process we’re aiming for.

It’s interesting to realise that we’re going through the same process both in KDE and Qt. It’s also interesting that it’s happening at the same time for both — well, slightly ahead for Qt. That’s not, however, a coincidence.

I read a comment on the dot article about opposing a VCS switch every two years. Well, we’re not switching just for the fun of switching. We’re doing it because there are many compelling reasons to do so. (Also, it’s been over 3 years since the Subversion switch, about 4 since we started seriously considering it; Trolltech has been using Perforce for almost 9 years)

And it’s happening now because the DVCS tools have matured enough that we can migrate massive repositories into it. The Qt repository right now has about 170,000 commits and is over 900 MB in size (in Git, well packed). And the KDE repositories I imported had 79404, 71892, 60182 commits for kdelibs, kdebase and koffice, respectively.

And because the old processes and tools have become outdated. And, finally, because we’re people and we talk -) (that is, exchange of experience and opinions)

Switching to Git

So far I have not approached the second part of my blog title. There’s a very good reason for that: most of what we want to do, the workflow we want to introduce, does not depend on any specific tool. There are feature requirements that many tools do not fulfill, but many do fit the bill.

So why Git, in specific?

We had a lengthy process internally at Trolltech trying to decide whether we should switch to a DVCS and, if so, which tool it should be. That was a very interesting process, but one that would deserve an entire blog on the subject. We had a restricted set at the beginning, but only two serious contenders at the end: Git and Mercurial.

At one point, we came up with a list of what were the criteria we were going to use to make the decision. And then we took a look at which criteria were showstoppers. At the end of the process, there was a clear winner.

The most important criteria in that decision were:

  • Quality of the conversion process (from Perforce)
  • In-house knowledge of the tool
  • Ability of the tool to support our proposed workflow

While the latter criterion was a tie between Mercurial and Git, the first two is where there was a clear winner.

(Disclaimer: there were other reasons, with a varying degree of importance, including some where Git lost to Mercurial)

And if you look at it, those are the exact same criteria that are of importance to KDE now. Sure, there are other tools that also do the job, but who’s going to do the conversion? Who’s going to support and help the developers who aren’t familiar with the tool?

For close to a year now, we’ve had the kde-scm-interest mailing list, whose mandate is to propose a plan to convert from Subversion to another VCS (or Source Control Management - SCM) and how the layout and workflow would be with this tool. Which VCS, it’s not specified. Any is welcome, barring CVS (we’re not going back), Subversion (it’s not conversion if we stay where we are) and solutions that aren’t Free and Open Source.

If you inspect the archives, you’ll see that there’s only one contender. So far, anyways. Others are more than welcome to join and repeat the process for other tools. But mind you: you’re a year behind schedule.

This weekend, I finished converting the KDE Subversion repository into Git. The process created no less than 493 different repositories: I decided that each application in extragear, kdereview, kdesupport or playground should get its own repository. There will be more when I run it again.

The process isn’t correct yet. There are definite import errors found: for instance, Thomas Zander inspected the the KOffice repository and realised that several branches were missing. What’s more, I still have a few ideas to do copy-with-history, which means preserving correctly the moves in SVN. Many of our projects originated in the old kdenonbeta, which I didn’t import.

I am forced to realise that Git isn’t completely ready for us yet. I’ve been using Git for well over a year now and I can see it improving build after build. 1.6.0 is very nice, but not there yet. So I ask the Git developer community: how do we handle 493 separate but related repositories? Mind you, we want to maintain the ability to build them all with very simple commands.

So, while Git is by no means decided for KDE — well advanced, I’d say — it is decided for Qt. We have kickstarted the process to completely switch to Git. Very soon now, we’ll be in the final leg of that process and will hopefully have some news on it. Our goal is to stop using Perforce for Qt 4.5 by October 1st.

Trolltech: Trolltech Labs Blogs

Workflow and switching to Git, part 1: Processes

You know that with the Title I chose for this blog, I could be talking about Qt or about KDE. It’s ambiguous… -)

Yesterday, the dot had an article about a new development process for KDE that requires the use of a Decentralised Version Control System (DVCS for short). Believe me if you will, I had nothing to do with that article: I had not talked to Jos before he published it and I even admit to not attending the talks at Akademy on the subject.

But it was a pleasant surprise to read it.

Resistance to change

I’ve been discussing the switch to a different VCS for KDE and for Qt for over a year now. I’ve met a lot of resistance and the article on the dot was no different. There’s a lot of people who oppose the idea.

There’s always resistance to change. People don’t do it out of malice. Quite to the contrary, they do it because resistance to change is a natural reaction. It’s a way of your body and your mind letting you know you’re exiting your comfort zone. And that’s a natural human reaction. Brides and grooms having cold feet the morning of their wedding wouldn’t be a cliché otherwise: they’re about to make a life-changing decision.

Really, look back to all your life-changing decisions and events in your life (gradual changes don’t count). How many of those did you jump into with two feet ahead? Not many, you’ll agree. Marrying, getting a new job, moving to another city or country, for example, are all life-changing decisions. Incidentally, I’ve moved between countries 4 times already and only one of them (the last one) was with two feet ahead: it was when I decided to come back to Trolltech in Norway.

So the resistance we’re seeing now in the KDE community and inside the Trolltech (a.k.a. Qt Software in Nokia) developer community is natural. Some of the criticism is based on technical issues that have to be addressed, most is only fear that has to be managed.

In fact, there’s a whole profession on that, which is called Change Management.

New workflow

The article on the dot discussed the development process where “It’s always Summer in trunk”. I don’t know who coined that expression, but it’s a nice one. I think it appeared in the KDE circle in a blog by Sebastian Kügler: he asked the question “What if we never froze trunk?”

I was part of the discussions that led to that question, when we were discussing where Phonon would live. With my Qt hat on, I was asking for anywhere where “there’s no freeze when TT developers are working on development.

In his blog and in the article, Sebas and others are advocating this idea. It’s something we already do for Qt’s development: the mainline of development never freezes. The feature freezes are preceded by a branching. In KDE terms, it would be equivalent of branches/KDE/4.1 branching off trunk/KDE just before the feature freeze.

That’s fine by itself, but you need the proper tools to pull it off. Remember that you’re going to work extensively with two branches. To give you an idea of the work involved, from the moment that Qt 4.4 branched off the mainline until today, there were 7744 commits into the Qt 4.4 branch (2771 of which after 4.4.0) and 9768 in the mainline (that includes the 4.4 ones). Whereas in KDELibs, there were 3783 commits to trunk since the 4.0 branch, but only 590 into the 4.0 branch since the same point. That’s approximately the same time period.

But the workflow goes beyond “It’s always Summer in trunk” (we’re already there with Qt and I said this blog is both about KDE and Qt). It’s about doing most of the development — which is where most of regressions occur, potentially — in separate branches. More than that, it’s about maintaining an ultra-stable branch somewhere.

If development is where “hot” is, then I’d say that actually “It’s always Spring in trunk”. We don’t want trunk to overheat — even economists say overheated economies are bad (cf. China). We want it to be a self-sustaining exothermic process. Like Spring, there should be periods where it cools down a bit more, there should be periods where it’s warmer than usual.

(I could also have chosen Autumn, but I thought Spring made my analogy look nicer)

Finally, we want developers to feel like experimenting without fear of breaking stuff. We want developers to freely collaborate with each other. And we want new developers to feel readily welcome, not second-class citizens. Granted, obtaining a KDE SVN account is rather easy, compared to many projects out there. But I’ve heard from many new Qt employees who felt like their first commits were very daunting. It was my case too.

Trolltech: Trolltech Labs Blogs

Data Bindings

Been having some fun this week trying to add support for data bindings to Qt Script, and now I have something that seems to work. This code shows the basic usage:

QScriptEngine engine;
QPushButton button;
QScriptValue scriptButton = engine.newQObject(&button);
engine.evaluate("x = 'foo'");
scriptButton.setProperty("text", "x", QScriptValue::DataBinding);

This will cause the button’s text property to be updated whenever the script variable x changes, either from C++ (QScriptValue::setProperty()) or from
script. QObject properties can be part of the binding expression as well, as long as the NOTIFY attribute is specified in the Q_PROPERTY definition. Qt Script will discover that the property has a signal associated with it and use it to track changes. Qt’s classes already use NOTIFY for some properties (e.g. QLabel::text).

Below is a small example. The text property of a label is bound to the text property of a lineedit and the script variable verb; the final value is made by concatenating the lineedit’s text, the verb and a string literal.

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget win;
    QVBoxLayout *vbox = new QVBoxLayout(&win);
    QLineEdit *lineEdit = new QLineEdit();
    QLabel *label = new QLabel();
    label->setStyleSheet("font-size: 24px");
    vbox->addWidget(lineEdit);
    vbox->addWidget(label);

    QScriptEngine engine;
    QScriptEngineDebugger debugger;
    debugger.attachTo(&engine);
    vbox->addWidget(debugger.widget(QScriptEngineDebugger::ConsoleWidget));

    QScriptValue scriptLineEdit = engine.newQObject(lineEdit);
    engine.globalObject().setProperty("lineEdit", scriptLineEdit);
    QScriptValue scriptLabel = engine.newQObject(label);
    engine.globalObject().setProperty("label", scriptLabel);

    engine.evaluate("verb = 'smack'");
    scriptLabel.setProperty("text", "lineEdit.text + ' ' + verb + 's you!'", QScriptValue::DataBinding);

    win.show();

    return app.exec();
}

The result, after typing something into the lineedit and assigning something to verb:

Qt Script data binding example

I’ve also added an extension to QScriptClass that enables you to send property change notifications for custom (non-QObject-based) script objects, i.e. you can use your own notify mechanism.

As I said, this isn’t in Qt yet, it’s just an experiment, but it’s looking pretty interesting.

Trolltech: Trolltech Labs Blogs

Qt 4 on maemo

I love Qt, which is one reason I work for Trolltech^WQtsoftware in Nokia. and thanks to the efforts of the qt4 on maemo project Maemo Qt4, there is yet another platform/device open to any application that is created with Qt4.

gutenbrowser on maemo

Here is my old-yet-updated Gutenbrowser project on Maemo on n810. (the copyright on gutenbrowser is 1998-2008! now). I don’t work on it as much as it needs. Especially now with rug rats and yard apes about.

All it took was a recompile!

Just install the scratchbox sdk for maemo. Grab the qt4 for Maemo sources, compile, install them, and your good to go! hmmm… what’s next?

Trolltech: Trolltech Labs Blogs

Unifying JavaScript Argument-passing Styles

At Akademy (which was a great event by the way!) I had an interesting talk with Pino (the man with Okular vision 8-) ) about an almost equally interesting feature of the Adobe Acrobat JavaScript API. Quoting the reference:

Many of the JavaScript methods provided by Acrobat accept either a list of arguments, as is customary in JavaScript, or a single object argument with properties that contain the arguments. For example, these two calls are equivalent:

app.alert("Acrobat Multimedia", 3);

app.alert( { cMsg: "Acrobat Multimedia", nIcon: 3 } );

The second form uses JavaScript’s object literal syntax to provide arguments in a declarative style, which can make for more readable code, and relieves the script author of having to worry about the order of arguments. However, it does present a new challenge to the implementer of the API: Does he have to implement every function twice now, once per argument-passing style?

Short answer: No (and that’s the honest truth). Long answer: Read on.

What we’ll do is wrap a proxy function around the function that implements the API; the job of the proxy is to detect which particular argument-passing style is used in an invocation, and call the real function using a single argument-passing style regardless (i.e. convert the object literal to a list or vice versa). Essentially we are building our own little type system on top of barebones JS. Sure, this means that some additional glue code has to be written for initializing the JS bindings, and there will be a slight overhead involved with calling a public API function, but I believe in most cases that’s a small price to pay, considering the alternative. The solution presented works on a per-function basis anyway, so you don’t have to use it for everything.

I’ve written a small JavaScript function, called argumentative(), that does the work; you can download it here. To use it, you first prepare your own “private” implementations of the API in whatever call-style you wish, for example list-style:

function __alert(msg, icon, type, title, doc, checkbox)
{
    // For now we just dump the arguments, a real implementation
    // would display a message box.
    print("msg:", msg, "icon:", icon, "type:", type);
    print("title:", title, "doc:", doc, "checkbox:", checkbox);
}

Then you call argumentative(), passing it your function, and an array of argument descriptors. argumentative() will return a proxy function, which is the function you actually want to expose to script authors (i.e. your public API).

alert = argumentative(__alert,
    [ { name: 'cMsg', type: String },
      { name: 'nIcon', type: Number, defaultValue: 0 },
      { name: 'nType', type: Number, defaultValue: 0 },
      { name: 'cTitle', type: String, defaultValue: 'Adobe Acrobat' },
      { name: 'oDoc', type: Object, optional: true },
      { name: 'oCheckbox', type: Object, optional: true,
        properties: [ { name: 'cMsg', type: String, defaultValue: 'Do not show this message again' },
                          { name: 'bInitialValue', type: Boolean, defaultValue: false } ]
      }
    ]);

The purpose of the name property of an argument descriptor should be obvious. The type property is optional; if it is specified, the proxy function will check that the actual argument is of the specified type before invoking your function; this means you can potentially get rid of a lot of type checks in your own code. (The type-checking approach is inspired by John Resig’s strict() function, found in his book “Pro JavaScript Techniques”.) The defaultValue property is optional; if it is specified, its value will be used if the argument is missing in a call. Descriptors for object-based types can additionally specify a properties property, which is just another array of argument descriptors; the proxy function will recursively validate the properties of the object, and substitute in default values if appropriate, before calling your function.

Anyway, now the script author can either do:

alert("my message", 1, 2, "my title", null, { cMsg: "check", bInitialValue: false } );

or

alert( { cMsg: "my message", nIcon: 1, nType: 2, cTitle: "my title",
          oDoc: null, oCheckbox: { cMsg: "check", bInitialValue: false } } );

To your implementation, the two calls will appear identical. (By the way, the argumentative() function lets you control which style you want to receive the arguments in; if you pass 1 as the third argument, your function will receive arguments single-argument-object style, instead of as a list.) If the script author does this:

alert();
alert( { } );

in both cases he will get an error saying that the cMsg argument is missing, as expected. Similarly, if he does this:

alert( { cMsg: "my message", oCheckbox: { cMsg: "check", bInitialValue: "ciao" } } );

he will get an error saying that the argument oCheckbox.bInitialValue has the wrong type.

In the case of the Adobe JS bindings, the argumentative() function could also easily be augmented to support the special acrohelp argument (in which case the function should return a list of its own arguments, rather than call the real function); the function proxy already has all the information it needs.

OK, now for the Qt Script-related part (I almost forgot this is a Qt blog). Most, if not all, JS API functions like those for Acrobat (including alert()) have to be implemented as native functions. So how can you take advantage of the argumentative() functionality in this case? It’s actually pretty simple, as demonstrated by the following C++ snippet:

QScriptEngine engine;
/* evaluate argumentative.js
 ... ... */

QScriptValue descriptors = engine.evaluate(/* the same array of descriptors defined in an earlier snippet */);
QScriptValue fun = engine.newFunction(alert); // alert is a function pointer
QScriptValue proxy = eng.evaluate("argumentative")
                    .call(QScriptValue(), QScriptValueList() << fun << descriptors);
engine.globalObject().setProperty("alert", proxy); // install the public API function

The full example can be downloaded here; it’s a partial implemention of the alert() function using a proper Qt message box, and shows that the native function works the same regardless of which argument-passing style the script uses.

Trolltech: Trolltech Labs Blogs

font anatomy

For the last 5 years a huge focus of my work has been on fonts and text. You know you went to far when you can tell the difference between a Helvetica and an Arial by just looking at the printed ‘a’.
Its unsurprising that people end up asking me what the difference is between leading and linespacing, why the customer claims we don’t do kerning for that specific font, why WYSIWYG actually fails for most people. I naturally can’t be because I’m the only one stupid enough to claim to know this, right?
I considered claiming ignorance, but then my weird behavior may no longer have any reason, so that would just make me a worse freak. Instead I just wrote an application that shows everyone how text works. And I’ll write a blog or two about what you can see on screen and how that relates to your questions even before you have them. Genius or what?
So, here is an example text;
fontanatomy1.png
let me quickly go over the different parts. In red we have the outline, this is the total amount of space that the text takes. This is what is reserved in your user interface for the text. The sizes you see on the right hand side are the major anatomical dividers of a font face. Much like your body has a head and legs (I’m making assumptions about that, work with me). The baseline is the only one that is really interesting to point out. it’s the zero-point for a font. All measurements start from there. So you have a part that’s above and a part that’s below the baseline. I’ll leave it to your imagination to mirror that to your own anatomy.
In blue we have the size taken by the individual characters. But when we are talking about fonts we actually should be talking about glyphs. There are subtle differences, but I won’t bore you with that. Each glyph has its own rectangle as you can see in the blue. This is useful to see since the m is wider than the j, which is useful to know since you position the characters next to each other. The blue little gradients are helpers (called bearings) to position the glyphs better so they visually look more pleasing.

Ok, with the basics behind you here are a bit more interesting things; consider the two following screenshots.
fontanatomy2.pngfontanatomy3.png

The only difference is that kerning is turned on for the first and turned off for the second. Notice how the blue boxes overlap in the first image and how they are simply placed side by side in the second.
In general you want kerning to be turned on, its on by default in Qt because it increases readability.

Last example; this one is tricky.
fontanatomy4.pngfontanatomy5.png
Fonts are designed in a way that they can be scaled and reused for any size. Which is a pretty neat idea since it avoids using a crystal ball to figure out which sizes to ship your font in. There is a little problem, though. A font that is printed on paper at 10cm per character needs a lot of detail but if you use the same character at on screen at just a couple of millimeters height, you have problems to make that one look good.
So, font makers ship something called ‘hints’. Which make their fonts look better at smaller sizes then the computer could do automatically. This is enabled per default and is practically speaking exactly what you want.
Except for one problem; if you add all those little adjustments they can add up. So much that if you have a sentence you can have a word that fits just fine when you show the font on screen, but if you then take the same width and same text but on paper, those little adjustments may just move a word to the next line.
In other words; hinting gets in the way of what you see is what you get text-layout. So, in Qt you can turn this off. Allowing you to get the exact same line-breakings on screen as you get on paper.
Look at the following two screenshots. You will see a little spacing between the little blue squares in the one where the hinting is turned off. We call this mode ‘designer metrics’.
if you want to play around with this stuff yourself, here you can find the sources;

svn checkout svn://labs.trolltech.com/svn/graphics/fontAnatomy

For the people that are still here, thanks for sharing the pain! And I’ll answer the question of “why should I care!”. The concepts shown in this blog have good support in Qt4. The point to take home is that the font is the one that specifies all the information. If the font doesn’t have kerning, game over. If the font has horrible sizing information, you are out of luck. With this little tool at least you can see the differences that different fonts make.

Trolltech: Trolltech Labs Blogs

Fun with D-Bus at Akademy

To summarize my achievement at Akademy:

[Argument: a{sv} {"a" = [Variant(int): 1], "b" = [Variant(QByteArray): {99}], "c" = [Variant(QString): "b"], "d" = [Variant(uint): 42], "date" = [Variant: [Argument: (iii) 1977, 1, 1]], "datetime" = [Variant: [Argument: ((iii)(iiii)i) [Argument: (iii) 0, 0, 0],[Argument: (iiii) 8, 59, 31, 0], 0]], "dtlist" = [Variant: [Argument: a((iii)(iiii)i) {[Argument: ((iii)(iiii)i) [Argument: (iii) 0, 0, 0], [Argument: (iiii) -1, -1, -1, -1], 0], [Argument: ((iii)(iiii)i) [Argument: (iii) 1977, 9, 13], [Argument: (iiii) 0, 0, 0, 0], 0], [Argument: ((iii)(iiii)i) [Argument: (iii) 2006, 6, 18], [Argument: (iiii) 13, 14, 0, 0], 0]}]], "e" = [Variant(short): -47], "f" = [Variant: [Variant(int): 0]], "ismap" = [Variant: [Argument: a{is} {-47 = "c", 1 = "a", 2000 = "b"}]], "lldtmap" = [Variant: [Argument: a{x((iii)(iiii)i)} {0 = [Argument: ((iii)(iiii)i) [Argument: (iii) 0, 0, 0], [Argument: (iiii) -1, -1, -1, -1], 0], 1 = [Argument: ((iii)(iiii)i)[Argument: (iii) 1970, 1, 1], [Argument: (iiii) 0, 0, 1, 0], 1], 1150629776 = [Argument: ((iii)(iiii)i) [Argument: (iii) 2006, 6, 18], [Argument: (iiii) 11, 22, 56, 0], 1]}]], "pointf" = [Variant: [Argument: (dd) 0.5, -0.5]], "ssmap" = [Variant: [Argument: a{ss} {"a" = "a", "b" = "c", "c" = "b"}]], "time" = [Variant: [Argument: (iiii) 8, 58, 0, 0]]}]

Looks scary? It’s supposed to. D-Bus supports recursive complex types like structures, maps or variants, and until now, neither the Qt D-Bus viewer (part of Qt’s demos) nor the qdbus command line client were able to dump the contents of complex arguments. So, one day of hacking later, and thanks to a small API addition from Mr. QtDBus Thiago, we can now show pretty much everything that comes through the bus. The above example shows the output of one of our D-Bus tests - you can find complex structures inside variants and complex structs inside maps, and everything is nicely dumped.

But don’t worry - not many interfaces use deep nesting. Why we started to write the code in the first place is to display rectangles (4 integers in a D-Bus structure) from Qt’s D-Bus accessibility, Decibel’s properties (a D-Bus map structure) or some of the more complex calls of Telepathy.

The code will be available in Qt 4.5’s snapshots, happy introspecting!

P.S.: Many, many thanks to the organizers of this year’s Akademy. As always, it’s a great pleasure to be here.

Trolltech: Trolltech Labs Blogs

In the flow

Sometimes when you think you’re on to something, and you end up in the flow, so bad, that it overshadows everything you’re doing. Ariya and I were working on optimizations in Graphics View and stumbled over an optimization for clipping that made a certain benchmark run 40 - forty - times faster. The patch has no known side effects, comes perfectly for free, and even opens up a couple of more optimizations we can do.

I couldn’t think of anything else on the way home from work. When I came home, I ate dinner, and immediately ran over to my home desktop, installed Git, and tried to find some way to continue where I left off.

It’s a wonderful feeling. If this patch really works this well, it’ll make it into Qt upstream, for everybody’s benefit. Mix that together with a lot of other optimization work that we’ve done, and hopefully things will truly fly.

I, for one, am looking forward to Qt 4.5 :-).

I'm going to aKademy

Trolltech: Trolltech Labs Blogs

too much Qt going on!

A great deal of things are happening for Qt right now. Very exciting news:
Qt frontend for Mozilla engine (or, rather, has finally been dusted off and updated) Now we have two of the best browser backends to choose from. (or three if you want to use that ActiveX thing)

and

Nokia gives out free N810 devices to developers in Akademy 2008. Wow, thats a heap of n810’s to throw around.

Too bad Kate forgot to mention the other talks from Nokia:

And if course, I cannot really yet mention all the really powerful great stuff being developed at Qt Sofware/Nokia.. but I really want too! Because its just too cool and will blow your minds.

Trolltech: Trolltech Labs Blogs

Opendocument format

The Open Document Format (ODF) is an ISO standardized method of storing rich text and other office data. The ODF standard has grown in popularity over the last years quite a bit. Many governments around the world have passed laws stating that any sort of communication between the government and its people has to be done in ODF.
The attraction for ODF is strong, it is the first standard in this field that is completely open and it has a wide enough coverage that you can store your word processor and even most DTP documents in it without losing data.
I find the part where the standard is open very important, as an individual I have been able to sit on the ODF technical committee and I have been able to co-decide the direction of the standard. Various list-item related stuff has a finger of mine in there, for example.
Equally important is that everyone who wants to can implement ODF support in his or her application. All the information is available to do so, for free, on the web.

So, for end users the biggest advantage of the uptake of ODF is that more and more applications will standardize on this one format and thus applications will be much more interoperable. OpenOffice and KOffice are the early adopters here, I expect that many more applications will start to generate or consume ODF in some form or other. For example to export an abstract dataset to a nicely formatted document ready for printing, or the web.

Currently rich-text is mostly exchanged between different applications as html. Unfortunately html was not designed for this purpose. Sending an email with html markup kind of works. But you should take a look at the html that Qt or Word generate. Loads of extra non-html tags are written out just to put the layout information somewhere when html doesn’t have any equivalent features.
Those made up tags will be lost when the html is opened by another application than the one that created it.
Longer term I expect to see email applications to send ODF as well as html in their emails. Just so they can use the much broader ODF set of features.

Interestingly, a text exchange format gets more useful when more applications support it. This should be obvious )
To speed up ODF recognition Qt 4.5 will ship with an ODF writer. Qt’s text module turns into a one stop document generation API where you can use QTextCursor to create your document via a nice API and you can then export the created QTextDocument to ODF ready to be opened by any opendocument implementation. Naturally exporting to plain text and html are still supported, as is printing to PDF.

Support for writing ODF in Qt sets a trend that we believe in the OpenDocument Format and we think its useful to have for our customers, the open source community and all end-users out there.

I always think its important to point out what our current solution does not do, just to avoid disappointment. The QTextDocumentWriter has support for each feature in Qt. So you can expect all features you can access using QTextCursor to be exported. This, however, is a subset of features in ODF. Qt’s ODF-writer does not aim to support each and every feature in ODF. So don’t expect you can write spreadsheets or some obscure ODF-text features that Qt doesn’t have.

There is work going on to make an ODF Reader too for a future release, the aim is to support all the features we write out but also try to map ODF features to Qt’s feature set where it makes sense.
The writer is in the unstable snapshots already, and will be released in 4.5. You can find the documentation online at; doc.trolltech.com/main-snapshot/qtextdocumentwriter.html

Trolltech: Trolltech Labs Blogs

Network Cache!

The past few weeks I have been hacking on another feature in Qt. Going with the theme of making Qt 4.5 faster I added a cache system to QNetworkAccessManager and provided a simple QNetworkDiskCache that can be used by most applications. Under the hood the new http backend has been enhanced to support all the http rfc cache features you would expect (even behave better than FireFox in one case). Adding a cache system is very important to a lot of our customers.

- Anyone who wants to use rss/atom feeds absolutely must have a cache system in place.
- Anyone who uses QtWebKit has been looking forward to a cache system.
- Any other application that pulls down files off the network such as in XMLPatterns can use the cache to improve performance and reduce network overhead.

To store the cache QDesktopServices::storageLocation has a new enum CacheLocation that can be used to determine a proper cross platform location for where cache files can be stored. The included QNetworkDiskCache is simple and should be good enough for a lot of customers, but for those that want to write a highly optimized one for small devices or to hook into another cache system (such as MSIE’s) the interface QAbstractNetworkCache is provided so you can implement custom cache systems.

For many applications enabling the cache will be as simple as:
QNetworkDiskCache *diskCache = new QNetworkDiskCache(this);
QString location = QDesktopServices::storageLocation(QDesktopServices::CacheLocation);
diskCache->setCacheDirectory(location);
networkAccessManager->setCache(diskCache);

To see it in action you can checkout the demo browser the 4.5 snapshots where I have enabled it.

Trolltech: Trolltech Labs Blogs

Zooming text

Some of my colleagues on the graphics team have been writing graphics dojo demos with impressive speed and with a rainy weekend I thought I’d get into the action.
As I’m regarded as the text guy I thought it would be fitting to have a demo that uses text, so I made a text effect class that animates text fading in and fading out.

One thing that I see a lot of people do is that if they want to zoom into text, they change the fontsize. There is a fundamental problem with that approach as text doesn’t scale linearly (due to hinting). So in Qt4 we have a much simpler and more powerful way of scaling text that fits better in graphics concepts. You simply scale the QPainter during painting.
This means that if you call myPainter.scale(2,2); your 12pt font will suddenly appear as a nicely scaled 24pt font. Or, more accurately, it will show the original text at 200% zoom.

This is very simple and due to us reusing the same font settings we avoid recalculation and text layout. So it will actually be quite fast. So fast that you can animate it quite smoothly. As is shown in the demo.

There is not much more to say about it, so just grab the code and run it!
svn checkout svn://labs.trolltech.com/svn/graphics/dojo/zoomingtext

zoom1.png
zoom2.png
zoom3.png
zoom4.png

Trolltech: Trolltech Labs Blogs

New.s.

New business cards (not arrived yet). New employee badge (photo looks bad, as always). New email address (@nokia.com). New phone (starts with N). New intranet (huge). New Desktop (KDE 4.1 - I’m so impressed by you guys). New presentation templates (for my Akademy presentation). New marital status. New version control system (git).

And a new patch to make Qt 4.4 build within the LSB 3.2 environment, we’re getting very close to having one binary Qt/X11 Linux version to rule all distributions (bye bye distribution pain): lsb3.2-20080801.patch

Disclaimer: The patch above is unsupported, please contact my first name dot last name at domain starting with N for questions.

Trolltech: Trolltech Labs Blogs

Phonon on Windows CE

Since the Windows CE platform is still missing support for Phonon in 4.4, we are working on Phonon for this new Qt platform. We ported the Direct Show backend to Windows Mobile. Sadly there are only very few Direct Show filters available by default on Windows Mobile. But there is nothing we can do about this from the Qt side.

Because not all Windows CE SDKs and Devices support Direct Show, I also wrote a backend for the
Wave Form API from Windows CE. This backend has a lower footprint, but is for now only able to play wave files.

If you want to try out Phonon for Windows CE, then check out the Qt main snapshots, and either configure your Qt/Windows CE build with Phonon enabled (configure -platform win32-msvc2005 -xplatform wincewm50pocket-msvc2005 -phonon) or build Phonon manually (src\phonon).

While playing around with Phonon do not forget to deploy phonon and the plugin for the backend you want to use.

For people, who are not familiar with Phonon. Playing a wave file with Phonon just takes two lines of code:

Phonon::MediaObject *music = Phonon::createPlayer(Phonon::MusicCategory, Phonon::MediaSource("test.wav"));
music->play();

The Windows CE team is always happy to receive feedback. You can subscribe the qt-wince-interest mailing list by sending the word “subscribe” in the subject of a message to qt-wince-interest-subscribe@trolltech.com.

Trolltech: Trolltech Labs Blogs

Old school effect: the radial blur

For this episode of the graphics dojo I’ve implemented the classic radial blur effect. The core radial blur effect is implemented with per-pixel manipulation, which Qt lets us do quite elegantly using the QImage class. The final dojo example uses the radial blur effect in combination with scrolling text drawn using QPainter to create a nice visual impression. Below is a screenshot of the effect as well as a recording:

Radial blur screenshot

Radial blur movie capture

As usual, the source code is available from the SVN repository: svn checkout svn://labs.trolltech.com/svn/graphics/dojo/radialblur

Trolltech: Trolltech Labs Blogs

Releases and other stuff — three blogs for the price of one

Qt released

Qt logo
Since the saying “The release is not out until you blog about it” is still in effect, I have the pleasure of announcing that Qt 4.4.1 has been released.

Here’s the download button:

Download Qt

The 4.4.1 release is a patch-level release, meaning it’s a bug-fix release on top of Qt 4.4.0, maintaining both forward and backwards compatibility. It’s a drop-in replacement for Qt 4.4.0 and shouldn’t cause you any problems.

The full changelog can be found on our website.

This release happened about a month later than I had originally planned to. We postponed it until we could make sure that 4.4.1 is better than 4.4.0. Also, we can find explanations relating to Summer in Norway:

  • Key people leaving for vacations
  • Scheduled power supply cuts
  • Air conditioning machines being turned off in our building
  • Temperatures in Norway being quite high this year (often reaching 30°C)

And you thought that Winter in Norway was a problem…

KDE 4.1 released

Of course, I couldn’t let it pass that KDE 4.1 has been released, dedicated to KDE long-time contributor Uwe Thiem. Uwe had been doing a great job spreading Open Source and Free Software in Africa (Namibia to be precise). And many would say that’s where it’s needed the most.

KDE 4.1

In any case, KDE 4 has come a long way since the 4.0 release back in January. Back then, applications were great; the desktop was shiny and new, but limited. Many things I was used to simply didn’t work. Even for a long-time KDE contributor such as myself, it was hard to let the good, old KDE 3.5 go. But ever since KDE 2.2, I’ve always used the bleeding edge version. If using it back then wasn’t a problem, today is should be even less.

But that’s old history! Six months have passed!

KDE 4.1 is a lot better today. Many of the things that people complained about in Plasma have been fixed. And, of course, the applications that were already great got even better. Everyone deserves a praise for their work, however minor their contributions might have been. (I submitted only a few crash fixes)

Sure, it’s not perfect — nothing is. However, given the pace of development, I’m sure those things will get sorted out quite soon.

We’re going to Akademy

Yes, the Trolls/Nokians will be going to Akademy 2008.

Going to Akademy 2008

The following developing Trolls will be coming: Andreas Aardal Hanssen, Daniel Molkentin, Daniel Teske, Harald Fernengel, Jesper Thomschütz, Kent Hansen, Lars Knoll, Marius Bugge Monsen, Matthias Ettrich, Olivier Goffart, Oswald Buddenhagen, Simon Hausmann, Thomas Cooksey, Thomas Zander, and I. Most of those had to learn how to use the new Nokia Travel Planner in the last week.

Besides those, there will be other Nokians coming from all parts of the globe. I know of people coming from Finland and from Brazil.

Hope to see you in Belgium!

And for those who can’t come to Akademy, save the date:
Qt Developer Days 2008
MUNICH, Germany: October 14th – 15th
REDWOOD CITY, California: October 29th – 30th

Trolltech: Trolltech Labs Blogs

A sturdier bridge (still troubled water underneath)

A while back we announced the research project Qt Jambi AWT Bridge which allows you to mix AWT/Swing components and Qt widgets in the same window on Windows and Linux.

There were a few issues with the original version. The main problems were the fact that your window would be deactivated by the window manager when you clicked inside an embedded widget, some issues with unnecessary whitespace around the embedded components when you embedded AWT inside of Qt, and some people experienced a race condition which caused the embedded widgets to sometimes disappear.

The project has now largely been rewritten to be more robust, and both the window activation issues and whitespace issues have been resolved. If you sync the latest version from Subversion, you should be able to see major improvements. There are still some issues with keyboard focus (tabbing between the application widgets and the embedded widgets) which we are trying to resolve.