[niepce] Support flagging pictures.



commit 155334e34a381c707ba31733e840b3560267e486
Author: Hub Figuiere <hub figuiere net>
Date:   Sat Nov 5 21:36:42 2011 -0700

    Support flagging pictures.

 data/icons/Makefile.am                |    4 ++-
 data/icons/niepce-flag-pick.png       |  Bin 0 -> 1656 bytes
 data/icons/niepce-flag-reject.png     |  Bin 0 -> 817 bytes
 doc/database.txt                      |    1 +
 src/engine/db/libfile.cpp             |   15 +++++-------
 src/engine/db/libfile.hpp             |   11 +++-----
 src/engine/db/library.cpp             |   25 +++++++++++++------
 src/engine/db/metadata.hpp            |    9 +++++--
 src/niepce/ui/librarycellrenderer.cpp |   41 +++++++++++++++++++++++++++++++++
 src/niepce/ui/librarycellrenderer.hpp |    9 ++++++-
 src/niepce/ui/moduleshell.cpp         |   23 ++++++++++++++++++
 src/niepce/ui/selectioncontroller.cpp |   19 +++++++++++++++
 src/niepce/ui/selectioncontroller.hpp |    4 ++-
 13 files changed, 131 insertions(+), 30 deletions(-)
---
diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am
index 76bbf08..c8d6b92 100644
--- a/data/icons/Makefile.am
+++ b/data/icons/Makefile.am
@@ -5,4 +5,6 @@ dist_icons_DATA = niepce-jpg-fmt.png niepce-raw-fmt.png niepce-rawjpeg-fmt.png\
 	niepce-tiff-fmt.png niepce-png-fmt.png\
 	niepce-img-fmt.png niepce-unknown-fmt.png niepce-video-fmt.png\
 	niepce-set-star.png niepce-unset-star.png\
-	niepce-rotate-left.png niepce-rotate-right.png
+	niepce-rotate-left.png niepce-rotate-right.png \
+	niepce-flag-pick.png niepce-flag-reject.png  \
+	$(NULL)
diff --git a/data/icons/niepce-flag-pick.png b/data/icons/niepce-flag-pick.png
new file mode 100644
index 0000000..dd6d527
Binary files /dev/null and b/data/icons/niepce-flag-pick.png differ
diff --git a/data/icons/niepce-flag-reject.png b/data/icons/niepce-flag-reject.png
new file mode 100644
index 0000000..c07ae0b
Binary files /dev/null and b/data/icons/niepce-flag-reject.png differ
diff --git a/doc/database.txt b/doc/database.txt
index ab54955..ab6094c 100644
--- a/doc/database.txt
+++ b/doc/database.txt
@@ -24,6 +24,7 @@ files           id             Unique ID in the database
                                Exif (time_t)
 		rating         The file rating (0-5)
 		label          The label (labels.id)
+		flag           The file flage. (-1 reject, 0 none, +1 flagged)
 		import_date    The date of import in the database (time_t)
 		mod_date       The date modified (time_t)
 		xmp            The XMP blob
