[Gnucash-changes] r11936 - gnucash/trunk/src/gnome-utils -
Correctly update the tree model when an account is moved. Fixes
David Hampton
hampton at cvs.gnucash.org
Mon Nov 14 18:43:13 EST 2005
Author: hampton
Date: 2005-11-14 18:43:13 -0500 (Mon, 14 Nov 2005)
New Revision: 11936
Trac: http://svn.gnucash.org/trac/changeset/11936
Modified:
gnucash/trunk/src/gnome-utils/gnc-tree-model-account.c
Log:
Correctly update the tree model when an account is moved. Fixes
#313782.
Modified: gnucash/trunk/src/gnome-utils/gnc-tree-model-account.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-model-account.c 2005-11-14 23:42:26 UTC (rev 11935)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-model-account.c 2005-11-14 23:43:13 UTC (rev 11936)
@@ -1366,9 +1366,19 @@
/* Account Tree Model - Engine Event Handling Functions */
/************************************************************/
+/** This data structure maintains a record of a pending removal of an
+ * account from GnuCash. There is a chicken/egg problem whereby the
+ * account cannot be removed from the model before it is removed from
+ * the account group (throws the indices off), but after the account
+ * has been removed from the account group a path to the account
+ * can't be generated. This data structure holds a temporary copy of
+ * the account path to bridge this problem. */
typedef struct _remove_data {
+ /** The guid of the account that was removed. */
GUID guid;
+ /** A pointer to the model containing the account. */
GncTreeModelAccount *model;
+ /** The path within the model to the account. */
GtkTreePath *path;
} remove_data;
@@ -1406,35 +1416,72 @@
}
-/** This function is a helper routine for the following
- * gnc_tree_model_account_event_handler() function. It is called
- * from an iterator over all the pending account removals, and is
- * responsible for selecting the right item(s), deleting it from the
- * pending list, and then sending the "row_deleted" signal to any/all
- * parent models.
+/** This function is a one-shot helper routine for the following
+ * gnc_tree_model_account_event_handler() function. It must be armed
+ * each time an item is removed from the model. This function will
+ * be called as an idle function some time after the user requests
+ * the deletion. This function will send the "row_deleted"
+ * signal to any/all parent models for each entry deleted.
*
* @internal
*
- * @param data An item in the pending deletion list.
+ * @param unused
*
- * @param entity The guid value of the destroyed item.
+ * @return FALSE. Tells the glib idle function to remove this
+ * handler, making it a one-shot that will be re-armed at the next
+ * item removal.
*/
-static void
-gnc_tree_model_account_delete_event_helper (remove_data *data,
- GUID *entity)
+static gboolean
+gnc_tree_model_account_do_deletions (gpointer unused)
{
- if (!guid_equal(&data->guid, entity))
- return;
+ GSList *iter, *next = NULL;
+ remove_data *data;
- pending_removals = g_slist_remove (pending_removals, data);
+ for (iter = pending_removals; iter != NULL; iter = next) {
+ next = g_slist_next(iter);
+ data = iter->data;
+ pending_removals = g_slist_delete_link (pending_removals, iter);
- gtk_tree_model_row_deleted (GTK_TREE_MODEL(data->model), data->path);
- gnc_tree_model_account_path_changed (data->model, data->path);
- gtk_tree_path_free(data->path);
- g_free(data);
+ gtk_tree_model_row_deleted (GTK_TREE_MODEL(data->model), data->path);
+ gnc_tree_model_account_path_changed (data->model, data->path);
+ gtk_tree_path_free(data->path);
+ g_free(data);
+ }
+
+ /* Remove me */
+ return FALSE;
}
+/** This function is a helper routine for the following
+ * gnc_tree_model_account_event_handler() function. It is called to
+ * add an item to the pending removal list.
+ *
+ * @param entity The guid value of the account that is being removed
+ * from the model.
+ *
+ * @param model A pointer to the tree model.
+ *
+ * @param path The path to the removed account. This can't be
+ * generated once the account is removed.
+ */
+static void
+pending_list_add (GUID *entity,
+ GncTreeModelAccount *model,
+ GtkTreePath *path)
+{
+ remove_data *data;
+
+ data = malloc(sizeof(*data));
+ data->guid = *entity;
+ data->model = model;
+ data->path = path;
+ pending_removals = g_slist_append (pending_removals, data);
+ g_idle_add_full(G_PRIORITY_HIGH_IDLE,
+ gnc_tree_model_account_do_deletions, NULL, NULL);
+}
+
+
/** This function is the handler for all event messages from the
* engine. Its purpose is to update the account tree model any time
* an account is added to the engine or deleted from the engine.
@@ -1473,7 +1520,6 @@
GtkTreePath *path;
GtkTreeIter iter;
Account *account;
- remove_data *data;
const gchar *account_name;
/* hard failures */
@@ -1518,16 +1564,12 @@
return;
}
- data = malloc(sizeof(*data));
- data->guid = *entity;
- data->model = model;
- data->path = path;
- pending_removals = g_slist_append (pending_removals, data);
+ pending_list_add(entity, model, path);
LEAVE(" ");
return;
case GNC_EVENT_MODIFY:
- DEBUG("change account %p (%s)", account, account_name);
+ DEBUG("modify account %p (%s)", account, account_name);
path = gnc_tree_model_account_get_path_from_account (model, account);
if (path == NULL) {
LEAVE("account not in model");
@@ -1546,9 +1588,6 @@
case GNC_EVENT_DESTROY:
/* Tell the filters/view the account has been deleted. */
DEBUG("destroy account %p (%s)", account, account_name);
- g_slist_foreach (pending_removals,
- (GFunc)gnc_tree_model_account_delete_event_helper,
- entity);
break;
default:
More information about the gnucash-changes
mailing list