MythTV master
langsettings.cpp
Go to the documentation of this file.
1
2#include "langsettings.h"
3
4// qt
5#include <QEventLoop>
6#include <QDir>
7#include <QFileInfo>
8
9// libmythbase
10#include "libmythbase/iso3166.h"
11#include "libmythbase/iso639.h"
18
19// libmythui
24
26 :MythScreenType(parent, "LanguageSelection"),
27 m_exitOnFinish(exitOnFinish),
28 m_language(gCoreContext->GetSetting("Language")),
29 m_country(gCoreContext->GetSetting("Country"))
30{
31 if (exitOnFinish)
32 {
33 m_loop = new QEventLoop();
34 }
35}
36
38{
40 {
41 delete m_loop;
42 }
43}
44
46{
47 if (!LoadWindowFromXML("config-ui.xml", "languageselection", this))
48 return false;
49
50 bool err = false;
51 UIUtilE::Assign(this, m_languageList, "languages", &err);
52 UIUtilE::Assign(this, m_countryList, "countries", &err);
53 UIUtilE::Assign(this, m_saveButton, "save", &err);
54 UIUtilE::Assign(this, m_cancelButton, "cancel", &err);
55
56 if (err)
57 {
58 LOG(VB_GENERAL, LOG_ALERT,
59 "Cannot load screen 'languageselection'");
60 return false;
61 }
62
63#if 0
64 connect(m_countryList, &MythUIButton::Clicked, this, &LanguageSelection::LocaleClicked);
65 connect(m_languageList, &MythUIButton::Clicked, this, &LanguageSelection::LanguageClicked);
66#endif
67
70
71 m_languageList->SetLCDTitles(tr("Preferred language"), "");
72 m_countryList->SetLCDTitles(tr("Your location"), "");
73
75
76 return true;
77}
78
80{
81 auto *locale = new MythLocale();
82
83 QString langCode;
84
86 {
87 // If the global MythLocale instance exists, then we should use it
88 // since it's informed by previously chosen values from the
89 // database.
90 *locale = *gCoreContext->GetLocale();
91 }
92 else
93 {
94 // If no global MythLocale instance exists then we're probably
95 // bootstrapping before the database is available, in that case
96 // we want to load language from the locale XML defaults if they
97 // exist.
98 // e.g. the locale defaults might define en_GB for Australia which has
99 // no translation of it's own. We can't automatically derive en_GB
100 // from en_AU which MythLocale will arrive at and there is no 'en'
101 // translation.
102 langCode = locale->GetLocaleSetting("Language");
103 }
104
105 if (langCode.isEmpty())
106 langCode = locale->GetLanguageCode();
107 QString localeCode = locale->GetLocaleCode();
108 QString countryCode = locale->GetCountryCode();
109
110 LOG(VB_GENERAL, LOG_INFO,
111 QString("System Locale (%1), Country (%2), Language (%3)")
112 .arg(localeCode, countryCode, langCode));
113
114 QMap<QString,QString> langMap = MythTranslation::getLanguages();
115 QStringList langs = langMap.values();
116 langs.sort();
117 bool foundLanguage = false;
118 for (const auto& nativeLang : std::as_const(langs))
119 {
120 QString code = langMap.key(nativeLang); // Slow, but map is small
121 QString language = GetISO639EnglishLanguageName(code);
122 auto *item = new MythUIButtonListItem(m_languageList, nativeLang);
123 item->SetText(language, "language");
124 item->SetText(nativeLang, "nativelanguage");
125 item->SetData(code);
126
127 // We have to compare against locale for languages like en_GB
128 if (code.toLower() == m_language.toLower() ||
129 code == langCode || code == localeCode)
130 {
132 foundLanguage = true;
133 }
134 }
135
136 if (m_languageList->IsEmpty())
137 {
138 LOG(VB_GUI, LOG_ERR, "ERROR - Failed to load translations, at least "
139 "one translation file MUST be installed.");
140
141 auto *item = new MythUIButtonListItem(m_languageList,
142 "English (United States)");
143 item->SetText("English (United States)", "language");
144 item->SetText("English (United States)", "nativelanguage");
145 item->SetData("en_US");
146 }
147
148 if (!foundLanguage)
150
152 QStringList locales = localesMap.values();
153 locales.sort();
154 for (const auto& country : std::as_const(locales))
155 {
156 QString code = localesMap.key(country); // Slow, but map is small
157 QString nativeCountry = GetISO3166CountryName(code);
158 auto *item = new MythUIButtonListItem(m_countryList, country);
159 item->SetData(code);
160 item->SetText(country, "country");
161 item->SetText(nativeCountry, "nativecountry");
162 item->SetImage(QString("locale/%1.png").arg(code.toLower()));
163
164 if (code == m_country || code == countryCode)
166 }
167
168 delete locale;
169}
170
172
174{
175 m_languageChanged = false;
176 QString language = gCoreContext->GetSetting("Language", "");
177 QString country = gCoreContext->GetSetting("Country", "");
178 // Ask for language if we don't already know.
179 if (force || language.isEmpty() || country.isEmpty())
180 {
182 if (!mainStack)
183 return false;
184
185 auto *langSettings = new LanguageSelection(mainStack, true);
186
187 if (langSettings->Create())
188 {
189 mainStack->AddScreen(langSettings, false);
190 langSettings->m_loop->exec();
191 mainStack->PopScreen(langSettings, false);
192 }
193 else
194 {
195 delete langSettings;
196 }
197 }
198
199 return m_languageChanged;
200}
201
203{
205
206 if (!item)
207 {
208 Close();
209 LOG(VB_GUI, LOG_ERR,
210 "LanguageSelection::Save called without current languageList");
211 return;
212 }
213
214 QString langCode = item->GetData().toString();
215 gCoreContext->SaveSetting("Language", langCode);
216
218
219 if (!item)
220 {
221 Close();
222 LOG(VB_GUI, LOG_ERR,
223 "LanguageSelection::Save called without current countryList");
224 return;
225 }
226
227 QString countryCode = item->GetData().toString();
228 gCoreContext->SaveSetting("Country", countryCode);
229
230 if (m_language != langCode)
231 m_languageChanged = true;
232
233 Close();
234}
235
237{
238 if (m_exitOnFinish)
239 m_loop->quit();
240 else
242}
LanguageSelection(MythScreenStack *parent, bool exitOnFinish=false)
static bool m_languageChanged
Definition: langsettings.h:53
static bool prompt(bool force=false)
Ask the user for the language to use.
bool Create(void) override
MythUIButton * m_saveButton
Definition: langsettings.h:48
MythUIButton * m_cancelButton
Definition: langsettings.h:49
void Close(void) override
MythUIButtonList * m_countryList
Definition: langsettings.h:47
MythUIButtonList * m_languageList
Definition: langsettings.h:46
QEventLoop * m_loop
Definition: langsettings.h:56
~LanguageSelection(void) override
void Load(void) override
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
void SaveSetting(const QString &key, int newValue)
QString GetSetting(const QString &key, const QString &defaultval="")
MythLocale * GetLocale(void) const
QString GetLocaleSetting(const QString &key)
Definition: mythlocale.cpp:207
MythScreenStack * GetMainStack()
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Screen in which all other widgets are contained and rendered.
void BuildFocusList(void)
virtual void Close()
static QMap< QString, QString > getLanguages(void)
void SetLCDTitles(const QString &title, const QString &columnList="")
MythUIButtonListItem * GetItemCurrent() const
void SetItemCurrent(MythUIButtonListItem *item)
void SetValueByData(const QVariant &data)
void Clicked()
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
QString GetISO3166CountryName(const QString &iso3166Code)
Definition: iso3166.cpp:368
ISO3166ToNameMap GetISO3166EnglishCountryMap(void)
Returns a map of ISO-3166 country codes mapped to the country name in English.
Definition: iso3166.cpp:344
ISO 3166-1 support functions.
QMap< QString, QString > ISO3166ToNameMap
Definition: iso3166.h:23
QString GetISO639EnglishLanguageName(const QString &iso639_1)
Definition: iso639.cpp:962
ISO 639-1 and ISO 639-2 support functions.
bool force
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythMainWindow * GetMythMainWindow(void)
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27