kde-playground/kdepimlibs/kresources/managerimpl.cpp

478 lines
13 KiB
C++
Raw Permalink Normal View History

/*
This file is part of libkresources.
Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
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 <kaboutdata.h>
#include <krandom.h>
#include <kdebug.h>
#include <kconfig.h>
#include <kstandarddirs.h>
#include <kconfiggroup.h>
#include <QtDBus/QtDBus>
#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<Resource *> ManagerImpl::resources()
{
return QList<Resource *>( d->mResources );
}
QList<Resource *> ManagerImpl::resources( bool active )
{
QList<Resource *> 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 ) );
}