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



Author: tvb
Date: Fri Oct 24 08:47:12 2008
New Revision: 1992
URL: http://svn.gnome.org/viewvc/glade3?rev=1992&view=rev

Log:

	* plugins/gtk+/Makefile.am, plugins/gtk+/glade-button-editor.[ch]:
	Added new #GladeEditable implementation for GtkButton general page.

	* plugins/gtk+/glade-gtk.c, plugins/gtk+/gtk+.xml.in: Completely reworked GtkButton, 
	much cleaner and less code now.




Added:
   trunk/plugins/gtk+/glade-button-editor.c
   trunk/plugins/gtk+/glade-button-editor.h
Modified:
   trunk/ChangeLog
   trunk/gladeui/glade-editor-property.c
   trunk/gladeui/glade-editor-property.h
   trunk/gladeui/glade-editor-table.c
   trunk/gladeui/glade-project.c
   trunk/gladeui/glade-property.c
   trunk/gladeui/glade-widget-adaptor.c
   trunk/gladeui/glade-widget-adaptor.h
   trunk/plugins/gtk+/Makefile.am
   trunk/plugins/gtk+/glade-gtk.c
   trunk/plugins/gtk+/gtk+.xml.in

Modified: trunk/gladeui/glade-editor-property.c
==============================================================================
--- trunk/gladeui/glade-editor-property.c	(original)
+++ trunk/gladeui/glade-editor-property.c	Fri Oct 24 08:47:12 2008
@@ -57,9 +57,16 @@
 	PROP_USE_COMMAND
 };
 
+enum {
+	CHANGED,
+	LAST_SIGNAL
+};
+
 static GtkTableClass             *table_class;
 static GladeEditorPropertyClass  *editor_property_class;
 
+static guint  glade_eprop_signals[LAST_SIGNAL] = { 0, };
+
 #define GLADE_PROPERTY_TABLE_ROW_SPACING 2
 #define FLAGS_COLUMN_SETTING             0
 #define FLAGS_COLUMN_SYMBOL              1
@@ -104,7 +111,9 @@
 	if (glade_property_class_compare (eprop->property->klass,
 					  eprop->property->value, value, fmt) != 0)
 		GLADE_EDITOR_PROPERTY_GET_CLASS (eprop)->load (eprop, eprop->property);
-
+	else
+		/* publish a value change to those interested */
+		g_signal_emit (G_OBJECT (eprop), glade_eprop_signals [CHANGED], 0, eprop->property);
 }
 
 void
@@ -563,6 +572,24 @@
 	eprop_class->load          = glade_editor_property_load_common;
 	eprop_class->create_input  = NULL;
 
+	
+	/**
+	 * GladeEditorProperty::value-changed:
+	 * @gladeeditorproperty: the #GladeEditorProperty which changed value
+	 * @arg1: the #GladeProperty that's value changed.
+	 *
+	 * Emitted when a contained property changes value
+	 */
+	glade_eprop_signals[CHANGED] =
+		g_signal_new ("value-changed",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (GladeEditorPropertyClass, changed),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__OBJECT,
+			      G_TYPE_NONE, 1, GLADE_TYPE_PROPERTY);
+
+
 	/* Properties */
 	g_object_class_install_property 
 		(object_class, PROP_PROPERTY_CLASS,

Modified: trunk/gladeui/glade-editor-property.h
==============================================================================
--- trunk/gladeui/glade-editor-property.h	(original)
+++ trunk/gladeui/glade-editor-property.h	Fri Oct 24 08:47:12 2008
@@ -123,6 +123,7 @@
 
 	GtkWidget  *(* create_input)  (GladeEditorProperty *);
 
+	void       *(* changed)       (GladeEditorProperty *, GladeProperty *);
 };
 
 

Modified: trunk/gladeui/glade-editor-table.c
==============================================================================
--- trunk/gladeui/glade-editor-table.c	(original)
+++ trunk/gladeui/glade-editor-table.c	Fri Oct 24 08:47:12 2008
@@ -83,6 +83,9 @@
 		     GParamSpec       *pspec,
 		     GladeEditorTable *table)
 {
+	if (!GTK_WIDGET_MAPPED (table))
+		return;
+
 	table->loading = TRUE;
 	if (table->name_entry)
 		gtk_entry_set_text (GTK_ENTRY (table->name_entry), table->loaded_widget->name);

Modified: trunk/gladeui/glade-project.c
==============================================================================
--- trunk/gladeui/glade-project.c	(original)
+++ trunk/gladeui/glade-project.c	Fri Oct 24 08:47:12 2008
@@ -191,9 +191,9 @@
 
 static GtkWidget   *glade_project_build_prefs_dialog        (GladeProject      *project);
 
-static void         format_libglade_button_clicked          (GtkWidget         *widget,
+static void         format_libglade_button_toggled          (GtkWidget         *widget,
 							     GladeProject      *project);
-static void         format_builder_button_clicked           (GtkWidget         *widget,
+static void         format_builder_button_toggled           (GtkWidget         *widget,
 							     GladeProject      *project);
 static void         policy_project_wide_button_clicked      (GtkWidget         *widget,
 							     GladeProject      *project);
@@ -3400,9 +3400,9 @@
 
 		/* Update the toggle button in the prefs dialog here: */
 		g_signal_handlers_block_by_func (project->priv->glade_radio,
-						 G_CALLBACK (format_libglade_button_clicked), project);
+						 G_CALLBACK (format_libglade_button_toggled), project);
 		g_signal_handlers_block_by_func (project->priv->builder_radio,
-						 G_CALLBACK (format_builder_button_clicked), project);
+						 G_CALLBACK (format_builder_button_toggled), project);
 
 		if (format == GLADE_PROJECT_FORMAT_GTKBUILDER)
 			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (project->priv->builder_radio), TRUE);
@@ -3410,9 +3410,9 @@
 			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (project->priv->glade_radio), TRUE);
 
 		g_signal_handlers_unblock_by_func (project->priv->glade_radio,
-						   G_CALLBACK (format_libglade_button_clicked), project);
+						   G_CALLBACK (format_libglade_button_toggled), project);
 		g_signal_handlers_unblock_by_func (project->priv->builder_radio,
-						   G_CALLBACK (format_builder_button_clicked), project);
+						   G_CALLBACK (format_builder_button_toggled), project);
 
 	}
 }
@@ -3427,14 +3427,14 @@
 
 
 static void
