GUI Translation
This chapter deals with the translation of the graphic user interface (GUI) of KDE and its applications. For background information on what is actually translated here (i.e. the .pot and the .po files) please read the gettext Info pages. (Remember: the KDE on-line help provides a very convenient way to read this kind of documentation). — Special thanks to Christopher Kuhi for creating the first version of this section from the German original.

POT and PO Files
To provide a template for translations, the English menu and dialog texts of a program are stored in text files with the extension .pot (short for "PO Template" like .po stands for "Portable Object".) To see examples of how POTs and POs look you may want to pay a visit to WebSVN after reading the following topographic information about the directory structure.
From the standard templates or "POT files" translation teams produce the PO files for their respective language — simply by loading anyfile.pot to a text editor or one of the specialized PO programs and saving it as anyfile.po to another directory. After translating the strings inside the file, these POs will contain the menu and dialog texts for a given program if users choose, for example, "German" or "Icelandic" as the standard language. To be exact, there is another intermediate step which make MOs ("Machine Objects") from the POs during compilation. But this is something which translators do not generally need to worry about. At least, not as long as their POs are in the correct format; see below under the heading Checking and Committing Your Work.
The POT files and all translations can be found in a separate KDE folder called l10n-kf5 and represent their own package. Included are:
the POT files in the folder l10n-kf5/templates/
the language-specific PO files in the folder l10n-kf5/$LANGUAGE/messages/package-name/, (e.g. l10n-kf5/de/messages/dolphin/dolphin.po for a German file)
the language-specific PO files for documentation in the folder l10n-kf5/$LANGUAGE/docmessages/package-name/, (e.g. l10n-kf5/de/docmessages/dolphin/dolphin.po for a German file)
the language-specific documentation in the folder l10n-kf5/$LANGUAGE/docs/package-name/appfolder/index.docbook, (e.g. l10n-kf5/de/docs/applications/dolphin/index.docbook)
($LANGUAGE is short for language codes like "de", "fr", "ru", etc. As already mentioned, these abbreviations are nearly code from RFC 3066.

To-do Lists for GUI Translation
There are mainly two ways to find out which programs have not been translated yet:
Try to figure it out from the KDE internationalization status table.
Compare the POT files with the POs for the particular language. In other words: If there are no PO files for a particular program under "l10n-kf5/$LANGUAGE/messages/package-name" then the chances are pretty good that the program has not been translated yet. (This comparison is done automatically by the "Project Overview" of Lokalize, by the way.)
However, before translators jump right in, it is probably a good idea to ask their team coordinator whether a program is not being worked on by someone else and to make sure that the program is not being rewritten or replaced by another one. To-do lists for your team and a system of "package maintainers" (people who are responsible for the translation of whole KDE packages like kdeutils, kdemultimedia etc.) can also often be a big help in avoiding duplicate work.
KDE programs are constantly improved. The downside to this rapid development is that almost all GUI texts are constantly changing and the translations are just as constantly in need of revisions. To find out which already-translated programs need a revision, either SVN update your working directory or refer to KDE's GUI messages translation statistics.
The above mentioned statistics page organizes the information at three levels: SVN branch, translation team and package. At the package level you will find detailed information about the amount of fuzzies in each .po file. The .po files with fuzzies are the ones in need of a revision. "Fuzzy" is like a kind of question mark for the translations. These are sections which have been marked by an automatic checking routine (in msgmerge) as "suspicious" which means something to the effect of: "Please check this translation again because the original has changed".
An overview of how the language teams are doing is provided on the Translation statistics by team for trunk branch. Based on the percentage of translated messages the decision is made which languages will be part of a KDE release and which are not. (Normally, around 90% of frameworks and around 75% of kde-workspace should be translated in order to get into a release.)
When the essential requirements will be met, you should send a message about this at kde-i18n-doc@kde.org (but please do not attach translated files to it) to obtain further instructions.

Step by Step: The Translation of POTs and POs
General material on the subject can be found in the Info pages for the Gettext package. For a basic understanding of what is expected in KDE translation it follows a description of how the handling of POTs and POs looked like before it was done with specialized programs like Lokalize:
If there is no translation for a given program (i.e. there are no PO files with the same name in the appropriate folder "l10n-kf5/$LANGUAGE/messages/package-name/") — and only if this is the case! — then a POT file is loaded into an text editor and saved with the ".po" ending in the folder where it was missing. This results in a file with a name like "l10n-kf5/$LANGUAGE/messages/package-name/program-name.po". For instance: if you are sure that Kate was not translated to your language yet, you load the recent l10n-kf5/templates/messages/kate/kate.pot and save it as l10n-kf5/$LANGUAGE/messages/kate/kate.po . Then you can start translating.
From now on you do all your work for the given program with the PO file. Most of the work consists of updating, improving, and unifying earlier translations (i.e. POs which are already there).
After you have filled out (or updated) the header (who, when, etc. as well as deleting the first "fuzzy" tag, see below) you fill in the empty strings with new translations. In POs that were already translated at an earlier time you check the "fuzzy" translations and correct them if necessary. Either way, remove the "fuzzy" tag at the beginning of the line after you finished working on it.
Nowadays, most of these steps are done automatically by specialized programs like Lokalize — from choosing the POT files and saving them as POs, through header updates and removing fuzzy entries to syntax checks.
A sample header could look like this:

msgid ""
msgstr ""
"Project-Id-Version: Some Program\n"
"POT-Creation-Date: 2009-08-23 02:43+0200\n"
"PO-Revision-Date: 2009-08-28 12:25+0200\n"
"Last-Translator: Somebody <null@kde.org>\n"
"Language-Team: Some Language <kde-i18n-doc@kde.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Lokalize 1.0\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"

If you are working with a text editor do not remove the initial "msgid / msgstr". Otherwise, the compilation will terminate with a parse error. On the other hand, you should remove the "fuzzy" which is initially there.
The entries for Content-Type and the Transfer-Encoding are not relevant at the moment. But the charset should be set to UTF-8 in this case, i.e. 8bit Unicode Transfer Format.
The actual translation would look as follows. The original line:


#: kedit.cpp:90 kedit.cpp:1071
msgid "Show &Status Bar"
msgstr ""

...you would translate like this (assuming you were translating it to German):


#: kedit.cpp:90 kedit.cpp:1071
msgid "Show &Status Bar"
msgstr "&Statusleiste anzeigen"

And from the incorrect:


#: ReniceDlg.cpp:31
#, fuzzy
msgid "Renice Process"
msgstr "Laufende Prozesse"

...you would produce the correct translation:


#: ReniceDlg.cpp:31 
msgid "Renice Process"
msgstr "Neue Prozesspriorität"

After the corrections have been done you need to delete the "fuzzy" tag. Otherwise, the corrected string will just be ignored during compilation.
Finally there might be lines at the end of the file beginning with "#~" like this:


#~ msgid "Where do you want to go tomorrow?"
#~ msgstr "Where do you want to go tomorrow?"
#~ msgid "No comment available"
#~ msgstr "Keine Erklärung verfügbar"

These lines have been commented out, but may be used later on to translate messages should they reappear in program. If you want you can delete them from time to time in the interest of disk space and bandwidth. Lokalize, for instance, does not do this automatically.
For any other questions on this topic you are once more advised to look at the Info pages for the GNU gettext package (see the KDE on-line help).

Peculiarities and Difficulties
The KDE-specific handling of plural slightly differs from the standard Gettext way of handling plurals. For information you have to refer to the perfect article in TechBase.
We already mentioned that the characters "#" and "~" have special meaning. A few other things to watch out for are the following:
The "&" character in one of the examples above is used to mark an "accelerator key", ie a letter which in combination with Alt (on PC keyboards) will execute the command; i.e. Alt + S for "Show &Status Bar". You have to make sure that the same letter is not marked twice within one menu. See Compilation, Context and Accelerator Checks.
Special characters such as quotes must be "escaped" (i.e. preceded with a backslash), if you want to use them as part of the text (see example below).
Unescaped quotes will be interpreted by the programs which read the file as the end of the "msgstr". The test routine msgfmt --statistics --check-header, described below, would terminate at this point with an error. The syntax highlighting and the check routines in Lokalize will help you with the handling of these special characters.


#: cardmaps.cpp:105
#, c-format
msgid "kpat: PANIC, cannot load card pixmap \"%1\"\n"
msgstr "KPat: schwerer Fehler, Kartenbild \"%1\" kann nicht geladen werden\n"

One problem which languages with longer than average words (German, for example, is notorious here) sometimes encounter is dialog boxes which are too small, cutting off or cramming together translated text. This is one of the things that can only be determined for sure by checking the translations in the compiled program. The obvious, but always temporary, solution is to "keep it short." You would basically do this if there were no more time to pursue the proper solution, namely contacting the author of the program so that he/she can adjust the geometry of the offending boxes. In any case, an email describing the problem should be sent to the author or even better create a new bug report in KDE Bugs.
Sometimes English text appears in the program interface even though the PO file has been completely translated, and the text in question cannot even be found there.
One way this can happen is when the text comes from "somewhere else" (often from frameworks which can be found throughout the KDE interface, sometimes from separate modules of the same program that have extra POs or user interface files (.ui), resource files (.rc), configuration files (.kcfg), desktop files (.desktop), json files (.json) or even from ). Another possibility is that this particular text has not been made "i18n conform" by the author or simply not loaded by them.
Any strings which should be seen by the user are supposed to be passed to the C++ function QString i18n(const char *text). This ensures that the properly localized version of a string is shown (assuming there is a translation). Thus, it is only possible to translate texts which have been prepared in this manner. In cases where the untranslated text cannot be found in the PO file the author may have forgotten to do this. If you want to know for sure, you need to look in the source to the program; for example, you can find out the filename and line number by using grep -n "text in question" *.cpp in the source code folder.
Anyway, if you discover such a case, please file a bug at bugs.kde.org or write the author of the program. Do not just leave the problem unmentioned. If you are not sure about how the message should be improved, and how it may effect other languages, it will be reasonable to write to kde-i18n-doc@kde.org where the issue can be discussed with translators from other languages.

Using Specialized Programs for GUI Translation
There are several packages to assist you with practical GUI translation. They automatically search fuzzy or untranslated strings, present you with possible or comparable translations for a given string, and perform syntax, spell and other checks to ensure that the files will work correctly. At the moment, Lokalize is the only one that can really be recommended. You can also use Kate, Emacs, Vim, or VirTaal.

Lokalize
Developed by Nick Shaforostoff. The recommended package for GUI translation for the time being.
As of version 2.0 its contents and capabilities can be described as follows:
General Features:
User friendly, easy to understand and widely configurable user interface.
Every part of Lokalize comes with extensive context ("What's this") help that make every function easy to understand and to handle.
PO-File Editor:
Capability to open multiple files (on multiple tabs) as well as Translation Memory and Project Overview
Full editing functionality, accessible through the graphic user interface as well as through user definable keyboard shortcuts
Powerful spell checking functionality
Capability to show diffs to older messages
Full navigation capabilities (such as go to next fuzzy or untranslated string)
Simple access to powerful Translation Memory through F7
Unlimited undo capability
Syntax highlighting
Automatic file header updates
Automatic change of "fuzzy" status of translated messages
Support for easy insertion of tags and URLs through T
A "rough translation" function to initialize untranslated messages with suggestion from a Translation Memory
Automatic syntax check with msgfmt when saving
Full Drag & Drop - support
Configurable fonts for message editor
Quick overview over context in the po file
Showing source code by references in message comments
Project Overview:
File manager view for directories of the l10n module (or similarly structured) directories), showing the present status of all PO files: if they are in need of a revision or not, how many fuzzies and untranslated strings are included etc. This view is always automatically updated and reflects all changes done to the files, including changes by programs other than Lokalize.
Easy file open mechanisms for editing in Lokalize: double click, keyboard or context menu
Powerful navigation using PO file statistics
Automatic comparisons and statistics of POT and PO files for a quick overview which and how many files are translated (or not) and which files may be obsolete
Both the Lokalize Editor and the embedded Project Overview come with extensive "What's this" help that makes every function easy to understand and use. You can get the package from the kdesdk module of KDE

