hopefully fixed the crashes

This commit is contained in:
Patrick von Reth 2013-07-09 20:13:24 +02:00
parent ca1a89d3ef
commit 41061f322e
15 changed files with 86 additions and 110 deletions

View File

@ -24,13 +24,9 @@
#include <QDebug> #include <QDebug>
namespace Snore{ namespace Snore{
class SnoreIcon::SnoreIconData class SnoreIcon::SnoreIconData : public QSharedData
{ {
public: public:
SnoreIconData():
m_isLocalFile(false)
{ }
SnoreIconData(const QImage &img): SnoreIconData(const QImage &img):
m_img(img), m_img(img),
m_isLocalFile(false) m_isLocalFile(false)
@ -59,8 +55,6 @@ public:
~SnoreIconData() ~SnoreIconData()
{} {}
QAtomicInt m_ref;
QImage m_img; QImage m_img;
QByteArray m_data; QByteArray m_data;
QString m_localUrl; QString m_localUrl;
@ -78,48 +72,32 @@ SnoreIcon::SnoreIcon() :
{ {
} }
SnoreIcon::SnoreIcon(const QImage &img) SnoreIcon::SnoreIcon(const QImage &img):
d(new SnoreIconData(img))
{ {
d = new SnoreIconData(img);
d->m_ref.ref();
} }
SnoreIcon::SnoreIcon(const QString &url) SnoreIcon::SnoreIcon(const QString &url):
d(new SnoreIconData(url))
{ {
d = new SnoreIconData(url);
d->m_ref.ref();
} }
SnoreIcon::SnoreIcon(const SnoreIcon &other) SnoreIcon::SnoreIcon(const SnoreIcon &other)
{ {
if(other.d) d = other.d;
{
other.d->m_ref.ref();
d = other.d;
}
else
{
d = NULL;
}
} }
SnoreIcon &SnoreIcon::operator=(const SnoreIcon &other) SnoreIcon &SnoreIcon::operator=(const SnoreIcon &other)
{ {
if(d && !d->m_ref.deref())
{
delete d;
}
other.d->m_ref.ref();
d = other.d; d = other.d;
return *this; return *this;
} }
SnoreIcon::~SnoreIcon() SnoreIcon::~SnoreIcon()
{ {
if(d && !d->m_ref.deref())
{
delete d;
}
} }
@ -131,10 +109,14 @@ const QImage &SnoreIcon::image() const{
} }
const QString &SnoreIcon::localUrl()const{ const QString &SnoreIcon::localUrl()const{
if(d->m_localUrl.isEmpty()){ if(d->m_localUrl.isEmpty())
if(hasedImages.contains(hash())){ {
if(hasedImages.contains(hash()))
{
d->m_localUrl = hasedImages[hash()]; d->m_localUrl = hasedImages[hash()];
}else{ }
else
{
d->m_localUrl = SnoreCore::snoreTMP(); d->m_localUrl = SnoreCore::snoreTMP();
d->m_localUrl = d->m_localUrl.append(hash()).append(".png"); d->m_localUrl = d->m_localUrl.append(hash()).append(".png");
hasedImages[hash()] = d->m_localUrl; hasedImages[hash()] = d->m_localUrl;
@ -145,16 +127,16 @@ const QString &SnoreIcon::localUrl()const{
} }
const QByteArray &SnoreIcon::imageData() const{ const QByteArray &SnoreIcon::imageData() const{
if(d->m_data.isEmpty()){ if(d->m_data.isEmpty() && !image().isNull()){
QBuffer buffer( &d->m_data ); QBuffer buffer( &d->m_data );
buffer.open( QBuffer::WriteOnly ); buffer.open( QBuffer::WriteOnly );
d->m_img.save( &buffer, "PNG" ); image().save( &buffer, "PNG" );
} }
return d->m_data; return d->m_data;
} }
const QString &SnoreIcon::hash() const{ const QString &SnoreIcon::hash() const{
if(d->m_hash.isEmpty()){ if(d->m_hash.isEmpty() && !imageData().isNull()){
QCryptographicHash h(QCryptographicHash::Md5); QCryptographicHash h(QCryptographicHash::Md5);
h.addData(imageData()); h.addData(imageData());
d->m_hash = h.result().toHex(); d->m_hash = h.result().toHex();

View File

@ -37,7 +37,7 @@ public:
const QImage &image() const; const QImage &image() const;
const QString &localUrl() const; const QString &localUrl() const;
const QString &url() const; const QString &url() const;
const QByteArray &imageData() const; const QByteArray &imageData() const ;
const QString &hash() const; const QString &hash() const;
bool isLocalFile() const; bool isLocalFile() const;
bool isEmpty() const; bool isEmpty() const;
@ -47,7 +47,7 @@ private:
static QHash<QString,QString> hasedImages; static QHash<QString,QString> hasedImages;
private: private:
class SnoreIconData; class SnoreIconData;
SnoreIconData* d; QExplicitlySharedDataPointer<SnoreIconData> d;

View File

@ -28,16 +28,20 @@
#include <QTextDocumentFragment> #include <QTextDocumentFragment>
#include <QTextDocument> #include <QTextDocument>
#include <QSharedData>
namespace Snore{ namespace Snore{
int Notification::notificationMetaID = qRegisterMetaType<Notification>(); int Notification::notificationMetaID = qRegisterMetaType<Notification>();
int Notification::notificationCount = 0; QAtomicInt Notification::notificationCount = 0;
uint Notification::m_idCount = 1;
class Notification::NotificationData uint Notification::m_idCount;
class Notification::NotificationData : public QSharedData
{ {
public: public:
NotificationData ( const QString &application,const QString &alert,const QString &title,const QString &text,const SnoreIcon &icon,int timeout,uint id,NotificationEnums::Prioritys::prioritys priority ): NotificationData ( const QString &application,const QString &alert,const QString &title,const QString &text,const SnoreIcon &icon,int timeout,uint id,NotificationEnums::Prioritys::prioritys priority ):
m_id ( id == 0 ?m_idCount++:id), m_id ( id == 0 ?m_idCount++:id),
@ -51,17 +55,16 @@ public:
m_priority(priority), m_priority(priority),
m_closeReason(NotificationEnums::CloseReasons::NONE) m_closeReason(NotificationEnums::CloseReasons::NONE)
{ {
qDebug()<< "Creating Notification: ActiveNotifications" << ++notificationCount << "id" << m_id; notificationCount.ref();
m_ref.ref(); qDebug()<< "Creating Notification: ActiveNotifications" << notificationCount << "id" << m_id;
} }
~NotificationData(){ ~NotificationData(){
qDebug() << "Cloasing Notification:" << m_id << m_ref; notificationCount.deref();
qDebug() << "Deleting Notification: ActiveNotifications"<<--notificationCount; qDebug() << "Deleting Notification: ActiveNotifications" << notificationCount << "id" << m_id;
} }
QAtomicInt m_ref;
uint m_id; uint m_id;
int m_timeout; int m_timeout;
Notification::Action *m_actionInvoked; Notification::Action *m_actionInvoked;
@ -77,6 +80,8 @@ public:
QVariantHash m_hints; QVariantHash m_hints;
}; };
@ -99,34 +104,17 @@ Notification::Notification ( const QString &application, const QString &alert, c
d = new NotificationData(application,alert,title,text,icon,timeout,id,priority); d = new NotificationData(application,alert,title,text,icon,timeout,id,priority);
} }
Notification::Notification ( const Notification &other ) Notification::Notification ( const Notification &other ) :
d(other.d)
{ {
if(other.d)
{
other.d->m_ref.ref();
d = other.d;
}
else
{
d = NULL;
}
} }
Notification::~Notification() Notification::~Notification()
{ {
if(d && !d->m_ref.deref())
{
delete d;
}
} }
Notification &Notification::operator=(const Notification& other) Notification &Notification::operator=(const Notification& other)
{ {
if(d && !d->m_ref.deref())
{
delete d;
}
other.d->m_ref.ref();
d = other.d; d = other.d;
return *this; return *this;
} }
@ -136,7 +124,7 @@ const uint &Notification::id() const
return d->m_id; return d->m_id;
} }
const SnoreIcon &Notification::icon() const const SnoreIcon &Notification::icon()
{ {
return d->m_icon; return d->m_icon;
} }
@ -161,7 +149,7 @@ void Notification::setActionInvoked ( const int &id)
d->m_actionInvoked = d->m_actions[id]; d->m_actionInvoked = d->m_actions[id];
} }
void Notification::setSource(SnoreFrontend *source) const{ void Notification::setSource(SnoreFrontend *source){
d->m_source = source; d->m_source = source;
} }
@ -242,7 +230,7 @@ void Notification::insertHint ( const QString &key, const QVariant &val )
bool Notification::isValid() const bool Notification::isValid() const
{ {
return d != NULL; return d;
} }
QDataStream &operator<< ( QDataStream &stream, const Notification &noti ) QDataStream &operator<< ( QDataStream &stream, const Notification &noti )

View File

@ -56,12 +56,12 @@ public:
const int &timeout() const; const int &timeout() const;
const Action* actionInvoked() const; const Action* actionInvoked() const;
void setSource(class SnoreFrontend *source)const; void setSource(class SnoreFrontend *source);
class SnoreFrontend *source() const; class SnoreFrontend *source() const;
const QString &application() const; const QString &application() const;
const QString &title() const; const QString &title() const;
const QString &text() const; const QString &text() const;
const SnoreIcon &icon() const; const SnoreIcon &icon();
const QString &alert() const; const QString &alert() const;
void setSticky(); void setSticky();
bool sticky() const; bool sticky() const;
@ -84,8 +84,8 @@ public:
private: private:
static uint m_idCount; static uint m_idCount;
class NotificationData; class NotificationData;
NotificationData* d; QExplicitlySharedDataPointer<NotificationData> d;
static int notificationCount; static QAtomicInt notificationCount;
static int notificationMetaID; static int notificationMetaID;
}; };

View File

@ -56,18 +56,17 @@ bool SnoreBackend::init( SnoreCore *snore )
} }
bool SnoreBackend::requestCloseNotification ( Notification notification,NotificationEnums::CloseReasons::closeReasons reason ) void SnoreBackend::requestCloseNotification ( Notification notification,NotificationEnums::CloseReasons::closeReasons reason )
{ {
if(slotCloseNotification(notification)) if(canCloseNotification())
{ {
notification.setCloseReason(reason); closeNotification(notification,reason);
return true;
} }
return false;
} }
void SnoreBackend::closeNotification(Notification n, NotificationEnums::CloseReasons::closeReasons reason) void SnoreBackend::closeNotification(Notification n, NotificationEnums::CloseReasons::closeReasons reason)
{ {
qDebug() << __func__ << n;
if(m_activeNotifications.contains(n.id())) if(m_activeNotifications.contains(n.id()))
{ {
m_activeNotifications.remove(n.id()); m_activeNotifications.remove(n.id());
@ -77,6 +76,11 @@ void SnoreBackend::closeNotification(Notification n, NotificationEnums::CloseRea
emit closeNotification(n); emit closeNotification(n);
} }
void SnoreBackend::slotCloseNotification(Notification notification)
{
Q_UNUSED(notification)
}
SnoreSecondaryBackend::SnoreSecondaryBackend(const QString &name) SnoreSecondaryBackend::SnoreSecondaryBackend(const QString &name)
:SnoreBackend(name) :SnoreBackend(name)
{ {

View File

@ -39,10 +39,12 @@ public:
virtual ~SnoreBackend(); virtual ~SnoreBackend();
virtual bool init(SnoreCore *snore); virtual bool init(SnoreCore *snore);
bool requestCloseNotification( Snore::Notification notification,NotificationEnums::CloseReasons::closeReasons reason ); void requestCloseNotification( Snore::Notification notification,NotificationEnums::CloseReasons::closeReasons reason );
Snore::Notification getActiveNotificationByID(uint id); Snore::Notification getActiveNotificationByID(uint id);
virtual bool canCloseNotification() = 0;
signals: signals:
void closeNotification( Snore::Notification ); void closeNotification( Snore::Notification );
@ -51,7 +53,7 @@ public slots:
virtual void slotRegisterApplication ( Snore::Application *application ) = 0; virtual void slotRegisterApplication ( Snore::Application *application ) = 0;
virtual void slotUnregisterApplication ( Snore::Application *application ) = 0; virtual void slotUnregisterApplication ( Snore::Application *application ) = 0;
virtual void slotNotify ( Snore::Notification notification ) = 0; virtual void slotNotify ( Snore::Notification notification ) = 0;
virtual bool slotCloseNotification ( Snore::Notification notification ) =0; virtual void slotCloseNotification ( Snore::Notification notification );
protected: protected:
void closeNotification(Snore::Notification,Snore::NotificationEnums::CloseReasons::closeReasons); void closeNotification(Snore::Notification,Snore::NotificationEnums::CloseReasons::closeReasons);

View File

@ -329,10 +329,7 @@ Notification SnoreCore::getActiveNotificationByID(uint id)
void SnoreCore::requestCloseNotification(Notification n, NotificationEnums::CloseReasons::closeReasons r) void SnoreCore::requestCloseNotification(Notification n, NotificationEnums::CloseReasons::closeReasons r)
{ {
if(m_notificationBackend->requestCloseNotification(n,r)) m_notificationBackend->requestCloseNotification(n,r);
{
emit notificationClosed(n);
}
} }
} }

View File

@ -88,11 +88,6 @@ void Growl::slotNotify(Notification notification){
} }
} }
bool Growl::slotCloseNotification(Notification notification){
Q_UNUSED(notification);
return false;
}
void Growl::gntpCallback(const int &id,const std::string &reason,const std::string &data){ void Growl::gntpCallback(const int &id,const std::string &reason,const std::string &data){
qDebug()<<"Growl Callback"<<id<<QString(reason.c_str())<<QString(data.c_str()); qDebug()<<"Growl Callback"<<id<<QString(reason.c_str())<<QString(data.c_str());
Notification n = s_instance->snore()->getActiveNotificationByID(id); Notification n = s_instance->snore()->getActiveNotificationByID(id);
@ -108,3 +103,8 @@ void Growl::gntpCallback(const int &id,const std::string &reason,const std::stri
} }
s_instance->closeNotification(n,r); s_instance->closeNotification(n,r);
} }
bool Growl::canCloseNotification()
{
return false;
}

View File

@ -31,6 +31,7 @@ public:
Growl(); Growl();
~Growl(); ~Growl();
static void gntpCallback(const int &id,const std::string &reason,const std::string &data); static void gntpCallback(const int &id,const std::string &reason,const std::string &data);
bool canCloseNotification();
private: private:
//a static instance for the static callback methode //a static instance for the static callback methode
@ -42,7 +43,6 @@ public slots:
void slotRegisterApplication(Snore::Application *application); void slotRegisterApplication(Snore::Application *application);
void slotUnregisterApplication(Snore::Application *application); void slotUnregisterApplication(Snore::Application *application);
void slotNotify(Snore::Notification notification); void slotNotify(Snore::Notification notification);
bool slotCloseNotification(Snore::Notification notification);
}; };

View File

@ -142,6 +142,11 @@ bool SnarlBackend::init(SnoreCore *snore){
return SnoreBackend::init(snore); return SnoreBackend::init(snore);
} }
bool SnarlBackend::canCloseNotification()
{
return true;
}
void SnarlBackend::slotRegisterApplication(Application *application){ void SnarlBackend::slotRegisterApplication(Application *application){
SnarlInterface *snarlInterface = NULL; SnarlInterface *snarlInterface = NULL;
if(m_applications.contains(application->name())){ if(m_applications.contains(application->name())){
@ -226,8 +231,7 @@ void SnarlBackend::slotNotify(Notification notification){
startTimeout(notification.id(),notification.timeout()); startTimeout(notification.id(),notification.timeout());
} }
bool SnarlBackend::slotCloseNotification(Notification notification) void SnarlBackend::slotCloseNotification(Notification notification)
{ {
m_defautSnarlinetrface->Hide(m_idMap.take(notification.id())); m_defautSnarlinetrface->Hide(m_idMap.take(notification.id()));
return true;
} }

View File

@ -32,6 +32,7 @@ public:
SnarlBackend(); SnarlBackend();
~SnarlBackend(); ~SnarlBackend();
virtual bool init(Snore::SnoreCore *snore); virtual bool init(Snore::SnoreCore *snore);
bool canCloseNotification();
private: private:
class SnarlWidget; class SnarlWidget;
@ -43,7 +44,7 @@ public slots:
void slotRegisterApplication(Snore::Application *application); void slotRegisterApplication(Snore::Application *application);
void slotUnregisterApplication(Snore::Application *application); void slotUnregisterApplication(Snore::Application *application);
void slotNotify(Snore::Notification notification); void slotNotify(Snore::Notification notification);
bool slotCloseNotification(Snore::Notification notification); void slotCloseNotification(Snore::Notification notification);
private: private:
QHash<uint,LONG32> m_idMap; QHash<uint,LONG32> m_idMap;

View File

@ -49,6 +49,11 @@ bool SnoreToast::init(SnoreCore *snore)
return SnoreBackend::init(snore); return SnoreBackend::init(snore);
} }
bool SnoreToast::canCloseNotification()
{
return false;
}
void SnoreToast::slotRegisterApplication(Application *application) void SnoreToast::slotRegisterApplication(Application *application)
{ {
Q_UNUSED(application) Q_UNUSED(application)
@ -84,12 +89,6 @@ void SnoreToast::slotNotify(Notification notification)
qDebug() << notification.id(); qDebug() << notification.id();
} }
bool SnoreToast::slotCloseNotification(Notification notification)
{
Q_UNUSED(notification)
return false;
}
void SnoreToast::slotToastNotificationClosed(int code, QProcess::ExitStatus) void SnoreToast::slotToastNotificationClosed(int code, QProcess::ExitStatus)
{ {
QProcess *p = qobject_cast<QProcess*>(sender()); QProcess *p = qobject_cast<QProcess*>(sender());

View File

@ -11,6 +11,7 @@ public:
SnoreToast(); SnoreToast();
~SnoreToast(); ~SnoreToast();
bool init(Snore::SnoreCore *snore); bool init(Snore::SnoreCore *snore);
bool canCloseNotification();
// SnoreBackend interface // SnoreBackend interface
@ -18,7 +19,6 @@ public slots:
void slotRegisterApplication(Snore::Application *application); void slotRegisterApplication(Snore::Application *application);
void slotUnregisterApplication(Snore::Application *application); void slotUnregisterApplication(Snore::Application *application);
void slotNotify(Snore::Notification notification); void slotNotify(Snore::Notification notification);
bool slotCloseNotification(Snore::Notification notification);
private slots: private slots:
void slotToastNotificationClosed(int code, QProcess::ExitStatus); void slotToastNotificationClosed(int code, QProcess::ExitStatus);

View File

@ -26,6 +26,11 @@ bool TrayIconNotifer::init(SnoreCore *snore){
return SnoreBackend::init(snore); return SnoreBackend::init(snore);
} }
bool TrayIconNotifer::canCloseNotification()
{
return false;
}
void TrayIconNotifer::slotRegisterApplication ( Application *application ) void TrayIconNotifer::slotRegisterApplication ( Application *application )
{ {
Q_UNUSED ( application ) Q_UNUSED ( application )
@ -43,17 +48,11 @@ void TrayIconNotifer::slotNotify( Notification notification )
} }
} }
bool TrayIconNotifer::slotCloseNotification( Notification notification )
{
Q_UNUSED ( notification )
return false;
}
void TrayIconNotifer::displayNotification(){ void TrayIconNotifer::displayNotification(){
qDebug()<<"Display"<<m_notificationQue.size(); qDebug()<<"Display"<<m_notificationQue.size();
Notification notification = m_notificationQue.takeFirst(); Notification notification = m_notificationQue.takeFirst();
if(!m_notificationQue.isEmpty()){ if(!m_notificationQue.isEmpty()){
QTimer::singleShot(notification.timeout()*1000,this,SLOT(slotCloseNotification())); QTimer::singleShot(notification.timeout()*1000,this,SLOT(slotCloseNotificationByTimeout()));
} }
qDebug()<<"taking"<<notification.title(); qDebug()<<"taking"<<notification.title();
@ -62,7 +61,7 @@ void TrayIconNotifer::displayNotification(){
m_lastNotify.restart(); m_lastNotify.restart();
} }
void TrayIconNotifer::slotCloseNotification(){ void TrayIconNotifer::slotCloseNotificationByTimeout(){
Notification n = snore()->getActiveNotificationByID(m_displayed); Notification n = snore()->getActiveNotificationByID(m_displayed);
if(n.isValid()){ if(n.isValid()){
closeNotification(n,NotificationEnums::CloseReasons::TIMED_OUT); closeNotification(n,NotificationEnums::CloseReasons::TIMED_OUT);

View File

@ -18,12 +18,12 @@ class TrayIconNotifer:public Snore::SnoreBackend
public: public:
TrayIconNotifer (); TrayIconNotifer ();
virtual bool init(Snore::SnoreCore *snore); virtual bool init(Snore::SnoreCore *snore);
bool canCloseNotification();
public slots: public slots:
void slotRegisterApplication ( Snore::Application *application ); void slotRegisterApplication ( Snore::Application *application );
void slotUnregisterApplication ( Snore::Application *application ); void slotUnregisterApplication ( Snore::Application *application );
void slotNotify ( Snore::Notification notification ); void slotNotify ( Snore::Notification notification );
bool slotCloseNotification ( Snore::Notification notification );
private: private:
QSystemTrayIcon *m_trayIcon; QSystemTrayIcon *m_trayIcon;
@ -34,7 +34,7 @@ private:
private slots: private slots:
void displayNotification(); void displayNotification();
void actionInvoked(); void actionInvoked();
void slotCloseNotification(); void slotCloseNotificationByTimeout();
}; };
#endif // TRAYICONNOTIFER_H #endif // TRAYICONNOTIFER_H