This is gnucash-design.info, produced by makeinfo version 4.1 from
gnucash-design.texinfo.


INFO-DIR-SECTION Programming

START-INFO-DIR-ENTRY
* gnucash: (gnucash-design).       Design of the GnuCash program
END-INFO-DIR-ENTRY


   This file documents the design of the GnuCash program.

   Copyright 2000 Gnumatic Incorporated

   This is Edition 1.8.4, last updated 13 August 2001, of the `GnuCash
Design Document', version 1.8.4.

   Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with the
Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts
being LIST, and with the Back-Cover Texts being LIST.  A copy of the
license is included in the section entitled "GNU Free Documentation
License".


File: gnucash-design.info,  Node: Split Setters,  Prev: Split Getters,  Up: Splits

Split Setters
-------------

 - Function: void xaccSplitSetMemo (Split * SPLIT, const char * MEMO)
     Set the memo field of SPLIT to MEMO.

 - Function: void xaccSplitSetAction (Split * SPLIT, const char *
          ACTION)
     Set the action field of SPLIT to MEMO. The action field is an
     arbitrary string, but is intended to be conveniently limited to a
     menu of selections such as "Buy", "Sell", "Interest", etc.

 - Function: void xaccSplitSetReconcile (Split * SPLIT, char
          RECONCILED_FLAG)
     Set the reconciled flag of SPLIT to RECONCILED_FLAG. For the
     possible values and meanings of RECONCILED_FLAG, see *Note Split
     Getters::.

 - Function: void xaccSplitSetDateReconciledSecs (Split * SPLIT, time_t
          TIME)
     Set the reconciliation date of SPLIT to TIME.

 - Function: void xaccSplitSetDateReconciledTS (Split * SPLIT, Timespec
          * TS)
     Set the reconciliation date of SPLIT to TS.

 - Function: void xaccSplitSetShareAmount (Split * SPLIT, gnc_numeric
          amount)
     Set the share quantity of SPLIT to AMOUNT.

 - Function: void xaccSplitSetSharePrice (Split * SPLIT, gnc_numeric
          PRICE)
     Set the share price of SPLIT to PRICE.

 - Function: void xaccSplitSetSharePriceAndAmount (Split * SPLIT,
          gnc_numeric PRICE, gnc_numeric AMOUNT)
     Set both the share price and share quantity of SPLIT. This routine
     is more efficent than calling `xaccSplitSetShareAmount' and
     `xaccSplitSetSharePrice' in succesion.

 - Function: void xaccSplitSetValue (Split * SPLIT, gnc_numeric VALUE)
     Adjust the share quantity of SPLIT so that SPLIT's value is equal
     to VALUE.

 - Function: void xaccSplitSetBaseValue (Split * SPLIT, gnc_numeric
          VALUE, const char * BASE_CURRENCY)
     Set either the share quantity or value of SPLIT depending upon
     whether BASE_CURRENCY is the security or current of SPLIT's parent
     Account. *Note Accounts::.


File: gnucash-design.info,  Node: Transactions,  Next: Accounts,  Prev: Splits,  Up: Engine

Transactions
============

   A Transaction is the Engine abstraction of an accounting entry in a
Journal. In accounting terms, a Transaction is a Journal Entry. As
such, it contains the following pieces of information:

A list of Ledger Entries, or Splits
     The list of debits and credits which make up this Transaction. As
     in accounting, a Transaction is balanced when the sum of the
     debits equals the sum of the credits.

The entry date
     The date the transaction was entered into GnuCash.

The post date
     The date the transaction was posted. This is often the date the
     transaction was recorded by the bank, or the date the user
     initiated the transaction (i.e., wrote the check, made the ATM
     withdrawal).

A transaction number field
     This field is intended to hold a transaction number, such as a
     check number or an ID assigned by a bank to an electronic transfer.

A description
     A textual description of the transaction.

   In addition to the above, Transactions contain a key-value pair
frame.

The Transaction Edit Cycle
--------------------------

   The Engine supports (and, in fact, requires) a 2-phase
commit/rollback cycle for modifying Transactions and their constituent
Splits. A Transaction must be opened for editing using
`xaccTransBeginEdit()' before any of the following actions may be taken.

   * Modifying any field of a Transaction.

   * Modifying any Split belonging to the Transaction. That includes
     re-parenting a Split to a different Account or a different
     Transaction.  In the case of re-parenting to a new Transaction,
     both Transactions must be opened for editing.

   * Deleting any Split belonging to the Transaction.

   * Adding a Split to the transaction.

   * Deleting the Transaction.


   After the desired changes have been made, they must either be
committed using `xaccTransCommitEdit()' or rolled back using
`xaccTransRollbackEdit()'. Rolling back a transaction will undo any
changes which have been made to it or to its Splits since it was opened
for editing.

* Menu:

* General Transaction API::
* Transaction Getters::
* Transaction Setters::


File: gnucash-design.info,  Node: General Transaction API,  Next: Transaction Getters,  Prev: Transactions,  Up: Transactions

