glom r1698 - in trunk: . glom glom/libglom/data_structure/layout glom/mode_data glom/mode_design/print_layouts glom/utility_widgets/db_adddel po



Author: murrayc
Date: Wed Oct  8 16:42:11 2008
New Revision: 1698
URL: http://svn.gnome.org/viewvc/glom?rev=1698&view=rev

Log:
2008-10-07  Murray Cumming  <murrayc murrayc com>

* glom/mode_data/box_data_portal.cc
* glom/base_db.h
* glom/base_db.cc:
Moved code from Box_Data_Portal::init_db_details() into
set_found_set_where_clause_for_portal() so it can be reused.
Added get_field_value_in_database() overload that
takes a FoundSet.
* glom/mode_design/print_layouts/canvas_layout_item.cc
* glom/mode_design/print_layouts/canvas_layout_item.h: moved some code into
get_rows_count_for_portal() so it can be reused.
* glom/frame_glom.cc
* glom/mode_design/print_layouts/canvas_print_layout.cc
 * glom/mode_design/print_layouts/canvas_print_layout.h:
fill_with_data(): Added and used some helper functions to fill tables
(for portals) with data so that portals actually show field data when
printed.


Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/glom/base_db.cc
   trunk/glom/base_db.h
   trunk/glom/frame_glom.cc
   trunk/glom/libglom/data_structure/layout/usesrelationship.cc
   trunk/glom/mode_data/box_data_list_related.cc
   trunk/glom/mode_data/box_data_portal.cc
   trunk/glom/mode_design/print_layouts/canvas_layout_item.cc
   trunk/glom/mode_design/print_layouts/canvas_layout_item.h
   trunk/glom/mode_design/print_layouts/canvas_print_layout.cc
   trunk/glom/mode_design/print_layouts/canvas_print_layout.h
   trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.cc
   trunk/po/Makefile.in.in

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Wed Oct  8 16:42:11 2008
@@ -1,3 +1,5 @@
+1.7.3:
+
 1.7.2:
 
 * Drag-and-drop Layout:

Modified: trunk/glom/base_db.cc
==============================================================================
--- trunk/glom/base_db.cc	(original)
+++ trunk/glom/base_db.cc	Wed Oct  8 16:42:11 2008
@@ -2166,9 +2166,56 @@
   type_vecConstLayoutFields list_fields;
   sharedptr<const LayoutItem_Field> layout_item = field_in_record.m_field;
   list_fields.push_back(layout_item);