-format_libglade_button_clicked (GtkWidget *widget,
+format_libglade_button_toggled (GtkWidget *widget,
 				GladeProject *project)
 {
 	glade_command_set_project_format (project, GLADE_PROJECT_FORMAT_LIBGLADE);
 }
 
 static void
-format_builder_button_clicked (GtkWidget *widget,
+format_builder_button_toggled (GtkWidget *widget,
 			       GladeProject *project)
 {
 	glade_command_set_project_format (project, GLADE_PROJECT_FORMAT_GTKBUILDER);
@@ -3551,11 +3551,11 @@
 	else
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (project->priv->glade_radio), TRUE);
 
-	g_signal_connect (G_OBJECT (project->priv->glade_radio), "clicked",
-			  G_CALLBACK (format_libglade_button_clicked), project);
+	g_signal_connect (G_OBJECT (project->priv->glade_radio), "toggled",
+			  G_CALLBACK (format_libglade_button_toggled), project);
 
-	g_signal_connect (G_OBJECT (project->priv->builder_radio), "clicked",
-			  G_CALLBACK (format_builder_button_clicked), project);
+	g_signal_connect (G_OBJECT (project->priv->builder_radio), "toggled",
+			  G_CALLBACK (format_builder_button_toggled), project);
 
 
 	/* Naming policy format */

Modified: trunk/gladeui/glade-property.c
==============================================================================
--- trunk/gladeui/glade-property.c	(original)
+++ trunk/gladeui/glade-property.c	Fri Oct 24 08:47:12 2008
@@ -1120,7 +1120,7 @@
 	 * (excepting those that specified otherwise).
 	 */
 	if (!(property->klass->save_always || property->save_always) &&
-	    glade_property_equals_value (property, property->klass->orig_def))
+	    glade_property_original_default (property))
 		return;
 
 	/* Escape our string and save with underscores */

Modified: trunk/gladeui/glade-widget-adaptor.c
==============================================================================
--- trunk/gladeui/glade-widget-adaptor.c	(original)
+++ trunk/gladeui/glade-widget-adaptor.c	Fri Oct 24 08:47:12 2008
@@ -3541,6 +3541,41 @@
 }
 
 
