[glade/glade-3-8] Backported feature to make GladeProject remember unknown object classes



commit a6e497dd91bb33cefa2682f70144d8d0a66a26b4
Author: Juan Pablo Ugarte <juanpablougarte gmail com>
Date:   Fri Sep 20 11:08:39 2013 -0300

    Backported feature to make GladeProject remember unknown object classes

 gladeui/Makefile.am         |    7 ++
 gladeui/glade-object-stub.c |  224 +++++++++++++++++++++++++++++++++++++++++++
 gladeui/glade-object-stub.h |   57 +++++++++++
 gladeui/glade-project.c     |  105 +++++++++++++++-----
 gladeui/glade-utils.c       |   15 ++--
 gladeui/glade-widget.c      |   43 +++++----
 gladeui/glade-xml-utils.c   |   13 +++-
 gladeui/glade-xml-utils.h   |    1 +
 8 files changed, 410 insertions(+), 55 deletions(-)
---
diff --git a/gladeui/Makefile.am b/gladeui/Makefile.am
index b4741b2..1e4e5b8 100644
--- a/gladeui/Makefile.am
+++ b/gladeui/Makefile.am
@@ -25,6 +25,7 @@ libgladeui_1_la_SOURCES = \
        glade-placeholder.c \
        glade-custom.c \
        glade-inspector.c \
+       glade-object-stub.c \
        glade-xml-utils.c \
        glade-palette.c \
        glade-design-layout.c \
@@ -117,6 +118,12 @@ libgladeuiinclude_HEADERS = \
        glade-cell-renderer-icon.h
 
 
+noinst_HEADERS = \
+       glade-marshallers.h \
+       glade-design-layout.h \
+       glade-object-stub.h \
+       glade-popup.h \
+       glade-accumulators.h
 
 if PLATFORM_WIN32
 libgladeui_1_la_LDFLAGS += -no-undefined
