diff --git a/autotests/persondatatests.cpp b/autotests/persondatatests.cpp --- a/autotests/persondatatests.cpp +++ b/autotests/persondatatests.cpp @@ -25,10 +25,10 @@ //private includes #include "personmanager_p.h" -#include "personpluginmanager_p.h" //public kpeople includes #include +#include #include "fakecontactsource.h" diff --git a/autotests/personsmodeltest.cpp b/autotests/personsmodeltest.cpp --- a/autotests/personsmodeltest.cpp +++ b/autotests/personsmodeltest.cpp @@ -26,10 +26,10 @@ //private includes #include "personmanager_p.h" -#include "personpluginmanager_p.h" //public kpeople includes #include +#include #include "fakecontactsource.h" diff --git a/autotests/personsproxymodeltest.cpp b/autotests/personsproxymodeltest.cpp --- a/autotests/personsproxymodeltest.cpp +++ b/autotests/personsproxymodeltest.cpp @@ -26,10 +26,10 @@ //private includes #include "personmanager_p.h" -#include "personpluginmanager_p.h" //public kpeople includes #include +#include #include #include "fakecontactsource.h" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -57,6 +57,7 @@ ecm_generate_headers(KPeople_CamelCase_HEADERS HEADER_NAMES PersonData + PersonPluginManager PersonsModel Global REQUIRED_HEADERS KPeople_HEADERS diff --git a/src/global.cpp b/src/global.cpp --- a/src/global.cpp +++ b/src/global.cpp @@ -19,7 +19,7 @@ #include "global.h" #include "personmanager_p.h" -#include "personpluginmanager_p.h" +#include "personpluginmanager.h" #include "backends/abstractcontact.h" //these namespace members expose the useful bits of PersonManager diff --git a/src/persondata.cpp b/src/persondata.cpp --- a/src/persondata.cpp +++ b/src/persondata.cpp @@ -20,7 +20,7 @@ #include "metacontact_p.h" #include "personmanager_p.h" -#include "personpluginmanager_p.h" +#include "personpluginmanager.h" #include "backends/basepersonsdatasource.h" #include "backends/contactmonitor.h" #include "backends/abstractcontact.h" diff --git a/src/personpluginmanager_p.h b/src/personpluginmanager.h rename from src/personpluginmanager_p.h rename to src/personpluginmanager.h --- a/src/personpluginmanager_p.h +++ b/src/personpluginmanager.h @@ -1,5 +1,6 @@ /* Copyright (C) 2013 David Edmundson + Copyright (C) 2018 Igor Poboiko This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -31,10 +32,35 @@ class AbstractPersonAction; class BasePersonsDataSource; +/** + This class allows applications to manage DataSource plugins + + It can be useful if an application wants to use custom DataSource, + without exposing it to other KPeople-based applications + (i.e. without installing a system-wide plugin) + + Another use-case is that it allows to pass custom arguments to DataSources + (i.e. an ItemModel which will be used as a source of data) + + @since 5.51 + */ class KPEOPLE_EXPORT PersonPluginManager { public: + /** + * Use this if you explicitly don't want KPeople to autoload all the + * available data source plugins via KPluginLoader. + * + * The default behavior is to autoload them + */ + static void setAutoloadDataSourcePlugins(bool autoloadDataSourcePlugins); static QList dataSourcePlugins(); + /** + * Adds custom data source. If DataSource with such @p sourceId was already loaded, we override it + * + * Takes ownership of the @p source + */ + static void addDataSource(const QString &sourceId, BasePersonsDataSource *source); static BasePersonsDataSource *dataSource(const QString &sourceId); static QList actions(); diff --git a/src/personpluginmanager.cpp b/src/personpluginmanager.cpp --- a/src/personpluginmanager.cpp +++ b/src/personpluginmanager.cpp @@ -16,7 +16,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "personpluginmanager_p.h" +#include "personpluginmanager.h" #include "backends/basepersonsdatasource.h" #include @@ -26,6 +26,7 @@ #include #include +#include #include "kpeople_debug.h" @@ -39,6 +40,7 @@ QHash dataSourcePlugins; void loadDataSourcePlugins(); + bool m_autoloadDataSourcePlugins; bool m_loadedDataSourcePlugins; QMutex m_mutex; @@ -46,8 +48,9 @@ Q_GLOBAL_STATIC(PersonPluginManagerPrivate, s_instance) -PersonPluginManagerPrivate::PersonPluginManagerPrivate(): - m_loadedDataSourcePlugins(false) +PersonPluginManagerPrivate::PersonPluginManagerPrivate() + : m_autoloadDataSourcePlugins(true) + , m_loadedDataSourcePlugins(false) { } @@ -62,9 +65,15 @@ Q_FOREACH (const KPluginMetaData &service, pluginList) { KPluginLoader loader(service.fileName()); KPluginFactory *factory = loader.factory(); - BasePersonsDataSource *dataSource = qobject_cast(factory->create()); + BasePersonsDataSource *dataSource = factory->create(); if (dataSource) { - dataSourcePlugins[dataSource->sourcePluginId()] = dataSource; + const QString pluginId = dataSource->sourcePluginId(); + if (!dataSourcePlugins.contains(pluginId)) { + dataSourcePlugins[pluginId] = dataSource; + } else { + dataSource->deleteLater(); + qCDebug(KPEOPLE_LOG) << "Plugin" << pluginId << "was already loaded manually, ignoring..."; + } } else { qCWarning(KPEOPLE_LOG) << "Failed to create data source " << service.name() << service.fileName(); } @@ -86,32 +95,43 @@ m_loadedDataSourcePlugins = true; } +void PersonPluginManager::setAutoloadDataSourcePlugins(bool autoloadDataSourcePlugins) +{ + s_instance->m_autoloadDataSourcePlugins = autoloadDataSourcePlugins; +} + +void PersonPluginManager::addDataSource(const QString &sourceId, BasePersonsDataSource *source) +{ + QMutexLocker(&s_instance->m_mutex); + if (s_instance->dataSourcePlugins.contains(sourceId)) { + qCWarning(KPEOPLE_LOG) << "Attempting to load data source that is already loaded, overriding!"; + s_instance->dataSourcePlugins[sourceId]->deleteLater(); + } + s_instance->dataSourcePlugins.insert(sourceId, source); +} + void PersonPluginManager::setDataSourcePlugins(const QHash &dataSources) { - s_instance->m_mutex.lock(); + QMutexLocker(&s_instance->m_mutex); qDeleteAll(s_instance->dataSourcePlugins); s_instance->dataSourcePlugins = dataSources; s_instance->m_loadedDataSourcePlugins = true; - s_instance->m_mutex.unlock(); } QList PersonPluginManager::dataSourcePlugins() { - s_instance->m_mutex.lock(); - if (!s_instance->m_loadedDataSourcePlugins) { + QMutexLocker(&s_instance->m_mutex); + if (!s_instance->m_loadedDataSourcePlugins && s_instance->m_autoloadDataSourcePlugins) { s_instance->loadDataSourcePlugins(); } - s_instance->m_mutex.unlock(); return s_instance->dataSourcePlugins.values(); } BasePersonsDataSource *PersonPluginManager::dataSource(const QString &sourceId) { - s_instance->m_mutex.lock(); - if (!s_instance->m_loadedDataSourcePlugins) { + QMutexLocker(&s_instance->m_mutex); + if (!s_instance->m_loadedDataSourcePlugins && s_instance->m_autoloadDataSourcePlugins) { s_instance->loadDataSourcePlugins(); } - s_instance->m_mutex.unlock(); - return s_instance->dataSourcePlugins.value(sourceId); } diff --git a/src/personsmodel.cpp b/src/personsmodel.cpp --- a/src/personsmodel.cpp +++ b/src/personsmodel.cpp @@ -21,7 +21,7 @@ #include "personsmodel.h" -#include "personpluginmanager_p.h" +#include "personpluginmanager.h" #include "metacontact_p.h" #include "backends/basepersonsdatasource.h" #include "personmanager_p.h"