kio Library API Documentation

knotifydialog.cpp

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