/* Copyright (C) 2000,2002 Carsten Pfeiffer Copyright (C) 2002 Neil Stevens This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation; This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library, If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace KNotify; enum { COL_EXECUTE = 0, COL_STDERR = 1, COL_MESSAGE = 2, COL_LOGFILE = 3, COL_SOUND = 4, COL_TASKBAR = 5, COL_EVENT = 6 }; // // I don't feel like subclassing KComboBox and find ways to insert that into // the .ui file... // namespace KNotify { class SelectionCombo { public: // // Mind the order in fill() and type() // static void fill( KComboBox *combo ) { combo->insertItem( i18n("Sounds") ); combo->insertItem( i18n("Logging") ); combo->insertItem( i18n("Program Execution") ); combo->insertItem( i18n("Message Windows") ); combo->insertItem( i18n("Passive Windows") ); combo->insertItem( i18n("Standard Error Output") ); combo->insertItem( i18n("Taskbar") ); } static int type( KComboBox *combo ) { switch( combo->currentItem() ) { case 0: return KNotifyClient::Sound; case 1: return KNotifyClient::Logfile; case 2: return KNotifyClient::Execute; case 3: return KNotifyClient::Messagebox; case 4: return KNotifyClient::PassivePopup; case 5: return KNotifyClient::Stderr; case 6: return KNotifyClient::Taskbar; } return KNotifyClient::None; } }; // Needed for displaying tooltips in the listview's QHeader class KNotifyToolTip : public TQToolTip { public: KNotifyToolTip( TQHeader *header ) : TQToolTip( header ) { m_tips[COL_EXECUTE] = i18n("Execute a program"); m_tips[COL_STDERR] = i18n("Print to Standard error output"); m_tips[COL_MESSAGE] = i18n("Display a messagebox"); m_tips[COL_LOGFILE] = i18n("Log to a file"); m_tips[COL_SOUND] = i18n("Play a sound"); m_tips[COL_TASKBAR] = i18n("Flash the taskbar entry"); } virtual ~KNotifyToolTip() {} protected: virtual void maybeTip ( const TQPoint& p ) { TQHeader *header = static_cast( tqparentWidget() ); int section = 0; if ( header->orientation() == Qt::Horizontal ) section= header->sectionAt( p.x() ); else section= header->sectionAt( p.y() ); if ( ( section < 0 ) || ( static_cast( section ) >= (sizeof(m_tips) / sizeof(TQString)) ) ) return; tip( header->sectionRect( section ), m_tips[section] ); } private: TQString m_tips[6]; }; } int KNotifyDialog::configure( TQWidget *parent, const char *name, const KAboutData *aboutData ) { KNotifyDialog dialog( parent, name, true, aboutData ); return dialog.exec(); } KNotifyDialog::KNotifyDialog( TQWidget *parent, const char *name, bool modal, const KAboutData *aboutData ) : KDialogBase(parent, name, modal, i18n("Notification Settings"), Ok | Apply | Cancel | Default, Ok, true ) { TQVBox *box = makeVBoxMainWidget(); m_notifyWidget = new KNotifyWidget( box, "knotify widget" ); if ( aboutData ) addApplicationEvents( aboutData->appName() ); connect( this, TQT_SIGNAL( okClicked() ), m_notifyWidget, TQT_SLOT( save() )); connect( this, TQT_SIGNAL( applyClicked() ), m_notifyWidget, TQT_SLOT( save() )); } KNotifyDialog::~KNotifyDialog() { } void KNotifyDialog::addApplicationEvents( const char *appName ) { addApplicationEvents( TQString::fromUtf8( appName ) + TQString::tqfromLatin1( "/eventsrc" ) ); } void KNotifyDialog::addApplicationEvents( const TQString& path ) { Application *app = m_notifyWidget->addApplicationEvents( path ); if ( app ) { m_notifyWidget->addVisibleApp( app ); m_notifyWidget->sort(); } } void KNotifyDialog::clearApplicationEvents() { m_notifyWidget->clear(); } void KNotifyDialog::slotDefault() { m_notifyWidget->resetDefaults( true ); // ask user } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// class KNotifyWidget::Private { public: TQPixmap pixmaps[6]; KNotifyToolTip *toolTip; }; // simple access to all knotify-handled applications KNotifyWidget::KNotifyWidget( TQWidget *parent, const char *name, bool handleAllApps ) : KNotifyWidgetBase( parent, name ? name : "KNotifyWidget" ) { d = new Private; m_allApps.setAutoDelete( true ); if ( !handleAllApps ) { m_affectAllApps->hide(); m_playerButton->hide(); } SelectionCombo::fill( m_comboEnable ); SelectionCombo::fill( m_comboDisable ); m_listview->setFullWidth( true ); m_listview->setAllColumnsShowFocus( true ); TQPixmap pexec = SmallIcon("exec"); TQPixmap pstderr = SmallIcon("terminal"); TQPixmap pmessage = SmallIcon("info"); TQPixmap plogfile = SmallIcon("log"); TQPixmap psound = SmallIcon("sound"); TQPixmap ptaskbar = SmallIcon("kicker"); d->pixmaps[COL_EXECUTE] = pexec; d->pixmaps[COL_STDERR] = pstderr; d->pixmaps[COL_MESSAGE] = pmessage; d->pixmaps[COL_LOGFILE] = plogfile; d->pixmaps[COL_SOUND] = psound; d->pixmaps[COL_TASKBAR] = ptaskbar; int w = KIcon::SizeSmall + 6; TQHeader *header = m_listview->header(); header->setLabel( COL_EXECUTE, pexec, TQString::null, w ); header->setLabel( COL_STDERR, pstderr, TQString::null, w ); header->setLabel( COL_MESSAGE, pmessage, TQString::null, w ); header->setLabel( COL_LOGFILE, plogfile, TQString::null, w ); header->setLabel( COL_SOUND, psound, TQString::null, w ); header->setLabel( COL_TASKBAR, ptaskbar, TQString::null, w ); d->toolTip = new KNotifyToolTip( header ); m_playButton->setIconSet( SmallIconSet( "player_play" ) ); connect( m_playButton, TQT_SIGNAL( clicked() ), TQT_SLOT( playSound() )); connect( m_listview, TQT_SIGNAL( currentChanged( TQListViewItem * ) ), TQT_SLOT( slotEventChanged( TQListViewItem * ) )); connect( m_listview, TQT_SIGNAL(clicked( TQListViewItem *, const TQPoint&, int)), TQT_SLOT( slotItemClicked( TQListViewItem *, const TQPoint&, int ))); connect( m_playSound, TQT_SIGNAL( toggled( bool )), TQT_SLOT( soundToggled( bool )) ); connect( m_logToFile, TQT_SIGNAL( toggled( bool )), TQT_SLOT( loggingToggled( bool )) ); connect( m_execute, TQT_SIGNAL( toggled( bool )), TQT_SLOT( executeToggled( bool )) ); connect( m_messageBox, TQT_SIGNAL( toggled( bool )), TQT_SLOT( messageBoxChanged() ) ); connect( m_passivePopup, TQT_SIGNAL( toggled( bool )), TQT_SLOT( messageBoxChanged() ) ); connect( m_stderr, TQT_SIGNAL( toggled( bool )), TQT_SLOT( stderrToggled( bool ) ) ); connect( m_taskbar, TQT_SIGNAL( toggled( bool )), TQT_SLOT( taskbarToggled( bool ) ) ); connect( m_soundPath, TQT_SIGNAL( textChanged( const TQString& )), TQT_SLOT( soundFileChanged( const TQString& ))); connect( m_logfilePath, TQT_SIGNAL( textChanged( const TQString& )), TQT_SLOT( logfileChanged( const TQString& ) )); connect( m_executePath, TQT_SIGNAL( textChanged( const TQString& )), TQT_SLOT( commandlineChanged( const TQString& ) )); connect( m_soundPath, TQT_SIGNAL( openFileDialog( KURLRequester * )), TQT_SLOT( openSoundDialog( KURLRequester * ))); connect( m_logfilePath, TQT_SIGNAL( openFileDialog( KURLRequester * )), TQT_SLOT( openLogDialog( KURLRequester * ))); connect( m_executePath, TQT_SIGNAL( openFileDialog( KURLRequester * )), TQT_SLOT( openExecDialog( KURLRequester * ))); connect( m_extension, TQT_SIGNAL( clicked() ), TQT_SLOT( toggleAdvanced()) ); connect( m_buttonEnable, TQT_SIGNAL( clicked() ), TQT_SLOT( enableAll() )); connect( m_buttonDisable, TQT_SIGNAL( clicked() ), TQT_SLOT( enableAll() )); TQString whatsThis = i18n("You may use the following macros
" "in the commandline:
" "%e: for the event name,
" "%a: for the name of the application that sent the event,
" "%s: for the notification message,
" "%w: for the numeric window ID where the event originated,
" "%i: for the numeric event ID."); TQWhatsThis::add( m_execute, whatsThis ); TQWhatsThis::add( m_executePath, whatsThis ); showAdvanced( false ); slotEventChanged( 0L ); // disable widgets by default } KNotifyWidget::~KNotifyWidget() { delete d->toolTip; delete d; } void KNotifyWidget::toggleAdvanced() { showAdvanced( m_logToFile->isHidden() ); } void KNotifyWidget::showAdvanced( bool show ) { if ( show ) { m_extension->setText( i18n("Advanced <<") ); TQToolTip::add( m_extension, i18n("Hide advanced options") ); m_logToFile->show(); m_logfilePath->show(); m_execute->show(); m_executePath->show(); m_messageBox->show(); m_passivePopup->show(); m_stderr->show(); m_taskbar->show(); m_passivePopup->setEnabled( m_messageBox->isChecked() ); m_actionsBoxLayout->setSpacing( KDialog::spacingHint() ); } else { m_extension->setText( i18n("Advanced >>") ); TQToolTip::add( m_extension, i18n("Show advanced options") ); m_logToFile->hide(); m_logfilePath->hide(); m_execute->hide(); m_executePath->hide(); m_messageBox->hide(); m_passivePopup->hide(); m_stderr->hide(); m_taskbar->hide(); m_actionsBoxLayout->setSpacing( 0 ); } } Application * KNotifyWidget::addApplicationEvents( const TQString& path ) { kdDebug() << "**** knotify: adding path: " << path << endl; TQString relativePath = path; if ( path.tqat(0) == '/' && KStandardDirs::exists( path ) ) relativePath = makeRelative( path ); if ( !relativePath.isEmpty() ) { Application *app = new Application( relativePath ); m_allApps.append( app ); return app; } return 0L; } void KNotifyWidget::clear() { clearVisible(); m_allApps.clear(); } void KNotifyWidget::clearVisible() { m_visibleApps.clear(); m_listview->clear(); slotEventChanged( 0L ); // disable widgets } void KNotifyWidget::showEvent( TQShowEvent *e ) { selectItem( m_listview->firstChild() ); KNotifyWidgetBase::showEvent( e ); } void KNotifyWidget::slotEventChanged( TQListViewItem *item ) { bool on = (item != 0L); m_actionsBox->setEnabled( on ); m_controlsBox->setEnabled( on ); if ( !on ) return; ListViewItem *lit = static_cast( item ); updateWidgets( lit ); } void KNotifyWidget::updateWidgets( ListViewItem *item ) { bool enable; bool checked; blockSignals( true ); // don't emit changed() signals const Event& event = item->event(); // sound settings m_playButton->setEnabled( !event.soundfile.isEmpty() ); m_soundPath->setURL( event.soundfile ); enable = (event.dontShow & KNotifyClient::Sound) == 0; checked = enable && !event.soundfile.isEmpty() && (event.presentation & KNotifyClient::Sound); m_playSound->setEnabled( enable ); m_playSound->setChecked( checked ); m_soundPath->setEnabled( checked ); // logfile settings m_logfilePath->setURL( event.logfile ); enable = (event.dontShow & KNotifyClient::Logfile) == 0; checked = enable && !event.logfile.isEmpty() && (event.presentation & KNotifyClient::Logfile); m_logToFile->setEnabled( enable ); m_logToFile->setChecked( checked ); m_logfilePath->setEnabled( checked ); // execute program settings m_executePath->setURL( event.commandline ); enable = (event.dontShow & KNotifyClient::Execute) == 0; checked = enable && !event.commandline.isEmpty() && (event.presentation & KNotifyClient::Execute); m_execute->setEnabled( enable ); m_execute->setChecked( checked ); m_executePath->setEnabled( checked ); // other settings m_messageBox->setChecked(event.presentation & (KNotifyClient::Messagebox | KNotifyClient::PassivePopup)); enable = (event.dontShow & KNotifyClient::Messagebox) == 0; m_messageBox->setEnabled( enable ); m_passivePopup->setChecked(event.presentation & KNotifyClient::PassivePopup); enable = (event.dontShow & KNotifyClient::PassivePopup) == 0; m_passivePopup->setEnabled( enable ); m_stderr->setChecked( event.presentation & KNotifyClient::Stderr ); enable = (event.dontShow & KNotifyClient::Stderr) == 0; m_stderr->setEnabled( enable ); m_taskbar->setChecked(event.presentation & KNotifyClient::Taskbar); enable = (event.dontShow & KNotifyClient::Taskbar) == 0; m_taskbar->setEnabled( enable ); updatePixmaps( item ); blockSignals( false ); } void KNotifyWidget::updatePixmaps( ListViewItem *item ) { TQPixmap emptyPix; Event &event = item->event(); bool doIt = (event.presentation & KNotifyClient::Execute) && !event.commandline.isEmpty(); item->setPixmap( COL_EXECUTE, doIt ? d->pixmaps[COL_EXECUTE] : emptyPix ); doIt = (event.presentation & KNotifyClient::Sound) && !event.soundfile.isEmpty(); item->setPixmap( COL_SOUND, doIt ? d->pixmaps[COL_SOUND] : emptyPix ); doIt = (event.presentation & KNotifyClient::Logfile) && !event.logfile.isEmpty(); item->setPixmap( COL_LOGFILE, doIt ? d->pixmaps[COL_LOGFILE] : emptyPix ); item->setPixmap( COL_MESSAGE, (event.presentation & (KNotifyClient::Messagebox | KNotifyClient::PassivePopup)) ? d->pixmaps[COL_MESSAGE] : emptyPix ); item->setPixmap( COL_STDERR, (event.presentation & KNotifyClient::Stderr) ? d->pixmaps[COL_STDERR] : emptyPix ); item->setPixmap( COL_TASKBAR, (event.presentation & KNotifyClient::Taskbar) ? d->pixmaps[COL_TASKBAR] : emptyPix ); } void KNotifyWidget::addVisibleApp( Application *app ) { if ( !app || (m_visibleApps.tqfindRef( app ) != -1) ) return; m_visibleApps.append( app ); addToView( app->eventList() ); TQListViewItem *item = m_listview->selectedItem(); if ( !item ) item = m_listview->firstChild(); selectItem( item ); } void KNotifyWidget::addToView( const EventList& events ) { ListViewItem *item = 0L; EventListIterator it( events ); for ( ; it.current(); ++it ) { Event *event = it.current(); item = new ListViewItem( m_listview, event ); if ( (event->presentation & KNotifyClient::Execute) && !event->commandline.isEmpty() ) item->setPixmap( COL_EXECUTE, d->pixmaps[COL_EXECUTE] ); if ( (event->presentation & KNotifyClient::Sound) && !event->soundfile.isEmpty() ) item->setPixmap( COL_SOUND, d->pixmaps[COL_SOUND] ); if ( (event->presentation & KNotifyClient::Logfile) && !event->logfile.isEmpty() ) item->setPixmap( COL_LOGFILE, d->pixmaps[COL_LOGFILE] ); if ( event->presentation & (KNotifyClient::Messagebox|KNotifyClient::PassivePopup) ) item->setPixmap( COL_MESSAGE, d->pixmaps[COL_MESSAGE] ); if ( event->presentation & KNotifyClient::Stderr ) item->setPixmap( COL_STDERR, d->pixmaps[COL_STDERR] ); if ( event->presentation & KNotifyClient::Taskbar ) item->setPixmap( COL_TASKBAR, d->pixmaps[COL_TASKBAR] ); } } void KNotifyWidget::widgetChanged( TQListViewItem *item, int what, bool on, TQWidget *buddy ) { if ( signalsBlocked() ) return; if ( buddy ) buddy->setEnabled( on ); Event &e = static_cast( item )->event(); if ( on ) { e.presentation |= what; if ( buddy ) buddy->setFocus(); } else e.presentation &= ~what; emit changed( true ); } void KNotifyWidget::soundToggled( bool on ) { TQListViewItem *item = m_listview->currentItem(); if ( !item ) return; bool doIcon = on && !m_soundPath->url().isEmpty(); item->setPixmap( COL_SOUND, doIcon ? d->pixmaps[COL_SOUND] : TQPixmap() ); widgetChanged( item, KNotifyClient::Sound, on, m_soundPath ); } void KNotifyWidget::loggingToggled( bool on ) { TQListViewItem *item = m_listview->currentItem(); if ( !item ) return; bool doIcon = on && !m_logfilePath->url().isEmpty(); item->setPixmap(COL_LOGFILE, doIcon ? d->pixmaps[COL_LOGFILE] : TQPixmap()); widgetChanged( item, KNotifyClient::Logfile, on, m_logfilePath ); } void KNotifyWidget::executeToggled( bool on ) { TQListViewItem *item = m_listview->currentItem(); if ( !item ) return; bool doIcon = on && !m_executePath->url().isEmpty(); item->setPixmap(COL_EXECUTE, doIcon ? d->pixmaps[COL_EXECUTE] : TQPixmap()); widgetChanged( item, KNotifyClient::Execute, on, m_executePath ); } void KNotifyWidget::messageBoxChanged() { if ( signalsBlocked() ) return; m_passivePopup->setEnabled( m_messageBox->isChecked() ); TQListViewItem *item = m_listview->currentItem(); if ( !item ) return; bool on = m_passivePopup->isEnabled(); item->setPixmap( COL_MESSAGE, on ? d->pixmaps[COL_MESSAGE] : TQPixmap() ); Event &e = static_cast( item )->event(); if ( m_messageBox->isChecked() ) { if ( m_passivePopup->isChecked() ) { e.presentation |= KNotifyClient::PassivePopup; e.presentation &= ~KNotifyClient::Messagebox; } else { e.presentation &= ~KNotifyClient::PassivePopup; e.presentation |= KNotifyClient::Messagebox; } } else { e.presentation &= ~KNotifyClient::Messagebox; e.presentation &= ~KNotifyClient::PassivePopup; } emit changed( true ); } void KNotifyWidget::stderrToggled( bool on ) { TQListViewItem *item = m_listview->currentItem(); if ( !item ) return; item->setPixmap( COL_STDERR, on ? d->pixmaps[COL_STDERR] : TQPixmap() ); widgetChanged( item, KNotifyClient::Stderr, on ); } void KNotifyWidget::taskbarToggled( bool on ) { TQListViewItem *item = m_listview->currentItem(); if ( !item ) return; item->setPixmap( COL_TASKBAR, on ? d->pixmaps[COL_TASKBAR] : TQPixmap() ); widgetChanged( item, KNotifyClient::Taskbar, on ); } void KNotifyWidget::soundFileChanged( const TQString& text ) { if ( signalsBlocked() ) return; TQListViewItem *item = m_listview->currentItem(); if ( !item ) return; m_playButton->setEnabled( !text.isEmpty() ); currentEvent()->soundfile = text; bool ok = !text.isEmpty() && m_playSound->isChecked(); item->setPixmap( COL_SOUND, ok ? d->pixmaps[COL_SOUND] : TQPixmap() ); emit changed( true ); } void KNotifyWidget::logfileChanged( const TQString& text ) { if ( signalsBlocked() ) return; TQListViewItem *item = m_listview->currentItem(); if ( !item ) return; currentEvent()->logfile = text; bool ok = !text.isEmpty() && m_logToFile->isChecked(); item->setPixmap( COL_LOGFILE, ok ? d->pixmaps[COL_LOGFILE] : TQPixmap() ); emit changed( true ); } void KNotifyWidget::commandlineChanged( const TQString& text ) { if ( signalsBlocked() ) return; TQListViewItem *item = m_listview->currentItem(); if ( !item ) return; currentEvent()->commandline = text; bool ok = !text.isEmpty() && m_execute->isChecked(); item->setPixmap( COL_EXECUTE, ok ? d->pixmaps[COL_EXECUTE] : TQPixmap() ); emit changed( true ); } void KNotifyWidget::slotItemClicked( TQListViewItem *item, const TQPoint&, int col ) { if ( !item || !item->isSelected() ) return; Event *event = currentEvent(); if ( !event ) return; // very unlikely, but safety first bool doShowAdvanced = false; switch( col ) { case COL_EXECUTE: m_execute->toggle(); m_executePath->setFocus(); doShowAdvanced = true; break; case COL_STDERR: m_stderr->toggle(); break; case COL_TASKBAR: m_taskbar->toggle(); break; case COL_MESSAGE: m_passivePopup->setChecked( true ); // default to passive popups m_messageBox->toggle(); break; case COL_LOGFILE: m_logToFile->toggle(); m_logfilePath->setFocus(); doShowAdvanced = true; break; case COL_SOUND: m_playSound->toggle(); break; default: // do nothing break; } if ( doShowAdvanced && !m_logToFile->isVisible() ) { showAdvanced( true ); m_listview->ensureItemVisible( m_listview->currentItem() ); } } void KNotifyWidget::sort( bool ascending ) { m_listview->setSorting( COL_EVENT, ascending ); m_listview->sort(); } void KNotifyWidget::selectItem( TQListViewItem *item ) { if ( item ) { m_listview->setCurrentItem( item ); item->setSelected( true ); slotEventChanged( item ); } } void KNotifyWidget::resetDefaults( bool ask ) { if ( ask ) { if ( KMessageBox::warningContinueCancel(this, i18n("This will cause the notifications " "to be reset to their defaults."), i18n("Are You Sure?"), i18n("&Reset")) != KMessageBox::Continue) return; } reload( true ); // defaults emit changed( true ); } void KNotifyWidget::reload( bool revertToDefaults ) { m_listview->clear(); ApplicationListIterator it( m_visibleApps ); for ( ; it.current(); ++it ) { it.current()->reloadEvents( revertToDefaults ); addToView( it.current()->eventList() ); } m_listview->sort(); selectItem( m_listview->firstChild() ); } void KNotifyWidget::save() { kdDebug() << "save\n"; ApplicationListIterator it( m_allApps ); while ( it.current() ) { (*it)->save(); ++it; } if ( kapp ) { if ( !kapp->dcopClient()->isAttached() ) kapp->dcopClient()->attach(); kapp->dcopClient()->send("knotify", "", "reconfigure()", TQString("")); } emit changed( false ); } // returns e.g. "kwin/eventsrc" from a given path // "/opt/kde3/share/apps/kwin/eventsrc" TQString KNotifyWidget::makeRelative( const TQString& fullPath ) { int slash = fullPath.tqfindRev( '/' ) - 1; slash = fullPath.tqfindRev( '/', slash ); if ( slash < 0 ) return TQString::null; return fullPath.mid( slash+1 ); } Event * KNotifyWidget::currentEvent() { TQListViewItem *current = m_listview->currentItem(); if ( !current ) return 0L; return &static_cast( current )->event(); } void KNotifyWidget::openSoundDialog( KURLRequester *requester ) { // only need to init this once requester->disconnect( TQT_SIGNAL( openFileDialog( KURLRequester * )), this, TQT_SLOT( openSoundDialog( KURLRequester * ))); KFileDialog *fileDialog = requester->fileDialog(); fileDialog->setCaption( i18n("Select Sound File") ); TQStringList filters; filters << "audio/x-wav" << "audio/x-mp3" << "application/ogg" << "audio/x-adpcm"; fileDialog->setMimeFilter( filters ); // find the first "sound"-resource that contains files const Application *app = currentEvent()->application(); TQStringList soundDirs = KGlobal::dirs()->findDirs("data", app->appName() + "/sounds"); soundDirs += KGlobal::dirs()->resourceDirs( "sound" ); if ( !soundDirs.isEmpty() ) { KURL soundURL; TQDir dir; dir.setFilter( TQDir::Files | TQDir::Readable ); TQStringList::ConstIterator it = soundDirs.begin(); while ( it != soundDirs.end() ) { dir = *it; if ( dir.isReadable() && dir.count() > 2 ) { soundURL.setPath( *it ); fileDialog->setURL( soundURL ); break; } ++it; } } } void KNotifyWidget::openLogDialog( KURLRequester *requester ) { // only need to init this once requester->disconnect( TQT_SIGNAL( openFileDialog( KURLRequester * )), this, TQT_SLOT( openLogDialog( KURLRequester * ))); KFileDialog *fileDialog = requester->fileDialog(); fileDialog->setCaption( i18n("Select Log File") ); TQStringList filters; filters << "text/x-log" << "text/plain"; fileDialog->setMimeFilter( filters ); } void KNotifyWidget::openExecDialog( KURLRequester *requester ) { // only need to init this once requester->disconnect( TQT_SIGNAL( openFileDialog( KURLRequester * )), this, TQT_SLOT( openExecDialog( KURLRequester * ))); KFileDialog *fileDialog = requester->fileDialog(); fileDialog->setCaption( i18n("Select File to Execute") ); TQStringList filters; filters << "application/x-executable" << "application/x-shellscript" << "application/x-perl" << "application/x-python"; fileDialog->setMimeFilter( filters ); } void KNotifyWidget::playSound() { TQString soundPath = m_soundPath->url(); if (!KIO::NetAccess::exists( m_soundPath->url(), true, 0 )) { bool foundSound=false; // find the first "sound"-resource that contains files const Application *app = currentEvent()->application(); TQStringList soundDirs = KGlobal::dirs()->findDirs("data", app->appName() + "/sounds"); soundDirs += KGlobal::dirs()->resourceDirs( "sound" ); if ( !soundDirs.isEmpty() ) { TQDir dir; dir.setFilter( TQDir::Files | TQDir::Readable ); TQStringList::ConstIterator it = soundDirs.begin(); while ( it != soundDirs.end() ) { dir = *it; if ( dir.isReadable() && dir.count() > 2 && KIO::NetAccess::exists( *it + m_soundPath->url(), true, 0 )) { foundSound=true; soundPath = *it + m_soundPath->url(); break; } ++it; } } if ( !foundSound ) { KMessageBox::sorry(this, i18n("The specified file does not exist." )); return; } } KAudioPlayer::play( soundPath ); } void KNotifyWidget::enableAll() { bool enable = (sender() == m_buttonEnable); enableAll( SelectionCombo::type(enable ? m_comboEnable : m_comboDisable), enable ); } void KNotifyWidget::enableAll( int what, bool enable ) { if ( m_listview->childCount() == 0 ) return; bool affectAll = m_affectAllApps->isChecked(); // multi-apps mode ApplicationListIterator appIt( affectAll ? m_allApps : m_visibleApps ); for ( ; appIt.current(); ++appIt ) { const EventList& events = appIt.current()->eventList(); EventListIterator it( events ); for ( ; it.current(); ++it ) { if ( enable ) it.current()->presentation |= what; else it.current()->presentation &= ~what; } } // now make the listview reflect the changes TQListViewItemIterator it( m_listview->firstChild() ); for ( ; it.current(); ++it ) { ListViewItem *item = static_cast( it.current() ); updatePixmaps( item ); } TQListViewItem *item = m_listview->currentItem(); if ( !item ) item = m_listview->firstChild(); selectItem( item ); emit changed( true ); } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// // // path must be "appname/eventsrc", i.e. a relative path // Application::Application( const TQString &path ) { TQString config_file = path; config_file[config_file.tqfind('/')] = '.'; m_events = 0L; config = new KConfig(config_file, false, false); kc = new KConfig(path, true, false, "data"); kc->setGroup( TQString::tqfromLatin1("!Global!") ); m_icon = kc->readEntry(TQString::tqfromLatin1("IconName"), TQString::tqfromLatin1("misc")); m_description = kc->readEntry( TQString::tqfromLatin1("Comment"), i18n("No description available") ); int index = path.tqfind( '/' ); if ( index >= 0 ) m_appname = path.left( index ); else kdDebug() << "Cannot determine application name from path: " << path << endl; } Application::~Application() { delete config; delete kc; delete m_events; } const EventList& Application::eventList() { if ( !m_events ) { m_events = new EventList; m_events->setAutoDelete( true ); reloadEvents(); } return *m_events; } void Application::save() { if ( !m_events ) return; EventListIterator it( *m_events ); Event *e; while ( (e = it.current()) ) { config->setGroup( e->configGroup ); config->writeEntry( "presentation", e->presentation ); config->writePathEntry( "soundfile", e->soundfile ); config->writePathEntry( "logfile", e->logfile ); config->writePathEntry( "commandline", e->commandline ); ++it; } config->sync(); } void Application::reloadEvents( bool revertToDefaults ) { if ( m_events ) m_events->clear(); else { m_events = new EventList; m_events->setAutoDelete( true ); } Event *e = 0L; TQString global = TQString::tqfromLatin1("!Global!"); TQString default_group = TQString::tqfromLatin1(""); TQString name = TQString::tqfromLatin1("Name"); TQString comment = TQString::tqfromLatin1("Comment"); TQStringList conflist = kc->groupList(); TQStringList::ConstIterator it = conflist.begin(); while ( it != conflist.end() ) { if ( (*it) != global && (*it) != default_group ) { // event group kc->setGroup( *it ); e = new Event( this ); e->name = kc->readEntry( name ); e->description = kc->readEntry( comment ); e->dontShow = kc->readNumEntry("nopresentation", 0 ); e->configGroup = *it; if ( e->name.isEmpty() && e->description.isEmpty() ) delete e; else { // load the event if( !e->name.isEmpty() && e->description.isEmpty() ) e->description = e->name; // default to passive popups over plain messageboxes int default_rep = kc->readNumEntry("default_presentation", 0 | KNotifyClient::PassivePopup); TQString default_logfile = kc->readPathEntry("default_logfile"); TQString default_soundfile = kc->readPathEntry("default_sound"); TQString default_commandline = kc->readPathEntry("default_commandline"); config->setGroup(*it); if ( revertToDefaults ) { e->presentation = default_rep; e->logfile = default_logfile; e->soundfile = default_soundfile; e->commandline = default_commandline; } else { e->presentation = config->readNumEntry("presentation", default_rep); e->logfile = config->readPathEntry("logfile", default_logfile); e->soundfile = config->readPathEntry("soundfile", default_soundfile); e->commandline = config->readPathEntry("commandline", default_commandline); } m_events->append( e ); } } ++it; } return; } /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// ListViewItem::ListViewItem( TQListView *view, Event *event ) : TQListViewItem( view ), m_event( event ) { setText( COL_EVENT, event->text() ); } int ListViewItem::compare ( TQListViewItem * i, int col, bool ascending ) const { ListViewItem *item = static_cast( i ); int myPres = m_event->presentation; int otherPres = item->event().presentation; int action = 0; switch ( col ) { case COL_EVENT: // use default sorting return TQListViewItem::compare( i, col, ascending ); case COL_EXECUTE: action = KNotifyClient::Execute; break; case COL_LOGFILE: action = KNotifyClient::Logfile; break; case COL_MESSAGE: action = (KNotifyClient::Messagebox | KNotifyClient::PassivePopup); break; case COL_SOUND: action = KNotifyClient::Sound; break; case COL_STDERR: action = KNotifyClient::Stderr; break; case COL_TASKBAR: action = KNotifyClient::Taskbar; break; } if ( (myPres & action) == (otherPres & action) ) { // default sorting by event return TQListViewItem::compare( i, COL_EVENT, true ); } if ( myPres & action ) return -1; if ( otherPres & action ) return 1; return 0; } #include "knotifydialog.moc"