00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "knotification.h"
00029 #include "knotificationmanager_p.h"
00030
00031 #include <kmessagebox.h>
00032 #include <klocale.h>
00033 #include <kiconloader.h>
00034 #include <kconfig.h>
00035 #include <kpassivepopup.h>
00036 #include <kdialog.h>
00037 #include <kmacroexpander.h>
00038 #include <kwindowsystem.h>
00039 #include <kdebug.h>
00040 #include <kvbox.h>
00041 #include <kapplication.h>
00042
00043 #include <QMap>
00044 #include <QPixmap>
00045 #include <QPointer>
00046 #include <QLabel>
00047 #include <QTimer>
00048 #include <QTabWidget>
00049 #include <QFile>
00050 #include <QStringList>
00051 #include <QTextStream>
00052 #include <QDateTime>
00053 #include <QDBusError>
00054
00055 struct KNotification::Private
00056 {
00057 QString eventId;
00058 int id;
00059 int ref;
00060
00061 QWidget *widget;
00062 QString title;
00063 QString text;
00064 QStringList actions;
00065 QPixmap pixmap;
00066 ContextList contexts;
00067 NotificationFlags flags;
00068 KComponentData componentData;
00069
00070 QTimer updateTimer;
00071
00072 Private() : id(0), ref(1), widget(0l) {}
00078 static void raiseWidget(QWidget *w);
00079 };
00080
00081 KNotification::KNotification(const QString& eventId, QWidget *parent, const NotificationFlags& flags) :
00082 QObject(parent) , d(new Private)
00083 {
00084 d->eventId=eventId;
00085 d->flags=flags;
00086 setWidget(parent);
00087 connect(&d->updateTimer,SIGNAL(timeout()), this, SLOT(update()));
00088 d->updateTimer.setSingleShot(true);
00089 d->updateTimer.setInterval(100);
00090 }
00091
00092 KNotification::~KNotification()
00093 {
00094 kDebug( 299 ) << d->id;
00095 if(d ->id > 0)
00096 KNotificationManager::self()->close( d->id );
00097 delete d;
00098 }
00099
00100 QString KNotification::eventId() const
00101 {
00102 return d->eventId;
00103 }
00104
00105 QString KNotification::title() const
00106 {
00107 return d->title;
00108 }
00109
00110 QString KNotification::text() const
00111 {
00112 return d->text;
00113 }
00114
00115 QWidget *KNotification::widget() const
00116 {
00117 return d->widget;
00118 }
00119
00120 void KNotification::setWidget(QWidget *wid)
00121 {
00122 d->widget = wid;
00123 setParent(wid);
00124 if ( wid && d->flags & CloseWhenWidgetActivated ) {
00125 wid->installEventFilter(this);
00126 }
00127 }
00128
00129 void KNotification::setTitle(const QString &title)
00130 {
00131 d->title = title;
00132 if(d->id > 0)
00133 d->updateTimer.start();
00134 }
00135
00136 void KNotification::setText(const QString &text)
00137 {
00138 d->text=text;
00139 if(d->id > 0)
00140 d->updateTimer.start();
00141 }
00142
00143 QPixmap KNotification::pixmap() const
00144 {
00145 return d->pixmap;
00146 }
00147
00148 void KNotification::setPixmap(const QPixmap &pix)
00149 {
00150 d->pixmap=pix;
00151 if(d->id > 0)
00152 d->updateTimer.start();
00153 }
00154
00155 QStringList KNotification::actions() const
00156 {
00157 return d->actions;
00158 }
00159
00160 void KNotification::setActions(const QStringList& as )
00161 {
00162 d->actions=as;
00163 if(d->id > 0)
00164 d->updateTimer.start();
00165 }
00166
00167 KNotification::ContextList KNotification::contexts() const
00168 {
00169 return d->contexts;
00170 }
00171
00172 void KNotification::setContexts( const KNotification::ContextList &contexts)
00173 {
00174 d->contexts=contexts;
00175 }
00176
00177 void KNotification::addContext( const KNotification::Context & context)
00178 {
00179 d->contexts << context;
00180 }
00181
00182 void KNotification::addContext( const QString & context_key, const QString & context_value )
00183 {
00184 d->contexts << qMakePair( context_key , context_value );
00185 }
00186
00187 KNotification::NotificationFlags KNotification::flags() const
00188 {
00189 return d->flags;
00190 }
00191
00192 void KNotification::setFlags(const NotificationFlags & flags)
00193 {
00194 d->flags=flags;
00195 }
00196
00197
00198 void KNotification::setComponentData(const KComponentData &c)
00199 {
00200 d->componentData = c;
00201 }
00202
00203 void KNotification::activate(unsigned int action)
00204 {
00205 switch (action)
00206 {
00207 case 0:
00208 emit activated();
00209 break;
00210 case 1:
00211 emit action1Activated();
00212 break;
00213 case 2:
00214 emit action2Activated();
00215 break;
00216 case 3:
00217 emit action3Activated();
00218 break;
00219 }
00220 emit activated(action);
00221 if(d->id != -1)
00222 deleteLater();
00223 d->id = -2;
00224 }
00225
00226
00227 void KNotification::close()
00228 {
00229 kDebug( 299 ) << d->id;
00230 if(d->id >= 0)
00231 KNotificationManager::self()->close( d->id );
00232 if(d->id != -1)
00233 deleteLater();
00234 d->id = -2;
00235 emit closed();
00236 }
00237
00238
00239 void KNotification::raiseWidget()
00240 {
00241 if ( !d->widget ) {
00242 return;
00243 }
00244
00245 Private::raiseWidget( d->widget );
00246 }
00247
00248
00249 void KNotification::Private::raiseWidget(QWidget *w)
00250 {
00251
00252 if(w->isTopLevel())
00253 {
00254 w->raise();
00255 #if defined(Q_WS_WIN) || defined(Q_WS_MAC)
00256 w->activateWindow();
00257 #else
00258 KWindowSystem::activateWindow( w->winId() );
00259 #endif
00260 }
00261 else
00262 {
00263 QWidget *pw=w->parentWidget();
00264 raiseWidget(pw);
00265
00266 if( QTabWidget *tab_widget=qobject_cast<QTabWidget*>(pw))
00267 {
00268 tab_widget->setCurrentIndex(tab_widget->indexOf(w));
00269 }
00270 }
00271 }
00272
00273
00274 KNotification *KNotification::event( const QString& eventid , const QString& text,
00275 const QPixmap& pixmap, QWidget *widget, const NotificationFlags &flags, const KComponentData &componentData)
00276 {
00277 KNotification *notify=new KNotification(eventid, widget, flags);
00278 notify->setText(text);
00279 notify->setPixmap(pixmap);
00280 notify->setComponentData(componentData);
00281
00282 QTimer::singleShot(0,notify,SLOT(sendEvent()));
00283
00284 return notify;
00285 }
00286
00287
00288 KNotification *KNotification::event( StandardEvent eventid , const QString& text,
00289 const QPixmap& pixmap, QWidget *widget, const NotificationFlags &flags)
00290 {
00291 QString message;
00292 switch ( eventid ) {
00293 case Warning:
00294 message = QLatin1String("warning");
00295 break;
00296 case Error:
00297 message = QLatin1String("fatalerror");
00298 break;
00299 case Catastrophe:
00300 message = QLatin1String("catastrophe");
00301 break;
00302 case Notification:
00303 default:
00304 message = QLatin1String("notification");
00305 break;
00306 }
00307 return event( message, text, pixmap, widget , flags | DefaultEvent );
00308 }
00309
00310 void KNotification::ref()
00311 {
00312 d->ref++;
00313 }
00314
00315 void KNotification::deref()
00316 {
00317 d->ref--;
00318 if(d->ref==0)
00319 close();
00320 }
00321
00322 void KNotification::beep( const QString & reason, QWidget * widget )
00323 {
00324 event( QLatin1String("beep"), reason, QPixmap(), widget , CloseOnTimeout | DefaultEvent );
00325 }
00326
00327 void KNotification::sendEvent()
00328 {
00329 if(d->id<=0)
00330 {
00331 QString appname;
00332
00333 if(d->flags & DefaultEvent)
00334 appname = QLatin1String("kde");
00335 else if(d->componentData.isValid()) {
00336 appname = d->componentData.componentName();
00337 } else {
00338 appname = KGlobal::mainComponent().componentName();
00339 }
00340
00341 if(!(d->flags & Persistent))
00342 {
00343 QTimer::singleShot(6*1000, this, SLOT(close()));
00344 }
00345 if (KNotificationManager::self()->notify( this , d->pixmap , d->actions , d->contexts , appname ))
00346 d->id = -1;
00347 }
00348 else
00349 {
00350 KNotificationManager::self()->reemit(this , d->id );
00351 }
00352 }
00353
00354 void KNotification::slotReceivedId(int id)
00355 {
00356 if(d->id == -2)
00357 {
00358 KNotificationManager::self()->close( id, true );
00359 deleteLater();
00360 return;
00361 }
00362 d->id=id;
00363 kDebug(299) << id;
00364 if(d->id>0)
00365 {
00366 KNotificationManager::self()->insert(this,d->id);
00367 }
00368 else
00369 {
00370
00371 QTimer::singleShot(0, this, SLOT(deref()));
00372 }
00373
00374 }
00375
00376 void KNotification::slotReceivedIdError(const QDBusError& error)
00377 {
00378 if(d->id == -2)
00379 {
00380 deleteLater();
00381 return;
00382 }
00383 kWarning(299) << "Error while contacting notify daemon" << error.message();
00384 d->id = -3;
00385 QTimer::singleShot(0, this, SLOT(deref()));
00386 }
00387
00388
00389 void KNotification::update()
00390 {
00391 KNotificationManager::self()->update(this, d->id);
00392 }
00393
00394 bool KNotification::eventFilter( QObject * watched, QEvent * event )
00395 {
00396 if( watched == d->widget )
00397 {
00398 if( event->type() == QEvent::WindowActivate )
00399 {
00400 if( d->flags & CloseWhenWidgetActivated )
00401 QTimer::singleShot(500, this, SLOT(close()));
00402 }
00403
00404 }
00405
00406 return false;
00407 }
00408
00409
00410 #include "knotification.moc"