[glom/glom-1-22] DbAddDel: Replace use of TreeView::remove_all_columns().



commit be48bb89cfe92bdac8dd2adefb5f425f8e706e9b
Author: Murray Cumming <murrayc murrayc com>
Date:   Wed Oct 30 14:51:45 2013 +0100

    DbAddDel: Replace use of TreeView::remove_all_columns().
    
    * glom/utils_ui.[h|cc]:
      Add a treeview_delete_all_columns() method to explicitly
      delete the columns instead of just removing them and sometimes
      implicitly deleting them with Gtk::TreeView::remove_all_columns().
    * glom/mode_data/db_adddel/db_adddel.[h|cc]:
    * glom/utility_widgets/adddel/adddel.cc:
    * glom/import_csv/dialog_import_csv.cc: Use it.
    
    This seems to fix a crash when switching between Data and Find mode,
    though that might just have been due to not resetting the pointer
    to the button column.

 glom/import_csv/dialog_import_csv.cc  |    6 ++--
 glom/mode_data/db_adddel/db_adddel.cc |   13 +++++++++-
 glom/mode_data/db_adddel/db_adddel.h  |    2 +
 glom/utility_widgets/adddel/adddel.cc |    2 +-
 glom/utils_ui.cc                      |   41 +++++++++++++++++++++++++++++++++
 glom/utils_ui.h                       |    3 ++
 6 files changed, 61 insertions(+), 6 deletions(-)
---
diff --git a/glom/import_csv/dialog_import_csv.cc b/glom/import_csv/dialog_import_csv.cc
index fe0b1f5..829f667 100644
--- a/glom/import_csv/dialog_import_csv.cc
+++ b/glom/import_csv/dialog_import_csv.cc
@@ -252,7 +252,7 @@ void Dialog_Import_CSV::clear()
   // TODO: Do we explicitely need to cancel async operations?
   // TODO: Disconnect idle handlers
   m_sample_model.reset();
-  m_sample_view->remove_all_columns();
+  Utils::treeview_delete_all_columns(m_sample_view);
   m_sample_view->set_model(m_sample_model);
   m_field_model.reset();
   m_field_model_sorted.reset();
@@ -433,7 +433,7 @@ void Dialog_Import_CSV::begin_parse()
   // Clear sample preview since we reparse everything, perhaps with
   // another encoding.
   m_sample_model.reset();
-  m_sample_view->remove_all_columns();
+  Utils::treeview_delete_all_columns(m_sample_view);
   m_sample_view->set_model(m_sample_model); // Empty model
   m_parser->clear();
 
@@ -450,7 +450,7 @@ void Dialog_Import_CSV::on_parser_encoding_error()
   m_parser->clear();
   // Clear sample preview (TODO: Let it visible, and only remove when reparsing?)
   m_sample_model.reset();
-  m_sample_view->remove_all_columns();
+  Utils::treeview_delete_all_columns(m_sample_view);
   m_sample_view->set_model(m_sample_model); // Empty model
 
   // Don't allow the import button to be pressed when an error occured. This
diff --git a/glom/mode_data/db_adddel/db_adddel.cc b/glom/mode_data/db_adddel/db_adddel.cc
index cb70fb6..2db276b 100644
--- a/glom/mode_data/db_adddel/db_adddel.cc
+++ b/glom/mode_data/db_adddel/db_adddel.cc
@@ -677,7 +677,7 @@ void DbAddDel::construct_specified_columns()
   m_TreeView.set_model(m_refListStore); // clear old model from treeview
 
   //Remove all View columns:
-  m_TreeView.remove_all_columns();
+  treeview_delete_all_columns();
 
 
   //Add new View Colums:
@@ -2084,7 +2084,7 @@ void DbAddDel::set_open_button_title(const Glib::ustring& title)
 
 void DbAddDel::show_hint_model()
 {
-  m_TreeView.remove_all_columns();
+  treeview_delete_all_columns();
   m_treeviewcolumn_button = 0; //When we removed the view columns, this was deleted because it's manage()ed.
 
   m_model_hint = Gtk::ListStore::create(m_columns_hint);
@@ -2470,4 +2470,13 @@ void DbAddDel::on_selection_changed(bool selection)
   m_signal_record_selection_changed.emit();
 }
 
