From c3b88d149d566cddf87e2fbb0f180e79da2b95ad Mon Sep 17 00:00:00 2001
From: Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>
Date: Mon, 9 Mar 2015 16:03:36 -0400
Subject: [PATCH] collection: Port the NumberCategoryModel to the colleciton
 system

Also rename addBackend() to addCollection()

Refs #68098
---
 src/collectioninterface.hpp        | 13 +++++----
 src/collectionmanagerinterface.h   |  8 +++---
 src/collectionmanagerinterface.hpp | 11 ++++----
 src/collectionmodel.cpp            |  2 ++
 src/numbercategory.cpp             | 44 +++++++++++++++++++++++++++++-
 src/numbercategory.h               | 27 +++++++++++++-----
 src/numbercategorymodel.cpp        | 43 +++++++++++++++++++++++------
 src/numbercategorymodel.h          | 11 ++++++--
 src/profilemodel.cpp               |  2 +-
 src/transitionalpersonbackend.cpp  |  2 +-
 10 files changed, 128 insertions(+), 35 deletions(-)

diff --git a/src/collectioninterface.hpp b/src/collectioninterface.hpp
index f1998841..9f028e23 100644
--- a/src/collectioninterface.hpp
+++ b/src/collectioninterface.hpp
@@ -54,26 +54,27 @@ d_ptr(new CollectionInterfacePrivate())
 
    //The cast is safe because the metatype is checked earlier
    d_ptr->m_fAdd = [editor](ItemBase<QObject>* item)->bool {
-      return editor->addNew(static_cast<T*>(item));
+      return editor?editor->addNew(static_cast<T*>(item)) : false;
    };
    d_ptr->m_fSave = [editor](ItemBase<QObject>* item)->bool {
-      return editor->edit(static_cast<T*>(item));
+      return editor?editor->edit(static_cast<T*>(item)) : false;
    };
    d_ptr->m_fEdit = [editor](ItemBase<QObject>* item)->bool {
-      return editor->edit(static_cast<T*>(item));
+      return editor?editor->edit(static_cast<T*>(item)) : false;
    };
    d_ptr->m_fRemove = [editor](ItemBase<QObject>* item)->bool {
-      return editor->remove(static_cast<T*>(item));
+      return editor?editor->remove(static_cast<T*>(item)) : false;
    };
    d_ptr->m_fSize = [editor]()->int {
-      return editor->items().size();
+      return editor?editor->items().size() : 0;
    };
 }
 
 template<typename T>
 QVector<T*> CollectionInterface::items() const
 {
-   return editor<T>()->items();
+   const CollectionEditor<T>* e = editor<T>();
+   return e?e->items() : QVector<T*>();
 }
 
 template<typename T>
diff --git a/src/collectionmanagerinterface.h b/src/collectionmanagerinterface.h
index ab1e6b6b..2f235092 100644
--- a/src/collectionmanagerinterface.h
+++ b/src/collectionmanagerinterface.h
@@ -107,8 +107,8 @@ public:
     * Issue with LLVM 3.5svn shipped in Mac OSX with variadic template
     */
    template <class T2>
-   T2* addBackend(const LoadOptions options = LoadOptions::NONE);
-#else
+   T2* addCollection(const LoadOptions options = LoadOptions::NONE);
+#endif
    /**
     * This method is used to add a collection to a model. The LoadOptions
     * can be used to enforce some parameters. Please note this function is
@@ -121,8 +121,8 @@ public:
     * @return The newly created collection
     */
    template <class T2, typename ...Ts>
-   T2* addBackend(Ts... args, const LoadOptions options = LoadOptions::NONE);
-#endif // Q_OS_DARWIN
+   T2* addCollection(Ts... args, const LoadOptions options = LoadOptions::NONE);
+
 
    /// Do this manager have active collections
    virtual bool hasEnabledCollections (CollectionInterface::SupportedFeatures features = CollectionInterface::SupportedFeatures::NONE) const final;
diff --git a/src/collectionmanagerinterface.hpp b/src/collectionmanagerinterface.hpp
index c0f7c422..4d5e4fad 100644
--- a/src/collectionmanagerinterface.hpp
+++ b/src/collectionmanagerinterface.hpp
@@ -52,10 +52,10 @@ CollectionManagerInterfacePrivate<T>::~CollectionManagerInterfacePrivate()
       delete m_pMediator;
 }
 
-template<class T>
 #ifdef Q_OS_DARWIN
+template<class T>
 template <class T2>
