2 Copyright (C) 2000,2002 Carsten Pfeiffer <pfeiffer@kde.org>
3 Copyright (C) 2002 Neil Stevens <neil@qualityassistant.com>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation;
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library, If not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include <dcopclient.h>
21 #include <kaboutdata.h>
22 #include <kapplication.h>
23 #include <kaudioplayer.h>
24 #include <kcombobox.h>
28 #include <kfiledialog.h>
29 #include <kiconloader.h>
30 #include <kicontheme.h>
31 #include <klineedit.h>
33 #include <kmessagebox.h>
34 #include <knotifyclient.h>
35 #include <knotifydialog.h>
36 #include <kstandarddirs.h>
37 #include <kurlrequester.h>
38 #include <kio/netaccess.h>
40 #include "knotification.h"
42 #include <qcheckbox.h>
45 #include <qpushbutton.h>
53 using namespace KNotify
;
67 // I don't feel like subclassing KComboBox and find ways to insert that into
76 // Mind the order in fill() and type()
78 static void fill( KComboBox
*combo
)
80 combo
->addItem( i18n("Sounds") );
81 combo
->addItem( i18n("Logging") );
82 combo
->addItem( i18n("Program Execution") );
83 combo
->addItem( i18n("Message Windows") );
84 combo
->addItem( i18n("Passive Windows") );
85 combo
->addItem( i18n("Standard Error Output") );
86 combo
->addItem( i18n("Taskbar") );
89 static int type( KComboBox
*combo
)
91 switch( combo
->currentIndex() )
94 return KNotifyClient::Sound
;
96 return KNotifyClient::Logfile
;
98 return KNotifyClient::Execute
;
100 return KNotifyClient::Messagebox
;
102 return KNotifyClient::PassivePopup
;
104 return KNotifyClient::Stderr
;
106 return KNotifyClient::Taskbar
;
109 return KNotifyClient::None
;
117 int KNotifyDialog::configure( QWidget
*parent
, const char *name
,
118 const KAboutData
*aboutData
)
120 KNotifyDialog
dialog( parent
, name
, true, aboutData
);
121 return dialog
.exec();
124 KNotifyDialog::KNotifyDialog( QWidget
*parent
, const char *name
, bool modal
,
125 const KAboutData
*aboutData
)
126 : KDialogBase(parent
, name
, modal
, i18n("Notification Settings"),
127 Ok
| Apply
| Cancel
| Default
, Ok
, true )
129 KVBox
*box
= makeVBoxMainWidget();
131 m_notifyWidget
= new KNotifyWidget( box
, "knotify widget" );
134 addApplicationEvents( aboutData
->appName() );
136 connect( this, SIGNAL( okClicked() ), m_notifyWidget
, SLOT( save() ));
137 connect( this, SIGNAL( applyClicked() ), m_notifyWidget
, SLOT( save() ));
140 KNotifyDialog::~KNotifyDialog()
144 void KNotifyDialog::addApplicationEvents( const char *appName
)
146 addApplicationEvents( QString::fromUtf8( appName
) +
147 QLatin1String( "/eventsrc" ) );
150 void KNotifyDialog::addApplicationEvents( const QString
& path
)
152 Application
*app
= m_notifyWidget
->addApplicationEvents( path
);
155 m_notifyWidget
->addVisibleApp( app
);
156 m_notifyWidget
->sort();
160 void KNotifyDialog::clearApplicationEvents()
162 m_notifyWidget
->clear();
165 void KNotifyDialog::slotDefault()
167 m_notifyWidget
->resetDefaults( true ); // ask user
171 //////////////////////////////////////////////////////////////////////
172 //////////////////////////////////////////////////////////////////////
175 class KNotifyWidget::Private
183 // simple access to all knotify-handled applications
184 KNotifyWidget::KNotifyWidget( QWidget
*parent
, const char *name
,
186 : KNotifyWidgetBase( parent
, name
? name
: "KNotifyWidget" )
190 m_allApps
.setAutoDelete( true );
192 if ( !handleAllApps
)
194 m_affectAllApps
->hide();
195 m_playerButton
->hide();
198 SelectionCombo::fill( m_comboEnable
);
199 SelectionCombo::fill( m_comboDisable
);
201 m_listview
->setFullWidth( true );
202 m_listview
->setAllColumnsShowFocus( true );
204 QPixmap pexec
= SmallIcon("exec");
205 QPixmap pstderr
= SmallIcon("terminal");
206 QPixmap pmessage
= SmallIcon("info");
207 QPixmap plogfile
= SmallIcon("log");
208 QPixmap psound
= SmallIcon("sound");
209 QPixmap ptaskbar
= SmallIcon("kicker");
211 d
->pixmaps
[COL_EXECUTE
] = pexec
;
212 d
->pixmaps
[COL_STDERR
] = pstderr
;
213 d
->pixmaps
[COL_MESSAGE
] = pmessage
;
214 d
->pixmaps
[COL_LOGFILE
] = plogfile
;
215 d
->pixmaps
[COL_SOUND
] = psound
;
216 d
->pixmaps
[COL_TASKBAR
] = ptaskbar
;
218 int w
= KIcon::SizeSmall
+ 6;
220 Q3Header
*header
= m_listview
->header();
222 header
->setLabel( COL_EXECUTE
, pexec
, QString::null
, w
);
223 header
->setLabel( COL_STDERR
, pstderr
, QString::null
, w
);
224 header
->setLabel( COL_MESSAGE
, pmessage
, QString::null
, w
);
225 header
->setLabel( COL_LOGFILE
, plogfile
, QString::null
, w
);
226 header
->setLabel( COL_SOUND
, psound
, QString::null
, w
);
227 header
->setLabel( COL_TASKBAR
, ptaskbar
, QString::null
, w
);
229 header
->installEventFilter( this );
230 d
->tips
[COL_EXECUTE
] = i18n("Execute a program");
231 d
->tips
[COL_STDERR
] = i18n("Print to Standard error output");
232 d
->tips
[COL_MESSAGE
] = i18n("Display a messagebox");
233 d
->tips
[COL_LOGFILE
] = i18n("Log to a file");
234 d
->tips
[COL_SOUND
] = i18n("Play a sound");
235 d
->tips
[COL_TASKBAR
] = i18n("Flash the taskbar entry");
238 m_playButton
->setIcon( SmallIconSet( "player_play" ) );
239 connect( m_playButton
, SIGNAL( clicked() ), SLOT( playSound() ));
241 connect( m_listview
, SIGNAL( currentChanged( Q3ListViewItem
* ) ),
242 SLOT( slotEventChanged( Q3ListViewItem
* ) ));
243 connect( m_listview
, SIGNAL(clicked( Q3ListViewItem
*, const QPoint
&, int)),
244 SLOT( slotItemClicked( Q3ListViewItem
*, const QPoint
&, int )));
246 connect( m_playSound
, SIGNAL( toggled( bool )),
247 SLOT( soundToggled( bool )) );
248 connect( m_logToFile
, SIGNAL( toggled( bool )),
249 SLOT( loggingToggled( bool )) );
250 connect( m_execute
, SIGNAL( toggled( bool )),
251 SLOT( executeToggled( bool )) );
252 connect( m_messageBox
, SIGNAL( toggled( bool )),
253 SLOT( messageBoxChanged() ) );
254 connect( m_passivePopup
, SIGNAL( toggled( bool )),
255 SLOT( messageBoxChanged() ) );
256 connect( m_stderr
, SIGNAL( toggled( bool )),
257 SLOT( stderrToggled( bool ) ) );
258 connect( m_taskbar
, SIGNAL( toggled( bool )),
259 SLOT( taskbarToggled( bool ) ) );
261 connect( m_soundPath
, SIGNAL( textChanged( const QString
& )),
262 SLOT( soundFileChanged( const QString
& )));
263 connect( m_logfilePath
, SIGNAL( textChanged( const QString
& )),
264 SLOT( logfileChanged( const QString
& ) ));
265 connect( m_executePath
, SIGNAL( textChanged( const QString
& )),
266 SLOT( commandlineChanged( const QString
& ) ));
268 connect( m_soundPath
, SIGNAL( openFileDialog( KURLRequester
* )),
269 SLOT( openSoundDialog( KURLRequester
* )));
270 connect( m_logfilePath
, SIGNAL( openFileDialog( KURLRequester
* )),
271 SLOT( openLogDialog( KURLRequester
* )));
272 connect( m_executePath
, SIGNAL( openFileDialog( KURLRequester
* )),
273 SLOT( openExecDialog( KURLRequester
* )));
275 connect( m_extension
, SIGNAL( clicked() ),
276 SLOT( toggleAdvanced()) );
278 connect( m_buttonEnable
, SIGNAL( clicked() ), SLOT( enableAll() ));
279 connect( m_buttonDisable
, SIGNAL( clicked() ), SLOT( enableAll() ));
281 QString whatsThis
= i18n("<qt>You may use the following macros<br>"
282 "in the commandline:<br>"
283 "<b>%e</b>: for the event name,<br>"
284 "<b>%a</b>: for the name of the application that sent the event,<br>"
285 "<b>%s</b>: for the notification message,<br>"
286 "<b>%w</b>: for the numeric window ID where the event originated,<br>"
287 "<b>%i</b>: for the numeric event ID.");
288 m_execute
->setWhatsThis(whatsThis
);
289 m_executePath
->setWhatsThis(whatsThis
);
291 showAdvanced( false );
293 slotEventChanged( 0L ); // disable widgets by default
296 KNotifyWidget::~KNotifyWidget()
301 void KNotifyWidget::toggleAdvanced()
303 showAdvanced( m_logToFile
->isHidden() );
306 void KNotifyWidget::showAdvanced( bool show
)
310 m_extension
->setText( i18n("Advanced <<") );
311 m_extension
->setToolTip( i18n("Hide advanced options") );
314 m_logfilePath
->show();
316 m_executePath
->show();
317 m_messageBox
->show();
318 m_passivePopup
->show();
322 m_passivePopup
->setEnabled( m_messageBox
->isChecked() );
323 m_actionsBox
->layout()->setSpacing( KDialog::spacingHint() );
327 m_extension
->setText( i18n("Advanced >>") );
328 m_extension
->setToolTip( i18n("Show advanced options") );
331 m_logfilePath
->hide();
333 m_executePath
->hide();
334 m_messageBox
->hide();
335 m_passivePopup
->hide();
339 m_actionsBox
->layout()->setSpacing( 0 );
343 Application
* KNotifyWidget::addApplicationEvents( const QString
& path
)
345 kdDebug() << "**** knotify: adding path: " << path
<< endl
;
346 QString relativePath
= path
;
348 if ( path
.at(0) == '/' && KStandardDirs::exists( path
) )
349 relativePath
= makeRelative( path
);
351 if ( !relativePath
.isEmpty() )
353 Application
*app
= new Application( relativePath
);
354 m_allApps
.append( app
);
361 void KNotifyWidget::clear()
367 void KNotifyWidget::clearVisible()
369 m_visibleApps
.clear();
371 slotEventChanged( 0L ); // disable widgets
374 bool KNotifyWidget::eventFilter( QObject
* watched
, QEvent
* event
)
376 if ( watched
== d
->header
&& event
->type() == QEvent::ToolTip
)
378 QHelpEvent
* he
= static_cast<QHelpEvent
*>(event
);
381 if ( d
->header
->orientation() == Qt::Horizontal
)
382 section
= d
->header
->sectionAt( he
->pos().x() );
384 section
= d
->header
->sectionAt( he
->pos().y() );
386 if ( ( section
< 0 ) || ( static_cast<uint
>( section
) >= (sizeof(d
->tips
) / sizeof(QString
)) ) )
389 QToolTip::showText( d
->header
->sectionRect( section
).bottomLeft(), d
->tips
[section
],
395 return KNotifyWidgetBase::eventFilter(watched
, event
);
398 void KNotifyWidget::showEvent( QShowEvent
*e
)
400 selectItem( m_listview
->firstChild() );
401 KNotifyWidgetBase::showEvent( e
);
404 void KNotifyWidget::slotEventChanged( Q3ListViewItem
*item
)
406 bool on
= (item
!= 0L);
408 m_actionsBox
->setEnabled( on
);
409 m_controlsBox
->setEnabled( on
);
414 ListViewItem
*lit
= static_cast<ListViewItem
*>( item
);
415 updateWidgets( lit
);
418 void KNotifyWidget::updateWidgets( ListViewItem
*item
)
423 blockSignals( true ); // don't emit changed() signals
425 const Event
& event
= item
->event();
428 m_playButton
->setEnabled( !event
.soundfile
.isEmpty() );
429 m_soundPath
->setURL( event
.soundfile
);
430 enable
= (event
.dontShow
& KNotifyClient::Sound
) == 0;
431 checked
= enable
&& !event
.soundfile
.isEmpty() &&
432 (event
.presentation
& KNotifyClient::Sound
);
433 m_playSound
->setEnabled( enable
);
434 m_playSound
->setChecked( checked
);
435 m_soundPath
->setEnabled( checked
);
439 m_logfilePath
->setURL( event
.logfile
);
440 enable
= (event
.dontShow
& KNotifyClient::Logfile
) == 0;
441 checked
= enable
&& !event
.logfile
.isEmpty() &&
442 (event
.presentation
& KNotifyClient::Logfile
);
443 m_logToFile
->setEnabled( enable
);
444 m_logToFile
->setChecked( checked
);
445 m_logfilePath
->setEnabled( checked
);
448 // execute program settings
449 m_executePath
->setURL( event
.commandline
);
450 enable
= (event
.dontShow
& KNotifyClient::Execute
) == 0;
451 checked
= enable
&& !event
.commandline
.isEmpty() &&
452 (event
.presentation
& KNotifyClient::Execute
);
453 m_execute
->setEnabled( enable
);
454 m_execute
->setChecked( checked
);
455 m_executePath
->setEnabled( checked
);
459 m_messageBox
->setChecked(event
.presentation
& (KNotifyClient::Messagebox
| KNotifyClient::PassivePopup
));
460 enable
= (event
.dontShow
& KNotifyClient::Messagebox
) == 0;
461 m_messageBox
->setEnabled( enable
);
463 m_passivePopup
->setChecked(event
.presentation
& KNotifyClient::PassivePopup
);
464 enable
= (event
.dontShow
& KNotifyClient::PassivePopup
) == 0;
465 m_passivePopup
->setEnabled( enable
);
467 m_stderr
->setChecked( event
.presentation
& KNotifyClient::Stderr
);
468 enable
= (event
.dontShow
& KNotifyClient::Stderr
) == 0;
469 m_stderr
->setEnabled( enable
);
471 m_taskbar
->setChecked(event
.presentation
& KNotifyClient::Taskbar
);
472 enable
= (event
.dontShow
& KNotifyClient::Taskbar
) == 0;
473 m_taskbar
->setEnabled( enable
);
475 updatePixmaps( item
);
477 blockSignals( false );
480 void KNotifyWidget::updatePixmaps( ListViewItem
*item
)
483 Event
&event
= item
->event();
485 bool doIt
= (event
.presentation
& KNotifyClient::Execute
) &&
486 !event
.commandline
.isEmpty();
487 item
->setPixmap( COL_EXECUTE
, doIt
? d
->pixmaps
[COL_EXECUTE
] : emptyPix
);
489 doIt
= (event
.presentation
& KNotifyClient::Sound
) &&
490 !event
.soundfile
.isEmpty();
491 item
->setPixmap( COL_SOUND
, doIt
? d
->pixmaps
[COL_SOUND
] : emptyPix
);
493 doIt
= (event
.presentation
& KNotifyClient::Logfile
) &&
494 !event
.logfile
.isEmpty();
495 item
->setPixmap( COL_LOGFILE
, doIt
? d
->pixmaps
[COL_LOGFILE
] : emptyPix
);
497 item
->setPixmap( COL_MESSAGE
,
498 (event
.presentation
&
499 (KNotifyClient::Messagebox
| KNotifyClient::PassivePopup
)) ?
500 d
->pixmaps
[COL_MESSAGE
] : emptyPix
);
502 item
->setPixmap( COL_STDERR
,
503 (event
.presentation
& KNotifyClient::Stderr
) ?
504 d
->pixmaps
[COL_STDERR
] : emptyPix
);
505 item
->setPixmap( COL_TASKBAR
,
506 (event
.presentation
& KNotifyClient::Taskbar
) ?
507 d
->pixmaps
[COL_TASKBAR
] : emptyPix
);
510 void KNotifyWidget::addVisibleApp( Application
*app
)
512 if ( !app
|| (m_visibleApps
.findRef( app
) != -1) )
515 m_visibleApps
.append( app
);
516 addToView( app
->eventList() );
518 Q3ListViewItem
*item
= m_listview
->selectedItem();
520 item
= m_listview
->firstChild();
525 void KNotifyWidget::addToView( const EventList
& events
)
527 ListViewItem
*item
= 0L;
529 EventListIterator
it( events
);
531 for ( ; it
.current(); ++it
)
533 Event
*event
= it
.current();
534 item
= new ListViewItem( m_listview
, event
);
536 if ( (event
->presentation
& KNotifyClient::Execute
) &&
537 !event
->commandline
.isEmpty() )
538 item
->setPixmap( COL_EXECUTE
, d
->pixmaps
[COL_EXECUTE
] );
539 if ( (event
->presentation
& KNotifyClient::Sound
) &&
540 !event
->soundfile
.isEmpty() )
541 item
->setPixmap( COL_SOUND
, d
->pixmaps
[COL_SOUND
] );
542 if ( (event
->presentation
& KNotifyClient::Logfile
) &&
543 !event
->logfile
.isEmpty() )
544 item
->setPixmap( COL_LOGFILE
, d
->pixmaps
[COL_LOGFILE
] );
545 if ( event
->presentation
& (KNotifyClient::Messagebox
|KNotifyClient::PassivePopup
) )
546 item
->setPixmap( COL_MESSAGE
, d
->pixmaps
[COL_MESSAGE
] );
547 if ( event
->presentation
& KNotifyClient::Stderr
)
548 item
->setPixmap( COL_STDERR
, d
->pixmaps
[COL_STDERR
] );
549 if ( event
->presentation
& KNotifyClient::Taskbar
)
550 item
->setPixmap( COL_TASKBAR
, d
->pixmaps
[COL_TASKBAR
] );
554 void KNotifyWidget::widgetChanged( Q3ListViewItem
*item
,
555 int what
, bool on
, QWidget
*buddy
)
557 if ( signalsBlocked() )
561 buddy
->setEnabled( on
);
563 Event
&e
= static_cast<ListViewItem
*>( item
)->event();
566 e
.presentation
|= what
;
571 e
.presentation
&= ~what
;
573 emit
changed( true );
576 void KNotifyWidget::soundToggled( bool on
)
578 Q3ListViewItem
*item
= m_listview
->currentItem();
581 bool doIcon
= on
&& !m_soundPath
->url().isEmpty();
582 item
->setPixmap( COL_SOUND
, doIcon
? d
->pixmaps
[COL_SOUND
] : QPixmap() );
583 widgetChanged( item
, KNotifyClient::Sound
, on
, m_soundPath
);
586 void KNotifyWidget::loggingToggled( bool on
)
588 Q3ListViewItem
*item
= m_listview
->currentItem();
591 bool doIcon
= on
&& !m_logfilePath
->url().isEmpty();
592 item
->setPixmap(COL_LOGFILE
, doIcon
? d
->pixmaps
[COL_LOGFILE
] : QPixmap());
593 widgetChanged( item
, KNotifyClient::Logfile
, on
, m_logfilePath
);
596 void KNotifyWidget::executeToggled( bool on
)
598 Q3ListViewItem
*item
= m_listview
->currentItem();
601 bool doIcon
= on
&& !m_executePath
->url().isEmpty();
602 item
->setPixmap(COL_EXECUTE
, doIcon
? d
->pixmaps
[COL_EXECUTE
] : QPixmap());
603 widgetChanged( item
, KNotifyClient::Execute
, on
, m_executePath
);
606 void KNotifyWidget::messageBoxChanged()
608 if ( signalsBlocked() )
611 m_passivePopup
->setEnabled( m_messageBox
->isChecked() );
613 Q3ListViewItem
*item
= m_listview
->currentItem();
617 bool on
= m_passivePopup
->isEnabled();
618 item
->setPixmap( COL_MESSAGE
, on
? d
->pixmaps
[COL_MESSAGE
] : QPixmap() );
620 Event
&e
= static_cast<ListViewItem
*>( item
)->event();
622 if ( m_messageBox
->isChecked() ) {
623 if ( m_passivePopup
->isChecked() ) {
624 e
.presentation
|= KNotifyClient::PassivePopup
;
625 e
.presentation
&= ~KNotifyClient::Messagebox
;
628 e
.presentation
&= ~KNotifyClient::PassivePopup
;
629 e
.presentation
|= KNotifyClient::Messagebox
;
633 e
.presentation
&= ~KNotifyClient::Messagebox
;
634 e
.presentation
&= ~KNotifyClient::PassivePopup
;
637 emit
changed( true );
640 void KNotifyWidget::stderrToggled( bool on
)
642 Q3ListViewItem
*item
= m_listview
->currentItem();
645 item
->setPixmap( COL_STDERR
, on
? d
->pixmaps
[COL_STDERR
] : QPixmap() );
646 widgetChanged( item
, KNotifyClient::Stderr
, on
);
649 void KNotifyWidget::taskbarToggled( bool on
)
651 Q3ListViewItem
*item
= m_listview
->currentItem();
654 item
->setPixmap( COL_TASKBAR
, on
? d
->pixmaps
[COL_TASKBAR
] : QPixmap() );
655 widgetChanged( item
, KNotifyClient::Taskbar
, on
);
658 void KNotifyWidget::soundFileChanged( const QString
& text
)
660 if ( signalsBlocked() )
663 Q3ListViewItem
*item
= m_listview
->currentItem();
667 m_playButton
->setEnabled( !text
.isEmpty() );
669 currentEvent()->soundfile
= text
;
670 bool ok
= !text
.isEmpty() && m_playSound
->isChecked();
671 item
->setPixmap( COL_SOUND
, ok
? d
->pixmaps
[COL_SOUND
] : QPixmap() );
673 emit
changed( true );
676 void KNotifyWidget::logfileChanged( const QString
& text
)
678 if ( signalsBlocked() )
681 Q3ListViewItem
*item
= m_listview
->currentItem();
685 currentEvent()->logfile
= text
;
686 bool ok
= !text
.isEmpty() && m_logToFile
->isChecked();
687 item
->setPixmap( COL_LOGFILE
, ok
? d
->pixmaps
[COL_LOGFILE
] : QPixmap() );
689 emit
changed( true );
692 void KNotifyWidget::commandlineChanged( const QString
& text
)
694 if ( signalsBlocked() )
697 Q3ListViewItem
*item
= m_listview
->currentItem();
701 currentEvent()->commandline
= text
;
702 bool ok
= !text
.isEmpty() && m_execute
->isChecked();
703 item
->setPixmap( COL_EXECUTE
, ok
? d
->pixmaps
[COL_EXECUTE
] : QPixmap() );
705 emit
changed( true );
708 void KNotifyWidget::slotItemClicked( Q3ListViewItem
*item
, const QPoint
&,
711 if ( !item
|| !item
->isSelected() )
714 Event
*event
= currentEvent();
716 return; // very unlikely, but safety first
718 bool doShowAdvanced
= false;
724 m_executePath
->setFocus();
725 doShowAdvanced
= true;
734 m_passivePopup
->setChecked( true ); // default to passive popups
735 m_messageBox
->toggle();
738 m_logToFile
->toggle();
739 m_logfilePath
->setFocus();
740 doShowAdvanced
= true;
743 m_playSound
->toggle();
745 default: // do nothing
749 if ( doShowAdvanced
&& !m_logToFile
->isVisible() )
751 showAdvanced( true );
752 m_listview
->ensureItemVisible( m_listview
->currentItem() );
756 void KNotifyWidget::sort( bool ascending
)
758 m_listview
->setSorting( COL_EVENT
, ascending
);
762 void KNotifyWidget::selectItem( Q3ListViewItem
*item
)
766 m_listview
->setCurrentItem( item
);
767 item
->setSelected( true );
768 slotEventChanged( item
);
772 void KNotifyWidget::resetDefaults( bool ask
)
776 if ( KMessageBox::warningContinueCancel(this,
777 i18n("This will cause the notifications "
778 "to be reset to their defaults."),
779 i18n("Are You Sure?"),
781 != KMessageBox::Continue
)
785 reload( true ); // defaults
786 emit
changed( true );
789 void KNotifyWidget::reload( bool revertToDefaults
)
792 ApplicationListIterator
it( m_visibleApps
);
793 for ( ; it
.current(); ++it
)
795 it
.current()->reloadEvents( revertToDefaults
);
796 addToView( it
.current()->eventList() );
800 selectItem( m_listview
->firstChild() );
803 void KNotifyWidget::save()
805 kdDebug() << "save\n";
807 ApplicationListIterator
it( m_allApps
);
808 while ( it
.current() )
816 if ( !KApplication::dcopClient()->isAttached() )
817 KApplication::dcopClient()->attach();
818 DCOPRef("knotify", "").send("reconfigure()");
821 emit
changed( false );
824 // returns e.g. "kwin/eventsrc" from a given path
825 // "/opt/kde3/share/apps/kwin/eventsrc"
826 QString
KNotifyWidget::makeRelative( const QString
& fullPath
)
828 int slash
= fullPath
.lastIndexOf( '/' ) - 1;
829 slash
= fullPath
.lastIndexOf( '/', slash
);
832 return QString::null
;
834 return fullPath
.mid( slash
+1 );
837 Event
* KNotifyWidget::currentEvent()
839 Q3ListViewItem
*current
= m_listview
->currentItem();
843 return &static_cast<ListViewItem
*>( current
)->event();
846 void KNotifyWidget::openSoundDialog( KURLRequester
*requester
)
848 // only need to init this once
849 requester
->disconnect( SIGNAL( openFileDialog( KURLRequester
* )),
850 this, SLOT( openSoundDialog( KURLRequester
* )));
852 KFileDialog
*fileDialog
= requester
->fileDialog();
853 fileDialog
->setWindowTitle( i18n("Select Sound File") );
855 filters
<< "audio/x-wav" << "audio/x-mp3" << "application/ogg"
857 fileDialog
->setMimeFilter( filters
);
859 // find the first "sound"-resource that contains files
860 const Application
*app
= currentEvent()->application();
861 QStringList soundDirs
=
862 KGlobal::dirs()->findDirs("data", app
->appName() + "/sounds");
863 soundDirs
+= KGlobal::dirs()->resourceDirs( "sound" );
865 if ( !soundDirs
.isEmpty() ) {
868 dir
.setFilter( QDir::Files
| QDir::Readable
);
869 QStringList::ConstIterator it
= soundDirs
.begin();
870 while ( it
!= soundDirs
.end() ) {
872 if ( dir
.isReadable() && dir
.count() > 2 ) {
873 soundURL
.setPath( *it
);
874 fileDialog
->setURL( soundURL
);
882 void KNotifyWidget::openLogDialog( KURLRequester
*requester
)
884 // only need to init this once
885 requester
->disconnect( SIGNAL( openFileDialog( KURLRequester
* )),
886 this, SLOT( openLogDialog( KURLRequester
* )));
888 KFileDialog
*fileDialog
= requester
->fileDialog();
889 fileDialog
->setWindowTitle( i18n("Select Log File") );
891 filters
<< "text/x-log" << "text/plain";
892 fileDialog
->setMimeFilter( filters
);
895 void KNotifyWidget::openExecDialog( KURLRequester
*requester
)
897 // only need to init this once
898 requester
->disconnect( SIGNAL( openFileDialog( KURLRequester
* )),
899 this, SLOT( openExecDialog( KURLRequester
* )));
902 KFileDialog
*fileDialog
= requester
->fileDialog();
903 fileDialog
->setWindowTitle( i18n("Select File to Execute") );
905 filters
<< "application/x-executable" << "application/x-shellscript"
906 << "application/x-perl" << "application/x-python";
907 fileDialog
->setMimeFilter( filters
);
910 void KNotifyWidget::playSound()
912 if (!KIO::NetAccess::exists( m_soundPath
->url(), true, 0 )) {
913 bool foundSound
=false;
915 // find the first "sound"-resource that contains files
916 const Application
*app
= currentEvent()->application();
917 QStringList soundDirs
= KGlobal::dirs()->findDirs("data", app
->appName() + "/sounds");
918 soundDirs
+= KGlobal::dirs()->resourceDirs( "sound" );
920 if ( !soundDirs
.isEmpty() ) {
922 dir
.setFilter( QDir::Files
| QDir::Readable
);
923 QStringList::ConstIterator it
= soundDirs
.begin();
924 while ( it
!= soundDirs
.end() ) {
926 if ( dir
.isReadable() && dir
.count() > 2 &&
927 KIO::NetAccess::exists( *it
+ m_soundPath
->url(), true, 0 )) {
935 KMessageBox::sorry(this, i18n("The specified file does not exist." ));
939 KAudioPlayer::play( m_soundPath
->url() );
942 void KNotifyWidget::enableAll()
944 bool enable
= (sender() == m_buttonEnable
);
945 enableAll( SelectionCombo::type(enable
? m_comboEnable
: m_comboDisable
),
949 void KNotifyWidget::enableAll( int what
, bool enable
)
951 if ( m_listview
->childCount() == 0 )
954 bool affectAll
= m_affectAllApps
->isChecked(); // multi-apps mode
956 ApplicationListIterator
appIt( affectAll
? m_allApps
: m_visibleApps
);
957 for ( ; appIt
.current(); ++appIt
)
959 const EventList
& events
= appIt
.current()->eventList();
960 EventListIterator
it( events
);
961 for ( ; it
.current(); ++it
)
964 it
.current()->presentation
|= what
;
966 it
.current()->presentation
&= ~what
;
970 // now make the listview reflect the changes
971 Q3ListViewItemIterator
it( m_listview
->firstChild() );
972 for ( ; it
.current(); ++it
)
974 ListViewItem
*item
= static_cast<ListViewItem
*>( it
.current() );
975 updatePixmaps( item
);
978 Q3ListViewItem
*item
= m_listview
->currentItem();
980 item
= m_listview
->firstChild();
983 emit
changed( true );
987 //////////////////////////////////////////////////////////////////////
988 //////////////////////////////////////////////////////////////////////
992 // path must be "appname/eventsrc", i.e. a relative path
994 Application::Application( const QString
&path
)
996 QString config_file
= path
;
997 config_file
[config_file
.indexOf('/')] = '.';
999 config
= new KConfig(config_file
, false, false);
1000 kc
= new KConfig(path
, true, false, "data");
1001 kc
->setGroup( QLatin1String("Global") );
1002 m_icon
= kc
->readEntry(QLatin1String("IconName"),
1003 QLatin1String("misc"));
1004 m_description
= kc
->readEntry( QLatin1String("Comment"),
1005 i18n("No description available") );
1007 int index
= path
.indexOf( '/' );
1009 m_appname
= path
.left( index
);
1011 kdDebug() << "Cannot determine application name from path: " << path
<< endl
;
1014 Application::~Application()
1022 const EventList
& Application::eventList()
1025 m_events
= new EventList
;
1026 m_events
->setAutoDelete( true );
1034 void Application::save()
1039 EventListIterator
it( *m_events
);
1041 while ( (e
= it
.current()) ) {
1042 config
->setGroup( "Event/" + e
->configGroup
);
1043 int n
= KNotification::staticMetaObject
.indexOfEnumerator( "NotifyPresentation" );
1044 config
->writeEntry( "Action", QString(KNotification::staticMetaObject
.enumerator(n
).valueToKeys(e
->presentation
) ));
1045 config
->writePathEntry( "sound", e
->soundfile
);
1046 config
->writePathEntry( "logfile", e
->logfile
);
1047 config
->writePathEntry( "commandline", e
->commandline
);
1055 void Application::reloadEvents( bool revertToDefaults
)
1061 m_events
= new EventList
;
1062 m_events
->setAutoDelete( true );
1067 QString global
= QLatin1String("Global");
1068 QString default_group
= QLatin1String("<default>");
1069 QString name
= QLatin1String("Name");
1070 QString comment
= QLatin1String("Comment");
1072 QStringList conflist
= kc
->groupList();
1073 QStringList::ConstIterator it
= conflist
.begin();
1074 QRegExp
rx("^Event/([^/]*)$");
1075 while ( it
!= conflist
.end() ) {
1076 if ( rx
.indexIn(*it
) > -1 ) { // event group
1077 kc
->setGroup( *it
);
1079 e
= new Event( this );
1080 e
->name
= kc
->readEntry( name
);
1081 e
->description
= kc
->readEntry( comment
);
1082 e
->dontShow
= kc
->readNumEntry("nopresentation", 0 );
1083 e
->configGroup
= rx
.cap(1);
1085 int presentationEnum
= KNotification::staticMetaObject
.indexOfEnumerator( "NotifyPresentation" );
1088 if ( e
->name
.isEmpty() || e
->description
.isEmpty() )
1090 else { // load the event
1091 // default to passive popups over plain messageboxes
1092 const QString
& default_rep
= kc
->readEntry("Action");
1093 QString default_logfile
= kc
->readPathEntry("default_logfile");
1094 QString default_soundfile
= kc
->readPathEntry("sound");
1095 QString default_commandline
= kc
->readPathEntry("default_commandline");
1097 config
->setGroup(*it
);
1099 if ( revertToDefaults
)
1101 e
->presentation
= KNotification::staticMetaObject
.enumerator(presentationEnum
).keysToValue(default_rep
.toLatin1());
1102 e
->logfile
= default_logfile
;
1103 e
->soundfile
= default_soundfile
;
1104 e
->commandline
= default_commandline
;
1109 e
->presentation
= KNotification::staticMetaObject
.enumerator(presentationEnum
).keysToValue(
1110 config
->readEntry("presentation", default_rep
).toLatin1());
1111 e
->logfile
= config
->readPathEntry("logfile",
1113 e
->soundfile
= config
->readPathEntry("sound",
1115 e
->commandline
= config
->readPathEntry("commandline",
1116 default_commandline
);
1119 m_events
->append( e
);
1129 ///////////////////////////////////////////////////////////////////
1130 ///////////////////////////////////////////////////////////////////
1132 ListViewItem::ListViewItem( Q3ListView
*view
, Event
*event
)
1133 : Q3ListViewItem( view
),
1136 setText( COL_EVENT
, event
->text() );
1139 int ListViewItem::compare ( Q3ListViewItem
* i
, int col
, bool ascending
) const
1141 ListViewItem
*item
= static_cast<ListViewItem
*>( i
);
1142 int myPres
= m_event
->presentation
;
1143 int otherPres
= item
->event().presentation
;
1149 case COL_EVENT
: // use default sorting
1150 return Q3ListViewItem::compare( i
, col
, ascending
);
1153 action
= KNotifyClient::Execute
;
1156 action
= KNotifyClient::Logfile
;
1159 action
= (KNotifyClient::Messagebox
| KNotifyClient::PassivePopup
);
1162 action
= KNotifyClient::Sound
;
1165 action
= KNotifyClient::Stderr
;
1168 action
= KNotifyClient::Taskbar
;
1172 if ( (myPres
& action
) == (otherPres
& action
) )
1174 // default sorting by event
1175 return Q3ListViewItem::compare( i
, COL_EVENT
, true );
1178 if ( myPres
& action
)
1180 if ( otherPres
& action
)
1186 #include "knotifydialog.moc"