[glom/spread-table] FlowTable: More fixes for child HBox memory management.



commit 9711c2dc5382e50c73f129423346c82797f96023
Author: Murray Cumming <murrayc murrayc com>
Date:   Thu Oct 14 11:04:41 2010 +0200

    FlowTable: More fixes for child HBox memory management.
    
    * glom/utility_widgets/flowtable.cc: Added checks and corrections, though
      there is still an odd warning about a refcount.

 ChangeLog                         |    7 ++++
 glom/utility_widgets/flowtable.cc |   62 +++++++++++++++++++++++++------------
 2 files changed, 49 insertions(+), 20 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d45e5fb..0e5bb92 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2010-10-14  Murray Cumming  <murrayc murrayc com>>
+
+	FlowTable: More fixes for child HBox memory management.
+
+	* glom/utility_widgets/flowtable.cc: Added checks and corrections, though
+  there is still an odd warning about a refcount.
+
 2010-10-14  Murray Cumming  <murrayc murrayc com>
 
 	FlowTable: Fix child HBox memory management.
diff --git a/glom/utility_widgets/flowtable.cc b/glom/utility_widgets/flowtable.cc
index a8c86ba..9947a76 100644
--- a/glom/utility_widgets/flowtable.cc
+++ b/glom/utility_widgets/flowtable.cc
@@ -35,10 +35,13 @@ FlowTable::FlowTable()
 
 FlowTable::~FlowTable()
 {
-  for(type_list_hboxes::iterator iter = m_list_hboxes.begin(); iter != m_list_hboxes.end(); ++iter)
+  while(!m_list_hboxes.empty())
   {
+    type_list_hboxes::iterator iter = m_list_hboxes.begin();
     Gtk::HBox* hbox = *iter;
-    delete hbox;
+
+    std::cout << G_STRFUNC << ": hbox=" << hbox << std::endl;
+    delete_and_forget_hbox(hbox);
   }
 }
 
@@ -59,12 +62,19 @@ Gtk::HBox* FlowTable::get_parent_hbox(Gtk::Widget* first)
       Gtk::HBox* hbox = dynamic_cast<Gtk::HBox*>(widget);
       if(hbox) //The first and second widgets are inside an HBox
       {
-        const type_children box_children = hbox->get_children();
-        if(!box_children.empty())
+        //Check that it is one of our special HBoxes,
+        //though this check should not be neccesary:
+        const type_list_hboxes::const_iterator iter_boxes =
+          std::find(m_list_hboxes.begin(), m_list_hboxes.end(), hbox);
+        if(iter_boxes != m_list_hboxes.end())
         {
-          const Gtk::Widget* child_widget = box_children[0]; //TODO: Is this definitely the left-most one?
-          if(child_widget == first)
-            return hbox;
+          const type_children box_children = hbox->get_children();
+          if(!box_children.empty())
+          {
+            const Gtk::Widget* child_widget = box_children[0]; //TODO: Is this definitely the left-most one?
+            if(child_widget == first)
+              return hbox;
+          }
         }
       }
     }
@@ -75,13 +85,36 @@ Gtk::HBox* FlowTable::get_parent_hbox(Gtk::Widget* first)
 
 void FlowTable::delete_and_forget_hbox(Gtk::HBox* hbox)
 {
+  //Remove its children because the API hides the fact that they are inside the HBox.
+  //Otherwise they could even be deleted by the HBox.
+  typedef std::vector<Widget*> type_children;
+  type_children children = hbox->get_children();
+  while(!children.empty())
+  {
+    Gtk::Widget* widget = children[0];
+    hbox->remove(*widget);
+    children = hbox->get_children();
+  }
+
+  std::cout << G_STRFUNC << "Removing: hbox=" << hbox << std::endl;
+  if(hbox->get_parent() == this)
+  {
+    Gtk::SpreadTable::remove(*hbox);
+  }
+  else
+  {
+    std::cerr << G_STRFUNC << ": hbox is not a direct child." << std::endl;
+  }
+
+  //Delete and forget it:
   for(type_list_hboxes::iterator iter = m_list_hboxes.begin(); iter != m_list_hboxes.end(); ++iter)
   {
     Gtk::HBox* this_hbox = *iter;
     if(hbox == this_hbox)
     {
-      delete hbox;
+      delete hbox; //TODO: This causes a warning during gtk_container_remove(), though we have already removed it: sys:1: Warning: g_object_ref: assertion `object->ref_count > 0' failed
       m_list_hboxes.erase(iter);
+      return;
     }
   }
 }
@@ -193,18 +226,7 @@ void FlowTable::remove(Gtk::Widget& first)
   Gtk::HBox* parent = get_parent_hbox(&first);
   if(parent)
   {
-    //Remove its children because the API hides the fact that they are inside the HBox.
-    //Otherwise they could even be deleted by the HBox.
-    typedef std::vector<Widget*> type_children;
-    type_children children = parent->get_children();
-    while(!children.empty())
-    {
-      Gtk::Widget* widget = children[0];
-      remove(*widget);
-      children = get_children();
-    }
-
-    Gtk::SpreadTable::remove(*parent);
+    std::cout << G_STRFUNC << ": parent=" << parent << std::endl;
     delete_and_forget_hbox(parent);
     return;
   }



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