diff --git a/gladeui/glade-object-stub.c b/gladeui/glade-object-stub.c
new file mode 100644
index 0000000..e15ce32
--- /dev/null
+++ b/gladeui/glade-object-stub.c
@@ -0,0 +1,224 @@
+/*
+ * glade-object-stub.c
+ *
+ * Copyright (C) 2011 Juan Pablo Ugarte
+   *
+ * Author: Juan Pablo Ugarte <juanpablougarte gmail com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+   *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ */
+
+#include <config.h>
+
+#include <glib/gi18n-lib.h>
+#include "glade-object-stub.h"
+#include "glade-project.h"
+
+struct _GladeObjectStubPrivate
+{
+  GtkLabel *label;
+  
+  gchar *type;
+  GladeXmlNode *node;
+};
+
+#define GLADE_OBJECT_STUB_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GLADE_TYPE_OBJECT_STUB, 
GladeObjectStubPrivate))
+
+enum
+{
+  PROP_0,
+
+  PROP_OBJECT_TYPE,
+  PROP_XML_NODE
+};
+
+
+G_DEFINE_TYPE (GladeObjectStub, glade_object_stub, GTK_TYPE_INFO_BAR);
+
+#define RESPONSE_DELETE 1
+#define RESPONSE_DELETE_ALL 2
+
+static void
+on_infobar_response (GladeObjectStub *stub, gint response_id)
+{
+  GladeWidget *gwidget = glade_widget_get_from_gobject (stub);
+  
+  if (response_id == RESPONSE_DELETE)
+    {
+      GList widgets = {0, };
+      widgets.data = gwidget;
+      glade_command_delete (&widgets);
+    }
+  else if (response_id == RESPONSE_DELETE_ALL)
+    {
+      GladeProject *project = glade_widget_get_project (gwidget);
+      GList *stubs = NULL;
+      const GList *l;
+
+      for (l = glade_project_get_objects (project); l; l = g_list_next (l))
+        {
+          if (GLADE_IS_OBJECT_STUB (l->data))
+            {
+              GladeWidget *gobj = glade_widget_get_from_gobject (l->data);
+              stubs = g_list_prepend (stubs, gobj);
+            }
+        }
+
+      glade_command_delete (stubs);
+      g_list_free (stubs);
+    }
+}
+
+static void
+glade_object_stub_init (GladeObjectStub *object)
+{
+  GladeObjectStubPrivate *priv = GLADE_OBJECT_STUB_PRIVATE (object);
+  GtkWidget *label = gtk_label_new (NULL);
+
+  object->priv = priv;
+  priv->type = NULL;
+  priv->node = NULL;
+  
+  priv->label = GTK_LABEL (label);
+  gtk_label_set_line_wrap (priv->label, TRUE);
+  
+  gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (object))), label);
+
+  gtk_info_bar_add_button (GTK_INFO_BAR (object),
+                           _("Delete"), RESPONSE_DELETE);
+  gtk_info_bar_add_button (GTK_INFO_BAR (object),
+                           _("Delete All"), RESPONSE_DELETE_ALL);
+  
+  g_signal_connect (object, "response", G_CALLBACK (on_infobar_response), NULL);
+}
+
+static void
+glade_object_stub_finalize (GObject *object)
+{
+  GladeObjectStubPrivate *priv = GLADE_OBJECT_STUB (object)->priv;
+
+  g_free (priv->type);
+  
+  if (priv->node) glade_xml_node_delete (priv->node);
+
+  G_OBJECT_CLASS (glade_object_stub_parent_class)->finalize (object);
+}
+
+static void
+glade_object_stub_refresh_text (GladeObjectStub *stub)
+{
+  GladeObjectStubPrivate *priv = stub->priv;
+  gchar *markup;
+
+  if (priv->type == NULL) return;
+
+  markup = g_markup_printf_escaped ("<b>FIXME:</b> Unable to create object with type %s", priv->type);
+
+  gtk_label_set_markup (priv->label, markup);
+  gtk_info_bar_set_message_type (GTK_INFO_BAR (stub), GTK_MESSAGE_WARNING);
+  g_free (markup);
+}
+
+static void
+glade_object_stub_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+  GladeObjectStubPrivate *priv;
+  GladeObjectStub *stub;
+  
+  g_return_if_fail (GLADE_IS_OBJECT_STUB (object));
+
+  stub = GLADE_OBJECT_STUB (object);
+  priv = stub->priv;
+  
+  switch (prop_id)
+    {
+      case PROP_OBJECT_TYPE:
+        g_free (priv->type);
+        priv->type = g_value_dup_string (value);
+        glade_object_stub_refresh_text (stub);
+        break;
+      case PROP_XML_NODE:
+        if (priv->node) glade_xml_node_delete (priv->node);
+        priv->node = g_value_dup_boxed (value);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+glade_object_stub_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+  GladeObjectStubPrivate *priv;
+  
+  g_return_if_fail (GLADE_IS_OBJECT_STUB (object));
+
+  priv = GLADE_OBJECT_STUB (object)->priv;
+  
+  switch (prop_id)
+    {
+      case PROP_OBJECT_TYPE:
+        g_value_set_string (value, priv->type);
+        break;
+      case PROP_XML_NODE:
+        g_value_set_boxed (value, priv->node);
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static GType
+glade_xml_node_get_type (void)
+{
+  static GType type = 0;
+
+  if (type) return type;
+
+  type = g_boxed_type_register_static ("GladeXmlNode",
+                                       (GBoxedCopyFunc) glade_xml_node_copy,
+                                       (GBoxedFreeFunc) glade_xml_node_delete);
+  return type;
+}
+
+static void
+glade_object_stub_class_init (GladeObjectStubClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (GladeObjectStubPrivate));
+
+  object_class->finalize = glade_object_stub_finalize;
+  object_class->set_property = glade_object_stub_set_property;
+  object_class->get_property = glade_object_stub_get_property;
+
+  g_object_class_install_property (object_class,
+                                   PROP_OBJECT_TYPE,
+                                   g_param_spec_string ("object-type",
+                                                        "Object Type",
+                                                        "The object type this stub replaces",
+                                                        NULL,
+                                                        G_PARAM_READWRITE));
+  g_object_class_install_property (object_class,
+                                   PROP_XML_NODE,
+                                   g_param_spec_boxed ("xml-node",
+                                                       "XML node",
+                                                       "The XML representation of the original object this 
is replacing",
+                                                       glade_xml_node_get_type (),
+                                                       G_PARAM_READWRITE));
+}
diff --git a/gladeui/glade-object-stub.h b/gladeui/glade-object-stub.h
new file mode 100644
index 0000000..42369b4
--- /dev/null
+++ b/gladeui/glade-object-stub.h
@@ -0,0 +1,57 @@
+/*
+ * glade-object-stub.h
+ *
+ * Copyright (C) 2011 Juan Pablo Ugarte
+ *
+ * Author: Juan Pablo Ugarte <juanpablougarte gmail com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ */
+
+#ifndef _GLADE_OBJECT_STUB_H_
+#define _GLADE_OBJECT_STUB_H_
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GLADE_TYPE_OBJECT_STUB             (glade_object_stub_get_type ())
+#define GLADE_OBJECT_STUB(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_OBJECT_STUB, 
GladeObjectStub))
+#define GLADE_OBJECT_STUB_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_OBJECT_STUB, 
GladeObjectStubClass))
+#define GLADE_IS_OBJECT_STUB(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_OBJECT_STUB))
+#define GLADE_IS_OBJECT_STUB_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_OBJECT_STUB))
+#define GLADE_OBJECT_STUB_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_TYPE_OBJECT_STUB, 
GladeObjectStubClass))
+
+typedef struct _GladeObjectStubClass GladeObjectStubClass;
+typedef struct _GladeObjectStub GladeObjectStub;
+typedef struct _GladeObjectStubPrivate GladeObjectStubPrivate;
+
+struct _GladeObjectStubClass
+{
+  GtkInfoBarClass parent_class;
+};
+
+struct _GladeObjectStub
+{
+  GtkInfoBar parent_instance;
+  GladeObjectStubPrivate *priv;
+};
+
+GType glade_object_stub_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* _GLADE_OBJECT_STUB_H_ */
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index 4ac349a..850e7bf 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -49,7 +49,7 @@
 #include "glade-project.h"
 #include "glade-command.h"
 #include "glade-name-context.h"
