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 char const * xlsx_write_pivot_cache_definition (XLSXWriteState *state, GsfOutfile *wb_part, GODataCache const *cache, unsigned int cache_def_num) { GsfXMLOut *xml; int i, n; char const *record_id; char *name = g_strdup_printf ("pivotCacheDefinition%u.xml", cache_def_num); GsfOutput *cache_def_part = gsf_outfile_new_child_full (state->pivotCache.dir, name, FALSE, "content-type", "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml", NULL); char const *cache_def_id = gsf_outfile_open_pkg_relate (GSF_OUTFILE_OPEN_PKG (cache_def_part), GSF_OUTFILE_OPEN_PKG (wb_part), "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition"); record_id = xlsx_write_pivot_cache_records (state, cache, cache_def_part, cache_def_num); xml = gsf_xml_out_new (cache_def_part); gsf_xml_out_start_element (xml, "pivotCacheDefinition"); gsf_xml_out_add_cstr_unchecked (xml, "xmlns", ns_ss); gsf_xml_out_add_cstr_unchecked (xml, "xmlns:r", ns_rel); gsf_xml_out_add_cstr (xml, "r:id", record_id); if (cache->refreshed_by) gsf_xml_out_add_cstr (xml, "refreshedBy", cache->refreshed_by); if (cache->refreshed_on) { if (state->version == ECMA_376_2006) gsf_xml_out_add_float (xml, "refreshedDate", go_val_as_float (cache->refreshed_on), -1); else { GOFormat const *format = go_format_new_from_XL ("yyyy-mm-dd\"T\"hh:mm:ss"); gchar *date = format_value (format, cache->refreshed_on, NULL, -1, NULL); gsf_xml_out_add_cstr_unchecked (xml, "refreshedDateIso", date); g_free (date); go_format_unref (format); } } gsf_xml_out_add_int (xml, "createdVersion", cache->XL_created_ver); gsf_xml_out_add_int (xml, "refreshedVersion", cache->XL_refresh_ver); gsf_xml_out_add_uint (xml, "recordCount", go_data_cache_num_items (cache)); xlsx_add_bool (xml, "upgradeOnRefresh", cache->refresh_upgrades); xlsx_write_pivot_cache_source (state, xml, cache); gsf_xml_out_start_element (xml, "cacheFields"); n = go_data_cache_num_fields (cache); gsf_xml_out_add_uint (xml, "count", n); for (i = 0 ; i < n ; i++) xlsx_write_pivot_cache_field (state, xml, go_data_cache_get_field (cache, i)); gsf_xml_out_end_element (xml); /* </cacheFields> */ gsf_xml_out_end_element (xml); /* </pivotCacheDefinition> */ g_object_unref (xml); gsf_output_close (cache_def_part); g_object_unref (cache_def_part); g_free (name); return cache_def_id; }
static char const * xlsx_write_pivot_cache_records (XLSXWriteState *state, GODataCache const *cache, GsfOutput *cache_def_part, unsigned int cache_records_num) { unsigned int i, j; GsfXMLOut *xml; char *name = g_strdup_printf ("pivotCacheRecords%u.xml", cache_records_num); GsfOutput *record_part = gsf_outfile_new_child_full (state->pivotCache.dir, name, FALSE, "content-type", "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml", NULL); char const *record_id = gsf_outfile_open_pkg_relate (GSF_OUTFILE_OPEN_PKG (record_part), GSF_OUTFILE_OPEN_PKG (cache_def_part), "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords"); xml = gsf_xml_out_new (record_part); gsf_xml_out_start_element (xml, "pivotCacheRecords"); gsf_xml_out_add_cstr_unchecked (xml, "xmlns", ns_ss); gsf_xml_out_add_cstr_unchecked (xml, "xmlns:r", ns_rel); gsf_xml_out_add_int (xml, "count", go_data_cache_num_items (cache)); for (j = 0 ; j < go_data_cache_num_items (cache); j++) { gsf_xml_out_start_element (xml, "r"); for (i = 0 ; i < go_data_cache_num_fields (cache); i++) { GODataCacheField *field = go_data_cache_get_field (cache, i); switch (go_data_cache_field_ref_type (field)) { case GO_DATA_CACHE_FIELD_TYPE_INDEXED_I8 : case GO_DATA_CACHE_FIELD_TYPE_INDEXED_I16 : /* fallthrough */ case GO_DATA_CACHE_FIELD_TYPE_INDEXED_I32 : /* fallthrough */ gsf_xml_out_start_element (xml, "x"); gsf_xml_out_add_int (xml, "v", go_data_cache_get_index (cache, field, j)); gsf_xml_out_end_element (xml); break; case GO_DATA_CACHE_FIELD_TYPE_INLINE : xlsx_write_pivot_val (state, xml, go_data_cache_field_get_val (field, j)); break; case GO_DATA_CACHE_FIELD_TYPE_NONE : continue; } } gsf_xml_out_end_element (xml); /* </r> */ } gsf_xml_out_end_element (xml); /* </pivotCacheRecords> */ g_object_unref (xml); gsf_output_close (record_part); g_object_unref (record_part); g_free (name); return record_id; }
static void xlsx_write_pivot_cache_source (XLSXWriteState *state, GsfXMLOut *xml, GODataCache const *cache) { GODataCacheSource const *src = go_data_cache_get_source (cache); if (NULL == src) return; if (IS_GNM_DATA_CACHE_SOURCE (src)) { GnmDataCacheSource const *ssrc = GNM_DATA_CACHE_SOURCE (src); Sheet const *src_sheet = gnm_data_cache_source_get_sheet (ssrc); GnmRange const *r = gnm_data_cache_source_get_range (ssrc); char const *name = gnm_data_cache_source_get_name (ssrc); gsf_xml_out_start_element (xml, "cacheSource"); gsf_xml_out_add_cstr_unchecked (xml, "type", "worksheet"); gsf_xml_out_start_element (xml, "worksheetSource"); if (NULL != r) xlsx_add_range (xml, "ref", r); if (NULL != src_sheet) gsf_xml_out_add_cstr (xml, "sheet", src_sheet->name_unquoted); if (NULL != name) gsf_xml_out_add_cstr (xml, "name", name); /* "id" == sheetId : do we need this ? */ gsf_xml_out_end_element (xml); /* </worksheetSource> */ gsf_xml_out_end_element (xml); /* </cacheSource> */ } else { g_warning ("UNSUPPORTED GODataCacheSource of type %s", G_OBJECT_TYPE_NAME(src)); } }
static void xlsx_write_pivot_cache_field (XLSXWriteState *state, GsfXMLOut *xml, GODataCacheField const *field) { GOValArray const *vals; gsf_xml_out_start_element (xml, "cacheField"); gsf_xml_out_add_cstr (xml, "name", go_data_cache_field_get_name (field)->str); gsf_xml_out_add_int (xml, "numFmtId", 0); /* TODO */ if (NULL != (vals = go_data_cache_field_get_vals (field, FALSE))) xlsx_write_pivot_val_array (state, xml, vals, "sharedItems"); if (NULL != (vals = go_data_cache_field_get_vals (field, TRUE))) { int parent_group; GOValBucketer *bucketer = NULL; const char *group_by = NULL; g_object_get (G_OBJECT (field), "group-parent", &parent_group, "bucketer", &bucketer, NULL); gsf_xml_out_start_element (xml, "fieldGroup"); if (parent_group >= 0) gsf_xml_out_add_int (xml, "base", parent_group); gsf_xml_out_start_element (xml, "rangePr"); switch (bucketer->type) { case GO_VAL_BUCKET_SECOND : group_by = "seconds"; break; case GO_VAL_BUCKET_MINUTE : group_by = "minutes"; break; case GO_VAL_BUCKET_HOUR : group_by = "hours"; break; case GO_VAL_BUCKET_DAY_OF_YEAR : group_by = "days"; break; case GO_VAL_BUCKET_MONTH : group_by = "months"; break; case GO_VAL_BUCKET_CALENDAR_QUARTER : group_by = "quarters"; break; case GO_VAL_BUCKET_YEAR : group_by = "years"; break; default: /* default to linear */; case GO_VAL_BUCKET_SERIES_LINEAR :break; } if (group_by) gsf_xml_out_add_cstr_unchecked (xml, "groupBy", group_by); if (bucketer->type == GO_VAL_BUCKET_SERIES_LINEAR) { gsf_xml_out_add_float (xml, "startNum", bucketer->details.series.minimum, -1); gsf_xml_out_add_float (xml, "endNum", bucketer->details.series.maximum, -1); gsf_xml_out_add_float (xml, "groupInterval", bucketer->details.series.step, -1); } else { xlsx_write_date (state, xml, "startDate", bucketer->details.dates.minimum); xlsx_write_date (state, xml, "endDate", bucketer->details.dates.maximum); } gsf_xml_out_end_element (xml); /* </rangePr> */ xlsx_write_pivot_val_array (state, xml, vals, "groupItems"); gsf_xml_out_end_element (xml); /* </fieldGroup> */ } gsf_xml_out_end_element (xml); /* </cacheField> */ }
static void xlsx_write_date (XLSXWriteState *state, GsfXMLOut *xml, char const *id, gnm_float v) { GOVal *tmp = go_val_new_float (v); char *d = format_value (state->date_fmt, tmp, NULL, -1, workbook_date_conv (state->base.wb)); gsf_xml_out_add_cstr_unchecked (xml, id, d); g_free (d); go_val_free (tmp); }
/* * * DO * NOT * COMPILE * DIRECTLY * * DO * NOT * COMPILE * DIRECTLY * * DO * NOT * COMPILE * DIRECTLY * * * included via xlsx-write.c **/ static void xlsx_write_pivot_val (XLSXWriteState *state, GsfXMLOut *xml, GOVal const *v) { switch (v->type) { case VALUE_CELLRANGE: case VALUE_ARRAY: g_warning ("REMOVE THIS CODE WHEN WE MOVE TO GOFFICE"); break; case VALUE_EMPTY: gsf_xml_out_simple_element (xml, "m", NULL); break; case VALUE_BOOLEAN: gsf_xml_out_start_element (xml, "b"); xlsx_add_bool (xml, "v", v->v_bool.val); gsf_xml_out_end_element (xml); break; case VALUE_FLOAT: { GOFormat const *fmt = go_val_get_fmt (v); if (NULL != fmt && go_format_is_date (fmt)) { char *d = format_value (state->date_fmt, v, NULL, -1, workbook_date_conv (state->base.wb)); gsf_xml_out_start_element (xml, "d"); gsf_xml_out_add_cstr_unchecked (xml, "v", d); gsf_xml_out_end_element (xml); } else { gsf_xml_out_start_element (xml, "n"); gsf_xml_out_add_float (xml, "v", v->v_float.val, -1); gsf_xml_out_end_element (xml); } break; } case VALUE_ERROR : gsf_xml_out_start_element (xml, "e"); gsf_xml_out_add_cstr (xml, "v", v->v_err.mesg->str); gsf_xml_out_end_element (xml); break; case VALUE_STRING : gsf_xml_out_start_element (xml, "s"); gsf_xml_out_add_cstr (xml, "v", v->v_str.val->str); gsf_xml_out_end_element (xml); break; } }
static gboolean gsf_outfile_open_pkg_close (GsfOutput *output) { GsfOutfileOpenPkg *open_pkg = GSF_OUTFILE_OPEN_PKG (output); GsfOutput *dir; gboolean res = FALSE; char *rels_name; if (NULL == open_pkg->sink || gsf_output_is_closed (open_pkg->sink)) return TRUE; /* Generate [Content_types].xml when we close the root dir */ if (NULL == gsf_output_name (output)) { GsfOutput *out = gsf_outfile_new_child (GSF_OUTFILE (open_pkg->sink), "[Content_Types].xml", FALSE); GsfXMLOut *xml = gsf_xml_out_new (out); gsf_xml_out_start_element (xml, "Types"); gsf_xml_out_add_cstr_unchecked (xml, "xmlns", "http://schemas.openxmlformats.org/package/2006/content-types"); gsf_open_pkg_write_content_default (xml, "rels", "application/vnd.openxmlformats-package.relationships+xml"); gsf_open_pkg_write_content_default (xml, "xlbin", "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"); gsf_open_pkg_write_content_default (xml, "xml", "application/xml"); gsf_open_pkg_write_content_override (open_pkg, "/", xml); gsf_xml_out_end_element (xml); /* </Types> */ g_object_unref (xml); gsf_output_close (out); g_object_unref (out); dir = open_pkg->sink; rels_name = g_strdup (".rels"); } else { res = gsf_output_close (open_pkg->sink); dir = (GsfOutput *)gsf_output_container (open_pkg->sink); rels_name = g_strconcat (gsf_output_name (output), ".rels", NULL); } if (NULL != open_pkg->relations) { GsfOutput *rels; GsfXMLOut *xml; GsfOpenPkgRel *rel; GSList *ptr; dir = gsf_outfile_new_child (GSF_OUTFILE (dir), "_rels", TRUE); rels = gsf_outfile_new_child (GSF_OUTFILE (dir), rels_name, FALSE); xml = gsf_xml_out_new (rels); gsf_xml_out_start_element (xml, "Relationships"); gsf_xml_out_add_cstr_unchecked (xml, "xmlns", "http://schemas.openxmlformats.org/package/2006/relationships"); for (ptr = open_pkg->relations ; ptr != NULL ; ptr = ptr->next) { rel = ptr->data; gsf_xml_out_start_element (xml, "Relationship"); gsf_xml_out_add_cstr (xml, "Id", rel->id); gsf_xml_out_add_cstr (xml, "Type", rel->type); gsf_xml_out_add_cstr (xml, "Target", rel->target); if (rel->is_extern) gsf_xml_out_add_cstr_unchecked (xml, "TargetMode", "External"); gsf_xml_out_end_element (xml); /* </Relationship> */ g_free (rel->id); g_free (rel->type); g_free (rel->target); g_free (rel); } g_slist_free (open_pkg->relations); gsf_xml_out_end_element (xml); /* </Relationships> */ g_object_unref (xml); gsf_output_close (rels); g_object_unref (rels); g_object_unref (dir); } g_free (rels_name); /* close the container */ if (NULL == gsf_output_name (output)) return gsf_output_close (open_pkg->sink); return res; }
static int test_xml_indent (void) { GsfOutput *mem = gsf_output_memory_new (); GsfXMLOut *xml = gsf_xml_out_new (mem); const char *data; gboolean pprint; int err; const char *expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<outer>\n" " <data/>\n" " <data attr=\"val\"/>\n" " <data>text</data>\n" " <data>\n" " <inner>text</inner>\n" " </data>\n" " <data>text</data>\n" " <data><inner>text</inner></data>\n" "</outer>\n"; gsf_xml_out_start_element (xml, "outer"); gsf_xml_out_start_element (xml, "data"); gsf_xml_out_end_element (xml); gsf_xml_out_start_element (xml, "data"); gsf_xml_out_add_cstr_unchecked (xml, "attr", "val"); gsf_xml_out_end_element (xml); gsf_xml_out_start_element (xml, "data"); gsf_xml_out_add_cstr_unchecked (xml, NULL, "text"); gsf_xml_out_end_element (xml); gsf_xml_out_start_element (xml, "data"); gsf_xml_out_start_element (xml, "inner"); gsf_xml_out_add_cstr_unchecked (xml, NULL, "text"); gsf_xml_out_end_element (xml); gsf_xml_out_end_element (xml); gsf_xml_out_start_element (xml, "data"); pprint = gsf_xml_out_set_pretty_print (xml, FALSE); gsf_xml_out_add_cstr_unchecked (xml, NULL, "text"); gsf_xml_out_set_pretty_print (xml, pprint); gsf_xml_out_end_element (xml); gsf_xml_out_start_element (xml, "data"); pprint = gsf_xml_out_set_pretty_print (xml, FALSE); gsf_xml_out_start_element (xml, "inner"); gsf_xml_out_add_cstr_unchecked (xml, NULL, "text"); gsf_xml_out_end_element (xml); gsf_xml_out_set_pretty_print (xml, pprint); gsf_xml_out_end_element (xml); gsf_xml_out_end_element (xml); g_object_unref (xml); data = (const char *)gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (mem)); g_printerr ("Got\n%s\n", data); err = !g_str_equal (data, expected); if (err) g_printerr ("Expected\n%s\n", expected); g_object_unref (mem); return err; }