[libgda] Keep the same iterator in GdauiRawForm if possible



commit b0ed56e9d34e09676c04df642fcb2d3cc3c4bc89
Author: Vivien Malerba <malerba gnome-db org>
Date:   Tue Jan 26 22:37:01 2010 +0100

    Keep the same iterator in GdauiRawForm if possible
    
    
    refactored the code with GdauiRawGrid

 libgda-ui/gdaui-raw-form.c   |  140 +++++++++++++++++++++++++-----------------
 libgda-ui/gdaui-raw-grid.c   |   34 +----------
 libgda-ui/internal/utility.c |   45 +++++++++++++
 libgda-ui/internal/utility.h |    4 +
 4 files changed, 133 insertions(+), 90 deletions(-)
---
diff --git a/libgda-ui/gdaui-raw-form.c b/libgda-ui/gdaui-raw-form.c
index c1d3bea..b812f3c 100644
--- a/libgda-ui/gdaui-raw-form.c
+++ b/libgda-ui/gdaui-raw-form.c
@@ -364,6 +364,21 @@ gdaui_raw_form_dispose (GObject *object)
 	parent_class->dispose (object);
 }
 
+static gboolean
+proxy_reset_was_soft (GdauiRawForm *form, GdaDataModel *new_model)
+{
+	GdaDataModelIter *iter;
+	gboolean retval = FALSE;
+
+	if (!new_model || (new_model != (GdaDataModel*) form->priv->proxy))
+		return FALSE;
+
+	iter = gda_data_model_create_iter (new_model);
+	retval = ! _gdaui_utility_iter_differ (form->priv->iter, iter);
+	g_object_unref (iter);
+	return retval;
+}
+
 static void
 gdaui_raw_form_set_property (GObject *object,
 			     guint param_id,
@@ -376,69 +391,80 @@ gdaui_raw_form_set_property (GObject *object,
         form = GDAUI_RAW_FORM (object);
         if (form->priv) {
                 switch (param_id) {
-		case PROP_MODEL:
-			ptr = GDA_DATA_MODEL(g_value_get_object (value));
+		case PROP_MODEL: {
+			gboolean reset;
+
+			ptr = GDA_DATA_MODEL (g_value_get_object (value));
 			if (ptr)
 				g_return_if_fail (GDA_IS_DATA_MODEL (ptr));
-			if (form->priv->proxy) {
-				/* remove old data model settings */
-				g_signal_handlers_disconnect_by_func (form->priv->iter,
-								      G_CALLBACK (iter_row_changed_cb), form);
-				g_signal_handlers_disconnect_by_func (form->priv->iter,
-								      G_CALLBACK (iter_validate_set_cb), form);
-
-				g_object_unref (G_OBJECT (form->priv->iter));
-				form->priv->iter = NULL;
-
-				g_signal_handlers_disconnect_by_func (G_OBJECT (form->priv->proxy),
-								      G_CALLBACK (proxy_row_inserted_or_removed_cb),
-								      form);
-				g_signal_handlers_disconnect_by_func (G_OBJECT (form->priv->proxy),
-								      G_CALLBACK (proxy_changed_cb), form);
-				g_signal_handlers_disconnect_by_func (G_OBJECT (form->priv->proxy),
-								      G_CALLBACK (proxy_reset_cb), form);
-				g_object_unref (G_OBJECT (form->priv->proxy));
-				form->priv->proxy = NULL;
-				form->priv->model = NULL;
-			}
-			if (ptr) {
-				/* handle the data model */
-				if (GDA_IS_DATA_PROXY (ptr)) {
-					form->priv->proxy = (GdaDataProxy *) ptr;
-					g_object_ref (ptr);
+			reset = !proxy_reset_was_soft (form, (GdaDataModel*) ptr);
+
+			if (reset) {
+				if (form->priv->proxy) {
+					/* remove old data model settings */
+					g_signal_handlers_disconnect_by_func (form->priv->iter,
+									      G_CALLBACK (iter_row_changed_cb),
+									      form);
+					g_signal_handlers_disconnect_by_func (form->priv->iter,
+									      G_CALLBACK (iter_validate_set_cb),
+									      form);
+					g_object_unref (G_OBJECT (form->priv->iter));
+					form->priv->iter = NULL;
+
+					g_signal_handlers_disconnect_by_func (G_OBJECT (form->priv->proxy),
+									      G_CALLBACK (proxy_row_inserted_or_removed_cb),
+									      form);
+					g_signal_handlers_disconnect_by_func (G_OBJECT (form->priv->proxy),
+									      G_CALLBACK (proxy_changed_cb), form);
+					g_signal_handlers_disconnect_by_func (G_OBJECT (form->priv->proxy),
+									      G_CALLBACK (proxy_reset_cb), form);
+					g_object_unref (G_OBJECT (form->priv->proxy));
+					form->priv->proxy = NULL;
+					form->priv->model = NULL;
 				}
-				else
-					form->priv->proxy = (GdaDataProxy *) gda_data_proxy_new ((GdaDataModel*) ptr);
-
-				form->priv->model = gda_data_proxy_get_proxied_model (form->priv->proxy);
-
-				form->priv->iter = gda_data_model_create_iter ((GdaDataModel *) form->priv->proxy);
-				gda_data_model_iter_move_to_row (form->priv->iter, 0);
-
-				g_signal_connect (form->priv->iter, "validate-set",
-						  G_CALLBACK (iter_validate_set_cb), form);
-				g_signal_connect (form->priv->iter, "row-changed",
-						  G_CALLBACK (iter_row_changed_cb), form);
-
-				g_signal_connect (G_OBJECT (form->priv->proxy), "row_inserted",
-						  G_CALLBACK (proxy_row_inserted_or_removed_cb), form);
-				g_signal_connect (G_OBJECT (form->priv->proxy), "row_removed",
-						  G_CALLBACK (proxy_row_inserted_or_removed_cb), form);
-				g_signal_connect (G_OBJECT (form->priv->proxy), "changed",
-						  G_CALLBACK (proxy_changed_cb), form);
-				g_signal_connect (G_OBJECT (form->priv->proxy), "reset",
-						  G_CALLBACK (proxy_reset_cb), form);
-
-				/* we don't want chuncking */
-				g_object_set (object, "paramlist", form->priv->iter, NULL);
-				gda_data_proxy_set_sample_size (form->priv->proxy, 0);
-				gdaui_raw_form_initialize (form, NULL, NULL);
-				iter_row_changed_cb (form->priv->iter, gda_data_model_iter_get_row (form->priv->iter), form);
+				if (ptr) {
+					/* handle the data model */
+					if (GDA_IS_DATA_PROXY (ptr)) {
+						form->priv->proxy = (GdaDataProxy *) ptr;
+						g_object_ref (ptr);
+					}
+					else
+						form->priv->proxy = (GdaDataProxy *) gda_data_proxy_new ((GdaDataModel*) ptr);
+
+					form->priv->model = gda_data_proxy_get_proxied_model (form->priv->proxy);
+					form->priv->iter = gda_data_model_create_iter ((GdaDataModel *) form->priv->proxy);
+					gda_data_model_iter_move_to_row (form->priv->iter, 0);
+					
+					g_signal_connect (form->priv->iter, "validate-set",
+							  G_CALLBACK (iter_validate_set_cb), form);
+					g_signal_connect (form->priv->iter, "row-changed",
+							  G_CALLBACK (iter_row_changed_cb), form);
+					
+					g_signal_connect (G_OBJECT (form->priv->proxy), "row_inserted",
+							  G_CALLBACK (proxy_row_inserted_or_removed_cb), form);
+					g_signal_connect (G_OBJECT (form->priv->proxy), "row_removed",
+							  G_CALLBACK (proxy_row_inserted_or_removed_cb), form);
+					g_signal_connect (G_OBJECT (form->priv->proxy), "changed",
+							  G_CALLBACK (proxy_changed_cb), form);
+					g_signal_connect (G_OBJECT (form->priv->proxy), "reset",
+							  G_CALLBACK (proxy_reset_cb), form);
+
+					/* we don't want chuncking */
+					g_object_set (object, "paramlist", form->priv->iter, NULL);
+					gda_data_proxy_set_sample_size (form->priv->proxy, 0);
+					gdaui_raw_form_initialize (form, NULL, NULL);
+				}
+				if (form->priv->iter)
+					iter_row_changed_cb (form->priv->iter,
+							     gda_data_model_iter_get_row (form->priv->iter), form);
+				gdaui_raw_form_widget_set_write_mode ((GdauiDataProxy *) form,
+								      form->priv->write_mode);
 			}
-
-			gdaui_raw_form_widget_set_write_mode ((GdauiDataProxy *) form, form->priv->write_mode);
+			else
+				gda_data_model_iter_move_to_row (form->priv->iter, 0);
 			g_signal_emit_by_name (object, "proxy-changed", form->priv->proxy);
 			break;
+		}
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 			break;
diff --git a/libgda-ui/gdaui-raw-grid.c b/libgda-ui/gdaui-raw-grid.c
index cb7a29d..276e8d4 100644
--- a/libgda-ui/gdaui-raw-grid.c
+++ b/libgda-ui/gdaui-raw-grid.c
@@ -444,45 +444,13 @@ static gboolean
 proxy_reset_was_soft (GdauiRawGrid *grid, GdaDataModel *new_model)
 {
 	GdaDataModelIter *iter;
-	GSList *olist, *nlist;
 	gboolean retval = FALSE;
 
 	if (!new_model || (new_model != (GdaDataModel*) grid->priv->proxy))
 		return FALSE;
 
 	iter = gda_data_model_create_iter (new_model);
-	for (olist = GDA_SET (grid->priv->iter)->holders, nlist = GDA_SET (iter)->holders;
-	     olist && nlist;
-	     olist = olist->next, nlist = nlist->next) {
-		GdaHolder *oh, *nh;
-		oh = GDA_HOLDER (olist->data);
-		nh = GDA_HOLDER (nlist->data);
-
-		if (gda_holder_get_not_null (oh) != gda_holder_get_not_null (nh))
-			goto out;
-
-		GType ot, nt;
-		ot = gda_holder_get_g_type (oh);
-		nt = gda_holder_get_g_type (nh);
-		if (ot && (ot != nt))
-			goto out;
-		if (ot != nt)
-			g_object_set (oh, "g-type", nt, NULL);
-
-		const gchar *oid, *nid;
-		oid = gda_holder_get_id (oh);
-		nid = gda_holder_get_id (nh);
-		if ((oid && !nid) || (!oid && nid) ||
-		    (oid && strcmp (oid, nid)))
-			goto out;
-	}
-
-	if (olist || nlist)
-		goto out;
-
-	retval = TRUE;
-
- out:
+	retval = ! _gdaui_utility_iter_differ (grid->priv->iter, iter);
 	g_object_unref (iter);
 	return retval;
 }
diff --git a/libgda-ui/internal/utility.c b/libgda-ui/internal/utility.c
index 90ec629..3dbb572 100644
--- a/libgda-ui/internal/utility.c
+++ b/libgda-ui/internal/utility.c
@@ -538,3 +538,48 @@ _gdaui_utility_show_error (GtkWindow *parent, const gchar *format, ...)
 	gtk_dialog_run (GTK_DIALOG (dialog));
 	gtk_widget_destroy (dialog);
 }
+
+/*
+ * Compares 2 GdaDataModelIter
+ *
+ * Returns: %TRUE if they have at least one difference
+ */
+gboolean
+_gdaui_utility_iter_differ (GdaDataModelIter *iter1, GdaDataModelIter *iter2)
+{
+	GSList *list1, *list2;
+        gboolean retval = TRUE;
+
+	for (list1 = GDA_SET (iter1)->holders, list2 = GDA_SET (iter2)->holders;
+             list1 && list2;
+             list1 = list1->next, list2 = list2->next) {
+                GdaHolder *oh, *nh;
+                oh = GDA_HOLDER (list1->data);
+                nh = GDA_HOLDER (list2->data);
+
+                if (gda_holder_get_not_null (oh) != gda_holder_get_not_null (nh))
+                        goto out;
+
+                GType ot, nt;
+                ot = gda_holder_get_g_type (oh);
+                nt = gda_holder_get_g_type (nh);
+                if (ot && (ot != nt))
+                        goto out;
+                if (ot != nt)
+                        g_object_set (oh, "g-type", nt, NULL);
+
+                const gchar *oid, *nid;
+                oid = gda_holder_get_id (oh);
+                nid = gda_holder_get_id (nh);
+                if ((oid && !nid) || (!oid && nid) ||
+                    (oid && strcmp (oid, nid)))
+                        goto out;
+        }
+
+        if (list1 || list2)
+                goto out;
+        retval = FALSE; /* iters don't differ */
+
+ out:
+        return retval;
+}
diff --git a/libgda-ui/internal/utility.h b/libgda-ui/internal/utility.h
index 7479bc6..88b6d22 100644
--- a/libgda-ui/internal/utility.h
+++ b/libgda-ui/internal/utility.h
@@ -54,3 +54,7 @@ gboolean         _gdaui_utility_display_error_with_keep_or_discard_choice (Gdaui
 void             _gdaui_utility_display_error                             (GdauiDataProxy *form, gboolean can_discard, GError *filled_error);
 void             _gdaui_utility_show_error (GtkWindow *parent, const gchar *format, ...);
 
+/*
+ * Misc
+ */
+gboolean         _gdaui_utility_iter_differ (GdaDataModelIter *iter1, GdaDataModelIter *iter2);



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