• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • arts
 

arts

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

arts

Skip menu "arts"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

arts

Skip menu "arts"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for arts by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.