lmi-commits
[Top][All Lists]
Advanced

[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();



reply via email to

[Prev in Thread] Current Thread [Next in Thread]