[glade3/glade-3-8] * gladeui/glade-app.[ch]: Added glade_app_queue_selection_changed()



commit 34331cd71bc721c3c2dcea3f4a3ca9c845082a41
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Fri Dec 17 17:30:54 2010 +0900

    	* gladeui/glade-app.[ch]: Added glade_app_queue_selection_changed()
    
    	* gladeui/glade-command.c: queue selection changes when widgets are added, this
    	  avoids synchrounously poking the model when the selection changes various times
    	  in a command sequence such as changing a menu item's type.
    
    	* gladeui/glade-base-editor.c: Dont call glade_command_create/delete() directly
    	  in change-type, keep delegating this work to build-child/delete-child signals.
    
    	* gladeui/glade-widget.[ch]: Added glade_widget_is_ancestor()
    
    	* gladeui/glade-utils.c: Change glade_util_find_iter_by_widget() to use
    	  glade_widget_is_ancestor() and speed up searches a little this way.

 ChangeLog                   |   16 +++++++++++++
 gladeui/glade-app.c         |   21 +++++++++++++++++
 gladeui/glade-app.h         |    2 +
 gladeui/glade-base-editor.c |   52 +++++++++++++++++++++++++++++++-----------
 gladeui/glade-command.c     |    2 +-
 gladeui/glade-utils.c       |   35 +++++++++++++++++++---------
 gladeui/glade-widget.c      |   29 ++++++++++++++++++++++++
 gladeui/glade-widget.h      |    4 +++
 8 files changed, 135 insertions(+), 26 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4902248..8124aee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2010-12-17  Tristan Van Berkom <tristanvb openismus com>
+
+	* gladeui/glade-app.[ch]: Added glade_app_queue_selection_changed()
+
+	* gladeui/glade-command.c: queue selection changes when widgets are added, this
+	  avoids synchrounously poking the model when the selection changes various times
+	  in a command sequence such as changing a menu item's type.
+
+	* gladeui/glade-base-editor.c: Dont call glade_command_create/delete() directly
+	  in change-type, keep delegating this work to build-child/delete-child signals.
+
+	* gladeui/glade-widget.[ch]: Added glade_widget_is_ancestor()
+
+	* gladeui/glade-utils.c: Change glade_util_find_iter_by_widget() to use
+	  glade_widget_is_ancestor() and speed up searches a little this way.
+
 2010-12-16  Tristan Van Berkom <tristanvb openismus com>
 
 	* plugins/gtk+/glade-gtk.c: Avoid using gtk_combo_box_set_entry_text_column directly (build
diff --git a/gladeui/glade-app.c b/gladeui/glade-app.c
index 0979b20..d409e00 100644
--- a/gladeui/glade-app.c
+++ b/gladeui/glade-app.c
@@ -94,6 +94,8 @@ struct _GladeAppPrivate
 	GList *undo_list, *redo_list;	/* Lists of buttons to refresh in update-ui signal */
 
 	GladePointerMode pointer_mode;  /* Current mode for the pointer in the workspace */
+
+	guint selection_changed_id; /* for queue_selection_changed() */
 };
 
 static guint glade_app_signals[LAST_SIGNAL] = { 0 };
@@ -1619,6 +1621,25 @@ glade_app_selection_changed (void)
 	}
 }
 
