2014-11-15 04:16:00 +02:00
|
|
|
/*
|
|
|
|
Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
|
|
|
|
Copyright (c) 2000 Matthias Elter <elter@kde.org>
|
|
|
|
Copyright (c) 2004 Frans Englich <frans.englich@telia.com>
|
|
|
|
|
|
|
|
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; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include <QtDBus/QtDBus>
|
|
|
|
|
|
|
|
#include <KAboutData>
|
|
|
|
#include <KApplication>
|
|
|
|
#include <KCmdLineArgs>
|
|
|
|
#include <KCModuleInfo>
|
|
|
|
#include <KCMultiDialog>
|
|
|
|
#include <KDebug>
|
|
|
|
#include <KLocale>
|
|
|
|
#include <KServiceTypeTrader>
|
|
|
|
#include <KStartupInfo>
|
|
|
|
#include <KGlobal>
|
|
|
|
#include <KIcon>
|
|
|
|
#include <kdeversion.h>
|
|
|
|
|
2015-02-27 09:28:46 +00:00
|
|
|
#include "moc_main.cpp"
|
2014-11-15 04:16:00 +02:00
|
|
|
|
|
|
|
KService::List m_modules;
|
|
|
|
|
|
|
|
static bool caseInsensitiveLessThan(const KService::Ptr s1, const KService::Ptr s2)
|
|
|
|
{
|
|
|
|
const int compare = QString::compare(s1->desktopEntryName(),
|
|
|
|
s2->desktopEntryName(),
|
|
|
|
Qt::CaseInsensitive);
|
|
|
|
return (compare < 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void listModules()
|
|
|
|
{
|
|
|
|
const KService::List services = KServiceTypeTrader::self()->query( "KCModule", "[X-KDE-ParentApp] == 'kcontrol' or [X-KDE-ParentApp] == 'kinfocenter'" );
|
|
|
|
for( KService::List::const_iterator it = services.begin();
|
|
|
|
it != services.end(); ++it)
|
|
|
|
{
|
|
|
|
const KService::Ptr s = (*it);
|
|
|
|
m_modules.append(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
qStableSort(m_modules.begin(), m_modules.end(), caseInsensitiveLessThan);
|
|
|
|
}
|
|
|
|
|
|
|
|
static KService::Ptr locateModule(const QString& module)
|
|
|
|
{
|
|
|
|
QString path = module;
|
|
|
|
|
|
|
|
if (!path.endsWith(QLatin1String(".desktop")))
|
|
|
|
path += ".desktop";
|
|
|
|
|
|
|
|
KService::Ptr service = KService::serviceByStorageId( path );
|
|
|
|
if (!service) {
|
|
|
|
return KService::Ptr();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!service->hasServiceType("KCModule")) {
|
|
|
|
// Not a KCModule. E.g. "kcmshell4 akonadi" finds services/kresources/kabc/akonadi.desktop, unrelated.
|
|
|
|
return KService::Ptr();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( service->noDisplay() ) {
|
2022-10-22 19:31:24 +03:00
|
|
|
kDebug() << module << " should not be loaded.";
|
2014-11-15 04:16:00 +02:00
|
|
|
return KService::Ptr();
|
|
|
|
}
|
|
|
|
|
|
|
|
return service;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KCMShell::isRunning()
|
|
|
|
{
|
|
|
|
QString owner = QDBusConnection::sessionBus().interface()->serviceOwner(m_serviceName);
|
|
|
|
if( owner == QDBusConnection::sessionBus().baseService() )
|
|
|
|
return false; // We are the one and only.
|
|
|
|
|
2022-10-22 19:31:24 +03:00
|
|
|
kDebug() << "kcmshell4 with modules '" <<
|
2022-11-13 01:41:49 +02:00
|
|
|
m_serviceName << "' is already running.";
|
2014-11-15 04:16:00 +02:00
|
|
|
|
|
|
|
QDBusInterface iface(m_serviceName, "/KCModule/dialog", "org.kde.KCMShellMultiDialog");
|
|
|
|
QDBusReply<void> reply = iface.call("activate", kapp->startupId());
|
|
|
|
if (!reply.isValid())
|
|
|
|
{
|
2022-10-22 19:31:24 +03:00
|
|
|
kDebug() << "Calling D-Bus function dialog::activate() failed.";
|
2014-11-15 04:16:00 +02:00
|
|
|
return false; // Error, we have to do it ourselves.
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
KCMShellMultiDialog::KCMShellMultiDialog(KPageDialog::FaceType dialogFace, QWidget *parent)
|
|
|
|
: KCMultiDialog(parent)
|
|
|
|
{
|
|
|
|
setFaceType(dialogFace);
|
|
|
|
setModal(true);
|
|
|
|
|
|
|
|
QDBusConnection::sessionBus().registerObject("/KCModule/dialog", this, QDBusConnection::ExportScriptableSlots);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KCMShellMultiDialog::activate( const QByteArray& asn_id )
|
|
|
|
{
|
2022-10-22 19:31:24 +03:00
|
|
|
kDebug() ;
|
2014-11-15 04:16:00 +02:00
|
|
|
|
|
|
|
#ifdef Q_WS_X11
|
|
|
|
KStartupInfo::setNewStartupId( this, asn_id );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void KCMShell::setServiceName(const QString &dbusName )
|
|
|
|
{
|
|
|
|
m_serviceName = QLatin1String( "org.kde.kcmshell_" ) + dbusName;
|
|
|
|
QDBusConnection::sessionBus().registerService(m_serviceName);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KCMShell::waitForExit()
|
|
|
|
{
|
2022-10-22 19:31:24 +03:00
|
|
|
kDebug();
|
2014-11-15 04:16:00 +02:00
|
|
|
|
|
|
|
QDBusServiceWatcher *watcher = new QDBusServiceWatcher(this);
|
|
|
|
watcher->setConnection(QDBusConnection::sessionBus());
|
|
|
|
watcher->setWatchMode(QDBusServiceWatcher::WatchForOwnerChange);
|
|
|
|
watcher->addWatchedService(m_serviceName);
|
|
|
|
connect(watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
|
|
|
|
SLOT(appExit(QString,QString,QString)));
|
|
|
|
exec();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KCMShell::appExit(const QString &appId, const QString &oldName, const QString &newName)
|
|
|
|
{
|
|
|
|
Q_UNUSED(appId);
|
|
|
|
Q_UNUSED(newName);
|
2022-10-22 19:31:24 +03:00
|
|
|
kDebug();
|
2014-11-15 04:16:00 +02:00
|
|
|
|
|
|
|
if (!oldName.isEmpty())
|
|
|
|
{
|
2022-10-22 19:31:24 +03:00
|
|
|
kDebug() << "'" << appId << "' closed, dereferencing.";
|
2014-11-15 04:16:00 +02:00
|
|
|
KGlobal::deref();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-09 16:39:54 +00:00
|
|
|
int main(int _argc, char *_argv[])
|
2014-11-15 04:16:00 +02:00
|
|
|
{
|
|
|
|
KAboutData aboutData( "kcmshell", 0, ki18n("KDE Control Module"),
|
|
|
|
KDE_VERSION_STRING,
|
|
|
|
ki18n("A tool to start single KDE control modules"),
|
|
|
|
KAboutData::License_GPL,
|
|
|
|
ki18n("(c) 1999-2004, The KDE Developers") );
|
|
|
|
|
|
|
|
aboutData.addAuthor(ki18n("Frans Englich"), ki18n("Maintainer"), "frans.englich@kde.org");
|
|
|
|
aboutData.addAuthor(ki18n("Daniel Molkentin"), KLocalizedString(), "molkentin@kde.org");
|
|
|
|
aboutData.addAuthor(ki18n("Matthias Hoelzer-Kluepfel"),KLocalizedString(), "hoelzer@kde.org");
|
|
|
|
aboutData.addAuthor(ki18n("Matthias Elter"),KLocalizedString(), "elter@kde.org");
|
|
|
|
aboutData.addAuthor(ki18n("Matthias Ettrich"),KLocalizedString(), "ettrich@kde.org");
|
|
|
|
aboutData.addAuthor(ki18n("Waldo Bastian"),KLocalizedString(), "bastian@kde.org");
|
|
|
|
|
|
|
|
KCmdLineArgs::init(_argc, _argv, &aboutData);
|
|
|
|
|
|
|
|
KCmdLineOptions options;
|
|
|
|
options.add("list", ki18n("List all possible modules"));
|
|
|
|
options.add("+module", ki18n("Configuration module to open"));
|
|
|
|
options.add("lang <language>", ki18n("Specify a particular language"));
|
|
|
|
options.add("silent", ki18n("Do not display main window"));
|
|
|
|
options.add("args <arguments>", ki18n("Arguments for the module"));
|
|
|
|
KCmdLineArgs::addCmdLineOptions( options ); // Add our own options.
|
|
|
|
KCMShell app;
|
|
|
|
|
|
|
|
const KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
|
|
|
|
|
|
|
const QString lang = args->getOption("lang");
|
|
|
|
if( !lang.isEmpty() ) {
|
|
|
|
KGlobal::setLocale(new KLocale(aboutData.catalogName(), lang));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args->isSet("list"))
|
|
|
|
{
|
2022-10-23 18:44:48 +03:00
|
|
|
std::cout << i18n("The following modules are available:").toLocal8Bit().data() << std::endl;
|
2014-11-15 04:16:00 +02:00
|
|
|
|
|
|
|
listModules();
|
|
|
|
|
|
|
|
int maxLen=0;
|
|
|
|
|
|
|
|
for( KService::List::ConstIterator it = m_modules.constBegin(); it != m_modules.constEnd(); ++it)
|
|
|
|
{
|
|
|
|
int len = (*it)->desktopEntryName().length();
|
|
|
|
if (len > maxLen)
|
|
|
|
maxLen = len;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( KService::List::ConstIterator it = m_modules.constBegin(); it != m_modules.constEnd(); ++it)
|
|
|
|
{
|
|
|
|
QString entry("%1 - %2");
|
|
|
|
|
|
|
|
entry = entry.arg((*it)->desktopEntryName().leftJustified(maxLen, ' '))
|
|
|
|
.arg(!(*it)->comment().isEmpty() ? (*it)->comment()
|
|
|
|
: i18n("No description available"));
|
|
|
|
|
2022-10-23 18:44:48 +03:00
|
|
|
std::cout << entry.toLocal8Bit().data() << std::endl;
|
2014-11-15 04:16:00 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args->count() < 1)
|
|
|
|
{
|
|
|
|
args->usage();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString serviceName;
|
|
|
|
KService::List modules;
|
|
|
|
for (int i = 0; i < args->count(); i++)
|
|
|
|
{
|
|
|
|
const QString arg = args->arg(i);
|
|
|
|
KService::Ptr service = locateModule(arg);
|
|
|
|
if (!service) {
|
|
|
|
service = locateModule("kcm_" + arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (service) {
|
|
|
|
modules.append(service);
|
|
|
|
if( !serviceName.isEmpty() )
|
|
|
|
serviceName += '_';
|
|
|
|
serviceName += args->arg(i);
|
|
|
|
} else {
|
|
|
|
fprintf(stderr, "%s\n", i18n("Could not find module '%1'. See kcmshell4 --list for the full list of modules.", arg).toLocal8Bit().constData());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if this particular module combination is already running */
|
|
|
|
app.setServiceName(serviceName);
|
|
|
|
if( app.isRunning() ) {
|
|
|
|
app.waitForExit();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
KPageDialog::FaceType ftype = KPageDialog::Plain;
|
|
|
|
|
|
|
|
if (modules.count() < 1) {
|
|
|
|
return 0;
|
|
|
|
} else if (modules.count() > 1) {
|
|
|
|
ftype = KPageDialog::List;
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList moduleArgs;
|
|
|
|
QString x = args->getOption("args");
|
|
|
|
moduleArgs << x.split(QRegExp(" +"));
|
|
|
|
|
|
|
|
KCMShellMultiDialog *dlg = new KCMShellMultiDialog(ftype);
|
|
|
|
KCmdLineArgs *kdeargs = KCmdLineArgs::parsedArgs("kde");
|
|
|
|
if (kdeargs && kdeargs->isSet("caption")) {
|
|
|
|
dlg->setCaption(QString());
|
|
|
|
kdeargs->clear();
|
|
|
|
} else if (modules.count() == 1) {
|
|
|
|
dlg->setCaption(modules.first()->name());
|
|
|
|
}
|
|
|
|
|
2015-08-28 05:29:36 +03:00
|
|
|
foreach(const KSharedPtr<KService> it, modules)
|
|
|
|
dlg->addModule(it, 0, moduleArgs);
|
2014-11-15 04:16:00 +02:00
|
|
|
|
|
|
|
if ( !args->isSet( "icon" ) && modules.count() == 1)
|
|
|
|
{
|
|
|
|
QString iconName = KCModuleInfo(modules.first()).icon();
|
|
|
|
dlg->setWindowIcon( KIcon(iconName) );
|
|
|
|
}
|
|
|
|
dlg->exec();
|
|
|
|
delete dlg;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
// vim: sw=4 et sts=4
|