kde-workspace/kcmshell/main.cpp

290 lines
8.9 KiB
C++
Raw Permalink Normal View History

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() ) {
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.
kDebug() << "kcmshell4 with modules '" <<
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())
{
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 )
{
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()
{
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);
kDebug();
2014-11-15 04:16:00 +02:00
if (!oldName.isEmpty())
{
kDebug() << "'" << appId << "' closed, dereferencing.";
2014-11-15 04:16:00 +02:00
KGlobal::deref();
}
}
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"))
{
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"));
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