[goffice] Implement some of the GOFormat ODF output
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: svn-commits-list gnome org
- Subject: [goffice] Implement some of the GOFormat ODF output
- Date: Wed, 27 May 2009 09:24:48 -0400 (EDT)
commit 2c918081b8e7c2bc2fa33f63591ce7be71869f2d
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date: Wed May 27 07:23:47 2009 -0600
Implement some of the GOFormat ODF output
2009-05-27 Andreas J. Guelzow <aguelzow pyrshep ca>
* goffice/utils/go-format.c (fill_accumulator): new
(go_format_output_date_to_odf): new
(odf_add_bool): new
(go_format_output_fraction_to_odf): new stub
(go_format_output_scientific_number_to_odf): new stub
(go_format_output_number_to_odf): new stub
(go_format_output_to_odf): implement
---
ChangeLog | 10 ++
goffice/utils/go-format.c | 349 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 358 insertions(+), 1 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a64f123..a8f2561 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2009-05-27 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * goffice/utils/go-format.c (fill_accumulator): new
+ (go_format_output_date_to_odf): new
+ (odf_add_bool): new
+ (go_format_output_fraction_to_odf): new stub
+ (go_format_output_scientific_number_to_odf): new stub
+ (go_format_output_number_to_odf): new stub
+ (go_format_output_to_odf): implement
+
2009-05-27 Jean Bréfort <jean brefort normalesup org>
* goffice/gtk/goffice-gtk.c (go_gtk_builder_new): renamed for more
diff --git a/goffice/utils/go-format.c b/goffice/utils/go-format.c
index 7ad8b10..e3b5e0f 100644
--- a/goffice/utils/go-format.c
+++ b/goffice/utils/go-format.c
@@ -4907,6 +4907,11 @@ go_format_default_accounting (void)
/********************* GOFormat ODF Support ***********************/
+#define STYLE "style:"
+#define FOSTYLE "fo:"
+#define NUMBER "number:"
+
+
#ifdef DEFINE_COMMON
char *
go_format_odf_style_map (GOFormat const **conditional_format, GOFormat const *fmt, int i)
@@ -4950,9 +4955,351 @@ go_format_odf_style_map (GOFormat const **conditional_format, GOFormat const *fm
#endif
#ifdef DEFINE_COMMON
+
+static const guchar *
+fill_accumulator (GString *accum, const guchar *prg)
+{
+ g_string_erase (accum, 0, -1);
+
+ while (1) {
+ switch (*prg) {
+ case OP_CHAR: {
+ const guchar *next;
+ prg++;
+ next = g_utf8_next_char (prg);
+ g_string_append_len (accum, prg, next - prg);
+ prg = next;
+ break;
+ }
+ case OP_STRING: {
+ size_t len;
+ prg++;
+ len = strlen (prg);
+ g_string_append (accum, prg);
+ prg += len + 1;
+ break;
+ }
+ default:
+ return prg;
+ }
+ }
+}
+
+static
+go_format_output_date_to_odf (GsfXMLOut *xout, GOFormat const *fmt, char const *name, gboolean time_only)
+{
+ const guchar *prg = fmt->u.number.program;
+ GString *accum = g_string_new (NULL);
+
+ gsf_xml_out_start_element (xout, time_only ? NUMBER "time_style"
+ : NUMBER "date-style");
+ gsf_xml_out_add_cstr (xout, STYLE "name", name);
+ gsf_xml_out_add_cstr (xout, NUMBER "format-source", "fixed");
+
+ while (1) {
+ GOFormatOp op = *prg++;
+
+ switch (op) {
+ case OP_END:
+ gsf_xml_out_end_element (xout); /* </number:date-style or time-style> */
+ g_string_free (accum, TRUE);
+ return;
+
+ case OP_STRING:
+ case OP_CHAR:
+ prg = fill_accumulator (accum, prg - 1);
+ gsf_xml_out_simple_element (xout, NUMBER "text", accum->str);
+ break;
+
+ case OP_CHAR_INVISIBLE:
+ case OP_FILL:
+ prg = g_utf8_next_char (prg);
+ break;
+
+ case OP_LOCALE: {
+ prg += sizeof (GOFormatLocale);
+ prg += strlen ((const char *)prg) + 1;
+ break;
+ }
+
+ case OP_DATE_ROUND:
+ prg += 2;
+ break;
+
+ case OP_DATE_YEAR:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "year");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "long");
+ gsf_xml_out_add_cstr (xout, NUMBER "calendar", "gregorian");
+ gsf_xml_out_end_element (xout); /* </number:year> */
+ break;
+
+ case OP_DATE_YEAR_2:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "year");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "short");
+ gsf_xml_out_add_cstr (xout, NUMBER "calendar", "gregorian");
+ gsf_xml_out_end_element (xout); /* </number:year> */
+ break;
+
+ case OP_DATE_YEAR_THAI:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "year");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "long");
+ gsf_xml_out_add_cstr (xout, NUMBER "calendar", "buddhist");
+ gsf_xml_out_end_element (xout); /* </number:year> */
+ break;
+
+ case OP_DATE_YEAR_THAI_2:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "year");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "short");
+ gsf_xml_out_add_cstr (xout, NUMBER "calendar", "buddhist");
+ gsf_xml_out_end_element (xout); /* </number:year> */
+ break;
+
+ case OP_DATE_MONTH:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "month");
+ gsf_xml_out_add_cstr (xout, NUMBER "possessive-form", "false");
+ gsf_xml_out_add_cstr (xout, NUMBER "textual", "false");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "short");
+ gsf_xml_out_end_element (xout); /* </number:month> */
+ break;
+
+ case OP_DATE_MONTH_2:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "month");
+ gsf_xml_out_add_cstr (xout, NUMBER "possessive-form", "false");
+ gsf_xml_out_add_cstr (xout, NUMBER "textual", "false");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "long");
+ gsf_xml_out_end_element (xout); /* </number:month> */
+ break;
+
+ case OP_DATE_MONTH_NAME:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "month");
+ gsf_xml_out_add_cstr (xout, NUMBER "possessive-form", "false");
+ gsf_xml_out_add_cstr (xout, NUMBER "textual", "true");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "long");
+ gsf_xml_out_end_element (xout); /* </number:month> */
+ break;
+
+ case OP_DATE_MONTH_NAME_1: /* ODF does not support single letter abbreviation */
+ case OP_DATE_MONTH_NAME_3:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "month");
+ gsf_xml_out_add_cstr (xout, NUMBER "possessive-form", "false");
+ gsf_xml_out_add_cstr (xout, NUMBER "textual", "true");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "short");
+ gsf_xml_out_end_element (xout); /* </number:month> */
+ break;
+
+ case OP_DATE_DAY:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "day");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "short");
+ gsf_xml_out_end_element (xout); /* </number:day> */
+ break;
+
+ case OP_DATE_DAY_2:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "day");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "long");
+ gsf_xml_out_end_element (xout); /* </number:day> */
+ break;
+
+ case OP_DATE_WEEKDAY:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "day-of-week");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "long");
+ gsf_xml_out_end_element (xout); /* </number:day-of-week> */
+ break;
+
+ case OP_DATE_WEEKDAY_3:
+ if (time_only) break;
+ gsf_xml_out_start_element (xout, NUMBER "day-of-week");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "short");
+ gsf_xml_out_end_element (xout); /* </number:day-of-week> */
+ break;
+
+ case OP_TIME_HOUR:
+ gsf_xml_out_start_element (xout, NUMBER "hours");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "short");
+ gsf_xml_out_end_element (xout); /* </number:hours> */
+ break;
+
+ case OP_TIME_HOUR_N:
+ prg++;
+ /* break; fall through */
+ case OP_TIME_HOUR_2:
+ gsf_xml_out_start_element (xout, NUMBER "hours");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "long");
+ gsf_xml_out_end_element (xout); /* </number:hours> */
+ break;
+
+ case OP_TIME_AP:
+ prg++;
+ prg++;
+ /* break; fall through */
+ case OP_TIME_AMPM:
+ gsf_xml_out_simple_element (xout, NUMBER "am-pm", NULL);
+ break;
+
+ case OP_TIME_MINUTE:
+ gsf_xml_out_start_element (xout, NUMBER "minutes");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "short");
+ gsf_xml_out_end_element (xout); /* </number:minutes> */
+ break;
+
+ case OP_TIME_MINUTE_N:
+ prg++;
+ /* break; fall through */
+ case OP_TIME_MINUTE_2:
+ gsf_xml_out_start_element (xout, NUMBER "minutes");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "long");
+ gsf_xml_out_end_element (xout); /* </number:minutes> */
+ break;
+
+ case OP_TIME_SECOND:
+ gsf_xml_out_start_element (xout, NUMBER "seconds");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "short");
+ gsf_xml_out_end_element (xout); /* </number:seconds> */
+ break;
+
+ case OP_TIME_SECOND_N:
+ prg++;
+ case OP_TIME_SECOND_2:
+ gsf_xml_out_start_element (xout, NUMBER "seconds");
+ gsf_xml_out_add_cstr (xout, NUMBER "style", "long");
+ gsf_xml_out_end_element (xout); /* </number:seconds> */
+ break;
+
+ case OP_TIME_SECOND_DECIMAL_START:
+ /* Reset to start of decimal string. */
+/* date_dec_ptr = fsecond; */
+/* go_string_append_gstring (dst, decimal); */
+ break;
+
+ case OP_TIME_SECOND_DECIMAL_DIGIT:
+/* g_string_append_c (dst, *date_dec_ptr++); */
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+static void
+odf_add_bool (GsfXMLOut *xout, char const *id, gboolean val)
+{
+ gsf_xml_out_add_cstr_unchecked (xout, id, val ? "true" : "false");
+}
+
+static void
+go_format_output_fraction_to_odf (GsfXMLOut *xout, GOFormat const *fmt, char const *name)
+{
+/* FIXME: we are using default of ?? at this time */
+ gsf_xml_out_start_element (xout, NUMBER "number-style");
+ gsf_xml_out_add_cstr (xout, STYLE "name", name);
+ gsf_xml_out_start_element (xout, NUMBER "fraction");
+/* gsf_xml_out_add_int (xout, NUMBER "denominator-value", 1); */
+ odf_add_bool (xout, NUMBER "grouping", FALSE);
+ gsf_xml_out_add_int (xout, NUMBER "min-denominator-digits", 3);
+ gsf_xml_out_add_int (xout, NUMBER "min-integer-digits", 0);
+ gsf_xml_out_add_int (xout, NUMBER "min-numerator-digits", 1);
+ gsf_xml_out_end_element (xout); /* </number:fraction> */
+ gsf_xml_out_end_element (xout); /* </number:number-style> */
+}
+
+static void
+go_format_output_scientific_number_to_odf (GsfXMLOut *xout, GOFormat const *fmt, char const *name)
+{
+/* FIXME: we are using default of "0.00E+00" at this time */
+ gsf_xml_out_start_element (xout, NUMBER "number-style");
+ gsf_xml_out_add_cstr (xout, STYLE "name", name);
+ gsf_xml_out_start_element (xout, NUMBER "scientific-number");
+ gsf_xml_out_add_int (xout, NUMBER "decimal-places", 2);
+ odf_add_bool (xout, NUMBER "grouping", FALSE);
+ gsf_xml_out_add_int (xout, NUMBER "min-integer-digits", 1);
+ gsf_xml_out_add_int (xout, NUMBER "min-exponent-digits", 2);
+ gsf_xml_out_end_element (xout); /* </number:scientific-number> */
+ gsf_xml_out_end_element (xout); /* </number:number-style> */
+}
+
+static void
+go_format_output_number_to_odf (GsfXMLOut *xout, GOFormat const *fmt, char const *name, gboolean percentage)
+{
+ if (percentage) {
+/* FIXME: we are using default of "0.00%" at this time */
+ gsf_xml_out_start_element (xout, NUMBER "percentage-style");
+ gsf_xml_out_add_cstr (xout, STYLE "name", name);
+ gsf_xml_out_start_element (xout, NUMBER "number");
+ gsf_xml_out_add_int (xout, NUMBER "decimal-places", 2);
+/* gsf_xml_out_add_cstr (xout, NUMBER "decimal-replacement", ); */
+ gsf_xml_out_add_int (xout, NUMBER "display-factor", 1);
+ odf_add_bool (xout, NUMBER "grouping", FALSE);
+ gsf_xml_out_add_int (xout, NUMBER "min-integer-digits", 1);
+ gsf_xml_out_end_element (xout); /* </number:number> */
+ gsf_xml_out_simple_element(xout, NUMBER "text", "%");
+ gsf_xml_out_end_element (xout); /* </number:percentage-style> */
+ } else {
+/* FIXME: we are using default of "#,##0.00" at this time */
+ gsf_xml_out_start_element (xout, NUMBER "number-style");
+ gsf_xml_out_add_cstr (xout, STYLE "name", name);
+ gsf_xml_out_start_element (xout, NUMBER "number");
+ gsf_xml_out_add_int (xout, NUMBER "decimal-places", 2);
+/* gsf_xml_out_add_cstr (xout, NUMBER "decimal-replacement", ); */
+ gsf_xml_out_add_int (xout, NUMBER "display-factor", 1);
+ odf_add_bool (xout, NUMBER "grouping", TRUE);
+ gsf_xml_out_add_int (xout, NUMBER "min-integer-digits", 1);
+ gsf_xml_out_end_element (xout); /* </number:number> */
+ gsf_xml_out_end_element (xout); /* </number:number-style> */
+ }
+}
+
+#endif
+
+#ifdef DEFINE_COMMON
gboolean
go_format_output_to_odf (GsfXMLOut *xout, GOFormat const *fmt, char const *name)
{
- return FALSE;
+ gboolean pp = TRUE, result = TRUE;
+
+ if ((fmt == NULL) || (fmt->typ != GO_FMT_NUMBER))
+ return FALSE;
+
+ g_object_get (G_OBJECT (xout), "pretty-print", &pp, NULL);
+ /* We need to switch off pretty printing since number:text preserves whitespace */
+ g_object_set (G_OBJECT (xout), "pretty-print", FALSE, NULL);
+
+ switch (go_format_get_family (fmt)) {
+ case GO_FORMAT_GENERAL:
+ result = FALSE;
+ break;
+ case GO_FORMAT_DATE:
+ go_format_output_date_to_odf (xout, fmt, name, FALSE);
+ break;
+ case GO_FORMAT_TIME:
+ go_format_output_date_to_odf (xout, fmt, name, TRUE);
+ break;
+ case GO_FORMAT_FRACTION:
+ go_format_output_fraction_to_odf (xout, fmt, name);
+ break;
+ case GO_FORMAT_SCIENTIFIC:
+ go_format_output_scientific_number_to_odf (xout, fmt, name);
+ break;
+ case GO_FORMAT_PERCENTAGE:
+ go_format_output_number_to_odf (xout, fmt, name, TRUE);
+ break;
+ default:
+ go_format_output_number_to_odf (xout, fmt, name, FALSE);
+ break;
+ }
+
+ g_object_set (G_OBJECT (xout), "pretty-print", pp, NULL);
+
+ return result;
}
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]