MythTV  master
mythuithemecache.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QDir>
3 #include <QDateTime>
4 
5 // MythTV
6 #include "mythlogging.h"
7 #include "mthreadpool.h"
8 #include "mythdb.h"
9 #include "remotefile.h"
10 #include "mythdownloadmanager.h"
11 #include "mythdate.h"
12 #include "mythdirs.h"
13 #include "mythuithemecache.h"
14 
15 // Std
16 #include <unistd.h>
17 #include <sys/stat.h>
18 
19 // Temp for DEFAULT_UI_THEME, ImageCacheMode etc
20 #include "mythuihelper.h"
21 
22 #define LOC QString("UICache: ")
23 
25  : m_imageThreadPool(new MThreadPool("MythUIHelper"))
26 {
27  m_maxCacheSize.fetchAndStoreRelease(GetMythDB()->GetNumSetting("UIImageCacheSize", 30) * 1024 * 1024);
28  LOG(VB_GUI, LOG_INFO, LOC + QString("MythUI Image Cache size set to %1 bytes")
29  .arg(m_maxCacheSize.fetchAndAddRelease(0)));
30 }
31 
33 {
36 
37  QMutableMapIterator<QString, MythImage *> i(m_imageCache);
38  while (i.hasNext())
39  {
40  i.next();
41  i.value()->SetIsInCache(false);
42  i.value()->DecrRef();
43  i.remove();
44  }
45  m_cacheTrack.clear();
46 
47  delete m_imageThreadPool;
48 }
49 
51 {
52  m_cacheScreenSize = Size;
53 }
54 
56 {
57  m_themecachedir.clear();
58 }
59 
61 {
62  QMutexLocker locker(&m_cacheLock);
63 
64  QMutableMapIterator<QString, MythImage *> i(m_imageCache);
65 
66  while (i.hasNext())
67  {
68  i.next();
69  i.value()->SetIsInCache(false);
70  i.value()->DecrRef();
71  i.remove();
72  }
73 
74  m_cacheTrack.clear();
75  m_cacheSize.fetchAndStoreOrdered(0);
76 
80 }
81 
83 {
85 
86  QString themecachedir = m_themecachedir;
87 
88  m_themecachedir += '/';
89 
90  QDir dir(GetThemeBaseCacheDir());
91  dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
92  QFileInfoList list = dir.entryInfoList();
93 
94  QMap<QDateTime, QString> dirtimes;
95 
96  for (const auto & fi : qAsConst(list))
97  {
98  if (fi.isDir() && !fi.isSymLink())
99  {
100  if (fi.absoluteFilePath() == themecachedir)
101  continue;
102  dirtimes[fi.lastModified()] = fi.absoluteFilePath();
103  }
104  }
105 
106  // Cache two themes/resolutions to allow sampling other themes without
107  // incurring a penalty. Especially for those writing new themes or testing
108  // changes of an existing theme. The space used is neglible when compared
109  // against the average video
110  while (static_cast<size_t>(dirtimes.size()) >= 2)
111  {
112  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("Removing cache dir: %1")
113  .arg(dirtimes.begin().value()));
114 
115  RemoveCacheDir(dirtimes.begin().value());
116  dirtimes.erase(dirtimes.begin());
117  }
118 
119  for (const auto & dirtime : qAsConst(dirtimes))
120  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("Keeping cache dir: %1").arg(dirtime));
121 }
122 
123 void MythUIThemeCache::RemoveCacheDir(const QString& Dir)
124 {
125  QString cachedirname = GetThemeBaseCacheDir();
126 
127  if (!Dir.startsWith(cachedirname))
128  return;
129 
130  LOG(VB_GENERAL, LOG_ERR, LOC + QString("Removing stale cache dir: %1").arg(Dir));
131 
132  QDir dir(Dir);
133  if (!dir.exists())
134  return;
135 
136  dir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
137  QFileInfoList list = dir.entryInfoList();
138  for (const auto & fi : qAsConst(list))
139  {
140  if (fi.isFile() && !fi.isSymLink())
141  {
142  QFile file(fi.absoluteFilePath());
143  file.remove();
144  }
145  else if (fi.isDir() && !fi.isSymLink())
146  {
147  RemoveCacheDir(fi.absoluteFilePath());
148  }
149  }
150 
151  dir.rmdir(Dir);
152 }
153 
160 void MythUIThemeCache::PruneCacheDir(const QString& dirname)
161 {
162  int days = GetMythDB()->GetNumSetting("UIDiskCacheDays", 7);
163  if (days == -1)
164  {
165  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Pruning cache directory: %1 is disabled")
166  .arg(dirname));
167  return;
168  }
169 
170  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Pruning cache directory: %1").arg(dirname));
171  QDateTime cutoff = MythDate::current().addDays(-days);
172  qint64 cutoffsecs = cutoff.toSecsSinceEpoch();
173 
174  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("Removing files not accessed since %1")
175  .arg(cutoff.toLocalTime().toString(Qt::ISODate)));
176 
177  // Trying to save every cycle possible within this loop. The
178  // stat() call seems significantly faster than the fi.fileRead()
179  // method. The documentation for QFileInfo says that the
180  // fi.absoluteFilePath() method has to query the file system, so
181  // use fi.filePath() method here and then add the directory if
182  // needed. Using dir.entryList() and adding the dirname each time
183  // is also slower just using dir.entryInfoList().
184  QDir dir(dirname);
185  dir.setFilter(QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot);
186  dir.setSorting(QDir::NoSort);
187  QFileInfoList entries = dir.entryInfoList();
188  int kept = 0;
189  int deleted = 0;
190  int errors = 0;
191  for (const QFileInfo & fi : qAsConst(entries))
192  {
193  struct stat buf {};
194  QString fullname = fi.filePath();
195  if (not fullname.startsWith('/'))
196  fullname = dirname + "/" + fullname;
197  int rc = stat(fullname.toLocal8Bit(), &buf);
198  if (rc >= 0)
199  {
200  if (buf.st_atime < cutoffsecs)
201  {
202  deleted += 1;
203  LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC + QString("%1 Delete %2")
204  .arg(fi.lastRead().toLocalTime().toString(Qt::ISODate)).arg(fi.fileName()));
205  unlink(qPrintable(fullname));
206  }
207  else
208  {
209  kept += 1;
210  LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC + QString("%1 Keep %2")
211  .arg(fi.lastRead().toLocalTime().toString(Qt::ISODate)).arg(fi.fileName()));
212  }
213  }
214  else
215  {
216  errors += 1;
217  }
218  }
219 
220  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Kept %1 files, deleted %2 files, stat error on %3 files")
221  .arg(kept).arg(deleted).arg(errors));
222 }
223 
225 {
226  static QString s_oldcachedir;
227  QString tmpcachedir = GetThemeBaseCacheDir() + "/" +
228  GetMythDB()->GetSetting("Theme", DEFAULT_UI_THEME) + "." +
229  QString::number(m_cacheScreenSize.width()) + "." +
230  QString::number(m_cacheScreenSize.height());
231 
232  if (tmpcachedir != s_oldcachedir)
233  {
234  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("Creating cache dir: %1").arg(tmpcachedir));
235  QDir dir;
236  dir.mkdir(tmpcachedir);
237  s_oldcachedir = tmpcachedir;
238  }
239  return tmpcachedir;
240 }
241 
249 QString MythUIThemeCache::GetCacheDirByUrl(const QString& URL)
250 {
251  if (URL.startsWith("myth:") || URL.startsWith("-"))
252  return GetThumbnailDir();
253  return GetThemeCacheDir();
254 }
255 
256 MythImage* MythUIThemeCache::LoadCacheImage(QString File, const QString& Label,
257  MythPainter *Painter,
258  ImageCacheMode cacheMode)
259 {
260  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
261  QString("LoadCacheImage(%1,%2)").arg(File).arg(Label));
262 
263  if (File.isEmpty() || Label.isEmpty())
264  return nullptr;
265 
266  if (!(kCacheForceStat & cacheMode))
267  {
268  // Some screens include certain images dozens or even hundreds of
269  // times. Even if the image is in the cache, there is still a
270  // stat system call on the original file to see if it has changed.
271  // This code relaxes the original-file check so that the check
272  // isn't repeated if it was already done within kImageCacheTimeout
273  // seconds.
274 
275  // This only applies to the MEMORY cache
276  const uint kImageCacheTimeout = 60;
277  qint64 now = MythDate::current().toSecsSinceEpoch();
278 
279  QMutexLocker locker(&m_cacheLock);
280 
281  if (m_imageCache.contains(Label) &&
282  m_cacheTrack[Label] + kImageCacheTimeout > now)
283  {
284  m_imageCache[Label]->IncrRef();
285  return m_imageCache[Label];
286  }
287  }
288 
289  MythImage *ret = nullptr;
290 
291  // Check Memory Cache
292  ret = GetImageFromCache(Label);
293 
294  // If the image is in the memory or we are not ignoring the disk cache
295  // then proceed to check whether the source file is newer than our cached
296  // copy
297  if (ret || !(cacheMode & kCacheIgnoreDisk))
298  {
299  // Create url to image in disk cache
300  QString cachefilepath;
301  cachefilepath = GetCacheDirByUrl(Label) + '/' + Label;
302  QFileInfo cacheFileInfo(cachefilepath);
303 
304  // If the file isn't in the disk cache, then we don't want to bother
305  // checking the last modified times of the original
306  if (!cacheFileInfo.exists())
307  return nullptr;
308 
309  // Now compare the time on the source versus our cached copy
310  QDateTime srcLastModified;
311 
312  // For internet images this involves querying the headers of the remote
313  // image. This is slow even without redownloading the whole image
314  if ((File.startsWith("http://")) ||
315  (File.startsWith("https://")) ||
316  (File.startsWith("ftp://")))
317  {
318  // If the image is in the memory cache then skip the last modified
319  // check, since memory cached images are loaded in the foreground
320  // this can cause an intolerable delay. The images won't stay in
321  // the cache forever and so eventually they will be checked.
322  if (ret)
323  srcLastModified = cacheFileInfo.lastModified();
324  else
325  srcLastModified = GetMythDownloadManager()->GetLastModified(File);
326  }
327  else if (File.startsWith("myth://"))
328  {
329  srcLastModified = RemoteFile::LastModified(File);
330  }
331  else
332  {
333  if (!GetMythUI()->FindThemeFile(File))
334  return nullptr;
335 
336  QFileInfo original(File);
337 
338  if (original.exists())
339  srcLastModified = original.lastModified();
340  }
341 
342  // Now compare the timestamps, if the cached image is newer than the
343  // source image we can use it, otherwise we want to remove it from the
344  // cache
345  if (cacheFileInfo.lastModified() >= srcLastModified)
346  {
347  // If we haven't already loaded the image from the memory cache
348  // and we're not ignoring the disk cache, then it's time to load
349  // it from there instead
350  if (!ret && (cacheMode == kCacheNormal))
351  {
352 
353  if (Painter)
354  {
355  ret = Painter->GetFormatImage();
356 
357  // Load file from disk cache to memory cache
358  if (ret->Load(cachefilepath))
359  {
360  // Add to ram cache, and skip saving to disk since that is
361  // where we found this in the first place.
362  CacheImage(Label, ret, true);
363  }
364  else
365  {
366  LOG(VB_GUI | VB_FILE, LOG_WARNING, LOC +
367  QString("LoadCacheImage: Could not load :%1")
368  .arg(cachefilepath));
369 
370  ret->SetIsInCache(false);
371  ret->DecrRef();
372  ret = nullptr;
373  }
374  }
375  }
376  }
377  else
378  {
379  ret = nullptr;
380  // If file has changed on disk, then remove it from the memory
381  // and disk cache
382  RemoveFromCacheByURL(Label);
383  }
384  }
385 
386  return ret;
387 }
388 
390 {
391  QMutexLocker locker(&m_cacheLock);
392 
393  if (m_imageCache.contains(URL))
394  {
395  m_cacheTrack[URL] = MythDate::current().toSecsSinceEpoch();
396  m_imageCache[URL]->IncrRef();
397  return m_imageCache[URL];
398  }
399 
400  /*
401  if (QFileInfo(URL).exists())
402  {
403  MythImage *im = GetMythPainter()->GetFormatImage();
404  im->Load(URL,false);
405  return im;
406  }
407  */
408 
409  return nullptr;
410 }
411 
412 MythImage *MythUIThemeCache::CacheImage(const QString& URL, MythImage* Image, bool NoDisk)
413 {
414  if (!Image)
415  return nullptr;
416 
417  if (!NoDisk)
418  {
419  QString dstfile = GetCacheDirByUrl(URL) + '/' + URL;
420  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("Saved to Cache (%1)").arg(dstfile));
421  // Save to disk cache
422  Image->save(dstfile, "PNG");
423  }
424 
425  // delete the oldest cached images until we fall below threshold.
426  QMutexLocker locker(&m_cacheLock);
427 
428  while ((m_cacheSize.fetchAndAddOrdered(0) +
429 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
430  Image->byteCount()
431 #else
432  Image->sizeInBytes()
433 #endif
434  ) >=
435  m_maxCacheSize.fetchAndAddOrdered(0) && !m_imageCache.empty())
436  {
437  QMap<QString, MythImage *>::iterator it = m_imageCache.begin();
438  qint64 oldestTime = MythDate::current().toSecsSinceEpoch();
439  QString oldestKey = it.key();
440 
441  int count = 0;
442 
443  for (; it != m_imageCache.end(); ++it)
444  {
445  if (m_cacheTrack[it.key()] < oldestTime)
446  {
447  if ((2 == it.value()->IncrRef()) && (it.value() != Image))
448  {
449  oldestTime = m_cacheTrack[it.key()];
450  oldestKey = it.key();
451  count++;
452  }
453  it.value()->DecrRef();
454  }
455  }
456 
457  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +QString("%1 images are eligible for expiry").arg(count));
458  if (count > 0)
459  {
460  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("Cache too big (%1), removing :%2:")
461  .arg(m_cacheSize.fetchAndAddOrdered(0) +
462 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
463  Image->byteCount()
464 #else
465  Image->sizeInBytes()
466 #endif
467  )
468  .arg(oldestKey));
469 
470  m_imageCache[oldestKey]->SetIsInCache(false);
471  m_imageCache[oldestKey]->DecrRef();
472  m_imageCache.remove(oldestKey);
473  m_cacheTrack.remove(oldestKey);
474  }
475  else
476  {
477  break;
478  }
479  }
480 
481  QMap<QString, MythImage *>::iterator it = m_imageCache.find(URL);
482 
483  if (it == m_imageCache.end())
484  {
485  Image->IncrRef();
486  m_imageCache[URL] = Image;
487  m_cacheTrack[URL] = MythDate::current().toSecsSinceEpoch();
488 
489  Image->SetIsInCache(true);
490  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
491  QString("NOT IN RAM CACHE, Adding, and adding to size :%1: :%2:").arg(URL)
492 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
493  .arg(Image->byteCount())
494 #else
495  .arg(Image->sizeInBytes())
496 #endif
497  );
498  }
499 
500  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("MythUIHelper::CacheImage : Cache Count = :%1: size :%2:")
501  .arg(m_imageCache.count()).arg(m_cacheSize.fetchAndAddRelaxed(0)));
502 
503  return m_imageCache[URL];
504 }
505 
507 {
508  QMutexLocker locker(&m_cacheLock);
509  QMap<QString, MythImage *>::iterator it = m_imageCache.find(URL);
510 
511  if (it != m_imageCache.end())
512  {
513  m_imageCache[URL]->SetIsInCache(false);
514  m_imageCache[URL]->DecrRef();
515  m_imageCache.remove(URL);
516  m_cacheTrack.remove(URL);
517  }
518 
519  QString dstfile = GetCacheDirByUrl(URL) + '/' + URL;
520  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("RemoveFromCacheByURL removed :%1: from cache").arg(dstfile));
521  QFile::remove(dstfile);
522 }
523 
525 {
526  QList<QString>::iterator it;
527 
528  QString partialKey = File;
529  partialKey.replace('/', '-');
530 
531  m_cacheLock.lock();
532  QList<QString> m_imageCacheKeys = m_imageCache.keys();
533  m_cacheLock.unlock();
534 
535  for (it = m_imageCacheKeys.begin(); it != m_imageCacheKeys.end(); ++it)
536  {
537  if ((*it).contains(partialKey))
539  }
540 
541  // Loop through files to cache any that were not caught by
542  // RemoveFromCacheByURL
543  QDir dir(GetThemeCacheDir());
544  QFileInfoList list = dir.entryInfoList();
545 
546  for (const auto & fileInfo : list)
547  {
548  if (fileInfo.fileName().contains(partialKey))
549  {
550  LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
551  QString("RemoveFromCacheByFile removed: %1: from cache")
552  .arg(fileInfo.fileName()));
553 
554  if (!dir.remove(fileInfo.fileName()))
555  {
556  LOG(VB_GENERAL, LOG_ERR, LOC +
557  QString("Failed to delete %1 from the theme cache")
558  .arg(fileInfo.fileName()));
559  }
560  }
561  }
562 }
563 
564 bool MythUIThemeCache::IsImageInCache(const QString& URL)
565 {
566  QMutexLocker locker(&m_cacheLock);
567  if (m_imageCache.contains(URL))
568  return true;
569  if (QFileInfo::exists(URL))
570  return true;
571  return false;
572 }
573 
575 {
576  if (Image)
577  {
578 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
579  m_cacheSize.fetchAndAddOrdered(Image->byteCount());
580 #else
581  m_cacheSize.fetchAndAddOrdered(Image->sizeInBytes());
582 #endif
583  }
584 }
585 
587 {
588  if (Image)
589  {
590 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
591  m_cacheSize.fetchAndAddOrdered(-Image->byteCount());
592 #else
593  m_cacheSize.fetchAndAddOrdered(-Image->sizeInBytes());
594 #endif
595  }
596 }
597 
599 {
600  return m_imageThreadPool;
601 }
602 
else
else
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:477
RemoteFile::LastModified
QDateTime LastModified(void) const
Definition: remotefile.cpp:1268
fileInfo
QFileInfo fileInfo(filename)
MythImage::Load
bool Load(MythImageReader *reader)
Definition: mythimage.cpp:278
mythdb.h
MythUIThemeCache::m_cacheScreenSize
QSize m_cacheScreenSize
Definition: mythuithemecache.h:59
MythUIThemeCache::m_imageCache
QMap< QString, MythImage * > m_imageCache
Definition: mythuithemecache.h:48
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
arg
arg(title).arg(filename).arg(doDelete))
MythUIThemeCache::MythUIThemeCache
MythUIThemeCache()
Definition: mythuithemecache.cpp:24
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:45
build_compdb.file
file
Definition: build_compdb.py:55
mythdirs.h
Image
Definition: image.h:30
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
MythUIThemeCache::SetScreenSize
void SetScreenSize(QSize Size)
Definition: mythuithemecache.cpp:50
MythUIThemeCache::m_cacheSize
QAtomicInteger< qint64 > m_cacheSize
Definition: mythuithemecache.h:55
MythImage::SetIsInCache
void SetIsInCache(bool bCached)
Definition: mythimage.cpp:72
MythUIThemeCache::m_themecachedir
QString m_themecachedir
Definition: mythuithemecache.h:58
mythdate.h
MythUIThemeCache::RemoveFromCacheByURL
void RemoveFromCacheByURL(const QString &URL)
Definition: mythuithemecache.cpp:506
mythlogging.h
MythUIThemeCache::IsImageInCache
bool IsImageInCache(const QString &URL)
Definition: mythuithemecache.cpp:564
remotefile.h
ImageCacheMode
ImageCacheMode
Definition: mythuithemecache.h:11
MythDB::GetNumSetting
int GetNumSetting(const QString &key, int defaultval)
Definition: mythdb.cpp:570
kCacheNormal
@ kCacheNormal
Definition: mythuithemecache.h:13
kCacheForceStat
@ kCacheForceStat
Definition: mythuithemecache.h:16
MythUIThemeCache::PruneCacheDir
static void PruneCacheDir(const QString &Dir)
Remove all files in the cache that haven't been accessed in a user configurable number of days.
Definition: mythuithemecache.cpp:160
MythImage::DecrRef
int DecrRef(void) override
Decrements reference count and deletes on 0.
Definition: mythimage.cpp:54
MythUIThemeCache::RemoveFromCacheByFile
void RemoveFromCacheByFile(const QString &File)
Definition: mythuithemecache.cpp:524
GetThemeBaseCacheDir
QString GetThemeBaseCacheDir(void)
Returns the base directory where all theme related files should be cached.
Definition: mythdirs.cpp:257
MythUIThemeCache::GetThemeCacheDir
QString GetThemeCacheDir()
Definition: mythuithemecache.cpp:224
MythUIThemeCache::RemoveCacheDir
void RemoveCacheDir(const QString &Dir)
Definition: mythuithemecache.cpp:123
MythUIThemeCache::LoadCacheImage
MythImage * LoadCacheImage(QString File, const QString &Label, MythPainter *Painter, ImageCacheMode cacheMode=kCacheNormal)
Definition: mythuithemecache.cpp:256
uint
unsigned int uint
Definition: compat.h:141
kCacheIgnoreDisk
@ kCacheIgnoreDisk
Definition: mythuithemecache.h:14
MythUIThemeCache::ClearOldImageCache
void ClearOldImageCache()
Definition: mythuithemecache.cpp:82
MythUIThemeCache::IncludeInCacheSize
void IncludeInCacheSize(MythImage *Image)
Definition: mythuithemecache.cpp:574
MythUIThemeCache::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: mythuithemecache.cpp:249
mythuithemecache.h
DEFAULT_UI_THEME
#define DEFAULT_UI_THEME
Definition: mythuithemehelper.h:7
GetThumbnailDir
QString GetThumbnailDir(void)
Returns the directory where all non-theme thumbnail files should be cached.
Definition: mythdirs.cpp:249
MythUIThemeCache::GetImageFromCache
MythImage * GetImageFromCache(const QString &URL)
Definition: mythuithemecache.cpp:389
GetRemoteCacheDir
QString GetRemoteCacheDir(void)
Returns the directory for all files cached from the backend.
Definition: mythdirs.cpp:241
mthreadpool.h
mythuihelper.h
MThreadPool
Definition: mthreadpool.h:17
dir
QDir dir
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1174
MythPainter
Definition: mythpainter.h:32
MythImage
Definition: mythimage.h:36
MythDB::GetSetting
QString GetSetting(const QString &_key, const QString &defaultval)
Definition: mythdb.cpp:369
MythUIThemeCache::m_maxCacheSize
QAtomicInteger< qint64 > m_maxCacheSize
Definition: mythuithemecache.h:56
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:14
MythUIThemeCache::ExcludeFromCacheSize
void ExcludeFromCacheSize(MythImage *Image)
Definition: mythuithemecache.cpp:586
MythUIThemeCache::m_cacheLock
QMutex m_cacheLock
Definition: mythuithemecache.h:50
LOC
#define LOC
Definition: mythuithemecache.cpp:22
MythUIThemeCache::UpdateImageCache
void UpdateImageCache()
Definition: mythuithemecache.cpp:60
MythUIThemeCache::m_cacheTrack
QMap< QString, qint64 > m_cacheTrack
Definition: mythuithemecache.h:49
MythDownloadManager::GetLastModified
QDateTime GetLastModified(const QString &url)
Gets the Last Modified timestamp for a URI.
Definition: mythdownloadmanager.cpp:1545
MythUIThemeCache::ClearThemeCacheDir
void ClearThemeCacheDir()
Definition: mythuithemecache.cpp:55
MythUIThemeCache::m_imageThreadPool
MThreadPool * m_imageThreadPool
Definition: mythuithemecache.h:60
mythdownloadmanager.h
MythUIThemeCache::~MythUIThemeCache
~MythUIThemeCache()
Definition: mythuithemecache.cpp:32
GetMythUI
MythUIHelper * GetMythUI()
Definition: mythuihelper.cpp:66
MythUIThemeCache::GetImageThreadPool
MThreadPool * GetImageThreadPool()
Definition: mythuithemecache.cpp:598
MythUIThemeCache::CacheImage
MythImage * CacheImage(const QString &URL, MythImage *Image, bool NoDisk=false)
Definition: mythuithemecache.cpp:412
GetMythDownloadManager
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
Definition: mythdownloadmanager.cpp:145