+
+/**
+ * glade_widget_adaptor_create_eprop_by_name:
+ * @adaptor: A #GladeWidgetAdaptor
+ * @property_id: the string if of the coresponding #GladePropertyClass to be edited
+ * @packing: whether this reffers to a packing property
+ * @use_command: whether to use the GladeCommand interface
+ * to commit property changes
+ * 
+ * Creates a #GladeEditorProperty to edit #GladePropertyClass @name in @adaptor
+ *
+ * Returns: A newly created #GladeEditorProperty
+ */
+GladeEditorProperty *
+glade_widget_adaptor_create_eprop_by_name (GladeWidgetAdaptor *adaptor,
+					   const gchar        *property_id,
+					   gboolean            packing,
+					   gboolean            use_command)
+{
+	GladePropertyClass *klass;
+	g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), NULL);
+	g_return_val_if_fail (property_id && property_id[0], NULL);
+
+	if (packing)
+		klass = glade_widget_adaptor_get_pack_property_class (adaptor, property_id);
+	else
+		klass = glade_widget_adaptor_get_property_class (adaptor, property_id);
+
+	g_return_val_if_fail (klass != NULL, NULL);
+
+	return GLADE_WIDGET_ADAPTOR_GET_CLASS
+		(adaptor)->create_eprop (adaptor, klass, use_command);
+}
+
+
 /**
  * glade_widget_adaptor_string_from_value:
  * @adaptor: A #GladeWidgetAdaptor

Modified: trunk/gladeui/glade-widget-adaptor.h
==============================================================================
--- trunk/gladeui/glade-widget-adaptor.h	(original)
+++ trunk/gladeui/glade-widget-adaptor.h	Fri Oct 24 08:47:12 2008
@@ -864,6 +864,11 @@
 							      GladePropertyClass *klass,
 							      gboolean            use_command);
 
+GladeEditorProperty *glade_widget_adaptor_create_eprop_by_name (GladeWidgetAdaptor *adaptor,
+								const gchar        *property_id,
+								gboolean            packing,
+								gboolean            use_command);
+
 gchar               *glade_widget_adaptor_string_from_value  (GladeWidgetAdaptor *adaptor,
 							      GladePropertyClass *klass,
 							      const GValue       *value,

Modified: trunk/plugins/gtk+/Makefile.am
==============================================================================
--- trunk/plugins/gtk+/Makefile.am	(original)
+++ trunk/plugins/gtk+/Makefile.am	Fri Oct 24 08:47:12 2008
@@ -25,14 +25,14 @@
 
 libgladegtk_la_SOURCES     = glade-gtk.c glade-accels.c glade-attributes.c glade-convert.c fixed-bg.xpm \
 	glade-column-types.c  glade-model-data.c glade-text-button.c glade-cell-renderer-button.c \
-	glade-icon-sources.c
+	glade-icon-sources.c glade-button-editor.c
 
 libgladegtk_la_LDFLAGS     = -module -avoid-version $(AM_LDFLAGS)
 libgladegtk_la_LIBADD      = $(libgladeui) $(GTK_LIBS)
 
 libgladegtkincludedir= $(includedir)/libgladeui-1.0/gladeui
 libgladegtkinclude_HEADERS = glade-gtk.h glade-accels.h glade-attributes.h glade-column-types.h glade-model-data.h \
-	glade-text-button.h glade-cell-renderer-button.h glade-icon-sources.h
+	glade-text-button.h glade-cell-renderer-button.h glade-icon-sources.h glade-button-editor.h
 
 if PLATFORM_WIN32
 libgladegtk_la_LDFLAGS += -no-undefined

Added: trunk/plugins/gtk+/glade-button-editor.c
==============================================================================
--- (empty file)
+++ trunk/plugins/gtk+/glade-button-editor.c	Fri Oct 24 08:47:12 2008
@@ -0,0 +1,480 @@
+/* -*- 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 <glib/gi18n-lib.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "glade-button-editor.h"
+
+
+static void glade_button_editor_finalize        (GObject              *object);
+
+static void glade_button_editor_editable_init   (GladeEditableIface *iface);
+
+static void glade_button_editor_grab_focus      (GtkWidget            *widget);
+
+
+G_DEFINE_TYPE_WITH_CODE (GladeButtonEditor, glade_button_editor, GTK_TYPE_VBOX,
+                         G_IMPLEMENT_INTERFACE (GLADE_TYPE_EDITABLE,
+                                                glade_button_editor_editable_init));
+
+
+static void
+glade_button_editor_class_init (GladeButtonEditorClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+	object_class->finalize     = glade_button_editor_finalize;
+	widget_class->grab_focus   = glade_button_editor_grab_focus;
+}
+
+static void
+glade_button_editor_init (GladeButtonEditor *self)
+{
+}
+
+static void
+project_changed (GladeProject      *project,
+		 GladeCommand      *command,
+		 gboolean           execute,
+		 GladeButtonEditor *button_editor)
+{
+	if (button_editor->modifying ||
+	    !GTK_WIDGET_MAPPED (button_editor))
+		return;
+
+	/* Reload on all commands */
+	glade_editable_load (GLADE_EDITABLE (button_editor), button_editor->loaded_widget);
+}
+
+
+static void
+project_finalized (GladeButtonEditor *button_editor,
+		   GladeProject       *where_project_was)
+{
+	button_editor->loaded_widget = NULL;
+
+	glade_editable_load (GLADE_EDITABLE (button_editor), NULL);
+}
+
+static void
+glade_button_editor_load (GladeEditable *editable,
+			  GladeWidget   *widget)
+{
+	GladeButtonEditor *button_editor = GLADE_BUTTON_EDITOR (editable);
+	GladeWidget       *gchild = NULL;
+	GtkWidget         *child, *button;
+	gboolean           use_stock = FALSE;
+	GList *l;
+
+	button_editor->loading = TRUE;
+
+	/* Since we watch the project*/
+	if (button_editor->loaded_widget)
+	{
+		/* watch custom-child and use-stock properties here for reloads !!! */
+
+		g_signal_handlers_disconnect_by_func (G_OBJECT (button_editor->loaded_widget->project),
+						      G_CALLBACK (project_changed), button_editor);
+
+		/* The widget could die unexpectedly... */
+		g_object_weak_unref (G_OBJECT (button_editor->loaded_widget->project),
+				     (GWeakNotify)project_finalized,
+				     button_editor);
+	}
+
+	/* Mark our widget... */
+	button_editor->loaded_widget = widget;
+
+	if (button_editor->loaded_widget)
+	{
+		/* This fires for undo/redo */
+		g_signal_connect (G_OBJECT (button_editor->loaded_widget->project), "changed",
+				  G_CALLBACK (project_changed), button_editor);
+
+		/* The widget/project could die unexpectedly... */
+		g_object_weak_ref (G_OBJECT (button_editor->loaded_widget->project),
+				   (GWeakNotify)project_finalized,
+				   button_editor);
+	}
+
+	/* load the embedded editable... */
+	glade_editable_load (GLADE_EDITABLE (button_editor->embed), widget);
+
+	for (l = button_editor->properties; l; l = l->next)
+		glade_editor_property_load_by_widget (GLADE_EDITOR_PROPERTY (l->data), widget);
+
+
+	if (widget)
+	{
+		button = GTK_WIDGET (widget->object);
+		child  = GTK_BIN (button)->child;
+		if (child)
+			gchild = glade_widget_get_from_gobject (child);
+
+		/* Setup radio and sensitivity states */
+		if ((gchild && gchild->parent) ||  // a widget is manually inside
+		    GLADE_IS_PLACEHOLDER (child)) // placeholder there, custom mode
+		{
+			/* Custom */
+			gtk_widget_set_sensitive (button_editor->standard_frame, FALSE);
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_editor->custom_radio), TRUE);
+		}
+		else
+		{
+			/* Standard */
+			gtk_widget_set_sensitive (button_editor->standard_frame, TRUE);
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_editor->standard_radio), TRUE);
+			
+			glade_widget_property_get (widget, "use-stock", &use_stock);
+			
+			if (use_stock)
+			{
+				gtk_widget_set_sensitive (button_editor->stock_frame, TRUE);
+				gtk_widget_set_sensitive (button_editor->label_frame, FALSE);
+				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_editor->stock_radio), TRUE);
+			}
+			else
+			{
+				gtk_widget_set_sensitive (button_editor->stock_frame, FALSE);
+				gtk_widget_set_sensitive (button_editor->label_frame, TRUE);
+				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_editor->label_radio), TRUE);
+			}
+		}
+	}
+	button_editor->loading = FALSE;
+}
+
+static void
+glade_button_editor_editable_init (GladeEditableIface *iface)
+{
+	iface->load = glade_button_editor_load;
+}
+
+static void
+glade_button_editor_finalize (GObject *object)
+{
+	GladeButtonEditor *button_editor = GLADE_BUTTON_EDITOR (object);
+
+	if (button_editor->properties)
+		g_list_free (button_editor->properties);
+
+	G_OBJECT_CLASS (glade_button_editor_parent_class)->finalize (object);
+}
+
+static void
+glade_button_editor_grab_focus (GtkWidget *widget)
+{
+	GladeButtonEditor *button_editor = GLADE_BUTTON_EDITOR (widget);
+
+	gtk_widget_grab_focus (button_editor->embed);
+}
+
+/* Secion control radio button callbacks: */
+static void
+standard_toggled (GtkWidget         *widget,
+		  GladeButtonEditor *button_editor)
+{
+	GladeProperty     *property;
+	GladeWidget       *gchild = NULL;
+	GtkWidget         *child, *button;
+
+	if (button_editor->loading || !button_editor->loaded_widget)
+		return;
+
+	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_editor->standard_radio)))
+		return;
+
+	button_editor->modifying = TRUE;
+
+	glade_command_push_group (_("Setting %s to use standard configuration"), 
+				  button_editor->loaded_widget->name);
+
+	/* If theres a widget customly inside... command remove it first... */
+	button = GTK_WIDGET (button_editor->loaded_widget->object);
+	child  = GTK_BIN (button)->child;
+	if (child)
+		gchild = glade_widget_get_from_gobject (child);
+
+	if (gchild && gchild->parent == button_editor->loaded_widget)
+	{
+		GList widgets = { 0, };
+		widgets.data = gchild;
+		glade_command_delete (&widgets);
+	}
+
+	property = glade_widget_get_property (button_editor->loaded_widget, "custom-child");
+	glade_command_set_property (property, FALSE);
+
+	glade_command_pop_group ();
+
+	button_editor->modifying = FALSE;
+
+	/* reload buttons and sensitivity and stuff... */
+	glade_editable_load (GLADE_EDITABLE (button_editor), 
+			     button_editor->loaded_widget);
+}
+
+static void
+custom_toggled (GtkWidget         *widget,
+		GladeButtonEditor *button_editor)
+{
+	GladeProperty     *property;
+
+	if (button_editor->loading || !button_editor->loaded_widget)
+		return;
+
+	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_editor->custom_radio)))
+		return;
+
+	button_editor->modifying = TRUE;
+
+	glade_command_push_group (_("Setting %s to use a custom child"), 
+				  button_editor->loaded_widget->name);
+
+	/* clear out some things... */
+	property = glade_widget_get_property (button_editor->loaded_widget, "image");
+	glade_command_set_property (property, NULL);
+
+	property = glade_widget_get_property (button_editor->loaded_widget, "use-stock");
+	glade_command_set_property (property, FALSE);
+
+	property = glade_widget_get_property (button_editor->loaded_widget, "stock");
+	glade_command_set_property (property, 0);
+
+	property = glade_widget_get_property (button_editor->loaded_widget, "label");
+	glade_command_set_property (property, NULL);
+
+	/* Add a placeholder via the custom-child property... */
+	property = glade_widget_get_property (button_editor->loaded_widget, "custom-child");
+	glade_command_set_property (property, TRUE);
+
+	glade_command_pop_group ();
+
+	button_editor->modifying = FALSE;
+
+	/* reload buttons and sensitivity and stuff... */
+	glade_editable_load (GLADE_EDITABLE (button_editor), 
+			     button_editor->loaded_widget);
+}
+
+static void
+stock_toggled (GtkWidget         *widget,
+	       GladeButtonEditor *button_editor)
+{
+	GladeProperty     *property;
+
+	if (button_editor->loading || !button_editor->loaded_widget)
+		return;
+
+	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_editor->stock_radio)))
+		return;
+
+	button_editor->modifying = TRUE;
+
+	glade_command_push_group (_("Setting %s to use a stock button"), button_editor->loaded_widget->name);
+
+	/* clear out stuff... */
+	property = glade_widget_get_property (button_editor->loaded_widget, "image");
+	glade_command_set_property (property, NULL);
+
+	property = glade_widget_get_property (button_editor->loaded_widget, "label");
+	glade_command_set_property (property, NULL);
+
+	property = glade_widget_get_property (button_editor->loaded_widget, "use-stock");
+	glade_command_set_property (property, TRUE);
+
+	property = glade_widget_get_property (button_editor->loaded_widget, "stock");
+	glade_command_set_property (property, 0);
+
+	glade_command_pop_group ();
+
+	button_editor->modifying = FALSE;
+
+	/* reload buttons and sensitivity and stuff... */
+	glade_editable_load (GLADE_EDITABLE (button_editor), 
+			     button_editor->loaded_widget);
+}
+
+static void
+label_toggled (GtkWidget         *widget,
+	       GladeButtonEditor *button_editor)
+{
+	GladeProperty     *property;
+	GValue             value = { 0, };
+
+	if (button_editor->loading || !button_editor->loaded_widget)
+		return;
+
+	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_editor->label_radio)))
+		return;
+
+	button_editor->modifying = TRUE;
+
+	glade_command_push_group (_("Setting %s to use a label and image"), button_editor->loaded_widget->name);
+
+	property = glade_widget_get_property (button_editor->loaded_widget, "stock");
+	glade_command_set_property (property, 0);
+
+	property = glade_widget_get_property (button_editor->loaded_widget, "use-stock");
+	glade_command_set_property (property, FALSE);
+
+	property = glade_widget_get_property (button_editor->loaded_widget, "label");
+	glade_property_get_default (property, &value);
+	glade_command_set_property_value (property, &value);
+	g_value_unset (&value);
+
+	glade_command_pop_group ();
+
+	button_editor->modifying = FALSE;
+
+	/* reload buttons and sensitivity and stuff... */
+	glade_editable_load (GLADE_EDITABLE (button_editor), 
+			     button_editor->loaded_widget);
+}
+
+static void
+table_attach (GtkWidget *table, 
+	      GtkWidget *child, 
+	      gint pos, gint row)
+{
+	gtk_table_attach (GTK_TABLE (table), child,
+			  pos, pos+1, row, row +1,
+			  GTK_EXPAND | GTK_FILL,
+			  GTK_EXPAND | GTK_FILL,
+			  3, 1);
+}
+
+
+GtkWidget *
+glade_button_editor_new (GladeWidgetAdaptor *adaptor,
+			 GladeEditable      *embed)
+{
+	GladeButtonEditor   *button_editor;
+	GladeEditorProperty *eprop;
+	GtkWidget           *vbox, *table, *frame;
+
+	g_return_val_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor), NULL);
+	g_return_val_if_fail (GLADE_IS_EDITABLE (embed), NULL);
+
+	button_editor = g_object_new (GLADE_TYPE_BUTTON_EDITOR, NULL);
+	button_editor->embed = GTK_WIDGET (embed);
+
+	button_editor->standard_radio = gtk_radio_button_new_with_label (NULL, _("Configure button content"));
+	button_editor->custom_radio   = gtk_radio_button_new_with_label_from_widget
+		(GTK_RADIO_BUTTON (button_editor->standard_radio), _("Add custom button content"));
+
+	button_editor->stock_radio = gtk_radio_button_new_with_label (NULL, _("Stock button"));
+	button_editor->label_radio = gtk_radio_button_new_with_label_from_widget
+		(GTK_RADIO_BUTTON (button_editor->stock_radio), _("Label with optional image"));
+
+	g_signal_connect (G_OBJECT (button_editor->standard_radio), "toggled",
+			  G_CALLBACK (standard_toggled), button_editor);
+	g_signal_connect (G_OBJECT (button_editor->custom_radio), "toggled",
+			  G_CALLBACK (custom_toggled), button_editor);
+	g_signal_connect (G_OBJECT (button_editor->stock_radio), "toggled",
+			  G_CALLBACK (stock_toggled), button_editor);
+	g_signal_connect (G_OBJECT (button_editor->label_radio), "toggled",
+			  G_CALLBACK (label_toggled), button_editor);
+
+	/* Pack the parent on top... */
+	gtk_box_pack_start (GTK_BOX (button_editor), GTK_WIDGET (embed), FALSE, FALSE, 0);
+
+	/* Standard frame... */
+	frame = gtk_frame_new (NULL);
+	gtk_frame_set_label_widget (GTK_FRAME (frame), button_editor->standard_radio);
+	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+	gtk_box_pack_start (GTK_BOX (button_editor), frame, FALSE, FALSE, 8);
+
+	button_editor->standard_frame = gtk_alignment_new (0.5F, 0.5F, 1.0F, 1.0F);
+	gtk_alignment_set_padding (GTK_ALIGNMENT (button_editor->standard_frame), 6, 0, 12, 0);
+	gtk_container_add (GTK_CONTAINER (frame), button_editor->standard_frame);
+
+	vbox = gtk_vbox_new (FALSE, 8);
+	gtk_container_add (GTK_CONTAINER (button_editor->standard_frame), vbox);
+
+	/* Populate stock frame here... */
+	frame = gtk_frame_new (NULL);
+	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+	gtk_frame_set_label_widget (GTK_FRAME (frame), button_editor->stock_radio);
+	gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 4);
+
+	button_editor->stock_frame = gtk_alignment_new (0.5F, 0.5F, 1.0F, 1.0F);
+	gtk_alignment_set_padding (GTK_ALIGNMENT (button_editor->stock_frame), 6, 0, 12, 0);
+	gtk_container_add (GTK_CONTAINER (frame), button_editor->stock_frame);
+
+	table = gtk_table_new (0, 0, FALSE);
+	gtk_container_add (GTK_CONTAINER (button_editor->stock_frame), table);
+
+	eprop = glade_widget_adaptor_create_eprop_by_name (adaptor, "stock", FALSE, TRUE);
+	table_attach (table, eprop->item_label, 0, 0);
+	table_attach (table, GTK_WIDGET (eprop), 1, 0);
+	button_editor->properties = g_list_prepend (button_editor->properties, eprop);
+
+	eprop = glade_widget_adaptor_create_eprop_by_name (adaptor, "image-position", FALSE, TRUE);
+	table_attach (table, eprop->item_label, 0, 1);
+	table_attach (table, GTK_WIDGET (eprop), 1, 1);
+	button_editor->properties = g_list_prepend (button_editor->properties, eprop);
+
+	/* Populate label frame here... */
+	frame = gtk_frame_new (NULL);
+	gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+	gtk_frame_set_label_widget (GTK_FRAME (frame), button_editor->label_radio);
+	gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 4);
+
+	button_editor->label_frame = gtk_alignment_new (0.5F, 0.5F, 1.0F, 1.0F);
+	gtk_alignment_set_padding (GTK_ALIGNMENT (button_editor->label_frame), 6, 0, 12, 0);
+	gtk_container_add (GTK_CONTAINER (frame), button_editor->label_frame);
+
+	table = gtk_table_new (0, 0, FALSE);
+	gtk_container_add (GTK_CONTAINER (button_editor->label_frame), table);
+
+	eprop = glade_widget_adaptor_create_eprop_by_name (adaptor, "label", FALSE, TRUE);
+	table_attach (table, eprop->item_label, 0, 0);
+	table_attach (table, GTK_WIDGET (eprop), 1, 0);
+	button_editor->properties = g_list_prepend (button_editor->properties, eprop);
+
+	eprop = glade_widget_adaptor_create_eprop_by_name (adaptor, "use-underline", FALSE, TRUE);
+	table_attach (table, eprop->item_label, 0, 1);
+	table_attach (table, GTK_WIDGET (eprop), 1, 1);
+	button_editor->properties = g_list_prepend (button_editor->properties, eprop);
+
+	eprop = glade_widget_adaptor_create_eprop_by_name (adaptor, "image", FALSE, TRUE);
+	table_attach (table, eprop->item_label, 0, 2);
+	table_attach (table, GTK_WIDGET (eprop), 1, 2);
+	button_editor->properties = g_list_prepend (button_editor->properties, eprop);
+
+	eprop = glade_widget_adaptor_create_eprop_by_name (adaptor, "image-position", FALSE, TRUE);
+	table_attach (table, eprop->item_label, 0, 3);
+	table_attach (table, GTK_WIDGET (eprop), 1, 3);
+	button_editor->properties = g_list_prepend (button_editor->properties, eprop);
+
+	/* Custom radio button on the bottom */
+	gtk_box_pack_start (GTK_BOX (button_editor), button_editor->custom_radio, FALSE, FALSE, 0);
+
+	gtk_widget_show_all (GTK_WIDGET (button_editor));
+
+	return GTK_WIDGET (button_editor);
+}

