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"
62 Query* pre_filter_query;
64 GNCLedgerDisplayType ld_type;
69 gboolean use_double_line_default;
71 gboolean needs_refresh;
73 GNCLedgerDisplayDestroy destroy;
74 GNCLedgerDisplayGetParent get_parent;
76 GHashTable *excluded_template_acc_hash;
80 gint number_of_subaccounts;
87static QofLogModule log_module = GNC_MOD_LEDGER;
91static GNCLedgerDisplay*
92gnc_ledger_display_internal (
Account* lead_account,
Query* q,
93 GNCLedgerDisplayType ld_type,
96 gboolean use_double_line,
98 gboolean mismatched_commodities);
101gnc_ledger_display_refresh_internal (GNCLedgerDisplay* ld);
103static void gnc_ledger_display_make_query (GNCLedgerDisplay* ld,
119gnc_ledger_display_type (GNCLedgerDisplay* ld)
133 ld->user_data = user_data;
137gnc_ledger_display_get_user_data (GNCLedgerDisplay* ld)
142 return ld->user_data;
147 GNCLedgerDisplayDestroy destroy,
148 GNCLedgerDisplayGetParent get_parent)
153 ld->destroy = destroy;
154 ld->get_parent = get_parent;
176exclude_template_accounts (
Query* q, GHashTable *excluded_template_acc_hash)
188 for (node = al; node; node = next)
191 next = g_list_next (node);
193 if (g_hash_table_lookup (excluded_template_acc_hash, acc) != NULL)
194 al = g_list_delete_link (al, node);
196 g_hash_table_insert (excluded_template_acc_hash, acc, acc);
200 xaccQueryAddAccountMatch (q, al, QOF_GUID_MATCH_NONE, QOF_QUERY_AND);
208find_by_leader (gpointer
find_data, gpointer user_data)
211 GNCLedgerDisplay* ld = user_data;
220find_by_query (gpointer
find_data, gpointer user_data)
223 GNCLedgerDisplay* ld = user_data;
225 if (ld->reg->type != SEARCH_LEDGER)
231 return ld->query == q;
235find_by_reg (gpointer
find_data, gpointer user_data)
238 GNCLedgerDisplay* ld = user_data;
243 return ld->reg == reg;
252 GNC_PREF_DEFAULT_STYLE_JOURNAL))
253 new_style = REG_STYLE_JOURNAL;
255 GNC_PREF_DEFAULT_STYLE_AUTOLEDGER))
256 new_style = REG_STYLE_AUTO_LEDGER;
262look_for_portfolio_cb (
Account* account, gpointer data)
268gnc_get_reg_type (
Account* leader, GNCLedgerDisplayType ld_type)
273 if (ld_type == LD_GL)
274 return GENERAL_JOURNAL;
278 if (ld_type == LD_SINGLE)
280 switch (account_type)
283 return BANK_REGISTER;
286 return CASH_REGISTER;
289 return ASSET_REGISTER;
292 return CREDIT_REGISTER;
295 return LIABILITY_REGISTER;
298 return PAYABLE_REGISTER;
301 return RECEIVABLE_REGISTER;
305 return STOCK_REGISTER;
308 return INCOME_REGISTER;
311 return EXPENSE_REGISTER;
314 return EQUITY_REGISTER;
317 return CURRENCY_REGISTER;
320 return TRADING_REGISTER;
323 PERR (
"unknown account type %d\n", account_type);
324 return BANK_REGISTER;
328 if (ld_type != LD_SUBACCOUNT)
330 PERR (
"unknown ledger type %d\n", ld_type);
331 return BANK_REGISTER;
334 switch (account_type)
348 reg_type = GENERAL_JOURNAL;
352 if (ret) reg_type = PORTFOLIO_LEDGER;
359 reg_type = PORTFOLIO_LEDGER;
364 reg_type = INCOME_LEDGER;
369 reg_type = GENERAL_JOURNAL;
373 PERR (
"unknown account type:%d", account_type);
374 reg_type = GENERAL_JOURNAL;
386 return (gld->use_double_line_default ||
388 GNC_PREF_DOUBLE_LINE_MODE));
397 gboolean use_double_line;
398 GNCLedgerDisplay* ld;
400 ENTER (
"account=%p", account);
406 use_double_line = TRUE;
409 use_double_line = FALSE;
413 reg_type = gnc_get_reg_type (account, LD_SINGLE);
415 ld = gnc_ledger_display_internal (account, NULL, LD_SINGLE, reg_type,
416 gnc_get_default_register_style (acc_type),
417 use_double_line, FALSE, FALSE);
426 gboolean mismatched_commodities)
429 GNCLedgerDisplay* ld;
431 ENTER (
"account=%p", account);
433 reg_type = gnc_get_reg_type (account, LD_SUBACCOUNT);
435 ld = gnc_ledger_display_internal (account, NULL, LD_SUBACCOUNT,
436 reg_type, REG_STYLE_JOURNAL, FALSE,
437 FALSE, mismatched_commodities);
448 GNCLedgerDisplay* ld;
449 GHashTable *exclude_template_accounts_hash;
453 query = qof_query_create_for (GNC_ID_SPLIT);
457 exclude_template_accounts_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
466 exclude_template_accounts (query, exclude_template_accounts_hash);
469 static const time64 secs_per_thirty_days = 2592000;
472 xaccQueryAddDateMatchTT (query,
477 ld = gnc_ledger_display_internal (NULL, query, LD_GL, GENERAL_JOURNAL,
478 REG_STYLE_JOURNAL, FALSE, FALSE, FALSE);
480 ld->excluded_template_acc_hash = exclude_template_accounts_hash;
500 GNCLedgerDisplay* ld;
503 gboolean isTemplateModeTrue;
505 ENTER (
"id=%s",
id ?
id :
"(null)");
508 isTemplateModeTrue = TRUE;
510 q = qof_query_create_for (GNC_ID_SPLIT);
512 book = gnc_get_current_book();
520 xaccQueryAddSingleAccountMatch (q, acct, QOF_QUERY_AND);
523 ld = gnc_ledger_display_internal (NULL, q, LD_GL,
548 if (ld->get_parent == NULL)
551 return ld->get_parent (ld);
555gnc_ledger_display_parent (
void* user_data)
557 GNCLedgerDisplay* ld = user_data;
562gnc_ledger_display_set_watches (GNCLedgerDisplay* ld, GList* splits)
566 gnc_gui_component_clear_watches (ld->component_id);
568 gnc_gui_component_watch_entity_type (ld->component_id,
570 QOF_EVENT_MODIFY | QOF_EVENT_DESTROY
571 | GNC_EVENT_ITEM_CHANGED);
573 for (node = splits; node; node = node->next)
575 Split* split = node->data;
578 gnc_gui_component_watch_entity (ld->component_id,
585refresh_handler (GHashTable* changes, gpointer user_data)
587 GNCLedgerDisplay* ld = user_data;
591 ENTER (
"changes=%p, user_data=%p", changes, user_data);
595 LEAVE (
"already loading");
599 has_leader = (ld->ld_type == LD_SINGLE || ld->ld_type == LD_SUBACCOUNT);
606 gnc_close_gui_component (ld->component_id);
612 if (changes && has_leader)
614 info = gnc_gui_get_entity_events (changes, &ld->leader);
615 if (info && (info->event_mask & QOF_EVENT_DESTROY))
617 gnc_close_gui_component (ld->component_id);
625 DEBUG (
"immediate refresh because ledger is visible");
630 ld->needs_refresh = TRUE;
636close_handler (gpointer user_data)
638 GNCLedgerDisplay* ld = user_data;
643 gnc_unregister_gui_component (ld->component_id);
644 ld->component_id = NO_COMPONENT;
653 if (ld->excluded_template_acc_hash)
654 g_hash_table_destroy (ld->excluded_template_acc_hash);
660 ld->pre_filter_query = NULL;
666gnc_ledger_display_make_query (GNCLedgerDisplay* ld,
686 PERR (
"unknown ledger type: %d", ld->ld_type);
691 ld->query = qof_query_create_for (GNC_ID_SPLIT);
697 if ((limit != 0) && (type != SEARCH_LEDGER))
707 if (ld->ld_type == LD_SUBACCOUNT)
710 ld->number_of_subaccounts = g_list_length (accounts);
715 accounts = g_list_prepend (accounts, leader);
717 xaccQueryAddAccountMatch (ld->query, accounts,
718 QOF_GUID_MATCH_ANY, QOF_QUERY_AND);
720 g_list_free (accounts);
728 GNCLedgerDisplay* ld;
730 ENTER (
"query=%p", query);
732 ld = gnc_ledger_display_internal (NULL, query, LD_GL, type, style,
733 FALSE, FALSE, FALSE);
735 ld->excluded_template_acc_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
740static GNCLedgerDisplay*
741gnc_ledger_display_internal (
Account* lead_account,
Query* q,
742 GNCLedgerDisplayType ld_type,
745 gboolean use_double_line,
746 gboolean is_template,
747 gboolean mismatched_commodities)
749 GNCLedgerDisplay* ld;
756 klass = REGISTER_SINGLE_CM_CLASS;
758 if (reg_type >= NUM_SINGLE_REGISTER_TYPES)
760 PERR (
"single-account register with wrong split register type");
766 PERR (
"single-account register with no account specified");
772 PWARN (
"single-account register with external query");
776 ld = gnc_find_first_gui_component (klass, find_by_leader, lead_account);
783 klass = REGISTER_SUBACCOUNT_CM_CLASS;
787 PERR (
"sub-account register with no lead account");
793 PWARN (
"account register with external query");
797 ld = gnc_find_first_gui_component (klass, find_by_leader, lead_account);
804 klass = REGISTER_GL_CM_CLASS;
808 PWARN (
"general journal with no query");
814 PERR (
"bad ledger type: %d", ld_type);
819 ld = g_new (GNCLedgerDisplay, 1);
823 ld->ld_type = ld_type;
826 ld->needs_refresh = TRUE;
828 ld->get_parent = NULL;
829 ld->user_data = NULL;
830 ld->excluded_template_acc_hash = NULL;
839 gnc_ledger_display_make_query (ld, limit, reg_type);
843 ld->component_id = gnc_register_gui_component (klass,
851 ld->use_double_line_default = use_double_line;
854 is_template, mismatched_commodities);
856 gnc_split_register_set_data (ld->reg, ld, gnc_ledger_display_parent);
871 if (!ledger_display || !q)
874 g_return_if_fail (ledger_display->ld_type == LD_GL);
886 return gnc_find_first_gui_component (REGISTER_GL_CM_CLASS, find_by_query, q);
894gnc_ledger_display_refresh_internal (GNCLedgerDisplay* ld)
897 GList* pre_filter_splits = NULL;
912 gnc_ledger_display_set_watches (ld, splits);
914 if (!gnc_split_register_full_refresh_ok (ld->reg))
922 ld->needs_refresh = FALSE;
933 LEAVE (
"no display");
939 LEAVE (
"already loading");
945 if (ld->ld_type == LD_SUBACCOUNT)
950 if (g_list_length (accounts) != ld->number_of_subaccounts)
952 time64 start_time, end_time;
953 xaccQueryGetDateMatchTT (ld->query, &start_time, &end_time);
955 cleared_match_t cleared_match = xaccQueryGetClearedMatch (ld->query);
957 gnc_ledger_display_make_query (ld,
959 gnc_get_reg_type (leader, ld->ld_type));
964 if (cleared_match != CLEARED_ALL)
965 xaccQueryAddClearedMatch (ld->query, cleared_match, QOF_QUERY_AND);
967 if (start_time || end_time)
969 xaccQueryAddDateMatchTT (ld->query,
970 start_time != 0, start_time,
971 end_time != 0, end_time,
975 g_list_free (accounts);
985 if (!ld->reg->is_template && (ld->reg->type == SEARCH_LEDGER || ld->ld_type == LD_GL))
987 exclude_template_accounts (ld->query, ld->excluded_template_acc_hash);
992 gnc_ledger_display_refresh_internal (ld);
1001 ld->visible = focus;
1003 if (ld->visible && ld->needs_refresh)
1005 DEBUG (
"deferred refresh because ledger is now visible");
1011gnc_ledger_display_refresh_by_split_register (SplitRegister* reg)
1013 GNCLedgerDisplay* ld;
1018 ld = gnc_find_first_gui_component (REGISTER_SINGLE_CM_CLASS,
1026 ld = gnc_find_first_gui_component (REGISTER_SUBACCOUNT_CM_CLASS,
1034 ld = gnc_find_first_gui_component (REGISTER_GL_CM_CLASS,
1042 ld = gnc_find_first_gui_component (REGISTER_TEMPLATE_CM_CLASS,
1056 gnc_close_gui_component (ld->component_id);
Account handling public routines.
Anchor Scheduled Transaction info in a book.
API for Transactions and Splits (journal entries)
Date and Time handling routines.
All type declarations for the whole Gnucash engine.
Additional event handling code.
Public declarations for GncLedgerDisplay class.
Generic api to store and retrieve preferences.
utility functions for the GnuCash UI
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed.
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
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...
#define xaccAccountGetGUID(X)
gboolean xaccAccountIsPriced(const Account *acc)
Returns true if the account is a stock, mutual fund or currency, otherwise false.
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...
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id,...
@ ACCT_TYPE_INCOME
Income accounts are used to denote income.
@ ACCT_TYPE_MUTUAL
Mutual Fund accounts will typically be shown in registers which show three columns: price,...
@ ACCT_TYPE_TRADING
Account used to record multiple commodity transactions.
@ ACCT_TYPE_EXPENSE
Expense accounts are used to denote expenses.
@ ACCT_TYPE_BANK
The bank account type denotes a savings or checking account held at a bank.
@ ACCT_TYPE_PAYABLE
A/P account type.
@ ACCT_TYPE_ASSET
asset (and liability) accounts indicate generic, generalized accounts that are none of the above.
@ ACCT_TYPE_CURRENCY
The currency account type indicates that the account is a currency trading account.
@ ACCT_TYPE_RECEIVABLE
A/R account type.
@ ACCT_TYPE_CASH
The cash account type is used to denote a shoe-box or pillowcase stuffed with * cash.
@ ACCT_TYPE_LIABILITY
liability (and asset) accounts indicate generic, generalized accounts that are none of the above.
@ ACCT_TYPE_EQUITY
Equity account is used to balance the balance sheet.
@ ACCT_TYPE_CREDIT
The Credit card account is used to denote credit (e.g.
@ ACCT_TYPE_STOCK
Stock accounts will typically be shown in registers which show three columns: price,...
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
time64 gnc_time64_get_today_start(void)
The gnc_time64_get_today_start() routine returns a time64 value corresponding to the first second of ...
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 xaccTransGetGUID(X)
void gnc_ledger_display_set_handlers(GNCLedgerDisplay *ld, GNCLedgerDisplayDestroy destroy, GNCLedgerDisplayGetParent get_parent)
set the handlers used by the ledger display
GNCLedgerDisplay * gnc_ledger_display_gl(void)
opens up a general ledger window
GNCLedgerDisplay * gnc_ledger_display_template_gl(char *id)
Displays a template ledger.
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.
Query * gnc_ledger_display_get_query(GNCLedgerDisplay *ld)
return the query associated with a ledger
GNCLedgerDisplay * gnc_ledger_display_simple(Account *account)
opens up a register window to display a single account
void gnc_ledger_display_refresh(GNCLedgerDisplay *ld)
redisplay/redraw only the indicated window.
GNCLedgerDisplay * gnc_ledger_display_query(Query *query, SplitRegisterType type, SplitRegisterStyle style)
display a general ledger for an arbitrary query
GtkWidget * gnc_ledger_display_get_parent(GNCLedgerDisplay *ld)
Returns the parent of a given ledger display.
void gnc_ledger_display_close(GNCLedgerDisplay *ld)
close the window
void gnc_ledger_display_set_query(GNCLedgerDisplay *ledger_display, Query *q)
Set the query used for a register.
Account * gnc_ledger_display_leader(GNCLedgerDisplay *ld)
Implementations.
void gnc_ledger_display_set_user_data(GNCLedgerDisplay *ld, gpointer user_data)
get and set the user data associated with the ledger
GNCLedgerDisplay * gnc_ledger_display_find_by_query(Query *q)
If the given ledger display still exists, return it.
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.
SplitRegister * gnc_ledger_display_get_split_register(GNCLedgerDisplay *ld)
return the split register associated with a ledger display
void gnc_ledger_display_set_focus(GNCLedgerDisplay *ld, gboolean focus)
Mark the ledger as being in focus (refresh immediately) or not.
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...
#define DEBUG(format, args...)
Print a debugging message.
#define LEAVE(format, args...)
Print a function exit debugging message.
#define PERR(format, args...)
Log a serious error.
#define PWARN(format, args...)
Log a warning.
#define ENTER(format, args...)
Print a function entry debugging message.
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Get an float value from the preferences backend.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
gboolean qof_query_equal(const QofQuery *q1, const QofQuery *q2)
Compare two queries for equality.
QofQuery * qof_query_copy(QofQuery *q)
Make a copy of the indicated query.
void qof_query_set_book(QofQuery *query, QofBook *book)
Set the book to be searched.
void qof_query_destroy(QofQuery *query)
Frees the resources associate with a Query object.
GList * qof_query_run(QofQuery *query)
Perform the query, return the results.
void qof_query_set_max_results(QofQuery *q, int n)
Set the maximum number of results that should be returned.
Account * gnc_book_get_template_root(const QofBook *book)
Returns the template group from the book.
SplitRegisterStyle
Register styles.
SplitRegisterType
Register types.
void gnc_split_register_load(SplitRegister *reg, GList *slist, GList *pre_filter_slist, Account *default_account)
Populates the rows of a register.
void gnc_split_register_set_template_account(SplitRegister *reg, Account *template_account)
Set the template account for use in a template register.
SplitRegister * gnc_split_register_new(SplitRegisterType type, SplitRegisterStyle style, gboolean use_double_line, gboolean is_template, gboolean mismatched_commodities)
Creates a new split register.
void gnc_split_register_destroy(SplitRegister *reg)
Destroys a split register.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
TableControl specialized for the SplitRegister.
TableModels specialized for SplitRegister and template SplitRegister.
The type used to store guids in C.
The GNCLedgerDisplay struct describes a single register/ledger instance.