[niepce] Issue #10 - Add support for file status



commit c54fd2c62b179feb4332e610e6f6ae3571433b51
Author: Hubert Figuière <hub figuiere net>
Date:   Sat Feb 24 12:48:11 2018 -0500

    Issue #10 - Add support for file status
    
    -Draw a badge if file is missing
    
    https://gitlab.gnome.org/GNOME/niepce/issues/10

 data/icons/Makefile.am                |   1 +
 data/icons/niepce-missing.png         | Bin 0 -> 832 bytes
 src/engine/db/libfile.rs              |  10 ++++++++-
 src/engine/library/notification.rs    |  23 ++++++++++++++++++-
 src/niepce/ui/gridviewmodule.cpp      |   4 +++-
 src/niepce/ui/imageliststore.cpp      |  37 +++++++++++++++++++++----------
 src/niepce/ui/imageliststore.hpp      |  14 ++++++++----
 src/niepce/ui/librarycellrenderer.cpp |  40 ++++++++++++++++++++++++++--------
 src/niepce/ui/librarycellrenderer.hpp |  20 +++++++++--------
 src/niepce/ui/thumbstripview.cpp      |   4 +++-
 src/rust_bindings.hpp                 |   3 ++-
 11 files changed, 118 insertions(+), 38 deletions(-)
---
diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am
index 4805c4d..9972fae 100644
--- a/data/icons/Makefile.am
+++ b/data/icons/Makefile.am
@@ -8,4 +8,5 @@ dist_icons_DATA = niepce-jpg-fmt.png niepce-raw-fmt.png niepce-rawjpeg-fmt.png\
        niepce-flag-pick.png niepce-flag-reject.png  \
        niepce-transform-rotate.png \
        niepce-image-generic.png \
+       niepce-missing.png \
        $(NULL)
