[glom] Print Layout: Move items to next page when expanding portals.



commit 8ee56b20bc84bf89f5882797274a5bc0721fe0ba
Author: Murray Cumming <murrayc murrayc com>
Date:   Wed Oct 12 23:17:27 2011 +0200

    Print Layout: Move items to next page when expanding portals.
    
    * glom/print_layout/canvas_print_layout.[h|cc]: move_items_below_item():
    Use a new move_fully_to_page() method to make sure that items are never
    in the margins if that is possible, when expanding related records
    portals for real data.
    Also add extra pages when necessary.

 ChangeLog                                |   10 +++
 glom/print_layout/canvas_print_layout.cc |  105 +++++++++++++++++++++++++++++-
 glom/print_layout/canvas_print_layout.h  |   15 ++++
 3 files changed, 129 insertions(+), 1 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 98880db..d6ad645 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2011-10-12  Murray Cumming  <murrayc murrayc com>
 
+	Print Layout: Move items to next page when expanding portals.
+
+	* glom/print_layout/canvas_print_layout.[h|cc]: move_items_below_item():
+	Use a new move_fully_to_page() method to make sure that items are never 
+	in the margins if that is possible, when expanding related records 
+	portals for real data.
+	Also add extra pages when necessary.
+
+2011-10-12  Murray Cumming  <murrayc murrayc com>
+
 	Print Layout: Related Records: Move others down when expanding.
 
 	* glom/print_layout/canvas_layout_item.[h|cc]: Added 
diff --git a/glom/print_layout/canvas_print_layout.cc b/glom/print_layout/canvas_print_layout.cc
index b448d31..28979e4 100644
--- a/glom/print_layout/canvas_print_layout.cc
+++ b/glom/print_layout/canvas_print_layout.cc
@@ -682,6 +682,11 @@ Glib::RefPtr<Gtk::PageSetup> Canvas_PrintLayout::get_page_setup()
   return m_page_setup;
 }
 
