summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tvb@src.gnome.org>2008-04-01 04:19:12 +0000
committerTristan Van Berkom <tvb@src.gnome.org>2008-04-01 04:19:12 +0000
commitc9f234fa07ea3c2616aa147844710da321e5ef6d (patch)
tree49e9385931bcdb09cc9b63465a5b66a4778a5260
parentf87c7d8a2fc8ff90620a33a80a42c0dd01e6b5bc (diff)
downloadglade-c9f234fa07ea3c2616aa147844710da321e5ef6d.tar.gz
Implemented loading and building of the widget hierarchy, currently only
* gladeui/glade-widget.[ch], gladeui/glade-widget-adaptor.[ch], various files: Implemented loading and building of the widget hierarchy, currently only types and widget names, no properties or packing properties - but internal children and placeholders are loaded correctly. svn path=/branches/builder/; revision=1754
-rw-r--r--ChangeLog8
-rw-r--r--gladeui/glade-project.c143
-rw-r--r--gladeui/glade-widget-adaptor.c48
-rw-r--r--gladeui/glade-widget-adaptor.h27
-rw-r--r--gladeui/glade-widget.c148
-rw-r--r--gladeui/glade-widget.h8
-rw-r--r--gladeui/glade-xml-utils.h1
7 files changed, 327 insertions, 56 deletions
diff --git a/ChangeLog b/ChangeLog
index 2d90063c..a1f1d874 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-04-01 Tristan Van Berkom <tvb@gnome.org>
+
+ * gladeui/glade-widget.[ch], gladeui/glade-widget-adaptor.[ch],
+ various files: Implemented loading and building of the widget
+ hierarchy, currently only types and widget names, no properties
+ or packing properties - but internal children and placeholders
+ are loaded correctly.
+
2008-03-30 Tristan Van Berkom <tvb@gnome.org>
* gladeui/glade-parser.[ch]
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index aa6e790c..b4f6525c 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -764,9 +764,112 @@ glade_project_new (void)
return g_object_new (GLADE_TYPE_PROJECT, NULL);
}
+
+static void
+glade_project_fix_object_props (GladeProject *project)
+{
+ GList *l, *ll;
+ GValue *value;
+ GladeWidget *gwidget;
+ GladeProperty *property;
+ gchar *txt;
+
+ for (l = project->priv->objects; l; l = l->next)
+ {
+ gwidget = glade_widget_get_from_gobject (l->data);
+
+ for (ll = gwidget->properties; ll; ll = ll->next)
+ {
+ property = GLADE_PROPERTY (ll->data);
+
+ if (glade_property_class_is_object (property->klass) &&
+ (txt = g_object_get_data (G_OBJECT (property),
+ "glade-loaded-object")) != NULL)
+ {
+ /* Parse the object list and set the property to it
+ * (this magicly works for both objects & object lists)
+ */
+ value = glade_property_class_make_gvalue_from_string
+ (property->klass, txt, project);
+
+ glade_property_set_value (property, value);
+
+ g_value_unset (value);
+ g_free (value);
+
+ g_object_set_data (G_OBJECT (property),
+ "glade-loaded-object", NULL);
+ }
+ }
+ }
+}
+
gboolean
glade_project_load_from_file (GladeProject *project, const gchar *path)
{
+ GladeXmlContext *context;
+ GladeXmlDoc *doc;
+ GladeXmlNode *root;
+ GladeXmlNode *node;
+ GladeWidget *widget;
+
+ project->priv->path = glade_util_canonical_path (path);
+
+ project->priv->selection = NULL;
+ project->priv->objects = NULL;
+ project->priv->loading = TRUE;
+
+
+ /* get the context & root node of the catalog file */
+ if (!(context =
+ glade_xml_context_new_from_path (path,
+ NULL,
+ GLADE_XML_TAG_PROJECT)))
+ {
+ g_warning ("Couldn't open glade file [%s].", path);
+ return FALSE;
+ }
+
+ doc = glade_xml_context_get_doc (context);
+ root = glade_xml_doc_get_root (doc);
+
+ if (!glade_xml_node_verify (root, GLADE_XML_TAG_PROJECT))
+ {
+ g_warning ("Glade file root node is not '%s', skipping %s",
+ GLADE_XML_TAG_PROJECT, path);
+ glade_xml_context_free (context);
+ return FALSE;
+ }
+
+ for (node = glade_xml_node_get_children (root);
+ node; node = glade_xml_node_next (node))
+ {
+ if ((widget = glade_widget_read (project, NULL, node, NULL)) != NULL)
+ glade_project_add_object (project, NULL, widget->object);
+ }
+
+ if (glade_util_file_is_writeable (project->priv->path) == FALSE)
+ glade_project_set_readonly (project, TRUE);
+
+
+ project->priv->mtime = glade_util_get_file_mtime (project->priv->path, NULL);
+
+ /* Reset project status here too so that you get a clean
+ * slate after calling glade_project_open().
+ */
+ project->priv->modified = FALSE;
+ project->priv->loading = FALSE;
+
+ /* Emit "parse-finished" signal */
+ g_signal_emit (project, glade_project_signals [PARSE_FINISHED], 0);
+
+ /* Now we have to loop over all the object properties
+ * and fix'em all ('cause they probably weren't found)
+ */
+ glade_project_fix_object_props (project);
+
+ return TRUE;
+
#if LOADING_WAS_IMPLEMENTED
GladeInterface *interface;
@@ -799,7 +902,6 @@ glade_project_load_from_file (GladeProject *project, const gchar *path)
#endif // LOADING_WAS_IMPLEMENTED
- return TRUE;
}
@@ -1615,45 +1717,6 @@ loadable_interface (GladeInterface *interface, const gchar *path)
#endif // LOADING_WAS_IMPLEMENTED
-static void
-glade_project_fix_object_props (GladeProject *project)
-{
- GList *l, *ll;
- GValue *value;
- GladeWidget *gwidget;
- GladeProperty *property;
- gchar *txt;
-
- for (l = project->priv->objects; l; l = l->next)
- {
- gwidget = glade_widget_get_from_gobject (l->data);
-
- for (ll = gwidget->properties; ll; ll = ll->next)
- {
- property = GLADE_PROPERTY (ll->data);
-
- if (glade_property_class_is_object (property->klass) &&
- (txt = g_object_get_data (G_OBJECT (property),
- "glade-loaded-object")) != NULL)
- {
- /* Parse the object list and set the property to it
- * (this magicly works for both objects & object lists)
- */
- value = glade_property_class_make_gvalue_from_string
- (property->klass, txt, project);
-
- glade_property_set_value (property, value);
-
- g_value_unset (value);
- g_free (value);
-
- g_object_set_data (G_OBJECT (property),
- "glade-loaded-object", NULL);
- }
- }
- }
-}
-
#if LOADING_WAS_IMPLEMENTED
static gboolean
diff --git a/gladeui/glade-widget-adaptor.c b/gladeui/glade-widget-adaptor.c
index 85910920..f867c0bd 100644
--- a/gladeui/glade-widget-adaptor.c
+++ b/gladeui/glade-widget-adaptor.c
@@ -758,6 +758,25 @@ glade_widget_adaptor_object_child_action_activate (GladeWidgetAdaptor *adaptor,
adaptor->name, action_id);
}
+static void
+glade_widget_adaptor_object_read_widget (GladeWidgetAdaptor *adaptor,
+ GladeWidget *widget,
+ GladeXmlNode *node)
+{
+ /* XXX Here were looking at a GladeWidget object built with native
+ * defaults
+ */
+
+ /* first all the properties */
+ g_print ("reading widget '%s' of class '%s'\n",
+ widget->name, adaptor->name);
+
+
+
+ /* then all the signals */
+
+}
+
/*******************************************************************************
GladeWidgetAdaptor type registration and class initializer
*******************************************************************************/
@@ -797,6 +816,7 @@ glade_widget_adaptor_class_init (GladeWidgetAdaptorClass *adaptor_class)
adaptor_class->child_get_property = NULL;
adaptor_class->action_activate = glade_widget_adaptor_object_action_activate;
adaptor_class->child_action_activate= glade_widget_adaptor_object_child_action_activate;
+ adaptor_class->read_widget = glade_widget_adaptor_object_read_widget;
/* Base defaults here */
adaptor_class->fixed = FALSE;
@@ -1037,6 +1057,11 @@ gwa_extend_with_node_load_sym (GladeWidgetAdaptorClass *klass,
GLADE_TAG_CHILD_ACTION_ACTIVATE_FUNCTION,
&symbol))
klass->child_action_activate = symbol;
+
+ if (glade_xml_load_sym_from_node (node, module,
+ GLADE_TAG_READ_WIDGET_FUNCTION,
+ &symbol))
+ klass->read_widget = symbol;
}
static void
@@ -2785,3 +2810,26 @@ glade_widget_adaptor_child_action_activate (GladeWidgetAdaptor *adaptor,
GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor)->child_action_activate (adaptor, container, object, action_path);
}
+
+
+
+/**
+ * glade_widget_adaptor_read_widget:
+ * @adaptor: A #GladeWidgetAdaptor
+ * @widget: The #GladeWidget
+ * @node: The #GladeXmlNode
+ *
+ * This function is called to update @widget from @node
+ * when loading xml files.
+ */
+void
+glade_widget_adaptor_read_widget (GladeWidgetAdaptor *adaptor,
+ GladeWidget *widget,
+ GladeXmlNode *node)
+{
+ g_return_if_fail (GLADE_IS_WIDGET_ADAPTOR (adaptor));
+ g_return_if_fail (GLADE_IS_WIDGET (widget));
+ g_return_if_fail (node != NULL);
+
+ GLADE_WIDGET_ADAPTOR_GET_CLASS (adaptor)->read_widget (adaptor, widget, node);
+}
diff --git a/gladeui/glade-widget-adaptor.h b/gladeui/glade-widget-adaptor.h
index c1701cec..773a615a 100644
--- a/gladeui/glade-widget-adaptor.h
+++ b/gladeui/glade-widget-adaptor.h
@@ -330,6 +330,25 @@ typedef void (* GladeChildActionActivateFunc) (GladeWidgetAdaptor *adaptor,
GObject *object,
const gchar *action_path);
+
+
+
+
+/**
+ * GladeReadWidgetFunc:
+ * @adaptor: A #GladeWidgetAdaptor
+ * @widget: The #GladeWidget
+ * @node: The #GladeXmlNode
+ *
+ * This function is called to update @widget from @node.
+ *
+ */
+typedef void (* GladeReadWidgetFunc) (GladeWidgetAdaptor *adaptor,
+ GladeWidget *widget,
+ GladeXmlNode *node);
+
+
+
/* GladeSignalClass contains all the info we need for a given signal, such as
* the signal name, and maybe more in the future
*/
@@ -472,6 +491,9 @@ struct _GladeWidgetAdaptorClass
GladeActionActivateFunc action_activate; /* This method is used to catch actions */
GladeChildActionActivateFunc child_action_activate; /* This method is used to catch packing actions */
+
+
+ GladeReadWidgetFunc read_widget; /* Reads widget attributes from xml */
};
#define glade_widget_adaptor_create_widget(adaptor, query, ...) \
@@ -622,6 +644,11 @@ void glade_widget_adaptor_child_action_activate (GladeWidgetAdap
GObject *container,
GObject *object,
const gchar *action_path);
+
+void glade_widget_adaptor_read_widget (GladeWidgetAdaptor *adaptor,
+ GladeWidget *widget,
+ GladeXmlNode *node);
+
G_END_DECLS
#endif /* __GLADE_WIDGET_ADAPTOR_H__ */
diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c
index a90c70a4..32ab829e 100644
--- a/gladeui/glade-widget.c
+++ b/gladeui/glade-widget.c
@@ -3863,36 +3863,158 @@ glade_widget_write_child (GArray *children,
return TRUE;
}
+#endif // LOADING_WAS_IMPLEMENTED
+
+
+
+static void
+glade_widget_read_children (GladeWidget *widget,
+ GladeXmlNode *node)
+{
+ GladeXmlNode *child, *widget_node;
+ GladeWidget *child_widget;
+
+ /*
+ * Deal with children...
+ */
+ for (child = glade_xml_node_get_children (node);
+ child; child = glade_xml_node_next (child))
+ {
+ const gchar *node_name = glade_xml_node_get_name (child);
+ gchar *internal_name;
+
+ if (strcmp (node_name, GLADE_XML_TAG_CHILD) != 0)
+ continue;
+
+ internal_name =
+ glade_xml_get_property_string
+ (child, GLADE_XML_TAG_INTERNAL_CHILD);
+
+ if ((widget_node =
+ glade_xml_search_child
+ (child, GLADE_XML_TAG_WIDGET)) != NULL)
+ {
+ child_widget =
+ glade_widget_read (widget->project,
+ widget,
+ widget_node,
+ internal_name);
+
+ if (child_widget && !internal_name)
+ glade_widget_adaptor_add
+ (widget->adaptor,
+ widget->object,
+ child_widget->object);
+
+
+ } else {
+ GObject *palaceholder =
+ G_OBJECT (glade_placeholder_new ());
+ /*glade_widget_set_child_type_from_child_info */
+ /*(info, parent->adaptor, palaceholder); */
+
+ glade_widget_adaptor_add (widget->adaptor,
+ widget->object,
+ palaceholder);
+
+ }
+ g_free (internal_name);
+ }
+}
+
+
/**
* glade_widget_read:
* @project: a #GladeProject
- * @info: a #GladeWidgetInfo
+ * @parent: The parent #GladeWidget or %NULL
+ * @node: a #GladeXmlNode
*
- * Returns: a new #GladeWidget for @project, based on @info
+ * Returns: a new #GladeWidget for @project, based on @node
*/
GladeWidget *
-glade_widget_read (GladeProject *project, GladeWidgetInfo *info)
+glade_widget_read (GladeProject *project,
+ GladeWidget *parent,
+ GladeXmlNode *node,
+ const gchar *internal)
{
- GladeWidget *widget;
+ GladeWidgetAdaptor *adaptor;
+ GladeWidget *widget = NULL;
+ gchar *klass, *id;
+
glade_widget_push_superuser ();
loading_project = project;
-
- if ((widget = glade_widget_new_from_widget_info
- (info, project, NULL)) != NULL)
+
+ if (!glade_xml_node_verify (node, GLADE_XML_TAG_WIDGET))
+ return NULL;
+
+
+ if ((klass =
+ glade_xml_get_property_string_required
+ (node, GLADE_XML_TAG_CLASS, NULL)) != NULL)
{
-#if 0
- if (glade_verbose)
- glade_widget_debug (widget);
-#endif
- }
+ if ((id =
+ glade_xml_get_property_string_required
+ (node, GLADE_XML_TAG_ID, NULL)) != NULL)
+ {
+ /*
+ * Create GladeWidget instance based on type.
+ */
+ if ((adaptor =
+ glade_widget_adaptor_get_by_name (klass)) != NULL)
+ {
+
+ // Internal children !!!
+ if (internal)
+ {
+ GObject *child_object =
+ glade_widget_get_internal_child
+ (parent, internal);
+
+ if (!child_object)
+ {
+ g_warning ("Failed to locate "
+ "internal child %s of %s",
+ internal,
+ glade_widget_get_name (parent));
+ return FALSE;
+ }
+
+ if (!(widget =
+ glade_widget_get_from_gobject (child_object)))
+ g_error ("Unable to get GladeWidget "
+ "for internal child %s\n",
+ internal);
+
+ /* Apply internal widget name from here */
+ glade_widget_set_name (widget, id);
+ } else {
+ widget = glade_widget_adaptor_create_widget
+ (adaptor, FALSE,
+ "name", id,
+ "parent", parent,
+ "project", project,
+ "reason", GLADE_CREATE_LOAD, NULL);
+ }
+
+ glade_widget_adaptor_read_widget (adaptor,
+ widget,
+ node);
+
+ glade_widget_read_children (widget, node);
+
+ }
+ g_free (id);
+ }
+ g_free (klass);
+ }
loading_project = NULL;
glade_widget_pop_superuser ();
return widget;
}
-#endif // LOADING_WAS_IMPLEMENTED
+
static gint glade_widget_su_stack = 0;
diff --git a/gladeui/glade-widget.h b/gladeui/glade-widget.h
index 213f7906..5f81cb36 100644
--- a/gladeui/glade-widget.h
+++ b/gladeui/glade-widget.h
@@ -139,9 +139,11 @@ void glade_widget_remove_child (GladeWidget *p
/* XXX GladeWidgetInfo *glade_widget_write (GladeWidget *widget, */
/* GladeInterface *interface); */
-/* GladeWidget *glade_widget_read (GladeProject *project, */
-/* GladeWidgetInfo *info); */
-
+GladeWidget *glade_widget_read (GladeProject *project,
+ GladeWidget *parent,
+ GladeXmlNode *node,
+ const gchar *internal);
+
void glade_widget_replace (GladeWidget *parent,
GObject *old_object,
GObject *new_object);
diff --git a/gladeui/glade-xml-utils.h b/gladeui/glade-xml-utils.h
index 49bccd68..638b1ec6 100644
--- a/gladeui/glade-xml-utils.h
+++ b/gladeui/glade-xml-utils.h
@@ -63,6 +63,7 @@ typedef struct _GladeXmlDoc GladeXmlDoc;
#define GLADE_TAG_CONSTRUCTOR_FUNCTION "constructor-function"
#define GLADE_TAG_ACTION_ACTIVATE_FUNCTION "action-activate-function"
#define GLADE_TAG_CHILD_ACTION_ACTIVATE_FUNCTION "child-action-activate-function"
+#define GLADE_TAG_READ_WIDGET_FUNCTION "read-widget-function"
#define GLADE_TAG_PROPERTIES "properties"
#define GLADE_TAG_PACKING_PROPERTIES "packing-properties"
#define GLADE_TAG_PROPERTY "property"