00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kcmoduleproxy.h"
00021 #include "kcmoduleproxy_p.h"
00022
00023 #include <QtGui/QApplication>
00024 #include <QtGui/QCursor>
00025 #include <QtCore/QDataStream>
00026 #include <QtGui/QKeyEvent>
00027 #include <QtCore/QFileInfo>
00028 #include <QtGui/QFrame>
00029 #include <QtGui/QLabel>
00030 #include <QtGui/QLayout>
00031 #include <QtCore/QPoint>
00032
00033 #include <QtGui/QImage>
00034
00035 #include <QtDBus/QtDBus>
00036
00037 #include <kaboutdata.h>
00038 #include <kcmodule.h>
00039 #include <kcmoduleinfo.h>
00040
00041 #include <kdebug.h>
00042 #include <kdialog.h>
00043 #include <klocale.h>
00044 #include <kservice.h>
00045 #include <kstandarddirs.h>
00046 #include <kuser.h>
00047
00048 #include <kvbox.h>
00049
00050 #include <kcmoduleloader.h>
00051
00052 #include "ksettingswidgetadaptor.h"
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 KCModule* KCModuleProxy::realModule() const
00070 {
00071 Q_D(const KCModuleProxy);
00072
00073
00074
00075
00076
00077
00078 if( !d->kcm )
00079 {
00080 QApplication::setOverrideCursor( Qt::WaitCursor );
00081 const_cast<KCModuleProxyPrivate *>(d)->loadModule();
00082 QApplication::restoreOverrideCursor();
00083 }
00084 return d->kcm;
00085 }
00086
00087 void KCModuleProxyPrivate::loadModule()
00088 {
00089 if( !topLayout )
00090 {
00091 topLayout = new QVBoxLayout( parent );
00092 topLayout->setMargin( 0 );
00093
00094 QString name = modInfo.handle();
00095 dbusPath = QLatin1String("/internal/KSettingsWidget/") + name;
00096 dbusService = QLatin1String("org.kde.internal.KSettingsWidget-") + name;
00097 }
00098
00099 if( QDBusConnection::sessionBus().registerService( dbusService ) || bogusOccupier )
00100 {
00101
00102 kDebug(711) << "Module not already loaded, loading module " << modInfo.moduleName() << " from library " << modInfo.library() << " using symbol " << modInfo.handle();
00103
00104 kcm = KCModuleLoader::loadModule( modInfo, KCModuleLoader::Inline, parent, args );
00105
00106 QObject::connect(kcm, SIGNAL(changed(bool)), parent, SLOT(_k_moduleChanged(bool)));
00107 QObject::connect(kcm, SIGNAL(destroyed()), parent, SLOT(_k_moduleDestroyed()));
00108 QObject::connect( kcm, SIGNAL(quickHelpChanged()), parent, SIGNAL(quickHelpChanged()) );
00109 parent->setWhatsThis( kcm->quickHelp() );
00110
00111 if ( kcm->layout() ) {
00112 kcm->layout()->setMargin( 0 );
00113 }
00114 topLayout->addWidget( kcm );
00115 if( !modInfo.handle().isEmpty() )
00116 QDBusConnection::sessionBus().registerObject(dbusPath, new KSettingsWidgetAdaptor(parent), QDBusConnection::ExportAllSlots);
00117
00118 if ( !rootInfo &&
00119 kcm->useRootOnlyMessage() &&
00120 !KUser().isSuperUser() )
00121 {
00122 rootInfo = new QLabel( parent );
00123 topLayout->insertWidget( 0, rootInfo );
00124
00125 rootInfo->setFrameShape( QFrame::Box );
00126 rootInfo->setFrameShadow( QFrame::Raised );
00127
00128 const QString message = kcm->rootOnlyMessage();
00129 if( message.isEmpty() )
00130 rootInfo->setText( i18n(
00131 "<b>Changes in this section require root access.</b><br />"
00132 "On applying your changes you will have to supply your root "
00133 "password." ) );
00134 else
00135 rootInfo->setText(message);
00136
00137 rootInfo->setWhatsThis( i18n(
00138 "This section requires special permissions, probably "
00139 "for system-wide changes; therefore, it is "
00140 "required that you provide the root password to be "
00141 "able to change the module's properties. If "
00142 "you cannot provide the password, the changes of the "
00143 "module cannot be saved " ) );
00144 }
00145 }
00146 else
00147 {
00148 kDebug(711) << "Module already loaded, loading KCMError";
00149
00150
00151 QDBusInterface proxy( dbusService, dbusPath, "org.kde.internal.KSettingsWidget" );
00152 QDBusReply<QString> reply = proxy.call("applicationName");
00153
00154 if( reply.isValid() )
00155 {
00156 QObject::connect( QDBusConnection::sessionBus().interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)),
00157 parent, SLOT(_k_ownerChanged(QString,QString,QString)));
00158 kcm = KCModuleLoader::reportError( KCModuleLoader::Inline,
00159 i18nc( "Argument is application name", "This configuration section is "
00160 "already opened in %1" , reply.value() ), " ", parent );
00161 topLayout->addWidget( kcm );
00162 }
00163 else
00164 {
00165 kDebug(711) << "Calling KCModuleProxy's DBus interface for fetching the name failed.";
00166 bogusOccupier = true;
00167 loadModule();
00168 }
00169 }
00170 }
00171
00172 void KCModuleProxyPrivate::_k_ownerChanged(const QString &service, const QString &oldOwner, const QString &)
00173 {
00174 if (service == dbusService && !oldOwner.isEmpty()) {
00175
00176
00177 delete kcm;
00178 kcm = 0;
00179 Q_Q(KCModuleProxy);
00180 q->realModule();
00181
00182 Q_ASSERT(kcm);
00183 kcm->show();
00184 }
00185 }
00186
00187 void KCModuleProxy::showEvent( QShowEvent * ev )
00188 {
00189 Q_D(KCModuleProxy);
00190
00191 ( void )realModule();
00192
00193
00194 if( d->kcm ) {
00195 d->kcm->showEvent(ev);
00196 }
00197
00198 QWidget::showEvent( ev );
00199
00200 }
00201
00202 KCModuleProxy::~KCModuleProxy()
00203 {
00204 deleteClient();
00205 KCModuleLoader::unloadModule(moduleInfo());
00206
00207 delete d_ptr;
00208 }
00209
00210 void KCModuleProxy::deleteClient()
00211 {
00212 Q_D(KCModuleProxy);
00213 delete d->kcm;
00214 d->kcm = 0;
00215
00216 qApp->syncX();
00217 }
00218
00219 void KCModuleProxyPrivate::_k_moduleChanged(bool c)
00220 {
00221 if(changed == c) {
00222 return;
00223 }
00224
00225 Q_Q(KCModuleProxy);
00226 changed = c;
00227 emit q->changed(c);
00228 emit q->changed(q);
00229 }
00230
00231 void KCModuleProxyPrivate::_k_moduleDestroyed()
00232 {
00233 kcm = 0;
00234 }
00235
00236 KCModuleProxy::KCModuleProxy( const KService::Ptr& service, QWidget * parent,
00237 const QStringList& args )
00238 : QWidget(parent), d_ptr(new KCModuleProxyPrivate(this, KCModuleInfo(service), args))
00239 {
00240 d_ptr->q_ptr = this;
00241 }
00242
00243 KCModuleProxy::KCModuleProxy( const KCModuleInfo& info, QWidget * parent,
00244 const QStringList& args )
00245 : QWidget(parent), d_ptr(new KCModuleProxyPrivate(this, info, args))
00246 {
00247 d_ptr->q_ptr = this;
00248 }
00249
00250 KCModuleProxy::KCModuleProxy( const QString& serviceName, QWidget * parent,
00251 const QStringList& args )
00252 : QWidget(parent), d_ptr(new KCModuleProxyPrivate(this, KCModuleInfo(serviceName), args))
00253 {
00254 d_ptr->q_ptr = this;
00255 }
00256
00257
00258 void KCModuleProxy::load()
00259 {
00260 Q_D(KCModuleProxy);
00261 if( realModule() )
00262 {
00263 d->kcm->load();
00264 d->_k_moduleChanged(false);
00265 }
00266 }
00267
00268 void KCModuleProxy::save()
00269 {
00270 Q_D(KCModuleProxy);
00271 if( d->changed && realModule() )
00272 {
00273 d->kcm->save();
00274 d->_k_moduleChanged(false);
00275 }
00276 }
00277
00278 void KCModuleProxy::defaults()
00279 {
00280 Q_D(KCModuleProxy);
00281 if( realModule() )
00282 d->kcm->defaults();
00283 }
00284
00285 QString KCModuleProxy::quickHelp() const
00286 {
00287 return realModule() ? realModule()->quickHelp() : QString();
00288 }
00289
00290 const KAboutData * KCModuleProxy::aboutData() const
00291 {
00292 return realModule() ? realModule()->aboutData() : 0;
00293 }
00294
00295 KCModule::Buttons KCModuleProxy::buttons() const
00296 {
00297 if( realModule() )
00298 return realModule()->buttons();
00299 return KCModule::Buttons( KCModule::Help | KCModule::Default | KCModule::Apply );
00300 }
00301
00302 QString KCModuleProxy::rootOnlyMessage() const
00303 {
00304 return realModule() ? realModule()->rootOnlyMessage() : QString();
00305 }
00306
00307 bool KCModuleProxy::useRootOnlyMessage() const
00308 {
00309 return realModule() ? realModule()->useRootOnlyMessage() : true;
00310 }
00311
00312 KComponentData KCModuleProxy::componentData() const
00313 {
00314 return realModule() ? realModule()->componentData() : KComponentData();
00315 }
00316
00317 bool KCModuleProxy::changed() const
00318 {
00319 Q_D(const KCModuleProxy);
00320 return d->changed;
00321 }
00322
00323 KCModuleInfo KCModuleProxy::moduleInfo() const
00324 {
00325 Q_D(const KCModuleProxy);
00326 return d->modInfo;
00327 }
00328
00329 QString KCModuleProxy::dbusService() const
00330 {
00331 Q_D(const KCModuleProxy);
00332 return d->dbusService;
00333 }
00334
00335 QString KCModuleProxy::dbusPath() const
00336 {
00337 Q_D(const KCModuleProxy);
00338 return d->dbusPath;
00339 }
00340
00341 QSize KCModuleProxy::minimumSizeHint() const
00342 {
00343 return QWidget::minimumSizeHint();
00344 }
00345
00346
00347
00348
00349
00350
00351
00352 #include "kcmoduleproxy.moc"
00353
00354