Aus Linux-Magazin 01/2001

Internationalisierung von KDE-Anwendungen

Abb.3: KBabel ist ein po-Datei-Editor mit vielen nützlichen Features.

Nachdem es in Heft 11/2000 um die Übersetzung von GNOME-Programmen ging, soll nun natürlich auch KDE nicht zu kurz kommen. Dieser Artikel gibt einen Überblick über die vorhandenen Mechanismen zur Internationalisierung von KDE-Anwendungen und über die Arbeit der Übersetzungsteams.

Mit der Veröffentlichung der Version 2.0 unterstützt KDE bereits mehr als 30 Sprachen, weitere werden nach der Veröffentlichung hinzukommen. Das ist nicht nur auf die aktiven Übersetzerteams von KDE zurückzuführen, sondern auch auf die sehr gute Unterstützung für die Lokalisierung seitens der KDE- und Qt-Bibliotheken. Abbildung 2 gibt einen Überblick über die verschiedenen Optionen, die alle im KDE-Kontrollzentrum konfigurierbar sind.

Abb.1: Die deutsche Arbeitfläche von KDE

Abb.1: Die deutsche Arbeitfläche von KDE

KLocale

Wie schon in [1] erklärt, gehört nicht nur die Übersetzung der Texte (Menüs, Meldungen und Ähnliches) eines Programms zur Lokalisierung, sondern es sind auch Dinge wie Zahlenformatierungen sowie Formate von Datums- und Zeitangaben oder Währungen zu beachten. Darüber hinaus sind weitere regionale Besonderheiten zu berücksichtigen, ob etwa die Woche am Sonntag oder am Montag beginnt. Das wird aber wahrscheinlich nur bei speziellen Anwendungen wie einem Terminplaner notwendig sein.

Zur Bewältigung der komplexen Aufgabe stellt KDE die Klasse KLocale bereit. Sie enthält die benötigten Funktionen, der Entwickler muss sich nicht um Initialisierungen oder Einstellungen kümmern. Die vom Benutzer im Kontrollzentrum eingestellten Optionen werden automatisch von KLocale benutzt. Man braucht sich nicht mal um das Erzeugen oder Freigeben einer Instanz dieser Klasse zu sorgen. Die global für die Anwendung verfügbare Instanz von KLocale erhält man jederzeit durch:

KLocale *locale =  KGlobal:£ocale();

Dabei wird, falls noch nicht vorhanden, ein Objekt von KLocale erzeugt und beim Beenden der Anwendung automatisch freigegeben.

Was stellt nun KLocale genau zur Verfügung? Zuerst natürlich Funktionen für die Übersetzung von Texten. Funktionen deshalb, da KDE die Funktionalität von gettext etwas erweitert, um einige Einschränkungen zu umgehen. Außerdem gibt es Funktionen für die Ein- und Ausgabe von Zahlen, Datums- und Zeitangaben sowie Währungen: QString KLocale::formatNumber (double num) zur Ausgabe oder double readNumber (const QString&) zur Eingabe von Zahlen nach den lokalen Gepflogenheiten. Also beispielsweise in Deutschland 2,5 statt 2.5.

Listing1: Mit
Kontextinformation versehene Texte in der po-Datei

#: src/program.cpp:10
msgid ""
"_: the viewn"
"View"
msgstr "Ansicht"

#: src/program.cpp:11
msgid ""
"_: to view somethingn"
"View"
msgstr "Ansehen"
Abb.2: Länder- und sprachspezifische Einstellungen im KDE-Kontrollzentrum.

Abb.2: Länder- und sprachspezifische Einstellungen im KDE-Kontrollzentrum.

Übersetzungen

Wie man diese Formatierungsfunktionen in seinem Programm einsetzt, hängt von den Umständen ab und soll deshalb hier nicht weiter erörtert werden. Im Sinne gut internationalisierter Software sollte jedoch jede Ein- und Ausgabe durch diese Funktionen geschleust werden. Weitere Informationen zu den Formatierungsfunktionen und zu KLocale allgemein sind in der Dokumentation zur Bibliothek kdecore zu finden [2] .

Wie oben schon erwähnt, benutzt KDE für die Übersetzung der Programmtexte ebenso wie GNOME und viele andere Projekte gettext. Dies hat zwar durchaus seine Stärken, aber leider auch seine Schwächen (siehe Kasten “Funktionsweise von gettext“). Daher stellt KLocale neben der Funktion QString KLocale:ªranslate(const char *text) noch eine weitere Funktion QString KLocale:ªranslate(const char* index, const char* text) zur Verfügung.

