[glom] Move do_print_layout() to PrintLayoutUtils.



commit ae8dd3d6338cb65f79e12aacfb37d460d4ab2820
Author: Murray Cumming <murrayc murrayc com>
Date:   Tue Oct 4 11:50:25 2011 +0200

    Move do_print_layout() to PrintLayoutUtils.
    
    * glom/application.[h|cc]: Remove the new print_layout(PrintLayout) override.
    * glom/frame_glom.[h|cc]:
    * glom/mode_data/box_data_details.cc: Adapted, using
      PrintLayoutUtils::do_print_layout() instead.

 ChangeLog                                  |    9 +
 glom/application.cc                        |    6 -
 glom/application.h                         |    1 -
 glom/frame_glom.cc                         |   81 +-------
 glom/frame_glom.h                          |    1 -
 glom/mode_data/box_data_details.cc         |    7 +-
 glom/print_layout/print_layout_utils.cc    |  286 ++++++++++++++++++++++++++++
 glom/print_layout/print_layout_utils.h     |   51 +++++
 tests/test_selfhosting_new_from_example.cc |   17 ++
 9 files changed, 375 insertions(+), 84 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index aa95ed1..7493013 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2011-10-04  Murray Cumming  <murrayc murrayc com>
 
+	Move do_print_layout() to PrintLayoutUtils.
+
+	* glom/application.[h|cc]: Remove the new print_layout(PrintLayout) override.
+	* glom/frame_glom.[h|cc]:
+	* glom/mode_data/box_data_details.cc: Adapted, using 
+  PrintLayoutUtils::do_print_layout() instead.
+
+2011-10-04  Murray Cumming  <murrayc murrayc com>
+
 	PrintOperation_PrintLayout: Move to print_layout/:
 	
 	* Makefile_glom.am:  Mention the changed paths.
diff --git a/glom/application.cc b/glom/application.cc
index 749150e..750a901 100644
--- a/glom/application.cc
+++ b/glom/application.cc
@@ -2769,12 +2769,6 @@ void Application::do_print_layout(const Glib::ustring& print_layout_name, bool p
   m_pFrame->do_print_layout(print_layout_name, preview, transient_for);
 }
 
-void Application::do_print_layout(const sharedptr<const PrintLayout>& print_layout, bool preview, Gtk::Window* transient_for)
-{
-  m_pFrame->do_print_layout(print_layout, preview, transient_for);
-}
-
-
 bool Application::do_restore_backup(const Glib::ustring& backup_uri)
 {
   // We cannot use an uri here, because we cannot untar remote files.
diff --git a/glom/application.h b/glom/application.h
index 2481861..09780fe 100644
--- a/glom/application.h
+++ b/glom/application.h
@@ -97,7 +97,6 @@ public:
   void do_menu_developer_fields(Gtk::Window& parent, const Glib::ustring table_name);
   void do_menu_developer_relationships(Gtk::Window& parent, const Glib::ustring table_name);
   void do_print_layout(const Glib::ustring& print_layout_name, bool preview = false, Gtk::Window* transient_for = 0);
-  void do_print_layout(const sharedptr<const PrintLayout>& print_layout, bool preview = false, Gtk::Window* transient_for = 0);
   bool do_restore_backup(const Glib::ustring& backup_uri);
 #endif //GLOM_ENABLE_CLIENT_ONLY
 
diff --git a/glom/frame_glom.cc b/glom/frame_glom.cc
index 84ec909..0abdb37 100644
--- a/glom/frame_glom.cc
+++ b/glom/frame_glom.cc
@@ -59,6 +59,8 @@
 #include <glom/print_layout/printoperation_printlayout.h>
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
+#include <glom/print_layout/print_layout_utils.h>
+
 #include <glom/filechooser_export.h>
 #include <libglom/privs.h>
 #include <libglom/db_utils.h>
@@ -2317,28 +2319,17 @@ void Frame_Glom::on_menu_report_selected(const Glib::ustring& report_name)
 }
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
-
+ 
 void Frame_Glom::on_menu_print_layout_selected(const Glib::ustring& print_layout_name)
 {
-  do_print_layout(print_layout_name, false /* not preview */);
+  do_print_layout(print_layout_name, false /* not preview */, get_app_window());
 }
 
 void Frame_Glom::do_print_layout(const Glib::ustring& print_layout_name, bool preview, Gtk::Window* transient_for)
 {
-  Document* document = get_document();
-  sharedptr<PrintLayout> print_layout = document->get_print_layout(m_table_name, print_layout_name);
-    
-  do_print_layout(print_layout, preview, transient_for);
-}
+  const Document* document = get_document();
+  sharedptr<const PrintLayout> print_layout = document->get_print_layout(m_table_name, print_layout_name);
     
