KTutorial 0.5.1 released!

2012/12/07

This is the first release licensed under the GPLv2+, and the first one containing translations provided by the KDE localization teams (thank you for your work! 🙂 ).

The release notes contain more information about the changes from 0.5 release.

Check the download page for information about downloading and building KTutorial.

Preventing graphical automated tests from interrupting you

2012/12/06

You may have found that running graphical automated tests (like unit tests for view subdirectories in ktutorial-library and ktutorial-editor) can be very annoying. Ideally, you would launch the tests and then go on working on something else while they run. The problem is that, while you are trying to work on something else, the windows created by the unit tests are constantly appearing and disappearing.

If you don’t want to use the time spent running the tests giving a rest to your eyes far away from your monitor, and you want to use your computer while the tests are running, there is an easy solution: run the tests in a different display than the one you are using.

To do this, you must start that other display before running the tests. Xnest can be used to start another display inside a window in your current display. You should also start a window manager for that display to ensure that the tests will run in a “real” environment. Both things can be done in a single command (and as a user, there is no need to become root for this):
(Xnest :1 2>/dev/null & ) && (kwin -display :1 2>/dev/null & )

That command assumes that you are using just one display, and that you want to start a second display :1. If you are already using several displays, adjust the number accordingly. The redirection of error output (2>/dev/null) is not mandatory; it is just used to prevent the console to be flooded with error messages.

Once the second display is started, you can execute the tests on it with:
DISPLAY=:1 ctest

Of course, you may also export the DISPLAY variable, or run a specific test executable, instead of using ctest.

Finally, once you no longer need the auxiliar display, just close its window. That will end the kwin and Xnest processes.

Example of KTutorial for the real world: Gwenview

2012/08/30

In this third and last example I will show the KTutorial implementation of a tutorial for Gwenview.

Like the previous tutorial for Kdenlive, this tutorial was made after the release of KTutorial 0.5, so nothing had to be changed in KTutorial to implement it. Unlike the Kdenlive tutorial, for this one I had to modify Gwenview code for something else than just to use KTutorial. But it was not to add object names like for the showFoto tutorial. In this case, I added a little hack to reparent KActions from the main KActionCollection to the main application window.

The KActionCollection created by KXmlGuiWindow (the base class of the main application window) is not parented to the main application window. However, the KActions are parented to the KActionCollection. KTutorial scripted tutorials (like those exported from the editor) can only find objects that are descendants of the main application window, so the KActions have to be reparented to the main Gwenview window to be found by KTutorial.

Note that reparenting the KActions is not mandatory for KTutorial to work with Gwenview (or any other application). However, it provides a more interactive experience, at least with the tutorial I implemented in this example. If the KActions could not have been used the tutorial could have been written anyway, but it would have contained more “Continue” buttons to change to the new step, instead of changing when the user does what he is asked to do.

Well, here it is the video showing the tutorial being followed in Gwenview (Theora, 1280×800, 12MB). The source for this tutorial, which can be viewed and edited using KTutorial editor, can be downloaded here: “Full screen interface” tutorial for Gwenview.

As I have already said, the changes made to Gwenview are the same that for Kdenlive, but also reparenting the KActions: Gwenview is linked against KTutorial (if found), the tutorial itself is added as a Javascript file, the tutorial script is included in the message extraction for i10n and the KActions are reparented to the main application window. If you want to try this patch yourself, here it is: Gwenview patch (against current master at the time of this writing, which is ef544ad9).

I hope you have liked this three example series and, who knows, maybe become interested about KTutorial 🙂

Example of KTutorial for the real world: Kdenlive

2012/08/28

In the previous post I showed the KTutorial implementation of a KDE UserBase tutorial for showFoto. Now I will show a tutorial for Kdenlive.

This time, instead of adapting for KTutorial an already existing tutorial, I wrote the tutorial myself from scratch. I was not sure of what license the Kdenlive tutorials are under, so I made my own CC by-sa tutorial showing how to add a slide transition between two clips.

There are other two differences worth being mentioned. The first is that I made the Kdenlive tutorial once I released KTutorial 0.5. The showFoto tutorial was made during the KTutorial 0.5 development, and it was used to identify problems when using KTutorial in applications other than the KTutorial editor itself. But the Kdenlive tutorial was made using the released KTutorial 0.5 instead. That is, nothing had to be changed or fixed on KTutorial to implement this tutorial.

The other difference is that the Kdenlive code was modified just to use KTutorial. No object names were set this time. I could have added object names, or properties to Kdenlive classes, or custom WaitFors, or even made a C++ tutorial, and get an even more interactive tutorial. But I wanted to adapt to just what Kdenlive code provided. I think that the result was pretty good 🙂 (although it would not have been so good if Kdenlive code did not contain already a lot of object names 😉 ).

