[glom] In progress sortby choices



commit 352da279e1f8a0270d9d8deacb1d937ad5d5f35b
Author: Murray Cumming <murrayc murrayc com>
Date:   Thu Dec 29 00:17:32 2011 +0100

    In progress sortby choices

 Makefile.am                                        |    2 +-
 Makefile_glom.am                                   |    4 +-
 glom/libglom/data_structure/foundset.h             |    1 +
 .../data_structure/layout/fieldformatting.cc       |    9 +-
 .../data_structure/layout/fieldformatting.h        |   13 ++-
 .../layout/report_parts/layoutitem_groupby.h       |    4 +-
 glom/libglom/document/document.cc                  |   30 +++-
 glom/libglom/utils.cc                              |   31 ++++-
 glom/libglom/utils.h                               |    4 +
 glom/mode_data/datawidget/cellcreation.cc          |    5 +-
 .../mode_data/datawidget/combo_as_radio_buttons.cc |    3 +-
 .../datawidget/combochoiceswithtreemodel.cc        |   15 +-
 .../layout/layout_item_dialogs/box_formatting.cc   |   71 ++++++++-
 .../layout/layout_item_dialogs/box_formatting.h    |    5 +
 .../layout/layout_item_dialogs/dialog_group_by.cc  |   17 +--
 .../layout/layout_item_dialogs/dialog_group_by.h   |    4 +-
 ..._groupby_sortfields.cc => dialog_sortfields.cc} |   46 +++---
 ...og_groupby_sortfields.h => dialog_sortfields.h} |   12 +-
 po/POTFILES.in                                     |    4 +-
 tests/test_glade_derived_instantiation.cc          |    4 +-
 ui/developer/box_formatting.glade                  |   61 +++++++-
 ..._sort_fields.glade => dialog_sort_fields.glade} |  162 ++++++++++++--------
 22 files changed, 357 insertions(+), 150 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 7d707cc..2fd53d4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -133,7 +133,6 @@ dist_glade_developer_DATA = ui/developer/dialog_add_related_table.glade \
 	ui/developer/dialog_field_summary.glade \
 	ui/developer/dialog_flowtable.glade \
 	ui/developer/dialog_group_by.glade \
-	ui/developer/dialog_groupby_sort_fields.glade \
 	ui/developer/dialog_initial_password.glade \
 	ui/developer/dialog_line.glade \
 	ui/developer/dialog_layout_field_properties.glade \
@@ -142,6 +141,7 @@ dist_glade_developer_DATA = ui/developer/dialog_add_related_table.glade \
 	ui/developer/dialog_notebook.glade \
 	ui/developer/dialog_relationships_overview.glade \
 	ui/developer/dialog_script_library.glade \
+	ui/developer/dialog_sort_fields.glade \
 	ui/developer/dialog_translation_copy.glade \
 	ui/developer/dialog_translation_identify_original.glade \
 	ui/developer/dialog_user.glade \
diff --git a/Makefile_glom.am b/Makefile_glom.am
index ce853b6..e59d9f6 100644
--- a/Makefile_glom.am
+++ b/Makefile_glom.am
@@ -322,14 +322,14 @@ glom_source_files +=							\
 	glom/mode_design/layout/layout_item_dialogs/dialog_group_by.h			\
 	glom/mode_design/layout/layout_item_dialogs/dialog_fieldslist.cc	\
 	glom/mode_design/layout/layout_item_dialogs/dialog_fieldslist.h	\
-	glom/mode_design/layout/layout_item_dialogs/dialog_groupby_sortfields.cc	\
-	glom/mode_design/layout/layout_item_dialogs/dialog_groupby_sortfields.h		\
 	glom/mode_design/layout/layout_item_dialogs/dialog_imageobject.cc		\
 	glom/mode_design/layout/layout_item_dialogs/dialog_imageobject.h		\
 	glom/mode_design/layout/layout_item_dialogs/dialog_line.cc		\
 	glom/mode_design/layout/layout_item_dialogs/dialog_line.h			\
 	glom/mode_design/layout/layout_item_dialogs/dialog_notebook.cc			\
 	glom/mode_design/layout/layout_item_dialogs/dialog_notebook.h			\
+	glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.cc	\
+	glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.h		\
 	glom/mode_design/layout/layout_item_dialogs/dialog_textobject.cc		\
 	glom/mode_design/layout/layout_item_dialogs/dialog_textobject.h			\
 	glom/mode_design/relationships_overview/canvas_group_dbtable.cc			\
diff --git a/glom/libglom/data_structure/foundset.h b/glom/libglom/data_structure/foundset.h
index 2eb610d..0ffab3c 100644
--- a/glom/libglom/data_structure/foundset.h
+++ b/glom/libglom/data_structure/foundset.h
@@ -47,6 +47,7 @@ public:
   sharedptr<const Relationship> m_extra_join; // Only used for doubly-related related records (portals), in which case the WHERE clause is also slightly different.
   Gnome::Gda::SqlExpr m_where_clause;
 
+  //TODO: Avoid duplication with types in FieldFormatting.
   ///field, ascending
   typedef std::pair< sharedptr<const LayoutItem_Field>, bool> type_pair_sort_field;
   typedef std::list<type_pair_sort_field> type_sort_clause;
diff --git a/glom/libglom/data_structure/layout/fieldformatting.cc b/glom/libglom/data_structure/layout/fieldformatting.cc
index 3cdb2cf..72b310f 100644
--- a/glom/libglom/data_structure/layout/fieldformatting.cc
+++ b/glom/libglom/data_structure/layout/fieldformatting.cc
@@ -243,31 +243,34 @@ void FieldFormatting::set_has_related_choices(bool val)
   m_choices_related = val;
 }
 
-void FieldFormatting::set_choices_related(const sharedptr<const Relationship>& relationship, const sharedptr<LayoutItem_Field>& field, const sharedptr<LayoutGroup>& extra_layout, bool show_all)
+void FieldFormatting::set_choices_related(const sharedptr<const Relationship>& relationship, const sharedptr<LayoutItem_Field>& field, const sharedptr<LayoutGroup>& extra_layout, const type_list_sort_fields& sort_fields, bool show_all)
 {
   set_relationship(relationship);
 
   m_choices_related_field = field;
   m_choices_extra_layout_group = extra_layout;
+  m_choices_related_sort_fields = sort_fields;
   m_choices_related_show_all = show_all;
 }
 
-void FieldFormatting::get_choices_related(sharedptr<const Relationship>& relationship, sharedptr<const LayoutItem_Field>& field, sharedptr<const LayoutGroup>& extra_layout, bool& show_all) const
+void FieldFormatting::get_choices_related(sharedptr<const Relationship>& relationship, sharedptr<const LayoutItem_Field>& field, sharedptr<const LayoutGroup>& extra_layout, type_list_sort_fields& sort_fields, bool& show_all) const
 {
   relationship = get_relationship();
 
   field = m_choices_related_field;
   extra_layout = m_choices_extra_layout_group;
+  sort_fields = m_choices_related_sort_fields;
   show_all = m_choices_related_show_all;
 }
 
 
