• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kio

knotifydialog.cpp

Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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("Advanced <<") );
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("Advanced >>") );
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     QString soundPath = m_soundPath->url();
00918     if (!KIO::NetAccess::exists( m_soundPath->url(), true, 0 )) {        
00919         bool foundSound=false;
00920 
00921         // find the first "sound"-resource that contains files
00922         const Application *app = currentEvent()->application();
00923         QStringList soundDirs = KGlobal::dirs()->findDirs("data", app->appName() + "/sounds");
00924         soundDirs += KGlobal::dirs()->resourceDirs( "sound" );
00925 
00926         if ( !soundDirs.isEmpty() ) {
00927            QDir dir;
00928            dir.setFilter( QDir::Files | QDir::Readable );
00929            QStringList::ConstIterator it = soundDirs.begin();
00930            while ( it != soundDirs.end() ) {
00931                dir = *it;
00932                if ( dir.isReadable() && dir.count() > 2 && 
00933                 KIO::NetAccess::exists( *it + m_soundPath->url(), true, 0 )) {
00934                        foundSound=true;
00935                        soundPath = *it + m_soundPath->url();
00936                        break;
00937                }
00938                ++it;
00939            }
00940         }
00941         if ( !foundSound ) {
00942             KMessageBox::sorry(this, i18n("The specified file does not exist." ));
00943             return;
00944         }
00945     }
00946     KAudioPlayer::play( soundPath );
00947 }
00948 
00949 void KNotifyWidget::enableAll()
00950 {
00951     bool enable = (sender() == m_buttonEnable);
00952     enableAll( SelectionCombo::type(enable ? m_comboEnable : m_comboDisable),
00953                enable );
00954 }
00955 
00956 void KNotifyWidget::enableAll( int what, bool enable )
00957 {
00958     if ( m_listview->childCount() == 0 )
00959         return;
00960 
00961     bool affectAll = m_affectAllApps->isChecked(); // multi-apps mode
00962 
00963     ApplicationListIterator appIt( affectAll ? m_allApps : m_visibleApps );
00964     for ( ; appIt.current(); ++appIt )
00965     {
00966         const EventList& events = appIt.current()->eventList();
00967         EventListIterator it( events );
00968         for ( ; it.current(); ++it )
00969         {
00970             if ( enable )
00971                 it.current()->presentation |= what;
00972             else
00973                 it.current()->presentation &= ~what;
00974         }
00975     }
00976 
00977     // now make the listview reflect the changes
00978     QListViewItemIterator it( m_listview->firstChild() );
00979     for ( ; it.current(); ++it )
00980     {
00981         ListViewItem *item = static_cast<ListViewItem*>( it.current() );
00982         updatePixmaps( item );
00983     }
00984 
00985     QListViewItem *item = m_listview->currentItem();
00986     if ( !item )
00987         item = m_listview->firstChild();
00988     selectItem( item );
00989 
00990     emit changed( true );
00991 }
00992 
00993 
00996 
00997 
00998 //
00999 // path must be "appname/eventsrc", i.e. a relative path
01000 //
01001 Application::Application( const QString &path )
01002 {
01003     QString config_file = path;
01004     config_file[config_file.find('/')] = '.';
01005     m_events = 0L;
01006     config = new KConfig(config_file, false, false);
01007     kc = new KConfig(path, true, false, "data");
01008     kc->setGroup( QString::fromLatin1("!Global!") );
01009     m_icon = kc->readEntry(QString::fromLatin1("IconName"),
01010                            QString::fromLatin1("misc"));
01011     m_description = kc->readEntry( QString::fromLatin1("Comment"),
01012                                    i18n("No description available") );
01013 
01014     int index = path.find( '/' );
01015     if ( index >= 0 )
01016         m_appname = path.left( index );
01017     else
01018         kdDebug() << "Cannot determine application name from path: " << path << endl;
01019 }
01020 
01021 Application::~Application()
01022 {
01023     delete config;
01024     delete kc;
01025     delete m_events;
01026 }
01027 
01028 
01029 const EventList&  Application::eventList()
01030 {
01031     if ( !m_events ) {
01032         m_events = new EventList;
01033         m_events->setAutoDelete( true );
01034         reloadEvents();
01035     }
01036 
01037     return *m_events;
01038 }
01039 
01040 
01041 void Application::save()
01042 {
01043     if ( !m_events )
01044         return;
01045 
01046     EventListIterator it( *m_events );
01047     Event *e;
01048     while ( (e = it.current()) ) {
01049         config->setGroup( e->configGroup );
01050         config->writeEntry( "presentation", e->presentation );
01051         config->writePathEntry( "soundfile", e->soundfile );
01052         config->writePathEntry( "logfile", e->logfile );
01053         config->writePathEntry( "commandline", e->commandline );
01054 
01055         ++it;
01056     }
01057     config->sync();
01058 }
01059 
01060 
01061 void Application::reloadEvents( bool revertToDefaults )
01062 {
01063     if ( m_events )
01064         m_events->clear();
01065     else
01066     {
01067         m_events = new EventList;
01068         m_events->setAutoDelete( true );
01069     }
01070 
01071     Event *e = 0L;
01072 
01073     QString global = QString::fromLatin1("!Global!");
01074     QString default_group = QString::fromLatin1("<default>");
01075     QString name = QString::fromLatin1("Name");
01076     QString comment = QString::fromLatin1("Comment");
01077 
01078     QStringList conflist = kc->groupList();
01079     QStringList::ConstIterator it = conflist.begin();
01080 
01081     while ( it != conflist.end() ) {
01082         if ( (*it) != global && (*it) != default_group ) { // event group
01083             kc->setGroup( *it );
01084 
01085             e = new Event( this );
01086             e->name = kc->readEntry( name );
01087             e->description = kc->readEntry( comment );
01088             e->dontShow = kc->readNumEntry("nopresentation", 0 );
01089             e->configGroup = *it;
01090             if ( e->name.isEmpty() && e->description.isEmpty() )
01091                 delete e;
01092             else { // load the event
01093                 if( !e->name.isEmpty() && e->description.isEmpty() )
01094                         e->description = e->name;
01095                 // default to passive popups over plain messageboxes
01096                 int default_rep = kc->readNumEntry("default_presentation",
01097                                                    0 | KNotifyClient::PassivePopup);
01098                 QString default_logfile = kc->readPathEntry("default_logfile");
01099                 QString default_soundfile = kc->readPathEntry("default_sound");
01100                 QString default_commandline = kc->readPathEntry("default_commandline");
01101 
01102                 config->setGroup(*it);
01103 
01104                 if ( revertToDefaults )
01105                 {
01106                     e->presentation = default_rep;
01107                     e->logfile = default_logfile;
01108                     e->soundfile = default_soundfile;
01109                     e->commandline = default_commandline;
01110                 }
01111 
01112                 else
01113                 {
01114                     e->presentation = config->readNumEntry("presentation",
01115                                                            default_rep);
01116                     e->logfile = config->readPathEntry("logfile",
01117                                                    default_logfile);
01118                     e->soundfile = config->readPathEntry("soundfile",
01119                                                      default_soundfile);
01120                     e->commandline = config->readPathEntry("commandline",
01121                                                        default_commandline);
01122                 }
01123 
01124                 m_events->append( e );
01125             }
01126         }
01127 
01128         ++it;
01129     }
01130 
01131     return;
01132 }
01133 
01136 
01137 ListViewItem::ListViewItem( QListView *view, Event *event )
01138     : QListViewItem( view ),
01139       m_event( event )
01140 {
01141     setText( COL_EVENT, event->text() );
01142 }
01143 
01144 int ListViewItem::compare ( QListViewItem * i, int col, bool ascending ) const
01145 {
01146     ListViewItem *item = static_cast<ListViewItem*>( i );
01147     int myPres = m_event->presentation;
01148     int otherPres = item->event().presentation;
01149 
01150     int action = 0;
01151 
01152     switch ( col )
01153     {
01154         case COL_EVENT: // use default sorting
01155             return QListViewItem::compare( i, col, ascending );
01156 
01157         case COL_EXECUTE:
01158             action = KNotifyClient::Execute;
01159             break;
01160         case COL_LOGFILE:
01161             action = KNotifyClient::Logfile;
01162             break;
01163         case COL_MESSAGE:
01164             action = (KNotifyClient::Messagebox | KNotifyClient::PassivePopup);
01165             break;
01166         case COL_SOUND:
01167             action = KNotifyClient::Sound;
01168             break;
01169         case COL_STDERR:
01170             action = KNotifyClient::Stderr;
01171             break;
01172         case COL_TASKBAR:
01173             action = KNotifyClient::Taskbar;
01174             break;
01175     }
01176 
01177     if ( (myPres & action) == (otherPres & action) )
01178     {
01179         // default sorting by event
01180         return QListViewItem::compare( i, COL_EVENT, true );
01181     }
01182 
01183     if ( myPres & action )
01184         return -1;
01185     if ( otherPres & action )
01186         return 1;
01187 
01188     return 0;
01189 }
01190 
01191 #include "knotifydialog.moc"

kio

Skip menu "kio"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal