paperbox r104 - in trunk: . src



Author: markoa
Date: Sun Feb 24 23:14:44 2008
New Revision: 104
URL: http://svn.gnome.org/viewvc/paperbox?rev=104&view=rev

Log:
Category content editing, data shown only in the editor

Modified:
   trunk/ChangeLog
   trunk/src/category-editor-model.cc
   trunk/src/category-editor-model.hh
   trunk/src/category-editor.cc
   trunk/src/category-editor.hh
   trunk/src/category-factory.cc
   trunk/src/category-factory.hh
   trunk/src/category.cc
   trunk/src/category.hh

Modified: trunk/src/category-editor-model.cc
==============================================================================
--- trunk/src/category-editor-model.cc	(original)
+++ trunk/src/category-editor-model.cc	Sun Feb 24 23:14:44 2008
@@ -20,17 +20,42 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include <vector>
+#include <glibmm-utils/ustring.h>
 #include "category-editor-model.hh"
 
 namespace paperbox {
 
+    using std::list;
     using std::map;
+    using std::vector;
     using boost::shared_ptr;
 
     typedef map<Glib::ustring,
                 boost::shared_ptr<CategoryEditorData> >::iterator
     model_data_iter;
 
+    ///
+
+    CategoryEditorData::CategoryEditorData(const Glib::ustring& name)
+        :
+        dirty(false)
+    {
+        category = CategoryFactory::create_category(name);
+        buffer = Gtk::TextBuffer::create();
+    }
+
+    CategoryEditorData::CategoryEditorData(shared_ptr<Category>& cat)
+        :
+        dirty(false)
+    {
+        category = cat;
+        buffer = Gtk::TextBuffer::create();
+        buffer->set_text(category->get_tags_as_string());
+    }
+
+    ///
+
     CategoryEditorModel::CategoryEditorModel()
     {
     }
@@ -39,10 +64,24 @@
     {
     }
 
-    // loads data for all existing categories
-    void
+    // loads data for all existing categories from the fs
+    list<shared_ptr<CategoryEditorData> > 
     CategoryEditorModel::load_category_data()
     {
+        list<shared_ptr<CategoryEditorData> > data;
+        list<shared_ptr<Category> > categories(
+            CategoryFactory::load_categories());
+
+        list<shared_ptr<Category> >::iterator it(categories.begin());
+        list<shared_ptr<Category> >::iterator end(categories.end());
+
+        for ( ; it != end; ++it) {
+            shared_ptr<CategoryEditorData> ptr(new CategoryEditorData(*it));
+            data.push_back(ptr);
+            model_data_[(*it)->get_name()] = ptr;
+        }
+
+        return data;
     }
 
     boost::shared_ptr<CategoryEditorData>
@@ -51,12 +90,13 @@
         CategoryEditorData* data = 0;
         shared_ptr<CategoryEditorData> ptr;
 
-        data = new CategoryEditorData;
-
-        // might throw CategoryNotFound to the caller here
-        data->category = CategoryFactory::create_category(name);
-        data->buffer = Gtk::TextBuffer::create();
+        if (! CategoryFactory::is_name_available(name))
+            throw CategoryExists(
+                // TODO: this should be _()
+                Glib::Util::uprintf("Category %s already exists",
+                                    name.c_str()));
 
+        data = new CategoryEditorData(name);
         ptr.reset(data);
         model_data_[name] = ptr;
 
@@ -78,6 +118,11 @@
     void
     CategoryEditorModel::save_category(const Glib::ustring& name)
     {
+        shared_ptr<CategoryEditorData> ptr = get_category(name);
+        vector<Glib::ustring> new_tags(
+            Glib::Util::split(ptr->buffer->get_text(), " "));
+        ptr->category->reset_tags(new_tags);
+        ptr->dirty = false;
     }
 
     void

Modified: trunk/src/category-editor-model.hh
==============================================================================
--- trunk/src/category-editor-model.hh	(original)
+++ trunk/src/category-editor-model.hh	Sun Feb 24 23:14:44 2008
@@ -24,6 +24,7 @@
 #define __PAPER_BOX_CATEGORY_EDITOR_MODEL_HH__
 
 #include <map>
+#include <boost/noncopyable.hpp>
 #include <boost/shared_ptr.hpp>
 #include <gtkmm/textbuffer.h>
 #include "category.hh"
@@ -31,10 +32,16 @@
 
 namespace paperbox {
 
-    struct CategoryEditorData
+    class CategoryEditorData : public boost::noncopyable
     {
+    public:
+        explicit CategoryEditorData(const Glib::ustring& name);
+        explicit CategoryEditorData(boost::shared_ptr<Category>& cat);
+        ~CategoryEditorData() {}
+
         boost::shared_ptr<Category> category;
         Glib::RefPtr<Gtk::TextBuffer> buffer;
+        bool dirty;
     };
 
     class CategoryEditorModel
@@ -43,6 +50,8 @@
         explicit CategoryEditorModel();
         ~CategoryEditorModel();
 
+        std::list<boost::shared_ptr<CategoryEditorData> > load_category_data();
+
         // throws CategoryExists, propagated from CategoryFactory
         boost::shared_ptr<CategoryEditorData> new_category(const Glib::ustring& name);
 
@@ -55,8 +64,6 @@
         void delete_category(const Glib::ustring& name);
 
     protected:
-        void load_category_data();
-
         std::map<Glib::ustring,
                  boost::shared_ptr<CategoryEditorData> > model_data_;
     };

Modified: trunk/src/category-editor.cc
==============================================================================
--- trunk/src/category-editor.cc	(original)
+++ trunk/src/category-editor.cc	Sun Feb 24 23:14:44 2008
@@ -20,6 +20,7 @@
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include <list>
 #include <gtkmm/stock.h>
 #include <gtkmm-utils/dialog.h>
 #include "category-editor.hh"
@@ -29,6 +30,7 @@
 
 namespace paperbox {
 
+    using std::list;
     using boost::shared_ptr;
 
     CategoryEditor::CategoryEditor(
@@ -44,6 +46,7 @@
         init_gui();
         connect_signals();
         model_.reset(new CategoryEditorModel());
+        load_categories();
     }
 
     CategoryEditor::~CategoryEditor()
@@ -85,9 +88,9 @@
         vbox_left_->pack_start(button_delete_, false, false);
 
         // TODO: verify the string and wrap in _()
-        label_category_tags_.set_text("Here are the contents:");
+        label_category_tags_.set_text("Tags contained:");
         hbox_contents_->pack_start(label_category_tags_);
-        hbox_contents_->pack_start(button_save_);
+        hbox_contents_->pack_start(button_save_, false, false);
 
         vbox_right_->pack_start(scroll_window_);
         scroll_window_.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
@@ -105,15 +108,12 @@
         button_delete_.signal_clicked().connect(
             sigc::mem_fun(*this, &CategoryEditor::on_button_delete_clicked));
 
+        button_save_.signal_clicked().connect(
+            sigc::mem_fun(*this, &CategoryEditor::on_button_save_clicked));
+
         // connect the selection function
         category_view_->selection->set_select_function(
             sigc::mem_fun(*this, &CategoryEditor::on_category_selected));
-
-        // and select the first list
-        //TODO: yes, but we need to load them all first
-//        if (! category_view_->treemodel->children().empty())
-//            category_view_->selection->select(
-//                category_view_->treemodel->children().begin());
     }
 
     int
@@ -124,6 +124,36 @@
     }
 
     void
