[niepce] library: rework the notifications to be strongly typed



commit 8b3912a266769d02dc0dc3622da422e0852b8065
Author: Hubert Figuière <hub figuiere net>
Date:   Wed May 31 21:58:44 2017 -0400

    library: rework the notifications to be strongly typed

 src/engine/db/library.cpp              |   25 ++--
 src/engine/db/library.hpp              |   30 +-----
 src/engine/library/commands.cpp        |   52 ++++----
 src/engine/library/notification.hpp    |  204 ++++++++++++++++++++++++++++++++
 src/engine/library/thumbnailcache.cpp  |    2 +-
 src/fwk/toolkit/notification.hpp       |    7 +-
 src/fwk/toolkit/notificationcenter.cpp |    3 +-
 src/fwk/toolkit/notificationcenter.hpp |    2 +-
 src/niepce/modules/map/mapmodule.cpp   |    6 +-
 src/niepce/ui/gridviewmodule.cpp       |   26 ++---
 src/niepce/ui/imageliststore.cpp       |   15 +--
 src/niepce/ui/niepcewindow.cpp         |   24 ++--
 src/niepce/ui/workspacecontroller.cpp  |   44 +++----
 13 files changed, 296 insertions(+), 144 deletions(-)
---
diff --git a/src/engine/db/library.cpp b/src/engine/db/library.cpp
index bff8928..fa22705 100644
--- a/src/engine/db/library.cpp
+++ b/src/engine/db/library.cpp
@@ -62,11 +62,13 @@ Library::Library(const std::string & dir, const NotificationCenter::Ptr & nc)
         m_dbdrv = m_dbmgr->connect_to_db(desc, "", "");
         m_inited = init();
 
