MythTV  master
mythuihelper.cpp
Go to the documentation of this file.
1 #include "mythuihelper.h"
2 
3 #include <cmath>
4 #include <unistd.h>
5 #include <iostream>
6 
7 #include <QImage>
8 #include <QPixmap>
9 #include <QMutex>
10 #include <QPalette>
11 #include <QMap>
12 #include <QDir>
13 #include <QFileInfo>
14 #include <QApplication>
15 #include <QPainter>
16 #include <QStyleFactory>
17 #include <QSize>
18 #include <QFile>
19 #include <QAtomicInt>
20 #include <QEventLoop>
21 #include <QTimer>
22 #include <QScreen>
23 
24 // mythbase headers
25 #include "mythdirs.h"
26 #include "mythlogging.h"
27 #include "mythdownloadmanager.h"
28 #include "mythdb.h"
29 #include "remotefile.h"
30 #include "mythcorecontext.h"
31 #include "storagegroup.h"
32 #include "mythdate.h"
33 #include "mthreadpool.h"
34 
35 // mythui headers
36 #include "mythprogressdialog.h"
37 #include "mythimage.h"
38 #include "screensaver.h"
39 #include "mythmainwindow.h"
40 #include "themeinfo.h"
41 #include "x11colors.h"
42 #include "mythdisplay.h"
43 
44 #define LOC QString("MythUIHelper: ")
45 
46 static MythUIHelper *mythui = nullptr;
47 static QMutex uiLock;
48 
50 {
51  if (mythui)
52  return mythui;
53 
54  uiLock.lock();
55 
56  if (!mythui)
57  mythui = new MythUIHelper();
58 
59  uiLock.unlock();
60 
61  // These directories should always exist. Don't test first as
62  // there's no harm in trying to create an existing directory.
63  QDir dir;
64  dir.mkdir(GetThemeBaseCacheDir());
65  dir.mkdir(GetRemoteCacheDir());
66  dir.mkdir(GetThumbnailDir());
67 
68  return mythui;
69 }
70 
72 {
75  uiLock.lock();
76  delete mythui;
77  mythui = nullptr;
78  uiLock.unlock();
79 }
80 
82 {
83  return MythUIHelper::getMythUI();
84 }
85 
87 {
89 }
90 
92 {
93 public:
95  : m_parent(p), m_cacheLock(new QMutex(QMutex::Recursive)),
96  m_imageThreadPool(new MThreadPool("MythUIHelper")) {}
98 
99  void Init();
100  void StoreGUIsettings(void);
101 
102  MythUIHelper *m_parent {nullptr};
103 
106  QString m_themename;
107  QPalette m_palette;
108 
109  // The part of the screen(s) allocated for the GUI. Unless
110  // overridden by the user, defaults to the full drawable area.
111  QRect m_screenRect { 0, 0, 0, 0};
112 
113  // Command-line GUI size, which overrides both the above sets of sizes
114  static int x_override;
115  static int y_override;
116  static int w_override;
117  static int h_override;
118 
119  float m_wmult {1.0F};
120  float m_hmult {1.0F};
121 
122  int m_fontStretch {100};
123 
124  // Dimensions of the theme
125  QSize m_baseSize { 800, 600 };
126  bool m_isWide {false};
127 
128  bool m_themeloaded {false};
129 
130  QMap<QString, MythImage *> m_imageCache;
131  QMap<QString, qint64> m_cacheTrack;
132  QMutex *m_cacheLock {nullptr};
133 
134 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
135  QAtomicInt m_cacheSize {0};
136  QAtomicInt m_maxCacheSize {30 * 1024 * 1024};
137 #else
138  // This change is because of the QImage change from byteCount() to
139  // sizeInBytes(), the latter returning a 64bit value.
140  QAtomicInteger<qint64> m_cacheSize {0};
141  QAtomicInteger<qint64> m_maxCacheSize {30 * 1024 * 1024};
142 #endif
143 
145  QString m_userThemeDir;
146 
147  MythDisplay *m_display {nullptr};
148 
150 
151  MythUIMenuCallbacks m_callbacks {nullptr,nullptr,nullptr,nullptr,nullptr};
152 
153  QStringList m_searchPaths;
154 
156  bool m_screensaverEnabled {false};
157  bool m_screenSetup {false};
158 };
159 
164 
166 {
167  QMutableMapIterator<QString, MythImage *> i(m_imageCache);
168 
169  while (i.hasNext())
170  {
171  i.next();
172  i.value()->SetIsInCache(false);
173  i.value()->DecrRef();
174  i.remove();
175  }
176 
177  m_cacheTrack.clear();
178 
179  delete m_cacheLock;
180  delete m_imageThreadPool;
181  delete m_screensaver;
182 
183  if (m_display)
184  {
185  // N.B. we always call this to ensure the desktop mode is restored
186  // in case the setting was changed
189  }
190 }
191 
193 {
194  if (!m_display)
198  m_screenSetup = true;
199 
200  StorageGroup sgroup("Themes", gCoreContext->GetHostName());
201  m_userThemeDir = sgroup.GetFirstDir(true);
202 }
203 
208 {
209  if (x_override >= 0 && y_override >= 0)
210  {
211  GetMythDB()->OverrideSettingForSession("GuiOffsetX", QString::number(x_override));
212  GetMythDB()->OverrideSettingForSession("GuiOffsetY", QString::number(y_override));
213  }
214 
215  if (w_override > 0 && h_override > 0)
216  {
217  GetMythDB()->OverrideSettingForSession("GuiWidth", QString::number(w_override));
218  GetMythDB()->OverrideSettingForSession("GuiHeight", QString::number(h_override));
219  }
220 
221  int x = GetMythDB()->GetNumSetting("GuiOffsetX");
222  int y = GetMythDB()->GetNumSetting("GuiOffsetY");
223  int width = 0;
224  int height = 0;
225  GetMythDB()->GetResolutionSetting("Gui", width, height);
226 
227  if (!m_display)
229  QRect screenbounds = m_display->GetScreenBounds();
230 
231  // As per MythMainWindow::Init, fullscreen is indicated by all zero's in settings
232  if (x == 0 && y == 0 && width == 0 && height == 0)
233  m_screenRect = screenbounds;
234  else
235  m_screenRect = QRect(x, y, width, height);
236 
237  if (m_screenRect.width() < 160 || m_screenRect.height() < 160)
238  {
239  LOG(VB_GENERAL, LOG_ERR, LOC +
240  "Somehow, your screen size settings are bad.\n\t\t\t" +
241  QString("GuiResolution: %1\n\t\t\t")
242  .arg(GetMythDB()->GetSetting("GuiResolution")) +
243  QString(" old GuiWidth: %1\n\t\t\t")
244  .arg(GetMythDB()->GetNumSetting("GuiWidth")) +
245  QString(" old GuiHeight: %1\n\t\t\t")
246  .arg(GetMythDB()->GetNumSetting("GuiHeight")) +
247  QString("width: %1 ").arg(m_screenRect.width()) +
248  QString("height: %1\n\t\t\t").arg(m_screenRect.height()) +
249  "Falling back to 640x480");
250  m_screenRect.setSize(QSize(640, 480));
251  }
252 
253  m_wmult = m_screenRect.width() / static_cast<float>(m_baseSize.width());
254  m_hmult = m_screenRect.height() / static_cast<float>(m_baseSize.height());
255 
256  // Default font, _ALL_ fonts inherit from this!
257  // e.g All fonts will be 19 pixels unless a new size is explicitly defined.
258  QFont font = QFont("Arial");
259 
260  if (!font.exactMatch())
261  font = QFont();
262 
263  font.setStyleHint(QFont::SansSerif, QFont::PreferAntialias);
264  font.setPixelSize(static_cast<int>(lroundf(19.0F * m_hmult)));
265  int stretch = static_cast<int>(100 / m_display->GetPixelAspectRatio());
266  font.setStretch(stretch); // QT
267  m_fontStretch = stretch; // MythUI
268 
269  QApplication::setFont(font);
270 }
271 
273 {
274  d = new MythUIHelperPrivate(this);
275 }
276 
278 {
279  delete d;
280 }
281 
283 {
284  d->Init();
285  d->m_callbacks = cbs;
286 
287  d->m_maxCacheSize.fetchAndStoreRelease(
288  GetMythDB()->GetNumSetting("UIImageCacheSize", 30) * 1024 * 1024);
289 
290  LOG(VB_GUI, LOG_INFO, LOC +
291  QString("MythUI Image Cache size set to %1 bytes")
292  .arg(d->m_maxCacheSize.fetchAndAddRelease(0)));
293 }
294 
295 // This init is used for showing the startup UI that is shown
296 // before the database is initialized. The above init is called later,
297 // after the DB is available.
298 // This class does not mind being Initialized twice.
300 {
301  d->Init();
302 }
303 
305 {
306  return &(d->m_callbacks);
307 }
308 
310 {
311  return d->m_screenSetup;
312 }
313 
315 {
317 }
318 
320 {
322  d->m_themecachedir.clear();
323 
324  if (!d->m_display)
326 
327  // Switch to desired GUI resolution
328  if (d->m_display->UsingVideoModes())
329  d->m_display->SwitchToGUI(true);
330 
331  QApplication::setStyle("Windows");
332 
333  QString themename = GetMythDB()->GetSetting("Theme", DEFAULT_UI_THEME);
334  QString themedir = FindThemeDir(themename);
335 
336  auto *themeinfo = new ThemeInfo(themedir);
337  if (themeinfo)
338  {
339  d->m_isWide = themeinfo->IsWide();
340  d->m_baseSize = themeinfo->GetBaseRes();
341  d->m_themename = themeinfo->GetName();
342  LOG(VB_GUI, LOG_INFO, LOC +
343  QString("Using theme base resolution of %1x%2")
344  .arg(d->m_baseSize.width()).arg(d->m_baseSize.height()));
345  delete themeinfo;
346  }
347 
348  // Recalculate GUI dimensions
349  d->StoreGUIsettings();
350 
351  d->m_themepathname = themedir + '/';
352  d->m_searchPaths.clear();
353 
354  d->m_themeloaded = false;
355 
356  themename = GetMythDB()->GetSetting("MenuTheme", "defaultmenu");
357 
358  if (themename == "default")
359  themename = "defaultmenu";
360 
361  d->m_menuthemepathname = FindMenuThemeDir(themename);
362 }
363 
365 {
366  QMutexLocker locker(d->m_cacheLock);
367 
368  QMutableMapIterator<QString, MythImage *> i(d->m_imageCache);
369 
370  while (i.hasNext())
371  {
372  i.next();
373  i.value()->SetIsInCache(false);
374  i.value()->DecrRef();
375  i.remove();
376  }
377 
378  d->m_cacheTrack.clear();
379 
380  d->m_cacheSize.fetchAndStoreOrdered(0);
381 
385 }
386 
388 {
389  QMutexLocker locker(d->m_cacheLock);
390 
391  if (d->m_imageCache.contains(url))
392  {
393  d->m_cacheTrack[url] = MythDate::current().toSecsSinceEpoch();
394  d->m_imageCache[url]->IncrRef();
395  return d->m_imageCache[url];
396  }
397 
398  /*
399  if (QFileInfo(url).exists())
400  {
401  MythImage *im = GetMythPainter()->GetFormatImage();
402  im->Load(url,false);
403  return im;
404  }
405  */
406 
407  return nullptr;
408 }
409 
411 {
412  if (im)
413  {
414 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
415  d->m_cacheSize.fetchAndAddOrdered(im->byteCount());
416 #else
417  d->m_cacheSize.fetchAndAddOrdered(im->sizeInBytes());
418 #endif
419  }
420 }
421 
423 {
424  if (im)
425  {
426 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
427  d->m_cacheSize.fetchAndAddOrdered(-im->byteCount());
428 #else
429  d->m_cacheSize.fetchAndAddOrdered(-im->sizeInBytes());
430 #endif
431  }
432 }
433 
435  bool nodisk)
436 {
437  if (!im)
438  return nullptr;
439 
440  if (!nodisk)
441  {
442  QString dstfile = GetCacheDirByUrl(url) + '/' + url;
443 
444  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
445  QString("Saved to Cache (%1)").arg(dstfile));
446 
447  // Save to disk cache
448  im->save(dstfile, "PNG");
449  }
450 
451  // delete the oldest cached images until we fall below threshold.
452  QMutexLocker locker(d->m_cacheLock);
453 
454  while ((d->m_cacheSize.fetchAndAddOrdered(0) +
455 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
456  im->byteCount()
457 #else
458  im->sizeInBytes()
459 #endif
460  ) >=
461  d->m_maxCacheSize.fetchAndAddOrdered(0) &&
462  !d->m_imageCache.empty())
463  {
464  QMap<QString, MythImage *>::iterator it = d->m_imageCache.begin();
465  qint64 oldestTime = MythDate::current().toSecsSinceEpoch();
466  QString oldestKey = it.key();
467 
468  int count = 0;
469 
470  for (; it != d->m_imageCache.end(); ++it)
471  {
472  if (d->m_cacheTrack[it.key()] < oldestTime)
473  {
474  if ((2 == it.value()->IncrRef()) && (it.value() != im))
475  {
476  oldestTime = d->m_cacheTrack[it.key()];
477  oldestKey = it.key();
478  count++;
479  }
480  it.value()->DecrRef();
481  }
482  }
483 
484  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
485  QString("%1 images are eligible for expiry").arg(count));
486 
487  if (count > 0)
488  {
489  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
490  QString("Cache too big (%1), removing :%2:")
491  .arg(d->m_cacheSize.fetchAndAddOrdered(0) +
492 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
493  im->byteCount()
494 #else
495  im->sizeInBytes()
496 #endif
497  )
498  .arg(oldestKey));
499 
500  d->m_imageCache[oldestKey]->SetIsInCache(false);
501  d->m_imageCache[oldestKey]->DecrRef();
502  d->m_imageCache.remove(oldestKey);
503  d->m_cacheTrack.remove(oldestKey);
504  }
505  else
506  {
507  break;
508  }
509  }
510 
511  QMap<QString, MythImage *>::iterator it = d->m_imageCache.find(url);
512 
513  if (it == d->m_imageCache.end())
514  {
515  im->IncrRef();
516  d->m_imageCache[url] = im;
517  d->m_cacheTrack[url] = MythDate::current().toSecsSinceEpoch();
518 
519  im->SetIsInCache(true);
520  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
521  QString("NOT IN RAM CACHE, Adding, and adding to size :%1: :%2:")
522  .arg(url)
523 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
524  .arg(im->byteCount())
525 #else
526  .arg(im->sizeInBytes())
527 #endif
528  );
529  }
530 
531  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
532  QString("MythUIHelper::CacheImage : Cache Count = :%1: size :%2:")
533  .arg(d->m_imageCache.count())
534  .arg(d->m_cacheSize.fetchAndAddRelaxed(0)));
535 
536  return d->m_imageCache[url];
537 }
538 
539 void MythUIHelper::RemoveFromCacheByURL(const QString &url)
540 {
541  QMutexLocker locker(d->m_cacheLock);
542  QMap<QString, MythImage *>::iterator it = d->m_imageCache.find(url);
543 
544  if (it != d->m_imageCache.end())
545  {
546  d->m_imageCache[url]->SetIsInCache(false);
547  d->m_imageCache[url]->DecrRef();
548  d->m_imageCache.remove(url);
549  d->m_cacheTrack.remove(url);
550  }
551 
552  QString dstfile;
553 
554  dstfile = GetCacheDirByUrl(url) + '/' + url;
555  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
556  QString("RemoveFromCacheByURL removed :%1: from cache").arg(dstfile));
557  QFile::remove(dstfile);
558 }
559 
560 void MythUIHelper::RemoveFromCacheByFile(const QString &fname)
561 {
562  QList<QString>::iterator it;
563 
564  QString partialKey = fname;
565  partialKey.replace('/', '-');
566 
567  d->m_cacheLock->lock();
568  QList<QString> m_imageCacheKeys = d->m_imageCache.keys();
569  d->m_cacheLock->unlock();
570 
571  for (it = m_imageCacheKeys.begin(); it != m_imageCacheKeys.end(); ++it)
572  {
573  if ((*it).contains(partialKey))
575  }
576 
577  // Loop through files to cache any that were not caught by
578  // RemoveFromCacheByURL
579  QDir dir(GetThemeCacheDir());
580  QFileInfoList list = dir.entryInfoList();
581 
582  for (const auto & fileInfo : list)
583  {
584  if (fileInfo.fileName().contains(partialKey))
585  {
586  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
587  QString("RemoveFromCacheByFile removed: %1: from cache")
588  .arg(fileInfo.fileName()));
589 
590  if (!dir.remove(fileInfo.fileName()))
591  {
592  LOG(VB_GENERAL, LOG_ERR, LOC +
593  QString("Failed to delete %1 from the theme cache")
594  .arg(fileInfo.fileName()));
595  }
596  }
597  }
598 }
599 
600 bool MythUIHelper::IsImageInCache(const QString &url)
601 {
602  QMutexLocker locker(d->m_cacheLock);
603 
604  if (d->m_imageCache.contains(url))
605  return true;
606 
607  if (QFileInfo(url).exists())
608  return true;
609 
610  return false;
611 }
612 
614 {
615  static QString s_oldcachedir;
616  QString tmpcachedir = GetThemeBaseCacheDir() + "/" +
617  GetMythDB()->GetSetting("Theme", DEFAULT_UI_THEME) +
618  "." + QString::number(d->m_screenRect.width()) +
619  "." + QString::number(d->m_screenRect.height());
620 
621  if (tmpcachedir != s_oldcachedir)
622  {
623  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
624  QString("Creating cache dir: %1").arg(tmpcachedir));
625  QDir dir;
626  dir.mkdir(tmpcachedir);
627  s_oldcachedir = tmpcachedir;
628  }
629  return tmpcachedir;
630 }
631 
639 QString MythUIHelper::GetCacheDirByUrl(const QString& url)
640 {
641  if (url.startsWith("myth:") || url.startsWith("-"))
642  return GetThumbnailDir();
643  return GetThemeCacheDir();
644 }
645 
647 {
649 
650  QString themecachedir = d->m_themecachedir;
651 
652  d->m_themecachedir += '/';
653 
654  QDir dir(GetThemeBaseCacheDir());
655  dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
656  QFileInfoList list = dir.entryInfoList();
657 
658  QFileInfoList::const_iterator it = list.begin();
659  QMap<QDateTime, QString> dirtimes;
660 
661  while (it != list.end())
662  {
663  const QFileInfo *fi = &(*it++);
664 
665  if (fi->isDir() && !fi->isSymLink())
666  {
667  if (fi->absoluteFilePath() == themecachedir)
668  continue;
669 
670  dirtimes[fi->lastModified()] = fi->absoluteFilePath();
671  }
672  }
673 
674  // Cache two themes/resolutions to allow sampling other themes without
675  // incurring a penalty. Especially for those writing new themes or testing
676  // changes of an existing theme. The space used is neglible when compared
677  // against the average video
678  while ((size_t)dirtimes.size() >= 2)
679  {
680  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("Removing cache dir: %1")
681  .arg(dirtimes.begin().value()));
682 
683  RemoveCacheDir(dirtimes.begin().value());
684  dirtimes.erase(dirtimes.begin());
685  }
686 
687  for (const auto & dirtime : qAsConst(dirtimes))
688  {
689  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
690  QString("Keeping cache dir: %1").arg(dirtime));
691  }
692 }
693 
694 void MythUIHelper::RemoveCacheDir(const QString &dirname)
695 {
696  QString cachedirname = GetThemeBaseCacheDir();
697 
698  if (!dirname.startsWith(cachedirname))
699  return;
700 
701  LOG(VB_GENERAL, LOG_ERR, LOC +
702  QString("Removing stale cache dir: %1").arg(dirname));
703 
704  QDir dir(dirname);
705 
706  if (!dir.exists())
707  return;
708 
709  dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
710  QFileInfoList list = dir.entryInfoList();
711  QFileInfoList::const_iterator it = list.begin();
712 
713  while (it != list.end())
714  {
715  const QFileInfo *fi = &(*it++);
716 
717  if (fi->isFile() && !fi->isSymLink())
718  {
719  QFile file(fi->absoluteFilePath());
720  file.remove();
721  }
722  else if (fi->isDir() && !fi->isSymLink())
723  {
724  RemoveCacheDir(fi->absoluteFilePath());
725  }
726  }
727 
728  dir.rmdir(dirname);
729 }
730 
737 void MythUIHelper::PruneCacheDir(const QString& dirname)
738 {
739  int days = GetMythDB()->GetNumSetting("UIDiskCacheDays", 7);
740  if (days == -1) {
741  LOG(VB_GENERAL, LOG_INFO, LOC +
742  QString("Pruning cache directory: %1 is disabled").arg(dirname));
743  return;
744  }
745 
746  LOG(VB_GENERAL, LOG_INFO, LOC +
747  QString("Pruning cache directory: %1").arg(dirname));
748  QDateTime cutoff = MythDate::current().addDays(-days);
749  qint64 cutoffsecs = cutoff.toSecsSinceEpoch();
750 
751  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
752  QString("Removing files not accessed since %1")
753  .arg(cutoff.toLocalTime().toString(Qt::ISODate)));
754 
755  int kept = 0;
756  int deleted = 0;
757  int errcnt = 0;
758  QDir dir(dirname);
759  dir.setFilter(QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot);
760  dir.setSorting(QDir::NoSort);
761 
762  // Trying to save every cycle possible within this loop. The
763  // stat() call seems significantly faster than the fi.fileRead()
764  // method. The documentation for QFileInfo says that the
765  // fi.absoluteFilePath() method has to query the file system, so
766  // use fi.filePath() method here and then add the directory if
767  // needed. Using dir.entryList() and adding the dirname each time
768  // is also slower just using dir.entryInfoList().
769  for (const QFileInfo & fi : dir.entryInfoList())
770  {
771  struct stat buf {};
772  QString fullname = fi.filePath();
773  if (not fullname.startsWith('/'))
774  fullname = dirname + "/" + fullname;
775  QByteArray fullname8 = fullname.toLocal8Bit();
776  int rc = stat(fullname8, &buf);
777  if (rc == -1)
778  {
779  errcnt += 1;
780  continue;
781  }
782  if (buf.st_atime >= cutoffsecs)
783  {
784  kept += 1;
785  LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC +
786  QString("%1 Keep %2")
787  .arg(fi.lastRead().toLocalTime().toString(Qt::ISODate))
788  .arg(fi.fileName()));
789  continue;
790  }
791  deleted += 1;
792  LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC +
793  QString("%1 Delete %2")
794  .arg(fi.lastRead().toLocalTime().toString(Qt::ISODate))
795  .arg(fi.fileName()));
796  unlink(fullname8);
797  }
798 
799  LOG(VB_GENERAL, LOG_INFO, LOC +
800  QString("Kept %1 files, deleted %2 files, stat error on %3 files")
801  .arg(kept).arg(deleted).arg(errcnt));
802 }
803 
805 {
806  d->StoreGUIsettings();
807 }
808 
810 {
811  return d->m_screenRect;
812 }
813 
814 void MythUIHelper::GetScreenSettings(float &XFactor, float &YFactor)
815 {
816  XFactor = d->m_wmult;
817  YFactor = d->m_hmult;
818 }
819 
820 void MythUIHelper::GetScreenSettings(QRect &Rect, float &XFactor, float &YFactor)
821 {
822  XFactor = d->m_wmult;
823  YFactor = d->m_hmult;
824  Rect = d->m_screenRect;
825 }
826 
836 void MythUIHelper::ParseGeometryOverride(const QString &geometry)
837 {
838  QRegExp sre("^(\\d+)x(\\d+)$");
839  QRegExp lre(R"(^(\d+)x(\d+)([+-]\d+)([+-]\d+)$)");
840  QStringList geo;
841  bool longForm = false;
842 
843  if (sre.exactMatch(geometry))
844  {
845  geo = sre.capturedTexts();
846  }
847  else if (lre.exactMatch(geometry))
848  {
849  geo = lre.capturedTexts();
850  longForm = true;
851  }
852  else
853  {
854  LOG(VB_GENERAL, LOG_ERR, LOC +
855  "Geometry does not match either form -\n\t\t\t"
856  "WIDTHxHEIGHT or WIDTHxHEIGHT+XOFF+YOFF");
857  return;
858  }
859 
860  bool parsed = false;
861  int tmp_h = 0;
862  int tmp_w = geo[1].toInt(&parsed);
863 
864  if (!parsed)
865  {
866  LOG(VB_GENERAL, LOG_ERR, LOC +
867  "Could not parse width of geometry override");
868  }
869 
870  if (parsed)
871  {
872  tmp_h = geo[2].toInt(&parsed);
873 
874  if (!parsed)
875  {
876  LOG(VB_GENERAL, LOG_ERR, LOC +
877  "Could not parse height of geometry override");
878  }
879  }
880 
881  if (parsed)
882  {
885  LOG(VB_GENERAL, LOG_INFO, LOC +
886  QString("Overriding GUI size: width=%1 height=%2")
887  .arg(tmp_w).arg(tmp_h));
888  }
889  else
890  {
891  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to override GUI size.");
892  }
893 
894  if (longForm)
895  {
896  int tmp_x = geo[3].toInt(&parsed);
897  if (!parsed)
898  {
899  LOG(VB_GENERAL, LOG_ERR, LOC +
900  "Could not parse horizontal offset of geometry override");
901  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to override GUI offset.");
902  return;
903  }
904 
905  int tmp_y = geo[4].toInt(&parsed);
906  if (!parsed)
907  {
908  LOG(VB_GENERAL, LOG_ERR, LOC +
909  "Could not parse vertical offset of geometry override");
910  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to override GUI offset.");
911  return;
912  }
913 
916  LOG(VB_GENERAL, LOG_INFO, LOC +
917  QString("Overriding GUI offset: x=%1 y=%2")
918  .arg(tmp_x).arg(tmp_y));
919  }
920 }
921 
923 {
924  return (MythUIHelperPrivate::x_override >= 0 ||
928 }
929 
936 {
937  // NB Call IsGeometryOverridden first to ensure this is valid
940 }
941 
953 QString MythUIHelper::FindThemeDir(const QString &themename, bool doFallback)
954 {
955  QString testdir;
956  QDir dir;
957 
958  if (!themename.isEmpty())
959  {
960  testdir = d->m_userThemeDir + themename;
961 
962  dir.setPath(testdir);
963 
964  if (dir.exists())
965  return testdir;
966 
967  testdir = GetThemesParentDir() + themename;
968  dir.setPath(testdir);
969 
970  if (dir.exists())
971  return testdir;
972 
973  LOG(VB_GENERAL, LOG_WARNING, LOC + QString("No theme dir: '%1'")
974  .arg(dir.absolutePath()));
975  }
976 
977  if (!doFallback)
978  return QString();
979 
980  testdir = GetThemesParentDir() + DEFAULT_UI_THEME;
981  dir.setPath(testdir);
982 
983  if (dir.exists())
984  {
985  LOG(VB_GENERAL, LOG_ERR, LOC +
986  QString("Could not find theme: %1 - Switching to %2")
987  .arg(themename).arg(DEFAULT_UI_THEME));
988  GetMythDB()->OverrideSettingForSession("Theme", DEFAULT_UI_THEME);
989  return testdir;
990  }
991 
992  LOG(VB_GENERAL, LOG_WARNING, LOC + QString("No default theme dir: '%1'")
993  .arg(dir.absolutePath()));
994 
996  dir.setPath(testdir);
997 
998  if (dir.exists())
999  {
1000  LOG(VB_GENERAL, LOG_ERR, LOC +
1001  QString("Could not find theme: %1 - Switching to %2")
1002  .arg(themename).arg(FALLBACK_UI_THEME));
1003  GetMythDB()->OverrideSettingForSession("Theme", FALLBACK_UI_THEME);
1004  return testdir;
1005  }
1006 
1007  LOG(VB_GENERAL, LOG_ERR, LOC + QString("No fallback GUI theme dir: '%1'")
1008  .arg(dir.absolutePath()));
1009 
1010  return QString();
1011 }
1012 
1021 QString MythUIHelper::FindMenuThemeDir(const QString &menuname)
1022 {
1023  QString testdir;
1024  QDir dir;
1025 
1026  testdir = d->m_userThemeDir + menuname;
1027 
1028  dir.setPath(testdir);
1029 
1030  if (dir.exists())
1031  return testdir;
1032 
1033  testdir = GetThemesParentDir() + menuname;
1034  dir.setPath(testdir);
1035 
1036  if (dir.exists())
1037  return testdir;
1038 
1039  testdir = GetShareDir();
1040  dir.setPath(testdir);
1041 
1042  if (dir.exists())
1043  {
1044  LOG(VB_GENERAL, LOG_ERR, LOC +
1045  QString("Could not find menu theme: %1 - Switching to default")
1046  .arg(menuname));
1047 
1048  GetMythDB()->SaveSetting("MenuTheme", "default");
1049  return testdir;
1050  }
1051 
1052  LOG(VB_GENERAL, LOG_ERR, LOC +
1053  QString("Could not find menu theme: %1 - Fallback to default failed.")
1054  .arg(menuname));
1055 
1056  return QString();
1057 }
1058 
1060 {
1061  return d->m_menuthemepathname;
1062 }
1063 
1065 {
1066  return d->m_themepathname;
1067 }
1068 
1070 {
1071  return d->m_themename;
1072 }
1073 
1075 {
1076  if (!d->m_searchPaths.isEmpty())
1077  return d->m_searchPaths;
1078 
1079  // traverse up the theme inheritance list adding their location to the search path
1080  QList<ThemeInfo> themeList = GetThemes(THEME_UI);
1081  bool found = true;
1082  QString themeName = d->m_themename;
1083  QString baseName;
1084  QString dirName;
1085 
1086  while (found && !themeName.isEmpty())
1087  {
1088  // find the ThemeInfo for this theme
1089  found = false;
1090  baseName = "";
1091  dirName = "";
1092 
1093  for (int x = 0; x < themeList.count(); x++)
1094  {
1095  if (themeList.at(x).GetName() == themeName)
1096  {
1097  found = true;
1098  baseName = themeList.at(x).GetBaseTheme();
1099  dirName = themeList.at(x).GetDirectoryName();
1100  break;
1101  }
1102  }
1103 
1104  // try to find where the theme is installed
1105  if (found)
1106  {
1107  QString themedir = FindThemeDir(dirName, false);
1108  if (!themedir.isEmpty())
1109  {
1110  LOG(VB_GUI, LOG_INFO, LOC + QString("Adding path '%1' to theme search paths").arg(themedir));
1111  d->m_searchPaths.append(themedir + '/');
1112  }
1113  else
1114  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find ui theme location: %1").arg(themedir));
1115  }
1116  else
1117  {
1118  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Could not find inherited theme: %1").arg(themeName));
1119  }
1120 
1121  themeName = baseName;
1122  }
1123 
1124  if (d->m_isWide)
1125  d->m_searchPaths.append(GetThemesParentDir() + "default-wide/");
1126 
1127  d->m_searchPaths.append(GetThemesParentDir() + "default/");
1128  d->m_searchPaths.append("/tmp/");
1129  return d->m_searchPaths;
1130 }
1131 
1133 {
1134  QFileInfoList fileList;
1135  QList<ThemeInfo> themeList;
1136  QDir themeDirs(GetThemesParentDir());
1137  themeDirs.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
1138  themeDirs.setSorting(QDir::Name | QDir::IgnoreCase);
1139 
1140  fileList.append(themeDirs.entryInfoList());
1141 
1142  themeDirs.setPath(d->m_userThemeDir);
1143 
1144  fileList.append(themeDirs.entryInfoList());
1145 
1146  for (const auto & theme : qAsConst(fileList))
1147  {
1148  if (theme.baseName() == "default" ||
1149  theme.baseName() == "default-wide" ||
1150  theme.baseName() == "Slave")
1151  continue;
1152 
1153  ThemeInfo themeInfo(theme.absoluteFilePath());
1154 
1155  if (themeInfo.GetType() & type)
1156  themeList.append(themeInfo);
1157  }
1158 
1159  return themeList;
1160 }
1161 
1162 bool MythUIHelper::FindThemeFile(QString &path)
1163 {
1164  QFileInfo fi(path);
1165 
1166  if (fi.isAbsolute() && fi.exists())
1167  return true;
1168 #ifdef Q_OS_ANDROID
1169  if (path.startsWith("assets:/") && fi.exists())
1170  return true;
1171 #endif
1172 
1173  QString file;
1174  bool foundit = false;
1175  const QStringList searchpath = GetThemeSearchPath();
1176 
1177  for (const auto & ii : qAsConst(searchpath))
1178  {
1179  if (fi.isRelative())
1180  {
1181  file = ii + fi.filePath();
1182  }
1183  else if (fi.isAbsolute() && !fi.isRoot())
1184  {
1185  file = ii + fi.fileName();
1186  }
1187 
1188  if (QFile::exists(file))
1189  {
1190  path = file;
1191  foundit = true;
1192  break;
1193  }
1194  }
1195 
1196  return foundit;
1197 }
1198 
1199 MythImage *MythUIHelper::LoadCacheImage(QString srcfile, const QString& label,
1200  MythPainter *painter,
1201  ImageCacheMode cacheMode)
1202 {
1203  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
1204  QString("LoadCacheImage(%1,%2)").arg(srcfile).arg(label));
1205 
1206  if (srcfile.isEmpty() || label.isEmpty())
1207  return nullptr;
1208 
1209  if (!(kCacheForceStat & cacheMode))
1210  {
1211  // Some screens include certain images dozens or even hundreds of
1212  // times. Even if the image is in the cache, there is still a
1213  // stat system call on the original file to see if it has changed.
1214  // This code relaxes the original-file check so that the check
1215  // isn't repeated if it was already done within kImageCacheTimeout
1216  // seconds.
1217 
1218  // This only applies to the MEMORY cache
1219  const uint kImageCacheTimeout = 60;
1220  qint64 now = MythDate::current().toSecsSinceEpoch();
1221 
1222  QMutexLocker locker(d->m_cacheLock);
1223 
1224  if (d->m_imageCache.contains(label) &&
1225  d->m_cacheTrack[label] + kImageCacheTimeout > now)
1226  {
1227  d->m_imageCache[label]->IncrRef();
1228  return d->m_imageCache[label];
1229  }
1230  }
1231 
1232  MythImage *ret = nullptr;
1233 
1234  // Check Memory Cache
1235  ret = GetImageFromCache(label);
1236 
1237  // If the image is in the memory or we are not ignoring the disk cache
1238  // then proceed to check whether the source file is newer than our cached
1239  // copy
1240  if (ret || !(cacheMode & kCacheIgnoreDisk))
1241  {
1242  // Create url to image in disk cache
1243  QString cachefilepath;
1244  cachefilepath = GetCacheDirByUrl(label) + '/' + label;
1245  QFileInfo cacheFileInfo(cachefilepath);
1246 
1247  // If the file isn't in the disk cache, then we don't want to bother
1248  // checking the last modified times of the original
1249  if (!cacheFileInfo.exists())
1250  return nullptr;
1251 
1252  // Now compare the time on the source versus our cached copy
1253  QDateTime srcLastModified;
1254 
1255  // For internet images this involves querying the headers of the remote
1256  // image. This is slow even without redownloading the whole image
1257  if ((srcfile.startsWith("http://")) ||
1258  (srcfile.startsWith("https://")) ||
1259  (srcfile.startsWith("ftp://")))
1260  {
1261  // If the image is in the memory cache then skip the last modified
1262  // check, since memory cached images are loaded in the foreground
1263  // this can cause an intolerable delay. The images won't stay in
1264  // the cache forever and so eventually they will be checked.
1265  if (ret)
1266  srcLastModified = cacheFileInfo.lastModified();
1267  else
1268  {
1269  srcLastModified =
1271  }
1272  }
1273  else if (srcfile.startsWith("myth://"))
1274  srcLastModified = RemoteFile::LastModified(srcfile);
1275  else
1276  {
1277  if (!FindThemeFile(srcfile))
1278  return nullptr;
1279 
1280  QFileInfo original(srcfile);
1281 
1282  if (original.exists())
1283  srcLastModified = original.lastModified();
1284  }
1285 
1286  // Now compare the timestamps, if the cached image is newer than the
1287  // source image we can use it, otherwise we want to remove it from the
1288  // cache
1289  if (cacheFileInfo.lastModified() >= srcLastModified)
1290  {
1291  // If we haven't already loaded the image from the memory cache
1292  // and we're not ignoring the disk cache, then it's time to load
1293  // it from there instead
1294  if (!ret && (cacheMode == kCacheNormal))
1295  {
1296 
1297  if (painter)
1298  {
1299  ret = painter->GetFormatImage();
1300 
1301  // Load file from disk cache to memory cache
1302  if (ret->Load(cachefilepath))
1303  {
1304  // Add to ram cache, and skip saving to disk since that is
1305  // where we found this in the first place.
1306  CacheImage(label, ret, true);
1307  }
1308  else
1309  {
1310  LOG(VB_GUI | VB_FILE, LOG_WARNING, LOC +
1311  QString("LoadCacheImage: Could not load :%1")
1312  .arg(cachefilepath));
1313 
1314  ret->SetIsInCache(false);
1315  ret->DecrRef();
1316  ret = nullptr;
1317  }
1318  }
1319  }
1320  }
1321  else
1322  {
1323  ret = nullptr;
1324  // If file has changed on disk, then remove it from the memory
1325  // and disk cache
1326  RemoveFromCacheByURL(label);
1327  }
1328  }
1329 
1330  return ret;
1331 }
1332 
1334 {
1335  QFont font = QApplication::font();
1336  font.setPointSize(GetMythMainWindow()->NormalizeFontSize(25));
1337  font.setWeight(QFont::Bold);
1338 
1339  return font;
1340 }
1341 
1343 {
1344  QFont font = QApplication::font();
1345  font.setPointSize(GetMythMainWindow()->NormalizeFontSize(16));
1346  font.setWeight(QFont::Bold);
1347 
1348  return font;
1349 }
1350 
1352 {
1353  QFont font = QApplication::font();
1354  font.setPointSize(GetMythMainWindow()->NormalizeFontSize(12));
1355  font.setWeight(QFont::Bold);
1356 
1357  return font;
1358 }
1359 
1361 {
1362  if (qobject_cast<QApplication*>(QCoreApplication::instance()) != nullptr)
1363  {
1364  QCoreApplication::postEvent(
1367  }
1368 }
1369 
1371 {
1372  if (qobject_cast<QApplication*>(QCoreApplication::instance()) != nullptr)
1373  {
1374  QCoreApplication::postEvent(
1377  }
1378 }
1379 
1381 {
1382  if (qobject_cast<QApplication*>(QCoreApplication::instance()) != nullptr)
1383  {
1384  QCoreApplication::postEvent(
1387  }
1388 }
1389 
1391 {
1392  if (d->m_screensaver)
1393  {
1394  d->m_screensaver->Disable();
1395  d->m_screensaverEnabled = false;
1396  }
1397 }
1398 
1400 {
1401  if (d->m_screensaver)
1402  {
1403  d->m_screensaver->Restore();
1404  d->m_screensaverEnabled = true;
1405  }
1406 }
1407 
1409 {
1410  if (d->m_screensaver)
1411  {
1412  d->m_screensaver->Reset();
1413  d->m_screensaverEnabled = false;
1414  }
1415 }
1416 
1418 {
1419  return d->m_screensaverEnabled;
1420 }
1421 
1423 {
1424  if (!d->m_screensaver)
1425  return false;
1426 
1427  return d->m_screensaver->Asleep();
1428 }
1429 
1430 void MythUIHelper::AddCurrentLocation(const QString& location)
1431 {
1432  QMutexLocker locker(&m_locationLock);
1433 
1434  if (m_currentLocation.isEmpty() || m_currentLocation.last() != location)
1435  m_currentLocation.push_back(location);
1436 }
1437 
1439 {
1440  QMutexLocker locker(&m_locationLock);
1441 
1442  if (m_currentLocation.isEmpty())
1443  return QString("UNKNOWN");
1444 
1445  return m_currentLocation.takeLast();
1446 }
1447 
1448 QString MythUIHelper::GetCurrentLocation(bool fullPath, bool mainStackOnly)
1449 {
1450  QString result;
1451  QMutexLocker locker(&m_locationLock);
1452 
1453  if (fullPath)
1454  {
1455  // get main stack top screen
1457  result = stack->GetLocation(true);
1458 
1459  if (!mainStackOnly)
1460  {
1461  // get popup stack main screen
1462  stack = GetMythMainWindow()->GetStack("popup stack");
1463 
1464  if (!stack->GetLocation(true).isEmpty())
1465  result += '/' + stack->GetLocation(false);
1466  }
1467 
1468  // if there's a location in the stringlist add that (non mythui screen or external app running)
1469  if (!m_currentLocation.isEmpty())
1470  {
1471  for (int x = 0; x < m_currentLocation.count(); x++)
1472  result += '/' + m_currentLocation[x];
1473  }
1474  }
1475  else
1476  {
1477  // get main stack top screen
1479  result = stack->GetLocation(false);
1480 
1481  if (!mainStackOnly)
1482  {
1483  // get popup stack top screen
1484  stack = GetMythMainWindow()->GetStack("popup stack");
1485 
1486  if (!stack->GetLocation(false).isEmpty())
1487  result = stack->GetLocation(false);
1488  }
1489 
1490  // if there's a location in the stringlist use that (non mythui screen or external app running)
1491  if (!m_currentLocation.isEmpty())
1492  result = m_currentLocation.last();
1493  }
1494 
1495  if (result.isEmpty())
1496  result = "UNKNOWN";
1497 
1498  return result;
1499 }
1500 
1502 {
1503  return d->m_imageThreadPool;
1504 }
1505 
1506 QSize MythUIHelper::GetBaseSize(void) const
1507 {
1508  return d->m_baseSize;
1509 }
1510 
1512 {
1513  d->m_fontStretch = stretch;
1514 }
1515 
1517 {
1518  return d->m_fontStretch;
1519 }
MythUIHelper::~MythUIHelper
~MythUIHelper()
Definition: mythuihelper.cpp:277
GetThemesParentDir
QString GetThemesParentDir(void)
Definition: mythdirs.cpp:225
else
else
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:474
themedir
static QString themedir
Definition: mythdirs.cpp:21
RemoteFile::LastModified
QDateTime LastModified(void) const
Definition: remotefile.cpp:1269
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:304
fileInfo
QFileInfo fileInfo(filename)
ScreenSaverEvent::ssetDisable
@ ssetDisable
Definition: screensaver.h:11
ScreenSaverControl::Restore
void Restore(void)
Definition: screensaver.cpp:62
x11colors.h
MythUIHelperPrivate::m_parent
MythUIHelper * m_parent
Definition: mythuihelper.cpp:102
MythUIHelper::RemoveCurrentLocation
QString RemoveCurrentLocation(void)
Definition: mythuihelper.cpp:1438
MythUIHelperPrivate::Init
void Init()
Definition: mythuihelper.cpp:192
uiLock
static QMutex uiLock
Definition: mythuihelper.cpp:47
MythImage::Load
bool Load(MythImageReader *reader)
Definition: mythimage.cpp:278
screensaver.h
mythdb.h
MythUIHelperPrivate::m_themeloaded
bool m_themeloaded
Do we have a palette and pixmap to use?
Definition: mythuihelper.cpp:128
MythUIHelper::m_currentLocation
QStringList m_currentLocation
Definition: mythuihelper.h:143
MythUIHelperPrivate::m_display
MythDisplay * m_display
Definition: mythuihelper.cpp:147
ScreenSaverControl::Reset
void Reset(void)
Definition: screensaver.cpp:69
MythUIHelper::DoRestoreScreensaver
void DoRestoreScreensaver(void)
Definition: mythuihelper.cpp:1399
MythUIHelperPrivate::m_cacheLock
QMutex * m_cacheLock
Definition: mythuihelper.cpp:132
MythUIHelperPrivate::m_imageThreadPool
MThreadPool * m_imageThreadPool
Definition: mythuihelper.cpp:149
MythUIHelper::ExcludeFromCacheSize
void ExcludeFromCacheSize(MythImage *im)
Definition: mythuihelper.cpp:422
MythUIHelperPrivate::m_hmult
float m_hmult
Definition: mythuihelper.cpp:120
MythUIHelper::GetThemeSearchPath
QStringList GetThemeSearchPath(void)
Definition: mythuihelper.cpp:1074
MythPainter::GetFormatImage
MythImage * GetFormatImage()
Returns a blank reference counted image in the format required for the Draw functions for this painte...
Definition: mythpainter.cpp:540
ScreenSaverControl::Asleep
bool Asleep(void)
Definition: screensaver.cpp:76
MythUIHelper::GetScreenIsAsleep
bool GetScreenIsAsleep(void)
Definition: mythuihelper.cpp:1422
MythUIHelper::GetImageFromCache
MythImage * GetImageFromCache(const QString &url)
Returns a reference counted image base on the URL.
Definition: mythuihelper.cpp:387
MythUIHelper::MythUIHelper
MythUIHelper()
Definition: mythuihelper.cpp:272
MythUIHelperPrivate::StoreGUIsettings
void StoreGUIsettings(void)
Apply any user overrides to the screen geometry.
Definition: mythuihelper.cpp:207
MythScreenStack
Definition: mythscreenstack.h:16
arg
arg(title).arg(filename).arg(doDelete))
MythUIHelper::PruneCacheDir
static void PruneCacheDir(const QString &dirname)
Remove all files in the cache that haven't been accessed in a user configurable number of days.
Definition: mythuihelper.cpp:737
MythUIHelper::GetBigFont
static QFont GetBigFont(void)
Definition: mythuihelper.cpp:1333
MythUIHelper::getMythUI
static MythUIHelper * getMythUI(void)
Definition: mythuihelper.cpp:49
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythUIHelper::FindThemeFile
bool FindThemeFile(QString &path)
Definition: mythuihelper.cpp:1162
MythUIHelper::DoDisableScreensaver
void DoDisableScreensaver(void)
Definition: mythuihelper.cpp:1390
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:46
build_compdb.file
file
Definition: build_compdb.py:55
MythUIHelperPrivate::m_screenSetup
bool m_screenSetup
Definition: mythuihelper.cpp:157
mythdirs.h
MythUIHelper::GetScreensaverEnabled
bool GetScreensaverEnabled(void)
Definition: mythuihelper.cpp:1417
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &stackname)
Definition: mythmainwindow.cpp:309
MythUIHelperPrivate::m_imageCache
QMap< QString, MythImage * > m_imageCache
Definition: mythuihelper.cpp:130
MythDisplay::GetPixelAspectRatio
double GetPixelAspectRatio(void)
Definition: mythdisplay.cpp:257
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
mythprogressdialog.h
MythUIHelper::GetImageThreadPool
MThreadPool * GetImageThreadPool(void)
Definition: mythuihelper.cpp:1501
MythUIHelper::m_locationLock
QMutex m_locationLock
Definition: mythuihelper.h:142
MythUIHelperPrivate::w_override
static int w_override
Definition: mythuihelper.cpp:116
MythUIHelperPrivate::m_themepathname
QString m_themepathname
Definition: mythuihelper.cpp:105
MythUIHelper::DoResetScreensaver
void DoResetScreensaver(void)
Definition: mythuihelper.cpp:1408
ScreenSaverControl::Disable
void Disable(void)
Definition: screensaver.cpp:55
ScreenSaverEvent::ssetRestore
@ ssetRestore
Definition: screensaver.h:11
MythImage::SetIsInCache
void SetIsInCache(bool bCached)
Definition: mythimage.cpp:72
ScreenSaverControl
Controls all instances of the screensaver.
Definition: screensaver.h:44
MythDisplay::SwitchToDesktop
void SwitchToDesktop(void)
Return the screen to the original desktop video mode.
Definition: mythdisplay.cpp:624
MythUIHelper::RemoveFromCacheByURL
void RemoveFromCacheByURL(const QString &url)
Definition: mythuihelper.cpp:539
MythUIHelperPrivate::y_override
static int y_override
Definition: mythuihelper.cpp:115
MythUIHelperPrivate::MythUIHelperPrivate
MythUIHelperPrivate(MythUIHelper *p)
Definition: mythuihelper.cpp:94
baseName
QString baseName
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:590
mythdate.h
MythUIHelper::CacheImage
MythImage * CacheImage(const QString &url, MythImage *im, bool nodisk=false)
Definition: mythuihelper.cpp:434
mythdisplay.h
DEFAULT_UI_THEME
#define DEFAULT_UI_THEME
Definition: mythuihelper.h:12
mythlogging.h
themeinfo.h
MythUIHelperPrivate::m_baseSize
QSize m_baseSize
Definition: mythuihelper.cpp:125
remotefile.h
MythUIHelper::GetThemeCacheDir
QString GetThemeCacheDir(void)
Definition: mythuihelper.cpp:613
MythUIHelper::GetCurrentLocation
QString GetCurrentLocation(bool fullPath=false, bool mainStackOnly=true)
Definition: mythuihelper.cpp:1448
MythUIHelperPrivate::h_override
static int h_override
Definition: mythuihelper.cpp:117
hardwareprofile.config.p
p
Definition: config.py:33
kCacheForceStat
@ kCacheForceStat
Definition: mythuihelper.h:29
MythUIHelper::UpdateScreenSettings
void UpdateScreenSettings(void)
Definition: mythuihelper.cpp:804
GetShareDir
QString GetShareDir(void)
Definition: mythdirs.cpp:222
MythUIHelper::GetBaseSize
QSize GetBaseSize(void) const
Definition: mythuihelper.cpp:1506
ScreenSaverEvent
Definition: screensaver.h:9
MythUIHelper::GetSmallFont
static QFont GetSmallFont(void)
Definition: mythuihelper.cpp:1351
MythUIHelper::destroyMythUI
static void destroyMythUI(void)
Definition: mythuihelper.cpp:71
kCacheIgnoreDisk
@ kCacheIgnoreDisk
Definition: mythuihelper.h:27
MythUIHelperPrivate::m_userThemeDir
QString m_userThemeDir
Definition: mythuihelper.cpp:145
MythImage::DecrRef
int DecrRef(void) override
Decrements reference count and deletes on 0.
Definition: mythimage.cpp:54
MythUIHelperPrivate::m_callbacks
MythUIMenuCallbacks m_callbacks
Definition: mythuihelper.cpp:151
GetThemeBaseCacheDir
QString GetThemeBaseCacheDir(void)
Returns the base directory where all theme related files should be cached.
Definition: mythdirs.cpp:257
MythUIHelperPrivate::m_screensaver
ScreenSaverControl * m_screensaver
Definition: mythuihelper.cpp:155
MythUIHelper::GetFontStretch
int GetFontStretch(void) const
Definition: mythuihelper.cpp:1516
StorageGroup::GetFirstDir
QString GetFirstDir(bool appendSlash=false) const
Definition: storagegroup.cpp:189
MythUIHelper::d
MythUIHelperPrivate * d
Definition: mythuihelper.h:140
MythUIHelper::ClearOldImageCache
void ClearOldImageCache(void)
Definition: mythuihelper.cpp:646
ThemeInfo
Definition: themeinfo.h:22
MythDisplay::UsingVideoModes
virtual bool UsingVideoModes(void)
Definition: mythdisplay.h:29
MythUIHelperPrivate::m_cacheSize
QAtomicInteger< qint64 > m_cacheSize
Definition: mythuihelper.cpp:140
MythUIHelper::RemoveFromCacheByFile
void RemoveFromCacheByFile(const QString &fname)
Definition: mythuihelper.cpp:560
storagegroup.h
MythUIHelper::IncludeInCacheSize
void IncludeInCacheSize(MythImage *im)
Definition: mythuihelper.cpp:410
MythUIHelperPrivate::m_isWide
bool m_isWide
Definition: mythuihelper.cpp:126
MythUIHelperPrivate::m_themename
QString m_themename
Definition: mythuihelper.cpp:106
GetSetting
t<< doc.toString(4);f.close();LOG(VB_JOBQUEUE, LOG_INFO, "Copying video file");bool res=copyFile(filename, saveDirectory+title+"/"+baseName);if(!res) return 0;if(QFile::exists(filename+".png")) { LOG(VB_JOBQUEUE, LOG_INFO, "Copying preview image");res=copyFile(filename+".png", saveDirectory+title+"/"+baseName+".png");if(!res) return 0;} LOG(VB_JOBQUEUE, LOG_INFO, "Item Archived OK");return 1;}int NativeArchive::exportVideo(QDomElement &itemNode, const QString &saveDirectory){ QString dbVersion=gCoreContext-> GetSetting("DBSchemaVer", "")
MythUIHelper::FindThemeDir
QString FindThemeDir(const QString &themename, bool doFallback=true)
Returns the full path to the theme denoted by themename.
Definition: mythuihelper.cpp:953
MythUIHelperPrivate::m_searchPaths
QStringList m_searchPaths
Definition: mythuihelper.cpp:153
ThemeType
ThemeType
Definition: themeinfo.h:14
uint
unsigned int uint
Definition: compat.h:140
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
MythDisplay
Definition: mythdisplay.h:19
MythUIHelper::LoadQtConfig
void LoadQtConfig(void)
Definition: mythuihelper.cpp:319
MythUIHelper::GetGeometryOverride
static QRect GetGeometryOverride(void)
Return the raw geometry override rectangle.
Definition: mythuihelper.cpp:935
GetThumbnailDir
QString GetThumbnailDir(void)
Returns the directory where all non-theme thumbnail files should be cached.
Definition: mythdirs.cpp:249
MythUIHelperPrivate::m_menuthemepathname
QString m_menuthemepathname
Definition: mythuihelper.cpp:104
MythUIHelper::RemoveCacheDir
void RemoveCacheDir(const QString &dirname)
Definition: mythuihelper.cpp:694
GetRemoteCacheDir
QString GetRemoteCacheDir(void)
Returns the directory for all files cached from the backend.
Definition: mythdirs.cpp:241
MythUIHelper::SetFontStretch
void SetFontStretch(int stretch)
Definition: mythuihelper.cpp:1511
MythDisplay::AcquireRelease
static MythDisplay * AcquireRelease(bool Acquire=true)
Definition: mythdisplay.cpp:70
MythUIHelper::IsImageInCache
bool IsImageInCache(const QString &url)
Definition: mythuihelper.cpp:600
MythUIHelper::GetMediumFont
static QFont GetMediumFont(void)
Definition: mythuihelper.cpp:1342
mythburn.themeName
string themeName
Definition: mythburn.py:218
mthreadpool.h
mythuihelper.h
MythImage::IncrRef
int IncrRef(void) override
Increments reference count.
Definition: mythimage.cpp:46
MythUIHelper::IsTopScreenInitialized
static bool IsTopScreenInitialized(void)
Definition: mythuihelper.cpp:314
MythUIHelper::IsGeometryOverridden
static bool IsGeometryOverridden(void)
Definition: mythuihelper.cpp:922
MThreadPool
Definition: mthreadpool.h:18
mythimage.h
ThemeInfo::GetType
int GetType() const
Definition: themeinfo.h:35
MythUIHelperPrivate::m_themecachedir
QString m_themecachedir
Definition: mythuihelper.cpp:144
MythUIHelperPrivate::~MythUIHelperPrivate
~MythUIHelperPrivate()
Definition: mythuihelper.cpp:165
MythUIHelper::GetThemeName
QString GetThemeName(void)
Definition: mythuihelper.cpp:1069
mythcorecontext.h
MythUIHelper::GetCacheDirByUrl
QString GetCacheDirByUrl(const QString &url)
Look at the url being read and decide whether the cached version should go into the theme cache or th...
Definition: mythuihelper.cpp:639
dir
QDir dir
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1171
MythPainter
Definition: mythpainter.h:33
MythDisplay::SwitchToGUI
bool SwitchToGUI(bool Wait=false)
Switches to the GUI resolution.
Definition: mythdisplay.cpp:700
MythImage
Definition: mythimage.h:37
MythUIHelper::AddCurrentLocation
void AddCurrentLocation(const QString &location)
Definition: mythuihelper.cpp:1430
MythCoreContext::ResetLanguage
void ResetLanguage(void)
Definition: mythcorecontext.cpp:1801
ScreenSaverEvent::ssetReset
@ ssetReset
Definition: screensaver.h:11
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:14
MythDisplay::GetScreenBounds
QRect GetScreenBounds(void)
Definition: mythdisplay.cpp:271
MythUIHelperPrivate::m_screenRect
QRect m_screenRect
Definition: mythuihelper.cpp:111
MythUIHelper::GetThemeDir
QString GetThemeDir(void)
Definition: mythuihelper.cpp:1064
MythUIHelper::Init
void Init(void)
Definition: mythuihelper.cpp:299
MythUIHelper::GetThemes
QList< ThemeInfo > GetThemes(ThemeType type)
Definition: mythuihelper.cpp:1132
MythUIHelper::ResetScreensaver
static void ResetScreensaver(void)
Definition: mythuihelper.cpp:1380
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:107
StorageGroup
Definition: storagegroup.h:12
MythUIHelperPrivate::m_maxCacheSize
QAtomicInteger< qint64 > m_maxCacheSize
Definition: mythuihelper.cpp:141
MythUIHelper::GetMenuThemeDir
QString GetMenuThemeDir(void)
Definition: mythuihelper.cpp:1059
MythScreenStack::GetLocation
QString GetLocation(bool fullPath) const
Definition: mythscreenstack.cpp:360
LOC
#define LOC
Definition: mythuihelper.cpp:44
FALLBACK_UI_THEME
#define FALLBACK_UI_THEME
Definition: mythuihelper.h:13
MythUIHelper::IsScreenSetup
bool IsScreenSetup(void)
Definition: mythuihelper.cpp:309
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:856
MythUIHelper::DisableScreensaver
static void DisableScreensaver(void)
Definition: mythuihelper.cpp:1360
MythDownloadManager::GetLastModified
QDateTime GetLastModified(const QString &url)
Gets the Last Modified timestamp for a URI.
Definition: mythdownloadmanager.cpp:1554
MythUIHelperPrivate
Definition: mythuihelper.cpp:92
MythUIHelper::LoadCacheImage
MythImage * LoadCacheImage(QString srcfile, const QString &label, MythPainter *painter, ImageCacheMode cacheMode=kCacheNormal)
Returns a reference counted image from the cache.
Definition: mythuihelper.cpp:1199
MythUIHelper
Definition: mythuihelper.h:42
MythUIHelper::GetMenuCBs
MythUIMenuCallbacks * GetMenuCBs(void)
Definition: mythuihelper.cpp:304
MythUIHelperPrivate::m_wmult
float m_wmult
Definition: mythuihelper.cpp:119
mythdownloadmanager.h
GetMythUI
MythUIHelper * GetMythUI()
Definition: mythuihelper.cpp:81
mythmainwindow.h
MythUIHelperPrivate::m_cacheTrack
QMap< QString, qint64 > m_cacheTrack
Definition: mythuihelper.cpp:131
MythUIHelperPrivate::m_palette
QPalette m_palette
Colour scheme.
Definition: mythuihelper.cpp:107
MythScreenType::IsInitialized
bool IsInitialized(void) const
Has Init() been called on this screen?
Definition: mythscreentype.cpp:376
THEME_UI
@ THEME_UI
Definition: themeinfo.h:16
ImageCacheMode
ImageCacheMode
Definition: mythuihelper.h:25
MythUIHelper::RestoreScreensaver
static void RestoreScreensaver(void)
Definition: mythuihelper.cpp:1370
MythUIHelper::ParseGeometryOverride
static void ParseGeometryOverride(const QString &geometry)
Parse an X11 style command line geometry string.
Definition: mythuihelper.cpp:836
mythui
static MythUIHelper * mythui
Definition: mythuihelper.cpp:46
DestroyMythUI
void DestroyMythUI()
Definition: mythuihelper.cpp:86
MythUIHelperPrivate::m_fontStretch
int m_fontStretch
Definition: mythuihelper.cpp:122
MythUIHelperPrivate::x_override
static int x_override
Definition: mythuihelper.cpp:114
MythUIHelper::GetScreenSettings
QRect GetScreenSettings(void)
Definition: mythuihelper.cpp:809
GetMythDownloadManager
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
Definition: mythdownloadmanager.cpp:161
MythUIHelperPrivate::m_screensaverEnabled
bool m_screensaverEnabled
Definition: mythuihelper.cpp:156
kCacheNormal
@ kCacheNormal
Definition: mythuihelper.h:26
MythScreenStack::GetTopScreen
virtual MythScreenType * GetTopScreen(void) const
Definition: mythscreenstack.cpp:179
MythUIHelper::UpdateImageCache
void UpdateImageCache(void)
Definition: mythuihelper.cpp:364
MythUIMenuCallbacks
Definition: mythuihelper.h:33
MythUIHelper::FindMenuThemeDir
QString FindMenuThemeDir(const QString &menuname)
Returns the full path to the menu theme denoted by menuname.
Definition: mythuihelper.cpp:1021