glade3 r1961 - in trunk: . gladeui plugins/gtk+



Author: tvb
Date: Sun Sep 28 04:37:44 2008
New Revision: 1961
URL: http://svn.gnome.org/viewvc/glade3?rev=1961&view=rev

Log:

	* plugins/gtk+/glade-gtk.c, plugins/gtk+/glade-column-types.[ch],	
	  plugins/gtk+/Makefile.am, plugins/gtk+/gtk+.xml.in: Added load/save/edit
	  support for GtkTreeStore/GtkListStore basic columns and data definitions
	  (store data still not translatable...) - Juan Pablo Ugarte

	* gladeui/glade-utils.c: Added convenience funcs glade_utils_string_from_value()
	  and glade_utils_value_from_string(), these actually use glade-property-class api.



Modified:
   trunk/ChangeLog
   trunk/TODO
   trunk/gladeui/Makefile.am
   trunk/gladeui/glade-palette.c
   trunk/gladeui/glade-property-class.c
   trunk/gladeui/glade-property-class.h
   trunk/gladeui/glade-utils.c
   trunk/gladeui/glade-utils.h
   trunk/gladeui/glade-widget.c
   trunk/plugins/gtk+/Makefile.am
   trunk/plugins/gtk+/glade-attributes.c
   trunk/plugins/gtk+/glade-gtk.c
   trunk/plugins/gtk+/gtk+.xml.in

Modified: trunk/TODO
==============================================================================
--- trunk/TODO	(original)
+++ trunk/TODO	Sun Sep 28 04:37:44 2008
@@ -11,3 +11,6 @@
 Add versioning metadata for libglade unsupported properties and widgets.
 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

Modified: trunk/gladeui/Makefile.am
==============================================================================
--- trunk/gladeui/Makefile.am	(original)
+++ trunk/gladeui/Makefile.am	Sun Sep 28 04:37:44 2008
@@ -110,6 +110,7 @@
 	glade-xml-utils.h \
 	glade-signal.h \
 	glade-cursor.h \
+    glade-catalog.h \
 	glade-widget-action.h
 
 

Modified: trunk/gladeui/glade-palette.c
==============================================================================
--- trunk/gladeui/glade-palette.c	(original)
+++ trunk/gladeui/glade-palette.c	Sun Sep 28 04:37:44 2008
@@ -325,7 +325,6 @@
 static void
 glade_palette_toggled (GladePalette *palette)
 {
-	GladeProject       *project;
 	GladeWidgetAdaptor *adaptor;
 	GladeWidget        *widget;
 

Modified: trunk/gladeui/glade-property-class.c
==============================================================================
--- trunk/gladeui/glade-property-class.c	(original)
+++ trunk/gladeui/glade-property-class.c	Sun Sep 28 04:37:44 2008
@@ -1028,17 +1028,14 @@
 	va_end (vl);
 }
 
-/**
- * glade_property_class_new_from_spec:
- * @handle: A generic pointer (i.e. a #GladeWidgetClass)
- * @spec: A #GParamSpec
- *
- * Returns: a newly created #GladePropertyClass based on @spec
- *          or %NULL if its unsupported.
+
+/* "need_handle": An evil trick to let us create pclasses without
+ * adaptors and editors.
  */
 GladePropertyClass *
