[niepce] Basic addin modules manager, copied from Gnote
- From: Hubert FiguiÃre <hub src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [niepce] Basic addin modules manager, copied from Gnote
- Date: Sat, 12 Nov 2011 06:14:45 +0000 (UTC)
commit cdaefbad43a06fa3548eaf83d110fab750ab6c2c
Author: Hub Figuiere <hub figuiere net>
Date: Fri Oct 28 21:25:00 2011 -0700
Basic addin modules manager, copied from Gnote
configure.ac | 1 +
src/fwk/Makefile.am | 3 +-
src/fwk/base/debug.cpp | 2 +-
src/fwk/base/map.hpp | 73 ++++++++++++++
src/fwk/toolkit/Makefile.am | 2 +
src/fwk/toolkit/application.cpp | 7 +-
src/fwk/toolkit/application.hpp | 10 ++
src/fwk/toolkit/widgets/addinstreemodel.cpp | 80 +++++++++++++++
src/fwk/toolkit/widgets/addinstreemodel.hpp | 75 ++++++++++++++
src/fwk/utils/MODULES_HOWTO | 73 ++++++++++++++
src/fwk/utils/Makefile.am | 8 +-
src/fwk/utils/dynamicmodule.cpp | 90 +++++++++++++++++
src/fwk/utils/dynamicmodule.hpp | 96 ++++++++++++++++++
src/fwk/utils/files.cpp | 18 +++-
src/fwk/utils/files.hpp | 2 +
src/fwk/utils/modulefactory.hpp | 74 ++++++++++++++
src/fwk/utils/modulemanager.cpp | 102 ++++++++++++++++++++
src/fwk/utils/modulemanager.hpp | 61 ++++++++++++
src/niepce/Makefile.am | 1 +
src/niepce/modules/Makefile.am | 2 +-
src/niepce/modules/interfaces/Makefile.am | 14 +++
.../modules/interfaces/ipostimportprocessing.cpp | 9 ++
.../modules/interfaces/ipostimportprocessing.hpp | 25 +++++
src/niepce/ui/niepceapplication.cpp | 13 ++-
24 files changed, 825 insertions(+), 16 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 9d5123c..aa4c50e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -157,6 +157,7 @@ src/niepce/ui/dialogs/Makefile
src/niepce/ui/thumb-view/Makefile
src/niepce/modules/Makefile
src/niepce/modules/darkroom/Makefile
+src/niepce/modules/interfaces/Makefile
src/niepce/Makefile
src/fwk/Makefile
src/fwk/utils/Makefile
diff --git a/src/fwk/Makefile.am b/src/fwk/Makefile.am
index 4dfe978..0cdeacb 100644
--- a/src/fwk/Makefile.am
+++ b/src/fwk/Makefile.am
@@ -25,5 +25,6 @@ libfwk_a_SOURCES = base/color.hpp base/color.cpp \
base/fractions.hpp base/fractions.cpp \
base/moniker.hpp base/moniker.cpp \
base/geometry.hpp base/geometry.cpp \
- base/singleton.hpp
+ base/singleton.hpp \
+ base/map.hpp \
$(NULL)
\ No newline at end of file
diff --git a/src/fwk/base/debug.cpp b/src/fwk/base/debug.cpp
index 761127c..817eb02 100644
--- a/src/fwk/base/debug.cpp
+++ b/src/fwk/base/debug.cpp
@@ -107,7 +107,7 @@ namespace fwk {
const char* func, va_list marker)
{
char buf[128];
- snprintf(buf, 128, "(%d) ", (int)pthread_self());
+ snprintf(buf, 128, "(%ld) ", (long)pthread_self());
fwrite(buf, 1, strlen(buf), stderr);
fwrite(prefix, 1, strlen(prefix), stderr);
diff --git a/src/fwk/base/map.hpp b/src/fwk/base/map.hpp
new file mode 100644
index 0000000..c4f54cf
--- /dev/null
+++ b/src/fwk/base/map.hpp
@@ -0,0 +1,73 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef __FWK_MAP_HPP_
+#define __FWK_MAP_HPP_
+
+#include <list>
+#include <vector>
+#include <map>
+
+namespace fwk {
+
+ /** get all the keys from the map. */
+ template <typename _Map>
+ void map_get_keys(const _Map & m, std::vector<typename _Map::mapped_type> & l)
+ {
+ l.clear();
+ for(typename _Map::const_iterator iter = m.begin();
+ iter != m.end(); ++iter) {
+ l.push_back(iter->first);
+ }
+ }
+
+
+ /** get all the mapped elements from the map. */
+ template <typename _Map>
+ void map_get_values(const _Map & m, std::list<typename _Map::mapped_type> & l)
+ {
+ l.clear();
+ for(typename _Map::const_iterator iter = m.begin();
+ iter != m.end(); ++iter) {
+ l.push_back(iter->second);
+ }
+ }
+
+
+ /** call operator delete on all the data element. */
+ template <typename _Map>
+ void map_delete_all_second(const _Map & m)
+ {
+ for(typename _Map::const_iterator iter = m.begin();
+ iter != m.end(); ++iter) {
+ delete iter->second;
+ }
+ }
+
+}
+
+
+#endif
diff --git a/src/fwk/toolkit/Makefile.am b/src/fwk/toolkit/Makefile.am
index 7c0940a..3de9bc1 100644
--- a/src/fwk/toolkit/Makefile.am
+++ b/src/fwk/toolkit/Makefile.am
@@ -1,6 +1,7 @@
+
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/ext \
@LIBGLIBMM_CFLAGS@ \
@LIBGTKMM_CFLAGS@ \
@@ -25,6 +26,7 @@ libniepceframework_a_SOURCES = configuration.hpp configuration.cpp \
configdatabinder.hpp configdatabinder.cpp \
gdkutils.hpp gdkutils.cpp \
gtkutils.hpp gtkutils.cpp \
+ widgets/addinstreemodel.hpp widgets/addinstreemodel.cpp \
widgets/toolboxitemwidget.hpp widgets/toolboxitemwidget.cpp \
widgets/editablehscale.hpp widgets/editablehscale.cpp \
widgets/dock-item.cpp widgets/dock-item.hpp \
diff --git a/src/fwk/toolkit/application.cpp b/src/fwk/toolkit/application.cpp
index 800b8b3..c7a8334 100644
--- a/src/fwk/toolkit/application.cpp
+++ b/src/fwk/toolkit/application.cpp
@@ -29,6 +29,7 @@
#include "fwk/base/debug.hpp"
#include "fwk/utils/boost.hpp"
+#include "fwk/utils/modulemanager.hpp"
#include "application.hpp"
#include "uicontroller.hpp"
#include "frame.hpp"
@@ -39,8 +40,9 @@ namespace fwk {
Application::Ptr Application::m_application;
Application::Application(const char * name)
- : m_config(Glib::ustring("/apps/") + name),
- m_refUIManager(Gtk::UIManager::create())
+ : m_config(Glib::ustring("/apps/") + name)
+ , m_refUIManager(Gtk::UIManager::create())
+ , m_module_manager(new ModuleManager())
{
register_theme(_("System"), "");
}
@@ -48,6 +50,7 @@ Application::Application(const char * name)
Application::~Application()
{
+ delete m_module_manager;
}
diff --git a/src/fwk/toolkit/application.hpp b/src/fwk/toolkit/application.hpp
index 14d563a..cdd4d67 100644
--- a/src/fwk/toolkit/application.hpp
+++ b/src/fwk/toolkit/application.hpp
@@ -34,6 +34,8 @@
namespace fwk {
+class ModuleManager;
+
class Application
: public Controller
{
@@ -75,6 +77,13 @@ public:
UndoHistory & undo_history()
{ return m_undo; }
UndoTransaction * begin_undo(const std::string & label);
+
+ // Module management
+ /** @return the module manager
+ * It is guaranted to be safe to call from the constructor
+ */
+ ModuleManager * module_manager() const
+ { return m_module_manager; }
protected:
Application(const char *);
static Application::Ptr m_application;
@@ -86,6 +95,7 @@ private:
Glib::RefPtr<Gtk::UIManager> m_refUIManager;
UndoHistory m_undo;
std::vector<ThemeDesc> m_themes;
+ ModuleManager *m_module_manager;
};
}
diff --git a/src/fwk/toolkit/widgets/addinstreemodel.cpp b/src/fwk/toolkit/widgets/addinstreemodel.cpp
new file mode 100644
index 0000000..83eb17d
--- /dev/null
+++ b/src/fwk/toolkit/widgets/addinstreemodel.cpp
@@ -0,0 +1,80 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#include <glibmm/i18n.h>
+
+#include "fwk/toolkit/widgets/addinstreemodel.hpp"
+
+
+
+namespace fwk {
+
+
+ AddinsTreeModel::Ptr AddinsTreeModel::create(Gtk::TreeView * treeview)
+ {
+ AddinsTreeModel::Ptr p(new AddinsTreeModel());
+ if(treeview) {
+ treeview->set_model(p);
+ p->set_columns(treeview);
+ }
+ return p;
+ }
+
+ AddinsTreeModel::AddinsTreeModel()
+ : Gtk::TreeStore()
+ {
+ set_column_types(m_columns);
+ }
+
+ fwk::DynamicModule * AddinsTreeModel::get_module(const Gtk::TreeIter & iter)
+ {
+ fwk::DynamicModule * module = NULL;
+ if(iter) {
+ iter->get_value(2, module);
+ }
+ return module;
+ }
+
+
+ void AddinsTreeModel::set_columns(Gtk::TreeView *treeview)
+ {
+ treeview->append_column(_("Name"), m_columns.name);
+ treeview->append_column(_("Description"), m_columns.description);
+ }
+
+
+ Gtk::TreeIter AddinsTreeModel::append(const fwk::DynamicModule *module)
+ {
+ Gtk::TreeIter iter = Gtk::TreeStore::append();
+ iter->set_value(0, std::string(module->name()));
+ iter->set_value(1, std::string(module->description()));
+ iter->set_value(2, module);
+ return iter;
+ }
+
+
+
+}
diff --git a/src/fwk/toolkit/widgets/addinstreemodel.hpp b/src/fwk/toolkit/widgets/addinstreemodel.hpp
new file mode 100644
index 0000000..8c397bd
--- /dev/null
+++ b/src/fwk/toolkit/widgets/addinstreemodel.hpp
@@ -0,0 +1,75 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+#ifndef __FWK_UTILS_ADDINSTREEMODEL_HPP_
+#define __FWK_UTILS_ADDINSTREEMODEL_HPP_
+
+#include <gtkmm/treestore.h>
+#include <gtkmm/treeview.h>
+
+#include "fwk/utils/dynamicmodule.hpp"
+
+namespace fwk {
+
+class AddinsTreeModel
+ : public Gtk::TreeStore
+{
+public:
+ typedef Glib::RefPtr<AddinsTreeModel> Ptr;
+ static Ptr create(Gtk::TreeView * treeview);
+
+ DynamicModule * get_module(const Gtk::TreeIter &);
+
+ Gtk::TreeIter append(const fwk::DynamicModule *);
+ class AddinsColumns
+ : public Gtk::TreeModelColumnRecord
+ {
+ public:
+ AddinsColumns()
+ {
+ add(name);
+ add(description);
+ add(addin);
+ }
+
+ Gtk::TreeModelColumn<std::string> name;
+ Gtk::TreeModelColumn<std::string> description;
+ Gtk::TreeModelColumn<const DynamicModule *> addin;
+ };
+ AddinsColumns m_columns;
+
+protected:
+ AddinsTreeModel();
+ void set_columns(Gtk::TreeView *v);
+private:
+
+};
+
+}
+
+
+#endif
diff --git a/src/fwk/utils/MODULES_HOWTO b/src/fwk/utils/MODULES_HOWTO
new file mode 100644
index 0000000..61300e5
--- /dev/null
+++ b/src/fwk/utils/MODULES_HOWTO
@@ -0,0 +1,73 @@
+The Module code is inherited from gnote. It is meant
+to provide lean a mean module implementing several interfaces.
+
+Modules declaration:
+
+-Create a class MyModule that inherite from fwk::DynamicModule.
+-Implement the various virtual functions needed for a module
+ (see DynamicModule.hpp)
+-You need to declare the entry point using:
+ DECLARE_MODULE(MyModule);
+
+Module implementation:
+
+The module implementation is a factory to instanciate the
+interfaces implementations.
+
+-In the module contructor you must declare the interfaces
+ implementation using:
+ ADD_INTERFACE(MyInterfaceImplementation)
+ MyInterfaceImplementation is one of the interface you implement.
+ There can be any number for the module. It is the name of the
+ class whose declaration should be accesssible.
+-MyModule::id() returns a unique id, which is a string.
+
+Generic Interface:
+
+A generic interface define an interface for the module functionality.
+This is how the app will call your module.
+-A generic interface is class that inherit from fwk::IInterface and
+sigc::trackable.
+-It should define the following static member:
+ static const char * IFACE_NAME;
+ Its value is a string. It should be unique to all the interfaces
+ and this is how we will know what your module provides.
+
+Interface Implementation
+
+-MyInterfaceImplementation inherit for said generic interface.
+-MyInterfaceImplementation should define and implement a static
+constructor with the following signature and implementation.
+ static MyInterface *MyInterface::create()
+ { return new MyInterface; }
+
+Loading Modules:
+
+-Declare an instance of fwk::ModuleManager.
+-Call add_path() to add directories where to load modules from
+-Call load_modules() to load them all.
+-Call get_modules() to obtain the list of loaded modules.
+
+Querying interfaces:
+
+-On the module ask it if implements an interface with has_interface()
+-Ask for the interface using query_interface() and obtain a IfaceFactoryBase*
+-Intanciate the interface.
+
+Sample code:
+
+ fwk::ModuleManager module_manager;
+ module_manager.add_path("/usr/local/share/myapp/addins");
+ module_manager.load_modules();
+ const fwk::ModuleList & modules = module_manager.get_modules();
+
+ for(fwk::ModuleList::const_iterator iter = modules.begin();
+ iter != modules.end() ++iter) {
+ const DynamicModule * dynamicmodule = *iter;
+ if(dynamicmodule->has_interface("foo::MyInterface")) {
+ IfaceFactoryBase *factory = dynamicmodule->query_interface("foo::MyInterface");
+ MyInterface * iface = factory();
+ // ...
+ }
+ }
+
diff --git a/src/fwk/utils/Makefile.am b/src/fwk/utils/Makefile.am
index 5224513..519c4e5 100644
--- a/src/fwk/utils/Makefile.am
+++ b/src/fwk/utils/Makefile.am
@@ -8,7 +8,7 @@ TESTS = testfiles testxmp \
testpathutils \
teststringutils test_db test_db2 test_db3 test_db4 testufrawmeta
-EXTRA_DIST = test.xmp test2.ufraw
+EXTRA_DIST = test.xmp test2.ufraw MODULES_HOWTO
check_PROGRAMS = testfiles testxmp \
testpathutils \
@@ -85,5 +85,9 @@ libniepceutils_a_SOURCES = \
db/insertstatement.cpp db/insertstatement.hpp \
db/sqlstatement.cpp db/sqlstatement.hpp \
db/sqlite/sqlitecnxdrv.cpp db/sqlite/sqlitecnxdrv.hpp \
- db/sqlite/sqlitecnxmgrdrv.cpp db/sqlite/sqlitecnxmgrdrv.hpp
+ db/sqlite/sqlitecnxmgrdrv.cpp db/sqlite/sqlitecnxmgrdrv.hpp \
+ dynamicmodule.hpp dynamicmodule.cpp \
+ modulefactory.hpp \
+ modulemanager.hpp modulemanager.cpp \
+ $(NULL)
diff --git a/src/fwk/utils/dynamicmodule.cpp b/src/fwk/utils/dynamicmodule.cpp
new file mode 100644
index 0000000..4165767
--- /dev/null
+++ b/src/fwk/utils/dynamicmodule.cpp
@@ -0,0 +1,90 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#include "fwk/base/map.hpp"
+#include "dynamicmodule.hpp"
+#include "modulefactory.hpp"
+
+
+namespace fwk {
+
+ DynamicModule::DynamicModule()
+ : m_enabled(true)
+ {
+ }
+
+
+ DynamicModule::~DynamicModule()
+ {
+ fwk::map_delete_all_second(m_interfaces);
+ }
+
+ const char * DynamicModule::copyright() const
+ {
+ return "";
+ }
+
+
+ void DynamicModule::enabled(bool enable)
+ {
+ m_enabled = enable;
+ }
+
+ IfaceFactoryBase * DynamicModule::query_interface(const char * intf) const
+ {
+ std::map<std::string, IfaceFactoryBase *>::const_iterator iter;
+ iter = m_interfaces.find(intf);
+ if(iter == m_interfaces.end()) {
+ return NULL;
+ }
+
+ return iter->second;
+ }
+
+ bool DynamicModule::has_interface(const char * intf) const
+ {
+ std::map<std::string, IfaceFactoryBase *>::const_iterator iter;
+ iter = m_interfaces.find(intf);
+ return (iter != m_interfaces.end());
+ }
+
+
+ void DynamicModule::add(const char * iface, IfaceFactoryBase* mod)
+ {
+ std::map<std::string, IfaceFactoryBase *>::iterator iter;
+ iter = m_interfaces.find(iface);
+ if(iter == m_interfaces.end()) {
+ m_interfaces.insert(std::make_pair(iface, mod));
+ }
+ else {
+ // replace
+ delete iter->second;
+ iter->second = mod;
+ }
+ }
+
+
+}
diff --git a/src/fwk/utils/dynamicmodule.hpp b/src/fwk/utils/dynamicmodule.hpp
new file mode 100644
index 0000000..9614b63
--- /dev/null
+++ b/src/fwk/utils/dynamicmodule.hpp
@@ -0,0 +1,96 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+
+#ifndef __FWK_DYNAMICMODULE_HPP_
+#define __FWK_DYNAMICMODULE_HPP_
+
+#include <map>
+#include <string>
+
+
+namespace fwk {
+
+class IfaceFactoryBase;
+class DynamicModule;
+
+typedef DynamicModule* (*instanciate_func_t)();
+
+#define DECLARE_MODULE(klass) \
+ extern "C" fwk::DynamicModule* dynamic_module_instanciate() \
+ { return new klass; }
+
+
+#define ADD_INTERFACE_IMPL(klass) \
+ add(klass::IFACE_NAME, \
+ new fwk::IfaceFactory<klass>)
+
+
+class DynamicModule
+{
+public:
+
+ virtual ~DynamicModule();
+
+ virtual const char * id() const = 0;
+ virtual const char * name() const = 0;
+ virtual const char * description() const = 0;
+ virtual const char * authors() const = 0;
+ virtual const char * category() const = 0;
+ virtual const char * version() const = 0;
+ virtual const char * copyright() const;
+ bool enabled() const
+ {
+ return m_enabled;
+ }
+
+ void enabled(bool enable=true);
+
+ /** Query an "interface"
+ * may return NULL
+ */
+ IfaceFactoryBase * query_interface(const char *) const;
+ /** Check if the module provide and interface */
+ bool has_interface(const char *) const;
+
+ void load();
+
+protected:
+ DynamicModule();
+
+ /** */
+ void add(const char * iface, IfaceFactoryBase*);
+
+private:
+ bool m_enabled;
+ std::map<std::string, IfaceFactoryBase *> m_interfaces;
+};
+
+
+
+}
+
+#endif
diff --git a/src/fwk/utils/files.cpp b/src/fwk/utils/files.cpp
index 3c2948f..4cc9821 100644
--- a/src/fwk/utils/files.cpp
+++ b/src/fwk/utils/files.cpp
@@ -34,14 +34,20 @@ namespace fwk {
}
+ bool filter_ext(const Glib::RefPtr<Gio::FileInfo> & file, const std::string & ext)
+ {
+ std::string file_ext = fwk::path_extension(file->get_name());
+ boost::to_lower(file_ext);
+ if(file_ext == ext) {
+ return false;
+ }
+ return true;
+ }
+
bool filter_xmp_out(const Glib::RefPtr<Gio::FileInfo> & file)
{
- std::string ext = fwk::path_extension(file->get_name());
- boost::to_lower(ext);
- if(ext == ".xmp") {
- return false;
- }
- return true;
+ static const std::string ext(".xmp");
+ return filter_ext(file, ext);
}
diff --git a/src/fwk/utils/files.hpp b/src/fwk/utils/files.hpp
index c9a31ec..0192828 100644
--- a/src/fwk/utils/files.hpp
+++ b/src/fwk/utils/files.hpp
@@ -34,6 +34,8 @@
namespace fwk {
bool filter_none(const Glib::RefPtr<Gio::FileInfo> & file);
+ bool filter_ext(const Glib::RefPtr<Gio::FileInfo> & file,
+ const std::string & ext);
bool filter_xmp_out(const Glib::RefPtr<Gio::FileInfo> & file);
class FileList
diff --git a/src/fwk/utils/modulefactory.hpp b/src/fwk/utils/modulefactory.hpp
new file mode 100644
index 0000000..4308a9b
--- /dev/null
+++ b/src/fwk/utils/modulefactory.hpp
@@ -0,0 +1,74 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef __FWK_MODULE_FACTORY_HPP__
+#define __FWK_MODULE_FACTORY_HPP__
+
+
+namespace fwk {
+
+class IInterface
+{
+public:
+ virtual ~IInterface()
+ {
+ }
+protected:
+ IInterface()
+ {
+ }
+};
+
+
+class IfaceFactoryBase
+{
+public:
+ virtual ~IfaceFactoryBase()
+ {}
+
+ /** instanciate. The returned object pointer is owned by the caller.
+ * it MAY return NULL
+ */
+ virtual IInterface *operator()() = 0;
+};
+
+
+template <typename _Interface>
+class IfaceFactory
+ : public IfaceFactoryBase
+{
+public:
+ virtual IInterface *operator()()
+ {
+ return _Interface::create();
+ }
+};
+
+}
+
+
+#endif
+
diff --git a/src/fwk/utils/modulemanager.cpp b/src/fwk/utils/modulemanager.cpp
new file mode 100644
index 0000000..5f3276b
--- /dev/null
+++ b/src/fwk/utils/modulemanager.cpp
@@ -0,0 +1,102 @@
+/*
+ * niepce
+ * copied from
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#include <dlfcn.h>
+
+#include <boost/bind.hpp>
+
+#include <gmodule.h>
+#include <glibmm/module.h>
+
+#include "fwk/utils/files.hpp"
+#include "fwk/utils/pathutils.hpp"
+#include "fwk/base/debug.hpp"
+#include "fwk/base/map.hpp"
+#include "dynamicmodule.hpp"
+#include "modulemanager.hpp"
+
+namespace fwk {
+
+
+ ModuleManager::~ModuleManager()
+ {
+ for(ModuleList::const_iterator mod_iter = m_modules.begin();
+ mod_iter != m_modules.end(); ++mod_iter) {
+ delete *mod_iter;
+ }
+ }
+
+
+ void ModuleManager::add_path(const std::string & dir)
+ {
+ m_dirs.insert(dir);
+ DBG_OUT("add path %s", dir.c_str());
+ }
+
+
+ void ModuleManager::load_modules()
+ {
+ std::string ext = std::string(".") + G_MODULE_SUFFIX;
+
+ for(std::set<std::string>::const_iterator iter = m_dirs.begin();
+ iter != m_dirs.end(); ++iter) {
+
+ fwk::FileList::Ptr l;
+ l = FileList::getFilesFromDirectory(*iter, boost::bind(&fwk::filter_ext, _1, ext));
+
+ for(FileList::const_iterator mod_iter = l->begin();
+ mod_iter != l->end(); ++mod_iter) {
+
+ Glib::Module module(*iter + "/" + path_basename(*mod_iter),
+ Glib::MODULE_BIND_LOCAL);
+ DBG_OUT("load module %s", path_basename(*mod_iter).c_str());
+
+ if(!module) {
+ DBG_OUT("error loading %s", Glib::Module::get_last_error().c_str());
+ continue;
+ }
+ void * func = NULL;
+ bool found = module.get_symbol("dynamic_module_instanciate", func);
+
+ if(!found) {
+ DBG_OUT("error getting symbol %s", Glib::Module::get_last_error().c_str());
+ continue;
+ }
+ instanciate_func_t real_func = (instanciate_func_t)func;
+ DynamicModule * dmod = (*real_func)();
+
+ if(dmod) {
+ m_modules.push_back(dmod);
+ module.make_resident();
+ }
+ }
+
+ }
+ }
+
+}
diff --git a/src/fwk/utils/modulemanager.hpp b/src/fwk/utils/modulemanager.hpp
new file mode 100644
index 0000000..3a2d2ed
--- /dev/null
+++ b/src/fwk/utils/modulemanager.hpp
@@ -0,0 +1,61 @@
+/*
+ * gnote
+ *
+ * Copyright (C) 2009 Hubert Figuiere
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+
+#ifndef __FWK_MODULEMANAGER_HPP_
+#define __FWK_MODULEMANAGER_HPP_
+
+#include <vector>
+#include <set>
+#include <string>
+
+namespace fwk {
+
+class DynamicModule;
+
+typedef std::vector<DynamicModule *> ModuleList;
+
+class ModuleManager
+{
+public:
+ ~ModuleManager();
+
+ /** add path to list the modules */
+ void add_path(const std::string & dir);
+ void load_modules();
+
+ const ModuleList & get_modules() const
+ { return m_modules; }
+private:
+ std::set<std::string> m_dirs;
+
+ ModuleList m_modules;
+};
+
+
+}
+
+#endif
+
diff --git a/src/niepce/Makefile.am b/src/niepce/Makefile.am
index ff3932a..3740b59 100644
--- a/src/niepce/Makefile.am
+++ b/src/niepce/Makefile.am
@@ -19,6 +19,7 @@ niepce_LDADD = \
$(top_builddir)/src/engine/library/libniepcelibrary.a \
$(top_builddir)/src/engine/db/libniepcedb.a \
$(top_builddir)/src/niepce/modules/darkroom/libmoduledarkroom.a \
+ $(top_builddir)/src/niepce/modules/interfaces/libinterfaces.a \
$(top_builddir)/src/fwk/toolkit/libniepceframework.a \
$(top_builddir)/src/fwk/utils/libniepceutils.a \
$(top_builddir)/src/fwk/libfwk.a \
diff --git a/src/niepce/modules/Makefile.am b/src/niepce/modules/Makefile.am
index c9cba6c..ef95e63 100644
--- a/src/niepce/modules/Makefile.am
+++ b/src/niepce/modules/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = darkroom
\ No newline at end of file
+SUBDIRS = darkroom interfaces
\ No newline at end of file
diff --git a/src/niepce/modules/interfaces/Makefile.am b/src/niepce/modules/interfaces/Makefile.am
new file mode 100644
index 0000000..e9bdfae
--- /dev/null
+++ b/src/niepce/modules/interfaces/Makefile.am
@@ -0,0 +1,14 @@
+
+
+INCLUDES = -I$(top_srcdir)/src/ \
+ @LIBGLIBMM_CFLAGS@ \
+ @LIBGTKMM_CFLAGS@
+
+
+noinst_HEADERS = ipostimportprocessing.hpp \
+ $(NULL)
+
+noinst_LIBRARIES = libinterfaces.a
+
+libinterfaces_a_SOURCES = ipostimportprocessing.cpp \
+ $(NULL)
\ No newline at end of file
diff --git a/src/niepce/modules/interfaces/ipostimportprocessing.cpp b/src/niepce/modules/interfaces/ipostimportprocessing.cpp
new file mode 100644
index 0000000..0dccd09
--- /dev/null
+++ b/src/niepce/modules/interfaces/ipostimportprocessing.cpp
@@ -0,0 +1,9 @@
+
+
+#include "ipostimportprocessing.hpp"
+
+namespace niepce {
+
+ const char * IPostImportProcessing::IFACE_NAME = "niepce::PostImportPorcessing";
+
+}
diff --git a/src/niepce/modules/interfaces/ipostimportprocessing.hpp b/src/niepce/modules/interfaces/ipostimportprocessing.hpp
new file mode 100644
index 0000000..58625f3
--- /dev/null
+++ b/src/niepce/modules/interfaces/ipostimportprocessing.hpp
@@ -0,0 +1,25 @@
+
+
+#ifndef __MODULES_INTF_POSTIMPORTPROCESSING_HPP_
+#define __MODULES_INTF_POSTIMPORTPROCESSING_HPP_
+
+#include <sigc++/trackable.h>
+
+#include "engine/db/libfile.hpp"
+#include "fwk/utils/modulefactory.hpp"
+
+namespace niepce {
+
+class IPostImportProcessing
+ : public fwk::IInterface
+ , public sigc::trackable
+{
+public:
+ static const char * IFACE_NAME;
+
+ virtual void post_process_image(const eng::LibFile::Ptr & file) = 0;
+};
+
+}
+
+#endif
diff --git a/src/niepce/ui/niepceapplication.cpp b/src/niepce/ui/niepceapplication.cpp
index 6fb0051..6859967 100644
--- a/src/niepce/ui/niepceapplication.cpp
+++ b/src/niepce/ui/niepceapplication.cpp
@@ -22,6 +22,7 @@
#include <glibmm/i18n.h>
#include <gtkmm/aboutdialog.h>
+#include "fwk/utils/modulemanager.hpp"
#include "niepce/stock.hpp"
#include "niepceapplication.hpp"
#include "niepcewindow.hpp"
@@ -35,10 +36,15 @@ NiepceApplication::NiepceApplication()
: Application(PACKAGE)
{
niepce::Stock::registerStockItems();
- const char * themedir = DATADIR"/niepce/themes/";
+ const char * themedir = DATADIR"/"PACKAGE"/themes/";
register_theme(_("Niepce Dark"),
std::string(themedir) + "niepce-dark.gtkrc");
+
+ fwk::ModuleManager * modmgr = module_manager();
+ DBG_ASSERT(modmgr != NULL, "module manager is NULL.");
+ // path for modules is $PREFIX/share/niepce/modules/$VERSION
+ modmgr->add_path(DATADIR"/"PACKAGE"/modules/"VERSION);
}
Application::Ptr NiepceApplication::create()
@@ -61,8 +67,9 @@ void NiepceApplication::on_about()
// dlg.set_name("Niepce");
dlg.set_program_name("Niepce Digital");
dlg.set_version(VERSION);
- dlg.set_comments(Glib::ustring(_("A digital photo application.\n\nBuild options: "
- NIEPCE_BUILD_CONFIG)));
+ dlg.set_comments(Glib::ustring(_("A digital photo application.\n\n"
+ "Build options: ")) +
+ NIEPCE_BUILD_CONFIG);
dlg.run();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]