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();
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();
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();
00110
00111 if ( d->mFactory ) {
00112 d->mFactory->reloadConfig();
00113 } else {
00114 d->mFactory = Factory::self( d->mFamily );
00115 }
00116
00117 if ( !cfg ) {
00118 createStandardConfig();
00119 } else {
00120 d->mConfig = cfg;
00121 }
00122
00123 d->mStandard = 0;
00124 KConfigGroup group = d->mConfig->group( "General" );
00125
00126 QStringList keys = group.readEntry( "ResourceKeys", QStringList() );
00127 keys += group.readEntry( "PassiveResourceKeys", QStringList() );
00128
00129 const QString standardKey = group.readEntry( "Standard" );
00130
00131 for ( QStringList::const_iterator it = keys.constBegin(); it != keys.constEnd(); ++it ) {
00132 readResourceConfig( *it, false );
00133 }
00134
00135 d->mConfigRead = true;
00136 }
00137
00138 void ManagerImpl::writeConfig( KConfig *cfg )
00139 {
00140 kDebug();
00141
00142 if ( !cfg ) {
00143 createStandardConfig();
00144 } else {
00145 d->mConfig = cfg;
00146 }
00147
00148 QStringList activeKeys;
00149 QStringList passiveKeys;
00150
00151
00152 Resource::List::Iterator it;
00153 for ( it = d->mResources.begin(); it != d->mResources.end(); ++it ) {
00154 writeResourceConfig( *it, false );
00155
00156 QString key = (*it)->identifier();
00157 if ( (*it)->isActive() ) {
00158 activeKeys.append( key );
00159 } else {
00160 passiveKeys.append( key );
00161 }
00162 }
00163
00164
00165
00166 kDebug() << "Saving general info";
00167 KConfigGroup group = d->mConfig->group( "General" );
00168 group.writeEntry( "ResourceKeys", activeKeys );
00169 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00170 if ( d->mStandard ) {
00171 group.writeEntry( "Standard", d->mStandard->identifier() );
00172 } else {
00173 group.writeEntry( "Standard", "" );
00174 }
00175
00176 group.sync();
00177 kDebug() << "finished";
00178 }
00179
00180 void ManagerImpl::add( Resource *resource )
00181 {
00182 resource->setActive( true );
00183
00184 if ( d->mResources.isEmpty() ) {
00185 d->mStandard = resource;
00186 }
00187
00188 d->mResources.append( resource );
00189
00190 if ( d->mConfigRead ) {
00191 writeResourceConfig( resource, true );
00192 }
00193
00194 signalKResourceAdded( d->mId, resource->identifier() );
00195 }
00196
00197 void ManagerImpl::remove( Resource *resource )
00198 {
00199 if ( d->mStandard == resource ) {
00200 d->mStandard = 0;
00201 }
00202 removeResource( resource );
00203
00204 d->mResources.removeAll( resource );
00205
00206 signalKResourceDeleted( d->mId, resource->identifier() );
00207
00208 delete resource;
00209
00210 kDebug() << "Finished";
00211 }
00212
00213 void ManagerImpl::change( Resource *resource )
00214 {
00215 writeResourceConfig( resource, true );
00216
00217 signalKResourceModified( d->mId, resource->identifier() );
00218 }
00219
00220 void ManagerImpl::setActive( Resource *resource, bool active )
00221 {
00222 if ( resource && resource->isActive() != active ) {
00223 resource->setActive( active );
00224 }
00225 }
00226
00227 Resource *ManagerImpl::standardResource()
00228 {
00229 return d->mStandard;
00230 }
00231
00232 void ManagerImpl::setStandardResource( Resource *resource )
00233 {
00234 d->mStandard = resource;
00235 }
00236
00237
00238
00239 void ManagerImpl::dbusKResourceAdded( const QString &managerId,
00240 const QString &resourceId )
00241 {
00242 if ( managerId == d->mId ) {
00243 kDebug() << "Ignore D-Bus notification to myself";
00244 return;
00245 }
00246 kDebug() << "Receive D-Bus call: added resource" << resourceId;
00247
00248 if ( getResource( resourceId ) ) {
00249 kDebug() << "This resource is already known to me.";
00250 }
00251
00252 if ( !d->mConfig ) {
00253 createStandardConfig();
00254 }
00255
00256 d->mConfig->reparseConfiguration();
00257 Resource *resource = readResourceConfig( resourceId, true );
00258
00259 if ( resource ) {
00260 d->mNotifier->notifyResourceAdded( resource );
00261 } else {
00262 kError() << "Received D-Bus: resource added for unknown resource"
00263 << resourceId;
00264 }
00265 }
00266
00267 void ManagerImpl::dbusKResourceModified( const QString &managerId,
00268 const QString &resourceId )
00269 {
00270 if ( managerId == d->mId ) {
00271 kDebug() << "Ignore D-Bus notification to myself";
00272 return;
00273 }
00274 kDebug() << "Receive D-Bus call: modified resource" << resourceId;
00275
00276 Resource *resource = getResource( resourceId );
00277 if ( resource ) {
00278 d->mNotifier->notifyResourceModified( resource );
00279 } else {
00280 kError() << "Received D-Bus: resource modified for unknown resource"
00281 << resourceId;
00282 }
00283 }
00284
00285 void ManagerImpl::dbusKResourceDeleted( const QString &managerId,
00286 const QString &resourceId )
00287 {
00288 if ( managerId == d->mId ) {
00289 kDebug() << "Ignore D-Bus notification to myself";
00290 return;
00291 }
00292 kDebug() << "Receive D-Bus call: deleted resource" << resourceId;
00293
00294 Resource *resource = getResource( resourceId );
00295 if ( resource ) {
00296 d->mNotifier->notifyResourceDeleted( resource );
00297
00298 kDebug() << "Removing item from mResources";
00299
00300 if ( d->mStandard == resource ) {
00301 d->mStandard = 0;
00302 }
00303 d->mResources.removeAll( resource );
00304 } else {
00305 kError() << "Received D-Bus: resource deleted for unknown resource"
00306 << resourceId;
00307 }
00308 }
00309
00310 QStringList ManagerImpl::resourceNames()
00311 {
00312 QStringList result;
00313
00314 Resource::List::ConstIterator it;
00315 for ( it = d->mResources.constBegin(); it != d->mResources.constEnd(); ++it ) {
00316 result.append( (*it)->resourceName() );
00317 }
00318 return result;
00319 }
00320
00321 Resource::List *ManagerImpl::resourceList()
00322 {
00323 return &d->mResources;
00324 }
00325
00326 QList<Resource *> ManagerImpl::resources()
00327 {
00328 return QList<Resource *>( d->mResources );
00329 }
00330
00331 QList<Resource *> ManagerImpl::resources( bool active )
00332 {
00333 QList<Resource *> result;
00334
00335 for ( int i = 0; i < d->mResources.size(); ++i ) {
00336 if ( d->mResources.at(i)->isActive() == active ) {
00337 result.append( d->mResources.at(i) );
00338 }
00339 }
00340 return result;
00341 }
00342
00343 Resource *ManagerImpl::readResourceConfig( const QString &identifier,
00344 bool checkActive )
00345 {
00346 kDebug() << identifier;
00347
00348 if ( !d->mFactory ) {
00349 kError() << "mFactory is 0. Did the app forget to call readConfig?";
00350 return 0;
00351 }
00352
00353 KConfigGroup group = d->mConfig->group( "Resource_" + identifier );
00354
00355 QString type = group.readEntry( "ResourceType" );
00356 QString name = group.readEntry( "ResourceName" );
00357 Resource *resource = d->mFactory->resource( type, group );
00358 if ( !resource ) {
00359 kDebug() << "Failed to create resource with id" << identifier;
00360 return 0;
00361 }
00362
00363 if ( resource->identifier().isEmpty() ) {
00364 resource->setIdentifier( identifier );
00365 }
00366
00367 group = d->mConfig->group( "General" );
00368
00369 QString standardKey = group.readEntry( "Standard" );
00370 if ( standardKey == identifier ) {
00371 d->mStandard = resource;
00372 }
00373
00374 if ( checkActive ) {
00375 QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() );
00376 resource->setActive( activeKeys.contains( identifier ) );
00377 }
00378 d->mResources.append( resource );
00379
00380 return resource;
00381 }
00382
00383 void ManagerImpl::writeResourceConfig( Resource *resource, bool checkActive )
00384 {
00385 QString key = resource->identifier();
00386
00387 kDebug() << "Saving resource" << key;
00388
00389 if ( !d->mConfig ) {
00390 createStandardConfig();
00391 }
00392
00393 KConfigGroup group( d->mConfig, "Resource_" + key );
00394 resource->writeConfig( group );
00395
00396 group = d->mConfig->group( "General" );
00397 QString standardKey = group.readEntry( "Standard" );
00398
00399 if ( resource == d->mStandard && standardKey != key ) {
00400 group.writeEntry( "Standard", resource->identifier() );
00401 } else if ( resource != d->mStandard && standardKey == key ) {
00402 group.writeEntry( "Standard", "" );
00403 }
00404
00405 if ( checkActive ) {
00406 QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() );
00407 QStringList passiveKeys = group.readEntry( "PassiveResourceKeys", QStringList() );
00408 if ( resource->isActive() ) {
00409 if ( passiveKeys.contains( key ) ) {
00410 passiveKeys.removeAll( key );
00411 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00412 }
00413 if ( !activeKeys.contains( key ) ) {
00414 activeKeys.append( key );
00415 group.writeEntry( "ResourceKeys", activeKeys );
00416 }
00417 } else if ( !resource->isActive() ) {
00418 if ( activeKeys.contains( key ) ) {
00419 activeKeys.removeAll( key );
00420 group.writeEntry( "ResourceKeys", activeKeys );
00421 }
00422 if ( !passiveKeys.contains( key ) ) {
00423 passiveKeys.append( key );
00424 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00425 }
00426 }
00427 }
00428
00429 d->mConfig->sync();
00430 }
00431
00432 void ManagerImpl::removeResource( Resource *resource )
00433 {
00434 QString key = resource->identifier();
00435
00436 if ( !d->mConfig ) {
00437 createStandardConfig();
00438 }
00439
00440 KConfigGroup group = d->mConfig->group( "General" );
00441 QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() );
00442 if ( activeKeys.contains( key ) ) {
00443 activeKeys.removeAll( key );
00444 group.writeEntry( "ResourceKeys", activeKeys );
00445 } else {
00446 QStringList passiveKeys= group.readEntry( "PassiveResourceKeys", QStringList() );
00447 passiveKeys.removeAll( key );
00448 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00449 }
00450
00451 QString standardKey = group.readEntry( "Standard" );
00452 if ( standardKey == key ) {
00453 group.writeEntry( "Standard", "" );
00454 }
00455
00456 d->mConfig->deleteGroup( "Resource_" + resource->identifier() );
00457 group.sync();
00458 }
00459
00460 Resource *ManagerImpl::getResource( const QString &identifier )
00461 {
00462 Resource::List::ConstIterator it;
00463 for ( it = d->mResources.constBegin(); it != d->mResources.constEnd(); ++it ) {
00464 if ( (*it)->identifier() == identifier ) {
00465 return *it;
00466 }
00467 }
00468 return 0;
00469 }
00470
00471 QString ManagerImpl::defaultConfigFile( const QString &family )
00472 {
00473 return KStandardDirs::locateLocal( "config",
00474 QString( "kresources/%1/stdrc" ).arg( family ) );
00475 }
00476
00477 #include "managerimpl.moc"