+static gboolean
+selection_change_idle (GladeApp *app)
+{
+	glade_app_selection_changed ();
+	app->priv->selection_changed_id = 0;
+	return FALSE;
+}
+
+void
+glade_app_queue_selection_changed (void)
+{
+	GladeApp  *app = glade_app_get ();
+
+	if (app->priv->selection_changed_id == 0)
+		app->priv->selection_changed_id = 
+			g_idle_add ((GSourceFunc)selection_change_idle, app);
+}
+
+
 GladeApp*
 glade_app_new (void)
 {
diff --git a/gladeui/glade-app.h b/gladeui/glade-app.h
index 620dbfa..87000d1 100644
--- a/gladeui/glade-app.h
+++ b/gladeui/glade-app.h
@@ -193,6 +193,8 @@ void               glade_app_selection_clear   (gboolean  emit_signal);
  
 void               glade_app_selection_changed (void);
 
+void               glade_app_queue_selection_changed (void);
+
 /* package paths */
 
 const gchar       *glade_app_get_catalogs_dir  (void) G_GNUC_CONST;
diff --git a/gladeui/glade-base-editor.c b/gladeui/glade-base-editor.c
index 5e35c95..d890cfc 100644
--- a/gladeui/glade-base-editor.c
+++ b/gladeui/glade-base-editor.c
@@ -322,6 +322,31 @@ glade_base_editor_project_widget_name_changed (GladeProject *project,
 					       GladeWidget  *widget,
 					       GladeBaseEditor *editor);
 
+
+static GladeWidget *
+glade_base_editor_delegate_build_child (GladeBaseEditor *editor,
+					GladeWidget     *parent,
+					GType            type)
+{
+	GladeWidget *child = NULL;
+	g_signal_emit (editor, glade_base_editor_signals[SIGNAL_BUILD_CHILD],
+		       0, parent, type, &child);
+	return child;
+}
+
+static gboolean
+glade_base_editor_delegate_delete_child (GladeBaseEditor *editor,
+					 GladeWidget     *parent,
+					 GladeWidget     *child)
+{
+	gboolean retval;
+
+	g_signal_emit (editor, glade_base_editor_signals[SIGNAL_DELETE_CHILD],
+		       0, parent, child, &retval);
+
+	return retval;
+}
+
 static void
 glade_base_editor_name_activate (GtkEntry *entry, GladeWidget *gchild)
 {
@@ -678,9 +703,8 @@ glade_base_editor_add_child (GladeBaseEditor *editor,
 				  glade_widget_get_name (gparent));
 	
 	/* Build Child */
-	g_signal_emit (editor, glade_base_editor_signals[SIGNAL_BUILD_CHILD],
-		       0, gparent, type, &gchild_new);
-	
+	gchild_new = glade_base_editor_delegate_build_child (editor, gparent, type);
+
 	if (gchild_new == NULL)
 	{
 		glade_command_pop_group ();
@@ -862,7 +886,6 @@ glade_base_editor_delete_child (GladeBaseEditor *e)
 {
 	GladeWidget *child, *gparent;
 	GtkTreeIter iter, parent;
-	gboolean retval;
 
 	if (!glade_base_editor_get_child_selected (e, &iter)) return;
 
@@ -881,8 +904,7 @@ glade_base_editor_delete_child (GladeBaseEditor *e)
 				  glade_widget_get_name (gparent));
 	
 	/* Emit delete-child signal */
-	g_signal_emit (e, glade_base_editor_signals[SIGNAL_DELETE_CHILD],
-		       0, gparent, child, &retval);
+	glade_base_editor_delegate_delete_child (e, gparent, child);
 
 	glade_command_pop_group ();
 }
@@ -1302,10 +1324,8 @@ glade_base_editor_change_type (GladeBaseEditor *editor,
 			       GladeWidget *gchild,
 			       GType type)
 {
-	GladeBaseEditorPrivate *e = editor->priv;
-	GladeWidgetAdaptor     *adaptor = glade_widget_adaptor_get_by_type (type);
 	GladeWidget            *parent, *gchild_new;
-	GList                   list = {0, }, *children, *l;
+	GList                  *children, *l;
 	GObject                *child, *child_new;
 	GtkTreeIter             iter;
 	gchar                  *name, *class_name;
@@ -1322,11 +1342,12 @@ glade_base_editor_change_type (GladeBaseEditor *editor,
 	glade_base_editor_find_child (editor, gchild, &iter);
 	
 	/* Create new widget */
-	gchild_new = glade_command_create (adaptor, parent, NULL, e->project);
+	gchild_new = glade_base_editor_delegate_build_child (editor, parent, type);
+
 	child_new = glade_widget_get_object (gchild_new);
 
 	/* Cut and Paste childrens */
-	if ((children = glade_widget_adaptor_get_children (gchild->adaptor, child)))
+	if ((children = glade_widget_get_children (gchild)) != NULL)
 	{
 		GList *gchildren = NULL;
 		
@@ -1354,10 +1375,13 @@ glade_base_editor_change_type (GladeBaseEditor *editor,
 	glade_widget_copy_properties (gchild_new, gchild, TRUE, TRUE);
 	
 	/* Delete old widget */
-	list.data = gchild;
-	glade_command_delete (&list);
+ 	glade_base_editor_delegate_delete_child (editor, parent, gchild);
 	
-	/* Apply packing properties to the new object */
+	/* Apply packing properties to the new object 
+	 * 
+	 * No need to use GladeCommand here on the newly created widget,
+	 * they just become the initial state for this object.
+	 */
 	l = gchild->packing_properties;
 	while (l)
 	{
diff --git a/gladeui/glade-command.c b/gladeui/glade-command.c
index 3394bd8..285336e 100644
--- a/gladeui/glade-command.c
+++ b/gladeui/glade-command.c
@@ -1401,7 +1401,7 @@ glade_command_add_execute (GladeCommandAddRemove *me)
 
 			glade_widget_show (cdata->widget);
 		}
-		glade_app_selection_changed ();
+		glade_app_queue_selection_changed ();
 	}
 	return TRUE;
 	
diff --git a/gladeui/glade-utils.c b/gladeui/glade-utils.c
index 78940cb..2d634f9 100644
--- a/gladeui/glade-utils.c
+++ b/gladeui/glade-utils.c
@@ -1105,25 +1105,38 @@ glade_util_find_iter (GtkTreeModel *model,
 
 	while (retval == NULL)
 	{
+		GladeWidget *widget;
+
 		gtk_tree_model_get (model, next, column, &object, -1);
-		if (object == glade_widget_get_object (findme))
+		if (object &&
+		    gtk_tree_model_get_column_type (model, column) == G_TYPE_OBJECT)
+			g_object_unref (object);
+
+		widget = glade_widget_get_from_gobject (object);
+
+		if (widget == findme)
 		{
 			retval = gtk_tree_iter_copy (next);
 			break;
 		}
-		else if (gtk_tree_model_iter_has_child (model, next))
+		else if (glade_widget_is_ancestor (findme, widget))
 		{
-			GtkTreeIter  child;
-			gtk_tree_model_iter_children (model, &child, next);
-			if ((retval = glade_util_find_iter
-			     (model, &child, findme, column)) != NULL)
-				break;
+			if (gtk_tree_model_iter_has_child (model, next))
+			{
+				GtkTreeIter  child;
+				gtk_tree_model_iter_children (model, &child, next);
+				if ((retval = glade_util_find_iter
+				     (model, &child, findme, column)) != NULL)
+					break;
+			}
+
+			/* Only search the branches where the searched widget
+			 * is actually a child of the this row, optimize the
+			 * searching this way
+			 */
+			break;
 		}
 
-		if (object &&
-		    gtk_tree_model_get_column_type (model, column) == G_TYPE_OBJECT)
-			g_object_unref (object);
-		
 		if (!gtk_tree_model_iter_next (model, next))
 			break;
 	}
diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c
index 6bbb043..d5acc5d 100644
--- a/gladeui/glade-widget.c
+++ b/gladeui/glade-widget.c
@@ -4010,6 +4010,35 @@ glade_widget_write (GladeWidget     *widget,
 }
 
 
+/**
+ * gtk_widget_is_ancestor:
+ * @widget: a #GladeWidget
+ * @ancestor: another #GladeWidget
+ *
+ * Determines whether @widget is somewhere inside @ancestor, possibly with
+ * intermediate containers.
+ *
+ * Return value: %TRUE if @ancestor contains @widget as a child,
+ *    grandchild, great grandchild, etc.
+ **/
+gboolean
+glade_widget_is_ancestor (GladeWidget      *widget,
+			  GladeWidget      *ancestor)
+{
+  g_return_val_if_fail (GLADE_IS_WIDGET (widget), FALSE);
+  g_return_val_if_fail (GLADE_IS_WIDGET (ancestor), FALSE);
+
+  while (widget)
+    {
+      if (widget->parent == ancestor)
+	return TRUE;
+      widget = widget->parent;
+    }
+
+  return FALSE;
+}
+
+
 static gint glade_widget_su_stack = 0;
 
 /**
diff --git a/gladeui/glade-widget.h b/gladeui/glade-widget.h
index bbc3f1d..3d909f7 100644
--- a/gladeui/glade-widget.h
+++ b/gladeui/glade-widget.h
@@ -273,6 +273,10 @@ GladeEditorProperty    *glade_widget_create_editor_property (GladeWidget      *w
 							     gboolean          use_command);
 
 gchar                  *glade_widget_generate_path_name     (GladeWidget      *widget);
+
+gboolean                glade_widget_is_ancestor            (GladeWidget      *widget,
+							     GladeWidget      *ancestor);
+
 /*******************************************************************************
                       Project, object property references
  *******************************************************************************/



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