-
+#include "glade-object-stub.h"
 
 #define VALID_ITER(project, iter) ((iter)!= NULL && G_IS_OBJECT ((iter)->user_data) && 
((GladeProject*)(project))->priv->stamp == (iter)->stamp)
 
@@ -142,6 +142,8 @@ struct _GladeProjectPrivate
                               * (full or relative path, null means project directory).
                               */
        
+       GList *unknown_catalogs; /* List of CatalogInfo catalogs */
+
        /* Control on the preferences dialog to update buttons etc when properties change */
        GtkWidget *prefs_dialog;
        GtkWidget *glade_radio;
@@ -162,6 +164,12 @@ struct _GladeProjectPrivate
        gboolean   load_cancel;
 };
 
+typedef struct 
+{
+  gchar *catalog;
+  gint position;
+} CatalogInfo;
+
 typedef struct {
        GladeWidget      *toplevel;
        GladeNameContext *names;
@@ -355,6 +363,21 @@ glade_project_finalize (GObject *object)
        }
        g_list_free (project->priv->toplevels);
 
+       if (project->priv->unknown_catalogs)
+       {
+               GList *l;
+
+               for (l = project->priv->unknown_catalogs; l; l = g_list_next (l))
+               {
+                       CatalogInfo *data = l->data;
+                       g_free (data->catalog);
+                       g_free (data);
+               }
+
+               g_list_free (project->priv->unknown_catalogs);
+               project->priv->unknown_catalogs = NULL;
+       }
+
        G_OBJECT_CLASS (glade_project_parent_class)->finalize (object);
 }
 
@@ -631,6 +654,7 @@ glade_project_init (GladeProject *project)
        priv->prev_redo_item = NULL;
        priv->first_modification = NULL;
        priv->first_modification_is_na = FALSE;
+       priv->unknown_catalogs = NULL;
 
        priv->toplevel_names = glade_name_context_new ();
        priv->naming_policy = GLADE_POLICY_PROJECT_WIDE;
