[glom] Python button scripts: Avoid a crash with buttons in lists.



commit 1bdba251e9c3d55b3dccade784fa3b60f8a8a1aa
Author: Murray Cumming <murrayc murrayc com>
Date:   Sun Feb 28 22:43:12 2010 +0100

    Python button scripts: Avoid a crash with buttons in lists.
    
    * glom/mode_data/box_data_list.[h|cc]: on_adddel_script_button_clicked():
    Run the script in the (existing) on_script_button_idle() idle handler because
    the script can cause the cell (that is emitting the signal) to be destroyed,
    by navigating to a different table. This fixes that crash.
    * glom/mode_data/box_data_list_related.cc: Do the same here.
    * glom/mode_data/notebook_data.cc: on_list_user_requested_details(): Use
    the same idle handler trick here, just in case.

 ChangeLog                               |   12 +++++++++++
 glom/mode_data/box_data_list.cc         |   32 +++++++++++++++++-------------
 glom/mode_data/box_data_list.h          |    2 +-
 glom/mode_data/box_data_list_related.cc |   31 ++++++++++++++++-------------
 glom/mode_data/box_data_list_related.h  |    2 +-
 glom/mode_data/notebook_data.cc         |   14 ++++++++++++-
 glom/mode_data/notebook_data.h          |    4 ++-
 7 files changed, 65 insertions(+), 32 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ebdf663..3e60cd6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2010-02-28  Murray Cumming  <murrayc murrayc com>
 
+  Python button scripts: Avoid a crash with buttons in lists.
+  
+	* glom/mode_data/box_data_list.[h|cc]: on_adddel_script_button_clicked():
+	Run the script in the (existing) on_script_button_idle() idle handler because 
+	the script can cause the cell (that is emitting the signal) to be destroyed, 
+	by navigating to a different table. This fixes that crash.
+	* glom/mode_data/box_data_list_related.cc: Do the same here.
+	* glom/mode_data/notebook_data.cc: on_list_user_requested_details(): Use 
+	the same idle handler trick here, just in case.
+
+2010-02-28  Murray Cumming  <murrayc murrayc com>
+
 	Added unit test for the new button script ui python API.
 	
 	* Makefile_tests.am:
