diff --git a/mythtv/libs/libmythui/mythuinotificationcenter.cpp b/mythtv/libs/libmythui/mythuinotificationcenter.cpp index 4059d47ff28..500ea6beda1 100644 --- a/mythtv/libs/libmythui/mythuinotificationcenter.cpp +++ b/mythtv/libs/libmythui/mythuinotificationcenter.cpp @@ -469,45 +469,16 @@ void MythUINotificationScreen::SetSingleShotTimer(int s) m_timer->start(ms); } -/////////////////////// MythUINotificationCenter - -MythUINotificationCenter *MythUINotificationCenter::g_singleton = NULL; -QMutex MythUINotificationCenter::g_lock; -MythUINotificationCenter *MythUINotificationCenter::GetInstance(void) -{ - QMutexLocker lock(&g_lock); - - if (g_singleton) - return g_singleton; - - const bool isGuiThread = - QThread::currentThread() == QCoreApplication::instance()->thread(); +/////////////////////// NCPrivate - if (!isGuiThread) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "Constructor not called from GUI thread"); - } - else - { - g_singleton = new MythUINotificationCenter(); - } - return g_singleton; -} - -MythUINotificationCenter::MythUINotificationCenter() +NCPrivate::NCPrivate() : m_screenStack(NULL), m_currentId(0) { - const bool isGuiThread = - QThread::currentThread() == QCoreApplication::instance()->thread(); - if (!isGuiThread) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "Constructor not called from GUI thread"); - } } -MythUINotificationCenter::~MythUINotificationCenter() +NCPrivate::~NCPrivate() { const bool isGuiThread = QThread::currentThread() == QCoreApplication::instance()->thread(); @@ -531,20 +502,13 @@ MythUINotificationCenter::~MythUINotificationCenter() delete m_screenStack; m_screenStack = NULL; - - // if we're deleting global instancce; set g_singleton to 0 - // in practice this is always the case - if (this == g_singleton) - { - g_singleton = NULL; - } } /** * Remove screen from screens list. * Qt slot called upon MythScreenType::Exiting(). */ -void MythUINotificationCenter::ScreenDeleted(void) +void NCPrivate::ScreenDeleted(void) { MythUINotificationScreen *screen = static_cast(sender()); @@ -602,19 +566,15 @@ void MythUINotificationCenter::ScreenDeleted(void) } } -void MythUINotificationCenter::ScreenStackDeleted(void) +void NCPrivate::ScreenStackDeleted(void) { m_screenStack = NULL; } -bool MythUINotificationCenter::Queue(MythNotification ¬ification) +bool NCPrivate::Queue(MythNotification ¬ification) { QMutexLocker lock(&m_lock); - // Just in case we got deleted half-way while GUI thread was quitting - if (!g_singleton) - return false; - int id = notification.GetId(); void *parent = notification.GetParent(); @@ -657,19 +617,10 @@ bool MythUINotificationCenter::Queue(MythNotification ¬ification) return true; } -void MythUINotificationCenter::ProcessQueue(void) +void NCPrivate::ProcessQueue(void) { QMutexLocker lock(&m_lock); - const bool isGuiThread = - QThread::currentThread() == QCoreApplication::instance()->thread(); - - if (!isGuiThread) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "ProcessQueue not called from GUI thread"); - return; - } - DeleteAllScreens(); foreach (MythNotification *n, m_notifications) @@ -731,8 +682,7 @@ void MythUINotificationCenter::ProcessQueue(void) * CreateScreen will create a MythUINotificationScreen instance. * This screen will not be displayed until it is used. */ -MythUINotificationScreen *MythUINotificationCenter::CreateScreen(MythNotification *n, - int id) +MythUINotificationScreen *NCPrivate::CreateScreen(MythNotification *n, int id) { MythUINotificationScreen *screen; @@ -756,14 +706,10 @@ MythUINotificationScreen *MythUINotificationCenter::CreateScreen(MythNotificatio return screen; } -int MythUINotificationCenter::Register(void *from) +int NCPrivate::Register(void *from) { QMutexLocker lock(&m_lock); - // Just in case we got deleted half-way while GUI thread was quitting - if (!g_singleton) - return false; - if (!from) return -1; @@ -774,14 +720,10 @@ int MythUINotificationCenter::Register(void *from) return m_currentId; } -void MythUINotificationCenter::UnRegister(void *from, int id, bool closeimemdiately) +void NCPrivate::UnRegister(void *from, int id, bool closeimemdiately) { QMutexLocker lock(&m_lock); - // Just in case we got deleted half-way while GUI thread was quitting - if (!g_singleton) - return; - if (!m_registrations.contains(id)) { LOG(VB_GENERAL, LOG_ERR, LOC + @@ -819,7 +761,7 @@ void MythUINotificationCenter::UnRegister(void *from, int id, bool closeimemdiat GetMythMainWindow(), new MythUINotificationCenterEvent()); } -MythNotificationScreenStack *MythUINotificationCenter::GetScreenStack(void) +MythNotificationScreenStack *NCPrivate::GetScreenStack(void) { if (!m_screenStack) { @@ -830,10 +772,10 @@ MythNotificationScreenStack *MythUINotificationCenter::GetScreenStack(void) return m_screenStack; } -void MythUINotificationCenter::DeleteAllRegistrations(void) +void NCPrivate::DeleteAllRegistrations(void) { QMap::iterator it = m_registrations.begin(); - + for (; it != m_registrations.end();) { m_deletedScreens.append(*it); @@ -842,7 +784,7 @@ void MythUINotificationCenter::DeleteAllRegistrations(void) m_registrations.clear(); } -void MythUINotificationCenter::DeleteAllScreens(void) +void NCPrivate::DeleteAllScreens(void) { // delete all screens waiting to be deleted while(!m_deletedScreens.isEmpty()) @@ -859,7 +801,7 @@ void MythUINotificationCenter::DeleteAllScreens(void) * Insert screen into list of screens. * Returns index in screens list. */ -int MythUINotificationCenter::InsertScreen(MythUINotificationScreen *screen) +int NCPrivate::InsertScreen(MythUINotificationScreen *screen) { QList::iterator it = m_screens.begin(); QList::iterator itend = m_screens.end(); @@ -888,7 +830,7 @@ int MythUINotificationCenter::InsertScreen(MythUINotificationScreen *screen) * Remove screen from list of screens. * Returns index in screens list. */ -int MythUINotificationCenter::RemoveScreen(MythUINotificationScreen *screen) +int NCPrivate::RemoveScreen(MythUINotificationScreen *screen) { QList::iterator it = m_screens.begin(); QList::iterator itend = m_screens.end(); @@ -910,7 +852,7 @@ int MythUINotificationCenter::RemoveScreen(MythUINotificationScreen *screen) /** * Re-position screens on display. */ -void MythUINotificationCenter::RefreshScreenPosition(int from) +void NCPrivate::RefreshScreenPosition(int from) { QList::iterator it = m_screens.begin(); QList::iterator itend = m_screens.end(); @@ -937,27 +879,7 @@ void MythUINotificationCenter::RefreshScreenPosition(int from) } } -QDateTime MythUINotificationCenter::ScreenExpiryTime(MythScreenType *screen) -{ - MythUINotificationScreen *s = - dynamic_cast(screen); - - if (!s) - return QDateTime(); - return s->m_expiry; -} - -bool MythUINotificationCenter::ScreenCreated(MythScreenType *screen) -{ - MythUINotificationScreen *s = - dynamic_cast(screen); - - if (!s) - return true;; - return s->m_created; -} - -void MythUINotificationCenter::GetNotificationScreens(QList &_screens) +void NCPrivate::GetNotificationScreens(QList &_screens) { QList list; QVector screens; @@ -1013,6 +935,127 @@ void MythUINotificationCenter::GetNotificationScreens(QList &_s _screens = list; } +/////////////////////// MythUINotificationCenter + +MythUINotificationCenter *MythUINotificationCenter::g_singleton = NULL; +QMutex MythUINotificationCenter::g_lock; + +MythUINotificationCenter *MythUINotificationCenter::GetInstance(void) +{ + QMutexLocker lock(&g_lock); + + if (g_singleton) + return g_singleton; + + const bool isGuiThread = + QThread::currentThread() == QCoreApplication::instance()->thread(); + + if (!isGuiThread) + { + LOG(VB_GENERAL, LOG_ERR, LOC + "Constructor not called from GUI thread"); + } + else + { + g_singleton = new MythUINotificationCenter(); + } + return g_singleton; +} + +MythUINotificationCenter::MythUINotificationCenter() + : d(new NCPrivate()) +{ + const bool isGuiThread = + QThread::currentThread() == QCoreApplication::instance()->thread(); + + if (!isGuiThread) + { + LOG(VB_GENERAL, LOG_ERR, LOC + "Constructor not called from GUI thread"); + } +} + +MythUINotificationCenter::~MythUINotificationCenter() +{ + const bool isGuiThread = + QThread::currentThread() == QCoreApplication::instance()->thread(); + + if (!isGuiThread) + { + LOG(VB_GENERAL, LOG_ERR, LOC + "Destructor not called from GUI thread"); + } + + delete d; + d = NULL; + + // if we're deleting global instancce; set g_singleton to 0 + // in practice this is always the case + if (this == g_singleton) + { + g_singleton = NULL; + } +} + +bool MythUINotificationCenter::Queue(MythNotification ¬ification) +{ + return d->Queue(notification); +} + +void MythUINotificationCenter::ProcessQueue(void) +{ + const bool isGuiThread = + QThread::currentThread() == QCoreApplication::instance()->thread(); + + if (!isGuiThread) + { + LOG(VB_GENERAL, LOG_ERR, LOC + "ProcessQueue not called from GUI thread"); + return; + } + + d->ProcessQueue(); +} + +int MythUINotificationCenter::Register(void *from) +{ + // Just in case we got deleted half-way while GUI thread was quitting + if (!g_singleton) + return false; + + return d->Register(from); +} + +void MythUINotificationCenter::UnRegister(void *from, int id, bool closeimemdiately) +{ + // Just in case we got deleted half-way while GUI thread was quitting + if (!g_singleton) + return; + + d->UnRegister(from, id, closeimemdiately); +} + +QDateTime MythUINotificationCenter::ScreenExpiryTime(MythScreenType *screen) +{ + MythUINotificationScreen *s = + dynamic_cast(screen); + + if (!s) + return QDateTime(); + return s->m_expiry; +} + +bool MythUINotificationCenter::ScreenCreated(MythScreenType *screen) +{ + MythUINotificationScreen *s = + dynamic_cast(screen); + + if (!s) + return true;; + return s->m_created; +} + +void MythUINotificationCenter::GetNotificationScreens(QList &_screens) +{ + d->GetNotificationScreens(_screens); +} + void MythUINotificationCenter::UpdateScreen(MythScreenType *screen) { MythUINotificationScreen *s = diff --git a/mythtv/libs/libmythui/mythuinotificationcenter.h b/mythtv/libs/libmythui/mythuinotificationcenter.h index c3925f60702..9c1e5ae07dd 100644 --- a/mythtv/libs/libmythui/mythuinotificationcenter.h +++ b/mythtv/libs/libmythui/mythuinotificationcenter.h @@ -9,25 +9,18 @@ #ifndef __MythTV__mythnotifications__ #define __MythTV__mythnotifications__ -#include #include -#include -#include #include +#include #include "mythuiexp.h" -#include "mythevent.h" #include "mythnotification.h" // .h -class MythUINotificationScreen; -class MythScreenStack; -class MythPainter; class MythScreenType; -class QPaintDevice; -class MythNotificationScreenStack; +class NCPrivate; class MUI_PUBLIC MythUINotificationCenterEvent : public MythEvent { @@ -37,10 +30,8 @@ class MUI_PUBLIC MythUINotificationCenterEvent : public MythEvent static Type kEventType; }; -class MUI_PUBLIC MythUINotificationCenter : public QObject +class MUI_PUBLIC MythUINotificationCenter { - Q_OBJECT - public: MythUINotificationCenter(void); virtual ~MythUINotificationCenter(); @@ -107,37 +98,11 @@ class MUI_PUBLIC MythUINotificationCenter : public QObject */ void ProcessQueue(void); -private slots: - void ScreenDeleted(void); - private: - friend class MythNotificationScreenStack; - friend class MythUINotificationScreen; - - MythUINotificationScreen *CreateScreen(MythNotification *notification, - int id = -1); - MythNotificationScreenStack *GetScreenStack(void); - void ScreenStackDeleted(void); - void DeleteAllRegistrations(void); - void DeleteAllScreens(void); - int InsertScreen(MythUINotificationScreen *screen); - int RemoveScreen(MythUINotificationScreen *screen); - void RefreshScreenPosition(int from = 0); + NCPrivate *d; -private: - MythNotificationScreenStack *m_screenStack; - QList m_notifications; - QList m_screens; - QList m_deletedScreens; - QMap m_registrations; - QList m_suspended; - QMap m_clients; - QMutex m_lock; - int m_currentId; - QMap m_converted; - - // protected by g_lock static QMutex g_lock; + // protected by g_lock static MythUINotificationCenter *g_singleton; }; diff --git a/mythtv/libs/libmythui/mythuinotificationcenter_private.h b/mythtv/libs/libmythui/mythuinotificationcenter_private.h index b06a7a9ec43..9c327ed9a2e 100644 --- a/mythtv/libs/libmythui/mythuinotificationcenter_private.h +++ b/mythtv/libs/libmythui/mythuinotificationcenter_private.h @@ -10,6 +10,10 @@ #define MythTV_mythuinotificationcenter_private_h #include +#include +#include +#include + #include #include "mythscreenstack.h" @@ -19,6 +23,108 @@ #include "mythuiprogressbar.h" #include "mythuinotificationcenter.h" +// Forward declarations +class MythUINotificationScreen; +class MythNotificationScreenStack; + +class NCPrivate : public QObject +{ + Q_OBJECT + +public slots: + void ScreenDeleted(void); + +public: + NCPrivate(void); + virtual ~NCPrivate(); + + /** + * Queue a notification + * Queue() is thread-safe and can be called from anywhere. + * Typical use would be MythUINotificationCenter::GetInstance()->Queue(notification) + */ + bool Queue(MythNotification ¬ification); + + /** + * returns the MythUINotificationCenter singleton + */ + static MythUINotificationCenter *GetInstance(void); + + /** + * An application can register in which case it will be assigned a + * reusable screen, which can be modified or updated + * Register takes a pointer of the client registering. This is used + * to make sure a registered Id can only be used by the client who registered + * for it. + * Returns a unique Id that can be provided with a MythNotification + * Return -1 is case of error + */ + int Register(void *from); + /** + * Unregister the client. + * If the notification had set a duration, the screen will be left to + * laps, unless forcedisconnect is set; in which case the screen will + * be closed immediately. + */ + void UnRegister(void *from, int id, bool closeimemdiately = false); + + /* + * OSD drawing utilities + */ + + /** + * Return when the given screen is going to expire + * will return an invalid QDateTime if screen isn't a MythUINotificationScreen + */ + QDateTime ScreenExpiryTime(MythScreenType *screen); + /** + * Return true if ::Create() has been called on screen. + * will always return true should screen not be a MythUINotificationScreen + */ + bool ScreenCreated(MythScreenType *screen); + /** + * Return the list of notification screens being currently displayed. + * The list contains pointer of existing screen's copies, with ::Create() + * not called yet. + */ + void GetNotificationScreens(QList &screens); + /** + * Will call ::doInit() if the screen is a MythUINotificationScreen and + * ::Create() has been called for it already + */ + void UpdateScreen(MythScreenType *screen); + /** + * ProcessQueue will be called by the GUI event handler and will process + * all queued MythNotifications and delete screens marked to be deleted + * ProcessQueue must be called from GUI thread + */ + void ProcessQueue(void); + + void ScreenStackDeleted(void); + +private: + + MythUINotificationScreen *CreateScreen(MythNotification *notification, + int id = -1); + MythNotificationScreenStack *GetScreenStack(void); + void DeleteAllRegistrations(void); + void DeleteAllScreens(void); + int InsertScreen(MythUINotificationScreen *screen); + int RemoveScreen(MythUINotificationScreen *screen); + void RefreshScreenPosition(int from = 0); + + MythNotificationScreenStack *m_screenStack; + QList m_notifications; + QList m_screens; + QList m_deletedScreens; + QMap m_registrations; + QList m_suspended; + QMap m_clients; + QMutex m_lock; + int m_currentId; + QMap m_converted; +}; + class MythUINotificationScreen : public MythScreenType { Q_OBJECT @@ -107,7 +213,7 @@ class MythNotificationScreenStack : public MythScreenStack { public: MythNotificationScreenStack(MythMainWindow *parent, const QString& name, - MythUINotificationCenter *owner) + NCPrivate *owner) : MythScreenStack(parent, name), m_owner(owner) { } @@ -131,7 +237,7 @@ class MythNotificationScreenStack : public MythScreenStack } private: - MythUINotificationCenter *m_owner; + NCPrivate *m_owner; };