+    CategoryEditor::add_new_row(shared_ptr<CategoryEditorData>& data)
+    {
+        // update our view - create a new row, set the buffer
+        Gtk::TreeModel::Row row = *(category_view_->treemodel->append());
+
+        row[category_view_->columns.col_name] = data->category->get_name();
+        category_view_->selection->select(row);
+
+        text_view_.set_buffer(data->buffer);
+    }
+
+    void
+    CategoryEditor::load_categories()
+    {
+        list<shared_ptr<CategoryEditorData> > cats(
+            model_->load_category_data());
+
+        list<shared_ptr<CategoryEditorData> >::iterator it(cats.begin());
+        list<shared_ptr<CategoryEditorData> >::iterator end(cats.end());
+
+        for ( ; it != end; ++it)
+            add_new_row(*it);
+
+        // select the first list item, if any
+        if (! category_view_->treemodel->children().empty())
+            category_view_->selection->select(
+                category_view_->treemodel->children().begin());
+    }
+
+    void
     CategoryEditor::on_button_new_clicked()
     {
         shared_ptr<DialogEntry> dialog(DialogEntry::create());
@@ -141,13 +171,7 @@
             // create a new data model and category file
             shared_ptr<CategoryEditorData> data = model_->new_category(name);
 
-            // update our view - create a new row, set the buffer
-            Gtk::TreeModel::Row row = *(category_view_->treemodel->append());
-
-            row[category_view_->columns.col_name] = name;
-            category_view_->selection->select(row);
-
-            text_view_.set_buffer(data->buffer);
+            add_new_row(data);
             
         } catch (const CategoryExists& ex) {
             Gtk::Util::display_dialog_error(ex.what());
@@ -170,6 +194,8 @@
         if (! ((cat_name != selected_name_) && (! path_selected)))
             return true; // selection hasn't changed
 
+        selected_name_ = cat_name;
+
         try {
             shared_ptr<CategoryEditorData> data =
                 model_->get_category(cat_name);
@@ -184,4 +210,10 @@
         return true;
     }
 
+    void
+    CategoryEditor::on_button_save_clicked()
+    {
+        model_->save_category(selected_name_);
+    }
+
 } // namespace paperbox