-void FieldFormatting::get_choices_related(sharedptr<const Relationship>& relationship, sharedptr<LayoutItem_Field>& field, sharedptr<LayoutGroup>& extra_layout, bool& show_all)
+void FieldFormatting::get_choices_related(sharedptr<const Relationship>& relationship, sharedptr<LayoutItem_Field>& field, sharedptr<LayoutGroup>& extra_layout, type_list_sort_fields& sort_fields, bool& show_all)
 {
   relationship = get_relationship();
 
   field = m_choices_related_field;
   extra_layout = m_choices_extra_layout_group;
+  sort_fields = m_choices_related_sort_fields;
   show_all = m_choices_related_show_all;
 }
 
diff --git a/glom/libglom/data_structure/layout/fieldformatting.h b/glom/libglom/data_structure/layout/fieldformatting.h
index 810c24b..383193c 100644
--- a/glom/libglom/data_structure/layout/fieldformatting.h
+++ b/glom/libglom/data_structure/layout/fieldformatting.h
@@ -59,6 +59,9 @@ public:
   virtual type_list_values get_choices_custom() const;
   virtual void set_choices_custom(const type_list_values& choices);
 
+  typedef std::pair< sharedptr<const LayoutItem_Field>, bool /* is_ascending */> type_pair_sort_field;
+  typedef std::list<type_pair_sort_field> type_list_sort_fields;
+
   /** Discover whether the entered data should only be one of the available
    * choices.
    * @param [out] as_radio_buttons: Whether the choices should be displayed as
@@ -70,9 +73,12 @@ public:
    */
   void set_choices_restricted(bool val = true, bool as_radio_buttons = false);
 
-  void get_choices_related(sharedptr<const Relationship>& relationship, sharedptr<LayoutItem_Field>& field, sharedptr<LayoutGroup>& extra_layout, bool& show_all);
-  void get_choices_related(sharedptr<const Relationship>& relationship, sharedptr<const LayoutItem_Field>& field, sharedptr<const LayoutGroup>& extra_layout, bool& show_all) const;
-  void set_choices_related(const sharedptr<const Relationship>& relationship_name, const sharedptr<LayoutItem_Field>& field, const sharedptr<LayoutGroup>& extra_layout, bool show_all);
+  //TODO: Add a ChoicesRelated class?
+
+  
+  void get_choices_related(sharedptr<const Relationship>& relationship, sharedptr<LayoutItem_Field>& field, sharedptr<LayoutGroup>& extra_layout, type_list_sort_fields& sort_fields, bool& show_all);
+  void get_choices_related(sharedptr<const Relationship>& relationship, sharedptr<const LayoutItem_Field>& field, sharedptr<const LayoutGroup>& extra_layout, type_list_sort_fields& sort_fields, bool& show_all) const;
+  void set_choices_related(const sharedptr<const Relationship>& relationship_name, const sharedptr<LayoutItem_Field>& field, const sharedptr<LayoutGroup>& extra_layout, const type_list_sort_fields& sort_fields, bool show_all);
 
   //Just for convenience:
   sharedptr<const Relationship> get_choices_related_relationship(bool& show_all) const;
@@ -179,6 +185,7 @@ private:
 
   sharedptr<LayoutItem_Field> m_choices_related_field;
   sharedptr<LayoutGroup> m_choices_extra_layout_group;
+  type_list_sort_fields m_choices_related_sort_fields;
   bool m_choices_related_show_all;
 };
 
diff --git a/glom/libglom/data_structure/layout/report_parts/layoutitem_groupby.h b/glom/libglom/data_structure/layout/report_parts/layoutitem_groupby.h
index c97cbff..83e92ee 100644
--- a/glom/libglom/data_structure/layout/report_parts/layoutitem_groupby.h
+++ b/glom/libglom/data_structure/layout/report_parts/layoutitem_groupby.h
@@ -44,8 +44,8 @@ public:
 
   virtual LayoutItem* clone() const;
 
-  typedef std::pair< sharedptr<const LayoutItem_Field>, bool /* is_ascending */> type_pair_sort_field;
-  typedef std::list<type_pair_sort_field> type_list_sort_fields;
+  typedef FieldFormatting::type_pair_sort_field type_pair_sort_field;
+  typedef FieldFormatting::type_list_sort_fields type_list_sort_fields;
 
   sharedptr<LayoutItem_Field> get_field_group_by();
   sharedptr<const LayoutItem_Field> get_field_group_by() const;
diff --git a/glom/libglom/document/document.cc b/glom/libglom/document/document.cc
index 49985e5..d520f29 100644
--- a/glom/libglom/document/document.cc
+++ b/glom/libglom/document/document.cc
@@ -221,6 +221,7 @@ static const char GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_FIELD[] = "choices_relat
 static const char GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_EXTRA_LAYOUT[] = "choices_related_extra_layout";
 static const char GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SECOND[] = "choices_related_second"; //deprecated
 static const char GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SHOW_ALL[] = "choices_related_show_all";
+static const char GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SORTBY[] = "choices_related_sortby";
 
 static const char GLOM_NODE_TRANSLATIONS_SET[] = "trans_set";
 static const char GLOM_NODE_TRANSLATION[] = "trans";
@@ -1455,13 +1456,16 @@ void Document::fill_layout_field_details(const Glib::ustring& parent_table_name,
       sharedptr<const Relationship> choice_relationship;
       sharedptr<LayoutItem_Field> choice_layout_first;
       sharedptr<LayoutGroup> choice_extra_layouts;
+      FieldFormatting::type_list_sort_fields choice_sort_fields;
       bool choice_show_all = false;
-      layout_withformatting->m_formatting.get_choices_related(choice_relationship, choice_layout_first, choice_extra_layouts, choice_show_all);
+      layout_withformatting->m_formatting.get_choices_related(choice_relationship, choice_layout_first, choice_extra_layouts, choice_sort_fields, choice_show_all);
       
       const Glib::ustring table_name = (choice_relationship ? choice_relationship->get_to_table() : Glib::ustring());
       if(choice_layout_first)
         choice_layout_first->set_full_field_details( get_field(table_name, choice_layout_first->get_name()) );
       fill_layout_field_details(parent_table_name, choice_extra_layouts); //recurse
+
+      //TODO: Handle choice_sort_fields.
     }
 
     sharedptr<LayoutItem_Field> layout_field = sharedptr<LayoutItem_Field>::cast_dynamic(layout_item);
@@ -1475,13 +1479,16 @@ void Document::fill_layout_field_details(const Glib::ustring& parent_table_name,
         sharedptr<const Relationship> choice_relationship;
         sharedptr<LayoutItem_Field> choice_layout_first;
         sharedptr<LayoutGroup> choice_extra_layouts;
+        FieldFormatting::type_list_sort_fields choice_sort_fields;
         bool choice_show_all = false;
-        field->m_default_formatting.get_choices_related(choice_relationship, choice_layout_first, choice_extra_layouts, choice_show_all);
+        field->m_default_formatting.get_choices_related(choice_relationship, choice_layout_first, choice_extra_layouts, choice_sort_fields, choice_show_all);
         
         const Glib::ustring table_name = (choice_relationship ? choice_relationship->get_to_table() : Glib::ustring());
         if(choice_layout_first)
           choice_layout_first->set_full_field_details( get_field(table_name, choice_layout_first->get_name()) );
         fill_layout_field_details(parent_table_name, choice_extra_layouts); //recurse
+
+        //TODO: Handle choice_sort_fields.
       }
     }
     else
@@ -2115,8 +2122,16 @@ void Document::load_after_layout_item_formatting(const xmlpp::Element* element,
         }
       }
 
