rendered paste bodyIndex: mythtv/libs/libmythui/mythuiimage.cpp===================================================================--- mythtv/libs/libmythui/mythuiimage.cpp (revision 21272)+++ mythtv/libs/libmythui/mythuiimage.cpp (working copy)@@ -1,18 +1,78 @@ #include <cstdlib> +// Mythui+#include "mythuiimage.h"+#include "mythpainter.h"+#include "mythmainwindow.h"+#include "mythuihelper.h"+#include "mythscreentype.h"++// QT #include <QFile> #include <QDir> #include <QDomDocument> #include <QImageReader>+#include <QThread>+#include <QEvent>+#include <QCoreApplication> +// Libmythdb #include "mythverbose.h" -#include "mythuiimage.h"-#include "mythpainter.h"-#include "mythmainwindow.h"-#include "mythuihelper.h"-#include "mythscreentype.h"+class ImageLoadThread; +const int kImageLoadEventType = 35112;++/*!+* \class ImageLoadThread+*/+class ImageLoadEvent : public QEvent+{+ public:+ ImageLoadEvent(ImageLoadThread *thread, MythImage *image,+ const QString &filename, int number)+ : QEvent((QEvent::Type)kImageLoadEventType),+ m_thread(thread), m_image(image), m_filename(filename),+ m_number(number) { }+ + ImageLoadThread *GetThread() const { return m_thread; }+ MythImage *GetImage() const { return m_image; }+ const QString GetFilename() const { return m_filename; }+ const int GetNumber() const { return m_number; }+ + private:+ ImageLoadThread *m_thread;+ MythImage *m_image;+ QString m_filename;+ int m_number;+};++/*!+* \class ImageLoadThread+*/+class ImageLoadThread : public QThread+{+ public:+ ImageLoadThread(MythUIImage *parent, const QString &filename,+ int number)+ : m_parent(parent), m_filename(filename), m_number(number) { };++ void run()+ {+ MythImage *image = m_parent->LoadImage(m_filename, m_number);+ ImageLoadEvent *le = new ImageLoadEvent(this, image, m_filename,+ m_number);+ QCoreApplication::sendEvent(m_parent, le);+ }++ private:+ MythUIImage *m_parent;+ QString m_filename;+ int m_number;+};++/////////////////////////////////////////////////////////////////+ MythUIImage::MythUIImage(const QString &filepattern, int low, int high, int delayms, MythUIType *parent, const QString &name)@@ -317,7 +377,7 @@ * \brief Generates a unique identifying string for this image which is used * as a key in the image cache. */-QString MythUIImage::GenImageLabel(const QString &filename, int w, int h)+QString MythUIImage::GenImageLabel(const QString &filename, int w, int h) const { QString imagelabel; QString s_Attrib;@@ -345,7 +405,7 @@ * \brief Generates a unique identifying string for this image which is used * as a key in the image cache. */-QString MythUIImage::GenImageLabel(int w, int h)+QString MythUIImage::GenImageLabel(int w, int h) const { return GenImageLabel(m_Filename, w, h); }@@ -356,154 +416,156 @@ bool MythUIImage::Load(void) { Clear();-+ SetRedraw();--// if (!IsVisible(true))-// return false;-+ if (m_Filename.isEmpty() && (!m_gradient)) return false; - QSize newSize;+ // if (!IsVisible(true))+ // return false; - VERBOSE(VB_FILE, QString("MythUIImage::Load (%1) Object %2").arg(m_Filename).arg(objectName()));- for (int i = m_LowNum; i <= m_HighNum; i++) {- MythImage *image = NULL;- bool bNeedLoad = false;+ ImageLoadThread *thread = new ImageLoadThread(this, m_Filename, i);+ thread->run();+ } - if (m_gradient)- {- QSize gradsize;- if (!m_Area.isEmpty())- gradsize = m_Area.size();- else- gradsize = QSize(10, 10);+ return true;+} - image = MythImage::Gradient(gradsize, m_gradientStart,- m_gradientEnd, m_gradientAlpha,- m_gradientDirection);- image->UpRef();- }+/**+* \brief Load the images in a another thread, do not call directly+*/+MythImage *MythUIImage::LoadImage(const QString &imFile, int imageNumber) const+{+ QString filename = imFile;+ + VERBOSE(VB_FILE, QString("MythUIImage::Load (%1) Object %2").arg(filename)+ .arg(objectName()));++ MythImage *image = NULL;+ bool bNeedLoad = false;++ if (m_gradient)+ {+ QSize gradsize;+ if (!m_Area.isEmpty())+ gradsize = m_Area.size(); else- bNeedLoad = true;+ gradsize = QSize(10, 10); - int w = -1;- int h = -1;+ image = MythImage::Gradient(gradsize, m_gradientStart,+ m_gradientEnd, m_gradientAlpha,+ m_gradientDirection);+ image->UpRef();+ }+ else+ bNeedLoad = true; - bool bForceResize = false;- bool bFoundInCache = false;+ int w = -1;+ int h = -1; - QString imagelabel;+ bool bForceResize = false;+ bool bFoundInCache = false; - if (!m_ForceSize.isNull())- {- if (m_ForceSize.width() != -1)- w = m_ForceSize.width();+ QString imagelabel; - if (m_ForceSize.height() != -1)- h = m_ForceSize.height();+ if (!m_ForceSize.isNull())+ {+ if (m_ForceSize.width() != -1)+ w = m_ForceSize.width(); - bForceResize = true;- }+ if (m_ForceSize.height() != -1)+ h = m_ForceSize.height(); - if (bNeedLoad)- {+ bForceResize = true;+ } - QString filename = m_Filename;- if (m_HighNum >= 1)- filename = QString(m_Filename).arg(i);+ if (bNeedLoad)+ {+ if (imageNumber >= 1)+ filename = QString(filename).arg(imageNumber); - imagelabel = GenImageLabel(filename, w, h);+ imagelabel = GenImageLabel(filename, w, h); - image = GetMythUI()->LoadCacheImage(filename, imagelabel);- if (image)- {- image->UpRef();- VERBOSE(VB_FILE, QString("MythUIImage::Load found in cache :%1:").arg(imagelabel));- if (m_isReflected)- image->setIsReflected(true);+ image = GetMythUI()->LoadCacheImage(filename, imagelabel);+ if (image)+ {+ image->UpRef();+ VERBOSE(VB_FILE, QString("MythUIImage::Load found in cache :%1:").arg(imagelabel));+ if (m_isReflected)+ image->setIsReflected(true); - bFoundInCache = true;- }- else- {- VERBOSE(VB_FILE, QString("MythUIImage::Load Not Found in "- "cache. Loading Directly :%1:")- .arg(filename));- image = GetMythPainter()->GetFormatImage();- image->UpRef();- if (!image->Load(filename))- {- VERBOSE(VB_FILE, QString("MythUIImage::Load Could not load :%1:").arg(filename));- image->DownRef();- SetRedraw();- return false;- }- }+ bFoundInCache = true; } else- imagelabel = GenImageLabel(w,h);-- if (!bFoundInCache) {- if (bForceResize)- image->Resize(QSize(w, h), m_preserveAspect);-- if (m_isMasked)+ VERBOSE(VB_FILE, QString("MythUIImage::Load Not Found in "+ "cache. Loading Directly :%1:")+ .arg(filename));+ image = GetMythPainter()->GetFormatImage();+ image->UpRef();+ if (!image->Load(filename)) {- QRect imageArea = image->rect();- QRect maskArea = m_maskImage->rect();-- // Crop the mask to the image- int x = 0;- int y = 0;- if (maskArea.width() > imageArea.width())- x = (maskArea.width() - imageArea.width()) / 2;- if (maskArea.height() > imageArea.height())- y = (maskArea.height() - imageArea.height()) / 2;-- if (x > 0 || y > 0)- imageArea.translate(x,y);- QImage mask = m_maskImage->copy(imageArea);- image->setAlphaChannel(mask.alphaChannel());+ VERBOSE(VB_FILE, QString("MythUIImage::Load Could not load "+ ":%1:").arg(filename));+ image->DownRef();+ return NULL; }+ }+ }+ else+ imagelabel = GenImageLabel(w,h); - if (m_isReflected)- image->Reflect(m_reflectAxis, m_reflectShear, m_reflectScale,- m_reflectLength, m_reflectSpacing);+ if (!bFoundInCache)+ {+ if (bForceResize)+ image->Resize(QSize(w, h), m_preserveAspect); - if (m_isGreyscale)- image->ToGreyscale();+ if (m_isMasked)+ {+ QRect imageArea = image->rect();+ QRect maskArea = m_maskImage->rect(); - // Save scaled copy to cache- if (bNeedLoad)- GetMythUI()->CacheImage(imagelabel, image);- }+ // Crop the mask to the image+ int x = 0;+ int y = 0;+ if (maskArea.width() > imageArea.width())+ x = (maskArea.width() - imageArea.width()) / 2;+ if (maskArea.height() > imageArea.height())+ y = (maskArea.height() - imageArea.height()) / 2; - if (!bForceResize)- {- newSize = newSize.expandedTo(image->size());- SetSize(newSize);+ if (x > 0 || y > 0)+ imageArea.translate(x,y);+ QImage mask = m_maskImage->copy(imageArea);+ image->setAlphaChannel(mask.alphaChannel()); } - if (image->isNull())- {- VERBOSE(VB_FILE, QString("MythUIImage::Load Image is NULL :%1:").arg(m_Filename));- image->DownRef();- }- else- {- image->SetChanged();- m_Images.push_back(image);- }+ if (m_isReflected)+ image->Reflect(m_reflectAxis, m_reflectShear, m_reflectScale,+ m_reflectLength, m_reflectSpacing);++ if (m_isGreyscale)+ image->ToGreyscale();++ // Save scaled copy to cache+ if (bNeedLoad)+ GetMythUI()->CacheImage(imagelabel, image); } - m_LastDisplay = QTime::currentTime();+ if (image->isNull())+ {+ VERBOSE(VB_FILE, QString("MythUIImage::Load Image is NULL :%1:")+ .arg(filename));+ image->DownRef();+ }+ else+ {+ image->SetChanged();+ } - return true;+ return image; } /**@@ -787,3 +849,67 @@ MythUIType::LoadNow(); } +/**+* \copydoc MythUIType::customEvent()+*/+void MythUIImage::customEvent(QEvent *event)+{+ if (event->type() == kImageLoadEventType)+ {+ ImageLoadEvent *le = dynamic_cast<ImageLoadEvent*>(event);++ ImageLoadThread *thread = le->GetThread();+ MythImage *image = le->GetImage();+ + if (thread)+ delete thread;++ if (image)+ {+ QString filename = le->GetFilename();+ + if (filename == m_Filename)+ {+ int number = le->GetNumber();+ + if (m_ForceSize.isNull())+ SetSize(image->size());++ // Image events may arrive out of sequence because some images+ // load faster than others, so we ensure they are inserted+ // in the intended order+ if (number > 0)+ { + // Debugging+ if (m_Images.value(number))+ {+ // There should be no image that this location, if+ // we find one then something is wrong.+ VERBOSE(VB_IMPORTANT, QString("DEBUG Image Thread: "+ "Found image in m_Images position %1 where "+ "there should be none. Filename %2").arg(number)+ .arg(filename));+ image->DownRef();+ }+ else+ {+ //m_Images.insert(number, image);+ m_Images.push_back(image);+ //image->DownRef();+ }+ }+ else+ m_Images.push_back(image);++ SetRedraw();+ m_LastDisplay = QTime::currentTime();+ }+ else+ {+ VERBOSE(VB_IMPORTANT, QString("Mis-Match File: %1 Not: %2")+ .arg(filename).arg(m_Filename));+ image->DownRef();+ }+ }+ }+}Index: mythtv/libs/libmythui/mythuiimage.h===================================================================--- mythtv/libs/libmythui/mythuiimage.h (revision 21272)+++ mythtv/libs/libmythui/mythuiimage.h (working copy)@@ -7,8 +7,9 @@ #include "mythimage.h" class MythScreenType;+class ImageLoadThread; -/**+/*! * \class MythUIImage * * \brief Image widget, displays a single image or multiple images in sequence@@ -57,6 +58,8 @@ void Init(void); void Clear(void);+ MythImage* LoadImage(const QString &imFile, int imageNumber = 0) const;+ void customEvent(QEvent *event); virtual bool ParseElement(QDomElement &element); virtual void CopyFrom(MythUIType *base);@@ -70,8 +73,8 @@ void SetCropRect(int x, int y, int width, int height); void SetCropRect(const MythRect &rect); - QString GenImageLabel(const QString &filename, int w, int h);- QString GenImageLabel(int w, int h);+ QString GenImageLabel(const QString &filename, int w, int h) const;+ QString GenImageLabel(int w, int h) const; QString m_Filename; QString m_OrigFilename;@@ -110,10 +113,13 @@ bool m_isGreyscale; + ImageLoadThread *m_imageLoadThread;+ friend class MythThemeBase; friend class MythUIButtonListItem; friend class MythUIProgressBar; friend class MythUITextEdit;+ friend class ImageLoadThread; }; #endif