00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "knotifyclient.h"
00022
00023
#include <qdatastream.h>
00024
#include <qptrstack.h>
00025
00026
#include <kapplication.h>
00027
#include <kstandarddirs.h>
00028
#include <kapplication.h>
00029
#include <kconfig.h>
00030
#include <dcopclient.h>
00031
#include <kdebug.h>
00032
#include <kstaticdeleter.h>
00033
00034
static const char daemonName[] =
"knotify";
00035
00036
static int sendNotifyEvent(
const QString &message,
const QString &text,
00037
int present,
int level,
const QString &sound,
00038
const QString &file,
int winId )
00039 {
00040
if (!kapp)
return 0;
00041
00042
DCOPClient *client=kapp->dcopClient();
00043
if (!client->
isAttached())
00044 {
00045 client->
attach();
00046
if (!client->
isAttached())
00047
return 0;
00048 }
00049
00050
int uniqueId = kMax( 1, kapp->random() );
00051
00052
00053
QWidget* widget =
QWidget::find( winId );
00054
if( widget )
00055 winId = widget->
topLevelWidget()->winId();
00056
00057
QByteArray data;
00058
QDataStream ds(data, IO_WriteOnly);
00059
QString appname =
KNotifyClient::instance()->
instanceName();
00060 ds << message << appname << text << sound << file << present << level
00061 << winId << uniqueId;
00062
00063
if ( !
KNotifyClient::startDaemon() )
00064
return 0;
00065
00066
if ( client->
send(daemonName,
"Notify",
"notify(QString,QString,QString,QString,QString,int,int,int,int)", data) )
00067 {
00068
return uniqueId;
00069 }
00070
00071
return 0;
00072 }
00073
00074 int KNotifyClient::event( StandardEvent type,
const QString& text )
00075 {
00076
return event( 0, type, text );
00077 }
00078
00079 int KNotifyClient::event(
const QString &message,
const QString &text)
00080 {
00081
return event(0, message, text);
00082 }
00083
00084 int KNotifyClient::userEvent(
const QString &text,
int present,
int level,
00085
const QString &sound,
const QString &file)
00086 {
00087
return userEvent( 0, text, present, level, sound, file );
00088 }
00089
00090
00091 int KNotifyClient::event(
int winId, StandardEvent type,
const QString& text )
00092 {
00093
QString message;
00094
switch ( type ) {
00095
case cannotOpenFile:
00096 message = QString::fromLatin1(
"cannotopenfile");
00097
break;
00098
case warning:
00099 message = QString::fromLatin1(
"warning");
00100
break;
00101
case fatalError:
00102 message = QString::fromLatin1(
"fatalerror");
00103
break;
00104
case catastrophe:
00105 message = QString::fromLatin1(
"catastrophe");
00106
break;
00107
case notification:
00108
default:
00109 message = QString::fromLatin1(
"notification");
00110
break;
00111 }
00112
00113
return sendNotifyEvent( message, text, Default, Default,
00114 QString::null, QString::null, winId );
00115 }
00116
00117 int KNotifyClient::event(
int winId,
const QString &message,
00118
const QString &text)
00119 {
00120
return sendNotifyEvent(message, text, Default, Default, QString::null, QString::null, winId);
00121 }
00122
00123 int KNotifyClient::userEvent(
int winId,
const QString &text,
int present,
00124
int level,
00125
const QString &sound,
const QString &file)
00126 {
00127
return sendNotifyEvent(QString::null, text, present, level, sound, file, winId);
00128 }
00129
00130 int KNotifyClient::getPresentation(
const QString &eventname)
00131 {
00132
int present;
00133
if (eventname.
isEmpty())
return Default;
00134
00135
KConfig eventsfile( KNotifyClient::instance()->instanceName()+
".eventsrc",
true,
false);
00136 eventsfile.
setGroup(eventname);
00137
00138 present=eventsfile.
readNumEntry(
"presentation", -1);
00139
00140
return present;
00141 }
00142
00143 QString KNotifyClient::getFile(
const QString &eventname,
int present)
00144 {
00145
if (eventname.
isEmpty())
return QString::null;
00146
00147
KConfig eventsfile( KNotifyClient::instance()->instanceName()+
".eventsrc",
true,
false);
00148 eventsfile.
setGroup(eventname);
00149
00150
switch (present)
00151 {
00152
case (Sound):
00153
return eventsfile.
readPathEntry(
"soundfile");
00154
case (Logfile):
00155
return eventsfile.
readPathEntry(
"logfile");
00156 }
00157
00158
return QString::null;
00159 }
00160
00161 int KNotifyClient::getDefaultPresentation(
const QString &eventname)
00162 {
00163
int present;
00164
if (eventname.
isEmpty())
return Default;
00165
00166
KConfig eventsfile( KNotifyClient::instance()->instanceName()+
"/eventsrc",
true,
false,
"data");
00167 eventsfile.
setGroup(eventname);
00168
00169 present=eventsfile.
readNumEntry(
"default_presentation", -1);
00170
00171
return present;
00172 }
00173
00174 QString KNotifyClient::getDefaultFile(
const QString &eventname,
int present)
00175 {
00176
if (eventname.
isEmpty())
return QString::null;
00177
00178
KConfig eventsfile( KNotifyClient::instance()->instanceName()+
"/eventsrc",
true,
false,
"data");
00179 eventsfile.
setGroup(eventname);
00180
00181
switch (present)
00182 {
00183
case (Sound):
00184
return eventsfile.
readPathEntry(
"default_sound");
00185
case (Logfile):
00186
return eventsfile.
readPathEntry(
"default_logfile");
00187 }
00188
00189
return QString::null;
00190 }
00191
00192 bool KNotifyClient::startDaemon()
00193 {
00194
static bool firstTry =
true;
00195
if (firstTry && !kapp->dcopClient()->isApplicationRegistered(daemonName)) {
00196 firstTry =
false;
00197
return KApplication::startServiceByDesktopName(daemonName) == 0;
00198 }
00199
return true;
00200 }
00201
00202
00203 void KNotifyClient::beep(
const QString& reason)
00204 {
00205
if ( !kapp ||
KNotifyClient::Instance::currentInstance()->
useSystemBell() ) {
00206
QApplication::beep();
00207
return;
00208 }
00209
00210
DCOPClient *client=kapp->dcopClient();
00211
if (!client->
isAttached())
00212 {
00213 client->
attach();
00214
if (!client->
isAttached() || !client->
isApplicationRegistered(daemonName))
00215 {
00216
QApplication::beep();
00217
return;
00218 }
00219 }
00220
00221
if ( client->
isApplicationRegistered(
"kaccess" ) )
00222 {
00223
QApplication::beep();
00224
return;
00225 }
00226
00227
KNotifyClient::event(KNotifyClient::notification, reason);
00228 }
00229
00230
00231 KInstance *
KNotifyClient::instance() {
00232
return KNotifyClient::Instance::current();
00233 }
00234
00235
00236
class KNotifyClient::InstanceStack
00237 {
00238
public:
00239 InstanceStack() { m_defaultInstance = 0; }
00240
virtual ~InstanceStack() {
delete m_defaultInstance; }
00241
void push(Instance *instance) { m_instances.push(instance); }
00242
00243
void pop(Instance *instance)
00244 {
00245
if (m_instances.top() ==
instance)
00246 m_instances.pop();
00247
else if (!m_instances.isEmpty())
00248 {
00249 kdWarning(160) <<
"Tried to remove an Instance that is not the current," <<
endl;
00250 kdWarning(160) <<
"Resetting to the main KApplication." <<
endl;
00251 m_instances.clear();
00252 }
00253
else
00254 kdWarning(160) <<
"Tried to remove an Instance, but the stack was empty." <<
endl;
00255 }
00256
00257 Instance *currentInstance()
00258 {
00259
if (m_instances.isEmpty())
00260 {
00261 m_defaultInstance =
new Instance(kapp);
00262 }
00263
return m_instances.top();
00264 }
00265
00266
private:
00267
QPtrStack<Instance> m_instances;
00268 Instance *m_defaultInstance;
00269 };
00270
00271 KNotifyClient::InstanceStack * KNotifyClient::Instance::s_instances = 0L;
00272
static KStaticDeleter<KNotifyClient::InstanceStack > instancesDeleter;
00273
00274
struct KNotifyClient::InstancePrivate
00275 {
00276
KInstance *
instance;
00277
bool useSystemBell;
00278 };
00279
00280 KNotifyClient::Instance::Instance(
KInstance *instance)
00281 {
00282 d =
new InstancePrivate;
00283 d->instance =
instance;
00284 instances()->push(
this);
00285
00286
KConfig *config =
instance->
config();
00287
KConfigGroupSaver cs( config,
"General" );
00288 d->useSystemBell = config->
readBoolEntry(
"UseSystemBell",
false );
00289 }
00290
00291 KNotifyClient::Instance::~Instance()
00292 {
00293
if (s_instances)
00294 s_instances->pop(
this);
00295
delete d;
00296 }
00297
00298 KNotifyClient::InstanceStack *KNotifyClient::Instance::instances()
00299 {
00300
if (!s_instances)
00301 instancesDeleter.setObject(s_instances,
new InstanceStack);
00302
return s_instances;
00303 }
00304
00305 bool KNotifyClient::Instance::useSystemBell()
const
00306
{
00307
return d->useSystemBell;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 KNotifyClient::Instance *
KNotifyClient::Instance::currentInstance()
00320 {
00321
return instances()->currentInstance();
00322 }
00323
00324 KInstance *
KNotifyClient::Instance::current()
00325 {
00326
return currentInstance()->
d->instance;
00327 }