diff --git a/src/engine/Account.c b/src/engine/Account.c index afa5629645..437c70f7c8 100644 --- a/src/engine/Account.c +++ b/src/engine/Account.c @@ -1,7 +1,7 @@ /********************************************************************\ * Account.c -- Account data structure implementation * * Copyright (C) 1997 Robin D. Clark * - * Copyright (C) 1997-2001 Linas Vepstas * + * Copyright (C) 1997-2002 Linas Vepstas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -39,6 +39,7 @@ #include "gnc-engine-util.h" #include "gnc-event-p.h" #include "gnc-lot.h" +#include "gnc-lot-p.h" #include "kvp_frame.h" #include "kvp-util-p.h" #include "messages.h" @@ -98,6 +99,7 @@ xaccInitAccount (Account * acc, GNCBook *book) acc->commodity_scu = 0; acc->splits = NULL; + acc->lots = NULL; acc->version = 0; acc->version_check = 0; @@ -273,6 +275,21 @@ xaccFreeAccount (Account *acc) acc->children = NULL; } + /* remove lots -- although these should be gone by now. */ + if (acc->lots) + { + PERR (" instead of calling xaccFreeAccount(), please call \n" + " xaccAccountBeginEdit(); xaccAccountDestroy(); \n"); + + for (lp=acc->lots; lp; lp=lp->next) + { + GNCLot *lot = lp->data; + gnc_lot_destroy (lot); + } + g_list_free (acc->lots); + acc->lots = NULL; + } + /* Next, clean up the splits */ /* NB there shouldn't be any splits by now ... they should * have been all been freed by CommitEdit(). We can remove this @@ -388,6 +405,8 @@ xaccAccountCommitEdit (Account *acc) * and then the splits ... */ if (acc->do_free) { + GList *lp; + acc->editlevel++; /* First, recursively free children */ @@ -407,6 +426,15 @@ xaccAccountCommitEdit (Account *acc) xaccTransCommitEdit (t); } + /* the lots should be empty by now */ + for (lp=acc->lots; lp; lp=lp->next) + { + GNCLot *lot = lp->data; + gnc_lot_destroy (lot); + } + g_list_free (acc->lots); + acc->lots = NULL; + acc->core_dirty = TRUE; acc->editlevel--; } @@ -908,6 +936,47 @@ xaccClearMarkDownGr (AccountGroup *grp, short val) /********************************************************************\ \********************************************************************/ +void +xaccAccountInsertLot (Account *acc, GNCLot *lot) +{ + GList *sl; + Account * old_acc = NULL; + + if (!acc || !lot) return; + + /* pull it out of the old account */ + if (lot->account && lot->account != acc) + { + old_acc = lot->account; + xaccAccountBeginEdit (old_acc); + old_acc->lots = g_list_remove (old_acc->lots, lot); + + } + + xaccAccountBeginEdit(acc); + lot->account = acc; + acc->lots = g_list_prepend (acc->lots, lot); + + /* Move all slots over to the new account. At worst, + * this is a no-op. */ + if (lot->splits) + { + for (sl = lot->splits; sl; sl=sl->next) + { + Split *s = sl->data; + if (s->acc != acc) + { + xaccAccountInsertSplit (acc, s); + } + } + } + xaccAccountCommitEdit(acc); + xaccAccountCommitEdit(old_acc); +} + +/********************************************************************\ +\********************************************************************/ + void xaccAccountInsertSplit (Account *acc, Split *split) { diff --git a/src/engine/Account.h b/src/engine/Account.h index fa470bcd89..f1d4f9f360 100644 --- a/src/engine/Account.h +++ b/src/engine/Account.h @@ -1,7 +1,7 @@ /********************************************************************\ * Account.h -- Account handling public routines * * Copyright (C) 1997 Robin D. Clark * - * Copyright (C) 1997-2001 Linas Vepstas * + * Copyright (C) 1997-2002 Linas Vepstas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -200,6 +200,14 @@ Account * xaccAccountLookupTwin (Account *acc, GNCBook *book); gboolean xaccAccountEqual(Account *a, Account* b, gboolean check_guids); /* ------------------ */ +/* The xaccAccountInsertLot() method will register the indicated lot + * with this account. Any splits later inserted into this lot must + * belong to this account. If the lot is already in another account, + * the lot, and all of the splits in it, will be moved from that + * account to this account. + */ +void xaccAccountInsertLot (Account *, GNCLot *); + /* * The xaccAccountInsertSplit() method will insert the indicated * split into the indicated account. If the split already diff --git a/src/engine/AccountP.h b/src/engine/AccountP.h index e620dfecfa..4f36b5f642 100644 --- a/src/engine/AccountP.h +++ b/src/engine/AccountP.h @@ -1,7 +1,7 @@ /********************************************************************\ * AccountP.h -- Account engine-private data structure * * Copyright (C) 1997 Robin D. Clark * - * Copyright (C) 1997-2001, Linas Vepstas * + * Copyright (C) 1997-2002, Linas Vepstas * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -122,6 +122,7 @@ struct account_s guint32 version_check; /* data aging timestamp */ SplitList *splits; /* list of split pointers */ + LotList *lots; /* list of lot pointers */ /* keep track of nesting level of begin/end edit calls */ gint32 editlevel; diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index 6631f225ff..f532fec7a1 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -163,6 +163,7 @@ xaccDupeSplit (Split *s) split->parent = s->parent; split->acc = s->acc; + split->lot = s->lot; split->memo = g_cache_insert (gnc_engine_get_string_cache(), s->memo); split->action = g_cache_insert (gnc_engine_get_string_cache(), s->action); @@ -205,6 +206,7 @@ xaccFreeSplit (Split *split) split->amount = gnc_numeric_zero(); split->value = gnc_numeric_zero(); split->parent = NULL; + split->lot = NULL; xaccSplitSetAccount(split, NULL); split->date_reconciled.tv_sec = 0; diff --git a/src/engine/gnc-engine.h b/src/engine/gnc-engine.h index 054a573d33..e707af6d09 100644 --- a/src/engine/gnc-engine.h +++ b/src/engine/gnc-engine.h @@ -41,6 +41,7 @@ typedef struct gnc_session_struct GNCSession; typedef GList AccountList; typedef GList BookList; +typedef GList LotList; typedef GList SplitList; typedef GList TransList; diff --git a/src/engine/gnc-lot.c b/src/engine/gnc-lot.c index fc891295f4..758be9db2e 100644 --- a/src/engine/gnc-lot.c +++ b/src/engine/gnc-lot.c @@ -103,18 +103,18 @@ gnc_lot_destroy (GNCLot *lot) const GUID * gnc_lot_get_guid (GNCLot *lot) { - if (!lot) return NULL; - return &lot->guid; + if (!lot) return NULL; + return &lot->guid; } void gnc_lot_set_guid (GNCLot *lot, GUID uid) { - if (!lot) return; + if (!lot) return; - if (guid_equal (&lot->guid, &uid)) return; + if (guid_equal (&lot->guid, &uid)) return; - xaccRemoveEntity(lot->book->entity_table, &lot->guid); + xaccRemoveEntity(lot->book->entity_table, &lot->guid); lot->guid = uid; xaccStoreEntity(lot->book->entity_table, lot, &lot->guid, GNC_ID_LOT); } @@ -139,8 +139,8 @@ gnc_lot_get_account (GNCLot *lot) kvp_frame * gnc_lot_get_slots (GNCLot *lot) { - if (!lot) return NULL; - return lot->kvp_data; + if (!lot) return NULL; + return lot->kvp_data; } /* ============================================================= */ @@ -189,7 +189,7 @@ gnc_lot_add_split (GNCLot *lot, Split *split) acc = xaccSplitGetAccount (split); if (NULL == lot->account) { - lot->account = acc; + xaccAccountInsertLot (acc, lot); } else if (lot->account != acc) { @@ -200,11 +200,11 @@ gnc_lot_add_split (GNCLot *lot, Split *split) return; } - if (split->lot) - { - gnc_lot_remove_split (split->lot, split); - } - split->lot = lot; + if (split->lot) + { + gnc_lot_remove_split (split->lot, split); + } + split->lot = lot; lot->splits = g_list_append (lot->splits, split); } @@ -215,7 +215,7 @@ gnc_lot_remove_split (GNCLot *lot, Split *split) if (!lot || !split) return; lot->splits = g_list_remove (lot->splits, split); - split->lot = NULL; + split->lot = NULL; if (NULL == lot->splits) {