kio Library API Documentation

knotifydialog.cpp

00001 /*
00002   Copyright (C) 2000,2002 Carsten Pfeiffer <pfeiffer@kde.org>
00003   Copyright (C) 2002 Neil Stevens <neil@qualityassistant.com>
00004 
00005   This program is free software; you can redistribute it and/or
00006   modify it under the terms of the GNU Library General Public
00007   License version 2 as published by the Free Software Foundation;
00008 
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012   General Public License for more details.
00013 
00014   You should have received a copy of the GNU Library General Public License
00015   along with this library,  If not, write to the Free Software Foundation,
00016   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #include <dcopclient.h>
00020 
00021 #include <kaboutdata.h>
00022 #include <kapplication.h>
00023 #include <kaudioplayer.h>
00024 #include <kcombobox.h>
00025 #include <kconfig.h>
00026 #include <kcursor.h>
00027 #include <kdebug.h>
00028 #include <kfiledialog.h>
00029 #include <kiconloader.h>
00030 #include <kicontheme.h>
00031 #include <klineedit.h>
00032 #include <klocale.h>
00033 #include <kmessagebox.h>
00034 #include <knotifyclient.h>
00035 #include <knotifydialog.h>
00036 #include <kstandarddirs.h>
00037 #include <kurlrequester.h>
00038 
00039 #include <qcheckbox.h>
00040 #include <qgroupbox.h>
00041 #include <qheader.h>
00042 #include <qlabel.h>
00043 #include <qlistview.h>
00044 #include <qlayout.h>
00045 #include <qptrlist.h>
00046 #include <qpushbutton.h>
00047 #include <qstring.h>
00048 #include <qtooltip.h>
00049 #include <qtimer.h>
00050 #include <qvbox.h>
00051 
00052 using namespace KNotify;
00053 
00054 //
00055 // I don't feel like subclassing KComboBox and find ways to insert that into
00056 // the .ui file...
00057 //
00058 namespace KNotify
00059 {
00060     class SelectionCombo
00061     {
00062     public:
00063         //
00064         // Mind the order in fill() and type()
00065         //
00066         static void fill( KComboBox *combo )
00067         {
00068             combo->insertItem( i18n("Sounds") );
00069             combo->insertItem( i18n("Logging") );
00070             combo->insertItem( i18n("Program Execution") );
00071             combo->insertItem( i18n("Message Windows") );
00072             combo->insertItem( i18n("Passive Windows") );
00073             combo->insertItem( i18n("Standard Error Output") );
00074         }
00075 
00076         static int type( KComboBox *combo )
00077         {
00078             switch( combo->currentItem() )
00079             {
00080                 case 0:
00081                     return KNotifyClient::Sound;
00082                 case 1:
00083                     return KNotifyClient::Logfile;
00084                 case 2:
00085                     return KNotifyClient::Execute;
00086                 case 3:
00087                     return KNotifyClient::Messagebox;
00088                 case 4:
00089                     return KNotifyClient::PassivePopup;
00090                 case 5:
00091                     return KNotifyClient::Stderr;
00092             }
00093 
00094             return KNotifyClient::None;
00095         }
00096     };
00097 }
00098 
00099 
00100 int KNotifyDialog::configure( QWidget *parent, const char *name,
00101                               const KAboutData *aboutData )
00102 {
00103     KNotifyDialog dialog( parent, name, true, aboutData );
00104     return dialog.exec();
00105 }
00106 
00107 KNotifyDialog::KNotifyDialog( QWidget *parent, const char *name, bool modal,
00108                               const KAboutData *aboutData )
00109     : KDialogBase(parent, name, modal, i18n("Notification Settings"),
00110                   Ok | Apply | Cancel | Default, Ok, true )
00111 {
00112     QVBox *box = makeVBoxMainWidget();
00113 
00114     m_notifyWidget = new KNotifyWidget( box, "knotify widget" );
00115 
00116     if ( aboutData )
00117         addApplicationEvents( aboutData->appName() );
00118 
00119     connect( this, SIGNAL( okClicked() ), m_notifyWidget, SLOT( save() ));
00120     connect( this, SIGNAL( applyClicked() ), m_notifyWidget, SLOT( save() ));
00121 }
00122 
00123 KNotifyDialog::~KNotifyDialog()
00124 {
00125 }
00126 
00127 void KNotifyDialog::addApplicationEvents( const char *appName )
00128 {
00129     addApplicationEvents( QString::fromUtf8( appName ) +
00130                           QString::fromLatin1( "/eventsrc" ) );
00131 }
00132 
00133 void KNotifyDialog::addApplicationEvents( const QString& path )
00134 {
00135     Application *app = m_notifyWidget->addApplicationEvents( path );
00136     if ( app )
00137     {
00138         m_notifyWidget->addVisibleApp( app );
00139         m_notifyWidget->sort();
00140     }
00141 }
00142 
00143 void KNotifyDialog::clearApplicationEvents()
00144 {
00145     m_notifyWidget->clear();
00146 }
00147 
00148 void KNotifyDialog::slotDefault()
00149 {
00150     m_notifyWidget->resetDefaults( true ); // ask user
00151 }
00152 
00153 
00156 
00157 
00158 #define COL_EXECUTE 0
00159 #define COL_STDERR  1
00160 #define COL_MESSAGE 2
00161 #define COL_LOGFILE 3
00162 #define COL_SOUND   4
00163 #define COL_EVENT   5
00164 
00165 class KNotifyWidget::Private
00166 {
00167 public:
00168     QPixmap pixmaps[5];
00169 };
00170 
00171 // simple access to all knotify-handled applications
00172 KNotifyWidget::KNotifyWidget( QWidget *parent, const char *name,
00173                               bool handleAllApps )
00174     : KNotifyWidgetBase( parent, name ? name : "KNotifyWidget" )
00175 {
00176     d = new Private;
00177 
00178     m_allApps.setAutoDelete( true );
00179 
00180     layout()->setMargin( 0 );
00181     layout()->setSpacing( KDialogBase::spacingHint() );
00182 
00183     if ( !handleAllApps )
00184     {
00185         m_affectAllApps->hide();
00186         m_playerButton->hide();
00187     }
00188 
00189     SelectionCombo::fill( m_comboEnable );
00190     SelectionCombo::fill( m_comboDisable );
00191 
00192     m_listview->setFullWidth( true );
00193     m_listview->setAllColumnsShowFocus( true );
00194 
00195     QPixmap pexec = SmallIcon("exec");
00196     QPixmap pstderr = SmallIcon("terminal");
00197     QPixmap pmessage = SmallIcon("info");
00198     QPixmap plogfile = SmallIcon("log");
00199     QPixmap psound = SmallIcon("sound");
00200 
00201     d->pixmaps[COL_EXECUTE] = pexec;
00202     d->pixmaps[COL_STDERR]  = pstderr;
00203     d->pixmaps[COL_MESSAGE] = pmessage;
00204     d->pixmaps[COL_LOGFILE] = plogfile;
00205     d->pixmaps[COL_SOUND]   = psound;
00206 
00207     int w = KIcon::SizeSmall + 6;
00208 
00209     QHeader *header = m_listview->header();
00210     header->setLabel( COL_EXECUTE, pexec,    QString::null, w );
00211     header->setLabel( COL_STDERR,  pstderr,  QString::null, w );
00212     header->setLabel( COL_MESSAGE, pmessage, QString::null, w );
00213     header->setLabel( COL_LOGFILE, plogfile, QString::null, w );
00214     header->setLabel( COL_SOUND,   psound,   QString::null, w );
00215 
00216     m_playButton->setPixmap( SmallIcon( "1rightarrow" ) );
00217     connect( m_playButton, SIGNAL( clicked() ), SLOT( playSound() ));
00218 
00219     connect( m_listview, SIGNAL( currentChanged( QListViewItem * ) ),
00220              SLOT( slotEventChanged( QListViewItem * ) ));
00221     connect( m_listview, SIGNAL(clicked( QListViewItem *, const QPoint&, int)),
00222              SLOT( slotItemClicked( QListViewItem *, const QPoint&, int )));
00223 
00224     connect( m_playSound, SIGNAL( toggled( bool )),
00225              SLOT( soundToggled( bool )) );
00226     connect( m_logToFile, SIGNAL( toggled( bool )),
00227              SLOT( loggingToggled( bool )) );
00228     connect( m_execute, SIGNAL( toggled( bool )),
00229              SLOT( executeToggled( bool )) );
00230     connect( m_messageBox, SIGNAL( toggled( bool )),
00231              SLOT( messageBoxChanged() ) );
00232     connect( m_passivePopup, SIGNAL( toggled( bool )),
00233              SLOT( messageBoxChanged() ) );
00234     connect( m_stderr, SIGNAL( toggled( bool )),
00235              SLOT( stderrToggled( bool ) ) );
00236 
00237     connect( m_soundPath, SIGNAL( textChanged( const QString& )),
00238              SLOT( soundFileChanged( const QString& )));
00239     connect( m_logfilePath, SIGNAL( textChanged( const QString& )),
00240              SLOT( logfileChanged( const QString& ) ));
00241     connect( m_executePath, SIGNAL( textChanged( const QString& )),
00242              SLOT( commandlineChanged( const QString& ) ));
00243 
00244     connect( m_soundPath, SIGNAL( openFileDialog( KURLRequester * )),
00245              SLOT( openSoundDialog( KURLRequester * )));
00246     connect( m_logfilePath, SIGNAL( openFileDialog( KURLRequester * )),
00247              SLOT( openLogDialog( KURLRequester * )));
00248     connect( m_executePath, SIGNAL( openFileDialog( KURLRequester * )),
00249              SLOT( openExecDialog( KURLRequester * )));
00250 
00251     connect( m_extension, SIGNAL( clicked() ),
00252              SLOT( toggleAdvanced()) );
00253 
00254     connect( m_buttonEnable, SIGNAL( clicked() ), SLOT( enableAll() ));
00255     connect( m_buttonDisable, SIGNAL( clicked() ), SLOT( enableAll() ));
00256 
00257     showAdvanced( false );
00258     
00259     slotEventChanged( 0L ); // disable widgets by default
00260 }
00261 
00262 KNotifyWidget::~KNotifyWidget()
00263 {
00264     delete d;
00265 }
00266 
00267 void KNotifyWidget::toggleAdvanced()
00268 {
00269     showAdvanced( m_logToFile->isHidden() );
00270 }
00271 
00272 void KNotifyWidget::showAdvanced( bool show )
00273 {
00274     if ( show )
00275     {
00276         m_extension->setText( i18n("Fewer Op&tions") );
00277         QToolTip::add( m_extension, i18n("Hide advanced options") );
00278 
00279         m_logToFile->show();
00280         m_logfilePath->show();
00281         m_execute->show();
00282         m_executePath->show();
00283         m_messageBox->show();
00284         m_passivePopup->show();
00285         m_stderr->show();
00286         m_controlsBox->show();
00287 
00288         m_actionsBoxLayout->setSpacing( KDialog::spacingHint() );
00289     }
00290     else
00291     {
00292         m_extension->setText( i18n("More Op&tions") );
00293         QToolTip::add( m_extension, i18n("Show advanced options") );
00294 
00295         m_logToFile->hide();
00296         m_logfilePath->hide();
00297         m_execute->hide();
00298         m_executePath->hide();
00299         m_messageBox->hide();
00300         m_passivePopup->hide();
00301         m_stderr->hide();
00302         m_controlsBox->hide();
00303 
00304         m_actionsBoxLayout->setSpacing( 0 );
00305     }
00306 }
00307 
00308 Application * KNotifyWidget::addApplicationEvents( const QString& path )
00309 {
00310     kdDebug() << "**** knotify: adding path: " << path << endl;
00311     QString relativePath = path;
00312 
00313     if ( path.at(0) == '/' && KStandardDirs::exists( path ) )
00314         relativePath = makeRelative( path );
00315 
00316     if ( !relativePath.isEmpty() )
00317     {
00318         Application *app = new Application( relativePath );
00319         m_allApps.append( app );
00320         return app;
00321     }
00322 
00323     return 0L;
00324 }
00325 
00326 void KNotifyWidget::clear()
00327 {
00328     clearVisible();
00329     m_allApps.clear();
00330 }
00331 
00332 void KNotifyWidget::clearVisible()
00333 {
00334     m_visibleApps.clear();
00335     m_listview->clear();
00336     slotEventChanged( 0L ); // disable widgets
00337 }
00338 
00339 void KNotifyWidget::showEvent( QShowEvent *e )
00340 {
00341     selectItem( m_listview->firstChild() );
00342     KNotifyWidgetBase::showEvent( e );
00343 }
00344 
00345 void KNotifyWidget::slotEventChanged( QListViewItem *item )
00346 {
00347     bool on = (item != 0L);
00348 
00349     m_actionsBox->setEnabled( on );
00350     m_controlsBox->setEnabled( on );
00351 
00352     if ( !on )
00353         return;
00354 
00355     ListViewItem *lit = static_cast<ListViewItem*>( item );
00356     updateWidgets( lit );
00357 }
00358 
00359 void KNotifyWidget::updateWidgets( ListViewItem *item )
00360 {
00361     bool enable;
00362     bool checked;
00363 
00364     blockSignals( true ); // don't emit changed() signals
00365 
00366     const Event& event = item->event();
00367 
00368     // sound settings
00369     m_playButton->setEnabled( !event.soundfile.isEmpty() );
00370     m_soundPath->setURL( event.soundfile );
00371     enable = (event.dontShow & KNotifyClient::Sound) == 0;
00372     checked = enable && !event.soundfile.isEmpty() &&
00373               (event.presentation & KNotifyClient::Sound);
00374     m_playSound->setEnabled( enable );
00375     m_playSound->setChecked( checked );
00376     m_soundPath->setEnabled( checked );
00377 
00378 
00379     // logfile settings
00380     m_logfilePath->setURL( event.logfile );
00381     enable = (event.dontShow & KNotifyClient::Logfile) == 0;
00382     checked = enable && !event.logfile.isEmpty()  &&
00383               (event.presentation & KNotifyClient::Logfile);
00384     m_logToFile->setEnabled( enable );
00385     m_logToFile->setChecked( checked );
00386     m_logfilePath->setEnabled( checked );
00387 
00388 
00389     // execute program settings
00390     m_executePath->setURL( event.commandline );
00391     enable = (event.dontShow & KNotifyClient::Execute) == 0;
00392     checked = enable && !event.commandline.isEmpty() &&
00393               (event.presentation & KNotifyClient::Execute);
00394     m_execute->setEnabled( enable );
00395     m_execute->setChecked( checked );
00396     m_executePath->setEnabled( checked );
00397 
00398 
00399     // other settings
00400     m_messageBox->setChecked(event.presentation & (KNotifyClient::Messagebox | KNotifyClient::PassivePopup));
00401     m_passivePopup->setChecked(event.presentation & KNotifyClient::PassivePopup);
00402     m_stderr->setChecked( event.presentation & KNotifyClient::Stderr );
00403 
00404     updatePixmaps( item );
00405 
00406     blockSignals( false );
00407 }
00408 
00409 void KNotifyWidget::updatePixmaps( ListViewItem *item )
00410 {
00411     QPixmap emptyPix;
00412     Event &event = item->event();
00413 
00414     bool doIt = (event.presentation & KNotifyClient::Execute) &&
00415                 !event.commandline.isEmpty();
00416     item->setPixmap( COL_EXECUTE, doIt ? d->pixmaps[COL_EXECUTE] : emptyPix );
00417 
00418     doIt = (event.presentation & KNotifyClient::Sound) && 
00419            !event.soundfile.isEmpty();
00420     item->setPixmap( COL_SOUND, doIt ? d->pixmaps[COL_SOUND] : emptyPix );
00421 
00422     doIt = (event.presentation & KNotifyClient::Logfile) &&
00423            !event.logfile.isEmpty();
00424     item->setPixmap( COL_LOGFILE, doIt ? d->pixmaps[COL_LOGFILE] : emptyPix );
00425 
00426     item->setPixmap( COL_MESSAGE,
00427                      (event.presentation &
00428                       (KNotifyClient::Messagebox | KNotifyClient::PassivePopup)) ?
00429                      d->pixmaps[COL_MESSAGE] : emptyPix );
00430 
00431     item->setPixmap( COL_STDERR,
00432                      (event.presentation & KNotifyClient::Stderr) ?
00433                      d->pixmaps[COL_STDERR] : emptyPix );
00434 }
00435 
00436 void KNotifyWidget::addVisibleApp( Application *app )
00437 {
00438     if ( !app || (m_visibleApps.findRef( app ) != -1) )
00439         return;
00440 
00441     m_visibleApps.append( app );
00442     addToView( app->eventList() );
00443 
00444     QListViewItem *item = m_listview->selectedItem();
00445     if ( !item )
00446         item = m_listview->firstChild();
00447 
00448     selectItem( item );
00449 }
00450 
00451 void KNotifyWidget::addToView( const EventList& events )
00452 {
00453     ListViewItem *item = 0L;
00454 
00455     EventListIterator it( events );
00456 
00457     for ( ; it.current(); ++it )
00458     {
00459         Event *event = it.current();
00460         item = new ListViewItem( m_listview, event );
00461 
00462         if ( (event->presentation & KNotifyClient::Execute) &&
00463              !event->commandline.isEmpty() )
00464             item->setPixmap( COL_EXECUTE, d->pixmaps[COL_EXECUTE] );
00465         if ( (event->presentation & KNotifyClient::Sound) &&
00466              !event->soundfile.isEmpty() )
00467             item->setPixmap( COL_SOUND, d->pixmaps[COL_SOUND] );
00468         if ( (event->presentation & KNotifyClient::Logfile) &&
00469              !event->logfile.isEmpty() )
00470             item->setPixmap( COL_LOGFILE, d->pixmaps[COL_LOGFILE] );
00471         if ( event->presentation & (KNotifyClient::Messagebox|KNotifyClient::PassivePopup) )
00472             item->setPixmap( COL_MESSAGE, d->pixmaps[COL_MESSAGE] );
00473         if ( event->presentation & KNotifyClient::Stderr )
00474             item->setPixmap( COL_STDERR, d->pixmaps[COL_STDERR] );
00475     }
00476 }
00477 
00478 void KNotifyWidget::widgetChanged( QListViewItem *item,
00479                                    int what, bool on, QWidget *buddy )
00480 {
00481     if ( signalsBlocked() )
00482         return;
00483 
00484     if ( buddy )
00485         buddy->setEnabled( on );
00486 
00487     Event &e = static_cast<ListViewItem*>( item )->event();
00488     if ( on )
00489     {
00490         e.presentation |= what;
00491         if ( buddy )
00492             buddy->setFocus();
00493     }
00494     else
00495         e.presentation &= ~what;
00496 
00497     emit changed( true );
00498 }
00499 
00500 void KNotifyWidget::soundToggled( bool on )
00501 {
00502     QListViewItem *item = m_listview->currentItem();
00503     if ( !item )
00504         return;
00505     bool doIcon = on && !m_soundPath->url().isEmpty();
00506     item->setPixmap( COL_SOUND, doIcon ? d->pixmaps[COL_SOUND] : QPixmap() );
00507     widgetChanged( item, KNotifyClient::Sound, on, m_soundPath );
00508 }
00509 
00510 void KNotifyWidget::loggingToggled( bool on )
00511 {
00512     QListViewItem *item = m_listview->currentItem();
00513     if ( !item )
00514         return;
00515     bool doIcon = on && !m_logfilePath->url().isEmpty();
00516     item->setPixmap(COL_LOGFILE, doIcon ? d->pixmaps[COL_LOGFILE] : QPixmap());
00517     widgetChanged( item, KNotifyClient::Logfile, on, m_logfilePath );
00518 }
00519 
00520 void KNotifyWidget::executeToggled( bool on )
00521 {
00522     QListViewItem *item = m_listview->currentItem();
00523     if ( !item )
00524         return;
00525     bool doIcon = on && !m_executePath->url().isEmpty();
00526     item->setPixmap(COL_EXECUTE, doIcon ? d->pixmaps[COL_EXECUTE] : QPixmap());
00527     widgetChanged( item, KNotifyClient::Execute, on, m_executePath );
00528 }
00529 
00530 void KNotifyWidget::messageBoxChanged()
00531 {
00532     if ( signalsBlocked() )
00533         return;
00534 
00535     m_passivePopup->setEnabled( m_messageBox->isChecked() );
00536 
00537     QListViewItem *item = m_listview->currentItem();
00538     if ( !item )
00539         return;
00540 
00541     bool on = m_passivePopup->isEnabled();
00542     item->setPixmap( COL_MESSAGE, on ? d->pixmaps[COL_MESSAGE] : QPixmap() );
00543 
00544     Event &e = static_cast<ListViewItem*>( item )->event();
00545 
00546     if ( m_messageBox->isChecked() ) {
00547     if ( m_passivePopup->isChecked() ) {
00548         e.presentation |= KNotifyClient::PassivePopup;
00549         e.presentation &= ~KNotifyClient::Messagebox;
00550     }
00551     else {
00552         e.presentation &= ~KNotifyClient::PassivePopup;
00553         e.presentation |= KNotifyClient::Messagebox;
00554     }
00555     }
00556     else {
00557         e.presentation &= ~KNotifyClient::Messagebox;
00558         e.presentation &= ~KNotifyClient::PassivePopup;
00559     }
00560 
00561     emit changed( true );
00562 }
00563 
00564 void KNotifyWidget::stderrToggled( bool on )
00565 {
00566     QListViewItem *item = m_listview->currentItem();
00567     if ( !item )
00568         return;
00569     item->setPixmap( COL_STDERR, on ? d->pixmaps[COL_STDERR] : QPixmap() );
00570     widgetChanged( item, KNotifyClient::Stderr, on );
00571 }
00572 
00573 void KNotifyWidget::soundFileChanged( const QString& text )
00574 {
00575     if ( signalsBlocked() )
00576         return;
00577 
00578     QListViewItem *item = m_listview->currentItem();
00579     if ( !item )
00580         return;
00581 
00582     m_playButton->setEnabled( !text.isEmpty() );
00583 
00584     currentEvent()->soundfile = text;
00585     bool ok = !text.isEmpty() && m_playSound->isChecked();
00586     item->setPixmap( COL_SOUND, ok ? d->pixmaps[COL_SOUND] : QPixmap() );
00587 
00588     emit changed( true );
00589 }
00590 
00591 void KNotifyWidget::logfileChanged( const QString& text )
00592 {
00593     if ( signalsBlocked() )
00594         return;
00595 
00596     QListViewItem *item = m_listview->currentItem();
00597     if ( !item )
00598         return;
00599 
00600     currentEvent()->logfile = text;
00601     bool ok = !text.isEmpty() && m_logToFile->isChecked();
00602     item->setPixmap( COL_LOGFILE, ok ? d->pixmaps[COL_LOGFILE] : QPixmap() );
00603     
00604     emit changed( true );
00605 }
00606 
00607 void KNotifyWidget::commandlineChanged( const QString& text )
00608 {
00609     if ( signalsBlocked() )
00610         return;
00611 
00612     QListViewItem *item = m_listview->currentItem();
00613     if ( !item )
00614         return;
00615 
00616     currentEvent()->commandline = text;
00617     bool ok = !text.isEmpty() && m_execute->isChecked();
00618     item->setPixmap( COL_EXECUTE, ok ? d->pixmaps[COL_EXECUTE] : QPixmap() );
00619 
00620     emit changed( true );
00621 }
00622 
00623 void KNotifyWidget::slotItemClicked( QListViewItem *item, const QPoint&, 
00624                                      int col )
00625 {
00626     if ( !item || !item->isSelected() )
00627         return;
00628 
00629     Event *event = currentEvent();
00630     if ( !event )
00631         return; // very unlikely, but safety first
00632     
00633     bool doShowAdvanced = false;
00634     
00635     switch( col )
00636     {
00637         case COL_EXECUTE:
00638             m_execute->toggle();
00639             m_executePath->setFocus();
00640             doShowAdvanced = true;
00641             break;
00642         case COL_STDERR:
00643             m_stderr->toggle();
00644             break;
00645         case COL_MESSAGE:
00646             m_passivePopup->setChecked( true ); // default to passive popups
00647             m_messageBox->toggle();
00648             break;
00649         case COL_LOGFILE:
00650             m_logToFile->toggle();
00651             m_logfilePath->setFocus();
00652             doShowAdvanced = true;
00653             break;
00654         case COL_SOUND:
00655             m_playSound->toggle();
00656             break;
00657         default: // do nothing
00658             break;
00659     }
00660     
00661     if ( doShowAdvanced && !m_logToFile->isVisible() )
00662     {
00663         showAdvanced( true );
00664         m_listview->ensureItemVisible( m_listview->currentItem() );
00665     }
00666 }
00667 
00668 void KNotifyWidget::sort( bool ascending )
00669 {
00670     m_listview->setSorting( COL_EVENT, ascending );
00671     m_listview->sort();
00672 }
00673 
00674 void KNotifyWidget::selectItem( QListViewItem *item )
00675 {
00676     if ( item )
00677     {
00678         m_listview->setCurrentItem( item );
00679         item->setSelected( true );
00680         slotEventChanged( item );
00681     }
00682 }
00683 
00684 void KNotifyWidget::resetDefaults( bool ask )
00685 {
00686     if ( ask )
00687     {
00688         if ( KMessageBox::warningContinueCancel(this,
00689                                    i18n("This will cause the notifications "
00690                                         "to be reset to their defaults!"),
00691                                                 i18n("Are you sure?"),
00692                                                 i18n("Continue"))
00693              != KMessageBox::Continue)
00694             return;
00695     }
00696 
00697     reload( true ); // defaults
00698     emit changed( true );
00699 }
00700 
00701 void KNotifyWidget::reload( bool revertToDefaults )
00702 {
00703     m_listview->clear();
00704     ApplicationListIterator it( m_visibleApps );
00705     for ( ; it.current(); ++it )
00706     {
00707         it.current()->reloadEvents( revertToDefaults );
00708         addToView( it.current()->eventList() );
00709     }
00710 
00711     m_listview->sort();
00712     selectItem( m_listview->firstChild()  );
00713 }
00714 
00715 void KNotifyWidget::save()
00716 {
00717     kdDebug() << "save\n";
00718 
00719     ApplicationListIterator it( m_allApps );
00720     while ( it.current() )
00721     {
00722         (*it)->save();
00723         ++it;
00724     }
00725 
00726     if ( kapp )
00727     {
00728         if ( !kapp->dcopClient()->isAttached() )
00729             kapp->dcopClient()->attach();
00730         kapp->dcopClient()->send("knotify", "", "reconfigure()", "");
00731     }
00732 
00733     emit changed( false );
00734 }
00735 
00736 // returns e.g. "kwin/eventsrc" from a given path
00737 // "/opt/kde3/share/apps/kwin/eventsrc"
00738 QString KNotifyWidget::makeRelative( const QString& fullPath )
00739 {
00740     int slash = fullPath.findRev( '/' ) - 1;
00741     slash = fullPath.findRev( '/', slash );
00742 
00743     if ( slash < 0 )
00744         return QString::null;
00745 
00746     return fullPath.mid( slash+1 );
00747 }
00748 
00749 Event * KNotifyWidget::currentEvent()
00750 {
00751     QListViewItem *current = m_listview->currentItem();
00752     if ( !current )
00753         return 0L;
00754 
00755     return &static_cast<ListViewItem*>( current )->event();
00756 }
00757 
00758 void KNotifyWidget::openSoundDialog( KURLRequester *requester )
00759 {
00760     // only need to init this once
00761     requester->disconnect( SIGNAL( openFileDialog( KURLRequester * )),
00762                            this, SLOT( openSoundDialog( KURLRequester * )));
00763 
00764     KFileDialog *fileDialog = requester->fileDialog();
00765     fileDialog->setCaption( i18n("Select Sound File") );
00766     QStringList filters;
00767     filters << "audio/x-wav" << "audio/x-mp3" << "application/x-ogg"
00768             << "audio/x-adpcm";
00769     fileDialog->setMimeFilter( filters );
00770 
00771     // find the first "sound"-resource that contains files
00772     const Application *app = currentEvent()->application();
00773     QStringList soundDirs =
00774         KGlobal::dirs()->findDirs("data", app->appName() + "/sounds");
00775     soundDirs += KGlobal::dirs()->resourceDirs( "sound" );
00776 
00777     if ( !soundDirs.isEmpty() ) {
00778         KURL soundURL;
00779         QDir dir;
00780         dir.setFilter( QDir::Files | QDir::Readable );
00781         QStringList::ConstIterator it = soundDirs.begin();
00782         while ( it != soundDirs.end() ) {
00783             dir = *it;
00784             if ( dir.isReadable() && dir.count() > 2 ) {
00785                 soundURL.setPath( *it );
00786                 fileDialog->setURL( soundURL );
00787                 break;
00788             }
00789             ++it;
00790         }
00791     }
00792 }
00793 
00794 void KNotifyWidget::openLogDialog( KURLRequester *requester )
00795 {
00796     // only need to init this once
00797     requester->disconnect( SIGNAL( openFileDialog( KURLRequester * )),
00798                            this, SLOT( openLogDialog( KURLRequester * )));
00799 
00800     KFileDialog *fileDialog = requester->fileDialog();
00801     fileDialog->setCaption( i18n("Select Log File") );
00802     QStringList filters;
00803     filters << "text/x-log" << "text/plain";
00804     fileDialog->setMimeFilter( filters );
00805 }
00806 
00807 void KNotifyWidget::openExecDialog( KURLRequester *requester )
00808 {
00809     // only need to init this once
00810     requester->disconnect( SIGNAL( openFileDialog( KURLRequester * )),
00811                            this, SLOT( openExecDialog( KURLRequester * )));
00812 
00813 
00814     KFileDialog *fileDialog = requester->fileDialog();
00815     fileDialog->setCaption( i18n("Select File to Execute") );
00816     QStringList filters;
00817     filters << "application/x-executable" << "application/x-shellscript"
00818             << "application/x-perl" << "application/x-python";
00819     fileDialog->setMimeFilter( filters );
00820 }
00821 
00822 void KNotifyWidget::playSound()
00823 {
00824     KAudioPlayer::play( m_soundPath->url() );
00825 }
00826 
00827 void KNotifyWidget::enableAll()
00828 {
00829     bool enable = (sender() == m_buttonEnable);
00830     enableAll( SelectionCombo::type(enable ? m_comboEnable : m_comboDisable),
00831                enable );
00832 }
00833 
00834 void KNotifyWidget::enableAll( int what, bool enable )
00835 {
00836     if ( m_listview->childCount() == 0 )
00837         return;
00838 
00839     bool affectAll = m_affectAllApps->isChecked(); // multi-apps mode
00840 
00841     ApplicationListIterator appIt( affectAll ? m_allApps : m_visibleApps );
00842     for ( ; appIt.current(); ++appIt )
00843     {
00844         const EventList& events = appIt.current()->eventList();
00845         EventListIterator it( events );
00846         for ( ; it.current(); ++it )
00847         {
00848             if ( enable )
00849                 it.current()->presentation |= what;
00850             else
00851                 it.current()->presentation &= ~what;
00852         }
00853     }
00854 
00855     // now make the listview reflect the changes
00856     QListViewItemIterator it( m_listview->firstChild() );
00857     for ( ; it.current(); ++it )
00858     {
00859         ListViewItem *item = static_cast<ListViewItem*>( it.current() );
00860         updatePixmaps( item );
00861     }
00862 
00863     QListViewItem *item = m_listview->currentItem();
00864     if ( !item )
00865         item = m_listview->firstChild();
00866     selectItem( item );
00867 
00868     emit changed( true );
00869 }
00870 
00871 
00874 
00875 
00876 //
00877 // path must be "appname/eventsrc", i.e. a relative path
00878 //
00879 Application::Application( const QString &path )
00880 {
00881     QString config_file = path;
00882     config_file[config_file.find('/')] = '.';
00883     m_events = 0L;
00884     config = new KConfig(config_file, false, false);
00885     kc = new KConfig(path, true, false, "data");
00886     kc->setGroup( QString::fromLatin1("!Global!") );
00887     m_icon = kc->readEntry(QString::fromLatin1("IconName"),
00888                            QString::fromLatin1("misc"));
00889     m_description = kc->readEntry( QString::fromLatin1("Comment"),
00890                                    i18n("No description available") );
00891 
00892     int index = path.find( '/' );
00893     if ( index >= 0 )
00894         m_appname = path.left( index );
00895     else
00896         kdDebug() << "Cannot determine application name from path: " << path << endl;
00897 }
00898 
00899 Application::~Application()
00900 {
00901     delete config;
00902     delete kc;
00903     delete m_events;
00904 }
00905 
00906 
00907 const EventList&  Application::eventList()
00908 {
00909     if ( !m_events ) {
00910         m_events = new EventList;
00911         m_events->setAutoDelete( true );
00912         reloadEvents();
00913     }
00914 
00915     return *m_events;
00916 }
00917 
00918 
00919 void Application::save()
00920 {
00921     if ( !m_events )
00922         return;
00923 
00924     EventListIterator it( *m_events );
00925     Event *e;
00926     while ( (e = it.current()) ) {
00927         config->setGroup( e->configGroup );
00928         config->writeEntry( "presentation", e->presentation );
00929         config->writeEntry( "soundfile", e->soundfile );
00930         config->writeEntry( "logfile", e->logfile );
00931         config->writeEntry( "commandline", e->commandline );
00932 
00933         ++it;
00934     }
00935     config->sync();
00936 }
00937 
00938 
00939 void Application::reloadEvents( bool revertToDefaults )
00940 {
00941     if ( m_events )
00942         m_events->clear();
00943     else
00944     {
00945         m_events = new EventList;
00946         m_events->setAutoDelete( true );
00947     }
00948 
00949     Event *e = 0L;
00950 
00951     QString global = QString::fromLatin1("!Global!");
00952     QString default_group = QString::fromLatin1("<default>");
00953     QString name = QString::fromLatin1("Name");
00954     QString comment = QString::fromLatin1("Comment");
00955 
00956     QStringList conflist = kc->groupList();
00957     QStringList::ConstIterator it = conflist.begin();
00958 
00959     while ( it != conflist.end() ) {
00960         if ( (*it) != global && (*it) != default_group ) { // event group
00961             kc->setGroup( *it );
00962 
00963             e = new Event( this );
00964             e->name = kc->readEntry( name );
00965             e->description = kc->readEntry( comment );
00966             e->configGroup = *it;
00967 
00968             if ( e->name.isEmpty() || e->description.isEmpty() )
00969                 delete e;
00970 
00971             else { // load the event
00972                 // default to passive popups over plain messageboxes
00973                 int default_rep = kc->readNumEntry("default_presentation", 
00974                                                    0 | KNotifyClient::PassivePopup);
00975                 QString default_logfile = kc->readPathEntry("default_logfile");
00976                 QString default_soundfile = kc->readPathEntry("default_sound");
00977                 QString default_commandline = kc->readPathEntry("default_commandline");
00978                 config->setGroup(*it);
00979                 e->dontShow = config->readNumEntry("nopresentation", 0 );
00980 
00981                 if ( revertToDefaults )
00982                 {
00983                     e->presentation = default_rep;
00984                     e->logfile = default_logfile;
00985                     e->soundfile = default_soundfile;
00986                     e->commandline = default_commandline;
00987                 }
00988 
00989                 else
00990                 {
00991                     e->presentation = config->readNumEntry("presentation",
00992                                                            default_rep);
00993                     e->logfile = config->readPathEntry("logfile",
00994                                                    default_logfile);
00995                     e->soundfile = config->readPathEntry("soundfile",
00996                                                      default_soundfile);
00997                     e->commandline = config->readPathEntry("commandline",
00998                                                        default_commandline);
00999                 }
01000 
01001                 m_events->append( e );
01002             }
01003         }
01004 
01005         ++it;
01006     }
01007 
01008     return;
01009 }
01010 
01013 
01014 ListViewItem::ListViewItem( QListView *view, Event *event )
01015     : QListViewItem( view ),
01016       m_event( event )
01017 {
01018     setText( COL_EVENT, event->text() );
01019 }
01020 
01021 int ListViewItem::compare ( QListViewItem * i, int col, bool ascending ) const
01022 {
01023     ListViewItem *item = static_cast<ListViewItem*>( i );
01024     int myPres = m_event->presentation;
01025     int otherPres = item->event().presentation;
01026 
01027     int action = 0;
01028 
01029     switch ( col )
01030     {
01031         case COL_EVENT: // use default sorting
01032             return QListViewItem::compare( i, col, ascending );
01033 
01034         case COL_EXECUTE:
01035             action = KNotifyClient::Execute;
01036             break;
01037         case COL_LOGFILE:
01038             action = KNotifyClient::Logfile;
01039             break;
01040         case COL_MESSAGE:
01041             action = (KNotifyClient::Messagebox | KNotifyClient::PassivePopup);
01042             break;
01043         case COL_SOUND:
01044             action = KNotifyClient::Sound;
01045             break;
01046         case COL_STDERR:
01047             action = KNotifyClient::Stderr;
01048             break;
01049     }
01050 
01051     if ( (myPres & action) == (otherPres & action) )
01052     {
01053         // default sorting by event
01054         return QListViewItem::compare( i, COL_EVENT, true );
01055     }
01056 
01057     if ( myPres & action )
01058         return -1;
01059     if ( otherPres & action )
01060         return 1;
01061 
01062     return 0;
01063 }
01064 
01065 #include "knotifydialog.moc"
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.4.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 27 22:15:31 2005 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001