[glom] Combo widgets: Support multiple extra fields.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom] Combo widgets: Support multiple extra fields.
- Date: Wed, 8 Sep 2010 10:28:11 +0000 (UTC)
commit 7973657aa82d40fa1b0c9fae305264afe26878ba
Author: Murray Cumming <murrayc murrayc com>
Date: Wed Sep 8 11:44:39 2010 +0200
Combo widgets: Support multiple extra fields.
* glom/libglom/utils.cc: get_choice_values(): Actually get extra values other
than than the first one, by actually using the index instead of just 1.
* glom/mode_data/datawidget/combochoiceswithtreemodel.[h|cc]:
Added a virtual create_model(), to create model columns dynamically. So far
they are just text columns.
set_choices_with_second(): Recreate the model here each time.
* glom/mode_data/datawidget/combo.[h|cc]:
* glom/mode_data/datawidget/comboentry.[h|cc]: Override create_model() to
also set up the view columns using the widgets' specific API.
* glom/mode_data/datawidget/combochoices.h: set_choices_related():
Stop this from being virtual because we no longer override it.
ChangeLog | 16 ++++
glom/libglom/document/document.cc | 1 -
glom/libglom/utils.cc | 3 +-
glom/mode_data/datawidget/combo.cc | 57 +++++---------
glom/mode_data/datawidget/combo.h | 5 +-
glom/mode_data/datawidget/combochoices.h | 2 +-
.../datawidget/combochoiceswithtreemodel.cc | 83 +++++++++++++++++---
.../datawidget/combochoiceswithtreemodel.h | 21 ++----
glom/mode_data/datawidget/comboentry.cc | 46 ++++-------
glom/mode_data/datawidget/comboentry.h | 5 +-
glom/utility_widgets/db_adddel/db_adddel.h | 11 ---
11 files changed, 136 insertions(+), 114 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6cb6bfb..14f07dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
2010-09-08 Murray Cumming <murrayc murrayc com>
+ Combo widgets: Support multiple extra fields.
+
+ * glom/libglom/utils.cc: get_choice_values(): Actually get extra values other
+ than than the first one, by actually using the index instead of just 1.
+ * glom/mode_data/datawidget/combochoiceswithtreemodel.[h|cc]:
+ Added a virtual create_model(), to create model columns dynamically. So far
+ they are just text columns.
+ set_choices_with_second(): Recreate the model here each time.
+ * glom/mode_data/datawidget/combo.[h|cc]:
+ * glom/mode_data/datawidget/comboentry.[h|cc]: Override create_model() to
+ also set up the view columns using the widgets' specific API.
+ * glom/mode_data/datawidget/combochoices.h: set_choices_related():
+ Stop this from being virtual because we no longer override it.
+
+2010-09-08 Murray Cumming <murrayc murrayc com>
+
Initial support for multiple show-also fields in related choices.
* glom/glom_developer.glade: Formatting box: related choices:
diff --git a/glom/libglom/document/document.cc b/glom/libglom/document/document.cc
index 6860a65..cc318dd 100644
--- a/glom/libglom/document/document.cc
+++ b/glom/libglom/document/document.cc
@@ -2020,7 +2020,6 @@ void Document::load_after_layout_item_formatting(const xmlpp::Element* element,
xmlpp::Element* nodeExtraLayout = get_node_child_named(element, GLOM_ATTRIBUTE_FORMAT_CHOICES_RELATED_EXTRA_LAYOUT);
if(nodeExtraLayout)
{
- std::cout << "debuga1" << std::endl;
xmlpp::Element* nodeGroups = get_node_child_named(nodeExtraLayout, GLOM_NODE_DATA_LAYOUT_GROUPS);
if(nodeGroups)
{
diff --git a/glom/libglom/utils.cc b/glom/libglom/utils.cc
index 2691fa0..ff3770c 100644
--- a/glom/libglom/utils.cc
+++ b/glom/libglom/utils.cc
@@ -524,6 +524,7 @@ Utils::type_list_values_with_second Utils::get_choice_values(const Document* doc
iter != extra_fields.end(); ++iter)
{
const sharedptr<const LayoutItem> item = *iter;
+ std::cout << "debug: item=" << item->get_name() << std::endl;
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.
@@ -586,7 +587,7 @@ Utils::type_list_values_with_second Utils::get_choice_values(const Document* doc
type_list_values list_values;
for(guint i = 1; i < cols_count; ++i)
{
- list_values.push_back(datamodel->get_value_at(1, row));
+ list_values.push_back(datamodel->get_value_at(i, row));
}
itempair.second = list_values;
diff --git a/glom/mode_data/datawidget/combo.cc b/glom/mode_data/datawidget/combo.cc
index fe0d980..d693b18 100644
--- a/glom/mode_data/datawidget/combo.cc
+++ b/glom/mode_data/datawidget/combo.cc
@@ -38,8 +38,7 @@ namespace DataWidgetChildren
{
ComboGlom::ComboGlom()
-: ComboChoicesWithTreeModel(),
- m_cell_second(0)
+: ComboChoicesWithTreeModel()
{
#ifndef GLOM_ENABLE_CLIENT_ONLY
setup_menu();
@@ -50,10 +49,7 @@ ComboGlom::ComboGlom()
void ComboGlom::init()
{
- #ifndef GLOM_ENABLE_MAEMO
- set_model(m_refModel);
- pack_start(m_Columns.m_col_first);
- #else
+ #ifdef GLOM_ENABLE_MAEMO
//Maemo:
set_selector(m_maemo_selector);
m_maemo_selector.set_model(0, m_refModel);
@@ -73,40 +69,25 @@ ComboGlom::~ComboGlom()
{
}
-void ComboGlom::set_choices_related(const Document* document)
+void ComboGlom::create_model(guint columns_count)
{
- //TODO: Remove duplication with ComboEntry:
- sharedptr<LayoutItem_Field> layout_item =
- sharedptr<LayoutItem_Field>::cast_dynamic(get_layout_item());
- bool choice_show_all = false;
- bool choice_has_second = false;
- layout_item->get_formatting_used().get_has_related_choices(choice_show_all, choice_has_second);
-
- //Add the extra cell if necessary:
- if(!m_cell_second && choice_has_second)
- {
- #ifndef GLOM_ENABLE_MAEMO
- //We don't use this convenience method, because we want more control over the renderer.
- //and CellLayout gives no way to get the renderer back afterwards.
- //(well, maybe set_cell_data_func(), but that's a bit awkward.)
- //pack_start(m_Columns.m_col_second);
+ //Create the model itself:
+ ComboChoicesWithTreeModel::create_model(columns_count);
- m_cell_second = Gtk::manage(new Gtk::CellRendererText);
- m_cell_second->set_property("xalign", 0.0);
+ //Show the model in the view:
+ set_model(m_refModel);
+
+ for(guint i = 0; i < columns_count; ++i)
+ {
+ Gtk::CellRendererText* cell = Gtk::manage(new Gtk::CellRendererText);
+ cell->set_property("xalign", 0.0);
//Use the renderer:
- pack_start(*m_cell_second);
+ pack_start(*cell);
//Make the renderer render the column:
- add_attribute(m_cell_second->_property_renderable(), m_Columns.m_col_second);
- std::cout << "debug: Added second column." << std::endl;
- #else
- //Maemo:
- column->pack_start(m_Columns.m_col_second);
- #endif //GLOM_ENABLE_MAEMO
+ add_attribute(*cell, "text", i);
}
-
- ComboChoicesWithTreeModel::set_choices_related(document);
}
void ComboGlom::check_for_change()
@@ -177,7 +158,9 @@ void ComboGlom::set_text(const Glib::ustring& text)
for(Gtk::TreeModel::iterator iter = m_refModel->children().begin(); iter != m_refModel->children().end(); ++iter)
{
- Glib::ustring this_text = (*iter)[m_Columns.m_col_first];
+ const Gtk::TreeModel::Row row = *iter;
+ Glib::ustring this_text;
+ row.get_value(0, this_text);
if(this_text == text)
{
@@ -225,8 +208,10 @@ Glib::ustring ComboGlom::get_text() const
if(iter)
{
- Gtk::TreeModel::Row row = *iter;
- return row[m_Columns.m_col_first];
+ const Gtk::TreeModel::Row row = *iter;
+ Glib::ustring text;
+ row.get_value(0, text);
+ return text;
}
return Glib::ustring();
diff --git a/glom/mode_data/datawidget/combo.h b/glom/mode_data/datawidget/combo.h
index 830cb5c..17afac0 100644
--- a/glom/mode_data/datawidget/combo.h
+++ b/glom/mode_data/datawidget/combo.h
@@ -72,10 +72,9 @@ public:
virtual Gnome::Gda::Value get_value() const;
- virtual void set_choices_related(const Document* document);
-
private:
void init();
+ virtual void create_model(guint columns_count);
#ifndef GLOM_ENABLE_MAEMO
// Note that this is a normal signal handler when glibmm was complied
@@ -100,8 +99,6 @@ private:
#ifdef GLOM_ENABLE_MAEMO
Hildon::TouchSelector m_maemo_selector;
#endif
-
- Gtk::CellRenderer* m_cell_second;
};
} //namespace DataWidetChildren
diff --git a/glom/mode_data/datawidget/combochoices.h b/glom/mode_data/datawidget/combochoices.h
index 6c885d0..5b0776b 100644
--- a/glom/mode_data/datawidget/combochoices.h
+++ b/glom/mode_data/datawidget/combochoices.h
@@ -51,7 +51,7 @@ public:
/**
* See also refresh_data_from_database_with_foreign_key().
*/
- virtual void set_choices_related(const Document* document);
+ void set_choices_related(const Document* document);
/** Update a choices widget's list of related choices if a relevant value in its parent table has changed.
*
diff --git a/glom/mode_data/datawidget/combochoiceswithtreemodel.cc b/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
index 5726b7d..36de73c 100644
--- a/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
+++ b/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
@@ -39,20 +39,68 @@ ComboChoicesWithTreeModel::ComboChoicesWithTreeModel()
init();
}
+ComboChoicesWithTreeModel::~ComboChoicesWithTreeModel()
+{
+ delete_model();
+}
+
void ComboChoicesWithTreeModel::init()
{
ComboChoices::init();
- m_refModel = Gtk::ListStore::create(m_Columns);
}
-ComboChoicesWithTreeModel::~ComboChoicesWithTreeModel()
+void ComboChoicesWithTreeModel::create_model(guint columns_count)
{
+ delete_model();
+
+ Gtk::TreeModel::ColumnRecord record;
+
+ //Create the TreeModelColumns, adding them to the ColumnRecord:
+ m_vec_model_columns.resize(columns_count, 0);
+ for(guint i = 0; i < columns_count; ++i)
+ {
+ type_model_column* model_column = new type_model_column();
+
+ //Store it so we can use it and delete it later:
+ m_vec_model_columns[i] = model_column;
+
+ record.add(*model_column);
+ }
+
+ //Create the model:
+ m_refModel = Gtk::ListStore::create(record);
+}
+
+void ComboChoicesWithTreeModel::delete_model()
+{
+ //Delete the vector's items:
+ for(type_vec_model_columns::iterator iter = m_vec_model_columns.begin(); iter != m_vec_model_columns.end(); ++iter)
+ {
+ type_model_column* model_column = *iter;
+ if(model_column)
+ delete model_column;
+ }
+ m_vec_model_columns.clear();
+
+ m_refModel.reset();
}
void ComboChoicesWithTreeModel::set_choices_with_second(const type_list_values_with_second& list_values)
{
- m_refModel->clear();
+ //Recreate the entire model:
+ guint columns_count = 1; //For the main field.
+ if(!list_values.empty())
+ {
+ type_list_values_with_second::const_iterator iter= list_values.begin();
+ if(iter != list_values.end())
+ {
+ const type_list_values& second = iter->second;
+ columns_count += second.size();
+ }
+ }
+ create_model(columns_count);
+ //Fill the model with data:
//TODO: Remove duplication with ComboEntry:
sharedptr<LayoutItem_Field> layout_item =
sharedptr<LayoutItem_Field>::cast_dynamic(get_layout_item());
@@ -74,24 +122,36 @@ void ComboChoicesWithTreeModel::set_choices_with_second(const type_list_values_w
if(layout_choice_first)
{
- 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);
+ const Glib::ustring text =
+ Conversions::get_text_for_gda_value(layout_choice_first->get_glom_type(), iter->first, layout_choice_first->get_formatting_used().m_numeric_format);
+ row.set_value(0, text);
- //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())
{
+ guint model_index = 1; //0 is for the main field.
+ type_list_values::const_iterator iterValues = extra_values.begin();
for(LayoutGroup::type_list_const_items::const_iterator iterExtra = extra_fields.begin();
iterExtra != extra_fields.end(); ++iterExtra)
{
+ if(model_index >= columns_count)
+ break;
+
+ if(iterValues == extra_values.end())
+ break;
+
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;
+ const Gnome::Gda::Value value = *iterValues;
+ const Glib::ustring text =
+ Conversions::get_text_for_gda_value(item_field->get_glom_type(), value, item_field->get_formatting_used().m_numeric_format);
+ row.set_value(model_index, text);
}
+
+ ++model_index;
+ ++iterValues;
}
}
}
@@ -101,7 +161,7 @@ void ComboChoicesWithTreeModel::set_choices_with_second(const type_list_values_w
void ComboChoicesWithTreeModel::set_choices(const FieldFormatting::type_list_values& list_values)
{
- m_refModel->clear();
+ create_model(1);
for(FieldFormatting::type_list_values::const_iterator iter = list_values.begin(); iter != list_values.end(); ++iter)
{
@@ -113,8 +173,7 @@ void ComboChoicesWithTreeModel::set_choices(const FieldFormatting::type_list_val
{
const Gnome::Gda::Value value = *iter;
const Glib::ustring text = Conversions::get_text_for_gda_value(layout_item->get_glom_type(), value, layout_item->get_formatting_used().m_numeric_format);
-
- row[m_Columns.m_col_first] = text;
+ row.set_value(0, text);
}
}
}
diff --git a/glom/mode_data/datawidget/combochoiceswithtreemodel.h b/glom/mode_data/datawidget/combochoiceswithtreemodel.h
index 8cad4e8..6c0d16e 100644
--- a/glom/mode_data/datawidget/combochoiceswithtreemodel.h
+++ b/glom/mode_data/datawidget/combochoiceswithtreemodel.h
@@ -41,28 +41,21 @@ public:
protected:
void init();
+ virtual void create_model(guint columns_count);
virtual void set_choices_with_second(const type_list_values_with_second& list_values);
- //Tree model columns:
- class ModelColumns : public Gtk::TreeModel::ColumnRecord
- {
- public:
-
- ModelColumns()
- { add(m_col_first); add(m_col_second); }
-
- Gtk::TreeModelColumn<Glib::ustring> m_col_first; //The data to choose - this must be text.
- Gtk::TreeModelColumn<Glib::ustring> m_col_second;
- };
+ Glib::RefPtr<Gtk::ListStore> m_refModel;
- ModelColumns m_Columns;
+private:
+ typedef Gtk::TreeModelColumn<Glib::ustring> type_model_column;
+ typedef std::vector< type_model_column* > type_vec_model_columns;
+ type_vec_model_columns m_vec_model_columns;
- Glib::RefPtr<Gtk::ListStore> m_refModel;
+ void delete_model();
};
} //namespace DataWidetChildren
} //namespace Glom
#endif //GLOM_UTILITY_WIDGETS_COMBO_CHOICES_WITH_TREE_MODEL_H
-
diff --git a/glom/mode_data/datawidget/comboentry.cc b/glom/mode_data/datawidget/comboentry.cc
index 5188330..b7afa88 100644
--- a/glom/mode_data/datawidget/comboentry.cc
+++ b/glom/mode_data/datawidget/comboentry.cc
@@ -42,8 +42,7 @@ namespace DataWidgetChildren
{
ComboEntry::ComboEntry()
-: ComboChoicesWithTreeModel(),
- m_cell_second(0)
+: ComboChoicesWithTreeModel()
{
#ifndef GLOM_ENABLE_CLIENT_ONLY
setup_menu();
@@ -72,10 +71,7 @@ const Gtk::Entry* ComboEntry::get_entry() const
void ComboEntry::init()
{
-#ifndef GLOM_ENABLE_MAEMO
- set_model(m_refModel);
- set_text_column(m_Columns.m_col_first);
-#else
+#ifdef GLOM_ENABLE_CLIENT_ONLY
//Maemo:
set_selector(m_maemo_selector);
@@ -112,36 +108,26 @@ ComboEntry::~ComboEntry()
{
}
-void ComboEntry::set_choices_related(const Document* document)
+void ComboEntry::create_model(guint columns_count)
{
- sharedptr<LayoutItem_Field> layout_item =
- sharedptr<LayoutItem_Field>::cast_dynamic(get_layout_item());
- bool choice_show_all = false;
- bool choice_has_second = false;
- layout_item->get_formatting_used().get_has_related_choices(choice_show_all, choice_has_second);
-
- if(!m_cell_second && choice_has_second) //Use a more efficient way of discovering if there is a second column.
- {
- #ifndef GLOM_ENABLE_MAEMO
- //We don't use this convenience method, because we want more control over the renderer.
- //and CellLayout gives no way to get the renderer back afterwards.
- //(well, maybe set_cell_data_func(), but that's a bit awkward.)
- //pack_start(m_Columns.m_col_second);
+ //Create the model itself:
+ ComboChoicesWithTreeModel::create_model(columns_count);
- m_cell_second = Gtk::manage(new Gtk::CellRendererText);
- m_cell_second->set_property("xalign", 0.0);
+ //Show model in the view:
+ set_model(m_refModel);
+ set_text_column(0);
+
+ for(guint i = 1; i < columns_count; ++i)
+ {
+ Gtk::CellRendererText* cell = Gtk::manage(new Gtk::CellRendererText);
+ cell->set_property("xalign", 0.0);
//Use the renderer:
- pack_start(*m_cell_second);
+ pack_start(*cell);
//Make the renderer render the column:
- add_attribute(m_cell_second->_property_renderable(), m_Columns.m_col_second);
- #else //GLOM_ENABLE_MAEMO
- column->pack_start(m_Columns.m_col_second, false);
- #endif //GLOM_ENABLE_MAEMO
+ add_attribute(*cell, "text", i);
}
-
- ComboChoicesWithTreeModel::set_choices_related(document);
}
void ComboEntry::set_layout_item(const sharedptr<LayoutItem>& layout_item, const Glib::ustring& table_name)
@@ -189,7 +175,7 @@ void ComboEntry::check_for_change()
bool success = false;
sharedptr<const LayoutItem_Field> layout_item = sharedptr<const LayoutItem_Field>::cast_dynamic(get_layout_item());
- Gnome::Gda::Value value = Conversions::parse_value(layout_item->get_glom_type(), get_entry()->get_text(), layout_item->get_formatting_used().m_numeric_format, success);
+ const Gnome::Gda::Value value = Conversions::parse_value(layout_item->get_glom_type(), get_entry()->get_text(), layout_item->get_formatting_used().m_numeric_format, success);
if(success)
{
diff --git a/glom/mode_data/datawidget/comboentry.h b/glom/mode_data/datawidget/comboentry.h
index 87fa061..df8fe21 100644
--- a/glom/mode_data/datawidget/comboentry.h
+++ b/glom/mode_data/datawidget/comboentry.h
@@ -71,10 +71,9 @@ public:
virtual void set_read_only(bool read_only = true);
- virtual void set_choices_related(const Document* document);
-
private:
void init();
+ virtual void create_model(guint columns_count);
//Overrides of default signal handlers:
@@ -110,8 +109,6 @@ private:
#ifdef GLOM_ENABLE_MAEMO
Hildon::TouchSelectorEntry m_maemo_selector;
#endif
-
- Gtk::CellRenderer* m_cell_second;
};
} //namespace DataWidetChildren
diff --git a/glom/utility_widgets/db_adddel/db_adddel.h b/glom/utility_widgets/db_adddel/db_adddel.h
index e09521d..7ea85dd 100644
--- a/glom/utility_widgets/db_adddel/db_adddel.h
+++ b/glom/utility_widgets/db_adddel/db_adddel.h
@@ -405,9 +405,6 @@ private:
Gtk::TreeView m_TreeView;
#endif
-
- Gtk::TreeModel::ColumnRecord m_ColumnRecord;
-
//typedef Gtk::ListStore type_model_store;
typedef DbTreeModel type_model_store;
Glib::RefPtr<type_model_store> m_refListStore;
@@ -493,14 +490,6 @@ private:
bool m_bPreventUserSignals, m_bIgnoreTreeViewSignals;
};
-/*
- class DynamicColumnRecord : public Gtk::TreeModel::ColumnRecord
- {
- typedef std::vector<Gtk::TreeModelColumnBase> type_vecColumns;
- type_vecColumns m_vecColumns;
- };
-*/
-
//When no columns have been chosen in the layout editor,
//show this model to give the user a hint about what to do:
class ModelColumnsEmptyHint : public Gtk::TreeModel::ColumnRecord
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]