[niepce] Fix the strip view where only one item would be displayed or it would crash. This is a bug caused by



commit 4c7867c4a7756d082cb24eec173d5ccf5e62713a
Author: Hubert Figuière <hub figuiere net>
Date:   Tue Jun 18 19:14:25 2013 -0400

    Fix the strip view where only one item would be displayed or it would
    crash. This is a bug caused by internal changes in GtkIconView between
    3.2 and 3.4.
    
    The ThumbStripView is now implementing Gtk::Orientable.

 src/niepce/ui/filmstripcontroller.cpp      |   30 ++++++----
 src/niepce/ui/imageliststore.hpp           |    2 +
 src/niepce/ui/librarycellrenderer.cpp      |    2 +-
 src/niepce/ui/thumb-view/eog-thumb-nav.cpp |   14 +++--
 src/niepce/ui/thumb-view/eog-thumb-nav.hpp |    4 +-
 src/niepce/ui/thumbstripview.cpp           |   86 +++++++++++++++++++++-------
 src/niepce/ui/thumbstripview.hpp           |   30 +++++++++-
 7 files changed, 125 insertions(+), 43 deletions(-)
---
diff --git a/src/niepce/ui/filmstripcontroller.cpp b/src/niepce/ui/filmstripcontroller.cpp
index ac51460..73477aa 100644
--- a/src/niepce/ui/filmstripcontroller.cpp
+++ b/src/niepce/ui/filmstripcontroller.cpp
@@ -43,7 +43,7 @@ Gtk::Widget * FilmStripController::buildWidget(const Glib::RefPtr<Gtk::UIManager
     }
     DBG_ASSERT(m_store, "m_store NULL");
     m_thumbview = manage(new ThumbStripView(m_store));
