[glom] Fix crashes when using choices with fixed lists.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom] Fix crashes when using choices with fixed lists.
- Date: Sat, 12 Mar 2011 15:22:54 +0000 (UTC)
commit 7093469abe8dd414e1cf5e8a87bdeb5ee197f46d
Author: Murray Cumming <murrayc murrayc com>
Date: Sat Mar 12 16:22:20 2011 +0100
Fix crashes when using choices with fixed lists.
* glom/mode_data/datawidget/combochoiceswithtreemodel.[h|cc]:
create_model_non_db(): Instead of creating just a text-based treemodel,
create a Value-based one with an extra text column at the end. That is what
the related-records model has, though it uses a custom TreeModel.
The text column is needed for GtkComboBox when it has has-entry=true:
(See https://bugzilla.gnome.org/show_bug.cgi?id=631167 )
Add get_fixed_model_text_column() so that other code knows which column that
is.
* glom/mode_data/datawidget/cellrenderer_dblist.cc: set_choices_fixed(),
repack_cells_fixed():
* glom/mode_data/datawidget/combo.cc:set_choices_fixed():
Adapt to use the special column instead of assuming that column 0 is a text
column.
Previously Glom::Combo::set_value() crashed because we tried to get a
Value<Gnome::Gda::Value> where there was a Value<ustring>.
ChangeLog | 20 ++++++++
glom/mode_data/datawidget/cellrenderer_dblist.cc | 8 ++--
glom/mode_data/datawidget/combo.cc | 9 +++-
.../datawidget/combochoiceswithtreemodel.cc | 51 ++++++++++++++++---
.../datawidget/combochoiceswithtreemodel.h | 18 ++++++-
5 files changed, 89 insertions(+), 17 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index c4f332a..a52d047 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2011-03-12 Murray Cumming <murrayc murrayc com>
+
+ Fix crashes when using choices with fixed lists.
+
+ * glom/mode_data/datawidget/combochoiceswithtreemodel.[h|cc]:
+ create_model_non_db(): Instead of creating just a text-based treemodel,
+ create a Value-based one with an extra text column at the end. That is what
+ the related-records model has, though it uses a custom TreeModel.
+ The text column is needed for GtkComboBox when it has has-entry=true:
+ (See https://bugzilla.gnome.org/show_bug.cgi?id=631167 )
+ Add get_fixed_model_text_column() so that other code knows which column that
+ is.
+ * glom/mode_data/datawidget/cellrenderer_dblist.cc: set_choices_fixed(),
+ repack_cells_fixed():
+ * glom/mode_data/datawidget/combo.cc: set_choices_fixed():
+ Adapt to use the special column instead of assuming that column 0 is a text
+ column.
+ Previously Glom::Combo::set_value() crashed because we tried to get a
+ Value<Gnome::Gda::Value> where there was a Value<ustring>.
+
2011-03-08 Murray Cumming <murrayc murrayc com>
Remove some unnecessary padding/borders around the main window.
diff --git a/glom/mode_data/datawidget/cellrenderer_dblist.cc b/glom/mode_data/datawidget/cellrenderer_dblist.cc
index fcc391d..a080bb0 100644
--- a/glom/mode_data/datawidget/cellrenderer_dblist.cc
+++ b/glom/mode_data/datawidget/cellrenderer_dblist.cc
@@ -48,7 +48,7 @@ void CellRendererDbList::set_choices_fixed(const FieldFormatting::type_list_valu
//Show model in the view:
property_model() = model;
- property_text_column() = 0; //This must be a text column, in m_refModel.
+ property_text_column() = get_fixed_model_text_column(); //This must be a text column, in m_refModel.
property_editable() = true; //It would be useless if we couldn't edit it.
//The other cells are added in on_editing_started().
@@ -112,7 +112,7 @@ void CellRendererDbList::repack_cells_fixed(Gtk::CellLayout* combobox)
cell->unreference();
//Make the renderer render the column:
- combobox->add_attribute(*cell, "text", 0);
+ combobox->add_attribute(*cell, "text", get_fixed_model_text_column());
cell->property_xalign() = 0.0f;
@@ -121,9 +121,9 @@ void CellRendererDbList::repack_cells_fixed(Gtk::CellLayout* combobox)
//Add extra cells:
Glib::ListHandle<Gtk::CellRenderer*> cells = combobox->get_cells();
- if(cells.size() < m_vec_model_columns_fixed.size())
+ if(cells.size() < m_vec_model_columns_value_fixed.size())
{
- for(guint col = cells.size(); col != m_vec_model_columns_fixed.size(); ++col)
+ for(guint col = cells.size(); col != m_vec_model_columns_value_fixed.size(); ++col)
{
Gtk::CellRenderer* cell = 0;
if(m_db_layout_items.empty())
diff --git a/glom/mode_data/datawidget/combo.cc b/glom/mode_data/datawidget/combo.cc
index 670f360..17fca4d 100644
--- a/glom/mode_data/datawidget/combo.cc
+++ b/glom/mode_data/datawidget/combo.cc
@@ -88,7 +88,7 @@ void ComboGlom::set_choices_fixed(const FieldFormatting::type_list_values& list_
if(get_has_entry())
{
- set_entry_text_column(0);
+ set_entry_text_column( get_fixed_model_text_column() );
}
else
{
@@ -103,11 +103,16 @@ void ComboGlom::set_choices_fixed(const FieldFormatting::type_list_values& list_
return;
}
- const guint columns_count = model->get_n_columns();
+ guint columns_count = model->get_n_columns();
+ if(columns_count)
+ columns_count -= 1; //The last one is the just the extra text-equivalent of the first one, for GtkComboBox wth has-entry=true.
+
for(guint i = 0; i < columns_count; ++i)
{
//set_entry_text_column() adds its own CellRenderer,
//which we cannot replace without confusing (and crashing) GtkComboBox.
+ //We used the special get_fixed_model_text_column() column for that,
+ //so we don't need to add another cell renderer for the value-equivalent of that column:
if(i == 0 && get_has_entry())
continue;
diff --git a/glom/mode_data/datawidget/combochoiceswithtreemodel.cc b/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
index 2fcf74e..445b7aa 100644
--- a/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
+++ b/glom/mode_data/datawidget/combochoiceswithtreemodel.cc
@@ -52,6 +52,15 @@ void ComboChoicesWithTreeModel::init()
ComboChoices::init();
}
+int ComboChoicesWithTreeModel::get_fixed_model_text_column() const
+{
+ const int count = m_refModel->get_n_columns();
+ if(count > 0)
+ return count -1;
+ else
+ return 0; //An error, but better than a negative number.
+}
+
void ComboChoicesWithTreeModel::create_model_non_db(guint columns_count)
{
delete_model();
@@ -59,13 +68,29 @@ void ComboChoicesWithTreeModel::create_model_non_db(guint columns_count)
Gtk::TreeModel::ColumnRecord record;
//Create the TreeModelColumns, adding them to the ColumnRecord:
- m_vec_model_columns_fixed.resize(columns_count, 0);
+
+ m_vec_model_columns_value_fixed.resize(columns_count, 0);
for(guint i = 0; i < columns_count; ++i)
- {
- type_model_column_fixed* model_column = new type_model_column_fixed();
+ {
+ //Create a value column for all columns
+ //for instance for later value comparison.
+ type_model_column_value_fixed* model_column = new type_model_column_value_fixed();
+
+ //Store it so we can use it and delete it later:
+ m_vec_model_columns_value_fixed[i] = model_column;
+ record.add(*model_column);
+ }
+
+ //Create a text column, for use by a GtkComboBox with has-entry, which allows no other column type:
+ //Note that get_fixed_model_text_column() assumes that this is the last column:
+ m_vec_model_columns_string_fixed.resize(1, 0);
+ if(columns_count > 0)
+ {
+ type_model_column_string_fixed* model_column = new type_model_column_string_fixed();
+
//Store it so we can use it and delete it later:
- m_vec_model_columns_fixed[i] = model_column;
+ m_vec_model_columns_string_fixed.push_back(model_column);
record.add(*model_column);
}
@@ -77,12 +102,20 @@ void ComboChoicesWithTreeModel::create_model_non_db(guint columns_count)
void ComboChoicesWithTreeModel::delete_model()
{
//Delete the vector's items:
- for(type_vec_model_columns_fixed::iterator iter = m_vec_model_columns_fixed.begin(); iter != m_vec_model_columns_fixed.end(); ++iter)
+ for(type_vec_model_columns_string_fixed::iterator iter = m_vec_model_columns_string_fixed.begin(); iter != m_vec_model_columns_string_fixed.end(); ++iter)
+ {
+ type_model_column_string_fixed* model_column = *iter;
+ delete model_column;
+ }
+ m_vec_model_columns_string_fixed.clear();
+
+ //Delete the vector's items:
+ for(type_vec_model_columns_value_fixed::iterator iter = m_vec_model_columns_value_fixed.begin(); iter != m_vec_model_columns_value_fixed.end(); ++iter)
{
- type_model_column_fixed* model_column = *iter;
+ type_model_column_value_fixed* model_column = *iter;
delete model_column;
}
- m_vec_model_columns_fixed.clear();
+ m_vec_model_columns_value_fixed.clear();
m_refModel.reset();
}
@@ -189,8 +222,10 @@ void ComboChoicesWithTreeModel::set_choices_fixed(const FieldFormatting::type_li
if(layout_item)
{
const Gnome::Gda::Value value = *iter;
+ row.set_value(0, value);
+
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.set_value(0, text);
+ row.set_value(1, text);
}
}
diff --git a/glom/mode_data/datawidget/combochoiceswithtreemodel.h b/glom/mode_data/datawidget/combochoiceswithtreemodel.h
index 4a185a2..65f3be0 100644
--- a/glom/mode_data/datawidget/combochoiceswithtreemodel.h
+++ b/glom/mode_data/datawidget/combochoiceswithtreemodel.h
@@ -56,9 +56,21 @@ protected:
*/
int get_fixed_cell_height(Gtk::Widget& widget);
- typedef Gtk::TreeModelColumn<Glib::ustring> type_model_column_fixed;
- typedef std::vector< type_model_column_fixed* > type_vec_model_columns_fixed;
- type_vec_model_columns_fixed m_vec_model_columns_fixed; //If set_choices_fixed() was used.
+
+ typedef Gtk::TreeModelColumn<Glib::ustring> type_model_column_string_fixed;
+ typedef std::vector< type_model_column_string_fixed* > type_vec_model_columns_string_fixed;
+ type_vec_model_columns_string_fixed m_vec_model_columns_string_fixed; //If set_choices_fixed() was used.
+
+ typedef Gtk::TreeModelColumn<Gnome::Gda::Value> type_model_column_value_fixed;
+ typedef std::vector< type_model_column_value_fixed* > type_vec_model_columns_value_fixed;
+ type_vec_model_columns_value_fixed m_vec_model_columns_value_fixed; //If set_choices_fixed() was used.
+
+ /** Get the index of the extra column, at the end, that is just a
+ * text representation of the first column, for use by GtkCombo with has-entry=true,
+ * which accepts only a text column.
+ */
+ int get_fixed_model_text_column() const;
+
typedef std::vector< sharedptr<const LayoutItem_Field> > type_vec_const_layout_items;
type_vec_const_layout_items m_db_layout_items; //If set_choices_related() was used.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]