-void Frame_Glom::do_print_layout(const sharedptr<const PrintLayout>& print_layout, bool preview, Gtk::Window* transient_for)
-{
-  if(!print_layout)
-  {
-    std::cerr << G_STRFUNC << ": print_layout was null" << std::endl;
-    return;
-  }
-  
   const Privileges table_privs = Privs::get_current_privs(m_table_name);
 
   //Don't try to print tables that the user can't view.
@@ -2347,64 +2338,12 @@ void Frame_Glom::do_print_layout(const sharedptr<const PrintLayout>& print_layou
     //TODO: Warn the user.
     return;
   }
-
-  Canvas_PrintLayout canvas;
-  add_view(&canvas); //So it has access to the document.
-  canvas.set_print_layout(m_table_name, print_layout);
-
-  //Do not show things that are only for editing the print layout:
-  canvas.remove_grid();
-  canvas.set_rules_visibility(false);
-  canvas.set_outlines_visibility(false);
-
-  //Create a new PrintOperation with our PageSetup and PrintSettings:
-  //(We use our derived PrintOperation class)
-  Glib::RefPtr<PrintOperationPrintLayout> print = PrintOperationPrintLayout::create();
-  print->set_canvas(&canvas);
-
-  print->set_track_print_status();
-
-  //TODO: Put this in a utility function.
-  Glib::RefPtr<Gtk::PageSetup> page_setup;
-  const Glib::ustring key_file_text = print_layout->get_page_setup();
-  if(!key_file_text.empty())
-  {
-    Glib::KeyFile key_file;
-    key_file.load_from_data(key_file_text);
-    page_setup = Gtk::PageSetup::create_from_key_file(key_file);
-  }
-
-  print->set_default_page_setup(page_setup);
-
-  //print->set_print_settings(m_refSettings);
-
-  //print->signal_done().connect(sigc::bind(sigc::mem_fun(*this,
-  //                &ExampleWindow::on_printoperation_done), print));
-
+  
   const FoundSet found_set = m_Notebook_Data.get_found_set_details();
-  canvas.fill_with_data(found_set);
-
-  try
-  {
-    if(!transient_for)
-      transient_for = get_app_window();
-
-    if(transient_for)
-    {
-      print->run(
-        (preview ? Gtk::PRINT_OPERATION_ACTION_PREVIEW : Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG),
-        *transient_for);
-    }
-  }
-  catch (const Gtk::PrintError& ex)
-  {
-    //See documentation for exact Gtk::PrintError error codes.
-    std::cerr << "An error occurred while trying to run a print operation:"
-        << ex.what() << std::endl;
-  }
-
-  remove_view(&canvas);
+  PrintLayoutUtils::do_print_layout(print_layout, found_set, 
+    preview, document, transient_for);
 }
+ 
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
diff --git a/glom/frame_glom.h b/glom/frame_glom.h
index 4d2568d..40288cc 100644
--- a/glom/frame_glom.h
+++ b/glom/frame_glom.h
@@ -71,7 +71,6 @@ public:
   void set_databases_selected(const Glib::ustring& strName);
 
   void do_print_layout(const Glib::ustring& print_layout_name, bool preview = false, Gtk::Window* transient_for = 0);
-  void do_print_layout(const sharedptr<const PrintLayout>& print_layout, bool preview, Gtk::Window* transient_for = 0);
 
   void on_box_tables_selected(const Glib::ustring& strName);
 
diff --git a/glom/mode_data/box_data_details.cc b/glom/mode_data/box_data_details.cc
index de9cb4b..703759d 100644
--- a/glom/mode_data/box_data_details.cc
+++ b/glom/mode_data/box_data_details.cc
@@ -935,11 +935,8 @@ void Box_Data_Details::print_layout()
   
   //Show the print preview window:
   Application* app = Application::get_application();