@@ -1036,6 +1060,7 @@ glade_project_read_requires (GladeProject *project,
        gchar        *required_lib = NULL;
        gboolean      loadable = TRUE;
        guint16       major, minor;
+       gint          position = 0;
 
        for (node = glade_xml_node_get_children_with_comments (root_node); 
             node; node = glade_xml_node_next_with_comments (node))
@@ -1062,6 +1087,17 @@ glade_project_read_requires (GladeProject *project,
                 */
                if (!glade_catalog_is_loaded (required_lib))
                {
+                       CatalogInfo *data = g_new0(CatalogInfo, 1);
+
+                       data->catalog = required_lib;
+                       data->position = position;
+
+                       /* Keep a list of unknown catalogs to avoid loosing the requirement */
+                       project->priv->unknown_catalogs = g_list_append (project->priv->unknown_catalogs,
+                                                           data);
+                       /* Also keep the version */
+                       glade_project_set_target_version (project, required_lib, major, minor);
+
                        if (!loadable)
                                g_string_append (string, ", ");
 
@@ -1075,9 +1111,10 @@ glade_project_read_requires (GladeProject *project,
 
                        glade_project_set_target_version
                                (project, required_lib, major, minor);
+                       g_free (required_lib);
                }
-               
-               g_free (required_lib);
+
+               position++;
        }
 
        if (!loadable)
@@ -1468,12 +1505,7 @@ glade_project_load_internal (GladeProject *project)
        /* XXX Need to load project->priv->comment ! */
        glade_project_read_comment (project, doc);
 
-       if (glade_project_read_requires (project, root, project->priv->path, &has_gtk_dep) == FALSE)
-       {
-               project->priv->loading = FALSE;
-               glade_xml_context_free (context);
-               return FALSE;
-       }
+       glade_project_read_requires (project, root, project->priv->path, &has_gtk_dep);
 
        glade_project_read_naming_policy (project, root);
 
@@ -2270,25 +2302,37 @@ static gboolean
 glade_project_verify (GladeProject *project, 
                      gboolean      saving)
 {
-       GString     *string = g_string_new (NULL);
-       GladeWidget *widget;
-       GList       *list;
-       gboolean     ret = TRUE;
-       gchar       *path_name;
-
-       for (list = project->priv->objects; list; list = list->next)
-       {
-               widget = glade_widget_get_from_gobject (list->data);
-
-               path_name = glade_widget_generate_path_name (widget);
+  GString *string = g_string_new (NULL);
+  GList *list;
+  gboolean ret = TRUE;
+  
+  for (list = project->priv->objects; list; list = list->next)
+    {
+      GladeWidget *widget = glade_widget_get_from_gobject (list->data);
+      
+      if (GLADE_IS_OBJECT_STUB (list->data))
+        {
+          gchar *type;
+          g_object_get (list->data, "object-type", &type, NULL);
+          
+          /* translators: reffers to an unknow object named '%s' of type '%s' */
+          g_string_append_printf (string, _("Unknow object %s with type %s\n"), 
+                                  glade_widget_get_name (widget), type);
+          g_free (type);
+        }
+      else
+        {
+          gchar *path_name = glade_widget_generate_path_name (widget);
 
-               glade_project_verify_adaptor (project, widget->adaptor, 
-                                             path_name, string, saving, FALSE, NULL);
-               glade_project_verify_properties_internal (widget, path_name, string, FALSE);
-               glade_project_verify_signals (widget, path_name, string, FALSE);
+          glade_project_verify_adaptor (project, glade_widget_get_adaptor (widget),
+                                        path_name, string, saving, FALSE, NULL);
+          glade_project_verify_properties_internal (widget, path_name, string,
+                                                    FALSE);
+          glade_project_verify_signals (widget, path_name, string, FALSE);
 
-               g_free (path_name);
-       }
+          g_free (path_name);
+        }
+    }
 
        if (string->len > 0)
        {
@@ -3498,7 +3542,14 @@ glade_project_required_libs (GladeProject *project)
        if (!required)
                required = g_list_prepend (required, g_strdup ("gtk+"));
 
-       return g_list_reverse (required);
+       for (l = project->priv->unknown_catalogs; l; l = g_list_next (l))
+       {
+               CatalogInfo *data = l->data;
+               /* Keep position to make sure we do not create a diff when saving */
+               required = g_list_insert (required, g_strdup (data->catalog), data->position);
+       }
+
+       return required;
 }
 
 /**
diff --git a/gladeui/glade-utils.c b/gladeui/glade-utils.c
index 0032465..ae52501 100644
--- a/gladeui/glade-utils.c
+++ b/gladeui/glade-utils.c
@@ -250,16 +250,17 @@ glade_util_ui_message (GtkWidget           *parent,
 
        dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
                                         GTK_DIALOG_DESTROY_WITH_PARENT,
-                                        message_type,
-                                        buttons_type,
-                                        "%s",
-                                        string);
+                                        message_type, buttons_type, NULL);
 
-       gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+       gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), string);
 
        if (widget)
-               gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
-                                 widget, TRUE, TRUE, 2);
+       {
+               gtk_box_pack_end (GTK_BOX
+                                                (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
+                                                widget, TRUE, TRUE, 2);
+               gtk_widget_show (widget);
+       }
 
        response = gtk_dialog_run (GTK_DIALOG (dialog));
 
diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c
index 7ca924c..d8045be 100644
--- a/gladeui/glade-widget.c
+++ b/gladeui/glade-widget.c
@@ -56,8 +56,7 @@
 #include "glade-app.h"
 #include "glade-design-view.h"
 #include "glade-widget-action.h"
-
-
+#include "glade-object-stub.h"
 
 static void         glade_widget_set_adaptor           (GladeWidget           *widget,
                                                        GladeWidgetAdaptor    *adaptor);
@@ -3876,26 +3875,22 @@ glade_widget_read (GladeProject *project,
                                                                  widget,
                                                                  node);
                        }
-                       else if (adaptor)
+                       else
                        {
-                               if (G_TYPE_IS_ABSTRACT (adaptor->type))
-                                       glade_util_ui_message (glade_app_get_window (),
-                                                      GLADE_UI_WARN, NULL,
-                                                      "Unable to load widget %s with abstract class %s",
-                                                      id, klass);
-                               else
-                                       glade_util_ui_message (glade_app_get_window (),
-                                                      GLADE_UI_WARN, NULL,
-                                                      "Unable to load widget %s of class %s",
-                                                      id, klass);
-                                       
+                               GObject *stub = g_object_new (GLADE_TYPE_OBJECT_STUB,
+                                                             "object-type", klass,
+                                                             "xml-node", node,
+                                                             NULL);
+
+                               widget = glade_widget_adaptor_create_widget (glade_widget_adaptor_get_by_type 
(GTK_TYPE_HBOX),
+                                                                            FALSE,
+                                                                            "parent", parent,
+                                                                            "project", project,
+                                                                            "reason", GLADE_CREATE_LOAD,
+                                                                            "object", stub,
+                                                                            "name", id,
+                                                                            NULL);
                        }
-                       else
-                               glade_util_ui_message (glade_app_get_window (),
-                                                      GLADE_UI_WARN, NULL,
-                                                      "Unable to load widget %s of unknown class %s",
-                                                      id, klass);
-
                        g_free (id);
                }
                g_free (klass);
@@ -4034,6 +4029,14 @@ glade_widget_write (GladeWidget     *widget,
        GList *l, *list;
        GladeProjectFormat fmt = glade_project_get_format (widget->project);
 
+       /* Check if its an unknown object, and use saved xml if so */
+       if (GLADE_IS_OBJECT_STUB (widget->object))
+       {
+               g_object_get (widget->object, "xml-node", &widget_node, NULL);
+               glade_xml_node_append_child (node, widget_node);
+               return;
+       }
+
        widget_node = glade_xml_node_new (context, GLADE_XML_TAG_WIDGET (fmt));
        glade_xml_node_append_child (node, widget_node);
 
diff --git a/gladeui/glade-xml-utils.c b/gladeui/glade-xml-utils.c
index 8958fe8..a6642e2 100644
--- a/gladeui/glade-xml-utils.c
+++ b/gladeui/glade-xml-utils.c
@@ -751,7 +751,18 @@ glade_xml_node_new_comment (GladeXmlContext *context, const gchar *comment)
        return (GladeXmlNode *) xmlNewDocComment ((xmlDocPtr) context->doc, BAD_CAST(comment));
 }
 
-                                          
+GladeXmlNode *
+glade_xml_node_copy (GladeXmlNode *node)
+{
+  if (node)
+    {
+      xmlNodePtr xnode = (xmlNodePtr) node;
+      return (GladeXmlNode *) xmlDocCopyNode (xnode, NULL, 1);
+    }
+  else
+    return NULL;
+}
+
 void
 glade_xml_node_delete (GladeXmlNode *node)
 {
diff --git a/gladeui/glade-xml-utils.h b/gladeui/glade-xml-utils.h
index 9fda0c8..d52a8e0 100644
--- a/gladeui/glade-xml-utils.h
+++ b/gladeui/glade-xml-utils.h
@@ -251,6 +251,7 @@ void glade_xml_node_set_property_boolean (GladeXmlNode *node_in, const gchar *na
 /* Node operations */
 GladeXmlNode * glade_xml_node_new (GladeXmlContext *context, const gchar *name);
 GladeXmlNode * glade_xml_node_new_comment (GladeXmlContext *context, const gchar *comment);
+GladeXmlNode * glade_xml_node_copy (GladeXmlNode *node);
 void           glade_xml_node_delete (GladeXmlNode *node);
 GladeXmlNode * glade_xml_node_get_children (GladeXmlNode *node);
 GladeXmlNode * glade_xml_node_get_parent (GladeXmlNode *node_in);


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