[glom/feature_choices_related_layout] In progress
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom/feature_choices_related_layout] In progress
- Date: Wed, 11 Aug 2010 15:41:40 +0000 (UTC)
commit dbf7d551709b291c5e76520ad9d2a99f867ef26f
Author: Murray Cumming <murrayc murrayc com>
Date: Wed Aug 11 17:41:22 2010 +0200
In progress
.../data_structure/layout/fieldformatting.cc | 16 ++--
.../data_structure/layout/fieldformatting.h | 13 ++-
glom/libglom/data_structure/layout/layoutgroup.cc | 32 +++++-
glom/libglom/data_structure/layout/layoutgroup.h | 15 ++--
glom/libglom/document/document.cc | 70 ++++++++++---
glom/libglom/utils.cc | 34 +++++--
glom/libglom/utils.h | 4 +-
.../mode_data/datawidget/combo_as_radio_buttons.cc | 53 +++++++---
glom/mode_data/datawidget/combochoices.cc | 104 ++------------------
glom/mode_data/datawidget/combochoices.h | 3 +-
.../datawidget/combochoiceswithtreemodel.cc | 31 +++++-
11 files changed, 205 insertions(+), 170 deletions(-)
---
diff --git a/glom/libglom/data_structure/layout/fieldformatting.cc b/glom/libglom/data_structure/layout/fieldformatting.cc
index 2d0cd7f..8a9d91e 100644
--- a/glom/libglom/data_structure/layout/fieldformatting.cc
+++ b/glom/libglom/data_structure/layout/fieldformatting.cc
@@ -56,7 +56,7 @@ FieldFormatting::FieldFormatting(const FieldFormatting& src)
m_text_color_background(src.m_text_color_background),
m_horizontal_alignment(src.m_horizontal_alignment),
m_choices_related_field(src.m_choices_related_field),
- m_choices_related_field_second(src.m_choices_related_field_second),
+ m_choices_extra_layout_group(src.m_choices_extra_layout_group),
m_choices_related_show_all(src.m_choices_related_show_all)
{
}
@@ -75,7 +75,7 @@ bool FieldFormatting::operator==(const FieldFormatting& src) const
(m_choices_custom == src.m_choices_custom) &&
(m_choices_related == src.m_choices_related) &&
(m_choices_related_field == src.m_choices_related_field) &&
- (m_choices_related_field_second == src.m_choices_related_field_second) &&
+ (m_choices_extra_layout_group == src.m_choices_extra_layout_group) &&
(m_text_format_multiline == src.m_text_format_multiline) &&
(m_text_multiline_height_lines == src.m_text_multiline_height_lines) &&
(m_text_font == src.m_text_font) &&
@@ -98,7 +98,7 @@ FieldFormatting& FieldFormatting::operator=(const FieldFormatting& src)
m_choices_custom = src.m_choices_custom;
m_choices_related = src.m_choices_related;
m_choices_related_field = src.m_choices_related_field;
- m_choices_related_field_second = src.m_choices_related_field_second;
+ m_choices_extra_layout_group = src.m_choices_extra_layout_group;
m_choices_related_show_all = src.m_choices_related_show_all;
m_text_format_multiline = src.m_text_format_multiline;
@@ -234,7 +234,7 @@ bool FieldFormatting::get_has_related_choices() const
bool FieldFormatting::get_has_related_choices(bool& show_all, bool& with_second) const
{
show_all = m_choices_related_show_all;
- with_second = m_choices_related_field_second;
+ with_second = m_choices_extra_layout_group;
return m_choices_related;
}
@@ -243,21 +243,21 @@ void FieldFormatting::set_has_related_choices(bool val)
m_choices_related = val;
}
-void FieldFormatting::set_choices_related(const sharedptr<const Relationship>& relationship, const sharedptr<const LayoutItem_Field>& field, const sharedptr<const LayoutItem_Field>& field_second, bool show_all)
+void FieldFormatting::set_choices_related(const sharedptr<const Relationship>& relationship, const sharedptr<const LayoutItem_Field>& field, const sharedptr<LayoutGroup>& extra_layout, bool show_all)
{
set_relationship(relationship);
m_choices_related_field = field;
- m_choices_related_field_second = field_second;
+ m_choices_extra_layout_group = extra_layout;
m_choices_related_show_all = show_all;
}
-void FieldFormatting::get_choices_related(sharedptr<const Relationship>& relationship, sharedptr<const LayoutItem_Field>& field, sharedptr<const LayoutItem_Field>& field_second, bool& show_all) const
+void FieldFormatting::get_choices_related(sharedptr<const Relationship>& relationship, sharedptr<const LayoutItem_Field>& field, sharedptr<const LayoutGroup>& extra_layout, bool& show_all) const
{
relationship = get_relationship();
field = m_choices_related_field;
- field_second = m_choices_related_field_second;
+ extra_layout = m_choices_extra_layout_group;
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 0ee8406..44e4dd9 100644
--- a/glom/libglom/data_structure/layout/fieldformatting.h
+++ b/glom/libglom/data_structure/layout/fieldformatting.h
@@ -31,6 +31,7 @@ namespace Glom
{
class LayoutItem_Field;
+class LayoutGroup;
//TODO: This should probably be renamed to Formatting, because it is used for static text items too.
class FieldFormatting : public UsesRelationship //The UsesRelationship base has the relationship for the choices.
@@ -68,15 +69,15 @@ public:
*/
void set_choices_restricted(bool val = true, bool as_radio_buttons = false);
- void get_choices_related(sharedptr<const Relationship>& relationship_name, sharedptr<const LayoutItem_Field>& field, sharedptr<const LayoutItem_Field>& field_second, bool& show_all) const;
- void set_choices_related(const sharedptr<const Relationship>& relationship_name, const sharedptr<const LayoutItem_Field>& field, const sharedptr<const LayoutItem_Field>& field_second, bool show_all);
-
+ void get_choices_related(sharedptr<const Relationship>& relationship_name, 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<const LayoutItem_Field>& field, const sharedptr<LayoutGroup>& extra_layout, bool show_all);
+
//Just for convenience:
sharedptr<const Relationship> get_choices_related_relationship(bool& show_all) const;
-
-
+
+
/** Get whether the text should be displayed with multiple lines in the
* details view. Text is displayed with a single line in the list view.
* @returns whether the text should be displayed with multiple lines
@@ -168,7 +169,7 @@ private:
HorizontalAlignment m_horizontal_alignment;
sharedptr<const LayoutItem_Field> m_choices_related_field;
- sharedptr<const LayoutItem_Field> m_choices_related_field_second;
+ sharedptr<LayoutGroup> m_choices_extra_layout_group;
bool m_choices_related_show_all;
};
diff --git a/glom/libglom/data_structure/layout/layoutgroup.cc b/glom/libglom/data_structure/layout/layoutgroup.cc
index 0fd490c..2220877 100644
--- a/glom/libglom/data_structure/layout/layoutgroup.cc
+++ b/glom/libglom/data_structure/layout/layoutgroup.cc
@@ -149,7 +149,7 @@ void LayoutGroup::add_item(const sharedptr<LayoutItem>& item, const sharedptr<co
//std::vector::insert() adds before rather than after:
// jhs: We want to add after rather than before - at least for dnd
//++iter;
-
+
m_list_items.insert(iter, item);
}
@@ -157,7 +157,7 @@ void LayoutGroup::remove_item (const sharedptr<LayoutItem>& item)
{
sharedptr<LayoutItem> unconst = sharedptr<LayoutItem>::cast_const(item);
type_list_items::iterator iter = std::find(m_list_items.begin(), m_list_items.end(), unconst);
- m_list_items.erase(iter);
+ m_list_items.erase(iter);
}
LayoutGroup::type_list_items LayoutGroup::get_items()
@@ -179,6 +179,26 @@ LayoutGroup::type_list_const_items LayoutGroup::get_items() const
return result;
}
+LayoutGroup::type_list_const_items LayoutGroup::get_items_recursive() const
+{
+ type_list_const_items result;
+
+ for(type_list_items::const_iterator iter = m_list_items.begin(); iter != m_list_items.end(); ++iter)
+ {
+ const sharedptr<const LayoutItem> item = *iter;
+ sharedptr<const LayoutGroup> group = sharedptr<const LayoutGroup>::cast_dynamic(item);
+ if(group)
+ {
+ const type_list_const_items sub_result = group->get_items_recursive();
+ result.insert(result.end(), sub_result.begin(), sub_result.end());
+ }
+ else
+ result.push_back(item);
+ }
+
+ return result;
+}
+
void LayoutGroup::remove_relationship(const sharedptr<const Relationship>& relationship)
{
LayoutGroup::type_list_items::iterator iterItem = m_list_items.begin();
@@ -193,7 +213,7 @@ void LayoutGroup::remove_relationship(const sharedptr<const Relationship>& relat
if(*(uses_rel->get_relationship()) == *relationship) //TODO_Performance: Slow if there are lots of translations.
{
m_list_items.erase(iterItem);
- iterItem = m_list_items.begin(); //Start again, because we changed the container.AddDel
+ iterItem = m_list_items.begin(); //Start again, because we changed the container.AddDel
continue;
}
}
@@ -222,7 +242,7 @@ void LayoutGroup::remove_field(const Glib::ustring& field_name)
if(field_item->get_name() == field_name)
{
m_list_items.erase(iterItem);
- iterItem = m_list_items.begin(); //Start again, because we changed the container.AddDel
+ iterItem = m_list_items.begin(); //Start again, because we changed the container.AddDel
continue;
}
}
@@ -257,7 +277,7 @@ void LayoutGroup::remove_field(const Glib::ustring& table_name, const Glib::ustr
if(field_item->get_name() == field_name)
{
m_list_items.erase(iterItem);
- iterItem = m_list_items.begin(); //Start again, because we changed the container.AddDel
+ iterItem = m_list_items.begin(); //Start again, because we changed the container.AddDel
continue;
}
}
@@ -422,7 +442,7 @@ void LayoutGroup::set_columns_count(guint columns_count)
{
m_columns_count = columns_count;
}
-
+
double LayoutGroup::get_border_width() const
{
return m_border_width;
diff --git a/glom/libglom/data_structure/layout/layoutgroup.h b/glom/libglom/data_structure/layout/layoutgroup.h
index d44fe6f..f95395c 100644
--- a/glom/libglom/data_structure/layout/layoutgroup.h
+++ b/glom/libglom/data_structure/layout/layoutgroup.h
@@ -58,14 +58,14 @@ public:
/** Add the item after the specified existing item.
* @param item The item to add.
- * @param position The item after which the item should be added.
+ * @param position The item after which the item should be added.
*/
void add_item(const sharedptr<LayoutItem>& item, const sharedptr<const LayoutItem>& position);
-
+
/** Remove a layout item from the group
* @param item The item to remove.
*/
- void remove_item (const sharedptr<LayoutItem>& item);
+ void remove_item (const sharedptr<LayoutItem>& item);
/** Remove any instance of the field (from the current table) from the layout.
*/
@@ -94,13 +94,17 @@ public:
guint get_columns_count() const;
void set_columns_count(guint columns_count);
-
+
typedef std::vector< sharedptr<LayoutItem> > type_list_items;
type_list_items get_items();
typedef std::vector< sharedptr<const LayoutItem> > type_list_const_items;
type_list_const_items get_items() const;
+ /** Get the items recursively, depth-first, not returning any groups.
+ */
+ type_list_const_items get_items_recursive() const;
+
virtual Glib::ustring get_part_type_name() const;
virtual Glib::ustring get_report_part_id() const;
@@ -118,6 +122,3 @@ private:
} //namespace Glom
#endif //GLOM_DATASTRUCTURE_LAYOUTGROUP_H
-
-
-
diff --git a/glom/libglom/document/document.cc b/glom/libglom/document/document.cc
index f830de7..3d71af6 100644
--- a/glom/libglom/document/document.cc
+++ b/glom/libglom/document/document.cc
@@ -197,7 +197,8 @@ namespace Glom
#define GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED "choices_related"
#define GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_RELATIONSHIP "choices_related_relationship"
#define GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_FIELD "choices_related_field"
-#define GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SECOND "choices_related_second"
+#define GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_EXTRA_LAYOUT "choices_related_extra_layout"
+#define GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SECOND "choices_related_second" //deprecated
#define GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SHOW_ALL "choices_related_show_all"
#define GLOM_NODE_TRANSLATIONS_SET "trans_set"
@@ -1986,20 +1987,49 @@ void Document::load_after_layout_item_formatting(const xmlpp::Element* element,
const Glib::ustring relationship_name = get_node_attribute_value(element, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_RELATIONSHIP);
if(!relationship_name.empty())
{
+ sharedptr<const Relationship> relationship = get_relationship(table_name, relationship_name);
+
bool show_all = get_node_attribute_value_as_bool(element, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SHOW_ALL);
if(get_document_format_version() < 6)
{
show_all = true; //This was the behaviour before this checkbox existed.
}
-
+
const Glib::ustring field_first = get_node_attribute_value(element, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_FIELD);
- const Glib::ustring field_second = get_node_attribute_value(element, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SECOND);
- /* TODO:
- sharedptr<Relationship> relationship = get_relationship(table_name, relationship_name);
+ sharedptr<LayoutItem_Field> layout_field_first = sharedptr<LayoutItem_Field>::create();
+ layout_field_first->set_name(field_first);
+
+ sharedptr<LayoutGroup> extra_layouts;
+
+ //Previous versions just saved a single extra field name, instead of a whole set of layoutgroups:
+ if(m_document_format_version < 6)
+ {
+ //The deprecated way:
+ const Glib::ustring field_second = get_node_attribute_value(element, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SECOND);
+ if(!field_second.empty())
+ {
+ extra_layouts = sharedptr<LayoutGroup>::create();
+ sharedptr<LayoutItem_Field> item = sharedptr<LayoutItem_Field>::create();
+ item->set_name(field_second);
+ extra_layouts->add_item(item);
+ }
+ }
+ else
+ {
+ //Get the extra layout for related choices:
+ xmlpp::Element* nodeExtraLayout = get_node_child_named(element, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_EXTRA_LAYOUT);
+ if(nodeExtraLayout)
+ {
+ xmlpp::Element* nodeGroups = get_node_child_named(nodeExtraLayout, GLOM_NODE_DATA_LAYOUT_GROUPS);
+ if(nodeGroups)
+ load_after_layout_group(nodeGroups, relationship->get_to_table(), extra_layouts);
+ }
+ }
+
format.set_choices_related(relationship,
- field_first, field_second,
+ layout_field_first, extra_layouts,
show_all);
- */
+
//Full details are updated in filled-in ().
}
}
@@ -2997,20 +3027,26 @@ void Document::save_before_layout_item_formatting(xmlpp::Element* nodeItem, cons
set_node_attribute_value_as_bool(nodeItem, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED, format.get_has_related_choices() );
sharedptr<const Relationship> choice_relationship;
- sharedptr<const LayoutItem_Field> choice_layout_first, choice_layout_second;
+ sharedptr<const LayoutItem_Field> choice_layout_first;
+ sharedptr<const LayoutGroup> choice_extra_layouts;
bool choice_show_all = false;
- format.get_choices_related(choice_relationship, choice_layout_first, choice_layout_second, choice_show_all);
+ format.get_choices_related(choice_relationship, choice_layout_first, choice_extra_layouts, choice_show_all);
- Glib::ustring choice_field, choice_second;
+ Glib::ustring choice_field;
if(choice_layout_first)
choice_field = choice_layout_first->get_name();
- if(choice_layout_second)
- choice_second = choice_layout_first->get_name();
-
+
set_node_attribute_value(nodeItem, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_RELATIONSHIP, glom_get_sharedptr_name(choice_relationship));
set_node_attribute_value(nodeItem, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_FIELD, choice_field);
- set_node_attribute_value(nodeItem, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SECOND, choice_second);
set_node_attribute_value_as_bool(nodeItem, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_SHOW_ALL, choice_show_all);
+
+ //Save the extra fields to show for related choices:
+ if(choice_extra_layouts)
+ {
+ xmlpp::Element* nodeExtraLayout = nodeItem->add_child(GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_EXTRA_LAYOUT);
+ xmlpp::Element* nodeGroups = nodeExtraLayout->add_child(GLOM_NODE_DATA_LAYOUT_GROUPS);
+ save_before_layout_group(nodeGroups, choice_extra_layouts);
+ }
}
}
@@ -3923,7 +3959,7 @@ sharedptr<const Relationship> Document::get_field_used_in_relationship_to_one(co
if(!layout_field)
{
std::cerr << G_STRFUNC << ": layout_field was null" << std::endl;
- return result;
+ return result;
}
const Glib::ustring table_used = layout_field->get_table_used(table_name);
@@ -3931,7 +3967,7 @@ sharedptr<const Relationship> Document::get_field_used_in_relationship_to_one(co
if(iterFind == m_tables.end())
{
std::cerr << G_STRFUNC << ": table not found:" << table_used << std::endl;
- return result;
+ return result;
}
//Look at each relationship:
@@ -4201,7 +4237,7 @@ guint Document::get_latest_known_document_format_version()
// Version 3: (Glom 1.10). Support for the old one-big-string example_rows format was removed, and we now use (unquoted) non-postgres libgda escaping.
// Version 4: (Glom 1.12). Portal navigation options were simplified, with a "none" option. network_sharing was added, defaulting to off.
// Version 5: (Glom 1.14). Extra layout item formatting options were added, plus a startup script.
- // Version 6: (Glom 1.16). Extra show_all option for choices that show related records.
+ // Version 6: (Glom 1.16). Extra show_all option for choices that show related records. Extra related choice fields are now a layout group instead of just a second field name.
return 6;
}
diff --git a/glom/libglom/utils.cc b/glom/libglom/utils.cc
index 5aa0b8b..839d788 100644
--- a/glom/libglom/utils.cc
+++ b/glom/libglom/utils.cc
@@ -503,9 +503,10 @@ Utils::type_list_values_with_second Utils::get_choice_values(const Document* doc
const FieldFormatting& format = field->get_formatting_used();
sharedptr<const Relationship> choice_relationship;
- sharedptr<const LayoutItem_Field> layout_choice_first, layout_choice_second;
+ sharedptr<const LayoutItem_Field> layout_choice_first;
+ sharedptr<const LayoutGroup> layout_choice_extra;
bool choice_show_all = false;
- format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_second, choice_show_all);
+ format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_extra, choice_show_all);
if(!choice_relationship)
{
@@ -515,8 +516,19 @@ Utils::type_list_values_with_second Utils::get_choice_values(const Document* doc
Utils::type_vecConstLayoutFields fields;
fields.push_back(layout_choice_first);
- if(layout_choice_second)
- fields.push_back(layout_choice_second);
+
+ if(layout_choice_extra)
+ {
+ const LayoutGroup::type_list_const_items extra_fields = layout_choice_extra->get_items_recursive();
+ for(LayoutGroup::type_list_const_items::const_iterator iter = extra_fields.begin();
+ iter != extra_fields.end(); ++iter)
+ {
+ const sharedptr<const LayoutItem> item = *iter;
+ const sharedptr<const LayoutItem_Field> item_field = sharedptr<const LayoutItem_Field>::cast_dynamic(item);
+ if(item_field)
+ fields.push_back(item_field); //TODO: Don't ignore other usable items such as static text.
+ }
+ }
const Glib::ustring to_table = choice_relationship->get_to_table();
const sharedptr<const Field> to_field = document->get_field(to_table, choice_relationship->get_to_field());
@@ -566,11 +578,19 @@ Utils::type_list_values_with_second Utils::get_choice_values(const Document* doc
for(guint row = 0; row < count; ++row)
{
- std::pair<Gnome::Gda::Value, Gnome::Gda::Value> itempair;
+ std::pair<Gnome::Gda::Value, type_list_values> itempair;
itempair.first = datamodel->get_value_at(0, row);
- if(layout_choice_second && (cols_count > 1))
- itempair.second = datamodel->get_value_at(1, row);
+ if(layout_choice_extra && (cols_count > 1))
+ {
+ type_list_values list_values;
+ for(guint i = 1; i < cols_count; ++i)
+ {
+ list_values.push_back(datamodel->get_value_at(1, row));
+ }
+
+ itempair.second = list_values;
+ }
result.push_back(itempair);
}
diff --git a/glom/libglom/utils.h b/glom/libglom/utils.h
index 07ef714..8fd204e 100644
--- a/glom/libglom/utils.h
+++ b/glom/libglom/utils.h
@@ -111,8 +111,8 @@ Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_with_key(
Gnome::Gda::SqlExpr get_find_where_clause_quick(const Document* document, const Glib::ustring& table_name, const Gnome::Gda::Value& quick_search);
-
-typedef std::list< std::pair<Gnome::Gda::Value, Gnome::Gda::Value> > type_list_values_with_second;
+typedef std::list<Gnome::Gda::Value> type_list_values;
+typedef std::list< std::pair<Gnome::Gda::Value, type_list_values> > type_list_values_with_second; //TODO: Rename this now that we have more than just 1 extra field.
type_list_values_with_second get_choice_values_all(const Document* document, const sharedptr<const LayoutItem_Field>& field);
type_list_values_with_second get_choice_values(const Document* document, const sharedptr<const LayoutItem_Field>& field, const Gnome::Gda::Value& foreign_key_value);
diff --git a/glom/mode_data/datawidget/combo_as_radio_buttons.cc b/glom/mode_data/datawidget/combo_as_radio_buttons.cc
index 2551795..4b3021b 100644
--- a/glom/mode_data/datawidget/combo_as_radio_buttons.cc
+++ b/glom/mode_data/datawidget/combo_as_radio_buttons.cc
@@ -54,7 +54,7 @@ void ComboAsRadioButtons::init()
void ComboAsRadioButtons::set_choices_with_second(const type_list_values_with_second& list_values)
{
//Clear existing buttons:
- for(type_map_buttons::iterator iter = m_map_buttons.begin();
+ for(type_map_buttons::iterator iter = m_map_buttons.begin();
iter != m_map_buttons.end(); ++iter)
{
Gtk::RadioButton* button = iter->second;
@@ -62,14 +62,19 @@ void ComboAsRadioButtons::set_choices_with_second(const type_list_values_with_se
}
m_map_buttons.clear();
- sharedptr<LayoutItem_Field> layout_item =
+ sharedptr<LayoutItem_Field> layout_item =
sharedptr<LayoutItem_Field>::cast_dynamic(get_layout_item());
const FieldFormatting& format = layout_item->get_formatting_used();
sharedptr<const Relationship> choice_relationship;
- sharedptr<const LayoutItem_Field> layout_choice_first, layout_choice_second;
+ sharedptr<const LayoutItem_Field> layout_choice_first;
+ sharedptr<const LayoutGroup> layout_choice_extra;
bool choice_show_all = false;
- format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_second, choice_show_all);
-
+ format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_extra, choice_show_all);
+
+ LayoutGroup::type_list_const_items extra_fields;
+ if(layout_choice_extra)
+ extra_fields = layout_choice_extra->get_items_recursive();
+
//Add new buttons:
Gtk::RadioButton::Group group;
for(type_list_values_with_second::const_iterator iter = list_values.begin(); iter != list_values.end(); ++iter)
@@ -78,12 +83,28 @@ void ComboAsRadioButtons::set_choices_with_second(const type_list_values_with_se
{
const Glib::ustring value_first = Conversions::get_text_for_gda_value(layout_choice_first->get_glom_type(), iter->first, layout_choice_first->get_formatting_used().m_numeric_format);
Glib::ustring title = value_first;
- if(layout_choice_second)
+
+ //TODO: Support multiple extra fields:
+ //For now, use only the first extra field:
+ const type_list_values extra_values = iter->second;
+ if(layout_choice_extra && !extra_values.empty())
{
- const Glib::ustring value_second = Conversions::get_text_for_gda_value(layout_choice_second->get_glom_type(), iter->second, layout_choice_second->get_formatting_used().m_numeric_format);
- title += " - " + value_second; //TODO: Find a better way to join them?
+ for(LayoutGroup::type_list_const_items::const_iterator iterExtra = extra_fields.begin();
+ iterExtra != extra_fields.end(); ++iterExtra)
+ {
+ const sharedptr<const LayoutItem> item = *iterExtra;
+ const sharedptr<const LayoutItem_Field> item_field = sharedptr<const LayoutItem_Field>::cast_dynamic(item);
+ if(item_field)
+ {
+ const Gnome::Gda::Value value = *(extra_values.begin()); //TODO: Use a vector instead?
+ const Glib::ustring value_second = Conversions::get_text_for_gda_value(item_field->get_glom_type(), value, item_field->get_formatting_used().m_numeric_format);
+
+ title += " - " + value_second; //TODO: Find a better way to join them?
+ break;
+ }
+ }
}
-
+
Gtk::RadioButton* button = new Gtk::RadioButton(group, title);
m_map_buttons[value_first] = button;
pack_start(*button);
@@ -95,13 +116,13 @@ void ComboAsRadioButtons::set_choices_with_second(const type_list_values_with_se
button->signal_button_press_event().connect(
sigc::mem_fun(*this, &ComboAsRadioButtons::on_radiobutton_button_press_event), false);
}
- }
+ }
}
void ComboAsRadioButtons::set_choices(const FieldFormatting::type_list_values& list_values)
{
//Clear existing buttons:
- for(type_map_buttons::iterator iter = m_map_buttons.begin();
+ for(type_map_buttons::iterator iter = m_map_buttons.begin();
iter != m_map_buttons.end(); ++iter)
{
Gtk::RadioButton* button = iter->second;
@@ -117,7 +138,7 @@ void ComboAsRadioButtons::set_choices(const FieldFormatting::type_list_values& l
if(layout_item)
{
const Glib::ustring value_first = Conversions::get_text_for_gda_value(layout_item->get_glom_type(), *iter, layout_item->get_formatting_used().m_numeric_format);
-
+
Gtk::RadioButton* button = new Gtk::RadioButton(group, value_first);
m_map_buttons[value_first] = button;
pack_start(*button);
@@ -125,20 +146,20 @@ void ComboAsRadioButtons::set_choices(const FieldFormatting::type_list_values& l
button->signal_toggled().connect(
sigc::mem_fun(*this, &ComboAsRadioButtons::on_radiobutton_toggled));
}
- }
+ }
}
ComboAsRadioButtons::~ComboAsRadioButtons()
{
- for(type_map_buttons::iterator iter = m_map_buttons.begin();
+ for(type_map_buttons::iterator iter = m_map_buttons.begin();
iter != m_map_buttons.end(); ++iter)
{
Gtk::RadioButton* button = iter->second;
delete button;
}
- m_map_buttons.clear();
+ m_map_buttons.clear();
}
void ComboAsRadioButtons::check_for_change()
@@ -226,7 +247,7 @@ Glib::ustring ComboAsRadioButtons::get_text() const
return iter->first;
}
}
-
+
return Glib::ustring();
}
diff --git a/glom/mode_data/datawidget/combochoices.cc b/glom/mode_data/datawidget/combochoices.cc
index 1a5f1bd..b77420e 100644
--- a/glom/mode_data/datawidget/combochoices.cc
+++ b/glom/mode_data/datawidget/combochoices.cc
@@ -52,9 +52,9 @@ ComboChoices::~ComboChoices()
bool ComboChoices::refresh_data_from_database_with_foreign_key(const Document* document, const Gnome::Gda::Value& foreign_key_value)
{
- sharedptr<LayoutItem_Field> layout_item =
+ sharedptr<LayoutItem_Field> layout_item =
sharedptr<LayoutItem_Field>::cast_dynamic(get_layout_item());
-
+
if(!layout_item || Conversions::value_is_empty(foreign_key_value))
{
//Clear the choices list:
@@ -62,95 +62,11 @@ bool ComboChoices::refresh_data_from_database_with_foreign_key(const Document* d
set_choices_with_second(list_values);
return true;
}
-
- sharedptr<const Relationship> choice_relationship;
- sharedptr<const LayoutItem_Field> choice_field, choice_field_second;
- bool choice_show_all = false;
- layout_item->get_formatting_used().get_choices_related(choice_relationship, choice_field, choice_field_second, choice_show_all);
-
- if(!choice_field)
- {
- std::cerr << G_STRFUNC << ": !choice_field." << std::endl;
- return false;
- }
-
-
- if(choice_show_all)
- {
- //The list should be set in set_choices_related() instead.
- std::cerr << G_STRFUNC << ": Called with choice_show_all=true." << std::endl;
- return false;
- }
-
- Utils::type_vecConstLayoutFields fields;
- fields.push_back(choice_field);
- if(choice_field_second)
- fields.push_back(choice_field_second);
-
- //std::cout << G_STRFUNC << "debug: choice_field=" << choice_field->get_name() << ", choice_field_second" << choice_field_second->get_name() << std::endl;
-
- const Glib::ustring to_table = choice_relationship->get_to_table();
- const sharedptr<const Field> to_field = document->get_field(to_table, choice_relationship->get_to_field());
-
- //TODO: Support related relationships (in the UI too):
- Glib::RefPtr<Gnome::Gda::SqlBuilder> builder = Utils::build_sql_select_with_key(
- to_table,
- fields,
- to_field,
- foreign_key_value);
-
- if(!builder)
- {
- std::cerr << G_STRFUNC << ": builder is null." << std::endl;
- return false;
- }
-
- //TODO: builder->select_order_by(choice_field_id);
-
- //Connect to database and get the related values:
- sharedptr<SharedConnection> connection = ConnectionPool::get_instance()->connect();
-
- if(!connection)
- {
- std::cerr << G_STRFUNC << ": connection is null." << std::endl;
- return false;
- }
- const std::string sql_query =
- Utils::sqlbuilder_get_full_query(builder);
- //std::cout << "get_choice_values: Executing SQL: " << sql_query << std::endl;
- Glib::RefPtr<Gnome::Gda::DataModel> datamodel =
- connection->get_gda_connection()->statement_execute_select(sql_query);
-
- if(datamodel)
- {
- type_list_values_with_second list_values;
-
- const guint count = datamodel->get_n_rows();
- const guint cols_count = datamodel->get_n_columns();
- //std::cout << " result: count=" << count << std::endl;
- for(guint row = 0; row < count; ++row)
- {
-
- std::pair<Gnome::Gda::Value, Gnome::Gda::Value> itempair;
- itempair.first = datamodel->get_value_at(0, row);
-
- if(choice_field_second && (cols_count > 1))
- itempair.second = datamodel->get_value_at(1, row);
-
- list_values.push_back(itempair);
- }
-
- const Gnome::Gda::Value old_value = get_value();
- set_choices_with_second(list_values);
- set_value(old_value); //Try to preserve the value, even in iter-based ComboBoxes.
- }
- else
- {
- std::cerr << G_STRFUNC << ": Error while executing SQL" << std::endl <<
- " " << sql_query << std::endl;
- return false;
- }
+ const Utils::type_list_values_with_second list_values = Utils::get_choice_values(document, layout_item, foreign_key_value);
+ const Gnome::Gda::Value old_value = get_value();
+ set_choices_with_second(list_values);
+ set_value(old_value); //Try to preserve the value, even in iter-based ComboBoxes.
return true;
}
@@ -158,14 +74,14 @@ bool ComboChoices::refresh_data_from_database_with_foreign_key(const Document* d
void ComboChoices::set_choices_related(const Document* document)
{
type_list_values_with_second list_values;
-
- sharedptr<LayoutItem_Field> layout_item =
+
+ sharedptr<LayoutItem_Field> layout_item =
sharedptr<LayoutItem_Field>::cast_dynamic(get_layout_item());
if(layout_item)
{
bool choice_show_all = false;
- const sharedptr<const Relationship> choice_relationship =
- layout_item->get_formatting_used().get_choices_related_relationship(choice_show_all);
+ const sharedptr<const Relationship> choice_relationship =
+ layout_item->get_formatting_used().get_choices_related_relationship(choice_show_all);
//Set the values now because if it will be the same regardless of the foreign key value.
//Otherwise show them when refresh_data_from_database_with_foreign_key() is called.
diff --git a/glom/mode_data/datawidget/combochoices.h b/glom/mode_data/datawidget/combochoices.h
index 8f85323..6c885d0 100644
--- a/glom/mode_data/datawidget/combochoices.h
+++ b/glom/mode_data/datawidget/combochoices.h
@@ -62,7 +62,8 @@ public:
protected:
void init();
- typedef std::list< std::pair<Gnome::Gda::Value, Gnome::Gda::Value> > type_list_values_with_second;
+ typedef std::list<Gnome::Gda::Value> type_list_values;
+ typedef std::list< std::pair<Gnome::Gda::Value, type_list_values> > type_list_values_with_second;
virtual void set_choices_with_second(const type_list_values_with_second& list_values) = 0;
//Gnome::Gda::Value m_value; //The last-stored value. We have this because the displayed value might be unparseable.
diff --git a/glom/mode_data/datawidget/combochoiceswithtreemodel.cc b/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
index 0b64031..5726b7d 100644
--- a/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
+++ b/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
@@ -54,14 +54,19 @@ void ComboChoicesWithTreeModel::set_choices_with_second(const type_list_values_w
m_refModel->clear();
//TODO: Remove duplication with ComboEntry:
- sharedptr<LayoutItem_Field> layout_item =
+ sharedptr<LayoutItem_Field> layout_item =
sharedptr<LayoutItem_Field>::cast_dynamic(get_layout_item());
const FieldFormatting& format = layout_item->get_formatting_used();
sharedptr<const Relationship> choice_relationship;
- sharedptr<const LayoutItem_Field> layout_choice_first, layout_choice_second;
+ sharedptr<const LayoutItem_Field> layout_choice_first;
+ sharedptr<const LayoutGroup> layout_choice_extra;
bool choice_show_all = false;
- format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_second, choice_show_all);
-
+ format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_extra, choice_show_all);
+
+ LayoutGroup::type_list_const_items extra_fields;
+ if(layout_choice_extra)
+ extra_fields = layout_choice_extra->get_items_recursive();
+
for(type_list_values_with_second::const_iterator iter = list_values.begin(); iter != list_values.end(); ++iter)
{
Gtk::TreeModel::iterator iterTree = m_refModel->append();
@@ -71,9 +76,23 @@ void ComboChoicesWithTreeModel::set_choices_with_second(const type_list_values_w
{
row[m_Columns.m_col_first] = Conversions::get_text_for_gda_value(layout_choice_first->get_glom_type(), iter->first, layout_choice_first->get_formatting_used().m_numeric_format);
- if(layout_choice_second)
+ //TODO: Support multiple extra fields:
+ //For now, use only the first extra field:
+ const type_list_values extra_values = iter->second;
+ if(layout_choice_extra && !extra_values.empty())
{
- row[m_Columns.m_col_second] = Conversions::get_text_for_gda_value(layout_choice_second->get_glom_type(), iter->second, layout_choice_second->get_formatting_used().m_numeric_format);
+ for(LayoutGroup::type_list_const_items::const_iterator iterExtra = extra_fields.begin();
+ iterExtra != extra_fields.end(); ++iterExtra)
+ {
+ const sharedptr<const LayoutItem> item = *iterExtra;
+ const sharedptr<const LayoutItem_Field> item_field = sharedptr<const LayoutItem_Field>::cast_dynamic(item);
+ if(item_field)
+ {
+ const Gnome::Gda::Value value = *(extra_values.begin()); //TODO: Use a vector instead?
+ row[m_Columns.m_col_second] = Conversions::get_text_for_gda_value(item_field->get_glom_type(), value, item_field->get_formatting_used().m_numeric_format);
+ break;
+ }
+ }
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]