+void DbAddDel::treeview_delete_all_columns()
+{
+  Utils::treeview_delete_all_columns(&m_TreeView);
+
+  //Reset this too, because we must have just deleted it:
+  m_treeviewcolumn_button = 0;
+}
+
+
 } //namespace Glom
diff --git a/glom/mode_data/db_adddel/db_adddel.h b/glom/mode_data/db_adddel/db_adddel.h
index dfc4b6f..01473af 100644
--- a/glom/mode_data/db_adddel/db_adddel.h
+++ b/glom/mode_data/db_adddel/db_adddel.h
@@ -433,6 +433,8 @@ protected:
 
 private:
 
+  void treeview_delete_all_columns();
+
   bool m_find_mode;
   bool m_allow_only_one_related_record;
 
diff --git a/glom/utility_widgets/adddel/adddel.cc b/glom/utility_widgets/adddel/adddel.cc
index 7697f86..ce76a1e 100644
--- a/glom/utility_widgets/adddel/adddel.cc
+++ b/glom/utility_widgets/adddel/adddel.cc
@@ -611,7 +611,7 @@ void AddDel::construct_specified_columns()
   m_TreeView.set_model(m_refListStore);
 
   //Remove all View columns:
-  m_TreeView.remove_all_columns();
+  Utils::treeview_delete_all_columns(&m_TreeView);
 
   //Add new View Colums:
   int model_column_index = 0;
diff --git a/glom/utils_ui.cc b/glom/utils_ui.cc
index 80c57ed..624565b 100644
--- a/glom/utils_ui.cc
+++ b/glom/utils_ui.cc
@@ -546,4 +546,45 @@ bool Utils::script_check_for_pygtk2_with_warning(const Glib::ustring& script, Gt
   return true;
 }
 
+void Utils::treeview_delete_all_columns(Gtk::TreeView* treeview)
+{
+  if(!treeview)
+    return;
+
+  //We use this instead of just Gtk::TreeView::remove_all_columns()
+  //because that deletes columns as a side-effect of unreferencing them,
+  //and that behaviour might be fixed in gtkmm sometime,
+  //and whether they should be deleted by that would depend on whether we used Gtk::manage().
+  //Deleting them explicitly is safer and clearer. murrayc.
+
+  //Remove all View columns:
+  typedef std::vector<Gtk::TreeView::Column*> type_vec_columns;
+  type_vec_columns vecViewColumns (treeview->get_columns());
+
+  for (type_vec_columns::iterator iter (vecViewColumns.begin ()), columns_end (vecViewColumns.end ());
+    iter != columns_end;
+    ++iter)
+  {
+    Gtk::TreeView::Column* pViewColumn (*iter);
+    if(!pViewColumn)
+      continue;
+
+    GtkTreeViewColumn* weak_ptr = 0;
+    g_object_add_weak_pointer (G_OBJECT (pViewColumn->gobj()), (gpointer*)&weak_ptr);
+
+    //Keep the object alive, instead of letting gtk_tree_view_remove_column() delete it by reducing its 
reference to 0,
+    //so we can explicitly delete it.
+    //This feels safer, considering some strange crashes I've seen when using 
Gtk::TreeView::remove_all_columns(),
+    //though that might have been just because we didn't reset m_treeviewcolumn_button. murrayc.
+    pViewColumn->reference();
+    treeview->remove_column(*pViewColumn);
+    delete pViewColumn; //This should cause it to be removed.
+
+    if(weak_ptr)
+    {
+      std::cerr << G_STRFUNC << ": The GtkTreeViewColumn was not destroyed as expected." << std::endl;
+    }
+  }
+}
+
 } //namespace Glom
diff --git a/glom/utils_ui.h b/glom/utils_ui.h
index fb12000..128cd19 100644
--- a/glom/utils_ui.h
+++ b/glom/utils_ui.h
@@ -23,6 +23,7 @@
 
 #include "config.h"
 #include <gtkmm/dialog.h>
+#include <gtkmm/treeview.h>
 #include <libglom/data_structure/field.h>
 #include <libglom/data_structure/numeric_format.h>
 
@@ -103,6 +104,8 @@ std::string get_icon_path(const Glib::ustring& filename);
  */
 bool script_check_for_pygtk2_with_warning(const Glib::ustring& script, Gtk::Window* parent_window);
 
+void treeview_delete_all_columns(Gtk::TreeView* treeview);
+
 } //namespace Utils
 
 } //namespace Glom


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