[glom] Related Records: Correct automatic navigation to related relationships.



commit a545e2acd0a6155ced84f66c54a9b463a751047c
Author: Murray Cumming <murrayc murrayc com>
Date:   Mon Sep 12 11:56:14 2011 +0200

    Related Records: Correct automatic navigation to related relationships.
    
    * glom/base_db.[h|cc]: get_portal_navigation_relationship_automatic():
      Remove the unused (well, should have been unused) navigation_main output
      parameter.
      Document the method so we know what the parameters and result really mean.
      In particular, a empty result means that the portal's regular relationship
      should just be used.
    * glom/mode_data/box_data_portal.[h|cc]: get_suitable_table_to_view_details():
    Document its parameters so we know what table the relationship belongs to,
    if any relationship is even needed.
    Use get_navigation_relationship_specific() if specified and correct the
    logic so that the correct table is always used.
    get_suitable_record_to_view_details(): Document this too.
    * glom/mode_design/layout/dialog_layout_calendar_related.cc: update_ui():
    * glom/mode_design/layout/dialog_layout_list_related.cc: update_ui():
    Adapted.

 ChangeLog                                          |   20 +++++++++++
 glom/base_db.cc                                    |    8 +---
 glom/base_db.h                                     |    6 ++--
 glom/mode_data/box_data_portal.cc                  |   36 +++++++++++++------
 glom/mode_data/box_data_portal.h                   |   15 ++++++++
 glom/mode_data/flowtablewithfields.cc              |    1 +
 .../layout/dialog_layout_calendar_related.cc       |   10 ++----
 .../layout/dialog_layout_list_related.cc           |   11 ++----
 8 files changed, 72 insertions(+), 35 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 3595fa0..197ae9a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2011-09-12  Murray Cumming  <murrayc murrayc com>
+
+	Related Records: Correct automatic navigation to related relationships.
+
+	* glom/base_db.[h|cc]: get_portal_navigation_relationship_automatic():
+  Remove the unused (well, should have been unused) navigation_main output
+  parameter.
+  Document the method so we know what the parameters and result really mean.
+  In particular, a empty result means that the portal's regular relationship
+  should just be used.
+	* glom/mode_data/box_data_portal.[h|cc]: get_suitable_table_to_view_details():
+	Document its parameters so we know what table the relationship belongs to, 
+	if any relationship is even needed.
+	Use get_navigation_relationship_specific() if specified and correct the 
+	logic so that the correct table is always used.
+	get_suitable_record_to_view_details(): Document this too.
+	* glom/mode_design/layout/dialog_layout_calendar_related.cc: update_ui():
+	* glom/mode_design/layout/dialog_layout_list_related.cc: update_ui():
+	Adapted.
+
 2011-09-09  Murray Cumming  <murrayc murrayc com>
 
 	ComboGlom::set_value(): Do not cause a change to be signalled.
diff --git a/glom/base_db.cc b/glom/base_db.cc
index 9a4e8fb..bad14ed 100644
--- a/glom/base_db.cc
+++ b/glom/base_db.cc
@@ -1690,11 +1690,8 @@ sharedptr<const LayoutItem_Field> Base_DB::get_field_identifies_non_hidden_relat
   return result;
 }
 