Dabei wird das erste Argument einerseits dazu benutzt, dem Übersetzer mehr Informationen über die Verwendung des gegebenen Textes zu geben, und andererseits, um die Einschränkung von gettext zu umgehen, dass es für denselben Text nur eine Übersetzung geben kann. Es wird nämlich dann der aus beiden gegebenen Texten zusammengesetzte Text benutzt, um die Übersetzung zu erhalten. Man könnte also beispielsweise einmal translate(“the view”,”View”) und einmal translate(“to view something”,”View”) verwenden. Diese Texte erscheinen dann in der po-Datei, wie in Listing 1 gezeigt. Der Übersetzer darf dabei die jeweils erste Zeile nicht mit übersetzen, sondern nur den eigentlichen Text.

Als Entwickler sollte man darauf achten, überall dort die erweiterte Funktionalität zu nutzen, wo Text – aus dem Kontext gerissen – nicht eindeutig ist. Weitere Beispiele dafür sind Wörter wie “open”, “new” und allgemein kurze Begriffe oder Sätze, bei denen die Bedeutung unklar ist, sobald sie isoliert erscheinen. Man erspart damit den Übersetzern viel Arbeit und Missverständnisse.

Natürlich will man als Programmierer nicht andauernd solche Ungetüme wie KGlobal:£ocale()->translate(…) schreiben. Um das etwas abzukürzen, gibt es die zwei globalen Funktionen i18n(const char* text) und i18n(const char* index, const char* text), die einem genau das abnehmen und sonst die gleiche Funktionsweise wie die translate-Funktionen haben. Damit wäre die wichtigste Funktionalität von KLocale auch schon erklärt.

Listing 2:
Makefile.am im po-Verzeichnis

POFILES = AUTO

merge:
        @catalogs='$(POFILES)'; 
        for cat in $$catalogs; do 
        echo $$cat $$name; 
        msgmerge -o $$cat.new $$cat $(PACKAGE).pot ; 
        if test -s $$cat.new; then 
          grep -v ""POT-Creation" $$cat.new > $$cat.new.2 ; 
          grep -v ""POT-Creation" $$cat > $$cat.new.1; 
          if diff $$cat.new.1 $$cat.new.2; then 
                rm $$cat.new;  
          else  
                mv $$cat.new $$cat ; 
        fi; 
        rm -f $$cat.new.1 $$cat.new.2 ;
        fi ;
        done

Satzbau

Mit der Benutzung dieser Funktionen ist es aber noch nicht ganz getan, es gibt noch ein paar weitere Dinge zu beachten, die es ansonsten schwer machen, die Programmtexte gut zu übersetzen. Womit wir bei der Klasse QString der Qt-Bibliothek gelandet wären. Der +-Operator verleitet leicht dazu, sich Sätze aus Textbausteinen zusammenzubauen.

Das ist jedoch Gift für eine gelungene Übersetzung. Erstens sieht der Übersetzer in der po-Datei immer nur die einzelnen Bausteine und muss sich dann zusammenreimen, dass diese mit anderen kombiniert werden. Zweitens sieht der Satz in einer anderen Sprache nicht unbedingt genauso aus wie im Englischen. Der Übersetzer muss also versuchen, seine Übersetzung irgendwie um den künstlich vorgegebenen Satzaufbau herum zu konstruieren. Dass das nicht immer möglich ist, sollte einleuchtend sein. Beispiel:

QString msg=i18n("Do you really want to delete file ")+filename

Eigentlich würde man das übersetzen mit: Wollen Sie die Datei ” + filename + ” wirklich löschen? Das ist aber leider nicht möglich. Der Übersetzer könnte sich dann zwar eine Notlösung zusammenbasteln, aber das ist natürlich nicht ideal und wahrscheinlich nicht in allen Sprachen machbar.

Ein ähnliches Problem entsteht, wenn man die Funktion sprintf mit mehr als einem Argument verwendet, da es dem Übersetzer nicht möglich ist, die Reihenfolge der Argumente zu verändern und somit der Satzaufbau wieder weitgehend festgelegt ist.

Die Lösung dieser beiden Probleme bringt die Funktion QString::arg, die dem Übersetzer bei der Reihenfolge der eingesetzten Argumente völlig freie Wahl lässt. Das wird dadurch bewerkstelligt, dass an den üblichen Formatangaben von sprintf wie %s oder %d Platzhalter der Art %i benutzt werden, wobei i eine positive ganze Zahl ist. Das Format des eingesetzten Textes wird dabei durch die Funktion arg bestimmt, die für alle möglichen Argumente überladen ist. Eine typische Anwendung wäre:

msg=i18n("Overwrite %1 with %2?" ).arg(oldName).arg(newName);

Dabei wird immer der Platzhalter mit der niedrigsten Zahl durch das nächste Argument ersetzt, auch wenn dieser Platzhalter nicht an nächster Stelle steht. Der Übersetzer könnte nun also den Text übersetzen mit: Soll %2 %1 überschreiben? oder mit Soll %1 mit %2 überschrieben werden?