+Glib::RefPtr<const Gtk::PageSetup> Canvas_PrintLayout::get_page_setup() const
+{
+  return m_page_setup;
+}
+
 void Canvas_PrintLayout::set_page_count(guint count)
 {
   if(count < 1)
@@ -1195,6 +1200,8 @@ void Canvas_PrintLayout::move_items_below_item(const Glib::RefPtr<CanvasLayoutIt
   double item_height = 0;
   canvas_item->get_width_height(item_width, item_height);
 
+  double bottom_max = 0;
+
   const int count = root->get_n_children();
   for(int i = 0; i < count; ++i)
   {
@@ -1211,7 +1218,7 @@ void Canvas_PrintLayout::move_items_below_item(const Glib::RefPtr<CanvasLayoutIt
     if(y < y_start)
       continue;
 
-    //Ignore items that would not overlap even if the had the same y:
+    //Ignore items that would not overlap even if they had the same y:
     double width = 0;
     double height = 0;
     derived->get_width_height(width, height);
@@ -1221,10 +1228,106 @@ void Canvas_PrintLayout::move_items_below_item(const Glib::RefPtr<CanvasLayoutIt
     if( x > (item_x + item_width))
       continue;
 
+    //Move it down:
     y += offset;
     derived->set_xy(x, y);
+
+    //Move it some more if necessary:
+    y = move_fully_to_page(derived);
+
+    //Check where the bottom is:
+    const double bottom = y + height;
+    bottom_max = std::max(bottom_max, bottom);
   }
+
+  //Add extra pages if necessary:
+  const guint page_count_needed = get_page_for_y(bottom_max);
+  if(page_count_needed > get_page_count())
+  {
+    set_page_count(page_count_needed);
+  }
+}
+
+guint Canvas_PrintLayout::get_page_for_y(double y) const
+{
+  const double page_height = get_page_height();
+  if(!page_height)
+    return 0; //Avoid a division by zero.
+     
+  const double pages = y / (double)page_height;
+  std::cout << "pages = " << pages << ", for y=" << y << ", page_height=" << page_height << std::endl;
+  
+  double pages_integral = 0;
+  const double pages_fractional = modf(pages, &pages_integral);
+  std::cout << "pages_integral =" <<  pages_integral << std::endl;
+  
+  const guint pages_full = (guint)pages_integral + (pages_fractional ? 1 : 0);
+ std::cout << "pages_full =" <<  pages_full << std::endl;
+  
+  return pages_full;
 }
 
+double Canvas_PrintLayout::move_fully_to_page(const Glib::RefPtr<CanvasLayoutItem>& item)
+{
+  double top_margin = 0;
+  double bottom_margin = 0;
+  const double page_height = get_page_height(top_margin, bottom_margin);
+
+  double x = 0;
+  double y = 0;
+  item->get_xy(x, y);
+
+  //Ignore items that would not overlap even if they had the same y:
+  double width = 0;
+  double height = 0;
+  item->get_width_height(width, height);
+
+  const double usable_page_height = page_height - top_margin - bottom_margin;
+  if(height > usable_page_height)
+    return y; //It will always be in a margin because it is so big. We could never move it somewhere where it would not be.
+
+  bool moved = false;
+  const guint current_page = get_page_for_y(y);
+  const double usable_page_start = current_page * page_height + top_margin;
+  if(y < usable_page_start) //If it is in the top margin:
+  {
+    //Move it to the end of the top margin:
+    y = usable_page_start;
+    moved = true;
+  }
+
+  const double usable_page_end = (current_page + 1) * page_height - bottom_margin;
+  if((y + height) > usable_page_end) //If it is in the top margin:
+  {
+    //Move it to the start of the next page:
+    y = (current_page + 1) * page_height + top_margin;
+    moved = false;
+  }
+
+  item->set_xy(x, y);
+  return y;
+}
+
+double Canvas_PrintLayout::get_page_height() const
+{
+  double margin_top = 0;
+  double margin_bottom = 0;
+  return get_page_height(margin_top, margin_bottom);
+}
+
+double Canvas_PrintLayout::get_page_height(double& margin_top, double& margin_bottom) const
+{
+  const Glib::RefPtr<const Gtk::PageSetup> page_setup = get_page_setup();
+  const Gtk::PaperSize paper_size = page_setup->get_paper_size();
+  const Gtk::Unit units = property_units();
+  
+  double page_height = 0;
+  if(page_setup->get_orientation() == Gtk::PAGE_ORIENTATION_PORTRAIT) //TODO: Handle the reverse orientations too?
+    page_height = paper_size.get_height(units);
+  else
+    page_height = paper_size.get_width(units);
+
+  return page_height;
+}
 
 } //namespace Glom
diff --git a/glom/print_layout/canvas_print_layout.h b/glom/print_layout/canvas_print_layout.h
index 3bdd7f5..0525aa2 100644
--- a/glom/print_layout/canvas_print_layout.h
+++ b/glom/print_layout/canvas_print_layout.h
@@ -50,6 +50,7 @@ public:
 
   void set_page_setup(const Glib::RefPtr<Gtk::PageSetup>& page_setup);
   Glib::RefPtr<Gtk::PageSetup> get_page_setup();
+  Glib::RefPtr<const Gtk::PageSetup> get_page_setup() const;
   
   void set_page_count(guint count);
   guint get_page_count() const;
@@ -131,6 +132,20 @@ private:
   
   Glib::RefPtr<Goocanvas::Polyline> create_margin_line(double x1, double y1, double x2, double y2);
 
+  /** Discover what page the y position is on:
+   */
+  guint get_page_for_y(double y) const;
+
+  double get_page_height() const;
+  double get_page_height(double& margin_top, double& margin_bottom) const;
+
+  /** Move the item to the start of a page, past the top margin,
+   * if it is currently in the bottom margin of a page, or in the top margin of a page.
+   *
+   * @result The new y position of the item.
+   */
+  double move_fully_to_page(const Glib::RefPtr<CanvasLayoutItem>& item);
+
   Glib::ustring m_table_name;
   bool m_modified; //TODO: Actually check this?
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]