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 "mythcorecontext.h"
11 #include "mythstorage.h"
12 #include "mythdirs.h"
13 #include "mythlogging.h"
14 #include "mythlocale.h"
15 #include "mythtranslation.h"
16 #include "iso3166.h"
17 #include "iso639.h"
18 
19 // libmythui
20 #include "mythuibuttonlist.h"
21 #include "mythuibutton.h"
22 #include "mythmainwindow.h"
23 #include "mythscreenstack.h"
24 
26  :MythScreenType(parent, "LanguageSelection"),
27  m_exitOnFinish(exitOnFinish)
28 {
29  m_language = gCoreContext->GetSetting("Language");
30  m_country = gCoreContext->GetSetting("Country");
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, SIGNAL(itemClicked(MythUIButtonListItem*)),
65  SLOT(LocaleClicked(MythUIButtonListItem*)));
66  connect(m_languageList, SIGNAL(itemClicked(MythUIButtonListItem*)),
67  SLOT(LanguageClicked(MythUIButtonListItem*)));
68 #endif
69 
70  connect(m_saveButton, SIGNAL(Clicked()), SLOT(Save()));
71  connect(m_cancelButton, SIGNAL(Clicked()), SLOT(Close()));
72 
73  m_languageList->SetLCDTitles(tr("Preferred language"), "");
74  m_countryList->SetLCDTitles(tr("Your location"), "");
75 
77 
78  return true;
79 }
80 
82 {
83  auto *locale = new MythLocale();
84 
85  QString langCode;
86 
87  if (gCoreContext->GetLocale())
88  {
89  // If the global MythLocale instance exists, then we should use it
90  // since it's informed by previously chosen values from the
91  // database.
92  *locale = *gCoreContext->GetLocale();
93  }
94  else
95  {
96  // If no global MythLocale instance exists then we're probably
97  // bootstrapping before the database is available, in that case
98  // we want to load language from the locale XML defaults if they
99  // exist.
100  // e.g. the locale defaults might define en_GB for Australia which has
101  // no translation of it's own. We can't automatically derive en_GB
102  // from en_AU which MythLocale will arrive at and there is no 'en'
103  // translation.
104  langCode = locale->GetLocaleSetting("Language");
105  }
106 
107  if (langCode.isEmpty())
108  langCode = locale->GetLanguageCode();
109  QString localeCode = locale->GetLocaleCode();
110  QString countryCode = locale->GetCountryCode();
111 
112  LOG(VB_GENERAL, LOG_INFO,
113  QString("System Locale (%1), Country (%2), Language (%3)")
114  .arg(localeCode).arg(countryCode).arg(langCode));
115 
116  QMap<QString,QString> langMap = MythTranslation::getLanguages();
117  QStringList langs = langMap.values();
118  langs.sort();
119  bool foundLanguage = false;
120  for (QStringList::Iterator it = langs.begin(); it != langs.end(); ++it)
121  {
122  QString nativeLang = *it;
123  QString code = langMap.key(nativeLang); // Slow, but map is small
124  QString language = GetISO639EnglishLanguageName(code);
125  auto item = new MythUIButtonListItem(m_languageList, nativeLang);
126  item->SetText(language, "language");
127  item->SetText(nativeLang, "nativelanguage");
128  item->SetData(code);
129 
130  // We have to compare against locale for languages like en_GB
131  if (code.toLower() == m_language.toLower() ||
132  code == langCode || code == localeCode)
133  {
135  foundLanguage = true;
136  }
137  }
138 
139  if (m_languageList->IsEmpty())
140  {
141  LOG(VB_GUI, LOG_ERR, "ERROR - Failed to load translations, at least "
142  "one translation file MUST be installed.");
143 
144  auto item = new MythUIButtonListItem(m_languageList,
145  "English (United States)");
146  item->SetText("English (United States)", "language");
147  item->SetText("English (United States)", "nativelanguage");
148  item->SetData("en_US");
149  }
150 
151  if (!foundLanguage)
152  m_languageList->SetValueByData("en_US");
153 
155  QStringList locales = localesMap.values();
156  locales.sort();
157  for (QStringList::Iterator it = locales.begin(); it != locales.end();
158  ++it)
159  {
160  QString country = *it;
161  QString code = localesMap.key(country); // Slow, but map is small
162  QString nativeCountry = GetISO3166CountryName(code);
163  auto item = new MythUIButtonListItem(m_countryList, country);
164  item->SetData(code);
165  item->SetText(country, "country");
166  item->SetText(nativeCountry, "nativecountry");
167  item->SetImage(QString("locale/%1.png").arg(code.toLower()));
168 
169  if (code == m_country || code == countryCode)
171  }
172 
173  delete locale;
174 }
175 
177 
179 {
180  m_languageChanged = false;
181  QString language = gCoreContext->GetSetting("Language", "");
182  QString country = gCoreContext->GetSetting("Country", "");
183  // Ask for language if we don't already know.
184  if (force || language.isEmpty() || country.isEmpty())
185  {
187  if (!mainStack)
188  return false;
189 
190  auto *langSettings = new LanguageSelection(mainStack, true);
191 
192  if (langSettings->Create())
193  {
194  mainStack->AddScreen(langSettings, false);
195  langSettings->m_loop->exec();
196  mainStack->PopScreen(langSettings, false);
197  }
198  else
199  delete langSettings;
200  }
201 
202  return m_languageChanged;
203 }
204 
206 {
208 
209  if (!item)
210  {
211  Close();
212  LOG(VB_GUI, LOG_ERR,
213  "LanguageSelection::Save called without current languageList");
214  return;
215  }
216 
217  QString langCode = item->GetData().toString();
218  gCoreContext->SaveSettingOnHost("Language", langCode, nullptr);
219 
220  item = m_countryList->GetItemCurrent();
221 
222  if (!item)
223  {
224  Close();
225  LOG(VB_GUI, LOG_ERR,
226  "LanguageSelection::Save called without current countryList");
227  return;
228  }
229 
230  QString countryCode = item->GetData().toString();
231  gCoreContext->SaveSettingOnHost("Country", countryCode, nullptr);
232 
233  if (m_language != langCode)
234  m_languageChanged = true;
235 
236  Close();
237 }
238 
240 {
241  if (m_exitOnFinish)
242  m_loop->quit();
243  else
245 }
void Load(void) override
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
ISO 639-1 and ISO 639-2 support functions.
MythLocale * GetLocale(void) const
MythUIButton * m_saveButton
Definition: langsettings.h:48
ISO 3166-1 support functions.
MythUIButtonList * m_languageList
Definition: langsettings.h:46
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythScreenStack * GetMainStack()
MythUIButton * m_cancelButton
Definition: langsettings.h:49
void BuildFocusList(void)
QString GetISO3166CountryName(const QString &iso3166Code)
Definition: iso3166.cpp:368
QString GetLocaleSetting(const QString &key)
Definition: mythlocale.cpp:206
virtual void Close()
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
QString GetSetting(const QString &key, const QString &defaultval="")
bool Create(void) override
MythUIButtonList * m_countryList
Definition: langsettings.h:47
static QMap< QString, QString > getLanguages(void)
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
void Close(void) override
static bool prompt(bool force=false)
Ask the user for the language to use.
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
static bool m_languageChanged
Definition: langsettings.h:53
QEventLoop * m_loop
Definition: langsettings.h:56
MythMainWindow * GetMythMainWindow(void)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
void SetLCDTitles(const QString &title, const QString &columnList="")
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
QMap< QString, QString > ISO3166ToNameMap
Definition: iso3166.h:23
void SetItemCurrent(MythUIButtonListItem *item)
QString GetISO639EnglishLanguageName(const QString &iso639_1)
Definition: iso639.cpp:967
ISO3166ToNameMap GetISO3166EnglishCountryMap(void)
Returns a map of ISO-3166 country codes mapped to the country name in English.
Definition: iso3166.cpp:344
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
Screen in which all other widgets are contained and rendered.
LanguageSelection(MythScreenStack *parent, bool exitOnFinish=false)
MythUIButtonListItem * GetItemCurrent() const
void SetValueByData(const QVariant &data)