Trotzdem sollte man jetzt nicht auf die Idee kommen, mit diesem Mechanismus etwas anderes als Zahlen, Dateinamen oder Ähnliches in Texte einzufügen, da es dadurch sehr leicht zu Problemen, etwa mit der Deklination, kommen kann.

Funktionsweise von
gettext

Grob gesagt ist gettext nichts weiter als eine Hash-Tabelle ([3]). Bei Umwandlung der po-Dateien (siehe [1]) in so genannte (g)mo-Dateien wird nichts anderes gemacht, als die Originaltexte und die Übersetzungen in ein maschinenlesbares Format zu bringen, das aus Geschwindigkeitsgründen optional eine Hash-Tabelle enthalten kann. Wenn man nun in einem Programm die Übersetzung eines Textes anfordert, schaut gettext in der vorher angegebenen Datei nach, ob es entweder den Hash-Wert oder den Text selbst dort findet, liest dann die dem Text oder dem Hash-Wert zugeordnete Übersetzung und gibt sie dem Programm zurück.

Das Problem liegt nun darin, dass es für den gleichen Text nur eine Übersetzung geben kann. Das ist zwar einerseits gewollt und sinnvoll, aber andererseits kann es durchaus passieren, dass ein und derselbe Text mehrmals vorkommt, aber in jeweils unterschiedlicher Bedeutung. Beispielsweise bedeutet “View” in der Menüleiste “Ansicht”, während es in einem Kontextmenü “ansehen” heißen kann. Um diese Einschränkung zu umgehen, benutzt KDE eine gepatchte Version von GNU gettext, die aber nur bei der Extraktion der Texte aus dem Quelltext benötigt wird. Sie ist im Paket kdesdk enthalten, das man von [4] herunterladen kann.

Listing 3: Auszug
aus dem Makefile.am zur Extraktion der Texte

messages: rc.cpp
      $(XGETTEXT) -C -ki18n -kI18N_NOOP -ktranslate 
      -x $(includedir)/kde.pot *.cpp -o $(top_srcdir)/po/$(PACKAGE).pot
                   
rc.cpp:
      extractrc *.rc *.ui > rc.cpp

Layout-Manager

Wie man an den bisherigen Beispielen schnell sieht, stimmt die Länge des übersetzten Textes meist nicht mit der Länge des Originaltextes überein. Aufgrund der Kompaktheit der englischen Sprache ist die Übersetzung häufig länger als das Original, bei Übersetzungen ins Deutsche ist das die Regel. Daher ist es ratsam, nirgends in seinem Programm festgelegte Größen, sondern überall die in Qt vorhandenen Layout-Klassen zu verwenden. Damit werden nicht nur die Minimum-Größen der Widgets automatisch an den Text angepasst, sondern die Layout-Manager kümmern sich auch um viele andere Dinge, wie beispielsweise die Anpassung an Größenveränderung des Fensters.

Abb.3: KBabel ist ein po-Datei-Editor mit vielen nützlichen Features.

Abb.3: KBabel ist ein po-Datei-Editor mit vielen nützlichen Features.

Makefiles

Wie kann man nun den Prozess des Extrahierens der Texte und die Installation der Übersetzungen automatisieren? Es wird hier davon ausgegangen, dass die Standard-Automake-Umgebung von KDE eingesetzt wird, also entweder eine Vorlage benutzt oder eine Vorlage mit KAppTemplate aus dem Paket kdesdk [4] erstellt wurde. Zuerst sollte man, falls noch nicht vorhanden, ein Unterverzeichnis po erzeugen. Hier kommen später die Übersetzungsvorlage sowie die übersetzten po-Dateien hinein. In diesem Verzeichnis legt man dann die Datei Makefile.am an, wie in Listing 2 gezeigt. Die Namen der po-Dateien in diesem Verzeichnis müssen der Konvention de.po folgen. Wenn das Verzeichnis und die Datei Makefile.am noch nicht vorhanden waren, ruft man jetzt noch einmal im obersten Verzeichnis Folgendes auf:

make -f Makefile.cvs; ./configure

Damit wird das neue Makefile erzeugt. Im Verzeichnis der Quelltexte sollte die Datei Makefile.am einen Eintrag enthalten, wie in Listing 3 zu sehen. Dabei ist extractrc ein Skript, das Texte aus XML-Dateien, wie sie etwa der Qt-Designer erzeugt oder wie sie zum Definieren der XML-GUI benutzt werden, extrahiert und in eine für gettext lesbare Form bringt. Damit werden auch Texte aus diesen Dateien mit in die po-Datei übernommen und stehen für die Übersetzung zur Verfügung. extractrc ist im Paket kdesdk [4] enthalten. Danach kann man einfach mit make messages im Quelltext-Verzeichnis die Texte extrahieren. Die Übersetzungsvorlage wird automatisch in das Verzeichnis po verschoben. Dort gleicht dann make merge die neue Vorlage mit den schon vorhandenen und übersetzten Dateien ab.