+      //Sort fields:
+      FieldFormatting::type_list_sort_fields sort_fields;
+      xmlpp::Element* elementSortBy = get_node_child_named(element, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SORTBY);
+      if(elementSortBy)
+      {
+        load_after_sort_by(elementSortBy, table_name, sort_fields);
+      }
+
       format.set_choices_related(relationship,
-        layout_field_first, extra_layouts,
+        layout_field_first, extra_layouts, sort_fields,
         show_all);
 
       //Full details are updated in filled-in ().
@@ -3210,8 +3225,9 @@ void Document::save_before_layout_item_formatting(xmlpp::Element* nodeItem, cons
     sharedptr<const Relationship> choice_relationship;
     sharedptr<const LayoutItem_Field> choice_layout_first;
     sharedptr<const LayoutGroup> choice_extra_layouts;
+    FieldFormatting::type_list_sort_fields choice_sort_fields;
     bool choice_show_all = false;
-    format.get_choices_related(choice_relationship, choice_layout_first, choice_extra_layouts, choice_show_all);
+    format.get_choices_related(choice_relationship, choice_layout_first, choice_extra_layouts, choice_sort_fields, choice_show_all);
 
     if(choice_relationship)
     {
@@ -3230,6 +3246,12 @@ void Document::save_before_layout_item_formatting(xmlpp::Element* nodeItem, cons
         xmlpp::Element* nodeGroups = nodeExtraLayout->add_child(GLOM_NODE_DATA_LAYOUT_GROUPS);
         save_before_layout_group(nodeGroups, choice_extra_layouts);
       }
+
+      if(!choice_sort_fields.empty())
+      {
+        xmlpp::Element* nodeSortBy = nodeItem->add_child(GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SORTBY);
+        save_before_sort_by(nodeSortBy, choice_sort_fields);
+      }
     }
   }
 }
