[gnote] Implement disabling/enabling of addins



commit 9f2a2dd5b94c36db2e1594381973013005365c4e
Author: Debarshi Ray <debarshir src gnome org>
Date:   Thu Dec 31 18:39:16 2009 +0200

    Implement disabling/enabling of addins
    
    Addins can now be disabled and enabled from the preferences dialog,
    but their states are not persistently stored.
    
    Fixes: https://bugzilla.gnome.org/597307

 src/addinmanager.cpp          |  106 ++++++++++++++++++++++++++++++++++++++--
 src/addinmanager.hpp          |    9 +++-
 src/preferencesdialog.cpp     |   41 ++++++++++++++--
 src/preferencesdialog.hpp     |    4 +-
 src/sharp/addinstreemodel.cpp |    4 +-
 src/sharp/addinstreemodel.hpp |    2 +-
 src/sharp/dynamicmodule.cpp   |    5 ++
 src/sharp/dynamicmodule.hpp   |    3 +
 8 files changed, 159 insertions(+), 15 deletions(-)
---
diff --git a/src/addinmanager.cpp b/src/addinmanager.cpp
index 1ba8795..fc2039d 100644
--- a/src/addinmanager.cpp
+++ b/src/addinmanager.cpp
@@ -1,6 +1,7 @@
 /*
  * gnote
  *
+ * Copyright (C) 2009 Debarshi Ray
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -97,8 +98,7 @@ namespace gnote {
     sharp::map_delete_all_second(m_app_addins);
     for(NoteAddinMap::const_iterator iter = m_note_addins.begin();
         iter != m_note_addins.end(); ++iter) {
-      std::for_each(iter->second.begin(), iter->second.end(), 
-                    boost::bind(&boost::checked_delete<NoteAddin>, _1));
+      sharp::map_delete_all_second(iter->second);
     }
     sharp::map_delete_all_second(m_addin_prefs);
     sharp::map_delete_all_second(m_import_addins);
@@ -108,6 +108,83 @@ namespace gnote {
     }
   }
 
+  void AddinManager::add_note_addin_info(
+                       const sharp::DynamicModule * dmod)
+  {
+    const char * const id = dmod->id();
+
+    {
+      const IdInfoMap::const_iterator iter
+                                        = m_note_addin_infos.find(id);
+      if (m_note_addin_infos.end() != iter) {
+        ERR_OUT("NoteAddin info %s already present", id);
+        return;
+      }
+    }
+
+    sharp::IfaceFactoryBase * const f = dmod->query_interface(
+                                          NoteAddin::IFACE_NAME);
+    if(!f) {
+      ERR_OUT("does not implement %s", NoteAddin::IFACE_NAME);
+      return;
+    }
+
+    m_note_addin_infos.insert(std::make_pair(std::string(id), f));
+
+    {
+      for(NoteAddinMap::iterator iter = m_note_addins.begin();
+          iter != m_note_addins.end(); ++iter) {
+        IdAddinMap & id_addin_map = iter->second;
+        IdAddinMap::const_iterator it = id_addin_map.find(id);
+        if (id_addin_map.end() != it) {
+          ERR_OUT("NoteAddin %s already present", id);
+          continue;
+        }
+
+        const Note::Ptr & note = iter->first;
+        NoteAddin * const addin = dynamic_cast<NoteAddin *>((*f)());
+        if (addin) {
+         addin->initialize(note);
+         id_addin_map.insert(std::make_pair(id, addin));
+        }
+      }
+    }
+  }
+
+  void AddinManager::erase_note_addin_info(
+                       const sharp::DynamicModule * dmod)
+  {
+    const char * const id = dmod->id();
+
+    {
+      const IdInfoMap::iterator iter = m_note_addin_infos.find(id);
+      if (m_note_addin_infos.end() == iter) {
+        ERR_OUT("NoteAddin info %s absent", id);
+        return;
+      }
+
+      m_note_addin_infos.erase(iter);
+    }
+
+    {
+      for(NoteAddinMap::iterator iter = m_note_addins.begin();
+          iter != m_note_addins.end(); ++iter) {
+        IdAddinMap & id_addin_map = iter->second;
+        IdAddinMap::iterator it = id_addin_map.find(id);
+        if (id_addin_map.end() == it) {
+          ERR_OUT("NoteAddin %s absent", id);
+          continue;
+        }
+
+        NoteAddin * const addin = it->second;
+        if (addin) {
+          addin->dispose(true);
+          id_addin_map.erase(it);
+        }
+      }
+    }
+  }
+
   void AddinManager::initialize_sharp_addins()
   {
 
@@ -148,7 +225,7 @@ namespace gnote {
 
       sharp::IfaceFactoryBase * f = dmod->query_interface(NoteAddin::IFACE_NAME);
       if(f) {
-        m_note_addin_infos.insert(std::make_pair(typeid(*f).name(), f));
+        m_note_addin_infos.insert(std::make_pair(dmod->id(), f));
       }
 
       f = dmod->query_interface(AddinPreferenceFactoryBase::IFACE_NAME);
@@ -177,10 +254,10 @@ namespace gnote {
       ERR_OUT("trying to load addins when they are already loaded");
       return;
     }
-    std::list<NoteAddin *> loaded_addins;
+    IdAddinMap loaded_addins;
     m_note_addins[note] = loaded_addins;
 
-    std::list<NoteAddin *> & loaded(m_note_addins[note]); // avoid copying the whole list
+    IdAddinMap & loaded(m_note_addins[note]); // avoid copying the whole map
     for(IdInfoMap::const_iterator iter = m_note_addin_infos.begin();
         iter != m_note_addin_infos.end(); ++iter) {
 
@@ -189,7 +266,7 @@ namespace gnote {
       NoteAddin * addin = dynamic_cast<NoteAddin *>(iface);
       if(addin) {
         addin->initialize(note);
-        loaded.push_back(addin);
+        loaded.insert(std::make_pair(addin_info.first, addin));
       }
       else {
         DBG_OUT("wrong type for the interface: %s", typeid(*iface).name());
@@ -198,6 +275,23 @@ namespace gnote {
     }
   }
 
+  ApplicationAddin * AddinManager::get_application_addin(
+                                     const std::string & id) const
+  {
+    const IdImportAddinMap::const_iterator import_iter
+      = m_import_addins.find(id);
+
+    if (m_import_addins.end() != import_iter)
+      return import_iter->second;
+
+    const AppAddinMap::const_iterator app_iter
+      = m_app_addins.find(id);
+
+    if (m_app_addins.end() != app_iter)
+      return app_iter->second;
+
+    return 0;
+  }
 
   void AddinManager::get_application_addins(std::list<ApplicationAddin*> & l) const
   {
diff --git a/src/addinmanager.hpp b/src/addinmanager.hpp
index 991938e..e1a5149 100644
--- a/src/addinmanager.hpp
+++ b/src/addinmanager.hpp
@@ -1,6 +1,7 @@
 /*
  * gnote
  *
+ * Copyright (C) 2009 Debarshi Ray
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -46,12 +47,17 @@ public:
   AddinManager(const std::string & conf_dir);
   ~AddinManager();
 
+  void add_note_addin_info(const sharp::DynamicModule * dmod);
+  void erase_note_addin_info(const sharp::DynamicModule * dmod);
+
   std::string & get_prefs_dir()
     {
       return m_addins_prefs_dir;
     }
 
   void load_addins_for_note(const Note::Ptr &);
+  ApplicationAddin * get_application_addin(const std::string & id)
+                                           const;
   void get_application_addins(std::list<ApplicationAddin*> &) const;
   void get_preference_tab_addins(std::list<PreferenceTabAddin *> &) const;
   void get_import_addins(std::list<ImportAddin*> &) const;
@@ -76,7 +82,8 @@ private:
   /// Key = TypeExtensionNode.Id
   typedef std::map<std::string, ApplicationAddin*> AppAddinMap;
   AppAddinMap                               m_app_addins;
-  typedef std::map<Note::Ptr, std::list<NoteAddin*> > NoteAddinMap;
+  typedef std::map<std::string, NoteAddin *> IdAddinMap;
+  typedef std::map<Note::Ptr, IdAddinMap> NoteAddinMap;
   NoteAddinMap                              m_note_addins;
   /// Key = TypeExtensionNode.Id
   /// the iface factory is not owned by the manager.
diff --git a/src/preferencesdialog.cpp b/src/preferencesdialog.cpp
index 754fb88..4079516 100644
--- a/src/preferencesdialog.cpp
+++ b/src/preferencesdialog.cpp
@@ -1,6 +1,7 @@
 /*
  * gnote
  *
+ * Copyright (C) 2009 Debarshi Ray
  * Copyright (C) 2009 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
@@ -158,6 +159,36 @@ namespace gnote {
 
   }
 
+  void PreferencesDialog::enable_addin(bool enable)
+  {
+    sharp::DynamicModule * const module = get_selected_addin();
+    if (!module)
+      return;
+
+    if (module->has_interface(NoteAddin::IFACE_NAME)) {
+      if (enable)
+        m_addin_manager.add_note_addin_info(module);
+      else
+        m_addin_manager.erase_note_addin_info(module);
+    }
+    else {
+      const char * const id = module->id();
+
+      ApplicationAddin * const addin
+        = m_addin_manager.get_application_addin(id);
+      if (!addin) {
+        ERR_OUT("ApplicationAddin %s absent", id);
+        return;
+      }
+
+      if (enable)
+        addin->initialize();
+      else
+        addin->shutdown();
+    }
+
+    module->enabled(enable);
+  }
   
   
   // Page 1
@@ -604,12 +635,12 @@ namespace gnote {
   }
 
 
-  const sharp::DynamicModule * PreferencesDialog::get_selected_addin()
+  sharp::DynamicModule * PreferencesDialog::get_selected_addin()
   {
     /// TODO really set
     Glib::RefPtr<Gtk::TreeSelection> select = m_addin_tree->get_selection();
     Gtk::TreeIter iter = select->get_selected();
-    const sharp::DynamicModule * module = NULL;
+    sharp::DynamicModule * module = NULL;
     if(iter) {
       module = m_addin_tree_model->get_module(iter);
     }
@@ -659,12 +690,14 @@ namespace gnote {
 
   void PreferencesDialog::on_enable_addin_button()
   {
-//    enable_addin(true);
+    enable_addin(true);
+    update_addin_buttons();
   }
 
   void PreferencesDialog::on_disable_addin_button()
   {
-//    enable_addin(false);
+    enable_addin(false);
+    update_addin_buttons();
   }
 
 
diff --git a/src/preferencesdialog.hpp b/src/preferencesdialog.hpp
index 34e33e8..b13a7a4 100644
--- a/src/preferencesdialog.hpp
+++ b/src/preferencesdialog.hpp
@@ -56,6 +56,8 @@ private:
   Gtk::Label *make_label (const std::string & label_text/*, params object[] args*/);
   Gtk::CheckButton *make_check_button (const std::string & label_text);
 