General Transaction API
-----------------------

 - Function: Transaction * xaccMallocTransaction (void)
     Allocate, initialize, and return a new Transaction.

 - Function: void xaccTransDestroy (Transaction * trans)
     Remove all of the Splits from each of their accounts and free the
     memory associated with them. This routine must be followed by
     either an `xaccTransCommitEdit()' in which case the transaction
     memory will be freed, or by `xaccTransRollbackEdit()', in which
     case all the original Splits are put back into place.

 - Function: void xaccTransAppendSplit (Transaction * TRANS, Split *
          SPLIT)
     Append SPLIT to the collection of Splits in TRANS. If the Split is
     already a part of another Transaction, it will be removed from
     that Transaction first.

 - Function: void xaccTransBeginEdit (Transaction * TRANS)
     This method must be called before any changes are made to TRANS or
     any of its component Splits. If this is not done, errors will
     result.

 - Function: void xaccTransCommitEdit (Transaction * TRANS)
     This method indicates that the changes to TRANS and its Splits are
     complete and should be made permanent. Note this routine may
     result in the deletion of the transaction, if the Transaction is
     "empty" (has no Splits) or if `xaccTransDestroy()' was called on
     the Transaction.

 - Function: void xaccTransRollbackEdit (Transaction * TRANS)
     Rejects all changes made to TRANS and its Splits, and sets TRANS
     back to where it was before the `xaccTransBeginEdit()' call. This
     includes restoring any deleted Splits, removing any added Splits,
     and undoing the effects of `xaccTransDestroy()', as well as
     restoring share quantities, memos, descriptions, etc.

 - Function: gboolean xaccTransIsOpen (Transaction * TRANS)
     Return `TRUE' if TRANS is open for editing. Otherwise, it returns
     `FALSE'.

 - Function: const GUID * xaccTransGetGUID (Transaction * TRANS)
     Return the GUID of TRANS.

 - Function: Transaction * xaccTransLookup (const GUID * GUID)
     Return the Transaction associated with GUID, or `NULL' if there is
     no such Transaction.

 - Function: kvp_value * xaccTransGetSlot (Transaction * TRANS, const
          char * KEY)
     Return the `kvp_value' associated with KEY in TRANS.  If there is
     none, `NULL' is returned.

 - Function: void xaccTransSetSlot (Split * TRANS, const char * KEY,
          const kvp_value * VALUE)
     Associate a copy of VALUE with KEY in TRANS.


File: gnucash-design.info,  Node: Transaction Getters,  Next: Transaction Setters,  Prev: General Transaction API,  Up: Transactions

Transaction Getters
-------------------

 - Function: Split * xaccTransGetSplit (Transaction * TRANS, int I)
     Return the Ith Split of TRANS.

 - Function: GList * xaccTransGetSplitList (Transaction * TRANS)
     Return a `GList' of the Splits in TRANS. This list is owned by
     TRANS and should not be modified in any way!

 - Function: const char * xaccTransGetNum (Transaction * TRANS)
     Return the number field of TRANS.

 - Function: const char * xaccTransGetDescription (Transaction * TRANS)
     Return the description field of TRANS.

 - Function: time_t xaccTransGetDate (Transaction * TRANS)
     Return the post date of TRANS as a `time_t' value.

 - Function: long long xaccTransGetDateL (Transaction * TRANS)
     Return the post date of TRANS as a `long long' value.

 - Function: void xaccTransGetDateTS (Transaction * TRANS, Timespec *
          TS)
     Return the post date of TRANS in TS.

 - Function: void xaccTransGetDateEnteredTS (Transaction * TRANS,
          Timespec * TS)
     Return the entry date of TRANS in TS.

 - Function: char * xaccTransGetDateStr (Transaction * TRANS)
     Return a string representing the post date of TRANS, or NULL if
     TRANS is NULL. The string must be freed with `free()' after use.

 - Function: int xaccTransCountSplits (Transaction * TRANS)
     Return the number of Splits in TRANS.


File: gnucash-design.info,  Node: Transaction Setters,  Prev: Transaction Getters,  Up: Transactions

Transaction Setters
-------------------

   Remember, before you modify a Transaction, you must open it for
editing with `xaccTransBeginEdit'.

 - Function: void xaccTransSetDate (Transaction * TRANS, int DAY, int
          MON, int YEAR)
     Set the post date of TRANS with DAY, MONTH, and YEAR.

 - Function: void xaccTransSetDateSecs (Transaction * TRANS, time_t
          TIME)
     Set the post date of TRANS using a `time_t' value.

 - Function: void xaccTransSetDateToday (Transaction * TRANS)
     Set the post date of TRANS to the current time.

 - Function: void xaccTransSetDateTS (Transaction * TRANS, const
          Timespec * TS)
     Set the post date of TRANS from TS.

 - Function: void xaccTransSetDateEnteredSecs (Transaction *trans,
          time_t time)
     Set the entry date of TRANS from a `time_t' value.

 - Function: void xaccTransSetDateEnteredTS (Transaction * TRANS, const
          Timespec * TS)
     Set the entry date of TRANS from TS.

 - Function: void xaccTransSetNum (Transaction * TRANS, const char *
          NUM)
     Set the number field of TRANS to NUM.

 - Function: void xaccTransSetDescription (Transaction * TRANS, const
          char * DESC)
     Set the description field of TRANS to DESC.


File: gnucash-design.info,  Node: Accounts,  Next: Account Groups,  Prev: Transactions,  Up: Engine

Accounts
========

   An Account is the Engine abstraction of an, well, an account.
Accounts contain the following pieces of information:

A list of Ledger Entries, or Splits
     The list of debits and credits which apply to the Account. The sum
     of all debits and credits is the account balance.

A type
     An integer code identifying the type of account. The Account type
     determines whether the Account holds shares valued in a currency
     or not. It is also used by the GUI and reporting system to
     determine how debits & credits to the Account should be treated
     and displayed.

A name
     The name of the Account.

An account code
     A string that is intended to hold a unique user-selected identifier
     for the account. However, uniqueness of this field is not enforced.

A description
     A textual description of the Account.

A currency
     The commodity that Splits in the account are valued in, i.e., the
     denomination of the 'value' member of Splits in the account.

A curreny SCU
     The SCU is the smallest convertible unit that the currency is
     traded in. This value overrides the default SCU of the currency.

A security
     For Accounts which may contain shares (such as stock accounts),
     the denomination of the 'share quantity' member of Splits in the
     accounts. For accounts which do not contain shares, the security
     is blank, and the share quantities are denominated in the Account
     currency.

A security SCU
     Analogous to the currency SCU, but for the security.

A parent and child Account Group.
     The parent and child of an Account are Account Groups (*note
     Account Groups::). Account Groups are used to connect Accounts
     together into an Account hierarchy.  If the parent Account Group
     is not present, the Account is at the top level of the hierarchy.
     If the child Account Group is not present, the Account has no
     children.

   In addition to the above, Accounts contain a key-value pair frame.

* Menu:

* Account Types::
* General Account API::
* Account Type API::
* Account Getters::
* Account Tax API::


File: gnucash-design.info,  Node: Account Types,  Next: General Account API,  Prev: Accounts,  Up: Accounts

Account Types
-------------

   Account Types are defined by the `GNCAccountType' enumeration.