Added: trunk/plugins/gtk+/glade-button-editor.h
==============================================================================
--- (empty file)
+++ trunk/plugins/gtk+/glade-button-editor.h	Fri Oct 24 08:47:12 2008
@@ -0,0 +1,79 @@
+/* -*- 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_TEXT_EDITOR_H_
+#define _GLADE_TEXT_EDITOR_H_
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GLADE_TYPE_BUTTON_EDITOR	            (glade_button_editor_get_type ())
+#define GLADE_BUTTON_EDITOR(obj)		    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_BUTTON_EDITOR, GladeButtonEditor))
+#define GLADE_BUTTON_EDITOR_CLASS(klass)	    (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_BUTTON_EDITOR, GladeButtonEditorClass))
+#define GLADE_IS_BUTTON_EDITOR(obj)	    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_BUTTON_EDITOR))
+#define GLADE_IS_BUTTON_EDITOR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_BUTTON_EDITOR))
+#define GLADE_BUTTON_EDITOR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_TYPE_BUTTON_EDITOR, GladeButtonButtonClass))
+
+typedef struct _GladeButtonEditor        GladeButtonEditor;
+typedef struct _GladeButtonEditorClass   GladeButtonEditorClass;
+
+struct _GladeButtonEditor
+{
+	GtkVBox  parent;
+
+	GladeWidget *loaded_widget; /* A handy pointer to the loaded widget ... */
+
+	GtkWidget *embed;
+
+	GtkWidget *standard_radio; /* Use standard properties to layout a button */
+	GtkWidget *custom_radio;   /* Use a placeholder in the button */
+
+	/* Available in standard mode: */
+	GtkWidget *stock_radio;    /* Create the button using the stock (Available: stock, image-position) */
+	GtkWidget *label_radio;    /* Create the button with a custom label
+				    * (Available: label, use-underline, image, image-position */
+
+	GtkWidget *standard_frame; /* Contains all the button configurations
+				    */
+	GtkWidget *stock_frame;    /* Contains stock and image-position properties
+				    */
+	GtkWidget *label_frame;    /* Contains label, use-underline, image and image-position properties 
+				    */
+
+	GList *properties;         /* A list of eprops to update at load() time */
+
+	gboolean loading;          /* Loading flag for loading widgets in the editor */
+	gboolean modifying;        /* Flag for monitoring project changes */
+};
+
+struct _GladeButtonEditorClass
+{
+	GtkVBoxClass parent;
+};
+
+GType            glade_button_editor_get_type (void);
+GtkWidget       *glade_button_editor_new      (GladeWidgetAdaptor *adaptor,
+					       GladeEditable      *editable);
+
+G_END_DECLS
+
+#endif  /* _GLADE_BUTTON_EDITOR_H_ */

