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