/* This file is part of libkresources. Copyright (c) 2002 Tobias Koenig Copyright (c) 2002 Jan-Pascal van Best Copyright (c) 2003 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "managerimpl.h" #include #include #include #include #include #include #include #include "resource.h" #include "factory.h" #include "manager.h" #include "kresourcesmanageradaptor.h" using namespace KRES; class ManagerImpl::ManagerImplPrivate { public: ManagerNotifier *mNotifier; QString mFamily; KConfig *mConfig; KConfig *mStdConfig; Resource *mStandard; Factory *mFactory; Resource::List mResources; QString mId; bool mConfigRead; }; ManagerImpl::ManagerImpl( ManagerNotifier *notifier, const QString &family ) : d( new ManagerImplPrivate ) { d->mNotifier = notifier; d->mFamily = family; d->mConfig = 0; d->mStdConfig = 0; d->mStandard = 0; d->mFactory = 0; d->mConfigRead = false; new KResourcesManagerAdaptor( this ); const QString dBusPath = QLatin1String( "/ManagerIface_" ) + family; QDBusConnection::sessionBus().registerObject( dBusPath, this ); kDebug(); d->mId = KRandom::randomString( 8 ); // Register with D-Bus QDBusConnection::sessionBus().registerService( QLatin1String("org.kde.KResourcesManager") ); QDBusConnection::sessionBus().connect( QString(), dBusPath, QLatin1String("org.kde.KResourcesManager"), QLatin1String("signalKResourceAdded"), this, SLOT(dbusKResourceAdded(QString,QString))); QDBusConnection::sessionBus().connect( QString(), dBusPath, QLatin1String("org.kde.KResourcesManager"), QLatin1String("signalKResourceModified"), this, SLOT(dbusKResourceModified(QString,QString))); QDBusConnection::sessionBus().connect( QString(), dBusPath, QLatin1String("org.kde.KResourcesManager"), QLatin1String("signalKResourceDeleted"), this, SLOT(dbusKResourceDeleted(QString,QString))); } ManagerImpl::~ManagerImpl() { kDebug(); qDeleteAll( d->mResources ); delete d->mStdConfig; delete d; } void ManagerImpl::createStandardConfig() { if ( !d->mStdConfig ) { QString file = defaultConfigFile( d->mFamily ); d->mStdConfig = new KConfig( file ); } d->mConfig = d->mStdConfig; } void ManagerImpl::readConfig( KConfig *cfg ) { kDebug(); if ( d->mFactory ) { d->mFactory->reloadConfig(); } else { d->mFactory = Factory::self( d->mFamily ); } if ( !cfg ) { createStandardConfig(); } else { d->mConfig = cfg; } d->mStandard = 0; KConfigGroup group = d->mConfig->group( "General" ); QStringList keys = group.readEntry( "ResourceKeys", QStringList() ); keys += group.readEntry( "PassiveResourceKeys", QStringList() ); const QString standardKey = group.readEntry( "Standard" ); for ( QStringList::const_iterator it = keys.constBegin(); it != keys.constEnd(); ++it ) { readResourceConfig( *it, false ); } d->mConfigRead = true; } void ManagerImpl::writeConfig( KConfig *cfg ) { kDebug(); if ( !cfg ) { createStandardConfig(); } else { d->mConfig = cfg; } QStringList activeKeys; QStringList passiveKeys; // First write all keys, collect active and passive keys on the way Resource::List::Iterator it; for ( it = d->mResources.begin(); it != d->mResources.end(); ++it ) { writeResourceConfig( *it, false ); QString key = ( *it )->identifier(); if ( ( *it )->isActive() ) { activeKeys.append( key ); } else { passiveKeys.append( key ); } } // And then the general group kDebug() << "Saving general info"; KConfigGroup group = d->mConfig->group( "General" ); group.writeEntry( "ResourceKeys", activeKeys ); group.writeEntry( "PassiveResourceKeys", passiveKeys ); if ( d->mStandard ) { group.writeEntry( "Standard", d->mStandard->identifier() ); } else { group.writeEntry( "Standard", QString() ); } group.sync(); kDebug() << "finished"; } void ManagerImpl::add( Resource *resource ) { resource->setActive( true ); if ( d->mResources.isEmpty() ) { d->mStandard = resource; } d->mResources.append( resource ); if ( d->mConfigRead ) { writeResourceConfig( resource, true ); } signalKResourceAdded( d->mId, resource->identifier() ); } void ManagerImpl::remove( Resource *resource ) { if ( d->mStandard == resource ) { d->mStandard = 0; } removeResource( resource ); d->mResources.removeAll( resource ); signalKResourceDeleted( d->mId, resource->identifier() ); delete resource; kDebug() << "Finished"; } void ManagerImpl::change( Resource *resource ) { writeResourceConfig( resource, true ); signalKResourceModified( d->mId, resource->identifier() ); } void ManagerImpl::setActive( Resource *resource, bool active ) { if ( resource && resource->isActive() != active ) { resource->setActive( active ); } } Resource *ManagerImpl::standardResource() { return d->mStandard; } void ManagerImpl::setStandardResource( Resource *resource ) { d->mStandard = resource; } // DBUS asynchronous functions void ManagerImpl::dbusKResourceAdded( const QString &managerId, const QString &resourceId ) { if ( managerId == d->mId ) { kDebug() << "Ignore D-Bus notification to myself"; return; } kDebug() << "Receive D-Bus call: added resource" << resourceId; if ( getResource( resourceId ) ) { kDebug() << "This resource is already known to me."; } if ( !d->mConfig ) { createStandardConfig(); } d->mConfig->reparseConfiguration(); Resource *resource = readResourceConfig( resourceId, true ); if ( resource ) { d->mNotifier->notifyResourceAdded( resource ); } else { kError() << "Received D-Bus: resource added for unknown resource" << resourceId; } } void ManagerImpl::dbusKResourceModified( const QString &managerId, const QString &resourceId ) { if ( managerId == d->mId ) { kDebug() << "Ignore D-Bus notification to myself"; return; } kDebug() << "Receive D-Bus call: modified resource" << resourceId; Resource *resource = getResource( resourceId ); if ( resource ) { d->mNotifier->notifyResourceModified( resource ); } else { kError() << "Received D-Bus: resource modified for unknown resource" << resourceId; } } void ManagerImpl::dbusKResourceDeleted( const QString &managerId, const QString &resourceId ) { if ( managerId == d->mId ) { kDebug() << "Ignore D-Bus notification to myself"; return; } kDebug() << "Receive D-Bus call: deleted resource" << resourceId; Resource *resource = getResource( resourceId ); if ( resource ) { d->mNotifier->notifyResourceDeleted( resource ); kDebug() << "Removing item from mResources"; // Now delete item if ( d->mStandard == resource ) { d->mStandard = 0; } d->mResources.removeAll( resource ); } else { kError() << "Received D-Bus: resource deleted for unknown resource" << resourceId; } } QStringList ManagerImpl::resourceNames() { QStringList result; Resource::List::ConstIterator it; Resource::List::ConstIterator end(d->mResources.constEnd()); for ( it = d->mResources.constBegin(); it != end; ++it ) { result.append( ( *it )->resourceName() ); } return result; } Resource::List *ManagerImpl::resourceList() { return &d->mResources; } QList ManagerImpl::resources() { return QList( d->mResources ); } QList ManagerImpl::resources( bool active ) { QList result; for ( int i = 0; i < d->mResources.size(); ++i ) { if ( d->mResources.at( i )->isActive() == active ) { result.append( d->mResources.at( i ) ); } } return result; } Resource *ManagerImpl::readResourceConfig( const QString &identifier, bool checkActive ) { kDebug() << identifier; if ( !d->mFactory ) { kError() << "mFactory is 0. Did the app forget to call readConfig?"; return 0; } KConfigGroup group = d->mConfig->group( QLatin1String("Resource_") + identifier ); QString type = group.readEntry( "ResourceType" ); QString name = group.readEntry( "ResourceName" ); Resource *resource = d->mFactory->resource( type, group ); if ( !resource ) { kDebug() << "Failed to create resource with id" << identifier; return 0; } if ( resource->identifier().isEmpty() ) { resource->setIdentifier( identifier ); } group = d->mConfig->group( "General" ); QString standardKey = group.readEntry( "Standard" ); if ( standardKey == identifier ) { d->mStandard = resource; } if ( checkActive ) { QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() ); resource->setActive( activeKeys.contains( identifier ) ); } d->mResources.append( resource ); return resource; } void ManagerImpl::writeResourceConfig( Resource *resource, bool checkActive ) { QString key = resource->identifier(); kDebug() << "Saving resource" << key; if ( !d->mConfig ) { createStandardConfig(); } KConfigGroup group( d->mConfig, QLatin1String("Resource_") + key ); resource->writeConfig( group ); group = d->mConfig->group( "General" ); QString standardKey = group.readEntry( "Standard" ); if ( resource == d->mStandard && standardKey != key ) { group.writeEntry( "Standard", resource->identifier() ); } else if ( resource != d->mStandard && standardKey == key ) { group.writeEntry( "Standard", "" ); } if ( checkActive ) { QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() ); QStringList passiveKeys = group.readEntry( "PassiveResourceKeys", QStringList() ); if ( resource->isActive() ) { if ( passiveKeys.contains( key ) ) { // remove it from passive list passiveKeys.removeAll( key ); group.writeEntry( "PassiveResourceKeys", passiveKeys ); } if ( !activeKeys.contains( key ) ) { // add it to active list activeKeys.append( key ); group.writeEntry( "ResourceKeys", activeKeys ); } } else if ( !resource->isActive() ) { if ( activeKeys.contains( key ) ) { // remove it from active list activeKeys.removeAll( key ); group.writeEntry( "ResourceKeys", activeKeys ); } if ( !passiveKeys.contains( key ) ) { // add it to passive list passiveKeys.append( key ); group.writeEntry( "PassiveResourceKeys", passiveKeys ); } } } d->mConfig->sync(); } void ManagerImpl::removeResource( Resource *resource ) { QString key = resource->identifier(); if ( !d->mConfig ) { createStandardConfig(); } KConfigGroup group = d->mConfig->group( "General" ); QStringList activeKeys = group.readEntry( "ResourceKeys", QStringList() ); if ( activeKeys.contains( key ) ) { activeKeys.removeAll( key ); group.writeEntry( "ResourceKeys", activeKeys ); } else { QStringList passiveKeys= group.readEntry( "PassiveResourceKeys", QStringList() ); passiveKeys.removeAll( key ); group.writeEntry( "PassiveResourceKeys", passiveKeys ); } QString standardKey = group.readEntry( "Standard" ); if ( standardKey == key ) { group.writeEntry( "Standard", "" ); } d->mConfig->deleteGroup( QLatin1String("Resource_") + resource->identifier() ); group.sync(); } Resource *ManagerImpl::getResource( const QString &identifier ) { Resource::List::ConstIterator it; for ( it = d->mResources.constBegin(); it != d->mResources.constEnd(); ++it ) { if ( ( *it )->identifier() == identifier ) { return *it; } } return 0; } QString ManagerImpl::defaultConfigFile( const QString &family ) { return KStandardDirs::locateLocal( "config", QString::fromLatin1( "kresources/%1/stdrc" ).arg( family ) ); }