[glom/spread-table] FlowTable: Fix child HBox memory management.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom/spread-table] FlowTable: Fix child HBox memory management.
- Date: Thu, 14 Oct 2010 08:18:41 +0000 (UTC)
commit 19c1e832bd74f8d4e38a6a4efede89262e4ff361
Author: Murray Cumming <murrayc murrayc com>
Date: Thu Oct 14 10:18:26 2010 +0200
FlowTable: Fix child HBox memory management.
* glom/utility_widgets/flowtable.[h|cc]: insert(), remove_all(), remove(),
destructor: Remember the implementation-only Gtk::HBox widgets and delete
them when appropriate. A simple Gtk::manage() was not enough for this.
ChangeLog | 8 ++++
glom/utility_widgets/flowtable.cc | 78 +++++++++++++++++++++++++++++++++----
glom/utility_widgets/flowtable.h | 7 +++
3 files changed, 85 insertions(+), 8 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 47fac4d..d45e5fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2010-10-14 Murray Cumming <murrayc murrayc com>
+
+ FlowTable: Fix child HBox memory management.
+
+ * glom/utility_widgets/flowtable.[h|cc]: insert(), remove_all(), remove(),
+ destructor: Remember the implementation-only Gtk::HBox widgets and delete
+ them when appropriate. A simple Gtk::manage() was not enough for this.
+
2010-10-12 Murray Cumming <murrayc murrayc com>
FlowTable: Avoid some runtime warnings.
diff --git a/glom/utility_widgets/flowtable.cc b/glom/utility_widgets/flowtable.cc
index 1e08161..a8c86ba 100644
--- a/glom/utility_widgets/flowtable.cc
+++ b/glom/utility_widgets/flowtable.cc
@@ -35,6 +35,55 @@ FlowTable::FlowTable()
FlowTable::~FlowTable()
{
+ for(type_list_hboxes::iterator iter = m_list_hboxes.begin(); iter != m_list_hboxes.end(); ++iter)
+ {
+ Gtk::HBox* hbox = *iter;
+ delete hbox;
+ }
+}
+
+Gtk::HBox* FlowTable::get_parent_hbox(Gtk::Widget* first)
+{
+ typedef std::vector<Widget*> type_children;
+ type_children children = get_children();
+ for(type_children::iterator iter = children.begin(); iter != children.end(); ++iter)
+ {
+ Gtk::Widget* widget = *iter;
+ if(!widget)
+ continue;
+
+ if(widget == first) //It must be a single item.
+ return 0; //It has no HBox parent.
+ else
+ {
+ 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())
+ {
+ const Gtk::Widget* child_widget = box_children[0]; //TODO: Is this definitely the left-most one?
+ if(child_widget == first)
+ return hbox;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+void FlowTable::delete_and_forget_hbox(Gtk::HBox* hbox)
+{
+ 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;
+ m_list_hboxes.erase(iter);
+ }
+ }
}
void FlowTable::set_design_mode(bool value)
@@ -58,7 +107,8 @@ void FlowTable::insert(Gtk::Widget* first, Gtk::Widget* second, int index, bool
{
if(first && second)
{
- Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox(false, get_horizontal_spacing()));
+ Gtk::HBox* hbox = new Gtk::HBox(false, get_horizontal_spacing());
+ m_list_hboxes.push_back(hbox); //So we can delete it whenever necessary.
hbox->pack_start(*first, Gtk::PACK_SHRINK);
hbox->pack_start(*second, expand ? Gtk::PACK_EXPAND_WIDGET : Gtk::PACK_SHRINK);
@@ -139,15 +189,27 @@ void FlowTable::remove_all()
void FlowTable::remove(Gtk::Widget& first)
{
- const int index = get_child_index(first);
- typedef std::vector<Widget*> type_children;
- type_children children = get_children();
- if((index >= 0) && ((guint)index < children.size()))
+ //Handle widgets that were added to an HBox:
+ Gtk::HBox* parent = get_parent_hbox(&first);
+ if(parent)
{
- Gtk::Widget* child = children[index];
- if(child)
- Gtk::SpreadTable::remove(*child);
+ //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);
+ delete_and_forget_hbox(parent);
+ return;
}
+
+ Gtk::SpreadTable::remove(first);
}
bool FlowTable::get_column_for_first_widget(const Gtk::Widget& first, guint& column) const
diff --git a/glom/utility_widgets/flowtable.h b/glom/utility_widgets/flowtable.h
index 42c442f..117b77d 100644
--- a/glom/utility_widgets/flowtable.h
+++ b/glom/utility_widgets/flowtable.h
@@ -60,10 +60,17 @@ protected:
private:
int get_child_index(const Gtk::Widget& first) const;
+ Gtk::HBox* get_parent_hbox(Gtk::Widget* first);
+ void delete_and_forget_hbox(Gtk::HBox* hbox);
+
bool m_design_mode;
//For drawing:
Glib::RefPtr<Gdk::Window> m_refGdkWindow;
+
+ //We remember the HBoxes so we can delete them when the are no longer used.
+ typedef std::list<Gtk::HBox*> type_list_hboxes;
+ type_list_hboxes m_list_hboxes;
};
} //namespace Glom
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]