-        m_dbdrv->create_function0("rewrite_xmp",
-                                  [this] () {
-                                      DBG_OUT("rewrite_xmp");
-                                      notify(NotifyType::XMP_NEEDS_UPDATE, boost::any());
-                                  });
+        m_dbdrv->create_function0(
+            "rewrite_xmp",
+            [this] () {
+                DBG_OUT("rewrite_xmp");
+                notify(
+                    LibNotification::make<LibNotification::Type::XMP_NEEDS_UPDATE>({}));
+            });
     }
     catch(const std::exception &e)
     {
@@ -78,19 +80,15 @@ Library::~Library()
 {
 }
 
-void Library::notify(NotifyType t, const boost::any & param)
+void Library::notify(LibNotification&& ln)
 {
     fwk::NotificationCenter::Ptr nc(m_notif_center.lock());
     if(nc) {
         DBG_OUT("notif");
         // pass the notification
         fwk::Notification::Ptr n(new fwk::Notification(niepce::NOTIFICATION_LIB));
-        std::lock_guard<fwk::Notification::mutex_t> lock(n->mutex());
-        LibNotification ln;
-        ln.type = t;
-        ln.param = param;
         n->setData(boost::any(ln));
-        nc->post(n);
+        nc->post(std::move(n));
     }
     else {
         DBG_OUT("try to send a notification without notification center");
@@ -192,7 +190,8 @@ bool Library::_initDb()
 
     m_dbdrv->execute_statement(fileUpdateTrigger);
     m_dbdrv->execute_statement(xmpUpdateTrigger);
-    notify(NotifyType::NEW_LIBRARY_CREATED, boost::any());
+    notify(LibNotification::make<LibNotification::Type::NEW_LIBRARY_CREATED>(
+               LibNotification::None{}));
     return true;
 }
 
@@ -598,7 +597,7 @@ library_id_t Library::makeKeyword(const std::string & keyword)
             if(m_dbdrv->execute_statement(sql2)) {
                 keyword_id = m_dbdrv->last_row_id();
                 Keyword::Ptr kw(new Keyword(keyword_id, keyword));
-                notify(NotifyType::ADDED_KEYWORD, boost::any(kw));
+                notify(LibNotification::make<LibNotification::Type::ADDED_KEYWORD>({kw}));
             }
         }
         catch(fwk::Exception & e)
diff --git a/src/engine/db/library.hpp b/src/engine/db/library.hpp
index a70dd4a..99cd5e0 100644
--- a/src/engine/db/library.hpp
+++ b/src/engine/db/library.hpp
@@ -37,6 +37,7 @@
 #include "engine/db/filebundle.hpp"
 #include "engine/db/keyword.hpp"
 #include "engine/db/label.hpp"
+#include "engine/library/notification.hpp"
 
 // The database schema version. Increase at each change.
 // Some will be persistent and have a conversion TBD.
@@ -53,26 +54,6 @@ class Library
 public:
     typedef std::shared_ptr<Library> Ptr;
 
-    enum class NotifyType {
-        NONE = 0,
-        NEW_LIBRARY_CREATED,
-        ADDED_FOLDERS,
-        ADDED_FILES,
-        ADDED_KEYWORDS,
-        ADDED_KEYWORD,
-        ADDED_LABELS,
-        FOLDER_CONTENT_QUERIED,
-        KEYWORD_CONTENT_QUERIED,
-        METADATA_QUERIED,
-        METADATA_CHANGED,
-        LABEL_CHANGED,
-        LABEL_DELETED,
-        XMP_NEEDS_UPDATE,
-        FOLDER_COUNTED,
-        FOLDER_COUNT_CHANGE,
-        FILE_MOVED
-    };
-
     /** Whether to import managed. */
     enum class Managed {
         NO = 0,
@@ -94,7 +75,7 @@ public:
     const std::string & dbName() const
         { return m_dbname; }
 
-    void notify(NotifyType t, const boost::any & param);
+    void notify(LibNotification&& n);
 
     /** add a file to the library
      * @param folder the path of the containing folder
@@ -230,13 +211,6 @@ private:
     bool                              m_inited;
 };
 
-
-struct LibNotification
-{
-    Library::NotifyType type;
-    boost::any          param;
-};
-
 }
 
 #endif
diff --git a/src/engine/library/commands.cpp b/src/engine/library/commands.cpp
index 9086667..3a05d4e 100644
--- a/src/engine/library/commands.cpp
+++ b/src/engine/library/commands.cpp
@@ -43,7 +43,7 @@ void Commands::cmdListAllKeywords(const Library::Ptr & lib)
     lib->getAllKeywords(l);
     /////
     // notify folder added l
-    lib->notify(Library::NotifyType::ADDED_KEYWORDS, boost::any(l));
+    lib->notify(LibNotification::make<LibNotification::Type::ADDED_KEYWORDS>({l}));
 }
 
 void Commands::cmdListAllFolders(const Library::Ptr & lib)
@@ -52,7 +52,7 @@ void Commands::cmdListAllFolders(const Library::Ptr & lib)
     lib->getAllFolders(l);
     /////
     // notify folder added l
-    lib->notify(Library::NotifyType::ADDED_FOLDERS, boost::any(l));
+    lib->notify(LibNotification::make<LibNotification::Type::ADDED_FOLDERS>({l}));
 }
 
 void Commands::cmdImportFile(const Library::Ptr & lib,
@@ -72,12 +72,10 @@ void Commands::cmdImportFile(const Library::Ptr & lib,
         pf = lib->addFolder(folder);
         LibFolder::ListPtr l(new LibFolder::List);
         l->push_back(pf);
-        lib->notify(Library::NotifyType::ADDED_FOLDERS,
-                    boost::any(l));
+        lib->notify(LibNotification::make<LibNotification::Type::ADDED_FOLDERS>({l}));
     }
     lib->addBundle(pf->id(), bundle, manage);
-    lib->notify(Library::NotifyType::ADDED_FILES,
-                boost::any());
+    lib->notify(LibNotification::make<LibNotification::Type::ADDED_FILES>({}));
 }
 
 void Commands::cmdImportFiles(const Library::Ptr & lib,
@@ -94,15 +92,13 @@ void Commands::cmdImportFiles(const Library::Ptr & lib,
         pf = lib->addFolder(folder);
         LibFolder::ListPtr l( new LibFolder::List );
         l->push_back(pf);
-        lib->notify(Library::NotifyType::ADDED_FOLDERS,
-                    boost::any(l));
+        lib->notify(LibNotification::make<LibNotification::Type::ADDED_FOLDERS>({l}));
     }
     std::for_each(bundles->begin(), bundles->end(),
                   [&lib, &pf, manage] (const auto& fb) {
                       lib->addBundle(pf->id(), fb, manage);
                   });
-    lib->notify(Library::NotifyType::ADDED_FILES,
-                boost::any());
+    lib->notify(LibNotification::make<LibNotification::Type::ADDED_FILES>({}));
 }
 
 
@@ -111,15 +107,16 @@ void Commands::cmdQueryFolderContent(const Library::Ptr & lib,
 {
     LibFile::ListPtr fl(new LibFile::List());
     lib->getFolderContent(folder_id, fl);
-    lib->notify(Library::NotifyType::FOLDER_CONTENT_QUERIED, boost::any(fl));
+    lib->notify(LibNotification::make<LibNotification::Type::FOLDER_CONTENT_QUERIED>(
+                    {folder_id, fl}));
 }
 
 void Commands::cmdCountFolder(const Library::Ptr & lib,
                               eng::library_id_t folder_id)
 {
     int count = lib->countFolder(folder_id);
-    lib->notify(Library::NotifyType::FOLDER_COUNTED,
-                boost::any(std::make_pair(folder_id, count)));
+    lib->notify(LibNotification::make<LibNotification::Type::FOLDER_COUNTED>(
+                    {folder_id, count}));
 }
 
 void Commands::cmdQueryKeywordContent(const Library::Ptr & lib,
@@ -127,7 +124,8 @@ void Commands::cmdQueryKeywordContent(const Library::Ptr & lib,
 {
     LibFile::ListPtr fl(new LibFile::List());
     lib->getKeywordContent(keyword_id, fl);
-    lib->notify(Library::NotifyType::KEYWORD_CONTENT_QUERIED, boost::any(fl));
+    lib->notify(LibNotification::make<LibNotification::Type::KEYWORD_CONTENT_QUERIED>(
+                    {keyword_id, fl}));
 }
 
 void Commands::cmdRequestMetadata(const Library::Ptr & lib,
@@ -135,7 +133,8 @@ void Commands::cmdRequestMetadata(const Library::Ptr & lib,
 {
     LibMetadata::Ptr lm(new LibMetadata(file_id));
     lib->getMetaData(file_id, lm);
-    lib->notify(Library::NotifyType::METADATA_QUERIED, boost::any(lm));
+    lib->notify(LibNotification::make<LibNotification::Type::METADATA_QUERIED>(
+                    {file_id, lm}));
 }
 
 void Commands::cmdSetMetadata(const Library::Ptr & lib,
@@ -147,7 +146,8 @@ void Commands::cmdSetMetadata(const Library::Ptr & lib,
     m.meta = meta;
     m.value = value;
     lib->setMetaData(file_id, meta, value);
-    lib->notify(Library::NotifyType::METADATA_CHANGED, boost::any(m));
+    lib->notify(LibNotification::make<LibNotification::Type::METADATA_CHANGED>(
+                    std::move(m)));
 }
 
 void Commands::cmdWriteMetadata(const Library::Ptr & lib,
@@ -161,12 +161,12 @@ void Commands::cmdMoveFileToFolder(const Library::Ptr & lib,
                                    library_id_t to_folder_id)
 {
     if(lib->moveFileToFolder(file_id, to_folder_id)) {
-        lib->notify(Library::NotifyType::FILE_MOVED,
-                    boost::any(std::make_pair(file_id, to_folder_id)));
-        lib->notify(Library::NotifyType::FOLDER_COUNT_CHANGE,
-                    boost::any(std::make_pair(from_folder_id, -1)));
-        lib->notify(Library::NotifyType::FOLDER_COUNT_CHANGE,
-                    boost::any(std::make_pair(to_folder_id, 1)));
+        lib->notify(LibNotification::make<LibNotification::Type::FILE_MOVED>(
+                        {file_id, from_folder_id, to_folder_id}));
+        lib->notify(LibNotification::make<LibNotification::Type::FOLDER_COUNT_CHANGE>(
+                        {from_folder_id, -1}));
+        lib->notify(LibNotification::make<LibNotification::Type::FOLDER_COUNT_CHANGE>(
+                        {to_folder_id, 1}));
     }
 }
 
@@ -174,7 +174,7 @@ void Commands::cmdListAllLabels(const Library::Ptr & lib)
 {
     eng::Label::ListPtr l(new eng::Label::List);
     lib->getAllLabels(l);
-    lib->notify(Library::NotifyType::ADDED_LABELS, boost::any(l));
+    lib->notify(LibNotification::make<LibNotification::Type::ADDED_LABELS>({l}));
 }
 
 void Commands::cmdCreateLabel(const Library::Ptr & lib,
@@ -184,7 +184,7 @@ void Commands::cmdCreateLabel(const Library::Ptr & lib,
     if(id != -1) {
         eng::Label::ListPtr l(new eng::Label::List);
         l->push_back(eng::Label::Ptr(new eng::Label(id, s, color)));
-        lib->notify(Library::NotifyType::ADDED_LABELS, boost::any(l));
+        lib->notify(LibNotification::make<LibNotification::Type::ADDED_LABELS>({l}));
     }
 }
 
@@ -193,7 +193,7 @@ void Commands::cmdDeleteLabel(const Library::Ptr & lib,
                               int label_id)
 {
     lib->deleteLabel(label_id);
-    lib->notify(Library::NotifyType::LABEL_DELETED, boost::any(label_id));
+    lib->notify(LibNotification::make<LibNotification::Type::LABEL_DELETED>({label_id}));
 }
 
 
@@ -203,7 +203,7 @@ void Commands::cmdUpdateLabel(const Library::Ptr & lib,
 {
     lib->updateLabel(label_id, name, color);
     eng::Label::Ptr label(new eng::Label(label_id, name, color));
-    lib->notify(Library::NotifyType::LABEL_CHANGED, boost::any(label));
+    lib->notify(LibNotification::make<LibNotification::Type::LABEL_CHANGED>({label}));
 }
 
 
diff --git a/src/engine/library/notification.hpp b/src/engine/library/notification.hpp
new file mode 100644
index 0000000..0220b64
--- /dev/null
+++ b/src/engine/library/notification.hpp
@@ -0,0 +1,204 @@
+/* -*- mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode:nil; -*- */
+/*
+ * niepce - engine/library/notification.hpp
+ *
+ * Copyright (C) 2009-2017 Hubert Figuiere
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 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/>.
+ */
+
+#pragma once
+
+#include <boost/variant.hpp>
+
+#include "engine/library/clienttypes.hpp"
+
+namespace eng {
+
+class LibNotification
+{
+public:
+    enum class Type {
+        NONE = 0,
+        NEW_LIBRARY_CREATED,
+        ADDED_FOLDERS,
+        ADDED_FILES,
+        ADDED_KEYWORDS,
+        ADDED_KEYWORD,
+        ADDED_LABELS,
+        FOLDER_CONTENT_QUERIED,
+        KEYWORD_CONTENT_QUERIED,
+        METADATA_QUERIED,
+        METADATA_CHANGED,
+        LABEL_CHANGED,
+        LABEL_DELETED,
+        XMP_NEEDS_UPDATE,
+        FOLDER_COUNTED,
+        FOLDER_COUNT_CHANGE,
+        FILE_MOVED
+    };
+
+    struct None {
+    };
+
+    struct Id {
+        library_id_t id;
+    };
+
+    struct AddedFolders {
+        LibFolder::ListPtr folders;
+    };
+
+    struct AddedKeyword {
+        Keyword::Ptr keyword;
+    };
+
+    struct AddedKeywords {
+        Keyword::ListPtr keywords;
+    };
+
+    struct AddedLabels {
+        Label::ListPtr labels;
+    };
+
+    struct FileMoved {
+        library_id_t file;
+        library_id_t from;
+        library_id_t to;
+    };
+
+    struct QueriedContent {
+        library_id_t container;
+        LibFile::ListPtr files;
+    };
+
+    struct MetadataContent {
+        library_id_t file;
+        LibMetadata::Ptr metadata;
+    };
+
+    typedef metadata_desc_t MetadataChange;
+
+    struct FolderCount {
+        library_id_t folder;
+        int32_t count;
+    };
+
+    struct LabelChange {
+        eng::Label::Ptr label;
+    };
+
+    // specialise this class template to map the notification parameter type
+    // with the notification type.
+    // By default type is None.
+    template<Type t> struct ParamType {
+        typedef None Type;
+    };
+
+    typedef boost::variant<None, Id, AddedFolders,
+                           AddedLabels, AddedKeyword, AddedKeywords,
+                           QueriedContent,
+                           MetadataContent, MetadataChange,
+                           LabelChange,
+                           FileMoved, FolderCount> Param;
+
+    Type type;
+
+    // Instanciate a notification. Will use the ParamType template to enforce the
+    // parameter type.
+    template<LibNotification::Type t>
+    static LibNotification make(typename LibNotification::ParamType<t>::Type&& p)
+        {
+            return LibNotification(t, p);
+        }
+    // Extract the parameter.
+    template<LibNotification::Type t>
+    const typename LibNotification::ParamType<t>::Type& get() const
+        {
+            return boost::get<typename LibNotification::ParamType<t>::Type>(param);
+        }
+private:
+    Param param;
+
+    LibNotification(Type t, Param&& p)
+        : type(t), param(p) {}
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::ADDED_FOLDERS> {
+    typedef AddedFolders Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::ADDED_KEYWORDS> {
+    typedef AddedKeywords Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::ADDED_KEYWORD> {
+    typedef AddedKeyword Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::ADDED_LABELS> {
+    typedef AddedLabels Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::FOLDER_CONTENT_QUERIED> {
+    typedef QueriedContent Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::KEYWORD_CONTENT_QUERIED> {
+    typedef QueriedContent Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::METADATA_QUERIED> {
+    typedef MetadataContent Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::METADATA_CHANGED> {
+    typedef MetadataChange Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::LABEL_CHANGED> {
+    typedef LabelChange Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::LABEL_DELETED> {
+    typedef Id Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::FOLDER_COUNTED> {
+    typedef FolderCount Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::FOLDER_COUNT_CHANGE> {
+    typedef FolderCount Type;
+};
+
+template<>
+struct LibNotification::ParamType<LibNotification::Type::FILE_MOVED> {
+    typedef FileMoved Type;
+};
+
+
+}
diff --git a/src/engine/library/thumbnailcache.cpp b/src/engine/library/thumbnailcache.cpp
index ecff92a..9b1c04b 100644
--- a/src/engine/library/thumbnailcache.cpp
+++ b/src/engine/library/thumbnailcache.cpp
@@ -104,7 +104,7 @@ void ThumbnailCache::execute(const ptr_t & task)
             tn.pixmap = pix;
             n->setData(boost::any(tn));
             DBG_OUT("notify thumbnail for id=%Ld", (long long)tn.id);
-            nc->post(n);
+            nc->post(std::move(n));
         }
     }
 }
diff --git a/src/fwk/toolkit/notification.hpp b/src/fwk/toolkit/notification.hpp
index d6017a8..1b9982f 100644
--- a/src/fwk/toolkit/notification.hpp
+++ b/src/fwk/toolkit/notification.hpp
@@ -25,7 +25,6 @@
 #define __FWK_NOTIFICATION_H__
 
 #include <memory>
-#include <mutex>
 #include <boost/any.hpp>
 
 namespace fwk {
@@ -35,15 +34,12 @@ namespace fwk {
        {
        public:
                typedef std::shared_ptr<Notification> Ptr;
-               typedef std::recursive_mutex mutex_t;
 
                Notification(int _type)
                        : m_type(_type)
                        {}
                ~Notification()
-                       { std::lock_guard<mutex_t> lock(m_mutex); }
-               mutex_t & mutex() const
-                       { return m_mutex; }
+                       {}
                int type() const
                        { return m_type; }
                const boost::any & data() const
@@ -51,7 +47,6 @@ namespace fwk {
                void setData(const boost::any & d)
                        { m_data = d; }
        private:
-               mutable mutex_t    m_mutex;
                int        m_type;
                boost::any m_data;
        };
diff --git a/src/fwk/toolkit/notificationcenter.cpp b/src/fwk/toolkit/notificationcenter.cpp
index 5cbc463..0fc0aeb 100644
--- a/src/fwk/toolkit/notificationcenter.cpp
+++ b/src/fwk/toolkit/notificationcenter.cpp
@@ -60,7 +60,7 @@ void NotificationCenter::unsubscribe(int /*type*/, const subscriber_t & /*s*/)
 //             m_subscribers.remove_if(std::bind(&boost::function_equal, _1, s));
 }
 
-void NotificationCenter::post(const Notification::Ptr & n)
+void NotificationCenter::post(Notification::Ptr&& n)
 {
     /* called out of thread */
     /* MUST be thread safe */
@@ -73,7 +73,6 @@ void NotificationCenter::_dispatch(void)
     /* this is not pop() like in STL. */
     Notification::Ptr notif( p->m_notificationQueue.pop() );
 
-    std::lock_guard<Notification::mutex_t> lock(notif->mutex());
     p->m_subscribers[notif->type()](notif);
 }
 
diff --git a/src/fwk/toolkit/notificationcenter.hpp b/src/fwk/toolkit/notificationcenter.hpp
index be2116d..3983c15 100644
--- a/src/fwk/toolkit/notificationcenter.hpp
+++ b/src/fwk/toolkit/notificationcenter.hpp
@@ -40,7 +40,7 @@ public:
     ~NotificationCenter();
 
     // called from out of thread
-    void post(const Notification::Ptr & n);
+    void post(Notification::Ptr && n);
 
     void subscribe(int type, const subscriber_t & );
     void unsubscribe(int type, const subscriber_t & );
diff --git a/src/niepce/modules/map/mapmodule.cpp b/src/niepce/modules/map/mapmodule.cpp
index bfddc54..8d7d99c 100644
--- a/src/niepce/modules/map/mapmodule.cpp
+++ b/src/niepce/modules/map/mapmodule.cpp
@@ -70,11 +70,9 @@ MapModule::on_lib_notification(const eng::LibNotification &ln)
         return;
     }
     switch(ln.type) {
-    case eng::Library::NotifyType::METADATA_QUERIED:
+    case eng::LibNotification::Type::METADATA_QUERIED:
     {
-        DBG_ASSERT(ln.param.type() == typeid(eng::LibMetadata::Ptr),
-                   "incorrect data type for the notification");
-        auto lm = boost::any_cast<eng::LibMetadata::Ptr>(ln.param);
+        auto lm = ln.get<eng::LibNotification::Type::METADATA_QUERIED>().metadata;
         DBG_OUT("received metadata in MapModule");
 
         if (lm) {
diff --git a/src/niepce/ui/gridviewmodule.cpp b/src/niepce/ui/gridviewmodule.cpp
index 8f3c3d7..df1643a 100644
--- a/src/niepce/ui/gridviewmodule.cpp
+++ b/src/niepce/ui/gridviewmodule.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - ui/gridviewmodule.cpp
  *
- * Copyright (C) 2009-2014 Hubert Figuiere
+ * Copyright (C) 2009-2017 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -55,35 +55,27 @@ void
 GridViewModule::on_lib_notification(const eng::LibNotification &ln)
 {
     switch(ln.type) {
-    case eng::Library::NotifyType::METADATA_QUERIED:
+    case eng::LibNotification::Type::METADATA_QUERIED:
     {
-        DBG_ASSERT(ln.param.type() == typeid(eng::LibMetadata::Ptr),
-                   "incorrect data type for the notification");
-        eng::LibMetadata::Ptr lm
-            = boost::any_cast<eng::LibMetadata::Ptr>(ln.param);
+        auto lm = ln.get<eng::LibNotification::Type::METADATA_QUERIED>();
         DBG_OUT("received metadata");
-        m_metapanecontroller->display(lm->id(), lm);
+        m_metapanecontroller->display(lm.file, lm.metadata);
         break;
     }
-    case eng::Library::NotifyType::METADATA_CHANGED:
+    case eng::LibNotification::Type::METADATA_CHANGED:
     {
         DBG_OUT("metadata changed");
-        DBG_ASSERT(ln.param.type() == typeid(eng::metadata_desc_t),
-                   "incorrect data type for the notification");
-        eng::metadata_desc_t m = boost::any_cast<eng::metadata_desc_t>(ln.param);
+        auto m = ln.get<eng::LibNotification::Type::METADATA_CHANGED>();
         if(m.id == m_metapanecontroller->displayed_file()) {
             // FIXME: actually just update the metadata
           m_shell.getLibraryClient()->requestMetadata(m.id);
         }
         break;
     }
-    case eng::Library::NotifyType::FILE_MOVED:
+    case eng::LibNotification::Type::FILE_MOVED:
     {
-        DBG_ASSERT(ln.param.type() == typeid(std::pair<eng::library_id_t,eng::library_id_t>),
-                   "incorrect data type for the notification");
-        std::pair<eng::library_id_t,eng::library_id_t> 
moved(boost::any_cast<std::pair<eng::library_id_t,eng::library_id_t> >(ln.param));
-
-// check that the file that was moved still match the content
+        auto moved = ln.get<eng::LibNotification::Type::FILE_MOVED>();
+// XXX check that the file that was moved still match the content
 
         break;
     }
diff --git a/src/niepce/ui/imageliststore.cpp b/src/niepce/ui/imageliststore.cpp
index 4fb2b0b..de449a4 100644
--- a/src/niepce/ui/imageliststore.cpp
+++ b/src/niepce/ui/imageliststore.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - ui/imageliststore.cpp
  *
- * Copyright (C) 2008 Hubert Figuiere
+ * Copyright (C) 2008-2017 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -89,11 +89,10 @@ Gtk::TreePath ImageListStore::get_path_from_id(eng::library_id_t id)
 void ImageListStore::on_lib_notification(const eng::LibNotification &ln)
 {
     switch(ln.type) {
-    case eng::Library::NotifyType::FOLDER_CONTENT_QUERIED:
-    case eng::Library::NotifyType::KEYWORD_CONTENT_QUERIED:
+    case eng::LibNotification::Type::FOLDER_CONTENT_QUERIED:
+    case eng::LibNotification::Type::KEYWORD_CONTENT_QUERIED:
     {
-        eng::LibFile::ListPtr l 
-            = boost::any_cast<eng::LibFile::ListPtr>(ln.param);
+        auto l = ln.get<eng::LibNotification::Type::FOLDER_CONTENT_QUERIED>().files;
         DBG_OUT("received folder content file # %lu", l->size());
         // clear the map before the list.
         m_idmap.clear();
@@ -114,9 +113,9 @@ void ImageListStore::on_lib_notification(const eng::LibNotification &ln)
         getLibraryClient()->thumbnailCache().request(l);
         break;
     }
-    case eng::Library::NotifyType::METADATA_CHANGED:
+    case eng::LibNotification::Type::METADATA_CHANGED:
     {
-        eng::metadata_desc_t m = boost::any_cast<eng::metadata_desc_t>(ln.param);
+        auto m = ln.get<eng::LibNotification::Type::METADATA_CHANGED>();
         fwk::PropertyIndex prop = m.meta;
         DBG_OUT("metadata changed %s", eng::_propertyName(prop));
         // only interested in a few props
@@ -132,7 +131,7 @@ void ImageListStore::on_lib_notification(const eng::LibNotification &ln)
         }
         break;
     }
-    case eng::Library::NotifyType::XMP_NEEDS_UPDATE:
+    case eng::LibNotification::Type::XMP_NEEDS_UPDATE:
     {
         fwk::Configuration & cfg = fwk::Application::app()->config();
         int write_xmp = false;
diff --git a/src/niepce/ui/niepcewindow.cpp b/src/niepce/ui/niepcewindow.cpp
index c5f8d65..2325b1b 100644
--- a/src/niepce/ui/niepcewindow.cpp
+++ b/src/niepce/ui/niepcewindow.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - ui/niepcewindow.cpp
  *
- * Copyright (C) 2007-2015 Hubert Figuière
+ * Copyright (C) 2007-2017 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -334,27 +334,25 @@ void NiepceWindow::create_initial_labels()
 void NiepceWindow::on_lib_notification(const eng::LibNotification & ln)
 {
     switch(ln.type) {
-    case eng::Library::NotifyType::NEW_LIBRARY_CREATED:
+    case eng::LibNotification::Type::NEW_LIBRARY_CREATED:
         create_initial_labels();
         break;
-    case eng::Library::NotifyType::ADDED_LABELS:
+    case eng::LibNotification::Type::ADDED_LABELS:
     {
-        eng::Label::ListPtr l 
-            = boost::any_cast<eng::Label::ListPtr>(ln.param);
-        m_libClient->getDataProvider()->addLabels(l);
+        auto l = ln.get<eng::LibNotification::Type::ADDED_LABELS>();
+        m_libClient->getDataProvider()->addLabels(l.labels);
         break;
     }
-    case eng::Library::NotifyType::LABEL_CHANGED:
+    case eng::LibNotification::Type::LABEL_CHANGED:
     {
-        const eng::Label::Ptr & l 
-            = boost::any_cast<const eng::Label::Ptr &>(ln.param);
-        m_libClient->getDataProvider()->updateLabel(l);
+        auto l = ln.get<eng::LibNotification::Type::LABEL_CHANGED>();
+        m_libClient->getDataProvider()->updateLabel(l.label);
         break;
     }
-    case eng::Library::NotifyType::LABEL_DELETED:
+    case eng::LibNotification::Type::LABEL_DELETED:
     {
-        int id = boost::any_cast<int>(ln.param);
-        m_libClient->getDataProvider()->deleteLabel(id);
+        auto id = ln.get<eng::LibNotification::Type::LABEL_DELETED>();
+        m_libClient->getDataProvider()->deleteLabel(id.id);
         break;
     }
     default:
diff --git a/src/niepce/ui/workspacecontroller.cpp b/src/niepce/ui/workspacecontroller.cpp
index 3eb4edf..f3aef8f 100644
--- a/src/niepce/ui/workspacecontroller.cpp
+++ b/src/niepce/ui/workspacecontroller.cpp
@@ -84,10 +84,9 @@ void WorkspaceController::on_lib_notification(const eng::LibNotification &ln)
 {
     DBG_OUT("notification for workspace");
     switch(ln.type) {
-    case eng::Library::NotifyType::ADDED_FOLDERS:
+    case eng::LibNotification::Type::ADDED_FOLDERS:
     {
-        eng::LibFolder::ListPtr l
-            = boost::any_cast<eng::LibFolder::ListPtr>(ln.param);
+        auto l = ln.get<eng::LibNotification::Type::ADDED_FOLDERS>().folders;
         DBG_OUT("received added folders # %lu", l->size());
         for_each(l->cbegin(), l->cend(),
                  [this] (const eng::LibFolder::Ptr& f) {
@@ -95,18 +94,16 @@ void WorkspaceController::on_lib_notification(const eng::LibNotification &ln)
                  });
         break;
     }
-    case eng::Library::NotifyType::ADDED_KEYWORD:
+    case eng::LibNotification::Type::ADDED_KEYWORD:
     {
-        eng::Keyword::Ptr k
-            = boost::any_cast<eng::Keyword::Ptr>(ln.param);
+        auto k = ln.get<eng::LibNotification::Type::ADDED_KEYWORD>().keyword;
         DBG_ASSERT(static_cast<bool>(k), "keyword must not be NULL");
         add_keyword_item(k);
         break;
     }
-    case eng::Library::NotifyType::ADDED_KEYWORDS:
+    case eng::LibNotification::Type::ADDED_KEYWORDS:
     {
-        eng::Keyword::ListPtr l
-            = boost::any_cast<eng::Keyword::ListPtr>(ln.param);
+        auto l = ln.get<eng::LibNotification::Type::ADDED_KEYWORDS>().keywords;
         DBG_ASSERT(static_cast<bool>(l), "keyword list must not be NULL");
         for_each(l->cbegin(), l->cend(),
                  [this] (const eng::Keyword::Ptr& k) {
@@ -114,41 +111,38 @@ void WorkspaceController::on_lib_notification(const eng::LibNotification &ln)
                  });
         break;
     }
-    case eng::Library::NotifyType::FOLDER_COUNTED:
+    case eng::LibNotification::Type::FOLDER_COUNTED:
     {
-        std::pair<eng::library_id_t,int> count(boost::any_cast<std::pair<eng::library_id_t,int> >(ln.param));
-        DBG_OUT("count for folder %Ld is %d", (long long)count.first, count.second);
+        auto count = ln.get<eng::LibNotification::Type::FOLDER_COUNTED>();
+        DBG_OUT("count for folder %Ld is %d", (long long)count.folder, count.count);
         std::map<eng::library_id_t, Gtk::TreeIter>::const_iterator iter
-            = m_folderidmap.find( count.first );
+            = m_folderidmap.find(count.folder);
         if(iter != m_folderidmap.cend()) {
             Gtk::TreeRow row = *(iter->second);
-            row[m_librarycolumns.m_count_n] = count.second;
-            row[m_librarycolumns.m_count] = std::to_string(count.second);
+            row[m_librarycolumns.m_count_n] = count.count;
+            row[m_librarycolumns.m_count] = std::to_string(count.count);
         }
 
         break;
     }
-    case eng::Library::NotifyType::FOLDER_COUNT_CHANGE:
+    case eng::LibNotification::Type::FOLDER_COUNT_CHANGE:
     {
-        std::pair<eng::library_id_t,int> count(boost::any_cast<std::pair<eng::library_id_t,int> >(ln.param));
-        DBG_OUT("count change for folder %Ld is %d", (long long)count.first, count.second);
+        auto count = ln.get<eng::LibNotification::Type::FOLDER_COUNT_CHANGE>();
+        DBG_OUT("count change for folder %Ld is %d", (long long)count.folder, count.count);
         std::map<eng::library_id_t, Gtk::TreeIter>::const_iterator iter
-            = m_folderidmap.find( count.first );
+            = m_folderidmap.find(count.folder);
         if(iter != m_folderidmap.cend()) {
             Gtk::TreeRow row = *(iter->second);
-            int new_count = row[m_librarycolumns.m_count_n] + count.second;
+            int new_count = row[m_librarycolumns.m_count_n] + count.count;
             row[m_librarycolumns.m_count_n] = new_count;
             row[m_librarycolumns.m_count] = std::to_string(new_count);
         }
 
         break;
     }
-    case eng::Library::NotifyType::FILE_MOVED:
+    case eng::LibNotification::Type::FILE_MOVED:
     {
-        DBG_ASSERT(ln.param.type() == typeid(std::pair<eng::library_id_t,eng::library_id_t>),
-                   "incorrect data type for the notification");
-
-        std::pair<eng::library_id_t,eng::library_id_t> 
moved(boost::any_cast<std::pair<eng::library_id_t,eng::library_id_t> >(ln.param));
+        auto moved = ln.get<eng::LibNotification::Type::FILE_MOVED>();
 
         break;
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]