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