-sharedptr<const UsesRelationship> Base_DB::get_portal_navigation_relationship_automatic(const sharedptr<LayoutItem_Portal>& portal, bool& navigation_main) const
+sharedptr<const UsesRelationship> Base_DB::get_portal_navigation_relationship_automatic(const sharedptr<LayoutItem_Portal>& portal) const
 {
-  //Initialize output parameters:
-  navigation_main = false;
-
   const Document* document = get_document();
 
   //If the related table is not hidden then we can just navigate to that:
@@ -1702,7 +1699,6 @@ sharedptr<const UsesRelationship> Base_DB::get_portal_navigation_relationship_au
   if(!(document->get_table_is_hidden(direct_related_table_name)))
   {
     //Non-hidden tables can just be shown directly. Navigate to it:
-    navigation_main = true;
     return sharedptr<UsesRelationship>();
   }
   else
@@ -1712,7 +1708,7 @@ sharedptr<const UsesRelationship> Base_DB::get_portal_navigation_relationship_au
     sharedptr<const LayoutItem_Field> field = get_field_is_from_non_hidden_related_record(portal);
     if(field)
     {
-      return field; //Returns the relationship part. (A relationship belonging to the portal's related table.)
+      return field; //Returns the UsesRelationship base part. (A relationship belonging to the portal's related table.)
       //sharedptr<UsesRelationship> result = sharedptr<UsesRelationship>::create();
       //result->set_relationship( portal->get_relationship() );
       //result->set_related_relationship( field->get_relationship() );
diff --git a/glom/base_db.h b/glom/base_db.h
index d2e8aca..cf945ab 100644
--- a/glom/base_db.h
+++ b/glom/base_db.h
@@ -303,11 +303,11 @@ protected:
   type_vecConstLayoutFields get_table_fields_to_show_for_sequence(const Glib::ustring& table_name, const Document::type_list_layout_groups& mapGroupSequence) const;
   void get_table_fields_to_show_for_sequence_add_group(const Glib::ustring& table_name, const Privileges& table_privs, const type_vec_fields& all_db_fields, const sharedptr<LayoutGroup>& group, type_vecConstLayoutFields& vecFields) const;
 
-  /** Get the relationship into which the row button should navigate,
-   * or the relationship itself, if the navigation_main output parameter is set to true after calling this method.
+  /** Get the relationship (from the related table) into which the row button should navigate,
+   * or none if it should use the portal's directly related table itself.
    * (If that should be chosen automatically, by looking at the fields in the portal.)
    */
-  sharedptr<const UsesRelationship> get_portal_navigation_relationship_automatic(const sharedptr<LayoutItem_Portal>& portal, bool& navigation_main) const;
+  sharedptr<const UsesRelationship> get_portal_navigation_relationship_automatic(const sharedptr<LayoutItem_Portal>& portal) const;
   sharedptr<const LayoutItem_Field> get_field_is_from_non_hidden_related_record(const sharedptr<const LayoutItem_Portal>& portal) const;
   sharedptr<const LayoutItem_Field> get_field_identifies_non_hidden_related_record(const sharedptr<const LayoutItem_Portal>& portal, sharedptr<const Relationship>& used_in_relationship) const;
 
diff --git a/glom/mode_data/box_data_portal.cc b/glom/mode_data/box_data_portal.cc
index b13ce87..fd6d1c8 100644
--- a/glom/mode_data/box_data_portal.cc
+++ b/glom/mode_data/box_data_portal.cc
@@ -269,7 +269,7 @@ void Box_Data_Portal::on_dialog_layout_hide()
 bool Box_Data_Portal::get_has_suitable_record_to_view_details() const
 {
   Glib::ustring navigation_table_name;
-  sharedptr<const UsesRelationship> navigation_relationship;
+  sharedptr<const UsesRelationship> navigation_relationship; //Ignored.
   get_suitable_table_to_view_details(navigation_table_name, navigation_relationship);
 
   return !(navigation_table_name.empty());
@@ -284,19 +284,24 @@ void Box_Data_Portal::get_suitable_table_to_view_details(Glib::ustring& table_na
     return;
 
 
-  sharedptr<const UsesRelationship> navigation_relationship = m_portal->get_navigation_relationship_specific();
+  sharedptr<const UsesRelationship> navigation_relationship;
 
   //Check whether a relationship was specified:
   if(m_portal->get_navigation_type() == LayoutItem_Portal::NAVIGATION_AUTOMATIC)
   {
     //std::cout << "debug: decide automatically." << std::endl;
     //Decide automatically:
-    bool navigation_relationship_main = false; // no longer used
-    navigation_relationship = get_portal_navigation_relationship_automatic(m_portal, navigation_relationship_main);
-    //std::cout << "debug: auto main=" << navigation_relationship_main << ", navigation_relationship=" << (navigation_relationship ? navigation_relationship->get_name() : navigation_relationship->get_relationship()->get_name()) << std::endl;
+    navigation_relationship = get_portal_navigation_relationship_automatic(m_portal);
+    //if(navigation_relationship && navigation_relationship->get_relationship())
+    //  std::cout << "  navigation_relationship->get_relationship()=" <<  navigation_relationship->get_relationship()->get_name() << std::endl;
+    //if(navigation_relationship && navigation_relationship->get_related_relationship())
+    //  std::cout << "  navigation_relationship->get_related_relationship()=" <<  navigation_relationship->get_related_relationship()->get_name() << std::endl;
+  }
+  else
+  {
+    navigation_relationship = m_portal->get_navigation_relationship_specific();
+    //std::cout << "debug: " << G_STRFUNC << ": Using specific nav." << std::endl;
   }
-  //else
-  //  std::cout << "debug: " << G_STRFUNC << ": Using specific nav." << std::endl;
 
   const Document* document = get_document();
   if(!document)
@@ -309,13 +314,15 @@ void Box_Data_Portal::get_suitable_table_to_view_details(Glib::ustring& table_na
   // The navigation_table_name (and therefore, the table_name output parameter,
   // as well) stays empty if the navrel type was set to none.
   Glib::ustring navigation_table_name;
-  if(m_portal->get_navigation_type() == LayoutItem_Portal::NAVIGATION_AUTOMATIC)
+  if(navigation_relationship)
   {
-    navigation_table_name = directly_related_table_name;
+    navigation_table_name = navigation_relationship->get_table_used(directly_related_table_name);
   }
-  else if(m_portal->get_navigation_type() == LayoutItem_Portal::NAVIGATION_SPECIFIC)
+  else if(m_portal->get_navigation_type() != LayoutItem_Portal::NAVIGATION_NONE)
   {
-    navigation_table_name = navigation_relationship->get_table_used(directly_related_table_name);
+    //An empty result from get_portal_navigation_relationship_automatic() or 
+    //get_navigation_relationship_specific() means we should use the directly related table:
+    navigation_table_name = directly_related_table_name;
   }
 
   if(navigation_table_name.empty())
@@ -343,6 +350,11 @@ void Box_Data_Portal::get_suitable_record_to_view_details(const Gnome::Gda::Valu
   Glib::ustring navigation_table_name;
   sharedptr<const UsesRelationship> navigation_relationship;
   get_suitable_table_to_view_details(navigation_table_name, navigation_relationship);
+  
+  //if(navigation_relationship && navigation_relationship->get_relationship())
+  //  std::cout << "debug: navigation_relationship=" << navigation_relationship->get_relationship()->get_name() << std::endl;
+  //if(navigation_relationship && navigation_relationship->get_related_relationship())
+  //  std::cout << "debug: navigation_related_relationship=" << navigation_relationship->get_related_relationship()->get_name() << std::endl;
 
   if(navigation_table_name.empty())
     return;
@@ -368,7 +380,7 @@ void Box_Data_Portal::get_suitable_record_to_view_details(const Gnome::Gda::Valu
   //For instance "invoice_line_id" if this is a portal to an "invoice_lines" table:
   const Glib::ustring related_table = m_portal->get_table_used(Glib::ustring() /* not relevant */);
   sharedptr<const Field> key_field = get_field_primary_key_for_table(related_table);
-  //std::cout << "DEBUG: related table=" << related_table << ", whose primary_key=" << key_field->get_name() << std::endl;
+  //std::cout << "DEBUG: related table=" << related_table << ", whose primary_key=" << key_field->get_name() << ", with value=" << primary_key_value.to_string() << "getting value for: " << layout_item->get_layout_display_name() << std::endl;
 
   Glib::RefPtr<Gnome::Gda::SqlBuilder> query = Utils::build_sql_select_with_key(related_table, fieldsToGet, key_field, primary_key_value);
   Glib::RefPtr<const Gnome::Gda::DataModel> data_model = DbUtils::query_execute_select(query);
diff --git a/glom/mode_data/box_data_portal.h b/glom/mode_data/box_data_portal.h
index de59ffa..71e1aa1 100644
--- a/glom/mode_data/box_data_portal.h
+++ b/glom/mode_data/box_data_portal.h
@@ -71,7 +71,22 @@ public:
   type_signal_portal_record_changed signal_portal_record_changed();
     
   bool get_has_suitable_record_to_view_details() const;
+
+  /** Discover what table to show when clicking on a related record.
+   * This table will not necessarily just be the directly related table.
+   *
+   * @param table_name The table that should be shown.
+   * @param relationship The relationship in the directly related table that should be used to get to that table. If this is empty then we should just show the table directly.
+   */
   void get_suitable_table_to_view_details(Glib::ustring& table_name, sharedptr<const UsesRelationship>& relationship) const;
+
+  /** Discover what record to show, in what table, when clicking on a related record.
+   * This record will not necessarily just be the directly related record.
+   *
+   * @param primary_key_value Identifies the related record that has been clicked.
+   * @param table_name The table that should be shown.
+   * @param table_primary_key_value Identifies the record in that table that should be shown.
+   */
   void get_suitable_record_to_view_details(const Gnome::Gda::Value& primary_key_value, Glib::ustring& table_name, Gnome::Gda::Value& table_primary_key_value) const;
 
 protected:
diff --git a/glom/mode_data/flowtablewithfields.cc b/glom/mode_data/flowtablewithfields.cc
index 8d16fef..3ffe17c 100644
--- a/glom/mode_data/flowtablewithfields.cc
+++ b/glom/mode_data/flowtablewithfields.cc
@@ -1211,6 +1211,7 @@ void FlowTableWithFields::on_flowtable_related_record_changed(const Glib::ustrin
   signal_related_record_changed().emit(relationship_name);
 }
 
+//TODO: Use Value by const &
 void FlowTableWithFields::on_portal_user_requested_details(Gnome::Gda::Value primary_key_value, Box_Data_Portal* portal_box)
 {
   sharedptr<const LayoutItem_Portal> portal = portal_box->get_portal();
diff --git a/glom/mode_design/layout/dialog_layout_calendar_related.cc b/glom/mode_design/layout/dialog_layout_calendar_related.cc
index 13481e3..ef54f98 100644
--- a/glom/mode_design/layout/dialog_layout_calendar_related.cc
+++ b/glom/mode_design/layout/dialog_layout_calendar_related.cc
@@ -226,16 +226,12 @@ void Dialog_Layout_Calendar_Related::update_ui(bool including_relationship_list)
 
   //Describe the automatic navigation:
   sharedptr<const UsesRelationship> relationship_navigation_automatic;
-  bool navigation_automatic_main = false;
-  relationship_navigation_automatic = get_portal_navigation_relationship_automatic(m_portal, navigation_automatic_main);
+  relationship_navigation_automatic = get_portal_navigation_relationship_automatic(m_portal);
   Glib::ustring automatic_navigation_description;
 
-  if(navigation_automatic_main)
-    automatic_navigation_description = m_portal->get_relationship_name_used();
-  else if(relationship_navigation_automatic)
+  automatic_navigation_description = m_portal->get_relationship_name_used();
+  if(relationship_navigation_automatic)
   {
-    automatic_navigation_description = m_portal->get_relationship_name_used();
-
     if(relationship_navigation_automatic->get_has_relationship_name())
       automatic_navigation_description += ("::" + relationship_navigation_automatic->get_relationship_name());
 
diff --git a/glom/mode_design/layout/dialog_layout_list_related.cc b/glom/mode_design/layout/dialog_layout_list_related.cc
index 181c245..3ffc777 100644
--- a/glom/mode_design/layout/dialog_layout_list_related.cc
+++ b/glom/mode_design/layout/dialog_layout_list_related.cc
@@ -265,16 +265,13 @@ void Dialog_Layout_List_Related::update_ui(bool including_relationship_list)
   }
 
   //Describe the automatic navigation:
-  sharedptr<const UsesRelationship> relationship_navigation_automatic;
-  bool navigation_automatic_main = false;
-  relationship_navigation_automatic = get_portal_navigation_relationship_automatic(m_portal, navigation_automatic_main);
+  sharedptr<const UsesRelationship> relationship_navigation_automatic = get_portal_navigation_relationship_automatic(m_portal);
   Glib::ustring automatic_navigation_description;
 
-  if(navigation_automatic_main)
-    automatic_navigation_description = m_portal->get_relationship_name_used();
-  else if(relationship_navigation_automatic)
+  automatic_navigation_description = m_portal->get_relationship_name_used();
+  if(relationship_navigation_automatic) //This is a relationship in the related table.
   {
-    automatic_navigation_description = m_portal->get_relationship_name_used();
+    //TODO: Put this in UsesRelationship so we can use it elsewhere too?
 
     if(relationship_navigation_automatic->get_has_relationship_name())
       automatic_navigation_description += ("::" + relationship_navigation_automatic->get_relationship_name());



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