[glom] Print Layout: Add experimental Create Standard feature.



commit d4e1297169d8b3b2dfa3b18dc49f0ef252903e81
Author: Murray Cumming <murrayc murrayc com>
Date:   Thu Sep 29 21:00:22 2011 +0200

    Print Layout: Add experimental Create Standard feature.
    
    	* glom/mode_design/print_layouts/window_print_layout_edit.[h|cc]:
    	Add an Insert/Create Standard Layout menu item which creates a layout
    	similar to the details layout.

 ChangeLog                                          |    8 +
 .../print_layouts/window_print_layout_edit.cc      |  165 ++++++++++++++++++++
 .../print_layouts/window_print_layout_edit.h       |    4 +
 glom/print_layout/canvas_print_layout.cc           |    7 +-
 4 files changed, 180 insertions(+), 4 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a00c5a3..01f0885 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2011-09-29  Murray Cumming  <murrayc murrayc com>
 
+	Print Layout: Add experimental Create Standard feature.
+
+	* glom/mode_design/print_layouts/window_print_layout_edit.[h|cc]:
+	Add an Insert/Create Standard Layout menu item which creates a layout 
+	similar to the details layout.
+
+2011-09-29  Murray Cumming  <murrayc murrayc com>
+
 	Dialog_Choose_ID: Work around a crash in GTK+.
 
 	* glom/mode_data/datawidget/dialog_choose_id.cc: Remove the Box_Data_List 
diff --git a/glom/mode_design/print_layouts/window_print_layout_edit.cc b/glom/mode_design/print_layouts/window_print_layout_edit.cc
index 68c8e86..3e6de6f 100644
--- a/glom/mode_design/print_layouts/window_print_layout_edit.cc
+++ b/glom/mode_design/print_layouts/window_print_layout_edit.cc
@@ -238,6 +238,8 @@ void Window_PrintLayout_Edit::init_menu()
                         sigc::mem_fun(*this, &Window_PrintLayout_Edit::on_menu_insert_line_horizontal) );
   m_action_group->add(Gtk::Action::create("Action_Menu_Insert_LineVertical", _("Insert _Vertical Line")),
                         sigc::mem_fun(*this, &Window_PrintLayout_Edit::on_menu_insert_line_vertical) );
+  m_action_group->add(Gtk::Action::create("Action_Menu_Insert_CreateStandard", _("_Create Standard Layout")),
+                        sigc::mem_fun(*this, &Window_PrintLayout_Edit::on_menu_insert_create_standard) );
 
 
   m_action_group->add(Gtk::Action::create("Menu_Align", _("_Align")));
@@ -313,6 +315,8 @@ void Window_PrintLayout_Edit::init_menu()
     "        <menuitem action='Action_Menu_Insert_RelatedRecords' />"
     "        <menuitem action='Action_Menu_Insert_LineHorizontal' />"
     "        <menuitem action='Action_Menu_Insert_LineVertical' />"
+    "        <separator />"
+    "        <menuitem action='Action_Menu_Insert_CreateStandard' />"
     "      </menu>"
     "      <menu action='Menu_Align'>"
     "        <menuitem action='Action_Menu_Align_Top' />"
@@ -896,6 +900,167 @@ void Window_PrintLayout_Edit::on_menu_insert_line_vertical()
   m_canvas.add_canvas_layout_item(item);
 }
 