diff --git a/glom/mode_data/box_data_list.cc b/glom/mode_data/box_data_list.cc
index 513a071..d2e9b00 100644
--- a/glom/mode_data/box_data_list.cc
+++ b/glom/mode_data/box_data_list.cc
@@ -221,7 +221,23 @@ void Box_Data_List::on_adddel_script_button_clicked(const sharedptr<const Layout
     return;
   
   const Gnome::Gda::Value primary_key_value = get_primary_key_value(row);
-  execute_button_script(layout_item, primary_key_value);
+
+  // TODO: Calling refresh_data_from_database(), 
+  // or navigating to a different table from inside the Python script,
+  // causes a crash somewhere down in GTK+, so it is done in an idle handler here.
+  // We are currently in a callback from the CellRendererButton_Text cell
+  // renderer which is deleted by a call to refresh_data_from_database().
+  // Probably this causes issues somewhere.
+  Glib::signal_idle().connect(
+    sigc::bind(
+      sigc::mem_fun(*this, &Box_Data_List::on_script_button_idle), 
+      layout_item,
+      primary_key_value));
+}
+
+bool Box_Data_List::on_script_button_idle(const sharedptr<const LayoutItem_Button>& layout_item, const Gnome::Gda::Value& primary_key)
+{
+  execute_button_script(layout_item, primary_key);
 
   // Refill view from database as the script might have changed arbitrary records
 
@@ -234,21 +250,9 @@ void Box_Data_List::on_adddel_script_button_clicked(const sharedptr<const Layout
     db_model->refresh_from_database(m_found_set);
 #endif
 
-  // TODO: Calling refresh_data_from_database() causes a crash somewhere
-  // down in GTK+, so it is done in a handler here.
-  // We are currently in a callback from the CellRendererButton_Text cell
-  // renderer which is deleted by a call to refresh_data_from_database().
-  // Probably this causes issues somewhere. 
-  Glib::signal_idle().connect(sigc::bind(sigc::mem_fun(*this, &Box_Data_List::on_script_button_idle), primary_key_value));
-
-  //refresh_data_from_database();
-  //set_primary_key_value_selected(primary_key);
-}
-
-bool Box_Data_List::on_script_button_idle(const Gnome::Gda::Value& primary_key)
-{
   refresh_data_from_database();
   set_primary_key_value_selected(primary_key);
+  
   return false;
 }
 
diff --git a/glom/mode_data/box_data_list.h b/glom/mode_data/box_data_list.h
index 245fcfe..ab43fb6 100644
--- a/glom/mode_data/box_data_list.h
+++ b/glom/mode_data/box_data_list.h
@@ -101,7 +101,7 @@ protected:
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
   void on_adddel_script_button_clicked(const sharedptr<const LayoutItem_Button>& layout_item, const Gtk::TreeModel::iterator& row);
-  virtual bool on_script_button_idle(const Gnome::Gda::Value& primary_key_value);
+  bool on_script_button_idle(const sharedptr<const LayoutItem_Button>& layout_item, const Gnome::Gda::Value& primary_key);
 
   virtual void print_layout();
   virtual void print_layout_group(xmlpp::Element* node_parent, const sharedptr<const LayoutGroup>& group);
diff --git a/glom/mode_data/box_data_list_related.cc b/glom/mode_data/box_data_list_related.cc
index 3df7266..58c9fc8 100644
--- a/glom/mode_data/box_data_list_related.cc
+++ b/glom/mode_data/box_data_list_related.cc
@@ -208,7 +208,23 @@ void Box_Data_List_Related::on_adddel_script_button_clicked(const sharedptr<cons
     return;
   
   const Gnome::Gda::Value primary_key_value = get_primary_key_value(row);
-  execute_button_script(layout_item, primary_key_value);
+
+  // TODO: Calling refresh_data_from_database(), 
+  // or navigating to a different table from inside the Python script,
+  // causes a crash somewhere down in GTK+, so it is done in an idle handler here.
+  // We are currently in a callback from the CellRendererButton_Text cell
+  // renderer which is deleted by a call to refresh_data_from_database().
+  // Probably this causes issues somewhere.
+  Glib::signal_idle().connect(
+    sigc::bind(
+      sigc::mem_fun(*this, &Box_Data_List_Related::on_script_button_idle), 
+      layout_item,
+      primary_key_value));
+}
+
+bool Box_Data_List_Related::on_script_button_idle(const sharedptr<const LayoutItem_Button>& layout_item, const Gnome::Gda::Value& primary_key)
+{
+  execute_button_script(layout_item, primary_key);
 
   // Refill view from database as the script might have changed arbitrary records
 
@@ -221,19 +237,6 @@ void Box_Data_List_Related::on_adddel_script_button_clicked(const sharedptr<cons
     db_model->refresh_from_database(m_found_set);
 #endif
 
-  // TODO: Calling refresh_data_from_database() causes a crash somewhere
-  // down in GTK+, so it is done in a handler here.
-  // We are currently in a callback from the CellRendererButton_Text cell
-  // renderer which is deleted by a call to refresh_data_from_database().
-  // Probably this causes issues somewhere. 
-  Glib::signal_idle().connect(sigc::bind(sigc::mem_fun(*this, &Box_Data_List_Related::on_script_button_idle), primary_key_value));
-
-  //refresh_data_from_database();
-  //set_primary_key_value_selected(primary_key);
-}
-
-bool Box_Data_List_Related::on_script_button_idle(const Gnome::Gda::Value& primary_key)
-{
   refresh_data_from_database();
   set_primary_key_value_selected(primary_key);
   return false;
diff --git a/glom/mode_data/box_data_list_related.h b/glom/mode_data/box_data_list_related.h
index c7aa80d..e008512 100644
--- a/glom/mode_data/box_data_list_related.h
+++ b/glom/mode_data/box_data_list_related.h
@@ -54,7 +54,7 @@ protected:
   void on_adddel_user_reordered_columns();
 
   void on_adddel_script_button_clicked(const sharedptr<const LayoutItem_Button>& layout_item, const Gtk::TreeModel::iterator& row);
-  bool on_script_button_idle(const Gnome::Gda::Value& primary_key_value);
+  bool on_script_button_idle(const sharedptr<const LayoutItem_Button>& layout_item, const Gnome::Gda::Value& primary_key);
 
   void on_adddel_record_added(const Gtk::TreeModel::iterator& row, const Gnome::Gda::Value& primary_key_value);
     
diff --git a/glom/mode_data/notebook_data.cc b/glom/mode_data/notebook_data.cc
index 278bf38..bc0611e 100644
--- a/glom/mode_data/notebook_data.cc
+++ b/glom/mode_data/notebook_data.cc
@@ -264,9 +264,21 @@ void Notebook_Data::show_details(const Gnome::Gda::Value& primary_key_value)
     m_connection_switch_page.unblock();  
 }
 
-void Notebook_Data::on_list_user_requested_details(const Gnome::Gda::Value& primary_key_value)
+bool Notebook_Data::on_idle_show_details(const Gnome::Gda::Value& primary_key_value)
 {
   show_details(primary_key_value);
+  return false; //Don't call this idle handler again.
+}
+
+void Notebook_Data::on_list_user_requested_details(const Gnome::Gda::Value& primary_key_value)
+{
+  //Show the details after a delay,
+  //to avoid problems with deleting the list GtkCellRenderer while 
+  //handling its signal.
+  Glib::signal_idle().connect(
+    sigc::bind(
+      sigc::mem_fun(*this, &Notebook_Data::on_idle_show_details),
+      primary_key_value));
 }
 
 void Notebook_Data::on_details_user_requested_related_details(const Glib::ustring& table_name, Gnome::Gda::Value primary_key_value)
diff --git a/glom/mode_data/notebook_data.h b/glom/mode_data/notebook_data.h
index 4b44c1b..cf8f69f 100644
--- a/glom/mode_data/notebook_data.h
+++ b/glom/mode_data/notebook_data.h
@@ -96,7 +96,9 @@ private:
   #ifdef GLOM_ENABLE_MAEMO
   void on_window_maemo_details_closed();
   #endif
-  
+
+  bool on_idle_show_details(const Gnome::Gda::Value& primary_key_value);
+
 protected:
   //Member widgets:
   Box_Data_List m_Box_List;



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