diff options
Diffstat (limited to 'doc/i18n.doc')
-rw-r--r-- | doc/i18n.doc | 593 |
1 files changed, 593 insertions, 0 deletions
diff --git a/doc/i18n.doc b/doc/i18n.doc new file mode 100644 index 000000000..d9b7a7ef2 --- /dev/null +++ b/doc/i18n.doc @@ -0,0 +1,593 @@ +/**************************************************************************** +** +** Explanation of moc and the meta object system +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Qt GUI Toolkit. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing retquirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** This file may be used under the terms of the Q Public License as +** defined by Trolltech ASA and appearing in the file LICENSE.QPL +** included in the packaging of this file. Licensees holding valid Qt +** Commercial licenses may use this file in accordance with the Qt +** Commercial License Agreement provided with the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +/*! \defgroup i18n + +\title Internationalization with Qt + +\keyword internationalization +\keyword i18n + +The internationalization of an application is the process of making +the application usable by people in countries other than one's own. + +\tableofcontents + +In some cases internationalization is simple, for example, making a US +application accessible to Australian or British users may retquire +little more than a few spelling corrections. But to make a US +application usable by Japanese users, or a Korean application usable +by German users, will retquire that the software operate not only in +different languages, but use different input techniques, character +encodings and presentation conventions. + +Qt tries to make internationalization as painless as possible for +developers. All input widgets and text drawing methods in Qt offer +built-in support for all supported languages. The built-in font engine +is capable of correctly and attractively rendering text that contains +characters from a variety of different writing systems at the same +time. + +Qt supports most languages in use today, in particular: +\list +\i All East Asian languages (Chinese, Japanese and Korean) +\i All Western languages (using Latin script) +\i Arabic +\i Cyrillic languages (Russian) +\i Greek +\i Hebrew +\i Thai and Lao +\i All scripts in Unicode 3.2 that do not retquire special processing +\endlist + +On Windows NT/2000/XP and Unix/X11 with Xft (client side font support) +the following languages are also supported: +\list +\i Bengali +\i Devanagari +\i Dhivehi (Thaana) +\i Gujarati +\i Gurmukhi +\i Kannada +\i Khmer +\i Malayalam (X11 only) +\i Myanmar (X11 only) +\i Syriac +\i Tamil +\i Telugu +\i Tibetan (X11 only) +\endlist + +Many of these writing systems exhibit special features: + +\list + +\i <b>Special line breaking behavior.</b> Some of the Asian languages are +written without spaces between words. Line breaking can occur either +after every character (with exceptions) as in Chinese, Japanese and +Korean, or after logical word boundaries as in Thai. + +\i <b>Bidirectional writing.</b> Arabic and Hebrew are written from right to +left, except for numbers and embedded English text which is written +left to right. The exact behavior is defined in the \link +http://www.unicode.org/unicode/reports/tr9/ Unicode Technical Report +#9 \endlink. + +\i <b>Non spacing or diacritical marks</b> (accents or umlauts in European +languages). Some languages such as Vietnamese make extensive use of +these marks and some characters can have more than one mark at the +same time to clarify pronunciation. + +\i <b>Ligatures.</b> In special contexts, some pairs of characters get +replaced by a combined glyph forming a ligature. Common examples are +the fl and fi ligatures used in typesetting US and European books. + +\endlist + +Qt tries to take care of all the special features listed above. You +usually don't have to worry about these features so long as you use +Qt's input widgets (e.g. QLineEdit, QTextEdit, and derived classes) +and Qt's display widgets (e.g. QLabel). + +Support for these writing systems is transparent to the programmer +and completely encapsulated in Qt's text engine. This means that you +don't need to have any knowledge about the writing system used in a +particular language, except for the following small points: +\list + +\i QPainter::drawText( int x, int y, const QString &str ) will always +draw the string with it's left edge at the position specified with +the x, y parameters. This will usually give you left aligned strings. +Arabic and Hebrew application strings are usually right +aligned, so for these languages use the version of drawText() that +takes a QRect since this will align in accordance with the language. + +\i When you write your own text input controls, use \l +QFontMetrics::charWidth() to determine the width of a character in a +string. In some languages (e.g. Arabic or languages from the Indian +subcontinent), the width and shape of a glyph changes depending on the +surrounding characters. Writing input controls usually retquires a +certain knowledge of the scripts it is going to be used in. Usually +the easiest way is to subclass QLineEdit or QTextEdit. + +\endlist + +The following sections give some information on the status +of the internationalization (i18n) support in Qt. + +See also the \link linguist-manual.book Qt Linguist\endlink manual. + +\section1 Step by Step + +Writing multi-platform international software with Qt is a gentle, +incremental process. Your software can become internationalized in +the following stages: + +\section2 Use QString for all User-visible Text + +Since QString uses the Unicode encoding internally, every +language in the world can be processed transparently using +familiar text processing operations. Also, since all Qt +functions that present text to the user take a QString as a +parameter, there is no char* to QString conversion overhead. + +Strings that are in "programmer space" (such as QObject names +and file format texts) need not use QString; the traditional +char* or the QCString class will suffice. + +You're unlikely to notice that you are using Unicode; +QString, and QChar are just like easier versions of the crude +const char* and char from traditional C. + +\section2 Use tr() for all Literal Text + +Wherever your program uses \c{"quoted text"} for text that will +be presented to the user, ensure that it is processed by the \l +QApplication::translate() function. Essentially all that is necessary +to achieve this is to use \l QObject::tr(). For example, assuming the +\c LoginWidget is a subclass of QWidget: + +\code + LoginWidget::LoginWidget() + { + QLabel *label = new QLabel( tr("Password:"), this ); + ... + } +\endcode + +This accounts for 99% of the user-visible strings you're likely to +write. + +If the quoted text is not in a member function of a +QObject subclass, use either the tr() function of an +appropriate class, or the QApplication::translate() function +directly: + +\code + void some_global_function( LoginWidget *logwid ) + { + QLabel *label = new QLabel( + LoginWidget::tr("Password:"), logwid ); + } + + void same_global_function( LoginWidget *logwid ) + { + QLabel *label = new QLabel( + qApp->translate("LoginWidget", "Password:"), + logwid ); + } +\endcode + +If you need to have translatable text completely +outside a function, there are two macros to help: QT_TR_NOOP() +and QT_TRANSLATE_NOOP(). They merely mark the text for +extraction by the \e lupdate utility described below. +The macros expand to just the text (without the context). + +Example of QT_TR_NOOP(): +\code + QString FriendlyConversation::greeting( int greet_type ) + { + static const char* greeting_strings[] = { + QT_TR_NOOP( "Hello" ), + QT_TR_NOOP( "Goodbye" ) + }; + return tr( greeting_strings[greet_type] ); + } +\endcode + +Example of QT_TRANSLATE_NOOP(): +\code + static const char* greeting_strings[] = { + QT_TRANSLATE_NOOP( "FriendlyConversation", "Hello" ), + QT_TRANSLATE_NOOP( "FriendlyConversation", "Goodbye" ) + }; + + QString FriendlyConversation::greeting( int greet_type ) + { + return tr( greeting_strings[greet_type] ); + } + + QString global_greeting( int greet_type ) + { + return qApp->translate( "FriendlyConversation", + greeting_strings[greet_type] ); + } +\endcode + +If you disable the const char* to QString automatic conversion +by compiling your software with the macro QT_NO_CAST_ASCII +defined, you'll be very likely to catch any strings you are +missing. See QString::fromLatin1() for more information. +Disabling the conversion can make programming a bit cumbersome. + +If your source language uses characters outside Latin-1, you +might find QObject::trUtf8() more convenient than +QObject::tr(), as tr() depends on the +QApplication::defaultCodec(), which makes it more fragile than +QObject::trUtf8(). + +\section2 Use QKeySequence() for Accelerator Values + +Accelerator values such as Ctrl+Q or Alt+F need to be +translated too. If you hardcode \c CTRL+Key_Q for "Quit" in +your application, translators won't be able to override +it. The correct idiom is + +\code + QPopupMenu *file = new QPopupMenu( this ); + file->insertItem( tr("&Quit"), this, SLOT(tquit()), + QKeySequence(tr("Ctrl+Q", "File|Quit")) ); +\endcode + +\section2 Use QString::arg() for Dynamic Text + +The QString::arg() functions offer a simple means for substituting +arguments: +\code + void FileCopier::showProgress( int done, int total, + const QString& current_file ) + { + label.setText( tr("%1 of %2 files copied.\nCopying: %3") + .arg(done) + .arg(total) + .arg(current_file) ); + } +\endcode + +In some languages the order of arguments may need to change, and this +can easily be achieved by changing the order of the % arguments. For +example: +\code + QString s1 = "%1 of %2 files copied. Copying: %3"; + QString s2 = "Kopierer nu %3. Av totalt %2 filer er %1 kopiert."; + + qDebug( s1.arg(5).arg(10).arg("somefile.txt").ascii() ); + qDebug( s2.arg(5).arg(10).arg("somefile.txt").ascii() ); +\endcode + +produces the correct output in English and Norwegian: +\code +5 of 10 files copied. Copying: somefile.txt +Kopierer nu somefile.txt. Av totalt 10 filer er 5 kopiert. +\endcode + +\section2 Produce Translations + +Once you are using tr() throughout an application, you can start +producing translations of the user-visible text in your program. + +\link linguist-manual.book Qt Linguist\endlink's manual provides +further information about Qt's translation tools, \e{Qt Linguist}, \e +lupdate and \e lrelease. + +Translation of a Qt application is a three-step process: + +\list 1 + +\i Run \e lupdate to extract translatable text from the C++ source +code of the Qt application, resulting in a message file for +translators (a \c .ts file). The utility recognizes the tr() construct +and the QT_*_NOOP macros described above and produces \c .ts files +(usually one per language). + +\i Provide translations for the source texts in the \c .ts file, using +\e{Qt Linguist}. Since \c .ts files are in XML format, you can also +edit them by hand. + +\i Run \e lrelease to obtain a light-weight message file (a \c .qm +file) from the \c .ts file, suitable only for end use. Think of the \c +.ts files as "source files", and \c .qm files as "object files". The +translator edits the \c .ts files, but the users of your application +only need the \c .qm files. Both kinds of files are platform and +locale independent. + +\endlist + +Typically, you will repeat these steps for every release of your +application. The \e lupdate utility does its best to reuse the +translations from previous releases. + +Before you run \e lupdate, you should prepare a project file. Here's +an example project file (\c .pro file): + +\code + HEADERS = funnydialog.h \ + wackywidget.h + SOURCES = funnydialog.cpp \ + main.cpp \ + wackywidget.cpp + FORMS = fancybox.ui + TRANSLATIONS = superapp_dk.ts \ + superapp_fi.ts \ + superapp_no.ts \ + superapp_se.ts +\endcode + +When you run \e lupdate or \e lrelease, you must give the name of the +project file as a command-line argument. + +In this example, four exotic languages are supported: Danish, Finnish, +Norwegian and Swedish. If you use \link qmake-manual.book +qmake\endlink, you usually don't need an extra project +file for \e lupdate; your \c qmake project file will work fine once +you add the \c TRANSLATIONS entry. + +In your application, you must \l QTranslator::load() the translation +files appropriate for the user's language, and install them using \l +QApplication::installTranslator(). + +If you have been using the old Qt tools (\c findtr, \c msg2qm and \c +mergetr), you can use \e qm2ts to convert your old \c .qm files. + +\e linguist, \e lupdate and \e lrelease are installed in the \c bin +subdirectory of the base directory Qt is installed into. Click Help|Manual +in \e{Qt Linguist} to access the user's manual; it contains a tutorial +to get you started. + +While these utilities offer a convenient way to create \c .qm files, +any system that writes \c .qm files is sufficient. You could make an +application that adds translations to a QTranslator with +QTranslator::insert() and then writes a \c .qm file with +QTranslator::save(). This way the translations can come from any +source you choose. + +\target qt-itself +Qt itself contains over 400 strings that will also need to be +translated into the languages that you are targeting. You will find +translation files for French and German in \c $QTDIR/translations as +well as a template for translating to other languages. (This directory +also contains some additional unsupported translations which may be +useful.) + +Typically, your application's main() function will look like this: +\code + int main( int argc, char **argv ) + { + QApplication app( argc, argv ); + + // translation file for Qt + QTranslator qt( 0 ); + qt.load( QString( "qt_" ) + QTextCodec::locale(), "." ); + app.installTranslator( &qt ); + + // translation file for application strings + QTranslator myapp( 0 ); + myapp.load( QString( "myapp_" ) + QTextCodec::locale(), "." ); + app.installTranslator( &myapp ); + + ... + + return app.exec(); + } +\endcode + +\section2 Support for Encodings + +The QTextCodec class and the facilities in QTextStream make it easy to +support many input and output encodings for your users' data. When an +application starts, the locale of the machine will determine the 8-bit +encoding used when dealing with 8-bit data: such as for font +selection, text display, 8-bit text I/O and character input. + +The application may occasionally retquire encodings other than the +default local 8-bit encoding. For example, an application in a +Cyrillic KOI8-R locale (the de-facto standard locale in Russia) might +need to output Cyrillic in the ISO 8859-5 encoding. Code for this +would be: + +\code + QString string = ...; // some Unicode text + + QTextCodec* codec = QTextCodec::codecForName( "ISO 8859-5" ); + QCString encoded_string = codec->fromUnicode( string ); + + ...; // use encoded_string in 8-bit operations +\endcode + +For converting Unicode to local 8-bit encodings, a shortcut is +available: the \link QString::local8Bit() local8Bit\endlink() method +of QString returns such 8-bit data. Another useful shortcut is the +\link QString::utf8() utf8\endlink() method, which returns text in the +8-bit UTF-8 encoding: this perfectly preserves Unicode information +while looking like plain US-ASCII if the text is wholly US-ASCII. + +For converting the other way, there are the QString::fromUtf8() and +QString::fromLocal8Bit() convenience functions, or the general code, +demonstrated by this conversion from ISO 8859-5 Cyrillic to Unicode +conversion: + +\code + QCString encoded_string = ...; // Some ISO 8859-5 encoded text. + + QTextCodec* codec = QTextCodec::codecForName("ISO 8859-5"); + QString string = codec->toUnicode(encoded_string); + + ...; // Use string in all of Qt's QString operations. +\endcode + +Ideally Unicode I/O should be used as this maximizes the portability +of documents between users around the world, but in reality it is +useful to support all the appropriate encodings that your users will +need to process existing documents. In general, Unicode (UTF-16 or +UTF-8) is best for information transferred between arbitrary people, +while within a language or national group, a local standard is often +more appropriate. The most important encoding to support is the one +returned by QTextCodec::codecForLocale(), as this is the one the user +is most likely to need for communicating with other people and +applications (this is the codec used by local8Bit()). + +Qt supports most of the more frequently used encodings natively. For a +complete list of supported encodings see the \l QTextCodec +documentation. + +In some cases and for less frequently used encodings it may be +necessary to write your own QTextCodec subclass. Depending on the +urgency, it may be useful to contact Trolltech technical support or +ask on the \c qt-interest mailing list to see if someone else is +already working on supporting the encoding. A useful interim measure +can be to use the QTextCodec::loadCharmapFile() function to build a +data-driven codec, although this approach has a memory and speed +penalty, especially with dynamically loaded libraries. For details of +writing your own QTextCodec, see the main QTextCodec class +documentation. + +\keyword localization + +\section2 Localize + +Localization is the process of adapting to local conventions, for +example presenting dates and times using the locally preferred +formats. Such localizations can be accomplished using appropriate tr() +strings. + +\code + void Clock::setTime(const QTime& t) + { + if ( tr("AMPM") == "AMPM" ) { + // 12-hour clock + } else { + // 24-hour clock + } + } +\endcode + +In the example, for the US we would leave the translation of "AMPM" as +it is and thereby use the 12-hour clock branch; but in Europe we would +translate it as something else (anything else, e.g. "EU") and this +will make the code use the 24-hour clock branch. + +Localizing images is not recommended. Choose clear icons that are +appropriate for all localities, rather than relying on local puns or +stretched metaphors. + +\section1 Dynamic Translation + +Some applications, such as Qt Linguist, must be able to support changes +to the user's language settings while they are still running. To make +widgets aware of changes to the system language, implement a public +slot called \c languageChange() in each widget that needs to be notified. +In this slot, you should update the text displayed by widgets using the +\l{QObject::tr()}{tr()} function in the usual way; for example: + +\code +void MyWidget::languageChange() +{ + titleLabel->setText(tr("Document Title")); + ... + okPushButton->setText(tr("&OK")); +} +\endcode + +The default event handler for QWidget subclasses responds to the +\link QEvent::Type LanguageChange\endlink event, and will call this slot +when necessary; other application components can also connect signals +to this slot to force widgets to update themselves. + +\section1 System Support + +Some of the operating systems and windowing systems that Qt runs on +only have limited support for Unicode. The level of support available +in the underlying system has some influence on the support that Qt can +provide on those platforms, although in general Qt applications need +not be too concerned with platform-specific limitations. + +\section2 Unix/X11 + +\list +\i Locale-oriented fonts and input methods. Qt hides these and + provides Unicode input and output. +\i Filesystem conventions such as + \link http://www.ietf.org/rfc/rfc2279.txt UTF-8 \endlink + are under development + in some Unix variants. All Qt file functions allow Unicode, + but convert filenames to the local 8-bit encoding, as + this is the Unix convention + (see QFile::setEncodingFunction() + to explore alternative encodings). +\i File I/O defaults to the local 8-bit encoding, + with Unicode options in QTextStream. +\endlist + +\section2 Windows + +\list +\i Qt provides full Unicode support, including input methods, fonts, + clipboard, drag-and-drop and file names. +\i File I/O defaults to Latin-1, with Unicode options in QTextStream. + Note that some Windows programs do not understand big-endian + Unicode text files even though that is the order prescribed by + the Unicode Standard in the absence of higher-level protocols. +\i Unlike programs written with MFC or plain winlib, Qt programs + are portable between Windows 95/98 and Windows NT. + \e {You do not need different binaries to support Unicode.} +\endlist + +\section1 Note about Locales on X11 + +Many Unix distributions contain only partial support for some locales. +For example, if you have a \c /usr/share/locale/ja_JP.EUC directory, +this does not necessarily mean you can display Japanese text; you also +need JIS encoded fonts (or Unicode fonts), and the \c +/usr/share/locale/ja_JP.EUC directory needs to be complete. For best +results, use complete locales from your system vendor. + +\section1 Relevant Qt Classes + +These classes are relevant to internationalizing Qt applications. +*/ |