[glade3] * plugins/gtk+/glade-gtk.c: - Check for type compatibility before setting cell renderer attribut
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glade3] * plugins/gtk+/glade-gtk.c: - Check for type compatibility before setting cell renderer attribut
- Date: Sun, 28 Mar 2010 03:11:07 +0000 (UTC)
commit f1bcd41832d6a919af24e94b58f86b0f819059fc
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Sat Mar 27 23:10:03 2010 -0400
* plugins/gtk+/glade-gtk.c:
- Check for type compatibility before setting cell renderer attributes
- Clear cell renderer attributes before setting liststore column types and resync them after
(Avoids cricital warnings where the underlying data types changed and dont match the properties
of the renderers)
- Fill in the gaps in model data while loading some columns with non serializable types
(fixes severe bug: model data was loaded with missing columns of data).
* plugins/gtk+/glade-column-types.c, plugins/gtk+/glade-model-data.c:
allow model data with explicitly G_TYPE_INVALID types.
ChangeLog | 9 +
plugins/gtk+/glade-column-types.c | 9 +-
plugins/gtk+/glade-gtk.c | 341 ++++++++++++++++++++++++-------------
plugins/gtk+/glade-model-data.c | 26 ++-
plugins/gtk+/glade-model-data.h | 2 +-
5 files changed, 254 insertions(+), 133 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index af16870..b61edd9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -14,6 +14,12 @@
- Substitute the old manual evaluation with GPC_VERSION_CHECK()
- Avoid critical warnings when setting GtkColorButton properties to NULL
- Avoid critical warnings when setting GtkComboBoxEntry::text-column < 0
+ - Check for type compatibility before setting cell renderer attributes
+ - Clear cell renderer attributes before setting liststore column types and resync them after
+ (Avoids cricital warnings where the underlying data types changed and dont match the properties
+ of the renderers)
+ - Fill in the gaps in model data while loading some columns with non serializable types
+ (fixes severe bug: model data was loaded with missing columns of data).
* gladeui/glade-property-class.h: Created convenience macro GPC_VERSION_CHECK
@@ -22,6 +28,9 @@
assume a path that is: ${prefix}/lib/glade3/modules/../../ and search it after the initial
module search path.
+ * plugins/gtk+/glade-column-types.c, plugins/gtk+/glade-model-data.c:
+ allow model data with explicitly G_TYPE_INVALID types.
+
2010-03-26 Tristan Van Berkom <tvb gnome org>
* gladeui/glade-palette.c: Left aligned and ellipsize end widget group titles (restored normal
diff --git a/plugins/gtk+/glade-column-types.c b/plugins/gtk+/glade-column-types.c
index 10efe4a..8b3b72b 100644
--- a/plugins/gtk+/glade-column-types.c
+++ b/plugins/gtk+/glade-column-types.c
@@ -145,7 +145,7 @@ glade_column_list_copy (GList *list)
for (l = list; l; l = g_list_next (l))
{
- GladeColumnType *new_data = g_new0(GladeColumnType, 1);
+ GladeColumnType *new_data = g_slice_new0 (GladeColumnType);
GladeColumnType *data = l->data;
new_data->type_name = g_strdup (data->type_name);
@@ -162,7 +162,7 @@ glade_column_type_free (GladeColumnType *column)
{
g_free (column->type_name);
g_free (column->column_name);
- g_free (column);
+ g_slice_free (GladeColumnType, column);
}
void
@@ -286,8 +286,7 @@ eprop_column_adjust_rows (GladeEditorProperty *eprop, GList *columns)
column = list->data;
- if ((data_type = g_type_from_name (column->type_name)) == G_TYPE_INVALID)
- data_type = G_TYPE_POINTER;
+ data_type = g_type_from_name (column->type_name);
if ((idx = glade_model_data_column_index (data_tree, column->column_name)) < 0)
{
@@ -324,7 +323,7 @@ eprop_column_append (GladeEditorProperty *eprop,
if (columns)
columns = glade_column_list_copy (columns);
- data = g_new0 (GladeColumnType, 1);
+ data = g_slice_new0 (GladeColumnType);
data->column_name = g_strdup (column_name);
data->type_name = g_strdup (type_name);
diff --git a/plugins/gtk+/glade-gtk.c b/plugins/gtk+/glade-gtk.c
index e0857dd..fb30166 100644
--- a/plugins/gtk+/glade-gtk.c
+++ b/plugins/gtk+/glade-gtk.c
@@ -10139,15 +10139,167 @@ glade_gtk_icon_factory_create_editable (GladeWidgetAdaptor *adaptor,
#define GLADE_TAG_DATA "data"
#define GLADE_TAG_COL "col"
+
+static gboolean
+glade_gtk_cell_layout_has_renderer (GtkCellLayout *layout,
+ GtkCellRenderer *renderer)
+{
+ GList *cells = gtk_cell_layout_get_cells (layout);
+ gboolean has_renderer;
+
+ has_renderer = (g_list_find (cells, renderer) != NULL);
+
+ g_list_free (cells);
+
+ return has_renderer;
+}
+
+static gboolean
+glade_gtk_cell_renderer_sync_attributes (GObject *object)
+{
+
+ GtkCellLayout *layout;
+ GtkCellRenderer *cell;
+ GladeWidget *widget = glade_widget_get_from_gobject (object);
+ GladeWidget *gmodel;
+ GladeProperty *property;
+ gchar *attr_prop_name;
+ GList *l, *column_list = NULL;
+ gint columns = 0;
+ static gint attr_len = 0;
+
+ if (!attr_len)
+ attr_len = strlen ("attr-");
+
+ /* Apply attributes to renderer when bound to a model in runtime */
+ widget = glade_widget_get_from_gobject (object);
+
+ if (widget->parent == NULL) return FALSE;
+
+ /* When creating widgets, sometimes the parent is set before parenting happens,
+ * here we have to be careful for that..
+ */
+ layout = GTK_CELL_LAYOUT (widget->parent->object);
+ cell = GTK_CELL_RENDERER (object);
+
+ if (!glade_gtk_cell_layout_has_renderer (layout, cell))
+ return FALSE;
+
+ if ((gmodel = glade_cell_renderer_get_model (widget)) == NULL)
+ return FALSE;
+
+ glade_widget_property_get (gmodel, "columns", &column_list);
+ columns = g_list_length (column_list);
+
+ gtk_cell_layout_clear_attributes (layout, cell);
+
+ for (l = widget->properties; l; l = l->next)
+ {
+ property = l->data;
+
+ if (strncmp (property->klass->id, "attr-", attr_len) == 0)
+ {
+ GladeProperty *attr_prop;
+ gint column = g_value_get_int (property->value);
+
+ attr_prop_name = &property->klass->id[attr_len];
+ attr_prop = glade_widget_get_property (widget, attr_prop_name);
+
+ if (column >= 0 && column < columns)
+ {
+ GladeColumnType *column_type = (GladeColumnType *)g_list_nth_data (column_list, column);
+ GType column_gtype = g_type_from_name (column_type->type_name);
+
+ if (column_gtype &&
+ g_value_type_transformable (column_gtype, attr_prop->klass->pspec->value_type))
+ gtk_cell_layout_add_attribute (layout, cell, attr_prop_name, column);
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+glade_gtk_cell_layout_sync_attributes (GObject *layout)
+{
+ GladeWidget *gwidget = glade_widget_get_from_gobject (layout);
+ GObject *cell;
+ GList *children, *l;
+
+ children = glade_widget_adaptor_get_children (gwidget->adaptor, layout);
+ for (l = children; l; l = l->next)
+ {
+ cell = l->data;
+ if (!GTK_IS_CELL_RENDERER (cell))
+ continue;
+
+ glade_gtk_cell_renderer_sync_attributes (cell);
+ }
+ g_list_free (children);
+
+ return FALSE;
+}
+
+static gboolean
+glade_gtk_cell_layout_clear_attributes (GObject *layout)
+{
+ GladeWidget *gwidget = glade_widget_get_from_gobject (layout);
+ GObject *cell;
+ GList *children, *l;
+
+ children = glade_widget_adaptor_get_children (gwidget->adaptor, layout);
+ for (l = children; l; l = l->next)
+ {
+ cell = l->data;
+ if (!GTK_IS_CELL_RENDERER (cell))
+ continue;
+
+ gtk_cell_layout_clear_attributes (GTK_CELL_LAYOUT (layout),
+ GTK_CELL_RENDERER (cell));
+ }
+ g_list_free (children);
+
+ return FALSE;
+}
+
static void
glade_gtk_store_set_columns (GObject *object,
const GValue *value)
{
- GList *l = g_value_get_boxed (value);
- gint i, n = g_list_length (l);
- GType *types = g_new (GType, n);
+ GladeWidget *widget = glade_widget_get_from_gobject (object);
+ GList *l;
+ gint i, n;
+ GType *types;
+
+ /* Clear the attributes for all cell renderers referring to this store */
+ for (l = widget->prop_refs; l; l = l->next)
+ {
+ GladeWidget *referring_widget = GLADE_PROPERTY (l->data)->widget;
+
+ if (GTK_IS_CELL_LAYOUT (referring_widget->object))
+ glade_gtk_cell_layout_clear_attributes (referring_widget->object);
+ else if (GTK_IS_TREE_VIEW (referring_widget->object))
+ {
+ GList *list, *children =
+ glade_widget_adaptor_get_children (referring_widget->adaptor,
+ referring_widget->object);
+
+ for (list = children; list; list = list->next)
+ {
+ /* Clear the GtkTreeViewColumns... */
+ if (GTK_IS_CELL_LAYOUT (l->data))
+ glade_gtk_cell_layout_clear_attributes (G_OBJECT (l->data));
+ }
+
+ g_list_free (children);
+ }
+ }
- for (i = 0; l; l = g_list_next (l), i++)
+ /* Apply new column types */
+ for (i = 0, l = g_value_get_boxed (value), n = g_list_length (l), types = g_new (GType, n);
+ l; l = g_list_next (l), i++)
{
GladeColumnType *data = l->data;
@@ -10161,6 +10313,33 @@ glade_gtk_store_set_columns (GObject *object,
gtk_list_store_set_column_types (GTK_LIST_STORE (object), n, types);
else
gtk_tree_store_set_column_types (GTK_TREE_STORE (object), n, types);
+
+ g_free (types);
+
+ /* Reset the attributes for all cell renderers referring to this store */
+ for (l = widget->prop_refs; l; l = l->next)
+ {
+ GladeWidget *referring_widget = GLADE_PROPERTY (l->data)->widget;
+
+ if (GTK_IS_CELL_LAYOUT (referring_widget->object))
+ glade_gtk_cell_layout_sync_attributes (referring_widget->object);
+ else if (GTK_IS_TREE_VIEW (referring_widget->object))
+ {
+ GList *list, *children =
+ glade_widget_adaptor_get_children (referring_widget->adaptor,
+ referring_widget->object);
+
+ for (list = children; list; list = list->next)
+ {
+ /* Clear the GtkTreeViewColumns... */
+ if (GTK_IS_CELL_LAYOUT (l->data))
+ glade_gtk_cell_layout_sync_attributes (G_OBJECT (l->data));
+ }
+
+ g_list_free (children);
+ }
+ }
+
}
static void
@@ -10207,8 +10386,8 @@ glade_gtk_store_set_data (GObject *object,
* and a sync will come soon with the right values
*/
column_type = gtk_tree_model_get_column_type (GTK_TREE_MODEL (object), colnum);
- if (!g_type_is_a (G_VALUE_TYPE (&data->value), column_type))
- break;
+ if (G_VALUE_TYPE (&data->value) != column_type)
+ continue;
if (GTK_IS_LIST_STORE (object))
gtk_list_store_set_value (GTK_LIST_STORE (object),
@@ -10327,7 +10506,10 @@ glade_gtk_store_string_from_value (GladeWidgetAdaptor *adaptor,
{
data = iter->data;
- if (G_VALUE_TYPE (&data->value) != G_TYPE_POINTER)
+ if (!G_VALUE_TYPE (&data->value) ||
+ G_VALUE_TYPE (&data->value) == G_TYPE_INVALID)
+ str = g_strdup ("(virtual)");
+ else if (G_VALUE_TYPE (&data->value) != G_TYPE_POINTER)
str = glade_utils_string_from_value (&data->value, fmt);
else
str = g_strdup ("(null)");
@@ -10430,8 +10612,9 @@ glade_gtk_store_write_data (GladeWidget *widget,
data = iter->data;
- /* Skip inserializable data */
- if (G_VALUE_TYPE (&data->value) == G_TYPE_POINTER)
+ /* Skip non-serializable data */
+ if (G_VALUE_TYPE (&data->value) == 0 ||
+ G_VALUE_TYPE (&data->value) == G_TYPE_POINTER)
continue;
string = glade_utils_string_from_value (&data->value,
@@ -10562,7 +10745,7 @@ glade_gtk_store_read_data (GladeWidget *widget, GladeXmlNode *node)
GNode *data_tree, *row, *item;
GladeModelData *data;
GValue *value;
- GList *column_types = NULL, *list;
+ GList *column_types = NULL;
GladeColumnType *column_type;
gint colnum;
@@ -10591,15 +10774,34 @@ glade_gtk_store_read_data (GladeWidget *widget, GladeXmlNode *node)
for (colnum = 0, col_node = glade_xml_node_get_children (row_node); col_node;
col_node = glade_xml_node_next (col_node))
{
+ gint read_column;
if (!glade_xml_node_verify (col_node, GLADE_TAG_COL))
continue;
- if (!(list = g_list_nth (column_types, colnum)))
- /* XXX Log this too... */
+ read_column = glade_xml_get_property_int (col_node, GLADE_TAG_ID, -1);
+ if (read_column < 0)
+ {
+ g_critical ("Parsed negative column id");
continue;
+ }
+
+ /* Catch up for gaps in the list where unserializable types are involved */
+ while (colnum < read_column)
+ {
+ column_type = g_list_nth_data (column_types, colnum);
- column_type = list->data;
+ data = glade_model_data_new (G_TYPE_INVALID, column_type->column_name);
+
+ item = g_node_new (data);
+ g_node_append (row, item);
+
+ colnum++;
+ }
+
+ if (!(column_type = g_list_nth_data (column_types, colnum)))
+ /* XXX Log this too... */
+ continue;
/* Ignore unloaded column types for the workspace */
if (g_type_from_name (column_type->type_name) != G_TYPE_INVALID)
@@ -10612,7 +10814,8 @@ glade_gtk_store_read_data (GladeWidget *widget, GladeXmlNode *node)
(g_type_from_name (column_type->type_name), value_str, widget->project, widget);
g_free (value_str);
- data = glade_model_data_new (g_type_from_name (column_type->type_name), column_type->column_name);
+ data = glade_model_data_new (g_type_from_name (column_type->type_name),
+ column_type->column_name);
g_value_copy (value, &data->value);
g_value_unset (value);
@@ -10620,10 +10823,9 @@ glade_gtk_store_read_data (GladeWidget *widget, GladeXmlNode *node)
}
else
{
- data = glade_model_data_new (G_TYPE_POINTER, column_type->column_name);
+ data = glade_model_data_new (G_TYPE_INVALID, column_type->column_name);
}
- data->name = g_strdup (column_type->column_name);
data->i18n_translatable = glade_xml_get_property_boolean (col_node, GLADE_TAG_TRANSLATABLE, FALSE);
data->i18n_context = glade_xml_get_property_string (col_node, GLADE_TAG_CONTEXT);
data->i18n_comment = glade_xml_get_property_string (col_node, GLADE_TAG_COMMENT);
@@ -10688,97 +10890,13 @@ glade_gtk_cell_renderer_action_activate (GladeWidgetAdaptor *adaptor,
}
-static gboolean
-glade_gtk_cell_layout_has_renderer (GtkCellLayout *layout,
- GtkCellRenderer *renderer)
-{
- GList *cells = gtk_cell_layout_get_cells (layout);
- gboolean has_renderer;
-
- has_renderer = (g_list_find (cells, renderer) != NULL);
-
- g_list_free (cells);
-
- return has_renderer;
-}
-
-static void
-glade_gtk_cell_renderer_sync_attributes (GObject *object)
-{
-
- GtkCellLayout *layout;
- GtkCellRenderer *cell;
- GladeWidget *widget = glade_widget_get_from_gobject (object);
- GladeWidget *gmodel;
- GladeProperty *property;
- gchar *attr_prop_name;
- GList *l;
- gint columns = 0;
- static gint attr_len = 0;
-
- if (!attr_len)
- attr_len = strlen ("attr-");
-
- /* Apply attributes to renderer when bound to a model in runtime */
- widget = glade_widget_get_from_gobject (object);
-
- if (widget->parent == NULL) return;
-
- /* When creating widgets, sometimes the parent is set before parenting happens,
- * here we have to be careful for that..
- */
- layout = GTK_CELL_LAYOUT (widget->parent->object);
- cell = GTK_CELL_RENDERER (object);
-
- if (!glade_gtk_cell_layout_has_renderer (layout, cell))
- return;
-
- if ((gmodel = glade_cell_renderer_get_model (widget)) != NULL)
- {
- GList *column_list = NULL;
- glade_widget_property_get (gmodel, "columns", &column_list);
- columns = g_list_length (column_list);
- }
-
- gtk_cell_layout_clear_attributes (layout, cell);
-
- for (l = widget->properties; l; l = l->next)
- {
- property = l->data;
-
- if (strncmp (property->klass->id, "attr-", attr_len) == 0)
- {
- attr_prop_name = &property->klass->id[attr_len];
-
- /* XXX TODO: Check that the cell supports the data type in the indexed column.
- *
- * use: gtk_tree_model_get_column_type (icon_view->priv->model, column)
- */
- if (g_value_get_int (property->value) >= 0 &&
- /* We have to set attributes before parenting when loading */
- (glade_widget_superuser () || g_value_get_int (property->value) < columns))
- gtk_cell_layout_add_attribute (layout, cell,
- attr_prop_name,
- g_value_get_int (property->value));
- }
- }
-}
-
-
-static gboolean
-sync_attributes_idle (GladeWidget *gwidget)
-{
- glade_gtk_cell_renderer_sync_attributes (gwidget->object);
- return FALSE;
-}
-
static void
renderer_format_changed (GladeProject *project,
GParamSpec *pspec,
GladeWidget *gwidget)
{
if (glade_project_get_format (project) == GLADE_PROJECT_FORMAT_GTKBUILDER)
- g_idle_add ((GSourceFunc)sync_attributes_idle, gwidget);
+ g_idle_add ((GSourceFunc)glade_gtk_cell_renderer_sync_attributes, gwidget->object);
}
static void
@@ -11231,6 +11349,8 @@ glade_gtk_cell_layout_read_child (GladeWidgetAdaptor *adaptor,
glade_widget_add_child (widget, child_widget, FALSE);
glade_gtk_cell_renderer_read_attributes (child_widget, node);
+
+ g_idle_add ((GSourceFunc)glade_gtk_cell_renderer_sync_attributes, child_widget->object);
}
}
}
@@ -11303,25 +11423,6 @@ glade_gtk_cell_layout_write_child (GladeWidgetAdaptor *adaptor,
glade_gtk_cell_renderer_write_attributes (widget, context, child_node);
}
-static void
-glade_gtk_cell_layout_sync_attributes (GObject *layout)
-{
- GladeWidget *gwidget = glade_widget_get_from_gobject (layout);
- GObject *cell;
- GList *children, *l;
-
- children = glade_widget_adaptor_get_children (gwidget->adaptor, layout);
- for (l = children; l; l = l->next)
- {
- cell = l->data;
- if (!GTK_IS_CELL_RENDERER (cell))
- continue;
-
- glade_gtk_cell_renderer_sync_attributes (cell);
- }
- g_list_free (children);
-}
-
static gchar *
glade_gtk_cell_layout_get_display_name (GladeBaseEditor *editor,
GladeWidget *gchild,
diff --git a/plugins/gtk+/glade-model-data.c b/plugins/gtk+/glade-model-data.c
index 1b38b34..57b5c6a 100644
--- a/plugins/gtk+/glade-model-data.c
+++ b/plugins/gtk+/glade-model-data.c
@@ -37,7 +37,8 @@ glade_model_data_new (GType type, const gchar *column_name)
{
GladeModelData *data = g_new0 (GladeModelData, 1);
- g_value_init (&data->value, type);
+ if (type != 0)
+ g_value_init (&data->value, type);
if (type == G_TYPE_STRING)
data->i18n_translatable = TRUE;
@@ -55,8 +56,11 @@ glade_model_data_copy (GladeModelData *data)
GladeModelData *dup = g_new0 (GladeModelData, 1);
- g_value_init (&dup->value, G_VALUE_TYPE (&data->value));
- g_value_copy (&data->value, &dup->value);
+ if (G_VALUE_TYPE (&data->value) != 0)
+ {
+ g_value_init (&dup->value, G_VALUE_TYPE (&data->value));
+ g_value_copy (&data->value, &dup->value);
+ }
dup->name = g_strdup (data->name);
@@ -72,7 +76,8 @@ glade_model_data_free (GladeModelData *data)
{
if (data)
{
- g_value_unset (&data->value);
+ if (G_VALUE_TYPE (&data->value) != 0)
+ g_value_unset (&data->value);
g_free (data->name);
g_free (data->i18n_context);
@@ -561,7 +566,7 @@ eprop_model_data_generate_store (GladeEditorProperty *eprop)
GArray *gtypes = g_array_new (FALSE, TRUE, sizeof (GType));
GtkTreeIter iter;
gint column_num, row_num;
- GType index_type = G_TYPE_INT, string_type = G_TYPE_STRING;
+ GType index_type = G_TYPE_INT, string_type = G_TYPE_STRING, pointer_type = G_TYPE_POINTER;
glade_property_get (eprop->property, &data_tree);
@@ -573,7 +578,9 @@ eprop_model_data_generate_store (GladeEditorProperty *eprop)
for (iter_node = data_tree->children->children; iter_node; iter_node = iter_node->next)
{
iter_data = iter_node->data;
- if (G_VALUE_TYPE (&iter_data->value) == GDK_TYPE_PIXBUF)
+ if (G_VALUE_TYPE (&iter_data->value) == 0)
+ g_array_append_val (gtypes, pointer_type);
+ else if (G_VALUE_TYPE (&iter_data->value) == GDK_TYPE_PIXBUF)
g_array_append_val (gtypes, string_type);
else
g_array_append_val (gtypes, G_VALUE_TYPE (&iter_data->value));
@@ -595,6 +602,9 @@ eprop_model_data_generate_store (GladeEditorProperty *eprop)
{
iter_data = iter_node->data;
+ if (G_VALUE_TYPE (&iter_data->value) == 0)
+ continue;
+
/* Special case, show the filename in the cellrenderertext */
if (G_VALUE_TYPE (&iter_data->value) == GDK_TYPE_PIXBUF)
{
@@ -838,12 +848,14 @@ eprop_model_generate_column (GladeEditorProperty *eprop,
GtkCellRenderer *renderer = NULL;
GtkAdjustment *adjustment;
GtkListStore *store;
- GType type = G_VALUE_TYPE (&data->value);
+ GType type = G_TYPE_INVALID;
gtk_tree_view_column_set_title (column, data->name);
gtk_tree_view_column_set_resizable (column, TRUE);
gtk_tree_view_column_set_expand (column, TRUE);
+ type = G_VALUE_TYPE (&data->value);
+
/* Support enum and flag types, and a hardcoded list of fundamental types */
if (type == G_TYPE_CHAR ||
type == G_TYPE_UCHAR ||
diff --git a/plugins/gtk+/glade-model-data.h b/plugins/gtk+/glade-model-data.h
index d0310ad..63b6f40 100644
--- a/plugins/gtk+/glade-model-data.h
+++ b/plugins/gtk+/glade-model-data.h
@@ -30,7 +30,7 @@ struct _GladeModelData
{
GValue value;
gchar *name;
-
+
gboolean i18n_translatable;
gchar *i18n_context;
gchar *i18n_comment;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]