static void gog_object_write_property_sax (GogObject const *obj, GParamSpec *pspec, GsfXMLOut *output) { GObject *val_obj; GType prop_type = G_PARAM_SPEC_VALUE_TYPE (pspec); GValue value = { 0 }; g_value_init (&value, prop_type); g_object_get_property (G_OBJECT (obj), pspec->name, &value); /* No need to save default values */ if (((pspec->flags & GOG_PARAM_POSITION) && gog_object_is_default_position_flags (obj, pspec->name)) || (!(pspec->flags & GOG_PARAM_FORCE_SAVE) && !(pspec->flags & GOG_PARAM_POSITION) && g_param_value_defaults (pspec, &value))) { g_value_unset (&value); return; } switch (G_TYPE_FUNDAMENTAL (prop_type)) { case G_TYPE_CHAR: case G_TYPE_UCHAR: case G_TYPE_BOOLEAN: case G_TYPE_INT: case G_TYPE_UINT: case G_TYPE_LONG: case G_TYPE_ULONG: case G_TYPE_ENUM: case G_TYPE_FLAGS: { GValue str = { 0 }; g_value_init (&str, G_TYPE_STRING); g_value_transform (&value, &str); gsf_xml_out_start_element (output, "property"); gsf_xml_out_add_cstr_unchecked (output, "name", pspec->name); gsf_xml_out_add_cstr (output, NULL, g_value_get_string (&str)); gsf_xml_out_end_element (output); /* </property> */ g_value_unset (&str); break; } case G_TYPE_FLOAT: case G_TYPE_DOUBLE: { GValue vd = { 0 }; GString *str = g_string_new (NULL); g_value_init (&vd, G_TYPE_DOUBLE); g_value_transform (&value, &vd); go_dtoa (str, "!g", g_value_get_double (&vd)); g_value_unset (&vd); gsf_xml_out_start_element (output, "property"); gsf_xml_out_add_cstr_unchecked (output, "name", pspec->name); gsf_xml_out_add_cstr (output, NULL, str->str); gsf_xml_out_end_element (output); /* </property> */ g_string_free (str, TRUE); break; } case G_TYPE_STRING: { char const *str = g_value_get_string (&value); if (str != NULL) { gsf_xml_out_start_element (output, "property"); gsf_xml_out_add_cstr_unchecked (output, "name", pspec->name); gsf_xml_out_add_cstr (output, NULL, str); gsf_xml_out_end_element (output); /* </property> */ } break; } case G_TYPE_OBJECT: val_obj = g_value_get_object (&value); if (val_obj != NULL) { if (GO_IS_PERSIST (val_obj)) { gsf_xml_out_start_element (output, "property"); gsf_xml_out_add_cstr_unchecked (output, "name", pspec->name); go_persist_sax_save (GO_PERSIST (val_obj), output); gsf_xml_out_end_element (output); /* </property> */ } else g_warning ("How are we supposed to persist this ??"); } break; default: g_warning ("I could not persist property \"%s\", since type \"%s\" is unhandled.", g_param_spec_get_name (pspec), g_type_name (G_TYPE_FUNDAMENTAL(prop_type))); } g_value_unset (&value); }
static void sop_sax_style (GsfXMLIn *xin, xmlChar const **attrs) { SheetObject *so = gnm_xml_in_cur_obj (xin); GnmSOPath *sop = GNM_SO_PATH (so); go_persist_prep_sax (GO_PERSIST (sop->style), xin, attrs); }
static void gnm_so_path_write_xml_sax (SheetObject const *so, GsfXMLOut *output, G_GNUC_UNUSED GnmConventions const *convs) { GnmSOPath const *sop = GNM_SO_PATH (so); char *svg; if (sop->text != NULL && *(sop->text) != '\0') { gsf_xml_out_add_cstr (output, "Label", sop->text); if (sop->markup != NULL) { GOFormat *fmt = go_format_new_markup (sop->markup, TRUE); gsf_xml_out_add_cstr (output, "LabelFormat", go_format_as_XL (fmt)); go_format_unref (fmt); } } if (sop->path) { svg = go_path_to_svg (sop->path); gsf_xml_out_add_cstr (output, "Path", svg); g_free (svg); } else if (sop->paths) { unsigned i; for (i = 0; i < sop->paths->len; i++) { gsf_xml_out_start_element (output, "Path"); svg = go_path_to_svg ((GOPath *) g_ptr_array_index (sop->paths, i)); gsf_xml_out_add_cstr (output, "Path", svg); g_free (svg); gsf_xml_out_end_element (output); /* </Path> */ } } gsf_xml_out_start_element (output, "Style"); go_persist_sax_save (GO_PERSIST (sop->style), output); gsf_xml_out_end_element (output); /* </Style> */ }
/* NOTE : every path through this must push something onto obj_stack. */ static void gogo_start (GsfXMLIn *xin, xmlChar const **attrs) { GogXMLReadState *state = (GogXMLReadState *)xin->user_state; xmlChar const *type = NULL, *role = NULL; GogObject *res; unsigned i; for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2) if (0 == strcmp (attrs[i], "type")) type = attrs[i+1]; else if (0 == strcmp (attrs[i], "role")) role = attrs[i+1]; if (NULL != type) { GType t = g_type_from_name (type); if (t == 0) { res = (GogObject *)gog_plot_new_by_name (type); if (NULL == res) res = (GogObject *)gog_trend_line_new_by_name (type); } else if (g_type_is_a (t, GOG_TYPE_OBJECT) && !G_TYPE_IS_ABSTRACT (t)) res = g_object_new (t, NULL); else res = NULL; if (res == NULL) { g_warning ("unknown type '%s'", type); } if (GOG_IS_GRAPH (res)) ((GogGraph *) res)->doc = (GODoc *) g_object_get_data (G_OBJECT (gsf_xml_in_get_input (xin)), "document"); } else res = NULL; if (role != NULL) { if (strcmp (role, GOG_BACKPLANE_OLD_ROLE_NAME) == 0) res = gog_object_add_by_name (state->obj, GOG_BACKPLANE_NEW_ROLE_NAME, res); else res = gog_object_add_by_name (state->obj, role, res); } if (res != NULL) { res->explicitly_typed_role = (type != NULL); if (GO_IS_PERSIST (res)) go_persist_prep_sax (GO_PERSIST (res), xin, attrs); } state->obj_stack = g_slist_prepend (state->obj_stack, state->obj); state->obj = res; }
void gog_object_write_xml_sax (GogObject const *obj, GsfXMLOut *output, gpointer user) { guint n; GParamSpec **props; GSList *ptr; g_return_if_fail (GOG_IS_OBJECT (obj)); gsf_xml_out_start_element (output, "GogObject"); /* Primary details */ if (obj->role != NULL) { if (strcmp (obj->role->id, GOG_BACKPLANE_NEW_ROLE_NAME) == 0) gsf_xml_out_add_cstr (output, "role", GOG_BACKPLANE_OLD_ROLE_NAME); else gsf_xml_out_add_cstr (output, "role", obj->role->id); } if (obj->explicitly_typed_role || obj->role == NULL) gsf_xml_out_add_cstr (output, "type", G_OBJECT_TYPE_NAME (obj)); /* properties */ props = g_object_class_list_properties (G_OBJECT_GET_CLASS (obj), &n); while (n-- > 0) if (props[n]->flags & GO_PARAM_PERSISTENT) gog_object_write_property_sax (obj, props[n], output); g_free (props); if (GO_IS_PERSIST (obj)) /* anything special for this class */ go_persist_sax_save (GO_PERSIST (obj), output); if (GOG_IS_DATASET (obj)) /* convenience to save data */ gog_dataset_sax_save (GOG_DATASET (obj), output, user); /* the children */ for (ptr = obj->children; ptr != NULL ; ptr = ptr->next) gog_object_write_xml_sax (ptr->data, output, user); gsf_xml_out_end_element (output); /* </GogObject> */ }
static void gogo_prop_start (GsfXMLIn *xin, xmlChar const **attrs) { GogXMLReadState *state = (GogXMLReadState *)xin->user_state; xmlChar const *prop_str = NULL, *type_str = NULL; GType prop_type; int i; if (NULL == state->obj) { state->prop_spec = NULL; return; } for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2) if (0 == strcmp (attrs[i], "name")) prop_str = attrs[i+1]; else if (0 == strcmp (attrs[i], "type")) type_str = attrs[i+1]; if (prop_str == NULL) { g_warning ("missing name for property of class `%s'", G_OBJECT_TYPE_NAME (state->obj)); return; } state->prop_spec = g_object_class_find_property ( G_OBJECT_GET_CLASS (state->obj), prop_str); if (state->prop_spec == NULL) { g_warning ("unknown property `%s' for class `%s'", prop_str, G_OBJECT_TYPE_NAME (state->obj)); return; } prop_type = G_PARAM_SPEC_VALUE_TYPE (state->prop_spec); if (G_TYPE_FUNDAMENTAL (prop_type) == G_TYPE_OBJECT) { GType type; GogObject *obj; if (NULL == type_str) { g_warning ("missing type for property `%s' of class `%s'", prop_str, G_OBJECT_TYPE_NAME (state->obj)); return; } type = g_type_from_name (type_str); if (0 == type) { g_warning ("unknown type '%s' for property `%s' of class `%s'", type_str, prop_str, G_OBJECT_TYPE_NAME (state->obj)); return; } else if (!g_type_is_a (type, prop_type) || G_TYPE_IS_ABSTRACT (type)) { g_warning ("invalid type '%s' for property `%s' of class `%s'", type_str, prop_str, G_OBJECT_TYPE_NAME (state->obj)); return; } obj = g_object_new (type, NULL); g_return_if_fail (obj != NULL); state->obj_stack = g_slist_prepend (state->obj_stack, state->obj); state->obj = obj; state->prop_pushed_obj = TRUE; if (GO_IS_PERSIST (obj)) go_persist_prep_sax (GO_PERSIST (obj), xin, attrs); } }