00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "managerimpl.h"
00024
00025 #include <kaboutdata.h>
00026 #include <krandom.h>
00027 #include <kdebug.h>
00028 #include <kconfig.h>
00029 #include <kstandarddirs.h>
00030 #include <kconfiggroup.h>
00031
00032 #include <QtDBus/QtDBus>
00033
00034 #include "resource.h"
00035 #include "factory.h"
00036 #include "manager.h"
00037 #include "kresourcesmanageradaptor.h"
00038
00039 using namespace KRES;
00040
00041 class ManagerImpl::ManagerImplPrivate
00042 {
00043 public:
00044 ManagerNotifier *mNotifier;
00045 QString mFamily;
00046 KConfig *mConfig;
00047 KConfig *mStdConfig;
00048 Resource *mStandard;
00049 Factory *mFactory;
00050 Resource::List mResources;
00051 QString mId;
00052 bool mConfigRead;
00053
00054 };
00055
00056 ManagerImpl::ManagerImpl( ManagerNotifier *notifier, const QString &family )
00057 : d( new ManagerImplPrivate )
00058 {
00059 d->mNotifier = notifier;
00060 d->mFamily = family;
00061 d->mConfig = 0;
00062 d->mStdConfig = 0;
00063 d->mStandard = 0;
00064 d->mFactory = 0;
00065 d->mConfigRead = false;
00066
00067 new KResourcesManagerAdaptor( this );
00068 const QString dBusPath = QLatin1String( "/ManagerIface_" ) + family;
00069 QDBusConnection::sessionBus().registerObject( dBusPath, this );
00070 kDebug(5650) << "ManagerImpl::ManagerImpl()";
00071
00072 d->mId = KRandom::randomString( 8 );
00073
00074
00075 QDBusConnection::sessionBus().registerService( "org.kde.KResourcesManager" );
00076
00077 QDBusConnection::sessionBus().connect( "", dBusPath,
00078 "org.kde.KResourcesManager", "signalKResourceAdded",
00079 this, SLOT(dbusKResourceAdded(QString,QString)));
00080 QDBusConnection::sessionBus().connect( "", dBusPath,
00081 "org.kde.KResourcesManager", "signalKResourceModified",
00082 this, SLOT(dbusKResourceModified(QString,QString)));
00083 QDBusConnection::sessionBus().connect( "", dBusPath,
00084 "org.kde.KResourcesManager", "signalKResourceDeleted",
00085 this, SLOT(dbusKResourceDeleted(QString,QString)));
00086 }
00087
00088 ManagerImpl::~ManagerImpl()
00089 {
00090 kDebug(5650) << "ManagerImpl::~ManagerImpl()";
00091
00092 qDeleteAll(d->mResources);
00093 delete d->mStdConfig;
00094 delete d;
00095 }
00096
00097 void ManagerImpl::createStandardConfig()
00098 {
00099 if ( !d->mStdConfig ) {
00100 QString file = defaultConfigFile( d->mFamily );
00101 d->mStdConfig = new KConfig( file );
00102 }
00103
00104 d->mConfig = d->mStdConfig;
00105 }
00106
00107 void ManagerImpl::readConfig( KConfig *cfg )
00108 {
00109 kDebug(5650) << "ManagerImpl::readConfig()";
00110
00111 delete d->mFactory;
00112 d->mFactory = Factory::self( d->mFamily );
00113
00114 if ( !cfg ) {
00115 createStandardConfig();
00116 } else {
00117 d->mConfig = cfg;
00118 }
00119
00120 d->mStandard = 0;
00121 KConfigGroup group = d->mConfig->group( "General" );
00122
00123 QStringList keys = group.readEntry( "ResourceKeys", QStringList() );
00124 keys += group.readEntry( "PassiveResourceKeys", QStringList() );
00125
00126 QString standardKey = group.readEntry( "Standard" );
00127
00128 for ( QStringList::Iterator it = keys.begin(); it != keys.end(); ++it ) {
00129 readResourceConfig( *it, false );
00130 }
00131
00132 d->mConfigRead = true;
00133 }
00134
00135 void ManagerImpl::writeConfig( KConfig *cfg )
00136 {
00137 kDebug(5650) << "ManagerImpl::writeConfig()";
00138
00139 if ( !cfg ) {
00140 createStandardConfig();
00141 } else {
00142 d->mConfig = cfg;
00143 }
00144
00145 QStringList activeKeys;
00146 QStringList passiveKeys;
00147
00148
00149 Resource::List::Iterator it;
00150 for ( it = d->mResources.begin(); it != d->mResources.end(); ++it ) {
00151 writeResourceConfig( *it, false );
00152
00153 QString key = (*it)->identifier();
00154 if ( (*it)->isActive() ) {
00155 activeKeys.append( key );
00156 } else {
00157 passiveKeys.append( key );
00158 }
00159 }
00160
00161
00162
00163 kDebug(5650) << "Saving general info";
00164 KConfigGroup group = d->mConfig->group( "General" );
00165 group.writeEntry( "ResourceKeys", activeKeys );
00166 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00167 if ( d->mStandard ) {
00168 group.writeEntry( "Standard", d->mStandard->identifier() );
00169 } else {
00170 group.writeEntry( "Standard", "" );
00171 }
00172
00173 group.sync();
00174 kDebug(5650) << "ManagerImpl::save() finished";
00175 }
00176
00177 void ManagerImpl::add( Resource *resource )
00178 {
00179 resource->setActive( true );
00180
00181 if ( d->mResources.isEmpty() ) {
00182 d->mStandard = resource;
00183 }
00184
00185 d->mResources.append( resource );
00186
00187 if ( d->mConfigRead ) {
00188 writeResourceConfig( resource, true );
00189 }
00190
00191 signalKResourceAdded( d->mId, resource->identifier() );
00192 }
00193
00194 void ManagerImpl::remove( Resource *resource )
00195 {
00196 if ( d->mStandard == resource ) {
00197 d->mStandard = 0;
00198 }
00199 removeResource( resource );
00200
00201 d->mResources.removeAll( resource );
00202
00203 signalKResourceDeleted( d->mId, resource->identifier() );
00204
00205 delete resource;
00206
00207 kDebug(5650) << "Finished ManagerImpl::remove()";
00208 }
00209
00210 void ManagerImpl::change( Resource *resource )
00211 {
00212 writeResourceConfig( resource, true );
00213
00214 signalKResourceModified( d->mId, resource->identifier() );
00215 }
00216
00217 void ManagerImpl::setActive( Resource *resource, bool active )
00218 {
00219 if ( resource && resource->isActive() != active ) {
00220 resource->setActive( active );
00221 }
00222 }
00223
00224 Resource *ManagerImpl::standardResource()
00225 {
00226 return d->mStandard;
00227 }
00228
00229 void ManagerImpl::setStandardResource( Resource *resource )
00230 {
00231 d->mStandard = resource;
00232 }
00233
00234
00235
00236 void ManagerImpl::dbusKResourceAdded( const QString &managerId,
00237 const QString &resourceId )
00238 {
00239 if ( managerId == d->mId ) {
00240 kDebug(5650) << "Ignore D-Bus notification to myself";
00241 return;
00242 }
00243 kDebug(5650) << "Receive D-Bus call: added resource" << resourceId;
00244
00245 if ( getResource( resourceId ) ) {
00246 kDebug(5650) << "This resource is already known to me.";
00247 }
00248
00249 if ( !d->mConfig ) {
00250 createStandardConfig();
00251 }
00252
00253 d->mConfig->reparseConfiguration();
00254 Resource *resource = readResourceConfig( resourceId, true );
00255
00256 if ( resource ) {
00257 d->mNotifier->notifyResourceAdded( resource );
00258 } else {
00259 kError() << "Received D-Bus: resource added for unknown resource"
00260 << resourceId;
00261 }
00262 }
00263
00264 void ManagerImpl::dbusKResourceModified( const QString &managerId,
00265 const QString &resourceId )
00266 {
00267 if ( managerId == d->mId ) {
00268 kDebug(5650) << "Ignore D-Bus notification to myself";
00269 return;
00270 }
00271 kDebug(5650) << "Receive D-Bus call: modified resource" << resourceId;
00272
00273 Resource *resource = getResource( resourceId );
00274 if ( resource ) {
00275 d->mNotifier->notifyResourceModified( resource );
00276 } else {
00277 kError() << "Received D-Bus: resource modified for unknown resource"
00278 << resourceId;
00279 }
00280 }
00281
00282 void ManagerImpl::dbusKResourceDeleted( const QString& managerId,
00283 const QString& resourceId )
00284 {
00285 if ( managerId == d->mId ) {
00286 kDebug(5650) << "Ignore D-Bus notification to myself";
00287 return;
00288 }
00289 kDebug(5650) << "Receive D-Bus call: deleted resource" << resourceId;
00290
00291 Resource *resource = getResource( resourceId );
00292 if ( resource ) {
00293 d->mNotifier->notifyResourceDeleted( resource );
00294
00295 kDebug(5650) << "Removing item from mResources";
00296
00297 if ( d->mStandard == resource ) {
00298 d->mStandard = 0;
00299 }
00300 d->mResources.removeAll( resource );
00301 } else {
00302 kError() << "Received D-Bus: resource deleted for unknown resource"
00303 << resourceId;
00304 }
00305 }
00306
00307 QStringList ManagerImpl::resourceNames()
00308 {
00309 QStringList result;
00310
00311 Resource::List::ConstIterator it;
00312 for ( it = d->mResources.begin(); it != d->mResources.end(); ++it ) {
00313 result.append( (*it)->resourceName() );
00314 }
00315 return result;
00316 }
00317
00318 Resource::List *ManagerImpl::resourceList()
00319 {
00320 return &d->mResources;
00321 }
00322
00323 QList<Resource *> ManagerImpl::resources()
00324 {
00325 return QList<Resource *>( d->mResources );
00326 }
00327
00328 QList<Resource *> ManagerImpl::resources( bool active )
00329 {
00330 QList<Resource *> result;
00331
00332 for ( int i = 0; i < d->mResources.size(); ++i ) {
00333 if ( d->mResources.at(i)->isActive() == active ) {
00334 result.append( d->mResources.at(i) );
00335 }
00336 }
00337 return result;
00338 }
00339
00340 Resource *ManagerImpl::readResourceConfig( const QString &identifier,
00341 bool checkActive )
00342 {
00343 kDebug(5650) << "ManagerImpl::readResourceConfig()" << identifier;
00344
00345 if ( !d->mFactory ) {
00346 kError(5650) << "ManagerImpl::readResourceConfig: mFactory is 0."
00347 << "Did the app forget to call readConfig?";
00348 return 0;
00349 }
00350
00351 KConfigGroup group = d->mConfig->group( "Resource_" + identifier );
00352
00353 QString type = group.readEntry( "ResourceType" );
00354 QString name = group.readEntry( "ResourceName" );
00355 Resource *resource = d->mFactory->resource( type, group );
00356 if ( !resource ) {
00357 kDebug(5650) << "Failed to create resource with id" << identifier;
00358 return 0;
00359 }
00360
00361 if ( resource->identifier().isEmpty() ) {
00362 resource->setIdentifier( identifier );
00363 }
00364
00365 group = d->mConfig->group( "General" );
00366
00367 QString standardKey = group.readEntry( "Standard" );
00368 if ( standardKey == identifier ) {
00369 d->mStandard = resource;
00370 }
00371
00372 if ( checkActive ) {
00373 QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() );
00374 resource->setActive( activeKeys.contains( identifier ) );
00375 }
00376 d->mResources.append( resource );
00377
00378 return resource;
00379 }
00380
00381 void ManagerImpl::writeResourceConfig( Resource *resource, bool checkActive )
00382 {
00383 QString key = resource->identifier();
00384
00385 kDebug(5650) << "Saving resource" << key;
00386
00387 if ( !d->mConfig ) {
00388 createStandardConfig();
00389 }
00390
00391 KConfigGroup group( d->mConfig, "Resource_" + key );
00392 resource->writeConfig( group );
00393
00394 group = d->mConfig->group( "General" );
00395 QString standardKey = group.readEntry( "Standard" );
00396
00397 if ( resource == d->mStandard && standardKey != key ) {
00398 group.writeEntry( "Standard", resource->identifier() );
00399 } else if ( resource != d->mStandard && standardKey == key ) {
00400 group.writeEntry( "Standard", "" );
00401 }
00402
00403 if ( checkActive ) {
00404 QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() );
00405 QStringList passiveKeys = group.readEntry( "PassiveResourceKeys", QStringList() );
00406 if ( resource->isActive() ) {
00407 if ( passiveKeys.contains( key ) ) {
00408 passiveKeys.removeAll( key );
00409 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00410 }
00411 if ( !activeKeys.contains( key ) ) {
00412 activeKeys.append( key );
00413 group.writeEntry( "ResourceKeys", activeKeys );
00414 }
00415 } else if ( !resource->isActive() ) {
00416 if ( activeKeys.contains( key ) ) {
00417 activeKeys.removeAll( key );
00418 group.writeEntry( "ResourceKeys", activeKeys );
00419 }
00420 if ( !passiveKeys.contains( key ) ) {
00421 passiveKeys.append( key );
00422 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00423 }
00424 }
00425 }
00426
00427 d->mConfig->sync();
00428 }
00429
00430 void ManagerImpl::removeResource( Resource *resource )
00431 {
00432 QString key = resource->identifier();
00433
00434 if ( !d->mConfig ) {
00435 createStandardConfig();
00436 }
00437
00438 KConfigGroup group = d->mConfig->group( "General" );
00439 QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() );
00440 if ( activeKeys.contains( key ) ) {
00441 activeKeys.removeAll( key );
00442 group.writeEntry( "ResourceKeys", activeKeys );
00443 } else {
00444 QStringList passiveKeys= group.readEntry( "PassiveResourceKeys", QStringList() );
00445 passiveKeys.removeAll( key );
00446 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00447 }
00448
00449 QString standardKey = group.readEntry( "Standard" );
00450 if ( standardKey == key ) {
00451 group.writeEntry( "Standard", "" );
00452 }
00453
00454 d->mConfig->deleteGroup( "Resource_" + resource->identifier() );
00455 group.sync();
00456 }
00457
00458 Resource *ManagerImpl::getResource( const QString &identifier )
00459 {
00460 Resource::List::ConstIterator it;
00461 for ( it = d->mResources.begin(); it != d->mResources.end(); ++it ) {
00462 if ( (*it)->identifier() == identifier ) {
00463 return *it;
00464 }
00465 }
00466 return 0;
00467 }
00468
00469 QString ManagerImpl::defaultConfigFile( const QString &family )
00470 {
00471 return KStandardDirs::locateLocal( "config",
00472 QString( "kresources/%1/stdrc" ).arg( family ) );
00473 }
00474
00475 #include "managerimpl.moc"