Modified: trunk/plugins/gtk+/glade-gtk.c
==============================================================================
--- trunk/plugins/gtk+/glade-gtk.c	(original)
+++ trunk/plugins/gtk+/glade-gtk.c	Fri Oct 24 08:47:12 2008
@@ -31,6 +31,7 @@
 #include "glade-column-types.h"
 #include "glade-model-data.h"
 #include "glade-icon-sources.h"
+#include "glade-button-editor.h"
 
 #include <gladeui/glade-editor-property.h>
 #include <gladeui/glade-base-editor.h>
@@ -196,23 +197,6 @@
 	return etype;
 }
 
-GType
-glade_gtk_button_type_get_type (void)
-{
-	static GType etype = 0;
-	if (etype == 0) {
-		static GEnumValue values[] = {
-			{ GLADEGTK_BUTTON_LABEL,     "GLADEGTK_BUTTON_LABEL", "glade-gtk-button-label" },
-			{ GLADEGTK_BUTTON_STOCK,     "GLADEGTK_BUTTON_STOCK", "glade-gtk-button-stock" },
-			{ GLADEGTK_BUTTON_CONTAINER, "GLADEGTK_BUTTON_CONTAINER", "glade-gtk-button-container" },
-			{ 0, NULL, NULL }
-		};
-
-		etype = g_enum_register_static ("GladeGtkButtonType", values);
-	}
-	return etype;
-}
-
 GParamSpec *
 glade_gtk_image_type_spec (void)
 {
@@ -222,16 +206,6 @@
 				  1, G_PARAM_READWRITE);
 }
 