-T2* CollectionManagerInterface<T>::addBackend(const LoadOptions options)
+T2* CollectionManagerInterface<T>::addCollection(const LoadOptions options)
 {
    T2* backend = new T2(d_ptr->itemMediator());
 
@@ -76,9 +76,11 @@ T2* CollectionManagerInterface<T>::addBackend(const LoadOptions options)
 
    return backend;
 }
-#else
+#endif
+
+template<class T>
 template <class T2, typename ...Ts>
-T2* CollectionManagerInterface<T>::addBackend(Ts... args, const LoadOptions options)
+T2* CollectionManagerInterface<T>::addCollection(Ts... args, const LoadOptions options)
 {
    T2* collection = new T2(d_ptr->itemMediator(),args...);
 
@@ -99,7 +101,6 @@ T2* CollectionManagerInterface<T>::addBackend(Ts... args, const LoadOptions opti
 
    return collection;
 }
-#endif //Q_OS_DARWIN
 
 template<class T>
 CollectionManagerInterface<T>::CollectionManagerInterface(QAbstractItemModel* self) : d_ptr(new CollectionManagerInterfacePrivate<T>(self,this))
diff --git a/src/collectionmodel.cpp b/src/collectionmodel.cpp
index b88f29fc..a1955954 100644
--- a/src/collectionmodel.cpp
+++ b/src/collectionmodel.cpp
@@ -300,6 +300,8 @@ void CollectionModelPrivate::registerNew(CollectionInterface* col)
       cat->m_AltName   = col->category();
       cat->collection  = nullptr;
 
+      m_hCategories[cat->m_AltName] = cat;
+
       q_ptr->beginInsertRows(QModelIndex(),m_lTopLevelBackends.size(),m_lTopLevelBackends.size());
       m_lTopLevelBackends << cat;
       q_ptr->endInsertRows();
diff --git a/src/numbercategory.cpp b/src/numbercategory.cpp
index f5610eea..db9dd743 100644
--- a/src/numbercategory.cpp
+++ b/src/numbercategory.cpp
@@ -20,6 +20,10 @@
 #include <QtCore/QSize>
 
 #include "delegates/pixmapmanipulationdelegate.h"
+#include "collectionmediator.h"
+#include "collectioneditor.h"
+#include "contactmethod.h"
+#include "numbercategorymodel.h"
 
 class NumberCategoryPrivate
 {
@@ -34,8 +38,9 @@ NumberCategoryPrivate::NumberCategoryPrivate() : m_pIcon(), m_Name()
 {
 }
 
-NumberCategory::NumberCategory(QObject* parent, const QString& name) : QObject(parent), d_ptr(new NumberCategoryPrivate())
+NumberCategory::NumberCategory(CollectionMediator<ContactMethod>* mediator, const QString& name) : CollectionInterface(static_cast<CollectionEditor<ContactMethod>*>(nullptr)), d_ptr(new NumberCategoryPrivate())
 {
+   Q_UNUSED(mediator)
    d_ptr->m_Name = name;
 }
 
@@ -43,6 +48,11 @@ NumberCategory::~NumberCategory()
 {
 }
 
+QVariant NumberCategory::icon() const
+{
+   return PixmapManipulationDelegate::instance()->numberCategoryIcon(d_ptr->m_pIcon,QSize(),false,false);
+}
+
 QVariant NumberCategory::icon(bool isTracked, bool isPresent) const
 {
    return PixmapManipulationDelegate::instance()->numberCategoryIcon(d_ptr->m_pIcon,QSize(),isTracked,isPresent);
@@ -53,6 +63,38 @@ QString  NumberCategory::name() const
    return d_ptr->m_Name;
 }
 
+QString NumberCategory::category() const
+{
+   return QObject::tr("Phone number types");
+}
+
+bool NumberCategory::isEnabled() const
+{
+   return true;
+}
+
+QByteArray NumberCategory::id() const
+{
+   return "numbercat"+d_ptr->m_Name.toLatin1();
+}
+
+bool NumberCategory::load()
+{
+   return false;
+}
+
+int NumberCategory::size() const
+{
+   return NumberCategoryModel::instance()->getSize(this);
+}
+
+CollectionInterface::SupportedFeatures NumberCategory::supportedFeatures() const
+{
+   return (CollectionInterface::SupportedFeatures)   (
+      CollectionInterface::SupportedFeatures::NONE   |
+      CollectionInterface::SupportedFeatures::LOAD   );
+}
+
 void NumberCategory::setIcon(const QVariant& pixmap)
 {
    d_ptr->m_pIcon = pixmap;
diff --git a/src/numbercategory.h b/src/numbercategory.h
index d9057e5c..09d87a7c 100644
--- a/src/numbercategory.h
+++ b/src/numbercategory.h
@@ -18,32 +18,45 @@
 #ifndef NUMBERCATEGORY_H
 #define NUMBERCATEGORY_H
 
-#include <QtCore/QObject>
+#include <collectioninterface.h>
 
 #include "typedefs.h"
 
 class QPixmap;
 class NumberCategoryPrivate;
+class ContactMethod;
+class NumberCategoryModel;
+template <typename T> class CollectionManagerInterface;
 
 /**
  * This class represent a ContactMethod category. Categories usually
  * come from the contact provider, but can be added dynamically too
  */
-class LIB_EXPORT NumberCategory : public QObject {
-   Q_OBJECT
+class LIB_EXPORT NumberCategory : public CollectionInterface {
+
 public:
    friend class NumberCategoryModel;
+   friend class CollectionManagerInterface<ContactMethod>;
+
+   virtual QString    name     () const override;
+   virtual QString    category () const override;
+   virtual QVariant   icon     () const override;
+   virtual bool       isEnabled() const override;
+   virtual QByteArray id       () const override;
+   virtual int        size     () const override;
+
+   QVariant icon(bool isTracked, bool isPresent = false) const;
+
+   virtual SupportedFeatures  supportedFeatures() const override;
+   virtual bool load  () override;
 
-   //Getter
-   QVariant icon(bool isTracked = false, bool isPresent = false) const;
-   QString  name() const;
 
    //Setter
    void setIcon(const QVariant& pixmap );
    void setName(const QString&  name   );
 
 private:
-   NumberCategory(QObject* parent, const QString& name);
+   NumberCategory(CollectionMediator<ContactMethod>* mediator, const QString& name);
    virtual ~NumberCategory();
 
    const QScopedPointer<NumberCategoryPrivate> d_ptr;
diff --git a/src/numbercategorymodel.cpp b/src/numbercategorymodel.cpp
index d6d4367d..fe4c6330 100644
--- a/src/numbercategorymodel.cpp
+++ b/src/numbercategorymodel.cpp
@@ -34,12 +34,13 @@ public:
    QVector<InternalTypeRepresentation*>   m_lCategories;
    QHash<int,InternalTypeRepresentation*> m_hByIdx;
    QHash<QString,InternalTypeRepresentation*> m_hByName;
+   QHash<const NumberCategory*,InternalTypeRepresentation*> m_hToInternal;
    static NumberCategory*                 m_spOther    ;
 };
 
 NumberCategory*      NumberCategoryModelPrivate::m_spOther    = nullptr;
 
-NumberCategoryModel::NumberCategoryModel(QObject* parent) : QAbstractListModel(parent),d_ptr(new NumberCategoryModelPrivate())
+NumberCategoryModel::NumberCategoryModel(QObject* parent) : QAbstractListModel(parent),CollectionManagerInterface(this),d_ptr(new NumberCategoryModelPrivate())
 {
 }
 
@@ -109,14 +110,16 @@ NumberCategory* NumberCategoryModel::addCategory(const QString& name, const QVar
       rep = new NumberCategoryModelPrivate::InternalTypeRepresentation();
       rep->counter = 0      ;
    }
-   NumberCategory* cat = new NumberCategory(this,name);
+   NumberCategory* cat = addCollection<NumberCategory,QString>(name,LoadOptions::NONE);
    cat->setIcon(icon);
    rep->category   = cat    ;
    rep->index      = index  ;
    rep->enabled    = enabled;
-   d_ptr->m_hByIdx[index] = rep    ;
-   d_ptr->m_hByName[name] = rep    ;
-   d_ptr->m_lCategories  << rep    ;
+
+   d_ptr->m_hToInternal[cat] = rep ;
+   d_ptr->m_hByIdx[index]    = rep ;
+   d_ptr->m_hByName[name]    = rep ;
+   d_ptr->m_lCategories     << rep ;
    emit layoutChanged()     ;
    return cat;
 }
@@ -180,11 +183,35 @@ NumberCategory* NumberCategoryModel::getCategory(const QString& type)
 
 NumberCategory* NumberCategoryModel::other()
 {
-   if (instance()->d_ptr->m_hByName["Other"])
-      return instance()->d_ptr->m_hByName["Other"]->category;
+   QString translated = QObject::tr("Other");
+   if (instance()->d_ptr->m_hByName[translated])
+      return instance()->d_ptr->m_hByName[translated]->category;
    if (NumberCategoryModelPrivate::m_spOther)
-      NumberCategoryModelPrivate::m_spOther = new NumberCategory(instance(),"Other");
+      NumberCategoryModelPrivate::m_spOther = instance()->addCollection<NumberCategory,QString>(translated,LoadOptions::NONE);
    return NumberCategoryModelPrivate::m_spOther;
 }
 
+int NumberCategoryModel::getSize(const NumberCategory* cat) const
+{
+   NumberCategoryModelPrivate::InternalTypeRepresentation* i = d_ptr->m_hToInternal[cat];
+   return i ? i->counter : 0;
+}
+
+void NumberCategoryModel::collectionAddedCallback(CollectionInterface* collection)
+{
+   Q_UNUSED(collection)
+}
+
+bool NumberCategoryModel::addItemCallback(const ContactMethod* item)
+{
+   Q_UNUSED(item)
+   return false;
+}
+
+bool NumberCategoryModel::removeItemCallback(const ContactMethod* item)
+{
+   Q_UNUSED(item)
+   return false;
+}
+
 #include <numbercategorymodel.moc>
diff --git a/src/numbercategorymodel.h b/src/numbercategorymodel.h
index 974be02f..9154e307 100644
--- a/src/numbercategorymodel.h
+++ b/src/numbercategorymodel.h
@@ -21,13 +21,14 @@
 
 #include <QtCore/QAbstractListModel>
 #include <QtCore/QVector>
+#include "collectionmanagerinterface.h"
 
 class NumberCategoryDelegate;
 class ContactMethod;
 class NumberCategory;
 class NumberCategoryModelPrivate;
 
-class LIB_EXPORT NumberCategoryModel : public QAbstractListModel {
+class LIB_EXPORT NumberCategoryModel : public QAbstractListModel, public CollectionManagerInterface<ContactMethod> {
    Q_OBJECT
 public:
 
@@ -54,9 +55,10 @@ public:
    QModelIndex nameToIndex(const QString& name) const;
    NumberCategory* getCategory(const QString& type);
    static NumberCategory* other();
+   int getSize(const NumberCategory* cat) const;
 
    //Mutator
-   void registerNumber  (ContactMethod* number);
+   void registerNumber  (ContactMethod* number); //FIXME this should be private
    void unregisterNumber(ContactMethod* number);
 
 private:
@@ -65,6 +67,11 @@ private:
 
    QScopedPointer<NumberCategoryModelPrivate> d_ptr;
 
+   //Re-implementation
+   virtual void collectionAddedCallback(CollectionInterface* collection) override;
+   virtual bool addItemCallback(const ContactMethod* item) override;
+   virtual bool removeItemCallback(const ContactMethod* item) override;
+
    //Singleton
    static NumberCategoryModel* m_spInstance;
 };
diff --git a/src/profilemodel.cpp b/src/profilemodel.cpp
index 458ba649..a35b956d 100644
--- a/src/profilemodel.cpp
+++ b/src/profilemodel.cpp
@@ -517,7 +517,7 @@ ProfileModel::ProfileModel(QObject* parent) : QAbstractItemModel(parent), d_ptr(
    d_ptr->m_lMimes << RingMimes::PLAIN_TEXT << RingMimes::HTML_TEXT << RingMimes::ACCOUNT << RingMimes::PROFILE;
 
    //Creating the profile contact backend
-   d_ptr->m_pProfileBackend = PersonModel::instance()->addBackend<ProfileContentBackend>(LoadOptions::FORCE_ENABLED);
+   d_ptr->m_pProfileBackend = PersonModel::instance()->addCollection<ProfileContentBackend>(LoadOptions::FORCE_ENABLED);
 
    //Once LibRingClient is ready, start listening
    QTimer::singleShot(0,d_ptr,SLOT(slotDelayedInit()));
diff --git a/src/transitionalpersonbackend.cpp b/src/transitionalpersonbackend.cpp
index 1fe73981..39fd2ae9 100644
--- a/src/transitionalpersonbackend.cpp
+++ b/src/transitionalpersonbackend.cpp
@@ -80,7 +80,7 @@ CollectionInterface* TransitionalPersonBackend::m_spInstance = nullptr;
 CollectionInterface* TransitionalPersonBackend::instance()
 {
    if (!m_spInstance) {
-      m_spInstance = PersonModel::instance()->addBackend<TransitionalPersonBackend>();
+      m_spInstance = PersonModel::instance()->addCollection<TransitionalPersonBackend>();
    }
    return m_spInstance;
 }
-- 
GitLab