r16416 - gnucash/branches/register-rewrite/src/engine - Implement CopyOnto semantics for both transactions and splits.
Chris Shoemaker
chris at cvs.gnucash.org
Sat Aug 11 17:04:03 EDT 2007
Author: chris
Date: 2007-08-11 16:59:20 -0400 (Sat, 11 Aug 2007)
New Revision: 16416
Trac: http://svn.gnucash.org/trac/changeset/16416
Modified:
gnucash/branches/register-rewrite/src/engine/Split.c
gnucash/branches/register-rewrite/src/engine/Split.h
gnucash/branches/register-rewrite/src/engine/Transaction.c
gnucash/branches/register-rewrite/src/engine/Transaction.h
gnucash/branches/register-rewrite/src/engine/TransactionP.h
Log:
Implement CopyOnto semantics for both transactions and splits.
- Export xaccFreeTransaction(), at least in the "private" header, since
it's the only correct thing to do with a duped Transaction that you
don't want to keep.
- In addition, add xaccTransCopyOntoAndChangeAccount() which is just
what is needed for copying a transaction from one account into another.
Modified: gnucash/branches/register-rewrite/src/engine/Split.c
===================================================================
--- gnucash/branches/register-rewrite/src/engine/Split.c 2007-08-11 20:47:13 UTC (rev 16415)
+++ gnucash/branches/register-rewrite/src/engine/Split.c 2007-08-11 20:59:20 UTC (rev 16416)
@@ -159,6 +159,8 @@
split->inst.entity.guid = s->inst.entity.guid;
split->inst.book = s->inst.book;
+ /* Do not call xaccSplitSetParent() or xaccSplitSetAccount because
+ we do not want to generate any events. */
split->parent = s->parent;
split->acc = s->acc;
split->orig_acc = s->orig_acc;
@@ -216,6 +218,33 @@
return split;
}
+/* This is really a helper for xaccTransCopyOnto. It doesn't reparent
+ the 'to' split to from's transaction, because xaccTransCopyOnto is
+ responsible for parenting the split to the correct transaction.
+ Also, from's parent transaction may not even be a valid
+ transaction, so this function may not modify anything about 'from'
+ or from's transaction.
+*/
+void
+xaccSplitCopyOnto(const Split *from, Split *to)
+{
+ if (!from || !to) return;
+ xaccTransBeginEdit (to->parent);
+
+ xaccSplitSetMemo(to, xaccSplitGetMemo(from));
+ xaccSplitSetAction(to, xaccSplitGetAction(from));
+ xaccSplitSetAmount(to, xaccSplitGetAmount(from));
+ xaccSplitSetValue(to, xaccSplitGetValue(from));
+ /* Setting the account is okay here because, even though the from
+ split might not really belong to the account it claims to,
+ setting the account won't cause any event involving from. */
+ xaccSplitSetAccount(to, xaccSplitGetAccount(from));
+ /* N.B. Don't set parent. */
+
+ qof_instance_set_dirty(QOF_INSTANCE(to));
+ xaccTransCommitEdit(to->parent);
+}
+
#ifdef DUMP_FUNCTIONS
static void
xaccSplitDump (const Split *split, const char *tag)
@@ -1350,7 +1379,6 @@
CACHE_REPLACE(split->memo, memo);
qof_instance_set_dirty(QOF_INSTANCE(split));
xaccTransCommitEdit(split->parent);
-
}
static void
Modified: gnucash/branches/register-rewrite/src/engine/Split.h
===================================================================
--- gnucash/branches/register-rewrite/src/engine/Split.h 2007-08-11 20:47:13 UTC (rev 16415)
+++ gnucash/branches/register-rewrite/src/engine/Split.h 2007-08-11 20:59:20 UTC (rev 16416)
@@ -97,6 +97,8 @@
*/
gboolean xaccSplitDestroy (Split *split);
+void xaccSplitCopyOnto(const Split *from, Split *to);
+
/** Returns the book of this split, i.e. the entity where this split
* is stored. */
QofBook * xaccSplitGetBook (const Split *split);
Modified: gnucash/branches/register-rewrite/src/engine/Transaction.c
===================================================================
--- gnucash/branches/register-rewrite/src/engine/Transaction.c 2007-08-11 20:47:13 UTC (rev 16415)
+++ gnucash/branches/register-rewrite/src/engine/Transaction.c 2007-08-11 20:59:20 UTC (rev 16416)
@@ -439,11 +439,65 @@
return trans;
}
+void
+xaccTransCopyOnto(const Transaction *from, Transaction *to)
+{
+ xaccTransCopyOntoAndChangeAccount(from, to, NULL, NULL);
+}
+/* This function explicitly must robustly handle some unusual input.
+
+ 'from' may be a duped trans (see xaccDupeTransaction), so its
+ splits may not really belong to the accounts that they say they do.
+
+ 'from_acc' need not be a valid account. It may be an already freed
+ Account. Therefore, it must not be dereferenced at all.
+
+ Neither 'from', nor 'from_acc', nor any of 'from's splits may be modified
+ in any way.
+
+ The 'to' transaction will end up with valid copies of from's
+ splits. In addition, the copies of any of from's splits that were
+ in from_acc (or at least claimed to be) will end up in to_acc.
+*/
+void
+xaccTransCopyOntoAndChangeAccount(const Transaction *from, Transaction *to,
+ const Account *from_acc, Account *to_acc)
+{
+ Timespec ts = {0,0};
+ gboolean change_accounts = FALSE;
+
+ if (!from || !to)
+ return;
+
+ change_accounts = from_acc && GNC_IS_ACCOUNT(to_acc) && from_acc != to_acc;
+ xaccTransBeginEdit(to);
+
+ FOR_EACH_SPLIT(to, xaccSplitDestroy(s));
+
+ xaccTransSetCurrency(to, xaccTransGetCurrency(from));
+ xaccTransSetDescription(to, xaccTransGetDescription(from));
+ xaccTransSetNum(to, xaccTransGetNum(from));
+ xaccTransSetNotes(to, xaccTransGetNotes(from));
+ xaccTransGetDatePostedTS(from, &ts);
+ xaccTransSetDatePostedTS(to, &ts);
+
+ /* Each new split will be parented to 'to' */
+ FOR_EACH_SPLIT(from, {
+ Split *new_split = xaccMallocSplit(
+ qof_instance_get_book(QOF_INSTANCE(from)));
+ xaccSplitCopyOnto(s, new_split);
+ if (change_accounts && xaccSplitGetAccount(s) == from_acc)
+ xaccSplitSetAccount(new_split, to_acc);
+ xaccSplitSetParent(new_split, to);
+ });
+ xaccTransCommitEdit(to);
+}
+
/********************************************************************\
\********************************************************************/
-static void
+void
xaccFreeTransaction (Transaction *trans)
{
GList *node;
Modified: gnucash/branches/register-rewrite/src/engine/Transaction.h
===================================================================
--- gnucash/branches/register-rewrite/src/engine/Transaction.h 2007-08-11 20:47:13 UTC (rev 16415)
+++ gnucash/branches/register-rewrite/src/engine/Transaction.h 2007-08-11 20:59:20 UTC (rev 16416)
@@ -132,6 +132,13 @@
*/
Transaction * xaccTransClone (const Transaction *t);
+void
+xaccTransCopyOnto(const Transaction *from, Transaction *to);
+
+void
+xaccTransCopyOntoAndChangeAccount(const Transaction *from, Transaction *to,
+ const Account *from_acc, Account *to_acc);
+
/** Equality.
*
* @param ta First transaction to compare
Modified: gnucash/branches/register-rewrite/src/engine/TransactionP.h
===================================================================
--- gnucash/branches/register-rewrite/src/engine/TransactionP.h 2007-08-11 20:47:13 UTC (rev 16415)
+++ gnucash/branches/register-rewrite/src/engine/TransactionP.h 2007-08-11 20:59:20 UTC (rev 16416)
@@ -136,6 +136,8 @@
*/
Transaction * xaccDupeTransaction (const Transaction *t);
+void xaccFreeTransaction (Transaction *trans);
+
/* The xaccTransSet/GetVersion() routines set & get the version
* numbers on this transaction. The version number is used to manage
* multi-user updates. These routines are private because we don't
More information about the gnucash-changes
mailing list