Enough chatting; here it is the video showing the tutorial being followed in Kdenlive (Theora, 1280×800, 14MB). The source for this tutorial, which can be viewed and edited using KTutorial editor, can be downloaded here: “Simple slide transition between two clips” tutorial for Kdenlive.

Like with showFoto, I have patched Kdenlive to record the video. The changes are the same that for showFoto, but for adding the object names: Kdenlive is linked against KTutorial (if found), the tutorial itself is added as a Javascript file and the tutorial script is included in the message extraction for i10n. If you want to try this patch yourself, here it is: Kdenlive patch (against current master at the time of this writing, which is 34f17213).

In the next post you can see a last example, this time for Gwenview 🙂

Example of KTutorial for the real world: showFoto

2012/08/24

As said in the previous post, this KTutorial release (0.5) was focused on getting KTutorial ready to be used by other applications besides the KTutorial editor itself. How was it done? Well, using KTutorial on other applications besides the KTutorial editor itself 🙂

Specifically, a real showFoto tutorial from KDE UserBase was implemented in KTutorial. And not only that; the tutorial was implemented entirely using KTutorial editor. Even if C++ tutorials are more powerful than scripted ones, the goal was to ensure that just using the editor (which creates Javascript tutorials) and without any manual tweaking of the generated code, a tutorial useful for a real application could be done. And, guess what? It can be done 🙂

I have recorded a video showing the tutorial being followed in showFoto (Theora, 1280×800, 13MB). The source for this tutorial, which can be viewed and edited using KTutorial editor, can be downloaded here: “Levels adjust” tutorial for showFoto.

Cool! So, does showFoto support KTutorial now? Well, no, it does not. I had to patch showFoto to record that video 😉

However, the changes are pretty simple: showFoto is linked against KTutorial (if found), the tutorial itself is added as a Javascript file, the tutorial script is included in the message extraction for i10n and the name of the QObjects referenced in the tutorial are set. If you want to try this patch yourself, here it is: digiKam/showFoto patch (against current master at the time of this writing, which is 9744d0d3).

In the next post you can see another example, this time for Kdenlive 🙂

KTutorial 0.5 released!

2012/08/21

The focus on this release was on getting KTutorial ready to be used by other applications besides the KTutorial editor itself.

The release notes contain more information about the changes from 0.4 release.

Check the download page for information about downloading and building KTutorial.

KTutorial 0.4 released!

2010/10/30

This release was geared mostly towards improving KTutorial editor (for example, tutorials can be saved and loaded now), although improvements were made also to KTutorial library (like being able to highlight widgets).

The release notes contain more information about the changes from 0.3 release.

Check the download page for information about downloading and building KTutorial.

KTutorial 0.3 released!

2010/03/24

The main feature introduced in this release is KTutorial editor, a graphical editor to ease tutorial authoring. It is still in an early stage of development (you can’t even save and load a tutorial to continue working on it later), but it will be improved in the next releases.

The release notes contain more information about the changes from 0.2 release.

Check the download page for information about downloading and building KTutorial.

(Yes, I forgot to add a post for release 0.2 in this blog 😉 )

Move to SourceForge.net

2010/01/31

Just a little note. KTutorial has moved from La Forja de RedIRIS to SourceForge.net.

Thanks to RedIRIS for hosting the project until now.

This is the new KTutorial project page.

Internationalization in Kross scripts

2010/01/04

As I said in the previous post, internationalization in Kross scripts is a subject that deserves its own post. Again, this is based on my own experiences, and I’m by no means an expert in script languages or Kross, so don’t treat this information as a universal truth 😉

Also note that internationalization (from now on, i18n) has a very broad scope. Here we’ll talk only about string i18n (allowing the messages to be translated to other languages). If you are interested in other i18n areas you’ll have to keep looking 😉

So let’s see if I can give some useful information after all 😉

Translation systems

First of all, what systems do we have to translate strings? The de facto standard in free software world is GNU gettext. It provides tools to extract the messages to be translated from the source code, a file format to store the translations, a library to translate the strings at runtime… Most popular programming languages support gettext, being it through its standard API (like in Python) or from 3rd party projects (like in Ruby).

But it is not the only system available. For example, Qt has its own translation system as part of its i18n support. Ruby also has an i18n module that contain a translation system (although it can use gettext files switching the backend).

What does KDE use? Although KDE uses a lot of Qt infrastructure, in the case of string translation it uses gettext instead. Well, an enhanced version of gettext with some very interesting features. For example, the semantic markup helps translators to better understand how a string should be translated, but it also benefits the users as it provides a richer and more consistent appearance for messages. Another interesting feature is Transcript, which aids in the correct translation of case based languages (among others).

Moreover, KDE libraries take care of gettext initialization, catalogs and so on, so you just have to mark the strings to be translated without worrying about setting everything up.

