Rework the events generated by the account/group files and consumed by

the GncTreeModelAccount.  Should eliminate all g_value_inset and
g_object_set_property warnings related to changes in the account tree.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13483 57a11ea4-9604-0410-9ed3-97b8803252fd
zzzoldfeatures/register-rewrite
David Hampton 20 years ago
parent d46c86ca3a
commit 015e064bcc

@ -1,5 +1,15 @@
2006-03-04 David Hampton <hampton@employees.org>
* src/gnome-utils/gnc-tree-model-account.c:
* src/engine/Account.c:
* src/engine/Group.c: Rework the events generated by the
account/group files and consumed by the GncTreeModelAccount.
Should eliminate all g_value_inset and g_object_set_property
warnings related to changes in the account tree.
* src/engine/Transaction.c:
* src/engine/gnc-event.h: Rename a data structure field.
* src/gnome-utils/dialog-account.c: Fix duplicate account name
checking bug that prevented editing account info.

@ -33,6 +33,7 @@
#include "Group.h"
#include "GroupP.h"
#include "TransactionP.h"
#include "gnc-event.h"
#include "gnc-lot.h"
#include "gnc-lot-p.h"
#include "gnc-pricedb.h"
@ -330,6 +331,8 @@ static inline void acc_free (QofInstance *inst)
void
xaccAccountCommitEdit (Account *acc)
{
GncEventData ed;
if(!qof_commit_edit(&acc->inst)) { return;}
/* If marked for deletion, get rid of subaccounts first,
@ -375,6 +378,10 @@ xaccAccountCommitEdit (Account *acc)
xaccGroupInsertAccount(acc->parent, acc);
}
ed.node = acc;
ed.idx = 0;
qof_event_gen(&acc->inst.entity, QOF_EVENT_MODIFY, &ed);
if (qof_commit_edit_part2(&acc->inst, on_err, noop, acc_free))
gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_MODIFY);
}
@ -890,6 +897,7 @@ xaccAccountRecomputeBalance (Account * acc)
gnc_numeric reconciled_balance;
Split *last_split = NULL;
GList *lp;
GncEventData ed;
if (NULL == acc) return;
if (acc->inst.editlevel > 0) return;
@ -934,6 +942,10 @@ xaccAccountRecomputeBalance (Account * acc)
acc->reconciled_balance = reconciled_balance;
acc->balance_dirty = FALSE;
ed.node = acc;
ed.idx = 0;
qof_event_gen(&acc->inst.entity, QOF_EVENT_MODIFY, &ed);
gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_MODIFY);
}

@ -32,6 +32,7 @@
#include "Group.h"
#include "GroupP.h"
#include "TransactionP.h"
#include "gnc-event.h"
static QofLogModule log_module = GNC_MOD_ENGINE;
@ -626,6 +627,8 @@ xaccAccountRemoveGroup (Account *acc)
void
xaccGroupRemoveAccount (AccountGroup *grp, Account *acc)
{
GncEventData ed;
if (!acc) return;
/* Note this routine might be called on accounts which
@ -642,8 +645,15 @@ xaccGroupRemoveAccount (AccountGroup *grp, Account *acc)
acc->parent = NULL;
/* Gather event data */
ed.node = grp->parent; /* The parent account */
ed.idx = g_list_index(grp->accounts, acc);
grp->accounts = g_list_remove (grp->accounts, acc);
/* Now send the event. */
qof_event_gen(&acc->inst.entity, QOF_EVENT_REMOVE, &ed);
grp->saved = 0;
/* if this was the last account in a group, delete
@ -696,6 +706,8 @@ group_sort_helper (gconstpointer a, gconstpointer b)
void
xaccGroupInsertAccount (AccountGroup *grp, Account *acc)
{
GncEventData ed;
if (!grp || !grp->book) return;
if (!acc) return;
@ -746,6 +758,11 @@ xaccGroupInsertAccount (AccountGroup *grp, Account *acc)
grp->accounts = g_list_insert_sorted (grp->accounts, acc,
group_sort_helper);
/* Gather event data */
ed.node = acc;
ed.idx = 0;
qof_event_gen(&acc->inst.entity, QOF_EVENT_ADD, &ed);
gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_ADD);
acc->inst.dirty = TRUE;