diff --git a/data/icons/niepce-missing.png b/data/icons/niepce-missing.png
new file mode 100644
index 0000000..0cf9d1a
Binary files /dev/null and b/data/icons/niepce-missing.png differ
diff --git a/src/engine/db/libfile.rs b/src/engine/db/libfile.rs
index 34ebbc0..575c7b2 100644
--- a/src/engine/db/libfile.rs
+++ b/src/engine/db/libfile.rs
@@ -1,7 +1,7 @@
 /*
  * niepce - eng/db/libfile.rs
  *
- * Copyright (C) 2017 Hubert Figuière
+ * Copyright (C) 2017-2018 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -42,6 +42,14 @@ pub enum FileType {
     VIDEO = 4,
 }
 
+#[repr(i32)]
+#[derive(Debug, Clone, Copy, PartialEq)]
+/// FileStatus indicate the transient status of the file on the storage.
+pub enum FileStatus {
+    Ok = 0, /// Foo
+    Missing = 1,
+}
+
 impl From<i32> for FileType {
     fn from(t: i32) -> Self {
         match t {
diff --git a/src/engine/library/notification.rs b/src/engine/library/notification.rs
index 86c6618..1e12efe 100644
--- a/src/engine/library/notification.rs
+++ b/src/engine/library/notification.rs
@@ -1,7 +1,7 @@
 /*
  * niepce - engine/library/notification.rs
  *
- * Copyright (C) 2017 Hubert Figuière
+ * Copyright (C) 2017-2018 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,6 +23,9 @@ use engine::db::{
     LibraryId,
     Label, LibFolder, LibMetadata, Keyword
 };
+use engine::db::libfile::{
+    FileStatus,
+};
 
 use root::eng::QueriedContent;
 
@@ -51,6 +54,7 @@ pub enum NotificationType {
     LABEL_DELETED,
     XMP_NEEDS_UPDATE,
     FILE_MOVED,
+    FILE_STATUS_CHANGED,
 }
 
 #[repr(C)]
@@ -60,6 +64,12 @@ pub struct FileMove {
     pub to: LibraryId,
 }
 
+#[repr(C)]
+pub struct FileStatusChange {
+    pub id: LibraryId,
+    pub status: FileStatus,
+}
+
 #[repr(C)]
 pub struct Count {
     pub id: LibraryId,
@@ -92,6 +102,7 @@ pub enum Notification {
     AddedKeyword(Keyword),
     AddedLabel(Label),
     FileMoved(FileMove),
+    FileStatusChanged(FileStatusChange),
     FolderContentQueried(Content),
     FolderCounted(Count),
     FolderCountChanged(Count),
@@ -148,6 +159,7 @@ pub extern "C" fn engine_library_notification_type(n: *const Notification) -> No
         Some(&Notification::AddedKeyword(_)) => NotificationType::ADDED_KEYWORD,
         Some(&Notification::AddedLabel(_)) => NotificationType::ADDED_LABEL,
         Some(&Notification::FileMoved(_)) => NotificationType::FILE_MOVED,
+        Some(&Notification::FileStatusChanged(_)) => NotificationType::FILE_STATUS_CHANGED,
         Some(&Notification::FolderContentQueried(_)) => NotificationType::FOLDER_CONTENT_QUERIED,
         Some(&Notification::FolderCounted(_)) => NotificationType::FOLDER_COUNTED,
         Some(&Notification::FolderCountChanged(_)) => NotificationType::FOLDER_COUNT_CHANGE,
@@ -174,6 +186,7 @@ pub extern "C" fn engine_library_notification_get_id(n: *const Notification) ->
         Some(&Notification::MetadataChanged(ref changed)) => changed.id,
         Some(&Notification::FolderDeleted(id)) => id,
         Some(&Notification::LabelDeleted(id)) => id,
+        Some(&Notification::FileStatusChanged(ref changed)) => changed.id,
         _ => unreachable!(),
     }
 }
@@ -195,6 +208,14 @@ pub extern "C" fn engine_library_notification_get_filemoved(n: *const Notificati
     }
 }
 
+#[no_mangle]
+pub extern "C" fn engine_library_notification_get_filestatus(n: *const Notification) -> FileStatus {
+    match unsafe { n.as_ref() } {
+        Some(&Notification::FileStatusChanged(ref s)) => s.status,
+        _ => unreachable!()
+    }
+}
+
 #[no_mangle]
 pub extern "C" fn engine_library_notification_get_libmetadata(n: *const Notification) -> *const LibMetadata {
     match unsafe { n.as_ref() } {
diff --git a/src/niepce/ui/gridviewmodule.cpp b/src/niepce/ui/gridviewmodule.cpp
index 357f138..63f595b 100644
--- a/src/niepce/ui/gridviewmodule.cpp
+++ b/src/niepce/ui/gridviewmodule.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - ui/gridviewmodule.cpp
  *
- * Copyright (C) 2009-2017 Hubert Figuiere
+ * Copyright (C) 2009-2018 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -115,6 +115,8 @@ Gtk::Widget * GridViewModule::buildWidget()
                                   m_model->columns().m_pix.index());
   cell_area->add_attribute(*libcell, "libfile",
                                   m_model->columns().m_libfile.index());
+  cell_area->add_attribute(*libcell, "status",
+                                  m_model->columns().m_file_status.index());
 
   m_scrollview.add(*m_librarylistview);
   m_scrollview.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
diff --git a/src/niepce/ui/imageliststore.cpp b/src/niepce/ui/imageliststore.cpp
index fd23fd9..5d1c752 100644
--- a/src/niepce/ui/imageliststore.cpp
+++ b/src/niepce/ui/imageliststore.cpp
@@ -89,6 +89,18 @@ Gtk::TreePath ImageListStore::get_path_from_id(eng::library_id_t id)
     return Gtk::TreePath();
 }
 
+void ImageListStore::add_libfile(const eng::LibFilePtr & f)
+{
+    Gtk::TreeModel::iterator riter = append();
+    Gtk::TreeRow row = *riter;
+    Glib::RefPtr<Gdk::Pixbuf> icon = get_loading_icon();
+    row[m_columns.m_pix] = icon;
+    row[m_columns.m_libfile] = f;
+    row[m_columns.m_strip_thumb]
+        = fwk::gdkpixbuf_scale_to_fit(icon, 100);
+    row[m_columns.m_file_status] = eng::FileStatus::Ok;
+    m_idmap[engine_db_libfile_id(f.get())] = riter;
+}
 
 void ImageListStore::on_lib_notification(const eng::LibNotification &ln)
 {
@@ -110,17 +122,9 @@ void ImageListStore::on_lib_notification(const eng::LibNotification &ln)
         // clear the map before the list.
         m_idmap.clear();
         clear();
-        for_each(l->cbegin(), l->cend(),
-                 [this] (const eng::LibFilePtr & f) {
-                     Gtk::TreeModel::iterator riter = append();
-                     Gtk::TreeRow row = *riter;
-                     Glib::RefPtr<Gdk::Pixbuf> icon = get_loading_icon();
-                     row[m_columns.m_pix] = icon;
-                     row[m_columns.m_libfile] = f;
-                     row[m_columns.m_strip_thumb]
-                         = fwk::gdkpixbuf_scale_to_fit(icon, 100);
-                     m_idmap[engine_db_libfile_id(f.get())] = riter;
-                 });
+        for_each(l->cbegin(), l->cend(), [this] (const eng::LibFilePtr & f) {
+                this->add_libfile(f);
+            });
         // at that point clear the cache because the icon view is populated.
         getLibraryClient()->thumbnailCache().request(*l);
         break;
@@ -144,6 +148,17 @@ void ImageListStore::on_lib_notification(const eng::LibNotification &ln)
         }
         break;
     }
+    case eng::NotificationType::FILE_STATUS_CHANGED:
+    {
+        auto status = engine_library_notification_get_filestatus(&ln);
+        auto id = engine_library_notification_get_id(&ln);
+        auto iter = m_idmap.find(id);
+        if (iter != m_idmap.end()) {
+            Gtk::TreeRow row = *(iter->second);
+            row[m_columns.m_file_status] = status;
+        }
+        break;
+    }
     case eng::NotificationType::METADATA_CHANGED:
     {
         auto m = engine_library_notification_get_metadatachange(&ln);
diff --git a/src/niepce/ui/imageliststore.hpp b/src/niepce/ui/imageliststore.hpp
index 7ce67b5..4f29a04 100644
--- a/src/niepce/ui/imageliststore.hpp
+++ b/src/niepce/ui/imageliststore.hpp
@@ -36,28 +36,31 @@
 namespace ui {
 
 /** @brief the general list store */
