[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] odd/pagination 91ddea1 3/3: Experiment with inversio
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] odd/pagination 91ddea1 3/3: Experiment with inversion of control |
Date: |
Wed, 12 Sep 2018 19:48:17 -0400 (EDT) |
branch: odd/pagination
commit 91ddea1fdac77571c0f4d4d940532ad15a0cd77f
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Experiment with inversion of control
---
ledger_pdf_generator_wx.cpp | 186 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 183 insertions(+), 3 deletions(-)
diff --git a/ledger_pdf_generator_wx.cpp b/ledger_pdf_generator_wx.cpp
index 2810f29..85ed1a4 100644
--- a/ledger_pdf_generator_wx.cpp
+++ b/ledger_pdf_generator_wx.cpp
@@ -1605,23 +1605,203 @@ class ill_reg_numeric_summary_attachment : public
ill_reg_numeric_summary_page
}
};
+class LMI_SO paginate
+{
+ public:
+ paginate() {}
+
+ int init(int total_rows, int rows_per_group, int max_lines_per_page);
+ void print();
+
+ private:
+ virtual void prelude () = 0;
+ virtual void open_page () = 0;
+ virtual void print_a_data_row () = 0;
+ virtual void print_a_separator() = 0;
+ virtual void close_page () = 0;
+ virtual void postlude () = 0;
+
+ int total_rows () const {return total_rows_ ;}
+ int rows_per_group () const {return rows_per_group_ ;}
+
+ int lines_on_full_page() const {return lines_on_full_page_;}
+ int lines_on_last_page() const {return lines_on_last_page_;}
+ int page_count () const {return page_count_ ;}
+
+ // init() arguments.
+ int total_rows_ {};
+ int rows_per_group_ {};
+
+ // init() results.
+ int lines_on_full_page_ {};
+ int lines_on_last_page_ {};
+ int page_count_ {};
+};
+
+int paginate::init(int total_rows, int rows_per_group, int max_lines_per_page)
+{
+ total_rows_ = total_rows ;
+ rows_per_group_ = rows_per_group ;
+
+ paginator p(total_rows, rows_per_group, max_lines_per_page);
+ lines_on_full_page_ = p.lines_on_full_page();
+ lines_on_last_page_ = p.lines_on_last_page();
+ page_count_ = p.page_count();
+
+ return page_count_;
+}
+
+void paginate::print()
+{
+ prelude();
+ int row = 0;
+ int line_count = 0;
+ for(int page = 0; page < page_count(); ++page)
+ {
+ int const max_lines =
+ ((page_count() - 1) == page)
+ ? lines_on_last_page()
+ : lines_on_full_page()
+ ;
+ open_page();
+ for(int line = 0; line < max_lines; ++line)
+ {
+ if(rows_per_group() != line % (1 + rows_per_group()))
+ {
+ print_a_data_row();
+ ++row;
+ }
+ else
+ {
+ print_a_separator();
+ }
+ ++line_count;
+ }
+ close_page();
+ }
+ postlude();
+ LMI_ASSERT(total_rows() == row);
+}
+
// Helper base class for pages showing a table displaying values for all
// contract years after some fixed content.
class page_with_tabular_report
:public numbered_page
,protected using_illustration_table
{
+ class pager : public paginate
+ {
+ public:
+ pager
+ (page_with_tabular_report& outer
+ ,Ledger const& ledger
+ ,pdf_writer_wx & writer
+ ,html_interpolator const& interpolate_html
+ ,wx_table_generator & table_gen
+ )
+ :outer_ {outer}
+ ,ledger_ {ledger}
+ ,writer_ {writer}
+ ,interpolate_html_ {interpolate_html}
+// ,table_gen_ {create_table_generator(ledger, writer)}
+ ,table_gen_ {table_gen}
+ ,pos_y_ {}
+ ,year_ {}
+ {}
+
+ private:
+ void prelude () override
+ {
+// Done in ctor-initializer instead.
+// table_gen_ = wx_table_generator
{outer_.create_table_generator(ledger_, writer_)};
+ }
+
+ void open_page () override
+ {
+ // "if": guesswork--next_page() seems to have been called already.
+ if(0 != year_) outer_.next_page(writer_);
+ outer_.numbered_page::render(ledger_, writer_, interpolate_html_);
+ pos_y_ = outer_.render_or_measure_fixed_page_part
+ (table_gen_
+ ,writer_
+ ,interpolate_html_
+ ,oe_render
+ );
+ }
+
+ void print_a_data_row () override
+ {
+ auto const v = outer_.visible_values(ledger_, interpolate_html_,
year_);
+ table_gen_.output_row(pos_y_, v);
+ ++year_;
+ }
+
+ void print_a_separator() override
+ {
+ pos_y_ += table_gen_.row_height();
+ }
+
+ void close_page () override
+ {
+// See open_page() above. This causes an assertion to fail:
+ // This function may only be called if we had reserved enough physical
+ // pages for these logical pages by overriding
get_extra_pages_needed().
+// LMI_ASSERT(0 < extra_pages_); <-- fails
+// Conjecture: once the last page has been printed, asking for
+// the "next" page fails because there is no next page.
+// outer_.next_page(writer_);
+ }
+
+ void postlude () override {}
+
+ page_with_tabular_report& outer_;
+ Ledger const& ledger_;
+ pdf_writer_wx & writer_;
+ html_interpolator const& interpolate_html_;
+ wx_table_generator & table_gen_;
+ int pos_y_;
+ int year_;
+ };
+
public:
void render
- (Ledger const& ledger
- ,pdf_writer_wx& writer
+ (Ledger const& ledger
+ ,pdf_writer_wx & writer
,html_interpolator const& interpolate_html
) override
{
- numbered_page::render(ledger, writer, interpolate_html);
+// Moving this line down, so that it follows the succeeding 'table_gen'
+// line and all the new code, seems perfectly okay.
+// numbered_page::render(ledger, writer, interpolate_html);
wx_table_generator table_gen{create_table_generator(ledger, writer)};
+ int const start_y = render_or_measure_fixed_page_part
+ (table_gen
+ ,writer
+ ,interpolate_html
+ ,oe_only_measure
+ );
+ int const max_lines_per_page = (get_footer_top() - start_y) /
table_gen.row_height();
+
+ pager p(*this, ledger, writer, interpolate_html, table_gen);
+ p.init
+ (ledger.GetMaxLength()
+ ,wx_table_generator::rows_per_group
+ ,max_lines_per_page
+ );
+ p.print();
+
+ // The original code is left in place below for reference;
+ // draw attention to the early exit that skips it:
+
+ // +---------+
+ // | return; |
+ // +---------+
+ return;
+
+ numbered_page::render(ledger, writer, interpolate_html);
+
// Just some cached values used inside the loop below.
auto const row_height = table_gen.row_height();
auto const page_bottom = get_footer_top();