-  if(app)
-  {
-    app->do_print_layout(print_layout, 
-      false /* print, not preview*/, app);
-  }
+  PrintLayoutUtils::do_print_layout(print_layout, m_found_set,
+    true /* not preview */, document, app);  
 }
 
 #ifndef GLOM_ENABLE_CLIENT_ONLY
diff --git a/glom/print_layout/print_layout_utils.cc b/glom/print_layout/print_layout_utils.cc
new file mode 100644
index 0000000..28693e6
--- /dev/null
+++ b/glom/print_layout/print_layout_utils.cc
@@ -0,0 +1,286 @@
+/* Glom
+ *
+ * Copyright (C) 2001-2011 Openismus GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glom/print_layout/print_layout_utils.h>
+#include <glom/print_layout/canvas_print_layout.h>
+#include <glom/print_layout/printoperation_printlayout.h>
+#include <iostream>
+
+namespace Glom
+{
+
+namespace PrintLayoutUtils
+{
+
+static Gtk::Unit get_units()
+{
+  //TODO: Deal with this properly if we ever allow non-MM units in the UI:
+  //m_canvas.property_units()
+  return Gtk::UNIT_MM;
+}
+
+/* Get the start and end of the page, inside the margins.
+ */
+static void get_page_y_start_and_end(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, guint page_number, double& y1, double& y2)
+{
+  y1 = 0;
+  y2 = 0;
+  
+  const Gtk::PaperSize paper_size = page_setup->get_paper_size();
+  const Gtk::Unit units = get_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);
+    
+  //y1:
+  y1 = page_height * (page_number);  
+  double y_border = page_setup->get_top_margin(units);
+  while(y1 <= y_border)
+    y1 += GRID_GAP;
+  
+  //y2:
+  y2 = page_height * (page_number + 1);  
+  y2 -= page_setup->get_bottom_margin(units); //TODO: Handle orientation here and wherever else we use the margin?
+
+  //std::cout << G_STRFUNC << "page_number=" << page_number << ", y1=" << y1 << "y2=" << y2 << std::endl;
+}
+
+
+static void create_standard(const sharedptr<const LayoutGroup>& layout_group, const sharedptr<LayoutGroup>& print_layout_group, const Glib::RefPtr<const Gtk::PageSetup>& page_setup, double x, double& y, guint& page_number)
+{
+  if(!layout_group || !print_layout_group)
+  {
+    return;
+  }
+
+  double min_y = 0; //ignored;
+  double max_y = 0;
+  get_page_y_start_and_end(page_setup, page_number, min_y, max_y);
+
+  const double height = ITEM_HEIGHT;
+  const double gap = GRID_GAP;
+
+  const Glib::ustring title = layout_group->get_title();
+  if(!title.empty())
+  {
+    sharedptr<LayoutItem_Text> text = sharedptr<LayoutItem_Text>::create();
+    text->set_text(title);
+    text->m_formatting.set_text_format_font("Sans Bold 10");
+
+    text->set_print_layout_position(x, y, ITEM_WIDTH_WIDE, height); //TODO: Enough and no more.
+    y += height + gap; //padding.
+
+    print_layout_group->add_item(text);
+
+    //Start on the next page, if necessary:
+    //TODO: Add a page if necessary:
+    if( y >= max_y )
+    {
+      page_number += 1;
+      get_page_y_start_and_end(page_setup, page_number, y, max_y);
+    }
+  }
+
+  //Recurse into the group's child items:
+  for(LayoutGroup::type_list_items::const_iterator iter = layout_group->m_list_items.begin(); iter != layout_group->m_list_items.end(); ++iter)
+  {
+    const sharedptr<const LayoutItem> item = *iter;
+    if(!item)
+      continue;
+
+    const sharedptr<const LayoutGroup> group = sharedptr<const LayoutGroup>::cast_dynamic(item);
+    const sharedptr<const LayoutItem_Portal> portal = sharedptr<const LayoutItem_Portal>::cast_dynamic(group);
+    if(portal)
+      continue; //TODO: Handle these.
+
+    if(group)
+    {
+      //Recurse: //TODO: Handle portals separately:
+      create_standard(group, print_layout_group, page_setup, x, y, page_number);
+    }
+    else
+    {
+      //Add field titles, if necessary:
+      const double title_width = ITEM_WIDTH_WIDE; //TODO: Calculate it based on the widest in the column. Or just halve the column to start.
+      const sharedptr<const LayoutItem_Field> field = sharedptr<const LayoutItem_Field>::cast_dynamic(item);
+      if(field)
+      {
+        sharedptr<LayoutItem_Text> text = sharedptr<LayoutItem_Text>::create();
+        text->set_text(field->get_title_or_name() + ":");
+        text->set_print_layout_position(x, y, title_width, height); //TODO: Enough and no more.
+        text->m_formatting.set_text_format_font("Sans 10");
+
+        print_layout_group->add_item(text);
+      }
+
+      //Add the item, such as a field:
+      sharedptr<LayoutItem> clone = glom_sharedptr_clone(item);
+
+      double item_x = x;
+      if(field)
+        item_x += (title_width + gap);
+
+      clone->set_print_layout_position(item_x, y, 100, height); //TODO: Enough and no more.
+      y += height + gap; //padding.
+
+      print_layout_group->add_item(clone);
+
+      //Start on the next page, if necessary:
+      //TODO: Add a page if necessary:
+      if( y >= max_y )
+      {
+        page_number += 1;
+        get_page_y_start_and_end(page_setup, page_number, y, max_y);
+      }
+    }
+  }
+}
+
+sharedptr<PrintLayout> create_standard(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, const Glib::ustring& table_name, const Document* document)
+{
+  sharedptr<PrintLayout> print_layout = sharedptr<PrintLayout>::create();  
+  
+  //Start inside the border, on the next grid line:
+  double y = 0;
+  double max_y = 0; //ignored
+  guint page_number = 0;
+  get_page_y_start_and_end(page_setup, page_number, y, max_y);
+  
+  double x = 0;
+  double x_border = 0;
+  if(page_setup)
+    x_border = page_setup->get_left_margin(get_units());
+  while(x <= x_border)
+    x += GRID_GAP;
+  
+  //The table title:
+  const Glib::ustring title = document->get_table_title_singular(table_name);
+  if(!title.empty())
+  {
+    sharedptr<LayoutItem_Text> text = sharedptr<LayoutItem_Text>::create();
+    text->set_text(title);
+    text->m_formatting.set_text_format_font("Sans Bold 12");
+
+    const double height = ITEM_HEIGHT;
+    text->set_print_layout_position(x, y, ITEM_WIDTH_WIDE, height); //TODO: Enough and no more.
+    y += height + GRID_GAP; //padding.
+
+    print_layout->m_layout_group->add_item(text);
+  }
+
+  //The layout:
+  //TODO: Use fill_layout_group_field_info()?
+  const Document::type_list_layout_groups layout_groups = 
+    document->get_data_layout_groups("details", table_name); //TODO: layout_platform.
+  for(Document::type_list_layout_groups::const_iterator iter = layout_groups.begin(); iter != layout_groups.end(); ++iter)
+  {
+    const sharedptr<const LayoutGroup> group = *iter;
+    if(!group)
+      continue;
+
+    create_standard(group, print_layout->m_layout_group, page_setup, x, y, page_number);
+  }
+
+  //Add extra pages if necessary:
+  if(page_number >= print_layout->get_page_count())
+  {
+    print_layout->set_page_count(page_number + 1);
+  }
+  
+  return print_layout;
+}
+
+void do_print_layout(const sharedptr<const PrintLayout>& print_layout, const FoundSet& found_set, bool preview, const Document* document, Gtk::Window* transient_for)
+{
+  if(!print_layout)
+  {
+    std::cerr << G_STRFUNC << ": print_layout was null" << std::endl;
+    return;
+  }
+  
+  if(!document)
+  {
+    std::cerr << G_STRFUNC << ": document was null" << std::endl;
+    return;
+  }
+  
+  //TODO: All this to be null when we allow that in Gtk::PrintOperation::run().
+  if(!transient_for)
+  {
+    std::cerr << G_STRFUNC << ":  transient_for was null" << std::endl;
+    return;
+  }
+
+  Canvas_PrintLayout canvas;
+  canvas.set_document(const_cast<Document*>(document)); //We const_cast because, for this use, it will not be changed.
+  canvas.set_print_layout(found_set.m_table_name, print_layout);
+
+  //Do not show things that are only for editing the print layout:
+  canvas.remove_grid();
+  canvas.set_rules_visibility(false);
+  canvas.set_outlines_visibility(false);
+
+  //Create a new PrintOperation with our PageSetup and PrintSettings:
+  //(We use our derived PrintOperation class)
+  Glib::RefPtr<PrintOperationPrintLayout> print = PrintOperationPrintLayout::create();
+  print->set_canvas(&canvas);
+
+  print->set_track_print_status();
+
+  //TODO: Put this in a utility function.
+  Glib::RefPtr<Gtk::PageSetup> page_setup;
+  const Glib::ustring key_file_text = print_layout->get_page_setup();
+  if(!key_file_text.empty())
+  {
+    Glib::KeyFile key_file;
+    key_file.load_from_data(key_file_text);
+    page_setup = Gtk::PageSetup::create_from_key_file(key_file);
+  }
+
+  print->set_default_page_setup(page_setup);
+
+  //print->set_print_settings(m_refSettings);
+
+  //print->signal_done().connect(sigc::bind(sigc::mem_fun(*this,
+  //                &ExampleWindow::on_printoperation_done), print));
+
+  canvas.fill_with_data(found_set);
+
+  try
+  {
+    print->run(
+      (preview ? Gtk::PRINT_OPERATION_ACTION_PREVIEW : Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG),
+      *transient_for);
+  }
+  catch (const Gtk::PrintError& ex)
+  {
+    //See documentation for exact Gtk::PrintError error codes.
+    std::cerr << "An error occurred while trying to run a print operation:"
+        << ex.what() << std::endl;
+  }
+}
+
+} //namespace PrintLayoutUtils
+
+} //namespace Glom
+
diff --git a/glom/print_layout/print_layout_utils.h b/glom/print_layout/print_layout_utils.h
new file mode 100644
index 0000000..1ecc4d5
--- /dev/null
+++ b/glom/print_layout/print_layout_utils.h
@@ -0,0 +1,51 @@
+/* Glom
+ *
+ * Copyright (C) 2001-2011 Openismus GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GLOM_PRINT_LAYOUT_UTILS_H
+#define GLOM_PRINT_LAYOUT_UTILS_H
+
+#include "config.h"
+#include <libglom/data_structure/print_layout.h>
+#include <libglom/document/document.h>
+#include <gtkmm/pagesetup.h>
+
+namespace Glom
+{
+
+namespace PrintLayoutUtils
+{
+
+const double GRID_GAP = 6.0f; //Roughly the right height for 12 point text.
+
+//Base the default item sizes on the grid gap, instead of being arbitrary:
+const double ITEM_HEIGHT = GRID_GAP;
+const double ITEM_WIDTH_WIDE = GRID_GAP * 10;
+
+//TODO: Move this into libglom, by replacing Gtk::PageSetup with a custom class.
+//However, this also uses goocanvas, which would need to have its GTK+ widget split away too.
+sharedptr<PrintLayout> create_standard(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, const Glib::ustring& table_name, const Document* document);
+
+void do_print_layout(const sharedptr<const PrintLayout>& print_layout, const FoundSet& found_set, bool preview, const Document* document, Gtk::Window* transient_for);
+
+} //namespace PrintLayoutUtils
+
+} //namespace Glom
+
+#endif //GLOM_PRINT_LAYOUT_UTILS_H
diff --git a/tests/test_selfhosting_new_from_example.cc b/tests/test_selfhosting_new_from_example.cc
index a36bac6..2ca8cab 100644
--- a/tests/test_selfhosting_new_from_example.cc
+++ b/tests/test_selfhosting_new_from_example.cc
@@ -198,6 +198,23 @@ int main()
   if(!recreated)
     cleanup();
   g_assert(recreated);
+  
+
+  //Test the standard print layout:
+  /* Actually, we can't do this without depending on more than libglom:
+  const Glib::ustring test_table_name = "albums";
+  Glib::RefPtr<Gtk::PageSetup> page_setup = Gtk::PageSetup::create(); //TODO: m_canvas.get_page_setup();
+  sharedptr<PrintLayout> print_layout = 
+    PrintLayoutUtils::create_standard(page_setup, "albums", document);
+  
+  //Show the print preview window:
+  FoundSet foundset;
+  foundset.m_table_name = test_table_name;
+  foundset.m_where_clause = Utils::build_simple_where_expression(
+    test_table_name, "album_id", Gnome::Gda::Value("1"));
+  PrintLayoutUtils::do_print_layout(print_layout, found_set, 
+    false, document, &window);
+  */
 
   cleanup();
 



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