Possible values are:

`BAD_TYPE, NO_TYPE'
     Both of these values indicate an illegal Account type.

`BANK'
     Denotes a savings or checking account held at a bank.    Such an
     account is often interest bearing.

`CASH'
     Denotes a shoe-box or pillowcase stuffed with cash. In other
     words, actual currency held by the user.

`CREDIT'
     Denotes credit card accounts.

`ASSET'
     Denotes a generic asset account.

`LIABILITY'
     Denotes a generic liability account.

`STOCK'
     A stock account containing stock shares.

`MUTUAL'
     A mutual fund account containing fund shares.

`CURRENCY'
     Denotes a currency trading account. In many ways, a currency
     trading   account is like a stock trading account, where both
     quantities   and prices are set. However, generally both currency
     and security   are national currencies.

`INCOME'
     Denotes an income account. The GnuCash financial model does not
     use 'categories'. Actual accounts are used instead.

`EXPENSE'
     Denotes an expense account.

`EQUITY = 10,'
     Denotes an equity account.


File: gnucash-design.info,  Node: General Account API,  Next: Account Type API,  Prev: Account Types,  Up: Accounts

General Account API
-------------------

 - Function: Account * xaccMallocAccount (void)
     Allocate and initialize an Account. The account must be destroyed
     by calling `xaccAccountBeginEdit' followed by `xaccAccountDestroy'.

 - Function: void xaccAccountDestroy (Account * ACCOUNT)
     Destroys ACCOUNT and frees all memory associated with it. This
     routine will also destroy the Account's children.  You must call
     `xaccAccountBeginEdit' before calling this function.

 - Function: void xaccAccountBeginEdit (Account * ACCOUNT)
     This routine, together with `xaccAccountCommitEdit', provide a
     two-phase-commit wrapper for account updates much in the same way
     as XACCTRANSBEGINEDIT and XACCTRANSCOMMITEDIT do for Transactions.

 - Function: void xaccAccountCommitEdit (Account * ACCOUNT)
     The counterpart to XACCACCOUNTBEGINEDIT.

 - Function: Account * xaccCloneAccountSimple (const Account * FROM)
     Return a 'copy' of FROM that is identical in the type, name, code,
     description, kvp data, and currency. All other fields are the same
     as an account returned by `xaccMallocAccount'.

 - Function: const GUID * xaccAccountGetGUID (Account * ACCOUNT)
     Return the globally unique id associated with ACCOUNT.

 - Function: Account * xaccAccountLookup (const GUID * GUID)
     Return the Account associated with GUID, or NULL if there is no
     such Account.

 - Function: kvp_frame * xaccAccountGetSlots (Account * ACCOUNT)
     Return the `kvp_frame' associated with ACCOUNT. User code may
     modify this `kvp_frame', but must not destroy it.

 - Function: void xaccAccountSetSlots_nc (Account * ACCOUNT, kvp_frame
          * FRAME)
     Set the `kvp_frame' associated wih ACCOUNT. After the call, FRAME
     is owned by ACCOUNT, so don't destroy it.


File: gnucash-design.info,  Node: Account Type API,  Next: Account Getters,  Prev: General Account API,  Up: Accounts