-  const Glib::ustring sql_query = Utils::build_sql_select_with_key(field_in_record.m_table_name,
+  Glib::ustring sql_query = Utils::build_sql_select_with_key(field_in_record.m_table_name,
       list_fields, field_in_record.m_key, field_in_record.m_key_value);
 
+  if(!sql_query.empty())
+    sql_query += " LIMIT 1";
+
+  Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute(sql_query);
+  if(data_model)
+  {
+    if(data_model->get_n_rows())
+    {
+      result = data_model->get_value_at(0, 0);
+    }
+  }
+  else
+  {
+    handle_error();
+  }
+
+  return result;
+}
+
+Gnome::Gda::Value Base_DB::get_field_value_in_database(const sharedptr<Field>& field, const FoundSet& found_set, Gtk::Window* parent_window)
+{
+  Gnome::Gda::Value result;  //TODO: Return suitable empty value for the field when failing?
+
+  //row is invalid, and ignored, for Box_Data_Details.
+  if(!field)
+  {
+    std::cerr << "Base_DB:gset_field_value_in_database(): field is empty." << std::endl;
+    return result;
+  }
+
+  if(found_set.m_where_clause.empty())
+  {
+    std::cerr << "Base_DB::get_field_value_in_database(): where_clause is empty." << std::endl;
+    return result;
+  }
+
+  type_vecConstLayoutFields list_fields;
+  sharedptr<LayoutItem_Field> layout_item = sharedptr<LayoutItem_Field>::create();
+  layout_item->set_full_field_details(field);
+  list_fields.push_back(layout_item);
+  Glib::ustring sql_query = Utils::build_sql_select_with_where_clause(found_set.m_table_name,
+    list_fields,
+    found_set.m_where_clause);
+
+  if(!sql_query.empty())
+    sql_query += " LIMIT 1";
+
   Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute(sql_query);
   if(data_model)
   {
@@ -2185,6 +2232,7 @@
   return result;
 }
 
+
 void Base_DB::do_calculations(const LayoutFieldInRecord& field_changed, bool first_calc_field)
 {
   //std::cout << "debug: Base_DB::do_calcualtions(): field_changed=" << field_changed.m_field->get_name() << std::endl;
@@ -2726,4 +2774,59 @@
   return result;
 }
 
+
+void Base_DB::set_found_set_where_clause_for_portal(FoundSet& found_set, const sharedptr<LayoutItem_Portal>& portal, const Gnome::Gda::Value& foreign_key_value)
+{
+  found_set.m_table_name = Glib::ustring();
+  found_set.m_where_clause = Glib::ustring();
+  found_set.m_extra_join = Glib::ustring();
+  found_set.m_extra_group_by = Glib::ustring();
+
+  if( !portal
+      || Conversions::value_is_empty(foreign_key_value) )
+  {
+    return;
+  }
+ 
+
+  sharedptr<Relationship> relationship = portal->get_relationship();
+
+  // Notice that, in the case that this is a portal to doubly-related records,
+  // The WHERE clause mentions the first-related table (though by the alias defined in extra_join)
+  // and we add an extra JOIN to mention the second-related table.
+
+  Glib::ustring where_clause_to_table_name = relationship->get_to_table();
+  sharedptr<Field> where_clause_to_key_field = get_fields_for_table_one_field(relationship->get_to_table(), relationship->get_to_field());
+
+  found_set.m_table_name = portal->get_table_used(Glib::ustring() /* parent table - not relevant */);
+      
+  sharedptr<const Relationship> relationship_related = portal->get_related_relationship();
+  if(relationship_related)
+  {
+    //Add the extra JOIN:
+    sharedptr<UsesRelationship> uses_rel_temp = sharedptr<UsesRelationship>::create();
+    uses_rel_temp->set_relationship(relationship);
+    //found_set.m_extra_join = uses_rel_temp->get_sql_join_alias_definition();
+    found_set.m_extra_join = "LEFT OUTER JOIN \"" + relationship->get_to_table() + "\" AS \"" + uses_rel_temp->get_sql_join_alias_name() + "\" ON (\"" + uses_rel_temp->get_sql_join_alias_name() + "\".\"" + relationship_related->get_from_field() + "\" = \"" + relationship_related->get_to_table() + "\".\"" + relationship_related->get_to_field() + "\")";
+
+    //Add an extra GROUP BY to ensure that we get no repeated records from the doubly-related table:
+    sharedptr<Field> to_table_primary_key = get_field_primary_key_for_table( relationship->get_to_table() );
+    if(to_table_primary_key)
+      found_set.m_extra_group_by = "GROUP BY \"" + found_set.m_table_name + "\".\"" + to_table_primary_key->get_name() + "\"";
+
+    //Adjust the WHERE clause appropriately for the extra JOIN:
+    where_clause_to_table_name = uses_rel_temp->get_sql_join_alias_name();
+
+    const Glib::ustring to_field_name = uses_rel_temp->get_to_field_used();
+    where_clause_to_key_field = get_fields_for_table_one_field(relationship->get_to_table(), to_field_name);
+    //std::cout << "extra_join=" << found_set.m_extra_join << std::endl;
+ 
+    //std::cout << "extra_join where_clause_to_key_field=" << where_clause_to_key_field->get_name() << std::endl;
+  }
+
+  if(where_clause_to_key_field)
+    found_set.m_where_clause = "\"" + where_clause_to_table_name + "\".\"" + relationship->get_to_field() + "\" = " + where_clause_to_key_field->sql(foreign_key_value);
+}
+
+
 } //namespace Glom

Modified: trunk/glom/base_db.h
==============================================================================
--- trunk/glom/base_db.h	(original)
+++ trunk/glom/base_db.h	Wed Oct  8 16:42:11 2008
@@ -267,9 +267,13 @@
   bool set_field_value_in_database(const LayoutFieldInRecord& field_in_record, const Gnome::Gda::Value& field_value, bool use_current_calculations = false, Gtk::Window* parent_window = 0);
   bool set_field_value_in_database(const LayoutFieldInRecord& field_in_record, const Gtk::TreeModel::iterator& row, const Gnome::Gda::Value& field_value, bool use_current_calculations = false, Gtk::Window* parent_window = 0);
 
