Käyttöliittymän lokalisointi Juha Järvensivu juha.jarvensivu@tut.fi 2008
Internatinalization Internationalization is the process of designing an application so that the user can run it using his or her cultural preferences without modifying or recompiling the code.
Lokalisoinnin painopisteitä Päiväys ja kellonaika Valuutta Kielet Puhelinnumerot ja osoitteet Mittayksiköt
Ongelmia Käyttöliittymään liitetyt tekstit ovat eri mittaisia eri kielillä kirjoitettuna Joissakin maissa luetaan vasemmalta oikealle Erikoismerkit esim ääkköset Kaikkialla ei ole käytössä sama kalenteri GregorianCalendar, JulianCalendar, JapaneseCalendar Päivämäärän formaatti ddmmyy, yymmdd Lukujen esittäminen desimaalipilkku vai -piste Merkkijonojen järjestäminen case-sensitive
Ratkaisuja Jaetaan käyttöliittymä kulttuuri-neutraaliin osaan ja lokalisoitavaan osaan Suuri osa ohjelmasta toimii suoraan kaikissa kulttuureissa Tallennetaan kulttuurisidonnaiset osat resurssitiedostoihin Uuden kulttuurin tukeminen ei vaadi muutoksia lähdekooditasolla
Kielen valinta Mitä kieltä ohjelma käyttää Voiko käyttäjä valita käytettävän kielen ohjelman asetuksista? Valitaanko kieli jo ohjelman asennusvaiheessa? Valitseeko ohjelma käytettävän kielen automaattisesti käyttöjärjestelmän kielen perusteella? Kaksikielisyyttä pitää välttää ohjelmassa ei saisi olla sekaisin esim suomen ja englannin kieltä
Yleisiä ohjeita lokalisointiin
1. Mieti minkälaista lokalisointia ohjelmalta mahdollisesti vaaditaan -Lokalisointi yleensä huomattavasti yksinkertaisempaa sukulaiskielille LTR vs RTL
2. Toteuta ohjelmaan tuki lokalisoinnille vaikka lokalisointia ei olisi tarkoitus heti tehdäkään - Vähäinenkin tuki helpottaa huomattavasti lokalisoinnin toteutusta jälkikäteen
3. Määrittele ohjelman merkkijonot omassa tiedostossaan (tai lue suoraan resurssitiedostosta) Esim. // Translations const String STR_BUTTON_OK = OK ; const String STR_BUTTON_CANCEL = Cancel ; const String STR_FILE_MENU = &File ; const String STR_FILE_ERROR = File cannot be read. ;
4. Suunnittele dialogin layout siten, että käännösteksteille jää riittävästi tilaa Rivitä pitkät UI-tekstit label = Teksti joka jakaantuu usealle riville label.wrap = true; Teksti joka jakaantuu usealle riville
5. Käytä painikkeissa ikoneita tekstin sijaan Ikonit voidaan toteuttaa vakiokokoisina UI-teksti voidaan näyttää esim tooltipvihjeenä
6. Noudata yhdenmukaista linjaa toimintojen nimeämisessä OK vs Ok File vs &File Entä jos samalla sanalla onkin useampi merkitys toisessa kielessä?
QT lokalisointi prosessi
Text engine QT:n sisään rakennettu tuki useille eri kielille All East Asian languages (Chinese, Japanese and Korean) All Western languages (using Latin script) Arabic Cyrillic languages (Russian, Ukrainian, etc.) Greek Hebrew Thai and Lao All scripts in Unicode 4.0 that do not require special processing QLineEdit ja QLabel toimivat automaattisesti oikein kaikille QT:n tukemille kielille
Tekstin määrittäminen aplikaatiossa QCoreApplication::translate(CONTEXT, SOURCE_TEXT, COMMENT) Esim QCoreApplication::translate( Menu text, &File, text shown on file menu ) QObject::tr( &File ); CONTEXT = luokan nimi Ei aseta kommenttia
Projekti file (.pro) Lisää projekti-fileen tarvittavat kielet TRANSLATIONS += arrowpad_en.ts TRANSLATIONS += arrowpad_fi.ts
lupdate - komento Käyttö: lupdate myproject.pro Etsii projektin koodeista käännettävät tekstit ja luo/päivittää translaatio tiedostot (ts-filet). Generoidut ts-filet annetaan kielitoimistolle, joka tekee käännökset Qt Linguist ohjelmalla.
Ts-file XML-tiedosto, joka sisältää käännettävät tekstit <!DOCTYPE TS><TS> <context> <name>menu text </name> <message> <source> &File </source> <translation type="unfinished"></translation> </message> <comment> text shown on file menu </comment> </context> </TS>
Käännöksen tekeminen QtLinguist ohjelmalla Onko kääntäjällä ajettava ohjelma käytössä vai pitääkö käännös tehdä annetun contekstin ja optionaalisen kommentin varassa?
Käännöksen tekeminen
Target locale Voidaan määrittää ts-filessä <!DOCTYPE TS><TS version="1.1" language="fi"> Jos ei ole määritetty, niin liguist yrittää arvata kielen tiedoston nimestä myapp_fi.ts
lrelease - komento Käyttö: lrelease myproject.pro Muuntaa xml-muotoiset ts-filet binääri muotoon (qm-file) Sovellus käyttää lokalisoitua tekstiä qmfilestä, jos sellainen löytyy lrelease hyväksyy vain ne merkkijonot, jotka ovat tyyppiä finished.
Translaation käyttöönotto int main(int argc, char *argv[]) { QApplication app(argc, argv); QTranslator translator; translator.load("hellotr_la"); app.installtranslator(&translator); QPushButton hello(qpushbutton::tr("hello world!")); hello.resize(100, 30); hello.show(); return app.exec(); }
Translaation käyttöönotto int main(int argc, char *argv[]) { } QApplication app(argc, argv); QString locale = QLocale::system().name(); QTranslator translator; translator.load(qstring("arrowpad_") + locale); app.installtranslator(&translator);
Dynaaminen translaatio void QWidget::changeEvent(QEvent *event) { if (e->type() == QEvent::LanguageChange) { titlelabel->settext(tr("document Title")); okpushbutton->settext(tr("&ok")); } else { QWidget::changeEvent(event); } }
QLocale Muuntaa numerojen ja niiden merkkijonomuotoisen esitystavan kahden kielen välillä QLocale egyptian(qlocale::arabic, QLocale::Egypt); QString s1 = egyptian.tostring(1.571429e+07, 'e'); QString s2 = egyptian.tostring(10); double d = egyptian.todouble(s1); int i = egyptian.toint(s2);
QLocale double d; QLocale::setDefault(QLocale::C); d = QString("1234,56").toDouble(&ok); // ok == false d = QString("1234.56").toDouble(&ok); // ok == true QLocale::setDefault(QLocale::German); d = QString("1234,56").toDouble(&ok); // ok == true d = QString("1234.56").toDouble(&ok); // ok == true
Päivämäärän ja ajan formaatti QDate, QTime, QDateTime QString QDate::toString(Qt::DateFormat df); Palauttaa lokalisoidun päivämäärän merkkijonona Käyttöjärjestelmän käyttämä formaatti Qt::SystemLocaleShortDate Qt::SystemLocaleLongDate QT:n application locale formaatti Qt::DefaultLocaleShortDate Qt::DefaultLocaleLongDate
Dynaaminen teksti void showprogress(int done, int total, const QString ¤tfile) { } label.settext(tr("%1 of %2 files copied.\ncopying: %3").arg(done).arg(total).arg(currentFile));
Lähteet Qt Assistant - Internationalization with Qt