33 #include "gnc-component-manager.h" 45 #define REGISTER_SINGLE_CM_CLASS "register-single" 46 #define REGISTER_SUBACCOUNT_CM_CLASS "register-subaccount" 47 #define REGISTER_GL_CM_CLASS "register-gl" 48 #define REGISTER_TEMPLATE_CM_CLASS "register-template" 50 #define GNC_PREF_DOUBLE_LINE_MODE "double-line-mode" 51 #define GNC_PREF_MAX_TRANS "max-transactions" 52 #define GNC_PREF_DEFAULT_STYLE_LEDGER "default-style-ledger" 53 #define GNC_PREF_DEFAULT_STYLE_AUTOLEDGER "default-style-autoledger" 54 #define GNC_PREF_DEFAULT_STYLE_JOURNAL "default-style-journal" 63 GNCLedgerDisplayType ld_type;
68 gboolean use_double_line_default;
70 GNCLedgerDisplayDestroy destroy;
71 GNCLedgerDisplayGetParent get_parent;
73 GHashTable *excluded_template_acc_hash;
77 gint number_of_subaccounts;
84 static QofLogModule log_module = GNC_MOD_LEDGER;
88 static GNCLedgerDisplay*
89 gnc_ledger_display_internal (
Account* lead_account, Query* q,
90 GNCLedgerDisplayType ld_type,
93 gboolean use_double_line,
95 gboolean mismatched_commodities);
97 static void gnc_ledger_display_refresh_internal (GNCLedgerDisplay* ld,
100 static void gnc_ledger_display_make_query (GNCLedgerDisplay* ld,
116 gnc_ledger_display_type (GNCLedgerDisplay* ld)
130 ld->user_data = user_data;
134 gnc_ledger_display_get_user_data (GNCLedgerDisplay* ld)
139 return ld->user_data;
144 GNCLedgerDisplayDestroy destroy,
145 GNCLedgerDisplayGetParent get_parent)
150 ld->destroy = destroy;
151 ld->get_parent = get_parent;
173 exclude_template_accounts (Query* q, GHashTable *excluded_template_acc_hash)
185 for (node = al; node; node = next)
188 next = g_list_next (node);
190 if (g_hash_table_lookup (excluded_template_acc_hash, acc) != NULL)
191 al = g_list_delete_link (al, node);
193 g_hash_table_insert (excluded_template_acc_hash, acc, acc);
197 xaccQueryAddAccountMatch (q, al, QOF_GUID_MATCH_NONE, QOF_QUERY_AND);
205 find_by_leader (gpointer
find_data, gpointer user_data)
208 GNCLedgerDisplay* ld = user_data;
217 find_by_query (gpointer
find_data, gpointer user_data)
220 GNCLedgerDisplay* ld = user_data;
222 if (ld->reg->type != SEARCH_LEDGER)
228 return ld->query == q;
232 find_by_reg (gpointer
find_data, gpointer user_data)
235 GNCLedgerDisplay* ld = user_data;
240 return ld->reg == reg;
249 GNC_PREF_DEFAULT_STYLE_JOURNAL))
250 new_style = REG_STYLE_JOURNAL;
252 GNC_PREF_DEFAULT_STYLE_AUTOLEDGER))
253 new_style = REG_STYLE_AUTO_LEDGER;
259 look_for_portfolio_cb (
Account* account, gpointer data)
265 gnc_get_reg_type (
Account* leader, GNCLedgerDisplayType ld_type)
270 if (ld_type == LD_GL)
271 return GENERAL_JOURNAL;
275 if (ld_type == LD_SINGLE)
277 switch (account_type)
280 return BANK_REGISTER;
283 return CASH_REGISTER;
286 return ASSET_REGISTER;
289 return CREDIT_REGISTER;
292 return LIABILITY_REGISTER;
295 return PAYABLE_REGISTER;
298 return RECEIVABLE_REGISTER;
302 return STOCK_REGISTER;
305 return INCOME_REGISTER;
308 return EXPENSE_REGISTER;
311 return EQUITY_REGISTER;
314 return CURRENCY_REGISTER;
317 return TRADING_REGISTER;
320 PERR (
"unknown account type %d\n", account_type);
321 return BANK_REGISTER;
325 if (ld_type != LD_SUBACCOUNT)
327 PERR (
"unknown ledger type %d\n", ld_type);
328 return BANK_REGISTER;
331 switch (account_type)
345 reg_type = GENERAL_JOURNAL;
349 if (ret) reg_type = PORTFOLIO_LEDGER;
356 reg_type = PORTFOLIO_LEDGER;
361 reg_type = INCOME_LEDGER;
366 reg_type = GENERAL_JOURNAL;
370 PERR (
"unknown account type:%d", account_type);
371 reg_type = GENERAL_JOURNAL;
383 return (gld->use_double_line_default ||
385 GNC_PREF_DOUBLE_LINE_MODE));
394 gboolean use_double_line;
395 GNCLedgerDisplay* ld;
397 ENTER (
"account=%p", account);
403 use_double_line = TRUE;
406 use_double_line = FALSE;
410 reg_type = gnc_get_reg_type (account, LD_SINGLE);
412 ld = gnc_ledger_display_internal (account, NULL, LD_SINGLE, reg_type,
413 gnc_get_default_register_style (acc_type),
414 use_double_line, FALSE, FALSE);
423 gboolean mismatched_commodities)
426 GNCLedgerDisplay* ld;
428 ENTER (
"account=%p", account);
430 reg_type = gnc_get_reg_type (account, LD_SUBACCOUNT);
432 ld = gnc_ledger_display_internal (account, NULL, LD_SUBACCOUNT,
433 reg_type, REG_STYLE_JOURNAL, FALSE,
434 FALSE, mismatched_commodities);
446 GNCLedgerDisplay* ld;
447 GHashTable *exclude_template_accounts_hash;
451 query = qof_query_create_for (GNC_ID_SPLIT);
455 exclude_template_accounts_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
464 exclude_template_accounts (query, exclude_template_accounts_hash);
469 xaccQueryAddDateMatchTT (query,
474 ld = gnc_ledger_display_internal (NULL, query, LD_GL, GENERAL_JOURNAL,
475 REG_STYLE_JOURNAL, FALSE, FALSE, FALSE);
477 ld->excluded_template_acc_hash = exclude_template_accounts_hash;
497 GNCLedgerDisplay* ld;
500 gboolean isTemplateModeTrue;
502 ENTER (
"id=%s",
id ?
id :
"(null)");
505 isTemplateModeTrue = TRUE;
507 q = qof_query_create_for (GNC_ID_SPLIT);
509 book = gnc_get_current_book();
517 xaccQueryAddSingleAccountMatch (q, acct, QOF_QUERY_AND);
520 ld = gnc_ledger_display_internal (NULL, q, LD_GL,
545 if (ld->get_parent == NULL)
548 return ld->get_parent (ld);
552 gnc_ledger_display_parent (
void* user_data)
554 GNCLedgerDisplay* ld = user_data;
559 gnc_ledger_display_set_watches (GNCLedgerDisplay* ld, GList* splits)
563 gnc_gui_component_clear_watches (ld->component_id);
565 gnc_gui_component_watch_entity_type (ld->component_id,
567 QOF_EVENT_MODIFY | QOF_EVENT_DESTROY
568 | GNC_EVENT_ITEM_CHANGED);
570 for (node = splits; node; node = node->next)
572 Split* split = node->data;
575 gnc_gui_component_watch_entity (ld->component_id,
582 refresh_handler (GHashTable* changes, gpointer user_data)
584 GNCLedgerDisplay* ld = user_data;
589 ENTER (
"changes=%p, user_data=%p", changes, user_data);
593 LEAVE (
"already loading");
597 has_leader = (ld->ld_type == LD_SINGLE || ld->ld_type == LD_SUBACCOUNT);
604 gnc_close_gui_component (ld->component_id);
610 if (changes && has_leader)
612 info = gnc_gui_get_entity_events (changes, &ld->leader);
613 if (info && (info->event_mask & QOF_EVENT_DESTROY))
615 gnc_close_gui_component (ld->component_id);
623 if (ld->ld_type == LD_SUBACCOUNT)
628 if (g_list_length (accounts) != ld->number_of_subaccounts)
629 gnc_ledger_display_make_query (ld,
631 gnc_get_reg_type (leader, ld->ld_type));
633 g_list_free (accounts);
637 if (!ld->reg->is_template && (ld->reg->type == SEARCH_LEDGER || ld->ld_type == LD_GL))
638 exclude_template_accounts (ld->query, ld->excluded_template_acc_hash);
647 gnc_ledger_display_set_watches (ld, splits);
649 gnc_ledger_display_refresh_internal (ld, splits);
654 close_handler (gpointer user_data)
656 GNCLedgerDisplay* ld = user_data;
661 gnc_unregister_gui_component (ld->component_id);
662 ld->component_id = NO_COMPONENT;
671 if (ld->excluded_template_acc_hash)
672 g_hash_table_destroy (ld->excluded_template_acc_hash);
681 gnc_ledger_display_make_query (GNCLedgerDisplay* ld,
701 PERR (
"unknown ledger type: %d", ld->ld_type);
706 ld->query = qof_query_create_for (GNC_ID_SPLIT);
712 if ((limit != 0) && (type != SEARCH_LEDGER))
722 if (ld->ld_type == LD_SUBACCOUNT)
725 ld->number_of_subaccounts = g_list_length (accounts);
730 accounts = g_list_prepend (accounts, leader);
732 xaccQueryAddAccountMatch (ld->query, accounts,
735 g_list_free (accounts);
743 GNCLedgerDisplay* ld;
745 ENTER (
"query=%p", query);
747 ld = gnc_ledger_display_internal (NULL, query, LD_GL, type, style,
748 FALSE, FALSE, FALSE);
750 ld->excluded_template_acc_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
755 static GNCLedgerDisplay*
756 gnc_ledger_display_internal (
Account* lead_account, Query* q,
757 GNCLedgerDisplayType ld_type,
760 gboolean use_double_line,
761 gboolean is_template,
762 gboolean mismatched_commodities)
764 GNCLedgerDisplay* ld;
772 klass = REGISTER_SINGLE_CM_CLASS;
774 if (reg_type >= NUM_SINGLE_REGISTER_TYPES)
776 PERR (
"single-account register with wrong split register type");
782 PERR (
"single-account register with no account specified");
788 PWARN (
"single-account register with external query");
792 ld = gnc_find_first_gui_component (klass, find_by_leader, lead_account);
799 klass = REGISTER_SUBACCOUNT_CM_CLASS;
803 PERR (
"sub-account register with no lead account");
809 PWARN (
"account register with external query");
813 ld = gnc_find_first_gui_component (klass, find_by_leader, lead_account);
820 klass = REGISTER_GL_CM_CLASS;
824 PWARN (
"general journal with no query");
830 PERR (
"bad ledger type: %d", ld_type);
835 ld = g_new (GNCLedgerDisplay, 1);
839 ld->ld_type = ld_type;
842 ld->get_parent = NULL;
843 ld->user_data = NULL;
844 ld->excluded_template_acc_hash = NULL;
853 gnc_ledger_display_make_query (ld, limit, reg_type);
855 ld->component_id = gnc_register_gui_component (klass,
863 ld->use_double_line_default = use_double_line;
866 is_template, mismatched_commodities);
872 gnc_ledger_display_set_watches (ld, splits);
874 gnc_ledger_display_refresh_internal (ld, splits);
882 if (!ledger_display || !q)
885 g_return_if_fail (ledger_display->ld_type == LD_GL);
897 return gnc_find_first_gui_component (REGISTER_GL_CM_CLASS, find_by_query, q);
905 gnc_ledger_display_refresh_internal (GNCLedgerDisplay* ld, GList* splits)
907 if (!ld || ld->loading)
928 LEAVE (
"no display");
934 LEAVE (
"already loading");
939 if (!ld->reg->is_template && (ld->reg->type == SEARCH_LEDGER || ld->ld_type == LD_GL))
940 exclude_template_accounts (ld->query, ld->excluded_template_acc_hash);
942 gnc_ledger_display_refresh_internal (ld,
qof_query_run (ld->query));
947 gnc_ledger_display_refresh_by_split_register (SplitRegister* reg)
949 GNCLedgerDisplay* ld;
954 ld = gnc_find_first_gui_component (REGISTER_SINGLE_CM_CLASS,
962 ld = gnc_find_first_gui_component (REGISTER_SUBACCOUNT_CM_CLASS,
970 ld = gnc_find_first_gui_component (REGISTER_GL_CM_CLASS,
978 ld = gnc_find_first_gui_component (REGISTER_TEMPLATE_CM_CLASS,
992 gnc_close_gui_component (ld->component_id);
void gnc_ledger_display_close(GNCLedgerDisplay *ld)
close the window
Public declarations for GncLedgerDisplay class.
void gnc_ledger_display_refresh(GNCLedgerDisplay *ld)
redisplay/redraw only the indicated window.
gboolean gnc_ledger_display_default_double_line(GNCLedgerDisplay *gld)
Returns a boolean of whether this display should be single or double lined mode by default...
Date and Time handling routines.
void gnc_split_register_load(SplitRegister *reg, GList *slist, Account *default_account)
Populates the rows of a register.
void gnc_split_register_destroy(SplitRegister *reg)
Destroys a split register.
gboolean xaccAccountIsPriced(const Account *acc)
Returns true if the account is a stock, mutual fund or currency, otherwise false. ...
utility functions for the GnuCash UI
Expense accounts are used to denote expenses.
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
Mutual Fund accounts will typically be shown in registers which show three columns: price...
gpointer gnc_account_foreach_descendant_until(const Account *acc, AccountCb2 thunk, gpointer user_data)
This method will traverse all children of this accounts and their descendants, calling 'func' on each...
TableControl specialized for the SplitRegister.
gboolean gnc_split_register_full_refresh_ok(SplitRegister *reg)
Private function – outsiders must not use this.
QofQuery * qof_query_copy(QofQuery *q)
Make a copy of the indicated query.
Account * gnc_ledger_display_leader(GNCLedgerDisplay *ld)
Implementations.
void gnc_split_register_set_template_account(SplitRegister *reg, Account *template_account)
Set the template account for use in a template register.
Account * gnc_book_get_template_root(const QofBook *book)
Returns the template group from the book.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
TableModels specialized for SplitRegister and template SplitRegister.
void gnc_tm_get_today_start(struct tm *tm)
The gnc_tm_get_today_start() routine takes a pointer to a struct tm and fills it in with the first se...
void gnc_ledger_display_set_query(GNCLedgerDisplay *ledger_display, Query *q)
Set the query used for a register.
void gnc_split_register_set_data(SplitRegister *reg, gpointer user_data, SRGetParentCallback get_parent)
Sets the user data and callback hooks for the register.
These expect a single object and expect the QofAccessFunc returns GncGUID*.
#define PERR(format, args...)
Log a serious error.
#define ENTER(format, args...)
Print a function entry debugging message.
The cash account type is used to denote a shoe-box or pillowcase stuffed with * cash.
Query * gnc_ledger_display_get_query(GNCLedgerDisplay *ld)
return the query associated with a ledger
Account used to record multiple commodity transactions.
void qof_query_set_max_results(QofQuery *q, int n)
Set the maximum number of results that should be returned.
Account * gnc_account_lookup_by_name(const Account *parent, const char *name)
The gnc_account_lookup_by_name() subroutine fetches the account by name from the descendants of the s...
#define PWARN(format, args...)
Log a warning.
Stock accounts will typically be shown in registers which show three columns: price, number of shares, and value.
GNCLedgerDisplay * gnc_ledger_display_subaccounts(Account *account, gboolean mismatched_commodities)
opens up a register window to display the parent account and all of its children. ...
#define xaccAccountGetGUID(X)
Account handling public routines.
void qof_query_destroy(QofQuery *query)
Frees the resources associate with a Query object.
void gnc_ledger_display_set_handlers(GNCLedgerDisplay *ld, GNCLedgerDisplayDestroy destroy, GNCLedgerDisplayGetParent get_parent)
set the handlers used by the ledger display
Income accounts are used to denote income.
The GNCLedgerDisplay struct describes a single register/ledger instance.
void qof_query_set_book(QofQuery *query, QofBook *book)
Set the book to be searched.
Anchor Scheduled Transaction info in a book.
The bank account type denotes a savings or checking account held at a bank.
time64 gnc_mktime(struct tm *time)
calculate seconds from the epoch given a time struct
Additional event handling code.
GtkWidget * gnc_ledger_display_get_parent(GNCLedgerDisplay *ld)
Returns the parent of a given ledger display.
asset (and liability) accounts indicate generic, generalized accounts that are none of the above...
All type declarations for the whole Gnucash engine.
The currency account type indicates that the account is a currency trading account.
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed...
#define xaccTransGetGUID(X)
Generic api to store and retrieve preferences.
GList * gnc_account_get_descendants(const Account *account)
This routine returns a flat list of all of the accounts that are descendants of the specified account...
GNCLedgerDisplay * gnc_ledger_display_template_gl(char *id)
Displays a template ledger.
GList * qof_query_run(QofQuery *query)
Perform the query, return the results.
liability (and asset) accounts indicate generic, generalized accounts that are none of the above...
GNCLedgerDisplay * gnc_ledger_display_simple(Account *account)
opens up a register window to display a single account
GNCLedgerDisplay * gnc_ledger_display_find_by_query(Query *q)
If the given ledger display still exists, return it.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
#define LEAVE(format, args...)
Print a function exit debugging message.
GNCLedgerDisplay * gnc_ledger_display_query(Query *query, SplitRegisterType type, SplitRegisterStyle style)
display a general ledger for an arbitrary query
gint64 time64
Many systems, including Microsoft Windows and BSD-derived Unixes like Darwin, are retaining the int-3...
GNCLedgerDisplay * gnc_ledger_display_gl(void)
opens up a general ledger window
SplitRegister * gnc_ledger_display_get_split_register(GNCLedgerDisplay *ld)
return the split register associated with a ledger display
Equity account is used to balance the balance sheet.
SplitRegisterType
Register types.
gint gnc_list_length_cmp(const GList *list, size_t len)
Scans the GList elements the minimum number of iterations required to test it against a specified siz...
API for Transactions and Splits (journal entries)
The type used to store guids in C.
void gnc_ledger_display_set_user_data(GNCLedgerDisplay *ld, gpointer user_data)
get and set the user data associated with the ledger
SplitRegister * gnc_split_register_new(SplitRegisterType type, SplitRegisterStyle style, gboolean use_double_line, gboolean is_template, gboolean mismatched_commodities)
Creates a new split register.
SplitRegisterStyle
Register styles.
The Credit card account is used to denote credit (e.g.
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Get an float value from the preferences backend.
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id...