Account Type API
----------------

 - Function: const char * xaccAccountGetTypeStr (GNCAccountType TYPE)
     Return a string corresponding to the given Account type suitable
     for display by a GUI. The string is translated with gettext
     according to the current locale.

 - Function: char * xaccAccountTypeEnumAsString (GNCAccountType TYPE)
     Return a string corresponding to the given Account type. The string
     is not translated and is independent of the current locale.

 - Function: gboolean xaccAccountStringToType (const char * STR,
          GNCAccountType * TYPE)
     Converts a string of the form returned by
     `xaccAccountTypeEnumAsString' to a type, return in TYPE. Returns
     true if the string corresponds to an actual type.

 - Function: GNCAccountType xaccAccountStringToEnum (const char * STR)
     Similar to `xaccAccountStringToEnum', but returns the type. If STR
     does not correspond to any valid type, `BAD_TYPE' is returned.

 - Function: gboolean xaccAccountTypesCompatible (GNCAccountType
          PARENT_TYPE, GNCAccountType CHILD_TYPE)
     Returns TRUE if accounts of type PARENT_TYPE can have child
     accounts of type CHILD_TYPE. This compatibility is not enforced by
     the engine, but one day it may be!


File: gnucash-design.info,  Node: Account Getters,  Next: Account Tax API,  Prev: Account Type API,  Up: Accounts

Account Getters
---------------

 - Function: GNCAccountType xaccAccountGetType (Account * ACCOUNT)
     Return the type of ACCOUNT.

 - Function: const char * xaccAccountGetName (Account * ACCOUNT)
     Return the name of ACCOUNT.

 - Function: const char * xaccAccountGetCode (Account * ACCOUNT)
     Return the code of ACCOUNT.

 - Function: const char * xaccAccountGetDescription (Account * ACCOUNT)
     Return the description of ACCOUNT.

 - Function: const char * xaccAccountGetNotes (Account * ACCOUNT)
     Return the notes of ACCOUNT.

 - Function: gnc_commodity * xaccAccountGetCurrency (Account * ACCOUNT)
     Return the currency of ACCOUNT.

 - Function: int xaccAccountGetCurrencySCU (Account * ACCOUNT)
     Return the SCU (smallest convertible unit) of ACCOUNT's currency.

 - Function: gnc_commodity * xaccAccountGetSecurity (Account * ACCOUNT)
     Return the security of ACCOUNT. For accounts without shares, this
     field will be `NULL'.

 - Function: int xaccAccountGetSecuritySCU (Account * ACCOUNT)
     Return the SCU (smallest convertible unit) of ACCOUNT's security.

 - Function: gnc_commodity * xaccAccountGetEffectiveSecurity (Account *
          ACCOUNT)
     Get the `effective' security of the account. If the account has a
     non-NULL security field, that field will be returned. Otherwise,
     the currency will be returned.

 - Function: AccountGroup * xaccAccountGetChildren (Account * ACCOUNT)
     Return the child group of ACCOUNT. The child group may be `NULL',
     indicating ACCOUNT has no children.

 - Function: AccountGroup * xaccAccountGetParent (Account * ACCOUNT)
     Return the parent Group of ACCOUNT. The parent may be `NULL',
     indicating ACCOUNT is a top-level Account. However, even if the
     parent is not `NULL', the account may still be top-level if the
     parent Group has no parent Account.

 - Function: Account * xaccAccountGetParentAccount (Account * ACCOUNT)
     Similar to `xaccAccountGetParent', but returns the parent Account
     of the parent Group if the parent Group exists. Otherwise, returns
     `NULL'.

 - Function: gnc_numeric xaccAccountGetBalance (Account * ACCOUNT)
     Return the balance of ACCOUNT, which is also the balance of the
     last Split in ACCOUNT. If there are no Splits, the balance is
     zero. The balance is denominated in the Account currency.

 - Function: gnc_numeric xaccAccountGetClearedBalance (Account *
          ACCOUNT)
     Return the cleared balance of ACCOUNT. The cleared balance is the
     balance of all Splits in ACCOUNT which are either cleared or
     reconciled or frozen. The cleared balance is denominated in the
     Account currency.

 - Function: gnc_numeric xaccAccountGetReconciledBalance (Account *
          ACCOUNT)
     Return the reconciled balance of ACCOUNT. The reconciled balance
     is the balance of all Splits in ACCOUNT which are reconciled or
     frozen.  The reconciled balance is denominated in the Account
     currency.

 - Function: gnc_numeric xaccAccountGetShareBalance (Account *account)
     Return the share balance of ACCOUNT, which is also the share
     balance of the last Split in ACCOUNT. If there are no Splits, the
     balance is zero. The balance is denominated in the Account
     security, if the Account security exits; otherwise the share
     balance is denominated in the Account currency.

 - Function: gnc_numeric xaccAccountGetShareClearedBalance (Account *
          ACCOUNT)
     Return the cleared share balance of ACCOUNT. The cleared share
     balance is the share balance of all Splits in ACCOUNT which are
     either cleared or reconciled or frozen. The cleared share balance
     is denominated as the share balance.

 - Function: gnc_numeric xaccAccountGetShareReconciledBalance (Account
          * ACCOUNT)
     Return the reconciled share balance of ACCOUNT. The reconciled
     share balance is the share balance of all Splits in ACCOUNT which
     are reconciled or frozen. The reconciled sharea balance is
     denominated as the share balance.

 - Function: gnc_numeric xaccAccountGetBalanceAsOfDate (Account *
          ACCOUNT, time_t DATE)
     Return the balance of ACCOUNT including all Splits whose parent
     Transactions have posted dates on or before DATE.

 - Function: gnc_numeric xaccAccountGetShareBalanceAsOfDate (Account *
          ACCOUNT, time_t DATE)
     Return the share balance of ACCOUNT including all Splits whose
     parent Transactions have posted dates on or before DATE.

 - Function: GList * xaccAccountGetSplitList (Account * ACCOUNT)
     Return a `GList' of the Splits in ACCOUNT. This list must not be
     modified in any way.

 - Function: char * xaccAccountGetFullName (Account * ACCOUNT, const
          char SEPARATOR)
     Returns the fully qualified name of ACCOUNT using the given
     separator character. The name must be g_freed after use. The fully
     qualified name of an account is the concatenation of the names of
     the account and all its ancestor accounts starting with the
     topmost account and ending with the given account. Each name is
     separated by the given character.


File: gnucash-design.info,  Node: Account Tax API,  Prev: Account Getters,  Up: Accounts

Account Tax API
---------------

   This set of API calls is related to tax information. All accounts
have a tax-related boolean flag that can be set or unset. There is an
additional set of API calls related to United States taxes that have
`US' in the function call names. Future API calls that are specific to
other countries should include the appropriate 2-letter country code in
the function names.

 - Function: gboolean xaccAccountGetTaxRelated (Account * ACCOUNT)
     Return the tax-related flag of ACCOUNT.

 - Function: void xaccAccountSetTaxRelated (Account * ACCOUNT, gboolean
          TAX_RELATED)
     Set the tax-related flag of ACCOUNT.

 - Function: const char * xaccAccountGetTaxUSCode (Account * ACCOUNT)
     Get the US-specific tax code associated with ACCOUNT, or `NULL' if
     there is none. These codes are internal to GnuCash and currently
     defined in `src/scm/report/txf-export.scm'.

 - Function: void xaccAccountSetTaxUSCode (Account * ACCOUNT, const
          char * CODE)
     Set the US-specific tax code associated with ACCOUNT.

 - Function: const char * xaccAccountGetTaxUSPayerNameSource (Account *
          ACCOUNT)
     Get the payer name source associated with ACCOUNT. See
     `src/scm/repot/taxtxf.scm' for details.

 - Function: void xaccAccountSetTaxUSPayerNameSource (Account *
          ACCOUNT, const char * SOURCE)
     Set the payer name source associated with ACCOUNT.


File: gnucash-design.info,  Node: Account Groups,  Next: GNCBooks,  Prev: Accounts,  Up: Engine

Account Groups
==============

   Account Groups are used by the Engine to connect Accounts together
into an Account hierarchy. Account Groups do not correspond to any
accounting concept - they are specific to the GnuCash engine. Account
Groups contain the following pieces of information:

A list of Accounts
     The list Accounts in the Group.

A not-saved flag
     Indicates whether any information in the hierarchy rooted at the
     Group needs to be saved. That includes Accounts, Splits, and
     Transactions.

   Account Groups do not have key-value frames or GUIDs.

* Menu:

* General Account Group API::
* Account Group Account API::


File: gnucash-design.info,  Node: General Account Group API,  Next: Account Group Account API,  Prev: Account Groups,  Up: Account Groups

General Account Group API
-------------------------

 - Function: AccountGroup * xaccMallocAccountGroup (void)
     Return a newly-allocated & initialized Account Group.  The Group
     must be freed with `xaccFreeAccountGroup'.

 - Function: void xaccFreeAccountGroup (AccountGroup * ACCOUNT_GROUP)
     Free the given Group and all its resources, including the Accounts.

 - Function: void xaccAccountGroupCommitEdit (AccountGroup * GRP)
     Recursively call `xaccAccountCommitEdit' on all child accounts and
     their children.

 - Function: void xaccGroupConcatGroup (AccountGroup * TO, AccountGroup
          * FROM)
     Move all accounts in FROM to TO. After this function returns, FROM
     will have been destroyed.

 - Function: void xaccGroupMergeAccounts (AccountGroup * GRP)
     Merge all accounts in GRP that have the same name and description.
     The semantics of this function are rather complex. Consult the
     implementation before use!

 - Function: gboolean xaccGroupNotSaved (AccountGroup * GRP)
     Return true if GRP has changes which have not been saved.

 - Function: void xaccGroupMarkSaved (AccountGroup * GRP)
     Mark GRP and all its children as saved.

 - Function: void xaccGroupMarkNotSaved (AccountGroup * GRP)
     Mark GRP as not saved.

 - Function: void xaccGroupMarkDoFree (AccountGroup * GRP)
     Mark all accounts in GRP as slated for destruction. This will
     improve the efficiency of destroying a large account hierarchy.


File: gnucash-design.info,  Node: Account Group Account API,  Prev: General Account Group API,  Up: Account Groups

Account Group Account API
-------------------------

 - Function: void xaccGroupRemoveAccount (AccountGroup * GRP, Account *
          ACCOUNT)
     Remove ACCOUNT from GRP. If ACCOUNT is not in GRP, the function
     will return without performing any action.  In no case will
     ACCOUNT be destroyed or modified.

 - Function: void xaccAccountRemoveGroup (Account * ACC)
     Remove ACC's child group. The child group is not otherwise
     modified or destroyed.

 - Function: void xaccGroupInsertAccount (AccountGroup * GRP, Account *
          ACC)
     Add ACC to GRP. If ACC is in another Group, it will be removed
     first.

 - Function: void xaccAccountInsertSubAccount (Account * PARENT,
          Account * CHILD)
     Like `xaccGroupInsertAccount', but uses a parent Account instead
     of a parent group. If PARENT does not have a child Group, one will
     be created.

 - Function: int xaccGroupGetNumSubAccounts (AccountGroup * GRP)
     Return the total number of Accounts in the hierarchy rooted at GRP.

 - Function: int xaccGroupGetNumAccounts (AccountGroup * GRP)
     Return the number of accounts in GRP. This count does not include
     Accounts lower in the hierarchy.

 - Function: int xaccGroupGetDepth (AccountGroup * GRP)
     Returns the length of the longest tree branch in the hierarchy
     rooted at GRP. Each link between an Account and its (non-null)
     children counts as one unit of length.

 - Function: Account * xaccGroupGetAccount (AccountGroup * GROUP, int
          INDEX)
     Return the INDEXth Account in GROUP, starting at zero.  If INDEX
     is out of range, `NULL' is returned.

 - Function: GList * xaccGroupGetSubAccounts (AccountGroup * GRP)
     Return a list of the Accounts, including sub-Accounts, in GRP. The
     returned list should be freed with `g_list_free' when no longer
     needed.

 - Function: GList * xaccGroupGetAccountList (AccountGroup * GRP)
     Return a list of the immediate children of GRP. The returned list
     should not be freed or modified in any way.