-GParamSpec *
-glade_gtk_button_type_spec (void)
-{
-	return g_param_spec_enum ("type", _("Method"), 
-				  _("The method to use to edit this button"),
-				  glade_gtk_button_type_get_type (),
-				  0, G_PARAM_READWRITE);
-}
-
-
 /* This function does absolutely nothing
  * (and is for use in overriding post_create functions).
  */
@@ -1528,12 +1502,17 @@
 				  GtkWidget          *container,
 				  GtkWidget          *child)
 {
+	GList *children;
 	gtk_container_remove (GTK_CONTAINER (container), child);
 
 	/* If this is the last one, add a placeholder by default.
 	 */
-	if (gtk_container_get_children (GTK_CONTAINER (container)) == NULL)
+	if ((children = gtk_container_get_children (GTK_CONTAINER (container))) == NULL)
+	{
 		gtk_container_add (GTK_CONTAINER (container), glade_placeholder_new ());
+	}
+	else
+		g_list_free (children);
 }
 
 void
@@ -5146,90 +5125,20 @@
 }
 
 /* ----------------------------- GtkButton ------------------------------ */
-static void
-glade_gtk_button_disable_label (GladeWidget *gwidget)
-{
-	glade_widget_property_set (gwidget, "use-underline", FALSE);
-
-	glade_widget_property_set_sensitive
-		(gwidget, "label", FALSE,
-		 _("This only applies with label type buttons"));
 
-	glade_widget_property_set_sensitive
-		(gwidget, "use-underline", FALSE,
-		 _("This only applies with label type buttons"));
-}
-
-static void
-glade_gtk_button_disable_stock (GladeWidget *gwidget)
+GladeEditable *
+glade_gtk_button_create_editable (GladeWidgetAdaptor  *adaptor,
+				  GladeEditorPageType  type)
 {
-	glade_widget_property_set (gwidget, "use-stock", FALSE);
-	glade_widget_property_set (gwidget, "stock", 0);
-
-	glade_widget_property_set_sensitive
-		(gwidget, "stock", FALSE,
-		 _("This only applies with stock type buttons"));
-
-	glade_widget_property_set_sensitive
-		(gwidget, "image-position", FALSE,
-		 _("This only applies with stock type buttons"));
-
-}
-
-static void
-glade_gtk_button_restore_container (GladeWidget *gwidget)
-{
-	GtkWidget *child = GTK_BIN (gwidget->object)->child;
-	if (child && glade_widget_get_from_gobject (child) == NULL)
-		gtk_container_remove (GTK_CONTAINER (gwidget->object), child);
-
-	if (GTK_BIN (gwidget->object)->child == NULL)
-		gtk_container_add (GTK_CONTAINER (gwidget->object), 
-				   glade_placeholder_new ());
-}
-
-static void
-glade_gtk_button_post_create_parse_finished (GladeProject *project,
-					     GObject *button)
-{
-	gboolean     use_stock = FALSE;
-	gchar       *label = NULL;
-	GEnumValue  *eval;
-	GEnumClass  *eclass;
-	GladeWidget *gbutton = glade_widget_get_from_gobject (button);
-	GladeCreateReason reason;
-
-	eclass   = g_type_class_ref (GLADE_TYPE_STOCK);
-
-	g_object_set_data (button, "glade-button-post-ran", GINT_TO_POINTER (1));
-	reason = GPOINTER_TO_INT (g_object_get_data (button, "glade-reason"));
-
-	glade_widget_property_get (gbutton, "use-stock", &use_stock);
-	glade_widget_property_get (gbutton, "label", &label);
+	GladeEditable *editable;
 
-	if (GTK_BIN (button)->child != NULL && 
-	    glade_widget_get_from_gobject (GTK_BIN (button)->child) != NULL)
-	{
-		glade_widget_property_set (gbutton, "glade-type", GLADEGTK_BUTTON_CONTAINER);
-	}
-	else if (use_stock)
-	{
-		if (label != NULL && strcmp (label, "glade-none") != 0 &&
-		    (eval = g_enum_get_value_by_nick (eclass, label)) != NULL)
-		{
-			g_object_set_data (G_OBJECT (gbutton), "stock", 
-					   GINT_TO_POINTER (eval->value));
-
-			glade_widget_property_set (gbutton, "stock", eval->value);
-		}
+	/* Get base editable */
+	editable = GWA_GET_CLASS (GTK_TYPE_CONTAINER)->create_editable (adaptor, type);
 
-		glade_widget_property_set (gbutton, "glade-type", GLADEGTK_BUTTON_STOCK);
-	}
-	else
-		/* Fallback to label type */
-		glade_widget_property_set (gbutton, "glade-type", GLADEGTK_BUTTON_LABEL);
+	if (type == GLADE_PAGE_GENERAL)
+		return (GladeEditable *)glade_button_editor_new (adaptor, editable);
 
-	g_type_class_unref (eclass);
+	return editable;
 }
 
 void
@@ -5251,234 +5160,135 @@
 			(button, "color-set", 
 			 G_CALLBACK (glade_gtk_color_button_refresh_color), gbutton);
 
-
-	if (GTK_IS_COLOR_BUTTON (button) ||
-	    GTK_IS_FONT_BUTTON (button))
-		return;
-
-	/* Internal buttons get there stock stuff introspected. */
-	if (reason == GLADE_CREATE_USER && gbutton->internal == NULL)
-	{
-		g_object_set_data (button, "glade-button-post-ran", GINT_TO_POINTER (1));
-
-		glade_widget_property_set (gbutton, "glade-type", GLADEGTK_BUTTON_LABEL);
-		glade_project_selection_set (GLADE_PROJECT (gbutton->project), 
-					     G_OBJECT (button), TRUE);
-	}
-	else
-	{
-		g_object_set_data (button, "glade-reason", GINT_TO_POINTER (reason));
-		g_signal_connect (glade_widget_get_project (gbutton),
-				  "parse-finished",
-				  G_CALLBACK (glade_gtk_button_post_create_parse_finished),
-				  button);
-	}
-
 	/* Disabled response-id until its in an action area */
 	glade_widget_property_set_sensitive (gbutton, "response-id", FALSE, 
 					     RESPID_INSENSITIVE_MSG);
 	glade_widget_property_set_enabled (gbutton, "response-id", FALSE);
-	
-
 }
 