Modified: trunk/src/category-editor.hh
==============================================================================
--- trunk/src/category-editor.hh	(original)
+++ trunk/src/category-editor.hh	Sun Feb 24 23:14:44 2008
@@ -34,6 +34,7 @@
 
 namespace paperbox {
 
+    class CategoryEditorData;
     class CategoryEditorModel;
 
     class CategoryEditor : public Gtk::Dialog
@@ -52,8 +53,12 @@
         void init_gui();
         void connect_signals();
 
+        void load_categories();
+        void add_new_row(boost::shared_ptr<CategoryEditorData>& data);
+
         void on_button_new_clicked();
         void on_button_delete_clicked();
+        void on_button_save_clicked();
         bool on_category_selected(const Glib::RefPtr<Gtk::TreeModel>& model,
                                   const Gtk::TreeModel::Path& path,
                                   bool path_selected);

Modified: trunk/src/category-factory.cc
==============================================================================
--- trunk/src/category-factory.cc	(original)
+++ trunk/src/category-factory.cc	Sun Feb 24 23:14:44 2008
@@ -40,12 +40,6 @@
     shared_ptr<Category>
     CategoryFactory::create_category(const Glib::ustring& name)
     {
-        if (! is_name_available(name))
-            throw CategoryExists(
-                // TODO: this should be _()
-                Glib::Util::uprintf("Category %s already exists",
-                                    name.c_str()));
-
         shared_ptr<Category> cat(new Category(name));
         return cat;
     }
@@ -79,8 +73,8 @@
         }
     }
 
-    bool
-    CategoryFactory::is_name_available(const Glib::ustring& name)
+    list<string>
+    CategoryFactory::get_categories_from_fs()
     {
         list<string> categories;
         string path = Category::get_default_path();
@@ -98,17 +92,43 @@
                 if (Glib::file_test(file, Glib::FILE_TEST_IS_REGULAR))
                     categories.push_back(*it);
             }
-
-            end = categories.end();
-            if (find(categories.begin(), end, name) == end) return true;
         }
         catch (Glib::FileError& ex) {
             LOG_EXCEPTION("Cannot open category directory "
                           << path << ": " << Glib::strerror(ex.code()));
         }
 
+        return categories;
+    }
+
+    bool
+    CategoryFactory::is_name_available(const Glib::ustring& name)
+    {
+        list<string> categories(get_categories_from_fs());
+        list<string>::iterator end(categories.end());
+
+        if (find(categories.begin(), end, name) == end)
+            return true;
+
         return false;
     }
 
+    list<shared_ptr<Category> >
+    CategoryFactory::load_categories()
+    {
+        list<shared_ptr<Category> > categories;
+        list<string> category_names(get_categories_from_fs());
+
+        list<string>::iterator it(category_names.begin());
+        list<string>::iterator end(category_names.end());
+
+        for ( ; it != end; ++it) {
+            shared_ptr<Category> cat = create_category(*it);
+            categories.push_back(cat);
+        }
+
+        return categories;
+    }
+
 } // namespace paperbox
 

