KDEUI
knotification.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2005-2006 Olivier Goffart <ogoffart at kde.org> 00003 00004 code from KNotify/KNotifyClient 00005 Copyright (c) 1997 Christian Esken (esken@kde.org) 00006 2000 Charles Samuels (charles@kde.org) 00007 2000 Stefan Schimanski (1Stein@gmx.de) 00008 2000 Matthias Ettrich (ettrich@kde.org) 00009 2000 Waldo Bastian <bastian@kde.org> 00010 2000-2003 Carsten Pfeiffer <pfeiffer@kde.org> 00011 2005 Allan Sandfeld Jensen <kde@carewolf.com> 00012 00013 This library is free software; you can redistribute it and/or 00014 modify it under the terms of the GNU Library General Public 00015 License version 2 as published by the Free Software Foundation. 00016 00017 This library is distributed in the hope that it will be useful, 00018 but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00020 Library General Public License for more details. 00021 00022 You should have received a copy of the GNU Library General Public License 00023 along with this library; see the file COPYING.LIB. If not, write to 00024 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00025 Boston, MA 02110-1301, USA. 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 bool needUpdate; 00072 00073 Private() : id(0), ref(1), widget(0l), needUpdate(false) {} 00079 static void raiseWidget(QWidget *w); 00080 }; 00081 00082 KNotification::KNotification(const QString& eventId, QWidget *parent, const NotificationFlags& flags) : 00083 QObject(parent) , d(new Private) 00084 { 00085 d->eventId=eventId; 00086 d->flags=flags; 00087 setWidget(parent); 00088 connect(&d->updateTimer,SIGNAL(timeout()), this, SLOT(update())); 00089 d->updateTimer.setSingleShot(true); 00090 d->updateTimer.setInterval(100); 00091 } 00092 00093 KNotification::KNotification( 00094 const QString& eventId, 00095 const NotificationFlags& flags, 00096 QObject *parent) 00097 : QObject(parent), 00098 d(new Private) 00099 { 00100 d->eventId=eventId; 00101 d->flags=flags; 00102 connect(&d->updateTimer,SIGNAL(timeout()), this, SLOT(update())); 00103 d->updateTimer.setSingleShot(true); 00104 d->updateTimer.setInterval(100); 00105 } 00106 00107 00108 KNotification::~KNotification() 00109 { 00110 if(d ->id > 0) 00111 KNotificationManager::self()->close( d->id ); 00112 delete d; 00113 } 00114 00115 QString KNotification::eventId() const 00116 { 00117 return d->eventId; 00118 } 00119 00120 QString KNotification::title() const 00121 { 00122 return d->title; 00123 } 00124 00125 QString KNotification::text() const 00126 { 00127 return d->text; 00128 } 00129 00130 QWidget *KNotification::widget() const 00131 { 00132 return d->widget; 00133 } 00134 00135 void KNotification::setWidget(QWidget *wid) 00136 { 00137 d->widget = wid; 00138 setParent(wid); 00139 if ( wid && d->flags & CloseWhenWidgetActivated ) { 00140 wid->installEventFilter(this); 00141 } 00142 } 00143 00144 void KNotification::setTitle(const QString &title) 00145 { 00146 d->needUpdate = true; 00147 d->title = title; 00148 if(d->id > 0) 00149 d->updateTimer.start(); 00150 } 00151 00152 void KNotification::setText(const QString &text) 00153 { 00154 d->needUpdate = true; 00155 d->text=text; 00156 if(d->id > 0) 00157 d->updateTimer.start(); 00158 } 00159 00160 QPixmap KNotification::pixmap() const 00161 { 00162 return d->pixmap; 00163 } 00164 00165 void KNotification::setPixmap(const QPixmap &pix) 00166 { 00167 d->needUpdate = true; 00168 d->pixmap=pix; 00169 if(d->id > 0) 00170 d->updateTimer.start(); 00171 } 00172 00173 QStringList KNotification::actions() const 00174 { 00175 return d->actions; 00176 } 00177 00178 void KNotification::setActions(const QStringList& as ) 00179 { 00180 d->needUpdate = true; 00181 d->actions=as; 00182 if(d->id > 0) 00183 d->updateTimer.start(); 00184 } 00185 00186 KNotification::ContextList KNotification::contexts() const 00187 { 00188 return d->contexts; 00189 } 00190 00191 void KNotification::setContexts( const KNotification::ContextList &contexts) 00192 { 00193 d->contexts=contexts; 00194 } 00195 00196 void KNotification::addContext( const KNotification::Context & context) 00197 { 00198 d->contexts << context; 00199 } 00200 00201 void KNotification::addContext( const QString & context_key, const QString & context_value ) 00202 { 00203 d->contexts << qMakePair( context_key , context_value ); 00204 } 00205 00206 KNotification::NotificationFlags KNotification::flags() const 00207 { 00208 return d->flags; 00209 } 00210 00211 void KNotification::setFlags(const NotificationFlags & flags) 00212 { 00213 d->flags=flags; 00214 } 00215 00216 00217 void KNotification::setComponentData(const KComponentData &c) 00218 { 00219 d->componentData = c; 00220 } 00221 00222 void KNotification::activate(unsigned int action) 00223 { 00224 switch (action) 00225 { 00226 case 0: 00227 emit activated(); 00228 break; 00229 case 1: 00230 emit action1Activated(); 00231 break; 00232 case 2: 00233 emit action2Activated(); 00234 break; 00235 case 3: 00236 emit action3Activated(); 00237 break; 00238 } 00239 emit activated(action); 00240 if(d->id != -1) 00241 deleteLater(); 00242 d->id = -2; 00243 } 00244 00245 00246 void KNotification::close() 00247 { 00248 if(d->id >= 0) 00249 KNotificationManager::self()->close( d->id ); 00250 if(d->id != -1) //=-1 mean still waiting for receiving the id 00251 deleteLater(); 00252 d->id = -2; 00253 emit closed(); 00254 } 00255 00256 00257 void KNotification::raiseWidget() 00258 { 00259 if ( !d->widget ) { 00260 return; 00261 } 00262 00263 Private::raiseWidget( d->widget ); 00264 } 00265 00266 00267 void KNotification::Private::raiseWidget(QWidget *w) 00268 { 00269 //TODO this function is far from finished. 00270 if(w->isTopLevel()) 00271 { 00272 w->raise(); 00273 #if defined(Q_WS_WIN) || defined(Q_WS_MAC) 00274 w->activateWindow(); 00275 #else 00276 KWindowSystem::activateWindow( w->winId() ); 00277 #endif 00278 } 00279 else 00280 { 00281 QWidget *pw=w->parentWidget(); 00282 raiseWidget(pw); 00283 00284 if( QTabWidget *tab_widget=qobject_cast<QTabWidget*>(pw)) 00285 { 00286 tab_widget->setCurrentIndex(tab_widget->indexOf(w)); 00287 } 00288 } 00289 } 00290 00291 KNotification *KNotification::event( const QString& eventid , const QString& title, const QString& text, 00292 const QPixmap& pixmap, QWidget *widget, const NotificationFlags &flags, const KComponentData &componentData) 00293 { 00294 KNotification *notify=new KNotification(eventid, widget, flags); 00295 notify->setTitle(title); 00296 notify->setText(text); 00297 notify->setPixmap(pixmap); 00298 notify->setComponentData(componentData); 00299 00300 QTimer::singleShot(0,notify,SLOT(sendEvent())); 00301 00302 return notify; 00303 } 00304 00305 KNotification *KNotification::event( const QString& eventid , const QString& text, 00306 const QPixmap& pixmap, QWidget *widget, const NotificationFlags &flags, const KComponentData &componentData) 00307 { 00308 return event( eventid, QString(), text, pixmap, widget, flags, componentData ); 00309 } 00310 00311 00312 KNotification *KNotification::event( StandardEvent eventid , const QString& title, const QString& text, 00313 const QPixmap& pixmap, QWidget *widget, const NotificationFlags &flags) 00314 { 00315 QString message; 00316 switch ( eventid ) { 00317 case Warning: 00318 message = QLatin1String("warning"); 00319 break; 00320 case Error: 00321 message = QLatin1String("fatalerror"); 00322 break; 00323 case Catastrophe: 00324 message = QLatin1String("catastrophe"); 00325 break; 00326 case Notification: // fall through 00327 default: 00328 message = QLatin1String("notification"); 00329 break; 00330 } 00331 return event( message, title, text, pixmap, widget , flags | DefaultEvent ); 00332 } 00333 00334 KNotification *KNotification::event( StandardEvent eventid , const QString& text, 00335 const QPixmap& pixmap, QWidget *widget, const NotificationFlags &flags) 00336 { 00337 return event( eventid, QString(), text, pixmap, widget , flags ); 00338 } 00339 00340 void KNotification::ref() 00341 { 00342 d->ref++; 00343 } 00344 00345 void KNotification::deref() 00346 { 00347 d->ref--; 00348 if(d->ref==0) 00349 close(); 00350 } 00351 00352 void KNotification::beep( const QString & reason, QWidget * widget ) 00353 { 00354 event( QLatin1String("beep"), reason, QPixmap(), widget , CloseOnTimeout | DefaultEvent ); 00355 } 00356 00357 void KNotification::sendEvent() 00358 { 00359 d->needUpdate = false; 00360 if(d->id == 0) 00361 { 00362 QString appname; 00363 00364 if(d->flags & DefaultEvent) 00365 appname = QLatin1String("kde"); 00366 else if(d->componentData.isValid()) { 00367 appname = d->componentData.componentName(); 00368 } else { 00369 appname = KGlobal::mainComponent().componentName(); 00370 } 00371 00372 if (KNotificationManager::self()->notify( this , d->pixmap , d->actions , d->contexts , appname )) 00373 d->id = -1; 00374 } 00375 else if(d->id > 0) 00376 { 00377 KNotificationManager::self()->reemit(this , d->id ); 00378 } 00379 else if(d->id == -1) 00380 { 00381 //schedule an update. 00382 d->needUpdate = true; 00383 } 00384 } 00385 00386 void KNotification::slotReceivedId(int id) 00387 { 00388 if(d->id == -2) //we are already closed 00389 { 00390 KNotificationManager::self()->close( id, /*force=*/ true ); 00391 deleteLater(); 00392 return; 00393 } 00394 d->id=id; 00395 if(d->id>0) 00396 { 00397 KNotificationManager::self()->insert(this,d->id); 00398 if (d->needUpdate) 00399 sendEvent(); 00400 } 00401 else 00402 { 00403 //if there is no presentation, delete the object 00404 QTimer::singleShot(0, this, SLOT(deref())); 00405 } 00406 00407 } 00408 00409 void KNotification::slotReceivedIdError(const QDBusError& error) 00410 { 00411 if(d->id == -2) //we are already closed 00412 { 00413 deleteLater(); 00414 return; 00415 } 00416 kWarning(299) << "Error while contacting notify daemon" << error.message(); 00417 d->id = -3; 00418 QTimer::singleShot(0, this, SLOT(deref())); 00419 } 00420 00421 00422 void KNotification::update() 00423 { 00424 KNotificationManager::self()->update(this, d->id); 00425 } 00426 00427 bool KNotification::eventFilter( QObject * watched, QEvent * event ) 00428 { 00429 if( watched == d->widget ) 00430 { 00431 if( event->type() == QEvent::WindowActivate ) 00432 { 00433 if( d->flags & CloseWhenWidgetActivated ) 00434 QTimer::singleShot(500, this, SLOT(close())); 00435 } 00436 //kDebug(299) << event->type(); 00437 } 00438 00439 return false; 00440 } 00441 00442 00443 #include "knotification.moc"
KDE 4.6 API Reference