From 3d72371a5b738690daf80db8b066be68045629a9 Mon Sep 17 00:00:00 2001 From: Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> Date: Thu, 12 Mar 2015 19:17:46 -0400 Subject: [PATCH] collection: Add a new mechanism to attach "configurator" and "creator" delegates to a CollectionInterface class. This can be used in conjunction with the CollectionModel in GUIs to configure various collections Refs #68352 --- CMakeLists.txt | 7 +++- src/categorizedcompositenode.cpp | 1 + src/collectionconfigurationinterface.h | 51 ++++++++++++++++++++++++++ src/collectioncreationinterface.h | 35 ++++++++++++++++++ src/collectioninterface.cpp | 10 +++++ src/collectioninterface.h | 14 +++++++ src/collectioninterface.hpp | 3 +- src/collectionmanagerinterface.cpp | 15 ++++++++ src/collectionmanagerinterface.h | 30 +++++++++++++-- src/collectionmanagerinterface.hpp | 36 +++++++++++++++++- src/private/collectionmodel_p.h | 16 +++++--- 11 files changed, 205 insertions(+), 13 deletions(-) create mode 100644 src/collectionconfigurationinterface.h create mode 100644 src/collectioncreationinterface.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4604af6d..7bafc794 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -315,6 +315,9 @@ SET( libringclient_LIB_HDRS src/collectioneditor.hpp src/fallbackpersoncollection.h src/securityflaw.h + src/collectioncreationinterface.h + src/collectionconfigurationinterface.h + ) SET(libringclient_video_LIB_HDRS @@ -446,7 +449,7 @@ ELSE() ENDIF(${ENABLE_LIBWRAP} MATCHES true) -# Manually wrap private files +# Manually wrap private files and interfaces SET(libringclient_PRIVATE_HDRS src/private/call_p.h src/private/account_p.h @@ -456,6 +459,8 @@ SET(libringclient_PRIVATE_HDRS src/private/videorenderer_p.h src/private/collectionmodel_p.h src/private/securityflaw_p.h + src/collectioncreationinterface.h + src/collectionconfigurationinterface.h ) IF(${ENABLE_LIBWRAP} MATCHES true) diff --git a/src/categorizedcompositenode.cpp b/src/categorizedcompositenode.cpp index 6fae53de..423176b0 100644 --- a/src/categorizedcompositenode.cpp +++ b/src/categorizedcompositenode.cpp @@ -40,6 +40,7 @@ CategorizedCompositeNode::CategorizedCompositeNode(CategorizedCompositeNode::Typ CategorizedCompositeNode::~CategorizedCompositeNode() { + delete d_ptr; } char CategorizedCompositeNode::dropState() diff --git a/src/collectionconfigurationinterface.h b/src/collectionconfigurationinterface.h new file mode 100644 index 00000000..7276e4eb --- /dev/null +++ b/src/collectionconfigurationinterface.h @@ -0,0 +1,51 @@ +/**************************************************************************** + * Copyright (C) 2015 by Savoir-Faire Linux * + * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ +#ifndef COLLECTIONCONFIGURATIONINTERFACE_H +#define COLLECTIONCONFIGURATIONINTERFACE_H + +#include <QtCore/QObject> + +#include "typedefs.h" + +class CollectionInterface; + +class LIB_EXPORT CollectionConfigurationInterface : public QObject +{ + Q_OBJECT +public: + + CollectionConfigurationInterface(QObject* parent = nullptr) : QObject(parent) {} + + //Getter + virtual QByteArray id () const = 0; + virtual QString name() const = 0; + virtual QVariant icon() const = 0; + + //Mutator + + /** + * This function will be called when a collection request to be configured + * + * @param col The collection to be edited. It can casted + * @param parent can be used for layout information. + */ + virtual void loadCollection(CollectionInterface* col, QObject* parent = nullptr) =0; +}; +Q_DECLARE_METATYPE(CollectionConfigurationInterface*) + +#endif diff --git a/src/collectioncreationinterface.h b/src/collectioncreationinterface.h new file mode 100644 index 00000000..d63e2071 --- /dev/null +++ b/src/collectioncreationinterface.h @@ -0,0 +1,35 @@ +/**************************************************************************** + * Copyright (C) 2015 by Savoir-Faire Linux * + * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ +#ifndef COLLECTIONCREATIONINTERFACE_H +#define COLLECTIONCREATIONINTERFACE_H + +#include <QtCore/QObject> + +#include "typedefs.h" +class LIB_EXPORT CollectionCreationInterface : public QObject +{ + Q_OBJECT +public: + virtual QByteArray id () const = 0; + virtual QString name() const = 0; + virtual QVariant icon() const = 0; +}; + +Q_DECLARE_METATYPE(CollectionCreationInterface*) + +#endif diff --git a/src/collectioninterface.cpp b/src/collectioninterface.cpp index f4092bb0..7d5ff7ce 100644 --- a/src/collectioninterface.cpp +++ b/src/collectioninterface.cpp @@ -114,3 +114,13 @@ QMetaObject CollectionInterface::metaObject() { return d_ptr->m_pEditorType; } + +CollectionConfigurationInterface* CollectionInterface::configurator() const +{ + return d_ptr->m_fConfigurator(); +} + +void CollectionInterface::setConfigurator(std::function<CollectionConfigurationInterface*()> getter) +{ + d_ptr->m_fConfigurator = getter; +} diff --git a/src/collectioninterface.h b/src/collectioninterface.h index ab99c52f..ba5391e1 100644 --- a/src/collectioninterface.h +++ b/src/collectioninterface.h @@ -26,9 +26,13 @@ #include "typedefs.h" +//Libstdc++ +#include <functional> + //Ring class CollectionInterfacePrivate; class CollectionEditorBase; +class CollectionConfigurationInterface; template<typename T> class CollectionEditor; template<typename T> class CollectionMediator; template<typename T> class ItemBase; @@ -48,6 +52,7 @@ class LIB_EXPORT CollectionInterface { template<typename T> friend class CollectionMediator; template<typename T> friend class CollectionManagerInterface; + friend class CollectionManagerInterfaceBase; friend class ItemBase<QObject>; public: @@ -203,7 +208,16 @@ public: */ bool add (ItemBase<QObject>* base); + /** + * Return an object that has been associated with this collection type + * + * It can be set using registerConfigarator() available in every collection + * manager objects such as PersonModel, HistoryModel and others. + */ + CollectionConfigurationInterface* configurator() const; + protected: + void setConfigurator(std::function<CollectionConfigurationInterface*()> getter); void addChildren(CollectionInterface* c); bool save (ItemBase<QObject>* base); diff --git a/src/collectioninterface.hpp b/src/collectioninterface.hpp index 9f028e23..29a66714 100644 --- a/src/collectioninterface.hpp +++ b/src/collectioninterface.hpp @@ -18,7 +18,6 @@ //TODO don't do this -#include <functional> template<typename T> class ItemBase; class CollectionInterfacePrivate { @@ -41,6 +40,8 @@ public: std::function<bool(ItemBase<QObject>*)> m_fEdit ; std::function<bool(ItemBase<QObject>*)> m_fRemove ; std::function<int() > m_fSize ; + + std::function<CollectionConfigurationInterface*()> m_fConfigurator; }; template<typename T> diff --git a/src/collectionmanagerinterface.cpp b/src/collectionmanagerinterface.cpp index 78782919..664101ee 100644 --- a/src/collectionmanagerinterface.cpp +++ b/src/collectionmanagerinterface.cpp @@ -30,4 +30,19 @@ public: void CollectionManagerInterfaceBase::registerToModel(CollectionInterface* col) const { CollectionModel::instance()->d_ptr->registerNew(col); +} + +void CollectionManagerInterfaceBase::addCreatorToList(CollectionCreationInterface* creator) +{ + CollectionModel::instance()->d_ptr->m_lCreator << creator; +} + +void CollectionManagerInterfaceBase::addConfiguratorToList(CollectionConfigurationInterface* configurator) +{ + CollectionModel::instance()->d_ptr->m_lConfigurator << configurator; +} + +void CollectionManagerInterfaceBase::setCollectionConfigurator(CollectionInterface* col, std::function<CollectionConfigurationInterface*()> getter) +{ + col->setConfigurator(getter); } \ No newline at end of file diff --git a/src/collectionmanagerinterface.h b/src/collectionmanagerinterface.h index 2f235092..6108379d 100644 --- a/src/collectionmanagerinterface.h +++ b/src/collectionmanagerinterface.h @@ -15,8 +15,8 @@ * You should have received a copy of the GNU General Public License * * along with this program. If not, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ -#ifndef BACKENDMANAGERINTERFACE_H -#define BACKENDMANAGERINTERFACE_H +#ifndef COLLECTIONMANAGERINTERFACE_H +#define COLLECTIONMANAGERINTERFACE_H #include "typedefs.h" @@ -25,6 +25,7 @@ //libstdc++ #include <type_traits> +#include <functional> //Ring #include <collectioninterface.h> @@ -39,6 +40,8 @@ enum LoadOptions { }; class CollectionManagerInterfaceBasePrivate; +class CollectionCreationInterface; +class CollectionConfigurationInterface; /** * Common elements for each CollectionManagerInterface @@ -49,12 +52,15 @@ public: virtual bool hasCollections (CollectionInterface::SupportedFeatures features = CollectionInterface::SupportedFeatures::NONE) const = 0; ///Enable / disable a collection - virtual bool enableBackend( CollectionInterface* collection, bool enabled) = 0; + virtual bool enableCollection( CollectionInterface* collection, bool enabled) = 0; virtual bool clearAllCollections() const = 0; protected: void registerToModel(CollectionInterface* col) const; + void addCreatorToList(CollectionCreationInterface* creator); + void addConfiguratorToList(CollectionConfigurationInterface* configurator); + void setCollectionConfigurator(CollectionInterface* col, std::function<CollectionConfigurationInterface*()> getter); private: CollectionManagerInterfaceBasePrivate* d_ptr; @@ -123,6 +129,22 @@ public: template <class T2, typename ...Ts> T2* addCollection(Ts... args, const LoadOptions options = LoadOptions::NONE); + /** + * Set an object that will be used when the user wish to add a new collection + * of that type. + * + * That object can be a widget or anything. I will be passed when a creator + * is requested for that type of collection. + */ + template <class T2> + CollectionCreationInterface* registerCreator(CollectionCreationInterface* creator = nullptr); + + /** + * @see template <class T2> void registerCreator(CollectionCreationInterface* creator); + */ + template <class T2> + CollectionConfigurationInterface* registerConfigarator(CollectionConfigurationInterface* creator = nullptr); + /// Do this manager have active collections virtual bool hasEnabledCollections (CollectionInterface::SupportedFeatures features = CollectionInterface::SupportedFeatures::NONE) const final; @@ -133,7 +155,7 @@ public: virtual const QVector< CollectionInterface* > enabledCollections(CollectionInterface::SupportedFeatures features = CollectionInterface::SupportedFeatures::NONE) const final; ///Enable / disable a collection - virtual bool enableBackend( CollectionInterface* collection, bool enabled) final; + virtual bool enableCollection( CollectionInterface* collection, bool enabled) final; virtual bool clearAllCollections() const; diff --git a/src/collectionmanagerinterface.hpp b/src/collectionmanagerinterface.hpp index 4d5e4fad..5928e0f0 100644 --- a/src/collectionmanagerinterface.hpp +++ b/src/collectionmanagerinterface.hpp @@ -63,6 +63,10 @@ T2* CollectionManagerInterface<T>::addCollection(const LoadOptions options) CollectionInterface* b = backend; d_ptr->m_lCollections << b; + setCollectionConfigurator(backend,[this]() { + return registerConfigarator<T2>(); + }); + if (options & LoadOptions::FORCE_ENABLED) { //TODO check is the backend is checked //Some backends can fail to load directly @@ -88,6 +92,12 @@ T2* CollectionManagerInterface<T>::addCollection(Ts... args, const LoadOptions o CollectionInterface* b = collection; d_ptr->m_lCollections << b; + //This is the last time we have the class type (T2), so create a lambda + //to keep track of the configurator type while we still can + setCollectionConfigurator(collection,[this]() { + return registerConfigarator<T2>(); + }); + if (options & LoadOptions::FORCE_ENABLED) { //TODO check is the collection is checked //Some collections can fail to load directly @@ -102,6 +112,30 @@ T2* CollectionManagerInterface<T>::addCollection(Ts... args, const LoadOptions o return collection; } +template<class T> +template <class T2> +CollectionCreationInterface* CollectionManagerInterface<T>::registerCreator(CollectionCreationInterface* creator) +{ + static CollectionCreationInterface* cfg = nullptr; + if (creator) { + cfg = creator; + addCreatorToList(creator); + } + return cfg; +} + +template<class T> +template <class T2> +CollectionConfigurationInterface* CollectionManagerInterface<T>::registerConfigarator(CollectionConfigurationInterface* configurator) +{ + static CollectionConfigurationInterface* cfg = nullptr; + if (configurator) { + cfg = configurator; + addConfiguratorToList(configurator); + } + return cfg; +} + template<class T> CollectionManagerInterface<T>::CollectionManagerInterface(QAbstractItemModel* self) : d_ptr(new CollectionManagerInterfacePrivate<T>(self,this)) { @@ -204,7 +238,7 @@ bool CollectionManagerInterface<T>::deleteItem(T* item) } template<class T> -bool CollectionManagerInterface<T>::enableBackend( CollectionInterface* collection, bool enabled) +bool CollectionManagerInterface<T>::enableCollection( CollectionInterface* collection, bool enabled) { Q_UNUSED(enabled) //TODO implement it collection->load(); diff --git a/src/private/collectionmodel_p.h b/src/private/collectionmodel_p.h index 0298b9de..4278746e 100644 --- a/src/private/collectionmodel_p.h +++ b/src/private/collectionmodel_p.h @@ -28,6 +28,8 @@ class QAbstractItemModel; class CollectionInterface; class CollectionModel; class CollectionExtensionInterface; +class CollectionConfigurationInterface; +class CollectionCreationInterface; class CollectionModelPrivate : public QObject { @@ -51,12 +53,14 @@ public: int manageableCount; }; - QHash<CollectionInterface*,ProxyItem*> m_hBackendsNodes; - QVector<ProxyItem*> m_lTopLevelBackends; - QVector<CollectionExtensionInterface*> m_lExtensions; - QHash<QString,ProxyItem*> m_hCategories; - static CollectionModel* m_spInstance; - QAbstractItemModel* m_pManageableProxy; + QHash<CollectionInterface*,ProxyItem*> m_hBackendsNodes; + QVector<ProxyItem*> m_lTopLevelBackends; + QVector<CollectionExtensionInterface*> m_lExtensions; + QHash<QString,ProxyItem*> m_hCategories; + static CollectionModel* m_spInstance; + QAbstractItemModel* m_pManageableProxy; + QList<CollectionConfigurationInterface*> m_lConfigurator; + QList<CollectionCreationInterface*> m_lCreator; //Helper void registerNew(CollectionInterface* col); -- GitLab