-static void
-glade_gtk_button_set_type (GObject *object, const GValue *value)
-{
-	GladeWidget        *gwidget;
-	GladeGtkButtonType  type;
-	
-	gwidget = glade_widget_get_from_gobject (object);
-	g_return_if_fail (GTK_IS_BUTTON (object));
-	g_return_if_fail (GLADE_IS_WIDGET (gwidget));
-
-	/* Exit if we're still loading project objects
-	 */
-	if (GPOINTER_TO_INT (g_object_get_data
-			     (object, "glade-button-post-ran")) == 0)
-		return;
-
-	type = g_value_get_enum (value);
-
-	switch (type)
-	{
-	case GLADEGTK_BUTTON_LABEL:
-		glade_widget_property_set_sensitive (gwidget, "label", TRUE, NULL);
-		glade_widget_property_set_sensitive (gwidget, "use-underline", TRUE, NULL);
-		glade_gtk_button_disable_stock (gwidget);
-		break;
-	case GLADEGTK_BUTTON_STOCK:
-		glade_widget_property_set (gwidget, "use-stock", TRUE);
-		glade_widget_property_set_sensitive (gwidget, "stock", TRUE, NULL);
-		glade_widget_property_set_sensitive (gwidget, "image-position", TRUE, NULL);
-		glade_gtk_button_disable_label (gwidget);
-		break;
-	case GLADEGTK_BUTTON_CONTAINER:
-
-		if (GPOINTER_TO_INT (g_object_get_data
-				     (object, "button-type-initially-set")) != 0)
-		{
-			/* Skip this on the initial setting */
-			glade_gtk_button_disable_label (gwidget);
-			glade_gtk_button_disable_stock (gwidget);
-		}
-		else
-		{
-			/* Initially setting container mode after a load is
-			 * a delicate dance.
-			 */
-			glade_widget_property_set (gwidget, "label", NULL);
-			
-			glade_widget_property_set_sensitive
-				(gwidget, "stock", FALSE,
-				 _("This only applies with stock type buttons"));
-
-			glade_widget_property_set_sensitive
-				(gwidget, "image-position", FALSE,
-				 _("This only applies with stock type buttons"));
-			
-			glade_widget_property_set_sensitive
-				(gwidget, "label", FALSE,
-				 _("This only applies with label type buttons"));
-			
-			glade_widget_property_set_sensitive
-				(gwidget, "use-underline", FALSE,
-				 _("This only applies with label type buttons"));
-		}
-		glade_widget_property_set (gwidget, "label", NULL);
-		glade_gtk_button_restore_container (gwidget);
-		break;
-	}		
-	g_object_set_data (object, "button-type-initially-set", GINT_TO_POINTER (1));
-}
-
-static void
-glade_gtk_button_set_stock (GObject *object, const GValue *value)
+void
+glade_gtk_button_set_property (GladeWidgetAdaptor *adaptor,
+			       GObject            *object, 
+			       const gchar        *id,
+			       const GValue       *value)
 {
-	GladeWidget   *gwidget;
-	GEnumClass    *eclass;
-	GEnumValue    *eval;
-	gint           val;
-
-	gwidget = glade_widget_get_from_gobject (object);
-	g_return_if_fail (GTK_IS_BUTTON (object));
-	g_return_if_fail (GLADE_IS_WIDGET (gwidget));
-
-	/* Exit if we're still loading project objects
-	 */
-	if (GPOINTER_TO_INT (g_object_get_data
-			     (object, "glade-button-post-ran")) == 0)
-		return;
-
-	val = g_value_get_enum (value);	
-	if (val == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (gwidget), "stock")))
-		return;
-	g_object_set_data (G_OBJECT (gwidget), "stock", GINT_TO_POINTER (val));
-
-	eclass   = g_type_class_ref (G_VALUE_TYPE (value));
-	if ((eval = g_enum_get_value (eclass, val)) != NULL)
+	if (strcmp (id, "custom-child") == 0)
 	{
-		/* setting to "none", ensure an appropriate label */
-		if (val == 0)
-			glade_widget_property_set (gwidget, "label", NULL);
-		else
+		if (g_value_get_boolean (value))
 		{
 			if (GTK_BIN (object)->child)
-			{
-				/* Here we would delete the coresponding GladeWidget from
-				 * the project (like we created it and added it), but this
-				 * screws up the undo stack, so instead we keep the stock
-				 * button insensitive while ther are usefull children in the
-				 * button.
-				 */
-				gtk_container_remove (GTK_CONTAINER (object), 
+				gtk_container_remove (GTK_CONTAINER (object),
 						      GTK_BIN (object)->child);
-			}
-			
-			/* Here we should remove any previously added GladeWidgets manualy
-			 * and from the project, not to leak them.
-			 */
-			glade_widget_property_set (gwidget, "label", eval->value_nick);
+
+			gtk_container_add (GTK_CONTAINER (object), glade_placeholder_new ());
 		}
 	}
-	g_type_class_unref (eclass);
-}
+	else if (strcmp (id, "stock") == 0)
+	{
+		GEnumClass    *eclass;
+		GEnumValue    *eval;
 
-void
-glade_gtk_button_set_property (GladeWidgetAdaptor *adaptor,
-			       GObject            *object, 
-			       const gchar        *id,
-			       const GValue       *value)
-{
-	if (!strcmp (id, "glade-type"))
-		glade_gtk_button_set_type (object, value);
-	else if (!strcmp (id, "stock"))
-		glade_gtk_button_set_stock (object, value);
+		/* Do it by hand cause we need the nick not the name */
+		eclass   = g_type_class_ref (G_VALUE_TYPE (value));
+		if ((eval = g_enum_get_value (eclass, g_value_get_enum (value))) != NULL)
+		{
+			if (g_value_get_enum (value) == 0)
+				gtk_button_set_label (GTK_BUTTON (object), NULL);
+			else
+				gtk_button_set_label (GTK_BUTTON (object), eval->value_nick);
+		}
+		g_type_class_unref (eclass);
+	}
 	else
 		GWA_GET_CLASS (GTK_TYPE_CONTAINER)->set_property (adaptor, object,
 								  id, value);
 }
 
 void
-glade_gtk_button_replace_child (GladeWidgetAdaptor  *adaptor,
-				GtkWidget           *container,
-				GtkWidget           *current,
-				GtkWidget           *new_widget)
+glade_gtk_button_read_widget (GladeWidgetAdaptor *adaptor,
+			      GladeWidget        *widget,
+			      GladeXmlNode       *node)
 {
-	GladeWidget *gbutton = glade_widget_get_from_gobject (container);
+	gboolean  use_stock;
+	gchar    *label = NULL;
+	gint      stock_id = 0;
 
-	g_return_if_fail (GLADE_IS_WIDGET (gbutton));
+	if (!glade_xml_node_verify 
+	    (node, GLADE_XML_TAG_WIDGET (glade_project_get_format (widget->project))))
+		return;
 
-	GWA_GET_CLASS
-		(GTK_TYPE_CONTAINER)->replace_child (adaptor, 
-						     G_OBJECT (container), 
-						     G_OBJECT (current), 
-						     G_OBJECT (new_widget));
-	
-	if (GLADE_IS_PLACEHOLDER (new_widget))
-		glade_widget_property_set_sensitive (gbutton, "glade-type", TRUE, NULL);
-	else
-		glade_widget_property_set_sensitive (gbutton, "glade-type", FALSE,
-						     _("You must remove any children before "
-						       "you can set the type"));
+	/* First chain up and read in all the normal properties.. */
+        GWA_GET_CLASS (G_TYPE_OBJECT)->read_widget (adaptor, widget, node);
 
+	/* Update the stock property */
+	glade_widget_property_get (widget, "use-stock", &use_stock);
+	if (use_stock)
+	{
+		glade_widget_property_get (widget, "label", &label);
+		if (label)
+			stock_id = glade_utils_enum_value_from_string (GLADE_TYPE_STOCK, label);
+		if (stock_id < 0)
+			stock_id = 0;
+		glade_widget_property_set (widget, "stock", stock_id);
+	}
 }
 
 void
