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