mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 18:32:51 +00:00
253 lines
6.9 KiB
C++
253 lines
6.9 KiB
C++
/*
|
|
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.
|
|
*/
|
|
/**
|
|
@file
|
|
This file is part of the KDE resource framework and defines the
|
|
Factory class.
|
|
|
|
@brief
|
|
A class for loading resource plugins.
|
|
|
|
@author Tobias Koenig
|
|
@author Jan-Pascal van Best
|
|
@author Cornelius Schumacher
|
|
*/
|
|
|
|
#include "factory.h"
|
|
|
|
#include <QtCore/QFile>
|
|
|
|
#include <kdebug.h>
|
|
#include <klocalizedstring.h>
|
|
#include <kconfig.h>
|
|
#include <kconfiggroup.h>
|
|
#include <kprocess.h>
|
|
#include <kservicetypetrader.h>
|
|
#include <kpluginloader.h>
|
|
|
|
#include "resource.h"
|
|
|
|
using namespace KRES;
|
|
|
|
class Factory::Private
|
|
{
|
|
public:
|
|
Resource *resourceInternal ( const QString &type, const KConfigGroup *group );
|
|
QString mResourceFamily;
|
|
QMap<QString, KService::Ptr> mTypeMap;
|
|
};
|
|
|
|
class FactoryMap : public QMap<QString, Factory*>
|
|
{
|
|
public:
|
|
~FactoryMap() { qDeleteAll( *this ); }
|
|
};
|
|
|
|
K_GLOBAL_STATIC( FactoryMap, mSelves )
|
|
|
|
Factory *Factory::self( const QString &resourceFamily )
|
|
{
|
|
kDebug();
|
|
|
|
Factory *factory = 0;
|
|
|
|
factory = mSelves->value( resourceFamily, 0 );
|
|
|
|
if ( !factory ) {
|
|
factory = new Factory( resourceFamily );
|
|
mSelves->insert( resourceFamily, factory );
|
|
|
|
// Akonadi migration
|
|
KConfig config( QLatin1String("kres-migratorrc") );
|
|
KConfigGroup migrationCfg( &config, "Migration" );
|
|
const bool enabled = migrationCfg.readEntry( "Enabled", false );
|
|
const bool setupClientBrige = migrationCfg.readEntry( "SetupClientBridge", true );
|
|
const int currentVersion = migrationCfg.readEntry( QLatin1String("Version-") + resourceFamily, 0 );
|
|
const int targetVersion = migrationCfg.readEntry( "TargetVersion", 0 );
|
|
if ( enabled && currentVersion < targetVersion ) {
|
|
kDebug() << "Performing Akonadi migration. Good luck!";
|
|
KProcess proc;
|
|
QStringList args = QStringList() << QLatin1String("--interactive-on-change") << QLatin1String("--type") << resourceFamily;
|
|
if ( !setupClientBrige ) {
|
|
args << QLatin1String("--omit-client-bridge");
|
|
}
|
|
proc.setProgram( QLatin1String("kres-migrator"), args );
|
|
proc.start();
|
|
bool result = proc.waitForStarted();
|
|
if ( result ) {
|
|
result = proc.waitForFinished();
|
|
}
|
|
if ( result && proc.exitCode() == 0 ) {
|
|
kDebug() << "Akonadi migration has been successful";
|
|
migrationCfg.writeEntry( QLatin1String("Version-") + resourceFamily, targetVersion );
|
|
migrationCfg.sync();
|
|
} else if ( !result || proc.exitCode() != 1 ) {
|
|
// exit code 1 means it is already running, so we are probably called by a migrator instance
|
|
kError() << "Akonadi migration failed!";
|
|
kError() << "command was: " << proc.program();
|
|
kError() << "exit code: " << proc.exitCode();
|
|
kError() << "stdout: " << proc.readAllStandardOutput();
|
|
kError() << "stderr: " << proc.readAllStandardError();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return factory;
|
|
}
|
|
|
|
Factory::Factory( const QString &resourceFamily ) :
|
|
d( new KRES::Factory::Private )
|
|
{
|
|
d->mResourceFamily = resourceFamily;
|
|
reloadConfig();
|
|
}
|
|
|
|
void Factory::reloadConfig()
|
|
{
|
|
d->mTypeMap.clear();
|
|
const KService::List plugins =
|
|
KServiceTypeTrader::self()->query(
|
|
QLatin1String("KResources/Plugin"),
|
|
QString::fromLatin1( "[X-KDE-ResourceFamily] == '%1'" ).arg( d->mResourceFamily ) );
|
|
|
|
KService::List::ConstIterator it;
|
|
for ( it = plugins.begin(); it != plugins.end(); ++it ) {
|
|
const QVariant type = ( *it )->property( QLatin1String("X-KDE-ResourceType") );
|
|
if ( !type.toString().isEmpty() ) {
|
|
d->mTypeMap.insert( type.toString(), *it );
|
|
}
|
|
}
|
|
}
|
|
|
|
Factory::~Factory()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
QStringList Factory::typeNames() const
|
|
{
|
|
return d->mTypeMap.keys();
|
|
}
|
|
|
|
ConfigWidget *Factory::configWidget( const QString &type, QWidget *parent )
|
|
{
|
|
if ( type.isEmpty() || !d->mTypeMap.contains( type ) ) {
|
|
return 0;
|
|
}
|
|
|
|
KService::Ptr ptr = d->mTypeMap[ type ];
|
|
KPluginLoader loader( ptr->library() );
|
|
KPluginFactory *factory = loader.factory();
|
|
if ( !factory ) {
|
|
kDebug() << "Factory creation failed: " << loader.errorString();
|
|
return 0;
|
|
}
|
|
|
|
PluginFactoryBase *pluginFactory = static_cast<PluginFactoryBase *>( factory );
|
|
|
|
if ( !pluginFactory ) {
|
|
kDebug() << "no plugin factory.";
|
|
return 0;
|
|
}
|
|
|
|
ConfigWidget *wdg = pluginFactory->configWidget( parent );
|
|
if ( !wdg ) {
|
|
kDebug() << "'" << ptr->library() << "' doesn't provide a ConfigWidget";
|
|
return 0;
|
|
}
|
|
|
|
return wdg;
|
|
}
|
|
|
|
QString Factory::typeName( const QString &type ) const
|
|
{
|
|
if ( type.isEmpty() || !d->mTypeMap.contains( type ) ) {
|
|
return QString();
|
|
}
|
|
|
|
KService::Ptr ptr = d->mTypeMap[ type ];
|
|
return ptr->name();
|
|
}
|
|
|
|
QString Factory::typeDescription( const QString &type ) const
|
|
{
|
|
if ( type.isEmpty() || !d->mTypeMap.contains( type ) ) {
|
|
return QString();
|
|
}
|
|
|
|
KService::Ptr ptr = d->mTypeMap[ type ];
|
|
return ptr->comment();
|
|
}
|
|
|
|
Resource *Factory::Private::resourceInternal( const QString &type, const KConfigGroup *group )
|
|
{
|
|
kDebug() << "(" << type << ", config )";
|
|
|
|
if ( type.isEmpty() || !mTypeMap.contains( type ) ) {
|
|
kDebug() << "no such type" << type;
|
|
return 0;
|
|
}
|
|
|
|
KService::Ptr ptr = mTypeMap[ type ];
|
|
KPluginLoader loader( ptr->library() );
|
|
KPluginFactory *factory = loader.factory();
|
|
if ( !factory ) {
|
|
kDebug() << "Factory creation failed" << loader.errorString();
|
|
return 0;
|
|
}
|
|
|
|
PluginFactoryBase *pluginFactory = static_cast<PluginFactoryBase *>( factory );
|
|
|
|
if ( !pluginFactory ) {
|
|
kDebug() << "no plugin factory.";
|
|
return 0;
|
|
}
|
|
|
|
Resource *resource;
|
|
if ( group ) {
|
|
resource = pluginFactory->resource( *group );
|
|
} else {
|
|
resource = pluginFactory->resource();
|
|
}
|
|
|
|
if ( !resource ) {
|
|
kDebug() << "'" << ptr->library()
|
|
<< "' is not a" << mResourceFamily << "plugin.";
|
|
return 0;
|
|
}
|
|
|
|
resource->setType( type );
|
|
|
|
return resource;
|
|
}
|
|
|
|
Resource *Factory::resource( const QString &type, const KConfigGroup &group )
|
|
{
|
|
return d->resourceInternal( type, &group );
|
|
}
|
|
|
|
Resource *Factory::resource( const QString &type )
|
|
{
|
|
return d->resourceInternal( type, 0 );
|
|
}
|