+void Window_PrintLayout_Edit::on_menu_insert_create_standard()
+{
+  //Ask for confirmation:
+  Gtk::MessageDialog dialog(Utils::bold_message(_("Create Standard Layout")), true, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE);
+  dialog.set_secondary_text(_("This is an experimental feature. It will remove all items from the print layout and then try to create a layout similar to the layout of the detail view."));
+  dialog.set_transient_for(*this);
+  dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+  dialog.add_button(_("Create"), Gtk::RESPONSE_OK);
+
+  const int response = dialog.run();
+  if(response != Gtk::RESPONSE_OK)
+    return;
+
+  const Document* document = dynamic_cast<const Document*>(get_document());
+  if(!document)
+  {
+    std::cerr << G_STRFUNC << ": document was null" << std::endl;
+    return;
+  }
+
+  m_print_layout = sharedptr<PrintLayout>::create();
+
+  //TODO: Use fill_layout_group_field_info()?
+  const Document::type_list_layout_groups layout_groups = document->get_data_layout_groups("details", m_table_name); //TODO: layout_platform.
+
+  //Start inside the border, on the next grid line:
+  double y = 0;
+  double y_border = 0;
+  const Glib::RefPtr<const Gtk::PageSetup> page_setup = m_canvas.get_page_setup();
+  if(page_setup)
+    y_border = page_setup->get_top_margin(m_canvas.property_units());
+
+  while(y <= y_border)
+    y += GRID_GAP;
+
+  double x = 0;
+  double x_border = 0;
+  if(page_setup)
+    x_border = page_setup->get_left_margin(m_canvas.property_units());
+  while(x <= x_border)
+    x += GRID_GAP;
+
+
+  //The table title:
+  const Glib::ustring title = document->get_table_title_singular(m_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.
+
+    m_print_layout->m_layout_group->add_item(text);
+  }
+
+  //The layout:
+  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, m_print_layout->m_layout_group, x, y);
+  }
+
+  m_canvas.set_print_layout(m_table_name, m_print_layout);
+}
+
+void Window_PrintLayout_Edit::create_standard(const sharedptr<const LayoutGroup>& layout_group, const sharedptr<LayoutGroup>& print_layout_group, double x, double& y)
+{
+  if(!layout_group || !print_layout_group)
+  {
+    return;
+  }
+
+  Glib::RefPtr<Gtk::PageSetup> page_setup = m_canvas.get_page_setup();
+  if(!page_setup)
+  {
+    std::cerr << G_STRFUNC << ": page_setup was null" << std::endl;
+    return;
+  }
+
+  double max_y = 0;
+  const Gtk::PaperSize paper_size = page_setup->get_paper_size();
+  const Gtk::Unit units = m_canvas.property_units();
+  if(page_setup->get_orientation() == Gtk::PAGE_ORIENTATION_PORTRAIT) //TODO: Handle the reverse orientations too?
+    max_y = paper_size.get_height(units);
+  else
+    max_y = paper_size.get_width(units);
+
+  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);
+
+    if( y >= max_y)
+      return;
+  }
+
+  //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, x, y);
+    }
+    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);
+
+      if(y >= max_y)
+        break;
+    }
+  }
+}
 void Window_PrintLayout_Edit::on_button_close()
 {
   hide();
diff --git a/glom/mode_design/print_layouts/window_print_layout_edit.h b/glom/mode_design/print_layouts/window_print_layout_edit.h
index 4900ea0..b4b634b 100644
--- a/glom/mode_design/print_layouts/window_print_layout_edit.h
+++ b/glom/mode_design/print_layouts/window_print_layout_edit.h
@@ -70,6 +70,8 @@ private:
   void on_menu_insert_relatedrecords();
   void on_menu_insert_line_horizontal();
   void on_menu_insert_line_vertical();
+  void on_menu_insert_create_standard();
+
   void on_menu_view_show_grid();
   void on_menu_view_show_rules();
   void on_menu_view_show_outlines();
@@ -127,6 +129,8 @@ private:
   void canvas_convert_from_drag_pixels(double& x, double& y, bool adjust_for_scrolling = false) const;
   void get_dimensions_of_multiple_selected_items(double& x, double& y, double& width, double& height);
 
+  void create_standard(const sharedptr<const LayoutGroup>& layout_group, const sharedptr<LayoutGroup>& print_layout_group, double x, double& y);
+
   //Box_DB_Table_Definition* m_box;
   Glib::ustring m_name_original;
   Glib::ustring m_table_name;
diff --git a/glom/print_layout/canvas_print_layout.cc b/glom/print_layout/canvas_print_layout.cc
index 3105931..0e64bea 100644
--- a/glom/print_layout/canvas_print_layout.cc
+++ b/glom/print_layout/canvas_print_layout.cc
@@ -78,7 +78,6 @@ void Canvas_PrintLayout::set_print_layout(const Glib::ustring& table_name, const
   add_layout_group(print_layout->m_layout_group, true /* is top-level */);
 
   //Use the page setup:
-  Glib::RefPtr<Gtk::PageSetup> page_setup;
   const Glib::ustring key_file_text = print_layout->get_page_setup();
   if(!key_file_text.empty())
   {
@@ -87,11 +86,11 @@ void Canvas_PrintLayout::set_print_layout(const Glib::ustring& table_name, const
     //TODO: Catch an exception
     key_file.load_from_data(key_file_text);
 
-    page_setup = Gtk::PageSetup::create_from_key_file(key_file);
+    Glib::RefPtr<Gtk::PageSetup> page_setup = 
+      Gtk::PageSetup::create_from_key_file(key_file);
+    set_page_setup(page_setup);
   }
 
-  set_page_setup(page_setup);
-
 
   //Add the rule lines:
   remove_rules();



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