Internationalization

From WxWiki
Revision as of 19:36, 19 October 2018 by Tierra (talk | contribs) (Text replacement - "<source>" to "<syntaxhighlight lang="cpp">")
Jump to navigation Jump to search

Internationalization

Also see the Internationalization section in the official docs, and wxWidgets "internat" sample

Other than text internationalization features are weak or missing. (e.g. Money formatting)


Getting started

Start by selecting which strings are translatable and mark them with the _() macro.

// example : 'Hello World' is flagged as translatable
wxMessageBox( _("Hello World") );

Once translatable strings are marked, you can extract the strings into a catalog using GNU gettext (you'll need to have it installed to extract the string catalog using the UNIX commands provided below, however your user will not need to have it installed since support is built inside wx).

# example sh script to generate catalog file
# it searches for strings marked with _() in all .cpp files in directory ./src
# the generated file is called 'app_name.pot' and is generated in ./po
CPP_FILE_LIST=`find ./src -name '*.cpp' -print`
xgettext -d app_name -s --keyword=_ -p ./po -o app_name.pot $CPP_FILE_LIST

Catalog editors may also be able to extract strings, however the process is less automatized this way.

Translating what's in the catalog

Once you have the .pot catalog, you can edit it in your favorite catalog editor. Here poEdit is the one used.

Starting a translation to a new language

  • Use menu 'File > New catalog from POT file'
  • Select the .pot catalog file
  • Enter appropriate information about yourself and the language
  • Translate the strings and save the file as a .po.

Updating an existing translation with latest strings updates

  • Open the .po file in poEdit
  • Choose menu 'Catalog > update from POT file'
  • Select the .pot catalog file

Data file organization

To be translated, your program must first have a catalog name, say "myprogram". This is just an identifier for your language files, nothing more.

There will be a directory on your system for installed languages, with a subdirectory for each language, for example 'nl' for Dutch.

  • Windows : these directories typically come under the application directory. So, if your program is translated into Dutch there will be a file localedir\nl\myprogram.mo.
  • Linux/Unix : generally {prefix}/share/locale/[lang code]/LC_MESSAGES/app_name.mo
  • Mac OS X : {App name}.app/Contents/Resources/[lang code].lproj/app_name.mo
    • Note that you should create an empty folder named en.lproj (if your app is natively in English) so that the system knows this language is supported even though you have no .mo file for this language

Your installer should take care of placing the language files in the appropriate directories.

You can check language codes here : http://xml.coverpages.org/iso639a.html

Getting it inside your app

Use code similar to this :

wxLocale* locale;
long language;

void initLanguageSupport()
{
    language =  wxLANGUAGE_DEFAULT;

    // fake functions, use proper implementation
    if( userWantsAnotherLanguageThanDefault() )
        language = getUsersFavoriteLanguage();
       
    // load language if possible, fall back to english otherwise
    if(wxLocale::IsAvailable(language))
    {
        locale = new wxLocale( language, wxLOCALE_CONV_ENCODING );

        #ifdef __WXGTK__
        // add locale search paths
        locale->AddCatalogLookupPathPrefix(wxT("/usr"));
        locale->AddCatalogLookupPathPrefix(wxT("/usr/local"));
        wxStandardPaths* paths = (wxStandardPaths*) &wxStandardPaths::Get();
        wxString prefix = paths->GetInstallPrefix();
        locale->AddCatalogLookupPathPrefix( prefix );
        #endif

        locale->AddCatalog(wxT("app_name"));

        if(! locale->IsOk() )
        {
            std::cerr << "selected language is wrong" << std::endl;
            delete locale;
            locale = new wxLocale( wxLANGUAGE_ENGLISH );
            language = wxLANGUAGE_ENGLISH;
        }
    }
    else
    {
        std::cout << "The selected language is not supported by your system."
                  << "Try installing support for this language." << std::endl;
        locale = new wxLocale( wxLANGUAGE_ENGLISH );
        language = wxLANGUAGE_ENGLISH;
    }

}

For other languages to work, you'll need your .po files compiled as .mo files (.mo translation files are binary versions of .po files) . poEdit will do it automatically upon saving if the appropriate option is checked in the preferences.

Support for RTL (right-to-left) languages

See http://wxwidgets.blogspot.com/2006/10/right-to-left-layout-rtl-support-in.html

See also

See also: Unicode, WxWidgets Source Oddities