diff --git a/src/Account.c b/src/Account.c index aaa0f76208..69d316bbf7 100644 --- a/src/Account.c +++ b/src/Account.c @@ -50,11 +50,9 @@ int next_free_unique_account_id = 0; /********************************************************************\ \********************************************************************/ -Account * -xaccMallocAccount( void ) - { - Account *acc = (Account *)_malloc(sizeof(Account)); - +void +xaccInitAccount (Account * acc) +{ acc->id = next_free_unique_account_id; next_free_unique_account_id ++; @@ -77,11 +75,23 @@ xaccMallocAccount( void ) acc->splits = (Split **) _malloc (sizeof (Split *)); acc->splits[0] = NULL; - return acc; - } + acc->changed = 0; +} /********************************************************************\ \********************************************************************/ + +Account * +xaccMallocAccount( void ) +{ + Account *acc = (Account *)_malloc(sizeof(Account)); + xaccInitAccount (acc); + return acc; +} + +/********************************************************************\ +\********************************************************************/ + void xaccFreeAccount( Account *acc ) { @@ -177,7 +187,9 @@ xaccInsertSplit ( Account *acc, Split *split ) if (!acc) return; if (!split) return; - /* mark the data file as needing to be saved: */ + /* mark the account as having changed, and + * the account group as requiring a save */ + acc -> changed = TRUE; if( acc->parent != NULL ) acc->parent->saved = FALSE; split->acc = (struct _account *) acc; @@ -234,7 +246,9 @@ xaccRemoveSplit ( Account *acc, Split *split ) if (!acc) return; if (!split) return; - /* mark the data file as needing to be saved: */ + /* mark the account as having changed, and + * the account group as requiring a save */ + acc -> changed = TRUE; if( acc->parent != NULL ) acc->parent->saved = FALSE; for( i=0,j=0; jnumSplits; i++,j++ ) { @@ -294,6 +308,7 @@ xaccRecomputeBalance( Account * acc ) Split *split, *last_split; if( NULL == acc ) return; + if (FALSE == acc->changed) return; split = acc->splits[0]; while (split) { diff --git a/src/Ledger.c b/src/Ledger.c index d196ade94f..72f3816930 100644 --- a/src/Ledger.c +++ b/src/Ledger.c @@ -93,13 +93,11 @@ printf ("xfr from %s to %s \n", xfr, new_acc_name); /* remove the partner split from the old account */ acc = (Account *) (partner_split->acc); xaccRemoveSplit (acc, partner_split); - accRefresh (acc); /* insert the partner split into the new account */ acc = (Account *) split->acc; acc = xaccGetPeerAccountFromName (acc, new_acc_name); xaccInsertSplit (acc, partner_split); - accRefresh (acc); /* loop over all of the debit splits, and refresh, * since they were all affected. */ @@ -108,7 +106,6 @@ printf ("xfr from %s to %s \n", xfr, new_acc_name); partner_split = trans->debit_splits[i]; while (partner_split) { acc = (Account *) (partner_split->acc); - accRefresh (acc); i++; partner_split = trans->debit_splits[i]; } @@ -124,13 +121,11 @@ printf ("xfr from %s to %s \n", xfr, new_acc_name); /* remove the partner split from the old account */ acc = (Account *) (partner_split->acc); xaccRemoveSplit (acc, partner_split); - accRefresh (acc); /* insert the partner split into the new account */ acc = (Account *) split->acc; acc = xaccGetPeerAccountFromName (acc, new_acc_name); xaccInsertSplit (acc, partner_split); - accRefresh (acc); } } } @@ -160,14 +155,11 @@ xaccSaveRegEntry (BasicRegister *reg) printf ("saving %s \n", trans->description); /* copy the contents from the cursor to the split */ - if (MOD_DATE & changed) { + if (MOD_DATE & changed) xaccTransSetDate (trans, reg->dateCell->date.tm_mday, reg->dateCell->date.tm_mon+1, reg->dateCell->date.tm_year+1900); - /* hack alert -- should resort split array's */ - } - if (MOD_NUM & changed) xaccTransSetNum (trans, reg->numCell->value); @@ -207,8 +199,6 @@ printf ("saving %s \n", trans->description); if (changed) { acc = (Account *) split->acc; accRefresh (acc); - acc = (Account *) trans->credit_split.acc; - accRefresh (acc); } } diff --git a/src/RegWindow.c b/src/RegWindow.c index 9f7bc1bf1f..f379a8accf 100644 --- a/src/RegWindow.c +++ b/src/RegWindow.c @@ -656,7 +656,7 @@ void regRefresh (RegWindow *regData) * refresh *all* register windows which contain this account * \********************************************************************/ -void accRefresh (Account *acc) +static void Refresh (Account *acc) { RegWindow *regData; int n; @@ -685,6 +685,31 @@ void accRefresh (Account *acc) recnRefresh (acc); } +/********************************************************************\ +\********************************************************************/ + +static void grpRefresh (AccountGroup *grp) +{ + int i; + Account *acc; + + if (!grp) return; + + for (i=0; inumAcc; i++) { + acc = grp->account[i]; + if (acc->changed) Refresh (acc); + acc->changed = 0; + grpRefresh (acc->children); + } +} + +void accRefresh (Account *acc) +{ + AccountGroup * root; + root = xaccGetAccountRoot (acc); + grpRefresh (root); +} + /********************************************************************\ * xaccDestroyRegWindow() * It is enought to call just XtDestroy Widget. Any allocated diff --git a/src/Transaction.c b/src/Transaction.c index 814aab6a94..764b2bcc9d 100644 --- a/src/Transaction.c +++ b/src/Transaction.c @@ -27,6 +27,7 @@ #include "config.h" +#include "Account.h" #include "date.h" #include "Transaction.h" #include "util.h" @@ -34,8 +35,8 @@ /********************************************************************\ * Because I can't use C++ for this project, doesn't mean that I * * can't pretend too! These functions perform actions on the * - * Transaction data structure, in order to encapsulate the knowledge * - * of the internals of the Transaction in one file. * + * Transaction data structure, in order to encapsulate the * + * knowledge of the internals of the Transaction in one file. * \********************************************************************/ /********************************************************************\ @@ -105,6 +106,28 @@ xaccFreeSplit( Split *split ) /********************************************************************\ \********************************************************************/ +#define MARK_SPLIT(split) { \ + Account *acc = (Account *) ((split)->acc); \ + if (acc) acc->changed = 1; \ +} + +static void +MarkChanged (Transaction *trans) +{ + MARK_SPLIT (&(trans->credit_split)); + + if (trans->debit_splits) { + int i=0; + while (trans->debit_splits[i]) { + MARK_SPLIT (trans->debit_splits[i]); + i++; + } + } +} + +/********************************************************************\ +\********************************************************************/ + int xaccCountSplits (Split **tarray) { @@ -126,11 +149,13 @@ xaccCountSplits (Split **tarray) void xaccSetShareAmount (Split *s, double amt) { + MARK_SPLIT(s); s -> damount = amt; } void xaccSetAmount (Split *s, double amt) { + MARK_SPLIT(s); /* remember, damount is actually share price */ s -> damount = amt / (s->share_price); } @@ -264,11 +289,12 @@ xaccTransRecomputeAmount (Transaction *trans) trans -> credit_split.damount = -amount; trans -> credit_split.share_price = 1.0; } - + MARK_SPLIT (&(trans->credit_split)); } /********************************************************************\ \********************************************************************/ + void xaccTransAppendSplit (Transaction *trans, Split *split) { @@ -461,16 +487,49 @@ xaccCountTransactions (Transaction **tarray) void xaccTransSetDate (Transaction *trans, int day, int mon, int year) { + Split *split; + Account *acc; + trans->date.year = year; trans->date.month = mon; trans->date.day = day; + + /* since the date has changed, we need to be careful to + * make sure all associated splits are in proper order + * in thier accounts + */ + + split = &(trans->credit_split); + acc = (Account *) split->acc; + xaccRemoveSplit (acc, split); + xaccInsertSplit (acc, split); + xaccRecomputeBalance (acc); + + if (trans->debit_splits) { + int i=0; + split = trans->debit_splits[i]; + while (split) { + acc = (Account *) split->acc; + xaccRemoveSplit (acc, split); + xaccInsertSplit (acc, split); + xaccRecomputeBalance (acc); + + i++; + split = trans->debit_splits[i]; + } + } } +/********************************************************************\ +\********************************************************************/ + + void xaccTransSetNum (Transaction *trans, const char *xnum) { if (trans->num) free (trans->num); trans->num = strdup (xnum); + MarkChanged (trans); } void @@ -478,6 +537,7 @@ xaccTransSetDescription (Transaction *trans, const char *desc) { if (trans->description) free (trans->description); trans->description = strdup (desc); + MarkChanged (trans); } void @@ -485,6 +545,7 @@ xaccTransSetMemo (Transaction *trans, const char *memo) { if (trans->credit_split.memo) free (trans->credit_split.memo); trans->credit_split.memo = strdup (memo); + MARK_SPLIT (&(trans->credit_split)); /* if there is only one split, then keep memos in sync. */ if (trans->debit_splits) { @@ -492,6 +553,7 @@ xaccTransSetMemo (Transaction *trans, const char *memo) if (0x0 == trans->debit_splits[1]) { free (trans->debit_splits[0]->memo); trans->debit_splits[0]->memo = strdup (memo); + MARK_SPLIT (trans->debit_splits[0]); } } } @@ -502,6 +564,7 @@ xaccTransSetAction (Transaction *trans, const char *actn) { if (trans->credit_split.action) free (trans->credit_split.action); trans->credit_split.action = strdup (actn); + MARK_SPLIT (&(trans->credit_split)); /* if there is only one split, then keep action in sync. */ if (trans->debit_splits) { @@ -509,6 +572,7 @@ xaccTransSetAction (Transaction *trans, const char *actn) if (0x0 == trans->debit_splits[1]) { free (trans->debit_splits[0]->action); trans->debit_splits[0]->action = strdup (actn); + MARK_SPLIT (trans->debit_splits[0]); } } } @@ -518,6 +582,7 @@ void xaccTransSetReconcile (Transaction *trans, char recn) { trans->credit_split.reconciled = recn; + MARK_SPLIT (&(trans->credit_split)); } /********************************************************************\ @@ -528,6 +593,7 @@ xaccSplitSetMemo (Split *split, const char *memo) { if (split->memo) free (split->memo); split->memo = strdup (memo); + MARK_SPLIT (split); } void @@ -535,12 +601,14 @@ xaccSplitSetAction (Split *split, const char *actn) { if (split->action) free (split->action); split->action = strdup (actn); + MARK_SPLIT (split); } void xaccSplitSetReconcile (Split *split, char recn) { split->reconciled = recn; + MARK_SPLIT (split); } /************************ END OF ************************************\