diff --git a/glom/libglom/utils.cc b/glom/libglom/utils.cc
index 3b6259f..bb588dd 100644
--- a/glom/libglom/utils.cc
+++ b/glom/libglom/utils.cc
@@ -553,8 +553,9 @@ Utils::type_list_values_with_second Utils::get_choice_values(const Document* doc
   sharedptr<const Relationship> choice_relationship;
   sharedptr<const LayoutItem_Field> layout_choice_first;
   sharedptr<const LayoutGroup> layout_choice_extra;
+  FieldFormatting::type_list_sort_fields choice_sort_fields;
   bool choice_show_all = false;
-  format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_extra, choice_show_all);
+  format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_extra, choice_sort_fields, choice_show_all);
 
   if(!choice_relationship)
   {
@@ -586,8 +587,11 @@ Utils::type_list_values_with_second Utils::get_choice_values(const Document* doc
     std::cerr << G_STRFUNC << ": to_field is null." << std::endl;
   }
 
-  type_sort_clause sort_clause;
-  sort_clause.push_back( type_pair_sort_field(layout_choice_first, true /* ascending */));
+  //Default to some sort order rather than none:
+  if(choice_sort_fields.empty())
+  {
+    choice_sort_fields.push_back( type_pair_sort_field(layout_choice_first, true /* ascending */));
+  }
 
   //TODO: Support related relationships (in the UI too):
   Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Utils::build_sql_select_with_key(
@@ -595,7 +599,7 @@ Utils::type_list_values_with_second Utils::get_choice_values(const Document* doc
     fields,
     to_field,
     foreign_key_value,
-    sort_clause);
+    choice_sort_fields);
 
   if(!builder)
   {
@@ -1351,6 +1355,25 @@ Glib::ustring Utils::get_list_of_layout_items_for_display(const sharedptr<const
     return Glib::ustring();
 }
 
+Glib::ustring Utils::get_list_of_sort_fields_for_display(const FieldFormatting::type_list_sort_fields& sort_fields)
+{
+  Glib::ustring text;
+  for(FieldFormatting::type_list_sort_fields::const_iterator iter = sort_fields.begin(); iter != sort_fields.end(); ++iter)
+  {
+    const sharedptr<const LayoutItem_Field> item = iter->first;
+    if(!item)
+      continue;
+    
+    if(!text.empty())
+      text += ", ";
+
+    text += item->get_layout_display_name();
+    //TODO: Show Ascending/Descending?
+  }
+
+  return text;
+}
+
 std::string Utils::get_temp_file_path(const std::string& prefix, const std::string& extension)
 {
   //Get a temporary file path:
diff --git a/glom/libglom/utils.h b/glom/libglom/utils.h
index a19fbde..3f456c9 100644
--- a/glom/libglom/utils.h
+++ b/glom/libglom/utils.h
@@ -210,6 +210,10 @@ Glib::ustring get_list_of_layout_items_for_display(const LayoutGroup::type_list_
  */
 Glib::ustring get_list_of_layout_items_for_display(const sharedptr<const LayoutGroup>& layout_group);
 
+/** Get a string to display to the user, as a representation of a sort order
+ */
+Glib::ustring get_list_of_sort_fields_for_display(const FieldFormatting::type_list_sort_fields& sort_fields);
+
 std::string get_temp_file_path(const std::string& prefix = std::string(), const std::string& extension = std::string());
 Glib::ustring get_temp_file_uri(const std::string& prefix = std::string(), const std::string& extension = std::string());
 
diff --git a/glom/mode_data/datawidget/cellcreation.cc b/glom/mode_data/datawidget/cellcreation.cc
index 5d8e8a2..f3f6f05 100644
--- a/glom/mode_data/datawidget/cellcreation.cc
+++ b/glom/mode_data/datawidget/cellcreation.cc
@@ -211,9 +211,10 @@ Gtk::CellRenderer* create_cell(const sharedptr<const LayoutItem>& layout_item, c
     {
       sharedptr<const Relationship> choice_relationship;
       sharedptr<const LayoutItem_Field> choice_field;
-      sharedptr<const LayoutGroup> choice_extras;
+      sharedptr<const LayoutGroup> choice_extras; //Ignored
+      FieldFormatting::type_list_sort_fields choice_sort_fields; //Ignored
       bool choice_show_all = false;
-      item_field->get_formatting_used().get_choices_related(choice_relationship, choice_field, choice_extras, choice_show_all);
+      item_field->get_formatting_used().get_choices_related(choice_relationship, choice_field, choice_extras, choice_sort_fields, choice_show_all);
 
       if(choice_relationship && choice_field)
       {
diff --git a/glom/mode_data/datawidget/combo_as_radio_buttons.cc b/glom/mode_data/datawidget/combo_as_radio_buttons.cc
index 157555f..2ee500d 100644
--- a/glom/mode_data/datawidget/combo_as_radio_buttons.cc
+++ b/glom/mode_data/datawidget/combo_as_radio_buttons.cc
@@ -69,8 +69,9 @@ void ComboAsRadioButtons::set_choices_with_second(const type_list_values_with_se
   sharedptr<const Relationship> choice_relationship;
   sharedptr<const LayoutItem_Field> layout_choice_first;
   sharedptr<const LayoutGroup> layout_choice_extra;
+  FieldFormatting::type_list_sort_fields choice_sort_fields; //Ignored. TODO?
   bool choice_show_all = false;
-  format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_extra, choice_show_all);
+  format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_extra, choice_sort_fields, choice_show_all);
 
   LayoutGroup::type_list_const_items extra_fields;
   if(layout_choice_extra)
diff --git a/glom/mode_data/datawidget/combochoiceswithtreemodel.cc b/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
index eb7eccc..ed6f709 100644
--- a/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
+++ b/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
@@ -121,7 +121,7 @@ void ComboChoicesWithTreeModel::delete_model()
   m_refModel.reset();
 }
 
-/*
+/* TODO: Remove this
 void ComboChoicesWithTreeModel::set_choices_with_second(const type_list_values_with_second& list_values)
 {
   //Recreate the entire model:
@@ -246,8 +246,9 @@ void ComboChoicesWithTreeModel::set_choices_related(const Document* document, co
   sharedptr<const Relationship> choice_relationship;
   sharedptr<const LayoutItem_Field> layout_choice_first;
   sharedptr<const LayoutGroup> layout_choice_extra;
+  FieldFormatting::type_list_sort_fields choice_sort_fields;
   bool choice_show_all = false;
-  format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_extra, choice_show_all);
+  format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_extra, choice_sort_fields, choice_show_all);
   if(layout_choice_first->get_glom_type() == Field::TYPE_INVALID)
     std::cerr << G_STRFUNC << ": layout_choice_first has invalid type. field name: " << layout_choice_first->get_name() << std::endl;
 
@@ -277,10 +278,12 @@ void ComboChoicesWithTreeModel::set_choices_related(const Document* document, co
       to_table, to_field, foreign_key_value);
   }
 
-  //Sort by the first field, because that is better than so sort at all.
-  //TODO: Allow the developer to specify the sort order:
-  found_set.m_sort_clause.push_back( FoundSet::type_pair_sort_field(layout_choice_first, true /* ascending */) );
-
+  found_set.m_sort_clause = choice_sort_fields;
+  if(found_set.m_sort_clause.empty())
+  {
+    //Sort by the first field, because that is better than so sort at all.
+    found_set.m_sort_clause.push_back( FoundSet::type_pair_sort_field(layout_choice_first, true /* ascending */) );
+  }
 
   m_db_layout_items.clear();
 
diff --git a/glom/mode_design/layout/layout_item_dialogs/box_formatting.cc b/glom/mode_design/layout/layout_item_dialogs/box_formatting.cc
index 55c5dc6..fb2805c 100644
--- a/glom/mode_design/layout/layout_item_dialogs/box_formatting.cc
+++ b/glom/mode_design/layout/layout_item_dialogs/box_formatting.cc
@@ -65,8 +65,11 @@ Box_Formatting::Box_Formatting(BaseObjectType* cobject, const Glib::RefPtr<Gtk::
   m_combo_choices_field(0),
   m_label_choices_extra_fields(0),
   m_button_choices_extra_fields(0),
+  m_label_choices_sortby(0),
+  m_button_choices_sortby(0),
   m_checkbutton_choices_related_show_all(0),
   m_dialog_choices_extra_fields(0),
+  m_dialog_choices_sortby(0),
   m_for_print_layout(false),
   m_show_numeric(true),
   m_show_editable_options(true)
@@ -138,6 +141,8 @@ Box_Formatting::Box_Formatting(BaseObjectType* cobject, const Glib::RefPtr<Gtk::
   builder->get_widget_derived("combobox_choices_related_field", m_combo_choices_field);
   builder->get_widget("label_choices_related_extra_fields", m_label_choices_extra_fields);
   builder->get_widget("button_choices_related_extra_fields", m_button_choices_extra_fields);
+  builder->get_widget("label_choices_related_sortby", m_label_choices_sortby);
+  builder->get_widget("button_choices_related_sortby", m_button_choices_sortby);
   builder->get_widget("checkbutton_choices_related_show_all", m_checkbutton_choices_related_show_all);
   builder->get_widget("radiobutton_choices_custom", m_radiobutton_choices_custom);
   builder->get_widget("radiobutton_choices_related", m_radiobutton_choices_related);
@@ -151,7 +156,9 @@ Box_Formatting::Box_Formatting(BaseObjectType* cobject, const Glib::RefPtr<Gtk::
   m_checkbox_format_color_negatives->signal_toggled().connect( sigc::mem_fun(*this, &Box_Formatting::on_checkbox) );
   m_checkbutton_choices_restricted->signal_toggled().connect( sigc::mem_fun(*this, &Box_Formatting::on_checkbox) );
   m_button_choices_extra_fields->signal_clicked().connect( sigc::mem_fun(*this, &Box_Formatting::on_button_choices_extra) );
+  m_button_choices_sortby->signal_clicked().connect( sigc::mem_fun(*this, &Box_Formatting::on_button_choices_sortby) );
 
+  //TODO: Delay this until it is used?
   if(!m_dialog_choices_extra_fields)
   {
     Utils::get_glade_widget_derived_with_warning(m_dialog_choices_extra_fields);
@@ -159,6 +166,14 @@ Box_Formatting::Box_Formatting(BaseObjectType* cobject, const Glib::RefPtr<Gtk::
     m_dialog_choices_extra_fields->set_title(_("Extra Fields"));
   }
 
+  //TODO: Delay this until it is used?
+  if(!m_dialog_choices_sortby)
+  {
+    Utils::get_glade_widget_derived_with_warning(m_dialog_choices_sortby);
+    add_view(m_dialog_choices_sortby); //Give it access to the document.
+    m_dialog_choices_sortby->set_title(_("Sort Order"));
+  }
+
   show_all_children();
 }
 
@@ -169,6 +184,12 @@ Box_Formatting::~Box_Formatting()
     remove_view(m_dialog_choices_extra_fields); //Give it access to the document.
     delete m_dialog_choices_extra_fields;
   }
+
+  if(m_dialog_choices_sortby)
+  {
+    remove_view(m_dialog_choices_sortby); //Give it access to the document.
+    delete m_dialog_choices_sortby;
+  }
 }
 
 void Box_Formatting::set_is_for_non_editable()
@@ -269,17 +290,19 @@ void Box_Formatting::set_formatting_for_non_field(const FieldFormatting& format,
     sharedptr<const Relationship> choices_relationship;
     sharedptr<const LayoutItem_Field> choices_field;
     sharedptr<const LayoutGroup> choices_field_extras;
+    FieldFormatting::type_list_sort_fields choices_sort_fields;
     bool choices_show_all = false;
-    format.get_choices_related(choices_relationship, choices_field, choices_field_extras, choices_show_all);
+    format.get_choices_related(choices_relationship, choices_field, choices_field_extras, choices_sort_fields, choices_show_all);
 
     m_combo_choices_relationship->set_selected_relationship(choices_relationship);
     on_combo_choices_relationship_changed(); //Fill the combos so we can set their active items.
     m_combo_choices_field->set_selected_field(choices_field ? choices_field->get_name() : Glib::ustring());
 
-    //Show the list of fields in a label:
+
+    //Show the list of extra fields in a label:
     const Glib::ustring text_extra_fields =
       Utils::get_list_of_layout_items_for_display(choices_field_extras);
-     m_label_choices_extra_fields->set_text(text_extra_fields);
+    m_label_choices_extra_fields->set_text(text_extra_fields);
 
     //Update the contents of the dialog that will be shown if Edit is clicked:
     const Glib::ustring related_to_table =
@@ -290,6 +313,14 @@ void Box_Formatting::set_formatting_for_non_field(const FieldFormatting& format,
       m_dialog_choices_extra_fields->set_fields(related_to_table, LayoutGroup::type_list_items());
 
 
+    //Show the list of sort fields in a label:
+    const Glib::ustring text_sortby =
+      Utils::get_list_of_sort_fields_for_display(choices_sort_fields);
+    m_label_choices_sortby->set_text(text_sortby);
+
+    //Update the contents of the dialog that will be shown if Edit is clicked:
+    m_dialog_choices_sortby->set_fields(related_to_table, choices_sort_fields);
+
 
     m_checkbutton_choices_related_show_all->set_active(choices_show_all);
 
@@ -365,8 +396,11 @@ bool Box_Formatting::get_formatting(FieldFormatting& format) const
     sharedptr<LayoutGroup> layout_choice_extra = sharedptr<LayoutGroup>::create();
     layout_choice_extra->m_list_items = m_dialog_choices_extra_fields->get_fields();
 
+    const FieldFormatting::type_list_sort_fields sort_fields = m_dialog_choices_sortby->get_fields();
+
     m_format.set_choices_related(choices_relationship,
       layout_choice_first, layout_choice_extra,
+      sort_fields,
       m_checkbutton_choices_related_show_all->get_active());
 
     //Custom choices:
@@ -419,7 +453,18 @@ void Box_Formatting::on_combo_choices_relationship_changed()
       //Update the label:
       const Glib::ustring text_extra_fields =
         Utils::get_list_of_layout_items_for_display(m_dialog_choices_extra_fields->get_fields());
-       m_label_choices_extra_fields->set_text(text_extra_fields);
+      m_label_choices_extra_fields->set_text(text_extra_fields);
+
+
+      //If the related table name has changed then the list of sort fields will probably
+      //be ignored, clearing the list, but we try to preserve it if possible:
+      const FieldFormatting::type_list_sort_fields sort_fields = m_dialog_choices_sortby->get_fields();
+      m_dialog_choices_sortby->set_fields(relationship->get_to_table(), sort_fields);
+
+      //Update the label: //TODO: Do the label updating in a shared function.
+      const Glib::ustring text_sortby =
+        Utils::get_list_of_sort_fields_for_display(m_dialog_choices_sortby->get_fields());
+      m_label_choices_sortby->set_text(text_sortby);
     }
   }
 }
@@ -525,6 +570,24 @@ void Box_Formatting::on_button_choices_extra()
   }
 }
 
+void Box_Formatting::on_button_choices_sortby()
+{
+  if(!m_dialog_choices_sortby)
+    return;
+
+  const int response = Glom::Utils::dialog_run_with_help(m_dialog_choices_sortby);
+  m_dialog_choices_sortby->hide();
+  if(response == Gtk::RESPONSE_OK && m_dialog_choices_sortby->get_modified())
+  {
+    //Update the label:
+    const Glib::ustring text_sortby =
+      Utils::get_list_of_sort_fields_for_display(m_dialog_choices_sortby->get_fields());
+    m_label_choices_sortby->set_text(text_sortby);
+
+    //Tell the parent (which connects directly to all other (regular) widgets):
+    m_signal_modified.emit();
+  }
+}
 
 Box_Formatting::type_signal_modified Box_Formatting::signal_modified()
 {
diff --git a/glom/mode_design/layout/layout_item_dialogs/box_formatting.h b/glom/mode_design/layout/layout_item_dialogs/box_formatting.h
index 912d8f9..33b64e1 100644
--- a/glom/mode_design/layout/layout_item_dialogs/box_formatting.h
+++ b/glom/mode_design/layout/layout_item_dialogs/box_formatting.h
@@ -34,6 +34,7 @@
 #include <glom/mode_design/layout/combobox_relationship.h>
 #include <glom/mode_design/layout/combobox_fields.h>
 #include <glom/mode_design/layout/layout_item_dialogs/dialog_fieldslist.h>
+#include <glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.h>
 
 namespace Glom
 {
@@ -78,6 +79,7 @@ private:
   void on_combo_choices_relationship_changed();
   void on_checkbox();
   void on_button_choices_extra();
+  void on_button_choices_sortby();
 
   void enforce_constraints();
 
@@ -114,9 +116,12 @@ private:
   ComboBox_Fields* m_combo_choices_field;
   Gtk::Label* m_label_choices_extra_fields;
   Gtk::Button* m_button_choices_extra_fields;
+  Gtk::Label* m_label_choices_sortby;
+  Gtk::Button* m_button_choices_sortby;
   Gtk::CheckButton* m_checkbutton_choices_related_show_all;
 
   Dialog_FieldsList* m_dialog_choices_extra_fields;
+  Dialog_SortFields* m_dialog_choices_sortby;
 
   mutable FieldFormatting m_format;
 
diff --git a/glom/mode_design/layout/layout_item_dialogs/dialog_group_by.cc b/glom/mode_design/layout/layout_item_dialogs/dialog_group_by.cc
index 33ee9c9..01bc1da 100644
--- a/glom/mode_design/layout/layout_item_dialogs/dialog_group_by.cc
+++ b/glom/mode_design/layout/layout_item_dialogs/dialog_group_by.cc
@@ -192,22 +192,7 @@ void Dialog_GroupBy::update_labels()
   }
 
   //Sort fields:
-  if(m_layout_item->get_has_fields_sort_by())
-  {
-    Glib::ustring text;
-    LayoutItem_GroupBy::type_list_sort_fields list_fields = m_layout_item->get_fields_sort_by();
-    for(LayoutItem_GroupBy::type_list_sort_fields::const_iterator iter = list_fields.begin(); iter != list_fields.end(); ++iter)
-    {
-      if(!text.empty())
-        text += ", ";
-
-      text += iter->first->get_layout_display_name();
-    }
-
-    m_label_sort_by->set_text(text);
-  }
-  else
-    m_label_sort_by->set_text( Glib::ustring() );
+  m_label_sort_by->set_text( Utils::get_list_of_sort_fields_for_display(m_layout_item->get_fields_sort_by()) );
 
   //Secondary Fields:
   const Glib::ustring text_secondary_fields =
diff --git a/glom/mode_design/layout/layout_item_dialogs/dialog_group_by.h b/glom/mode_design/layout/layout_item_dialogs/dialog_group_by.h
index 3b8a093..11e98b1 100644
--- a/glom/mode_design/layout/layout_item_dialogs/dialog_group_by.h
+++ b/glom/mode_design/layout/layout_item_dialogs/dialog_group_by.h
@@ -30,7 +30,7 @@
 #include <glom/utility_widgets/combo_textglade.h>
 #include <glom/mode_design/comboentry_currency.h>
 #include "dialog_fieldslist.h"
-#include "dialog_groupby_sortfields.h"
+#include "dialog_sortfields.h"
 #include "comboentry_borderwidth.h"
 
 namespace Glom
@@ -76,7 +76,7 @@ private:
   ComboEntry_BorderWidth* m_comboboxentry_border_width;
 
   Dialog_FieldsList* m_dialog_choose_secondary_fields;
-  Dialog_GroupBy_SortFields* m_dialog_choose_sort_fields;
+  Dialog_SortFields* m_dialog_choose_sort_fields;
 
   mutable sharedptr<LayoutItem_GroupBy> m_layout_item;
 
diff --git a/glom/mode_design/layout/layout_item_dialogs/dialog_groupby_sortfields.cc b/glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.cc
similarity index 85%
rename from glom/mode_design/layout/layout_item_dialogs/dialog_groupby_sortfields.cc
rename to glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.cc
index 8347b9d..0456dde 100644
--- a/glom/mode_design/layout/layout_item_dialogs/dialog_groupby_sortfields.cc
+++ b/glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.cc
@@ -18,7 +18,7 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#include "dialog_groupby_sortfields.h"
+#include "dialog_sortfields.h"
 #include "dialog_field_layout.h"
 
 //#include <libgnome/gnome-i18n.h>
@@ -27,10 +27,10 @@
 namespace Glom
 {
 
-const char* Dialog_GroupBy_SortFields::glade_id("dialog_groupby_sort_fields");
-const bool Dialog_GroupBy_SortFields::glade_developer(true);
+const char* Dialog_SortFields::glade_id("dialog_sort_fields");
+const bool Dialog_SortFields::glade_developer(true);
 
-Dialog_GroupBy_SortFields::Dialog_GroupBy_SortFields(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder)
+Dialog_SortFields::Dialog_SortFields(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder)
 : Dialog_Layout(cobject, builder, false /* means no table title */),
   m_treeview_fields(0),
   m_button_field_up(0),
@@ -54,7 +54,7 @@ Dialog_GroupBy_SortFields::Dialog_GroupBy_SortFields(BaseObjectType* cobject, co
 
     Gtk::CellRendererText* renderer_name = Gtk::manage(new Gtk::CellRendererText);
     column_name->pack_start(*renderer_name);
-    column_name->set_cell_data_func(*renderer_name, sigc::mem_fun(*this, &Dialog_GroupBy_SortFields::on_cell_data_name));
+    column_name->set_cell_data_func(*renderer_name, sigc::mem_fun(*this, &Dialog_SortFields::on_cell_data_name));
 
     m_treeview_fields->append_column_editable(_("Ascending"), m_ColumnsFields.m_col_ascending);
 
@@ -66,36 +66,36 @@ Dialog_GroupBy_SortFields::Dialog_GroupBy_SortFields(BaseObjectType* cobject, co
     Glib::RefPtr<Gtk::TreeView::Selection> refSelection = m_treeview_fields->get_selection();
     if(refSelection)
     {
-      refSelection->signal_changed().connect( sigc::mem_fun(*this, &Dialog_GroupBy_SortFields::on_treeview_fields_selection_changed) );
+      refSelection->signal_changed().connect( sigc::mem_fun(*this, &Dialog_SortFields::on_treeview_fields_selection_changed) );
     }
 
-    m_model_fields->signal_row_changed().connect( sigc::mem_fun(*this, &Dialog_GroupBy_SortFields::on_treemodel_row_changed) );
+    m_model_fields->signal_row_changed().connect( sigc::mem_fun(*this, &Dialog_SortFields::on_treemodel_row_changed) );
   }
 
 
   builder->get_widget("button_field_up", m_button_field_up);
-  m_button_field_up->signal_clicked().connect( sigc::mem_fun(*this, &Dialog_GroupBy_SortFields::on_button_field_up) );
+  m_button_field_up->signal_clicked().connect( sigc::mem_fun(*this, &Dialog_SortFields::on_button_field_up) );
 
   builder->get_widget("button_field_down", m_button_field_down);
-  m_button_field_down->signal_clicked().connect( sigc::mem_fun(*this, &Dialog_GroupBy_SortFields::on_button_field_down) );
+  m_button_field_down->signal_clicked().connect( sigc::mem_fun(*this, &Dialog_SortFields::on_button_field_down) );
 
   builder->get_widget("button_field_delete", m_button_field_delete);
-  m_button_field_delete->signal_clicked().connect( sigc::mem_fun(*this, &Dialog_GroupBy_SortFields::on_button_delete) );
+  m_button_field_delete->signal_clicked().connect( sigc::mem_fun(*this, &Dialog_SortFields::on_button_delete) );
 
   builder->get_widget("button_field_add", m_button_field_add);
-  m_button_field_add->signal_clicked().connect( sigc::mem_fun(*this, &Dialog_GroupBy_SortFields::on_button_add_field) );
+  m_button_field_add->signal_clicked().connect( sigc::mem_fun(*this, &Dialog_SortFields::on_button_add_field) );
 
   builder->get_widget("button_field_edit", m_button_field_edit);
-  m_button_field_edit->signal_clicked().connect( sigc::mem_fun(*this, &Dialog_GroupBy_SortFields::on_button_edit_field) );
+  m_button_field_edit->signal_clicked().connect( sigc::mem_fun(*this, &Dialog_SortFields::on_button_edit_field) );
 
   show_all_children();
 }
 
-Dialog_GroupBy_SortFields::~Dialog_GroupBy_SortFields()
+Dialog_SortFields::~Dialog_SortFields()
 {
 }
 
-void Dialog_GroupBy_SortFields::set_fields(const Glib::ustring& table_name, const LayoutItem_GroupBy::type_list_sort_fields& fields)
+void Dialog_SortFields::set_fields(const Glib::ustring& table_name, const LayoutItem_GroupBy::type_list_sort_fields& fields)
 {
   m_modified = false;
   m_table_name = table_name;
@@ -133,7 +133,7 @@ void Dialog_GroupBy_SortFields::set_fields(const Glib::ustring& table_name, cons
   m_modified = false;
 }
 
-void Dialog_GroupBy_SortFields::enable_buttons()
+void Dialog_SortFields::enable_buttons()
 {
   //Fields:
   Glib::RefPtr<Gtk::TreeView::Selection> refSelection = m_treeview_fields->get_selection();
@@ -175,17 +175,17 @@ void Dialog_GroupBy_SortFields::enable_buttons()
 }
 
 
-void Dialog_GroupBy_SortFields::on_button_field_up()
+void Dialog_SortFields::on_button_field_up()
 {
   move_treeview_selection_up(m_treeview_fields, m_ColumnsFields.m_col_sequence);
 }
 
-void Dialog_GroupBy_SortFields::on_button_field_down()
+void Dialog_SortFields::on_button_field_down()
 {
   move_treeview_selection_down(m_treeview_fields, m_ColumnsFields.m_col_sequence);
 }
 
-LayoutItem_GroupBy::type_list_sort_fields Dialog_GroupBy_SortFields::get_fields() const
+LayoutItem_GroupBy::type_list_sort_fields Dialog_SortFields::get_fields() const
 {
   LayoutItem_GroupBy::type_list_sort_fields result;
 
@@ -210,12 +210,12 @@ LayoutItem_GroupBy::type_list_sort_fields Dialog_GroupBy_SortFields::get_fields(
   return result;
 }
 
-void Dialog_GroupBy_SortFields::on_treeview_fields_selection_changed()
+void Dialog_SortFields::on_treeview_fields_selection_changed()
 {
   enable_buttons();
 }
 
-void Dialog_GroupBy_SortFields::on_button_add_field()
+void Dialog_SortFields::on_button_add_field()
 {
   //Get the chosen fields:
   type_list_field_items fields_list = offer_field_list(m_table_name, this);
@@ -247,7 +247,7 @@ void Dialog_GroupBy_SortFields::on_button_add_field()
   }
 }
 
-void Dialog_GroupBy_SortFields::on_button_delete()
+void Dialog_SortFields::on_button_delete()
 {
   Glib::RefPtr<Gtk::TreeView::Selection> refTreeSelection = m_treeview_fields->get_selection();
   if(refTreeSelection)
@@ -264,7 +264,7 @@ void Dialog_GroupBy_SortFields::on_button_delete()
 }
 
 
-void Dialog_GroupBy_SortFields::on_cell_data_name(Gtk::CellRenderer* renderer, const Gtk::TreeModel::iterator& iter)
+void Dialog_SortFields::on_cell_data_name(Gtk::CellRenderer* renderer, const Gtk::TreeModel::iterator& iter)
 {
   //Set the view's cell properties depending on the model's data:
   Gtk::CellRendererText* renderer_text = dynamic_cast<Gtk::CellRendererText*>(renderer);
@@ -282,7 +282,7 @@ void Dialog_GroupBy_SortFields::on_cell_data_name(Gtk::CellRenderer* renderer, c
 }
 
 
-void Dialog_GroupBy_SortFields::on_button_edit_field()
+void Dialog_SortFields::on_button_edit_field()
 {
   Glib::RefPtr<Gtk::TreeView::Selection> refTreeSelection = m_treeview_fields->get_selection();
   if(refTreeSelection)
diff --git a/glom/mode_design/layout/layout_item_dialogs/dialog_groupby_sortfields.h b/glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.h
similarity index 88%
rename from glom/mode_design/layout/layout_item_dialogs/dialog_groupby_sortfields.h
rename to glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.h
index 84a492a..5b9cbfe 100644
--- a/glom/mode_design/layout/layout_item_dialogs/dialog_groupby_sortfields.h
+++ b/glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.h
@@ -18,8 +18,8 @@
  * Boston, MA 02111-1307, USA.
  */
 
-#ifndef GLOM_MODE_DESIGN_DIALOG_GROUPBY_SORTFIELDS_H
-#define GLOM_MODE_DESIGN_DIALOG_GROUPBY_SORTFIELDS_H
+#ifndef GLOM_MODE_DESIGN_DIALOG_SORTFIELDS_H
+#define GLOM_MODE_DESIGN_DIALOG_SORTFIELDS_H
 
 #include <glom/base_db.h>
 #include <glom/mode_design/layout/dialog_layout.h>
@@ -28,15 +28,15 @@
 namespace Glom
 {
 
-class Dialog_GroupBy_SortFields
+class Dialog_SortFields
  : public Dialog_Layout //It has some useful stuff
 {
 public:
   static const char* glade_id;
   static const bool glade_developer;
 
-  Dialog_GroupBy_SortFields(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder);
-  virtual ~Dialog_GroupBy_SortFields();
+  Dialog_SortFields(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& builder);
+  virtual ~Dialog_SortFields();
 
 
   void set_fields(const Glib::ustring& table_name, const LayoutItem_GroupBy::type_list_sort_fields& table_fields);
@@ -86,4 +86,4 @@ private:
 
 } //namespace Glom
 
-#endif // GLOM_MODE_DESIGN_DIALOG_GROUPBY_SORTFIELDS_H
+#endif // GLOM_MODE_DESIGN_DIALOG_SORTFIELDS_H
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4af0307..a4209ba 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -95,10 +95,10 @@ glom/mode_design/layout/layout_item_dialogs/dialog_field_summary.cc
 glom/mode_design/layout/layout_item_dialogs/dialog_formatting.cc
 glom/mode_design/layout/layout_item_dialogs/dialog_group_by.cc
 glom/mode_design/layout/layout_item_dialogs/dialog_fieldslist.cc
-glom/mode_design/layout/layout_item_dialogs/dialog_groupby_sortfields.cc
 glom/mode_design/layout/layout_item_dialogs/dialog_imageobject.cc
 glom/mode_design/layout/layout_item_dialogs/dialog_line.cc
 glom/mode_design/layout/layout_item_dialogs/dialog_notebook.cc
+glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.cc
 glom/mode_design/layout/layout_item_dialogs/dialog_textobject.cc
 glom/mode_design/report_layout/dialog_layout_report.cc
 glom/mode_design/print_layouts/box_print_layouts.cc
@@ -161,7 +161,6 @@ ui/developer/dialog_fieldslist.glade
 ui/developer/dialog_field_summary.glade
 ui/developer/dialog_flowtable.glade
 ui/developer/dialog_group_by.glade
-ui/developer/dialog_groupby_sort_fields.glade
 ui/developer/dialog_initial_password.glade
 ui/developer/dialog_line.glade
 ui/developer/dialog_layout_field_properties.glade
@@ -170,6 +169,7 @@ ui/developer/dialog_new_library_script.glade
 ui/developer/dialog_notebook.glade
 ui/developer/dialog_relationships_overview.glade
 ui/developer/dialog_script_library.glade
+ui/developer/dialog_sort_fields.glade
 ui/developer/dialog_translation_copy.glade
 ui/developer/dialog_translation_identify_original.glade
 ui/developer/dialog_user.glade
diff --git a/tests/test_glade_derived_instantiation.cc b/tests/test_glade_derived_instantiation.cc
index 98160ac..5b9c5f1 100644
--- a/tests/test_glade_derived_instantiation.cc
+++ b/tests/test_glade_derived_instantiation.cc
@@ -57,7 +57,7 @@
 #include <glom/mode_design/dialog_fields.h>
 #include <glom/mode_design/dialog_initial_password.h>
 #include <glom/mode_design/layout/layout_item_dialogs/dialog_fieldslist.h>
-#include <glom/mode_design/layout/layout_item_dialogs/dialog_groupby_sortfields.h>
+#include <glom/mode_design/layout/layout_item_dialogs/dialog_sortfields.h>
 #include <glom/mode_design/layout/layout_item_dialogs/dialog_formatting.h>
 #include <glom/mode_design/script_library/dialog_new_script.h>
 #include <glom/mode_design/script_library/dialog_script_library.h>
@@ -152,7 +152,7 @@ int main(int argc, char *argv[])
   instantiate_widget<Dialog_FieldDefinition>();
   instantiate_widget<Box_Formatting>();
   instantiate_widget<Dialog_FieldsList>();
-  instantiate_widget<Dialog_GroupBy_SortFields>();
+  instantiate_widget<Dialog_SortFields>();
   instantiate_widget<Dialog_Line>();
   instantiate_widget<Dialog_ImageObject>();
   instantiate_widget<Dialog_Notebook>();
diff --git a/ui/developer/box_formatting.glade b/ui/developer/box_formatting.glade
index c444521..b3eec29 100644
--- a/ui/developer/box_formatting.glade
+++ b/ui/developer/box_formatting.glade
@@ -459,7 +459,7 @@
                               <object class="GtkTable" id="table8">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="n_rows">3</property>
+                                <property name="n_rows">5</property>
                                 <property name="n_columns">2</property>
                                 <property name="column_spacing">6</property>
                                 <property name="row_spacing">6</property>
@@ -580,6 +580,8 @@
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
                                     <property name="receives_default">False</property>
+                                    <property name="has_tooltip">True</property>
+                                    <property name="tooltip_markup" translatable="yes">If this option is selected then the choices will list values from all records in the related table. If this option is not selected then the choices will list values only from related records.</property>
                                     <property name="tooltip_text" translatable="yes">If this option is selected then the choices will list values from all records in the related table. If this option is not selected then the choices will list values only from related records.</property>
                                     <property name="use_action_appearance">False</property>
                                     <property name="xalign">0</property>
@@ -588,14 +590,71 @@
                                   <packing>
                                     <property name="left_attach">1</property>
                                     <property name="right_attach">2</property>
+                                    <property name="top_attach">4</property>
+                                    <property name="bottom_attach">5</property>
+                                    <property name="y_options"></property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkLabel" id="label1">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="xalign">1</property>
+                                    <property name="label" translatable="yes">Sort Order:</property>
+                                    <property name="justify">right</property>
+                                    <property name="single_line_mode">True</property>
+                                  </object>
+                                  <packing>
                                     <property name="top_attach">3</property>
                                     <property name="bottom_attach">4</property>
+                                    <property name="x_options">GTK_FILL</property>
                                     <property name="y_options"></property>
                                   </packing>
                                 </child>
                                 <child>
                                   <placeholder/>
                                 </child>
+                                <child>
+                                  <object class="GtkHBox" id="hbox2">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <child>
+                                      <object class="GtkLabel" id="label_choices_related_sortby">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="xalign">0</property>
+                                        <property name="label" translatable="yes">label</property>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">True</property>
+                                        <property name="fill">True</property>
+                                        <property name="position">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkButton" id="button_choices_related_sortby">
+                                        <property name="label">gtk-edit</property>
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="receives_default">True</property>
+                                        <property name="use_action_appearance">False</property>
+                                        <property name="use_stock">True</property>
+                                      </object>
+                                      <packing>
+                                        <property name="expand">False</property>
+                                        <property name="fill">False</property>
+                                        <property name="position">1</property>
+                                      </packing>
+                                    </child>
+                                  </object>
+                                  <packing>
+                                    <property name="left_attach">1</property>
+                                    <property name="right_attach">2</property>
+                                    <property name="top_attach">3</property>
+                                    <property name="bottom_attach">4</property>
+                                    <property name="y_options"></property>
+                                  </packing>
+                                </child>
                               </object>
                             </child>
                           </object>
diff --git a/ui/developer/dialog_groupby_sort_fields.glade b/ui/developer/dialog_sort_fields.glade
similarity index 83%
rename from ui/developer/dialog_groupby_sort_fields.glade
rename to ui/developer/dialog_sort_fields.glade
index 4592b56..beac1f6 100644
--- a/ui/developer/dialog_groupby_sort_fields.glade
+++ b/ui/developer/dialog_sort_fields.glade
@@ -1,29 +1,91 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="2.16"/>
-  <!-- interface-requires gtksourceview 0.0 -->
-  <!-- interface-naming-policy toplevel-contextual -->
-
-  <object class="GtkDialog" id="dialog_groupby_sort_fields">
+  <object class="GtkDialog" id="dialog_sort_fields">
+    <property name="can_focus">False</property>
     <property name="title" translatable="yes">Group By - Sort Fields</property>
     <property name="type_hint">dialog</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox8">
+      <object class="GtkBox" id="dialog-vbox8">
         <property name="visible">True</property>
+        <property name="can_focus">False</property>
         <property name="orientation">vertical</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area8">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="helpbutton6">
+                <property name="label">gtk-help</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="cancelbutton7">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button_close">
+                <property name="label">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
         <child>
           <object class="GtkVBox" id="vbox78">
             <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <property name="border_width">6</property>
-            <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
               <object class="GtkHBox" id="hbox78">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="spacing">6</property>
                 <child>
                   <object class="GtkLabel" id="label187">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="label" translatable="yes">Table: </property>
                   </object>
                   <packing>
@@ -35,6 +97,7 @@
                 <child>
                   <object class="GtkLabel" id="label_table_name">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -45,47 +108,55 @@
               </object>
               <packing>
                 <property name="expand">False</property>
+                <property name="fill">True</property>
                 <property name="position">0</property>
               </packing>
             </child>
             <child>
               <object class="GtkFrame" id="frame21">
                 <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <property name="label_xalign">0</property>
                 <property name="shadow_type">none</property>
                 <child>
                   <object class="GtkAlignment" id="alignment56">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="left_padding">12</property>
                     <child>
                       <object class="GtkVBox" id="vbox1">
                         <property name="visible">True</property>
-                        <property name="orientation">vertical</property>
+                        <property name="can_focus">False</property>
                         <property name="spacing">6</property>
                         <child>
                           <object class="GtkScrolledWindow" id="scrolledwindow17">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
-                            <property name="hscrollbar_policy">automatic</property>
-                            <property name="vscrollbar_policy">automatic</property>
                             <property name="shadow_type">in</property>
                             <child>
                               <object class="GtkTreeView" id="treeview_fields">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
+                                <child internal-child="selection">
+                                  <object class="GtkTreeSelection" id="treeview-selection1"/>
+                                </child>
                               </object>
                             </child>
                           </object>
                           <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
                             <property name="position">0</property>
                           </packing>
                         </child>
                         <child>
                           <object class="GtkHBox" id="hbox77">
                             <property name="visible">True</property>
+                            <property name="can_focus">False</property>
                             <child>
                               <object class="GtkHButtonBox" id="hbuttonbox36">
                                 <property name="visible">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="spacing">6</property>
                                 <property name="layout_style">start</property>
                                 <child>
@@ -95,6 +166,7 @@
                                     <property name="can_focus">True</property>
                                     <property name="can_default">True</property>
                                     <property name="receives_default">False</property>
+                                    <property name="use_action_appearance">False</property>
                                     <property name="use_stock">True</property>
                                   </object>
                                   <packing>
@@ -110,6 +182,7 @@
                                     <property name="can_focus">True</property>
                                     <property name="can_default">True</property>
                                     <property name="receives_default">False</property>
+                                    <property name="use_action_appearance">False</property>
                                     <property name="use_stock">True</property>
                                   </object>
                                   <packing>
@@ -120,12 +193,15 @@
                                 </child>
                               </object>
                               <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
                                 <property name="position">0</property>
                               </packing>
                             </child>
                             <child>
                               <object class="GtkHButtonBox" id="hbuttonbox37">
                                 <property name="visible">True</property>
+                                <property name="can_focus">False</property>
                                 <property name="spacing">6</property>
                                 <property name="layout_style">end</property>
                                 <child>
@@ -135,6 +211,7 @@
                                     <property name="can_focus">True</property>
                                     <property name="can_default">True</property>
                                     <property name="receives_default">False</property>
+                                    <property name="use_action_appearance">False</property>
                                     <property name="use_stock">True</property>
                                   </object>
                                   <packing>
@@ -150,6 +227,7 @@
                                     <property name="can_focus">True</property>
                                     <property name="can_default">True</property>
                                     <property name="receives_default">False</property>
+                                    <property name="use_action_appearance">False</property>
                                     <property name="use_stock">True</property>
                                   </object>
                                   <packing>
@@ -165,6 +243,7 @@
                                     <property name="can_focus">True</property>
                                     <property name="can_default">True</property>
                                     <property name="receives_default">False</property>
+                                    <property name="use_action_appearance">False</property>
                                     <property name="use_stock">True</property>
                                   </object>
                                   <packing>
@@ -175,6 +254,8 @@
                                 </child>
                               </object>
                               <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
                                 <property name="position">1</property>
                               </packing>
                             </child>
@@ -192,74 +273,23 @@
                 <child type="label">
                   <object class="GtkLabel" id="label186">
                     <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <property name="label" translatable="yes">&lt;b&gt;Sort Fields&lt;/b&gt;</property>
                     <property name="use_markup">True</property>
                   </object>
                 </child>
               </object>
               <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
                 <property name="position">1</property>
               </packing>
             </child>
           </object>
           <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area8">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="helpbutton6">
-                <property name="label">gtk-help</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="cancelbutton7">
-                <property name="label">gtk-cancel</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="button_close">
-                <property name="label">gtk-ok</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
             <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
           </packing>
         </child>
       </object>



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