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  {
192  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find ui theme location: %1").arg(themedir));
193  }
194  }
195  else
196  {
197  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find inherited theme: %1").arg(themeName));
198  }
199 
200  themeName = baseName;
201  }
202 
203  if (m_isWide)
204  m_searchPaths.append(GetThemesParentDir() + "default-wide/");
205 
206  m_searchPaths.append(GetThemesParentDir() + "default/");
207  m_searchPaths.append("/tmp/");
208  return m_searchPaths;
209 }
210 
212 {
213  QDir themeDirs(GetThemesParentDir());
214  themeDirs.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
215  themeDirs.setSorting(QDir::Name | QDir::IgnoreCase);
216  QFileInfoList fileList { themeDirs.entryInfoList() };
217  themeDirs.setPath(m_userThemeDir);
218  fileList.append(themeDirs.entryInfoList());
219 
220  QList<ThemeInfo> themeList;
221  for (const auto & theme : std::as_const(fileList))
222  {
223  if (theme.baseName() == "default" || theme.baseName() == "default-wide" ||
224  theme.baseName() == "Slave")
225  {
226  continue;
227  }
228 
229  ThemeInfo themeInfo(theme.absoluteFilePath());
230 
231  if (themeInfo.GetType() & Type)
232  themeList.append(themeInfo);
233  }
234 
235  return themeList;
236 }
237 
239 {
240  QFileInfo fi(Path);
241 
242  if (fi.isAbsolute() && fi.exists())
243  return true;
244 #ifdef Q_OS_ANDROID
245  if (Path.startsWith("assets:/") && fi.exists())
246  return true;
247 #endif
248 
249  QString file;
250  bool foundit = false;
251  const QStringList searchpath = GetThemeSearchPath();
252 
253  for (const auto & ii : std::as_const(searchpath))
254  {
255  if (fi.isRelative())
256  file = ii + fi.filePath();
257  else if (fi.isAbsolute() && !fi.isRoot())
258  file = ii + fi.fileName();
259 
260  if (QFile::exists(file))
261  {
262  Path = file;
263  foundit = true;
264  break;
265  }
266  }
267 
268  return foundit;
269 }
270 
272 {
273  return m_baseSize;
274 }
275 
276 
GetThemesParentDir
QString GetThemesParentDir(void)
Definition: mythdirs.cpp:264
themedir
static QString themedir
Definition: mythdirs.cpp:23
MythUIThemeHelper::GetBaseSize
QSize GetBaseSize() const
Definition: mythuithemehelper.cpp:271
MythUIThemeHelper::GetThemes
QList< ThemeInfo > GetThemes(ThemeType Type)
Definition: mythuithemehelper.cpp:211
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:1345
MythUIThemeHelper::m_themename
QString m_themename
Definition: mythuithemehelper.h:28
xbmcvfs.exists
bool exists(str path)
Definition: xbmcvfs.py:51
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
ThemeType
ThemeType
Definition: themeinfo.h:13
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:261
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
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:238
THEME_UI
@ THEME_UI
Definition: themeinfo.h:15
mythcorecontext.h
mythuithemehelper.h
StorageGroup
Definition: storagegroup.h:11
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:842
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:885
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:902