summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chain.cc3
-rw-r--r--src/filters.cc14
-rw-r--r--src/filters.h12
-rw-r--r--src/report.cc1
-rw-r--r--src/report.h4
5 files changed, 28 insertions, 6 deletions
diff --git a/src/chain.cc b/src/chain.cc
index ed800c47..2578387e 100644
--- a/src/chain.cc
+++ b/src/chain.cc
@@ -92,7 +92,8 @@ xact_handler_ptr chain_xact_handlers(report_t& report,
// collapse_xacts causes entries with multiple xacts to appear as entries
// with a subtotaled xact for each commodity used.
if (report.HANDLED(collapse))
- handler.reset(new collapse_xacts(handler, expr));
+ handler.reset(new collapse_xacts(handler, expr,
+ report.HANDLED(collapse_if_zero)));
// subtotal_xacts combines all the xacts it receives into one subtotal
// entry, which has one xact for each commodity in each account.
diff --git a/src/filters.cc b/src/filters.cc
index b33bd29b..8877812a 100644
--- a/src/filters.cc
+++ b/src/filters.cc
@@ -284,7 +284,16 @@ void collapse_xacts::report_subtotal()
if (count == 1) {
item_handler<xact_t>::operator()(*last_xact);
- } else {
+ }
+ else if (only_collapse_if_zero && ! subtotal.is_zero()) {
+ foreach (xact_t * xact, component_xacts)
+ item_handler<xact_t>::operator()(*xact);
+ component_xacts.clear();
+ }
+ else {
+ if (only_collapse_if_zero)
+ component_xacts.clear();
+
entry_temps.push_back(entry_t());
entry_t& entry = entry_temps.back();
entry.payee = last_entry->payee;
@@ -311,6 +320,9 @@ void collapse_xacts::operator()(xact_t& xact)
xact.add_to_value(subtotal, amount_expr);
count++;
+ if (only_collapse_if_zero)
+ component_xacts.push_back(&xact);
+
last_entry = xact.entry;
last_xact = &xact;
}
diff --git a/src/filters.h b/src/filters.h
index 6d8a2758..e4378b5f 100644
--- a/src/filters.h
+++ b/src/filters.h
@@ -381,17 +381,21 @@ class collapse_xacts : public item_handler<xact_t>
entry_t * last_entry;
xact_t * last_xact;
account_t totals_account;
+ bool only_collapse_if_zero;
- std::list<entry_t> entry_temps;
- std::list<xact_t> xact_temps;
+ std::list<entry_t> entry_temps;
+ std::list<xact_t> xact_temps;
+ std::list<xact_t *> component_xacts;
collapse_xacts();
public:
- collapse_xacts(xact_handler_ptr handler, expr_t& _amount_expr)
+ collapse_xacts(xact_handler_ptr handler, expr_t& _amount_expr,
+ bool _only_collapse_if_zero = false)
: item_handler<xact_t>(handler), amount_expr(_amount_expr),
count(0), last_entry(NULL), last_xact(NULL),
- totals_account(NULL, "<Total>") {
+ totals_account(NULL, "<Total>"),
+ only_collapse_if_zero(_only_collapse_if_zero) {
TRACE_CTOR(collapse_xacts, "xact_handler_ptr");
}
virtual ~collapse_xacts() {
diff --git a/src/report.cc b/src/report.cc
index 96304494..362fcfb1 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -388,6 +388,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
else OPT(cleared);
else OPT(code_as_payee);
else OPT(collapse);
+ else OPT(collapse_if_zero);
else OPT(comm_as_payee);
else OPT(cost);
else OPT_(current);
diff --git a/src/report.h b/src/report.h
index 5e198e22..b3a5c636 100644
--- a/src/report.h
+++ b/src/report.h
@@ -229,6 +229,10 @@ public:
parent->append_display_predicate("depth<=1");
});
+ OPTION_(report_t, collapse_if_zero, DO() {
+ parent->HANDLER(collapse).on();
+ });
+
OPTION(report_t, comm_as_payee); // -x
OPTION(report_t, cost);
OPTION(report_t, csv_format_);