diff --git a/src/engine/db/libfile.cpp b/src/engine/db/libfile.cpp
index bc7e201..2a4ceee 100644
--- a/src/engine/db/libfile.cpp
+++ b/src/engine/db/libfile.cpp
@@ -31,6 +31,7 @@ LibFile::LibFile(int _id, int _folderId, int _fsfileid, const std::string & p,
 	  m_name(_name), 
     m_main_file(_fsfileid, p),
 	  m_orientation(0), m_rating(0), m_label(0),
+    m_flag(0),
     m_file_type(FILE_TYPE_UNKNOWN)
 {
     
@@ -40,15 +41,6 @@ LibFile::~LibFile()
 {
 }
 
-
-const Keyword::IdList & LibFile::keywords() const
-{
-    if(!m_hasKeywordList) {
-//			storage()->fetchKeywordsForFile(m_id, m_keywordList);
-    }
-    return m_keywordList;
-}
-
 void LibFile::setOrientation(int32_t v)
 {
     m_orientation = v;
@@ -66,6 +58,11 @@ void LibFile::setLabel(int32_t v)
     m_label = v;
 }
 
+void LibFile::setFlag(int32_t v)
+{
+    m_flag = v;
+}
+
 void LibFile::setFileType(FileType v)
 {
     m_file_type = v;
diff --git a/src/engine/db/libfile.hpp b/src/engine/db/libfile.hpp
index ab42e2d..2289537 100644
--- a/src/engine/db/libfile.hpp
+++ b/src/engine/db/libfile.hpp
@@ -74,6 +74,9 @@ public:
     void setLabel(int32_t v);
     int32_t label() const
         { return m_label; }
+    void setFlag(int32_t v);
+    int32_t flag() const
+        { return m_flag; }
 
     /** Setter for the filetype.
      * @param v the FILETYPE of the file
@@ -85,11 +88,6 @@ public:
     
     /** set an arbitrary meta data value */
     void setMetaData(int meta, int32_t v); 
-
-    /** retrieve the keywords id list 
-     * @return the list
-     */
-    const Keyword::IdList & keywords() const;
 		
     /** return an URI of the real path
      * because the Gtk stuff want that.
@@ -112,9 +110,8 @@ private:
     int32_t     m_orientation;  /**< Exif orientatoin */
     int32_t     m_rating;       /**< rating */
     int32_t     m_label;        /**< Label ID */
+    int32_t     m_flag;         /**< Flag */
     FileType    m_file_type;    /**< File type */
-    mutable bool m_hasKeywordList;
-    mutable Keyword::IdList m_keywordList;
 };
 
 }
diff --git a/src/engine/db/library.cpp b/src/engine/db/library.cpp
index ee17475..684e166 100644
--- a/src/engine/db/library.cpp
+++ b/src/engine/db/library.cpp
@@ -126,8 +126,10 @@ bool Library::_initDb()
     SQLStatement vaultTable("CREATE TABLE vaults (id INTEGER PRIMARY KEY,"
                             " path TEXT)");
     SQLStatement folderTable("CREATE TABLE folders (id INTEGER PRIMARY KEY,"
-                             " path TEXT, name TEXT, vault_id INTEGER, "
-                             " locked INTEGER, virtual INTEGER,"
+                             " path TEXT, name TEXT, "
+                             " vault_id INTEGER DEFAULT 0, "
+                             " locked INTEGER DEFAULT 0, "
+                             " virtual INTEGER DEFAULT 0,"
                              " parent_id INTEGER)");
 
     SQLStatement initialFolders(
@@ -138,14 +140,15 @@ bool Library::_initDb()
     SQLStatement fileTable("CREATE TABLE files (id INTEGER PRIMARY KEY,"
                            " main_file INTEGER, name TEXT, parent_id INTEGER,"
                            " orientation INTEGER, file_type INTEGER, "
-                           " file_date INTEGER, rating INTEGER, label INTEGER,"
+                           " file_date INTEGER, rating INTEGER DEFAULT 0, "
+                           " label INTEGER, flag INTEGER DEFAULT 0, "
                            " import_date INTEGER, mod_date INTEGER, "
                            " xmp TEXT, xmp_date INTEGER, xmp_file INTEGER,"
                            " jpeg_file INTEGER)");
     SQLStatement fsFileTable("CREATE TABLE fsfiles (id INTEGER PRIMARY KEY,"
                              " path TEXT)");
     SQLStatement keywordTable("CREATE TABLE keywords (id INTEGER PRIMARY KEY,"
-                              " keyword TEXT, parent_id INTEGER)");
+                              " keyword TEXT, parent_id INTEGER DEFAULT 0)");
     SQLStatement keywordingTable("CREATE TABLE keywording (file_id INTEGER,"
                                  " keyword_id INTEGER)");
     SQLStatement labelTable("CREATE TABLE labels (id INTEGER PRIMARY KEY,"
@@ -472,7 +475,7 @@ static LibFile::Ptr getFileFromDbRow(const db::IConnectionDriver::Ptr & dbdrv)
     int32_t fsfid;
     std::string pathname;
     std::string name;
-    DBG_ASSERT(dbdrv->get_number_of_columns() == 9, "wrong number of columns");
+    DBG_ASSERT(dbdrv->get_number_of_columns() == 10, "wrong number of columns");
     dbdrv->get_column_content(0, id);
     dbdrv->get_column_content(1, fid);
     dbdrv->get_column_content(2, pathname);
@@ -488,6 +491,8 @@ static LibFile::Ptr getFileFromDbRow(const db::IConnectionDriver::Ptr & dbdrv)
     f->setRating(val);
     dbdrv->get_column_content(6, val);
     f->setLabel(val);
+    dbdrv->get_column_content(9, val);
+    f->setFlag(val);
 
     /* Casting needed. Remember that a simple enum like this is just a couple
      * of #define for integers.
@@ -502,7 +507,7 @@ void Library::getFolderContent(int folder_id, const LibFile::ListPtr & fl)
     SQLStatement sql(boost::format("SELECT files.id,parent_id,fsfiles.path,"
                                    "name,"
                                    "orientation,rating,label,file_type,"
-                                   "fsfiles.id"
+                                   "fsfiles.id,flag"
                                    " FROM files,fsfiles "
                                    " WHERE parent_id='%1%' "
                                    " AND files.main_file=fsfiles.id")
@@ -619,7 +624,7 @@ void Library::getKeywordContent(int keyword_id, const LibFile::ListPtr & fl)
 {
     SQLStatement sql(boost::format("SELECT files.id,parent_id,fsfiles.path,"
                                    "name,orientation,rating,label,file_type,"
-                                   " fsfiles.id "
+                                   " fsfiles.id,flag"
                                    " FROM files,fsfiles "
                                    " WHERE files.id IN "
                                    " (SELECT file_id FROM keywording "
@@ -721,7 +726,8 @@ bool Library::setMetaData(int file_id, int meta,
     switch(meta) {
     case MAKE_METADATA_IDX(eng::META_NS_XMPCORE, eng::META_XMPCORE_RATING):
     case MAKE_METADATA_IDX(eng::META_NS_XMPCORE, eng::META_XMPCORE_LABEL):
-    case MAKE_METADATA_IDX(eng::META_NS_TIFF, eng::META_TIFF_ORIENTATION):
+    case MAKE_METADATA_IDX(eng::META_NS_TIFF,    eng::META_TIFF_ORIENTATION):
+    case MAKE_METADATA_IDX(eng::META_NS_NIEPCE,  eng::META_NIEPCE_FLAG):
         if(value.type() == typeid(int32_t)) {
             // internal.
             int32_t nvalue = boost::any_cast<int32_t>(value);
@@ -737,6 +743,9 @@ bool Library::setMetaData(int file_id, int meta,
             case MAKE_METADATA_IDX(eng::META_NS_XMPCORE, eng::META_XMPCORE_LABEL):
                 col = "label";
                 break;
+            case MAKE_METADATA_IDX(eng::META_NS_NIEPCE, eng::META_NIEPCE_FLAG):
+                col = "flag";
+                break;
             }
             if(col) {
                 retval = setInternalMetaDataInt(file_id, col, nvalue);
diff --git a/src/engine/db/metadata.hpp b/src/engine/db/metadata.hpp
index f36594f..51b403e 100644
--- a/src/engine/db/metadata.hpp
+++ b/src/engine/db/metadata.hpp
@@ -27,13 +27,16 @@ namespace eng {
 enum {
     META_NS_XMPCORE = 0,
     META_NS_TIFF,
-    META_NS_EXIF
+    META_NS_EXIF,
+    META_NS_NIEPCE
 };
 
 /** Metadata for xmpcore. Combine with %META_NS_XMPCORE */
 enum {
     META_XMPCORE_RATING = 0,
-    META_XMPCORE_LABEL
+    META_XMPCORE_LABEL = 1,
+
+    _META_XMPCORE_LAST_
 };
 
 /** Metadata for tiff. Combine with %META_NS_TIFF */
@@ -42,7 +45,7 @@ enum {
 };
 
 enum {
-
+    META_NIEPCE_FLAG = 0
 };
 
 /** make a metadata index with a namespace and a value */
diff --git a/src/niepce/ui/librarycellrenderer.cpp b/src/niepce/ui/librarycellrenderer.cpp
index f9f7719..0f0b104 100644
--- a/src/niepce/ui/librarycellrenderer.cpp
+++ b/src/niepce/ui/librarycellrenderer.cpp
@@ -46,6 +46,7 @@ LibraryCellRenderer::LibraryCellRenderer(libraryclient::UIDataProvider *provider
       m_drawemblem(true),
       m_drawrating(true),
       m_drawlabel(true),
+      m_drawflag(true),
       m_uiDataProvider(provider),
       m_libfileproperty(*this, "libfile")
 {
@@ -66,6 +67,13 @@ LibraryCellRenderer::LibraryCellRenderer(libraryclient::UIDataProvider *provider
         m_unknown_format_emblem 
             = Cairo::ImageSurface::create_from_png(
                 std::string(DATADIR"/niepce/pixmaps/niepce-unknown-fmt.png"));
+
+        m_flag_reject
+            = Cairo::ImageSurface::create_from_png(
+                std::string(DATADIR"/niepce/pixmaps/niepce-flag-reject.png"));
+        m_flag_pick
+            = Cairo::ImageSurface::create_from_png(
+                std::string(DATADIR"/niepce/pixmaps/niepce-flag-pick.png"));
     }
     catch(const std::exception & e) {
         ERR_OUT("exception while creating emblems: %s", e.what());
@@ -103,6 +111,33 @@ void LibraryCellRenderer::_drawThumbnail(const Cairo::RefPtr<Cairo::Context> & c
     cr->paint();
 }
 
+
+void LibraryCellRenderer::_drawFlag(const Cairo::RefPtr<Cairo::Context> & cr, 
+                   int flag_value, double x, double y)
+{
+    if(flag_value == 0) {
+        return;
+    }
+
+    Cairo::RefPtr<Cairo::ImageSurface> pixbuf;
+    if(flag_value == -1) {
+        pixbuf = m_flag_reject;
+    }
+    else if(flag_value == 1) {
+        pixbuf = m_flag_pick;
+    }
+    else {
+        ERR_OUT("wrong flag value %d", flag_value);
+        return ;
+    }
+    int w = pixbuf->get_width();
+
+    cr->set_source(pixbuf, x - w, y);
+    cr->paint();
+}
+
+
+
 namespace {
 
 int drawFormatEmblem(const Cairo::RefPtr<Cairo::Context> & cr, 
@@ -222,6 +257,12 @@ LibraryCellRenderer::render_vfunc(const Glib::RefPtr<Gdk::Drawable>& window,
                                       fwk::RatingLabel::get_star(), 
                                       fwk::RatingLabel::get_unstar(), x, y);
     }
+    if(m_drawflag) {
+        double x, y;
+        x = r.x + r.width - CELL_PADDING;
+        y = r.y + CELL_PADDING;
+        _drawFlag(cr, file->flag(), x, y);
+    }
     
     if(m_drawemblem) {
         Cairo::RefPtr<Cairo::ImageSurface> emblem;
diff --git a/src/niepce/ui/librarycellrenderer.hpp b/src/niepce/ui/librarycellrenderer.hpp
index c6955ab..99f040d 100644
--- a/src/niepce/ui/librarycellrenderer.hpp
+++ b/src/niepce/ui/librarycellrenderer.hpp
@@ -73,6 +73,8 @@ public:
         { m_drawrating = val; }
     void set_drawlabel(bool val)
         { m_drawlabel = val; }
+    void set_drawflag(bool val)
+        { m_drawlabel = val; }
 
     Glib::PropertyProxy_ReadOnly<eng::LibFile::Ptr> property_libfile() const;
     Glib::PropertyProxy<eng::LibFile::Ptr>          property_libfile();
@@ -82,7 +84,8 @@ protected:
     void _drawThumbnail(const Cairo::RefPtr<Cairo::Context> & cr, 
                         Glib::RefPtr<Gdk::Pixbuf> & pixbuf,
                         const GdkRectangle & r);
-
+    void _drawFlag(const Cairo::RefPtr<Cairo::Context> & cr, 
+                   int flag_value, double x, double y);
 private:
     int                                 m_size;
     int                                 m_pad;
@@ -90,6 +93,7 @@ private:
     bool                                m_drawemblem;
     bool                                m_drawrating;
     bool                                m_drawlabel;
+    bool                                m_drawflag;
     libraryclient::UIDataProvider      *m_uiDataProvider;
     Glib::Property<eng::LibFile::Ptr>   m_libfileproperty;
     
@@ -98,6 +102,9 @@ private:
     Cairo::RefPtr<Cairo::ImageSurface>  m_img_format_emblem;
     Cairo::RefPtr<Cairo::ImageSurface>  m_video_format_emblem;
     Cairo::RefPtr<Cairo::ImageSurface>  m_unknown_format_emblem;
+
+    Cairo::RefPtr<Cairo::ImageSurface>  m_flag_reject;
+    Cairo::RefPtr<Cairo::ImageSurface>  m_flag_pick;
 };
 
 
diff --git a/src/niepce/ui/moduleshell.cpp b/src/niepce/ui/moduleshell.cpp
index b8391c6..27cc7bd 100644
--- a/src/niepce/ui/moduleshell.cpp
+++ b/src/niepce/ui/moduleshell.cpp
@@ -129,6 +129,24 @@ Gtk::Widget * ModuleShell::buildWidget(const Glib::RefPtr<Gtk::UIManager> & mana
                            sigc::mem_fun(*m_selection_controller,
                                          &SelectionController::set_rating),
                            5));
+
+    m_actionGroup->add(Gtk::Action::create("SetFlag", _("Set _Flag")));
+    m_actionGroup->add(Gtk::Action::create("SetFlagReject", _("Flag as _Rejected")),
+                          Gtk::AccelKey("x"), sigc::bind(
+                              sigc::mem_fun(*m_selection_controller,
+                                            &SelectionController::set_flag),
+                              -1));
+    m_actionGroup->add(Gtk::Action::create("SetFlagNone", _("_Unflagged")),
+                          Gtk::AccelKey("u"), sigc::bind(
+                              sigc::mem_fun(*m_selection_controller,
+                                            &SelectionController::set_flag),
+                              0));
+    m_actionGroup->add(Gtk::Action::create("SetFlagPick", _("Flag as _Pick")),
+                          Gtk::AccelKey("p"), sigc::bind(
+                              sigc::mem_fun(*m_selection_controller,
+                                            &SelectionController::set_flag),
+                              1));
+
     m_actionGroup->add(Gtk::Action::create("DeleteImage", Gtk::Stock::DELETE));
 
     manager->insert_action_group(m_actionGroup);
@@ -159,6 +177,11 @@ Gtk::Widget * ModuleShell::buildWidget(const Glib::RefPtr<Gtk::UIManager> & mana
         "        <menuitem action='SetLabel9'/>"
         "        <separator/>"
         "      </menu>"
+        "      <menu action='SetFlag'>"
+        "        <menuitem action='SetFlagReject'/>"
+        "        <menuitem action='SetFlagNone'/>"
+        "        <menuitem action='SetFlagPick'/>"
+        "      </menu>"
         "      <separator/>"
         "      <menuitem action='DeleteImage'/>"
         "    </menu>"
diff --git a/src/niepce/ui/selectioncontroller.cpp b/src/niepce/ui/selectioncontroller.cpp
index 96e8836..1cdaf86 100644
--- a/src/niepce/ui/selectioncontroller.cpp
+++ b/src/niepce/ui/selectioncontroller.cpp
@@ -222,6 +222,25 @@ void SelectionController::set_rating(int rating)
     }
 }
 
+void SelectionController::set_flag(int flag)
+{
+    DBG_OUT("flag = %d", flag);
+    int selection = get_selection();
+    if(selection >= 0) {
+        Gtk::TreeIter iter = m_imageliststore->get_iter_from_id(selection);
+        if(iter) {
+            eng::LibFile::Ptr file = (*iter)[m_imageliststore->columns().m_libfile];
+            DBG_OUT("old flag is %d", file->flag());
+            int old_value = file->flag();
+            _set_metadata(_("Set Flag"), file, 
+                          MAKE_METADATA_IDX(eng::META_NS_NIEPCE, eng::META_NIEPCE_FLAG), 
+                          old_value, flag);
+            // we need to set the rating here so that undo/redo works
+            // consistently.
+            file->setFlag(flag);
+        }
+    }
+}
 
 }
 
diff --git a/src/niepce/ui/selectioncontroller.hpp b/src/niepce/ui/selectioncontroller.hpp
index c343021..2b49102 100644
--- a/src/niepce/ui/selectioncontroller.hpp
+++ b/src/niepce/ui/selectioncontroller.hpp
@@ -86,8 +86,10 @@ public:
     void set_rating(int rating);
     /** set the label of selection to the label with index %label. */
     void set_label(int label);
+    /** set flag */
+    void set_flag(int flag);
 protected:
-	virtual void _added();
+    virtual void _added();
 private:
     int get_selection();
     libraryclient::LibraryClient::Ptr getLibraryClient();



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