kdelibs/kutils/kcmoduleproxy.cpp

357 lines
10 KiB
C++
Raw Normal View History

2014-11-13 01:04:59 +02:00
/* This file is part of the KDE project
Copyright (C) 2004 Frans Englich <frans.englich@telia.com>
Copyright (C) 2003 Matthias Kretz <kretz@kde.org>
This library 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 library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kcmoduleproxy.h"
#include "kcmoduleproxy_p.h"
#include <QtGui/QApplication>
#include <QtGui/QLayout>
#include <QtDBus/QDBusConnectionInterface>
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusReply>
2014-11-13 01:04:59 +02:00
#include <kaboutdata.h>
#include <kcmodule.h>
#include <kcmoduleinfo.h>
#include <kdebug.h>
#include <kdialog.h>
#include <klocale.h>
#include <kservice.h>
#include <kstandarddirs.h>
#include <kuser.h>
#include <kcmoduleloader.h>
#include "kcolorscheme.h"
#include "ksettingswidgetadaptor.h"
/*
TODO:
- Two Layout problems in runAsRoot:
* lblBusy doesn't show
* d->kcm/d->rootInfo doesn't get it right when the user presses cancel in the kdesudo dialog
2014-11-13 01:04:59 +02:00
- Resizing horizontally is contrained; minimum size is set somewhere.
It appears to be somehow derived from the module's size.
2014-11-13 01:04:59 +02:00
- Prettify: set icon in KCMultiDialog.
*/
2014-11-13 01:04:59 +02:00
/***************************************************************/
KCModule* KCModuleProxy::realModule() const
{
Q_D(const KCModuleProxy);
/*
* Note, don't call any function that calls realModule() since
* that leads to an infinite loop.
*/
/* Already loaded */
if (!d->kcm) {
QApplication::setOverrideCursor(Qt::WaitCursor);
const_cast<KCModuleProxyPrivate*>(d)->loadModule();
QApplication::restoreOverrideCursor();
}
return d->kcm;
2014-11-13 01:04:59 +02:00
}
void KCModuleProxyPrivate::loadModule()
{
if (!topLayout) {
topLayout = new QVBoxLayout(parent);
topLayout->setMargin(0);
QString name = modInfo.library();
name.replace("-", "_"); //hyphen is not allowed in dbus, only [A-Z][a-z][0-9]_
dbusPath = QLatin1String("/internal/KSettingsWidget/") + name;
dbusService = QLatin1String("org.kde.internal.KSettingsWidget_") + name;
}
2014-11-13 01:04:59 +02:00
if (QDBusConnection::sessionBus().registerService(dbusService) || bogusOccupier) {
/* We got the name we requested, because no one was before us,
* or, it was an random application which had picked that name
*/
kDebug(711) << "Module not already loaded, loading module " << modInfo.moduleName()
<< " from library " << modInfo.library();
2014-11-13 01:04:59 +02:00
kcm = KCModuleLoader::loadModule(modInfo, KCModuleLoader::Inline, parent, args);
2014-11-13 01:04:59 +02:00
QObject::connect(kcm, SIGNAL(changed(bool)), parent, SLOT(_k_moduleChanged(bool)));
QObject::connect(kcm, SIGNAL(destroyed()), parent, SLOT(_k_moduleDestroyed()));
QObject::connect(kcm, SIGNAL(quickHelpChanged()), parent, SIGNAL(quickHelpChanged()));
parent->setWhatsThis(kcm->quickHelp());
if (kcm->layout()) {
kcm->layout()->setMargin(0);
}
topLayout->addWidget( kcm );
if (!modInfo.library().isEmpty()) {
QDBusConnection::sessionBus().registerObject(
dbusPath, new KSettingsWidgetAdaptor(parent), QDBusConnection::ExportAllSlots
);
}
if (!rootInfo && /* If it's not already done */
kcm->useRootOnlyMessage() && /* kcm wants root message */
!KUser().isSuperUser() ) /* Not necessary if we're root */
{
#if 0
rootInfo = new QLabel(parent);
topLayout->insertWidget(0, rootInfo);
QPalette palette = rootInfo->palette();
KStatefulBrush stbrush(KColorScheme::Window, KColorScheme::NeutralBackground);
qDebug() << stbrush.brush(rootInfo);
palette.setBrush(QPalette::Window, stbrush.brush(rootInfo));
rootInfo->setPalette(palette);
rootInfo->setAutoFillBackground(true);
const QString message = kcm->rootOnlyMessage();
if (message.isEmpty() )
rootInfo->setText(
i18n(
"<b>Changes in this section require root access.</b><br />"
"On applying your changes you will have to supply your root "
"password." )
);
} else {
rootInfo->setText(message);
}
rootInfo->setWhatsThis(
i18n(
"This section requires special permissions, probably "
"for system-wide changes; therefore, it is "
"required that you provide the root password to be "
"able to change the module's properties. If "
"you cannot provide the password, the changes of the "
"module cannot be saved "
)
);
#endif
}
} else {
kDebug(711) << "Module already loaded, loading KCMError";
/* Figure out the name of where the module is already loaded */
QDBusInterface proxy(dbusService, dbusPath, "org.kde.internal.KSettingsWidget");
QDBusReply<QString> reply = proxy.call("applicationName");
if (reply.isValid()) {
QObject::connect(
QDBusConnection::sessionBus().interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
parent, SLOT(_k_ownerChanged(QString,QString,QString))
);
kcm = KCModuleLoader::reportError(
KCModuleLoader::Inline,
i18nc(
"Argument is application name", "This configuration section is "
"already opened in %1", reply.value()
),
" ",
parent
);
topLayout->addWidget(kcm);
} else {
kDebug(711) << "Calling KCModuleProxy's DBus interface for fetching the name failed.";
bogusOccupier = true;
loadModule();
}
}
2014-11-13 01:04:59 +02:00
}
void KCModuleProxyPrivate::_k_ownerChanged(const QString &service, const QString &oldOwner, const QString &)
{
if (service == dbusService && !oldOwner.isEmpty()) {
// Violence: Get rid of KCMError & CO, so that
// realModule() attempts to reload the module
delete kcm;
kcm = nullptr;
2014-11-13 01:04:59 +02:00
Q_Q(KCModuleProxy);
q->realModule();
Q_ASSERT(kcm);
kcm->show();
}
}
void KCModuleProxy::showEvent(QShowEvent *ev)
2014-11-13 01:04:59 +02:00
{
Q_D(KCModuleProxy);
(void)realModule();
2014-11-13 01:04:59 +02:00
/* We have no kcm, if we're in root mode */
if( d->kcm ) {
d->kcm->showEvent(ev);
2014-11-13 01:04:59 +02:00
}
QWidget::showEvent(ev);
2014-11-13 01:04:59 +02:00
}
KCModuleProxy::~KCModuleProxy()
{
deleteClient();
delete d_ptr;
2014-11-13 01:04:59 +02:00
}
void KCModuleProxy::deleteClient()
{
Q_D(KCModuleProxy);
delete d->kcm;
d->kcm = nullptr;
2014-11-13 01:04:59 +02:00
if (qApp) {
qApp->syncX();
}
2014-11-13 01:04:59 +02:00
}
void KCModuleProxyPrivate::_k_moduleChanged(bool c)
{
if (changed == c) {
2014-11-13 01:04:59 +02:00
return;
}
Q_Q(KCModuleProxy);
changed = c;
emit q->changed(c);
emit q->changed(q);
}
void KCModuleProxyPrivate::_k_moduleDestroyed()
{
kcm = nullptr;
2014-11-13 01:04:59 +02:00
}
KCModuleProxy::KCModuleProxy(const KService::Ptr &service, QWidget *parent,
const QStringList &args)
: QWidget(parent),
d_ptr(new KCModuleProxyPrivate(this, KCModuleInfo(service), args))
2014-11-13 01:04:59 +02:00
{
d_ptr->q_ptr = this;
}
KCModuleProxy::KCModuleProxy(const KCModuleInfo &info, QWidget *parent,
const QStringList &args)
: QWidget(parent),
d_ptr(new KCModuleProxyPrivate(this, info, args))
2014-11-13 01:04:59 +02:00
{
d_ptr->q_ptr = this;
}
KCModuleProxy::KCModuleProxy(const QString &serviceName, QWidget *parent,
const QStringList &args)
: QWidget(parent),
d_ptr(new KCModuleProxyPrivate(this, KCModuleInfo(serviceName), args))
2014-11-13 01:04:59 +02:00
{
d_ptr->q_ptr = this;
}
void KCModuleProxy::load()
{
Q_D(KCModuleProxy);
if (realModule()) {
d->kcm->load();
2014-11-13 01:04:59 +02:00
d->_k_moduleChanged(false);
}
2014-11-13 01:04:59 +02:00
}
void KCModuleProxy::save()
{
Q_D(KCModuleProxy);
if (d->changed && realModule()) {
d->kcm->save();
2014-11-13 01:04:59 +02:00
d->_k_moduleChanged(false);
}
2014-11-13 01:04:59 +02:00
}
void KCModuleProxy::defaults()
{
Q_D(KCModuleProxy);
if (realModule()) {
d->kcm->defaults();
}
2014-11-13 01:04:59 +02:00
}
QString KCModuleProxy::quickHelp() const
{
return realModule() ? realModule()->quickHelp() : QString();
2014-11-13 01:04:59 +02:00
}
const KAboutData* KCModuleProxy::aboutData() const
2014-11-13 01:04:59 +02:00
{
return realModule() ? realModule()->aboutData() : nullptr;
2014-11-13 01:04:59 +02:00
}
KCModule::Buttons KCModuleProxy::buttons() const
{
if (realModule()) {
return realModule()->buttons();
}
return KCModule::Buttons(KCModule::Help | KCModule::Default | KCModule::Apply);
2014-11-13 01:04:59 +02:00
}
QString KCModuleProxy::rootOnlyMessage() const
{
return realModule() ? realModule()->rootOnlyMessage() : QString();
2014-11-13 01:04:59 +02:00
}
bool KCModuleProxy::useRootOnlyMessage() const
{
return realModule() ? realModule()->useRootOnlyMessage() : true;
2014-11-13 01:04:59 +02:00
}
KComponentData KCModuleProxy::componentData() const
{
return realModule() ? realModule()->componentData() : KComponentData();
2014-11-13 01:04:59 +02:00
}
bool KCModuleProxy::changed() const
{
Q_D(const KCModuleProxy);
return d->changed;
2014-11-13 01:04:59 +02:00
}
KCModuleInfo KCModuleProxy::moduleInfo() const
{
Q_D(const KCModuleProxy);
return d->modInfo;
2014-11-13 01:04:59 +02:00
}
QString KCModuleProxy::dbusService() const
{
Q_D(const KCModuleProxy);
return d->dbusService;
2014-11-13 01:04:59 +02:00
}
QString KCModuleProxy::dbusPath() const
{
Q_D(const KCModuleProxy);
return d->dbusPath;
2014-11-13 01:04:59 +02:00
}
//X void KCModuleProxy::emitQuickHelpChanged()
//X {
//X emit quickHelpChanged();
//X }
/***************************************************************/
#include "moc_kcmoduleproxy.cpp"