Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Layout direction for Arabic is not determined based on the locale (Mac and Linux)

Has anyone managed to have the correct layout direction (left-to-right and right-to-left) be inferred from the user’s language settings?

I am having trouble localizing my application to the Arabic (Saudi Arabia) locale. Detection of the current locale, and loading and installing the appropriate QTranslators both work fine. (The text looks great on Linux!) The issue I have is that the global layout direction is not being inferred from the system locale.

The documentation for QApplication::layoutDirection states (with my highlights):

This property holds the default layout direction for this application. On system start-up, the default layout direction depends on the application's language.

This is not what happens, however: the layout is set to Qt::LeftToRight regardless of the system locale. I made a test program that displays the problem. It’s main function is:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTranslator translator;
    translator.load(":/layoutDirection.qm");
    a.installTranslator(&translator);

    Window w;
    w.show();

    return a.exec();
}

It also has a resource file containing the necessary images and translation files. It is defined like this:

<RCC>
    <!-- Arabic resources. The arrow points to the left. -->
    <qresource prefix="/" lang="ar">
        <file alias="arrow.png">images/arrow-rtl.png</file>
        <file alias="layoutDirection.qm">translations/layoutDirection_ar.qm</file>
    </qresource>
    <!-- English resources. The arrow points to the right. -->
    <qresource prefix="/" lang="en">
        <file alias="arrow.png">images/arrow-ltr.png</file>
        <file alias="layoutDirection.qm">translations/layoutDirection_en.qm</file>
    </qresource>
</RCC>

The source code of the Window class is trivial and the corresponding .ui file does not set the layoutDirection for any widget. When run on the English (United States) locale, the window looks like this:

English screenshot showing left-to-right layout, proper translation, and image of arrow pointing to the right

and when run on the Arabic (Saudi Arabia) locale, it looks like this:

Arabic screenshot showing wrong left-to-right layout, proper translation, and image of arrow pointing to the right

As you can see, the translation of the strings is correct and the image of the arrow points to the right, meaning that the correct resources were loaded. The layout direction is wrong: it should mirror the English layout.

Note. Since I don’t know the Arabic language, the example text is Google-translated. I apologize if it is incorrect.

Solution

Artyom's answer is correct and eventually led me to discovering how top-level Widgets determine their layout direction from the QApplication instance. The Internationalization with Qt manual says:

Qt itself contains several thousands of strings that will also need to be translated into the languages that you are targeting. You will find a number of translation files in the qttranslations repository.

The QApplication code has an interesting method, too:

static bool qt_detectRTLLanguage()
{
    return force_reverse ^
        (QGuiApplication::tr("QT_LAYOUT_DIRECTION",
                         "Translate this string to the string 'LTR' in left-to-right"
                         " languages or to 'RTL' in right-to-left languages (such as Hebrew"
                         " and Arabic) to get proper widget layout.") == QLatin1String("RTL"));
}

When the "QT_LAYOUT_DIRECTION" string is translated, the application will automatically detect its layout direction and everything works just fine:

Correct arabic layout on Linux

like image 943
andref Avatar asked Jul 29 '10 18:07

andref


1 Answers

As far as I know the layout direction should be set explicitly in Qt.

I know that GTK application do this automatically and qt does not and this is good thing.

I explain. Suppose you have untranslated application started in Arabic or Hebrew locale, what happens all layout displayed from right to left and everything looks ugly and not natural with RTL English stings. Think of untranslated IDE with RTL layout.

The trick to do this right, is to define a special translation key, so the original key has value LTR and only in translated applications to Arabic, Parisian or Hebrew it is translated to RTL.

So best would be something like that:

a.setLayoutDirection(tr("LTR")=="RTL" ? Qt::RightToLeft : Qt::LeftToRight)

And then the direction defined explicitly in the translation file.

So my good advice - from Hebrew speaker, do this the way I shown and don't try to do this automatically according to locale and regardless of actual translation.

like image 75
Artyom Avatar answered Oct 13 '22 00:10

Artyom