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