@ -36,6 +36,7 @@
#include "gnc-commodity.h"
#include "gnc-gconf-utils.h"
#include "gnc-engine.h"
#include "gnc-event.h"
#include "gnc-gobject-utils.h"
#include "gnc-ui-util.h"
@ -87,9 +88,10 @@ static void gnc_tree_model_account_set_toplevel (GncTreeModelAccount *model,
Account *toplevel);
/** Component Manager Callback ******************************************/
static void gnc_tree_model_account_event_handler (GUID *entity, QofIdType type,
GNCEngineEventType event_type,
gpointer user_data);
static void gnc_tree_model_account_event_handler (QofEntity *entity,
QofEventId event_type,
GncTreeModelAccount *model,
GncEventData *ed);
/** The instance private data for a account tree model. */
typedef struct GncTreeModelAccountPrivate
@ -253,7 +255,7 @@ gnc_tree_model_account_dispose (GObject *object)
priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
if (priv->event_handler_id) {
gnc_engine_unregister_event_handler (priv->event_handler_id);
qof_event_unregister_handler (priv->event_handler_id);
priv->event_handler_id = 0;
}
@ -304,8 +306,8 @@ gnc_tree_model_account_new (AccountGroup *group)
gnc_tree_model_account_set_toplevel (model, account);
}
priv->event_handler_id =
gnc_engine_register_event_handler (gnc_tree_model_account_event_handler, model);
priv->event_handler_id = qof_event_register_handler
((QofEventHandler)gnc_tree_model_account_event_handler, model);
LEAVE("model %p", model);
return GTK_TREE_MODEL (model);
@ -1367,24 +1369,6 @@ gnc_tree_model_account_get_path_from_account (GncTreeModelAccount *model,
/* 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;
static GSList *pending_removals = NULL;
/** This function performs common updating to the model after an
* account has been added or removed. The parent entry needs to be
* tapped on the shoulder so that it can correctly update the
@ -1406,11 +1390,12 @@ gnc_tree_model_account_path_changed (GncTreeModelAccount *model,
{
GtkTreeIter iter;
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);
}
while (gtk_tree_path_get_depth(path) > 0) {
if (!gtk_tree_model_get_iter (GTK_TREE_MODEL(model), &iter, path))
break;
gtk_tree_model_row_changed (GTK_TREE_MODEL(model), path, &iter);
gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL(model), path, &iter);
gtk_tree_path_up(path);
}
do {
@ -1419,72 +1404,6 @@ gnc_tree_model_account_path_changed (GncTreeModelAccount *model,
}
/** 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 unused
*
* @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 gboolean
gnc_tree_model_account_do_deletions (gpointer unused)
{
GSList *iter, *next = NULL;
remove_data *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);
}
/* 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.
@ -1514,88 +1433,80 @@ pending_list_add (GUID *entity,
* @param user_data A pointer to the account tree model.
*/
static void
gnc_tree_model_account_event_handler (GUID *entity, QofIdType type,
GNCEngineEventType event_type,
gpointer user_data)
gnc_tree_model_account_event_handler (QofEntity *entity,
QofEventId event_type,
GncTreeModelAccount *model,
GncEventData *ed)
{
GncTreeModelAccount *model;
GncTreeModelAccountPrivate *priv;
GtkTreePath *path;
GtkTreeIter iter;
Account *account;
const gchar *account_name;
/* hard failures */
g_return_if_fail(GNC_IS_TREE_MODEL_ACCOUNT(user_data));
/* soft failures */
if (safe_strcmp(type, GNC_ID_ACCOUNT) != 0)
return;
ENTER("entity %p of type %s, event %d, model %p",
entity, type, event_type, user_data);
model = (GncTreeModelAccount *)user_data;
GncTreeModelAccountPrivate *priv;
const gchar *parent_name;
GtkTreePath *path = NULL;
GtkTreeIter iter;
Account *account, *parent;
g_return_if_fail(model); /* Required */
if (!ed) return; /* Required for us. Not always sent. */
ENTER("entity %p of type %d, model %p, event_data %p",
entity, event_type, model, ed);
priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
/* What to do, that to do. */
switch (event_type) {
case QOF_EVENT_ADD:
/* Tell the filters/views where the new account was added. */
account = GNC_ACCOUNT(ed->node);
DEBUG("add account %p (%s)", account, xaccAccountGetName(account));
path = gnc_tree_model_account_get_path_from_account(model, account);
if (!path) {
DEBUG("can't generate path");
break;
}
if (!gnc_tree_model_account_get_iter(GTK_TREE_MODEL(model), &iter, path)) {
DEBUG("can't generate iter");
break;
}
gtk_tree_model_row_inserted (GTK_TREE_MODEL(model), path, &iter);
if (gtk_tree_path_up (path))
gnc_tree_model_account_path_changed(model, path);
break;
case QOF_EVENT_REMOVE:
parent = ed->node ? GNC_ACCOUNT(ed->node) : priv->toplevel;
parent_name = ed->node ? xaccAccountGetName(parent) : "Root";
DEBUG("remove child %d of account %p (%s)", ed->idx, parent, parent_name);
path = gnc_tree_model_account_get_path_from_account(model, parent);
if (!path) {
DEBUG("can't generate path");
break;
}
gtk_tree_path_append_index (path, ed->idx);
gtk_tree_model_row_deleted (GTK_TREE_MODEL(model), path);
gnc_tree_model_account_path_changed(model, path);
break;
case QOF_EVENT_MODIFY:
account = GNC_ACCOUNT(ed->node);
DEBUG("modify account %p (%s)", account, xaccAccountGetName(account));
path = gnc_tree_model_account_get_path_from_account(model, account);
if (!path) {
DEBUG("can't generate path");
break;
}
if (!gnc_tree_model_account_get_iter(GTK_TREE_MODEL(model), &iter, path)) {
DEBUG("can't generate iter");
break;
}
gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter);
break;
default:
DEBUG("unknown event type");
return;
}
/* Get the account.*/
priv = GNC_TREE_MODEL_ACCOUNT_GET_PRIVATE(model);
account = xaccAccountLookup (entity, priv->book);
if (!account) {
LEAVE("account not in this model's book");
return;
}
account_name = xaccAccountGetName(account);
switch (event_type) {
case GNC_EVENT_ADD:
/* Tell the filters/views where the new account was added. */
DEBUG("add account %p (%s)", account, account_name);
if (gnc_tree_model_account_get_iter_from_account (
model, account, &iter)) {
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_account_path_changed (model, path);
gtk_tree_path_free(path);
}
break;
case GNC_EVENT_REMOVE:
/* Record the path of this account for later use in destruction */
DEBUG("remove 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");
return;
}
pending_list_add(entity, model, path);
LEAVE(" ");
return;
case GNC_EVENT_MODIFY:
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");
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(" ");
return;
case GNC_EVENT_DESTROY:
/* Tell the filters/view the account has been deleted. */
DEBUG("destroy account %p (%s)", account, account_name);
break;
default:
LEAVE("ignored event for %p (%s)", account, account_name);
return;
}
LEAVE(" new stamp %u", model->stamp);
if (path)
gtk_tree_path_free(path);
LEAVE(" ");
return;
}

Loading…
Cancel
Save