| # arts Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

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

This file is part of the documentation for arts Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:27:55 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003