Modified: trunk/src/category-factory.hh
==============================================================================
--- trunk/src/category-factory.hh	(original)
+++ trunk/src/category-factory.hh	Sun Feb 24 23:14:44 2008
@@ -24,6 +24,7 @@
 #define __PAPER_BOX_CATEGORY_FACTORY_HH__
 
 #include <exception>
+#include <list>
 #include <string>
 #include <glibmm/ustring.h>
 #include <boost/shared_ptr.hpp>
@@ -52,10 +53,15 @@
         // throws CategoryNotFound
         static boost::shared_ptr<Category> get_category(const Glib::ustring& name);
 
+        static std::list<boost::shared_ptr<Category> > load_categories();
+
         // throws CategoryNotFound
         static void delete_category(const Glib::ustring& name);
 
         static bool is_name_available(const Glib::ustring& name);
+
+    protected:
+        static std::list<std::string> get_categories_from_fs();
     };
 
 } // namespace paperbox

Modified: trunk/src/category.cc
==============================================================================
--- trunk/src/category.cc	(original)
+++ trunk/src/category.cc	Sun Feb 24 23:14:44 2008
@@ -55,6 +55,20 @@
             lines.push_back(line);
         }
     }
+
+    // TODO: clean up the mess with strings vs ustrings.
+    // Loads open text stream's contents into a string list.
+    void read_lines(std::ifstream& fs,
+                    std::list<Glib::ustring>& lines)
+    {
+         std::string std_line;
+
+         while (! fs.eof()) {
+             std::getline(fs, std_line);
+             if (! std_line.size()) continue;
+             lines.push_back(std_line);
+         }
+    }
 }
 
 namespace paperbox {
@@ -63,6 +77,7 @@
 
     using std::list;
     using std::string;
+    using std::vector;
 
     using bfs::exists;
     using bfs::fstream;
@@ -79,8 +94,13 @@
         check_category_path();
 
         if (! exists(path_)) {
+            // touch
             ofstream empty_stream(path_);
             empty_stream.close();
+        } else {
+            // load tags
+            std::ifstream ifs(path_.string().c_str());
+            read_lines(ifs, tags_);
         }
     }
 
@@ -114,6 +134,20 @@
         fs.close();
         return true;
     }
+
+    void
+    Category::reset_tags(const vector<Glib::ustring>& new_tags)
+    {
+        using std::ios_base;
+        bfs::ofstream fs(path_, ios_base::out | ios_base::trunc);
+
+        vector<Glib::ustring>::const_iterator it(new_tags.begin());
+        vector<Glib::ustring>::const_iterator end(new_tags.end());
+        for ( ; it != end; ++it)
+            fs << *it << std::endl;
+
+        fs.close();
+    }
  
     bool
     Category::remove_tag(const Glib::ustring& tag)
@@ -156,6 +190,22 @@
         return tags_;
     }
 
+    Glib::ustring
+    Category::get_tags_as_string() const
+    {
+        Glib::ustring tag_text;
+        list<Glib::ustring>::const_iterator it(tags_.begin());
+        list<Glib::ustring>::const_iterator end(tags_.end());
+
+        if (it != end)
+            tag_text = *it++;
+
+        for ( ; it != end; ++it)
+            tag_text = tag_text + " " + *it;
+
+        return tag_text;
+    }
+
     std::string
     Category::get_default_path()
     {

Modified: trunk/src/category.hh
==============================================================================
--- trunk/src/category.hh	(original)
+++ trunk/src/category.hh	Sun Feb 24 23:14:44 2008
@@ -25,6 +25,7 @@
 
 #include <list>
 #include <string>
+#include <vector>
 #include <boost/filesystem.hpp>
 #include <boost/noncopyable.hpp>
 #include <glibmm/ustring.h>
@@ -40,9 +41,12 @@
         virtual ~Category();
 
         bool add_tag(const Glib::ustring& tag);
+        void reset_tags(const std::vector<Glib::ustring>& new_tags);
         bool remove_tag(const Glib::ustring& tag);
 
+        std::string get_name() const;
         std::list<Glib::ustring> get_tags() const;
+        Glib::ustring get_tags_as_string() const;
 
         static std::string get_default_path();
 
@@ -52,6 +56,12 @@
         std::list<Glib::ustring> tags_;
     };
 
+    inline std::string
+    Category::get_name() const
+    {
+        return name_;
+    }
+
 } // namespace paperbox
 
 #endif // __PAPER_BOX_CATEGORY_HH__



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