diff options
author | John Wiegley <johnw@newartisans.com> | 2004-08-09 17:32:20 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2004-08-09 17:32:20 -0400 |
commit | 05b2cc46fdf6accd2ecbdc3c1ce86829bc7bfa68 (patch) | |
tree | ab61a5efdcdfe7bb73f346da5e45ac228d6458c0 | |
parent | 2dc822291f3ecef34eb0ef2920c395b0e056fbda (diff) | |
download | fork-ledger-05b2cc46fdf6accd2ecbdc3c1ce86829bc7bfa68.tar.gz fork-ledger-05b2cc46fdf6accd2ecbdc3c1ce86829bc7bfa68.tar.bz2 fork-ledger-05b2cc46fdf6accd2ecbdc3c1ce86829bc7bfa68.zip |
fixed account display bug
-rw-r--r-- | format.cc | 81 | ||||
-rw-r--r-- | format.h | 24 | ||||
-rw-r--r-- | ledger.h | 20 | ||||
-rw-r--r-- | main.cc | 33 | ||||
-rw-r--r-- | valexpr.cc | 34 | ||||
-rw-r--r-- | valexpr.h | 2 | ||||
-rw-r--r-- | walk.h | 36 |
7 files changed, 142 insertions, 88 deletions
@@ -397,44 +397,59 @@ void format_transaction::operator()(transaction_t * xact) const last_xact = xact; } - -void format_account::operator()(account_t * account, - const unsigned int max_depth, - const bool report_top) const +bool format_account::disp_subaccounts_p(const account_t * account, + const item_predicate<account_t>& + disp_pred_functor, + const account_t *& to_show) { - // Don't output the account if only one child will be displayed - // which shows the exact same amount. jww (2004-08-03): How do - // compute the right figure? It should a value expression specified - // by the user, to say, "If this expression is equivalent between a - // parent account and a lone displayed child, then don't display the - // parent." - - if (bool output = ((report_top || account->parent != NULL) && - disp_pred_functor(account))) { - int counted = 0; - bool display = false; - - for (accounts_map::const_iterator i = account->accounts.begin(); - i != account->accounts.end(); - i++) { - if (! (*i).second->total) - continue; - - if ((*i).second->total != account->total || counted > 0) { - display = true; - break; - } - counted++; - } + bool display = false; + unsigned int counted = 0; + + to_show = NULL; + + for (accounts_map::const_iterator i = account->accounts.begin(); + i != account->accounts.end(); + i++) { + // jww (2004-08-03): How do compute the right figure? It should a + // value expression specified by the user, to say, "If this + // expression is equivalent between a parent account and a lone + // displayed child, then don't display the parent." - if (counted == 1 && ! display) - output = false; + if (! (*i).second->total || ! disp_pred_functor((*i).second)) + continue; - if (output && (max_depth == 0 || account->depth <= max_depth)) { - format.format_elements(output_stream, details_t(account)); - account->dflags |= ACCOUNT_DISPLAYED; + if ((*i).second->total != account->total || counted > 0) { + display = true; + break; } + to_show = (*i).second; + counted++; } + + return display; +} + +bool format_account::display_account(const account_t * account, + const item_predicate<account_t>& + disp_pred_functor) +{ + // Never display the master account, or an account that has already + // been displayed. + if (! account->parent || account->dflags & ACCOUNT_DISPLAYED) + return false; + + // At this point, one of two possibilities exists: the account is a + // leaf which matches the predicate restrictions; or it is a parent + // and two or more children must be subtotaled; or it is a parent + // and its child has been hidden by the predicate. So first, + // determine if it is a parent that must be displayed regardless of + // the predicate. + + const account_t * account_to_show = NULL; + if (disp_subaccounts_p(account, disp_pred_functor, account_to_show)) + return true; + + return ! account_to_show && disp_pred_functor(account); } } // namespace ledger @@ -204,9 +204,20 @@ class format_account : output_stream(_output_stream), format(_format), disp_pred_functor(display_predicate) {} - void operator()(account_t * account, - const unsigned int max_depth = 1, - const bool report_top = false) const; + static bool disp_subaccounts_p(const account_t * account, + const item_predicate<account_t>& + disp_pred_functor, + const account_t *& to_show); + static bool display_account(const account_t * account, + const item_predicate<account_t>& + disp_pred_functor); + + void operator()(const account_t * account) const { + if (display_account(account, disp_pred_functor)) { + format.format_elements(output_stream, details_t(account)); + account->dflags |= ACCOUNT_DISPLAYED; + } + } }; @@ -241,11 +252,8 @@ class format_equity next_lines_format.format_elements(output_stream, details_t(&summary)); } - void operator()(account_t * account, - const unsigned int max_depth = 1, - const bool report_top = false) const { - if ((report_top || account->parent != NULL) && - disp_pred_functor(account)) { + void operator()(const account_t * account) const { + if (format_account::display_account(account, disp_pred_functor)) { next_lines_format.format_elements(output_stream, details_t(account)); account->dflags |= ACCOUNT_DISPLAYED; total += account->value.quantity; @@ -41,9 +41,10 @@ class transaction_t amount_t cost; unsigned int flags; std::string note; - balance_pair_t total; - unsigned int index; - unsigned int dflags; + + mutable balance_pair_t total; + mutable unsigned int index; + mutable unsigned int dflags; transaction_t(entry_t * _entry, account_t * _account) : entry(_entry), account(_account), flags(TRANSACTION_NORMAL), @@ -105,15 +106,16 @@ class account_t account_t * parent; std::string name; std::string note; - unsigned long depth; + unsigned int depth; accounts_map accounts; transactions_list transactions; - balance_pair_t value; - balance_pair_t total; - unsigned long ident; - unsigned long dflags; - mutable std::string _fullname; + mutable balance_pair_t value; + mutable balance_pair_t total; + mutable unsigned long ident; + mutable unsigned long dflags; + mutable std::string _fullname; + static unsigned long next_ident; account_t(account_t * _parent, @@ -570,10 +570,19 @@ int main(int argc, char * argv[]) } if (display_predicate_string.empty()) { - if (command == "b" && ! show_empty) - display_predicate_string = "T"; - else if (command == "E") + if (command == "b") { + if (! show_empty) + display_predicate_string = "T"; + + if (! show_expanded) { + if (! display_predicate_string.empty()) + display_predicate_string += "&"; + display_predicate_string += "!n"; + } + } + else if (command == "E") { display_predicate_string = "a"; + } } if (! display_predicate_string.empty()) { @@ -640,16 +649,12 @@ int main(int argc, char * argv[]) format_t format(first_line_format); format_account formatter(std::cout, format, display_predicate.get()); walk_accounts(journal->master, formatter, predicate.get(), - xact_display_flags, show_subtotals, show_expanded ? 0 : 1, - sort_order.get()); - - if (! display_predicate.get() || - item_predicate<account_t>(display_predicate.get())(journal->master)) { - std::string end_format = "--------------------\n"; - format.reset(end_format + f); - format_account(std::cout, format)(journal->master, true, - display_predicate.get()); - } + xact_display_flags, show_subtotals, sort_order.get()); + + std::string end_format = "--------------------\n"; + format.reset(end_format + f); + format_account(std::cout, format, + display_predicate.get())(journal->master); } else if (command == "E") { format_t format(first_line_format); @@ -657,7 +662,7 @@ int main(int argc, char * argv[]) format_equity formatter(std::cout, format, nformat, display_predicate.get()); walk_accounts(journal->master, formatter, predicate.get(), - xact_display_flags, true, 0, sort_order.get()); + xact_display_flags, true, sort_order.get()); } else if (command == "e") { format_t format(first_line_format); @@ -158,18 +158,46 @@ void node_t::compute(balance_t& result, const details_t& details) const break; case CLEARED: - if (details.entry) + if (details.entry) { result = details.entry->state == entry_t::CLEARED; + } + else if (details.account) { + bool all_clear = true; + for (transactions_list::const_iterator i + = details.account->transactions.begin(); + i != details.account->transactions.end(); + i++) + if ((*i)->entry->state != entry_t::CLEARED) { + all_clear = false; + break; + } + result = all_clear; + } break; case REAL: - if (details.xact) + if (details.xact) { result = ! (details.xact->flags & TRANSACTION_VIRTUAL); + } + else if (details.account) { + bool all_real = true; + for (transactions_list::const_iterator i + = details.account->transactions.begin(); + i != details.account->transactions.end(); + i++) + if ((*i)->flags & TRANSACTION_VIRTUAL) { + all_real = false; + break; + } + result = all_real; + } break; case INDEX: if (details.xact) result = details.xact->index + 1; + else if (details.account) + result = details.account->depth - 1; break; case F_ARITH_MEAN: @@ -359,7 +387,7 @@ node_t * parse_term(std::istream& in) case 'd': node = new node_t(node_t::DATE); break; case 'X': node = new node_t(node_t::CLEARED); break; case 'R': node = new node_t(node_t::REAL); break; - case 'i': node = new node_t(node_t::INDEX); break; + case 'n': node = new node_t(node_t::INDEX); break; case 'B': node = new node_t(node_t::BALANCE); break; case 'T': node = new node_t(node_t::TOTAL); break; case 'C': node = new node_t(node_t::COST_TOTAL); break; @@ -57,7 +57,7 @@ struct node_t DATE, CLEARED, REAL, - INDEX, + INDEX, // for accounts, this is the DEPTH // Item totals BALANCE, @@ -154,25 +154,22 @@ inline void sort_accounts(account_t * account, } template <typename Function> -void walk__accounts(account_t * account, - const Function& functor, - const unsigned int max_depth) +void walk__accounts(account_t * account, const Function& functor) { - functor(account, max_depth); + functor(account); for (accounts_map::const_iterator i = account->accounts.begin(); i != account->accounts.end(); i++) - walk__accounts((*i).second, functor, max_depth); + walk__accounts((*i).second, functor); } template <typename Function> -void walk__accounts_sorted(account_t * account, - const Function& functor, - const unsigned int max_depth, - const node_t * sort_order) +void walk__accounts_sorted(account_t * account, + const Function& functor, + const node_t * sort_order) { - functor(account, max_depth); + functor(account); accounts_deque accounts; @@ -187,7 +184,7 @@ void walk__accounts_sorted(account_t * account, for (accounts_deque::const_iterator i = accounts.begin(); i != accounts.end(); i++) - walk__accounts_sorted(*i, functor, max_depth, sort_order); + walk__accounts_sorted(*i, functor, sort_order); } template <typename Function> @@ -217,13 +214,12 @@ inline void sum__accounts(account_t * account) } template <typename Function> -void walk_accounts(account_t * account, - const Function& functor, - const node_t * predicate, - unsigned int flags, - const bool calc_subtotals, - const unsigned int max_depth, - const node_t * sort_order = NULL) +void walk_accounts(account_t * account, + const Function& functor, + const node_t * predicate, + unsigned int flags, + const bool calc_subtotals, + const node_t * sort_order = NULL) { item_predicate<transaction_t> pred_functor(predicate); @@ -232,9 +228,9 @@ void walk_accounts(account_t * account, sum__accounts(account); if (sort_order) - walk__accounts_sorted<Function>(account, functor, max_depth, sort_order); + walk__accounts_sorted<Function>(account, functor, sort_order); else - walk__accounts<Function>(account, functor, max_depth); + walk__accounts<Function>(account, functor); } } // namespace ledger |