diff options
author | Tristan Van Berkom <tvb@src.gnome.org> | 2008-04-01 04:19:12 +0000 |
---|---|---|
committer | Tristan Van Berkom <tvb@src.gnome.org> | 2008-04-01 04:19:12 +0000 |
commit | c9f234fa07ea3c2616aa147844710da321e5ef6d (patch) | |
tree | 49e9385931bcdb09cc9b63465a5b66a4778a5260 | |
parent | f87c7d8a2fc8ff90620a33a80a42c0dd01e6b5bc (diff) | |
download | glade-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-- | ChangeLog | 8 | ||||
-rw-r--r-- | gladeui/glade-project.c | 143 | ||||
-rw-r--r-- | gladeui/glade-widget-adaptor.c | 48 | ||||
-rw-r--r-- | gladeui/glade-widget-adaptor.h | 27 | ||||
-rw-r--r-- | gladeui/glade-widget.c | 148 | ||||
-rw-r--r-- | gladeui/glade-widget.h | 8 | ||||
-rw-r--r-- | gladeui/glade-xml-utils.h | 1 |
7 files changed, 327 insertions, 56 deletions
@@ -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" |