-glade_property_class_new_from_spec (gpointer     handle,
-				    GParamSpec  *spec)
+glade_property_class_new_from_spec_full (gpointer     handle,
+					 GParamSpec  *spec,
+					 gboolean     need_handle)
 {
 	GObjectClass        *gtk_widget_class;
 	GladePropertyClass  *property_class;
@@ -1063,7 +1060,7 @@
 
 	/* Register only editable properties.
 	 */
-	if (!(eprop = glade_widget_adaptor_create_eprop
+	if (need_handle && !(eprop = glade_widget_adaptor_create_eprop
 	      (GLADE_WIDGET_ADAPTOR (handle), property_class, FALSE)))
 		goto failed;
 
@@ -1102,6 +1099,21 @@
 }
 
 /**
+ * glade_property_class_new_from_spec:
+ * @handle: A generic pointer (i.e. a #GladeWidgetClass)
+ * @spec: A #GParamSpec
+ *
+ * Returns: a newly created #GladePropertyClass based on @spec
+ *          or %NULL if its unsupported.
+ */
+GladePropertyClass *
+glade_property_class_new_from_spec (gpointer     handle,
+				    GParamSpec  *spec)
+{
+	glade_property_class_new_from_spec_full (handle, spec, TRUE);
+}
+
+/**
  * glade_property_class_is_visible:
  * @property_class: A #GladePropertyClass
  *

Modified: trunk/gladeui/glade-property-class.h
==============================================================================
--- trunk/gladeui/glade-property-class.h	(original)
+++ trunk/gladeui/glade-property-class.h	Sun Sep 28 04:37:44 2008
@@ -182,6 +182,10 @@
 GladePropertyClass *glade_property_class_new_from_spec           (gpointer             handle,
 								  GParamSpec          *spec);
 
+GladePropertyClass *glade_property_class_new_from_spec_full      (gpointer             handle,
+								  GParamSpec          *spec,
+								  gboolean             need_handle);
+
 GladePropertyClass *glade_property_class_clone                   (GladePropertyClass  *property_class);
 
 void                glade_property_class_free                    (GladePropertyClass  *property_class);

Modified: trunk/gladeui/glade-utils.c
==============================================================================
--- trunk/gladeui/glade-utils.c	(original)
+++ trunk/gladeui/glade-utils.c	Sun Sep 28 04:37:44 2008
@@ -1940,37 +1940,188 @@
 gint
 glade_utils_enum_value_from_string (GType enum_type, const gchar *strval)
 {
-	GEnumClass *enum_class;
-	GEnumValue *enum_value;
-	gint        value = 0;
-
-	enum_class = g_type_class_ref (enum_type);
-	if ((enum_value = g_enum_get_value_by_nick (enum_class, strval)) != NULL)
-		value = enum_value->value;
-	else
-		g_critical ("Couldnt find enum value for %s, type %s", 
-			    strval, g_type_name (enum_type));
-	
-	g_type_class_unref (enum_class);
-	
+	gint    value = 0;
+	GValue *gvalue;
+
+	if ((gvalue = glade_utils_value_from_string (enum_type, strval, NULL)) != NULL)
+	{
+		value = g_value_get_enum (gvalue);
+		g_value_unset (gvalue);
+		g_free (gvalue);
+	}
 	return value;
 }
 
 gchar *
 glade_utils_enum_string_from_value (GType enum_type, gint value)
 {
-	GEnumClass *enum_class;
-	GEnumValue *enum_value;
-	gchar      *ret = NULL;
-
-	enum_class = g_type_class_ref (enum_type);
-	if ((enum_value = g_enum_get_value (enum_class, value)) != NULL)
-		ret = g_strdup (enum_value->value_nick);
-	else
-		g_critical ("Couldnt find enum value for %d, type %s", 
-			    value, g_type_name (enum_type));
-	
-	g_type_class_unref (enum_class);
+	GValue gvalue = { 0, };
+	gchar *string;
+
+	g_value_init (&gvalue, enum_type);
+	g_value_set_enum (&gvalue, value);
+
+	string = glade_utils_string_from_value (enum_type, &gvalue, NULL);
+	g_value_unset (&gvalue);
+
+	return string;
+}
+
+
+/* A hash table of generically created property classes for
+ * fundamental types, so we can easily use glade's conversion
+ * system without using properties (only GTypes)
+ */
+static GHashTable *generic_property_classes = NULL;
+
+
+static gboolean
+utils_gtype_equal (gconstpointer v1,
+		 gconstpointer v2)
+{
+  return *((const GType*) v1) == *((const GType*) v2);
+}
+
+static guint
+utils_gtype_hash (gconstpointer v)
+{
+  return *(const GType*) v;
+}
+
+
+static GladePropertyClass *
+pclass_from_gtype (GType type)
+{
+	GladePropertyClass *property_class = NULL;
+	GParamSpec         *pspec = NULL;
+
+	if (!generic_property_classes)
+		generic_property_classes = g_hash_table_new_full (utils_gtype_hash, utils_gtype_equal,
+								  g_free, (GDestroyNotify)glade_property_class_free);
 	
-	return ret;
+	property_class = g_hash_table_lookup (generic_property_classes, &type);
+
+	if (!property_class)
+	{
+		/* Support enum and flag types, and a hardcoded list of fundamental types */
+		if (type == G_TYPE_CHAR)
+			pspec = g_param_spec_char ("dummy", "dummy", "dummy",
+						   G_MININT8, G_MAXINT8, 0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_UCHAR)
+			pspec = g_param_spec_char ("dummy", "dummy", "dummy",
+						   0, G_MAXUINT8, 0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_BOOLEAN)
+			pspec = g_param_spec_boolean ("dummy", "dummy", "dummy",
+						      FALSE, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_INT)
+			pspec = g_param_spec_int ("dummy", "dummy", "dummy",
+						  G_MININT, G_MAXINT, 0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_UINT)
+			pspec = g_param_spec_uint ("dummy", "dummy", "dummy",
+						   0, G_MAXUINT, 0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_LONG)
+			pspec = g_param_spec_long ("dummy", "dummy", "dummy",
+						    G_MINLONG, G_MAXLONG, 0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_ULONG)
+			pspec = g_param_spec_ulong ("dummy", "dummy", "dummy",
+						    0, G_MAXULONG, 0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_INT64)
+			pspec = g_param_spec_int64 ("dummy", "dummy", "dummy",
+						    G_MININT64, G_MAXINT64, 0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_UINT64)
+			pspec = g_param_spec_uint64 ("dummy", "dummy", "dummy",
+						     0, G_MAXUINT64, 0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_FLOAT)
+			pspec = g_param_spec_float ("dummy", "dummy", "dummy",
+						    G_MINFLOAT, G_MAXFLOAT, 0.0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_DOUBLE)
+			pspec = g_param_spec_double ("dummy", "dummy", "dummy",
+						     G_MINDOUBLE, G_MAXDOUBLE, 0.0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_STRING)
+			pspec = g_param_spec_string ("dummy", "dummy", "dummy",
+						     NULL, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (type == G_TYPE_OBJECT || g_type_is_a (type, G_TYPE_OBJECT))
+			pspec = g_param_spec_object ("dummy", "dummy", "dummy",
+						     type, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (G_TYPE_IS_ENUM (type))
+			pspec = g_param_spec_enum ("dummy", "dummy", "dummy",
+						   type, 0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+		else if (G_TYPE_IS_FLAGS (type))
+			pspec = g_param_spec_flags ("dummy", "dummy", "dummy",
+						    type, 0, G_PARAM_READABLE|G_PARAM_WRITABLE);
+
+		if (pspec)
+		{
+			if ((property_class = 
+			     glade_property_class_new_from_spec_full (NULL, pspec, FALSE)) != NULL)
+			{
+				/* XXX If we ever free the hash table, property classes wont touch
+				 * the allocated pspecs, so they would theoretically be leaked.
+				 */
+				g_hash_table_insert (generic_property_classes, 
+						     g_memdup (&type, sizeof (GType)), property_class);
+			}
+			else
+				g_warning ("Unable to create property class for type %s", g_type_name (type));
+		}
+		else
+			g_warning ("No generic conversion support for type %s", g_type_name (type));
+	}
+	return property_class;
+}
+
+/**
+ * glade_utils_value_from_string:
+ * @type: a #GType to convert with
+ * @string: the string to convert
+ * @project: the #GladeProject to look for formats of object names when needed
+ *
+ * Allocates and sets a #GValue of type @type
+ * set to @string (using glade conversion routines) 
+ *
+ * Returns: A newly allocated and set #GValue
+ */
+GValue *
+glade_utils_value_from_string (GType               type,
+			       const gchar        *string,
+			       GladeProject       *project)
+{
+	GladePropertyClass *pclass;
+
+	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
+	g_return_val_if_fail (string != NULL, NULL);
+
+	if ((pclass = pclass_from_gtype (type)) != NULL)
+		return glade_property_class_make_gvalue_from_string (pclass, string, project);
+
+	return NULL;
+}
+
+
+/**
+ * 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
+ *
+ * Serializes #GValue into a string 
+ * (using glade conversion routines) 
+ *
+ * Returns: A newly allocated string
+ */
+gchar *
+glade_utils_string_from_value (GType               type,
+			       const GValue       *value,
+			       GladeProject       *project)
+{
+	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));
+
+	return NULL;
 }

Modified: trunk/gladeui/glade-utils.h
==============================================================================
--- trunk/gladeui/glade-utils.h	(original)
+++ trunk/gladeui/glade-utils.h	Sun Sep 28 04:37:44 2008
@@ -137,6 +137,12 @@
 
 gchar            *glade_utils_enum_string_from_value (GType enum_type, gint value);
 
+GValue           *glade_utils_value_from_string   (GType               type,
+						   const gchar        *string,
+						   GladeProject       *project);
+gchar            *glade_utils_string_from_value   (GType               type,
+						   const GValue       *value,
+						   GladeProject       *project);
 
 G_END_DECLS
 

Modified: trunk/gladeui/glade-widget.c
==============================================================================
--- trunk/gladeui/glade-widget.c	(original)
+++ trunk/gladeui/glade-widget.c	Sun Sep 28 04:37:44 2008
@@ -2544,6 +2544,7 @@
  * Gets the value of @id_property in @widget
  *
  * Returns: whether @id_property was found or not.
+ *
  */
 gboolean
 glade_widget_property_get (GladeWidget      *widget,

Modified: trunk/plugins/gtk+/Makefile.am
==============================================================================
--- trunk/plugins/gtk+/Makefile.am	(original)
+++ trunk/plugins/gtk+/Makefile.am	Sun Sep 28 04:37:44 2008
@@ -23,7 +23,8 @@
 	$(PLUGINS_WARN_CFLAGS)         \
 	$(AM_CFLAGS)
 
-libgladegtk_la_SOURCES     = glade-gtk.c glade-accels.c glade-attributes.c glade-convert.c fixed-bg.xpm
+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
 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	Sun Sep 28 04:37:44 2008
@@ -850,9 +850,6 @@
 					    COLUMN_EDIT_TYPE, &edit_type,
 					    COLUMN_TEXT, &strval,
 					    -1);
-			
-			g_print ("Feeding attributes with a type %d value '%s'\n", type, strval);
-
 
 			gattr = glade_gtk_attribute_from_string (type, (edit_type == EDIT_TOGGLE) ? "" : strval);
 			strval = (g_free (strval), NULL);
@@ -917,8 +914,6 @@
 
 		new_text = gdk_color_to_string (&color);
 
-		g_print ("Setting color in store to '%s'\n", new_text);
-
 		gtk_tree_store_set (GTK_TREE_STORE (eprop_attrs->model), &iter,
 				    COLUMN_TEXT, new_text,
 				    COLUMN_NAME_WEIGHT, PANGO_WEIGHT_BOLD,

Modified: trunk/plugins/gtk+/glade-gtk.c
==============================================================================
--- trunk/plugins/gtk+/glade-gtk.c	(original)
+++ trunk/plugins/gtk+/glade-gtk.c	Sun Sep 28 04:37:44 2008
@@ -28,6 +28,7 @@
 #include "fixed-bg.xpm"
 #include "glade-accels.h"
 #include "glade-attributes.h"
+#include "glade-column-types.h"
 
 #include <gladeui/glade-editor-property.h>
 #include <gladeui/glade-base-editor.h>
@@ -856,7 +857,6 @@
 	fmt = glade_project_get_format (widget->project);
 
 	atk_node = glade_xml_node_new (context, GLADE_TAG_A11Y_A11Y);
-	glade_xml_node_append_child (node, atk_node);
 
 	if (fmt == GLADE_PROJECT_FORMAT_LIBGLADE)
 		glade_gtk_widget_write_atk_properties_libglade (widget, context, atk_node);
@@ -865,10 +865,9 @@
 	glade_gtk_widget_write_atk_actions (widget, context, atk_node);
 
 	if (!glade_xml_node_get_children (atk_node))
-	{
-		glade_xml_node_remove (atk_node);
 		glade_xml_node_delete (atk_node);
-	}
+	else
+		glade_xml_node_append_child (node, atk_node);
 
 	if (fmt == GLADE_PROJECT_FORMAT_GTKBUILDER)
 		glade_gtk_widget_write_atk_properties_gtkbuilder (widget, context, node);
@@ -7247,8 +7246,6 @@
 	GdkColor             *color;
 	GList                *list;
 
-	g_print ("Setting attributes !!!\n");
-
 	for (list = g_value_get_boxed (value); list; list = list->next)
 	{
 		gattr = list->data;
@@ -7492,15 +7489,14 @@
         GWA_GET_CLASS (G_TYPE_OBJECT)->write_widget (adaptor, widget, context, node);
 
 	attrs_node = glade_xml_node_new (context, GLADE_TAG_ATTRIBUTES);
-	glade_xml_node_append_child (node, attrs_node);
 
 	glade_gtk_write_attributes (widget, context, attrs_node);
 
 	if (!glade_xml_node_get_children (attrs_node))
-	{
-		glade_xml_node_remove (attrs_node);
 		glade_xml_node_delete (attrs_node);
-	}
+	else
+		glade_xml_node_append_child (node, attrs_node);
+
 }
 
 gchar *
@@ -7757,34 +7753,6 @@
 							      id, value);
 }
 
-/* ----------------------------- GtkTreeView ------------------------------ */
-void
-glade_gtk_tree_view_post_create (GladeWidgetAdaptor *adaptor,
-				 GObject            *object, 
-				 GladeCreateReason   reason)
-{
-	GtkWidget *tree_view = GTK_WIDGET (object);
-	GtkTreeStore *store;
-	GtkCellRenderer *renderer;
-	GtkTreeViewColumn *column;
-
-	store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
-
-	gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (store));
-	g_object_unref (G_OBJECT (store));
-
-	renderer = gtk_cell_renderer_text_new ();
-	column = gtk_tree_view_column_new_with_attributes
-		("Column 1", renderer, "text", 0, NULL);
-	gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
-
-	renderer = gtk_cell_renderer_text_new ();
-	column = gtk_tree_view_column_new_with_attributes
-		("Column 2", renderer, "text", 1, NULL);
-	gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
-}
-
-
 /* ----------------------------- GtkCombo ------------------------------ */
 void
 glade_gtk_combo_post_create (GladeWidgetAdaptor *adaptor,
@@ -8539,7 +8507,6 @@
 	GladeWidget   *awidget;
 
 	widgets_node = glade_xml_node_new (context, GLADE_TAG_SIZEGROUP_WIDGETS);
-	glade_xml_node_append_child (node, widgets_node);
 
 	if (glade_widget_property_get (widget, "widgets", &widgets))
 	{
@@ -8553,10 +8520,10 @@
 	}
 
 	if (!glade_xml_node_get_children (widgets_node))
-	{
-		glade_xml_node_remove (widgets_node);
 		glade_xml_node_delete (widgets_node);
-	}
+	else
+		glade_xml_node_append_child (node, widgets_node);
+	
 }
 
 
@@ -8609,3 +8576,373 @@
 		GWA_GET_CLASS (G_TYPE_OBJECT)->set_property (adaptor, object,
 							     property_name, value);
 }