File: gnucash-design.info,  Node: GNCBooks,  Next: Scrub,  Prev: Account Groups,  Up: Engine

GNCBooks
========

   The "GNCBook" interface encapsulates all the information about a
GnuCash dataset, including the methods used to read and write the
dataset to datastores.  This class provides several important services:

   * Prevents multiple users from editing the same file at the same
     time, thus avoiding lost data due to race conditions. Thus an
     'open book' implies that the associated file is locked.

   * Provides a search path for the file to be edited. This should
     simplify install & maintenance problems for users who may not have
     a good grasp of what a file system is, or where they want to keep
     their data files.


   The current implementation assumes the use of files and file locks;
however, the API was designed to be general enough to allow the use of
generic URL's, and/or implementation on top of SQL or other
database/persistant object technology.

* Menu:

* GNCBook API::


File: gnucash-design.info,  Node: GNCBook API,  Prev: GNCBooks,  Up: GNCBooks

GNCBook API
-----------

 - Function: GNCBook * gnc_book_new (void)
     Allocate, initialize, and return a new GNCBook. The new book will
     contain a newly allocated AccountGroup.

 - Function: void gnc_book_destroy (GNCBook * BOOK)
     End any editing session associated with BOOK, and free all memory
     associated with it.

 - Function: gboolean gnc_book_begin (GNCBook * BOOK, const char *
          BOOK_ID, gboolean ignore_lock, gboolean create_if_nonexistent)
     Begins a new book editing sesssion. It takes as an argument the
     book id.  The book id must be a string in the form of a URI/URL.
     In the current implementation, only one type of URI is supported,
     and that is the file URI: anything of the form
     <file:/home/somewhere/somedir/file.xac> The path part must be a
     valid path.  The file-part must be a valid GnuCash data file.
     Paths may be relative or absolute. If the path is relative; that
     is, if the argument is <file:somefile.xac> then a sequence of
     search paths are checked for a file of this name.

     The 'ignore_lock' argument, if set to TRUE, will cause this
     routine to ignore any file locks that it finds.  If set to FALSE,
     then file locks will be tested and obeyed.

     If the file exists, can be opened and read, and a lock can be
     obtained then a lock will be obtained and the function returns
     TRUE.

     If the file/database doesn't exist, and the create_if_nonexistent
     flag is set to TRUE, then the database is created.

     Otherwise the function returns FALSE.

 - Function: gboolean gnc_book_load (GNCBook * BOOK)
     Load the data associated with the book. The function returns TRUE
     on success.

 - Function: GNCBackendError gnc_book_get_error (GNCBook * BOOK)
     Obtain the reason for a failure. Standard errno values are used.
     Calling this routine resets the error value. This routine allows an
     implementation of multiple error values, e.g. in a stack, where
     this routine pops the top value. The current implementation has a
     stack that is one-deep.

     Some important error values:

    `EINVAL'
          bad argument

    `ETXTBSY'
          book id is in use; it's locked by someone else

    `ENOSYS'
          unsupported URI type

    `ERANGE'
          file path too long

    `ENOLCK'
          book not open when `gnc_book_save()' was called.


 - Function: const char * gnc_book_get_error_message (GNCBook * BOOK)
     Return a string describing the reason for the current error.
     Calling this routine resets the error value.

 - Function: GNCBackendError gnc_book_pop_error (GNCBook * BOOK)
     Same as `gnc_book_get_error', but the error value is reset in BOOK.

 - Function: AccountGroup * gnc_book_get_group (GNCBook * BOOK)
     Return the current top-level account group.

 - Function: void gnc_book_set_group (GNCBook * BOOK, AccountGroup *
          TOPGROUP)
     Set the topgroup to a new value.

 - Function: const char * gnc_book_get_file_path (GNCBook * BOOK)
     Return the fully-qualified file path for the book. That is, if a
     relative or partial filename was for the book, then it had to have
     been fully resolved to open the book. This routine returns the
     result of this resolution.

 - Function: gboolean gnc_book_save_may_clobber_data (GNCBook * BOOK)
     Return TRUE if saving the book would overwrite other information.

 - Function: void gnc_book_save (GNCBook * BOOK)
     Commit all changes that have been made to the book.

 - Function: void gnc_book_end (GNCBook * BOOK)
     Release the session lock. It will _not_ save the account group to
     a file. Thus, this method acts as an "abort" or "rollback"
     primitive.


File: gnucash-design.info,  Node: Scrub,  Prev: GNCBooks,  Up: Engine

Scrub
=====


File: gnucash-design.info,  Node: Component Manager,  Next: Register,  Prev: Engine,  Up: Top

Component Manager
*****************

   The Component Manager (hereafter referred to as the CM) is a
framework for managing GUI objects in GnuCash. The CM provides several
services.

   First, components may request automatic invocation of a 'refresh'
handler that is called when a component may need to be redrawn. This
mechanism is tied into the Engine's Event mechanism (*note Events::),
so that GUI components are notified when relevant Engine entities are
created, modified, or destroyed.

   Components may also provide a 'close' handler so that the component
may be closed through the CM API.

   The CM also provides the ability to search for existing components.

* Menu:

* Component Manager Introduction::
* Refresh Mechanism::
* CM Initialization and Shutdown::
* Refresh Handlers::
* Close Handlers::
* Registering and Unregistering Components::
* Watching Engine Objects::
* Controlling Refreshes::
* Finding Components::
* Iterating over Components::


File: gnucash-design.info,  Node: Component Manager Introduction,  Next: Refresh Mechanism,  Prev: Component Manager,  Up: Component Manager

Introduction
============

   The GnuCash GUI must manage many different components (registers,
reconcile windows, reports, graphs, main window, etc.).  Functions which
need to be performed on or with GUI components include:

   * Refreshing components. When Engine objects (Accounts,
     Transactions, Splits, etc.) are created, modified, or destroyed,
     the GUI components which reference those objects must be refreshed.

   * Searching for existing components. For example, when the user
     chooses to 'Reconcile' an account with an existing reconcile
     dialog, that dialog should be raised to the top in lieu of creating
     a new reconcile dialog.

   * Closing components.


   In particular, keeping components updated in the face of changes in
the Engine is a difficult problem. Requirements for handling refreshes
include:

   * The Engine should be able to inform user code when any account or
     transaction is changed (including changing their respective
     splits).  This requirement is satisfied by the Engine Events.

   * The refresh mechanism should not have specific knowledge of
     individual windows and other GUI elements. It should be easy to
     add new refreshable elements to the mechanism.

   * Changes should be batchable with respect to refreshes, so that a
     sequence of changes only cause a refresh after the last change in
     a batch. Batching should be nestable, for coding simplicity.

   * For very large batches of changes (loading files) we need to be
     able to turn off the mechanism entirely, perform the changes, and
     then perform a global, forced refresh. This should also be
     nestable.

   * The Engine should not be managing GUI components.

   * The refresh mechanism should be extendable to a multi-user
     situation in which changes can come from external components.

   * Components should be able to specify which Engine entities can
     cause refreshes. This requirement avoids allows the implementation
     to avoid unnecessary refreshing.



File: gnucash-design.info,  Node: Refresh Mechanism,  Next: CM Initialization and Shutdown,  Prev: Component Manager Introduction,  Up: Component Manager

Refresh Mechanism
=================

   The major design decisions of the CM relate to the refresh
mechanism. The refresh mechanism consists of two parts, the Engine
component and the GUI component. The Engine component is the Event
mechanism (*note Events::), while the GUI component is the Component
Manager, which provide refresh functionality as well as other services.

   The diagram below illustrated the design of the GnuCash refresh
mechanism.

                                 ----------
                                 |        |
                                 | Engine |
                                 |        |
                                 ----------
                                     /|\
                                      |
                                      |--- Events (from Engine)
                                      |
                                     \|/
                         -------------------------
                         |                       |
                         |   Component Manager   |
                         |                       |
                         -------------------------
                        /            /|\          \     GUI Commands
                       /              |            \--- including refresh
                      /              \|/            \   invocations (from CM)
     -----------------         -----------------
     |               |         |               |
     | GUI Component |         | GUI Component |           ...
     |               |         |               |
     -----------------         -----------------

   The top-level component is the Engine, which emits Events to the
Component Manager. In fact, the Engine will send events to any
registered handler, but in GnuCash, only the CM registers with the
engine. All other GUI components register with the CM.

   The CM invokes the refresh handlers of GUI components based on the
Engine events received the CM has received as well as information
provided by the GUI components (such as which specific Engine entities
the components are 'watching').


File: gnucash-design.info,  Node: CM Initialization and Shutdown,  Next: Refresh Handlers,  Prev: Refresh Mechanism,  Up: Component Manager

Initialization and Shutdown
===========================

 - Function: void gnc_component_manager_init (void)
     Initialize the Component Manager. This should be called before
     using an other CM functions.

 - Function: void gnc_component_manager_shutdown (void)
     Shutdown the Component Manager. This should be called to release
     Component Manager resources.


File: gnucash-design.info,  Node: Refresh Handlers,  Next: Close Handlers,  Prev: CM Initialization and Shutdown,  Up: Component Manager

Refresh Handlers
================

   When a component registers itself with the CM, it may specify two
different handlers: a refresh handler and a close handler. A refresh
handler is a function with the following type signature:

 - Data type: GNCComponentRefreshHandler void (*) (GHashTable *CHANGES,
          gpointer USER_DATA)
     This is the type signature of a refresh handler. The CHANGES hash
     describes the Engine events which have occurred since the last
     refresh.  It is used to determine whether a refresh is actually
     needed. It may, however, be `NULL', meaning the component must
     perform a refresh.  The `user_data' pointer is the data pointer
     supplied when the component was registered.

   When a refresh handler is invoked, it should perform the following
actions:

  1. Check if the component should be closed. When a refresh handler is
     invoked, any and all of the Engine objects which the component was
     referencing may have been destroyed, possibly making the component
     obsolete. For example, a dialog to edit the parameters of a
     specific Account should be automatically closed when the account
     is deleted. On the other hand, a list of all Accounts in a
     hierarchy should be updated when an Account is deleted, but not
     necessarily closed.

     Components must test for the destruction of critical Engine objects
     in two ways.

       1. Use the `GUID' lookup functions (such as
          `xaccAccountLookup'), to determine if the engine object is
          still bound to its `GUID'. Of course, this means that
          components should store the `GUID's of critical Engine
          objects instead of simply storing their C pointers.

       2. If the first test succeeds and the CHANGES hash table of the
          refresh handler is non-NULL, the component should use the
          hash to determine of the GNC_EVENT_DESTROY event has ocurred
          for the Engine object in question. The CHANGES hash is a
          mapping from `GUID's to `EventInfo' structures. An `EventInfo'
          structure has a single member, `event_mask', of type
          `GNCEngineEventType'. The `event_mask' is a logical or of the
          `GNC_EVENT_CREATE', `GNC_EVENT_MODIFY', and
          `GNC_EVENT_DESTROY' event types. Since refreshes may not
          occur with every Engine event, `event_mask' may have all
          three values.

          There is a utility function for accessing the CHANGES hash:

           - Function: const EventInfo * gnc_gui_get_entity_events
                    (GHashTable * CHANGES, GUID * ENTITY)
               Return the event info for the entity specified by
               ENTITY. If there are no events for that entity, `NULL'
               is returned.


     If the CHANGES hash is NULL, then the first test is sufficient to
     determine whether an object has been destroyed.

     If the refresh handler determines the component should be
     destroyed, it should destroy the component and return.

  2. Check if the component should be refreshed. If the CHANGES hash is
     `NULL', then the component must refresh itself. Otherwise, it may
     use the CHANGES hash to determine whether or not a refresh is
     actually necessary. However, since the component may specify which
     particular Engine objects are relevant (see "Watching Components"
     below), generally a component will simply refresh unconditionally.

  3. Refresh the component if necessary. This includes updating the GUI
     as well as internal structures to reflect the new state of Engine
     objects.