What translation systems can be used from Kross scripts? Thanks to the Translation Module, the KDE translation system can be used in Kross scripts, no matter what programming language the script is written in. But, as Kross only acts as a bridge between the script interpreter and C++ code, the translation systems available for the programming language of the script can be used from Kross. So the i18n module in Ruby or gettext in Python could be used. And if Qt bindings are available for the language, even the Qt translation system could be used!

Anyway, in my humble opinion, the best choice is to use Kross Translation Module (if we know for sure that the script will be executed from Kross). The Translation Module is available no matter which programming language was used to write the script, and it is provided by Kross, so it doesn’t depend on external libraries. Moreover, as it just forwards the function calls to the KDE translation system, all the fancy features given by it are available for free in the scripts. And, finally, the messages can be extracted from the scripts like they are extracted from C++ sources, storing them in the same file (so translators don’t have to care where the strings came from) and accessing them at runtime without any special configuration.

Message extraction

Translators need to know what strings they have to translate, and in order to accomplish this the translatable strings must be extracted from the source code. To do this, an extraction utility analyzes the source code looking for those strings. The programmer must mark the translatable strings so the extraction utility knows which strings have to be extracted and which not.

To mark the string usually just means to wrap the string with a function/method call that will also translate that string to the appropriate language when the application is running.

To extract the strings, gettext provides xgettext, which understands source code in a lot of programming languages, including Python. However, it doesn’t support yet Javascript nor Ruby explicitly. When a programming language is unknown, xgettext tries (as far as I know) with C like strings and functions. So, although neither Javascript nor Ruby are explicitly supported, double quote C like strings can be extracted apparently without problems. But it doesn’t support single quote strings, custom delimited strings or function calls without parenthesis.

See the following Ruby code as an example (note that mark is just an example function name):

mark("Hello world double quotes") # Extracted by xgettext
object.mark("Hello world method") # Extracted by xgettext

mark('Hello world single quotes') # Not extracted by xgettext
mark(%/Hello world custom quotes/) # Not extracted by xgettext
mark "Hello world without parenthesis" # Not extracted by xgettext

xgettext has also a very useful feature: it let’s you specify how the strings were marked in the source code. So it supports the default gettext function names, but can also extract custom functions. For example, you can say “wherever you find a function called i18nc with 2 arguments, treat the first item as string context and the second argument as the string to be translated”. This is used by KDE, as KDE i18n functions have a different name than gettext canonical functions.

Note that the file created by xgettext when the messages are extracted uses a format understood by gettext (although other translation systems may be able to read those files). Anyway, it is not a problem using Kross Translation Module, because as it was already said, KDE uses (an enhanced) gettext as its translation system.

In fact, the extraction of strings in KDE is done with xgettext, and it is automatic if the application is part of KDE’s subversion repository, although it can also be simplified a lot with an script for 3rd party applications, as shown in i18n Build System. However, the Messages.sh for subversion and 3rd party applications given in that article only support C/C++ files. They must be adjusted to also look for messages in Kross scripts. Take a look to the changes in KTutorial commit #65 as an example.

The gettext project for Ruby provides rgettext, which is a xgettext tailored for Ruby source code. However, it just works for Ruby source code, and as far as I can tell it doesn’t allow you to specify how the strings are marked (maybe with -r argument you can extend the behavior of rgettext, but I haven’t tested it), so you can just use the canonical gettext function names. That is, it can’t extract messages from a Ruby script that uses Kross Translation Module (as the function names are the same used in KDE libraries).

So, in the end, in order to be able to extract messages from Kross scripts using the translation module you just have to include the scripts in the files to be looked for strings, and keep a C/C++ style in Javascript and Ruby strings and translation module calls.

Runtime translation, catalog location…

Another section that starts with bold letters… It means that there is a lot to say about this subject, right? Wrong. That’s one of the nicest things about using the translation module: once the messages from the scripts are extracted along with the messages from C++ code you are done. They will be treated like the C++ internationalized strings when translated, merged, installed and used at runtime. Do the string translation already work in C++? So it will for Kross scripts 🙂

Well, I lied. There is one case where this is not so easy: when the scripts aren’t part of the application. If an script is provided as an add-on for the application by 3rd parties, the messages from that script weren’t probably extracted with the rest of messages of the application. So the script must provide also its own translation files like additional data (for example, packaging the script and the translations in a tar.gz file or something like that). The translation files would need to be loaded at runtime, which would require some infrastructure.

Anyway, I haven’t explored this scenario as it seems very strange, at least for tutorials. If someone makes a nice scripted tutorial for an application that tutorial is likely going to end as part of the application itself. It would be very strange if the tutorial was kept as a separate entity, and even more strange if it got its own translations (getting localized seems like a sign that it is good enough to become part of the application 😉 ).