[niepce] Persist the expanded states of the workspace treeview.



commit b69aa6bc00755c96a5337ef259f2b90c3e1bb127
Author: Hubert Figuière <hub figuiere net>
Date:   Sun Jun 23 17:06:13 2013 -0400

    Persist the expanded states of the workspace treeview.
    
    Add a librarylocal configuration.

 src/fwk/toolkit/configuration.cpp     |    3 +-
 src/fwk/toolkit/configuration.hpp     |    4 +
 src/niepce/ui/niepcewindow.cpp        |   11 ++-
 src/niepce/ui/niepcewindow.hpp        |    5 +-
 src/niepce/ui/workspacecontroller.cpp |  135 +++++++++++++++++++++++++++------
 src/niepce/ui/workspacecontroller.hpp |   13 +++-
 6 files changed, 139 insertions(+), 32 deletions(-)
---
diff --git a/src/fwk/toolkit/configuration.cpp b/src/fwk/toolkit/configuration.cpp
index 2da9471..4a0925f 100644
--- a/src/fwk/toolkit/configuration.cpp
+++ b/src/fwk/toolkit/configuration.cpp
@@ -40,8 +40,7 @@ namespace fwk {
 Glib::ustring Configuration::make_config_path(const Glib::ustring & file)
 {
     Glib::ustring filename = Glib::build_filename(Glib::get_user_config_dir(),
-                                      file);
-    filename = Glib::build_filename(filename, "config");
+                                                  file, "config");
     fwk::ensure_path_for_file(filename);
     return filename;
 }
diff --git a/src/fwk/toolkit/configuration.hpp b/src/fwk/toolkit/configuration.hpp
index 69f5b5a..df0efcc 100644
--- a/src/fwk/toolkit/configuration.hpp
+++ b/src/fwk/toolkit/configuration.hpp
@@ -21,6 +21,8 @@
 #ifndef _FRAMEWORK_CONFIGURATION_H_
 #define _FRAMEWORK_CONFIGURATION_H_
 
+#include <memory>
+
 #include <glibmm/ustring.h>
 #include <glibmm/keyfile.h>
 
