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