00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00069
00070
00071 namespace KNotify
00072 {
00073 class SelectionCombo
00074 {
00075 public:
00076
00077
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
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 );
00205 }
00206
00207
00210
00211
00212 class KNotifyWidget::Private
00213 {
00214 public:
00215 QPixmap pixmaps[6];
00216 KNotifyToolTip *toolTip;
00217 };
00218
00219
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 );
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 );
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 );
00429
00430 const Event& event = item->event();
00431
00432
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
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
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
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;
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 );
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:
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 );
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
00830
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
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
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
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
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
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();
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
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
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 ) {
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 {
01093 if( !e->name.isEmpty() && e->description.isEmpty() )
01094 e->description = e->name;
01095
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:
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
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"