+  void enable_addin(bool enable);
+
   void open_template_button_clicked();
   void on_font_button_clicked();
   void update_font_button(const std::string & font_desc);
@@ -64,7 +66,7 @@ private:
   void on_reset_sync_addin_button();
   void on_save_sync_addin_button();
 
-  const sharp::DynamicModule * get_selected_addin();
+  sharp::DynamicModule * get_selected_addin();
   void on_addin_tree_selection_changed();
   void update_addin_buttons();
   void load_addins();
diff --git a/src/sharp/addinstreemodel.cpp b/src/sharp/addinstreemodel.cpp
index c69c014..3d6c0bc 100644
--- a/src/sharp/addinstreemodel.cpp
+++ b/src/sharp/addinstreemodel.cpp
@@ -49,9 +49,9 @@ namespace sharp {
     set_column_types(m_columns);
   }
 
-  const sharp::DynamicModule * AddinsTreeModel::get_module(const Gtk::TreeIter & iter)
+  sharp::DynamicModule * AddinsTreeModel::get_module(const Gtk::TreeIter & iter)
   {
-    const sharp::DynamicModule * module = NULL;
+    sharp::DynamicModule * module = NULL;
     if(iter) {
       iter->get_value(2, module);
     }
diff --git a/src/sharp/addinstreemodel.hpp b/src/sharp/addinstreemodel.hpp
index 03a0a6c..625d266 100644
--- a/src/sharp/addinstreemodel.hpp
+++ b/src/sharp/addinstreemodel.hpp
@@ -42,7 +42,7 @@ public:
   typedef Glib::RefPtr<AddinsTreeModel> Ptr;
   static Ptr create(Gtk::TreeView * treeview);
 
-  const sharp::DynamicModule * get_module(const Gtk::TreeIter &);
+  sharp::DynamicModule * get_module(const Gtk::TreeIter &);
 
   Gtk::TreeIter append(const sharp::DynamicModule *);
   class AddinsColumns
diff --git a/src/sharp/dynamicmodule.cpp b/src/sharp/dynamicmodule.cpp
index d44f921..d916f3a 100644
--- a/src/sharp/dynamicmodule.cpp
+++ b/src/sharp/dynamicmodule.cpp
@@ -48,6 +48,11 @@ namespace sharp {
   }
 
   
+  void DynamicModule::enabled(bool enable)
+  {
+    m_enabled = enable;
+  }
+
   IfaceFactoryBase * DynamicModule::query_interface(const char * intf) const
   {
     std::map<std::string, IfaceFactoryBase *>::const_iterator iter;
diff --git a/src/sharp/dynamicmodule.hpp b/src/sharp/dynamicmodule.hpp
index c585a61..8448332 100644
--- a/src/sharp/dynamicmodule.hpp
+++ b/src/sharp/dynamicmodule.hpp
@@ -66,6 +66,9 @@ public:
     {
       return m_enabled;
     }
+
+  void enabled(bool enable=true);
+
   /** Query an "interface" 
    * may return NULL
    */



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