added a custom transaction formatter, format_entries, used by "print"

This commit is contained in:
John Wiegley 2004-09-24 06:29:01 -04:00
parent 2f16a82132
commit d110df6741
6 changed files with 111 additions and 24 deletions

View file

@ -332,12 +332,15 @@ void format_t::format(std::ostream& out, const details_t& details) const
= details.entry->transactions.begin(); = details.entry->transactions.begin();
i != details.entry->transactions.end(); i != details.entry->transactions.end();
i++) { i++) {
if (transaction_has_xdata(**i) &&
transaction_xdata(**i).dflags & TRANSACTION_TO_DISPLAY) {
xacts_count++; xacts_count++;
if (! first) if (! first)
first = *i; first = *i;
last = *i; last = *i;
} }
}
use_disp = (xacts_count == 2 && details.xact == last && use_disp = (xacts_count == 2 && details.xact == last &&
first->amount == - last->amount); first->amount == - last->amount);
@ -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, bool disp_subaccounts_p(const account_t& account,
const item_predicate<account_t>& disp_pred, const item_predicate<account_t>& disp_pred,
const account_t *& to_show) const account_t *& to_show)

View file

@ -90,6 +90,7 @@ struct format_t
class format_transactions : public item_handler<transaction_t> class format_transactions : public item_handler<transaction_t>
{ {
protected:
std::ostream& output_stream; std::ostream& output_stream;
format_t first_line_format; format_t first_line_format;
format_t next_lines_format; format_t next_lines_format;
@ -102,7 +103,23 @@ class format_transactions : public item_handler<transaction_t>
virtual void flush() { virtual void flush() {
output_stream.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); 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) { inline bool disp_subaccounts_p(const account_t& account) {
const account_t * temp; const account_t * temp;
return disp_subaccounts_p(account, item_predicate<account_t>(NULL), temp); return disp_subaccounts_p(account, item_predicate<account_t>(NULL), temp);
} }
bool display_account(const account_t& account, bool display_account(const account_t& account,
const item_predicate<account_t>& disp_pred); const item_predicate<account_t>& disp_pred);

View file

@ -248,13 +248,14 @@ int parse_and_report(int argc, char * argv[], char * envp[])
item_handler<transaction_t> * formatter; item_handler<transaction_t> * formatter;
std::list<item_handler<transaction_t> *> formatter_ptrs; std::list<item_handler<transaction_t> *> formatter_ptrs;
if (command == "b" || command == "E") { if (command == "b" || command == "E")
formatter = new set_account_value; formatter = new set_account_value;
formatter = chain_formatters(command, formatter, formatter_ptrs); else if (command == "p")
} else { formatter = new format_entries(*out, *format);
else
formatter = new format_transactions(*out, *format); formatter = new format_transactions(*out, *format);
formatter = chain_formatters(command, formatter, formatter_ptrs); formatter = chain_formatters(command, formatter, formatter_ptrs);
}
if (command == "e") if (command == "e")
walk_transactions(new_entry->transactions, *formatter); walk_transactions(new_entry->transactions, *formatter);

45
main.py
View file

@ -18,6 +18,8 @@ import os
import sys import sys
import string import string
true, false = 1, 0
from ledger import * from ledger import *
# Create the main journal object, into which all entries will be # 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 # these, but they rely on I/O streams, which Boost.Python does not
# provide a conversion layer for. # provide a conversion layer for.
class FormatTransaction (TransactionHandler): class FormatTransactions (TransactionHandler):
last_entry = None last_entry = None
output = None output = None
@ -176,10 +178,41 @@ class FormatTransaction (TransactionHandler):
if self.nformatter is not None and \ if self.nformatter is not None and \
self.last_entry is not None and \ self.last_entry is not None and \
xact.entry == self.last_entry: xact.entry == self.last_entry:
self.output.write(self.nformatter.format(xact)) self.output.write (self.nformatter.format (xact))
else: else:
self.output.write(self.formatter.format(xact)) self.output.write (self.formatter.format (xact))
self.last_entry = xact.entry 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): class FormatAccount (AccountHandler):
output = None output = None
@ -218,8 +251,10 @@ class FormatAccount (AccountHandler):
if command == "b" or command == "E": if command == "b" or command == "E":
handler = SetAccountValue() handler = SetAccountValue()
elif command == "p":
handler = FormatEntries(format)
else: else:
handler = FormatTransaction(format) handler = FormatTransactions(format)
# Chain transaction filters on top of the base handler. Most of these # Chain transaction filters on top of the base handler. Most of these
# filters customize the output for reporting. None of this is done # filters customize the output for reporting. None of this is done
@ -286,7 +321,7 @@ handler.flush ()
# the transactions that were just walked. # the transactions that were just walked.
if command == "b": if command == "b":
acct_formatter = FormatAccount (format, config.display_predicate) acct_formatter = FormatAccounts (format, config.display_predicate)
sum_accounts (journal.master) sum_accounts (journal.master)
walk_accounts (journal.master, acct_formatter, config.sort_string) walk_accounts (journal.master, acct_formatter, config.sort_string)
acct_formatter.flush () acct_formatter.flush ()

View file

@ -457,6 +457,7 @@ void export_walk()
typedef item_handler<transaction_t> xact_handler_t; typedef item_handler<transaction_t> xact_handler_t;
scope().attr("TRANSACTION_HANDLED") = TRANSACTION_HANDLED; scope().attr("TRANSACTION_HANDLED") = TRANSACTION_HANDLED;
scope().attr("TRANSACTION_TO_DISPLAY") = TRANSACTION_TO_DISPLAY;
scope().attr("TRANSACTION_DISPLAYED") = TRANSACTION_DISPLAYED; scope().attr("TRANSACTION_DISPLAYED") = TRANSACTION_DISPLAYED;
scope().attr("TRANSACTION_NO_TOTAL") = TRANSACTION_NO_TOTAL; scope().attr("TRANSACTION_NO_TOTAL") = TRANSACTION_NO_TOTAL;
@ -565,8 +566,8 @@ void export_walk()
typedef item_handler<account_t> account_handler_t; 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_TO_DISPLAY") = ACCOUNT_TO_DISPLAY;
scope().attr("ACCOUNT_DISPLAYED") = ACCOUNT_DISPLAYED;
class_< account_xdata_t > ("AccountXData") class_< account_xdata_t > ("AccountXData")
.def_readwrite("value", &account_xdata_t::value) .def_readwrite("value", &account_xdata_t::value)

9
walk.h
View file

@ -66,8 +66,9 @@ class compare_items {
// //
#define TRANSACTION_HANDLED 0x0001 #define TRANSACTION_HANDLED 0x0001
#define TRANSACTION_DISPLAYED 0x0002 #define TRANSACTION_TO_DISPLAY 0x0002
#define TRANSACTION_NO_TOTAL 0x0004 #define TRANSACTION_DISPLAYED 0x0004
#define TRANSACTION_NO_TOTAL 0x0008
struct transaction_xdata_t struct transaction_xdata_t
{ {
@ -404,8 +405,8 @@ class related_transactions : public item_handler<transaction_t>
// Account walking functions // Account walking functions
// //
#define ACCOUNT_DISPLAYED 0x1 #define ACCOUNT_TO_DISPLAY 0x1
#define ACCOUNT_TO_DISPLAY 0x2 #define ACCOUNT_DISPLAYED 0x2
struct account_xdata_t struct account_xdata_t
{ {