00001 #include "mythuihelper.h"
00002
00003 #include <cmath>
00004
00005 #include <QImage>
00006 #include <QPixmap>
00007 #include <QMutex>
00008 #include <QPalette>
00009 #include <QMap>
00010 #include <QDir>
00011 #include <QFileInfo>
00012 #include <QApplication>
00013 #include <QPainter>
00014 #include <QDesktopWidget>
00015 #include <QStyleFactory>
00016 #include <QSize>
00017 #include <QFile>
00018
00019 #include "mythdirs.h"
00020 #include "mythlogging.h"
00021 #include "mythdownloadmanager.h"
00022 #include "oldsettings.h"
00023 #include "screensaver.h"
00024 #include "mythmainwindow.h"
00025 #include "mythdb.h"
00026 #include "themeinfo.h"
00027 #include "x11colors.h"
00028 #include "mythdisplay.h"
00029 #include "DisplayRes.h"
00030 #include "mythprogressdialog.h"
00031 #include "mythimage.h"
00032 #include "remotefile.h"
00033 #include "mythcorecontext.h"
00034 #include "mthreadpool.h"
00035 #include "storagegroup.h"
00036
00037 #define LOC QString("MythUIHelper: ")
00038
00039 static MythUIHelper *mythui = NULL;
00040 static QMutex uiLock;
00041 QString MythUIHelper::x11_display;
00042
00043 MythUIHelper *MythUIHelper::getMythUI(void)
00044 {
00045 if (mythui)
00046 return mythui;
00047
00048 uiLock.lock();
00049
00050 if (!mythui)
00051 mythui = new MythUIHelper();
00052
00053 uiLock.unlock();
00054
00055 return mythui;
00056 }
00057
00058 void MythUIHelper::destroyMythUI(void)
00059 {
00060 uiLock.lock();
00061 delete mythui;
00062 mythui = NULL;
00063 uiLock.unlock();
00064 }
00065
00066 MythUIHelper *GetMythUI()
00067 {
00068 return MythUIHelper::getMythUI();
00069 }
00070
00071 void DestroyMythUI()
00072 {
00073 MythUIHelper::destroyMythUI();
00074 }
00075
00076 class MythUIHelperPrivate
00077 {
00078 public:
00079 MythUIHelperPrivate(MythUIHelper *p);
00080 ~MythUIHelperPrivate();
00081
00082 void Init();
00083
00084 void GetScreenBounds(void);
00085 void StoreGUIsettings(void);
00086
00087 double GetPixelAspectRatio(void);
00088
00089 Settings *m_qtThemeSettings;
00090
00091 bool m_themeloaded;
00092 QString m_menuthemepathname;
00093 QString m_themepathname;
00094 QString m_themename;
00095 QPalette m_palette;
00096
00097 float m_wmult, m_hmult;
00098 float m_pixelAspectRatio;
00099
00100
00101
00102 int m_xbase, m_ybase;
00103 int m_height, m_width;
00104
00105
00106 int m_baseWidth, m_baseHeight;
00107 bool m_isWide;
00108
00109 QMap<QString, MythImage *> imageCache;
00110 QMap<QString, uint> CacheTrack;
00111 QMutex *m_cacheLock;
00112 size_t m_cacheSize;
00113 QMutex *m_cacheSizeLock;
00114
00115 uint maxImageCacheSize;
00116
00117
00118
00119 int m_screenxbase, m_screenybase;
00120
00121
00122
00123 int m_screenwidth, m_screenheight;
00124
00125
00126 static int x_override, y_override, w_override, h_override;
00127
00128 QString themecachedir;
00129 QString m_userThemeDir;
00130
00131 ScreenSaverControl *screensaver;
00132 bool screensaverEnabled;
00133
00134 DisplayRes *display_res;
00135 bool screenSetup;
00136
00137 MThreadPool *m_imageThreadPool;
00138
00139 MythUIMenuCallbacks callbacks;
00140
00141 MythUIHelper *parent;
00142
00143 int m_fontStretch;
00144 };
00145
00146 int MythUIHelperPrivate::x_override = -1;
00147 int MythUIHelperPrivate::y_override = -1;
00148 int MythUIHelperPrivate::w_override = -1;
00149 int MythUIHelperPrivate::h_override = -1;
00150
00151 MythUIHelperPrivate::MythUIHelperPrivate(MythUIHelper *p)
00152 : m_qtThemeSettings(new Settings()),
00153 m_themeloaded(false),
00154 m_wmult(1.0), m_hmult(1.0), m_pixelAspectRatio(-1.0),
00155 m_xbase(0), m_ybase(0), m_height(0), m_width(0),
00156 m_baseWidth(800), m_baseHeight(600), m_isWide(false),
00157 m_cacheLock(new QMutex(QMutex::Recursive)), m_cacheSize(0),
00158 m_cacheSizeLock(new QMutex(QMutex::Recursive)),
00159 m_screenxbase(0), m_screenybase(0), m_screenwidth(0), m_screenheight(0),
00160 screensaver(NULL), screensaverEnabled(false), display_res(NULL),
00161 screenSetup(false), m_imageThreadPool(new MThreadPool("MythUIHelper")),
00162 parent(p), m_fontStretch(100)
00163 {
00164 }
00165
00166 MythUIHelperPrivate::~MythUIHelperPrivate()
00167 {
00168 QMutableMapIterator<QString, MythImage *> i(imageCache);
00169
00170 while (i.hasNext())
00171 {
00172 i.next();
00173 i.value()->SetIsInCache(false);
00174 i.value()->DownRef();
00175 i.remove();
00176 }
00177
00178 CacheTrack.clear();
00179
00180 delete m_cacheLock;
00181 delete m_cacheSizeLock;
00182 delete m_imageThreadPool;
00183 delete m_qtThemeSettings;
00184 delete screensaver;
00185
00186 if (display_res)
00187 DisplayRes::SwitchToDesktop();
00188 }
00189
00190 void MythUIHelperPrivate::Init(void)
00191 {
00192 screensaver = ScreenSaverControl::get();
00193 GetScreenBounds();
00194 StoreGUIsettings();
00195 screenSetup = true;
00196
00197 StorageGroup sgroup("Themes", gCoreContext->GetHostName());
00198 m_userThemeDir = sgroup.GetFirstDir(true);
00199 }
00200
00208 void MythUIHelperPrivate::GetScreenBounds()
00209 {
00210 QDesktopWidget *desktop = QApplication::desktop();
00211 bool hasXinerama = MythDisplay::GetNumberXineramaScreens() > 1;
00212 int numScreens = desktop->numScreens();
00213 int screen;
00214
00215 if (hasXinerama)
00216 {
00217 LOG(VB_GUI, LOG_INFO, LOC +
00218 QString("Total desktop dim: %1x%2, over %3 screen[s].")
00219 .arg(desktop->width()).arg(desktop->height()).arg(numScreens));
00220 }
00221
00222 if (numScreens > 1)
00223 {
00224 for (screen = 0; screen < numScreens; ++screen)
00225 {
00226 QRect dim = desktop->screenGeometry(screen);
00227 LOG(VB_GUI, LOG_INFO, LOC + QString("Screen %1 dim: %2x%3.")
00228 .arg(screen).arg(dim.width()).arg(dim.height()));
00229 }
00230 }
00231
00232 screen = desktop->primaryScreen();
00233 LOG(VB_GUI, LOG_INFO, LOC + QString("Primary screen: %1.").arg(screen));
00234
00235 if (hasXinerama)
00236 screen = GetMythDB()->GetNumSetting("XineramaScreen", screen);
00237
00238 if (screen == -1)
00239 {
00240 m_xbase = 0;
00241 m_ybase = 0;
00242 m_width = desktop->width();
00243 m_height = desktop->height();
00244
00245 LOG(VB_GUI, LOG_INFO, LOC +
00246 QString("Using all %1 screens. ").arg(numScreens) +
00247 QString("Dimensions: %1x%2").arg(m_width).arg(m_height));
00248
00249 return;
00250 }
00251
00252 if (hasXinerama)
00253 {
00254 if (screen < 0 || screen >= numScreens)
00255 {
00256 LOG(VB_GENERAL, LOG_WARNING, LOC +
00257 QString("Xinerama screen %1 was specified,"
00258 " but only %2 available, so using screen 0.")
00259 .arg(screen).arg(numScreens));
00260 screen = 0;
00261 }
00262 }
00263
00264
00265 {
00266 QRect bounds;
00267
00268 bool inWindow = GetMythDB()->GetNumSetting("RunFrontendInWindow", 0);
00269
00270 if (inWindow)
00271 LOG(VB_GUI, LOG_INFO, LOC + "Running in a window");
00272
00273 if (inWindow)
00274
00275
00276 bounds = desktop->availableGeometry(screen);
00277 else
00278 bounds = desktop->screenGeometry(screen);
00279
00280 m_xbase = bounds.x();
00281 m_ybase = bounds.y();
00282 m_width = bounds.width();
00283 m_height = bounds.height();
00284
00285 LOG(VB_GUI, LOG_INFO, LOC + QString("Using screen %1, %2x%3 at %4,%5")
00286 .arg(screen).arg(m_width).arg(m_height)
00287 .arg(m_xbase).arg(m_ybase));
00288 }
00289 }
00290
00294 void MythUIHelperPrivate::StoreGUIsettings()
00295 {
00296 if (x_override >= 0 && y_override >= 0)
00297 {
00298 GetMythDB()->OverrideSettingForSession("GuiOffsetX", QString::number(x_override));
00299 GetMythDB()->OverrideSettingForSession("GuiOffsetY", QString::number(y_override));
00300 }
00301
00302 if (w_override > 0 && h_override > 0)
00303 {
00304 GetMythDB()->OverrideSettingForSession("GuiWidth", QString::number(w_override));
00305 GetMythDB()->OverrideSettingForSession("GuiHeight", QString::number(h_override));
00306 }
00307
00308 m_screenxbase = GetMythDB()->GetNumSetting("GuiOffsetX");
00309 m_screenybase = GetMythDB()->GetNumSetting("GuiOffsetY");
00310
00311 m_screenwidth = m_screenheight = 0;
00312 GetMythDB()->GetResolutionSetting("Gui", m_screenwidth, m_screenheight);
00313
00314
00315
00316
00317 if (!m_screenxbase)
00318 m_screenxbase = m_xbase;
00319
00320 if (!m_screenybase)
00321 m_screenybase = m_ybase;
00322
00323 if (!m_screenwidth)
00324 m_screenwidth = m_width;
00325
00326 if (!m_screenheight)
00327 m_screenheight = m_height;
00328
00329 if (m_screenheight < 160 || m_screenwidth < 160)
00330 {
00331 LOG(VB_GENERAL, LOG_ERR, LOC +
00332 "Somehow, your screen size settings are bad.\n\t\t\t" +
00333 QString("GuiResolution: %1\n\t\t\t")
00334 .arg(GetMythDB()->GetSetting("GuiResolution")) +
00335 QString(" old GuiWidth: %1\n\t\t\t")
00336 .arg(GetMythDB()->GetNumSetting("GuiWidth")) +
00337 QString(" old GuiHeight: %1\n\t\t\t")
00338 .arg(GetMythDB()->GetNumSetting("GuiHeight")) +
00339 QString("m_width: %1").arg(m_width) +
00340 QString("m_height: %1\n\t\t\t").arg(m_height) +
00341 "Falling back to 640x480");
00342
00343 m_screenwidth = 640;
00344 m_screenheight = 480;
00345 }
00346
00347 m_wmult = m_screenwidth / (float)m_baseWidth;
00348 m_hmult = m_screenheight / (float)m_baseHeight;
00349
00350
00351
00352 QFont font = QFont("Arial");
00353
00354 if (!font.exactMatch())
00355 font = QFont();
00356
00357 font.setStyleHint(QFont::SansSerif, QFont::PreferAntialias);
00358 font.setPixelSize((int)((19.0f * m_hmult) + 0.5f));
00359 int stretch = (int)(100 / GetPixelAspectRatio());
00360 font.setStretch(stretch);
00361 m_fontStretch = stretch;
00362
00363 QApplication::setFont(font);
00364 }
00365
00366 double MythUIHelperPrivate::GetPixelAspectRatio(void)
00367 {
00368 if (m_pixelAspectRatio < 0)
00369 {
00370 if (!display_res)
00371 {
00372 DisplayRes *dispRes = DisplayRes::GetDisplayRes();
00373
00374 if (dispRes)
00375 m_pixelAspectRatio = dispRes->GetPixelAspectRatio();
00376 else
00377 m_pixelAspectRatio = 1.0;
00378 }
00379 else
00380 m_pixelAspectRatio = display_res->GetPixelAspectRatio();
00381 }
00382
00383 return m_pixelAspectRatio;
00384 }
00385
00386 MythUIHelper::MythUIHelper()
00387 {
00388 d = new MythUIHelperPrivate(this);
00389 }
00390
00391 MythUIHelper::~MythUIHelper()
00392 {
00393 delete d;
00394 }
00395
00396 void MythUIHelper::Init(MythUIMenuCallbacks &cbs)
00397 {
00398 d->Init();
00399 d->callbacks = cbs;
00400
00401 d->m_cacheSizeLock->lock();
00402 d->maxImageCacheSize = GetMythDB()->GetNumSetting("UIImageCacheSize", 20)
00403 * 1024 * 1024;
00404 d->m_cacheSizeLock->unlock();
00405
00406 LOG(VB_GUI, LOG_INFO, LOC +
00407 QString("MythUI Image Cache size set to %1 bytes")
00408 .arg(d->maxImageCacheSize));
00409 }
00410
00411 MythUIMenuCallbacks *MythUIHelper::GetMenuCBs(void)
00412 {
00413 return &(d->callbacks);
00414 }
00415
00416 bool MythUIHelper::IsScreenSetup(void)
00417 {
00418 return d->screenSetup;
00419 }
00420
00421 bool MythUIHelper::IsTopScreenInitialized(void)
00422 {
00423 return GetMythMainWindow()->GetMainStack()->GetTopScreen()->IsInitialized();
00424 }
00425
00426 void MythUIHelper::LoadQtConfig(void)
00427 {
00428 gCoreContext->ResetLanguage();
00429 d->themecachedir.clear();
00430
00431 if (GetMythDB()->GetNumSetting("UseVideoModes", 0))
00432 {
00433 DisplayRes *dispRes = DisplayRes::GetDisplayRes();
00434
00435 if (dispRes)
00436 {
00437 d->display_res = dispRes;
00438
00439 d->display_res->Initialize();
00440
00441 d->display_res->SwitchToGUI();
00442 }
00443 }
00444
00445
00446 d->GetScreenBounds();
00447
00448 delete d->m_qtThemeSettings;
00449
00450 d->m_qtThemeSettings = new Settings;
00451
00452 qApp->setStyle("Windows");
00453
00454 QString themename = GetMythDB()->GetSetting("Theme", DEFAULT_UI_THEME);
00455 QString themedir = FindThemeDir(themename);
00456
00457 ThemeInfo *themeinfo = new ThemeInfo(themedir);
00458
00459 if (themeinfo)
00460 {
00461 d->m_isWide = themeinfo->IsWide();
00462 d->m_baseWidth = themeinfo->GetBaseRes()->width();
00463 d->m_baseHeight = themeinfo->GetBaseRes()->height();
00464 d->m_themename = themeinfo->GetName();
00465 LOG(VB_GUI, LOG_INFO, LOC +
00466 QString("Using theme base resolution of %1x%2")
00467 .arg(d->m_baseWidth).arg(d->m_baseHeight));
00468 delete themeinfo;
00469 }
00470
00471
00472 d->StoreGUIsettings();
00473
00474 d->m_themepathname = themedir + '/';
00475
00476 themedir += "/qtlook.txt";
00477 d->m_qtThemeSettings->ReadSettings(themedir);
00478 d->m_themeloaded = false;
00479
00480 themename = GetMythDB()->GetSetting("MenuTheme", "defaultmenu");
00481
00482 if (themename == "default")
00483 themename = "defaultmenu";
00484
00485 d->m_menuthemepathname = FindMenuThemeDir(themename) + '/';
00486 }
00487
00488 Settings *MythUIHelper::qtconfig(void)
00489 {
00490 return d->m_qtThemeSettings;
00491 }
00492
00493 void MythUIHelper::UpdateImageCache(void)
00494 {
00495 QMutexLocker locker(d->m_cacheLock);
00496
00497 QMutableMapIterator<QString, MythImage *> i(d->imageCache);
00498
00499 while (i.hasNext())
00500 {
00501 i.next();
00502 i.value()->SetIsInCache(false);
00503 i.value()->DownRef();
00504 i.remove();
00505 }
00506
00507 d->CacheTrack.clear();
00508
00509 d->m_cacheSizeLock->lock();
00510 d->m_cacheSize = 0;
00511 d->m_cacheSizeLock->unlock();
00512
00513 ClearOldImageCache();
00514 }
00515
00516 MythImage *MythUIHelper::GetImageFromCache(const QString &url)
00517 {
00518 QMutexLocker locker(d->m_cacheLock);
00519
00520 if (d->imageCache.contains(url))
00521 {
00522 d->CacheTrack[url] = QDateTime::currentDateTime().toTime_t();
00523 return d->imageCache[url];
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535 return NULL;
00536 }
00537
00538 void MythUIHelper::IncludeInCacheSize(MythImage *im)
00539 {
00540 if (!im)
00541 return;
00542
00543 d->m_cacheSizeLock->lock();
00544 d->m_cacheSize += im->numBytes();
00545 d->m_cacheSizeLock->unlock();
00546 }
00547
00548 void MythUIHelper::ExcludeFromCacheSize(MythImage *im)
00549 {
00550 if (!im)
00551 return;
00552
00553 d->m_cacheSizeLock->lock();
00554 d->m_cacheSize -= im->numBytes();
00555 d->m_cacheSizeLock->unlock();
00556 }
00557
00558 MythImage *MythUIHelper::CacheImage(const QString &url, MythImage *im,
00559 bool nodisk)
00560 {
00561 if (!im)
00562 return NULL;
00563
00564 if (!nodisk)
00565 {
00566 QString dstfile = GetMythUI()->GetThemeCacheDir() + '/' + url;
00567
00568 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
00569 QString("Saved to Cache (%1)").arg(dstfile));
00570
00571
00572
00573 QDir themedir(GetMythUI()->GetThemeCacheDir());
00574
00575 if (!themedir.exists())
00576 themedir.mkdir(GetMythUI()->GetThemeCacheDir());
00577
00578
00579 im->save(dstfile, "PNG");
00580 }
00581
00582
00583 QMutexLocker locker(d->m_cacheLock);
00584 d->m_cacheSizeLock->lock();
00585
00586 while (d->m_cacheSize + im->numBytes() >= d->maxImageCacheSize &&
00587 d->imageCache.size())
00588 {
00589 d->m_cacheSizeLock->unlock();
00590 QMap<QString, MythImage *>::iterator it = d->imageCache.begin();
00591 uint oldestTime = QDateTime::currentDateTime().toTime_t();
00592 QString oldestKey = it.key();
00593
00594 int count = 0;
00595
00596 for (; it != d->imageCache.end(); ++it)
00597 {
00598 if (d->CacheTrack[it.key()] < oldestTime &&
00599 (it.value()->RefCount() == 1))
00600 {
00601 oldestTime = d->CacheTrack[it.key()];
00602 oldestKey = it.key();
00603 count++;
00604 }
00605 }
00606
00607 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
00608 QString("%1 images are eligible for expiry").arg(count));
00609
00610 if (count > 0)
00611 {
00612 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
00613 QString("Cache too big (%1), removing :%2:")
00614 .arg(d->m_cacheSize + im->numBytes()).arg(oldestKey));
00615
00616 d->imageCache[oldestKey]->DownRef();
00617 d->imageCache.remove(oldestKey);
00618 d->CacheTrack.remove(oldestKey);
00619
00620 d->m_cacheSizeLock->lock();
00621 }
00622 else
00623 {
00624 d->m_cacheSizeLock->lock();
00625 break;
00626 }
00627 }
00628
00629 d->m_cacheSizeLock->unlock();
00630
00631 QMap<QString, MythImage *>::iterator it = d->imageCache.find(url);
00632
00633 if (it == d->imageCache.end())
00634 {
00635 im->UpRef();
00636 d->imageCache[url] = im;
00637 d->CacheTrack[url] = QDateTime::currentDateTime().toTime_t();
00638
00639 im->SetIsInCache(true);
00640 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
00641 QString("NOT IN RAM CACHE, Adding, and adding to size :%1: :%2:")
00642 .arg(url).arg(im->numBytes()));
00643 }
00644
00645 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
00646 QString("MythUIHelper::CacheImage : Cache Count = :%1: size :%2:")
00647 .arg(d->imageCache.count()).arg(d->m_cacheSize));
00648
00649 return d->imageCache[url];
00650 }
00651
00652 void MythUIHelper::RemoveFromCacheByURL(const QString &url)
00653 {
00654 QMutexLocker locker(d->m_cacheLock);
00655 QMap<QString, MythImage *>::iterator it = d->imageCache.find(url);
00656
00657 if (it != d->imageCache.end())
00658 {
00659 d->imageCache[url]->SetIsInCache(false);
00660 d->imageCache[url]->DownRef();
00661 d->imageCache.remove(url);
00662 d->CacheTrack.remove(url);
00663 }
00664
00665 QString dstfile;
00666
00667 dstfile = GetThemeCacheDir() + '/' + url;
00668 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
00669 QString("RemoveFromCacheByURL removed :%1: from cache").arg(dstfile));
00670 QFile::remove(dstfile);
00671 }
00672
00673 void MythUIHelper::RemoveFromCacheByFile(const QString &fname)
00674 {
00675 QList<QString>::iterator it;
00676
00677 QString partialKey = fname;
00678 partialKey.replace('/', '-');
00679
00680 d->m_cacheLock->lock();
00681 QList<QString> imageCacheKeys = d->imageCache.keys();
00682 d->m_cacheLock->unlock();
00683
00684 for (it = imageCacheKeys.begin(); it != imageCacheKeys.end(); ++it)
00685 {
00686 if ((*it).contains(partialKey))
00687 RemoveFromCacheByURL(*it);
00688 }
00689
00690
00691
00692 QDir dir(GetThemeCacheDir());
00693 QFileInfoList list = dir.entryInfoList();
00694
00695 for (int i = 0; i < list.size(); ++i)
00696 {
00697 QFileInfo fileInfo = list.at(i);
00698
00699 if (fileInfo.fileName().contains(partialKey))
00700 {
00701 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
00702 QString("RemoveFromCacheByFile removed: %1: from cache")
00703 .arg(fileInfo.fileName()));
00704
00705 if (!dir.remove(fileInfo.fileName()))
00706 LOG(VB_GENERAL, LOG_ERR, LOC +
00707 QString("Failed to delete %1 from the theme cache")
00708 .arg(fileInfo.fileName()));
00709 }
00710 }
00711 }
00712
00713 bool MythUIHelper::IsImageInCache(const QString &url)
00714 {
00715 QMutexLocker locker(d->m_cacheLock);
00716
00717 if (d->imageCache.contains(url))
00718 return true;
00719
00720 if (QFileInfo(url).exists())
00721 return true;
00722
00723 return false;
00724 }
00725
00726 QString MythUIHelper::GetThemeCacheDir(void)
00727 {
00728 QString cachedirname = GetConfDir() + "/themecache/";
00729
00730 QString tmpcachedir = cachedirname +
00731 GetMythDB()->GetSetting("Theme", DEFAULT_UI_THEME) +
00732 "." + QString::number(d->m_screenwidth) +
00733 "." + QString::number(d->m_screenheight);
00734
00735 return tmpcachedir;
00736 }
00737
00738 void MythUIHelper::ClearOldImageCache(void)
00739 {
00740 QString cachedirname = GetConfDir() + "/themecache/";
00741
00742 d->themecachedir = GetThemeCacheDir();
00743
00744 QDir dir(cachedirname);
00745
00746 if (!dir.exists())
00747 dir.mkdir(cachedirname);
00748
00749 QString themecachedir = d->themecachedir;
00750
00751 d->themecachedir += '/';
00752
00753 dir.setPath(themecachedir);
00754
00755 if (!dir.exists())
00756 dir.mkdir(themecachedir);
00757
00758 dir.setPath(cachedirname);
00759
00760 QFileInfoList list = dir.entryInfoList();
00761
00762 QFileInfoList::const_iterator it = list.begin();
00763 QMap<QDateTime, QString> dirtimes;
00764 const QFileInfo *fi;
00765
00766 while (it != list.end())
00767 {
00768 fi = &(*it++);
00769
00770 if (fi->fileName() == "." || fi->fileName() == "..")
00771 continue;
00772
00773 if (fi->isDir() && !fi->isSymLink())
00774 {
00775 if (fi->absoluteFilePath() == themecachedir)
00776 continue;
00777
00778 dirtimes[fi->lastModified()] = fi->absoluteFilePath();
00779 }
00780 }
00781
00782
00783
00784
00785
00786 while ((size_t)dirtimes.size() >= 2)
00787 {
00788 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("Removing cache dir: %1")
00789 .arg(dirtimes.begin().value()));
00790
00791 RemoveCacheDir(dirtimes.begin().value());
00792 dirtimes.erase(dirtimes.begin());
00793 }
00794
00795 QMap<QDateTime, QString>::const_iterator dit = dirtimes.begin();
00796
00797 for (; dit != dirtimes.end(); ++dit)
00798 {
00799 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
00800 QString("Keeping cache dir: %1").arg(*dit));
00801 }
00802 }
00803
00804 void MythUIHelper::RemoveCacheDir(const QString &dirname)
00805 {
00806 QString cachedirname = GetConfDir() + "/themecache/";
00807
00808 if (!dirname.startsWith(cachedirname))
00809 return;
00810
00811 LOG(VB_GENERAL, LOG_ERR, LOC +
00812 QString("Removing stale cache dir: %1").arg(dirname));
00813
00814 QDir dir(dirname);
00815
00816 if (!dir.exists())
00817 return;
00818
00819 QFileInfoList list = dir.entryInfoList();
00820 QFileInfoList::const_iterator it = list.begin();
00821 const QFileInfo *fi;
00822
00823 while (it != list.end())
00824 {
00825 fi = &(*it++);
00826
00827 if (fi->fileName() == "." || fi->fileName() == "..")
00828 continue;
00829
00830 if (fi->isFile() && !fi->isSymLink())
00831 {
00832 QFile file(fi->absoluteFilePath());
00833 file.remove();
00834 }
00835 else if (fi->isDir() && !fi->isSymLink())
00836 {
00837 RemoveCacheDir(fi->absoluteFilePath());
00838 }
00839 }
00840
00841 dir.rmdir(dirname);
00842 }
00843
00844 void MythUIHelper::GetScreenBounds(int &xbase, int &ybase,
00845 int &width, int &height)
00846 {
00847 xbase = d->m_xbase;
00848 ybase = d->m_ybase;
00849
00850 width = d->m_width;
00851 height = d->m_height;
00852 }
00853
00854 void MythUIHelper::GetScreenSettings(float &wmult, float &hmult)
00855 {
00856 wmult = d->m_wmult;
00857 hmult = d->m_hmult;
00858 }
00859
00860 void MythUIHelper::GetScreenSettings(int &width, float &wmult,
00861 int &height, float &hmult)
00862 {
00863 height = d->m_screenheight;
00864 width = d->m_screenwidth;
00865
00866 wmult = d->m_wmult;
00867 hmult = d->m_hmult;
00868 }
00869
00870 void MythUIHelper::GetScreenSettings(int &xbase, int &width, float &wmult,
00871 int &ybase, int &height, float &hmult)
00872 {
00873 xbase = d->m_screenxbase;
00874 ybase = d->m_screenybase;
00875
00876 height = d->m_screenheight;
00877 width = d->m_screenwidth;
00878
00879 wmult = d->m_wmult;
00880 hmult = d->m_hmult;
00881 }
00882
00892 void MythUIHelper::ParseGeometryOverride(const QString &geometry)
00893 {
00894 QRegExp sre("^(\\d+)x(\\d+)$");
00895 QRegExp lre("^(\\d+)x(\\d+)([+-]\\d+)([+-]\\d+)$");
00896 QStringList geo;
00897 bool longForm = false;
00898
00899 if (sre.exactMatch(geometry))
00900 {
00901 sre.indexIn(geometry);
00902 geo = sre.capturedTexts();
00903 }
00904 else if (lre.exactMatch(geometry))
00905 {
00906 lre.indexIn(geometry);
00907 geo = lre.capturedTexts();
00908 longForm = true;
00909 }
00910 else
00911 {
00912 LOG(VB_GENERAL, LOG_ERR, LOC +
00913 "Geometry does not match either form -\n\t\t\t"
00914 "WIDTHxHEIGHT or WIDTHxHEIGHT+XOFF+YOFF");
00915 return;
00916 }
00917
00918 bool parsed;
00919 int tmp_w, tmp_h;
00920
00921 tmp_w = geo[1].toInt(&parsed);
00922
00923 if (!parsed)
00924 {
00925 LOG(VB_GENERAL, LOG_ERR, LOC +
00926 "Could not parse width of geometry override");
00927 }
00928
00929 if (parsed)
00930 {
00931 tmp_h = geo[2].toInt(&parsed);
00932
00933 if (!parsed)
00934 {
00935 LOG(VB_GENERAL, LOG_ERR, LOC +
00936 "Could not parse height of geometry override");
00937 }
00938 }
00939
00940 if (parsed)
00941 {
00942 MythUIHelperPrivate::w_override = tmp_w;
00943 MythUIHelperPrivate::h_override = tmp_h;
00944 LOG(VB_GENERAL, LOG_INFO, LOC +
00945 QString("Overriding GUI size: width=%1 height=%2")
00946 .arg(tmp_w).arg(tmp_h));
00947 }
00948 else
00949 {
00950 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to override GUI size.");
00951 }
00952
00953 if (longForm)
00954 {
00955 int tmp_x, tmp_y;
00956 tmp_x = geo[3].toInt(&parsed);
00957
00958 if (!parsed)
00959 {
00960 LOG(VB_GENERAL, LOG_ERR, LOC +
00961 "Could not parse horizontal offset of geometry override");
00962 }
00963
00964 if (parsed)
00965 {
00966 tmp_y = geo[4].toInt(&parsed);
00967
00968 if (!parsed)
00969 {
00970 LOG(VB_GENERAL, LOG_ERR, LOC +
00971 "Could not parse vertical offset of geometry override");
00972 }
00973 }
00974
00975 if (parsed)
00976 {
00977 MythUIHelperPrivate::x_override = tmp_x;
00978 MythUIHelperPrivate::y_override = tmp_y;
00979 LOG(VB_GENERAL, LOG_INFO, LOC +
00980 QString("Overriding GUI offset: x=%1 y=%2")
00981 .arg(tmp_x).arg(tmp_y));
00982 }
00983 else
00984 {
00985 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to override GUI offset.");
00986 }
00987 }
00988 }
00989
00990 bool MythUIHelper::IsGeometryOverridden(void)
00991 {
00992 return (MythUIHelperPrivate::x_override >= 0 ||
00993 MythUIHelperPrivate::y_override >= 0 ||
00994 MythUIHelperPrivate::w_override >= 0 ||
00995 MythUIHelperPrivate::h_override >= 0);
00996 }
00997
01006 QString MythUIHelper::FindThemeDir(const QString &themename)
01007 {
01008 QString testdir;
01009 QDir dir;
01010
01011 if (!themename.isEmpty())
01012 {
01013 testdir = d->m_userThemeDir + themename;
01014
01015 dir.setPath(testdir);
01016
01017 if (dir.exists())
01018 return testdir;
01019
01020 testdir = GetThemesParentDir() + themename;
01021 dir.setPath(testdir);
01022
01023 if (dir.exists())
01024 return testdir;
01025
01026 LOG(VB_GENERAL, LOG_WARNING, LOC + QString("No theme dir: '%1'")
01027 .arg(dir.absolutePath()));
01028 }
01029
01030 testdir = GetThemesParentDir() + DEFAULT_UI_THEME;
01031 dir.setPath(testdir);
01032
01033 if (dir.exists())
01034 {
01035 LOG(VB_GENERAL, LOG_ERR, LOC +
01036 QString("Could not find theme: %1 - Switching to %2")
01037 .arg(themename).arg(DEFAULT_UI_THEME));
01038 GetMythDB()->OverrideSettingForSession("Theme", DEFAULT_UI_THEME);
01039 return testdir;
01040 }
01041
01042 LOG(VB_GENERAL, LOG_WARNING, LOC + QString("No default theme dir: '%1'")
01043 .arg(dir.absolutePath()));
01044
01045 testdir = GetThemesParentDir() + FALLBACK_UI_THEME;
01046 dir.setPath(testdir);
01047
01048 if (dir.exists())
01049 {
01050 LOG(VB_GENERAL, LOG_ERR, LOC +
01051 QString("Could not find theme: %1 - Switching to %2")
01052 .arg(themename).arg(FALLBACK_UI_THEME));
01053 GetMythDB()->OverrideSettingForSession("Theme", FALLBACK_UI_THEME);
01054 return testdir;
01055 }
01056
01057 LOG(VB_GENERAL, LOG_ERR, LOC + QString("No fallback GUI theme dir: '%1'")
01058 .arg(dir.absolutePath()));
01059
01060 return QString();
01061 }
01062
01071 QString MythUIHelper::FindMenuThemeDir(const QString &menuname)
01072 {
01073 QString testdir;
01074 QDir dir;
01075
01076 testdir = d->m_userThemeDir + menuname;
01077
01078 dir.setPath(testdir);
01079
01080 if (dir.exists())
01081 return testdir;
01082
01083 testdir = GetThemesParentDir() + menuname;
01084 dir.setPath(testdir);
01085
01086 if (dir.exists())
01087 return testdir;
01088
01089 testdir = GetShareDir();
01090 dir.setPath(testdir);
01091
01092 if (dir.exists())
01093 {
01094 LOG(VB_GENERAL, LOG_ERR, LOC +
01095 QString("Could not find menu theme: %1 - Switching to default")
01096 .arg(menuname));
01097
01098 GetMythDB()->SaveSetting("MenuTheme", "default");
01099 return testdir;
01100 }
01101
01102 LOG(VB_GENERAL, LOG_ERR, LOC +
01103 QString("Could not find menu theme: %1 - Fallback to default failed.")
01104 .arg(menuname));
01105
01106 return QString();
01107 }
01108
01109 QString MythUIHelper::GetMenuThemeDir(void)
01110 {
01111 return d->m_menuthemepathname;
01112 }
01113
01114 QString MythUIHelper::GetThemeDir(void)
01115 {
01116 return d->m_themepathname;
01117 }
01118
01119 QString MythUIHelper::GetThemeName(void)
01120 {
01121 return d->m_themename;
01122 }
01123
01124 QStringList MythUIHelper::GetThemeSearchPath(void)
01125 {
01126 QStringList searchpath;
01127
01128 searchpath.append(GetThemeDir());
01129
01130 if (d->m_isWide)
01131 searchpath.append(GetThemesParentDir() + "default-wide/");
01132
01133 searchpath.append(GetThemesParentDir() + "default/");
01134 searchpath.append("/tmp/");
01135 return searchpath;
01136 }
01137
01138 QList<ThemeInfo> MythUIHelper::GetThemes(ThemeType type)
01139 {
01140 QFileInfoList fileList;
01141 QList<ThemeInfo> themeList;
01142 QDir themeDirs(GetThemesParentDir());
01143 themeDirs.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
01144 themeDirs.setSorting(QDir::Name | QDir::IgnoreCase);
01145
01146 fileList.append(themeDirs.entryInfoList());
01147
01148 themeDirs.setPath(d->m_userThemeDir);
01149
01150 fileList.append(themeDirs.entryInfoList());
01151
01152 for (QFileInfoList::iterator it = fileList.begin();
01153 it != fileList.end(); ++it)
01154 {
01155 QFileInfo &theme = *it;
01156
01157 if (theme.baseName() == "default" ||
01158 theme.baseName() == "default-wide" ||
01159 theme.baseName() == "Slave")
01160 continue;
01161
01162 ThemeInfo themeInfo(theme.absoluteFilePath());
01163
01164 if (themeInfo.GetType() & type)
01165 themeList.append(themeInfo);
01166 }
01167
01168 return themeList;
01169 }
01170
01171 void MythUIHelper::SetPalette(QWidget *widget)
01172 {
01173 QPalette pal = widget->palette();
01174
01175 const QString names[] = { "Foreground", "Button", "Light", "Midlight",
01176 "Dark", "Mid", "Text", "BrightText", "ButtonText",
01177 "Base", "Background", "Shadow", "Highlight",
01178 "HighlightedText"
01179 };
01180
01181 QString type = "Active";
01182
01183 for (int i = 0; i < 13; i++)
01184 {
01185 QString color = d->m_qtThemeSettings->GetSetting(type + names[i]);
01186
01187 if (!color.isEmpty())
01188 pal.setColor(QPalette::Active, (QPalette::ColorRole) i,
01189 createColor(color));
01190 }
01191
01192 type = "Disabled";
01193
01194 for (int i = 0; i < 13; i++)
01195 {
01196 QString color = d->m_qtThemeSettings->GetSetting(type + names[i]);
01197
01198 if (!color.isEmpty())
01199 pal.setColor(QPalette::Disabled, (QPalette::ColorRole) i,
01200 createColor(color));
01201 }
01202
01203 type = "Inactive";
01204
01205 for (int i = 0; i < 13; i++)
01206 {
01207 QString color = d->m_qtThemeSettings->GetSetting(type + names[i]);
01208
01209 if (!color.isEmpty())
01210 pal.setColor(QPalette::Inactive, (QPalette::ColorRole) i,
01211 createColor(color));
01212 }
01213
01214 widget->setPalette(pal);
01215 }
01216
01217 void MythUIHelper::ThemeWidget(QWidget *widget)
01218 {
01219 if (d->m_themeloaded)
01220 {
01221 widget->setPalette(d->m_palette);
01222 return;
01223 }
01224
01225 SetPalette(widget);
01226 d->m_palette = widget->palette();
01227
01228 QPixmap *bgpixmap = NULL;
01229
01230 if (!d->m_qtThemeSettings->GetSetting("BackgroundPixmap").isEmpty())
01231 {
01232 QString pmapname = d->m_themepathname +
01233 d->m_qtThemeSettings->GetSetting("BackgroundPixmap");
01234
01235 bgpixmap = LoadScalePixmap(pmapname);
01236
01237 if (bgpixmap)
01238 {
01239 d->m_palette.setBrush(widget->backgroundRole(), QBrush(*bgpixmap));
01240 widget->setPalette(d->m_palette);
01241 }
01242 }
01243 else if (!d->m_qtThemeSettings
01244 ->GetSetting("TiledBackgroundPixmap").isEmpty())
01245 {
01246 QString pmapname = d->m_themepathname +
01247 d->m_qtThemeSettings->GetSetting("TiledBackgroundPixmap");
01248
01249 int width, height;
01250 float wmult, hmult;
01251
01252 GetScreenSettings(width, wmult, height, hmult);
01253
01254 bgpixmap = LoadScalePixmap(pmapname);
01255
01256 if (bgpixmap)
01257 {
01258 QPixmap background(width, height);
01259 QPainter tmp(&background);
01260
01261 tmp.drawTiledPixmap(0, 0, width, height, *bgpixmap);
01262 tmp.end();
01263
01264 d->m_palette.setBrush(widget->backgroundRole(), QBrush(background));
01265 widget->setPalette(d->m_palette);
01266 }
01267 }
01268
01269 d->m_themeloaded = true;
01270
01271 delete bgpixmap;
01272 }
01273
01274 bool MythUIHelper::FindThemeFile(QString &path)
01275 {
01276 QFileInfo fi(path);
01277
01278 if (fi.isAbsolute() && fi.exists())
01279 return true;
01280
01281 QString file;
01282 bool foundit = false;
01283 const QStringList searchpath = GetThemeSearchPath();
01284
01285 for (QStringList::const_iterator ii = searchpath.begin();
01286 ii != searchpath.end(); ++ii)
01287 {
01288 if (fi.isRelative())
01289 {
01290 file = *ii + fi.filePath();
01291 }
01292 else if (fi.isAbsolute() && !fi.isRoot())
01293 {
01294 file = *ii + fi.fileName();
01295 }
01296
01297 if (QFile::exists(file))
01298 {
01299 path = file;
01300 foundit = true;
01301 break;
01302 }
01303 }
01304
01305 return foundit;
01306 }
01307
01308 QImage *MythUIHelper::LoadScaleImage(QString filename, bool fromcache)
01309 {
01310 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
01311 QString("LoadScaleImage(%1)").arg(filename));
01312
01313 if (filename.isEmpty() || filename == "none")
01314 return NULL;
01315
01316 if ((!FindThemeFile(filename)) &&
01317 (!filename.startsWith("http://")) &&
01318 (!filename.startsWith("https://")) &&
01319 (!filename.startsWith("ftp://")) &&
01320 (!filename.startsWith("myth://")))
01321 {
01322 LOG(VB_GENERAL, LOG_ERR, LOC + QString("LoadScaleImage(%1)")
01323 .arg(filename) + "Unable to find image file");
01324
01325 return NULL;
01326 }
01327
01328 QImage *ret = NULL;
01329 QImage tmpimage;
01330 int width, height;
01331 float wmult, hmult;
01332
01333 GetScreenSettings(width, wmult, height, hmult);
01334
01335 if (filename.startsWith("myth://"))
01336 {
01337 RemoteFile *rf = new RemoteFile(filename, false, false, 0);
01338
01339 QByteArray data;
01340 bool loaded = rf->SaveAs(data);
01341 delete rf;
01342
01343 if (loaded)
01344 tmpimage.loadFromData(data);
01345 else
01346 {
01347 LOG(VB_GENERAL, LOG_ERR, LOC +
01348 QString("LoadScaleImage(%1) failed to load remote image")
01349 .arg(filename));
01350 }
01351 }
01352 else if ((filename.startsWith("http://")) ||
01353 (filename.startsWith("https://")) ||
01354 (filename.startsWith("ftp://")))
01355 {
01356 QByteArray data;
01357
01358 if (GetMythDownloadManager()->download(filename, &data))
01359 tmpimage.loadFromData(data);
01360 else
01361 {
01362 LOG(VB_GENERAL, LOG_ERR, LOC +
01363 QString("LoadScaleImage(%1) failed to load remote image")
01364 .arg(filename));
01365 }
01366 }
01367 else
01368 {
01369 tmpimage.load(filename);
01370 }
01371
01372 if (width != d->m_baseWidth || height != d->m_baseHeight)
01373 {
01374 if (tmpimage.isNull())
01375 {
01376 LOG(VB_GENERAL, LOG_ERR, LOC +
01377 QString("LoadScaleImage(%1) failed to load image")
01378 .arg(filename));
01379
01380 return NULL;
01381 }
01382
01383 QImage tmp2 = tmpimage.scaled(
01384 (int)(tmpimage.width() * wmult),
01385 (int)(tmpimage.height() * hmult),
01386 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
01387
01388 ret = new QImage(tmp2);
01389 }
01390 else
01391 {
01392 ret = new QImage(tmpimage);
01393
01394 if (!ret->width() || !ret->height())
01395 {
01396 LOG(VB_GENERAL, LOG_ERR, LOC +
01397 QString("LoadScaleImage(%1) invalid image dimensions")
01398 .arg(filename));
01399
01400 delete ret;
01401 return NULL;
01402 }
01403 }
01404
01405 return ret;
01406 }
01407
01408 QPixmap *MythUIHelper::LoadScalePixmap(QString filename, bool fromcache)
01409 {
01410 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
01411 QString("LoadScalePixmap(%1)").arg(filename));
01412
01413 if (filename.isEmpty() || filename == "none")
01414 return NULL;
01415
01416 if (!FindThemeFile(filename) && (!filename.startsWith("myth:")))
01417 {
01418 LOG(VB_GENERAL, LOG_ERR, LOC + QString("LoadScalePixmap(%1)")
01419 .arg(filename) + "Unable to find image file");
01420
01421 return NULL;
01422 }
01423
01424 QPixmap *ret = NULL;
01425 QImage tmpimage;
01426 int width, height;
01427 float wmult, hmult;
01428
01429 GetScreenSettings(width, wmult, height, hmult);
01430
01431 if (filename.startsWith("myth://"))
01432 {
01433 RemoteFile *rf = new RemoteFile(filename, false, false, 0);
01434
01435 QByteArray data;
01436 bool loaded = rf->SaveAs(data);
01437 delete rf;
01438
01439 if (loaded)
01440 {
01441 tmpimage.loadFromData(data);
01442 }
01443 else
01444 {
01445 LOG(VB_GENERAL, LOG_ERR, LOC +
01446 QString("LoadScalePixmap(%1): failed to load remote image")
01447 .arg(filename));
01448 }
01449 }
01450 else
01451 {
01452 tmpimage.load(filename);
01453 }
01454
01455 if (width != d->m_baseWidth || height != d->m_baseHeight)
01456 {
01457 if (tmpimage.isNull())
01458 {
01459 LOG(VB_GENERAL, LOG_ERR, LOC +
01460 QString("LoadScalePixmap(%1) failed to load image")
01461 .arg(filename));
01462
01463 return NULL;
01464 }
01465
01466 QImage tmp2 = tmpimage.scaled((int)(tmpimage.width() * wmult),
01467 (int)(tmpimage.height() * hmult),
01468 Qt::IgnoreAspectRatio,
01469 Qt::SmoothTransformation);
01470 ret = new QPixmap(QPixmap::fromImage(tmp2));
01471 }
01472 else
01473 {
01474 ret = new QPixmap(QPixmap::fromImage(tmpimage));
01475
01476 if (!ret->width() || !ret->height())
01477 {
01478 LOG(VB_GENERAL, LOG_ERR, LOC +
01479 QString("LoadScalePixmap(%1) invalid image dimensions")
01480 .arg(filename));
01481
01482 delete ret;
01483 return NULL;
01484 }
01485 }
01486
01487 return ret;
01488 }
01489
01490 MythImage *MythUIHelper::LoadCacheImage(QString srcfile, QString label,
01491 MythPainter *painter,
01492 ImageCacheMode cacheMode)
01493 {
01494 LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
01495 QString("LoadCacheImage(%1,%2)").arg(srcfile).arg(label));
01496
01497 if (srcfile.isEmpty() || label.isEmpty())
01498 return NULL;
01499
01500 if (!(kCacheForceStat & cacheMode))
01501 {
01502
01503
01504
01505
01506
01507
01508 const uint kImageCacheTimeout = 5;
01509 uint now = QDateTime::currentDateTime().toTime_t();
01510
01511 QMutexLocker locker(d->m_cacheLock);
01512
01513 if (d->imageCache.contains(label) &&
01514 d->CacheTrack[label] + kImageCacheTimeout > now)
01515 {
01516 return d->imageCache[label];
01517 }
01518 }
01519
01520 QString cachefilepath = GetThemeCacheDir() + '/' + label;
01521 QFileInfo fi(cachefilepath);
01522
01523 MythImage *ret = NULL;
01524
01525 if (!!(cacheMode & kCacheIgnoreDisk) || fi.exists())
01526 {
01527
01528 if (!(cacheMode & kCacheIgnoreDisk))
01529 FindThemeFile(srcfile);
01530
01531 QDateTime srcLastModified;
01532 QFileInfo original(srcfile);
01533
01534 if ((srcfile.startsWith("http://")) ||
01535 (srcfile.startsWith("https://")) ||
01536 (srcfile.startsWith("ftp://")))
01537 {
01538 srcLastModified =
01539 GetMythDownloadManager()->GetLastModified(srcfile);
01540 }
01541 else if (srcfile.startsWith("myth://"))
01542 srcLastModified = RemoteFile::LastModified(srcfile);
01543 else if (original.exists())
01544 srcLastModified = original.lastModified();
01545
01546 if (!!(cacheMode & kCacheIgnoreDisk) ||
01547 (fi.lastModified() > srcLastModified))
01548 {
01549
01550 ret = GetImageFromCache(label);
01551
01552 if (!ret && (cacheMode == kCacheNormal) && painter)
01553 {
01554
01555 ret = painter->GetFormatImage();
01556
01557 if (!ret->Load(cachefilepath, false))
01558 {
01559 LOG(VB_GUI | VB_FILE, LOG_WARNING, LOC +
01560 QString("LoadCacheImage: Could not load :%1")
01561 .arg(cachefilepath));
01562
01563 ret->DownRef();
01564 ret = NULL;
01565 }
01566 else
01567 {
01568
01569
01570 CacheImage(label, ret, true);
01571 }
01572 }
01573 }
01574 else
01575 {
01576
01577
01578 RemoveFromCacheByURL(label);
01579 }
01580 }
01581
01582 return ret;
01583 }
01584
01585 QFont MythUIHelper::GetBigFont(void)
01586 {
01587 QFont font = QApplication::font();
01588 font.setPointSize(GetMythMainWindow()->NormalizeFontSize(25));
01589 font.setWeight(QFont::Bold);
01590
01591 return font;
01592 }
01593
01594 QFont MythUIHelper::GetMediumFont(void)
01595 {
01596 QFont font = QApplication::font();
01597 font.setPointSize(GetMythMainWindow()->NormalizeFontSize(16));
01598 font.setWeight(QFont::Bold);
01599
01600 return font;
01601 }
01602
01603 QFont MythUIHelper::GetSmallFont(void)
01604 {
01605 QFont font = QApplication::font();
01606 font.setPointSize(GetMythMainWindow()->NormalizeFontSize(12));
01607 font.setWeight(QFont::Bold);
01608
01609 return font;
01610 }
01611
01612 void MythUIHelper::DisableScreensaver(void)
01613 {
01614 if (QApplication::type() == QApplication::GuiClient)
01615 {
01616 QCoreApplication::postEvent(
01617 GetMythMainWindow(),
01618 new ScreenSaverEvent(ScreenSaverEvent::ssetDisable));
01619 }
01620 }
01621
01622 void MythUIHelper::RestoreScreensaver(void)
01623 {
01624 if (QApplication::type() == QApplication::GuiClient)
01625 {
01626 QCoreApplication::postEvent(
01627 GetMythMainWindow(),
01628 new ScreenSaverEvent(ScreenSaverEvent::ssetRestore));
01629 }
01630 }
01631
01632 void MythUIHelper::ResetScreensaver(void)
01633 {
01634 if (QApplication::type() == QApplication::GuiClient)
01635 {
01636 QCoreApplication::postEvent(
01637 GetMythMainWindow(),
01638 new ScreenSaverEvent(ScreenSaverEvent::ssetReset));
01639 }
01640 }
01641
01642 void MythUIHelper::DoDisableScreensaver(void)
01643 {
01644 if (d->screensaver)
01645 {
01646 d->screensaver->Disable();
01647 d->screensaverEnabled = false;
01648 }
01649 }
01650
01651 void MythUIHelper::DoRestoreScreensaver(void)
01652 {
01653 if (d->screensaver)
01654 {
01655 d->screensaver->Restore();
01656 d->screensaverEnabled = true;
01657 }
01658 }
01659
01660 void MythUIHelper::DoResetScreensaver(void)
01661 {
01662 if (d->screensaver)
01663 {
01664 d->screensaver->Reset();
01665 d->screensaverEnabled = false;
01666 }
01667 }
01668
01669 bool MythUIHelper::GetScreensaverEnabled(void)
01670 {
01671 return d->screensaverEnabled;
01672 }
01673
01674 bool MythUIHelper::GetScreenIsAsleep(void)
01675 {
01676 if (!d->screensaver)
01677 return false;
01678
01679 return d->screensaver->Asleep();
01680 }
01681
01684 void MythUIHelper::SetX11Display(const QString &display)
01685 {
01686 x11_display = display;
01687 x11_display.detach();
01688 }
01689
01690 QString MythUIHelper::GetX11Display(void)
01691 {
01692 QString ret = x11_display;
01693 ret.detach();
01694 return ret;
01695 }
01696
01697 void MythUIHelper::AddCurrentLocation(QString location)
01698 {
01699 QMutexLocker locker(&m_locationLock);
01700
01701 if (m_currentLocation.isEmpty() || m_currentLocation.last() != location)
01702 m_currentLocation.push_back(location);
01703 }
01704
01705 QString MythUIHelper::RemoveCurrentLocation(void)
01706 {
01707 QMutexLocker locker(&m_locationLock);
01708
01709 if (m_currentLocation.isEmpty())
01710 return QString("UNKNOWN");
01711
01712 return m_currentLocation.takeLast();
01713 }
01714
01715 QString MythUIHelper::GetCurrentLocation(bool fullPath, bool mainStackOnly)
01716 {
01717 QString result;
01718 QMutexLocker locker(&m_locationLock);
01719
01720 if (fullPath)
01721 {
01722
01723 MythScreenStack *stack = GetMythMainWindow()->GetMainStack();
01724 result = stack->GetLocation(true);
01725
01726 if (!mainStackOnly)
01727 {
01728
01729 stack = GetMythMainWindow()->GetStack("popup stack");
01730
01731 if (!stack->GetLocation(true).isEmpty())
01732 result += '/' + stack->GetLocation(false);
01733 }
01734
01735
01736 if (!m_currentLocation.isEmpty())
01737 {
01738 for (int x = 0; x < m_currentLocation.count(); x++)
01739 result += '/' + m_currentLocation[x];
01740 }
01741 }
01742 else
01743 {
01744
01745 MythScreenStack *stack = GetMythMainWindow()->GetMainStack();
01746 result = stack->GetLocation(false);
01747
01748 if (!mainStackOnly)
01749 {
01750
01751 stack = GetMythMainWindow()->GetStack("popup stack");
01752
01753 if (!stack->GetLocation(false).isEmpty())
01754 result = stack->GetLocation(false);
01755 }
01756
01757
01758 if (!m_currentLocation.isEmpty())
01759 result = m_currentLocation.last();
01760 }
01761
01762 if (result.isEmpty())
01763 result = "UNKNOWN";
01764
01765 return result;
01766 }
01767
01768 MThreadPool *MythUIHelper::GetImageThreadPool(void)
01769 {
01770 return d->m_imageThreadPool;
01771 }
01772
01773 double MythUIHelper::GetPixelAspectRatio(void) const
01774 {
01775 return d->GetPixelAspectRatio();
01776 }
01777
01778 QSize MythUIHelper::GetBaseSize(void) const
01779 {
01780 return QSize(d->m_baseWidth, d->m_baseHeight);
01781 }
01782
01783 void MythUIHelper::SetFontStretch(int stretch)
01784 {
01785 d->m_fontStretch = stretch;
01786 }
01787
01788 int MythUIHelper::GetFontStretch(void) const
01789 {
01790 return d->m_fontStretch;
01791 }