-  //Get a single field value from the database.
+  ///Get a single field value from the database.
   Gnome::Gda::Value get_field_value_in_database(const LayoutFieldInRecord& field_in_record, Gtk::Window* parent_window);
 
+  ///Get a single field value from the database.
+  Gnome::Gda::Value get_field_value_in_database(const sharedptr<Field>& field, const FoundSet& found_set, Gtk::Window* parent_window);
+
+
 
   SystemPrefs get_database_preferences() const;
   void set_database_preferences(const SystemPrefs& prefs);
@@ -312,6 +316,16 @@
 
   bool get_primary_key_is_in_foundset(const FoundSet& found_set, const Gnome::Gda::Value& primary_key_value);
 
+
+  /** A utility function to set the where_clause, even for doubly-related records.
+   *
+   * @param found_set The FoundSet to change.
+   * @param portal The related records portal whose records should be selected by the SQL query.
+   * @param foreign_key_value The value of the from field in the parent table.
+   */
+  void set_found_set_where_clause_for_portal(FoundSet& found_set, const sharedptr<LayoutItem_Portal>& portal, const Gnome::Gda::Value& foreign_key_value);
+
+
   static bool get_field_primary_key_index_for_fields(const type_vecFields& fields, guint& field_column);
   static bool get_field_primary_key_index_for_fields(const type_vecLayoutFields& fields, guint& field_column);
 

Modified: trunk/glom/frame_glom.cc
==============================================================================
--- trunk/glom/frame_glom.cc	(original)
+++ trunk/glom/frame_glom.cc	Wed Oct  8 16:42:11 2008
@@ -1979,6 +1979,7 @@
     return;
 
   Canvas_PrintLayout canvas;
+  add_view(&canvas); //So it has access to the document.
   canvas.set_print_layout(m_table_name, print_layout);
 
   //Create a new PrintOperation with our PageSetup and PrintSettings:
@@ -2008,6 +2009,8 @@
     std::cerr << "An error occurred while trying to run a print operation:"
         << ex.what() << std::endl;
   }
+
+  remove_view(&canvas);
 }
 #endif // !GLOM_ENABLE_CLIENT_ONLY
 

Modified: trunk/glom/libglom/data_structure/layout/usesrelationship.cc
==============================================================================
--- trunk/glom/libglom/data_structure/layout/usesrelationship.cc	(original)
+++ trunk/glom/libglom/data_structure/layout/usesrelationship.cc	Wed Oct  8 16:42:11 2008
@@ -189,7 +189,7 @@
     const Glib::ustring field_table_name = relationship->get_to_table();
     if(field_table_name.empty())
     {
-      g_warning("build_sql_select_with_where_clause(): field_table_name is null. relationship name = %s", relationship->get_name().c_str());
+      g_warning("get_sql_join_alias_name(): field_table_name is null. relationship name = %s", relationship->get_name().c_str());
     }
     */
 

