1 /* === This file is part of Calamares - <https://calamares.io> ===
2  *
3  *   SPDX-FileCopyrightText: 2014-2015 Teo Mrnjavac <teo@kde.org>
4  *   SPDX-FileCopyrightText: 2017-2019 Adriaan de Groot <groot@kde.org>
5  *   SPDX-License-Identifier: GPL-3.0-or-later
6  *
7  *   Calamares is Free Software: see the License-Identifier above.
8  *
9  *
10  */
11 
12 #ifndef LOCALE_TRANSLATION_H
13 #define LOCALE_TRANSLATION_H
14 
15 #include <QLocale>
16 #include <QObject>
17 #include <QString>
18 
19 namespace CalamaresUtils
20 {
21 namespace Locale
22 {
23 
24 /**
25  * @brief Consistent locale (language + country) naming.
26  *
27  * Support class to turn locale names (as used by Calamares's
28  * translation system) into QLocales, and also into consistent
29  * human-readable text labels.
30  *
31  * This handles special-cases in Calamares translations:
32  * - `sr@latin` is the name which Qt recognizes as `sr@latn`,
33  *   Serbian written with Latin characters (not Cyrillic).
34  * - `ca@valencia` is the Catalan dialect spoken in Valencia.
35  *   There is no Qt code for it.
36  */
37 class Translation : public QObject
38 {
39     Q_OBJECT
40 
41 public:
42     /** @brief Formatting option for label -- add (country) to label. */
43     enum class LabelFormat
44     {
45         AlwaysWithCountry,
46         IfNeededWithCountry
47     };
48 
49     struct Id
50     {
51         QString name;
52     };
53 
54     /** @brief Empty locale. This uses the system-default locale. */
55     Translation( QObject* parent = nullptr );
56 
57     /** @brief Construct from a locale name.
58      *
59      * The @p localeName should be one that Qt recognizes, e.g. en_US or ar_EY.
60      * The @p format determines whether the country name is always present
61      * in the label (human-readable form) or only if needed for disambiguation.
62      */
63     Translation( const Id& localeId, LabelFormat format = LabelFormat::IfNeededWithCountry, QObject* parent = nullptr );
64 
65 
66     /** @brief Define a sorting order.
67      *
68      * Locales are sorted by their id, which means the ISO 2-letter code + country.
69      */
70     bool operator<( const Translation& other ) const { return m_localeId < other.m_localeId; }
71 
72     /** @brief Is this locale English?
73      *
74      * en_US and en (American English) is defined as English. The Queen's
75      * English -- proper English -- is relegated to non-English status.
76      */
isEnglish()77     bool isEnglish() const { return m_localeId == QLatin1String( "en_US" ) || m_localeId == QLatin1String( "en" ); }
78 
79     /** @brief Get the human-readable name for this locale. */
label()80     QString label() const { return m_label; }
81     /** @brief Get the *English* human-readable name for this locale. */
englishLabel()82     QString englishLabel() const { return m_englishLabel; }
83 
84     /** @brief Get the Qt locale. */
locale()85     QLocale locale() const { return m_locale; }
86 
87     /** @brief Gets the Calamares internal name (code) of the locale.
88      *
89      * This is a strongly-typed return to avoid it ending up all over
90      * the place as a QString.
91      */
id()92     Id id() const { return { m_localeId }; }
93 
94     /// @brief Convenience accessor to the language part of the locale
language()95     QLocale::Language language() const { return m_locale.language(); }
96 
97     /// @brief Convenience accessor to the country part (if any) of the locale
country()98     QLocale::Country country() const { return m_locale.country(); }
99 
100     /** @brief Get a Qt locale for the given @p localeName
101      *
102      * This obeys special cases as described in the class documentation.
103      */
104     static QLocale getLocale( const Id& localeId );
105 
106 private:
107     QLocale m_locale;
108     QString m_localeId;  // the locale identifier, e.g. "en_GB"
109     QString m_label;  // the native name of the locale
110     QString m_englishLabel;
111 };
112 
113 }  // namespace Locale
114 }  // namespace CalamaresUtils
115 
116 #endif
117