-    GtkWidget *thn = eog_thumb_nav_new(m_thumbview, 
+    GtkWidget *thn = eog_thumb_nav_new(m_thumbview,
                                        EOG_THUMB_NAV_MODE_ONE_ROW, true);
     m_thumbview->set_selection_mode(Gtk::SELECTION_SINGLE);
     m_widget = Glib::wrap(thn);
@@ -51,8 +51,8 @@ Gtk::Widget * FilmStripController::buildWidget(const Glib::RefPtr<Gtk::UIManager
     return m_widget;
 }
 
-Gtk::IconView * FilmStripController::image_list() 
-{ 
+Gtk::IconView * FilmStripController::image_list()
+{
     return m_thumbview;
 }
 
@@ -61,18 +61,22 @@ eng::library_id_t FilmStripController::get_selected()
     eng::library_id_t id = 0;
     DBG_OUT("get selected in filmstrip");
     std::vector<Gtk::TreePath> paths = m_thumbview->get_selected_items();
-    if(!paths.empty()) {
-        Gtk::TreePath path(*(paths.begin()));
-        DBG_OUT("found path %s", path.to_string().c_str());
-        Gtk::TreeRow row = *(m_store->get_iter(path));
-        if(row) {
-            DBG_OUT("found row");
-            eng::LibFile::Ptr libfile = row[m_store->columns().m_libfile];
-            if(libfile) {
-                id = libfile->id();
-            }
+
+    if(paths.empty()) {
+        return 0;
+    }
+
+    Gtk::TreePath path(*(paths.begin()));
+    DBG_OUT("found path %s", path.to_string().c_str());
+    Gtk::TreeRow row = *(m_store->get_iter(path));
+    if(row) {
+        DBG_OUT("found row");
+        eng::LibFile::Ptr libfile = row[m_store->columns().m_libfile];
+        if(libfile) {
+            id = libfile->id();
         }
     }
+
     return id;
 }
 
diff --git a/src/niepce/ui/imageliststore.hpp b/src/niepce/ui/imageliststore.hpp
index 34a84eb..025d0b2 100644
--- a/src/niepce/ui/imageliststore.hpp
+++ b/src/niepce/ui/imageliststore.hpp
@@ -63,6 +63,8 @@ public:
         { return m_columns; }
     Gtk::TreePath get_path_from_id(eng::library_id_t id);
     Gtk::TreeIter get_iter_from_id(eng::library_id_t id);
+    size_t get_count() const
+        { return children().size(); }
 
     static Glib::RefPtr<ImageListStore> create();
 
diff --git a/src/niepce/ui/librarycellrenderer.cpp b/src/niepce/ui/librarycellrenderer.cpp
index a90df98..093ae34 100644
--- a/src/niepce/ui/librarycellrenderer.cpp
+++ b/src/niepce/ui/librarycellrenderer.cpp
@@ -1,7 +1,7 @@
 /*
  * niepce - ui/librarycellrenderer.cpp
  *
- * Copyright (C) 2008, 2011, 2013 Hubert Figuiere
+ * Copyright (C) 2008-2013 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
diff --git a/src/niepce/ui/thumb-view/eog-thumb-nav.cpp b/src/niepce/ui/thumb-view/eog-thumb-nav.cpp
index b2ff328..85fecd3 100644
--- a/src/niepce/ui/thumb-view/eog-thumb-nav.cpp
+++ b/src/niepce/ui/thumb-view/eog-thumb-nav.cpp
@@ -1,7 +1,7 @@
 /* Eye Of Gnome - Thumbnail Navigator
  *
  * Copyright (C) 2006 The Free Software Foundation
- * Copyright (C) 2009 Hubert Figuiere
+ * Copyright (C) 2009-2013 Hubert Figuiere
  *
  * Original author: Lucas Rocha <lucasr gnome org>
  *
@@ -37,7 +37,7 @@
 #define EOG_THUMB_NAV_GET_PRIVATE(object) \
        (G_TYPE_INSTANCE_GET_PRIVATE ((object), EOG_TYPE_THUMB_NAV, EogThumbNavPrivate))
 
-G_DEFINE_TYPE (EogThumbNav, eog_thumb_nav, GTK_TYPE_HBOX)
+G_DEFINE_TYPE (EogThumbNav, eog_thumb_nav, GTK_TYPE_BOX)
 
 #define EOG_THUMB_NAV_SCROLL_INC     1
 #define EOG_THUMB_NAV_SCROLL_MOVE    20
@@ -59,7 +59,7 @@ struct _EogThumbNavPrivate {
        GtkWidget        *button_right;
        GtkWidget        *sw;
        GtkWidget        *scale;
-  ui::ThumbStripView   *thumbview;
+       ui::ThumbStripView   *thumbview;
 };
 
 static void
@@ -247,7 +247,7 @@ eog_thumb_nav_constructor (GType type,
 
        if (priv->thumbview != NULL) {
                gtk_container_add (GTK_CONTAINER (priv->sw), 
-                       (GtkWidget*)priv->thumbview->gobj());
+                                  (GtkWidget*)priv->thumbview->Gtk::IconView::gobj());
                gtk_widget_show_all (priv->sw);
        }
 
@@ -431,7 +431,8 @@ eog_thumb_nav_set_mode (EogThumbNav *nav, EogThumbNavMode mode)
        switch (mode)
        {
        case EOG_THUMB_NAV_MODE_ONE_ROW:
-               priv->thumbview->set_columns (G_MAXINT);
+//             priv->thumbview->set_columns (-1);
+               priv->thumbview->set_orientation(Gtk::ORIENTATION_HORIZONTAL);
 
                priv->thumbview->set_size_request (-1, -1);
                priv->thumbview->set_item_height (100);
@@ -445,6 +446,7 @@ eog_thumb_nav_set_mode (EogThumbNav *nav, EogThumbNavMode mode)
                break;
 
        case EOG_THUMB_NAV_MODE_ONE_COLUMN:
+               priv->thumbview->set_orientation(Gtk::ORIENTATION_VERTICAL);
                priv->thumbview->set_columns (1);
 
                priv->thumbview->set_size_request (-1, -1);
@@ -460,6 +462,7 @@ eog_thumb_nav_set_mode (EogThumbNav *nav, EogThumbNavMode mode)
                break;
 
        case EOG_THUMB_NAV_MODE_MULTIPLE_ROWS:
+               priv->thumbview->set_orientation(Gtk::ORIENTATION_VERTICAL);
                priv->thumbview->set_columns (-1);
 
                priv->thumbview->set_size_request (-1, -1);
@@ -475,6 +478,7 @@ eog_thumb_nav_set_mode (EogThumbNav *nav, EogThumbNavMode mode)
                break;
 
        case EOG_THUMB_NAV_MODE_MULTIPLE_COLUMNS:
+               priv->thumbview->set_orientation(Gtk::ORIENTATION_VERTICAL);
                priv->thumbview->set_columns (-1);
 
                priv->thumbview->set_size_request (-1, -1);
diff --git a/src/niepce/ui/thumb-view/eog-thumb-nav.hpp b/src/niepce/ui/thumb-view/eog-thumb-nav.hpp
index 8981d38..f18ca00 100644
--- a/src/niepce/ui/thumb-view/eog-thumb-nav.hpp
+++ b/src/niepce/ui/thumb-view/eog-thumb-nav.hpp
@@ -49,13 +49,13 @@ typedef enum {
 } EogThumbNavMode;
 
 struct _EogThumbNav {
-       GtkHBox base_instance;
+       GtkBox base_instance;
 
        EogThumbNavPrivate *priv;
 };
 
 struct _EogThumbNavClass {
-       GtkHBoxClass parent_class;
+       GtkBoxClass parent_class;
 };
 
 GType           eog_thumb_nav_get_type          (void) G_GNUC_CONST;
diff --git a/src/niepce/ui/thumbstripview.cpp b/src/niepce/ui/thumbstripview.cpp
index 52377cb..83af1f3 100644
--- a/src/niepce/ui/thumbstripview.cpp
+++ b/src/niepce/ui/thumbstripview.cpp
@@ -62,7 +62,6 @@ public:
     ThumbStripCell();
 };
 
-
 ThumbStripCell::ThumbStripCell()
     : Glib::ObjectBase(typeid(ThumbStripCell))
     , LibraryCellRenderer(NULL)
@@ -76,22 +75,30 @@ ThumbStripCell::ThumbStripCell()
     set_drawflag(false);
 }
 
-
+ThumbStripViewBase::ThumbStripViewBase(const Glib::RefPtr<ui::ImageListStore> & store)
+    : Glib::ObjectBase(typeid(ThumbStripViewBase))
+    , Gtk::IconView(Glib::RefPtr<Gtk::TreeModel>::cast_dynamic(store))
+    , m_orientation_property(*this, "orientation")
+{
+}
 
 ThumbStripView::ThumbStripView(const Glib::RefPtr<ui::ImageListStore> & store)
-    : IconView(Glib::RefPtr<Gtk::TreeModel>::cast_dynamic(store))
+    : Glib::ObjectBase(typeid(ThumbStripView))
+    , ThumbStripViewBase(store)
+    , Gtk::Orientable()
     , m_start_thumb(0)
     , m_end_thumb(0)
     , m_store(store)
+    , m_model_item_count(0)
 {
-    m_renderer = new ThumbStripCell();
+    m_renderer = manage(new ThumbStripCell());
 
     pack_start(*m_renderer, FALSE);
     m_renderer->property_follow_state() = true;
     m_renderer->property_height() = 100;
     m_renderer->property_yalign() = 0.5;
     m_renderer->property_xalign() = 0.5;
-       
+
     add_attribute(*m_renderer, "pixbuf",
                   ui::ImageListStore::Columns::STRIP_THUMB_INDEX);
     add_attribute(*m_renderer, "libfile",
@@ -109,19 +116,58 @@ ThumbStripView::ThumbStripView(const Glib::RefPtr<ui::ImageListStore> & store)
 
 //  signal_drag_data_get().connect(
 //      sigc::mem_fun(*this, &ThumbStripView::on_drag_data_get));
+
+    setup_model(store);
 }
 
 void ThumbStripView::set_model(const Glib::RefPtr<ui::ImageListStore> & store)
 {
     m_store = store;
+    setup_model(store);
     IconView::set_model(store);
 }
 
+void ThumbStripView::setup_model(const Glib::RefPtr<ui::ImageListStore> & store)
+{
+    m_model_add.disconnect();
+    m_model_rm.disconnect();
+
+    m_model_item_count = m_store->get_count();
+    update_item_count();
+
+    m_model_add = store->signal_row_inserted()
+        .connect(sigc::mem_fun(*this, &ThumbStripView::row_added));
+    m_model_rm = store->signal_row_deleted()
+        .connect(sigc::mem_fun(*this, &ThumbStripView::row_deleted));
+}
+
 const Glib::RefPtr<ui::ImageListStore> & ThumbStripView::get_model() const
 {
     return m_store;
 }
 
+void ThumbStripView::row_added(const Gtk::TreeModel::Path&,
+                               const Gtk::TreeModel::iterator&)
+{
+    m_model_item_count++;
+    update_item_count();
+}
+
+void ThumbStripView::row_deleted(const Gtk::TreeModel::Path&)
+{
+    if(m_model_item_count) {
+        m_model_item_count--;
+        update_item_count();
+    }
+}
+
+void ThumbStripView::update_item_count()
+{
+    if (get_orientation() == Gtk::ORIENTATION_HORIZONTAL) {
+        set_columns(m_model_item_count);
+    }
+}
+
 void
 ThumbStripView::clear_range (int start_thumb, int end_thumb)
 {
@@ -159,12 +205,12 @@ ThumbStripView::update_visible_range (int start_thumb, int end_thumb)
 
     old_start_thumb = m_start_thumb;
     old_end_thumb = m_end_thumb;
-       
+
     if (start_thumb == old_start_thumb &&
         end_thumb == old_end_thumb) {
         return;
     }
-       
+
     if (old_start_thumb < start_thumb)
         clear_range (old_start_thumb, MIN (start_thumb - 1, old_end_thumb));
 
@@ -172,7 +218,7 @@ ThumbStripView::update_visible_range (int start_thumb, int end_thumb)
         clear_range (MAX (end_thumb + 1, old_start_thumb), old_end_thumb);
 
     add_range (start_thumb, end_thumb);
-       
+
     m_start_thumb = start_thumb;
     m_end_thumb = end_thumb;
 }
@@ -185,7 +231,7 @@ ThumbStripView::on_visible_range_changed()
     if (!get_visible_range (path1, path2)) {
         return;
     }
-               
+
     update_visible_range (path1[0], path2[0]);
 }
 
@@ -194,7 +240,7 @@ ThumbStripView::on_adjustment_changed ()
 {
     Gtk::TreePath path1, path2;
     int start_thumb, end_thumb;
-       
+
     if (!get_visible_range (path1, path2)) {
         return;
     }
@@ -202,7 +248,7 @@ ThumbStripView::on_adjustment_changed ()
     start_thumb = path1 [0];
     end_thumb = path2 [0];
 
-    add_range (start_thumb, end_thumb);        
+    add_range (start_thumb, end_thumb);
 
     /* case we added an image, we need to make sure that the shifted thumbnail is cleared */
     clear_range (end_thumb + 1, end_thumb + 1);
@@ -214,27 +260,27 @@ ThumbStripView::on_adjustment_changed ()
 void
 ThumbStripView::on_parent_set (Gtk::Widget */*old_parent*/)
 {
-    Gtk::ScrolledWindow *sw;
-    Glib::RefPtr<Gtk::Adjustment> hadjustment;
-    Glib::RefPtr<Gtk::Adjustment> vadjustment;
-
     Gtk::Widget *parent = get_parent ();
-    sw = dynamic_cast<Gtk::ScrolledWindow*>(parent);
+    Gtk::ScrolledWindow *sw = dynamic_cast<Gtk::ScrolledWindow*>(parent);
     if (!sw) {
+        // TODO shouldn't we disconnect all of that?
         return;
     }
-       
+
+    Glib::RefPtr<Gtk::Adjustment> hadjustment;
+    Glib::RefPtr<Gtk::Adjustment> vadjustment;
+
     /* if we have been set to a ScrolledWindow, we connect to the callback
        to set and unset thumbnails. */
     hadjustment = sw->get_hadjustment ();
     vadjustment = sw->get_vadjustment ();
-       
+
     /* when scrolling */
     hadjustment->signal_value_changed().connect(
         sigc::mem_fun(*this, &ThumbStripView::on_visible_range_changed));
     vadjustment->signal_value_changed().connect(
         sigc::mem_fun(*this, &ThumbStripView::on_visible_range_changed));
-       
+
     /* when the adjustment is changed, ie. probably we have new images added. */
     hadjustment->signal_changed().connect(
         sigc::mem_fun(*this, &ThumbStripView::on_adjustment_changed));
@@ -243,7 +289,7 @@ ThumbStripView::on_parent_set (Gtk::Widget */*old_parent*/)
 
     /* when resizing the scrolled window */
     sw->signal_size_allocate().connect(
-        sigc::hide<0>(sigc::mem_fun(*this, 
+        sigc::hide<0>(sigc::mem_fun(*this,
                                     &ThumbStripView::on_visible_range_changed)));
 }
 
diff --git a/src/niepce/ui/thumbstripview.hpp b/src/niepce/ui/thumbstripview.hpp
index e6ae618..e46d94a 100644
--- a/src/niepce/ui/thumbstripview.hpp
+++ b/src/niepce/ui/thumbstripview.hpp
@@ -1,7 +1,7 @@
 /*
  * niepce - niepce/ui/thumbstripview.hpp
  *
- * Copyright (C) 2009 Hubert Figuiere
+ * Copyright (C) 2009-2013 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
@@ -20,15 +20,31 @@
 #ifndef _THUMB_STRIP_VIEW_HPP_
 #define _THUMB_STRIP_VIEW_HPP_
 
+#include <glibmm/property.h>
+
 #include <gtkmm/iconview.h>
+#include <gtkmm/orientable.h>
 #include <gtkmm/cellrendererpixbuf.h>
 
 #include "niepce/ui/imageliststore.hpp"
 
 namespace ui {
 
+/** This is needed to implement the property
+ * That must be registered before the Interface is registered
+ */
+class ThumbStripViewBase
+    : public Gtk::IconView
+{
+protected:
+    ThumbStripViewBase(const Glib::RefPtr<ui::ImageListStore> & store);
+
+    Glib::Property<Gtk::Orientation> m_orientation_property;
+};
+
 class ThumbStripView
-  : public Gtk::IconView
+  : public ThumbStripViewBase
+  , public Gtk::Orientable
 {
 public:
     ThumbStripView(const Glib::RefPtr<ui::ImageListStore> & store);
@@ -47,10 +63,20 @@ private:
     void add_range(int, int);
     void clear_range (int start_thumb, int end_thumb);
 
+    void setup_model(const Glib::RefPtr<ui::ImageListStore> & store);
+    void row_added(const Gtk::TreeModel::Path&,
+                   const Gtk::TreeModel::iterator&);
+    void row_deleted(const Gtk::TreeModel::Path&);
+    void update_item_count();
+
     gint m_start_thumb; /* the first visible thumbnail */
     gint m_end_thumb;   /* the last visible thumbnail  */
     Glib::RefPtr<ui::ImageListStore> m_store;
     Gtk::CellRendererPixbuf  *m_renderer;
+
+    int m_model_item_count;
+    sigc::connection m_model_add;
+    sigc::connection m_model_rm;
 };
 
 


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