Modified: trunk/glom/mode_data/box_data_list_related.cc
==============================================================================
--- trunk/glom/mode_data/box_data_list_related.cc	(original)
+++ trunk/glom/mode_data/box_data_list_related.cc	Wed Oct  8 16:42:11 2008
@@ -126,7 +126,6 @@
   if(m_key_field && m_found_set.m_where_clause.empty()) //There's a key field, but no value.
   {
     //No Foreign Key value, so just show the field names:
-
     result = Base_DB_Table_Data::fill_from_database();
 
     //create_layout();

Modified: trunk/glom/mode_data/box_data_portal.cc
==============================================================================
--- trunk/glom/mode_data/box_data_portal.cc	(original)
+++ trunk/glom/mode_data/box_data_portal.cc	Wed Oct  8 16:42:11 2008
@@ -109,49 +109,16 @@
 bool Box_Data_Portal::refresh_data_from_database_with_foreign_key(const Gnome::Gda::Value& foreign_key_value)
 {
   m_key_value = foreign_key_value;
+  
 
   if(m_key_field && m_portal)
   {
     if(!Conversions::value_is_empty(m_key_value))
     {
-      sharedptr<Relationship> relationship = m_portal->get_relationship();
-
-      // Notice that, in the case that this is a portal to doubly-related records,
-      // The WHERE clause mentions the first-related table (though by the alias defined in extra_join)
-      // and we add an extra JOIN to mention the second-related table.
-
-      Glib::ustring where_clause_to_table_name = relationship->get_to_table();
-      sharedptr<Field> where_clause_to_key_field = m_key_field;
-
-      FoundSet found_set = m_found_set;
-      found_set.m_table_name = m_portal->get_table_used(Glib::ustring() /* parent table - not relevant */);
-      
-      sharedptr<const Relationship> relationship_related = m_portal->get_related_relationship();
-      if(relationship_related)
-      {
-         //Add the extra JOIN:
-         sharedptr<UsesRelationship> uses_rel_temp = sharedptr<UsesRelationship>::create();
-         uses_rel_temp->set_relationship(relationship);
-         //found_set.m_extra_join = uses_rel_temp->get_sql_join_alias_definition();
-         found_set.m_extra_join = "LEFT OUTER JOIN \"" + relationship->get_to_table() + "\" AS \"" + uses_rel_temp->get_sql_join_alias_name() + "\" ON (\"" + uses_rel_temp->get_sql_join_alias_name() + "\".\"" + relationship_related->get_from_field() + "\" = \"" + relationship_related->get_to_table() + "\".\"" + relationship_related->get_to_field() + "\")";
-
-         //Add an extra GROUP BY to ensure that we get no repeated records from the doubly-related table:
-         found_set.m_extra_group_by = "GROUP BY \"" + found_set.m_table_name + "\".\"" + m_key_field->get_name() + "\"";
-
-         //Adjust the WHERE clause appropriately for the extra JOIN:
-         where_clause_to_table_name = uses_rel_temp->get_sql_join_alias_name();
-
-         Glib::ustring to_field_name = uses_rel_temp->get_to_field_used();
-         where_clause_to_key_field = get_fields_for_table_one_field(relationship->get_to_table(), to_field_name);
-         //std::cout << "extra_join=" << found_set.m_extra_join << std::endl;
- 
-         //std::cout << "extra_join where_clause_to_key_field=" << where_clause_to_key_field->get_name() << std::endl;
-      }
-
-      found_set.m_where_clause = "\"" + where_clause_to_table_name + "\".\"" + relationship->get_to_field() + "\" = " + where_clause_to_key_field->sql(m_key_value);
-
-
-      //g_warning("refresh_data_from_database_with_foreign_key(): where_clause=%s", where_clause.c_str());
+      FoundSet found_set;
+      set_found_set_where_clause_for_portal(found_set, m_portal, m_key_value);
+   
+      //std::cout << "DEBUG: refresh_data_from_database_with_foreign_key(): where_clause=" << found_set.m_where_clause << std::endl;
       return Box_Data::refresh_data_from_database_with_where_clause(found_set);
     }
     else

Modified: trunk/glom/mode_design/print_layouts/canvas_layout_item.cc
==============================================================================
--- trunk/glom/mode_design/print_layouts/canvas_layout_item.cc	(original)
+++ trunk/glom/mode_design/print_layouts/canvas_layout_item.cc	Wed Oct  8 16:42:11 2008
@@ -145,6 +145,29 @@
   }
 }
 
+int CanvasLayoutItem::get_rows_count_for_portal(const sharedptr<const LayoutItem_Portal>& portal, double& row_height)
+{
+  if(!portal)
+  {
+    row_height = 0;
+    return 0;
+  }
+
+  row_height = std::max(portal->get_print_layout_row_height(), (double)1); //Avoid 0, because that makes the whole thing zero sized.
+
+  double ignore_x = 0;
+  double ignore_y = 0;
+  double total_width = 0;
+  double total_height = 0;
+  portal->get_print_layout_position(ignore_x, ignore_y, total_width, total_height);
+
+  const double max_rows_fraction = total_height / row_height;
+  double max_rows = 0;
+  modf(max_rows_fraction, &max_rows);
+
+  return max_rows;
+}
+
 Glib::RefPtr<CanvasItemMovable> CanvasLayoutItem::create_canvas_item_for_layout_item(const sharedptr<LayoutItem>& layout_item)
 {
   sharedptr<LayoutItem_Line> line;
@@ -245,16 +268,8 @@
             canvas_item->property_stroke_color() = "black";
 
             //Show as many rows as can fit in the height.
-            const double row_height = std::max(portal->get_print_layout_row_height(), (double)1); //Avoid 0, because that makes the whole thing zero sized.
-            double ignore_x = 0;
-            double ignore_y = 0;
-            double total_width = 0;
-            double total_height = 0;
-            portal->get_print_layout_position(ignore_x, ignore_y, total_width, total_height);
-
-            const double max_rows_fraction = total_height / row_height;
-            double max_rows = 0;
-            modf(max_rows_fraction, &max_rows);
+            double row_height = 0;
+            const int max_rows = get_rows_count_for_portal(portal, row_height);
 
             const LayoutGroup::type_list_items child_items = portal->get_items();
 

Modified: trunk/glom/mode_design/print_layouts/canvas_layout_item.h
==============================================================================
--- trunk/glom/mode_design/print_layouts/canvas_layout_item.h	(original)
+++ trunk/glom/mode_design/print_layouts/canvas_layout_item.h	Wed Oct  8 16:42:11 2008
@@ -30,6 +30,7 @@
 
 class CanvasTextMovable;
 class FieldFormatting;
+class LayoutItem_Portal;
 
 /** This has the appropriate child canvas item, depending on the type of the child LayoutItem.
  */
@@ -60,6 +61,8 @@
   /// Hide the missing-image pixbuf from images, for instance.
   void remove_empty_indicators();
 
+  static int get_rows_count_for_portal(const sharedptr<const LayoutItem_Portal>& portal, double& row_height);
+
 protected:
   /// Create the appropriate inner canvas item to represent the layout item.
   static Glib::RefPtr<CanvasItemMovable> create_canvas_item_for_layout_item(const sharedptr<LayoutItem>& layout_item);

Modified: trunk/glom/mode_design/print_layouts/canvas_print_layout.cc
==============================================================================
--- trunk/glom/mode_design/print_layouts/canvas_print_layout.cc	(original)
+++ trunk/glom/mode_design/print_layouts/canvas_print_layout.cc	Wed Oct  8 16:42:11 2008
@@ -24,6 +24,13 @@
 #include <gtkmm/stock.h>
 #include <glom/mode_design/print_layouts/dialog_text_formatting.h>
 #include <glom/mode_data/dialog_layout_list_related.h>
+
+//TODO: Remove these when we can just use a CanvasLayoutItem in a GooCanvasTable:
+#include <glom/utility_widgets/canvas/canvas_table_movable.h>
+#include <glom/utility_widgets/canvas/canvas_image_movable.h>
+#include <glom/utility_widgets/canvas/canvas_text_movable.h>
+#include <glom/libglom/data_structure/glomconversions.h>
+
 #include <glom/libglom/glade_utils.h>
 #include <glibmm/i18n.h>
 
@@ -543,19 +550,22 @@
   fill_with_data(m_items_group, found_set);
 }
 
-void Canvas_PrintLayout::fill_with_data(const Glib::RefPtr<Goocanvas::Group>& layout_group, const FoundSet& found_set)
+void Canvas_PrintLayout::fill_with_data(const Glib::RefPtr<Goocanvas::Group>& canvas_group, const FoundSet& found_set)
 {
   //A map of the text representation (e.g. field_name or relationship::field_name) to the index:
   typedef std::map<Glib::ustring, guint> type_map_layout_fields_index;
   type_map_layout_fields_index map_fields_index;
+
+  typedef std::list< sharedptr<LayoutItem_Portal> > type_list_portals;
+  type_list_portals list_portals;
   
   //Get list of fields to get from the database.
   Utils::type_vecLayoutFields fieldsToGet;
-  const int count = layout_group->get_n_children();
+  const int count = canvas_group->get_n_children();
   guint field_i = 0;
   for(int i = 0; i < count; ++i)
   {
-    Glib::RefPtr<Goocanvas::Item> base_canvas_item = layout_group->get_child(i);
+    Glib::RefPtr<Goocanvas::Item> base_canvas_item = canvas_group->get_child(i);
     Glib::RefPtr<CanvasLayoutItem> canvas_item = Glib::RefPtr<CanvasLayoutItem>::cast_dynamic(base_canvas_item);
     if(!canvas_item)
       continue;
@@ -578,7 +588,16 @@
     {
       sharedptr<LayoutItem_Portal> layoutitem_portal = sharedptr<LayoutItem_Portal>::cast_dynamic(layout_item);
       if(layoutitem_portal)
-        fill_with_data(canvas_item, found_set);
+      {
+        //Fill the related records table:
+        sharedptr<Relationship> relationship = layoutitem_portal->get_relationship();
+        if(relationship)
+        {
+          sharedptr<Field> from_field = get_fields_for_table_one_field(relationship->get_from_table(), relationship->get_from_field());
+          const Gnome::Gda::Value from_key_value = get_field_value_in_database(from_field, found_set, 0 /* TODO: window */);
+          fill_with_data_portal(canvas_item, from_key_value);
+        }
+      }
     }
   }
 
@@ -623,7 +642,7 @@
   //(and clear the no-image pixbuf from images):
   for(int i = 0; i < count; ++i)
   {
-    Glib::RefPtr<Goocanvas::Item> base_canvas_item = layout_group->get_child(i);
+    Glib::RefPtr<Goocanvas::Item> base_canvas_item = canvas_group->get_child(i);
     Glib::RefPtr<CanvasLayoutItem> canvas_item = Glib::RefPtr<CanvasLayoutItem>::cast_dynamic(base_canvas_item);
     if(!canvas_item)
       continue;
@@ -653,9 +672,117 @@
 }
 
 
-void Canvas_PrintLayout::fill_with_data_portal(const sharedptr<CanvasLayoutItem>& layout_portal, const FoundSet& found_set)
+void Canvas_PrintLayout::fill_with_data_portal(const Glib::RefPtr<CanvasLayoutItem>& canvas_item, const Gnome::Gda::Value& foreign_key_value)
 {
-  //TODO.
+  if(!canvas_item)
+    return;
+
+  sharedptr<LayoutItem> layout_item = canvas_item->get_layout_item();
+  sharedptr<LayoutItem_Portal> portal = sharedptr<LayoutItem_Portal>::cast_dynamic(layout_item);
+  if(!portal)
+    return;
+
+  Glib::RefPtr<CanvasTableMovable> canvas_table = Glib::RefPtr<CanvasTableMovable>::cast_dynamic(canvas_item->get_child());
+  if(!canvas_table)
+    return;
+
+  //TODO: When goocanvas supports groups (and therefore Glom::CanvasLayoutItem)
+  //in table cells, simplify this code by just setting the values of those
+  //existing items:
+  //
+  //Remove all existing cells, so we can recreate them:
+  //TODO: Add a function to goocanvas for this.
+  //TODO: Move the child stuff into group in goocanvas.
+
+  LayoutGroup::type_list_items child_layout_items = portal->get_items();
+  
+  //Build and run the SQL query for this portal:
+  type_vecLayoutFields fields_shown = get_portal_fields_to_show(portal);
+
+  FoundSet found_set;
+  found_set.m_table_name = portal->get_table_used(Glib::ustring() /* parent table_name, not used. */);
+  set_found_set_where_clause_for_portal(found_set, portal, foreign_key_value);
+
+  const Glib::ustring sql_query = Utils::build_sql_select_with_where_clause(found_set.m_table_name, fields_shown, found_set.m_where_clause, found_set.m_extra_join, found_set.m_sort_clause, found_set.m_extra_group_by);
+  //std::cout << "DEBUG: sql_query=" << sql_query << std::endl;
+  Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute(sql_query, 0 /* TODO: get_app_window() */);
+  if(!(datamodel))
+    return;
+    
+  const int db_rows_count = datamodel->get_n_rows();
+  if(!(db_rows_count > 0))
+    return;
+    
+  const int db_columns_count = datamodel->get_n_columns();
+  if(!db_columns_count)
+    return;
+
+  double row_height_ignored = 0;
+  const int rows_count = CanvasLayoutItem::get_rows_count_for_portal(portal, row_height_ignored);
+  const int cols_count = child_layout_items.size();
+
+  //Set the DB value for each cell:
+  for(int row = 0; row < rows_count; ++row)
+  {
+    int db_col = 0;
+    LayoutGroup::type_list_items::iterator iter_child_layout_items = child_layout_items.begin();
+    for(int col = 0; col < cols_count; ++col)
+    {
+      //Glib::RefPtr<Goocanvas::Item> canvas_child = base_item->get_cell_child(row, col); //TODO: Add this to GooCanvas::Table.
+      Glib::RefPtr<Goocanvas::Item> canvas_child = get_canvas_table_cell_child(canvas_table, row, col); //TODO: Add this to GooCanvas::Table.
+      if(!canvas_child)
+        std::cerr << "Canvas_PrintLayout::fill_with_data_portal(): canvas_child is NULL." << std::endl;
+
+      if(iter_child_layout_items == child_layout_items.end())
+        continue;
+      
+      sharedptr<LayoutItem> child_layout_item = *iter_child_layout_items;
+      sharedptr<LayoutItem_Field> field = sharedptr<LayoutItem_Field>::cast_dynamic(child_layout_item);
+      if(field)
+      {
+        Gnome::Gda::Value db_value;
+        if( row < datamodel->get_n_rows() )
+          db_value = datamodel->get_value_at(db_col, row);
+          
+        set_canvas_item_field_value(canvas_child, field, db_value);
+        ++db_col;
+      }
+
+      ++iter_child_layout_items;
+    }
+  }
+}
+
+void Canvas_PrintLayout::set_canvas_item_field_value(const Glib::RefPtr<Goocanvas::Item> canvas_item, const sharedptr<LayoutItem_Field> field, const Gnome::Gda::Value& value)
+{
+  if(!field)
+    return;
+
+  //Expect the appropriate canvas item, depending on the field type:
+  if(field->get_glom_type() == Field::TYPE_IMAGE)
+  {
+    Glib::RefPtr<CanvasImageMovable> canvas_image = Glib::RefPtr<CanvasImageMovable>::cast_dynamic(canvas_item);
+    if(!canvas_image)
+      return;
+
+    Glib::RefPtr<Gdk::Pixbuf> pixbuf = Conversions::get_pixbuf_for_gda_value(value);
+    canvas_image->property_pixbuf() = pixbuf;
+  }
+  else //text, numbers, date, time, boolean:
+  {
+  	Glib::RefPtr<CanvasTextMovable> canvas_text = Glib::RefPtr<CanvasTextMovable>::cast_dynamic(canvas_item);
+    if(!canvas_text)
+    {
+      std::cerr << "Canvas_PrintLayout::set_canvas_item_field_value(): The canvas item is not of the expected type. Instead it is of type." << std::endl;
+      return;
+    }
+
+    //FieldFormatting& formatting = field->m_formatting;
+    //check_and_apply_formatting(canvas_item, formatting);
+    const Glib::ustring text = 
+      Conversions::get_text_for_gda_value(field->get_glom_type(), value, field->m_formatting.m_numeric_format);
+    canvas_text->set_text(text);
+  }
 }
 
 void Canvas_PrintLayout::set_zoom_percent(guint percent)
@@ -693,6 +820,76 @@
     m_bounds_group->lower();
 }
 
+Glib::RefPtr<Goocanvas::Item> Canvas_PrintLayout::get_canvas_table_cell_child(const Glib::RefPtr<Goocanvas::Table>& table, int row, int col)
+{
+  Glib::RefPtr<Goocanvas::Item> result;
+
+  if(!table)
+    return result;
+
+  const int count = table->get_n_children();
+  for(int i = 0; i < count; ++i)
+  {
+    Glib::RefPtr<Goocanvas::Item> child = table->get_child(i);
+    if(!child)
+      continue;
+
+    Glib::Value<int> column_value;
+    column_value.init( Glib::Value<int>::value_type() );
+    table->get_child_property(child, "column", column_value);
+
+    Glib::Value<int> row_value;
+    row_value.init( Glib::Value<int>::value_type() );
+    table->get_child_property(child, "row", row_value);
+       
+    //This assumes that all items occupy only one cell:
+    if( (column_value.get() == col) &&
+        (row_value.get() == row) )
+    {
+      return child;
+    }
+  }
+
+  return result;
+}
+
+
+
+Base_DB::type_vecLayoutFields Canvas_PrintLayout::get_portal_fields_to_show(const sharedptr<LayoutItem_Portal>& portal)
+{
+  const Document_Glom* document = get_document();
+  if(!document)
+    std::cerr << "Canvas_PrintLayout::get_portal_fields_to_show(): document is NULL." << std::endl;
+
+  if(document && portal)
+  {
+    Document_Glom::type_list_layout_groups mapGroups;
+    mapGroups.push_back(portal);
+
+    sharedptr<const Relationship> relationship = portal->get_relationship();
+    if(relationship)
+    {
+      type_vecLayoutFields result = get_table_fields_to_show_for_sequence(portal->get_table_used(Glib::ustring() /* not relevant */), mapGroups);
+
+      //If the relationship does not allow editing, then mark all these fields as non-editable:
+      if(!(portal->get_relationship_used_allows_edit()))
+      {
+        for(type_vecLayoutFields::iterator iter = result.begin(); iter != result.end(); ++iter)
+        {
+          sharedptr<LayoutItem_Field> item = *iter;
+          if(item)
+            item->set_editable(false);
+        }
+      }
+
+      return result;
+    }
+  }
+
+  return type_vecLayoutFields();
+}
+
+
 } //namespace Glom
 
 

