From 6e63f6b4525fa635a73312dad51a2c54434b516d Mon Sep 17 00:00:00 2001 From: David Hampton Date: Fri, 3 Feb 2006 00:31:50 +0000 Subject: [PATCH] Better handling in the model event handling functions. Noticeable in the commodity and price trees when adding/deleting the first/last item. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13082 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 9 +++ src/gnome-utils/gnc-tree-model-account.c | 1 + src/gnome-utils/gnc-tree-model-commodity.c | 92 +++++++++++++++++----- src/gnome-utils/gnc-tree-model-price.c | 71 ++++++----------- 4 files changed, 107 insertions(+), 66 deletions(-) diff --git a/ChangeLog b/ChangeLog index f4d3db7608..3b98ef79ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2006-02-02 David Hampton + * src/gnome-utils/gnc-tree-model-commodity.c: + * src/gnome-utils/gnc-tree-model-account.c: + * src/gnome-utils/gnc-tree-model-price.c: Better handling in the + model event handling functions. Noticeable in the commodity and + price trees when adding/deleting the first/last item. + + * src/gnome/dialog-commodities.c: Fix a crash when manipulating + commodities before crating the first account. + * src/gnome-utils/gnc-file.c: Re-enable events before processing the book-opened hook. Solves some strange problems in the account tree which were caused by the Orphan account being created during diff --git a/src/gnome-utils/gnc-tree-model-account.c b/src/gnome-utils/gnc-tree-model-account.c index b8b007b55d..ea5c2977b4 100644 --- a/src/gnome-utils/gnc-tree-model-account.c +++ b/src/gnome-utils/gnc-tree-model-account.c @@ -1407,6 +1407,7 @@ gnc_tree_model_account_path_changed (GncTreeModelAccount *model, if (gtk_tree_path_up (path)) { if (gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path)) + gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter); gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL(model), path, &iter); } diff --git a/src/gnome-utils/gnc-tree-model-commodity.c b/src/gnome-utils/gnc-tree-model-commodity.c index 001eefdff1..c658f2eab9 100644 --- a/src/gnome-utils/gnc-tree-model-commodity.c +++ b/src/gnome-utils/gnc-tree-model-commodity.c @@ -1030,12 +1030,60 @@ typedef struct _remove_data { static GSList *pending_removals = NULL; +/** This function performs updating to the model after an commodity + * has been added. The parent entry needs to be tapped on the + * shoulder so that it can correctly update the disclosure triangle + * (first added child) or possibly rebuild its child list of that + * level of accounts is visible. + * + * @internal + * + * @param model The commodity tree model containing the commodity + * that has been added. + * + * @param path The path to the newly added item. + */ +static void +gnc_tree_model_commodity_path_added (GncTreeModelCommodity *model, + GtkTreeIter *iter) +{ + gnc_commodity_namespace *namespace; + GtkTreePath *path; + GtkTreeIter ns_iter; + GList *list; + + ENTER("model %p, iter (%p)%s", model, iter, iter_to_string(iter)); + + if (iter->user_data == ITER_IS_COMMODITY) { + /* Reach out and touch the namespace first */ + gnc_tree_model_commodity_iter_parent (GTK_TREE_MODEL(model), &ns_iter, iter); + namespace = gnc_tree_model_commodity_get_namespace (model, &ns_iter); + list = gnc_commodity_namespace_get_commodity_list(namespace); + if (g_list_length(list) == 1) { + path = gnc_tree_model_commodity_get_path (GTK_TREE_MODEL(model), &ns_iter); + gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &ns_iter); + gtk_tree_model_row_has_child_toggled(GTK_TREE_MODEL(model), path, &ns_iter); + gtk_tree_path_free(path); + } + } + + /* Now for either namespace or commodity */ + path = gnc_tree_model_commodity_get_path (GTK_TREE_MODEL(model), iter); + gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, iter); + gtk_tree_path_free(path); + + do { + model->stamp++; + } while (model->stamp == 0); + LEAVE(" "); +} + + /** This function performs common updating to the model after an - * commodity has been added or removed. The parent entry needs to be - * tapped on the shoulder so that it can correctly update the - * disclosure triangle (first added child/last removed child) or - * possibly rebuild its child list of that level of accounts is - * visible. + * commodity has been removed. The parent entry needs to be tapped + * on the shoulder so that it can correctly update the disclosure + * triangle (last removed child) or possibly rebuild its child list + * of that level of accounts is visible. * * @internal * @@ -1046,17 +1094,33 @@ static GSList *pending_removals = NULL; * item. */ static void -gnc_tree_model_commodity_path_changed (GncTreeModelCommodity *model, +gnc_tree_model_commodity_path_deleted (GncTreeModelCommodity *model, GtkTreePath *path) { + gnc_commodity_namespace *namespace; GtkTreeIter iter; + GList *list; + gint depth; debug_path(ENTER, path); - if (gtk_tree_path_up (path) && gtk_tree_path_get_depth (path) > 0) { + + depth = gtk_tree_path_get_depth(path); + if (depth == 2) { + /* It seems sufficient to tell the model that the parent row + * changed. This appears to force a reload of all its child rows, + * which handles removing the now gone commodity. */ + gtk_tree_path_up (path); + gnc_tree_model_commodity_get_iter (GTK_TREE_MODEL(model), &iter, path); debug_path(DEBUG, path); - gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path); DEBUG("iter %s", iter_to_string(&iter)); gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter); + namespace = gnc_tree_model_commodity_get_namespace (model, &iter); + if (namespace) { + list = gnc_commodity_namespace_get_commodity_list(namespace); + if (g_list_length(list) == 0) { + gtk_tree_model_row_has_child_toggled(GTK_TREE_MODEL(model), path, &iter); + } + } } do { @@ -1094,7 +1158,7 @@ gnc_tree_model_commodity_do_deletions (gpointer unused) pending_removals = g_slist_delete_link (pending_removals, iter); gtk_tree_model_row_deleted (GTK_TREE_MODEL(data->model), data->path); - gnc_tree_model_commodity_path_changed (data->model, data->path); + gnc_tree_model_commodity_path_deleted (data->model, data->path); gtk_tree_path_free(data->path); g_free(data); } @@ -1181,10 +1245,7 @@ gnc_tree_model_commodity_event_handler (GUID *entity, QofIdType type, case GNC_EVENT_ADD: /* Tell the filters/views where the new account was added. */ DEBUG("add %s", name); - path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter); - gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, &iter); - gnc_tree_model_commodity_path_changed (model, path); - gtk_tree_path_free(path); + gnc_tree_model_commodity_path_added (model, &iter); break; case GNC_EVENT_REMOVE: @@ -1213,11 +1274,6 @@ gnc_tree_model_commodity_event_handler (GUID *entity, QofIdType type, LEAVE("not in model"); return; } - if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path)) { - gtk_tree_path_free(path); - LEAVE("can't find iter for path"); - return; - } gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter); gtk_tree_path_free(path); LEAVE(" "); diff --git a/src/gnome-utils/gnc-tree-model-price.c b/src/gnome-utils/gnc-tree-model-price.c index 119b8632f9..e746838c4d 100644 --- a/src/gnome-utils/gnc-tree-model-price.c +++ b/src/gnome-utils/gnc-tree-model-price.c @@ -1325,54 +1325,31 @@ static GSList *pending_removals = NULL; */ static void gnc_tree_model_price_path_added (GncTreeModelPrice *model, - GtkTreePath *path) + GtkTreeIter *iter) { - GtkTreeIter iter; - GtkTreePath *copy; + GtkTreePath *path, *tmp_path; + GtkTreeIter tmp_iter; + gint *indices; + gint depth, i; - /* Update the commodity */ - debug_path(ENTER, path); -#if AIEEE - do { - gtk_tree_path_up (path); - debug_path(DEBUG, path); - gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path); - DEBUG("iter %s", iter_to_string(model, &iter)); - gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter); - } while (gtk_tree_path_get_depth(path) > 1); -#endif -#if UPDATE_ROOT_ONLY - while (gtk_tree_path_get_depth(path) != 1) - gtk_tree_path_up (path); - debug_path(DEBUG, path); - gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path); - DEBUG("iter %s", iter_to_string(model, &iter)); - gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter); -#endif -#ifdef IM_FUCKED - gtk_tree_path_up (path); - debug_path(DEBUG, path); - gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path); - DEBUG("iter %s", iter_to_string(model, &iter)); - gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter); -#endif + ENTER("model %p, iter (%p)%s", model, iter, iter_to_string(model, iter)); + path = gnc_tree_model_price_get_path (GTK_TREE_MODEL(model), iter); - /* Poke the namespace first */ - copy = gtk_tree_path_copy (path); - while (gtk_tree_path_get_depth(copy) != 1) - gtk_tree_path_up (copy); - debug_path(DEBUG, copy); - gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, copy); - DEBUG("iter %s", iter_to_string(model, &iter)); - gtk_tree_model_row_changed (GTK_TREE_MODEL(model), copy, &iter); - gtk_tree_path_free(copy); - - /* Now poke the commodity */ - gtk_tree_path_up (path); - debug_path(DEBUG, path); - gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path); - DEBUG("iter %s", iter_to_string(model, &iter)); - gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter); + /* Tag all the parent nodes as changed. */ + depth = gtk_tree_path_get_depth (path); + indices = gtk_tree_path_get_indices (path); + tmp_path = gtk_tree_path_new(); + for (i = 0; i <= depth - 1; i++) { + gtk_tree_path_append_index (tmp_path, indices[i]); + gnc_tree_model_price_get_iter (GTK_TREE_MODEL(model), &tmp_iter, tmp_path); + gtk_tree_model_row_changed(GTK_TREE_MODEL(model), tmp_path, &tmp_iter); + gtk_tree_model_row_has_child_toggled(GTK_TREE_MODEL(model), tmp_path, &tmp_iter); + } + gtk_tree_path_free(tmp_path); + + /* Now tag the new item as inserted. */ + gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, iter); + gtk_tree_path_free(path); do { model->stamp++; @@ -1528,9 +1505,7 @@ gnc_tree_model_price_event_handler (GUID *entity, QofIdType type, case GNC_EVENT_ADD: /* Tell the filters/views where the new account was added. */ DEBUG("add %s", name); - path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter); - gnc_tree_model_price_path_added (model, path); - gtk_tree_path_free(path); + gnc_tree_model_price_path_added (model, &iter); break; case GNC_EVENT_REMOVE: