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 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();
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() << "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() << "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() << "Finished";
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() << "Ignore D-Bus notification to myself";
00241 return;
00242 }
00243 kDebug() << "Receive D-Bus call: added resource" << resourceId;
00244
00245 if ( getResource( resourceId ) ) {
00246 kDebug() << "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() << "Ignore D-Bus notification to myself";
00269 return;
00270 }
00271 kDebug() << "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() << "Ignore D-Bus notification to myself";
00287 return;
00288 }
00289 kDebug() << "Receive D-Bus call: deleted resource" << resourceId;
00290
00291 Resource *resource = getResource( resourceId );
00292 if ( resource ) {
00293 d->mNotifier->notifyResourceDeleted( resource );
00294
00295 kDebug() << "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() << identifier;
00344
00345 if ( !d->mFactory ) {
00346 kError() << "mFactory is 0. Did the app forget to call readConfig?";
00347 return 0;
00348 }
00349
00350 KConfigGroup group = d->mConfig->group( "Resource_" + identifier );
00351
00352 QString type = group.readEntry( "ResourceType" );
00353 QString name = group.readEntry( "ResourceName" );
00354 Resource *resource = d->mFactory->resource( type, group );
00355 if ( !resource ) {
00356 kDebug() << "Failed to create resource with id" << identifier;
00357 return 0;
00358 }
00359
00360 if ( resource->identifier().isEmpty() ) {
00361 resource->setIdentifier( identifier );
00362 }
00363
00364 group = d->mConfig->group( "General" );
00365
00366 QString standardKey = group.readEntry( "Standard" );
00367 if ( standardKey == identifier ) {
00368 d->mStandard = resource;
00369 }
00370
00371 if ( checkActive ) {
00372 QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() );
00373 resource->setActive( activeKeys.contains( identifier ) );
00374 }
00375 d->mResources.append( resource );
00376
00377 return resource;
00378 }
00379
00380 void ManagerImpl::writeResourceConfig( Resource *resource, bool checkActive )
00381 {
00382 QString key = resource->identifier();
00383
00384 kDebug() << "Saving resource" << key;
00385
00386 if ( !d->mConfig ) {
00387 createStandardConfig();
00388 }
00389
00390 KConfigGroup group( d->mConfig, "Resource_" + key );
00391 resource->writeConfig( group );
00392
00393 group = d->mConfig->group( "General" );
00394 QString standardKey = group.readEntry( "Standard" );
00395
00396 if ( resource == d->mStandard && standardKey != key ) {
00397 group.writeEntry( "Standard", resource->identifier() );
00398 } else if ( resource != d->mStandard && standardKey == key ) {
00399 group.writeEntry( "Standard", "" );
00400 }
00401
00402 if ( checkActive ) {
00403 QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() );
00404 QStringList passiveKeys = group.readEntry( "PassiveResourceKeys", QStringList() );
00405 if ( resource->isActive() ) {
00406 if ( passiveKeys.contains( key ) ) {
00407 passiveKeys.removeAll( key );
00408 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00409 }
00410 if ( !activeKeys.contains( key ) ) {
00411 activeKeys.append( key );
00412 group.writeEntry( "ResourceKeys", activeKeys );
00413 }
00414 } else if ( !resource->isActive() ) {
00415 if ( activeKeys.contains( key ) ) {
00416 activeKeys.removeAll( key );
00417 group.writeEntry( "ResourceKeys", activeKeys );
00418 }
00419 if ( !passiveKeys.contains( key ) ) {
00420 passiveKeys.append( key );
00421 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00422 }
00423 }
00424 }
00425
00426 d->mConfig->sync();
00427 }
00428
00429 void ManagerImpl::removeResource( Resource *resource )
00430 {
00431 QString key = resource->identifier();
00432
00433 if ( !d->mConfig ) {
00434 createStandardConfig();
00435 }
00436
00437 KConfigGroup group = d->mConfig->group( "General" );
00438 QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() );
00439 if ( activeKeys.contains( key ) ) {
00440 activeKeys.removeAll( key );
00441 group.writeEntry( "ResourceKeys", activeKeys );
00442 } else {
00443 QStringList passiveKeys= group.readEntry( "PassiveResourceKeys", QStringList() );
00444 passiveKeys.removeAll( key );
00445 group.writeEntry( "PassiveResourceKeys", passiveKeys );
00446 }
00447
00448 QString standardKey = group.readEntry( "Standard" );
00449 if ( standardKey == key ) {
00450 group.writeEntry( "Standard", "" );
00451 }
00452
00453 d->mConfig->deleteGroup( "Resource_" + resource->identifier() );
00454 group.sync();
00455 }
00456
00457 Resource *ManagerImpl::getResource( const QString &identifier )
00458 {
00459 Resource::List::ConstIterator it;
00460 for ( it = d->mResources.begin(); it != d->mResources.end(); ++it ) {
00461 if ( (*it)->identifier() == identifier ) {
00462 return *it;
00463 }
00464 }
00465 return 0;
00466 }
00467
00468 QString ManagerImpl::defaultConfigFile( const QString &family )
00469 {
00470 return KStandardDirs::locateLocal( "config",
00471 QString( "kresources/%1/stdrc" ).arg( family ) );
00472 }
00473
00474 #include "managerimpl.moc"