summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tvb@src.gnome.org>2008-09-29 17:19:07 +0000
committerTristan Van Berkom <tvb@src.gnome.org>2008-09-29 17:19:07 +0000
commit6c5e4e2aa482016587b89c8c0def74a7bf7611be (patch)
tree2861c9a5099ddb5bbce62f9731493329e8047c9d
parentee72eaea33c010c4cf27606b1a0fcfec462b17d5 (diff)
downloadglade-6c5e4e2aa482016587b89c8c0def74a7bf7611be.tar.gz
Exported glade_column_list_copy/free()
* plugins/gtk+/glade-column-types.[ch]: Exported glade_column_list_copy/free() * plugins/gtk+/glade-model-data.[ch], plugins/gtk+/Makefile.am: Added model data pspec, editor not compĺete yet... * plugins/gtk+/glade-gtk.c, plugins/gtk+/gtk+.xml.in: Implemented new pspec as list/treestore's "data" property with load/save support. * plugins/gtk+/glade-convert.c: Made combos convert correctly with new modeldata pspec. * gladeui/glade-utils.[ch]: Added glade_utils_liststore_from_enum_type() svn path=/trunk/; revision=1963
-rw-r--r--ChangeLog15
-rw-r--r--TODO5
-rw-r--r--gladeui/glade-property-class.c7
-rw-r--r--gladeui/glade-utils.c57
-rw-r--r--gladeui/glade-utils.h5
-rw-r--r--plugins/gnome/bonobo.xml.in1
-rw-r--r--plugins/gnome/canvas.xml.in1
-rw-r--r--plugins/gtk+/Makefile.am2
-rwxr-xr-xplugins/gtk+/glade-attributes.c42
-rw-r--r--plugins/gtk+/glade-column-types.c32
-rw-r--r--plugins/gtk+/glade-column-types.h5
-rw-r--r--plugins/gtk+/glade-convert.c191
-rw-r--r--plugins/gtk+/glade-gtk.c234
-rw-r--r--plugins/gtk+/glade-model-data.c398
-rw-r--r--plugins/gtk+/glade-model-data.h76
-rw-r--r--plugins/gtk+/gtk+.xml.in10
16 files changed, 917 insertions, 164 deletions
diff --git a/ChangeLog b/ChangeLog
index fc21bdca..c717c931 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2008-09-29 Tristan Van Berkom <tvb@gnome.org>
+
+ * plugins/gtk+/glade-column-types.[ch]: Exported glade_column_list_copy/free()
+
+ * plugins/gtk+/glade-model-data.[ch], plugins/gtk+/Makefile.am: Added model data
+ pspec, editor not compĺete yet...
+
+ * plugins/gtk+/glade-gtk.c, plugins/gtk+/gtk+.xml.in: Implemented new pspec as
+ list/treestore's "data" property with load/save support.
+
+ * plugins/gtk+/glade-convert.c: Made combos convert correctly with new modeldata
+ pspec.
+
+ * gladeui/glade-utils.[ch]: Added glade_utils_liststore_from_enum_type()
+
2008-09-29 Juan Pablo Ugarte <juanpablougarte@gmail.com>
* plugins/gtk+/glade-column-types.[ch]: added missing files.
diff --git a/TODO b/TODO
index f5047767..31365b83 100644
--- a/TODO
+++ b/TODO
@@ -14,3 +14,8 @@ Sort objects from widgets in the inspector widget.
Make popup work in workspace with no-window widgets
Take care of external object property references (sync them) at rebuild time
Liststore/Treestore data is not translatable
+store data needs improvement and cant be released as is (cant even have spaces in data, needs real new structure).
+
+IMPORTANT!!! Go over all object type properties and mark them libglade unsupported,
+newly added objects need "since" versioning info updated, all around thoroughly
+check catalog data before release candidate.
diff --git a/gladeui/glade-property-class.c b/gladeui/glade-property-class.c
index 8771a2b3..8d9d4300 100644
--- a/gladeui/glade-property-class.c
+++ b/gladeui/glade-property-class.c
@@ -1039,7 +1039,7 @@ glade_property_class_new_from_spec_full (gpointer handle,
{
GObjectClass *gtk_widget_class;
GladePropertyClass *property_class;
- GladeEditorProperty *eprop;
+ GladeEditorProperty *eprop = NULL;
g_return_val_if_fail (spec != NULL, NULL);
gtk_widget_class = g_type_class_ref (GTK_TYPE_WIDGET);
@@ -1065,7 +1065,8 @@ glade_property_class_new_from_spec_full (gpointer handle,
goto failed;
/* Just created it to see if it was supported.... destroy now... */
- gtk_widget_destroy (GTK_WIDGET (eprop));
+ if (eprop)
+ gtk_widget_destroy (GTK_WIDGET (eprop));
/* If its on the GtkWidgetClass, it goes in "common"
* (unless stipulated otherwise in the xml file)
@@ -1110,7 +1111,7 @@ GladePropertyClass *
glade_property_class_new_from_spec (gpointer handle,
GParamSpec *spec)
{
- glade_property_class_new_from_spec_full (handle, spec, TRUE);
+ return glade_property_class_new_from_spec_full (handle, spec, TRUE);
}
/**
diff --git a/gladeui/glade-utils.c b/gladeui/glade-utils.c
index 251ec764..f67e14e2 100644
--- a/gladeui/glade-utils.c
+++ b/gladeui/glade-utils.c
@@ -1961,7 +1961,7 @@ glade_utils_enum_string_from_value (GType enum_type, gint value)
g_value_init (&gvalue, enum_type);
g_value_set_enum (&gvalue, value);
- string = glade_utils_string_from_value (enum_type, &gvalue, NULL);
+ string = glade_utils_string_from_value (&gvalue, NULL);
g_value_unset (&gvalue);
return string;
@@ -2100,7 +2100,6 @@ glade_utils_value_from_string (GType type,
/**
* glade_utils_string_from_value:
- * @type: a #GType to convert with
* @value: the value to convert
* @project: the #GladeProject to look for formats of object names when needed
*
@@ -2110,18 +2109,60 @@ glade_utils_value_from_string (GType type,
* Returns: A newly allocated string
*/
gchar *
-glade_utils_string_from_value (GType type,
- const GValue *value,
+glade_utils_string_from_value (const GValue *value,
GladeProject *project)
{
+ GladeProjectFormat fmt;
GladePropertyClass *pclass;
- g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
g_return_val_if_fail (value != NULL, NULL);
- if ((pclass = pclass_from_gtype (type)) != NULL)
- return glade_property_class_make_string_from_gvalue (pclass, value,
- glade_project_get_format (project));
+ fmt = project ? glade_project_get_format (project) : GLADE_PROJECT_FORMAT_GTKBUILDER;
+
+ if ((pclass = pclass_from_gtype (G_VALUE_TYPE (value))) != NULL)
+ return glade_property_class_make_string_from_gvalue (pclass, value, fmt);
return NULL;
}
+
+
+/**
+ * glade_utils_liststore_from_enum_type:
+ * @enum_type: A #GType
+ * @include_empty: wheather to prepend an "Unset" slot
+ *
+ * Creates a liststore suitable for comboboxes and such to
+ * chose from a variety of types.
+ *
+ * Returns: A new #GtkListStore
+ */
+GtkListStore *
+glade_utils_liststore_from_enum_type (GType enum_type,
+ gboolean include_empty)
+{
+ GtkListStore *store;
+ GtkTreeIter iter;
+ GEnumClass *eclass;
+ guint i;
+
+ eclass = g_type_class_ref (enum_type);
+
+ store = gtk_list_store_new (1, G_TYPE_STRING);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, _("Unset"),
+ -1);
+
+ for (i = 0; i < eclass->n_values; i++)
+ {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ 0, eclass->values[i].value_nick,
+ -1);
+ }
+
+ g_type_class_unref (eclass);
+
+ return store;
+}
diff --git a/gladeui/glade-utils.h b/gladeui/glade-utils.h
index d179a6ff..cf47bd85 100644
--- a/gladeui/glade-utils.h
+++ b/gladeui/glade-utils.h
@@ -140,10 +140,11 @@ gchar *glade_utils_enum_string_from_value (GType enum_type, gint valu
GValue *glade_utils_value_from_string (GType type,
const gchar *string,
GladeProject *project);
-gchar *glade_utils_string_from_value (GType type,
- const GValue *value,
+gchar *glade_utils_string_from_value (const GValue *value,
GladeProject *project);
+GtkListStore *glade_utils_liststore_from_enum_type (GType enum_type, gboolean include_empty);
+
G_END_DECLS
#endif /* __GLADE_UTILS_H__ */
diff --git a/plugins/gnome/bonobo.xml.in b/plugins/gnome/bonobo.xml.in
index e63c8a47..d90780c7 100644
--- a/plugins/gnome/bonobo.xml.in
+++ b/plugins/gnome/bonobo.xml.in
@@ -1,5 +1,6 @@
<glade-catalog name="bonobo"
library="gladegnome"
+ supports="libglade"
depends="gnome"
domain="glade3">
<glade-widget-classes>
diff --git a/plugins/gnome/canvas.xml.in b/plugins/gnome/canvas.xml.in
index 9bb4c087..eb38246f 100644
--- a/plugins/gnome/canvas.xml.in
+++ b/plugins/gnome/canvas.xml.in
@@ -1,6 +1,7 @@
<glade-catalog name="canvas"
icon-prefix="gnome"
library="gladegnome"
+ supports="libglade"
depends="gnome"
domain="glade3">
<glade-widget-classes>
diff --git a/plugins/gtk+/Makefile.am b/plugins/gtk+/Makefile.am
index c6bb76cf..9372f1fe 100644
--- a/plugins/gtk+/Makefile.am
+++ b/plugins/gtk+/Makefile.am
@@ -24,7 +24,7 @@ libgladegtk_la_CFLAGS = \
$(AM_CFLAGS)
libgladegtk_la_SOURCES = glade-gtk.c glade-accels.c glade-attributes.c glade-convert.c fixed-bg.xpm \
- glade-column-types.c glade-column-types.h
+ glade-column-types.c glade-column-types.h glade-model-data.c glade-model-data.h
libgladegtk_la_LDFLAGS = -module -avoid-version $(AM_LDFLAGS)
libgladegtk_la_LIBADD = $(libgladeui) $(GTK_LIBS)
diff --git a/plugins/gtk+/glade-attributes.c b/plugins/gtk+/glade-attributes.c
index 3e836c42..cc841290 100755
--- a/plugins/gtk+/glade-attributes.c
+++ b/plugins/gtk+/glade-attributes.c
@@ -241,36 +241,6 @@ typedef enum {
(type) == EDIT_COMBO ? COLUMN_COMBO_ACTIVE: COLUMN_TEXT_ACTIVE)
static GtkListStore *
-make_model_from_enum_type (GType enum_type)
-{
- GtkListStore *store;
- GtkTreeIter iter;
- GEnumClass *eclass;
- guint i;
-
- eclass = g_type_class_ref (enum_type);
-
- store = gtk_list_store_new (1, G_TYPE_STRING);
-
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- 0, _("Unset"),
- -1);
-
- for (i = 0; i < eclass->n_values; i++)
- {
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter,
- 0, eclass->values[i].value_nick,
- -1);
- }
-
- g_type_class_unref (eclass);
-
- return store;
-}
-
-static GtkListStore *
get_enum_model_for_combo (PangoAttrType type)
{
static GtkListStore *style_store = NULL,
@@ -282,32 +252,32 @@ get_enum_model_for_combo (PangoAttrType type)
{
case PANGO_ATTR_STYLE:
if (!style_store)
- style_store = make_model_from_enum_type (PANGO_TYPE_STYLE);
+ style_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_STYLE, TRUE);
return style_store;
case PANGO_ATTR_WEIGHT:
if (!weight_store)
- weight_store = make_model_from_enum_type (PANGO_TYPE_WEIGHT);
+ weight_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_WEIGHT, TRUE);
return weight_store;
case PANGO_ATTR_VARIANT:
if (!variant_store)
- variant_store = make_model_from_enum_type (PANGO_TYPE_VARIANT);
+ variant_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_VARIANT, TRUE);
return variant_store;
case PANGO_ATTR_STRETCH:
if (!stretch_store)
- stretch_store = make_model_from_enum_type (PANGO_TYPE_STRETCH);
+ stretch_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_STRETCH, TRUE);
return stretch_store;
case PANGO_ATTR_GRAVITY:
if (!gravity_store)
- gravity_store = make_model_from_enum_type (PANGO_TYPE_GRAVITY);
+ gravity_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_GRAVITY, TRUE);
return gravity_store;
case PANGO_ATTR_GRAVITY_HINT:
if (!gravity_hint_store)
- gravity_hint_store = make_model_from_enum_type (PANGO_TYPE_GRAVITY_HINT);
+ gravity_hint_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_GRAVITY_HINT, TRUE);
return gravity_hint_store;
default:
diff --git a/plugins/gtk+/glade-column-types.c b/plugins/gtk+/glade-column-types.c
index 9449c3bc..d55085b4 100644
--- a/plugins/gtk+/glade-column-types.c
+++ b/plugins/gtk+/glade-column-types.c
@@ -82,8 +82,8 @@ column_types_store_populate (GtkListStore *store)
}
}
-static GList *
-data_list_copy (GList *list)
+GList *
+glade_column_list_copy (GList *list)
{
GList *l, *retval = NULL;
@@ -101,8 +101,8 @@ data_list_copy (GList *list)
return g_list_reverse (retval);
}
-static void
-data_list_free (GList *list)
+void
+glade_column_list_free (GList *list)
{
GList *l;
@@ -125,8 +125,8 @@ glade_column_type_list_get_type (void)
if (!type_id)
type_id = g_boxed_type_register_static
("GladeColumnTypeList",
- (GBoxedCopyFunc) data_list_copy,
- (GBoxedFreeFunc) data_list_free);
+ (GBoxedCopyFunc) glade_column_list_copy,
+ (GBoxedFreeFunc) glade_column_list_free);
return type_id;
}
@@ -189,8 +189,8 @@ glade_standard_column_types_spec (void)
GladeParamSpecColumnTypes *pspec;
pspec = g_param_spec_internal (GLADE_TYPE_PARAM_COLUMN_TYPES,
- "fundamental-types", _("Fundamental Types"),
- _("A list of fundamental GTypes"),
+ "column-types", _("Column Types"),
+ _("A list of GTypes and thier names"),
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
return G_PARAM_SPEC (pspec);
}
@@ -250,10 +250,10 @@ eprop_reload_value (GladeEPropColumnTypes *eprop)
}
static void
-eprop_fundamental_append (GladeEPropColumnTypes *eprop_types,
- GType type,
- const gchar *name,
- const gchar *column_name)
+eprop_column_append (GladeEPropColumnTypes *eprop_types,
+ GType type,
+ const gchar *name,
+ const gchar *column_name)
{
gtk_list_store_insert_with_values (eprop_types->store, NULL, -1,
COLUMN_NAME, name ? name : g_type_name (type),
@@ -283,13 +283,13 @@ glade_eprop_column_types_load (GladeEditorProperty *eprop, GladeProperty *proper
{
GladeColumnType *data = l->data;
- eprop_fundamental_append (eprop_types, data->type, NULL, data->column_name);
+ eprop_column_append (eprop_types, data->type, NULL, data->column_name);
}
}
static void
glade_eprop_column_types_add_clicked (GtkWidget *button,
- GladeEPropColumnTypes *eprop_types)
+ GladeEPropColumnTypes *eprop_types)
{
GtkTreeIter iter;
GType type2add;
@@ -303,13 +303,13 @@ glade_eprop_column_types_add_clicked (GtkWidget *button,
COLUMN_GTYPE, &type2add,
-1);
- eprop_fundamental_append (eprop_types, type2add, name, NULL);
+ eprop_column_append (eprop_types, type2add, name, NULL);
eprop_reload_value (eprop_types);
}
static void
glade_eprop_column_types_delete_clicked (GtkWidget *button,
- GladeEPropColumnTypes *eprop_types)
+ GladeEPropColumnTypes *eprop_types)
{
GtkTreeIter iter;
if (gtk_tree_selection_get_selected (eprop_types->selection, NULL, &iter))
diff --git a/plugins/gtk+/glade-column-types.h b/plugins/gtk+/glade-column-types.h
index b9eb43aa..ac2126d7 100644
--- a/plugins/gtk+/glade-column-types.h
+++ b/plugins/gtk+/glade-column-types.h
@@ -32,6 +32,7 @@ typedef struct
gchar *column_name;
} GladeColumnType;
+
#define GLADE_TYPE_COLUMN_TYPE_LIST (glade_column_type_list_get_type())
#define GLADE_TYPE_PARAM_COLUMN_TYPES (glade_param_column_types_get_type())
#define GLADE_TYPE_EPROP_COLUMN_TYPES (glade_eprop_column_types_get_type())
@@ -47,6 +48,10 @@ GType glade_eprop_column_types_get_type (void) G_GNUC_CONST;
GParamSpec *glade_standard_column_types_spec (void);
+
+void glade_column_list_free (GList *list);
+GList *glade_column_list_copy (GList *list);
+
G_END_DECLS
#endif /* _GLADE_COLUMN_TYPES_H_ */
diff --git a/plugins/gtk+/glade-convert.c b/plugins/gtk+/glade-convert.c
index 16741493..4db43013 100644
--- a/plugins/gtk+/glade-convert.c
+++ b/plugins/gtk+/glade-convert.c
@@ -29,6 +29,8 @@
#include <glib/gi18n-lib.h>
#include "glade-gtk.h"
+#include "glade-column-types.h"
+#include "glade-model-data.h"
#include <gladeui/glade.h>
@@ -43,14 +45,20 @@ typedef struct {
} TextData;
typedef struct {
+ GladeWidget *widget;
+ gchar **items;
+} ComboData;
+
+typedef struct {
/* List of newly created objects to set */
GList *adjustments;
GList *textviews;
GList *tooltips;
+ GList *combos;
} ConvertData;
/*****************************************
- * Adjustments *
+ * GtkAdjustments *
*****************************************/
static void
convert_adjustments_finished (GladeProject *project,
@@ -185,7 +193,7 @@ convert_adjustments (GladeProject *project,
}
/*****************************************
- * TextViews *
+ * TextView:text *
*****************************************/
static void
convert_textviews_finished (GladeProject *project,
@@ -289,7 +297,7 @@ convert_textviews (GladeProject *project,
}
/*****************************************
- * Tooltips *
+ * GtkWidget:tooltips *
*****************************************/
static void
convert_tooltips_finished (GladeProject *project,
@@ -356,6 +364,181 @@ convert_tooltips (GladeProject *project,
}
/*****************************************
+ * Combo:items *
+ *****************************************/
+static GNode *
+combos_data_tree_from_items (gchar **items)
+{
+ GNode *row, *data_tree;
+ gint i;
+
+ if (!items)
+ return NULL;
+
+ data_tree = g_node_new (NULL);
+
+ for (i = 0; items[i]; i++)
+ {
+ GladeModelData *data = g_new0 (GladeModelData, 1);
+
+ g_value_init (&data->value, G_TYPE_STRING);
+ g_value_set_string (&data->value, items[i]);
+
+ row = g_node_new (NULL);
+ g_node_append (data_tree, row);
+ g_node_append_data (row, data);
+ }
+ return data_tree;
+}
+
+static gchar **
+combos_items_from_data_tree (GNode *data_tree)
+{
+ GNode *row, *item;
+ GPtrArray *array = g_ptr_array_new ();
+ GladeModelData *data;
+ gchar *string;
+
+ for (row = data_tree->children; row; row = row->next)
+ {
+ for (item = row->children; item; item = item->next)
+ {
+ data = item->data;
+ if (G_VALUE_TYPE (&data->value) == G_TYPE_STRING)
+ {
+ string = g_value_dup_string (&data->value);
+ g_ptr_array_add (array, string);
+ break;
+ }
+ }
+ }
+
+ if (array->len == 0)
+ return NULL;
+
+ g_ptr_array_add (array, NULL);
+
+ return (gchar **)g_ptr_array_free (array, FALSE);
+}
+
+static void
+convert_combos (GladeProject *project,
+ GladeProjectFormat new_format,
+ ConvertData *data)
+{
+ GladeWidget *widget, *gmodel;
+ GladeProperty *property;
+ ComboData *cdata;
+ GObject *model;
+ const GList *objects;
+ GNode *data_tree;
+ gchar **items;
+
+ for (objects = glade_project_get_objects (project); objects; objects = objects->next)
+ {
+ widget = glade_widget_get_from_gobject (objects->data);
+ if (!GTK_IS_COMBO_BOX (widget->object))
+ continue;
+
+ if (new_format == GLADE_PROJECT_FORMAT_GTKBUILDER)
+ {
+ items = NULL;
+ property = glade_widget_get_property (widget, "items");
+ glade_property_get (property, &items);
+
+ if (items)
+ {
+ cdata = g_new0 (ComboData, 1);
+ cdata->widget = widget;
+ cdata->items = g_strdupv (items);
+ data->combos = g_list_prepend (data->combos, cdata);
+
+ glade_command_set_property (property, NULL);
+ }
+ }
+ else
+ {
+ items = NULL;
+ data_tree = NULL;
+ gmodel = NULL;
+ model = NULL;
+ property = glade_widget_get_property (widget, "model");
+ glade_property_get (property, &model);
+
+ if (model && (gmodel = glade_widget_get_from_gobject (model)))
+ glade_widget_property_get (gmodel, "data", &data_tree);
+
+ if (data_tree)
+ items = combos_items_from_data_tree (data_tree);
+
+ if (items)
+ {
+ GList delete = { 0, };
+ delete.data = gmodel;
+
+ cdata = g_new0 (ComboData, 1);
+ cdata->widget = widget;
+ cdata->items = items;
+ data->combos = g_list_prepend (data->combos, cdata);
+
+ /* This will take care of unsetting the buffer property as well */
+ glade_command_delete (&delete);
+ }
+ }
+ }
+}
+
+static void
+convert_combos_finished (GladeProject *project,
+ ConvertData *data)
+{
+ GladeProjectFormat new_format = glade_project_get_format (project);
+ GladeWidgetAdaptor *adaptor = glade_widget_adaptor_get_by_type (GTK_TYPE_LIST_STORE);
+ GladeProperty *property;
+ GladeWidget *widget;
+ ComboData *cdata;
+ GNode *data_tree;
+ GList *list;
+
+ for (list = data->combos; list; list = list->next)
+ {
+ cdata = list->data;
+
+ if (new_format == GLADE_PROJECT_FORMAT_GTKBUILDER)
+ {
+ GList *columns = NULL;
+ GladeColumnType *column = g_new0 (GladeColumnType, 1);
+ column->type = G_TYPE_STRING;
+ columns = g_list_append (columns, column);
+
+ property = glade_widget_get_property (cdata->widget, "model");
+
+ /* Cant cancel a liststore.... */
+ widget = glade_command_create (adaptor, NULL, NULL, project);
+
+ glade_command_set_property (property, widget->object);
+
+ data_tree = combos_data_tree_from_items (cdata->items);
+
+ glade_widget_property_set (widget, "columns", columns);
+ glade_widget_property_set (widget, "data", data_tree);
+
+ glade_column_list_free (columns);
+ }
+ else
+ {
+ property = glade_widget_get_property (cdata->widget, "items");
+ glade_command_set_property (property, cdata->items);
+ }
+ g_strfreev (cdata->items);
+ g_free (cdata);
+ }
+
+ g_list_free (data->combos);
+}
+
+
+/*****************************************
* Main entry point *
*****************************************/
static void
@@ -365,6 +548,7 @@ glade_gtk_project_convert_finished (GladeProject *project,
convert_adjustments_finished (project, data);
convert_textviews_finished (project, data);
convert_tooltips_finished (project, data);
+ convert_combos_finished (project, data);
/* Once per conversion */
g_signal_handlers_disconnect_by_func (G_OBJECT (project),
@@ -382,6 +566,7 @@ glade_gtk_project_convert (GladeProject *project,
convert_adjustments (project, new_format, data);
convert_textviews (project, new_format, data);
convert_tooltips (project, new_format, data);
+ convert_combos (project, new_format, data);
/* Clean up after the new_format is in effect */
g_signal_connect (G_OBJECT (project), "convert-finished",
diff --git a/plugins/gtk+/glade-gtk.c b/plugins/gtk+/glade-gtk.c
index 9187b19e..a4510d00 100644
--- a/plugins/gtk+/glade-gtk.c
+++ b/plugins/gtk+/glade-gtk.c
@@ -29,6 +29,7 @@
#include "glade-accels.h"
#include "glade-attributes.h"
#include "glade-column-types.h"
+#include "glade-model-data.h"
#include <gladeui/glade-editor-property.h>
#include <gladeui/glade-base-editor.h>
@@ -7631,21 +7632,31 @@ glade_gtk_text_view_set_property (GladeWidgetAdaptor *adaptor,
/* ----------------------------- GtkComboBox ------------------------------ */
+static void
+combo_ensure_model (GObject *combo)
+{
+ GtkListStore *store;
+
+ if (!gtk_combo_box_get_model (GTK_COMBO_BOX (combo)))
+ {
+ /* Add store */
+ store = gtk_list_store_new (1, G_TYPE_STRING);
+ gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
+ g_object_unref (store);
+ }
+}
+
void
glade_gtk_combo_box_post_create (GladeWidgetAdaptor *adaptor,
GObject *object,
GladeCreateReason reason)
{
GtkCellRenderer *cell;
- GtkListStore *store;
g_return_if_fail (GTK_IS_COMBO_BOX (object));
- /* Add store */
- store = gtk_list_store_new (1, G_TYPE_STRING);
- gtk_combo_box_set_model (GTK_COMBO_BOX (object), GTK_TREE_MODEL (store));
- g_object_unref (store);
-
+ combo_ensure_model (object);
+
/* Add cell renderer */
cell = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (object), cell, TRUE);
@@ -7664,6 +7675,8 @@ glade_gtk_combo_box_set_items (GObject *object, const GValue *value)
combo = GTK_COMBO_BOX (object);
+ combo_ensure_model (object);
+
/* Empty the combo box */
gtk_list_store_clear (GTK_LIST_STORE (gtk_combo_box_get_model (combo)));
@@ -8602,21 +8615,28 @@ glade_gtk_store_set_columns (GObject *object,
}
if (GTK_IS_LIST_STORE (object))
+ {
+ gtk_list_store_clear (GTK_LIST_STORE (object));
gtk_list_store_set_column_types (GTK_LIST_STORE (object), n, types);
+ }
else
+ {
+ gtk_tree_store_clear (GTK_TREE_STORE (object));
gtk_tree_store_set_column_types (GTK_TREE_STORE (object), n, types);
+ }
}
static void
glade_gtk_store_set_data (GObject *object,
const GValue *value)
{
- GladeWidget *gwidget = glade_widget_get_from_gobject (object);
- GList *columns = NULL, *list;
+ GladeWidget *gwidget = glade_widget_get_from_gobject (object);
+ GList *columns = NULL, *list;
GladeColumnType *column;
- gchar **split, **subsplit;
- gint i, j;
- GtkTreeIter row_iter;
+ GNode *data_tree, *row, *iter;
+ gint colnum;
+ GtkTreeIter row_iter;
+ GladeModelData *data;
if (GTK_IS_LIST_STORE (object))
gtk_list_store_clear (GTK_LIST_STORE (object));
@@ -8624,48 +8644,36 @@ glade_gtk_store_set_data (GObject *object,
gtk_tree_store_clear (GTK_TREE_STORE (object));
glade_widget_property_get (gwidget, "columns", &columns);
+ data_tree = g_value_get_boxed (value);
/* Nothing to enter without columns defined */
- if (!columns) return;
-
- split = g_value_get_boxed (value);
-
- for (i = 0; split && split[i]; i++)
+ if (!data_tree || !columns)
+ return;
+
+ for (row = data_tree->children; row; row = row->next)
{
- if ((subsplit = g_strsplit (split[i], " ", 0)) != NULL)
+ if (GTK_IS_LIST_STORE (object))
+ gtk_list_store_append (GTK_LIST_STORE (object), &row_iter);
+ else
+ /* (for now no child data... ) */
+ gtk_tree_store_append (GTK_TREE_STORE (object), &row_iter, NULL);
+
+ for (colnum = 0, iter = row->children; iter;
+ colnum++, iter = iter->next)
{
+ data = iter->data;
+
+ if (!g_list_nth (columns, colnum))
+ break;
+
if (GTK_IS_LIST_STORE (object))
- gtk_list_store_append (GTK_LIST_STORE (object), &row_iter);
+ gtk_list_store_set_value (GTK_LIST_STORE (object),
+ &row_iter,
+ colnum, &data->value);
else
- /* (for now no child data... ) */
- gtk_tree_store_append (GTK_TREE_STORE (object), &row_iter, NULL);
-
- for (j = 0; subsplit[j]; j++)
- {
- if ((list = g_list_nth (columns, j)) != NULL)
- {
- GValue *row_value;
-
- column = list->data;
-
- if ((row_value =
- glade_utils_value_from_string (column->type, subsplit[j], NULL)) != NULL)
- {
-
- if (GTK_IS_LIST_STORE (object))
- gtk_list_store_set_value (GTK_LIST_STORE (object),
- &row_iter,
- j, row_value);
- else
- gtk_tree_store_set_value (GTK_TREE_STORE (object),
- &row_iter,
- j, row_value);
- }
- g_value_unset (row_value);
- g_free (row_value);
- }
- }
- g_strfreev (subsplit);
+ gtk_tree_store_set_value (GTK_TREE_STORE (object),
+ &row_iter,
+ colnum, &data->value);
}
}
}
@@ -8705,6 +8713,11 @@ glade_gtk_store_create_eprop (GladeWidgetAdaptor *adaptor,
"property-class", klass,
"use-command", use_command,
NULL);
+ else if (GLADE_IS_PARAM_SPEC_MODEL_DATA (klass->pspec))
+ eprop = g_object_new (GLADE_TYPE_EPROP_MODEL_DATA,
+ "property-class", klass,
+ "use-command", use_command,
+ NULL);
else
eprop = GWA_GET_CLASS
(G_TYPE_OBJECT)->create_eprop (adaptor,
@@ -8714,10 +8727,10 @@ glade_gtk_store_create_eprop (GladeWidgetAdaptor *adaptor,
}
gchar *
-glade_gtk_store_from_value (GladeWidgetAdaptor *adaptor,
- GladePropertyClass *klass,
- const GValue *value,
- GladeProjectFormat fmt)
+glade_gtk_store_string_from_value (GladeWidgetAdaptor *adaptor,
+ GladePropertyClass *klass,
+ const GValue *value,
+ GladeProjectFormat fmt)
{
if (GLADE_IS_PARAM_SPEC_COLUMN_TYPES (klass->pspec))
{
@@ -8736,6 +8749,17 @@ glade_gtk_store_from_value (GladeWidgetAdaptor *adaptor,
g_string_free (val, FALSE);
return retval;
}
+ else if (GLADE_IS_PARAM_SPEC_MODEL_DATA (klass->pspec))
+ {
+ GNode *node;
+
+ node = g_value_get_boxed (value);
+ if (node && node->children && node->children->children)
+ return g_strdup_printf (_("Data available"));
+ else
+ return g_strdup_printf (_("No data"));
+
+ }
else
return GWA_GET_CLASS
(G_TYPE_OBJECT)->string_from_value (adaptor,
@@ -8782,44 +8806,50 @@ glade_gtk_store_write_data (GladeWidget *widget,
{
GladeXmlNode *data_node, *col_node, *row_node;
GList *columns = NULL;
- gchar **split = NULL, **subsplit, *column_number;
- gint i, j;
-
- glade_widget_property_get (widget, "data", &split);
+ GladeModelData *data;
+ GNode *data_tree = NULL, *row, *iter;
+ gint colnum;
+
+ glade_widget_property_get (widget, "data", &data_tree);
glade_widget_property_get (widget, "columns", &columns);
/* XXX log errors about data not fitting columns here when
* loggin is available
*/
- if (!split || !columns)
+ if (!data_tree || !columns)
return;
data_node = glade_xml_node_new (context, GLADE_TAG_DATA);
- for (i = 0; split[i]; i++)
+ for (row = data_tree->children; row; row = row->next)
{
row_node = glade_xml_node_new (context, GLADE_TAG_ROW);
glade_xml_node_append_child (data_node, row_node);
- if ((subsplit = g_strsplit (split[i], " ", 0)) != NULL)
+ for (colnum = 0, iter = row->children; iter;
+ colnum++, iter = iter->next)
{
- for (j = 0; subsplit[j]; j++)
- {
- /* XXX Log error: data col j exceeds columns on row i */
- if (!g_list_nth (columns, j))
- break;
+ gchar *string, *column_number;
- column_number = g_strdup_printf ("%d", j);
+ data = iter->data;
- col_node = glade_xml_node_new (context, GLADE_TAG_COL);
- glade_xml_node_append_child (row_node, col_node);
- glade_xml_node_set_property_string (col_node, GLADE_TAG_ID,
- column_number);
- glade_xml_set_content (col_node, subsplit[j]);
+ string = glade_utils_string_from_value (&data->value,
+ widget->project);
- g_free (column_number);
- }
- g_strfreev (subsplit);
+ /* XXX Log error: data col j exceeds columns on row i */
+ if (!g_list_nth (columns, colnum))
+ break;
+
+ column_number = g_strdup_printf ("%d", colnum);
+
+ col_node = glade_xml_node_new (context, GLADE_TAG_COL);
+ glade_xml_node_append_child (row_node, col_node);
+ glade_xml_node_set_property_string (col_node, GLADE_TAG_ID,
+ column_number);
+ glade_xml_set_content (col_node, string);
+
+ g_free (column_number);
+ g_free (string);
}
}
@@ -8884,51 +8914,73 @@ static void
glade_gtk_store_read_data (GladeWidget *widget, GladeXmlNode *node)
{
GladeXmlNode *data_node, *row_node, *col_node;
- GPtrArray *data_array;
-
- data_array = g_ptr_array_new ();
+ GNode *data_tree, *row, *item;
+ GladeModelData *data;
+ GValue *value;
+ GList *column_types = NULL, *list;
+ GladeColumnType *column_type;
+ gint colnum;
if ((data_node = glade_xml_search_child (node, GLADE_TAG_DATA)) == NULL)
return;
+
+ /* XXX FIXME: Warn that columns werent there when parsing */
+ if (!glade_widget_property_get (widget, "columns", &column_types) || !column_types)
+ return;
+
+ /* Create root... */
+ data_tree = g_node_new (NULL);
for (row_node = glade_xml_node_get_children (data_node); row_node;
row_node = glade_xml_node_next (row_node))
{
- GString *string = NULL;
gchar *value_str;
if (!glade_xml_node_verify (row_node, GLADE_TAG_ROW))
continue;
+ row = g_node_new (NULL);
+ g_node_append (data_tree, row);
+
/* XXX FIXME: we are assuming that the columns are listed in order */
- for (col_node = glade_xml_node_get_children (row_node); col_node;
+ for (colnum = 0, col_node = glade_xml_node_get_children (row_node); col_node;
col_node = glade_xml_node_next (col_node))
{
if (!glade_xml_node_verify (col_node, GLADE_TAG_COL))
continue;
- value_str = glade_xml_get_content (col_node);
+ if (!(list = g_list_nth (column_types, colnum)))
+ /* XXX Log this too... */
+ continue;
- if (string)
- g_string_append_printf (string, " %s", value_str);
- else
- string = g_string_new (value_str);
+ column_type = list->data;
+ /* XXX Do we need object properties to somehow work at load time here ??
+ * should we be doing this part in "finished" ? ... todo thinkso...
+ */
+ value_str = glade_xml_get_content (col_node);
+ value = glade_utils_value_from_string (column_type->type, value_str, widget->project);
g_free (value_str);
- }
- /* harvest string onto the array ... */
- if (string)
- g_ptr_array_add (data_array,
- g_string_free (string, FALSE));
- }
+ data = g_new0 (GladeModelData, 1);
+ g_value_init (&data->value, column_type->type);
+ g_value_copy (value, &data->value);
+ g_value_unset (value);
+ g_free (value);
+
+ item = g_node_new (data);
+ g_node_append (row, item);
- g_ptr_array_add (data_array, NULL);
+ /* dont increment colnum on invalid xml tags... */
+ colnum++;
+ }
+ }
- glade_widget_property_set (widget, "data", data_array->pdata);
+ if (data_tree->children && data_tree->children)
+ glade_widget_property_set (widget, "data", data_tree);
- g_ptr_array_free (data_array, TRUE);
+ glade_model_data_tree_free (data_tree);
}
void
diff --git a/plugins/gtk+/glade-model-data.c b/plugins/gtk+/glade-model-data.c
new file mode 100644
index 00000000..3d9a3b23
--- /dev/null
+++ b/plugins/gtk+/glade-model-data.c
@@ -0,0 +1,398 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Tristan Van Berkom.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ * Tristan Van Berkom <tvb@gnome.org>
+ */
+
+#include <config.h>
+
+#include <gladeui/glade.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+#include "glade-model-data.h"
+
+
+
+GladeModelData *
+glade_model_data_copy (GladeModelData *data)
+{
+ if (!data)
+ return NULL;
+
+ GladeModelData *dup = g_new0 (GladeModelData, 1);
+
+ g_value_init (&dup->value, G_VALUE_TYPE (&data->value));
+ g_value_copy (&data->value, &dup->value);
+
+ dup->name = g_strdup (data->name);
+
+ dup->i18n_translatable = data->i18n_translatable;
+ dup->i18n_has_context = data->i18n_has_context;
+ dup->i18n_comment = g_strdup (data->i18n_comment);
+
+ return dup;
+}
+
+void
+glade_model_data_free (GladeModelData *data)
+{
+ if (data)
+ {
+ g_value_unset (&data->value);
+
+ g_free (data->name);
+ g_free (data->i18n_comment);
+ g_free (data);
+ }
+}
+
+GNode *
+glade_model_data_tree_copy (GNode *node)
+{
+ return g_node_copy_deep (node, (GCopyFunc)glade_model_data_copy, NULL);
+}
+
+static void
+model_data_traverse_free (GNode *node,
+ gpointer data)
+{
+ glade_model_data_free ((GladeModelData *)node->data);
+}
+
+void
+glade_model_data_tree_free (GNode *node)
+{
+ if (node)
+ {
+ g_node_traverse (node, G_IN_ORDER, G_TRAVERSE_ALL, -1,
+ (GNodeTraverseFunc)model_data_traverse_free, NULL);
+ g_node_destroy (node);
+ }
+}
+
+GType
+glade_model_data_tree_get_type (void)
+{
+ static GType type_id = 0;
+
+ if (!type_id)
+ type_id = g_boxed_type_register_static
+ ("GladeModelDataTree",
+ (GBoxedCopyFunc) glade_model_data_tree_copy,
+ (GBoxedFreeFunc) glade_model_data_tree_free);
+ return type_id;
+}
+
+/********************** GladeParamModelData ***********************/
+
+struct _GladeParamModelData
+{
+ GParamSpec parent_instance;
+};
+
+static gint
+param_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2)
+{
+ GNode *n1, *n2;
+ gint retval;
+
+ n1 = g_value_get_boxed (value1);
+ n2 = g_value_get_boxed (value2);
+
+ if (n1 == NULL && n2 == NULL) return 0;
+
+ if (n1 == NULL || n2 == NULL) return n1 - n2;
+
+ if ((retval =
+ g_node_n_nodes (n1, G_TRAVERSE_ALL) - g_node_n_nodes (n2, G_TRAVERSE_ALL)))
+ return retval;
+ else
+ /* XXX We could do alot better here... but right now we are using strings
+ * and ignoring changes somehow... need to fix that.
+ */
+ return GPOINTER_TO_INT (n1->data) - GPOINTER_TO_INT (n2->data);
+}
+
+GType
+glade_param_model_data_get_type (void)
+{
+ static GType model_data_type = 0;
+
+ if (model_data_type == 0)
+ {
+ GParamSpecTypeInfo pspec_info = {
+ sizeof (GladeParamModelData), /* instance_size */
+ 16, /* n_preallocs */
+ NULL, /* instance_init */
+ 0, /* value_type, assigned further down */
+ NULL, /* finalize */
+ NULL, /* value_set_default */
+ NULL, /* value_validate */
+ param_values_cmp, /* values_cmp */
+ };
+ pspec_info.value_type = GLADE_TYPE_MODEL_DATA_TREE;
+
+ model_data_type = g_param_type_register_static
+ ("GladeParamModelData", &pspec_info);
+ }
+ return model_data_type;
+}
+
+GParamSpec *
+glade_standard_model_data_spec (void)
+{
+ GladeParamModelData *pspec;
+
+ pspec = g_param_spec_internal (GLADE_TYPE_PARAM_MODEL_DATA,
+ "model-data", _("Model Data"),
+ _("A datastore property for GtkTreeModel"),
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+ return G_PARAM_SPEC (pspec);
+}
+
+/**************************** GladeEditorProperty *****************************/
+typedef struct
+{
+ GladeEditorProperty parent_instance;
+
+ GtkTreeView *view;
+ GtkListStore *store;
+} GladeEPropModelData;
+
+GLADE_MAKE_EPROP (GladeEPropModelData, glade_eprop_model_data)
+#define GLADE_EPROP_MODEL_DATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_EPROP_MODEL_DATA, GladeEPropModelData))
+#define GLADE_EPROP_MODEL_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_EPROP_MODEL_DATA, GladeEPropModelDataClass))
+#define GLADE_IS_EPROP_MODEL_DATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_EPROP_MODEL_DATA))
+#define GLADE_IS_EPROP_MODEL_DATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_EPROP_MODEL_DATA))
+#define GLADE_EPROP_MODEL_DATA_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GLADE_EPROP_MODEL_DATA, GladeEPropModelDataClass))
+
+
+static void
+glade_eprop_model_data_add_clicked (GtkWidget *button,
+ GladeEPropModelData *eprop_types)
+{
+ /* Add new row with default values */
+}
+
+static void
+glade_eprop_model_data_delete_clicked (GtkWidget *button,
+ GladeEPropModelData *eprop_types)
+{
+ /* User pressed delete: remove selected row and commit values from treeview to property */
+
+}
+
+static void
+eprop_treeview_row_deleted (GtkTreeModel *tree_model,
+ GtkTreePath *path,
+ GladeEditorProperty *eprop)
+{
+ /* User deleted a row: commit values from treeview to property */
+}
+
+
+static void
+glade_eprop_model_data_finalize (GObject *object)
+{
+ /* Chain up */
+ GObjectClass *parent_class = g_type_class_peek_parent (G_OBJECT_GET_CLASS (object));
+
+ GladeEPropModelData *eprop_data = GLADE_EPROP_MODEL_DATA (object);
+
+ if (eprop_data->store)
+ g_object_unref (G_OBJECT (eprop_data->store));
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static GtkListStore *
+eprop_model_data_generate_store (GladeEditorProperty *eprop)
+{
+ GtkListStore *store = NULL;
+ GladeModelData *iter_data, *row_data;
+ GNode *data_tree = NULL, *iter_node, *row_node;
+ GArray *gtypes = g_array_new (FALSE, TRUE, sizeof (GType));
+ GtkTreeIter iter;
+ gint column_num;
+
+ glade_property_get (eprop->property, &data_tree);
+
+
+ if (!data_tree || !data_tree->children || !data_tree->children->children)
+ return NULL;
+
+ /* Generate store with tailored column types */
+ for (iter_node = data_tree->children->children; iter_node; iter_node = iter_node->next)
+ {
+ iter_data = iter_node->data;
+ g_array_append_val (gtypes, G_VALUE_TYPE (&iter_data->value));
+ }
+ store = gtk_list_store_newv (gtypes->len, (GType *)gtypes->data);
+ g_array_free (gtypes, TRUE);
+
+ /* Now populate the store with data */
+ for (row_node = data_tree->children; row_node; row_node = row_node->next)
+ {
+ row_data = row_node->data;
+
+ gtk_list_store_append (store, &iter);
+
+ for (column_num = 0, iter_node = row_node->children; iter_node;
+ column_num++, iter_node = iter_node->next)
+ {
+ iter_data = iter_node->data;
+ gtk_list_store_set_value (store, &iter, column_num, &iter_data->value);
+ }
+ }
+ return store;
+}
+
+static GtkTreeViewColumn *
+eprop_model_generate_column (GladeEditorProperty *eprop,
+ GladeModelData *data)
+{
+ GtkTreeViewColumn *column = gtk_tree_view_column_new ();
+#if 0
+ /* Support enum and flag types, and a hardcoded list of fundamental types */
+ if (type == G_TYPE_CHAR)
+ else if (type == G_TYPE_UCHAR)
+ else if (type == G_TYPE_STRING)
+ /* Text renderer single char */
+ else if (type == G_TYPE_BOOLEAN)
+ /* Check renderer */
+ else if (type == G_TYPE_INT)
+ else if (type == G_TYPE_UINT)
+ else if (type == G_TYPE_LONG)
+ else if (type == G_TYPE_ULONG)
+ else if (type == G_TYPE_INT64)
+ else if (type == G_TYPE_UINT64)
+ /* spin renderer with customized adjustments */
+ else if (type == G_TYPE_FLOAT)
+ else if (type == G_TYPE_DOUBLE)
+ /* spin renderer with customized adjustments */
+ else if (type == G_TYPE_OBJECT || g_type_is_a (type, G_TYPE_OBJECT))
+ /* text renderer and object dialog (or raw text for pixbuf) */
+ else if (G_TYPE_IS_ENUM (type))
+ /* combobox renderer */
+ else if (G_TYPE_IS_FLAGS (type))
+#endif
+ return NULL;
+}
+
+static void
+eprop_model_data_generate_columns (GladeEditorProperty *eprop)
+{
+ GladeEPropModelData *eprop_data = GLADE_EPROP_MODEL_DATA (eprop);
+ GladeModelData *iter_data;
+ GtkTreeViewColumn *column;
+ GNode *data_tree = NULL, *iter_node;
+
+ glade_property_get (eprop->property, &data_tree);
+
+ /* Clear columns ... */
+ while ((column = gtk_tree_view_get_column (eprop_data->view, 0)) != NULL)
+ gtk_tree_view_remove_column (eprop_data->view, column);
+
+ if (!data_tree || !data_tree->children || !data_tree->children->children)
+ return;
+
+ /* Append new columns */
+ for (iter_node = data_tree->children->children; iter_node; iter_node = iter_node->next)
+ {
+ iter_data = iter_node->data;
+
+ column = eprop_model_generate_column (eprop, iter_data);
+ gtk_tree_view_append_column (eprop_data->view, column);
+ }
+}
+
+static void
+glade_eprop_model_data_load (GladeEditorProperty *eprop,
+ GladeProperty *property)
+{
+ GladeEditorPropertyClass *parent_class =
+ g_type_class_peek_parent (GLADE_EDITOR_PROPERTY_GET_CLASS (eprop));
+ GladeEPropModelData *eprop_data = GLADE_EPROP_MODEL_DATA (eprop);
+
+ /* Chain up first */
+ parent_class->load (eprop, property);
+
+ /* Recreate and populate store */
+ if (eprop_data->store)
+ g_object_unref (G_OBJECT (eprop_data->store));
+
+ eprop_data->store = eprop_model_data_generate_store (eprop);
+
+ if (eprop_data->store)
+ g_signal_connect (eprop_data->store, "row-deleted",
+ G_CALLBACK (eprop_treeview_row_deleted),
+ eprop);
+
+ /* Clear and create new columns with renderers */
+ eprop_model_data_generate_columns (eprop);
+}
+
+static GtkWidget *
+glade_eprop_model_data_create_input (GladeEditorProperty *eprop)
+{
+ GladeEPropModelData *eprop_data = GLADE_EPROP_MODEL_DATA (eprop);
+ GtkWidget *vbox, *hbox, *button, *swin;
+
+ vbox = gtk_vbox_new (FALSE, 2);
+
+ hbox = gtk_hbox_new (FALSE, 4);
+
+ /* Pack treeview/swindow on the left... */
+ swin = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+ gtk_box_pack_start (GTK_BOX (hbox), swin, TRUE, TRUE, 0);
+
+ /* hbox with add/remove row buttons on the right... */
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
+
+ button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (button),
+ gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON));
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (glade_eprop_model_data_add_clicked),
+ eprop_data);
+
+ button = gtk_button_new ();
+ gtk_button_set_image (GTK_BUTTON (button),
+ gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON));
+ gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (glade_eprop_model_data_delete_clicked),
+ eprop_data);
+
+ eprop_data->view = (GtkTreeView *)gtk_tree_view_new ();
+
+ gtk_tree_view_set_reorderable (GTK_TREE_VIEW (eprop_data->view), TRUE);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (eprop_data->view), TRUE);
+ gtk_container_add (GTK_CONTAINER (swin), GTK_WIDGET (eprop_data->view));
+
+ gtk_widget_show_all (hbox);
+ return hbox;
+}
diff --git a/plugins/gtk+/glade-model-data.h b/plugins/gtk+/glade-model-data.h
new file mode 100644
index 00000000..80f0c42d
--- /dev/null
+++ b/plugins/gtk+/glade-model-data.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Tristan Van Berkom.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ * Tristan Van Berkom <tvb@gnome.org>
+ */
+#ifndef _GLADE_MODEL_DATA_TREE_H_
+#define _STV_CAP_H_
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+struct _GladeModelData
+{
+ GValue value;
+ gchar *name;
+
+ gboolean i18n_translatable;
+ gboolean i18n_has_context;
+ gchar *i18n_comment;
+};
+
+typedef struct _GladeModelData GladeModelData;
+typedef struct _GladeParamModelData GladeParamModelData;
+
+
+#define GLADE_TYPE_MODEL_DATA_TREE (glade_model_data_tree_get_type())
+#define GLADE_TYPE_PARAM_MODEL_DATA (glade_param_model_data_get_type())
+#define GLADE_TYPE_EPROP_MODEL_DATA (glade_eprop_model_data_get_type())
+
+#define GLADE_IS_PARAM_SPEC_MODEL_DATA(pspec) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GLADE_TYPE_PARAM_MODEL_DATA))
+#define GLADE_PARAM_SPEC_MODEL_DATA(pspec) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((pspec), GLADE_TYPE_PARAM_MODEL_DATA, GladeParamSpecModelDataTree))
+
+GType glade_model_data_tree_get_type (void) G_GNUC_CONST;
+GType glade_param_model_data_get_type (void) G_GNUC_CONST;
+GType glade_eprop_model_data_get_type (void) G_GNUC_CONST;
+
+GParamSpec *glade_standard_model_data_spec (void);
+
+GladeModelData *glade_model_data_copy (GladeModelData *data);
+void glade_model_data_free (GladeModelData *data);
+
+GNode *glade_model_data_tree_copy (GNode *node);
+void glade_model_data_tree_free (GNode *node);
+
+void glade_model_data_insert_column (GNode *node,
+ GType type,
+ gint nth);
+void glade_model_data_remove_column (GNode *node,
+ GType type,
+ gint nth);
+void glade_model_data_reorder_column (GNode *node,
+ gint column,
+ gint nth);
+
+G_END_DECLS
+
+#endif /* _GLADE_MODEL_DATA_H_ */
diff --git a/plugins/gtk+/gtk+.xml.in b/plugins/gtk+/gtk+.xml.in
index 7361f1e2..4b32c11e 100644
--- a/plugins/gtk+/gtk+.xml.in
+++ b/plugins/gtk+/gtk+.xml.in
@@ -901,12 +901,13 @@ embedded in another object</_tooltip>
<signal id="popup" since="2.12"/>
</signals>
<properties>
+ <property id="model" libglade-unsupported="True"/>
<property id="popup-shown" since="2.10"/>
<property id="tearoff-title" since="2.10"/>
<property id="active" ignore="True"/>
<property id="column-span-column" ignore="True"/>
<property id="row-span-column" ignore="True"/>
- <property id="items" _name="Items" translatable="True">
+ <property id="items" _name="Items" translatable="True" libglade-only="True">
<spec>glade_standard_strv_spec</spec>
<_tooltip>The items in this combo box</_tooltip>
</property>
@@ -939,6 +940,7 @@ embedded in another object</_tooltip>
</property>
<property id="hadjustment" libglade-unsupported="True"/>
<property id="vadjustment" libglade-unsupported="True"/>
+ <property id="model" libglade-unsupported="True"/>
</properties>
</glade-widget-class>
@@ -1791,7 +1793,7 @@ embedded in another object</_tooltip>
libglade-unsupported="True" toplevel="True">
<set-property-function>glade_gtk_store_set_property</set-property-function>
<create-editor-property-function>glade_gtk_store_create_eprop</create-editor-property-function>
- <string-from-value-function>glade_gtk_store_from_value</string-from-value-function>
+ <string-from-value-function>glade_gtk_store_string_from_value</string-from-value-function>
<write-widget-function>glade_gtk_store_write_widget</write-widget-function>
<read-widget-function>glade_gtk_store_read_widget</read-widget-function>
<properties>
@@ -1800,7 +1802,7 @@ embedded in another object</_tooltip>
<_tooltip>Set column types for this model</_tooltip>
</property>
<property id="data" since="2.12" _name="Data" save="False">
- <spec>glade_standard_strv_spec</spec>
+ <spec>glade_standard_model_data_spec</spec>
<_tooltip>Enter a list of values to be applied on each row</_tooltip>
</property>
</properties>
@@ -1815,7 +1817,7 @@ embedded in another object</_tooltip>
<read-widget-function>glade_gtk_store_read_widget</read-widget-function>
<properties>
<property id="columns" since="2.12" _name="Columns" save="False">
- <spec>glade_standard_column_types_spec</spec>
+ <spec>glade_standard_model_data_spec</spec>
<_tooltip>Set column types for this model</_tooltip>
</property>
<property id="data" since="2.12" _name="Data" save="False">