MythTV  master
mythuithemehelper.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QDir>
3 
4 // MythTV
6 #include "libmythbase/mythdirs.h"
9 
10 #include "mythuithemehelper.h"
11 
12 #define LOC QString("ThemeHelper: ")
13 
15 {
16  StorageGroup sgroup("Themes", gCoreContext->GetHostName());
17  m_userThemeDir = sgroup.GetFirstDir(true);
18 
19  QString themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME);
20  QString themedir = FindThemeDir(themename);
21 
22  ThemeInfo themeinfo(themedir);
23  m_isWide = themeinfo.IsWide();
24  m_baseSize = themeinfo.GetBaseRes();
25  m_themename = themeinfo.GetName();
26  LOG(VB_GUI, LOG_INFO, LOC + QString("Using theme base resolution of %1x%2")
27  .arg(m_baseSize.width()).arg(m_baseSize.height()));
28 
29  m_themepathname = themedir + '/';
30  m_searchPaths.clear();
31 
32  themename = gCoreContext->GetSetting("MenuTheme", "defaultmenu");
33  if (themename == "default")
34  themename = "defaultmenu";
36 }
37 
48 QString MythUIThemeHelper::FindThemeDir(const QString& ThemeName, bool Fallback)
49 {
50  QString testdir;
51  QDir dir;
52 
53  if (!ThemeName.isEmpty())
54  {
55  testdir = m_userThemeDir + ThemeName;
56  dir.setPath(testdir);
57  if (dir.exists())
58  return testdir;
59 
60  testdir = GetThemesParentDir() + ThemeName;
61  dir.setPath(testdir);
62  if (dir.exists())
63  return testdir;
64 
65  LOG(VB_GENERAL, LOG_WARNING, LOC + QString("No theme dir: '%1'").arg(dir.absolutePath()));
66  }
67 
68  if (!Fallback)
69  return {};
70 
72  dir.setPath(testdir);
73  if (dir.exists())
74  {
75  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find theme: %1 - Switching to %2")
76  .arg(ThemeName, DEFAULT_UI_THEME));
78  return testdir;
79  }
80 
81  LOG(VB_GENERAL, LOG_WARNING, LOC + QString("No default theme dir: '%1'")
82  .arg(dir.absolutePath()));
83 
85  dir.setPath(testdir);
86  if (dir.exists())
87  {
88  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find theme: %1 - Switching to %2")
89  .arg(ThemeName, FALLBACK_UI_THEME));
91  return testdir;
92  }
93 
94  LOG(VB_GENERAL, LOG_ERR, LOC + QString("No fallback GUI theme dir: '%1'").arg(dir.absolutePath()));
95  return {};
96 }
97 
106 QString MythUIThemeHelper::FindMenuThemeDir(const QString& MenuName)
107 {
108  QString testdir;
109  QDir dir;
110 
111  testdir = m_userThemeDir + MenuName;
112  dir.setPath(testdir);
113  if (dir.exists())
114  return testdir;
115 
116  testdir = GetThemesParentDir() + MenuName;
117  dir.setPath(testdir);
118  if (dir.exists())
119  return testdir;
120 
121  testdir = GetShareDir();
122  dir.setPath(testdir);
123  if (dir.exists())
124  {
125  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find menu theme: %1 - Switching to default")
126  .arg(MenuName));
127  gCoreContext->SaveSetting("MenuTheme", "default");
128  return testdir;
129  }
130 
131  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find menu theme: %1 - Fallback to default failed.")
132  .arg(MenuName));
133  return {};
134 }
135 
137 {
138  return m_menuthemepathname;
139 }
140 
142 {
143  return m_themepathname;
144 }
145 
147 {
148  return m_themename;
149 }
150 
152 {
153  if (!m_searchPaths.isEmpty())
154  return m_searchPaths;
155 
156  // traverse up the theme inheritance list adding their location to the search path
157  QList<ThemeInfo> themeList = GetThemes(THEME_UI);
158  bool found = true;
159  QString themeName = m_themename;
160  QString baseName;
161  QString dirName;
162 
163  while (found && !themeName.isEmpty())
164  {
165  // find the ThemeInfo for this theme
166  found = false;
167  baseName = "";
168  dirName = "";
169 
170  for (int x = 0; x < themeList.count(); x++)
171  {
172  if (themeList.at(x).GetName() == themeName)
173  {
174  found = true;
175  baseName = themeList.at(x).GetBaseTheme();
176  dirName = themeList.at(x).GetDirectoryName();
177  break;
178  }
179  }
180 
181  // try to find where the theme is installed
182  if (found)
183  {
184  QString themedir = FindThemeDir(dirName, false);
185  if (!themedir.isEmpty())
186  {
187  LOG(VB_GUI, LOG_INFO, LOC + QString("Adding path '%1' to theme search paths").arg(themedir));
188  m_searchPaths.append(themedir + '/');
189  }
190  else
191  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find ui theme location: %1").arg(themedir));
192  }
193  else
194  {
195  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find inherited theme: %1").arg(themeName));
196  }
197 
198  themeName = baseName;
199  }
200 
201  if (m_isWide)
202  m_searchPaths.append(GetThemesParentDir() + "default-wide/");
203 
204  m_searchPaths.append(GetThemesParentDir() + "default/");
205  m_searchPaths.append("/tmp/");
206  return m_searchPaths;
207 }
208 
210 {
211  QDir themeDirs(GetThemesParentDir());
212  themeDirs.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
213  themeDirs.setSorting(QDir::Name | QDir::IgnoreCase);
214  QFileInfoList fileList { themeDirs.entryInfoList() };
215  themeDirs.setPath(m_userThemeDir);
216  fileList.append(themeDirs.entryInfoList());
217 
218  QList<ThemeInfo> themeList;
219  for (const auto & theme : std::as_const(fileList))
220  {
221  if (theme.baseName() == "default" || theme.baseName() == "default-wide" ||
222  theme.baseName() == "Slave")
223  {
224  continue;
225  }
226 
227  ThemeInfo themeInfo(theme.absoluteFilePath());
228 
229  if (themeInfo.GetType() & Type)
230  themeList.append(themeInfo);
231  }
232 
233  return themeList;
234 }
235 
237 {
238  QFileInfo fi(Path);
239 
240  if (fi.isAbsolute() && fi.exists())
241  return true;
242 #ifdef Q_OS_ANDROID
243  if (Path.startsWith("assets:/") && fi.exists())
244  return true;
245 #endif
246 
247  QString file;
248  bool foundit = false;
249  const QStringList searchpath = GetThemeSearchPath();
250 
251  for (const auto & ii : std::as_const(searchpath))
252  {
253  if (fi.isRelative())
254  file = ii + fi.filePath();
255  else if (fi.isAbsolute() && !fi.isRoot())
256  file = ii + fi.fileName();
257 
258  if (QFile::exists(file))
259  {
260  Path = file;
261  foundit = true;
262  break;
263  }
264  }
265 
266  return foundit;
267 }
268 
270 {
271  return m_baseSize;
272 }
273 
274 
GetThemesParentDir
QString GetThemesParentDir(void)
Definition: mythdirs.cpp:257
themedir
static QString themedir
Definition: mythdirs.cpp:23
MythUIThemeHelper::GetBaseSize
QSize GetBaseSize() const
Definition: mythuithemehelper.cpp:269
MythUIThemeHelper::GetThemes
QList< ThemeInfo > GetThemes(ThemeType Type)
Definition: mythuithemehelper.cpp:209
MythUIThemeHelper::GetThemeName
QString GetThemeName()
Definition: mythuithemehelper.cpp:146
LOC
#define LOC
Definition: mythuithemehelper.cpp:12
MythCoreContext::OverrideSettingForSession
void OverrideSettingForSession(const QString &key, const QString &value)
Definition: mythcorecontext.cpp:1337
MythUIThemeHelper::m_themename
QString m_themename
Definition: mythuithemehelper.h:28
MythUIThemeHelper::FindMenuThemeDir
QString FindMenuThemeDir(const QString &MenuName)
Returns the full path to the menu theme denoted by menuname.
Definition: mythuithemehelper.cpp:106
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
build_compdb.file
file
Definition: build_compdb.py:55
mythdirs.h
MythUIThemeHelper::m_menuthemepathname
QString m_menuthemepathname
Definition: mythuithemehelper.h:26
ThemeInfo::GetName
QString GetName() const
Definition: themeinfo.h:29
MythUIThemeHelper::m_baseSize
QSize m_baseSize
Definition: mythuithemehelper.h:30
mythlogging.h
ThemeInfo::IsWide
bool IsWide() const
Definition: themeinfo.cpp:247
MythUIThemeHelper::GetThemeDir
QString GetThemeDir()
Definition: mythuithemehelper.cpp:141
GetShareDir
QString GetShareDir(void)
Definition: mythdirs.cpp:254
MythUIThemeHelper::m_userThemeDir
QString m_userThemeDir
Definition: mythuithemehelper.h:29
MythUIThemeHelper::FindThemeDir
QString FindThemeDir(const QString &ThemeName, bool Fallback=true)
Returns the full path to the theme denoted by themename.
Definition: mythuithemehelper.cpp:48
StorageGroup::GetFirstDir
QString GetFirstDir(bool appendSlash=false) const
Definition: storagegroup.cpp:189
ThemeInfo
Definition: themeinfo.h:20
storagegroup.h
MythUIThemeHelper::GetThemeSearchPath
QStringList GetThemeSearchPath()
Definition: mythuithemehelper.cpp:151
ThemeType
ThemeType
Definition: themeinfo.h:13
ThemeInfo::GetBaseRes
QSize GetBaseRes() const
Definition: themeinfo.h:28
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
MythUIThemeHelper::m_searchPaths
QStringList m_searchPaths
Definition: mythuithemehelper.h:25
MythUIThemeHelper::m_themepathname
QString m_themepathname
Definition: mythuithemehelper.h:27
MythUIThemeHelper::m_isWide
bool m_isWide
Definition: mythuithemehelper.h:31
MythUIThemeHelper::InitThemeHelper
void InitThemeHelper()
Definition: mythuithemehelper.cpp:14
mythburn.themeName
string themeName
Definition: mythburn.py:218
DEFAULT_UI_THEME
static constexpr const char * DEFAULT_UI_THEME
Definition: mythuithemehelper.h:7
ThemeInfo::GetType
int GetType() const
Definition: themeinfo.h:34
MythUIThemeHelper::FindThemeFile
bool FindThemeFile(QString &Path)
Definition: mythuithemehelper.cpp:236
mythcorecontext.h
mythuithemehelper.h
StorageGroup
Definition: storagegroup.h:11
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:838
FALLBACK_UI_THEME
static constexpr const char * FALLBACK_UI_THEME
Definition: mythuithemehelper.h:8
MythUIThemeHelper::GetMenuThemeDir
QString GetMenuThemeDir()
Definition: mythuithemehelper.cpp:136
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:881
THEME_UI
@ THEME_UI
Definition: themeinfo.h:15
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:898