added a new backand which supports windows 8 notifications, refactoring

This commit is contained in:
Patrick von Reth 2013-07-01 11:18:15 +02:00
parent d9b7820f35
commit 5b5bd6e6d3
20 changed files with 251 additions and 39 deletions

View File

@ -4,6 +4,7 @@ set(SNORE_RCS ${SNORE_RCS} ../data/snore.qrc PARENT_SCOPE)
if(WIN32)
set(ICON_NAME zzz)
FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${ICON_NAME}.ico ICON)
string(REPLACE "\\" "\\\\" ICON ${ICON})
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${ICON_NAME}.rc "IDI_ICON1 ICON DISCARDABLE \"${ICON}\"\n")
set(SNORENOTIFY_DEPS ${SNORENOTIFY_DEPS} ${CMAKE_CURRENT_BINARY_DIR}/${ICON_NAME}.rc PARENT_SCOPE)
endif(WIN32)
@ -13,4 +14,4 @@ if(KDE4_FOUND)
if(CMAKE_INSTALL_PREFIX STREQUAL "/usr")
install(FILES snore.png DESTINATION /usr/share/pixmaps)
endif(CMAKE_INSTALL_PREFIX STREQUAL "/usr")
endif(KDE4_FOUND)
endif(KDE4_FOUND)

View File

