Item sorting should have access to the report scope

This commit is contained in:
John Wiegley 2017-01-04 12:02:15 -08:00
parent 0e1c6115b3
commit f27d7776ca
No known key found for this signature in database
GPG key ID: C144D8F4F19FE630
9 changed files with 69 additions and 37 deletions

View file

@ -186,9 +186,9 @@ post_handler_ptr chain_post_handlers(post_handler_ptr base_handler,
// value expression.
if (report.HANDLED(sort_)) {
if (report.HANDLED(sort_xacts_))
handler.reset(new sort_xacts(handler, report.HANDLER(sort_).str()));
handler.reset(new sort_xacts(handler, expr_t(report.HANDLER(sort_).str()), report));
else
handler.reset(new sort_posts(handler, report.HANDLER(sort_).str()));
handler.reset(new sort_posts(handler, report.HANDLER(sort_).str(), report));
}
// collapse_posts causes xacts with multiple posts to appear as xacts

View file

@ -33,8 +33,10 @@
#include "compare.h"
#include "op.h"
#include "scope.h"
#include "post.h"
#include "account.h"
#include "report.h"
namespace ledger {
@ -64,6 +66,20 @@ void push_sort_value(std::list<sort_value_t>& sort_values,
}
}
template <>
void compare_items<post_t>::find_sort_values(
std::list<sort_value_t>& sort_values, scope_t& scope) {
bind_scope_t bound_scope(report, scope);
push_sort_value(sort_values, sort_order.get_op(), bound_scope);
}
template <>
void compare_items<account_t>::find_sort_values(
std::list<sort_value_t>& sort_values, scope_t& scope) {
bind_scope_t bound_scope(report, scope);
push_sort_value(sort_values, sort_order.get_op(), bound_scope);
}
template <>
bool compare_items<post_t>::operator()(post_t * left, post_t * right)
{

View file

@ -48,6 +48,7 @@ namespace ledger {
class post_t;
class account_t;
class report_t;
void push_sort_value(std::list<sort_value_t>& sort_values,
expr_t::ptr_op_t node, scope_t& scope);
@ -56,23 +57,24 @@ template <typename T>
class compare_items
{
expr_t sort_order;
report_t& report;
compare_items();
public:
compare_items(const compare_items& other) : sort_order(other.sort_order) {
TRACE_CTOR(compare_items, "copy");
compare_items(const expr_t& _sort_order, report_t& _report) :
sort_order(_sort_order), report(_report) {
TRACE_CTOR(compare_items, "const value_expr&, report_t&");
}
compare_items(const expr_t& _sort_order) : sort_order(_sort_order) {
TRACE_CTOR(compare_items, "const value_expr&");
compare_items(const compare_items& other) :
sort_order(other.sort_order), report(other.report) {
TRACE_CTOR(compare_items, "copy");
}
~compare_items() throw() {
TRACE_DTOR(compare_items);
}
void find_sort_values(std::list<sort_value_t>& sort_values, scope_t& scope) {
push_sort_value(sort_values, sort_order.get_op(), scope);
}
void find_sort_values(std::list<sort_value_t>& sort_values, scope_t& scope);
bool operator()(T * left, T * right);
};

View file

@ -154,7 +154,7 @@ void truncate_xacts::operator()(post_t& post)
void sort_posts::post_accumulated_posts()
{
std::stable_sort(posts.begin(), posts.end(),
compare_items<post_t>(sort_order));
compare_items<post_t>(sort_order, report));
foreach (post_t * post, posts) {
post->xdata().drop_flags(POST_EXT_SORT_CALC);

View file

@ -237,17 +237,20 @@ class sort_posts : public item_handler<post_t>
posts_deque posts;
expr_t sort_order;
report_t& report;
sort_posts();
public:
sort_posts(post_handler_ptr handler, const expr_t& _sort_order)
: item_handler<post_t>(handler), sort_order(_sort_order) {
TRACE_CTOR(sort_posts, "post_handler_ptr, const value_expr&");
sort_posts(post_handler_ptr handler, const expr_t& _sort_order,
report_t& _report)
: item_handler<post_t>(handler), sort_order(_sort_order), report(_report) {
TRACE_CTOR(sort_posts, "post_handler_ptr, const value_expr&, report_t&");
}
sort_posts(post_handler_ptr handler, const string& _sort_order)
: item_handler<post_t>(handler), sort_order(_sort_order) {
TRACE_CTOR(sort_posts, "post_handler_ptr, const string&");
sort_posts(post_handler_ptr handler, const string& _sort_order,
report_t& _report)
: item_handler<post_t>(handler), sort_order(_sort_order), report(_report) {
TRACE_CTOR(sort_posts, "post_handler_ptr, const string&, report_t&");
}
virtual ~sort_posts() {
TRACE_DTOR(sort_posts);
@ -280,15 +283,17 @@ class sort_xacts : public item_handler<post_t>
sort_xacts();
public:
sort_xacts(post_handler_ptr handler, const expr_t& _sort_order)
: sorter(handler, _sort_order) {
sort_xacts(post_handler_ptr handler, const expr_t& _sort_order,
report_t& _report)
: sorter(handler, _sort_order, _report) {
TRACE_CTOR(sort_xacts,
"post_handler_ptr, const value_expr&");
"post_handler_ptr, const value_expr&, report_t&");
}
sort_xacts(post_handler_ptr handler, const string& _sort_order)
: sorter(handler, _sort_order) {
sort_xacts(post_handler_ptr handler, const string& _sort_order,
report_t& _report)
: sorter(handler, _sort_order, _report) {
TRACE_CTOR(sort_xacts,
"post_handler_ptr, const string&");
"post_handler_ptr, const string&, report_t&");
}
virtual ~sort_xacts() {
TRACE_DTOR(sort_xacts);

View file

@ -201,7 +201,7 @@ void sorted_accounts_iterator::push_back(account_t& account)
std::stable_sort(accounts_list.back().begin(),
accounts_list.back().end(),
compare_items<account_t>(sort_cmp));
compare_items<account_t>(sort_cmp, report));
#if DEBUG_ON
if (SHOW_DEBUG("account.sorted")) {
@ -234,7 +234,7 @@ void sorted_accounts_iterator::sort_accounts(account_t& account,
deque.push_back(pair.second);
std::stable_sort(deque.begin(), deque.end(),
compare_items<account_t>(sort_cmp));
compare_items<account_t>(sort_cmp, report));
#if DEBUG_ON
if (SHOW_DEBUG("account.sorted")) {

View file

@ -50,6 +50,7 @@
namespace ledger {
class journal_t;
class report_t;
template <typename Derived, typename Value, typename CategoryOrTraversal>
class iterator_facade_base
@ -279,8 +280,9 @@ class sorted_accounts_iterator
: public iterator_facade_base<sorted_accounts_iterator, account_t *,
boost::forward_traversal_tag>
{
expr_t sort_cmp;
bool flatten_all;
expr_t sort_cmp;
report_t& report;
bool flatten_all;
typedef std::deque<account_t *> accounts_deque_t;
@ -290,16 +292,21 @@ class sorted_accounts_iterator
public:
sorted_accounts_iterator(account_t& account,
const expr_t& _sort_cmp, bool _flatten_all)
: sort_cmp(_sort_cmp), flatten_all(_flatten_all) {
const expr_t& _sort_cmp,
report_t& _report,
bool _flatten_all)
: sort_cmp(_sort_cmp), report(_report),
flatten_all(_flatten_all) {
push_back(account);
increment();
TRACE_CTOR(sorted_accounts_iterator, "account_t&, expr_t, bool");
TRACE_CTOR(sorted_accounts_iterator,
"account_t&, expr_t, report_t&, bool");
}
sorted_accounts_iterator(const sorted_accounts_iterator& i)
: iterator_facade_base<sorted_accounts_iterator, account_t *,
boost::forward_traversal_tag>(i),
sort_cmp(i.sort_cmp), flatten_all(i.flatten_all),
sort_cmp(i.sort_cmp), report(i.report),
flatten_all(i.flatten_all),
accounts_list(i.accounts_list),
sorted_accounts_i(i.sorted_accounts_i),
sorted_accounts_end(i.sorted_accounts_end) {

View file

@ -431,8 +431,9 @@ namespace {
} else {
expr_t sort_expr(report.HANDLER(sort_).str());
sort_expr.set_context(&report);
sorted_accounts_iterator iter(*report.session.journal->master,
sort_expr, report.HANDLED(flat));
sorted_accounts_iterator iter(
*report.session.journal->master, sort_expr, report,
report.HANDLED(flat));
pass_down_accounts<sorted_accounts_iterator>
(handler, iter, predicate_t(report.HANDLER(display_).str(),
report.what_to_keep()), report);
@ -444,8 +445,9 @@ namespace {
} else {
expr_t sort_expr(report.HANDLER(sort_).str());
sort_expr.set_context(&report);
sorted_accounts_iterator iter(*report.session.journal->master,
sort_expr, report.HANDLED(flat));
sorted_accounts_iterator iter(
*report.session.journal->master, sort_expr, report,
report.HANDLED(flat));
pass_down_accounts<sorted_accounts_iterator>(handler, iter);
}
}

View file

@ -284,7 +284,7 @@ value_t session_t::fn_str(call_scope_t& args)
value_t session_t::fn_lot_price(call_scope_t& args)
{
amount_t amt(args.get<amount_t>(1, false));
amount_t amt(args.get<amount_t>(0, false));
if (amt.has_annotation() && amt.annotation().price)
return *amt.annotation().price;
else
@ -292,7 +292,7 @@ value_t session_t::fn_lot_price(call_scope_t& args)
}
value_t session_t::fn_lot_date(call_scope_t& args)
{
amount_t amt(args.get<amount_t>(1, false));
amount_t amt(args.get<amount_t>(0, false));
if (amt.has_annotation() && amt.annotation().date)
return *amt.annotation().date;
else
@ -300,7 +300,7 @@ value_t session_t::fn_lot_date(call_scope_t& args)
}
value_t session_t::fn_lot_tag(call_scope_t& args)
{
amount_t amt(args.get<amount_t>(1, false));
amount_t amt(args.get<amount_t>(0, false));
if (amt.has_annotation() && amt.annotation().tag)
return string_value(*amt.annotation().tag);
else