# kio Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

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

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