Das sieht alles nach Aufwand aus – aber es lohnt sich, auf die Texte in seiner Anwendung zu achten und Ein- und Ausgaben in anderen Sprachen und regionalen Gegebenheiten zu ermöglichen. Das kommt der Verbreitung der Anwendung und der Bedienbarkeit sehr zugute. (uwo)

Die
Übersetzer-Seite

Natürlich würde es nichts nützen, ein Programm auf Übersetzungen vorzubereiten, wenn es nicht auch Leute gäbe, die die Programmtexte in ihre Sprache übertragen. Hier soll ein kurzer Einblick in die Arbeit der Übersetzerteams, speziell des deutschen Teams gegeben werden. Haupt-Anlaufstelle ist der i18n-Server [5], auf dem alle wichtigen Informationen über die verschiedenen Teams, ein ausführliches Übersetzungs-Howto sowie noch jede Menge anderer nützlicher Sachen zu finden sind. Nicht sprachspezifische Dinge werden in der Mailingliste kde-i18n-doc@kde.org besprochen.

Für die Kommunikation der Übersetzer innerhalb eines Sprachenteams bestehen eigene Mailinglisten, so etwa kde-i18n-de@kde.org für das deutsche Übersetzerteam. Dort kann es manchmal ziemlich heiß hergehen, wenn beispielsweise darüber gestritten wird, wie etwas übersetzt werden soll. Dazu hat das deutsche Team außerdem ein Diskussionsforum [6] eingerichtet, in dem auch Anwender Feedback zu Übersetzungen geben.

Die Bedeutung einer guten Übersetzung sollte man übrigens nicht unterschätzen. Natürlich kann man es nicht allen recht machen, aber wenn durchgehend sinnvolle und konsistente Übersetzungen benutzt werden, lässt es sich bedeutend einfacher arbeiten und es entsteht ein angenehmer Gesamteindruck, was ja auch ein Ziel eines Desktop-Environments ist. Feedback ist also durchaus willkommen. Um die Konsistenz der Übersetzungen weiter zu verbessern, gibt es außerdem auf dem i18n-Server das Wörterbuch kdedict [7], in dem die häufigsten Begriffe aufgelistet sind. Zudem werden für alle Sprachen regelmäßig so genannte Kompendien erstellt, die mit Hilfe spezieller Werkzeugen helfen, möglichst einheitlich zu übersetzen. Solche speziellen Werkzeuge sind z.B. für Emacs-Erprobte der po-Mode, der in jeder Distribution enthalten sein sollte, und der KDE-Editor KBabel [8] (siehe Abbildung 3), der von den meisten KDE-Übersetzern und inzwischen auch von vielen Nicht-KDE-Übersetzern benutzt wird. KBabel übernimmt viele Routine-Dinge wie das Aktualisieren des Headers oder das Prüfen auf korrekte Syntax und hat auch sonst noch viele nützliche Features.

Wer Interesse bekommen hat, selbst bei der Übersetzung mitzumachen, der sollte sich einfach mal auf der Team-Homepage [9] umschauen, was ihn besonders interessieren würde. Da alle nur in ihrer Freizeit übersetzen, ist Hilfe jeder Art immer willkommen. Besonders im Bereich der Dokumentationen, der hier nicht behandelt wurde, ist noch sehr viel zu tun. Allerdings darf man sich das Übersetzen auch nicht zu einfach vorstellen. Es ist durchaus auch ein wenig Zähigkeit gefragt, wenn es erst mal darum geht, eine Betaversion von KDE zu installieren oder sich allgemein mit den Gepflogenheiten beim Übersetzen bekannt zu machen. Der Lohn für die Mühe ist, bei der Verbreitung von Linux geholfen zu haben und Teil eines großartigen Open-Source-Projekts zu sein.

Infos

[1] Thorsten Fischer: Die Internationale; Gnome-Programme übersetzen; Linux-Magazin 11/2000, Seite 114

[2] http://developer.kde.org/documentation/library/2.0-api/classref

[3] http://www.gnu.org/software/gettext/gettext.html

[4] http://ftp.kde.org/pub/kde/

[5] http://i18n.kde.org

[6] http://www.dtp-service.com/discus_d/

[7] http://i18n.kde.org/cgi-bin/kdedict.cgi

[8] http://i18n.kde.org/tools/kbabel

[9] http://i18n.kde.org/teams/de

Der
Autor

Matthias Kiefer studiert Physik an der Technischen Universität Karlsruhe und schreibt zur Zeit an seiner Diplomarbeit. Außerdem entwickelt er den Editor KBabel und übersetzt KDE-Programme ins Deutsche.

Copyright © 2002 Linux New Media AG

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben