kde-workspace/knotify/knotify.cpp
Ivailo Monev f39596ee19 generic: review configuration checks
since kde-runtime was merged into kde-workspace some checks definitions are
duplicated in config-runtime headers thus it is removed.

missing function and header checks were added, most of which also missing in
kde-runtime and kde-workspace so that is by no means mistake made during the
merge.

the check for libkstat for Solaris is actually done via /dev/kstat existence
check from ksysguardd/Solaris/Solaris.cmake.

Signed-off-by: Ivailo Monev <xakepa10@laimg.moc>
2020-02-24 20:10:10 +00:00

315 lines
8 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-workspace.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++;
foreach(KNotifyPlugin *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