Modified: trunk/glom/mode_design/print_layouts/canvas_print_layout.h
==============================================================================
--- trunk/glom/mode_design/print_layouts/canvas_print_layout.h	(original)
+++ trunk/glom/mode_design/print_layouts/canvas_print_layout.h	Wed Oct  8 16:42:11 2008
@@ -71,8 +71,14 @@
   void add_layout_group_children(const sharedptr<LayoutGroup>& group);
   void fill_layout_group(const sharedptr<LayoutGroup>& group);
 
-  static void fill_with_data(const Glib::RefPtr<Goocanvas::Group>& layout_group, const FoundSet& found_set);
-  static void fill_with_data_portal(const sharedptr<CanvasLayoutItem>& layout_portal, const FoundSet& found_set);
+  //These are not static, because they need access to the document:
+  void fill_with_data(const Glib::RefPtr<Goocanvas::Group>& canvas_group, const FoundSet& found_set);
+  void fill_with_data_portal(const Glib::RefPtr<CanvasLayoutItem>& canvas_item, const Gnome::Gda::Value& foreign_key_value);
+  static void set_canvas_item_field_value(const Glib::RefPtr<Goocanvas::Item> canvas_item, const sharedptr<LayoutItem_Field> field, const Gnome::Gda::Value& value);
+
+  static Glib::RefPtr<Goocanvas::Item> get_canvas_table_cell_child(const Glib::RefPtr<Goocanvas::Table>& table, int row, int col); //TODO: Add this to GooCanvas::Table.
+  
+  type_vecLayoutFields get_portal_fields_to_show(const sharedptr<LayoutItem_Portal>& portal);
 
   sharedptr<LayoutItem_Portal> offer_related_records(const sharedptr<LayoutItem_Portal>& portal, Gtk::Window* parent);
 

