|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2002 Daniel Molkentin <molkentin@kde.org>
|
|
|
|
|
|
|
|
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 <tqheader.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqpushbutton.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <tqvgroupbox.h>
|
|
|
|
#include <tqwhatsthis.h>
|
|
|
|
|
|
|
|
#include <dcopclient.h>
|
|
|
|
#include <dcopref.h>
|
|
|
|
|
|
|
|
#include <tdeaboutdata.h>
|
|
|
|
#include <tdeapplication.h>
|
|
|
|
#include <kbuttonbox.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kdesktopfile.h>
|
|
|
|
#include <kdialog.h>
|
|
|
|
#include <kgenericfactory.h>
|
|
|
|
#include <tdelistview.h>
|
|
|
|
#include <tdemessagebox.h>
|
|
|
|
#include <kservice.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
|
|
|
|
#include "kcmkded.h"
|
|
|
|
#include "kcmkded.moc"
|
|
|
|
|
|
|
|
typedef KGenericFactory<KDEDConfig, TQWidget> KDEDFactory;
|
|
|
|
K_EXPORT_COMPONENT_FACTORY( kcm_kded, KDEDFactory( "kcmkded" ) )
|
|
|
|
|
|
|
|
|
|
|
|
KDEDConfig::KDEDConfig(TQWidget* parent, const char* name, const TQStringList &) :
|
|
|
|
TDECModule( KDEDFactory::instance(), parent, name )
|
|
|
|
{
|
|
|
|
TDEAboutData *about =
|
|
|
|
new TDEAboutData( I18N_NOOP( "kcmkded" ), I18N_NOOP( "TDE Service Manager" ),
|
|
|
|
0, 0, TDEAboutData::License_GPL,
|
|
|
|
I18N_NOOP( "(c) 2002 Daniel Molkentin" ) );
|
|
|
|
about->addAuthor("Daniel Molkentin",0,"molkentin@kde.org");
|
|
|
|
setAboutData( about );
|
|
|
|
|
|
|
|
setQuickHelp( i18n("<h1>Service Manager</h1><p>This module allows you to have an overview of all plugins "
|
|
|
|
"running as TDE Services. Generally, there are two types of service:</p>"
|
|
|
|
"<ul><li>Services invoked at startup</li><li>Services called on demand</li></ul>"
|
|
|
|
"<p>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.</p>"
|
|
|
|
"<p><b> Use this with care: some services are vital for TDE; do not deactivate services if you"
|
|
|
|
" do not know what you are doing.</b></p>"));
|
|
|
|
|
|
|
|
RUNNING = i18n("Running")+" ";
|
|
|
|
NOT_RUNNING = i18n("Not running")+" ";
|
|
|
|
|
|
|
|
TQVBoxLayout *lay = new TQVBoxLayout( this, 0, KDialog::spacingHint() );
|
|
|
|
|
|
|
|
TQGroupBox *gb = new TQVGroupBox(i18n("Load-on-Demand Services"), this );
|
|
|
|
TQWhatsThis::add(gb, i18n("This is a list of available TDE services which will "
|
|
|
|
"be started on demand. They are only listed for convenience, as you "
|
|
|
|
"cannot manipulate these services."));
|
|
|
|
lay->addWidget( gb );
|
|
|
|
|
|
|
|
_lvLoD = new TDEListView( gb );
|
|
|
|
_lvLoD->addColumn(i18n("Service"));
|
|
|
|
_lvLoD->addColumn(i18n("Description"));
|
|
|
|
_lvLoD->addColumn(i18n("Status"));
|
|
|
|
_lvLoD->setAllColumnsShowFocus(true);
|
|
|
|
_lvLoD->header()->setStretchEnabled(true, 1);
|
|
|
|
|
|
|
|
gb = new TQVGroupBox(i18n("Startup Services"), this );
|
|
|
|
TQWhatsThis::add(gb, i18n("This shows all TDE services that can be loaded "
|
|
|
|
"on TDE startup. Checked services will be invoked on next startup. "
|
|
|
|
"Be careful with deactivation of unknown services."));
|
|
|
|
lay->addWidget( gb );
|
|
|
|
|
|
|
|
_lvStartup = new TDEListView( 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, Qt::Horizontal);
|
|
|
|
_pbStart = buttonBox->addButton( i18n("Start"));
|
|
|
|
_pbStop = buttonBox->addButton( i18n("Stop"));
|
|
|
|
|
|
|
|
_pbStart->setEnabled( false );
|
|
|
|
_pbStop->setEnabled( false );
|
|
|
|
|
|
|
|
connect(_pbStart, TQT_SIGNAL(clicked()), TQT_SLOT(slotStartService()));
|
|
|
|
connect(_pbStop, TQT_SIGNAL(clicked()), TQT_SLOT(slotStopService()));
|
|
|
|
connect(_lvStartup, TQT_SIGNAL(selectionChanged(TQListViewItem*)), TQT_SLOT(slotEvalItem(TQListViewItem*)) );
|
|
|
|
|
|
|
|
load();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setModuleGroup(TDEConfig *config, const TQString &filename)
|
|
|
|
{
|
|
|
|
TQString 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(TQString("Module-%1").arg(module));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KDEDConfig::autoloadEnabled(TDEConfig *config, const TQString &filename)
|
|
|
|
{
|
|
|
|
setModuleGroup(config, filename);
|
|
|
|
return config->readBoolEntry("autoload", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KDEDConfig::setAutoloadEnabled(TDEConfig *config, const TQString &filename, bool b)
|
|
|
|
{
|
|
|
|
setModuleGroup(config, filename);
|
|
|
|
return config->writeEntry("autoload", b);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KDEDConfig::load() {
|
|
|
|
load ( false );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KDEDConfig::load( bool useDefaults ) {
|
|
|
|
TDEConfig kdedrc("kdedrc", true, false);
|
|
|
|
kdedrc.setReadDefaults( useDefaults );
|
|
|
|
|
|
|
|
_lvStartup->clear();
|
|
|
|
_lvLoD->clear();
|
|
|
|
|
|
|
|
TQStringList files;
|
|
|
|
TDEGlobal::dirs()->findAllResources( "services",
|
|
|
|
TQString::fromLatin1( "kded/*.desktop" ),
|
|
|
|
true, true, files );
|
|
|
|
|
|
|
|
TQListViewItem* item = 0L;
|
|
|
|
CheckListItem* clitem;
|
|
|
|
for ( TQStringList::ConstIterator it = files.begin(); it != files.end(); ++it ) {
|
|
|
|
|
|
|
|
if ( KDesktopFile::isDesktopFile( *it ) ) {
|
|
|
|
KDesktopFile file( *it, true, "services" );
|
|
|
|
|
|
|
|
if ( file.readBoolEntry("X-TDE-Kded-autoload") ) {
|
|
|
|
clitem = new CheckListItem(_lvStartup, TQString::null);
|
|
|
|
connect(clitem, TQT_SIGNAL(changed(TQCheckListItem*)), TQT_SLOT(slotItemChecked(TQCheckListItem*)));
|
|
|
|
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-TDE-Library"));
|
|
|
|
}
|
|
|
|
else if ( file.readBoolEntry("X-TDE-Kded-load-on-demand") ) {
|
|
|
|
item = new TQListViewItem(_lvLoD, file.readName());
|
|
|
|
item->setText(1, file.readComment());
|
|
|
|
item->setText(2, NOT_RUNNING);
|
|
|
|
item->setText(4, file.readEntry("X-TDE-Library"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getServiceStatus();
|
|
|
|
emit changed( useDefaults );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KDEDConfig::save() {
|
|
|
|
TQCheckListItem* item = 0L;
|
|
|
|
|
|
|
|
TQStringList files;
|
|
|
|
TDEGlobal::dirs()->findAllResources( "services",
|
|
|
|
TQString::fromLatin1( "kded/*.desktop" ),
|
|
|
|
true, true, files );
|
|
|
|
|
|
|
|
TDEConfig kdedrc("kdedrc", false, false);
|
|
|
|
|
|
|
|
for ( TQStringList::ConstIterator it = files.begin(); it != files.end(); ++it ) {
|
|
|
|
|
|
|
|
if ( KDesktopFile::isDesktopFile( *it ) ) {
|
|
|
|
|
|
|
|
TDEConfig file( *it, false, false, "services" );
|
|
|
|
file.setGroup("Desktop Entry");
|
|
|
|
|
|
|
|
if (file.readBoolEntry("X-TDE-Kded-autoload")){
|
|
|
|
|
|
|
|
item = static_cast<TQCheckListItem *>(_lvStartup->findItem(file.readEntry("X-TDE-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" );
|
|
|
|
TQTimer::singleShot(0, this, TQT_SLOT(slotServiceRunningToggled()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KDEDConfig::defaults()
|
|
|
|
{
|
|
|
|
load( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KDEDConfig::getServiceStatus()
|
|
|
|
{
|
|
|
|
QCStringList modules;
|
|
|
|
TQCString replyType;
|
|
|
|
TQByteArray replyData;
|
|
|
|
|
|
|
|
|
|
|
|
if (!kapp->dcopClient()->call( "kded", "kded", "loadedModules()", TQByteArray(),
|
|
|
|
replyType, replyData ) ) {
|
|
|
|
|
|
|
|
_lvLoD->setEnabled( false );
|
|
|
|
_lvStartup->setEnabled( false );
|
|
|
|
KMessageBox::error(this, i18n("Unable to contact KDED."));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
if ( replyType == "QCStringList" ) {
|
|
|
|
TQDataStream reply(replyData, IO_ReadOnly);
|
|
|
|
reply >> modules;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for( TQListViewItemIterator it( _lvLoD); it.current() != 0; ++it )
|
|
|
|
it.current()->setText(2, NOT_RUNNING);
|
|
|
|
for( TQListViewItemIterator it( _lvStartup); it.current() != 0; ++it )
|
|
|
|
it.current()->setText(3, NOT_RUNNING);
|
|
|
|
for ( QCStringList::Iterator it = modules.begin(); it != modules.end(); ++it )
|
|
|
|
{
|
|
|
|
TQListViewItem *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()
|
|
|
|
{
|
|
|
|
TQString current = _lvStartup->currentItem()->text(4);
|
|
|
|
load();
|
|
|
|
TQListViewItem *item = _lvStartup->findItem(current, 4);
|
|
|
|
if (item)
|
|
|
|
_lvStartup->setCurrentItem(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KDEDConfig::slotEvalItem(TQListViewItem * 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()
|
|
|
|
{
|
|
|
|
TQCString service = _lvStartup->currentItem()->text(4).latin1();
|
|
|
|
|
|
|
|
TQByteArray data, replyData;
|
|
|
|
TQCString replyType;
|
|
|
|
TQDataStream arg( data, IO_WriteOnly );
|
|
|
|
arg << service;
|
|
|
|
if (kapp->dcopClient()->call( "kded", "kded", "loadModule(TQCString)", data, replyType, replyData ) ) {
|
|
|
|
TQDataStream 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()
|
|
|
|
{
|
|
|
|
TQCString service = _lvStartup->currentItem()->text(4).latin1();
|
|
|
|
kdDebug() << "Stopping: " << service << endl;
|
|
|
|
TQByteArray data;
|
|
|
|
TQDataStream arg( data, IO_WriteOnly );
|
|
|
|
|
|
|
|
arg << service;
|
|
|
|
if (kapp->dcopClient()->send( "kded", "kded", "unloadModule(TQCString)", data ) ) {
|
|
|
|
slotServiceRunningToggled();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
KMessageBox::error(this, i18n("Unable to stop service."));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void KDEDConfig::slotItemChecked(TQCheckListItem*)
|
|
|
|
{
|
|
|
|
emit changed(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
CheckListItem::CheckListItem(TQListView *parent, const TQString &text)
|
|
|
|
: TQObject(parent),
|
|
|
|
TQCheckListItem(parent, text, CheckBox)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
void CheckListItem::stateChange(bool on)
|
|
|
|
{
|
|
|
|
TQCheckListItem::stateChange(on);
|
|
|
|
emit changed(this);
|
|
|
|
}
|