C

Qt Quick Ultralite translation Example

// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial

import QtQuick 2.15
import QtQuickUltralite.Extras 2.0
import QtQuick.Controls 2.15
import fontconfiguration 1.0

Rectangle {
    id: root
    color: "#faf4e3"
    property int elideMode: Text.ElideNone
    property int textMaxWidth: textItemsTitle.width
    property color textsBackground: "transparent"

    property bool currentLanguageIsRTL : Qt.uiLanguage === "ar_SA"
    property bool currentLanguageIsComplexUnicodeScript : Qt.uiLanguage === "ar_SA" || Qt.uiLanguage === "th_TH"

    // Checks if currently selected font engine supports language.
    function languageSupportFilter(text: string) : string
    {
        if (FontConfiguration.isSpark) {
            // Spark supports all langauges
            return text;
        }
        // Static font engine does not support complex Unicode script based languages
        // in Text item.
        return currentLanguageIsComplexUnicodeScript ? "unsupported language" : text
    }

    readonly property font defaultFont: Qt.font({family: FontConfiguration.defaultFontFamily})
    readonly property font arabicFont: Qt.font({family: FontConfiguration.arabicFontFamily})
    readonly property font japaneseFont: Qt.font({family: FontConfiguration.japaneseFontFamily})
    readonly property font thaiFont: Qt.font({family: FontConfiguration.thaiFontFamily})

    function getFont() : font
    {
        var lang = Qt.uiLanguage
        switch (lang) {
            case "ja_JP": return japaneseFont;
            case "ar_SA": return arabicFont;
            case "th_TH": return thaiFont;
            default: return defaultFont;
        }
    }

    function flagForLanguage() : string
    {
        switch (Qt.uiLanguage) {
            case "lv_LV": return "latvia-flag-small.png"
            case "nb_NO": return "norway-flag-small.png"
            case "ja_JP": return "japan-flag-small.png"
            case "ar_SA": return "saudi-arabia-flag-small.png"
            case "th_TH": return "thai-flag-small.png"
            default: return "usa-flag-small.png";
        }
    }

    Column {
        spacing: -10
        anchors.right: parent.right
        anchors.rightMargin: 20
        anchors.top: parent.top
        anchors.topMargin: 33
        // MouseArea fills the entire window, bring
        // the CheckBoxes to the front.
        z: 1

        CheckBox {
            id: doElide
            checked: false
            text: "Elide text"
            onClicked: checked ? root.elideMode = Text.ElideRight : root.elideMode = Text.ElideNone
        }
        CheckBox {
            id: doBackground
            checked: false
            text: "Show text bounds"
            onClicked: checked ? root.textsBackground = "pink" : root.textsBackground = "transparent"
        }
    }

    Column {
        spacing: 14
        StaticText {
            width: root.width
            topPadding: 8
            textFormat: Text.StyledText
            text: qsTr("English language (US) <img src=\"usa-flag-small-icon.png\" width=\"38\" height=\"20\">")
        }

        Row {
            spacing: 30
            Item {} // dummy for spacing
            Image {
                readonly property bool horizontalScreen: root.width > root.height
                width: horizontalScreen ? root.width / 4 : root.width / 3
                height: horizontalScreen ? root.height / 4 : root.height / 8
                // If this application is build with, for example, only one translation
                // (see translation_lv.qmlproject), then only one of flag PNGs
                // is needed in the binary (registered with the resouce system).
                // By using a function here we prevent qmltocpp from trying to
                // resolve file paths to images at build-time. Instead
                // a code is generated that will try to resolve the path to
                // image at run-time.
                source: flagForLanguage()
            }
        }

        Row {
            spacing: 30
            // dummy item for spacing at the beginning
            Item {}

            Column {
                Text {
                    id: staticTextItemsTitle
                    text: "StaticText items"
                }

                Rectangle {
                    height: staticTextColumn.height
                    width: root.textMaxWidth
                    color: root.textsBackground
                    anchors.right: currentLanguageIsRTL ? parent.right : undefined
                    anchors.left: currentLanguageIsRTL ? undefined : parent.left
                    Column {
                        id: staticTextColumn
                        StaticText {
                            width: root.textMaxWidth
                            text: qsTr("orange", "color")
                        }
                        StaticText {
                            width: root.textMaxWidth
                            text: qsTr("orange", "fruit")
                        }
                        StaticText {
                            width: root.textMaxWidth
                            text: qsTr("sunrise")
                        }
                        StaticText {
                            // This string is not translated in the .ts files and
                            // will just fall back to the source string.
                            width: root.textMaxWidth
                            text: qsTr("hello")
                        }
                    }
                }
            }

            Column {
                Text {
                    id: textItemsTitle
                    text: "Text items"
                }

                Rectangle {
                    height: textColumn.height
                    width: root.textMaxWidth
                    color: root.textsBackground

                    Column {
                        id: textColumn

                        Text {
                            width: root.textMaxWidth
                            font: getFont()
                            elide: root.elideMode
                            text: languageSupportFilter(qsTr("orange", "color"))
                        }
                        Text {
                            width: root.textMaxWidth
                            font: getFont()
                            elide: root.elideMode
                            text: languageSupportFilter(qsTr("orange", "fruit"))
                        }
                        Text {
                            width: root.textMaxWidth
                            font: getFont()
                            elide: root.elideMode
                            text: languageSupportFilter(qsTr("sunrise"))
                        }
                        Text {
                            width: root.textMaxWidth
                            font: getFont()
                            elide: root.elideMode
                            // This string is not translated in the .ts files and
                            // will just fall back to the source string.
                            text: qsTr("hello")
                        }
                    }
                }
            }
        }
    }

    property bool allowLangSwitch : true

    // Disable language switching when this is compiled with
    // a single language.
    Component.onCompleted: allowLangSwitch = (Qt.uiLanguage == "")

    MouseArea {
        anchors.fill: parent
        onClicked: {
            if (!root.allowLangSwitch)
                return

            var lang = Qt.uiLanguage
            switch (lang) {
                case "nb_NO": lang = "lv_LV"; break;
                case "lv_LV": lang = "ja_JP"; break;
                case "ja_JP": lang = "ar_SA"; break;
                case "ar_SA": lang = "th_TH"; break;
                case "th_TH": lang = ""; break;
                default: lang = "nb_NO"; break;
            }
            Qt.uiLanguage = lang
        }
    }
}