Modified: trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.cc
==============================================================================
--- trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.cc	(original)
+++ trunk/glom/utility_widgets/db_adddel/glom_db_treemodel.cc	Wed Oct  8 16:42:11 2008
@@ -440,6 +440,9 @@
 #endif // GLIBMM_EXCEPTIONS_ENABLED
   }
 
+  if(m_found_set.m_table_name.empty())
+    std::cerr << "DEBUG: refresh_from_database(): found_set.m_table_name is empty." << std::endl;
+    
   if(m_connection && !m_found_set.m_table_name.empty() && m_get_records)
   {
     const Glib::ustring sql_query = Utils::build_sql_select_with_where_clause(m_found_set.m_table_name, m_column_fields, m_found_set.m_where_clause, m_found_set.m_extra_join, m_found_set.m_sort_clause, m_found_set.m_extra_group_by);

Modified: trunk/po/Makefile.in.in
==============================================================================
--- trunk/po/Makefile.in.in	(original)
+++ trunk/po/Makefile.in.in	Wed Oct  8 16:42:11 2008
@@ -54,16 +54,16 @@
 
 ALL_LINGUAS = @ALL_LINGUAS@
 
-PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; fi)
+PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; else echo "$(ALL_LINGUAS)"; fi)
 
 USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep ^$$lang$$ $(srcdir)/LINGUAS 2>/dev/null`" -o -n "`echo $$ALINGUAS|tr ' ' '\n'|grep ^$$lang$$`"; then printf "$$lang "; fi; done; fi)
 
 USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)" -o -n "$(LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done)
 
-POFILES=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done)
+POFILES=$(shell LINGUAS="$(PO_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done)
 
-DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(POFILES)
-EXTRA_DISTFILES = POTFILES.skip Makevars LINGUAS
+DISTFILES = Makefile.in.in POTFILES.in $(POFILES)
+EXTRA_DISTFILES = ChangeLog POTFILES.skip Makevars LINGUAS
 
 POTFILES = \
 # This comment gets stripped out



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