(X)Emacs in PO Mode
For ways to set this PO mode up with GNU Emacs, see the comments in the file po-mode.el that comes with the GNU gettext package. It also works with XEmacs if you set it up like this:
Copy po-mode.el (not the compiled .elc file) from the gettext package to a directory that's visible to XEmacs (e.g. /usr/X11R6/lib/xemacs/site-lisp/);
make the following entry at the beginning of the .emacs or, depending on your distribution, .xemacs-options file in your home directory: (autoload 'po-mode "po-mode")
and make the following new entry to Options -> Customize -> Variable -> auto-mode-alist: "\\.po[tx]?\\'\\|\\.po\\." (with the quotes) in the upper line and po-mode in the lower line (without any quotes).
The functionality is about as follows:
All important navigation features (go to next fuzzy, untranslated etc.)
Automatic insertion of (some) header data
Validation (checking if everything is formatted okay)
Lots of useful shortcuts for navigation, removing fuzzies etc.
Searching auxiliary-files for translations of a given string into other languages
Looking up strings in the sources
As always with Emacs, it takes some time to get used to it. (For instance, the buffer with the original text is kind of read-only and you have always to open a new buffer where you can work on your translation.) But for people who are used to Emacs or are willing to learn its ways, this mode can be a big help. Another factor might be that Emacs is apparently still one of the best ways to edit DocBook SGML which is also the format of KDE documentation. A very good introduction to working with Emacs in general and working with the SGML module in particular can be found as an Acrobat PDF file at www.snee.com/bob/sgmlfree/index.html
(Most info in the Emacs section thanks to Matthias Kiefer.)

Checking and Committing Your Work
Please, never commit a PO file to the SVN source tree without at least validating its syntax. Please also do the other checks described in this section. And do not forget about your spell checker.

Syntax Check: msgfmt --statistics --check-header
msgfmt --statistics --check-header /path/to/translated/files is the absolute minimum check you have to do on every file that you are about to send to your coordinator or to commit directly to SVN. What it does is give you either the number of (un)translated strings or the location and the nature of any formatting errors in your translated files. "msgfmt" (in case you are wondering) is part of the GNU gettext package.
Some specialized programs like Lokalize will assist you with this. Lokalize even contains an automated syntax check (among others) that saves you a lot of the work.
There are also nightly script (nicknamed Scripty) will run on the i18n server and also check the PO files. For wrong PO files, the script will tried to mark wrong entries as fuzzy, but it cannot report in the PO file more serious errors. Such errors are only reported to Scripty's log, which is publicly available. (The files are named like yymmdd.log where yy is the 2 digit year, mm the 2 digit month and dd the 2 digit day. As the logs are packed with full of information, a tip is to try to search all occurrences of your language code to get the corresponding errors.) You can spare yourself a lot of administrative work if you keep this from happening. And you can do this quite easy — you guessed it — by testing all your PO files yourself before committing them.

Checking for Missing Variables and Other Problems
Apart from syntax checks you also have to ensure that there are no problems in the following areas:
Context information: As pointed out before, PO files may contain comments on the exact meaning of a string (e.g. if "home" stands for the user directory, a key on the keyboard or the beginning of a line). This context information must not show up in your translation.
Arguments: Many strings show variables (%1, %2, %3...) which will be replaced with actual contents on runtime of the program. The variables of the original string must all show up in the translation (although not necessarily in the same order).
Equations: have to be balanced in the translation just the same as in the original.
Again, Lokalize provides automatic validation routines for all these possible issues. In recent versions, it also allows spell checking of your files.
Moreover, you cannot commit broken files using kdesvn: system just shows you the same error messages as msgfmt --statistics --check-header.

Syntax Check
Another major issue that can be found in translations is syntax violation. These issues cause wrong formatting of messages and even crashes of translated programs. To reveal this kind of issues you can use Pology. Please follow these instructions:
Run Lokalize (better with proper project opened)
Ensure python and python-dbus is installed
Run the following commands in konsole:

KDESVN=/home/your_account/hacking/kde/trunk/
KDESVNLANG=your_language_code
POLOGY=/your/clone/of/pology
cd $KDESVN/l10n-kf5/$KDESVNLANG
$POLOGY/scripts/posieve.py check-kde4 -s lokalize messages

of course you should adjust vars to your situation, and instead of running the check against whole messages/, you may want to specify e.g. messages/$project$.
After the last command Pology will open in Lokalize erroneous files and show feedback on errors in console output.
(Most info in this section thanks to Nick Shaforostoff.)

Compilation, Context and Accelerator Checks
To be able to check the translated packages in the context of the program interface, you have to generate the "(G)MO" files we mentioned above. This is accomplished by compiling the sub-folder of the l10n package appropriate to the translated language:
Change to the directory l10n-kf5 and compile the files with ../l10n-scripty/autogen.sh $LANGUAGE && cd $LANGUAGE && mkdir build && cd build && cmake .. && make (where $LANGUAGE is the language code)
In case there are any error you may want to try cmake .. && make -k; make -k docs; make -k install. With the -k parameter files and directories that do not compile are skipped. For more on this subject, see the info in the HOWTO section.
After su -c "make install" it should be possible to choose your language and to see your translation in the program interface (assuming you compiled the program also). Now you can start your context checks: Go through all menus and dialogs and check if all your translations make sense in their real environment. Make ready for some big surprises. Then correct your PO file, recompile and check again.
If you think that the mistakes in interface translation are due to the lack of context information in translation files, you should mail kde-i18n-doc mailing list so that authors or other competent persons add proper context and this doesn't happen to others.
These context checks are often neglected due to tight release schedules. But everybody who has seen how unprofessional and even ridiculous a whole program can look if it has a lot of out-of-context information in its menus will agree that these checks are among the most important things in the whole translation process.
Another test that can only be done after the translated program has been compiled is the check for "accelerator clashes".
As pointed out earlier, the "&" character in PO files is used to mark "accelerator keys" (a letter which in combination with Alt (on PC keyboards) will execute a command). Program authors and translators have to make sure that no accelerator key shows up twice in the same menu (e.g. that there is not something like "&Save" and "&Save as" but maybe "&Save" and "Save &as" ). In other words: you have to prevent "accelerator clashes".

Committing Your Work to SVN
After having checked their work, most translators will sent their completed translations to their language coordinator. The coordinator will usually check again and then commit their files to the main SVN server at svn.kde.org.
The necessary information on SVN and its graphical frontends is given in the section Taking a Look at Available Resources and SVN, including some hints about the commands and parameters needed.
You cannot commit a file if the SVN server has a more recent revision of the same file. In that case, you will probably need to use svn update to get the new version. SVN will merge it for you. You should check the result, as SVN merges only text files; it has not any idea about the syntax of a PO file. In some cases, you will get conflict, which you will need to fix (technically this is called "resolve").

SVN Conflicts
One thing to watch out for are version conflicts. When you update files by SVN, SVN will try to merge changes, if there are changes on both your local version of a file and the version of the SVN server of that file. SVN only merges text lines and this works normally well. But not always...
One kind of problems could be that the resulting file is not a valid PO file, as SVN has not any idea about the syntax of PO files, as for SVN, PO files are just a text files.
Another, more serious kind of problems is called a conflict. In that case, SVN gives up the merging, telling that it could not merge, as both the local change and the change of the server are on the same lines of a file. SVN remember that a conflict has happened and will refuse to commit the file until you have told SVN that the conflict was fixed.
In case of conflicts in text files, SVN tries to be helpful and puts special marks (lines with <, = and > characters) to help the user to see what are the conflicting change. It is your task as user to resolve (i.e. fix) the conflict. In the case of binary files, SVN cannot offer such a service, to avoid to corrupt the file.
For example:

# translation of granatier.po to Ukrainian
# Copyright (C) 2008-2009 This_file_is_part_of_KDE
# This file is distributed under the same license as the Granatier package.
#
# Yuri Chornoivan <yurchor@ukr.net>, 2008, 2009.
msgid ""
msgstr ""
"Project-Id-Version: granatier\n"
"Report-Msgid-Bugs-To: https://bugs.kde.org\n"
<<<<<<< .mine
"POT-Creation-Date: 2009-09-27 06:24+0200\n"
"PO-Revision-Date: 2009-09-27 10:00+0300\n"
=======
"POT-Creation-Date: 2009-09-27 06:24+0200\n"
"PO-Revision-Date: 2009-09-24 17:30+0300\n"
>>>>>>> .r1028458
"Last-Translator: Yuri Chornoivan <someaddress@ukr.net>\n"
"Language-Team: Ukrainian <nowhere@linux.org.ua>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Lokalize 0.3\n"

<<<<<<< .mine
#. i18n: file: generalsettings.ui:30
#. i18n: ectx: property (text), widget (QLabel, label_3)
#: rc.cpp:21 rc.cpp:89
msgid "Round Time in Seconds"
msgstr "Тривалість раунду у секундах"

#. i18n: file: generalsettings.ui:70
=======
#. i18n: file: generalsettings.ui:30
#. i18n: ectx: property (text), widget (QLabel, label_3)
#: rc.cpp:21 rc.cpp:89
msgid "Round Time in Seconds"
msgstr ""

#. i18n: file: generalsettings.ui:70
>>>>>>> .r1028458
#. i18n: ectx: property (text), widget (QLabel, label_2)
#: rc.cpp:24 rc.cpp:92
msgid "Points to win the game"
msgstr "Кількість очок, потрібна для виграшу"

Probably you wonder now how to solve such a problem. Normally you can try to solve it by using your normal tool, e.g. Lokalize. But sometimes, this is not possible and you need to use a text editor, e.g. Kate. An easy way of removing a conflict is to revert the file by the command svn revert. Another is to use one of the auxiliary files created by the update with have file names starting by the file name of the conflicting file. You can simply copy the version that you find correct instead of the file with a conflict.
When you have fixed the conflict, you need to tell SVN that you have fixed the conflict, so that SVN will allow you to commit the file. This can be done easily by svn resolved. (If you have chosen to revert the file, this step is not necessary, as SVN has already done it implicitly.)
Conflicts might appear often with PO files automatically merged by Scripty. Here a good solution is to keep working on the local version (so copy the corresponding file (.mine) over). Scripty will again work during the next European night and morning. But if you cannot wait you can do manual merge with templates. Just use the command ../l10n-scripty/merge_all.sh from your l10n-kf5/$LANGUAGE directory.