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"
13 #include "libmythbase/mythdirs.h"
14 #include "libmythbase/mythlocale.h"
18 
19 // libmythui
22 #include "libmythui/mythuibutton.h"
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 {
39  if (m_exitOnFinish)
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 
85  if (gCoreContext->GetLocale())
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)
149  m_languageList->SetValueByData("en_US");
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  delete langSettings;
195  }
196 
197  return m_languageChanged;
198 }
199 
201 {
203 
204  if (!item)
205  {
206  Close();
207  LOG(VB_GUI, LOG_ERR,
208  "LanguageSelection::Save called without current languageList");
209  return;
210  }
211 
212  QString langCode = item->GetData().toString();
213  gCoreContext->SaveSettingOnHost("Language", langCode, nullptr);
214 
215  item = m_countryList->GetItemCurrent();
216 
217  if (!item)
218  {
219  Close();
220  LOG(VB_GUI, LOG_ERR,
221  "LanguageSelection::Save called without current countryList");
222  return;
223  }
224 
225  QString countryCode = item->GetData().toString();
226  gCoreContext->SaveSettingOnHost("Country", countryCode, nullptr);
227 
228  if (m_language != langCode)
229  m_languageChanged = true;
230 
231  Close();
232 }
233 
235 {
236  if (m_exitOnFinish)
237  m_loop->quit();
238  else
240 }
MythUIButton::Clicked
void Clicked()
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:318
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1591
MythUIButtonList::SetValueByData
void SetValueByData(const QVariant &data)
Definition: mythuibuttonlist.cpp:1543
LanguageSelection::m_languageList
MythUIButtonList * m_languageList
Definition: langsettings.h:46
GetISO639EnglishLanguageName
QString GetISO639EnglishLanguageName(const QString &iso639_1)
Definition: iso639.cpp:962
MythLocale
Definition: mythlocale.h:12
LanguageSelection::~LanguageSelection
~LanguageSelection(void) override
Definition: langsettings.cpp:37
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:386
MythCoreContext::GetLocale
MythLocale * GetLocale(void) const
Definition: mythcorecontext.cpp:1758
mythscreenstack.h
LanguageSelection::Load
void Load(void) override
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
Definition: langsettings.cpp:79
LanguageSelection::LanguageSelection
LanguageSelection(MythScreenStack *parent, bool exitOnFinish=false)
Definition: langsettings.cpp:25
MythScreenStack
Definition: mythscreenstack.h:16
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
mythdirs.h
force
bool force
Definition: mythcommflag.cpp:70
mythuibuttonlist.h
GetISO3166CountryName
QString GetISO3166CountryName(const QString &iso3166Code)
Definition: iso3166.cpp:368
langsettings.h
MythTranslation::getLanguages
static QMap< QString, QString > getLanguages(void)
Definition: mythtranslation.cpp:118
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
LanguageSelection::m_loop
QEventLoop * m_loop
Definition: langsettings.h:56
MythUIButtonList::IsEmpty
bool IsEmpty() const
Definition: mythuibuttonlist.cpp:1672
mythlogging.h
LanguageSelection::m_cancelButton
MythUIButton * m_cancelButton
Definition: langsettings.h:49
GetISO3166EnglishCountryMap
ISO3166ToNameMap GetISO3166EnglishCountryMap(void)
Returns a map of ISO-3166 country codes mapped to the country name in English.
Definition: iso3166.cpp:344
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:206
mythtranslation.h
MythLocale::GetLocaleSetting
QString GetLocaleSetting(const QString &key)
Definition: mythlocale.cpp:205
MythUIButtonList::SetLCDTitles
void SetLCDTitles(const QString &title, const QString &columnList="")
Definition: mythuibuttonlist.cpp:3034
mythlocale.h
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3660
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
LanguageSelection::m_exitOnFinish
bool m_exitOnFinish
Definition: langsettings.h:51
LanguageSelection::Create
bool Create(void) override
Definition: langsettings.cpp:45
LanguageSelection::m_countryList
MythUIButtonList * m_countryList
Definition: langsettings.h:47
LanguageSelection::Save
void Save(void)
Definition: langsettings.cpp:200
mythcorecontext.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:687
LanguageSelection::prompt
static bool prompt(bool force=false)
Ask the user for the language to use.
Definition: langsettings.cpp:173
iso3166.h
ISO 3166-1 support functions.
MythScreenStack::PopScreen
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
Definition: mythscreenstack.cpp:86
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
LanguageSelection::m_country
QString m_country
Definition: langsettings.h:55
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1558
LanguageSelection::Close
void Close(void) override
Definition: langsettings.cpp:234
mythuibutton.h
iso639.h
ISO 639-1 and ISO 639-2 support functions.
LanguageSelection::m_language
QString m_language
Definition: langsettings.h:54
LanguageSelection::m_saveButton
MythUIButton * m_saveButton
Definition: langsettings.h:48
LanguageSelection::m_languageChanged
static bool m_languageChanged
Definition: langsettings.h:53
mythstorage.h
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
ISO3166ToNameMap
QMap< QString, QString > ISO3166ToNameMap
Definition: iso3166.h:23
MythCoreContext::SaveSettingOnHost
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
Definition: mythcorecontext.cpp:891
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:898