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  MythLocale *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  MythUIButtonListItem *item;
120  bool foundLanguage = false;
121  for (QStringList::Iterator it = langs.begin(); it != langs.end(); ++it)
122  {
123  QString nativeLang = *it;
124  QString code = langMap.key(nativeLang); // Slow, but map is small
125  QString language = GetISO639EnglishLanguageName(code);
126  item = new MythUIButtonListItem(m_languageList, nativeLang);
127  item->SetText(language, "language");
128  item->SetText(nativeLang, "nativelanguage");
129  item->SetData(code);
130 
131  // We have to compare against locale for languages like en_GB
132  if (code.toLower() == m_language.toLower() ||
133  code == langCode || code == localeCode)
134  {
136  foundLanguage = true;
137  }
138  }
139 
140  if (m_languageList->IsEmpty())
141  {
142  LOG(VB_GUI, LOG_ERR, "ERROR - Failed to load translations, at least "
143  "one translation file MUST be installed.");
144 
146  "English (United States)");
147  item->SetText("English (United States)", "language");
148  item->SetText("English (United States)", "nativelanguage");
149  item->SetData("en_US");
150  }
151 
152  if (!foundLanguage)
153  m_languageList->SetValueByData("en_US");
154 
156  QStringList locales = localesMap.values();
157  locales.sort();
158  for (QStringList::Iterator it = locales.begin(); it != locales.end();
159  ++it)
160  {
161  QString country = *it;
162  QString code = localesMap.key(country); // Slow, but map is small
163  QString nativeCountry = GetISO3166CountryName(code);
164  item = new MythUIButtonListItem(m_countryList, country);
165  item->SetData(code);
166  item->SetText(country, "country");
167  item->SetText(nativeCountry, "nativecountry");
168  item->SetImage(QString("locale/%1.png").arg(code.toLower()));
169 
170  if (code == m_country || code == countryCode)
172  }
173 
174  delete locale;
175 }
176 
178 
180 {
181  m_languageChanged = false;
182  QString language = gCoreContext->GetSetting("Language", "");
183  QString country = gCoreContext->GetSetting("Country", "");
184  // Ask for language if we don't already know.
185  if (force || language.isEmpty() || country.isEmpty())
186  {
188  if (!mainStack)
189  return false;
190 
191  LanguageSelection *langSettings = new LanguageSelection(mainStack,
192  true);
193 
194  if (langSettings->Create())
195  {
196  mainStack->AddScreen(langSettings, false);
197  langSettings->m_loop->exec();
198  mainStack->PopScreen(langSettings, false);
199  }
200  else
201  delete langSettings;
202  }
203 
204  return m_languageChanged;
205 }
206 
208 {
210 
211  if (!item)
212  {
213  Close();
214  LOG(VB_GUI, LOG_ERR,
215  "LanguageSelection::Save called without current languageList");
216  return;
217  }
218 
219  QString langCode = item->GetData().toString();
220  gCoreContext->SaveSettingOnHost("Language", langCode, nullptr);
221 
222  item = m_countryList->GetItemCurrent();
223 
224  if (!item)
225  {
226  Close();
227  LOG(VB_GUI, LOG_ERR,
228  "LanguageSelection::Save called without current countryList");
229  return;
230  }
231 
232  QString countryCode = item->GetData().toString();
233  gCoreContext->SaveSettingOnHost("Country", countryCode, nullptr);
234 
235  if (m_language != langCode)
236  m_languageChanged = true;
237 
238  Close();
239 }
240 
242 {
243  if (m_exitOnFinish)
244  m_loop->quit();
245  else
247 }
QString GetLocaleCode() const
Name of language in that language.
Definition: mythlocale.h:28
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
void SetData(QVariant data)
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 GetCountryCode() const
Definition: mythlocale.cpp:58
void SetImage(MythImage *image, const QString &name="")
Sets an image directly, should only be used in special circumstances since it bypasses the cache.
QString GetISO3166CountryName(const QString &iso3166Code)
Definition: iso3166.cpp:368
QMap< QString, QString > ISO3166ToNameMap
Definition: iso3166.h:23
QString GetLocaleSetting(const QString &key)
Definition: mythlocale.cpp:206
virtual void Close()
QString GetLanguageCode() const
Name of country in the native language.
Definition: mythlocale.cpp:75
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 SetText(const QString &text, const QString &name="", const QString &state="")
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)
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)