@@ -29,6 +31,8 @@ namespace fwk {
 class Configuration
 {
 public:
+    typedef std::shared_ptr<Configuration> Ptr;
+
     Configuration(const Glib::ustring & file);
     ~Configuration();
 
diff --git a/src/niepce/ui/niepcewindow.cpp b/src/niepce/ui/niepcewindow.cpp
index 948930d..7c9415d 100644
--- a/src/niepce/ui/niepcewindow.cpp
+++ b/src/niepce/ui/niepcewindow.cpp
@@ -20,6 +20,7 @@
 #include <string>
 
 #include <glibmm/i18n.h>
+#include <glibmm/miscutils.h>
 #include <gtkmm/window.h>
 #include <gtkmm/action.h>
 #include <gtkmm/box.h>
@@ -156,8 +157,7 @@ NiepceWindow::buildWidget(const Glib::RefPtr<Gtk::UIManager> & manager)
     m_notifcenter.reset(new niepce::NotificationCenter());
 
     Glib::ustring name("camera");
-    set_icon_from_theme(name);         
-
+    set_icon_from_theme(name);
 
     m_notifcenter->signal_lib_notification.connect(
         sigc::mem_fun(*this, &NiepceWindow::on_lib_notification));
@@ -442,13 +442,18 @@ std::string NiepceWindow::prompt_open_library()
 
 bool NiepceWindow::open_library(const std::string & libMoniker)
 {
-    m_libClient = LibraryClient::Ptr(new LibraryClient(fwk::Moniker(libMoniker),
+    fwk::Moniker mon = fwk::Moniker(libMoniker);
+    m_libClient = LibraryClient::Ptr(new LibraryClient(mon,
                                                        m_notifcenter));
     if(!m_libClient->ok()) {
         m_libClient = nullptr;
         return false;
     }
     set_title(libMoniker);
+    m_library_cfg
+        = fwk::Configuration::Ptr(
+            new fwk::Configuration(
+                Glib::build_filename(mon.path(), "config.ini")));
     m_libClient->getAllLabels();
     if(!m_moduleshell) {
         _createModuleShell();
diff --git a/src/niepce/ui/niepcewindow.hpp b/src/niepce/ui/niepcewindow.hpp
index 247a72f..d77150e 100644
--- a/src/niepce/ui/niepcewindow.hpp
+++ b/src/niepce/ui/niepcewindow.hpp
@@ -50,8 +50,10 @@ public:
 
     virtual void set_title(const std::string & title);
 
-    libraryclient::LibraryClient::Ptr getLibraryClient()
+    libraryclient::LibraryClient::Ptr getLibraryClient() const
         { return m_libClient; }
+    fwk::Configuration::Ptr getLibraryConfig() const
+        { return m_library_cfg; }
 
 protected:
     virtual Gtk::Widget * buildWidget(const Glib::RefPtr<Gtk::UIManager> & manager);
@@ -92,6 +94,7 @@ private:
     Gtk::Statusbar                 m_statusBar;
     Glib::RefPtr<Gtk::ActionGroup> m_refActionGroup;
     libraryclient::LibraryClient::Ptr m_libClient;
+    fwk::Configuration::Ptr        m_library_cfg;
 };
 
 }
diff --git a/src/niepce/ui/workspacecontroller.cpp b/src/niepce/ui/workspacecontroller.cpp
index cd99210..53ab23c 100644
--- a/src/niepce/ui/workspacecontroller.cpp
+++ b/src/niepce/ui/workspacecontroller.cpp
@@ -54,13 +54,14 @@ WorkspaceController::WorkspaceController()
         { ICON_KEYWORD, "application-certificate" },
         { 0, NULL }
     };
-    
+
     Glib::RefPtr< Gtk::IconTheme > icon_theme(Application::app()->getIconTheme());
     int i = 0;
     while(icons[i].icon_name) {
         try {
             m_icons[icons[i].icon_id] = icon_theme->load_icon(
-            Glib::ustring(icons[i].icon_name), 16, Gtk::ICON_LOOKUP_USE_BUILTIN);
+                Glib::ustring(icons[i].icon_name), 16,
+                Gtk::ICON_LOOKUP_USE_BUILTIN);
         }
         catch(const Gtk::IconThemeError & e)
         {
@@ -70,11 +71,15 @@ WorkspaceController::WorkspaceController()
     }
 }
 
-libraryclient::LibraryClient::Ptr WorkspaceController::getLibraryClient()
+libraryclient::LibraryClient::Ptr WorkspaceController::getLibraryClient() const
 {
-    return     std::dynamic_pointer_cast<NiepceWindow>(m_parent.lock())->getLibraryClient();
+    return std::dynamic_pointer_cast<NiepceWindow>(m_parent.lock())->getLibraryClient();
 }
 
+fwk::Configuration::Ptr WorkspaceController::getLibraryConfig() const
+{
+    return std::dynamic_pointer_cast<NiepceWindow>(m_parent.lock())->getLibraryConfig();
+}
 
 void WorkspaceController::on_lib_notification(const eng::LibNotification &ln)
 {
@@ -163,28 +168,67 @@ void WorkspaceController::on_count_notification(int)
 void WorkspaceController::on_libtree_selection()
 {
     Glib::RefPtr<Gtk::TreeSelection> selection = m_librarytree.get_selection();
-    Gtk::TreeModel::iterator selected = selection->get_selected();
-    if((*selected)[m_librarycolumns.m_type] == FOLDER_ITEM)
-    {
-        eng::library_id_t id = (*selected)[m_librarycolumns.m_id];
+    auto selected = selection->get_selected();
+    int type = (*selected)[m_librarycolumns.m_type];
+    eng::library_id_t id = (*selected)[m_librarycolumns.m_id];
+
+    switch(type) {
+
+    case FOLDER_ITEM:
         getLibraryClient()->queryFolderContent(id);
+        break;
+
+    case KEYWORD_ITEM:
+        getLibraryClient()->queryKeywordContent(id);
+        break;
+
+    default:
+        DBG_OUT("selected something not a folder");
     }
-    else if((*selected)[m_librarycolumns.m_type] == KEYWORD_ITEM)
-    {
-        eng::library_id_t id = (*selected)[m_librarycolumns.m_id];
-        getLibraryClient()->queryKeywordContent(id);                   
+}
+
+void WorkspaceController::on_row_expanded_collapsed(const Gtk::TreeIter& iter,
+                                                    const Gtk::TreePath& /*path*/,
+                                                    bool expanded)
+{
+    int type = (*iter)[m_librarycolumns.m_type];
+    fwk::Configuration::Ptr cfg = getLibraryConfig();
+    const char* key = nullptr;
+    switch(type) {
+    case FOLDERS_ITEM:
+        key = "workspace_folders_expanded";
+        break;
+    case PROJECTS_ITEM:
+        key = "workspace_projects_expanded";
+        break;
+    case KEYWORDS_ITEM:
+        key = "workspace_keywords_expanded";
+        break;
     }
-    else 
-    {
-        DBG_OUT("selected something not a folder");
+    if(cfg && key) {
+        cfg->setValue(key,
+                      boost::lexical_cast<std::string>(expanded));
     }
 }
 
+void WorkspaceController::on_row_expanded(const Gtk::TreeIter& iter,
+                                          const Gtk::TreePath& path)
+{
+    on_row_expanded_collapsed(iter, path, true);
+}
+
+void WorkspaceController::on_row_collapsed(const Gtk::TreeIter& iter,
+                                           const Gtk::TreePath& path)
+{
+    on_row_expanded_collapsed(iter, path, false);
+}
+
+
 void WorkspaceController::add_keyword_item(const eng::Keyword::Ptr & k)
 {
-    Gtk::TreeModel::iterator iter(add_item(m_treestore, m_keywordsNode->children(), 
-                                           m_icons[ICON_KEYWORD], k->keyword(), k->id(), 
-                                           KEYWORD_ITEM));
+    auto iter = add_item(m_treestore, m_keywordsNode->children(),
+                         m_icons[ICON_KEYWORD], k->keyword(), k->id(),
+                         KEYWORD_ITEM);
 //             getLibraryClient()->countKeyword(f->id());
     m_keywordsidmap[k->id()] = iter;
 }
@@ -196,10 +240,12 @@ void WorkspaceController::add_folder_item(const eng::LibFolder::Ptr & f)
         icon_idx = ICON_TRASH;
         getLibraryClient()->set_trash_id(f->id());
     }
-    Gtk::TreeModel::iterator iter(add_item(m_treestore, 
-                                           m_folderNode->children(), 
-                                           m_icons[icon_idx], 
-                                           f->name(), f->id(), FOLDER_ITEM));
+    auto iter = add_item(m_treestore, m_folderNode->children(),
+                         m_icons[icon_idx],
+                         f->name(), f->id(), FOLDER_ITEM);
+    if(f->is_expanded()) {
+        m_librarytree.expand_row(m_treestore->get_path(iter), false);
+    }
     getLibraryClient()->countFolder(f->id());
     m_folderidmap[f->id()] = iter;
 }
@@ -232,6 +278,8 @@ Gtk::Widget * WorkspaceController::buildWidget(const Glib::RefPtr<Gtk::UIManager
     m_widget = &m_vbox;
     m_treestore = Gtk::TreeStore::create(m_librarycolumns);
     m_librarytree.set_model(m_treestore);
+    DBG_ASSERT(m_treestore->get_flags() & Gtk::TREE_MODEL_ITERS_PERSIST,
+        "Model isn't persistent");
 
     m_folderNode = add_item(m_treestore, m_treestore->children(),
                             m_icons[ICON_FOLDER], 
@@ -245,7 +293,6 @@ Gtk::Widget * WorkspaceController::buildWidget(const Glib::RefPtr<Gtk::UIManager
                               m_icons[ICON_KEYWORD],
                               Glib::ustring(_("Keywords")), 0,
                               KEYWORDS_ITEM);
-
     m_librarytree.set_headers_visible(false);
     m_librarytree.append_column("", m_librarycolumns.m_icon);
     int num = m_librarytree.append_column("", m_librarycolumns.m_label);
@@ -264,12 +311,52 @@ Gtk::Widget * WorkspaceController::buildWidget(const Glib::RefPtr<Gtk::UIManager
     m_librarytree.get_selection()->signal_changed().connect (
         sigc::mem_fun(this, 
                       &WorkspaceController::on_libtree_selection));
+    m_librarytree.signal_row_expanded().connect(
+        sigc::mem_fun(this,
+                      &WorkspaceController::on_row_expanded));
+    m_librarytree.signal_row_collapsed().connect(
+        sigc::mem_fun(this,
+                      &WorkspaceController::on_row_collapsed));
 
     return m_widget;
 }
-       
+
 void WorkspaceController::on_ready()
 {
+    bool expanded = false;
+    fwk::Configuration::Ptr cfg = getLibraryConfig();
+
+    // pre-expand
+    try {
+        expanded =
+            boost::lexical_cast<int>(cfg->getValue("workspace_folders_expanded",
+                                                      "1"));
+        if(expanded) {
+            DBG_ASSERT(m_treestore->iter_is_valid(m_folderNode), "iter not valid");
+            expanded = m_librarytree.expand_row(m_treestore->get_path(m_folderNode),
+                                                false);
+            DBG_OUT("expanded %d", expanded);
+        }
+        expanded =
+            boost::lexical_cast<int>(cfg->getValue("workspace_projects_expanded",
+                                                      "0"));
+        if(expanded) {
+            m_librarytree.expand_row(m_treestore->get_path(m_projectNode),
+                                     true);
+        }
+        expanded =
+            boost::lexical_cast<int>(cfg->getValue("workspace_keywords_expanded",
+                                                      "0"));
+        if(expanded) {
+            m_librarytree.expand_row(m_treestore->get_path(m_keywordsNode),
+                                     true);
+        }
+    }
+    catch(const std::exception &e) {
+        ERR_OUT("error: %s", e.what());
+    }
+
+
     libraryclient::LibraryClient::Ptr libraryClient = getLibraryClient();
     if(libraryClient)
     {
diff --git a/src/niepce/ui/workspacecontroller.hpp b/src/niepce/ui/workspacecontroller.hpp
index a8202e7..ae3ef94 100644
--- a/src/niepce/ui/workspacecontroller.hpp
+++ b/src/niepce/ui/workspacecontroller.hpp
@@ -33,6 +33,7 @@
 #include "engine/db/libfolder.hpp"
 #include "fwk/toolkit/uicontroller.hpp"
 #include "fwk/toolkit/notification.hpp"
+#include "niepce/ui/niepcewindow.hpp"
 
 namespace Gtk {
 }
@@ -86,8 +87,16 @@ public:
     
     virtual Gtk::Widget * buildWidget(const Glib::RefPtr<Gtk::UIManager> &);
 private:
-    libraryclient::LibraryClient::Ptr getLibraryClient();
-    
+    void on_row_expanded_collapsed(const Gtk::TreeIter& iter,
+                                   const Gtk::TreePath& path, bool expanded);
+    void on_row_expanded(const Gtk::TreeIter& iter,
+                         const Gtk::TreePath& path);
+    void on_row_collapsed(const Gtk::TreeIter& iter,
+                          const Gtk::TreePath& path);
+
+    libraryclient::LibraryClient::Ptr getLibraryClient() const;
+    fwk::Configuration::Ptr getLibraryConfig() const;
+
     /** add a folder item to the treeview */
     void add_folder_item(const eng::LibFolder::Ptr & f);
     /** add a keyword item to the treeview */


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