@ -3,3 +3,7 @@ install(FILES FindLibsnore.cmake DESTINATION share/apps/cmake/modules)
if(KDE4_FOUND)
install(FILES snorenotify.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
endif(KDE4_FOUND)
if(WIN32)
add_subdirectory(snoretoast)
endif(WIN32)

View File

@ -0,0 +1 @@
install(FILES SnoreToast.exe DESTINATION bin)

Binary file not shown.

View File

@ -39,13 +39,22 @@ public:
SnoreIconData(const QString &url){
qDebug()<<"Creating SnoreIcon"<<url;
if(url.startsWith(":/")){
if(url.startsWith(":/"))
{
m_img = QImage(url);
m_isLocalFile = false;
}else if(QFile(url).exists()){
m_isLocalFile = true;
m_localFileName = url;
}
else if(QFile(url).exists())
{
m_isLocalFile = true;
m_localUrl = url;
}
else
{
m_url = url;
m_isLocalFile = false;
}
}
~SnoreIconData()
@ -54,7 +63,8 @@ public:
QImage m_img;
QByteArray m_data;
QString m_localFileName;
QString m_localUrl;
QString m_url;
QString m_hash;
bool m_isLocalFile;
@ -89,23 +99,23 @@ SnoreIcon::~SnoreIcon()
const QImage &SnoreIcon::image() const{
if(d->m_img.isNull() && d->m_isLocalFile){
d->m_img = QImage(d->m_localFileName);
d->m_img = QImage(d->m_localUrl);
}
return d->m_img;
}
const QString &SnoreIcon::localUrl()const{
if(d->m_localFileName.isEmpty()){
if(d->m_localUrl.isEmpty()){
if(hasedImages.contains(hash())){
d->m_localFileName = hasedImages[hash()];
d->m_localUrl = hasedImages[hash()];
}else{
d->m_localFileName = SnoreCore::snoreTMP();
d->m_localFileName = d->m_localFileName .append("/").append(hash()).append(".png");
hasedImages[hash()] = d->m_localFileName;
d->m_img.save(d->m_localFileName ,"PNG");
d->m_localUrl = SnoreCore::snoreTMP();
d->m_localUrl = d->m_localUrl.append(hash()).append(".png");
hasedImages[hash()] = d->m_localUrl;
d->m_img.save(d->m_localUrl ,"PNG");
}
}
return d->m_localFileName;
return d->m_localUrl;
}
const QByteArray &SnoreIcon::imageData() const{
@ -132,7 +142,12 @@ bool SnoreIcon::isLocalFile() const
}
bool SnoreIcon::isEmpty() const{
return d->m_hash.isEmpty() && d->m_img.isNull() && d->m_localFileName.isEmpty();
return d->m_hash.isEmpty() && d->m_img.isNull() && d->m_localUrl.isEmpty();
}
const QString &SnoreIcon::url() const
{
d->m_url.isEmpty()?localUrl():d->m_url;
}
}

View File

@ -35,6 +35,7 @@ public:
const QImage &image() const;
const QString &localUrl() const;
const QString &url() const;
const QByteArray &imageData() const;
const QString &hash() const;
bool isLocalFile() const;

View File

@ -237,6 +237,11 @@ void Notification::insertHint ( const QString &key, const QVariant &val )
d->m_hints.insert ( key,val );
}
const QObject *Notification::data() const
{
return d.data();
}
QDataStream & operator<< ( QDataStream &stream, const Notification &noti )
{
stream<<noti.toString();

View File

@ -96,6 +96,8 @@ public:
bool hintExists ( const QString &key );
void insertHint ( const QString &key,const QVariant &val );
const QObject *data() const;
private:
class NotificationData;

View File

@ -82,8 +82,8 @@ void SnorePlugin::startTimeout(uint id,int timeout){
void SnorePlugin::notificationTimedOut(){
uint id = m_timeout_order.takeFirst();
m_timeouts.take(id)->deleteLater();
if(activeNotifications.contains(id)){
Notification n = activeNotifications.take(id);
if(m_activeNotifications.contains(id)){
Notification n = m_activeNotifications.take(id);
snore()->closeNotification(n,NotificationEnums::CloseReasons::TIMED_OUT);
}
}

View File

@ -39,7 +39,7 @@ public:
const QString &name() const;
protected:
QHash<uint,Notification> activeNotifications;
QHash<uint,Notification> m_activeNotifications;
void startTimeout(uint id,int timeout);
private slots:
void notificationTimedOut();

View File

@ -4,3 +4,4 @@ add_subdirectory(freedesktop)
add_subdirectory(snarl)
add_subdirectory(growl)
add_subdirectory(trayicon)
add_subdirectory(snoretoast)

View File

@ -75,12 +75,12 @@ uint FreedesktopBackend::notify ( Notification noti )
if(replyMsg.type() == QDBusMessage::ReplyMessage){
id= replyMsg.arguments().at(0).toUInt();
qDebug()<<"DBUS_ID"<<id;
activeNotifications[id] = noti;
m_activeNotifications[id] = noti;
}
return id;
}
void FreedesktopBackend::actionInvoked(const uint &id, const QString &actionID){
Notification noti = activeNotifications[id];
Notification noti = m_activeNotifications[id];
if(noti.id() == 0)
return;
qDebug() <<"Action"<<id<<"|"<<actionID ;
@ -90,7 +90,7 @@ void FreedesktopBackend::actionInvoked(const uint &id, const QString &actionID){
void FreedesktopBackend::closeNotification ( Notification notification )
{
activeNotifications.remove(notification.id());
m_activeNotifications.remove(notification.id());
QDBusMessage message = QDBusMessage::createMethodCall(dbusServiceName, dbusPath, dbusInterfaceName,"CloseNotification");
QVariantList args;
args<<notification.id();
@ -105,7 +105,7 @@ void FreedesktopBackend::closed ( const uint &id,const uint &reason )
qDebug() <<"Closed"<<id<<"|"<<reason;
if(id == 0)
return;
Notification noti = activeNotifications.take(id);
Notification noti = m_activeNotifications.take(id);
snore()->closeNotification ( noti ,QFlag(reason));
}

View File

@ -79,7 +79,7 @@ uint Growl::notify(Notification notification){
Notification::toPlainText(notification.title()).toUtf8().constData(),
Notification::toPlainText(notification.text()).toUtf8().constData(),
notification.icon().localUrl().isEmpty()?NULL:notification.icon().localUrl().toUtf8().constData(),NULL,"1");
activeNotifications.insert(m_id,notification);
m_activeNotifications.insert(m_id,notification);
}catch(const std::exception& e){
qDebug()<<"Growl:"<<e.what();
@ -93,7 +93,7 @@ void Growl::closeNotification(Notification notification){
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());
Notification n = s_instance->activeNotifications.take(id);
Notification n = s_instance->m_activeNotifications.take(id);
NotificationEnums::CloseReasons::closeReasons r = NotificationEnums::CloseReasons::NONE;
if(reason == "TIMEDOUT")
r = NotificationEnums::CloseReasons::TIMED_OUT;

View File

@ -58,8 +58,8 @@ public:
int action = msg->wParam & 0xffff;
int data = (msg->wParam & 0xffffffff) >> 16;
uint notificationID = msg->lParam;
qDebug()<<"_snarl->activeNotifications"<<m_snarl->activeNotifications.keys();
Notification notification(m_snarl->activeNotifications[notificationID]);
qDebug()<<"_snarl->activeNotifications"<<m_snarl->m_activeNotifications.keys();
Notification notification(m_snarl->m_activeNotifications[notificationID]);
qDebug()<<"recived a Snarl callback id:"<<notificationID<<"action:"<<action<<"data:"<<data;
NotificationEnums::CloseReasons::closeReasons reason = NotificationEnums::CloseReasons::NONE;
switch(action){
@ -84,7 +84,7 @@ public:
break;
case SnarlEnums::SnarlUserBack:
qDebug()<<"Snalr user has returned";
m_snarl->activeNotifications.clear();
m_snarl->m_activeNotifications.clear();
m_snarl->m_away = false;
break;
default:
@ -191,7 +191,7 @@ uint SnarlBackend::notify(Notification notification){
}
//add ack stuff
if(!m_away)
activeNotifications[id] = notification;
m_activeNotifications[id] = notification;
}else{
//update message
snarlInterface->Update(notification.id(),
@ -209,7 +209,7 @@ uint SnarlBackend::notify(Notification notification){
void SnarlBackend::closeNotification(Notification notification){
m_defautSnarlinetrface->Hide(notification.id());
activeNotifications.remove(notification.id());
m_activeNotifications.remove(notification.id());
}
#include "snarl.moc"

View File

@ -0,0 +1,12 @@
if(WIN32)
message(STATUS "Adding SnoreToast notification backend")
set( TOASTER_SRC
snoretoast.cpp
)
add_library(snoretoast MODULE ${TOASTER_SRC} )
target_link_libraries(snoretoast snorecore ${QT_QTCORE_LIBRARY} )
install(TARGETS snoretoast ${SNORE_BACKEND_INSTALL_PATH})
endif(WIN32)

View File

@ -0,0 +1,112 @@
#include "snoretoast.h"
#include "core/snore.h"
#include "core/plugins/plugins.h"
#include "core/plugins/snorebackend.h"
#include <QDebug>
#include <QDir>
#include <QProcess>
#include <QSysInfo>
#include <windows.h>
using namespace Snore;
Q_EXPORT_PLUGIN2(snoretoast,SnoreToast)
SnoreToast::SnoreToast():
SnoreBackend("SnoreToast")
{
}
SnoreToast::~SnoreToast()
{
}
bool SnoreToast::init(SnoreCore *snore)
{
if(QSysInfo::windowsVersion() != QSysInfo::WV_WINDOWS8)
{
return false;
}
return SnoreBackend::init(snore);
}
void SnoreToast::registerApplication(Application *application)
{
Q_UNUSED(application)
}
void SnoreToast::unregisterApplication(Application *application)
{
Q_UNUSED(application)
}
uint SnoreToast::notify(Notification notification)
{
QProcess *p = new QProcess(this);
p->setProcessChannelMode(QProcess::MergedChannels);
connect(p,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(slotToastNotificationClosed(int,QProcess::ExitStatus)));
connect(qApp,SIGNAL(aboutToQuit()),p,SLOT(kill()));
connect(notification.data(),SIGNAL(destroyed()),p,SLOT(kill()));
QStringList arguements;
arguements << "-t"
<< Notification::toPlainText(notification.title())
<< "-m"
<< Notification::toPlainText(notification.text())
<< "-p"
// << notification.icon().isLocalFile()?QDir::toNativeSeparators(notification.icon().localUrl()):notification.icon().url()
<< QDir::toNativeSeparators(notification.icon().localUrl())
<< "-w";
qDebug() << "SnoreToast" << arguements;
p->start("SnoreToast", arguements);
uint id = p->pid()->dwProcessId;
p->setProperty("SNORE_NOTIFICATION_ID",id);
m_activeNotifications[id] = notification;
return id;
}
void SnoreToast::closeNotification(Notification notification)
{
Q_UNUSED(notification)
}
void SnoreToast::slotToastNotificationClosed(int code, QProcess::ExitStatus)
{
QProcess *p = qobject_cast<QProcess*>(sender());
Notification n = m_activeNotifications.take(p->property("SNORE_NOTIFICATION_ID").toUInt());
NotificationEnums::CloseReasons::closeReason reason = NotificationEnums::CloseReasons::CLOSED;
switch(code)
{
case 0:
reason = NotificationEnums::CloseReasons::CLOSED;
n.setActionInvoked(n.actions().begin().key());
snore()->notificationActionInvoked(n);
break;
case 1:
//hidden;
break;
case 2:
reason = NotificationEnums::CloseReasons::DISMISSED;
break;
case 3:
reason = NotificationEnums::CloseReasons::TIMED_OUT;
break;
case -1:
//failed
break;
}
snore()->closeNotification(n,reason);
}
#include "snoretoast.moc"

View File

@ -0,0 +1,29 @@
#ifndef TOASTER_H
#define TOASTER_H
#include "core/plugins/snorebackend.h"
class SnoreToast : public Snore::SnoreBackend
{
Q_OBJECT
Q_INTERFACES(Snore::SnoreBackend)
public:
SnoreToast();
~SnoreToast();
bool init(Snore::SnoreCore *snore);
// SnoreBackend interface
public slots:
void registerApplication(Snore::Application *application);
void unregisterApplication(Snore::Application *application);
uint notify(Snore::Notification notification);
void closeNotification(Snore::Notification notification);
private slots:
void slotToastNotificationClosed(int code, QProcess::ExitStatus);
};
#endif // TOASTER_H

View File

@ -0,0 +1,29 @@
#ifndef TOASTER_H
#define TOASTER_H
#include "core/plugins/snorebackend.h"
class SnoreToast : public Snore::SnoreBackend
{
Q_OBJECT
Q_INTERFACES(Snore::SnoreBackend)
public:
SnoreToast();
~SnoreToast();
bool init(Snore::SnoreCore *snore);
// SnoreBackend interface
public slots:
void registerApplication(Snore::Application *application);
void unregisterApplication(Snore::Application *application);
uint notify(Snore::Notification notification);
void closeNotification(Snore::Notification notification);
private slots:
void slotToastNotificationClosed(int code, QProcess::ExitStatus);
};
#endif // TOASTER_H

View File

@ -64,14 +64,14 @@ void TrayIconNotifer::displayNotification(){
qDebug()<<"taking"<<notification.title();
m_displayed = notification.id();
activeNotifications.insert(notification.id(),notification);
m_activeNotifications.insert(notification.id(),notification);
m_trayIcon->showMessage ( Notification::toPlainText(notification.title()),Notification::toPlainText(notification.text()),QSystemTrayIcon::NoIcon,notification.timeout() *1000 );
m_lastNotify.restart();
}
void TrayIconNotifer::closeNotification(){
if(activeNotifications.contains(m_displayed)){
Notification noti = activeNotifications.take(m_displayed);
if(m_activeNotifications.contains(m_displayed)){
Notification noti = m_activeNotifications.take(m_displayed);
snore()->closeNotification(noti,NotificationEnums::CloseReasons::TIMED_OUT);
}
displayNotification();
@ -79,8 +79,8 @@ void TrayIconNotifer::closeNotification(){
void TrayIconNotifer::actionInvoked(){
qDebug()<<"Traicon invoked"<<m_displayed;
if(activeNotifications.contains(m_displayed)){
Notification noti = activeNotifications.take(m_displayed);
if(m_activeNotifications.contains(m_displayed)){
Notification noti = m_activeNotifications.take(m_displayed);
if(noti.actions().isEmpty()){
noti.setActionInvoked(noti.actions().keys().first());
snore()->notificationActionInvoked(noti);

View File

@ -57,8 +57,8 @@ void FreedesktopFrontend::actionInvoked(Notification notification) {
void FreedesktopFrontend::notificationClosed(Notification notification) {
qDebug()<<"Closing Dbus notification"<<notification.id()<<"reason:"<<(int)notification.closeReason();
activeNotifications.remove(notification.id());
qDebug()<<"Active Dbus Notifications"<<activeNotifications.keys();
m_activeNotifications.remove(notification.id());
qDebug()<<"Active Dbus Notifications"<<m_activeNotifications.keys();
emit NotificationClosed(notification.id(),notification.closeReason());
}
@ -99,7 +99,7 @@ uint FreedesktopFrontend::Notify(const QString &app_name, uint replaces_id,
}
snore()->broadcastNotification(noti);
activeNotifications[noti.id()] = noti;
m_activeNotifications[noti.id()] = noti;
startTimeout(noti.id(),noti.timeout());
return noti.id();
}
@ -107,8 +107,8 @@ uint FreedesktopFrontend::Notify(const QString &app_name, uint replaces_id,
void FreedesktopFrontend::CloseNotification(uint id){
Notification noti = activeNotifications.take(id);
qDebug()<<"Active Dbus Notifications"<<activeNotifications.keys();
Notification noti = m_activeNotifications.take(id);
qDebug()<<"Active Dbus Notifications"<<m_activeNotifications.keys();
snore()->closeNotification(noti,NotificationEnums::CloseReasons::TIMED_OUT);
}