/* This file is part of the KDE project Copyright (C) 2002 Daniel Molkentin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 General Public License along with this program; see the file COPYING. 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 "kcmkded.h" #include "kcmkded.moc" typedef KGenericFactory KDEDFactory; K_EXPORT_COMPONENT_FACTORY( kcm_kded, KDEDFactory( "kcmkded" ) ) KDEDConfig::KDEDConfig(QWidget* parent, const char* name, const QStringList &) : KCModule( KDEDFactory::instance(), parent, name ) { KAboutData *about = new KAboutData( I18N_NOOP( "kcmkded" ), I18N_NOOP( "KDE Service Manager" ), 0, 0, KAboutData::License_GPL, I18N_NOOP( "(c) 2002 Daniel Molkentin" ) ); about->addAuthor("Daniel Molkentin",0,"molkentin@kde.org"); setAboutData( about ); setQuickHelp( i18n("

Service Manager

This module allows you to have an overview of all plugins of the " "KDE Daemon, also referred to as KDE Services. Generally, there are two types of service:

" "
  • Services invoked at startup
  • Services called on demand
" "

The latter are only listed for convenience. The startup services can be started and stopped. " "In Administrator mode, you can also define whether services should be loaded at startup.

" "

Use this with care: some services are vital for KDE; do not deactivate services if you" " do not know what you are doing.

")); RUNNING = i18n("Running")+" "; NOT_RUNNING = i18n("Not running")+" "; QVBoxLayout *lay = new QVBoxLayout( this, 0, KDialog::spacingHint() ); QGroupBox *gb = new QVGroupBox(i18n("Load-on-Demand Services"), this ); QWhatsThis::add(gb, i18n("This is a list of available KDE services which will " "be started on demand. They are only listed for convenience, as you " "cannot manipulate these services.")); lay->addWidget( gb ); _lvLoD = new KListView( gb ); _lvLoD->addColumn(i18n("Service")); _lvLoD->addColumn(i18n("Description")); _lvLoD->addColumn(i18n("Status")); _lvLoD->setAllColumnsShowFocus(true); _lvLoD->header()->setStretchEnabled(true, 1); gb = new QVGroupBox(i18n("Startup Services"), this ); QWhatsThis::add(gb, i18n("This shows all KDE services that can be loaded " "on KDE startup. Checked services will be invoked on next startup. " "Be careful with deactivation of unknown services.")); lay->addWidget( gb ); _lvStartup = new KListView( gb ); _lvStartup->addColumn(i18n("Use")); _lvStartup->addColumn(i18n("Service")); _lvStartup->addColumn(i18n("Description")); _lvStartup->addColumn(i18n("Status")); _lvStartup->setAllColumnsShowFocus(true); _lvStartup->header()->setStretchEnabled(true, 2); KButtonBox *buttonBox = new KButtonBox( gb, Horizontal); _pbStart = buttonBox->addButton( i18n("Start")); _pbStop = buttonBox->addButton( i18n("Stop")); _pbStart->setEnabled( false ); _pbStop->setEnabled( false ); connect(_pbStart, SIGNAL(clicked()), SLOT(slotStartService())); connect(_pbStop, SIGNAL(clicked()), SLOT(slotStopService())); connect(_lvStartup, SIGNAL(selectionChanged(QListViewItem*)), SLOT(slotEvalItem(QListViewItem*)) ); load(); } void setModuleGroup(KConfig *config, const QString &filename) { QString module = filename; int i = module.findRev('/'); if (i != -1) module = module.mid(i+1); i = module.findRev('.'); if (i != -1) module = module.left(i); config->setGroup(QString("Module-%1").arg(module)); } bool KDEDConfig::autoloadEnabled(KConfig *config, const QString &filename) { setModuleGroup(config, filename); return config->readBoolEntry("autoload", true); } void KDEDConfig::setAutoloadEnabled(KConfig *config, const QString &filename, bool b) { setModuleGroup(config, filename); return config->writeEntry("autoload", b); } void KDEDConfig::load() { load ( false ); } void KDEDConfig::load( bool useDefaults ) { KConfig kdedrc("kdedrc", true, false); kdedrc.setReadDefaults( useDefaults ); _lvStartup->clear(); _lvLoD->clear(); QStringList files; KGlobal::dirs()->findAllResources( "services", QString::fromLatin1( "kded/*.desktop" ), true, true, files ); QListViewItem* item = 0L; CheckListItem* clitem; for ( QStringList::ConstIterator it = files.begin(); it != files.end(); ++it ) { if ( KDesktopFile::isDesktopFile( *it ) ) { KDesktopFile file( *it, true, "services" ); if ( file.readBoolEntry("X-KDE-Kded-autoload") ) { clitem = new CheckListItem(_lvStartup, QString::null); connect(clitem, SIGNAL(changed(QCheckListItem*)), SLOT(slotItemChecked(QCheckListItem*))); clitem->setOn(autoloadEnabled(&kdedrc, *it)); item = clitem; item->setText(1, file.readName()); item->setText(2, file.readComment()); item->setText(3, NOT_RUNNING); item->setText(4, file.readEntry("X-KDE-Library")); } else if ( file.readBoolEntry("X-KDE-Kded-load-on-demand") ) { item = new QListViewItem(_lvLoD, file.readName()); item->setText(1, file.readComment()); item->setText(2, NOT_RUNNING); item->setText(4, file.readEntry("X-KDE-Library")); } } } getServiceStatus(); emit changed( useDefaults ); } void KDEDConfig::save() { QCheckListItem* item = 0L; QStringList files; KGlobal::dirs()->findAllResources( "services", QString::fromLatin1( "kded/*.desktop" ), true, true, files ); KConfig kdedrc("kdedrc", false, false); for ( QStringList::ConstIterator it = files.begin(); it != files.end(); ++it ) { if ( KDesktopFile::isDesktopFile( *it ) ) { KConfig file( *it, false, false, "services" ); file.setGroup("Desktop Entry"); if (file.readBoolEntry("X-KDE-Kded-autoload")){ item = static_cast(_lvStartup->findItem(file.readEntry("X-KDE-Library"),4)); if (item) { // we found a match, now compare and see what changed setAutoloadEnabled(&kdedrc, *it, item->isOn()); } } } } kdedrc.sync(); DCOPRef( "kded", "kded" ).call( "reconfigure" ); QTimer::singleShot(0, this, SLOT(slotServiceRunningToggled())); } void KDEDConfig::defaults() { load( true ); } void KDEDConfig::getServiceStatus() { QCStringList modules; QCString replyType; QByteArray replyData; if (!kapp->dcopClient()->call( "kded", "kded", "loadedModules()", QByteArray(), replyType, replyData ) ) { _lvLoD->setEnabled( false ); _lvStartup->setEnabled( false ); KMessageBox::error(this, i18n("Unable to contact KDED.")); return; } else { if ( replyType == "QCStringList" ) { QDataStream reply(replyData, IO_ReadOnly); reply >> modules; } } for( QListViewItemIterator it( _lvLoD); it.current() != 0; ++it ) it.current()->setText(2, NOT_RUNNING); for( QListViewItemIterator it( _lvStartup); it.current() != 0; ++it ) it.current()->setText(3, NOT_RUNNING); for ( QCStringList::Iterator it = modules.begin(); it != modules.end(); ++it ) { QListViewItem *item = _lvLoD->findItem(*it, 4); if ( item ) { item->setText(2, RUNNING); } item = _lvStartup->findItem(*it, 4); if ( item ) { item->setText(3, RUNNING); } } } void KDEDConfig::slotReload() { QString current = _lvStartup->currentItem()->text(4); load(); QListViewItem *item = _lvStartup->findItem(current, 4); if (item) _lvStartup->setCurrentItem(item); } void KDEDConfig::slotEvalItem(QListViewItem * item) { if (!item) return; if ( item->text(3) == RUNNING ) { _pbStart->setEnabled( false ); _pbStop->setEnabled( true ); } else if ( item->text(3) == NOT_RUNNING ) { _pbStart->setEnabled( true ); _pbStop->setEnabled( false ); } else // Error handling, better do nothing { _pbStart->setEnabled( false ); _pbStop->setEnabled( false ); } getServiceStatus(); } void KDEDConfig::slotServiceRunningToggled() { getServiceStatus(); slotEvalItem(_lvStartup->currentItem()); } void KDEDConfig::slotStartService() { QCString service = _lvStartup->currentItem()->text(4).latin1(); QByteArray data, replyData; QCString replyType; QDataStream arg( data, IO_WriteOnly ); arg << service; if (kapp->dcopClient()->call( "kded", "kded", "loadModule(QCString)", data, replyType, replyData ) ) { QDataStream reply(replyData, IO_ReadOnly); if ( replyType == "bool" ) { bool result; reply >> result; if ( result ) slotServiceRunningToggled(); else KMessageBox::error(this, i18n("Unable to start service.")); } else { kdDebug() << "loadModule() on kded returned an unexpected type of reply: " << replyType << endl; } } else { KMessageBox::error(this, i18n("Unable to contact KDED.")); } } void KDEDConfig::slotStopService() { QCString service = _lvStartup->currentItem()->text(4).latin1(); kdDebug() << "Stopping: " << service << endl; QByteArray data; QDataStream arg( data, IO_WriteOnly ); arg << service; if (kapp->dcopClient()->send( "kded", "kded", "unloadModule(QCString)", data ) ) { slotServiceRunningToggled(); } else { KMessageBox::error(this, i18n("Unable to stop service.")); } } void KDEDConfig::slotItemChecked(QCheckListItem*) { emit changed(true); } CheckListItem::CheckListItem(QListView *parent, const QString &text) : QObject(parent), QCheckListItem(parent, text, CheckBox) { } void CheckListItem::stateChange(bool on) { QCheckListItem::stateChange(on); emit changed(this); }