-class ImageListStore 
+class ImageListStore
     : public Gtk::ListStore
 {
 public:
-    class Columns 
+    class Columns
         : public Gtk::TreeModelColumnRecord
     {
     public:
         enum {
             THUMB_INDEX = 0,
             FILE_INDEX = 1,
-            STRIP_THUMB_INDEX = 2
+            STRIP_THUMB_INDEX = 2,
+            FILE_STATUS_INDEX = 3
         };
         Columns()
-            { 
+            {
                 add(m_pix);
                 add(m_libfile);
                 add(m_strip_thumb);
+                add(m_file_status);
             }
         Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > m_pix;
         Gtk::TreeModelColumn<eng::LibFilePtr> m_libfile;
         Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > m_strip_thumb;
+        Gtk::TreeModelColumn<eng::FileStatus> m_file_status;
     };
 
     const Columns & columns() const
@@ -77,6 +80,9 @@ public:
 protected:
     ImageListStore(const Columns& columns);
 private:
+    /// Add the LibFile to the model
+    void add_libfile(const eng::LibFilePtr & f);
+
     static Glib::RefPtr<Gdk::Pixbuf> get_loading_icon();
     libraryclient::LibraryClientPtr getLibraryClient();
     static bool is_property_interesting(fwk::PropertyIndex idx);
diff --git a/src/niepce/ui/librarycellrenderer.cpp b/src/niepce/ui/librarycellrenderer.cpp
index 209aee7..c27ffac 100644
--- a/src/niepce/ui/librarycellrenderer.cpp
+++ b/src/niepce/ui/librarycellrenderer.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - ui/librarycellrenderer.cpp
  *
- * Copyright (C) 2008-2017 Hubert Figuière
+ * Copyright (C) 2008-2018 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,27 +47,31 @@ LibraryCellRenderer::LibraryCellRenderer(const IModuleShell& shell)
       m_drawemblem(true),
       m_drawrating(true),
       m_drawlabel(true),
-      m_drawflag(true),
-      m_libfileproperty(*this, "libfile")
+      m_drawflag(true), m_drawstatus(true),
+      m_libfileproperty(*this, "libfile"),
+      m_statusproperty(*this, "status")
 {
     property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE;
     try {
-        m_raw_format_emblem 
+        m_raw_format_emblem
             = Cairo::ImageSurface::create_from_png(
                 std::string(DATADIR"/niepce/pixmaps/niepce-raw-fmt.png"));
-        m_rawjpeg_format_emblem 
+        m_rawjpeg_format_emblem
             = Cairo::ImageSurface::create_from_png(
                 std::string(DATADIR"/niepce/pixmaps/niepce-rawjpeg-fmt.png"));
-        m_img_format_emblem 
+        m_img_format_emblem
             = Cairo::ImageSurface::create_from_png(
-                std::string(DATADIR"/niepce/pixmaps/niepce-img-fmt.png"));     
-        m_video_format_emblem 
+                std::string(DATADIR"/niepce/pixmaps/niepce-img-fmt.png"));
+        m_video_format_emblem
             = Cairo::ImageSurface::create_from_png(
                 std::string(DATADIR"/niepce/pixmaps/niepce-video-fmt.png"));
-        m_unknown_format_emblem 
+        m_unknown_format_emblem
             = Cairo::ImageSurface::create_from_png(
                 std::string(DATADIR"/niepce/pixmaps/niepce-unknown-fmt.png"));
 
+        m_status_missing
+            = Cairo::ImageSurface::create_from_png(
+                std::string(DATADIR"/niepce/pixmaps/niepce-missing.png"));
         m_flag_reject
             = Cairo::ImageSurface::create_from_png(
                 std::string(DATADIR"/niepce/pixmaps/niepce-flag-reject.png"));
@@ -116,6 +120,17 @@ void LibraryCellRenderer::_drawThumbnail(const Cairo::RefPtr<Cairo::Context> & c
 }
 
 
+void LibraryCellRenderer::draw_status(const Cairo::RefPtr<Cairo::Context> & cr,
+                                      eng::FileStatus status, double x, double y) const
+{
+    if (status == eng::FileStatus::Ok) {
+        return;
+    }
+
+    cr->set_source(m_status_missing, x, y);
+    cr->paint();
+}
+
 void LibraryCellRenderer::_drawFlag(const Cairo::RefPtr<Cairo::Context> & cr, 
                    int flag_value, double x, double y)
 {
@@ -247,6 +262,13 @@ LibraryCellRenderer::render_vfunc(const Cairo::RefPtr<Cairo::Context>& cr,
         _drawFlag(cr, engine_db_libfile_flag(file.get()), x, y);
     }
 
+    auto status = m_statusproperty.get_value();
+    if (m_drawstatus && status != eng::FileStatus::Ok) {
+        double x = r.x + CELL_PADDING;
+        double y = r.y + CELL_PADDING;
+        draw_status(cr, status, 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 9d1528b..58cafc9 100644
--- a/src/niepce/ui/librarycellrenderer.hpp
+++ b/src/niepce/ui/librarycellrenderer.hpp
@@ -1,7 +1,7 @@
 /*
  * niepce - ui/librarycellrenderer.h
  *
- * Copyright (C) 2008,2011 Hubert Figuiere
+ * Copyright (C) 2008-2018 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,10 +17,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-
-
-#ifndef __UI_LIBRARY_CELL_RENDERER_H__
-#define __UI_LIBRARY_CELL_RENDERER_H__
+#pragma once
 
 #include <glibmm/property.h>
 #include <gtkmm/cellrendererpixbuf.h>
@@ -77,11 +74,14 @@ public:
     sigc::signal<void, int, int> signal_rating_changed;
 protected:
     /* drawing implementations */
-    void _drawThumbnail(const Cairo::RefPtr<Cairo::Context> & cr, 
+    void _drawThumbnail(const Cairo::RefPtr<Cairo::Context> & cr,
                         Glib::RefPtr<Gdk::Pixbuf> & pixbuf,
                         const GdkRectangle & r);
-    void _drawFlag(const Cairo::RefPtr<Cairo::Context> & cr, 
+    void _drawFlag(const Cairo::RefPtr<Cairo::Context> & cr,
                    int flag_value, double x, double y);
+    void draw_status(const Cairo::RefPtr<Cairo::Context> & cr,
+                     eng::FileStatus status, double x, double y) const;
+
 private:
     const IModuleShell& m_shell;
     int                                 m_size;
@@ -91,7 +91,9 @@ private:
     bool                                m_drawrating;
     bool                                m_drawlabel;
     bool                                m_drawflag;
+    bool m_drawstatus;
     Glib::Property<eng::LibFilePtr>   m_libfileproperty;
+    Glib::Property<eng::FileStatus> m_statusproperty;
 
     Cairo::RefPtr<Cairo::ImageSurface>  m_raw_format_emblem;
     Cairo::RefPtr<Cairo::ImageSurface>  m_rawjpeg_format_emblem;
@@ -99,6 +101,8 @@ private:
     Cairo::RefPtr<Cairo::ImageSurface>  m_video_format_emblem;
     Cairo::RefPtr<Cairo::ImageSurface>  m_unknown_format_emblem;
 
+    Cairo::RefPtr<Cairo::ImageSurface>  m_status_missing;
+
     Cairo::RefPtr<Cairo::ImageSurface>  m_flag_reject;
     Cairo::RefPtr<Cairo::ImageSurface>  m_flag_pick;
 };
@@ -115,5 +119,3 @@ private:
   fill-column:80
   End:
 */
-
-#endif
diff --git a/src/niepce/ui/thumbstripview.cpp b/src/niepce/ui/thumbstripview.cpp
index b78caa6..ca2fa56 100644
--- a/src/niepce/ui/thumbstripview.cpp
+++ b/src/niepce/ui/thumbstripview.cpp
@@ -1,7 +1,7 @@
 /* Eye Of Gnome - Thumbnail View
  *
  * Copyright (C) 2006 The Free Software Foundation
- * Copyright (C) 2007-2017 Hubert Figuière
+ * Copyright (C) 2007-2018 Hubert Figuière
  *
  * C++-ization: Hubert Figuiere <hub figuiere net>
  * Original Author: Claudio Saavedra <csaavedra alumnos utalca cl>
@@ -95,6 +95,8 @@ ThumbStripView::ThumbStripView(const Glib::RefPtr<ui::ImageListStore> & store,
                   ui::ImageListStore::Columns::STRIP_THUMB_INDEX);
     add_attribute(*m_renderer, "libfile",
                   ui::ImageListStore::Columns::FILE_INDEX);
+    add_attribute(*m_renderer, "status",
+                  ui::ImageListStore::Columns::FILE_STATUS_INDEX);
     set_selection_mode(Gtk::SELECTION_MULTIPLE);
     set_column_spacing(THUMB_STRIP_VIEW_SPACING);
 
diff --git a/src/rust_bindings.hpp b/src/rust_bindings.hpp
index 1a96b1d..8370d72 100644
--- a/src/rust_bindings.hpp
+++ b/src/rust_bindings.hpp
@@ -1,7 +1,7 @@
 /*
  * niepce - rust_bindings.hpp
  *
- * Copyright (C) 2017 Hubert Figuiere
+ * Copyright (C) 2017-2018 Hubert Figuiere
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -60,6 +60,7 @@ typedef ffi::RgbColour RgbColour;
 namespace eng {
 typedef ffi::LibraryId library_id_t; // XXX change this to LibraryId
 typedef ffi::FileType FileType;
+typedef ffi::FileStatus FileStatus;
 typedef ffi::Keyword Keyword;
 typedef ffi::LibFile LibFile;
 typedef ffi::LibFolder LibFolder;


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