From a3ca7143965a5c1af45a70fd0b2c4a513a75b024 Mon Sep 17 00:00:00 2001 From: Phil Longstaff Date: Sat, 27 Feb 2010 15:54:20 +0000 Subject: [PATCH] Convert GNCLot to use more gobject features. Removes all direct access to lot object fields, which are now accessed through functions or property names (for backend sql load). git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18745 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/backend/sql/gnc-lots-sql.c | 17 +- src/engine/Account.c | 16 +- src/engine/Period.c | 18 +- src/engine/Scrub2.c | 8 +- src/engine/Split.c | 8 +- src/engine/Transaction.c | 2 +- src/engine/cap-gains.c | 18 +- src/engine/gnc-engine.h | 2 +- src/engine/gnc-lot-p.h | 28 -- src/engine/gnc-lot.c | 504 ++++++++++++++++++++++----------- src/engine/gnc-lot.h | 16 +- src/engine/policy.c | 9 +- 12 files changed, 398 insertions(+), 248 deletions(-) diff --git a/src/backend/sql/gnc-lots-sql.c b/src/backend/sql/gnc-lots-sql.c index 02b552be38..7dbb0d98f7 100644 --- a/src/backend/sql/gnc-lots-sql.c +++ b/src/backend/sql/gnc-lots-sql.c @@ -31,6 +31,7 @@ #include #include "qof.h" +#include "Account.h" #include "gnc-lot.h" #include "gnc-backend-sql.h" @@ -49,7 +50,6 @@ static /*@ dependent @*//*@ null @*/ gpointer get_lot_account( gpointer pObject ); static void set_lot_account( gpointer pObject, /*@ null @*/ gpointer pValue ); -static void set_lot_is_closed( gpointer pObject, gboolean value ); static const GncSqlColumnTableEntry col_table[] = { @@ -57,8 +57,7 @@ static const GncSqlColumnTableEntry col_table[] = { "guid", CT_GUID, 0, COL_NNUL|COL_PKEY, "guid" }, { "account_guid", CT_GUID, 0, 0, NULL, NULL, (QofAccessFunc)get_lot_account, set_lot_account }, - { "is_closed", CT_BOOLEAN, 0, COL_NNUL, NULL, NULL, - (QofAccessFunc)gnc_lot_is_closed, (QofSetterFunc)set_lot_is_closed }, + { "is_closed", CT_BOOLEAN, 0, COL_NNUL, "is-closed" }, { NULL } /*@ +full_init_block @*/ }; @@ -98,18 +97,6 @@ set_lot_account( gpointer pObject, /*@ null @*/ gpointer pValue ) } } -static void -set_lot_is_closed( gpointer pObject, gboolean closed ) -{ - GNCLot* lot; - - g_return_if_fail( pObject != NULL ); - g_return_if_fail( GNC_IS_LOT(pObject) ); - - lot = GNC_LOT(pObject); - lot->is_closed = (char)closed; -} - static /*@ dependent @*//*@ null @*/ GNCLot* load_single_lot( GncSqlBackend* be, GncSqlRow* row ) { diff --git a/src/engine/Account.c b/src/engine/Account.c index d69588d7d9..57facef72c 100644 --- a/src/engine/Account.c +++ b/src/engine/Account.c @@ -1730,7 +1730,7 @@ xaccAccountRemoveLot (Account *acc, GNCLot *lot) ENTER ("(acc=%p, lot=%p)", acc, lot); priv->lots = g_list_remove(priv->lots, lot); - qof_event_gen (&lot->inst, QOF_EVENT_REMOVE, NULL); + qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_REMOVE, NULL); qof_event_gen (&acc->inst, QOF_EVENT_MODIFY, NULL); LEAVE ("(acc=%p, lot=%p)", acc, lot); } @@ -1739,35 +1739,37 @@ void xaccAccountInsertLot (Account *acc, GNCLot *lot) { AccountPrivate *priv, *opriv; - Account * old_acc = NULL; + Account * old_acc = NULL; + Account* lot_account; /* errors */ g_return_if_fail(GNC_IS_ACCOUNT(acc)); g_return_if_fail(GNC_IS_LOT(lot)); /* optimizations */ - if (lot->account == acc) + lot_account = gnc_lot_get_account(lot); + if (lot_account == acc) return; ENTER ("(acc=%p, lot=%p)", acc, lot); /* pull it out of the old account */ - if (lot->account) { - old_acc = lot->account; + if (lot_account) { + old_acc = lot_account; opriv = GET_PRIVATE(old_acc); opriv->lots = g_list_remove(opriv->lots, lot); } priv = GET_PRIVATE(acc); priv->lots = g_list_prepend(priv->lots, lot); - lot->account = acc; + gnc_lot_set_account(lot, acc); /* Don't move the splits to the new account. The caller will do this * if appropriate, and doing it here will not work if we are being * called from gnc_book_close_period since xaccAccountInsertSplit * will try to balance capital gains and things aren't ready for that. */ - qof_event_gen (&lot->inst, QOF_EVENT_ADD, NULL); + qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_ADD, NULL); qof_event_gen (&acc->inst, QOF_EVENT_MODIFY, NULL); LEAVE ("(acc=%p, lot=%p)", acc, lot); diff --git a/src/engine/Period.c b/src/engine/Period.c index 6b6ace706b..bbbd1406cb 100644 --- a/src/engine/Period.c +++ b/src/engine/Period.c @@ -228,11 +228,11 @@ gnc_book_insert_lot (QofBook *book, GNCLot *lot) col = qof_book_get_collection (book, GNC_ID_LOT); qof_instance_set_book(lot, book); - qof_collection_insert_entity (col, &lot->inst); + qof_collection_insert_entity (col, QOF_INSTANCE(lot)); /* Move the splits over (only if they haven't already been moved). */ col = qof_book_get_collection (book, GNC_ID_SPLIT); - for (snode = lot->splits; snode; snode=snode->next) + for (snode = gnc_lot_get_split_list(lot); snode; snode=snode->next) { Split *s = snode->data; if (qof_instance_get_book(s) != book) @@ -242,7 +242,7 @@ gnc_book_insert_lot (QofBook *book, GNCLot *lot) } } - twin = xaccAccountLookupTwin (lot->account, book); + twin = xaccAccountLookupTwin (gnc_lot_get_account(lot), book); if (!twin) { PERR ("near-fatal: twin account not found"); @@ -358,13 +358,13 @@ lot_has_open_trans_tree (GNCLot *lot) { SplitList *split_list, *snode; - if (1 == lot->marker) return FALSE; - if (2 == lot->marker) return TRUE; - lot->marker = 1; + if (1 == gnc_lot_get_marker(lot)) return FALSE; + if (2 == gnc_lot_get_marker(lot)) return TRUE; + gnc_lot_set_marker(lot, 1); if (FALSE == gnc_lot_is_closed(lot)) { - lot->marker = 2; + gnc_lot_set_marker(lot, 2); return TRUE; } @@ -375,7 +375,7 @@ lot_has_open_trans_tree (GNCLot *lot) Transaction *trans = s->parent; if (trans_has_open_lot_tree (trans)) { - lot->marker = 2; + gnc_lot_set_marker(lot, 2); return TRUE; } } @@ -445,7 +445,7 @@ clear_markers (Account *account, gpointer dummy) Transaction *trans = s->parent; GNCLot *lot = s->lot; trans->marker = 0; - if (lot) lot->marker = 0; + if (lot) gnc_lot_set_marker(lot, 0); } } diff --git a/src/engine/Scrub2.c b/src/engine/Scrub2.c index 3b2210718f..fc5846d04e 100644 --- a/src/engine/Scrub2.c +++ b/src/engine/Scrub2.c @@ -101,7 +101,7 @@ xaccLotFill (GNCLot *lot) GNCPolicy *pcy; if (!lot) return; - acc = lot->account; + acc = gnc_lot_get_account(lot); pcy = gnc_account_get_policy(acc); ENTER ("(lot=%s, acc=%s)", gnc_lot_get_title(lot), xaccAccountGetName(acc)); @@ -160,7 +160,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot) ENTER ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title")); - for (snode = lot->splits; snode; snode=snode->next) + for (snode = gnc_lot_get_split_list(lot); snode; snode=snode->next) { Split *s = snode->data; xaccSplitComputeCapGains (s, NULL); @@ -169,7 +169,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot) /* We double-check only closed lots */ if (FALSE == gnc_lot_is_closed (lot)) return; - for (snode = lot->splits; snode; snode=snode->next) + for (snode = gnc_lot_get_split_list(lot); snode; snode=snode->next) { Split *s = snode->data; Transaction *trans = s->parent; @@ -208,7 +208,7 @@ xaccLotScrubDoubleBalance (GNCLot *lot) */ PERR ("Closed lot fails to double-balance !! lot value=%s", gnc_num_dbg_to_string (value)); - for (node=lot->splits; node; node=node->next) + for (node = gnc_lot_get_split_list(lot); node; node=node->next) { Split *s = node->data; PERR ("s=%p amt=%s val=%s", s, diff --git a/src/engine/Split.c b/src/engine/Split.c index 848658663e..6f20ebf2c9 100644 --- a/src/engine/Split.c +++ b/src/engine/Split.c @@ -309,7 +309,7 @@ void mark_split (Split *s) } /* set dirty flag on lot too. */ - if (s->lot) s->lot->is_closed = -1; + if (s->lot) gnc_lot_set_closed_unknown(s->lot); } /* @@ -527,7 +527,7 @@ xaccSplitCommitEdit(Split *s) acc = s->acc; /* Remove from lot (but only if it hasn't been moved to new lot already) */ - if (s->lot && (s->lot->account != acc || qof_instance_get_destroying(s))) + if (s->lot && (gnc_lot_get_account(s->lot) != acc || qof_instance_get_destroying(s))) gnc_lot_remove_split (s->lot, s); /* Possibly remove the split from the original account... */ @@ -542,7 +542,7 @@ xaccSplitCommitEdit(Split *s) if (gnc_account_insert_split(acc, s)) { /* If the split's lot belonged to some other account, we leave it so. */ - if (s->lot && (NULL == s->lot->account)) + if (s->lot && (NULL == gnc_lot_get_account(s->lot))) xaccAccountInsertLot (acc, s->lot); } else { PERR("Account grabbed split prematurely."); @@ -558,7 +558,7 @@ xaccSplitCommitEdit(Split *s) } if (s->lot) { /* A change of value/amnt affects gains display, etc. */ - qof_event_gen (&s->lot->inst, QOF_EVENT_MODIFY, NULL); + qof_event_gen (QOF_INSTANCE(s->lot), QOF_EVENT_MODIFY, NULL); } /* Important: we save off the original parent transaction and account diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index f9ca3d06a1..fdb7652367 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -235,7 +235,7 @@ void gen_event_trans (Transaction *trans) if (lot) { /* A change of transaction date might affect opening date of lot */ - qof_event_gen (&lot->inst, QOF_EVENT_MODIFY, NULL); + qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_MODIFY, NULL); } } #endif diff --git a/src/engine/cap-gains.c b/src/engine/cap-gains.c index 04fd4c26e3..a12eefa2a4 100644 --- a/src/engine/cap-gains.c +++ b/src/engine/cap-gains.c @@ -690,7 +690,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc) if (!split) return; lot = split->lot; if (!lot) return; - pcy = gnc_account_get_policy(lot->account); + pcy = gnc_account_get_policy(gnc_lot_get_account(lot)); currency = split->parent->common_currency; ENTER ("(split=%p gains=%p status=0x%x lot=%s)", split, @@ -770,7 +770,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc) /* Note: if the value of the 'opening' split(s) has changed, * then the cap gains are changed. So we need to check not * only if this split is dirty, but also the lot-opening splits. */ - for (node=lot->splits; node; node=node->next) + for (node=gnc_lot_get_split_list(lot); node; node=node->next) { Split *s = node->data; if (pcy->PolicyIsOpeningSplit(pcy,lot,s)) @@ -830,7 +830,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc) gnc_numeric_abs(split->amount))) { GList *n; - for (n = lot->splits; n; n = n->next) + for (n = gnc_lot_get_split_list(lot); n; n = n->next) { Split *s = n->data; PINFO ("split amt=%s", gnc_num_dbg_to_string(s->amount)); @@ -849,7 +849,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc) gnc_numeric_negative_p(split->amount))) { GList *n; - for (n = lot->splits; n; n = n->next) + for (n = gnc_lot_get_split_list(lot); n; n = n->next) { Split *s = n->data; PINFO ("split amt=%s", gnc_num_dbg_to_string(s->amount)); @@ -925,7 +925,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc) if (NULL == lot_split) { - Account *lot_acc = lot->account; + Account *lot_acc = gnc_lot_get_account(lot); QofBook *book = qof_instance_get_book(lot_acc); new_gain_split = TRUE; @@ -1081,8 +1081,8 @@ xaccLotComputeCapGains (GNCLot *lot, Account *gain_acc) * to mark all splits dirty if the opening splits are dirty. */ ENTER("(lot=%p)", lot); - pcy = gnc_account_get_policy(lot->account); - for (node = lot->splits; node; node = node->next) + pcy = gnc_account_get_policy(gnc_lot_get_account(lot)); + for (node = gnc_lot_get_split_list(lot); node; node = node->next) { Split *s = node->data; if (pcy->PolicyIsOpeningSplit(pcy,lot,s)) @@ -1099,14 +1099,14 @@ xaccLotComputeCapGains (GNCLot *lot, Account *gain_acc) if (is_dirty) { - for (node = lot->splits; node; node = node->next) + for (node = gnc_lot_get_split_list(lot); node; node = node->next) { Split *s = node->data; s->gains |= GAINS_STATUS_VDIRTY; } } - for (node = lot->splits; node; node = node->next) + for (node = gnc_lot_get_split_list(lot); node; node = node->next) { Split *s = node->data; xaccSplitComputeCapGains (s, gain_acc); diff --git a/src/engine/gnc-engine.h b/src/engine/gnc-engine.h index d922967626..a13c6877a9 100644 --- a/src/engine/gnc-engine.h +++ b/src/engine/gnc-engine.h @@ -185,7 +185,7 @@ typedef struct gnc_commodity_table_s gnc_commodity_table; * * See the file src/doc/lots.txt for implmentation overview. */ -typedef struct gnc_lot_struct GNCLot; +typedef struct gnc_lot_s GNCLot; /** @brief Price of commodity on a given date. * A GNCPrice encapsulates price information: the cost of a commodity diff --git a/src/engine/gnc-lot-p.h b/src/engine/gnc-lot-p.h index 09bffdf8b1..4a8afc1c09 100644 --- a/src/engine/gnc-lot-p.h +++ b/src/engine/gnc-lot-p.h @@ -37,34 +37,6 @@ #ifndef GNC_LOT_P_H #define GNC_LOT_P_H -#include "gnc-lot.h" -#include "Account.h" - -struct gnc_lot_struct -{ - QofInstance inst; - - /* Account to which this lot applies. All splits in the lot must - * belong to this account. - */ - Account * account; - - /* List of splits that belong to this lot. */ - SplitList *splits; - - /* Handy cached value to indicate if lot is closed. */ - /* If value is negative, then the cache is invalid. */ - signed char is_closed; - - /* traversal marker, handy for preventing recursion */ - unsigned char marker; -}; - -struct _GncLotClass -{ - QofInstanceClass parent_class; -}; - #define gnc_lot_set_guid(L,G) qof_instance_set_guid(QOF_INSTANCE(L),&(G)) /* Register with the Query engine */ diff --git a/src/engine/gnc-lot.c b/src/engine/gnc-lot.c index dc7bcf4f0a..ff0ab3f353 100644 --- a/src/engine/gnc-lot.c +++ b/src/engine/gnc-lot.c @@ -39,10 +39,11 @@ * Copyright (c) 2002,2003 Linas Vepstas */ +#include "config.h" + #include #include -#include "config.h" #include "Account.h" #include "AccountP.h" #include "gnc-lot.h" @@ -54,37 +55,143 @@ /* This static indicates the debugging module that this .o belongs to. */ static QofLogModule log_module = GNC_MOD_LOT; +struct gnc_lot_s +{ + QofInstance inst; +}; + +enum { + PROP_0, + PROP_IS_CLOSED, + PROP_MARKER +}; + +typedef struct LotPrivate +{ + /* Account to which this lot applies. All splits in the lot must + * belong to this account. + */ + Account * account; + + /* List of splits that belong to this lot. */ + SplitList *splits; + + /* Handy cached value to indicate if lot is closed. */ + /* If value is negative, then the cache is invalid. */ + signed char is_closed; +#define LOT_CLOSED_UNKNOWN (-1) + + /* traversal marker, handy for preventing recursion */ + unsigned char marker; +} LotPrivate; + +#define GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE((o), GNC_TYPE_LOT, LotPrivate)) + +#define gnc_lot_set_guid(L,G) qof_instance_set_guid(QOF_INSTANCE(L),&(G)) + /* ============================================================= */ /* GObject Initialization */ -QOF_GOBJECT_IMPL(gnc_lot, GNCLot, QOF_TYPE_INSTANCE); +G_DEFINE_TYPE(GNCLot, gnc_lot, QOF_TYPE_INSTANCE) static void gnc_lot_init(GNCLot* lot) { + LotPrivate* priv; + + priv = GET_PRIVATE(lot); + priv->account = NULL; + priv->splits = NULL; + priv->is_closed = LOT_CLOSED_UNKNOWN; + priv->marker = 0; } static void -gnc_lot_dispose_real (GObject *lotp) +gnc_lot_dispose(GObject *lotp) { + G_OBJECT_CLASS(gnc_lot_parent_class)->dispose(lotp); } static void -gnc_lot_finalize_real(GObject* lotp) +gnc_lot_finalize(GObject* lotp) { + G_OBJECT_CLASS(gnc_lot_parent_class)->finalize(lotp); } static void -gnc_lot_init_data (GNCLot *lot, QofBook *book) +gnc_lot_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) { - ENTER ("(lot=%p, book=%p)", lot, book); - lot->account = NULL; - lot->splits = NULL; - lot->is_closed = -1; - lot->marker = 0; - - qof_instance_init_data(&lot->inst, GNC_ID_LOT, book); - LEAVE ("(lot=%p, book=%p)", lot, book); + GNCLot* lot; + LotPrivate* priv; + + g_return_if_fail(GNC_IS_LOT(object)); + + lot = GNC_LOT(object); + priv = GET_PRIVATE(lot); + switch(prop_id) { + case PROP_IS_CLOSED: + g_value_set_int(value, priv->is_closed); + break; + case PROP_MARKER: + g_value_set_int(value, priv->marker); + break; + } +} + +static void +gnc_lot_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) +{ + GNCLot* lot; + LotPrivate* priv; + + g_return_if_fail(GNC_IS_LOT(object)); + + lot = GNC_LOT(object); + priv = GET_PRIVATE(lot); + switch(prop_id) { + case PROP_IS_CLOSED: + priv->is_closed = g_value_get_int(value); + break; + case PROP_MARKER: + priv->marker = g_value_get_int(value); + break; + } +} + +static void +gnc_lot_class_init(GNCLotClass* klass) +{ + GObjectClass* gobject_class = G_OBJECT_CLASS(klass); + + gobject_class->dispose = gnc_lot_dispose; + gobject_class->finalize = gnc_lot_finalize; + gobject_class->get_property = gnc_lot_get_property; + gobject_class->set_property = gnc_lot_set_property; + + g_type_class_add_private(klass, sizeof(LotPrivate)); + + g_object_class_install_property( + gobject_class, + PROP_IS_CLOSED, + g_param_spec_int("is-closed", + "Is Lot Closed", + "Indication of whether this lot is open " + "or closed to further changes.", + -1, 1, 0, + G_PARAM_READWRITE)); + + g_object_class_install_property( + gobject_class, + PROP_MARKER, + g_param_spec_int("marker", + "Lot marker", + "Ipsum Lorem", + 0, G_MAXINT8, 0, + G_PARAM_READWRITE)); + + + } GNCLot * @@ -94,32 +201,33 @@ gnc_lot_new (QofBook *book) g_return_val_if_fail (book, NULL); lot = g_object_new (GNC_TYPE_LOT, NULL); - gnc_lot_init_data (lot, book); - qof_event_gen (&lot->inst, QOF_EVENT_CREATE, NULL); + qof_instance_init_data(QOF_INSTANCE(lot), GNC_ID_LOT, book); + qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_CREATE, NULL); return lot; } static void gnc_lot_free(GNCLot* lot) { - GList *node; - if (!lot) return; + GList *node; + LotPrivate* priv; + if (!lot) return; - ENTER ("(lot=%p)", lot); - qof_event_gen (&lot->inst, QOF_EVENT_DESTROY, NULL); + ENTER ("(lot=%p)", lot); + qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_DESTROY, NULL); + priv = GET_PRIVATE(lot); + for (node=priv->splits; node; node=node->next) + { + Split *s = node->data; + s->lot = NULL; + } + g_list_free (priv->splits); - for (node=lot->splits; node; node=node->next) - { - Split *s = node->data; - s->lot = NULL; - } - g_list_free (lot->splits); - - lot->account = NULL; - lot->is_closed = TRUE; - /* qof_instance_release (&lot->inst); */ - g_object_unref (lot); + priv->account = NULL; + priv->is_closed = TRUE; + /* qof_instance_release (&lot->inst); */ + g_object_unref (lot); } void @@ -137,7 +245,7 @@ gnc_lot_destroy (GNCLot *lot) void gnc_lot_begin_edit (GNCLot *lot) { - qof_begin_edit(&lot->inst); + qof_begin_edit(QOF_INSTANCE(lot)); } static void commit_err (QofInstance *inst, QofBackendError errcode) @@ -159,7 +267,7 @@ void gnc_lot_commit_edit (GNCLot *lot) { if (!qof_commit_edit (QOF_INSTANCE(lot))) return; - qof_commit_edit_part2 (&lot->inst, commit_err, noop, lot_free); + qof_commit_edit_part2 (QOF_INSTANCE(lot), commit_err, noop, lot_free); } /* ============================================================= */ @@ -184,16 +292,62 @@ gnc_lot_get_book (GNCLot *lot) gboolean gnc_lot_is_closed (GNCLot *lot) { - if (!lot) return TRUE; - if (0 > lot->is_closed) gnc_lot_get_balance (lot); - return lot->is_closed; + LotPrivate* priv; + if (!lot) return TRUE; + priv = GET_PRIVATE(lot); + if (0 > priv->is_closed) gnc_lot_get_balance (lot); + return priv->is_closed; } Account * gnc_lot_get_account (const GNCLot *lot) { - if (!lot) return NULL; - return lot->account; + LotPrivate* priv; + if (!lot) return NULL; + priv = GET_PRIVATE(lot); + return priv->account; +} + +void +gnc_lot_set_account(GNCLot* lot, Account* account) +{ + if (lot != NULL) + { + LotPrivate* priv; + priv = GET_PRIVATE(lot); + priv->account = account; + } +} + +unsigned char +gnc_lot_get_marker(const GNCLot* lot) +{ + LotPrivate* priv; + if (lot == NULL) return 0; + priv = GET_PRIVATE(lot); + return priv->marker; +} + +void +gnc_lot_set_marker(GNCLot* lot, unsigned char m) +{ + LotPrivate* priv; + if (lot != NULL) + { + priv = GET_PRIVATE(lot); + priv->marker = m; + } +} + +void +gnc_lot_set_closed_unknown(GNCLot* lot) +{ + LotPrivate* priv; + if (lot != NULL) + { + priv = GET_PRIVATE(lot); + priv->is_closed = LOT_CLOSED_UNKNOWN; + } } KvpFrame * @@ -205,14 +359,18 @@ gnc_lot_get_slots (const GNCLot *lot) SplitList * gnc_lot_get_split_list (const GNCLot *lot) { - if (!lot) return NULL; - return lot->splits; + LotPrivate* priv; + if (!lot) return NULL; + priv = GET_PRIVATE(lot); + return priv->splits; } gint gnc_lot_count_splits (const GNCLot *lot) { - if (!lot) return 0; - return g_list_length (lot->splits); + LotPrivate* priv; + if (!lot) return 0; + priv = GET_PRIVATE(lot); + return g_list_length (priv->splits); } /* ============================================================== */ @@ -221,15 +379,15 @@ gint gnc_lot_count_splits (const GNCLot *lot) const char * gnc_lot_get_title (const GNCLot *lot) { - if (!lot) return NULL; - return kvp_frame_get_string (lot->inst.kvp_data, "/title"); + if (!lot) return NULL; + return kvp_frame_get_string (gnc_lot_get_slots(lot), "/title"); } const char * gnc_lot_get_notes (const GNCLot *lot) { if (!lot) return NULL; - return kvp_frame_get_string (lot->inst.kvp_data, "/notes"); + return kvp_frame_get_string (gnc_lot_get_slots(lot), "/notes"); } void @@ -238,7 +396,7 @@ gnc_lot_set_title (GNCLot *lot, const char *str) if (!lot) return; qof_begin_edit(QOF_INSTANCE(lot)); qof_instance_set_dirty(QOF_INSTANCE(lot)); - kvp_frame_set_str (lot->inst.kvp_data, "/title", str); + kvp_frame_set_str (gnc_lot_get_slots(lot), "/title", str); gnc_lot_commit_edit(lot); } @@ -248,7 +406,7 @@ gnc_lot_set_notes (GNCLot *lot, const char *str) if (!lot) return; gnc_lot_begin_edit(lot); qof_instance_set_dirty(QOF_INSTANCE(lot)); - kvp_frame_set_str (lot->inst.kvp_data, "/notes", str); + kvp_frame_set_str (gnc_lot_get_slots(lot), "/notes", str); gnc_lot_commit_edit(lot); } @@ -257,38 +415,40 @@ gnc_lot_set_notes (GNCLot *lot, const char *str) gnc_numeric gnc_lot_get_balance (GNCLot *lot) { - GList *node; - gnc_numeric zero = gnc_numeric_zero(); - gnc_numeric baln = zero; - if (!lot) return zero; + LotPrivate* priv; + GList *node; + gnc_numeric zero = gnc_numeric_zero(); + gnc_numeric baln = zero; + if (!lot) return zero; - if (!lot->splits) - { - lot->is_closed = FALSE; - return zero; - } + priv = GET_PRIVATE(lot); + if (!priv->splits) + { + priv->is_closed = FALSE; + return zero; + } - /* Sum over splits; because they all belong to same account - * they will have same denominator. - */ - for (node=lot->splits; node; node=node->next) - { - Split *s = node->data; - gnc_numeric amt = xaccSplitGetAmount (s); - baln = gnc_numeric_add_fixed (baln, amt); - } + /* Sum over splits; because they all belong to same account + * they will have same denominator. + */ + for (node=priv->splits; node; node=node->next) + { + Split *s = node->data; + gnc_numeric amt = xaccSplitGetAmount (s); + baln = gnc_numeric_add_fixed (baln, amt); + } - /* cache a zero balance as a closed lot */ - if (gnc_numeric_equal (baln, zero)) - { - lot->is_closed = TRUE; - } - else - { - lot->is_closed = FALSE; - } + /* cache a zero balance as a closed lot */ + if (gnc_numeric_equal (baln, zero)) + { + priv->is_closed = TRUE; + } + else + { + priv->is_closed = FALSE; + } - return baln; + return baln; } /* ============================================================= */ @@ -297,42 +457,48 @@ void gnc_lot_get_balance_before (const GNCLot *lot, const Split *split, gnc_numeric *amount, gnc_numeric *value) { - GList *node; - gnc_numeric zero = gnc_numeric_zero(); - gnc_numeric amt = zero; - gnc_numeric val = zero; + LotPrivate* priv; + GList *node; + gnc_numeric zero = gnc_numeric_zero(); + gnc_numeric amt = zero; + gnc_numeric val = zero; - if (lot && lot->splits) - { - Transaction *ta, *tb; - const Split *target; - /* If this is a gains split, find the source of the gains and use - its transaction for the comparison. Gains splits are in separate - transactions that may sort after non-gains transactions. */ - target = xaccSplitGetGainsSourceSplit (split); - if (target == NULL) - target = split; - tb = xaccSplitGetParent (target); - for (node = lot->splits; node; node = node->next) - { - Split *s = node->data; - Split *source = xaccSplitGetGainsSourceSplit (s); - if (source == NULL) - source = s; - ta = xaccSplitGetParent (source); - if ((ta == tb && source != target) || - xaccTransOrder (ta, tb) < 0) - { - gnc_numeric tmpval = xaccSplitGetAmount (s); - amt = gnc_numeric_add_fixed (amt, tmpval); - tmpval = xaccSplitGetValue (s); - val = gnc_numeric_add_fixed (val, tmpval); - } - } - } + *amount = amt; + *value = val; + if (lot == NULL) return; - *amount = amt; - *value = val; + priv = GET_PRIVATE(lot); + if (priv->splits) + { + Transaction *ta, *tb; + const Split *target; + /* If this is a gains split, find the source of the gains and use + its transaction for the comparison. Gains splits are in separate + transactions that may sort after non-gains transactions. */ + target = xaccSplitGetGainsSourceSplit (split); + if (target == NULL) + target = split; + tb = xaccSplitGetParent (target); + for (node = priv->splits; node; node = node->next) + { + Split *s = node->data; + Split *source = xaccSplitGetGainsSourceSplit (s); + if (source == NULL) + source = s; + ta = xaccSplitGetParent (source); + if ((ta == tb && source != target) || + xaccTransOrder (ta, tb) < 0) + { + gnc_numeric tmpval = xaccSplitGetAmount (s); + amt = gnc_numeric_add_fixed (amt, tmpval); + tmpval = xaccSplitGetValue (s); + val = gnc_numeric_add_fixed (val, tmpval); + } + } + } + + *amount = amt; + *value = val; } /* ============================================================= */ @@ -340,71 +506,75 @@ gnc_lot_get_balance_before (const GNCLot *lot, const Split *split, void gnc_lot_add_split (GNCLot *lot, Split *split) { - Account * acc; - if (!lot || !split) return; + LotPrivate* priv; + Account * acc; + if (!lot || !split) return; + priv = GET_PRIVATE(lot); - ENTER ("(lot=%p, split=%p) %s amt=%s val=%s", lot, split, + ENTER ("(lot=%p, split=%p) %s amt=%s val=%s", lot, split, gnc_lot_get_title (lot), gnc_num_dbg_to_string (split->amount), gnc_num_dbg_to_string (split->value)); - gnc_lot_begin_edit(lot); - acc = xaccSplitGetAccount (split); - qof_instance_set_dirty(QOF_INSTANCE(lot)); - if (NULL == lot->account) - { - xaccAccountInsertLot (acc, lot); - } - else if (lot->account != acc) - { - PERR ("splits from different accounts cannot " - "be added to this lot!\n" - "\tlot account=\'%s\', split account=\'%s\'\n", - xaccAccountGetName(lot->account), xaccAccountGetName (acc)); - gnc_lot_commit_edit(lot); - LEAVE("different accounts"); - return; - } + gnc_lot_begin_edit(lot); + acc = xaccSplitGetAccount (split); + qof_instance_set_dirty(QOF_INSTANCE(lot)); + if (NULL == priv->account) + { + xaccAccountInsertLot (acc, lot); + } + else if (priv->account != acc) + { + PERR ("splits from different accounts cannot " + "be added to this lot!\n" + "\tlot account=\'%s\', split account=\'%s\'\n", + xaccAccountGetName(priv->account), xaccAccountGetName (acc)); + gnc_lot_commit_edit(lot); + LEAVE("different accounts"); + return; + } - if (lot == split->lot) { + if (lot == split->lot) { gnc_lot_commit_edit(lot); LEAVE("already in lot"); - return; /* handle not-uncommon no-op */ - } - if (split->lot) - { - gnc_lot_remove_split (split->lot, split); - } - xaccSplitSetLot(split, lot); + return; /* handle not-uncommon no-op */ + } + if (split->lot) + { + gnc_lot_remove_split (split->lot, split); + } + xaccSplitSetLot(split, lot); - lot->splits = g_list_append (lot->splits, split); + priv->splits = g_list_append (priv->splits, split); /* for recomputation of is-closed */ - lot->is_closed = -1; - gnc_lot_commit_edit(lot); + priv->is_closed = LOT_CLOSED_UNKNOWN; + gnc_lot_commit_edit(lot); - qof_event_gen (&lot->inst, QOF_EVENT_MODIFY, NULL); - LEAVE("added to lot"); + qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_MODIFY, NULL); + LEAVE("added to lot"); } void gnc_lot_remove_split (GNCLot *lot, Split *split) { - if (!lot || !split) return; + LotPrivate* priv; + if (!lot || !split) return; + priv = GET_PRIVATE(lot); - ENTER ("(lot=%p, split=%p)", lot, split); - gnc_lot_begin_edit(lot); - qof_instance_set_dirty(QOF_INSTANCE(lot)); - lot->splits = g_list_remove (lot->splits, split); - xaccSplitSetLot(split, NULL); - lot->is_closed = -1; /* force an is-closed computation */ + ENTER ("(lot=%p, split=%p)", lot, split); + gnc_lot_begin_edit(lot); + qof_instance_set_dirty(QOF_INSTANCE(lot)); + priv->splits = g_list_remove (priv->splits, split); + xaccSplitSetLot(split, NULL); + priv->is_closed = LOT_CLOSED_UNKNOWN; /* force an is-closed computation */ - if (NULL == lot->splits) - { - xaccAccountRemoveLot (lot->account, lot); - lot->account = NULL; - } - gnc_lot_commit_edit(lot); - qof_event_gen (&lot->inst, QOF_EVENT_MODIFY, NULL); + if (NULL == priv->splits) + { + xaccAccountRemoveLot (priv->account, lot); + priv->account = NULL; + } + gnc_lot_commit_edit(lot); + qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_MODIFY, NULL); } /* ============================================================== */ @@ -413,25 +583,29 @@ gnc_lot_remove_split (GNCLot *lot, Split *split) Split * gnc_lot_get_earliest_split (GNCLot *lot) { - if (! lot->splits) - return NULL; - lot->splits = g_list_sort (lot->splits, (GCompareFunc) xaccSplitOrderDateOnly); - return lot->splits->data; + LotPrivate* priv; + if (!lot) return NULL; + priv = GET_PRIVATE(lot); + if (! priv->splits) return NULL; + priv->splits = g_list_sort (priv->splits, (GCompareFunc) xaccSplitOrderDateOnly); + return priv->splits->data; } Split * gnc_lot_get_latest_split (GNCLot *lot) { - SplitList *node; + LotPrivate* priv; + SplitList *node; - if (! lot->splits) - return NULL; - lot->splits = g_list_sort (lot->splits, (GCompareFunc) xaccSplitOrderDateOnly); + if (!lot) return NULL; + priv = GET_PRIVATE(lot); + if (! priv->splits) return NULL; + priv->splits = g_list_sort (priv->splits, (GCompareFunc) xaccSplitOrderDateOnly); - for (node = lot->splits; node->next; node = node->next) + for (node = priv->splits; node->next; node = node->next) ; - return node->data; + return node->data; } /* ============================================================= */ diff --git a/src/engine/gnc-lot.h b/src/engine/gnc-lot.h index fca2d8d44a..780e831cba 100644 --- a/src/engine/gnc-lot.h +++ b/src/engine/gnc-lot.h @@ -59,10 +59,16 @@ #ifndef GNC_LOT_H #define GNC_LOT_H -typedef struct _GncLotClass GNCLotClass; +//typedef struct _GncLotClass GNCLotClass; #include "qof.h" -#include "gnc-lot-p.h" +#include "gnc-engine.h" +/*#include "gnc-lot-p.h"*/ + +typedef struct { + QofInstanceClass parent_class; +} GncLotClass; +#define GNCLotClass GncLotClass /* --- type macros --- */ #define GNC_TYPE_LOT (gnc_lot_get_type ()) @@ -114,6 +120,7 @@ gint gnc_lot_count_splits (const GNCLot *); * this lot is associated. */ /*@ dependent @*/ Account * gnc_lot_get_account (const GNCLot *); +void gnc_lot_set_account(GNCLot*, Account*); /** The gnc_lot_get_balance() routine returns the balance of the lot. * The commodity in which this balance is expressed is the commodity @@ -148,6 +155,11 @@ Split * gnc_lot_get_earliest_split (GNCLot *lot); */ Split * gnc_lot_get_latest_split (GNCLot *lot); +unsigned char gnc_lot_get_marker(const GNCLot*); +void gnc_lot_set_marker(GNCLot*, unsigned char); + +void gnc_lot_set_closed_unknown(GNCLot*); + /** Get and set the account title, or the account notes. */ const char * gnc_lot_get_title (const GNCLot *); const char * gnc_lot_get_notes (const GNCLot *); diff --git a/src/engine/policy.c b/src/engine/policy.c index 0f9fdcdbc9..b04377265c 100644 --- a/src/engine/policy.c +++ b/src/engine/policy.c @@ -56,8 +56,11 @@ DirectionPolicyGetSplit (GNCPolicy *pcy, GNCLot *lot, short reverse) Split *osplit; Transaction *otrans; Timespec open_ts; + Account* lot_account; - if (!pcy || !lot || !lot->account || !lot->splits) return NULL; + if (!pcy || !lot || !gnc_lot_get_split_list(lot)) return NULL; + lot_account = gnc_lot_get_account(lot); + if (!lot_account) return NULL; /* Recomputing the balance re-evaluates the lot closure */ baln = gnc_lot_get_balance (lot); @@ -66,7 +69,7 @@ DirectionPolicyGetSplit (GNCPolicy *pcy, GNCLot *lot, short reverse) want_positive = gnc_numeric_negative_p (baln); /* All splits in lot must share a common transaction currency. */ - split = lot->splits->data; + split = gnc_lot_get_split_list(lot)->data; common_currency = split->parent->common_currency; /* Don't add a split to the lot unless it will be the new last @@ -80,7 +83,7 @@ DirectionPolicyGetSplit (GNCPolicy *pcy, GNCLot *lot, short reverse) * hasn't been assigned to a lot. Return that split. * Make use of the fact that the splits in an account are * already in date order; so we don't have to sort. */ - node = xaccAccountGetSplitList (lot->account); + node = xaccAccountGetSplitList (lot_account); if (reverse) { node = g_list_last (node);