-glade_gtk_button_add_child (GladeWidgetAdaptor  *adaptor,
-			    GObject             *object, 
-			    GObject             *child)
+glade_gtk_button_write_widget (GladeWidgetAdaptor *adaptor,
+			       GladeWidget        *widget,
+			       GladeXmlContext    *context,
+			       GladeXmlNode       *node)
 {
-	GladeWidget *gwidget;
+	GladeXmlNode  *prop_node;
+	GladeProperty *label_prop;
+	gboolean  use_stock;
+	gchar    *label = NULL;
+	gint      stock_id = 0;
 
-	if (GTK_BIN (object)->child)
-		gtk_container_remove (GTK_CONTAINER (object), 
-				      GTK_BIN (object)->child);
-	
-	gtk_container_add (GTK_CONTAINER (object), GTK_WIDGET (child));
+	if (!glade_xml_node_verify
+	    (node, GLADE_XML_TAG_WIDGET (glade_project_get_format (widget->project))))
+		return;
 
-	if (GLADE_IS_PLACEHOLDER (child) == FALSE)
+	/* Start out by writing the use-stock prop so it stays at the top... */
+	glade_widget_property_get (widget, "use-stock", &use_stock);
+	if (use_stock)
 	{
-		gwidget = glade_widget_get_from_gobject (object);
-		glade_widget_property_set_sensitive (gwidget, "glade-type", FALSE,
-						     _("You must remove any children before "
-						       "you can set the type"));
-	}
-}
+		GEnumClass    *eclass;
+		GEnumValue    *eval;
 
-void
-glade_gtk_button_remove_child (GladeWidgetAdaptor  *adaptor,
-			       GObject             *object, 
-			       GObject             *child)
-{
-	GladeWidget *gwidget = glade_widget_get_from_gobject (object);
+		glade_widget_property_get (widget, "stock", &stock_id);
 
-	gtk_container_remove (GTK_CONTAINER (object), GTK_WIDGET (child));
-	gtk_container_add (GTK_CONTAINER (object), glade_placeholder_new());
+		eclass = g_type_class_ref (GLADE_TYPE_STOCK);
+		if (stock_id > 0 && 
+		    (eval = g_enum_get_value (eclass, stock_id)) != NULL)
+			label = g_strdup (eval->value_nick);
+		g_type_class_unref (eclass);
+
+		if (label)
+		{
+			/* Good thing stock items dont have translatable stock ids ! :D */
+			prop_node = glade_xml_node_new (context, GLADE_XML_TAG_PROPERTY);
+			glade_xml_node_append_child (node, prop_node);
+			
+			/* Name and value */
+			glade_xml_node_set_property_string (prop_node, GLADE_XML_TAG_NAME, "label");
+			glade_xml_set_content (prop_node, label);
+			
+			g_free (label);
+		}
+	}
+	else
+	{
+		label_prop = glade_widget_get_property (widget, "label");
+		glade_property_write (label_prop, context, node);
+	}
+
+	/* First chain up and read in all the normal properties.. */
+        GWA_GET_CLASS (G_TYPE_OBJECT)->write_widget (adaptor, widget, context, node);
 
-	glade_widget_property_set_sensitive (gwidget, "glade-type", TRUE, NULL);
 }
 
+
 /* ----------------------------- GtkImage ------------------------------ */
 static void
 glade_gtk_image_disable_filename (GladeWidget *gwidget)

Modified: trunk/plugins/gtk+/gtk+.xml.in
==============================================================================
--- trunk/plugins/gtk+/gtk+.xml.in	(original)
+++ trunk/plugins/gtk+/gtk+.xml.in	Fri Oct 24 08:47:12 2008
@@ -656,36 +656,29 @@
 
     <glade-widget-class name="GtkButton" generic-name="button" _title="Button">
       <post-create-function>glade_gtk_button_post_create</post-create-function>
-      <add-child-function>glade_gtk_button_add_child</add-child-function>
-      <remove-child-function>glade_gtk_button_remove_child</remove-child-function>
-      <replace-child-function>glade_gtk_button_replace_child</replace-child-function>
+      <create-editable-function>glade_gtk_button_create_editable</create-editable-function>
       <set-property-function>glade_gtk_button_set_property</set-property-function>
+      <read-widget-function>glade_gtk_button_read_widget</read-widget-function>
+      <write-widget-function>glade_gtk_button_write_widget</write-widget-function>
 
       <properties>
-	<property id="image" parentless-widget="True" create-type="GtkImage" libglade-unsupported="True"/>
-	<property id="use-stock" visible="False"/>
-
-      	<property id="label" default="button" translatable="True">
+	<property id="image" parentless-widget="True" create-type="GtkImage" 
+		  libglade-unsupported="True" custom-layout="True"/>
+	<property id="use-stock" visible="False" custom-layout="True"/>
+      	<property id="label" default="button" translatable="True" custom-layout="True" save="False">
             <visible-lines>2</visible-lines>
 	</property>
-
-	<property id="use-underline" weight="1.5"/>
-
-	<property id="stock" _name="Stock Button" save="False" weight="1.6">
+	<property id="use-underline" weight="1.5" custom-layout="True"/>
+	<property id="stock" _name="Stock Button" save="False" weight="1.6" custom-layout="True">
 	  <spec>glade_standard_stock_spec</spec>
 	  <_tooltip>The stock item for this button</_tooltip>
 	</property>
 
-	<property id="image-position" weight="1.7"/>
+        <property id="custom-child" save="False" visible="False" default="False">
+          <spec>glade_standard_boolean_spec</spec>
+        </property>
 
-	<property id="glade-type" _name="Edit Type" save="False" weight="0">
-	  <spec>glade_gtk_button_type_spec</spec>
-  	  <displayable-values>
-	    <value id="GLADEGTK_BUTTON_LABEL" _name="Label"/>
-	    <value id="GLADEGTK_BUTTON_STOCK" _name="Stock"/>
-	    <value id="GLADEGTK_BUTTON_CONTAINER" _name="Container"/>
-	  </displayable-values>
-	</property>
+	<property id="image-position" weight="1.7" custom-layout="True"/>
 
 	<property id="response-id" _name="Response ID" default="0" common="False" ignore="True" save-always="True">
 	  <spec>glade_standard_int_spec</spec>



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