summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--format.cc42
-rw-r--r--format.h19
-rw-r--r--main.cc11
-rwxr-xr-xmain.py45
-rw-r--r--walk.cc9
-rw-r--r--walk.h11
6 files changed, 112 insertions, 25 deletions
diff --git a/format.cc b/format.cc
index c41057fb..e83d7e7b 100644
--- a/format.cc
+++ b/format.cc
@@ -332,11 +332,14 @@ void format_t::format(std::ostream& out, const details_t& details) const
= details.entry->transactions.begin();
i != details.entry->transactions.end();
i++) {
- xacts_count++;
-
- if (! first)
- first = *i;
- last = *i;
+ if (transaction_has_xdata(**i) &&
+ transaction_xdata(**i).dflags & TRANSACTION_TO_DISPLAY) {
+ xacts_count++;
+
+ if (! first)
+ first = *i;
+ last = *i;
+ }
}
use_disp = (xacts_count == 2 && details.xact == last &&
@@ -406,6 +409,35 @@ void format_transactions::operator()(transaction_t& xact)
}
}
+void format_entries::format_last_entry()
+{
+ bool first = true;
+ for (transactions_list::const_iterator i = last_entry->transactions.begin();
+ i != last_entry->transactions.end();
+ i++) {
+ if (transaction_has_xdata(**i) &&
+ transaction_xdata(**i).dflags & TRANSACTION_TO_DISPLAY) {
+ if (first) {
+ first_line_format.format(output_stream, details_t(**i));
+ first = false;
+ } else {
+ next_lines_format.format(output_stream, details_t(**i));
+ }
+ transaction_xdata(**i).dflags |= TRANSACTION_DISPLAYED;
+ }
+ }
+}
+
+void format_entries::operator()(transaction_t& xact)
+{
+ if (last_entry && xact.entry != last_entry)
+ format_last_entry();
+
+ transaction_xdata(xact).dflags |= TRANSACTION_TO_DISPLAY;
+
+ last_entry = xact.entry;
+}
+
bool disp_subaccounts_p(const account_t& account,
const item_predicate<account_t>& disp_pred,
const account_t *& to_show)
diff --git a/format.h b/format.h
index 8b3f760f..f3bf671c 100644
--- a/format.h
+++ b/format.h
@@ -90,6 +90,7 @@ struct format_t
class format_transactions : public item_handler<transaction_t>
{
+ protected:
std::ostream& output_stream;
format_t first_line_format;
format_t next_lines_format;
@@ -102,7 +103,23 @@ class format_transactions : public item_handler<transaction_t>
virtual void flush() {
output_stream.flush();
}
+ virtual void operator()(transaction_t& xact);
+};
+
+class format_entries : public format_transactions
+{
+ public:
+ format_entries(std::ostream& output_stream, const std::string& format)
+ : format_transactions(output_stream, format) {}
+ void format_last_entry();
+
+ virtual void flush() {
+ format_last_entry();
+ last_entry = NULL;
+
+ format_transactions::flush();
+ }
virtual void operator()(transaction_t& xact);
};
@@ -113,7 +130,7 @@ bool disp_subaccounts_p(const account_t& account,
inline bool disp_subaccounts_p(const account_t& account) {
const account_t * temp;
return disp_subaccounts_p(account, item_predicate<account_t>(NULL), temp);
- }
+}
bool display_account(const account_t& account,
const item_predicate<account_t>& disp_pred);
diff --git a/main.cc b/main.cc
index 8e827212..f1dbeff4 100644
--- a/main.cc
+++ b/main.cc
@@ -248,13 +248,14 @@ int parse_and_report(int argc, char * argv[], char * envp[])
item_handler<transaction_t> * formatter;
std::list<item_handler<transaction_t> *> formatter_ptrs;
- if (command == "b" || command == "E") {
+ if (command == "b" || command == "E")
formatter = new set_account_value;
- formatter = chain_formatters(command, formatter, formatter_ptrs);
- } else {
+ else if (command == "p")
+ formatter = new format_entries(*out, *format);
+ else
formatter = new format_transactions(*out, *format);
- formatter = chain_formatters(command, formatter, formatter_ptrs);
- }
+
+ formatter = chain_formatters(command, formatter, formatter_ptrs);
if (command == "e")
walk_transactions(new_entry->transactions, *formatter);
diff --git a/main.py b/main.py
index 1f7157a8..2f6690d5 100755
--- a/main.py
+++ b/main.py
@@ -18,6 +18,8 @@ import os
import sys
import string
+true, false = 1, 0
+
from ledger import *
# Create the main journal object, into which all entries will be
@@ -141,7 +143,7 @@ else:
# these, but they rely on I/O streams, which Boost.Python does not
# provide a conversion layer for.
-class FormatTransaction (TransactionHandler):
+class FormatTransactions (TransactionHandler):
last_entry = None
output = None
@@ -176,10 +178,41 @@ class FormatTransaction (TransactionHandler):
if self.nformatter is not None and \
self.last_entry is not None and \
xact.entry == self.last_entry:
- self.output.write(self.nformatter.format(xact))
+ self.output.write (self.nformatter.format (xact))
else:
- self.output.write(self.formatter.format(xact))
+ self.output.write (self.formatter.format (xact))
self.last_entry = xact.entry
+ transaction_xdata (xact).dflags |= TRANSACTION_DISPLAYED
+
+class FormatEntries (FormatTransactions):
+ def __init__ (self, fmt):
+ self.last_entry = None
+ FormatTransactions.__init__(self, fmt)
+
+ def flush (self):
+ self.format_last_entry ()
+ self.last_entry = None
+ FormatTransactions.flush (self)
+
+ def format_last_entry (self):
+ first = true
+ for x in self.last_entry:
+ if transaction_has_xdata (x) and \
+ transaction_xdata (x).dflags & TRANSACTION_TO_DISPLAY:
+ if first or self.nformatter is None:
+ self.output.write (self.formatter.format (x))
+ first = false
+ else:
+ self.output.write (self.nformatter.format (x))
+ transaction_xdata (x).dflags |= TRANSACTION_TO_DISPLAY
+
+ def __call__ (self, xact):
+ if self.last_entry and self.last_entry != xact.entry:
+ self.format_last_entry ()
+
+ transaction_xdata (xact).dflags |= TRANSACTION_TO_DISPLAY
+
+ self.last_entry = xact.entry;
class FormatAccount (AccountHandler):
output = None
@@ -218,8 +251,10 @@ class FormatAccount (AccountHandler):
if command == "b" or command == "E":
handler = SetAccountValue()
+elif command == "p":
+ handler = FormatEntries(format)
else:
- handler = FormatTransaction(format)
+ handler = FormatTransactions(format)
# Chain transaction filters on top of the base handler. Most of these
# filters customize the output for reporting. None of this is done
@@ -286,7 +321,7 @@ handler.flush ()
# the transactions that were just walked.
if command == "b":
- acct_formatter = FormatAccount (format, config.display_predicate)
+ acct_formatter = FormatAccounts (format, config.display_predicate)
sum_accounts (journal.master)
walk_accounts (journal.master, acct_formatter, config.sort_string)
acct_formatter.flush ()
diff --git a/walk.cc b/walk.cc
index 6786eae4..8b528141 100644
--- a/walk.cc
+++ b/walk.cc
@@ -456,9 +456,10 @@ void export_walk()
{
typedef item_handler<transaction_t> xact_handler_t;
- scope().attr("TRANSACTION_HANDLED") = TRANSACTION_HANDLED;
- scope().attr("TRANSACTION_DISPLAYED") = TRANSACTION_DISPLAYED;
- scope().attr("TRANSACTION_NO_TOTAL") = TRANSACTION_NO_TOTAL;
+ scope().attr("TRANSACTION_HANDLED") = TRANSACTION_HANDLED;
+ scope().attr("TRANSACTION_TO_DISPLAY") = TRANSACTION_TO_DISPLAY;
+ scope().attr("TRANSACTION_DISPLAYED") = TRANSACTION_DISPLAYED;
+ scope().attr("TRANSACTION_NO_TOTAL") = TRANSACTION_NO_TOTAL;
class_< transaction_xdata_t > ("TransactionXData")
.def_readwrite("total", &transaction_xdata_t::total)
@@ -565,8 +566,8 @@ void export_walk()
typedef item_handler<account_t> account_handler_t;
- scope().attr("ACCOUNT_DISPLAYED") = ACCOUNT_DISPLAYED;
scope().attr("ACCOUNT_TO_DISPLAY") = ACCOUNT_TO_DISPLAY;
+ scope().attr("ACCOUNT_DISPLAYED") = ACCOUNT_DISPLAYED;
class_< account_xdata_t > ("AccountXData")
.def_readwrite("value", &account_xdata_t::value)
diff --git a/walk.h b/walk.h
index 40d2b66b..0c343fd3 100644
--- a/walk.h
+++ b/walk.h
@@ -65,9 +65,10 @@ class compare_items {
// Transaction handlers
//
-#define TRANSACTION_HANDLED 0x0001
-#define TRANSACTION_DISPLAYED 0x0002
-#define TRANSACTION_NO_TOTAL 0x0004
+#define TRANSACTION_HANDLED 0x0001
+#define TRANSACTION_TO_DISPLAY 0x0002
+#define TRANSACTION_DISPLAYED 0x0004
+#define TRANSACTION_NO_TOTAL 0x0008
struct transaction_xdata_t
{
@@ -404,8 +405,8 @@ class related_transactions : public item_handler<transaction_t>
// Account walking functions
//
-#define ACCOUNT_DISPLAYED 0x1
-#define ACCOUNT_TO_DISPLAY 0x2
+#define ACCOUNT_TO_DISPLAY 0x1
+#define ACCOUNT_DISPLAYED 0x2
struct account_xdata_t
{