mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 18:32:50 +00:00
316 lines
8.1 KiB
C++
316 lines
8.1 KiB
C++
/*
|
|
Copyright (C) 2005-2009 by Olivier Goffart <ogoffart at kde.org>
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
#include "knotify.h"
|
|
|
|
// KDE headers
|
|
#include <kapplication.h>
|
|
#include <kconfig.h>
|
|
#include <kdebug.h>
|
|
#include <kglobal.h>
|
|
#include <klocale.h>
|
|
#include <kservicetypetrader.h>
|
|
|
|
#include <config-runtime.h>
|
|
|
|
#include "knotifyconfig.h"
|
|
#include "ksolidnotify.h"
|
|
#include "notifybysound.h"
|
|
#include "notifybypopup.h"
|
|
#include "notifybyexecute.h"
|
|
#include "notifybylogfile.h"
|
|
#include "notifybytaskbar.h"
|
|
#include "notifybyktts.h"
|
|
|
|
|
|
|
|
KNotify::KNotify( QObject *parent )
|
|
: QObject( parent ),
|
|
m_counter(0)
|
|
{
|
|
loadConfig();
|
|
(void)new KNotifyAdaptor(this);
|
|
(void)new KSolidNotify(this);
|
|
QDBusConnection::sessionBus().registerObject("/Notify", this, QDBusConnection::ExportAdaptors
|
|
/*| QDBusConnection::ExportScriptableSlots | QDBusConnection::ExportScriptableSignals*/ );
|
|
}
|
|
|
|
KNotify::~KNotify()
|
|
{
|
|
qDeleteAll(m_notifications);
|
|
}
|
|
|
|
|
|
void KNotify::loadConfig()
|
|
{
|
|
qDeleteAll(m_plugins);
|
|
m_plugins.clear();
|
|
addPlugin(new NotifyBySound(this));
|
|
addPlugin(new NotifyByPopup(this));
|
|
addPlugin(new NotifyByExecute(this));
|
|
addPlugin(new NotifyByLogfile(this));
|
|
addPlugin(new NotifyByTaskbar(this));
|
|
addPlugin(new NotifyByKTTS(this));
|
|
|
|
KService::List offers = KServiceTypeTrader::self()->query("KNotify/NotifyMethod");
|
|
|
|
QVariantList args;
|
|
QString error;
|
|
|
|
foreach (const KService::Ptr service, offers)
|
|
{
|
|
KNotifyPlugin *plugin = service->createInstance<KNotifyPlugin>(this, args, &error);
|
|
if (plugin)
|
|
{
|
|
addPlugin(plugin);
|
|
}
|
|
else
|
|
{
|
|
kDebug() << "Could not load plugin" << service->name() << "due to:" << error;
|
|
}
|
|
}
|
|
}
|
|
|
|
void KNotify::addPlugin( KNotifyPlugin * p )
|
|
{
|
|
m_plugins[p->optionName()]=p;
|
|
connect(p,SIGNAL(finished( int )) , this , SLOT(slotPluginFinished( int ) ));
|
|
connect(p,SIGNAL(actionInvoked( int , int )) , this , SIGNAL(notificationActivated( int , int ) ));
|
|
}
|
|
|
|
|
|
|
|
void KNotify::reconfigure()
|
|
{
|
|
KGlobal::config()->reparseConfiguration();
|
|
KNotifyConfig::reparseConfiguration();
|
|
loadConfig();
|
|
}
|
|
|
|
void KNotify::closeNotification(int id)
|
|
{
|
|
if(!m_notifications.contains(id))
|
|
return;
|
|
Event *e=m_notifications[id];
|
|
|
|
kDebug() << e->id << " ref=" << e->ref;
|
|
|
|
//this has to be called before plugin->close or we will get double deletion because of slotPluginFinished
|
|
m_notifications.remove(id);
|
|
|
|
if(e->ref>0)
|
|
{
|
|
e->ref++;
|
|
KNotifyPlugin *plugin;
|
|
foreach(plugin , m_plugins)
|
|
{
|
|
plugin->close( id );
|
|
}
|
|
}
|
|
notificationClosed(id);
|
|
delete e;
|
|
}
|
|
|
|
int KNotify::event( const QString & event, const QString & appname, const ContextList & contexts, const QString & title, const QString & text, const KNotifyImage & image, const QStringList & actions, int timeout, WId winId )
|
|
{
|
|
m_counter++;
|
|
Event *e=new Event(appname , contexts , event );
|
|
e->id = m_counter;
|
|
e->ref = 1;
|
|
|
|
e->config.title=title;
|
|
e->config.text=text;
|
|
e->config.actions=actions;
|
|
e->config.image=image;
|
|
e->config.timeout=timeout;
|
|
e->config.winId=(WId)winId;
|
|
|
|
m_notifications.insert(m_counter,e);
|
|
emitEvent(e);
|
|
|
|
e->ref--;
|
|
kDebug() << e->id << " ref=" << e->ref;
|
|
if(e->ref==0)
|
|
{
|
|
m_notifications.remove(e->id);
|
|
delete e;
|
|
return 0;
|
|
}
|
|
return m_counter;
|
|
}
|
|
|
|
void KNotify::update(int id, const QString &title, const QString &text, const KNotifyImage& image, const QStringList& actions)
|
|
{
|
|
if(!m_notifications.contains(id))
|
|
return;
|
|
|
|
Event *e=m_notifications[id];
|
|
|
|
e->config.title=title;
|
|
e->config.text=text;
|
|
e->config.image = image;
|
|
e->config.actions = actions;
|
|
|
|
foreach(KNotifyPlugin *p, m_plugins)
|
|
{
|
|
p->update(id, &e->config);
|
|
}
|
|
}
|
|
void KNotify::reemit(int id, const ContextList& contexts)
|
|
{
|
|
if(!m_notifications.contains(id))
|
|
return;
|
|
Event *e=m_notifications[id];
|
|
e->config.contexts=contexts;
|
|
|
|
emitEvent(e);
|
|
}
|
|
|
|
void KNotify::emitEvent(Event *e)
|
|
{
|
|
QString presentstring=e->config.readEntry("Action");
|
|
QStringList presents=presentstring.split ('|');
|
|
|
|
if (!e->config.contexts.isEmpty() && !presents.first().isEmpty())
|
|
{
|
|
//Check whether the present actions are absolute, relative or invalid
|
|
bool relative = presents.first().startsWith('+') || presents.first().startsWith('-');
|
|
bool valid = true;
|
|
foreach (const QString & presentAction, presents)
|
|
valid &= ((presentAction.startsWith('+') || presentAction.startsWith('-')) == relative);
|
|
if (!valid)
|
|
{
|
|
kDebug() << "Context " << e->config.contexts << "present actions are invalid! Fallback to default present actions";
|
|
Event defaultEvent = Event(e->config.appname, ContextList(), e->config.eventid);
|
|
QString defaultPresentstring=defaultEvent.config.readEntry("Action");
|
|
presents = defaultPresentstring.split ('|');
|
|
} else if (relative)
|
|
{
|
|
// Obtain the list of present actions without context
|
|
Event noContextEvent = Event(e->config.appname, ContextList(), e->config.eventid);
|
|
QString noContextPresentstring = noContextEvent.config.readEntry("Action");
|
|
QSet<QString> noContextPresents = noContextPresentstring.split ('|').toSet();
|
|
foreach (const QString & presentAction, presents)
|
|
{
|
|
if (presentAction.startsWith('+'))
|
|
noContextPresents << presentAction.mid(1);
|
|
else
|
|
noContextPresents.remove(presentAction.mid(1));
|
|
}
|
|
presents = noContextPresents.toList();
|
|
}
|
|
}
|
|
|
|
foreach(const QString & action , presents)
|
|
{
|
|
if(!m_plugins.contains(action))
|
|
continue;
|
|
KNotifyPlugin *p=m_plugins[action];
|
|
e->ref++;
|
|
p->notify(e->id,&e->config);
|
|
}
|
|
}
|
|
|
|
void KNotify::slotPluginFinished( int id )
|
|
{
|
|
if(!m_notifications.contains(id))
|
|
return;
|
|
Event *e=m_notifications[id];
|
|
kDebug() << e->id << " ref=" << e->ref ;
|
|
e->ref--;
|
|
if(e->ref==0)
|
|
closeNotification( id );
|
|
}
|
|
|
|
KNotifyAdaptor::KNotifyAdaptor(QObject *parent)
|
|
: QDBusAbstractAdaptor(parent)
|
|
{
|
|
setAutoRelaySignals(true);
|
|
}
|
|
|
|
void KNotifyAdaptor::reconfigure()
|
|
{
|
|
static_cast<KNotify *>(parent())->reconfigure();
|
|
}
|
|
|
|
void KNotifyAdaptor::closeNotification(int id)
|
|
{
|
|
static_cast<KNotify *>(parent())->closeNotification(id);
|
|
}
|
|
|
|
int KNotifyAdaptor::event(const QString &event, const QString &fromApp, const QVariantList& contexts,
|
|
const QString &title, const QString &text, const QByteArray& image, const QStringList& actions,
|
|
int timeout, qlonglong winId)
|
|
// const QDBusMessage & , int _return )
|
|
|
|
{
|
|
/* I'm not sure this is the right way to read a a(ss) type, but it seems to work */
|
|
ContextList contextlist;
|
|
QString context_key;
|
|
foreach( const QVariant &v , contexts)
|
|
{
|
|
/* this code doesn't work
|
|
QVariantList vl=v.toList();
|
|
if(vl.count() != 2)
|
|
{
|
|
kWarning() << "Bad structure passed as argument" ;
|
|
continue;
|
|
}
|
|
contextlist << qMakePair(vl[0].toString() , vl[1].toString());*/
|
|
QString s=v.toString();
|
|
if(context_key.isEmpty())
|
|
context_key=s;
|
|
else {
|
|
contextlist << qMakePair(context_key , s);
|
|
context_key = "";
|
|
}
|
|
}
|
|
|
|
return static_cast<KNotify *>(parent())->event(event, fromApp, contextlist, title, text, image, actions, timeout, WId(winId));
|
|
}
|
|
|
|
void KNotifyAdaptor::reemit(int id, const QVariantList& contexts)
|
|
{
|
|
ContextList contextlist;
|
|
QString context_key;
|
|
foreach( const QVariant &v , contexts)
|
|
{
|
|
QString s=v.toString();
|
|
if(context_key.isEmpty())
|
|
context_key=s;
|
|
else {
|
|
contextlist << qMakePair(context_key , s);
|
|
context_key = "";
|
|
}
|
|
}
|
|
static_cast<KNotify *>(parent())->reemit(id, contextlist);
|
|
}
|
|
|
|
|
|
void KNotifyAdaptor::update(int id, const QString &title, const QString &text, const QByteArray& image, const QStringList& actions )
|
|
{
|
|
static_cast<KNotify *>(parent())->update(id, title, text, image, actions);
|
|
}
|
|
|
|
#include "moc_knotify.cpp"
|
|
|
|
// vim: sw=4 sts=4 ts=8 et
|
|
|
|
|