File: gnucash-design.info,  Node: Close Handlers,  Next: Registering and Unregistering Components,  Prev: Refresh Handlers,  Up: Component Manager

Close Handlers
==============

   A close handler is a function with the following type signature:

 - Data type: GNCComponentCloseHandler void (*) (gpointer USER_DATA)
     This is the type signature of a close handler. The `user_data'
     pointer is the data pointer supplied when the component was
     registered.

   The invocation of a close handler is a command to the component to
close itself. The component must close itself - the handler should not
be ignored. The component is still responsible for unregistering itself
with the Component Manager.


File: gnucash-design.info,  Node: Registering and Unregistering Components,  Next: Watching Engine Objects,  Prev: Close Handlers,  Up: Component Manager

Registering and Unregistering Components
========================================

 - Function: gint gnc_register_gui_component (const char *
          COMPONENT_CLASS, GNCComponentRefreshHandler REFRESH_HANDLER,
          GNCComponentCloseHandler CLOSE_HANDLER, gpointer USER_DATA)
     Register a gui component with the Component Manager.

     The variable COMPONENT_CLASS is a string specifying a class of
     components. Certain CM functions can be performed on all
     components in a class. For that reason, components in the same
     class should all use the same type for USER_DATA.

     REFRESH_HANDLER and CLOSE_HANDLER specify the refresh and close
     handlers, respectively. Either or both may be `NULL'.

     The USER_DATA is supplied as an argument when the handlers are
     invoked.

     The function returns the id of the newly-registered component, or
     `NO_COMPONENT' if there was an error.

   After a refresh handler is registered, the component must use the API
calls under "Watching Engine Objects" below to inform the Component
Manager which engine entities are being watched, i.e., which engine
entities may cause the component to need refreshing. When a component is
first registered, it is not watching anything, and thus will not receive
refresh events.

 - Function: void gnc_unregister_gui_component (gint COMPONENT_ID)
     Unregister the component with id COMPONENT from the CM.

 - Function: void gnc_unregister_gui_component_by_data (const char *
          COMPONENT_CLASS, gpointer USER_DATA)
     Unregister all gui components in the class COMPONENT_CLASS which
     have USER_DATA as a user data pointer.


File: gnucash-design.info,  Node: Watching Engine Objects,  Next: Controlling Refreshes,  Prev: Registering and Unregistering Components,  Up: Component Manager

Watching Engine Objects
=======================

 - Function: void gnc_gui_component_watch_entity (gint COMPONENT_ID,
          const GUID * ENTITY, GNCEngineEventType EVENT_MASK)
     If EVENT_MASK is non-zero, add the Engine entity specified by
     ENTITY to the list of entities being watched by the component with
     id COMPONENT_ID. Only the events specified by EVENTS are watched.
     If EVENT_MASK is 0, the call turns off watching for the entity.

 - Function: void gnc_gui_component_watch_entity_type (gint
          COMPONENT_ID, GNCIdType ENTITY_TYPE, GNCEngineEventType
          EVENT_MASK)
     if EVENT_MASK, turn on watching for all entities of ENTITY_TYPE.
     Only events specified by EVENT_MASK are watched. If EVENT_MASK is
     0, turns off watching for the entity type.

 - Function: void gnc_gui_component_clear_watches (gint COMPONENT_ID)
     Clear all watches for the component with id COMPONENT_ID.


File: gnucash-design.info,  Node: Controlling Refreshes,  Next: Finding Components,  Prev: Watching Engine Objects,  Up: Component Manager

Controlling Refreshes
=====================

 - Function: void gnc_suspend_gui_refresh (void)
     Suspend the invocation of refresh handlers by the Component
     Manager.  This routine may be called multiple times. Each call
     increases the suspend counter which starts at zero. When refreshes
     are not suspended, any engine event causes a refresh cycle in
     which the refresh handler for every component watching for that
     event is invoked.

 - Function: void gnc_resume_gui_refresh (void)
     Resume the invocation of refresh handlers by the Component Manager.
     Each call reduces the suspend counter by one. When the counter
     reaches zero, all events which have occured since the last refresh
     are collected and passed to refresh handlers via the CHANGES
     argument. Refresh handlers will still be excluded based on their
     watches.

 - Function: void gnc_gui_refresh_all (void)
     Force all components to refresh, i.e., invoke all refresh handlers
     with a `NULL' value for CHANGES.

     This routine may only be invoked when the suspend counter is zero.
     It should never be mixed with the suspend/resume refresh routines.

 - Function: gboolean gnc_gui_refresh_suspended (void)
     Returns TRUE if GUI refreshing is currently suspended.


File: gnucash-design.info,  Node: Finding Components,  Next: Iterating over Components,  Prev: Controlling Refreshes,  Up: Component Manager

Finding Components
==================

   The Component Manager API provides two functions that allow
components to be searched for. Each function uses a find handler to
perform the actual search work. A find handler is a function with the
following signature:

 - Data type: GNCComponentFindHandler gboolean (*) (gpointer FIND_DATA,
          gpointer USER_DATA)
     A find handler is invoked with the FIND_DATA specified in the
     search API call, and the USER_DATA of a particular component. The
     handler should return TRUE if the component matches the search
     criteria and FALSE otherwise.

 - Function: GList * gnc_find_gui_components (const char *
          COMPONENT_CLASS, GNCComponentFindHandler FIND_HANDLER,
          gpointer FIND_DATA)
     Search for all components in class COMPONENT_CLASS using
     FIND_HANDLER. Return a `GList' of the user data pointers of
     matching components.

 - Function: gpointer gnc_find_first_gui_component (const char *
          COMPONENT_CLASS, GNCComponentFindHandler FIND_HANDLER,
          gpointer FIND_DATA)
     Like `gnc_find_gui_components' above, but return the user data
     pointer of the first matching component, or `NULL' if there are no
     matching components.

