arts Library API Documentation

knotify.cpp

00001 /* 00002 Copyright (c) 1997 Christian Esken (esken@kde.org) 00003 2000 Charles Samuels (charles@kde.org) 00004 2000 Stefan Schimanski (1Stein@gmx.de) 00005 2000 Matthias Ettrich (ettrich@kde.org) 00006 2000 Waldo Bastian <bastian@kde.org> 00007 2000-2003 Carsten Pfeiffer <pfeiffer@kde.org> 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 2, or (at your option) 00012 any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00022 */ 00023 00024 // C headers 00025 #include <fcntl.h> 00026 #include <sys/types.h> 00027 #include <sys/stat.h> 00028 00029 // aRts headers 00030 #include <connect.h> 00031 #include <dispatcher.h> 00032 #include <flowsystem.h> 00033 #include <soundserver.h> 00034 00035 // QT headers 00036 #include <qfile.h> 00037 #include <qfileinfo.h> 00038 #include <qiomanager.h> 00039 #include <qstringlist.h> 00040 #include <qtextstream.h> 00041 00042 // KDE headers 00043 #include <dcopclient.h> 00044 #include <kaboutdata.h> 00045 #include <kartsdispatcher.h> 00046 #include <kartsserver.h> 00047 #include <kcmdlineargs.h> 00048 #include <kconfig.h> 00049 #include <kdebug.h> 00050 #include <kglobal.h> 00051 #include <klocale.h> 00052 #include <kmessagebox.h> 00053 #include <kpassivepopup.h> 00054 #include <kiconloader.h> 00055 #include <kmacroexpander.h> 00056 #include <kplayobjectfactory.h> 00057 #include <kaudiomanagerplay.h> 00058 #include <kprocess.h> 00059 #include <kstandarddirs.h> 00060 #include <kuniqueapplication.h> 00061 #include <kwin.h> 00062 00063 #include "knotify.h" 00064 #include "knotify.moc" 00065 00066 class KNotifyPrivate 00067 { 00068 public: 00069 KConfig* globalEvents; 00070 KConfig* globalConfig; 00071 QMap<QString, KConfig*> events; 00072 QMap<QString, KConfig*> configs; 00073 QString externalPlayer; 00074 KProcess *externalPlayerProc; 00075 00076 QPtrList<KDE::PlayObject> playObjects; 00077 QMap<KDE::PlayObject*,int> playObjectEventMap; 00078 int externalPlayerEventId; 00079 00080 bool useExternal; 00081 bool useArts; 00082 int volume; 00083 QTimer *playTimer; 00084 KAudioManagerPlay *audioManager; 00085 }; 00086 00087 // Yes, it's ugly to put this here, but this facilitates the cautious startup 00088 // procedure. 00089 KArtsServer *soundServer; 00090 00091 extern "C"{ 00092 00093 int kdemain(int argc, char **argv) 00094 { 00095 KAboutData aboutdata("knotify", I18N_NOOP("KNotify"), 00096 "3.0", I18N_NOOP("KDE Notification Server"), 00097 KAboutData::License_GPL, "(C) 1997-2003, KDE Developers"); 00098 aboutdata.addAuthor("Carsten Pfeiffer",I18N_NOOP("Current Maintainer"),"pfeiffer@kde.org"); 00099 aboutdata.addAuthor("Christian Esken",0,"esken@kde.org"); 00100 aboutdata.addAuthor("Stefan Westerfeld",I18N_NOOP("Sound support"),"stefan@space.twc.de"); 00101 aboutdata.addAuthor("Charles Samuels",I18N_NOOP("Previous Maintainer"),"charles@kde.org"); 00102 00103 KCmdLineArgs::init( argc, argv, &aboutdata ); 00104 KUniqueApplication::addCmdLineOptions(); 00105 00106 00107 // initialize application 00108 if ( !KUniqueApplication::start() ) { 00109 kdDebug() << "Running knotify found" << endl; 00110 return 0; 00111 } 00112 00113 KUniqueApplication app; 00114 app.disableSessionManagement(); 00115 00116 // KNotify is started on KDE startup and on demand (using 00117 // KNotifClient::startDaemon()) whenever a KNotify event occurs. Especially 00118 // KWin may fire many events (e.g. when a window pops up). When we have 00119 // problems with aRts or the installation, we might get an infinite loop 00120 // of knotify crashing, popping up the crashhandler window and kwin firing 00121 // another event, starting knotify again... 00122 // We try to prevent this by tracking our startup and offer options to 00123 // abort this. 00124 00125 KConfigGroup config( KGlobal::config(), "StartProgress" ); 00126 KConfig artsKCMConfig( "kcmartsrc" ); 00127 artsKCMConfig.setGroup( "Arts" ); 00128 bool useArts = artsKCMConfig.readBoolEntry( "StartServer", true ); 00129 if (useArts) 00130 useArts = config.readBoolEntry( "Use Arts", useArts ); 00131 bool ok = config.readBoolEntry( "Arts Init", true ); 00132 00133 if ( useArts && !ok ) 00134 { 00135 if ( KMessageBox::questionYesNo( 00136 0L, 00137 i18n("During the previous startup, KNotify crashed while creating " 00138 "Arts::Dispatcher. Do you want to try again or disable " 00139 "aRts sound output?"), 00140 i18n("KNotify Problem"), 00141 i18n("Try Again"), 00142 i18n("Disable aRts Output"), 00143 "KNotifyStartProgress", 00144 0 /* don't call KNotify :) */ 00145 ) 00146 == KMessageBox::No ) 00147 { 00148 useArts = false; 00149 } 00150 } 00151 00152 // when ArtsDispatcher crashes, we know it the next start. 00153 config.writeEntry( "Arts Init", false ); 00154 config.writeEntry( "Use Arts", useArts ); 00155 config.sync(); 00156 00157 KArtsDispatcher *dispatcher = 0; 00158 if ( useArts ) 00159 { 00160 dispatcher = new KArtsDispatcher; 00161 soundServer = new KArtsServer; 00162 } 00163 00164 // ok, seemed to work. 00165 config.writeEntry("Arts Init", useArts ); 00166 config.sync(); 00167 00168 ok = config.readBoolEntry( "KNotify Init", true ); 00169 if ( useArts && !ok ) 00170 { 00171 if ( KMessageBox::questionYesNo( 00172 0L, 00173 i18n("During the previous startup, KNotify crashed while instantiating " 00174 "KNotify. Do you want to try again or disable " 00175 "aRts sound output?"), 00176 i18n("KNotify Problem"), 00177 i18n("Try Again"), 00178 i18n("Disable aRts Output"), 00179 "KNotifyStartProgress", 00180 0 /* don't call KNotify :) */ 00181 ) 00182 == KMessageBox::No ) 00183 { 00184 useArts = false; 00185 delete soundServer; 00186 soundServer = 0L; 00187 delete dispatcher; 00188 dispatcher = 0L; 00189 } 00190 } 00191 00192 // when KNotify instantiation crashes, we know it the next start. 00193 config.writeEntry( "KNotify Init", false ); 00194 config.writeEntry( "Use Arts", useArts ); 00195 config.sync(); 00196 00197 // start notify service 00198 KNotify notify( useArts ); 00199 00200 config.writeEntry( "KNotify Init", true ); 00201 config.sync(); 00202 00203 app.dcopClient()->setDefaultObject( "Notify" ); 00204 app.dcopClient()->setDaemonMode( true ); 00205 // kdDebug() << "knotify starting" << endl; 00206 00207 int ret = app.exec(); 00208 delete soundServer; 00209 delete dispatcher; 00210 return ret; 00211 } 00212 }// end extern "C" 00213 00214 KNotify::KNotify( bool useArts ) 00215 : QObject(), DCOPObject("Notify") 00216 { 00217 d = new KNotifyPrivate; 00218 d->globalEvents = new KConfig("knotify/eventsrc", true, false, "data"); 00219 d->globalConfig = new KConfig("knotify.eventsrc", true, false); 00220 d->externalPlayerProc = 0; 00221 d->useArts = useArts; 00222 d->playObjects.setAutoDelete(true); 00223 d->audioManager = 0; 00224 if( useArts ) 00225 { 00226 connect( soundServer, SIGNAL( restartedServer() ), this, SLOT( restartedArtsd() ) ); 00227 restartedArtsd(); //started allready need to initialize d->audioManager 00228 } 00229 00230 d->volume = 100; 00231 00232 d->playTimer = 0; 00233 00234 loadConfig(); 00235 } 00236 00237 KNotify::~KNotify() 00238 { 00239 reconfigure(); 00240 00241 d->playObjects.clear(); 00242 00243 delete d->globalEvents; 00244 delete d->globalConfig; 00245 delete d->externalPlayerProc; 00246 delete d->audioManager; 00247 delete d; 00248 } 00249 00250 00251 void KNotify::loadConfig() { 00252 // load external player settings 00253 KConfig *kc = KGlobal::config(); 00254 kc->setGroup("Misc"); 00255 d->useExternal = kc->readBoolEntry( "Use external player", false ); 00256 d->externalPlayer = kc->readPathEntry("External player"); 00257 00258 // try to locate a suitable player if none is configured 00259 if ( d->externalPlayer.isEmpty() ) { 00260 QStringList players; 00261 players << "wavplay" << "aplay" << "auplay"; 00262 QStringList::Iterator it = players.begin(); 00263 while ( d->externalPlayer.isEmpty() && it != players.end() ) { 00264 d->externalPlayer = KStandardDirs::findExe( *it ); 00265 ++it; 00266 } 00267 } 00268 00269 // load default volume 00270 d->volume = kc->readNumEntry( "Volume", 100 ); 00271 } 00272 00273 00274 void KNotify::reconfigure() 00275 { 00276 kapp->config()->reparseConfiguration(); 00277 loadConfig(); 00278 00279 // clear loaded config files 00280 d->globalConfig->reparseConfiguration(); 00281 for ( QMapIterator<QString,KConfig*> it = d->configs.begin(); it != d->configs.end(); ++it ) 00282 delete it.data(); 00283 d->configs.clear(); 00284 } 00285 00286 00287 void KNotify::notify(const QString &event, const QString &fromApp, 00288 const QString &text, QString sound, QString file, 00289 int present, int level) 00290 { 00291 notify( event, fromApp, text, sound, file, present, level, 0, 1 ); 00292 } 00293 00294 void KNotify::notify(const QString &event, const QString &fromApp, 00295 const QString &text, QString sound, QString file, 00296 int present, int level, int winId) 00297 { 00298 notify( event, fromApp, text, sound, file, present, level, winId, 1 ); 00299 } 00300 00301 void KNotify::notify(const QString &event, const QString &fromApp, 00302 const QString &text, QString sound, QString file, 00303 int present, int level, int winId, int eventId ) 00304 { 00305 // kdDebug() << "event=" << event << " fromApp=" << fromApp << " text=" << text << " sound=" << sound << 00306 // " file=" << file << " present=" << present << " level=" << level << " winId=" << winId << " eventId=" << eventId endl; 00307 00308 QString commandline; 00309 00310 // check for valid events 00311 if ( !event.isEmpty() ) { 00312 00313 // get config file 00314 KConfig *eventsFile; 00315 KConfig *configFile; 00316 if ( d->events.contains( fromApp ) ) { 00317 eventsFile = d->events[fromApp]; 00318 } else { 00319 eventsFile=new KConfig(locate("data", fromApp+"/eventsrc"),true,false); 00320 d->events.insert( fromApp, eventsFile ); 00321 } 00322 if ( d->configs.contains( fromApp) ) { 00323 configFile = d->configs[fromApp]; 00324 } else { 00325 configFile=new KConfig(fromApp+".eventsrc",true,false); 00326 d->configs.insert( fromApp, configFile ); 00327 } 00328 00329 if ( !eventsFile->hasGroup( event ) && isGlobal(event) ) 00330 { 00331 eventsFile = d->globalEvents; 00332 configFile = d->globalConfig; 00333 } 00334 00335 eventsFile->setGroup( event ); 00336 configFile->setGroup( event ); 00337 00338 // get event presentation 00339 if ( present==-1 ) 00340 present = configFile->readNumEntry( "presentation", -1 ); 00341 if ( present==-1 ) 00342 present = eventsFile->readNumEntry( "default_presentation", 0 ); 00343 00344 // get sound file name 00345 if( present & KNotifyClient::Sound ) { 00346 QString theSound = configFile->readPathEntry( "soundfile" ); 00347 if ( theSound.isEmpty() ) 00348 theSound = eventsFile->readPathEntry( "default_sound" ); 00349 if ( !theSound.isEmpty() ) 00350 sound = theSound; 00351 } 00352 00353 // get log file name 00354 if( present & KNotifyClient::Logfile ) { 00355 QString theFile = configFile->readPathEntry( "logfile" ); 00356 if ( theFile.isEmpty() ) 00357 theFile = eventsFile->readPathEntry( "default_logfile" ); 00358 if ( !theFile.isEmpty() ) 00359 file = theFile; 00360 } 00361 00362 // get default event level 00363 if( present & KNotifyClient::Messagebox ) 00364 level = eventsFile->readNumEntry( "level", 0 ); 00365 00366 // get command line 00367 if (present & KNotifyClient::Execute ) { 00368 commandline = configFile->readPathEntry( "commandline" ); 00369 if ( commandline.isEmpty() ) 00370 commandline = eventsFile->readPathEntry( "default_commandline" ); 00371 } 00372 } 00373 00374 // emit event 00375 if ( present & KNotifyClient::Sound ) // && QFile(sound).isReadable() 00376 notifyBySound( sound, fromApp, eventId ); 00377 00378 if ( present & KNotifyClient::PassivePopup ) 00379 notifyByPassivePopup( text, fromApp, checkWinId( fromApp, winId )); 00380 00381 else if ( present & KNotifyClient::Messagebox ) 00382 notifyByMessagebox( text, level, checkWinId( fromApp, winId )); 00383 00384 if ( present & KNotifyClient::Logfile ) // && QFile(file).isWritable() 00385 notifyByLogfile( text, file ); 00386 00387 if ( present & KNotifyClient::Stderr ) 00388 notifyByStderr( text ); 00389 00390 if ( present & KNotifyClient::Execute ) 00391 notifyByExecute( commandline, event, fromApp, text, winId, eventId ); 00392 00393 if ( present & KNotifyClient::Taskbar ) 00394 notifyByTaskbar( checkWinId( fromApp, winId )); 00395 00396 QByteArray qbd; 00397 QDataStream ds(qbd, IO_WriteOnly); 00398 ds << event << fromApp << text << sound << file << present << level 00399 << winId << eventId; 00400 emitDCOPSignal("notifySignal(QString,QString,QString,QString,QString,int,int,int,int)", qbd); 00401 00402 } 00403 00404 00405 bool KNotify::notifyBySound( const QString &sound, const QString &appname, int eventId ) 00406 { 00407 if (sound.isEmpty()) { 00408 soundFinished( eventId, NoSoundFile ); 00409 return false; 00410 } 00411 00412 bool external = d->useExternal && !d->externalPlayer.isEmpty(); 00413 // get file name 00414 QString soundFile(sound); 00415 if ( QFileInfo(sound).isRelative() ) 00416 { 00417 QString search = QString("%1/sounds/%2").arg(appname).arg(sound); 00418 soundFile = KGlobal::instance()->dirs()->findResource("data", search); 00419 if ( soundFile.isEmpty() ) 00420 soundFile = locate( "sound", sound ); 00421 } 00422 if ( soundFile.isEmpty() || isPlaying( soundFile ) ) 00423 { 00424 soundFinished( eventId, soundFile.isEmpty() ? NoSoundFile : FileAlreadyPlaying ); 00425 return false; 00426 } 00427 00428 00429 // kdDebug() << "KNotify::notifyBySound - trying to play file " << soundFile << endl; 00430 00431 if (!external) { 00432 //If we disabled using aRts, just return, 00433 //(If we don't, we'll blow up accessing the null soundServer) 00434 if (!d->useArts) 00435 { 00436 soundFinished( eventId, NoSoundSupport ); 00437 return false; 00438 } 00439 00440 // play sound finally 00441 while( d->playObjects.count()>5 ) 00442 abortFirstPlayObject(); 00443 00444 KDE::PlayObjectFactory factory(soundServer->server()); 00445 if( d->audioManager ) 00446 factory.setAudioManagerPlay( d->audioManager ); 00447 KURL soundURL; 00448 soundURL.setPath(soundFile); 00449 KDE::PlayObject *playObject = factory.createPlayObject(soundURL, false); 00450 00451 if (playObject->isNull()) 00452 { 00453 soundFinished( eventId, NoSoundSupport ); 00454 delete playObject; 00455 return false; 00456 } 00457 00458 if ( d->volume != 100 ) 00459 { 00460 // It works to access the playObject immediately because we don't allow 00461 // non-file URLs for sounds. 00462 Arts::StereoVolumeControl volumeControl = Arts::DynamicCast(soundServer->server().createObject("Arts::StereoVolumeControl")); 00463 Arts::PlayObject player = playObject->object(); 00464 Arts::Synth_AMAN_PLAY ap = d->audioManager->amanPlay(); 00465 if( ! volumeControl.isNull() && ! player.isNull() && ! ap.isNull() ) 00466 { 00467 volumeControl.scaleFactor( d->volume/100.0 ); 00468 00469 ap.stop(); 00470 player._node()->stop(); 00471 Arts::disconnect( player, "left", ap, "left" ); 00472 Arts::disconnect( player, "right", ap, "right" ); 00473 00474 ap.start(); 00475 volumeControl.start(); 00476 player._node()->start(); 00477 00478 Arts::connect(player,"left",volumeControl,"inleft"); 00479 Arts::connect(player,"right",volumeControl,"inright"); 00480 00481 Arts::connect(volumeControl,"outleft",ap,"left"); 00482 Arts::connect(volumeControl,"outright",ap,"right"); 00483 00484 player._addChild( volumeControl, "volume" ); 00485 } 00486 } 00487 00488 playObject->play(); 00489 d->playObjects.append( playObject ); 00490 d->playObjectEventMap.insert( playObject, eventId ); 00491 00492 if ( !d->playTimer ) 00493 { 00494 d->playTimer = new QTimer( this ); 00495 connect( d->playTimer, SIGNAL( timeout() ), SLOT( playTimeout() ) ); 00496 } 00497 if ( !d->playTimer->isActive() ) 00498 d->playTimer->start( 1000 ); 00499 00500 return true; 00501 00502 } else if(!d->externalPlayer.isEmpty()) { 00503 // use an external player to play the sound 00504 KProcess *proc = d->externalPlayerProc; 00505 if (!proc) 00506 { 00507 proc = d->externalPlayerProc = new KProcess; 00508 connect( proc, SIGNAL( processExited( KProcess * )), 00509 SLOT( slotPlayerProcessExited( KProcess * ))); 00510 } 00511 if (proc->isRunning()) 00512 { 00513 soundFinished( eventId, PlayerBusy ); 00514 return false; // Skip 00515 } 00516 proc->clearArguments(); 00517 (*proc) << d->externalPlayer << QFile::encodeName( soundFile ); 00518 d->externalPlayerEventId = eventId; 00519 proc->start(KProcess::NotifyOnExit); 00520 return true; 00521 } 00522 00523 soundFinished( eventId, Unknown ); 00524 return false; 00525 } 00526 00527 bool KNotify::notifyByMessagebox(const QString &text, int level, WId winId) 00528 { 00529 // ignore empty messages 00530 if ( text.isEmpty() ) 00531 return false; 00532 00533 // display message box for specified event level 00534 switch( level ) { 00535 default: 00536 case KNotifyClient::Notification: 00537 KMessageBox::informationWId( winId, text, i18n("Notification"), 0, false ); 00538 break; 00539 case KNotifyClient::Warning: 00540 KMessageBox::sorryWId( winId, text, i18n("Warning"), false ); 00541 break; 00542 case KNotifyClient::Error: 00543 KMessageBox::errorWId( winId, text, i18n("Error"), false ); 00544 break; 00545 case KNotifyClient::Catastrophe: 00546 KMessageBox::errorWId( winId, text, i18n("Catastrophe!"), false ); 00547 break; 00548 } 00549 00550 return true; 00551 } 00552 00553 bool KNotify::notifyByPassivePopup( const QString &text, 00554 const QString &appName, 00555 WId senderWinId ) 00556 { 00557 KIconLoader iconLoader( appName ); 00558 if ( d->events.find( appName ) != d->events.end() ) { 00559 KConfigGroup config( d->events[ appName ], "!Global!" ); 00560 QString iconName = config.readEntry( "IconName", appName ); 00561 QPixmap icon = iconLoader.loadIcon( iconName, KIcon::Small ); 00562 QString title = config.readEntry( "Comment", appName ); 00563 KPassivePopup::message(title, text, icon, senderWinId); 00564 } else 00565 kdError() << "No events for app " << appName << "defined!" <<endl; 00566 00567 return true; 00568 } 00569 00570 bool KNotify::notifyByExecute(const QString &command, const QString& event, 00571 const QString& fromApp, const QString& text, 00572 int winId, int eventId) { 00573 if (!command.isEmpty()) { 00574 // kdDebug() << "executing command '" << command << "'" << endl; 00575 QMap<QChar,QString> subst; 00576 subst.insert( 'e', event ); 00577 subst.insert( 'a', fromApp ); 00578 subst.insert( 's', text ); 00579 subst.insert( 'w', QString::number( winId )); 00580 subst.insert( 'i', QString::number( eventId )); 00581 QString execLine = KMacroExpander::expandMacrosShellQuote( command, subst ); 00582 if ( execLine.isEmpty() ) 00583 execLine = command; // fallback 00584 00585 KProcess p; 00586 p.setUseShell(true); 00587 p << execLine; 00588 p.start(KProcess::DontCare); 00589 return true; 00590 } 00591 return false; 00592 } 00593 00594 00595 bool KNotify::notifyByLogfile(const QString &text, const QString &file) 00596 { 00597 // ignore empty messages 00598 if ( text.isEmpty() ) 00599 return true; 00600 00601 // open file in append mode 00602 QFile logFile(file); 00603 if ( !logFile.open(IO_WriteOnly | IO_Append) ) 00604 return false; 00605 00606 // append msg 00607 QTextStream strm( &logFile ); 00608 strm << "- KNotify " << QDateTime::currentDateTime().toString() << ": "; 00609 strm << text << endl; 00610 00611 // close file 00612 logFile.close(); 00613 return true; 00614 } 00615 00616 bool KNotify::notifyByStderr(const QString &text) 00617 { 00618 // ignore empty messages 00619 if ( text.isEmpty() ) 00620 return true; 00621 00622 // open stderr for output 00623 QTextStream strm( stderr, IO_WriteOnly ); 00624 00625 // output msg 00626 strm << "KNotify " << QDateTime::currentDateTime().toString() << ": "; 00627 strm << text << endl; 00628 00629 return true; 00630 } 00631 00632 bool KNotify::notifyByTaskbar( WId win ) 00633 { 00634 if( win == 0 ) 00635 return false; 00636 KWin::demandAttention( win ); 00637 return true; 00638 } 00639 00640 bool KNotify::isGlobal(const QString &eventname) 00641 { 00642 return d->globalEvents->hasGroup( eventname ); 00643 } 00644 00645 void KNotify::setVolume( int volume ) 00646 { 00647 if ( volume<0 ) volume=0; 00648 if ( volume>=100 ) volume=100; 00649 d->volume = volume; 00650 } 00651 00652 void KNotify::playTimeout() 00653 { 00654 for ( QPtrListIterator< KDE::PlayObject > it(d->playObjects); *it;) 00655 { 00656 QPtrListIterator< KDE::PlayObject > current = it; 00657 ++it; 00658 if ( (*current)->state() != Arts::posPlaying ) 00659 { 00660 QMap<KDE::PlayObject*,int>::Iterator eit = d->playObjectEventMap.find( *current ); 00661 if ( eit != d->playObjectEventMap.end() ) 00662 { 00663 soundFinished( *eit, PlayedOK ); 00664 d->playObjectEventMap.remove( eit ); 00665 } 00666 d->playObjects.remove( current ); 00667 } 00668 } 00669 if ( !d->playObjects.count() ) 00670 d->playTimer->stop(); 00671 } 00672 00673 bool KNotify::isPlaying( const QString& soundFile ) const 00674 { 00675 for ( QPtrListIterator< KDE::PlayObject > it(d->playObjects); *it; ++it) 00676 { 00677 if ( (*it)->mediaName() == soundFile ) 00678 return true; 00679 } 00680 00681 return false; 00682 } 00683 00684 void KNotify::slotPlayerProcessExited( KProcess *proc ) 00685 { 00686 soundFinished( d->externalPlayerEventId, 00687 (proc->normalExit() && proc->exitStatus() == 0) ? PlayedOK : Unknown ); 00688 } 00689 00690 void KNotify::abortFirstPlayObject() 00691 { 00692 QMap<KDE::PlayObject*,int>::Iterator it = d->playObjectEventMap.find( d->playObjects.getFirst() ); 00693 if ( it != d->playObjectEventMap.end() ) 00694 { 00695 soundFinished( it.data(), Aborted ); 00696 d->playObjectEventMap.remove( it ); 00697 } 00698 d->playObjects.removeFirst(); 00699 } 00700 00701 void KNotify::soundFinished( int eventId, PlayingFinishedStatus reason ) 00702 { 00703 QByteArray data; 00704 QDataStream stream( data, IO_WriteOnly ); 00705 stream << eventId << (int) reason; 00706 00707 DCOPClient::mainClient()->emitDCOPSignal( "KNotify", "playingFinished(int,int)", data ); 00708 } 00709 00710 WId KNotify::checkWinId( const QString &appName, WId senderWinId ) 00711 { 00712 if ( senderWinId == 0 ) 00713 { 00714 QCString senderId = kapp->dcopClient()->senderId(); 00715 QCString compare = (appName + "-mainwindow").latin1(); 00716 int len = compare.length(); 00717 // kdDebug() << "notifyByPassivePopup: appName=" << appName << " sender=" << senderId << endl; 00718 00719 QCStringList objs = kapp->dcopClient()->remoteObjects( senderId ); 00720 for (QCStringList::ConstIterator it = objs.begin(); it != objs.end(); it++ ) { 00721 QCString obj( *it ); 00722 if ( obj.left(len) == compare) { 00723 // kdDebug( ) << "found " << obj << endl; 00724 QCString replyType; 00725 QByteArray data, replyData; 00726 00727 if ( kapp->dcopClient()->call(senderId, obj, "getWinID()", data, replyType, replyData) ) { 00728 QDataStream answer(replyData, IO_ReadOnly); 00729 if (replyType == "int") { 00730 answer >> senderWinId; 00731 // kdDebug() << "SUCCESS, found getWinID(): type='" << QString(replyType) 00732 // << "' senderWinId=" << senderWinId << endl; 00733 } 00734 } 00735 } 00736 } 00737 } 00738 return senderWinId; 00739 } 00740 00741 void KNotify::restartedArtsd() 00742 { 00743 delete d->audioManager; 00744 d->audioManager = new KAudioManagerPlay( soundServer ); 00745 d->audioManager->setTitle( i18n( "KDE System Notifications" ) ); 00746 d->audioManager->setAutoRestoreID( "KNotify Aman Play" ); 00747 } 00748 00749 // vim: sw=4 sts=4 ts=8 et
KDE Logo
This file is part of the documentation for arts Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:44:05 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003