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