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 (const auto& nativeLang : qAsConst(langs))
121  {
122  QString code = langMap.key(nativeLang); // Slow, but map is small
123  QString language = GetISO639EnglishLanguageName(code);
124  auto *item = new MythUIButtonListItem(m_languageList, nativeLang);
125  item->SetText(language, "language");
126  item->SetText(nativeLang, "nativelanguage");
127  item->SetData(code);
128 
129  // We have to compare against locale for languages like en_GB
130  if (code.toLower() == m_language.toLower() ||
131  code == langCode || code == localeCode)
132  {
134  foundLanguage = true;
135  }
136  }
137 
138  if (m_languageList->IsEmpty())
139  {
140  LOG(VB_GUI, LOG_ERR, "ERROR - Failed to load translations, at least "
141  "one translation file MUST be installed.");
142 
143  auto *item = new MythUIButtonListItem(m_languageList,
144  "English (United States)");
145  item->SetText("English (United States)", "language");
146  item->SetText("English (United States)", "nativelanguage");
147  item->SetData("en_US");
148  }
149 
150  if (!foundLanguage)
151  m_languageList->SetValueByData("en_US");
152 
154  QStringList locales = localesMap.values();
155  locales.sort();
156  for (const auto& country : qAsConst(locales))
157  {
158  QString code = localesMap.key(country); // Slow, but map is small
159  QString nativeCountry = GetISO3166CountryName(code);
160  auto *item = new MythUIButtonListItem(m_countryList, country);
161  item->SetData(code);
162  item->SetText(country, "country");
163  item->SetText(nativeCountry, "nativecountry");
164  item->SetImage(QString("locale/%1.png").arg(code.toLower()));
165 
166  if (code == m_country || code == countryCode)
168  }
169 
170  delete locale;
171 }
172 
174 
176 {
177  m_languageChanged = false;
178  QString language = gCoreContext->GetSetting("Language", "");
179  QString country = gCoreContext->GetSetting("Country", "");
180  // Ask for language if we don't already know.
181  if (force || language.isEmpty() || country.isEmpty())
182  {
184  if (!mainStack)
185  return false;
186 
187  auto *langSettings = new LanguageSelection(mainStack, true);
188 
189  if (langSettings->Create())
190  {
191  mainStack->AddScreen(langSettings, false);
192  langSettings->m_loop->exec();
193  mainStack->PopScreen(langSettings, false);
194  }
195  else
196  delete langSettings;
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->SaveSettingOnHost("Language", langCode, nullptr);
216 
217  item = m_countryList->GetItemCurrent();
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->SaveSettingOnHost("Country", countryCode, nullptr);
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 }
force
bool force
Definition: mythtv/programs/mythcommflag/main.cpp:75
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:304
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1590
MythUIButtonList::SetValueByData
void SetValueByData(const QVariant &data)
Definition: mythuibuttonlist.cpp:1542
LanguageSelection::m_languageList
MythUIButtonList * m_languageList
Definition: langsettings.h:46
GetISO639EnglishLanguageName
QString GetISO639EnglishLanguageName(const QString &iso639_1)
Definition: iso639.cpp:967
MythLocale
Definition: mythlocale.h:13
LanguageSelection::~LanguageSelection
~LanguageSelection(void) override
Definition: langsettings.cpp:37
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:402
MythCoreContext::GetLocale
MythLocale * GetLocale(void) const
Definition: mythcorecontext.cpp:1772
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:81
LanguageSelection::LanguageSelection
LanguageSelection(MythScreenStack *parent, bool exitOnFinish=false)
Definition: langsettings.cpp:25
MythScreenStack
Definition: mythscreenstack.h:16
arg
arg(title).arg(filename).arg(doDelete))
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
mythdirs.h
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:119
MythUIButtonListItem
Definition: mythuibuttonlist.h:28
LanguageSelection::m_loop
QEventLoop * m_loop
Definition: langsettings.h:56
MythUIButtonList::IsEmpty
bool IsEmpty() const
Definition: mythuibuttonlist.cpp:1671
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:222
mythtranslation.h
MythLocale::GetLocaleSetting
QString GetLocaleSetting(const QString &key)
Definition: mythlocale.cpp:206
MythUIButtonList::SetLCDTitles
void SetLCDTitles(const QString &title, const QString &columnList="")
Definition: mythuibuttonlist.cpp:3038
mythlocale.h
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3588
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
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:202
mythcorecontext.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:692
LanguageSelection::prompt
static bool prompt(bool force=false)
Ask the user for the language to use.
Definition: langsettings.cpp:175
iso3166.h
ISO 3166-1 support functions.
MythScreenStack::PopScreen
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
Definition: mythscreenstack.cpp:83
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:107
LanguageSelection::m_country
QString m_country
Definition: langsettings.h:55
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1557
LanguageSelection::Close
void Close(void) override
Definition: langsettings.cpp:236
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:49
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:909
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:916