+
+/*--------------------------- GtkListStore ---------------------------------*/
+
+#define GLADE_TAG_COLUMNS	"columns"
+#define GLADE_TAG_COLUMN	"column"
+#define GLADE_TAG_TYPE		"type"
+
+#define GLADE_TAG_ROW           "row"
+#define GLADE_TAG_DATA          "data"
+#define GLADE_TAG_COL           "col"
+
+static void
+glade_gtk_store_set_columns (GObject *object,
+			     const GValue *value)
+{
+	GList *l = g_value_get_boxed (value);
+	gint i, n = g_list_length (l);
+	GType *types = g_new (GType, n);
+
+	for (i = 0; l; l = g_list_next (l), i++)
+	{
+		GladeColumnType *data = l->data;
+		types[i] = data->type;
+	}
+
+	if (GTK_IS_LIST_STORE (object))
+		gtk_list_store_set_column_types (GTK_LIST_STORE (object), n, types);
+	else
+		gtk_tree_store_set_column_types (GTK_TREE_STORE (object), n, types);
+}
+
+static void
+glade_gtk_store_set_data (GObject *object,
+			  const GValue *value)
+{
+	GladeWidget *gwidget = glade_widget_get_from_gobject (object);
+	GList  *columns = NULL, *list;
+	GladeColumnType *column;
+	gchar **split, **subsplit;
+	gint    i, j;
+	GtkTreeIter row_iter;
+	
+	if (GTK_IS_LIST_STORE (object))
+		gtk_list_store_clear (GTK_LIST_STORE (object));
+	else
+		gtk_tree_store_clear (GTK_TREE_STORE (object));
+	
+	glade_widget_property_get (gwidget, "columns", &columns);
+	
+	/* Nothing to enter without columns defined */
+	if (!columns) return;
+	
+	split = g_value_get_boxed (value);
+	
+	for (i = 0; split && split[i]; i++)
+	{
+		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 (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);
+		}
+	}
+}
+
+void
+glade_gtk_store_set_property (GladeWidgetAdaptor *adaptor,
+			      GObject *object,
+			      const gchar *property_name,
+			      const GValue *value)
+{
+	if (strcmp (property_name, "columns") == 0)
+	{
+		glade_gtk_store_set_columns (object, value);
+	} 
+	else if (strcmp (property_name, "data") == 0)
+	{
+		glade_gtk_store_set_data (object, value);
+	}
+	else
+		/* Chain Up */
+		GWA_GET_CLASS (G_TYPE_OBJECT)->set_property (adaptor,
+							     object,
+							     property_name, 
+							     value);
+}
+
+GladeEditorProperty *
+glade_gtk_store_create_eprop (GladeWidgetAdaptor *adaptor,
+			      GladePropertyClass *klass,
+			      gboolean            use_command)
+{
+	GladeEditorProperty *eprop;
+
+	/* chain up.. */
+	if (GLADE_IS_PARAM_SPEC_COLUMN_TYPES (klass->pspec))
+		eprop = g_object_new (GLADE_TYPE_EPROP_COLUMN_TYPES,
+				      "property-class", klass, 
+				      "use-command", use_command,
+				      NULL);
+	else
+		eprop = GWA_GET_CLASS 
+			(G_TYPE_OBJECT)->create_eprop (adaptor, 
+						       klass, 
+						       use_command);
+	return eprop;
+}
+
+gchar *
+glade_gtk_store_from_value (GladeWidgetAdaptor *adaptor,
+			    GladePropertyClass *klass,
+			    const GValue       *value,
+			    GladeProjectFormat  fmt)
+{
+	if (GLADE_IS_PARAM_SPEC_COLUMN_TYPES (klass->pspec))
+	{
+		GString *val = g_string_new ("");
+		gchar *retval;
+		GList *l;
+		
+		for (l = g_value_get_boxed (value); l; l = g_list_next (l))
+		{
+			GladeColumnType *data = l->data;
+			g_string_append_printf (val, (g_list_next (l)) ? "%s|" : "%s",
+						g_type_name (data->type));
+		}
+		
+		retval = val->str;
+		g_string_free (val, FALSE);
+		return retval;
+	}
+	else
+		return GWA_GET_CLASS 
+			(G_TYPE_OBJECT)->string_from_value (adaptor, 
+							    klass, 
+							    value,
+							    fmt);
+}
+
+static void
+glade_gtk_store_write_columns (GladeWidget        *widget,
+			       GladeXmlContext    *context,
+			       GladeXmlNode       *node)
+{
+	GladeXmlNode  *columns_node;
+	GladeProperty *prop;
+	GList *l;
+
+	prop = glade_widget_get_property (widget, "columns");
+
+	columns_node = glade_xml_node_new (context, GLADE_TAG_COLUMNS);
+	
+	for (l = g_value_get_boxed (prop->value); l; l = g_list_next (l))
+	{
+		GladeColumnType *data = l->data;
+		GladeXmlNode  *column_node;
+			
+		column_node = glade_xml_node_new (context, GLADE_TAG_COLUMN);
+		glade_xml_node_append_child (columns_node, column_node);
+		glade_xml_node_set_property_string (column_node, GLADE_TAG_TYPE,
+						    g_type_name (data->type));
+	}
+
+	if (!glade_xml_node_get_children (columns_node))
+		glade_xml_node_delete (columns_node);
+	else
+		glade_xml_node_append_child (node, columns_node);
+
+}
+
+static void
+glade_gtk_store_write_data (GladeWidget        *widget,
+			    GladeXmlContext    *context,
+			    GladeXmlNode       *node)
+{
+	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);
+	glade_widget_property_get (widget, "columns", &columns);
+
+	/* XXX log errors about data not fitting columns here when
+	 * loggin is available
+	 */
+	if (!split || !columns)
+		return;
+
+	data_node = glade_xml_node_new (context, GLADE_TAG_DATA);
+
+	for (i = 0; split[i]; i++)
+	{
+		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 (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]);
+
+				g_free (column_number);
+			}
+			g_strfreev (subsplit);
+		}
+	}
+
+	if (!glade_xml_node_get_children (data_node))
+		glade_xml_node_delete (data_node);
+	else
+		glade_xml_node_append_child (node, data_node);
+}
+
+
+void
+glade_gtk_store_write_widget (GladeWidgetAdaptor *adaptor,
+			      GladeWidget        *widget,
+			      GladeXmlContext    *context,
+			      GladeXmlNode       *node)
+{
+	if (!glade_xml_node_verify
+	    (node, GLADE_XML_TAG_WIDGET (glade_project_get_format (widget->project))))
+		return;
+
+	/* First chain up and write all the normal properties.. */
+        GWA_GET_CLASS (G_TYPE_OBJECT)->write_widget (adaptor, widget, context, node);
+
+	glade_gtk_store_write_columns (widget, context, node);
+	glade_gtk_store_write_data (widget, context, node);
+}
+
+static void
+glade_gtk_store_read_columns (GladeWidget *widget, GladeXmlNode *node)
+{
+	GladeXmlNode *columns_node;
+	GladeProperty *property;
+	GladeXmlNode *prop;
+	GList *types = NULL;
+	GValue value = {0,};
+	
+	if ((columns_node = glade_xml_search_child (node, GLADE_TAG_COLUMNS)) == NULL)
+		return;
+
+	for (prop = glade_xml_node_get_children (columns_node); prop;
+	     prop = glade_xml_node_next (prop))
+	{
+		GladeColumnType *data = g_new0 (GladeColumnType, 1);
+		gchar *type;
+		
+		if (!glade_xml_node_verify (prop, GLADE_TAG_COLUMN)) continue;
+
+		type = glade_xml_get_property_string_required (prop, GLADE_TAG_TYPE, NULL);
+		data->type = g_type_from_name (type);
+		
+		types = g_list_prepend (types, data);
+		g_free (type);
+	}
+	
+	property = glade_widget_get_property (widget, "columns");
+	g_value_init (&value, GLADE_TYPE_COLUMN_TYPE_LIST);
+	g_value_take_boxed (&value, g_list_reverse (types));
+	glade_property_set_value (property, &value);
+}
+
+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 ();
+
+	if ((data_node = glade_xml_search_child (node, GLADE_TAG_DATA)) == NULL)
+		return;
+	
+	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;
+
+		/* XXX FIXME: we are assuming that the columns are listed in order */
+		for (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 (string)
+				g_string_append_printf (string, " %s", value_str);
+			else
+				string = g_string_new (value_str);
+
+			g_free (value_str);
+		}
+
+		/* harvest string onto the array ... */
+		if (string)
+			g_ptr_array_add (data_array,
+					 g_string_free (string, FALSE));
+	}
+
+	g_ptr_array_add (data_array, NULL);
+
+	glade_widget_property_set (widget, "data", data_array->pdata);
+
+	g_ptr_array_free (data_array, TRUE);
+}
+
+void
+glade_gtk_store_read_widget (GladeWidgetAdaptor *adaptor,
+			     GladeWidget        *widget,
+			     GladeXmlNode       *node)
+{
+	if (!glade_xml_node_verify 
+	    (node, GLADE_XML_TAG_WIDGET (glade_project_get_format (widget->project))))
+		return;
+
+	/* First chain up and read in all the normal properties.. */
+        GWA_GET_CLASS (G_TYPE_OBJECT)->read_widget (adaptor, widget, node);
+
+	glade_gtk_store_read_columns (widget, node);
+	glade_gtk_store_read_data (widget, node);
+}

