glade3 r1963 - in trunk: . gladeui plugins/gnome plugins/gtk+



Author: tvb
Date: Mon Sep 29 17:19:07 2008
New Revision: 1963
URL: http://svn.gnome.org/viewvc/glade3?rev=1963&view=rev

Log:

	* 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()



Added:
   trunk/plugins/gtk+/glade-model-data.c
   trunk/plugins/gtk+/glade-model-data.h
Modified:
   trunk/ChangeLog
   trunk/TODO
   trunk/gladeui/glade-property-class.c
   trunk/gladeui/glade-utils.c
   trunk/gladeui/glade-utils.h
   trunk/plugins/gnome/bonobo.xml.in
   trunk/plugins/gnome/canvas.xml.in
   trunk/plugins/gtk+/Makefile.am
   trunk/plugins/gtk+/glade-attributes.c
   trunk/plugins/gtk+/glade-column-types.c
   trunk/plugins/gtk+/glade-column-types.h
   trunk/plugins/gtk+/glade-convert.c
   trunk/plugins/gtk+/glade-gtk.c
   trunk/plugins/gtk+/gtk+.xml.in

Modified: trunk/TODO
==============================================================================
--- trunk/TODO	(original)
+++ trunk/TODO	Mon Sep 29 17:19:07 2008
@@ -14,3 +14,8 @@
 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.

Modified: trunk/gladeui/glade-property-class.c
==============================================================================
--- trunk/gladeui/glade-property-class.c	(original)
+++ trunk/gladeui/glade-property-class.c	Mon Sep 29 17:19:07 2008
@@ -1039,7 +1039,7 @@
 {
 	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 @@
 		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 @@
 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);
 }
 
 /**

Modified: trunk/gladeui/glade-utils.c
==============================================================================
--- trunk/gladeui/glade-utils.c	(original)
+++ trunk/gladeui/glade-utils.c	Mon Sep 29 17:19:07 2008
@@ -1961,7 +1961,7 @@
 	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_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 @@
  * 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;
+}

Modified: trunk/gladeui/glade-utils.h
==============================================================================
--- trunk/gladeui/glade-utils.h	(original)
+++ trunk/gladeui/glade-utils.h	Mon Sep 29 17:19:07 2008
@@ -140,10 +140,11 @@
 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__ */

Modified: trunk/plugins/gnome/bonobo.xml.in
==============================================================================
--- trunk/plugins/gnome/bonobo.xml.in	(original)
+++ trunk/plugins/gnome/bonobo.xml.in	Mon Sep 29 17:19:07 2008
@@ -1,5 +1,6 @@
 <glade-catalog name="bonobo"
                library="gladegnome"
+	       supports="libglade"
                depends="gnome"
                domain="glade3">
   <glade-widget-classes>

Modified: trunk/plugins/gnome/canvas.xml.in
==============================================================================
--- trunk/plugins/gnome/canvas.xml.in	(original)
+++ trunk/plugins/gnome/canvas.xml.in	Mon Sep 29 17:19:07 2008
@@ -1,6 +1,7 @@
 <glade-catalog name="canvas"
                icon-prefix="gnome"
                library="gladegnome"
+	       supports="libglade"
                depends="gnome"
                domain="glade3">
   <glade-widget-classes>

Modified: trunk/plugins/gtk+/Makefile.am
==============================================================================
--- trunk/plugins/gtk+/Makefile.am	(original)
+++ trunk/plugins/gtk+/Makefile.am	Mon Sep 29 17:19:07 2008
@@ -24,7 +24,7 @@
 	$(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)
 

Modified: trunk/plugins/gtk+/glade-attributes.c
==============================================================================
--- trunk/plugins/gtk+/glade-attributes.c	(original)
+++ trunk/plugins/gtk+/glade-attributes.c	Mon Sep 29 17:19:07 2008
@@ -241,36 +241,6 @@
 	 (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 @@
 	{
 	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:

Modified: trunk/plugins/gtk+/glade-column-types.c
==============================================================================
--- trunk/plugins/gtk+/glade-column-types.c	(original)
+++ trunk/plugins/gtk+/glade-column-types.c	Mon Sep 29 17:19:07 2008
@@ -82,8 +82,8 @@
 	}
 }
 
-static GList *
-data_list_copy (GList *list)
+GList *
+glade_column_list_copy (GList *list)
 {
 	GList *l, *retval = NULL;
 	
@@ -101,8 +101,8 @@
 	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 @@
 	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 @@
 	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 @@
 }
 
 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 @@
 	{
 		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 @@
 			    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))

Modified: trunk/plugins/gtk+/glade-column-types.h
==============================================================================
--- trunk/plugins/gtk+/glade-column-types.h	(original)
+++ trunk/plugins/gtk+/glade-column-types.h	Mon Sep 29 17:19:07 2008
@@ -32,6 +32,7 @@
 	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 @@
 
 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_ */

Modified: trunk/plugins/gtk+/glade-convert.c
==============================================================================
--- trunk/plugins/gtk+/glade-convert.c	(original)
+++ trunk/plugins/gtk+/glade-convert.c	Mon Sep 29 17:19:07 2008
@@ -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 @@
 } 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 @@
 }
 
 /*****************************************
- *           TextViews                   *
+ *           TextView:text               *
  *****************************************/
 static void
 convert_textviews_finished (GladeProject  *project,
@@ -289,7 +297,7 @@
 }
 
 /*****************************************
- *           Tooltips                    *
+ *           GtkWidget:tooltips          *
  *****************************************/
 static void
 convert_tooltips_finished (GladeProject  *project,
@@ -356,6 +364,181 @@
 }
 
 /*****************************************
+ *           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 @@
 	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 @@
 	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",

Modified: trunk/plugins/gtk+/glade-gtk.c
==============================================================================
--- trunk/plugins/gtk+/glade-gtk.c	(original)
+++ trunk/plugins/gtk+/glade-gtk.c	Mon Sep 29 17:19:07 2008
@@ -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 @@
 
 
 /* ----------------------------- 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 @@
 
 	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 @@
 	}
 
 	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 @@
 		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 @@
 				      "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 @@
 }
 
 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 @@
 		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 @@
 {
 	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;
-
-				column_number = g_strdup_printf ("%d", j);
-
-				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]);
+			gchar   *string, *column_number;
 
-				g_free (column_number);
-			}
-			g_strfreev (subsplit);
+			data = iter->data;
+
+			string = glade_utils_string_from_value (&data->value, 
+								widget->project);
+
+			/* 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 @@
 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

Added: trunk/plugins/gtk+/glade-model-data.c
==============================================================================
--- (empty file)
+++ trunk/plugins/gtk+/glade-model-data.c	Mon Sep 29 17:19:07 2008
@@ -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;
+}

Added: trunk/plugins/gtk+/glade-model-data.h
==============================================================================
--- (empty file)
+++ trunk/plugins/gtk+/glade-model-data.h	Mon Sep 29 17:19:07 2008
@@ -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_ */

Modified: trunk/plugins/gtk+/gtk+.xml.in
==============================================================================
--- trunk/plugins/gtk+/gtk+.xml.in	(original)
+++ trunk/plugins/gtk+/gtk+.xml.in	Mon Sep 29 17:19:07 2008
@@ -901,12 +901,13 @@
 	<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 @@
 	</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 @@
 			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 @@
           <_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 @@
       <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">



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]