Modified: trunk/plugins/gtk+/gtk+.xml.in
==============================================================================
--- trunk/plugins/gtk+/gtk+.xml.in	(original)
+++ trunk/plugins/gtk+/gtk+.xml.in	Sun Sep 28 04:37:44 2008
@@ -926,7 +926,6 @@
     </glade-widget-class>
 
     <glade-widget-class name="GtkTreeView" generic-name="treeview" _title="Tree View">
-      <post-create-function>glade_gtk_tree_view_post_create</post-create-function>
       <properties>
         <property id="level-indentation" since="2.12"/>
         <property id="show-expanders" since="2.12"/>
@@ -943,6 +942,9 @@
       </properties>
     </glade-widget-class>
 
+    <glade-widget-class name="GtkTreeViewColumn" generic-name="treeviewcolumn" _title="Tree View Column">
+    </glade-widget-class>
+
     <glade-widget-class name="GtkIconView" generic-name="iconview" _title="Icon View">
       <properties>
         <property id="selection-mode">
@@ -1786,9 +1788,43 @@
 			libglade-unsupported="True" toplevel="True"/>
 
     <glade-widget-class name="GtkListStore" generic-name="liststore" _title="List Store" 
-			libglade-unsupported="True" toplevel="True"/>
+			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>
+      <write-widget-function>glade_gtk_store_write_widget</write-widget-function>
+      <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>
+          <_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>
+          <_tooltip>Enter a list of values to be applied on each row</_tooltip>
+        </property>
+      </properties>
+    </glade-widget-class>
+
     <glade-widget-class name="GtkTreeStore" generic-name="treestore" _title="Tree Store" 
-			libglade-unsupported="True" toplevel="True"/>
+			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>
+      <write-widget-function>glade_gtk_store_write_widget</write-widget-function>
+      <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>
+          <_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>
+          <_tooltip>Enter a list of values to be applied on each row</_tooltip>
+        </property>
+      </properties>
+    </glade-widget-class>
+
     <glade-widget-class name="GtkTreeModelFilter" generic-name="treemodelfilter" _title="Tree Model Filter" 
 			libglade-unsupported="True" toplevel="True"/>
     <glade-widget-class name="GtkTreeModelSort" generic-name="treemodelsort" _title="Tree Model Sort" 



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