1 /* vm: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
4 * openoffice-read.c : import open/star calc files
6 * Copyright (C) 2002-2007 Jody Goldberg (jody@gnome.org)
7 * Copyright (C) 2006 Luciano Miguel Wolf (luciano.wolf@indt.org.br)
8 * Copyright (C) 2007 Morten Welinder (terra@gnome.org)
9 * Copyright (C) 2006-2010 Andreas J. Guelzow (aguelzow@pyrshep.ca)
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) version 3.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
27 #include <gnumeric-config.h>
30 #include <gnm-plugin.h>
31 #include <workbook-view.h>
34 #include <sheet-view.h>
35 #include <sheet-merge.h>
36 #include <sheet-filter.h>
37 #include <selection.h>
42 #include <expr-impl.h>
43 #include <expr-name.h>
45 #include <parse-util.h>
46 #include <style-color.h>
47 #include <sheet-style.h>
49 #include <style-border.h>
50 #include <input-msg.h>
51 #include <gnm-format.h>
52 #include <print-info.h>
53 #include <command-context.h>
56 #include <sheet-object-cell-comment.h>
57 #include "sheet-object-widget.h"
58 #include <style-conditions.h>
59 #include <gnumeric-conf.h>
61 #include <sheet-object-graph.h>
62 #include <sheet-object-image.h>
64 #include <gnm-so-filled.h>
65 #include <gnm-so-line.h>
66 #include <gnm-so-path.h>
70 #include <goffice/goffice.h>
72 #include <gsf/gsf-libxml.h>
73 #include <gsf/gsf-input.h>
74 #include <gsf/gsf-infile.h>
75 #include <gsf/gsf-infile-zip.h>
76 #include <gsf/gsf-opendoc-utils.h>
77 #include <gsf/gsf-doc-meta-data.h>
78 #include <gsf/gsf-output-stdio.h>
79 #include <gsf/gsf-utils.h>
80 #include <glib/gi18n-lib.h>
85 GNM_PLUGIN_MODULE_HEADER
;
89 #define CXML2C(s) ((char const *)(s))
90 #define CC2XML(s) ((xmlChar const *)(s))
92 static inline gboolean
93 attr_eq (xmlChar
const *a
, char const *s
)
95 return !strcmp (CXML2C (a
), s
);
99 OO_SYMBOL_TYPE_AUTO
= 1,
100 OO_SYMBOL_TYPE_NONE
= 2,
101 OO_SYMBOL_TYPE_NAMED
= 3
105 OO_CHART_STYLE_PLOTAREA
= 0,
106 OO_CHART_STYLE_SERIES
= 1,
107 OO_CHART_STYLE_INHERITANCE
= 2
111 OO_FILL_TYPE_UNKNOWN
= 0,
114 OO_FILL_TYPE_GRADIENT
,
121 OOO_VER_UNKNOWN
= -1,
126 char const * const mime_type
;
128 } const OOVersions
[] = {
129 { "application/vnd.sun.xml.calc", OOO_VER_1
},
130 { "application/vnd.oasis.opendocument.spreadsheet", OOO_VER_OPENDOC
},
131 { "application/vnd.oasis.opendocument.spreadsheet-template", OOO_VER_OPENDOC
}
136 FORMULA_OPENFORMULA
= 0,
137 FORMULA_OLD_OPENOFFICE
,
139 NUM_FORMULAE_SUPPORTED
,
140 FORMULA_NOT_SUPPORTED
143 #define OD_BORDER_THIN 1
144 #define OD_BORDER_MEDIUM 2.5
145 #define OD_BORDER_THICK 5
163 OO_PLOT_SCATTER_COLOUR
,
201 char *implementation
;
202 char *source_cell_range
;
213 gboolean grid
; /* graph has grid? */
214 gboolean src_in_rows
; /* orientation of graph data: rows or columns */
215 GSList
*axis_props
; /* axis properties */
216 GSList
*plot_props
; /* plot properties */
217 GSList
*style_props
; /* any other properties */
218 GSList
*other_props
; /* any other properties */
234 GSList
*list
; /* used by Stock plot and textbox*/
237 /* set in plot-area */
241 gboolean src_in_rows
;
243 GnmRange src_abscissa
;
244 gboolean src_abscissa_set
;
246 gboolean src_label_set
;
249 unsigned series_count
; /* reset for each plotarea */
250 unsigned domain_count
; /* reset for each series */
251 unsigned data_pt_count
; /* reset for each series */
252 unsigned x_axis_count
; /* reset for each plotarea */
253 unsigned y_axis_count
; /* reset for each plotarea */
254 unsigned z_axis_count
; /* reset for each plotarea */
258 GogObject
*regression
;
261 GnmExprTop
const *title_expr
;
263 gchar
*title_position
;
264 gboolean title_manual_pos
;
269 OOChartStyle
*cur_graph_style
; /* for reading of styles */
271 GSList
*saved_graph_styles
;
272 GSList
*saved_hatches
;
273 GSList
*saved_dash_styles
;
274 GSList
*saved_fill_image_styles
;
275 GSList
*saved_gradient_styles
;
277 GHashTable
*named_axes
;
278 GHashTable
*graph_styles
;
280 GHashTable
*dash_styles
;
281 GHashTable
*fill_image_styles
;
282 GHashTable
*gradient_styles
;
283 GHashTable
*arrow_markers
;
285 OOChartStyle
*i_plot_styles
[OO_CHART_STYLE_INHERITANCE
];
286 /* currently active styles at plot-area, */
288 OOPlotType plot_type
;
289 OOPlotType plot_type_default
;
290 SheetObjectAnchor anchor
; /* anchor to draw the frame (images or graphs) */
291 double frame_offset
[4]; /* offset as given in the file */
292 gnm_float width
; /* This refers to the ODF frame element */
293 gnm_float height
; /* This refers to the ODF frame element */
297 gnm_float plot_area_x
;
298 gnm_float plot_area_y
;
299 gnm_float plot_area_width
;
300 gnm_float plot_area_height
;
305 GogObjectPosition legend_flag
;
309 char *cs_enhanced_path
;
312 GHashTable
*cs_variables
;
324 OOPageBreakType break_before
, break_after
;
327 GnmSheetVisibility visibility
;
329 gboolean tab_color_set
;
331 gboolean tab_text_color_set
;
332 GOColor tab_text_color
;
333 gboolean display_formulas
;
334 gboolean hide_col_header
;
335 gboolean hide_row_header
;
336 char *master_page_name
;
340 GHashTable
*settings
;
343 char *config_item_name
;
347 ODF_ELAPSED_SET_SECONDS
= 1 << 0,
348 ODF_ELAPSED_SET_MINUTES
= 1 << 1,
349 ODF_ELAPSED_SET_HOURS
= 1 << 2
354 double frame_offset
[4];
355 gboolean absolute_distance
;
360 typedef struct _OOParseState OOParseState
;
366 GSList
*span_style_stack
;
367 GSList
*span_style_list
;
368 gboolean content_is_simple
;
370 PangoAttrList
*attrs
;
373 /* odf_validation <table:name> <val1> */
374 /* odf_validation <table:condition> <of:cell-content-is-in-list("1";"2";"3")> */
375 /* odf_validation <table:display-list> <unsorted> */
376 /* odf_validation <table:base-cell-address> <Tabelle1.A1> */
379 char *base_cell_address
;
380 gboolean allow_blank
;
381 gboolean use_dropdown
;
383 ValidationStyle style
;
387 GString
*help_message
;
390 struct _OOParseState
{
391 GOIOContext
*context
; /* The IOcontext managing things */
392 WorkbookView
*wb_view
; /* View for the new workbook */
393 OOVer ver
; /* Its an OOo v1.0 or v2.0? */
394 gnm_float ver_odf
; /* specific ODF version */
395 GsfInfile
*zip
; /* Reference to the open file, to load graphs and images*/
397 GSList
*chart_list
; /* object_offset_t */
400 GnmCellPos extent_data
;
401 GnmComment
*cell_comment
;
403 GnmExprSharer
*sharer
;
405 int col_inc
, row_inc
;
406 gboolean content_is_error
;
408 GSList
*text_p_stack
;
409 oo_text_p_t text_p_for_cell
;
412 GHashTable
*controls
;
413 GHashTable
*validations
;
416 odf_validation_t
*cur_validation
;
420 GHashTable
*cell_datetime
;
421 GHashTable
*cell_date
;
422 GHashTable
*cell_time
;
426 GHashTable
*master_pages
;
427 GHashTable
*page_layouts
;
433 OOColRowStyle
*col_rows
;
434 OOSheetStyle
*sheets
;
435 gboolean requires_disposal
;
439 gint h_align_is_valid
; /* 0: not set; 1: fix; 2: value-type*/
440 gboolean repeat_content
;
441 int text_align
, gnm_halign
;
446 OOColRowStyle
*columns
;
447 OOChartStyle
*graphics
;
454 gboolean string_opened
;
457 gboolean truncate_hour_on_overflow
;
458 int elapsed_set
; /* using a sum of odf_elapsed_set_t */
462 gboolean percent_sign_seen
;
465 GSList
*cond_formats
;
468 GnmConventions
*convs
[NUM_FORMULAE_SUPPORTED
];
469 GHashTable
*openformula_namemap
;
470 GHashTable
*openformula_handlermap
;
474 GnmPageBreaks
*h
, *v
;
477 GnmPrintInformation
*cur_pi
;
479 char **cur_hf_format
;
486 char *object_name
; /* also used for table during preparsing */
487 OOControl
*cur_control
;
491 gsf_off_t last_progress_update
;
493 gboolean hd_ft_left_warned
;
514 gnm_float brightness
;
525 char const * const name
;
529 static OOEnum
const odf_chart_classes
[] = {
530 { "chart:area", OO_PLOT_AREA
},
531 { "chart:bar", OO_PLOT_BAR
},
532 { "chart:circle", OO_PLOT_CIRCLE
},
533 { "chart:line", OO_PLOT_LINE
},
534 { "chart:radar", OO_PLOT_RADAR
},
535 { "chart:filled-radar", OO_PLOT_RADARAREA
},
536 { "chart:ring", OO_PLOT_RING
},
537 { "chart:scatter", OO_PLOT_SCATTER
},
538 { "chart:stock", OO_PLOT_STOCK
},
539 { "chart:bubble", OO_PLOT_BUBBLE
},
540 { "chart:gantt", OO_PLOT_GANTT
},
541 { "chart:surface", OO_PLOT_CONTOUR
},
542 { "gnm:polar", OO_PLOT_POLAR
},
543 { "gnm:xyz-surface", OO_PLOT_XYZ_SURFACE
},
544 { "gnm:scatter-color", OO_PLOT_SCATTER_COLOUR
},
545 { "gnm:box", OO_PLOT_BOX
},
546 { "gnm:none", OO_PLOT_UNKNOWN
},
550 /* Some prototypes */
551 static GsfXMLInNode
const * get_dtd (void);
552 static GsfXMLInNode
const * get_styles_dtd (void);
553 static void oo_chart_style_free (OOChartStyle
*pointer
);
554 static OOFormula
odf_get_formula_type (GsfXMLIn
*xin
, char const **str
);
555 static char const *odf_strunescape (char const *string
, GString
*target
,
556 G_GNUC_UNUSED GnmConventions
const *convs
);
557 static void odf_sheet_suggest_size (GsfXMLIn
*xin
, int *cols
, int *rows
);
558 static void oo_prop_list_has (GSList
*props
, gboolean
*threed
, char const *tag
);
561 /* Implementations */
564 odf_go_string_append_c_n (GString
*target
, char c
, int n
)
567 go_string_append_c_n (target
, c
, (gsize
) n
);
571 maybe_update_progress (GsfXMLIn
*xin
)
573 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
574 GsfInput
*input
= gsf_xml_in_get_input (xin
);
575 gsf_off_t pos
= gsf_input_tell (input
);
577 if (pos
>= state
->last_progress_update
+ 10000) {
578 go_io_value_progress_update (state
->context
, pos
);
579 state
->last_progress_update
= pos
;
583 static GOErrorInfo
*oo_go_error_info_new_vprintf (GOSeverity severity
,
584 char const *msg_format
, ...)
585 G_GNUC_PRINTF (2, 3);
588 oo_go_error_info_new_vprintf (GOSeverity severity
,
589 char const *msg_format
, ...)
594 va_start (args
, msg_format
);
595 ei
= go_error_info_new_vprintf (severity
, msg_format
, args
);
601 static gboolean
oo_warning (GsfXMLIn
*xin
, char const *fmt
, ...)
602 G_GNUC_PRINTF (2, 3);
605 oo_warning (GsfXMLIn
*xin
, char const *fmt
, ...)
607 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
612 va_start (args
, fmt
);
613 detail
= g_strdup_vprintf (fmt
, args
);
616 if (IS_SHEET (state
->pos
.sheet
)) {
617 if (state
->pos
.eval
.col
>= 0 && state
->pos
.eval
.row
>= 0)
618 msg
= g_strdup_printf ("%s!%s",
619 state
->pos
.sheet
->name_quoted
,
620 cellpos_as_string (&state
->pos
.eval
));
622 msg
= g_strdup(state
->pos
.sheet
->name_quoted
);
624 msg
= g_strdup (_("General ODF error"));
626 if (0 != go_str_compare (msg
, state
->last_error
)) {
627 GOErrorInfo
*ei
= oo_go_error_info_new_vprintf
628 (GO_WARNING
, "%s", msg
);
630 go_io_error_info_set (state
->context
, ei
);
631 g_free (state
->last_error
);
632 state
->last_error
= msg
;
636 go_error_info_add_details
637 (state
->context
->info
->data
,
638 oo_go_error_info_new_vprintf (GO_WARNING
, "%s", detail
));
642 return FALSE
; /* convenience */
646 oo_attr_bool (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
647 int ns_id
, char const *name
, gboolean
*res
)
649 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
650 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
651 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
653 if (!gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), ns_id
, name
))
655 *res
= (g_ascii_strcasecmp (CXML2C (attrs
[1]), "false") &&
656 strcmp (CXML2C (attrs
[1]), "0"));
662 oo_attr_int (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
663 int ns_id
, char const *name
, int *res
)
668 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
669 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
670 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
672 if (!gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), ns_id
, name
))
675 errno
= 0; /* strtol sets errno, but does not clear it. */
676 tmp
= strtol (CXML2C (attrs
[1]), &end
, 10);
677 if (*end
|| errno
!= 0 || tmp
< INT_MIN
|| tmp
> INT_MAX
)
678 return oo_warning (xin
, _("Invalid integer '%s', for '%s'"),
686 oo_attr_int_range (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
687 int ns_id
, char const *name
, int *res
, int min
, int max
)
690 if (!oo_attr_int (xin
, attrs
, ns_id
, name
, &tmp
))
692 if (tmp
< min
|| tmp
> max
) {
693 oo_warning (xin
, _("Possible corrupted integer '%s' for '%s'"),
695 *res
= (tmp
< min
) ? min
: max
;
704 oo_attr_font_weight (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
707 if (!gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "font-weight"))
709 if (attr_eq (attrs
[1], "bold")) {
710 *res
= PANGO_WEIGHT_BOLD
;
712 } else if (attr_eq (attrs
[1], "normal")) {
713 *res
= PANGO_WEIGHT_NORMAL
;
716 return oo_attr_int_range (xin
, attrs
, OO_NS_FO
, "font-weight",
722 oo_attr_float (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
723 int ns_id
, char const *name
, gnm_float
*res
)
728 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
729 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
730 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
732 if (!gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), ns_id
, name
))
735 tmp
= gnm_strto (CXML2C (attrs
[1]), &end
);
737 return oo_warning (xin
, _("Invalid attribute '%s', expected number, received '%s'"),
744 oo_attr_percent (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
745 int ns_id
, char const *name
, gnm_float
*res
)
749 const char *val
= CXML2C (attrs
[1]);
751 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
752 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
753 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
755 if (!gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), ns_id
, name
))
758 tmp
= gnm_strto (val
, &end
);
759 if (end
== val
|| *end
!= '%' || *(end
+ 1))
760 return oo_warning (xin
,
761 _("Invalid attribute '%s', expected percentage,"
768 static GnmColor
*magic_transparent
;
771 oo_parse_color (GsfXMLIn
*xin
, xmlChar
const *str
, char const *name
)
775 g_return_val_if_fail (str
!= NULL
, NULL
);
777 if (3 == sscanf (CXML2C (str
), "#%2x%2x%2x", &r
, &g
, &b
))
778 return gnm_color_new_rgb8 (r
, g
, b
);
780 if (0 == strcmp (CXML2C (str
), "transparent"))
781 return style_color_ref (magic_transparent
);
783 oo_warning (xin
, _("Invalid attribute '%s', expected color, received '%s'"),
788 oo_attr_color (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
789 int ns_id
, char const *name
)
791 g_return_val_if_fail (attrs
!= NULL
, NULL
);
792 g_return_val_if_fail (attrs
[0] != NULL
, NULL
);
794 if (!gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), ns_id
, name
))
796 return oo_parse_color (xin
, attrs
[1], name
);
799 static GOLineDashType
800 odf_match_dash_type (OOParseState
*state
, gchar
const *dash_style
)
802 GOLineDashType t
= go_line_dash_from_str (dash_style
);
803 if (t
== GO_LINE_NONE
) {
804 gpointer res
= g_hash_table_lookup
805 (state
->chart
.dash_styles
, dash_style
);
807 t
= GPOINTER_TO_UINT(res
);
809 return ((t
== GO_LINE_NONE
)? GO_LINE_DOT
: t
);
813 odf_string_id (OOParseState
*state
, char const *string
)
815 char *id
= g_strdup_printf ("str%i", g_hash_table_size (state
->strings
));
816 g_hash_table_insert (state
->strings
, id
, g_strdup (string
));
821 odf_apply_style_props (GsfXMLIn
*xin
, GSList
*props
, GOStyle
*style
, gboolean in_chart_context
)
823 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
824 PangoFontDescription
*desc
;
826 gboolean desc_changed
= FALSE
;
827 char const *hatch_name
= NULL
;
828 char const *gradient_name
= NULL
;
829 char const *fill_image_name
= NULL
;
830 unsigned int gnm_hatch
= 0;
831 int symbol_type
= -1, symbol_name
= GO_MARKER_DIAMOND
;
832 double symbol_height
= -1., symbol_width
= -1.,
833 stroke_width
= -1., gnm_stroke_width
= -1.;
835 gboolean line_is_not_dash
= FALSE
;
836 unsigned int fill_type
= OO_FILL_TYPE_UNKNOWN
;
837 gboolean stroke_colour_set
= FALSE
;
838 gboolean lines_value
= !in_chart_context
;
839 gboolean gnm_auto_color_value_set
= FALSE
;
840 gboolean gnm_auto_color_value
= FALSE
;
841 gboolean gnm_auto_marker_outline_color_value_set
= FALSE
;
842 gboolean gnm_auto_marker_outline_color_value
= FALSE
;
843 gboolean gnm_auto_marker_fill_color_value_set
= FALSE
;
844 gboolean gnm_auto_marker_fill_color_value
= FALSE
;
845 gboolean gnm_auto_dash_set
= FALSE
;
846 gboolean gnm_auto_width_set
= FALSE
;
847 char const *stroke_dash
= NULL
;
848 char const *marker_outline_colour
= NULL
;
849 char const *marker_fill_colour
= NULL
;
850 gboolean gnm_auto_font_set
= FALSE
;
851 gboolean gnm_auto_font
= FALSE
;
852 gboolean gnm_foreground_solid
= FALSE
;
854 oo_prop_list_has (props
, &gnm_foreground_solid
, "gnm-foreground-solid");
855 style
->line
.auto_dash
= TRUE
;
857 desc
= pango_font_description_copy (style
->font
.font
->desc
);
858 for (l
= props
; l
!= NULL
; l
= l
->next
) {
859 OOProp
*prop
= l
->data
;
860 if (0 == strcmp (prop
->name
, "fill")) {
861 char const *val_string
= g_value_get_string (&prop
->value
);
862 if (0 == strcmp (val_string
, "solid")) {
863 style
->fill
.type
= GO_STYLE_FILL_PATTERN
;
864 style
->fill
.auto_type
= FALSE
;
865 style
->fill
.pattern
.pattern
= (gnm_foreground_solid
) ?
866 GO_PATTERN_FOREGROUND_SOLID
: GO_PATTERN_SOLID
;
867 fill_type
= OO_FILL_TYPE_SOLID
;
868 } else if (0 == strcmp (val_string
, "hatch")) {
869 style
->fill
.type
= GO_STYLE_FILL_PATTERN
;
870 style
->fill
.auto_type
= FALSE
;
871 fill_type
= OO_FILL_TYPE_HATCH
;
872 } else if (0 == strcmp (val_string
, "gradient")) {
873 style
->fill
.type
= GO_STYLE_FILL_GRADIENT
;
874 style
->fill
.auto_type
= FALSE
;
875 fill_type
= OO_FILL_TYPE_GRADIENT
;
876 } else if (0 == strcmp (val_string
, "bitmap")) {
877 style
->fill
.type
= GO_STYLE_FILL_IMAGE
;
878 style
->fill
.auto_type
= FALSE
;
879 fill_type
= OO_FILL_TYPE_BITMAP
;
880 } else { /* "none" */
881 style
->fill
.type
= GO_STYLE_FILL_NONE
;
882 style
->fill
.auto_type
= FALSE
;
883 fill_type
= OO_FILL_TYPE_NONE
;
885 } else if (0 == strcmp (prop
->name
, "fill-color")) {
887 gchar
const *color
= g_value_get_string (&prop
->value
);
888 if (gdk_rgba_parse (&rgba
, color
)) {
890 if (gnm_foreground_solid
) {
891 a
= GO_COLOR_UINT_A (style
->fill
.pattern
.fore
);
892 go_color_from_gdk_rgba (&rgba
, &style
->fill
.pattern
.fore
);
893 style
->fill
.auto_fore
= FALSE
;
894 style
->fill
.pattern
.fore
= GO_COLOR_CHANGE_A (style
->fill
.pattern
.fore
, a
);
896 a
= GO_COLOR_UINT_A (style
->fill
.pattern
.back
);
897 go_color_from_gdk_rgba (&rgba
, &style
->fill
.pattern
.back
);
898 style
->fill
.auto_back
= FALSE
;
899 style
->fill
.pattern
.back
= GO_COLOR_CHANGE_A (style
->fill
.pattern
.back
, a
);
902 }else if (0 == strcmp (prop
->name
, "opacity")) {
903 guint a
= 255 * g_value_get_double (&prop
->value
);
904 style
->fill
.pattern
.back
= GO_COLOR_CHANGE_A (style
->fill
.pattern
.back
, a
);
905 } else if (0 == strcmp (prop
->name
, "stroke-color")) {
907 gchar
const *color
= g_value_get_string (&prop
->value
);
908 if (gdk_rgba_parse (&rgba
, color
)) {
909 style
->line
.fore
= go_color_from_gdk_rgba (&rgba
, &style
->line
.color
);
910 style
->line
.auto_color
= FALSE
;
911 style
->line
.auto_fore
= FALSE
;
912 style
->line
.pattern
= GO_PATTERN_SOLID
;
913 stroke_colour_set
= TRUE
;
915 } else if (0 == strcmp (prop
->name
, "marker-outline-colour")) {
916 marker_outline_colour
= g_value_get_string (&prop
->value
);
917 } else if (0 == strcmp (prop
->name
, "marker-fill-colour")) {
918 marker_fill_colour
= g_value_get_string (&prop
->value
);
919 } else if (0 == strcmp (prop
->name
, "lines")) {
920 lines_value
= g_value_get_boolean (&prop
->value
);
921 } else if (0 == strcmp (prop
->name
, "gnm-auto-color")) {
922 gnm_auto_color_value_set
= TRUE
;
923 gnm_auto_color_value
= g_value_get_boolean (&prop
->value
);
924 } else if (0 == strcmp (prop
->name
, "gnm-auto-marker-outline-colour")) {
925 gnm_auto_marker_outline_color_value_set
= TRUE
;
926 gnm_auto_marker_outline_color_value
= g_value_get_boolean (&prop
->value
);
927 } else if (0 == strcmp (prop
->name
, "gnm-auto-marker-fill-colour")) {
928 gnm_auto_marker_fill_color_value_set
= TRUE
;
929 gnm_auto_marker_fill_color_value
= g_value_get_boolean (&prop
->value
);
930 } else if (0 == strcmp (prop
->name
, "color")) {
932 gchar
const *color
= g_value_get_string (&prop
->value
);
933 if (gdk_rgba_parse (&rgba
, color
)) {
934 go_color_from_gdk_rgba (&rgba
, &style
->font
.color
);
935 style
->font
.auto_color
= FALSE
;
937 } else if (0 == strcmp (prop
->name
, "gnm-auto-dash")) {
938 gnm_auto_dash_set
= TRUE
;
939 style
->line
.auto_dash
= g_value_get_boolean (&prop
->value
);
940 } else if (0 == strcmp (prop
->name
, "fill-gradient-name"))
941 gradient_name
= g_value_get_string (&prop
->value
);
942 else if (0 == strcmp (prop
->name
, "fill-hatch-name"))
943 hatch_name
= g_value_get_string (&prop
->value
);
944 else if (0 == strcmp (prop
->name
, "fill-image-name"))
945 fill_image_name
= g_value_get_string (&prop
->value
);
946 else if (0 == strcmp (prop
->name
, "gnm-pattern"))
947 gnm_hatch
= g_value_get_int (&prop
->value
);
948 else if (0 == strcmp (prop
->name
, "text-rotation-angle")) {
949 int angle
= g_value_get_int (&prop
->value
);
952 go_style_set_text_angle (style
, angle
);
953 } else if (0 == strcmp (prop
->name
, "font-size")) {
954 pango_font_description_set_size
955 (desc
, PANGO_SCALE
* g_value_get_double
958 } else if (0 == strcmp (prop
->name
, "font-weight")) {
959 pango_font_description_set_weight
960 (desc
, g_value_get_int (&prop
->value
));
962 } else if (0 == strcmp (prop
->name
, "font-variant")) {
963 pango_font_description_set_variant
964 (desc
, g_value_get_int (&prop
->value
));
966 } else if (0 == strcmp (prop
->name
, "font-style")) {
967 pango_font_description_set_style
968 (desc
, g_value_get_int (&prop
->value
));
970 } else if (0 == strcmp (prop
->name
, "font-stretch-pango")) {
971 pango_font_description_set_stretch
972 (desc
, g_value_get_int (&prop
->value
));
974 } else if (0 == strcmp (prop
->name
, "font-gravity-pango")) {
975 pango_font_description_set_gravity
976 (desc
, g_value_get_int (&prop
->value
));
978 } else if (0 == strcmp (prop
->name
, "font-family")) {
979 pango_font_description_set_family
980 (desc
, g_value_get_string (&prop
->value
));
982 } else if (0 == strcmp (prop
->name
, "stroke")) {
983 if (0 == strcmp (g_value_get_string (&prop
->value
), "solid")) {
984 style
->line
.dash_type
= GO_LINE_SOLID
;
985 if (!gnm_auto_dash_set
)
986 style
->line
.auto_dash
= FALSE
;
987 line_is_not_dash
= TRUE
;
988 } else if (0 == strcmp (g_value_get_string (&prop
->value
), "dash")) {
989 if (!gnm_auto_dash_set
)
990 style
->line
.auto_dash
= FALSE
;
991 line_is_not_dash
= FALSE
;
993 style
->line
.dash_type
= GO_LINE_NONE
;
994 if (!gnm_auto_dash_set
)
995 style
->line
.auto_dash
= FALSE
;
996 line_is_not_dash
= TRUE
;
998 } else if (0 == strcmp (prop
->name
, "stroke-dash"))
999 stroke_dash
= g_value_get_string (&prop
->value
);
1000 else if (0 == strcmp (prop
->name
, "symbol-type"))
1001 symbol_type
= g_value_get_int (&prop
->value
);
1002 else if (0 == strcmp (prop
->name
, "symbol-name"))
1003 symbol_name
= g_value_get_int (&prop
->value
);
1004 else if (0 == strcmp (prop
->name
, "symbol-height"))
1005 symbol_height
= g_value_get_double (&prop
->value
);
1006 else if (0 == strcmp (prop
->name
, "symbol-width"))
1007 symbol_width
= g_value_get_double (&prop
->value
);
1008 else if (0 == strcmp (prop
->name
, "stroke-width"))
1009 stroke_width
= g_value_get_double (&prop
->value
);
1010 else if (0 == strcmp (prop
->name
, "gnm-stroke-width"))
1011 gnm_stroke_width
= g_value_get_double (&prop
->value
);
1012 else if (0 == strcmp (prop
->name
, "gnm-auto-width")) {
1013 gnm_auto_width_set
= TRUE
;
1014 style
->line
.auto_width
= g_value_get_boolean (&prop
->value
);
1015 } else if (0 == strcmp (prop
->name
, "repeat"))
1016 style
->fill
.image
.type
= g_value_get_int (&prop
->value
);
1017 else if (0 == strcmp (prop
->name
, "gnm-auto-type"))
1018 style
->fill
.auto_type
= g_value_get_boolean (&prop
->value
);
1019 else if (0 == strcmp (prop
->name
, "gnm-auto-font")) {
1020 gnm_auto_font_set
= TRUE
;
1021 gnm_auto_font
= g_value_get_boolean (&prop
->value
);
1026 go_style_set_font_desc (style
, desc
);
1028 pango_font_description_free (desc
);
1029 style
->font
.auto_font
= gnm_auto_font_set
? gnm_auto_font
: !desc_changed
;
1032 * Stroke colour is tricky: if we have lines, that is what it
1033 * refers to. Otherwise it refers to markers.
1035 if (!gnm_auto_color_value_set
)
1036 gnm_auto_color_value
= !stroke_colour_set
;
1038 style
->line
.auto_color
= (lines_value
? gnm_auto_color_value
: TRUE
);
1040 if (gnm_stroke_width
>= 0)
1041 style
->line
.width
= gnm_stroke_width
;
1042 else if (stroke_width
== 0.) {
1043 style
->line
.width
= 0.;
1044 style
->line
.dash_type
= GO_LINE_NONE
;
1045 } else if (stroke_width
> 0)
1046 style
->line
.width
= stroke_width
;
1048 style
->line
.width
= 0;
1049 if (!gnm_auto_width_set
)
1050 style
->line
.auto_width
= FALSE
;
1052 if (stroke_dash
!= NULL
&& !line_is_not_dash
)
1053 style
->line
.dash_type
= odf_match_dash_type (state
, stroke_dash
);
1055 switch (fill_type
) {
1056 case OO_FILL_TYPE_HATCH
:
1057 if (hatch_name
!= NULL
) {
1058 GOPattern
*pat
= g_hash_table_lookup
1059 (state
->chart
.hatches
, hatch_name
);
1061 oo_warning (xin
, _("Unknown hatch name \'%s\'"
1062 " encountered!"), hatch_name
);
1064 style
->fill
.pattern
.fore
= pat
->fore
;
1065 style
->fill
.auto_fore
= gnm_auto_color_value_set
&& gnm_auto_color_value
;
1066 style
->fill
.pattern
.pattern
= (gnm_hatch
> 0) ?
1067 gnm_hatch
: pat
->pattern
;
1069 } else oo_warning (xin
, _("Hatch fill without hatch name "
1072 case OO_FILL_TYPE_GRADIENT
:
1073 if (gradient_name
!= NULL
) {
1074 gradient_info_t
*info
= g_hash_table_lookup
1075 (state
->chart
.gradient_styles
, gradient_name
);
1077 oo_warning (xin
, _("Unknown gradient name \'%s\'"
1078 " encountered!"), gradient_name
);
1080 style
->fill
.auto_fore
= FALSE
;
1081 style
->fill
.auto_back
= FALSE
;
1082 style
->fill
.pattern
.back
= info
->from
;
1083 style
->fill
.pattern
.fore
= info
->to
;
1084 style
->fill
.gradient
.dir
= info
->dir
;
1085 style
->fill
.gradient
.brightness
= -1.0;
1086 if (info
->brightness
>= 0)
1087 go_style_set_fill_brightness
1088 (style
, info
->brightness
);
1090 } else oo_warning (xin
, _("Gradient fill without gradient "
1091 "name encountered!"));
1093 case OO_FILL_TYPE_BITMAP
:
1094 if (fill_image_name
!= NULL
) {
1095 char const *href
= g_hash_table_lookup
1096 (state
->chart
.fill_image_styles
, fill_image_name
);
1098 oo_warning (xin
, _("Unknown image fill name \'%s\'"
1099 " encountered!"), fill_image_name
);
1102 char *href_complete
;
1105 if (strncmp (href
, "./", 2) == 0)
1107 if (strncmp (href
, "/", 1) == 0) {
1108 oo_warning (xin
, _("Invalid absolute file "
1109 "specification \'%s\' "
1110 "encountered."), href
);
1114 href_complete
= g_strconcat (state
->object_name
,
1116 path
= g_strsplit (href_complete
, "/", -1);
1117 input
= gsf_infile_child_by_aname
1118 (state
->zip
, (const char **) path
);
1121 oo_warning (xin
, _("Unable to open \'%s\'."),
1124 gsf_off_t len
= gsf_input_size (input
);
1125 guint8
const *data
= gsf_input_read (input
, len
, NULL
);
1126 GOImage
*image
= go_image_new_from_data (NULL
, data
, len
, NULL
, NULL
);
1128 g_clear_object (&style
->fill
.image
.image
);
1129 style
->fill
.image
.image
= image
;
1131 oo_warning (xin
, _("Unable to load "
1132 "the file \'%s\'."),
1136 g_object_unref (input
);
1138 g_free (href_complete
);
1140 } else oo_warning (xin
, _("Image fill without image "
1141 "name encountered!"));
1147 switch (symbol_type
) {
1148 case OO_SYMBOL_TYPE_AUTO
:
1149 m
= go_marker_new ();
1150 style
->marker
.auto_shape
= TRUE
;
1152 case OO_SYMBOL_TYPE_NONE
:
1153 style
->marker
.auto_shape
= FALSE
;
1154 m
= go_marker_new ();
1155 go_marker_set_shape (m
, GO_MARKER_NONE
);
1157 case OO_SYMBOL_TYPE_NAMED
:
1158 style
->marker
.auto_shape
= FALSE
;
1159 m
= go_marker_new ();
1160 go_marker_set_shape (m
, symbol_name
);
1169 if (symbol_type
!= OO_SYMBOL_TYPE_NONE
) {
1170 /* Inherit line colour. */
1171 go_marker_set_fill_color (m
, style
->line
.color
);
1172 if (marker_fill_colour
!= NULL
) {
1175 if (gdk_rgba_parse (&rgba
, marker_fill_colour
)) {
1176 go_color_from_gdk_rgba (&rgba
, &color
);
1177 go_marker_set_fill_color (m
, color
);
1180 go_marker_set_fill_color (m
, style
->line
.color
);
1181 style
->marker
.auto_fill_color
= gnm_auto_marker_fill_color_value_set
?
1182 gnm_auto_marker_fill_color_value
: gnm_auto_color_value
;
1183 if (marker_outline_colour
== NULL
)
1184 go_marker_set_outline_color (m
, style
->line
.color
);
1188 if (gdk_rgba_parse (&rgba
, marker_outline_colour
)) {
1189 go_color_from_gdk_rgba (&rgba
, &color
);
1190 go_marker_set_outline_color (m
, color
);
1192 go_marker_set_outline_color (m
, style
->line
.color
);
1194 style
->marker
.auto_outline_color
= gnm_auto_marker_outline_color_value_set
?
1195 gnm_auto_marker_outline_color_value
: gnm_auto_color_value
;
1198 if (symbol_height
>= 0. || symbol_width
>= 0.) {
1200 /* If we have only one dimension, use that for the other */
1201 if (symbol_width
< 0) symbol_width
= symbol_height
;
1202 if (symbol_height
< 0) symbol_height
= symbol_width
;
1204 size
= (symbol_height
+ symbol_width
+ 1) / 2;
1205 size
= MIN (size
, G_MAXINT
);
1207 go_marker_set_size (m
, (int)size
);
1210 if (gnm_object_has_readable_prop (state
->chart
.plot
,
1211 "default-style-has-markers",
1215 go_marker_get_shape (m
) == GO_MARKER_NONE
) {
1216 style
->marker
.auto_shape
= TRUE
;
1219 go_style_set_marker (style
, m
);
1225 oo_parse_spec_distance (char const *str
, gnm_float
*pts
)
1230 num
= go_strtod (str
, &end
);
1231 if (CXML2C (str
) != end
) {
1232 if (0 == strncmp (end
, "mm", 2)) {
1233 num
= GO_CM_TO_PT (num
/10.);
1235 } else if (0 == strncmp (end
, "m", 1)) {
1236 num
= GO_CM_TO_PT (num
*100.);
1238 } else if (0 == strncmp (end
, "km", 2)) {
1239 num
= GO_CM_TO_PT (num
*100000.);
1241 } else if (0 == strncmp (end
, "cm", 2)) {
1242 num
= GO_CM_TO_PT (num
);
1244 } else if (0 == strncmp (end
, "pt", 2)) {
1246 } else if (0 == strncmp (end
, "pc", 2)) { /* pica 12pt == 1 pica */
1249 } else if (0 == strncmp (end
, "ft", 2)) {
1250 num
= GO_IN_TO_PT (num
*12.);
1252 } else if (0 == strncmp (end
, "mi", 2)) {
1253 num
= GO_IN_TO_PT (num
*63360.);
1255 } else if (0 == strncmp (end
, "inch", 4)) {
1256 num
= GO_IN_TO_PT (num
);
1258 } else if (0 == strncmp (end
, "in", 2)) {
1259 num
= GO_IN_TO_PT (num
);
1262 return GINT_TO_POINTER(1);
1272 oo_parse_distance (GsfXMLIn
*xin
, xmlChar
const *str
,
1273 char const *name
, gnm_float
*pts
)
1275 char const *end
= NULL
;
1277 g_return_val_if_fail (str
!= NULL
, NULL
);
1279 if (0 == strncmp (CXML2C (str
), "none", 4)) {
1281 return CXML2C (str
) + 4;
1284 end
= oo_parse_spec_distance (CXML2C (str
), pts
);
1286 if (end
== GINT_TO_POINTER(1)) {
1287 oo_warning (xin
, _("Invalid attribute '%s', unknown unit '%s'"),
1292 oo_warning (xin
, _("Invalid attribute '%s', expected distance, received '%s'"),
1301 oo_attr_distance (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
1302 int ns_id
, char const *name
, gnm_float
*pts
)
1304 g_return_val_if_fail (attrs
!= NULL
, NULL
);
1305 g_return_val_if_fail (attrs
[0] != NULL
, NULL
);
1306 g_return_val_if_fail (attrs
[1] != NULL
, NULL
);
1308 if (!gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), ns_id
, name
))
1310 return oo_parse_distance (xin
, attrs
[1], name
, pts
);
1314 oo_attr_percent_or_distance (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
1315 int ns_id
, char const *name
, gnm_float
*res
,
1316 gboolean
*found_percent
)
1321 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
1322 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
1323 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
1324 g_return_val_if_fail (res
!= NULL
, FALSE
);
1325 g_return_val_if_fail (found_percent
!= NULL
, FALSE
);
1327 if (!gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), ns_id
, name
))
1330 tmp
= gnm_strto (CXML2C (attrs
[1]), &end
);
1331 if (*end
!= '%' || *(end
+ 1)) {
1332 *found_percent
= FALSE
;
1333 return (NULL
!= oo_parse_distance (xin
, attrs
[1], name
, res
));
1336 *found_percent
= TRUE
;
1341 oo_parse_angle (GsfXMLIn
*xin
, xmlChar
const *str
,
1342 char const *name
, int *angle
)
1347 g_return_val_if_fail (str
!= NULL
, NULL
);
1349 num
= gnm_strto (CXML2C (str
), &end
);
1350 if (CXML2C (str
) != end
) {
1352 num
= gnm_fmod (num
, 360);
1353 } else if (0 == strncmp (end
, "deg", 3)) {
1354 num
= gnm_fmod (num
, 360);
1356 } else if (0 == strncmp (end
, "grad", 4)) {
1357 num
= gnm_fmod (num
, 400);
1358 num
= num
* 10. / 9.;
1360 } else if (0 == strncmp (end
, "rad", 3)) {
1361 num
= gnm_fmod (num
, 2 * M_PIgnum
);
1362 num
= num
* 180. / M_PIgnum
;
1365 oo_warning (xin
, _("Invalid attribute '%s', unknown unit '%s'"),
1370 oo_warning (xin
, _("Invalid attribute '%s', expected angle, received '%s'"),
1375 num
= gnm_fake_round (num
);
1376 if (gnm_abs (num
) >= 360)
1384 /* returns degree */
1386 oo_attr_angle (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
1387 int ns_id
, char const *name
, int *deg
)
1389 g_return_val_if_fail (attrs
!= NULL
, NULL
);
1390 g_return_val_if_fail (attrs
[0] != NULL
, NULL
);
1391 g_return_val_if_fail (attrs
[1] != NULL
, NULL
);
1393 if (!gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), ns_id
, name
))
1395 return oo_parse_angle (xin
, attrs
[1], name
, deg
);
1399 odf_attr_range (GsfXMLIn
*xin
, xmlChar
const * const *attrs
, Sheet
*sheet
, GnmRange
*res
)
1403 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
1405 for (; attrs
[0] && attrs
[1] ; attrs
+= 2)
1406 if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
, "start-col", &res
->start
.col
, 0, gnm_sheet_get_last_col(sheet
)))
1408 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
, "start-row", &res
->start
.row
, 0, gnm_sheet_get_last_row(sheet
)))
1410 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
, "end-col", &res
->end
.col
, 0, gnm_sheet_get_last_col(sheet
)))
1412 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
, "end-row", &res
->end
.row
, 0, gnm_sheet_get_last_row(sheet
)))
1417 return flags
== 0xf;
1421 oo_attr_enum (GsfXMLIn
*xin
, xmlChar
const * const *attrs
,
1422 int ns_id
, char const *name
, OOEnum
const *enums
, int *res
)
1424 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
1425 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
1426 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
1428 if (!gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), ns_id
, name
))
1431 for (; enums
->name
!= NULL
; enums
++)
1432 if (!strcmp (enums
->name
, CXML2C (attrs
[1]))) {
1436 return oo_warning (xin
, _("Invalid attribute '%s', unknown enum value '%s'"),
1441 oo_cellref_check_for_err (GnmCellRef
*ref
, char const **start
)
1443 if (g_str_has_prefix (*start
, "$#REF!")) {
1444 ref
->sheet
= invalid_sheet
;
1448 if (g_str_has_prefix (*start
, "#REF!")) {
1449 ref
->sheet
= invalid_sheet
;
1457 oo_cellref_parse (GnmCellRef
*ref
, char const *start
, GnmParsePos
const *pp
,
1458 gchar
**foreign_sheet
)
1460 char const *tmp
, *ptr
= start
;
1461 GnmSheetSize
const *ss
;
1462 GnmSheetSize ss_max
= { GNM_MAX_COLS
, GNM_MAX_ROWS
};
1468 /* ignore abs vs rel for sheets */
1473 * SheetName ::= [^\. ']+ | "'" ([^'] | "''")+ "'" */
1477 /* missing close paren */
1478 if (NULL
== (tmp
= strchr (tmp
, '\'')))
1481 /* two in a row is the escape for a single */
1482 if (tmp
[1] == '\'') {
1487 /* If a name is quoted the entire named must be quoted */
1491 accum
= name
= g_alloca (tmp
-ptr
+1);
1493 if ('\'' == (*accum
++ = *ptr
++))
1498 if (NULL
== (tmp
= strchr (ptr
, '.')))
1500 name
= g_alloca (tmp
-ptr
+1);
1501 strncpy (name
, ptr
, tmp
-ptr
);
1502 name
[tmp
-ptr
] = '\0';
1509 if (foreign_sheet
!= NULL
) {
1510 /* This is a reference to a foreign workbook */
1511 *foreign_sheet
= g_strdup (name
);
1514 /* We have seen instances of ODF files generated by */
1515 /* Libreoffice referring internally to table included */
1516 /* inside charts. See */
1517 /* https://bugzilla.gnome.org/show_bug.cgi?id=698388 */
1518 /* Since all true sheets have been created during */
1519 /* preparsing, this reference should just be invalid! */
1521 ref
->sheet
= workbook_sheet_by_name (pp
->wb
, name
);
1522 if (ref
->sheet
== NULL
)
1523 ref
->sheet
= invalid_sheet
;
1526 ptr
++; /* local ref */
1530 tmp
= col_parse (ptr
, &ss_max
, &ref
->col
, &ref
->col_relative
);
1531 if (!tmp
&& !oo_cellref_check_for_err (ref
, &ptr
))
1535 tmp
= row_parse (ptr
, &ss_max
, &ref
->row
, &ref
->row_relative
);
1536 if (!tmp
&& !oo_cellref_check_for_err (ref
, &ptr
))
1541 if (ref
->sheet
== invalid_sheet
)
1544 sheet
= eval_sheet (ref
->sheet
, pp
->sheet
);
1545 ss
= gnm_sheet_get_size (sheet
);
1547 if (foreign_sheet
== NULL
&& (ss
->max_cols
<= ref
->col
|| ss
->max_rows
<= ref
->row
)) {
1548 int new_cols
= ref
->col
+ 1, new_rows
= ref
->row
+ 1;
1552 odf_sheet_suggest_size (NULL
, &new_cols
, &new_rows
);
1553 goundo
= gnm_sheet_resize (sheet
, new_cols
, new_rows
, NULL
, &err
);
1554 if (goundo
) g_object_unref (goundo
);
1556 ss
= gnm_sheet_get_size (sheet
);
1557 if (ss
->max_cols
<= ref
->col
|| ss
->max_rows
<= ref
->row
)
1561 if (ref
->col_relative
)
1562 ref
->col
-= pp
->eval
.col
;
1563 if (ref
->row_relative
)
1564 ref
->row
-= pp
->eval
.row
;
1570 odf_parse_external (char const *start
, gchar
**external
,
1571 GnmConventions
const *convs
)
1576 /* Source ::= "'" IRI "'" "#" */
1579 str
= g_string_new (NULL
);
1580 ptr
= odf_strunescape (start
, str
, convs
);
1582 if (ptr
== NULL
|| *ptr
!= '#') {
1583 g_string_free (str
, TRUE
);
1587 *external
= g_string_free (str
, FALSE
);
1592 oo_rangeref_parse (GnmRangeRef
*ref
, char const *start
, GnmParsePos
const *pp
,
1593 GnmConventions
const *convs
)
1597 char *external
= NULL
;
1598 char *external_sheet_1
= NULL
;
1599 char *external_sheet_2
= NULL
;
1600 ODFConventions
*oconv
= (ODFConventions
*)convs
;
1602 ptr
= odf_parse_external (start
, &external
, convs
);
1604 ptr2
= oo_cellref_parse (&ref
->a
, ptr
, pp
,
1605 external
? &external_sheet_1
: NULL
);
1611 ptr2
= oo_cellref_parse (&ref
->b
, ptr
+1, pp
,
1612 external
? &external_sheet_2
: NULL
);
1613 if (ptr2
== ptr
+ 1)
1620 if (ref
->b
.sheet
== invalid_sheet
)
1621 ref
->a
.sheet
= invalid_sheet
;
1623 if (external
!= NULL
) {
1624 Workbook
*wb
= pp
->wb
, *ext_wb
;
1625 Workbook
*ref_wb
= wb
? wb
: pp
->sheet
->workbook
;
1627 ext_wb
= (*convs
->input
.external_wb
) (convs
, ref_wb
, external
);
1628 if (ext_wb
== NULL
) {
1630 oo_warning (oconv
->xin
,
1631 _("Ignoring reference to unknown "
1632 "external workbook '%s'"),
1634 ref
->a
.sheet
= invalid_sheet
;
1636 if (external_sheet_1
!= NULL
)
1637 ref
->a
.sheet
= workbook_sheet_by_name
1638 (ext_wb
, external_sheet_1
);
1640 ref
->a
.sheet
= workbook_sheet_by_index
1642 if (external_sheet_2
!= NULL
)
1643 ref
->b
.sheet
= workbook_sheet_by_name
1644 (ext_wb
, external_sheet_1
);
1646 ref
->b
.sheet
= NULL
;
1649 g_free (external_sheet_1
);
1650 g_free (external_sheet_2
);
1656 oo_expr_rangeref_parse (GnmRangeRef
*ref
, char const *start
, GnmParsePos
const *pp
,
1657 GnmConventions
const *convs
)
1660 if (start
[0] == '[' && start
[1] != ']') {
1661 if (strncmp (start
, "[#REF!]", 7) == 0) {
1662 ref
->a
.sheet
= invalid_sheet
;
1665 ptr
= oo_rangeref_parse (ref
, start
+1, pp
, convs
);
1674 odf_strunescape (char const *string
, GString
*target
,
1675 G_GNUC_UNUSED GnmConventions
const *convs
)
1677 /* Constant strings are surrounded by double-quote characters */
1678 /* (QUOTATION MARK, U+0022); a literal double-quote character '"'*/
1679 /* (QUOTATION MARK, U+0022) as */
1680 /* string content is escaped by duplicating it. */
1682 char quote
= *string
++;
1683 size_t oldlen
= target
->len
;
1685 /* This should be UTF-8 safe as long as quote is ASCII. */
1687 while (*string
!= quote
) {
1688 if (*string
== '\0')
1690 g_string_append_c (target
, *string
);
1694 if (*string
== quote
)
1695 g_string_append_c (target
, quote
);
1696 } while (*string
++ == quote
);
1700 g_string_truncate (target
, oldlen
);
1704 /* Handle formatted text inside text:p */
1706 odf_text_p_add_text (OOParseState
*state
, char const *str
)
1710 g_return_if_fail (state
->text_p_stack
!= NULL
);
1711 ptr
= state
->text_p_stack
->data
;
1714 g_string_append (ptr
->gstr
, str
);
1716 ptr
->gstr
= g_string_new (str
);
1722 PangoAttrList
*attrs
;
1723 } odf_text_p_apply_style_t
;
1726 odf_text_p_apply_pango_attribute (PangoAttribute
*attribute
, gpointer ptr
)
1728 odf_text_p_apply_style_t
*data
= ptr
;
1729 PangoAttribute
*attr
= pango_attribute_copy (attribute
);
1731 attr
->start_index
= data
->start
;
1732 attr
->end_index
= data
->end
;
1734 pango_attr_list_change (data
->attrs
, attr
);
1740 odf_text_p_apply_style (OOParseState
*state
,
1741 PangoAttrList
*attrs
,
1745 odf_text_p_apply_style_t data
;
1750 g_return_if_fail (state
->text_p_stack
!= NULL
);
1751 ptr
= state
->text_p_stack
->data
;
1753 if (ptr
->attrs
== NULL
)
1754 ptr
->attrs
= pango_attr_list_new ();
1758 data
.attrs
= ptr
->attrs
;
1760 pango_attr_list_filter (attrs
, odf_text_p_apply_pango_attribute
, &data
);
1764 odf_push_text_p (OOParseState
*state
, gboolean permanent
)
1769 ptr
= &(state
->text_p_for_cell
);
1771 g_string_truncate (ptr
->gstr
, 0);
1773 pango_attr_list_unref (ptr
->attrs
);
1777 ptr
= g_new0 (oo_text_p_t
, 1);
1778 ptr
->permanent
= FALSE
;
1779 ptr
->content_is_simple
= TRUE
;
1781 ptr
->p_seen
= FALSE
;
1783 ptr
->span_style_stack
= NULL
;
1784 ptr
->span_style_list
= NULL
;
1785 state
->text_p_stack
= g_slist_prepend (state
->text_p_stack
, ptr
);
1789 odf_pop_text_p (OOParseState
*state
)
1792 GSList
*link
= state
->text_p_stack
;
1794 g_return_if_fail (state
->text_p_stack
!= NULL
);
1797 g_slist_free (ptr
->span_style_stack
);
1798 /* ptr->span_style_list should be NULL. If it isn't something went wrong and we are leaking here! */
1799 g_slist_free_full (ptr
->span_style_list
, g_free
);
1800 ptr
->span_style_stack
= NULL
;
1801 ptr
->span_style_list
= NULL
;
1802 if (!ptr
->permanent
) {
1804 g_string_free (ptr
->gstr
, TRUE
);
1806 pango_attr_list_unref (ptr
->attrs
);
1810 state
->text_p_stack
= g_slist_remove_link (state
->text_p_stack
, link
);
1811 g_slist_free_1 (link
);
1815 odf_text_content_start (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
1817 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
1818 oo_text_p_t
*ptr
= state
->text_p_stack
->data
;
1821 odf_text_p_add_text (state
, "\n");
1827 odf_text_content_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1829 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
1831 GSList
*list
= NULL
, *l
;
1833 g_return_if_fail ( state
->text_p_stack
!= NULL
);
1834 ptr
= state
->text_p_stack
->data
;
1836 g_return_if_fail (ptr
!= NULL
);
1837 g_return_if_fail (xin
->content
!= NULL
);
1839 if (strlen (xin
->content
->str
) > ptr
->offset
)
1841 (state
, xin
->content
->str
+ ptr
->offset
);
1843 l
= list
= g_slist_reverse(ptr
->span_style_list
);
1845 span_style_info_t
*ssi
= l
->data
;
1847 int start
= ssi
->start
;
1849 char *style_name
= ssi
->style_name
;
1850 if (style_name
!= NULL
&& end
> 0 && end
> start
) {
1851 PangoAttrList
*attrs
= g_hash_table_lookup (state
->styles
.text
, style_name
);
1853 oo_warning (xin
, _("Unknown text style with name \"%s\" encountered!"), style_name
);
1855 odf_text_p_apply_style (state
, attrs
, start
, end
);
1857 g_free (style_name
);
1862 g_slist_free (list
);
1863 ptr
->span_style_list
= NULL
;
1867 odf_text_span_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1869 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
1870 oo_text_p_t
*ptr
= state
->text_p_stack
->data
;
1872 if (ptr
->content_is_simple
) {
1873 span_style_info_t
*ssi
= g_new0 (span_style_info_t
, 1);
1875 if (xin
->content
->str
!= NULL
&& *xin
->content
->str
!= 0) {
1876 odf_text_p_add_text (state
, xin
->content
->str
+ ptr
->offset
);
1877 ptr
->offset
= strlen (xin
->content
->str
);
1880 ssi
->start
= ((ptr
->gstr
) ? ptr
->gstr
->len
: 0);
1882 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
1883 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TEXT
, "style-name"))
1884 ssi
->style_name
= g_strdup (attrs
[1]);
1886 ptr
->span_style_stack
= g_slist_prepend (ptr
->span_style_stack
, ssi
);
1887 ptr
->span_style_list
= g_slist_prepend (ptr
->span_style_list
, ssi
);
1892 odf_text_span_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1894 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
1895 oo_text_p_t
*ptr
= state
->text_p_stack
->data
;
1897 if (ptr
->content_is_simple
) {
1899 span_style_info_t
*ssi
= NULL
;
1901 g_return_if_fail (ptr
->span_style_stack
!= NULL
);
1903 if (xin
->content
->str
!= NULL
&& *xin
->content
->str
!= 0) {
1904 odf_text_p_add_text (state
, xin
->content
->str
+ ptr
->offset
);
1905 ptr
->offset
= strlen (xin
->content
->str
);
1908 end
= ((ptr
->gstr
) ? ptr
->gstr
->len
: 0);
1910 ssi
= ptr
->span_style_stack
->data
;
1911 ptr
->span_style_stack
= g_slist_delete_link (ptr
->span_style_stack
,
1912 ptr
->span_style_stack
);
1919 odf_text_special (GsfXMLIn
*xin
, int count
, char const *sym
)
1921 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
1922 oo_text_p_t
*ptr
= state
->text_p_stack
->data
;
1924 if (ptr
->content_is_simple
) {
1925 if (xin
->content
->str
!= NULL
&& *xin
->content
->str
!= 0) {
1926 odf_text_p_add_text (state
, xin
->content
->str
+ ptr
->offset
);
1927 ptr
->offset
= strlen (xin
->content
->str
);
1931 odf_text_p_add_text (state
, sym
);
1932 else if (count
> 0) {
1933 gchar
*space
= g_strnfill (count
, *sym
);
1934 odf_text_p_add_text (state
, space
);
1941 odf_text_space (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1945 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
1946 if (oo_attr_int_range (xin
, attrs
, OO_NS_TEXT
, "c", &count
, 0, INT_MAX
))
1948 odf_text_special (xin
, count
, " ");
1952 odf_text_symbol (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
1954 odf_text_special (xin
, 1, xin
->node
->user_data
.v_str
);
1957 /* End of handle formatted text inside text:p */
1961 oo_sheet_style_free (OOSheetStyle
*style
)
1964 g_free (style
->master_page_name
);
1970 GHashTable
*orig2fixed
;
1971 GHashTable
*fixed2orig
;
1972 OOParseState
*state
;
1973 GnmNamedExpr
*nexpr
;
1974 char const *nexpr_name
;
1975 } odf_fix_expr_names_t
;
1977 static odf_fix_expr_names_t
*
1978 odf_fix_expr_names_t_new (OOParseState
*state
)
1980 odf_fix_expr_names_t
*fen
= g_new (odf_fix_expr_names_t
, 1);
1982 fen
->fixed2orig
= g_hash_table_new (g_str_hash
, g_str_equal
);
1983 fen
->orig2fixed
= g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, g_free
);
1986 fen
->nexpr_name
= NULL
;
1992 odf_fix_expr_names_t_free (odf_fix_expr_names_t
*fen
)
1994 g_hash_table_unref (fen
->fixed2orig
);
1995 g_hash_table_unref (fen
->orig2fixed
);
2000 odf_fix_expr_names_t_add (odf_fix_expr_names_t
*fen
, char const *orig
, char *fixed
)
2002 char *orig_c
= g_strdup (orig
);
2003 g_hash_table_insert (fen
->orig2fixed
, orig_c
, fixed
);
2004 g_hash_table_insert (fen
->fixed2orig
, fixed
, orig_c
);
2008 odf_fix_en_validate (char const *name
, odf_fix_expr_names_t
*fen
)
2010 if (!expr_name_validate (name
))
2012 if (NULL
!= g_hash_table_lookup (fen
->fixed2orig
, name
))
2015 WORKBOOK_FOREACH_SHEET
2016 (fen
->state
->pos
.wb
, sheet
,
2019 parse_pos_init_sheet (&pp
, sheet
);
2020 if (expr_name_lookup (&pp
, name
))
2028 odf_fix_en_collect (G_GNUC_UNUSED gconstpointer key_
,
2029 GnmNamedExpr
*nexpr
, odf_fix_expr_names_t
*fen
)
2033 const char *name
= expr_name_name (nexpr
);
2035 if (expr_name_validate (name
))
2037 if (NULL
!= g_hash_table_lookup (fen
->orig2fixed
, name
))
2039 str
= g_string_new (name
);
2041 for (here
= str
->str
; *here
; here
= g_utf8_next_char (here
)) {
2042 if (!g_unichar_isalnum (g_utf8_get_char (here
)) &&
2044 int i
, limit
= g_utf8_next_char (here
) - here
;
2045 for (i
= 0; i
<limit
;i
++)
2049 while (!odf_fix_en_validate (str
->str
, fen
))
2050 g_string_append_c (str
, '_');
2051 odf_fix_expr_names_t_add (fen
, name
, g_string_free (str
, FALSE
));
2055 odf_fix_en_find (G_GNUC_UNUSED gconstpointer key
,
2056 GnmNamedExpr
*nexpr
, odf_fix_expr_names_t
*fen
)
2058 if (strcmp (expr_name_name (nexpr
), fen
->nexpr_name
) == 0)
2063 odf_fix_en_apply (const char *orig
, const char *fixed
, odf_fix_expr_names_t
*fen
)
2067 g_return_if_fail (orig
!= NULL
);
2068 g_return_if_fail (fixed
!= NULL
);
2069 g_return_if_fail (fen
!= NULL
);
2071 fen
->nexpr_name
= orig
;
2073 while (i
++ < 1000) {
2075 workbook_foreach_name (fen
->state
->pos
.wb
, FALSE
,
2076 (GHFunc
)odf_fix_en_find
, fen
);
2078 if (fen
->nexpr
== NULL
)
2081 expr_name_set_name (fen
->nexpr
, fixed
);
2088 * When we initialy validate names we have to accept every ODF name
2089 * in odf_fix_expr_names we fix them.
2095 odf_fix_expr_names (OOParseState
*state
)
2097 odf_fix_expr_names_t
*fen
= odf_fix_expr_names_t_new (state
);
2099 workbook_foreach_name (state
->pos
.wb
, FALSE
,
2100 (GHFunc
)odf_fix_en_collect
, fen
);
2101 g_hash_table_foreach (fen
->orig2fixed
, (GHFunc
)odf_fix_en_apply
, fen
);
2103 odf_fix_expr_names_t_free (fen
);
2107 * odf_expr_name_validate:
2108 * @name: tentative name
2110 * returns TRUE if the given name is valid, FALSE otherwise.
2112 * We are accepting names here that contain periods or look like addresses.
2113 * They need to be replaced when we have finished parsing the file since
2114 * they are not allowed inside Gnumeric.
2117 odf_expr_name_validate (const char *name
)
2122 g_return_val_if_fail (name
!= NULL
, FALSE
);
2127 v
= value_new_from_string (VALUE_BOOLEAN
, name
, NULL
, TRUE
);
2129 v
= value_new_from_string (VALUE_BOOLEAN
, name
, NULL
, FALSE
);
2135 /* Hmm... Now what? */
2136 if (!g_unichar_isalpha (g_utf8_get_char (name
)) &&
2140 for (p
= name
; *p
; p
= g_utf8_next_char (p
)) {
2141 if (!g_unichar_isalnum (g_utf8_get_char (p
)) &&
2142 p
[0] != '_' && p
[0] != '.')
2150 * This is ugly! And it's ods' fault.
2152 * On one hand we have function names like ORG.GNUMERIC.LOG2, on the
2153 * other we have inter-sheet name references Sheet2.localname
2154 * The former is a name, the latter is a sheet name, a sheetsep, and
2157 * To resolve that, we look ahead for a '('.
2160 odf_name_parser (char const *str
, GnmConventions
const *convs
)
2162 gunichar uc
= g_utf8_get_char (str
);
2163 const char *firstdot
= NULL
;
2166 if (!g_unichar_isalpha (uc
) && uc
!= '_' && uc
!= '\\')
2170 str
= g_utf8_next_char (str
);
2171 uc
= g_utf8_get_char (str
);
2174 if (dotcount
++ == 0)
2177 } while (g_unichar_isalnum (uc
) ||
2178 (uc
== '_' || uc
== '?' || uc
== '\\' || uc
== '.'));
2180 if (dotcount
== 1 && convs
->sheet_name_sep
== '.') {
2181 const char *p
= str
;
2183 while (g_unichar_isspace (g_utf8_get_char (p
)))
2184 p
= g_utf8_next_char (p
);
2193 static GnmExpr
const *
2194 oo_func_map_in (GnmConventions
const *convs
, Workbook
*scope
,
2195 char const *name
, GnmExprList
*args
);
2197 static GnmConventions
*
2198 oo_conventions_new (OOParseState
*state
, GsfXMLIn
*xin
)
2200 GnmConventions
*conv
= gnm_conventions_new_full
2201 (sizeof (ODFConventions
));
2202 ODFConventions
*oconv
= (ODFConventions
*)conv
;
2203 conv
->decode_ampersands
= TRUE
;
2204 conv
->exp_is_left_associative
= TRUE
;
2206 conv
->intersection_char
= '!';
2207 conv
->union_char
= '~';
2208 conv
->decimal_sep_dot
= TRUE
;
2209 conv
->range_sep_colon
= TRUE
;
2210 conv
->arg_sep
= ';';
2211 conv
->array_col_sep
= ';';
2212 conv
->array_row_sep
= '|';
2213 conv
->input
.string
= odf_strunescape
;
2214 conv
->input
.func
= oo_func_map_in
;
2215 conv
->input
.range_ref
= oo_expr_rangeref_parse
;
2216 conv
->input
.name
= odf_name_parser
;
2217 conv
->input
.name_validate
= odf_expr_name_validate
;
2218 conv
->sheet_name_sep
= '.';
2219 oconv
->state
= state
;
2226 oo_load_convention (OOParseState
*state
, GsfXMLIn
*xin
, OOFormula type
)
2228 GnmConventions
*convs
;
2230 g_return_if_fail (state
->convs
[type
] == NULL
);
2233 case FORMULA_MICROSOFT
:
2234 convs
= gnm_xml_io_conventions ();
2235 convs
->exp_is_left_associative
= TRUE
;
2237 case FORMULA_OLD_OPENOFFICE
:
2238 convs
= oo_conventions_new (state
, xin
);
2239 convs
->sheet_name_sep
= '!'; /* Note that we are using this also as a marker*/
2240 /* in the function handlers */
2242 case FORMULA_OPENFORMULA
:
2244 convs
= oo_conventions_new (state
, xin
);
2248 state
->convs
[type
] = convs
;
2251 static GnmExprTop
const *
2252 oo_expr_parse_str_try (GsfXMLIn
*xin
, char const *str
,
2253 GnmParsePos
const *pp
, GnmExprParseFlags flags
,
2254 OOFormula type
, GnmParseError
*perr
)
2256 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2258 if (state
->convs
[type
] == NULL
)
2259 oo_load_convention (state
, xin
, type
);
2260 return gnm_expr_parse_str (str
, pp
, flags
| GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_INVALID
,
2261 state
->convs
[type
], perr
);
2264 static GnmExprTop
const *
2265 oo_expr_parse_str (GsfXMLIn
*xin
, char const *str
,
2266 GnmParsePos
const *pp
, GnmExprParseFlags flags
,
2269 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2270 GnmExprTop
const *texpr
;
2273 parse_error_init (&perr
);
2275 texpr
= oo_expr_parse_str_try (xin
, str
, pp
, flags
, type
, &perr
);
2276 if (texpr
== NULL
) {
2278 /* There are faulty expressions in the wild that */
2279 /* are references w/o [] */
2280 char *test
= g_strdup_printf ("[%s]", str
);
2281 texpr
= oo_expr_parse_str_try (xin
, test
, pp
,
2286 oo_warning (xin
, _("Unable to parse '%s' ('%s')"),
2287 str
, perr
.err
->message
);
2289 parse_error_free (&perr
);
2292 texpr
= gnm_expr_sharer_share (state
->sharer
, texpr
);
2297 static GnmExprTop
const *
2298 odf_parse_range_address_or_expr (GsfXMLIn
*xin
, char const *str
)
2300 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2301 GnmExprTop
const *texpr
= NULL
;
2302 OOFormula f_type
= odf_get_formula_type (xin
, &str
);
2304 if (str
!= NULL
&& strlen (str
) > 0 && f_type
!= FORMULA_NOT_SUPPORTED
) {
2308 gnm_cellref_init (&ref
.a
, invalid_sheet
, 0, 0, TRUE
);
2309 gnm_cellref_init (&ref
.b
, invalid_sheet
, 0, 0, TRUE
);
2310 ptr
= oo_rangeref_parse
2312 parse_pos_init_sheet (&pp
, state
->pos
.sheet
),
2315 || ref
.a
.sheet
== invalid_sheet
)
2316 texpr
= oo_expr_parse_str (xin
, str
,
2318 GNM_EXPR_PARSE_DEFAULT
,
2321 GnmValue
*v
= value_new_cellrange (&ref
.a
, &ref
.b
, 0, 0);
2322 texpr
= gnm_expr_top_new_constant (v
);
2329 /****************************************************************************/
2332 oo_date_convention (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2334 /* <table:null-date table:date-value="1904-01-01"/> */
2335 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2336 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2337 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "date-value")) {
2338 if (!strncmp (CXML2C (attrs
[1]), "1904", 4))
2339 workbook_set_1904 (state
->pos
.wb
, TRUE
);
2343 oo_iteration (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2345 /* <table:iteration table:status="enable"/> */
2346 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2347 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2348 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "status"))
2349 workbook_iteration_enabled (state
->pos
.wb
,
2350 strcmp (CXML2C (attrs
[1]), "enable") == 0);
2354 odf_pi_parse_format_spec (GsfXMLIn
*xin
, char **fmt
, char const *needle
, char const *tag
)
2356 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2357 GString
*str
= g_string_new (*fmt
);
2359 gchar
*found
= NULL
;
2361 while (NULL
!= (found
= g_strstr_len (str
->str
+ start
, -1, needle
))) {
2362 char *op_start
= found
+ strlen (needle
);
2363 gchar
*p
= op_start
;
2365 while (*p
&& (*p
!= ']'))
2368 char *id
= g_strndup (op_start
, p
- op_start
);
2369 char const *formula
= g_hash_table_lookup (state
->strings
, id
);
2370 char const *orig_formula
= formula
;
2372 GnmExprTop
const *texpr
= NULL
;
2374 gint start_pos
= found
- str
->str
;
2377 g_string_erase (str
, start_pos
, p
- found
+ 1);
2379 if (formula
== NULL
)
2382 f_type
= odf_get_formula_type (xin
, &formula
);
2383 if (f_type
== FORMULA_NOT_SUPPORTED
) {
2384 oo_warning (xin
, _("Unsupported formula type encountered: %s"),
2388 formula
= gnm_expr_char_start_p (formula
);
2389 if (formula
== NULL
) {
2390 oo_warning (xin
, _("Expression '%s' does not start "
2391 "with a recognized character"), orig_formula
);
2394 texpr
= oo_expr_parse_str
2395 (xin
, formula
, &state
->pos
, GNM_EXPR_PARSE_DEFAULT
, f_type
);
2397 if (texpr
!= NULL
) {
2398 text
= gnm_expr_top_as_string (texpr
, &state
->pos
,
2399 gnm_conventions_default
);
2400 gnm_expr_top_unref (texpr
);
2405 subs
= g_strdup_printf ("&[%s:%s]", tag
, text
);
2408 g_string_insert (str
, start_pos
, subs
);
2409 start
= start_pos
+ strlen (subs
);
2418 *fmt
= g_string_free (str
, FALSE
);
2422 odf_pi_parse_format (GsfXMLIn
*xin
, char **fmt
)
2424 if ((*fmt
== NULL
) ||
2425 (NULL
== g_strstr_len (*fmt
, -1, "&[cell")))
2428 odf_pi_parse_format_spec (xin
, fmt
, "&[cellt:", NULL
);
2429 odf_pi_parse_format_spec (xin
, fmt
, "&[cell:", _("cell"));
2433 odf_pi_parse_hf (GsfXMLIn
*xin
, GnmPrintHF
*hf
)
2435 odf_pi_parse_format (xin
, &hf
->left_format
);
2436 odf_pi_parse_format (xin
, &hf
->middle_format
);
2437 odf_pi_parse_format (xin
, &hf
->right_format
);
2441 odf_pi_parse_expressions (GsfXMLIn
*xin
, GnmPrintInformation
*pi
)
2443 odf_pi_parse_hf (xin
, pi
->header
);
2444 odf_pi_parse_hf (xin
, pi
->footer
);
2448 oo_table_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2450 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2451 gchar
*style_name
= NULL
;
2452 gchar
*print_range
= NULL
;
2453 gboolean do_not_print
= FALSE
, tmp_b
;
2455 state
->pos
.eval
.col
= 0;
2456 state
->pos
.eval
.row
= 0;
2457 state
->print
.rep_rows_from
= -1;
2458 state
->print
.rep_rows_to
= -1;
2459 state
->print
.rep_cols_from
= -1;
2460 state
->print
.rep_cols_to
= -1;
2462 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2463 /* We need not check for the table name since we did that during pre-parsing */
2464 /* if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_TABLE, "name")) { */
2465 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "style-name")) {
2466 style_name
= g_strdup (CXML2C (attrs
[1]));
2467 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "print-ranges")) {
2468 print_range
= g_strdup (CXML2C (attrs
[1]));
2469 } else if (oo_attr_bool (xin
, attrs
, OO_NS_TABLE
, "print", &tmp_b
))
2470 do_not_print
= !tmp_b
;
2473 state
->pos
.sheet
= ((sheet_order_t
*)g_slist_nth_data (state
->sheet_order
, state
->table_n
))->sheet
;
2475 if (style_name
!= NULL
) {
2476 OOSheetStyle
const *style
= g_hash_table_lookup (state
->styles
.sheet
, style_name
);
2478 GnmPrintInformation
*pi
= NULL
;
2479 if (style
->master_page_name
)
2480 pi
= g_hash_table_lookup (state
->styles
.master_pages
,
2481 style
->master_page_name
);
2483 gnm_print_info_free (state
->pos
.sheet
->print_info
);
2484 state
->pos
.sheet
->print_info
= gnm_print_info_dup (pi
);
2485 odf_pi_parse_expressions (xin
, state
->pos
.sheet
->print_info
);
2487 g_object_set (state
->pos
.sheet
,
2488 "visibility", style
->visibility
,
2489 "text-is-rtl", style
->is_rtl
,
2490 "display-formulas", style
->display_formulas
,
2491 "display-column-header", !style
->hide_col_header
,
2492 "display-row-header", !style
->hide_row_header
,
2494 if (style
->tab_color_set
) {
2496 = gnm_color_new_go (style
->tab_color
);
2502 style_color_unref (color
);
2504 if (style
->tab_text_color_set
){
2507 (style
->tab_text_color
);
2513 style_color_unref (color
);
2517 g_free (style_name
);
2520 state
->pos
.sheet
->print_info
->do_not_print
= do_not_print
;
2522 if (state
->default_style
.rows
!= NULL
)
2523 sheet_row_set_default_size_pts (state
->pos
.sheet
,
2524 state
->default_style
.rows
->size_pts
);
2525 if (state
->default_style
.columns
!= NULL
)
2526 sheet_col_set_default_size_pts (state
->pos
.sheet
,
2527 state
->default_style
.columns
->size_pts
);
2528 if (print_range
!= NULL
) {
2529 GnmExprTop
const *texpr
= odf_parse_range_address_or_expr (xin
, print_range
);
2530 if (texpr
!= NULL
) {
2531 GnmNamedExpr
*nexpr
= expr_name_lookup (&state
->pos
, "Print_Area");
2533 expr_name_set_expr (nexpr
, texpr
);
2539 odf_shapes (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2541 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2542 state
->pos
.eval
.col
= -1; /* we use that to know that objects have absolute anchors */
2546 odf_shapes_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2548 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2549 state
->pos
.eval
.col
= 0;
2553 odf_init_pp (GnmParsePos
*pp
, GsfXMLIn
*xin
, gchar
const *base
)
2555 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2558 if (base
!= NULL
&& *base
!= 0) {
2559 GnmExprTop
const *texpr
= NULL
;
2560 char *tmp
= g_strconcat ("[", base
, "]", NULL
);
2562 /* base-cell-addresses are always required to be absolute (and contain a sheet name) */
2563 parse_pos_init (&ppp
, state
->pos
.wb
, state
->pos
.sheet
, 0, 0);
2564 texpr
= oo_expr_parse_str
2566 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
,
2567 FORMULA_OPENFORMULA
);
2569 if (texpr
!= NULL
) {
2570 if (GNM_EXPR_GET_OPER (texpr
->expr
) ==
2571 GNM_EXPR_OP_CELLREF
) {
2572 GnmCellRef
const *ref
= &texpr
->expr
->cellref
.ref
;
2573 parse_pos_init (pp
, state
->pos
.wb
, ref
->sheet
,
2574 ref
->col
, ref
->row
);
2576 gnm_expr_top_unref (texpr
);
2582 static GnmValidation
*
2583 odf_validation_new_list (GsfXMLIn
*xin
, odf_validation_t
*val
, guint offset
)
2585 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2586 GnmValidation
*validation
= NULL
;
2587 char *start
= NULL
, *end
= NULL
;
2589 GnmExprTop
const *texpr
= NULL
;
2592 start
= strchr (val
->condition
+ offset
, '(');
2594 end
= strrchr (start
, ')');
2598 odf_init_pp (&pp
, xin
, val
->base_cell_address
);
2600 if (*(start
+ 1) == '\"') {
2601 str
= g_string_new ("{");
2602 g_string_append_len (str
, start
+ 1, end
- start
- 1);
2603 g_string_append_c (str
, '}');
2605 str
= g_string_new (NULL
);
2606 g_string_append_len (str
, start
+ 1, end
- start
- 1);
2609 texpr
= oo_expr_parse_str (xin
, str
->str
, &pp
,
2610 GNM_EXPR_PARSE_DEFAULT
,
2614 validation
= gnm_validation_new (val
->style
,
2615 GNM_VALIDATION_TYPE_IN_LIST
,
2616 GNM_VALIDATION_OP_NONE
,
2619 val
->message
? val
->message
->str
: NULL
,
2625 g_string_free (str
, TRUE
);
2630 static GnmValidation
*
2631 odf_validation_new_single_expr (GsfXMLIn
*xin
, odf_validation_t
*val
,
2632 char const *start
, ValidationType val_type
,
2633 ValidationOp val_op
)
2635 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2636 GnmExprTop
const *texpr
= NULL
;
2638 GnmExprParseFlags flag
;
2640 odf_init_pp (&pp
, xin
, val
->base_cell_address
);
2641 flag
= (pp
.sheet
== NULL
|| state
->pos
.sheet
== pp
.sheet
)
2642 ? GNM_EXPR_PARSE_DEFAULT
2643 : GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
;
2645 texpr
= oo_expr_parse_str (xin
, start
, &pp
, flag
, val
->f_type
);
2648 return gnm_validation_new (val
->style
,
2653 val
->message
? val
->message
->str
: NULL
,
2663 static GnmValidation
*
2664 odf_validation_new_pair_expr (GsfXMLIn
*xin
, odf_validation_t
*val
,
2665 char const *start
, ValidationType val_type
,
2666 ValidationOp val_op
)
2668 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2670 GnmExprParseFlags flag
;
2671 GnmExprTop
const *texpr_a
= NULL
, *texpr_b
= NULL
;
2673 guint len
= strlen (start
);
2675 if (*start
!= '(' || *(start
+ len
- 1) != ')')
2679 pair
= g_strndup (start
, len
);
2681 odf_init_pp (&pp
, xin
, val
->base_cell_address
);
2682 flag
= (pp
.sheet
== NULL
|| state
->pos
.sheet
== pp
.sheet
)
2683 ? GNM_EXPR_PARSE_DEFAULT
2684 : GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
;
2687 gchar
* try = g_strrstr_len (pair
, len
, ",");
2688 GnmExprTop
const *texpr
;
2690 if (try == NULL
|| try == pair
)
2693 texpr
= oo_expr_parse_str (xin
, try + 1, &pp
, flag
, val
->f_type
);
2694 if (texpr
!= NULL
) {
2699 len
= try - pair
- 1;
2701 texpr_a
= oo_expr_parse_str (xin
, pair
, &pp
, flag
, val
->f_type
);
2703 if (texpr_b
!= NULL
) {
2705 return gnm_validation_new (val
->style
,
2710 val
->message
? val
->message
->str
: NULL
,
2721 static GnmValidation
*
2722 odf_validation_new_between (GsfXMLIn
*xin
, odf_validation_t
*val
, guint offset
, ValidationType vtype
,
2725 char *start
= val
->condition
+ offset
;
2727 while (*start
== ' ')
2730 return odf_validation_new_pair_expr
2731 (xin
, val
, start
, vtype
, no_not
? GNM_VALIDATION_OP_BETWEEN
: GNM_VALIDATION_OP_NOT_BETWEEN
);
2734 static GnmValidation
*
2735 odf_validation_new_op (GsfXMLIn
*xin
, odf_validation_t
*val
, guint offset
, ValidationType vtype
)
2737 char *start
= val
->condition
+ offset
;
2738 ValidationOp val_op
= GNM_VALIDATION_OP_NONE
;
2740 while (*start
== ' ')
2743 if (g_str_has_prefix (start
, ">=")) {
2744 val_op
= GNM_VALIDATION_OP_GTE
;
2746 } else if (g_str_has_prefix (start
, "<=")) {
2747 val_op
= GNM_VALIDATION_OP_LTE
;
2749 } else if (g_str_has_prefix (start
, "!=")) {
2750 val_op
= GNM_VALIDATION_OP_NOT_EQUAL
;
2752 } else if (g_str_has_prefix (start
, "=")) {
2753 val_op
= GNM_VALIDATION_OP_EQUAL
;
2755 } else if (g_str_has_prefix (start
, ">")) {
2756 val_op
= GNM_VALIDATION_OP_GT
;
2758 } else if (g_str_has_prefix (start
, "<")) {
2759 val_op
= GNM_VALIDATION_OP_LT
;
2763 if (val_op
== GNM_VALIDATION_OP_NONE
)
2766 while (*start
== ' ')
2769 return odf_validation_new_single_expr
2770 (xin
, val
, start
, vtype
, val_op
);
2773 static GnmValidation
*
2774 odf_validations_analyze (GsfXMLIn
*xin
, odf_validation_t
*val
, guint offset
,
2775 ValidationType vtype
, OOFormula f_type
)
2777 char const *str
= val
->condition
+ offset
;
2782 if (g_str_has_prefix (str
, "cell-content-is-in-list"))
2783 return odf_validation_new_list
2784 (xin
, val
, str
- val
->condition
+ strlen ("cell-content-is-in-list"));
2785 else if (g_str_has_prefix (str
, "cell-content-text-length()"))
2786 return odf_validation_new_op
2787 (xin
, val
, str
- val
->condition
+ strlen ("cell-content-text-length()"),
2788 GNM_VALIDATION_TYPE_TEXT_LENGTH
);
2789 else if (g_str_has_prefix (str
, "cell-content-text-length-is-between"))
2790 return odf_validation_new_between
2791 (xin
, val
, str
- val
->condition
+ strlen ("cell-content-text-length-is-between"),
2792 GNM_VALIDATION_TYPE_TEXT_LENGTH
, TRUE
);
2793 else if (g_str_has_prefix (str
, "cell-content-text-length-is-not-between"))
2794 return odf_validation_new_between
2795 (xin
, val
, str
- val
->condition
+ strlen ("cell-content-text-length-is-not-between"),
2796 GNM_VALIDATION_TYPE_TEXT_LENGTH
, FALSE
);
2797 else if (g_str_has_prefix (str
, "cell-content-is-decimal-number() and"))
2798 return odf_validations_analyze
2799 (xin
, val
, str
- val
->condition
+ strlen ("cell-content-is-decimal-number() and"),
2800 GNM_VALIDATION_TYPE_AS_NUMBER
, f_type
);
2801 else if (g_str_has_prefix (str
, "cell-content-is-whole-number() and"))
2802 return odf_validations_analyze
2803 (xin
, val
, str
- val
->condition
+ strlen ("cell-content-is-whole-number() and"),
2804 GNM_VALIDATION_TYPE_AS_INT
, f_type
);
2805 else if (g_str_has_prefix (str
, "cell-content-is-date() and"))
2806 return odf_validations_analyze
2807 (xin
, val
, str
- val
->condition
+ strlen ("cell-content-is-date() and"),
2808 GNM_VALIDATION_TYPE_AS_DATE
, f_type
);
2809 else if (g_str_has_prefix (str
, "cell-content-is-time() and"))
2810 return odf_validations_analyze
2811 (xin
, val
, str
- val
->condition
+ strlen ("cell-content-is-time() and"),
2812 GNM_VALIDATION_TYPE_AS_TIME
, f_type
);
2813 else if (g_str_has_prefix (str
, "is-true-formula(") && g_str_has_suffix (str
, ")")) {
2814 GString
*gstr
= g_string_new (str
+ strlen ("is-true-formula("));
2815 GnmValidation
*validation
;
2816 g_string_truncate (gstr
, gstr
->len
- 1);
2817 if (vtype
!= GNM_VALIDATION_TYPE_ANY
) {
2819 (xin
, _("Validation condition '%s' is not supported. "
2820 "It has been changed to '%s'."),
2821 val
->condition
, str
);
2823 validation
= odf_validation_new_single_expr
2824 (xin
, val
, gstr
->str
, GNM_VALIDATION_TYPE_CUSTOM
,
2825 GNM_VALIDATION_OP_NONE
);
2826 g_string_free (gstr
, TRUE
);
2828 } else if (g_str_has_prefix (str
, "cell-content()"))
2829 return odf_validation_new_op
2830 (xin
, val
, str
- val
->condition
+ strlen ("cell-content()"),
2832 else if (g_str_has_prefix (str
, "cell-content-is-between"))
2833 return odf_validation_new_between
2834 (xin
, val
, str
- val
->condition
+ strlen ("cell-content-is-between"),
2836 else if (g_str_has_prefix (str
, "cell-content-is-not-between"))
2837 return odf_validation_new_between
2838 (xin
, val
, str
- val
->condition
+ strlen ("cell-content-is-not-between"),
2844 static GnmInputMsg
*
2845 odf_validation_get_input_message (GsfXMLIn
*xin
, char const *name
)
2847 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2848 odf_validation_t
*val
= g_hash_table_lookup (state
->validations
, name
);
2853 if ((val
->help_message
!= NULL
&& val
->help_message
->len
> 0) ||
2854 (val
->help_title
!= NULL
&& strlen (val
->help_title
) > 0))
2855 return gnm_input_msg_new (val
->help_message
? val
->help_message
->str
: NULL
, val
->help_title
);
2860 static GnmValidation
*
2861 odf_validations_translate (GsfXMLIn
*xin
, char const *name
)
2863 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2864 odf_validation_t
*val
= g_hash_table_lookup (state
->validations
, name
);
2868 (xin
, _("Undefined validation style encountered: %s"),
2873 if (val
->condition
!= NULL
&& val
->f_type
!= FORMULA_NOT_SUPPORTED
) {
2874 const char *str
= val
->condition
;
2875 GnmValidation
*validation
;
2876 OOFormula f_type
= odf_get_formula_type (xin
, &str
);
2877 validation
= odf_validations_analyze
2878 (xin
, val
, str
- val
->condition
, GNM_VALIDATION_TYPE_ANY
, f_type
);
2879 if (validation
!= NULL
) {
2881 if (NULL
== (err
= gnm_validation_is_ok (validation
)))
2885 _("Ignoring invalid data "
2886 "validation because : %s"),
2888 gnm_validation_unref (validation
);
2893 if (val
->condition
!= NULL
)
2894 oo_warning (xin
, _("Unsupported validation condition "
2895 "encountered: \"%s\" with base address: \"%s\""),
2896 val
->condition
, val
->base_cell_address
);
2902 odf_validation_free (odf_validation_t
*val
)
2904 g_free (val
->condition
);
2905 g_free (val
->base_cell_address
);
2906 g_free (val
->title
);
2907 g_free (val
->help_title
);
2909 g_string_free (val
->message
, TRUE
);
2910 if (val
->help_message
)
2911 g_string_free (val
->help_message
, TRUE
);
2915 static odf_validation_t
*
2916 odf_validation_new (void)
2918 odf_validation_t
*val
= g_new0 (odf_validation_t
, 1);
2919 val
->use_dropdown
= TRUE
;
2920 val
->allow_blank
= TRUE
;
2921 val
->f_type
= FORMULA_NOT_SUPPORTED
;
2922 val
->style
= GNM_VALIDATION_STYLE_WARNING
;
2927 odf_validation (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2929 static OOEnum
const dropdown_types
[] = {
2931 { "sort-ascending", 1 },
2936 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2937 char const *name
= NULL
;
2939 odf_validation_t
*validation
= odf_validation_new ();
2941 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2){
2942 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
2943 OO_NS_TABLE
, "name" )) {
2944 name
= CXML2C (attrs
[1]);
2945 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
2946 OO_NS_TABLE
, "condition")) {
2947 char const *cond
= CXML2C (attrs
[1]);
2948 validation
->f_type
= odf_get_formula_type (xin
, &cond
);
2949 validation
->condition
= g_strdup (cond
);
2950 } else if (oo_attr_bool (xin
, attrs
,
2951 OO_NS_TABLE
, "allow-empty-cell",
2952 &validation
->allow_blank
)) {
2953 } else if (oo_attr_enum (xin
, attrs
, OO_NS_TABLE
, "display-list", dropdown_types
, &tmp
)) {
2954 validation
->use_dropdown
= (tmp
== 1);
2955 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
2956 OO_NS_TABLE
, "base-cell-address")) {
2957 validation
->base_cell_address
= g_strdup (CXML2C (attrs
[1]));
2961 g_hash_table_insert (state
->validations
, g_strdup (name
), validation
);
2962 state
->cur_validation
= validation
;
2964 odf_validation_free (validation
);
2965 state
->cur_validation
= NULL
;
2971 odf_validation_error_message (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2973 static OOEnum
const message_styles
[] = {
2974 { "information", GNM_VALIDATION_STYLE_INFO
},
2975 { "stop", GNM_VALIDATION_STYLE_STOP
},
2976 { "warning", GNM_VALIDATION_STYLE_WARNING
},
2980 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
2983 if (state
->cur_validation
)
2984 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2){
2985 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
2986 OO_NS_TABLE
, "title" )) {
2987 g_free (state
->cur_validation
->title
);
2988 state
->cur_validation
->title
= g_strdup (CXML2C (attrs
[1]));
2989 } else if (oo_attr_enum (xin
, attrs
, OO_NS_TABLE
, "message-type", message_styles
, &tmp
))
2990 state
->cur_validation
->style
= tmp
;
2991 /* ignoring TABLE "display" */
2994 odf_push_text_p (state
, FALSE
);
2998 odf_validation_error_message_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3001 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3003 g_return_if_fail (state
->text_p_stack
!= NULL
);
3004 ptr
= state
->text_p_stack
->data
;
3005 g_return_if_fail (ptr
!= NULL
);
3007 if (state
->cur_validation
) {
3008 state
->cur_validation
->message
= ptr
->gstr
;
3011 odf_pop_text_p (state
);
3015 odf_validation_help_message (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3017 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3019 if (state
->cur_validation
)
3020 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2){
3021 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
3022 OO_NS_TABLE
, "title" )) {
3023 g_free (state
->cur_validation
->help_title
);
3024 state
->cur_validation
->help_title
= g_strdup (CXML2C (attrs
[1]));
3026 /* ignoring TABLE "display" */
3029 odf_push_text_p (state
, FALSE
);
3033 odf_validation_help_message_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3036 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3038 g_return_if_fail (state
->text_p_stack
!= NULL
);
3039 ptr
= state
->text_p_stack
->data
;
3040 g_return_if_fail (ptr
!= NULL
);
3042 if (state
->cur_validation
) {
3043 state
->cur_validation
->help_message
= ptr
->gstr
;
3046 odf_pop_text_p (state
);
3050 odf_adjust_offsets_col (OOParseState
*state
, int *col
, double *x
, gboolean absolute
)
3052 ColRowInfo
const *cr
= sheet_col_get_info (state
->pos
.sheet
,
3054 int last
= gnm_sheet_get_last_col (state
->pos
.sheet
);
3055 if (absolute
&& *col
> 0)
3056 *x
-= sheet_col_get_distance_pts (state
->pos
.sheet
, 0, *col
);
3057 while (cr
->size_pts
< *x
&& *col
< last
) {
3059 (*x
) -= cr
->size_pts
;
3060 cr
= sheet_col_get_info (state
->pos
.sheet
, *col
);
3062 while (*x
< 0 && *col
> 0) {
3064 cr
= sheet_col_get_info (state
->pos
.sheet
, *col
);
3065 (*x
) += cr
->size_pts
;
3071 odf_adjust_offsets_row (OOParseState
*state
, int *row
, double *y
, gboolean absolute
)
3073 ColRowInfo
const *cr
= sheet_row_get_info (state
->pos
.sheet
,
3075 int last
= gnm_sheet_get_last_row (state
->pos
.sheet
);
3076 if (absolute
&& *row
> 0)
3077 *y
-= sheet_row_get_distance_pts (state
->pos
.sheet
, 0, *row
);
3078 while (cr
->size_pts
< *y
&& *row
< last
) {
3080 (*y
) -= cr
->size_pts
;
3081 cr
= sheet_row_get_info (state
->pos
.sheet
, *row
);
3083 while (*y
< 0 && *row
> 0) {
3085 cr
= sheet_row_get_info (state
->pos
.sheet
, *row
);
3086 (*y
) += cr
->size_pts
;
3092 odf_adjust_offsets (OOParseState
*state
, GnmCellPos
*pos
, double *x
, double *y
, gboolean absolute
)
3094 odf_adjust_offsets_col (state
, &pos
->col
, x
, absolute
);
3095 odf_adjust_offsets_row (state
, &pos
->row
, y
, absolute
);
3099 odf_z_idx_compare (gconstpointer a
, gconstpointer b
)
3101 object_offset_t
const *za
= a
, *zb
= b
;
3103 /* We are sorting indices in increasing order! */
3104 return (za
->z_index
- zb
->z_index
);
3108 odf_destroy_object_offset (gpointer data
)
3110 object_offset_t
*ob_off
= data
;
3112 g_free (ob_off
->control
);
3113 g_object_unref (ob_off
->so
);
3118 odf_complete_control_setup (OOParseState
*state
, object_offset_t
const *ob_off
)
3120 OOControl
*oc
= g_hash_table_lookup (state
->controls
, ob_off
->control
);
3121 GnmExprTop
const *result_texpr
= NULL
;
3122 SheetObject
*so
= ob_off
->so
;
3127 if ((oc
->t
== sheet_widget_checkbox_get_type () ||
3128 oc
->t
== sheet_widget_radio_button_get_type ()) && oc
->current_state
!= NULL
)
3129 g_object_set (G_OBJECT (so
), "active",
3130 strcmp (oc
->current_state
, "checked") == 0 ||
3131 strcmp (oc
->current_state
, "true") == 0, NULL
);
3132 if (oc
->linked_cell
) {
3135 char const *ptr
= oo_rangeref_parse
3136 (&ref
, oc
->linked_cell
,
3137 parse_pos_init_sheet (&pp
, state
->pos
.sheet
),
3139 if (ptr
!= oc
->linked_cell
3140 && ref
.a
.sheet
!= invalid_sheet
) {
3141 GnmValue
*v
= value_new_cellrange
3142 (&ref
.a
, &ref
.a
, 0, 0);
3143 GnmExprTop
const *texpr
3144 = gnm_expr_top_new_constant (v
);
3145 if (texpr
!= NULL
) {
3146 if (oc
->t
== sheet_widget_scrollbar_get_type () ||
3147 oc
->t
== sheet_widget_spinbutton_get_type () ||
3148 oc
->t
== sheet_widget_slider_get_type ())
3149 sheet_widget_adjustment_set_link
3151 else if (oc
->t
== sheet_widget_checkbox_get_type ())
3152 sheet_widget_checkbox_set_link
3154 else if (oc
->t
== sheet_widget_radio_button_get_type ())
3155 sheet_widget_radio_button_set_link
3157 else if (oc
->t
== sheet_widget_button_get_type ())
3158 sheet_widget_button_set_link
3160 else if (oc
->t
== sheet_widget_list_get_type () ||
3161 oc
->t
== sheet_widget_combo_get_type ()) {
3162 gnm_expr_top_ref ((result_texpr
= texpr
));
3163 sheet_widget_list_base_set_links (so
, texpr
, NULL
);
3165 gnm_expr_top_unref (texpr
);
3169 if (oc
->t
== sheet_widget_list_get_type () ||
3170 oc
->t
== sheet_widget_combo_get_type ()) {
3171 if (oc
->source_cell_range
) {
3174 char const *ptr
= oo_rangeref_parse
3175 (&ref
, oc
->source_cell_range
,
3176 parse_pos_init_sheet (&pp
, state
->pos
.sheet
),
3178 if (ptr
!= oc
->source_cell_range
&&
3179 ref
.a
.sheet
!= invalid_sheet
) {
3180 GnmValue
*v
= value_new_cellrange
3181 (&ref
.a
, &ref
.b
, 0, 0);
3182 GnmExprTop
const *texpr
3183 = gnm_expr_top_new_constant (v
);
3184 if (texpr
!= NULL
) {
3185 sheet_widget_list_base_set_links
3187 result_texpr
, texpr
);
3188 gnm_expr_top_unref (texpr
);
3192 if (result_texpr
!= NULL
)
3193 gnm_expr_top_unref (result_texpr
);
3194 sheet_widget_list_base_set_result_type (so
, oc
->as_index
);
3199 oo_table_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3201 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3202 int max_cols
, max_rows
;
3206 maybe_update_progress (xin
);
3208 if (NULL
!= state
->print
.page_breaks
.h
) {
3209 print_info_set_breaks (state
->pos
.sheet
->print_info
,
3210 state
->print
.page_breaks
.h
);
3211 state
->print
.page_breaks
.h
= NULL
;
3213 if (NULL
!= state
->print
.page_breaks
.v
) {
3214 print_info_set_breaks (state
->pos
.sheet
->print_info
,
3215 state
->print
.page_breaks
.v
);
3216 state
->print
.page_breaks
.v
= NULL
;
3219 max_cols
= gnm_sheet_get_max_cols (state
->pos
.sheet
);
3220 max_rows
= gnm_sheet_get_max_rows (state
->pos
.sheet
);
3222 if (state
->print
.rep_rows_from
>= 0) {
3223 if (state
->print
.rep_rows_to
< 0)
3224 state
->print
.rep_rows_to
= max_rows
- 1;
3225 g_free (state
->pos
.sheet
->print_info
->repeat_top
);
3226 state
->pos
.sheet
->print_info
->repeat_top
3227 = g_strdup (rows_name (state
->print
.rep_rows_from
,
3228 state
->print
.rep_rows_to
));
3230 if (state
->print
.rep_cols_from
>= 0) {
3231 if (state
->print
.rep_cols_to
< 0)
3232 state
->print
.rep_cols_to
= max_cols
- 1;
3233 g_free (state
->pos
.sheet
->print_info
->repeat_left
);
3234 state
->pos
.sheet
->print_info
->repeat_left
3235 = g_strdup (cols_name (state
->print
.rep_cols_from
,
3236 state
->print
.rep_cols_to
));
3239 /* We need to fix the anchors of all offsets, ensure that each object has an "odf-z-index", */
3240 /* and add the objects in the correct order. */
3241 state
->chart_list
= g_slist_reverse (state
->chart_list
);
3243 for (l
= state
->chart_list
; l
!= NULL
; l
= l
->next
) {
3244 object_offset_t
*ob_off
= l
->data
;
3245 if (top_z
< ob_off
->z_index
)
3246 top_z
= ob_off
->z_index
;
3249 for (l
= state
->chart_list
; l
!= NULL
; l
= l
->next
) {
3250 object_offset_t
*ob_off
= l
->data
;
3251 if (ob_off
->z_index
< 0) {
3253 ob_off
->z_index
= top_z
;
3255 g_print ("Object Ordering: Object without z-index encountered.\n");
3259 state
->chart_list
= g_slist_sort (state
->chart_list
,
3263 for (l
= state
->chart_list
; l
!= NULL
; l
= l
->next
) {
3264 object_offset_t
*ob_off
= l
->data
;
3265 SheetObjectAnchor
new;
3266 SheetObjectAnchor
const *old
= sheet_object_get_anchor (ob_off
->so
);
3267 GnmRange cell_base
= *sheet_object_get_range (ob_off
->so
);
3269 if (old
->mode
!= GNM_SO_ANCHOR_ABSOLUTE
) {
3270 odf_adjust_offsets (state
, &cell_base
.start
, &ob_off
->frame_offset
[0],
3271 &ob_off
->frame_offset
[1], ob_off
->absolute_distance
);
3272 if (old
->mode
== GNM_SO_ANCHOR_TWO_CELLS
)
3273 odf_adjust_offsets (state
, &cell_base
.end
, &ob_off
->frame_offset
[2],
3274 &ob_off
->frame_offset
[3], ob_off
->absolute_distance
);
3276 sheet_object_anchor_init (&new, &cell_base
, ob_off
->frame_offset
,
3277 old
->base
.direction
,
3279 sheet_object_set_anchor (ob_off
->so
, &new);
3281 sheet_object_set_sheet (ob_off
->so
, state
->pos
.sheet
);
3282 if (ob_off
->control
)
3283 odf_complete_control_setup (state
, ob_off
);
3284 odf_destroy_object_offset (ob_off
);
3288 g_slist_free (state
->chart_list
);
3289 state
->chart_list
= NULL
;
3290 state
->pos
.eval
.col
= state
->pos
.eval
.row
= 0;
3291 state
->pos
.sheet
= NULL
;
3295 oo_append_page_break (OOParseState
*state
, int pos
, gboolean is_vert
, gboolean is_manual
)
3297 GnmPageBreaks
*breaks
;
3300 if (NULL
== (breaks
= state
->print
.page_breaks
.v
))
3301 breaks
= state
->print
.page_breaks
.v
= gnm_page_breaks_new (TRUE
);
3303 if (NULL
== (breaks
= state
->print
.page_breaks
.h
))
3304 breaks
= state
->print
.page_breaks
.h
= gnm_page_breaks_new (FALSE
);
3307 gnm_page_breaks_append_break (breaks
, pos
,
3308 is_manual
? GNM_PAGE_BREAK_MANUAL
: GNM_PAGE_BREAK_NONE
);
3312 oo_set_page_break (OOParseState
*state
, int pos
, gboolean is_vert
, gboolean is_manual
)
3314 GnmPageBreaks
*breaks
= (is_vert
) ? state
->print
.page_breaks
.v
: state
->print
.page_breaks
.h
;
3316 switch (gnm_page_breaks_get_break (breaks
, pos
)) {
3317 case GNM_PAGE_BREAK_NONE
:
3318 oo_append_page_break (state
, pos
, is_vert
, is_manual
);
3320 case GNM_PAGE_BREAK_MANUAL
:
3322 case GNM_PAGE_BREAK_AUTO
:
3325 gnm_page_breaks_set_break (breaks
, pos
, GNM_PAGE_BREAK_MANUAL
);
3331 oo_col_row_style_apply_breaks (OOParseState
*state
, OOColRowStyle
*cr_style
,
3332 int pos
, gboolean is_vert
)
3335 if (cr_style
->break_before
!= OO_PAGE_BREAK_NONE
)
3336 oo_set_page_break (state
, pos
, is_vert
,
3337 cr_style
->break_before
== OO_PAGE_BREAK_MANUAL
);
3338 if (cr_style
->break_after
!= OO_PAGE_BREAK_NONE
)
3339 oo_append_page_break (state
, pos
+1, is_vert
,
3340 cr_style
->break_after
== OO_PAGE_BREAK_MANUAL
);
3344 oo_update_data_extent (OOParseState
*state
, int cols
, int rows
)
3346 if (state
->extent_data
.col
< (state
->pos
.eval
.col
+ cols
- 1))
3347 state
->extent_data
.col
= state
->pos
.eval
.col
+ cols
- 1;
3348 if (state
->extent_data
.row
< (state
->pos
.eval
.row
+ rows
- 1))
3349 state
->extent_data
.row
= state
->pos
.eval
.row
+ rows
- 1;
3352 static OOCellStyle
*
3353 odf_oo_cell_style_new (GnmStyle
*style
)
3355 OOCellStyle
*oostyle
= g_new0 (OOCellStyle
, 1);
3358 oostyle
->style
= gnm_style_dup (style
);
3360 oostyle
->style
= gnm_style_new ();
3365 odf_oo_cell_style_unref (OOCellStyle
*oostyle
)
3367 if (oostyle
!= NULL
&& (--(oostyle
->ref
)) == 0) {
3368 gnm_style_unref (oostyle
->style
);
3369 g_slist_free_full (oostyle
->styles
, (GDestroyNotify
) odf_oo_cell_style_unref
);
3370 g_slist_free_full (oostyle
->conditions
, g_free
);
3371 g_slist_free_full (oostyle
->bases
, g_free
);
3376 static OOCellStyle
*
3377 odf_oo_cell_style_ref (OOCellStyle
*oostyle
)
3383 static OOCellStyle
*
3384 odf_oo_cell_style_copy (OOCellStyle
*oostyle
)
3386 OOCellStyle
*new = odf_oo_cell_style_new (oostyle
->style
);
3387 new->styles
= go_slist_map (oostyle
->styles
, (GOMapFunc
)odf_oo_cell_style_ref
);
3388 new->conditions
= go_slist_map (oostyle
->conditions
, (GOMapFunc
)g_strdup
);
3389 new->bases
= go_slist_map (oostyle
->bases
, (GOMapFunc
)g_strdup
);
3394 odf_oo_cell_style_attach_condition (OOCellStyle
*oostyle
, OOCellStyle
*cstyle
,
3395 gchar
const *condition
, gchar
const *base
)
3397 g_return_if_fail (oostyle
!= NULL
);
3398 g_return_if_fail (cstyle
!= NULL
);
3399 g_return_if_fail (condition
!= NULL
);
3404 oostyle
->styles
= g_slist_append (oostyle
->styles
, odf_oo_cell_style_ref (cstyle
));
3405 oostyle
->conditions
= g_slist_append (oostyle
->conditions
, g_strdup (condition
));
3406 oostyle
->bases
= g_slist_append (oostyle
->bases
, g_strdup (base
));
3410 odf_style_load_two_values (GsfXMLIn
*xin
, char *condition
, GnmStyleCond
*cond
, gchar
const *base
, OOFormula f_type
)
3412 condition
= g_strstrip (condition
);
3413 if (*(condition
++) == '(') {
3414 guint len
= strlen (condition
);
3415 char *end
= condition
+ len
- 1;
3418 GnmExprTop
const *texpr
;
3420 odf_init_pp (&pp
, xin
, base
);
3424 gchar
* try = g_strrstr_len (condition
, len
, ",");
3425 GnmExprTop
const *texpr
;
3427 if (try == NULL
|| try == condition
) return FALSE
;
3429 texpr
= oo_expr_parse_str
3431 GNM_EXPR_PARSE_DEFAULT
,
3433 if (texpr
!= NULL
) {
3434 gnm_style_cond_set_expr (cond
, texpr
, 1);
3435 gnm_expr_top_unref (texpr
);
3439 len
= try - condition
- 1;
3441 texpr
= oo_expr_parse_str
3442 (xin
, condition
, &pp
,
3443 GNM_EXPR_PARSE_DEFAULT
,
3445 gnm_style_cond_set_expr (cond
, texpr
, 0);
3446 if (texpr
) gnm_expr_top_unref (texpr
);
3448 return (gnm_style_cond_get_expr (cond
, 0) &&
3449 gnm_style_cond_get_expr (cond
, 1));
3456 odf_style_load_one_value (GsfXMLIn
*xin
, char *condition
, GnmStyleCond
*cond
, gchar
const *base
, OOFormula f_type
)
3459 GnmExprTop
const *texpr
;
3461 odf_init_pp (&pp
, xin
, base
);
3462 texpr
= oo_expr_parse_str
3463 (xin
, condition
, &pp
,
3464 GNM_EXPR_PARSE_DEFAULT
,
3466 gnm_style_cond_set_expr (cond
, texpr
, 0);
3467 if (texpr
) gnm_expr_top_unref (texpr
);
3468 return (gnm_style_cond_get_expr (cond
, 0) != NULL
);
3472 odf_style_add_condition (GsfXMLIn
*xin
, GnmStyle
*style
, GnmStyle
*cstyle
,
3473 gchar
const *condition
, gchar
const *base
)
3475 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3477 gchar
const *full_condition
= condition
;
3478 GnmStyleCond
*cond
= NULL
;
3479 GnmStyleConditions
*sc
;
3480 gboolean success
= FALSE
;
3482 Sheet
*sheet
= state
->pos
.sheet
;
3484 g_return_if_fail (style
!= NULL
);
3485 g_return_if_fail (cstyle
!= NULL
);
3486 g_return_if_fail (condition
!= NULL
);
3487 g_return_if_fail (base
!= NULL
);
3489 f_type
= odf_get_formula_type (xin
, &condition
);
3491 if (g_str_has_prefix (condition
, "cell-content()")) {
3492 condition
+= strlen ("cell-content()") - 1;
3493 while (*(++condition
) == ' ');
3494 switch (*(condition
++)) {
3496 if (*condition
== '=') {
3498 cond
= gnm_style_cond_new (GNM_STYLE_COND_LTE
, sheet
);
3500 cond
= gnm_style_cond_new (GNM_STYLE_COND_LT
, sheet
);
3504 if (*condition
== '=') {
3506 cond
= gnm_style_cond_new (GNM_STYLE_COND_GTE
, sheet
);
3508 cond
= gnm_style_cond_new (GNM_STYLE_COND_GT
, sheet
);
3513 cond
= gnm_style_cond_new (GNM_STYLE_COND_EQUAL
, sheet
);
3517 if (*condition
== '=') {
3519 cond
= gnm_style_cond_new (GNM_STYLE_COND_NOT_EQUAL
, sheet
);
3527 char *text
= g_strdup (condition
);
3528 success
= odf_style_load_one_value (xin
, text
, cond
, base
, f_type
);
3532 } else if (g_str_has_prefix (condition
, "cell-content-is-between")) {
3534 cond
= gnm_style_cond_new (GNM_STYLE_COND_BETWEEN
, sheet
);
3535 condition
+= strlen ("cell-content-is-between");
3536 text
= g_strdup (condition
);
3537 success
= odf_style_load_two_values (xin
, text
, cond
, base
, f_type
);
3539 } else if (g_str_has_prefix (condition
, "cell-content-is-not-between")) {
3541 cond
= gnm_style_cond_new (GNM_STYLE_COND_NOT_BETWEEN
, sheet
);
3542 condition
+= strlen ("cell-content-is-not-between");
3543 text
= g_strdup (condition
);
3544 success
= odf_style_load_two_values (xin
, text
, cond
, base
, f_type
);
3546 } else if (g_str_has_prefix (condition
, "is-true-formula(") && g_str_has_suffix (condition
, ")") ) {
3548 cond
= gnm_style_cond_new (GNM_STYLE_COND_CUSTOM
, sheet
);
3549 condition
+= strlen ("is-true-formula(");
3550 text
= g_strdup (condition
);
3551 *(text
+ strlen (text
) - 1) = '\0';
3552 success
= odf_style_load_one_value (xin
, text
, cond
, base
, f_type
);
3556 if (!success
|| !cond
) {
3558 gnm_style_cond_free (cond
);
3560 _("Unknown condition '%s' encountered, ignoring."),
3565 gnm_style_cond_canonicalize (cond
);
3566 gnm_style_cond_set_overlay (cond
, cstyle
);
3568 if (gnm_style_is_element_set (style
, MSTYLE_CONDITIONS
) &&
3569 (sc
= gnm_style_get_conditions (style
)) != NULL
)
3570 gnm_style_conditions_insert (sc
, cond
, -1);
3572 sc
= gnm_style_conditions_new (sheet
);
3573 gnm_style_conditions_insert (sc
, cond
, -1);
3574 gnm_style_set_conditions (style
, sc
);
3577 gnm_style_cond_free (cond
);
3581 odf_style_from_oo_cell_style (GsfXMLIn
*xin
, OOCellStyle
*oostyle
)
3583 g_return_val_if_fail (oostyle
!= NULL
, NULL
);
3585 if (oostyle
->conditions
!= NULL
) {
3586 /* We need to incorporate the conditional styles */
3587 GnmStyle
*new_style
= gnm_style_dup (oostyle
->style
);
3588 GSList
*styles
= oostyle
->styles
, *conditions
= oostyle
->conditions
, *bases
= oostyle
->bases
;
3589 while (styles
&& conditions
&& bases
) {
3590 GnmStyle
*cstyle
= odf_style_from_oo_cell_style (xin
, styles
->data
);
3591 odf_style_add_condition (xin
, new_style
, cstyle
,
3592 conditions
->data
, bases
->data
);
3593 gnm_style_unref (cstyle
);
3594 styles
= styles
->next
;
3595 conditions
= conditions
->next
;
3596 bases
= bases
->next
;
3598 gnm_style_unref (oostyle
->style
);
3599 oostyle
->style
= new_style
;
3600 g_slist_free_full (oostyle
->styles
, (GDestroyNotify
) odf_oo_cell_style_unref
);
3601 g_slist_free_full (oostyle
->conditions
, g_free
);
3602 g_slist_free_full (oostyle
->bases
, g_free
);
3603 oostyle
->styles
= NULL
;
3604 oostyle
->conditions
= NULL
;
3605 oostyle
->bases
= NULL
;
3607 gnm_style_ref (oostyle
->style
);
3608 return oostyle
->style
;
3612 oo_col_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3614 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3615 OOColRowStyle
*col_info
= NULL
;
3616 OOCellStyle
*oostyle
= NULL
;
3617 GnmStyle
*style
= NULL
;
3618 int i
, repeat_count
= 1;
3619 gboolean hidden
= FALSE
;
3620 int max_cols
= gnm_sheet_get_max_cols (state
->pos
.sheet
);
3622 maybe_update_progress (xin
);
3624 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3625 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "default-cell-style-name")) {
3626 oostyle
= g_hash_table_lookup (state
->styles
.cell
, attrs
[1]);
3628 style
= odf_style_from_oo_cell_style (xin
, oostyle
);
3630 oo_warning (xin
, "The cell style with name <%s> is missing", CXML2C (attrs
[01]));
3631 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "style-name"))
3632 col_info
= g_hash_table_lookup (state
->styles
.col
, attrs
[1]);
3633 else if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
, "number-columns-repeated",
3634 &repeat_count
, 0, INT_MAX
- state
->pos
.eval
.col
))
3636 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "visibility"))
3637 hidden
= !attr_eq (attrs
[1], "visible");
3639 if (state
->pos
.eval
.col
+ repeat_count
> max_cols
) {
3640 max_cols
= gnm_sheet_get_max_cols (state
->pos
.sheet
);
3641 if (state
->pos
.eval
.col
+ repeat_count
> max_cols
) {
3642 oo_warning (xin
, _("Ignoring column information beyond"
3643 " column %i"), max_cols
);
3644 repeat_count
= max_cols
- state
->pos
.eval
.col
- 1;
3649 colrow_set_visibility (state
->pos
.sheet
, TRUE
, FALSE
, state
->pos
.eval
.col
,
3650 state
->pos
.eval
.col
+ repeat_count
- 1);
3652 if (NULL
!= style
) {
3654 r
.start
.col
= state
->pos
.eval
.col
;
3655 r
.end
.col
= state
->pos
.eval
.col
+ repeat_count
- 1;
3657 r
.end
.row
= ((sheet_order_t
*)g_slist_nth_data (state
->sheet_order
, state
->table_n
))->rows
- 1;
3658 sheet_style_apply_range (state
->pos
.sheet
, &r
, style
);
3660 if (col_info
!= NULL
) {
3661 if (state
->default_style
.columns
== NULL
&& repeat_count
> max_cols
/2) {
3662 int const last
= state
->pos
.eval
.col
+ repeat_count
;
3663 state
->default_style
.columns
= g_memdup (col_info
, sizeof (*col_info
));
3664 state
->default_style
.columns
->count
= repeat_count
;
3665 sheet_col_set_default_size_pts (state
->pos
.sheet
,
3666 state
->default_style
.columns
->size_pts
);
3667 if (col_info
->break_before
!= OO_PAGE_BREAK_NONE
)
3668 for (i
= state
->pos
.eval
.row
; i
< last
; i
++ )
3669 oo_set_page_break (state
, i
, TRUE
,
3670 col_info
->break_before
3671 == OO_PAGE_BREAK_MANUAL
);
3672 if (col_info
->break_after
!= OO_PAGE_BREAK_NONE
)
3673 for (i
= state
->pos
.eval
.col
; i
< last
; i
++ )
3674 oo_append_page_break (state
, i
+1, FALSE
,
3675 col_info
->break_after
3676 == OO_PAGE_BREAK_MANUAL
);
3678 int last
= state
->pos
.eval
.col
+ repeat_count
;
3679 for (i
= state
->pos
.eval
.col
; i
< last
; i
++ ) {
3680 /* I can not find a listing for the default but will
3681 * assume it is TRUE to keep the files rational */
3682 if (col_info
->size_pts
> 0.)
3683 sheet_col_set_size_pts (state
->pos
.sheet
, i
,
3684 col_info
->size_pts
, col_info
->manual
);
3685 oo_col_row_style_apply_breaks (state
, col_info
, i
, TRUE
);
3687 col_info
->count
+= repeat_count
;
3691 state
->pos
.eval
.col
+= repeat_count
;
3695 odf_table_header_rows (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3697 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3699 if (state
->print
.rep_rows_from
< 0)
3700 state
->print
.rep_rows_from
= state
->pos
.eval
.row
;
3701 /* otherwise we are continuing an existing range */
3704 odf_table_header_rows_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3706 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3708 state
->print
.rep_rows_to
= state
->pos
.eval
.row
- 1;
3712 odf_table_header_cols (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3714 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3716 if (state
->print
.rep_cols_from
< 0)
3717 state
->print
.rep_cols_from
= state
->pos
.eval
.col
;
3718 /* otherwise we are continuing an existing range */
3721 odf_table_header_cols_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3723 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3725 state
->print
.rep_cols_to
= state
->pos
.eval
.col
- 1;
3729 oo_row_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3731 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3732 OOColRowStyle
*row_info
= NULL
;
3733 OOCellStyle
*oostyle
= NULL
;
3734 GnmStyle
*style
= NULL
;
3735 int i
, repeat_count
= 1;
3736 gboolean hidden
= FALSE
;
3737 int max_rows
= gnm_sheet_get_max_rows (state
->pos
.sheet
);
3739 maybe_update_progress (xin
);
3741 state
->pos
.eval
.col
= 0;
3743 if (state
->pos
.eval
.row
>= max_rows
) {
3744 max_rows
= gnm_sheet_get_max_rows (state
->pos
.sheet
);
3745 if (state
->pos
.eval
.row
>= max_rows
) {
3746 oo_warning (xin
, _("Content past the maximum number of rows (%i) supported."), max_rows
);
3752 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3753 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "default-cell-style-name")) {
3754 oostyle
= g_hash_table_lookup (state
->styles
.cell
, attrs
[1]);
3756 style
= odf_style_from_oo_cell_style (xin
, oostyle
);
3758 oo_warning (xin
, "The cell style with name <%s> is missing", CXML2C (attrs
[01]));
3759 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "style-name"))
3760 row_info
= g_hash_table_lookup (state
->styles
.row
, attrs
[1]);
3761 else if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
, "number-rows-repeated", &repeat_count
, 0,
3762 INT_MAX
- state
->pos
.eval
.row
))
3764 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "visibility"))
3765 hidden
= !attr_eq (attrs
[1], "visible");
3768 if (state
->pos
.eval
.row
+ repeat_count
> max_rows
)
3769 /* There are probably lots of empty lines at the end. */
3770 repeat_count
= max_rows
- state
->pos
.eval
.row
- 1;
3773 colrow_set_visibility (state
->pos
.sheet
, FALSE
, FALSE
, state
->pos
.eval
.row
,
3774 state
->pos
.eval
.row
+repeat_count
- 1);
3776 if (NULL
!= style
) {
3778 r
.start
.row
= state
->pos
.eval
.row
;
3779 r
.end
.row
= state
->pos
.eval
.row
+ repeat_count
- 1;
3781 r
.end
.col
= ((sheet_order_t
*)g_slist_nth_data (state
->sheet_order
, state
->table_n
))->cols
- 1;;
3782 sheet_style_apply_range (state
->pos
.sheet
, &r
, style
);
3785 if (row_info
!= NULL
) {
3786 if (state
->default_style
.rows
== NULL
&& repeat_count
> max_rows
/2) {
3787 int const last
= state
->pos
.eval
.row
+ repeat_count
;
3788 state
->default_style
.rows
= g_memdup (row_info
, sizeof (*row_info
));
3789 state
->default_style
.rows
->count
= repeat_count
;
3790 sheet_row_set_default_size_pts (state
->pos
.sheet
,
3791 state
->default_style
.rows
->size_pts
);
3792 if (row_info
->break_before
!= OO_PAGE_BREAK_NONE
)
3793 for (i
= state
->pos
.eval
.row
; i
< last
; i
++ )
3794 oo_set_page_break (state
, i
, FALSE
,
3795 row_info
->break_before
3796 == OO_PAGE_BREAK_MANUAL
);
3797 if (row_info
->break_after
!= OO_PAGE_BREAK_NONE
)
3798 for (i
= state
->pos
.eval
.row
; i
< last
; i
++ )
3799 oo_append_page_break (state
, i
+1, FALSE
,
3800 row_info
->break_after
3801 == OO_PAGE_BREAK_MANUAL
);
3803 int const last
= state
->pos
.eval
.row
+ repeat_count
;
3804 for (i
= state
->pos
.eval
.row
; i
< last
; i
++ ) {
3805 if (row_info
->size_pts
> 0.)
3806 sheet_row_set_size_pts (state
->pos
.sheet
, i
,
3807 row_info
->size_pts
, row_info
->manual
);
3808 oo_col_row_style_apply_breaks (state
, row_info
, i
, FALSE
);
3810 row_info
->count
+= repeat_count
;
3814 state
->row_inc
= repeat_count
;
3818 oo_row_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3820 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3821 state
->pos
.eval
.row
+= state
->row_inc
;
3825 odf_get_formula_type (GsfXMLIn
*xin
, char const **str
)
3827 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3828 OOFormula f_type
= FORMULA_NOT_SUPPORTED
;
3829 if (state
->ver
== OOO_VER_OPENDOC
) {
3830 if (strncmp (*str
, "msoxl:", 6) == 0) {
3832 f_type
= FORMULA_MICROSOFT
;
3833 } else if (strncmp (*str
, "oooc:", 5) == 0) {
3835 f_type
= FORMULA_OLD_OPENOFFICE
;
3836 } else if (strncmp (*str
, "of:", 3) == 0) {
3838 f_type
= FORMULA_OPENFORMULA
;
3840 /* They really should include a namespace */
3841 /* We assume that it is an OpenFormula expression */
3843 f_type
= FORMULA_OPENFORMULA
;
3845 } else if (state
->ver
== OOO_VER_1
)
3846 f_type
= FORMULA_OLD_OPENOFFICE
;
3852 oo_cell_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3854 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
3855 GnmExprTop
const *texpr
= NULL
;
3856 GnmValue
*val
= NULL
;
3857 gboolean has_date
= FALSE
, has_datetime
= FALSE
, has_time
= FALSE
;
3859 gnm_float float_val
= 0;
3860 int array_cols
= -1, array_rows
= -1;
3861 int merge_cols
= 1, merge_rows
= 1;
3862 OOCellStyle
*oostyle
= NULL
;
3863 GnmStyle
*style
= NULL
;
3864 char const *style_name
= NULL
;
3865 char const *validation_name
= NULL
;
3866 char const *expr_string
;
3868 int max_cols
= gnm_sheet_get_max_cols (state
->pos
.sheet
);
3869 int max_rows
= gnm_sheet_get_max_rows (state
->pos
.sheet
);
3870 GnmValidation
*validation
= NULL
;
3871 gboolean possible_error_constant
= FALSE
;
3872 gboolean columns_spanned_fake
= FALSE
;
3874 maybe_update_progress (xin
);
3877 state
->content_is_error
= FALSE
;
3878 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3879 if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
, "number-columns-repeated",
3880 &state
->col_inc
, 0, INT_MAX
- state
->pos
.eval
.col
))
3882 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "error-value"))
3883 /* While the value of this attribute contains the true error value */
3884 /* it could have been retained by a consumer/producer who did change */
3885 /* the cell value, so we just remember that we saw this attribute. */
3886 possible_error_constant
= TRUE
;
3887 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "formula")) {
3890 if (attrs
[1] == NULL
) {
3891 oo_warning (xin
, _("Missing expression"));
3895 expr_string
= CXML2C (attrs
[1]);
3896 f_type
= odf_get_formula_type (xin
, &expr_string
);
3897 if (f_type
== FORMULA_NOT_SUPPORTED
) {
3899 _("Unsupported formula type encountered: %s"),
3904 expr_string
= gnm_expr_char_start_p (expr_string
);
3905 if (expr_string
== NULL
)
3906 oo_warning (xin
, _("Expression '%s' does not start "
3907 "with a recognized character"), attrs
[1]);
3908 else if (*expr_string
== '\0')
3909 /* Ick. They seem to store error cells as
3910 * having value date with expr : '=' and the
3911 * message in the content.
3913 state
->content_is_error
= TRUE
;
3915 texpr
= oo_expr_parse_str
3917 &state
->pos
, GNM_EXPR_PARSE_DEFAULT
, f_type
);
3918 if (possible_error_constant
&& texpr
!= NULL
&&
3919 GNM_EXPR_GET_OPER (texpr
->expr
) == GNM_EXPR_OP_CONSTANT
) {
3920 GnmValue
const *eval
= gnm_expr_get_constant (texpr
->expr
);
3921 if (VALUE_IS_ERROR (eval
)) {
3922 value_release (val
);
3923 val
= value_dup (eval
);
3924 gnm_expr_top_unref (texpr
);
3929 } else if (oo_attr_bool (xin
, attrs
,
3930 (state
->ver
== OOO_VER_OPENDOC
) ?
3931 OO_NS_OFFICE
: OO_NS_TABLE
,
3932 "boolean-value", &bool_val
)) {
3934 val
= value_new_bool (bool_val
);
3935 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
3936 (state
->ver
== OOO_VER_OPENDOC
) ? OO_NS_OFFICE
: OO_NS_TABLE
,
3939 unsigned y
, m
, d
, h
, mi
;
3941 unsigned n
= sscanf (CXML2C (attrs
[1]), "%u-%u-%uT%u:%u:%" GNM_SCANF_g
,
3942 &y
, &m
, &d
, &h
, &mi
, &s
);
3946 g_date_set_dmy (&date
, d
, m
, y
);
3947 if (g_date_valid (&date
)) {
3948 unsigned d_serial
= go_date_g_to_serial (&date
,
3949 workbook_date_conv (state
->pos
.wb
));
3952 = h
+ ((gnm_float
)mi
/ 60) +
3953 ((gnm_float
)s
/ 3600);
3954 val
= value_new_float (d_serial
+ time_frac
/ 24);
3955 has_datetime
= TRUE
;
3957 val
= value_new_int (d_serial
);
3963 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
3964 (state
->ver
== OOO_VER_OPENDOC
) ?
3965 OO_NS_OFFICE
: OO_NS_TABLE
,
3969 if (3 == sscanf (CXML2C (attrs
[1]), "PT%uH%uM%uS", &h
, &m
, &s
)) {
3970 unsigned secs
= h
* 3600 + m
* 60 + s
;
3971 val
= value_new_float (secs
/ (gnm_float
)86400);
3975 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
3976 (state
->ver
== OOO_VER_OPENDOC
) ?
3977 OO_NS_OFFICE
: OO_NS_TABLE
,
3980 val
= value_new_string (CXML2C (attrs
[1]));
3981 } else if (oo_attr_float (xin
, attrs
,
3982 (state
->ver
== OOO_VER_OPENDOC
) ? OO_NS_OFFICE
: OO_NS_TABLE
,
3983 "value", &float_val
)) {
3985 val
= value_new_float (float_val
);
3986 } else if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
,
3987 "number-matrix-columns-spanned",
3988 &array_cols
, 0, INT_MAX
))
3990 else if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
,
3991 "number-matrix-rows-spanned",
3992 &array_rows
, 0, INT_MAX
))
3994 else if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
,
3995 "number-columns-spanned", &merge_cols
, 0, INT_MAX
))
3997 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
,
3998 "columns-spanned-fake",
3999 &columns_spanned_fake
))
4001 else if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
,
4002 "number-rows-spanned", &merge_rows
, 0, INT_MAX
))
4004 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "style-name"))
4005 style_name
= attrs
[1];
4006 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
,
4007 "content-validation-name"))
4008 validation_name
= attrs
[1];
4011 if (columns_spanned_fake
)
4014 if (state
->pos
.eval
.col
>= max_cols
||
4015 state
->pos
.eval
.row
>= max_rows
) {
4017 gnm_expr_top_unref (texpr
);
4018 value_release (val
);
4022 merge_cols
= MIN (merge_cols
, max_cols
- state
->pos
.eval
.col
);
4023 merge_rows
= MIN (merge_rows
, max_rows
- state
->pos
.eval
.row
);
4025 if (style_name
!= NULL
) {
4027 oostyle
= g_hash_table_lookup (state
->styles
.cell_datetime
, style_name
);
4029 oostyle
= g_hash_table_lookup (state
->styles
.cell_date
, style_name
);
4031 oostyle
= g_hash_table_lookup (state
->styles
.cell_time
, style_name
);
4033 if (oostyle
== NULL
) {
4034 oostyle
= g_hash_table_lookup (state
->styles
.cell
, style_name
);
4035 if (((oostyle
!= NULL
) || (state
->ver
== OOO_VER_1
))
4036 && (has_datetime
|| has_date
|| has_time
)) {
4037 if ((oostyle
== NULL
) ||
4038 ((!gnm_style_is_element_set (oostyle
->style
, MSTYLE_FORMAT
))
4039 || go_format_is_general (gnm_style_get_format (oostyle
->style
)))) {
4041 oostyle
= (oostyle
== NULL
) ? odf_oo_cell_style_new (NULL
) :
4042 odf_oo_cell_style_copy (oostyle
);
4044 format
= go_format_default_date_time ();
4045 g_hash_table_replace (state
->styles
.cell_datetime
,
4046 g_strdup (style_name
), oostyle
);
4047 } else if (has_date
) {
4048 format
= go_format_default_date ();
4049 g_hash_table_replace (state
->styles
.cell_date
,
4050 g_strdup (style_name
), oostyle
);
4052 format
= go_format_default_time ();
4053 g_hash_table_replace (state
->styles
.cell_time
,
4054 g_strdup (style_name
), oostyle
);
4056 gnm_style_set_format (oostyle
->style
, format
);
4060 if (oostyle
!= NULL
)
4061 style
= odf_style_from_oo_cell_style (xin
, oostyle
);
4064 if (validation_name
!= NULL
) {
4065 GnmInputMsg
*message
;
4066 if (NULL
!= (validation
= odf_validations_translate (xin
, validation_name
))) {
4068 style
= gnm_style_new ();
4069 /* 1 reference for style*/
4070 gnm_style_set_validation (style
, validation
);
4072 if (NULL
!= (message
= odf_validation_get_input_message (xin
, validation_name
))) {
4074 style
= gnm_style_new ();
4075 /* 1 reference for style*/
4076 gnm_style_set_input_msg (style
, message
);
4080 if (style
== NULL
&& (merge_cols
> 1 || merge_rows
> 1)) {
4081 /* We may not have a new style but the current cell may */
4082 /* have been assigned a style earlier */
4083 GnmStyle
const *old_style
4084 = sheet_style_get (state
->pos
.sheet
, state
->pos
.eval
.col
,
4085 state
->pos
.eval
.row
);
4086 if (old_style
!= NULL
)
4087 style
= gnm_style_dup (old_style
);
4090 if (style
!= NULL
) {
4091 if (state
->col_inc
> 1 || state
->row_inc
> 1) {
4092 range_init_cellpos_size (&tmp
, &state
->pos
.eval
,
4093 state
->col_inc
, state
->row_inc
);
4094 sheet_style_apply_range (state
->pos
.sheet
, &tmp
, style
);
4095 } else if (merge_cols
> 1 || merge_rows
> 1) {
4096 range_init_cellpos_size (&tmp
, &state
->pos
.eval
,
4097 merge_cols
, merge_rows
);
4098 sheet_style_apply_range (state
->pos
.sheet
, &tmp
, style
);
4100 sheet_style_apply_pos (state
->pos
.sheet
,
4101 state
->pos
.eval
.col
, state
->pos
.eval
.row
,
4106 state
->text_p_for_cell
.content_is_simple
= FALSE
;
4107 if (texpr
!= NULL
) {
4108 GnmCell
*cell
= sheet_cell_fetch (state
->pos
.sheet
,
4109 state
->pos
.eval
.col
,
4110 state
->pos
.eval
.row
);
4112 if (array_cols
> 0 || array_rows
> 0) {
4114 Sheet
*sheet
= state
->pos
.sheet
;
4116 if (array_cols
<= 0) {
4118 oo_warning (xin
, _("Invalid array expression does not specify number of columns."));
4119 } else if (array_rows
<= 0) {
4121 oo_warning (xin
, _("Invalid array expression does not specify number of rows."));
4124 r
.start
= state
->pos
.eval
;
4126 r
.end
.col
+= array_cols
- 1;
4127 r
.end
.row
+= array_rows
- 1;
4129 if (r
.end
.col
> gnm_sheet_get_last_col (sheet
)) {
4132 _("Content past the maximum number "
4133 "of columns (%i) supported."),
4134 gnm_sheet_get_max_cols (sheet
));
4135 r
.end
.col
= gnm_sheet_get_last_col (sheet
);
4137 if (r
.end
.row
> gnm_sheet_get_last_row (sheet
)) {
4140 _("Content past the maximum number "
4141 "of rows (%i) supported."),
4142 gnm_sheet_get_max_rows (sheet
));
4143 r
.end
.row
= gnm_sheet_get_last_row (sheet
);
4146 gnm_cell_set_array (sheet
, &r
, texpr
);
4147 gnm_expr_top_unref (texpr
);
4149 gnm_cell_assign_value (cell
, val
);
4152 gnm_cell_set_expr_and_value (cell
, texpr
, val
,
4155 gnm_cell_set_expr (cell
, texpr
);
4156 gnm_expr_top_unref (texpr
);
4158 } else if (val
!= NULL
) {
4159 GnmCell
*cell
= sheet_cell_fetch (state
->pos
.sheet
,
4160 state
->pos
.eval
.col
, state
->pos
.eval
.row
);
4162 /* has cell previously been initialized as part of an array */
4163 if (gnm_cell_is_nonsingleton_array (cell
))
4164 gnm_cell_assign_value (cell
, val
);
4166 gnm_cell_set_value (cell
, val
);
4167 } else if (!state
->content_is_error
)
4168 /* store the content as a string */
4169 state
->text_p_for_cell
.content_is_simple
= TRUE
;
4171 if (merge_cols
> 1 || merge_rows
> 1) {
4172 range_init_cellpos_size (&tmp
, &state
->pos
.eval
,
4173 merge_cols
, merge_rows
);
4174 gnm_sheet_merge_add (state
->pos
.sheet
, &tmp
, FALSE
, NULL
);
4179 oo_cell_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4181 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4183 if (state
->col_inc
> 1 || state
->row_inc
> 1) {
4184 GnmCell
*cell
= sheet_cell_get (state
->pos
.sheet
,
4185 state
->pos
.eval
.col
, state
->pos
.eval
.row
);
4187 if (!gnm_cell_is_empty (cell
)) {
4190 for (j
= 0; j
< state
->row_inc
; j
++)
4191 for (i
= 0; i
< state
->col_inc
; i
++)
4192 if (j
> 0 || i
> 0) {
4193 next
= sheet_cell_fetch (state
->pos
.sheet
,
4194 state
->pos
.eval
.col
+ i
, state
->pos
.eval
.row
+ j
);
4195 if (gnm_cell_is_nonsingleton_array (next
))
4196 gnm_cell_assign_value (next
, value_dup (cell
->value
));
4198 gnm_cell_set_value (next
, value_dup (cell
->value
));
4202 state
->pos
.eval
.col
+= state
->col_inc
;
4206 oo_add_text_to_cell (OOParseState
*state
, char const *str
, PangoAttrList
*attrs
)
4209 PangoAttrList
*old
= NULL
;
4213 if (state
->curr_cell
== NULL
)
4216 if ((NULL
!= state
->curr_cell
->value
) && VALUE_IS_STRING (state
->curr_cell
->value
)) {
4217 GOFormat
*fmt
= state
->curr_cell
->value
->v_str
.fmt
;
4218 start
= strlen (state
->curr_cell
->value
->v_str
.val
->str
);
4220 go_format_ref (fmt
);
4221 v
= value_new_string_str
4222 (go_string_new_nocopy
4223 (g_strconcat (state
->curr_cell
->value
->v_str
.val
->str
,
4226 value_set_fmt (v
, fmt
);
4227 go_format_unref (fmt
);
4230 v
= value_new_string (str
);
4232 gnm_cell_assign_value (state
->curr_cell
, v
);
4235 if (state
->curr_cell
->value
->v_str
.fmt
!= NULL
) {
4236 old
= pango_attr_list_copy
4237 ((PangoAttrList
*)go_format_get_markup (state
->curr_cell
->value
->v_str
.fmt
));
4239 old
= pango_attr_list_new ();
4240 pango_attr_list_splice (old
, attrs
, start
, strlen (str
));
4241 fmt
= go_format_new_markup (old
, FALSE
);
4242 value_set_fmt (state
->curr_cell
->value
, fmt
);
4243 go_format_unref (fmt
);
4248 oo_cell_content_start (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4250 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4252 odf_push_text_p (state
, TRUE
);
4254 if (state
->text_p_for_cell
.content_is_simple
) {
4255 int max_cols
= gnm_sheet_get_max_cols (state
->pos
.sheet
);
4256 int max_rows
= gnm_sheet_get_max_rows (state
->pos
.sheet
);
4258 if (state
->pos
.eval
.col
>= max_cols
||
4259 state
->pos
.eval
.row
>= max_rows
)
4262 state
->curr_cell
= sheet_cell_fetch (state
->pos
.sheet
,
4263 state
->pos
.eval
.col
,
4264 state
->pos
.eval
.row
);
4266 if (VALUE_IS_STRING (state
->curr_cell
->value
)) {
4267 /* embedded newlines stored as a series of <p> */
4269 v
= value_new_string_str
4270 (go_string_new_nocopy
4271 (g_strconcat (state
->curr_cell
->value
->v_str
.val
->str
, "\n", NULL
)));
4272 gnm_cell_assign_value (state
->curr_cell
, v
);
4280 oo_cell_content_end (GsfXMLIn
*xin
, GsfXMLBlob
*blob
)
4282 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4284 if (state
->content_is_error
) {
4286 if (state
->curr_cell
== NULL
) {
4287 int max_cols
= gnm_sheet_get_max_cols (state
->pos
.sheet
);
4288 int max_rows
= gnm_sheet_get_max_rows (state
->pos
.sheet
);
4290 if (state
->pos
.eval
.col
>= max_cols
||
4291 state
->pos
.eval
.row
>= max_rows
)
4294 state
->curr_cell
= sheet_cell_fetch (state
->pos
.sheet
,
4295 state
->pos
.eval
.col
,
4296 state
->pos
.eval
.row
);
4298 v
= value_new_error (NULL
, xin
->content
->str
);
4299 gnm_cell_assign_value (state
->curr_cell
, v
);
4300 } else if (state
->text_p_for_cell
.content_is_simple
) {
4301 odf_text_content_end (xin
, blob
);
4302 if (state
->text_p_for_cell
.gstr
)
4303 oo_add_text_to_cell (state
, state
->text_p_for_cell
.gstr
->str
, state
->text_p_for_cell
.attrs
);
4305 odf_pop_text_p (state
);
4311 oo_cell_content_link (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4313 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4314 char const *href
= NULL
;
4315 char const *tip
= NULL
;
4316 GnmHLink
*hlink
= NULL
;
4318 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4319 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_XLINK
, "href"))
4320 href
= CXML2C (attrs
[1]);
4321 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_OFFICE
, "title"))
4322 tip
= CXML2C (attrs
[1]);
4327 char *link_text
= NULL
;
4329 if (g_str_has_prefix (href
, "http"))
4330 type
= gnm_hlink_url_get_type ();
4331 else if (g_str_has_prefix (href
, "mail"))
4332 type
= gnm_hlink_email_get_type ();
4333 else if (g_str_has_prefix (href
, "file"))
4334 type
= gnm_hlink_external_get_type ();
4337 type
= gnm_hlink_cur_wb_get_type ();
4340 link_text
= g_strdup (href
);
4342 // Switch to Sheet!A1 format quick'n'dirty.
4343 dot
= strchr (link_text
, '.');
4349 link_text
= g_strdup (href
);
4351 hlink
= gnm_hlink_new (type
, state
->pos
.sheet
);
4352 gnm_hlink_set_target (hlink
, link_text
);
4353 gnm_hlink_set_tip (hlink
, tip
);
4354 style
= gnm_style_new ();
4355 gnm_style_set_hlink (style
, hlink
);
4356 gnm_style_set_font_uline (style
, UNDERLINE_SINGLE
);
4357 gnm_style_set_font_color (style
, gnm_color_new_go (GO_COLOR_BLUE
));
4358 sheet_style_apply_pos (state
->pos
.sheet
,
4359 state
->pos
.eval
.col
, state
->pos
.eval
.row
,
4366 oo_covered_cell_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4368 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4371 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4372 if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
, "number-columns-repeated",
4373 &state
->col_inc
, 0, INT_MAX
- state
->pos
.eval
.col
))
4376 /* why bother it is covered ? */
4377 else if (!strcmp (CXML2C (attrs
[0]), OO_NS_TABLE
, "style-name"))
4378 style
= g_hash_table_lookup (state
->styles
.cell
, attrs
[1]);
4380 if (style
!= NULL
) {
4381 gnm_style_ref (style
);
4382 sheet_style_apply_pos (state
->pos
.sheet
,
4383 state
->pos
.eval
.col
, state
->pos
.eval
.row
,
4390 oo_covered_cell_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4392 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4393 state
->pos
.eval
.col
+= state
->col_inc
;
4399 oo_dash (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4401 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4402 GOLineDashType t
= GO_LINE_DOT
;
4403 char const *name
= NULL
;
4404 gnm_float distance
= 0., len_dot1
= 0., len_dot2
= 0.;
4405 int n_dots1
= 0, n_dots2
= 2;
4406 gboolean found_percent
;
4408 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4409 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "name"))
4410 name
= CXML2C (attrs
[1]);
4411 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "style"))
4412 /* rect or round, ignored */;
4413 else if (oo_attr_percent_or_distance (xin
, attrs
, OO_NS_DRAW
, "distance",
4414 &distance
, &found_percent
));
4415 else if (oo_attr_percent_or_distance (xin
, attrs
, OO_NS_DRAW
, "dots1-length",
4416 &len_dot1
, &found_percent
));
4417 else if (oo_attr_percent_or_distance (xin
, attrs
, OO_NS_DRAW
, "dots2-length",
4418 &len_dot2
, &found_percent
));
4419 else if (oo_attr_int_range (xin
, attrs
, OO_NS_DRAW
,
4420 "dots1", &n_dots1
, 0, 10));
4421 else if (oo_attr_int_range (xin
, attrs
, OO_NS_DRAW
,
4422 "dots2", &n_dots2
, 0, 10));
4424 /* We need to figure out the best matching dot style */
4427 /* only one type of dots */
4430 else if (len_dot1
< 4.5)
4432 else if (len_dot1
< 9)
4434 else if (len_dot1
< 15)
4437 t
= GO_LINE_LONG_DASH
;
4438 } else if (n_dots2
> 1 && n_dots1
> 1 )
4439 t
= GO_LINE_DASH_DOT_DOT_DOT
; /* no matching dashing available */
4440 else if ( n_dots2
== 1 && n_dots1
== 1) {
4441 gnm_float max
= (len_dot1
< len_dot2
) ? len_dot2
: len_dot1
;
4443 t
= GO_LINE_DASH_DOT
;
4445 t
= GO_LINE_S_DASH_DOT
;
4447 gnm_float max
= (len_dot1
< len_dot2
) ? len_dot2
: len_dot1
;
4448 int max_dots
= (n_dots1
< n_dots2
) ? n_dots2
: n_dots1
;
4451 t
= GO_LINE_DASH_DOT_DOT_DOT
;
4453 t
= GO_LINE_DASH_DOT_DOT
;
4455 t
= GO_LINE_S_DASH_DOT_DOT
;
4459 g_hash_table_replace (state
->chart
.dash_styles
,
4460 g_strdup (name
), GUINT_TO_POINTER (t
));
4462 oo_warning (xin
, _("Unnamed dash style encountered."));
4467 oo_fill_image (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4469 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4470 char const *name
= NULL
;
4471 char const *href
= NULL
;
4473 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4474 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "name"))
4475 name
= CXML2C (attrs
[1]);
4476 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
4477 OO_NS_XLINK
, "href"))
4478 href
= CXML2C (attrs
[1]);
4480 oo_warning (xin
, _("Unnamed image fill style encountered."));
4481 else if (href
== NULL
)
4482 oo_warning (xin
, _("Image fill style \'%s\' has no attached image."),
4485 g_hash_table_replace (state
->chart
.fill_image_styles
,
4486 g_strdup (name
), g_strdup (href
));
4491 oo_gradient (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4493 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4494 gradient_info_t
*info
= g_new0 (gradient_info_t
, 1);
4495 char const *name
= NULL
;
4497 char const *style
= NULL
;
4498 unsigned int axial_types
[] =
4499 {GO_GRADIENT_S_TO_N_MIRRORED
, GO_GRADIENT_SE_TO_NW_MIRRORED
,
4500 GO_GRADIENT_E_TO_W_MIRRORED
, GO_GRADIENT_NE_TO_SW_MIRRORED
,
4501 GO_GRADIENT_N_TO_S_MIRRORED
, GO_GRADIENT_NW_TO_SE_MIRRORED
,
4502 GO_GRADIENT_W_TO_E_MIRRORED
, GO_GRADIENT_SW_TO_NE_MIRRORED
};
4503 unsigned int linear_types
[] =
4504 {GO_GRADIENT_S_TO_N
, GO_GRADIENT_SE_TO_NW
,
4505 GO_GRADIENT_E_TO_W
, GO_GRADIENT_NE_TO_SW
,
4506 GO_GRADIENT_N_TO_S
, GO_GRADIENT_NW_TO_SE
,
4507 GO_GRADIENT_W_TO_E
, GO_GRADIENT_SW_TO_NE
};
4509 info
->brightness
= -1.;
4511 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4512 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "name"))
4513 name
= CXML2C (attrs
[1]);
4514 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "start-color")) {
4516 if (gdk_rgba_parse (&rgba
, CXML2C (attrs
[1])))
4517 go_color_from_gdk_rgba (&rgba
, &info
->from
);
4519 oo_warning (xin
, _("Unable to parse gradient color: %s"), CXML2C (attrs
[1]));
4520 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "end-color")) {
4522 if (gdk_rgba_parse (&rgba
, CXML2C (attrs
[1])))
4523 go_color_from_gdk_rgba (&rgba
, &info
->to
);
4525 oo_warning (xin
, _("Unable to parse gradient color: %s"), CXML2C (attrs
[1]));
4526 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "style"))
4527 style
= CXML2C (attrs
[1]);
4528 else if (oo_attr_float (xin
, attrs
, OO_GNUM_NS_EXT
,
4529 "brightness", &info
->brightness
));
4530 else if (NULL
!= oo_attr_angle (xin
, attrs
, OO_NS_DRAW
, "angle", &angle
));
4535 angle
= ((angle
+ 22)/45) % 8; /* angle is now 0,1,2,...,7*/
4537 if (style
!= NULL
&& 0 == strcmp (style
, "axial"))
4538 info
->dir
= axial_types
[angle
];
4540 info
->dir
= linear_types
[angle
];
4542 g_hash_table_replace (state
->chart
.gradient_styles
,
4543 g_strdup (name
), info
);
4545 oo_warning (xin
, _("Unnamed gradient style encountered."));
4551 oo_hatch (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4553 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4554 GOPattern
*hatch
= g_new (GOPattern
, 1);
4555 char const *hatch_name
= NULL
;
4556 gnm_float distance
= -1.0;
4558 char const *style
= NULL
;
4560 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4561 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "color")) {
4563 if (gdk_rgba_parse (&rgba
, CXML2C (attrs
[1])))
4564 go_color_from_gdk_rgba (&rgba
, &hatch
->fore
);
4566 oo_warning (xin
, _("Unable to parse hatch color: %s"), CXML2C (attrs
[1]));
4567 } else if (NULL
!= oo_attr_distance (xin
, attrs
, OO_NS_DRAW
, "distance", &distance
))
4569 else if (NULL
!= oo_attr_angle (xin
, attrs
, OO_NS_DRAW
, "rotation", &angle
))
4571 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "name"))
4572 hatch_name
= CXML2C (attrs
[1]);
4573 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "style"))
4574 style
= CXML2C (attrs
[1]);
4577 hatch
->pattern
= GO_PATTERN_THATCH
;
4578 else if (0 == strcmp (style
, "single")) {
4580 angle
= angle
+ 180;
4581 angle
= (angle
+ 22) / 45;
4584 hatch
->pattern
= (distance
< 2.5) ? GO_PATTERN_HORIZ
: GO_PATTERN_THIN_HORIZ
;
4587 hatch
->pattern
= (distance
< 2.5) ? GO_PATTERN_DIAG
: GO_PATTERN_THIN_DIAG
;
4590 hatch
->pattern
= (distance
< 2.5) ? GO_PATTERN_VERT
: GO_PATTERN_THIN_VERT
;
4593 hatch
->pattern
= (distance
< 2.5) ? GO_PATTERN_REV_DIAG
: GO_PATTERN_THIN_REV_DIAG
;
4596 } else if (0 == strcmp (style
, "double")) {
4599 angle
= (angle
+ 22) / 45;
4601 switch ((int)(distance
+ 0.5)) {
4604 hatch
->pattern
= (angle
== 0) ? GO_PATTERN_GREY75
: GO_PATTERN_THICK_DIAG_CROSS
;
4607 hatch
->pattern
= (angle
== 0) ? GO_PATTERN_GREY50
: GO_PATTERN_DIAG_CROSS
;
4610 hatch
->pattern
= (angle
== 0) ? GO_PATTERN_THIN_HORIZ_CROSS
: GO_PATTERN_THIN_DIAG_CROSS
;
4613 hatch
->pattern
= GO_PATTERN_GREY125
;
4616 hatch
->pattern
= GO_PATTERN_GREY625
;
4619 hatch
->pattern
= GO_PATTERN_THATCH
;
4620 } else if (0 == strcmp (style
, "triple")) {
4623 angle
= angle
% 180;
4624 angle
= (angle
+ 22)/45;
4627 hatch
->pattern
= (distance
< 2.5) ? GO_PATTERN_SMALL_CIRCLES
: GO_PATTERN_LARGE_CIRCLES
;
4630 hatch
->pattern
= (distance
< 2.5) ? GO_PATTERN_SEMI_CIRCLES
: GO_PATTERN_BRICKS
;
4633 hatch
->pattern
= GO_PATTERN_THATCH
;
4638 if (hatch_name
== NULL
) {
4640 oo_warning (xin
, _("Unnamed hatch encountered!"));
4642 g_hash_table_replace (state
->chart
.hatches
,
4643 g_strdup (hatch_name
), hatch
);
4647 static void odf_style_set_align_h (GnmStyle
*style
, gint h_align_is_valid
, gboolean repeat_content
,
4648 int text_align
, int gnm_halign
);
4651 odf_free_cur_style (OOParseState
*state
)
4653 switch (state
->cur_style
.type
) {
4654 case OO_STYLE_CELL
:
4655 if (state
->cur_style
.cells
!= NULL
) {
4656 odf_style_set_align_h (state
->cur_style
.cells
->style
,
4657 state
->h_align_is_valid
,
4658 state
->repeat_content
,
4659 state
->text_align
, state
->gnm_halign
);
4660 odf_oo_cell_style_unref (state
->cur_style
.cells
);
4661 state
->cur_style
.cells
= NULL
;
4666 if (state
->cur_style
.requires_disposal
)
4667 g_free (state
->cur_style
.col_rows
);
4668 state
->cur_style
.col_rows
= NULL
;
4670 case OO_STYLE_SHEET
:
4671 if (state
->cur_style
.requires_disposal
)
4672 oo_sheet_style_free (state
->cur_style
.sheets
);
4673 state
->cur_style
.sheets
= NULL
;
4675 case OO_STYLE_CHART
:
4676 case OO_STYLE_GRAPHICS
:
4677 if (state
->cur_style
.requires_disposal
)
4678 oo_chart_style_free (state
->chart
.cur_graph_style
);
4679 state
->chart
.cur_graph_style
= NULL
;
4682 pango_attr_list_unref (state
->cur_style
.text
);
4683 state
->cur_style
.text
= NULL
;
4688 state
->cur_style
.type
= OO_STYLE_UNKNOWN
;
4689 state
->cur_style
.requires_disposal
= FALSE
;
4693 oo_style (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4695 static OOEnum
const style_types
[] = {
4696 { "table-cell", OO_STYLE_CELL
},
4697 { "table-row", OO_STYLE_ROW
},
4698 { "table-column", OO_STYLE_COL
},
4699 { "table", OO_STYLE_SHEET
},
4700 { "graphics", OO_STYLE_GRAPHICS
},
4701 { "paragraph", OO_STYLE_PARAGRAPH
},
4702 { "text", OO_STYLE_TEXT
},
4703 { "chart", OO_STYLE_CHART
},
4704 { "graphic", OO_STYLE_GRAPHICS
},
4708 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4709 char const *name
= NULL
;
4710 char const *mp_name
= NULL
;
4711 char const *parent_name
= NULL
;
4712 OOCellStyle
*oostyle
;
4713 GOFormat
*fmt
= NULL
;
4715 OOChartStyle
*cur_style
;
4717 if (state
->cur_style
.type
!= OO_STYLE_UNKNOWN
)
4718 odf_free_cur_style (state
);
4720 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4721 if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "family", style_types
, &tmp
))
4722 state
->cur_style
.type
= tmp
;
4723 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "name"))
4724 name
= CXML2C (attrs
[1]);
4725 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "master-page-name"))
4726 mp_name
= CXML2C (attrs
[1]);
4727 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "parent-style-name"))
4728 parent_name
= CXML2C (attrs
[1]);
4729 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "data-style-name")) {
4730 GOFormat
*tmp
= g_hash_table_lookup (state
->formats
, attrs
[1]);
4735 switch (state
->cur_style
.type
) {
4737 state
->cur_style
.text
= pango_attr_list_new ();
4739 g_hash_table_replace (state
->styles
.text
,
4740 g_strdup (name
), pango_attr_list_ref (state
->cur_style
.text
));
4744 oostyle
= (parent_name
!= NULL
)
4745 ? g_hash_table_lookup (state
->styles
.cell
, parent_name
)
4748 state
->cur_style
.cells
= odf_oo_cell_style_copy (oostyle
);
4750 state
->cur_style
.cells
= odf_oo_cell_style_new (NULL
);
4752 state
->h_align_is_valid
= 0;
4753 state
->repeat_content
= FALSE
;
4754 state
->text_align
= -2;
4755 state
->gnm_halign
= -2;
4758 gnm_style_set_format (state
->cur_style
.cells
->style
, fmt
);
4761 odf_oo_cell_style_ref (state
->cur_style
.cells
);
4762 g_hash_table_replace (state
->styles
.cell
,
4763 g_strdup (name
), state
->cur_style
.cells
);
4764 } else if (0 == strcmp (xin
->node
->id
, "DEFAULT_STYLE")) {
4765 if (state
->default_style
.cells
)
4766 odf_oo_cell_style_unref (state
->default_style
.cells
);
4767 state
->default_style
.cells
= state
->cur_style
.cells
;
4768 odf_oo_cell_style_ref (state
->cur_style
.cells
);
4774 state
->cur_style
.col_rows
= g_new0 (OOColRowStyle
, 1);
4775 state
->cur_style
.col_rows
->size_pts
= -1.;
4777 g_hash_table_replace (state
->styles
.col
,
4778 g_strdup (name
), state
->cur_style
.col_rows
);
4779 else if (0 == strcmp (xin
->node
->id
, "DEFAULT_STYLE")) {
4780 if (state
->default_style
.columns
) {
4781 oo_warning (xin
, _("Duplicate default column style encountered."));
4782 g_free (state
->default_style
.columns
);
4784 state
->default_style
.columns
= state
->cur_style
.col_rows
;
4786 state
->cur_style
.requires_disposal
= TRUE
;
4790 state
->cur_style
.col_rows
= g_new0 (OOColRowStyle
, 1);
4791 state
->cur_style
.col_rows
->size_pts
= -1.;
4793 g_hash_table_replace (state
->styles
.row
,
4794 g_strdup (name
), state
->cur_style
.col_rows
);
4795 else if (0 == strcmp (xin
->node
->id
, "DEFAULT_STYLE")) {
4796 if (state
->default_style
.rows
) {
4797 oo_warning (xin
, _("Duplicate default row style encountered."));
4798 g_free (state
->default_style
.rows
);
4800 state
->default_style
.rows
= state
->cur_style
.col_rows
;
4802 state
->cur_style
.requires_disposal
= TRUE
;
4805 case OO_STYLE_SHEET
:
4806 state
->cur_style
.sheets
= g_new0 (OOSheetStyle
, 1);
4807 state
->cur_style
.sheets
->master_page_name
= g_strdup (mp_name
);
4809 g_hash_table_replace (state
->styles
.sheet
,
4810 g_strdup (name
), state
->cur_style
.sheets
);
4812 state
->cur_style
.requires_disposal
= TRUE
;
4815 case OO_STYLE_CHART
:
4816 case OO_STYLE_GRAPHICS
:
4817 state
->chart
.plot_type
= OO_PLOT_UNKNOWN
;
4818 cur_style
= g_new0(OOChartStyle
, 1);
4819 cur_style
->axis_props
= NULL
;
4820 cur_style
->plot_props
= NULL
;
4821 cur_style
->style_props
= NULL
;
4822 cur_style
->other_props
= NULL
;
4824 cur_style
->fmt
= go_format_ref (fmt
);
4825 state
->chart
.cur_graph_style
= cur_style
;
4827 g_hash_table_replace (state
->chart
.graph_styles
,
4829 state
->chart
.cur_graph_style
);
4830 else if (0 == strcmp (xin
->node
->id
, "DEFAULT_STYLE")) {
4831 if (state
->default_style
.graphics
) {
4832 oo_warning (xin
, _("Duplicate default chart/graphics style encountered."));
4833 g_free (state
->default_style
.graphics
);
4835 state
->default_style
.graphics
= state
->chart
.cur_graph_style
;
4837 state
->cur_style
.requires_disposal
= TRUE
;
4845 oo_style_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4847 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4848 odf_free_cur_style (state
);
4852 oo_canonical_format (const char *s
)
4855 * Quoting certain characters is options and has no functions effect
4856 * for the meaning of the format. However, some formats are recognized
4857 * as built-in and others are not. We therefore apply a simple mapping
4858 * to whatever form we prefer.
4860 if (g_str_equal (s
, "_(* -??_)"))
4861 s
= "_(* \"-\"??_)";
4863 return go_format_new_from_XL (s
);
4868 oo_date_day (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4870 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4871 gboolean is_short
= TRUE
;
4873 if (state
->cur_format
.accum
== NULL
)
4876 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4877 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_NUMBER
, "style"))
4878 is_short
= (attr_eq (attrs
[1], "short"));
4880 g_string_append (state
->cur_format
.accum
, is_short
? "d" : "dd");
4884 oo_date_month (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4886 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4887 gboolean as_text
= FALSE
;
4888 gboolean is_short
= TRUE
;
4890 if (state
->cur_format
.accum
== NULL
)
4893 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4894 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_NUMBER
, "style"))
4895 is_short
= attr_eq (attrs
[1], "short");
4896 else if (oo_attr_bool (xin
, attrs
, OO_NS_NUMBER
, "textual", &as_text
))
4898 g_string_append (state
->cur_format
.accum
, as_text
4899 ? (is_short
? "mmm" : "mmmm")
4900 : (is_short
? "m" : "mm"));
4903 oo_date_year (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4905 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4906 gboolean is_short
= TRUE
;
4908 if (state
->cur_format
.accum
== NULL
)
4911 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4912 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_NUMBER
, "style"))
4913 is_short
= attr_eq (attrs
[1], "short");
4914 g_string_append (state
->cur_format
.accum
, is_short
? "yy" : "yyyy");
4917 oo_date_era (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4921 oo_date_day_of_week (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4923 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4924 gboolean is_short
= TRUE
;
4926 if (state
->cur_format
.accum
== NULL
)
4929 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4930 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_NUMBER
, "style"))
4931 is_short
= attr_eq (attrs
[1], "short");
4932 g_string_append (state
->cur_format
.accum
, is_short
? "ddd" : "dddd");
4935 oo_date_week_of_year (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4939 oo_date_quarter (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4943 oo_date_hours (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4945 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4946 gboolean is_short
= TRUE
;
4947 gboolean truncate_hour_on_overflow
= TRUE
;
4948 gboolean truncate_hour_on_overflow_set
= FALSE
;
4950 if (state
->cur_format
.accum
== NULL
)
4953 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4954 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_NUMBER
, "style"))
4955 is_short
= attr_eq (attrs
[1], "short");
4956 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
,
4957 "truncate-on-overflow",
4958 &truncate_hour_on_overflow
))
4959 truncate_hour_on_overflow_set
= TRUE
;
4961 if (truncate_hour_on_overflow_set
) {
4962 if (truncate_hour_on_overflow
)
4963 g_string_append (state
->cur_format
.accum
, is_short
? "h" : "hh");
4965 g_string_append (state
->cur_format
.accum
, is_short
? "[h]" : "[hh]");
4966 state
->cur_format
.elapsed_set
|= ODF_ELAPSED_SET_HOURS
;
4969 if (state
->cur_format
.truncate_hour_on_overflow
)
4970 g_string_append (state
->cur_format
.accum
, is_short
? "h" : "hh");
4972 g_string_append (state
->cur_format
.accum
, is_short
? "[h]" : "[hh]");
4973 state
->cur_format
.elapsed_set
|= ODF_ELAPSED_SET_HOURS
;
4979 oo_date_minutes (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4981 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
4982 gboolean is_short
= TRUE
;
4983 gboolean truncate_hour_on_overflow
= TRUE
;
4984 gboolean truncate_hour_on_overflow_set
= FALSE
;
4986 if (state
->cur_format
.accum
== NULL
)
4989 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4990 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_NUMBER
, "style"))
4991 is_short
= attr_eq (attrs
[1], "short");
4992 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
,
4993 "truncate-on-overflow",
4994 &truncate_hour_on_overflow
))
4995 truncate_hour_on_overflow_set
= TRUE
;
4996 state
->cur_format
.pos_minutes
= state
->cur_format
.accum
->len
;
4998 if (truncate_hour_on_overflow_set
) {
4999 if (truncate_hour_on_overflow
)
5000 g_string_append (state
->cur_format
.accum
, is_short
? "m" : "mm");
5002 g_string_append (state
->cur_format
.accum
, is_short
? "[m]" : "[mm]");
5003 state
->cur_format
.elapsed_set
|= ODF_ELAPSED_SET_MINUTES
;
5006 if (state
->cur_format
.truncate_hour_on_overflow
||
5007 0 != (state
->cur_format
.elapsed_set
& ODF_ELAPSED_SET_HOURS
))
5008 g_string_append (state
->cur_format
.accum
, is_short
? "m" : "mm");
5010 g_string_append (state
->cur_format
.accum
, is_short
? "[m]" : "[mm]");
5011 state
->cur_format
.elapsed_set
|= ODF_ELAPSED_SET_MINUTES
;
5016 #define OO_DATE_SECONDS_PRINT_SECONDS { \
5017 g_string_append (state->cur_format.accum, \
5018 is_short ? "s" : "ss"); \
5020 g_string_append_c (state->cur_format.accum, \
5022 odf_go_string_append_c_n \
5023 (state->cur_format.accum, '0', digits); \
5029 oo_date_seconds (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5031 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5032 gboolean is_short
= TRUE
;
5034 gboolean truncate_hour_on_overflow
= TRUE
;
5035 gboolean truncate_hour_on_overflow_set
= FALSE
;
5037 if (state
->cur_format
.accum
== NULL
)
5040 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5041 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_NUMBER
, "style"))
5042 is_short
= attr_eq (attrs
[1], "short");
5043 else if (oo_attr_int_range (xin
, attrs
, OO_NS_NUMBER
,
5044 "decimal-places", &digits
, 0, 9))
5046 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
,
5047 "truncate-on-overflow",
5048 &truncate_hour_on_overflow
))
5049 truncate_hour_on_overflow_set
= TRUE
;
5051 state
->cur_format
.pos_seconds
= state
->cur_format
.accum
->len
;
5053 if (truncate_hour_on_overflow_set
) {
5054 if (truncate_hour_on_overflow
) {
5055 OO_DATE_SECONDS_PRINT_SECONDS
;
5057 g_string_append_c (state
->cur_format
.accum
, '[');
5058 OO_DATE_SECONDS_PRINT_SECONDS
;
5059 g_string_append_c (state
->cur_format
.accum
, ']');
5060 state
->cur_format
.elapsed_set
|= ODF_ELAPSED_SET_SECONDS
;
5063 if (state
->cur_format
.truncate_hour_on_overflow
||
5064 0 != (state
->cur_format
.elapsed_set
&
5065 (ODF_ELAPSED_SET_HOURS
| ODF_ELAPSED_SET_MINUTES
))) {
5066 OO_DATE_SECONDS_PRINT_SECONDS
;
5068 g_string_append_c (state
->cur_format
.accum
, '[');
5069 OO_DATE_SECONDS_PRINT_SECONDS
;
5070 g_string_append_c (state
->cur_format
.accum
, ']');
5071 state
->cur_format
.elapsed_set
|= ODF_ELAPSED_SET_SECONDS
;
5076 #undef OO_DATE_SECONDS_PRINT_SECONDS
5079 oo_date_am_pm (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
5081 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5082 gchar
const *am_suffix
= "AM";
5083 gchar
const *pm_suffix
= "PM";
5085 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5086 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "am-suffix"))
5087 am_suffix
= CXML2C (attrs
[1]);
5088 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "pm-suffix"))
5089 pm_suffix
= CXML2C (attrs
[1]);
5091 if (strlen (am_suffix
) > 2 || (*am_suffix
!= 'a' && *am_suffix
!= 'A') ||
5092 (*(am_suffix
+ 1) != 'm' && *(am_suffix
+ 1) != 'M' && *(am_suffix
+ 1) != 0))
5094 if (strlen (pm_suffix
) > 2 || (*pm_suffix
!= 'p' && *pm_suffix
!= 'P') ||
5095 (*(pm_suffix
+ 1) != 'm' && *(pm_suffix
+ 1) != 'M' && *(pm_suffix
+ 1) != 0))
5097 if (strlen (am_suffix
) != strlen (pm_suffix
))
5098 pm_suffix
= am_suffix
= "AM";
5100 if (state
->cur_format
.accum
!= NULL
) {
5101 g_string_append (state
->cur_format
.accum
, am_suffix
);
5102 g_string_append_c (state
->cur_format
.accum
, '/');
5103 g_string_append (state
->cur_format
.accum
, pm_suffix
);
5108 odf_embedded_text_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5110 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5112 state
->cur_format
.offset
= 0;
5114 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5115 if (oo_attr_int (xin
, attrs
, OO_NS_NUMBER
,
5116 "position", &(state
->cur_format
.offset
)))
5121 odf_insert_in_integer (OOParseState
*state
, const char *str
)
5123 gboolean needs_quoting
= FALSE
;
5125 GString
*accum
= state
->cur_format
.accum
;
5126 int pos
= state
->cur_format
.offset
;
5128 g_return_if_fail (pos
>= 0 && pos
< (int)accum
->len
);
5131 * We want to insert str in front of the state->cur_format.offset's
5132 * integer digit. For the moment we assume that we have just an
5133 * integer and str does not contain any quotation marks
5136 for (p
= str
; *p
; p
++) {
5144 needs_quoting
= TRUE
;
5149 if (needs_quoting
) {
5150 g_string_insert (accum
, accum
->len
- pos
, "\"\"");
5151 g_string_insert (accum
, accum
->len
- pos
- 1, str
);
5153 g_string_insert (accum
, accum
->len
- pos
, str
);
5158 odf_embedded_text_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
5160 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5162 if (state
->cur_format
.accum
== NULL
)
5165 odf_insert_in_integer (state
, xin
->content
->str
);
5167 state
->cur_format
.offset
= 0;
5171 odf_date_text_start (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
5173 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5174 state
->cur_format
.offset
= 0;
5175 state
->cur_format
.string_opened
= FALSE
;
5179 oo_date_text_append_quoted (OOParseState
*state
, char const *cnt
, int cnt_len
)
5181 if (!state
->cur_format
.string_opened
)
5182 g_string_append_c (state
->cur_format
.accum
, '"');
5183 state
->cur_format
.string_opened
= TRUE
;
5184 g_string_append_len (state
->cur_format
.accum
, cnt
, cnt_len
);
5188 oo_date_text_append_unquoted (OOParseState
*state
, char cnt
)
5190 if (state
->cur_format
.string_opened
)
5191 g_string_append_c (state
->cur_format
.accum
, '"');
5192 state
->cur_format
.string_opened
= FALSE
;
5193 g_string_append_c (state
->cur_format
.accum
, cnt
);
5197 oo_date_text_append (OOParseState
*state
, char const *cnt
, int cnt_len
)
5200 if (NULL
!= strchr (" /-(),:",*cnt
)) {
5201 oo_date_text_append_unquoted (state
, *cnt
);
5202 oo_date_text_append (state
, cnt
+ 1, cnt_len
- 1);
5204 } else if (state
->cur_format
.percentage
&& *cnt
== '%') {
5205 oo_date_text_append_unquoted (state
, '%');
5206 state
->cur_format
.percent_sign_seen
= TRUE
;
5207 oo_date_text_append (state
, cnt
+ 1, cnt_len
- 1);
5209 } else if (*cnt
== '"') {
5210 oo_date_text_append_unquoted (state
, '\\');
5211 oo_date_text_append_unquoted (state
, '"');
5212 oo_date_text_append (state
, cnt
+ 1, cnt_len
- 1);
5215 oo_date_text_append_quoted (state
, cnt
, 1);
5216 oo_date_text_append (state
, cnt
+ 1, cnt_len
- 1);
5221 /* date_text_end is also used for non-date formats */
5223 oo_date_text_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
5225 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5227 if (state
->cur_format
.accum
== NULL
)
5230 if (xin
->content
->len
> state
->cur_format
.offset
)
5231 oo_date_text_append (state
, xin
->content
->str
+ state
->cur_format
.offset
,
5232 xin
->content
->len
- state
->cur_format
.offset
);
5234 if (state
->cur_format
.string_opened
) {
5235 g_string_append_c (state
->cur_format
.accum
, '"');
5236 state
->cur_format
.string_opened
= FALSE
;
5238 state
->cur_format
.offset
= 0;
5242 oo_date_style (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5244 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5245 char const *name
= NULL
;
5246 int magic
= GO_FORMAT_MAGIC_NONE
;
5247 gboolean format_source_is_language
= FALSE
;
5248 gboolean truncate_hour_on_overflow
= TRUE
;
5250 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5251 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "name"))
5252 name
= CXML2C (attrs
[1]);
5253 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "family") &&
5254 !attr_eq (attrs
[1], "data-style"))
5256 else if (oo_attr_int (xin
, attrs
, OO_GNUM_NS_EXT
,
5257 "format-magic", &magic
))
5259 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_NUMBER
, "format-source"))
5260 format_source_is_language
= attr_eq (attrs
[1], "language");
5261 else if (oo_attr_bool (xin
, attrs
, OO_NS_NUMBER
,
5262 "truncate-on-overflow", &truncate_hour_on_overflow
));
5264 g_return_if_fail (state
->cur_format
.accum
== NULL
);
5266 /* We always save a magic number with source language, so if that is gone somebody may have changed formats */
5267 state
->cur_format
.magic
= format_source_is_language
? magic
: GO_FORMAT_MAGIC_NONE
;
5268 state
->cur_format
.accum
= (state
->cur_format
.magic
== GO_FORMAT_MAGIC_NONE
) ? g_string_new (NULL
) : NULL
;
5269 state
->cur_format
.name
= g_strdup (name
);
5270 state
->cur_format
.percentage
= FALSE
;
5271 state
->cur_format
.truncate_hour_on_overflow
= truncate_hour_on_overflow
;
5272 state
->cur_format
.elapsed_set
= 0;
5273 state
->cur_format
.pos_seconds
= 0;
5274 state
->cur_format
.pos_minutes
= 0;
5278 oo_date_style_end_rm_elapsed (GString
*str
, guint pos
)
5281 g_return_if_fail (str
->len
> pos
&& str
->str
[pos
] == '[');
5283 g_string_erase (str
, pos
, 1);
5284 end
= strcspn (str
->str
+ pos
, "]");
5285 g_string_erase (str
, pos
+ end
, 1);
5289 oo_date_style_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
5291 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5292 int elapsed
= state
->cur_format
.elapsed_set
;
5294 if (state
->cur_format
.name
== NULL
) {
5295 if (state
->cur_format
.accum
) {
5296 g_string_free (state
->cur_format
.accum
, TRUE
);
5297 state
->cur_format
.accum
= NULL
;
5299 oo_warning (xin
, _("Unnamed date style ignored."));
5301 if (state
->cur_format
.magic
!= GO_FORMAT_MAGIC_NONE
)
5302 g_hash_table_insert (state
->formats
, state
->cur_format
.name
,
5303 go_format_new_magic (state
->cur_format
.magic
));
5305 g_return_if_fail (state
->cur_format
.accum
!= NULL
);
5307 while (elapsed
!= 0 && elapsed
!= ODF_ELAPSED_SET_SECONDS
5308 && elapsed
!= ODF_ELAPSED_SET_MINUTES
5309 && elapsed
!= ODF_ELAPSED_SET_HOURS
) {
5310 /*We need to fix the format string since several times are set as "elapsed". */
5311 if (0 != (elapsed
& ODF_ELAPSED_SET_SECONDS
)) {
5312 oo_date_style_end_rm_elapsed (state
->cur_format
.accum
,
5313 state
->cur_format
.pos_seconds
);
5314 if (state
->cur_format
.pos_seconds
< state
->cur_format
.pos_minutes
)
5315 state
->cur_format
.pos_minutes
-= 2;
5316 elapsed
-= ODF_ELAPSED_SET_SECONDS
;
5318 oo_date_style_end_rm_elapsed (state
->cur_format
.accum
,
5319 state
->cur_format
.pos_minutes
);
5320 elapsed
-= ODF_ELAPSED_SET_MINUTES
;
5325 g_hash_table_insert (state
->formats
, state
->cur_format
.name
,
5326 oo_canonical_format (state
->cur_format
.accum
->str
));
5327 g_string_free (state
->cur_format
.accum
, TRUE
);
5330 state
->cur_format
.accum
= NULL
;
5331 state
->cur_format
.name
= NULL
;
5334 /*****************************************************************************************************/
5337 odf_fraction (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5339 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5340 gboolean grouping
= FALSE
;
5341 gboolean no_int_part
= FALSE
;
5342 gboolean denominator_fixed
= FALSE
;
5343 gboolean pi_scale
= FALSE
;
5344 int denominator
= 0;
5345 int min_d_digits
= 0;
5346 int max_d_digits
= 3;
5347 int min_i_digits
= -1;
5348 int min_n_digits
= 0;
5350 if (state
->cur_format
.accum
== NULL
)
5353 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5354 if (oo_attr_bool (xin
, attrs
, OO_NS_NUMBER
, "grouping", &grouping
)) {}
5355 else if (oo_attr_int (xin
, attrs
, OO_NS_NUMBER
, "denominator-value", &denominator
))
5356 denominator_fixed
= TRUE
;
5357 else if (oo_attr_int_range (xin
, attrs
, OO_NS_NUMBER
,
5358 "min-denominator-digits", &min_d_digits
, 0, 30))
5360 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
,
5361 "max-denominator-digits", &max_d_digits
, 0, 30))
5363 else if (oo_attr_int_range (xin
, attrs
, OO_NS_NUMBER
,
5364 "min-integer-digits", &min_i_digits
, 0, 30))
5366 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "no-integer-part", &no_int_part
)) {}
5367 else if (oo_attr_int_range (xin
, attrs
, OO_NS_NUMBER
,
5368 "min-numerator-digits", &min_n_digits
, 0, 30)) {}
5369 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "display-factor") &&
5370 attr_eq (attrs
[1], "pi"))
5373 if (!no_int_part
&& (state
->ver_odf
< 1.2 || min_i_digits
>= 0)) {
5374 g_string_append_c (state
->cur_format
.accum
, '#');
5375 odf_go_string_append_c_n (state
->cur_format
.accum
, '0',
5376 min_i_digits
> 0 ? min_i_digits
: 0);
5377 g_string_append_c (state
->cur_format
.accum
, ' ');
5379 odf_go_string_append_c_n (state
->cur_format
.accum
, '?', max_d_digits
- min_n_digits
);
5380 odf_go_string_append_c_n (state
->cur_format
.accum
, '0', min_n_digits
);
5382 g_string_append (state
->cur_format
.accum
, " pi");
5383 g_string_append_c (state
->cur_format
.accum
, '/');
5384 if (denominator_fixed
) {
5385 int denom
= denominator
;
5391 min_d_digits
-= count
;
5392 odf_go_string_append_c_n (state
->cur_format
.accum
, '0',
5394 g_string_append_printf (state
->cur_format
.accum
, "%i", denominator
);
5396 max_d_digits
-= min_d_digits
;
5397 odf_go_string_append_c_n (state
->cur_format
.accum
, '?',
5399 odf_go_string_append_c_n (state
->cur_format
.accum
, '0',
5405 odf_text_content (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
5407 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5408 g_string_append_c (state
->cur_format
.accum
, '@');
5412 odf_number (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5414 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5415 gboolean grouping
= FALSE
;
5416 int decimal_places
= 0;
5417 gboolean decimals_specified
= FALSE
;
5418 /* gnm_float display_factor = 1.; */
5419 int min_i_digits
= 1;
5420 int min_i_chars
= 1;
5422 if (state
->cur_format
.accum
== NULL
)
5425 /* We are ignoring number:decimal-replacement */
5427 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5428 if (oo_attr_bool (xin
, attrs
, OO_NS_NUMBER
, "grouping", &grouping
))
5430 else if (oo_attr_int_range (xin
, attrs
, OO_NS_NUMBER
, "decimal-places", &decimal_places
, 0, 30)) {
5431 decimals_specified
= TRUE
;
5432 } /* else if (gsf_xml_in_namecmp (xin, CXML2C (attrs[0]), OO_NS_NUMBER, */
5433 /* "display-factor")) */
5434 /* display_factor = gnm_strto (CXML2C (attrs[1]), NULL); */
5435 else if (oo_attr_int_range (xin
, attrs
, OO_NS_NUMBER
,
5436 "min-integer-digits", &min_i_digits
, 0, 30))
5438 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
,
5439 "min-integer-chars", &min_i_chars
, 0, 30))
5442 if (decimals_specified
|| (min_i_digits
!= 1) || grouping
|| (min_i_chars
> min_i_digits
)) {
5443 if (min_i_chars
> min_i_digits
) {
5444 go_format_generate_number_str (state
->cur_format
.accum
, min_i_chars
, decimal_places
,
5445 grouping
, FALSE
, FALSE
, NULL
, NULL
);
5446 while (min_i_chars
> min_i_digits
) {
5447 /* substitute the left most 0 by ? */
5448 char *zero
= strchr (state
->cur_format
.accum
->str
, '0');
5454 go_format_generate_number_str (state
->cur_format
.accum
, min_i_digits
, decimal_places
,
5455 grouping
, FALSE
, FALSE
, NULL
, NULL
);
5458 g_string_append (state
->cur_format
.accum
, go_format_as_XL (go_format_general ()));
5462 odf_scientific (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5464 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5465 GOFormatDetails
*details
;
5466 gboolean engineering
= FALSE
;
5467 gboolean use_literal_E
= FALSE
;
5469 if (state
->cur_format
.accum
== NULL
)
5472 details
= go_format_details_new (GO_FORMAT_SCIENTIFIC
);
5474 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5475 if (oo_attr_bool (xin
, attrs
, OO_NS_NUMBER
, "grouping", &details
->thousands_sep
)) {}
5476 else if (oo_attr_int_range (xin
, attrs
, OO_NS_NUMBER
, "decimal-places",
5477 &details
->num_decimals
, 0, 30))
5479 else if (oo_attr_int_range (xin
, attrs
, OO_NS_NUMBER
, "min-integer-digits",
5480 &details
->min_digits
, 0, 30))
5482 else if (oo_attr_int_range (xin
, attrs
, OO_NS_NUMBER
, "min-exponent-digits",
5483 &details
->exponent_digits
, 0, 30))
5485 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "forced-exponent-sign",
5486 &(details
->exponent_sign_forced
)))
5488 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "engineering",
5491 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "literal-E",
5494 details
->exponent_step
= 3;
5495 details
->use_markup
= !use_literal_E
;
5496 details
->simplify_mantissa
= (details
->min_digits
== 0) && !use_literal_E
;
5497 go_format_generate_str (state
->cur_format
.accum
, details
);
5499 go_format_details_free (details
);
5503 odf_currency_symbol_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
5505 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5507 if (state
->cur_format
.accum
== NULL
)
5509 if (0 == strcmp (xin
->content
->str
, "$")) {
5510 g_string_append_c (state
->cur_format
.accum
, '$');
5513 g_string_append (state
->cur_format
.accum
, "[$");
5514 go_string_append_gstring (state
->cur_format
.accum
, xin
->content
);
5515 g_string_append_c (state
->cur_format
.accum
, ']');
5520 odf_map (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5522 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5523 char const *condition
= NULL
;
5524 char const *style_name
= NULL
;
5526 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5527 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "condition"))
5528 condition
= attrs
[1];
5529 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "apply-style-name"))
5530 style_name
= attrs
[1];
5532 if (condition
!= NULL
&& style_name
!= NULL
&& g_str_has_prefix (condition
, "value()")) {
5534 while (*condition
== ' ') condition
++;
5535 state
->conditions
= g_slist_prepend (state
->conditions
, g_strdup (condition
));
5536 state
->cond_formats
= g_slist_prepend (state
->cond_formats
,
5537 g_strdup (style_name
));
5542 odf_format_invisible_text (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5544 /* This can only be called inside a fixed text string */
5545 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5546 char const *cnt
= xin
->content
->str
+ state
->cur_format
.offset
;
5547 int cnt_len
= xin
->content
->len
- state
->cur_format
.offset
;
5548 char const *text
= NULL
;
5551 state
->cur_format
.offset
+= 1;
5553 } else if (cnt_len
> 1) {
5554 oo_date_text_append (state
, cnt
, cnt_len
- 1);
5555 state
->cur_format
.offset
+= cnt_len
;
5558 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5559 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "char"))
5560 text
= CXML2C (attrs
[1]);
5563 if (state
->cur_format
.string_opened
) {
5564 g_string_append_c (state
->cur_format
.accum
, '"');
5565 state
->cur_format
.string_opened
= FALSE
;
5567 g_string_append_c (state
->cur_format
.accum
, '_');
5568 g_string_append (state
->cur_format
.accum
, text
);
5573 odf_format_repeated_text_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
5575 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5577 /* This really only works for a single character. */
5578 g_string_append_c (state
->cur_format
.accum
, '*');
5579 g_string_append (state
->cur_format
.accum
, xin
->content
->str
);
5583 odf_number_color (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5585 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5587 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
5588 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "color")){
5590 if (3 == sscanf (CXML2C (attrs
[1]), "#%2x%2x%2x", &r
, &g
, &b
)) {
5591 GOColor col
= GO_COLOR_FROM_RGB (r
, g
, b
);
5592 int i
= go_format_palette_index_from_color (col
);
5593 char *color
= go_format_palette_name_of_index (i
);
5594 g_string_append_c (state
->cur_format
.accum
, '[');
5595 g_string_append (state
->cur_format
.accum
, color
);
5596 g_string_append_c (state
->cur_format
.accum
, ']');
5604 odf_number_style (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5606 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5607 char const *name
= NULL
;
5609 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5610 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "name"))
5611 name
= CXML2C (attrs
[1]);
5613 g_return_if_fail (state
->cur_format
.accum
== NULL
);
5615 state
->cur_format
.accum
= g_string_new (NULL
);
5616 state
->cur_format
.name
= g_strdup (name
);
5617 state
->cur_format
.percentage
= FALSE
;
5618 state
->cur_format
.percent_sign_seen
= FALSE
;
5619 state
->conditions
= NULL
;
5620 state
->cond_formats
= NULL
;
5625 odf_number_percentage_style (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5627 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5629 odf_number_style (xin
, attrs
);
5630 state
->cur_format
.percentage
= TRUE
;
5634 odf_cond_to_xl (GsfXMLIn
*xin
, GString
*dst
, const char *cond
, int part
, int parts
)
5637 const char *oper
; /* xl-syntax */
5639 const char *cond0
= cond
;
5641 while (g_ascii_isspace (*cond
))
5644 if (cond
[0] == '>' && cond
[1] == '=')
5645 oper
= ">=", cond
+= 2;
5646 else if (cond
[0] == '>')
5648 else if (cond
[0] == '<' && cond
[1] == '=')
5649 oper
= "<=", cond
+= 2;
5650 else if (cond
[0] == '<' && cond
[1] == '>')
5651 oper
= "<>", cond
+= 2; /* Not standard, see bug 727297 */
5652 else if (cond
[0] == '<')
5654 else if (cond
[0] == '!' && cond
[1] == '=')
5655 oper
= "<>", cond
+= 2; /* surprise! */
5656 else if (cond
[0] == '=')
5661 while (g_ascii_isspace (*cond
))
5663 val
= go_strtod (cond
, &end
);
5664 if (*end
!= 0 || !go_finite (val
))
5668 * Don't add the default condition. Note, that on save we cannot store
5669 * whether the condition was implicit or not, so just assume it was.
5671 if (part
<= 2 && val
== 0.0) {
5672 static const char *defaults
[3] = { ">", "<", "=" };
5673 const char *def
= (parts
== 2 && part
== 0)
5676 if (g_str_equal (oper
, def
))
5680 g_string_append_c (dst
, '[');
5681 g_string_append (dst
, oper
);
5682 g_string_append (dst
, cond
); /* Copy value in string form */
5683 g_string_append_c (dst
, ']');
5687 oo_warning (xin
, _("Corrupted file: invalid number format condition [%s]."), cond0
);
5692 odf_number_style_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
5694 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5696 g_return_if_fail (state
->cur_format
.accum
!= NULL
);
5698 if (state
->cur_format
.percentage
&& !state
->cur_format
.percent_sign_seen
)
5699 g_string_append_c (state
->cur_format
.accum
, '%');
5700 state
->cur_format
.percentage
= FALSE
;
5702 if (state
->cur_format
.name
== NULL
) {
5703 g_string_free (state
->cur_format
.accum
, TRUE
);
5704 state
->cur_format
.accum
= NULL
;
5705 oo_warning (xin
, _("Corrupted file: unnamed number style ignored."));
5709 if (state
->conditions
!= NULL
) {
5710 /* We have conditional formats */
5711 int part
= 0, parts
= g_slist_length (state
->conditions
) + 1;
5713 GString
*accum
= g_string_new (NULL
);
5715 /* We added things in opposite order, so reverse now. */
5716 lc
= state
->conditions
= g_slist_reverse (state
->conditions
);
5717 lf
= state
->cond_formats
= g_slist_reverse (state
->cond_formats
);
5720 const char *cond
= lc
->data
;
5721 const char *fmtname
= lf
->data
;
5722 GOFormat
const *fmt
= g_hash_table_lookup (state
->formats
, fmtname
);
5724 odf_cond_to_xl (xin
, accum
, cond
, part
, parts
);
5727 oo_warning (xin
, _("This file appears corrupted, required "
5728 "formats are missing."));
5729 fmt
= go_format_general ();
5732 g_string_append (accum
, go_format_as_XL (fmt
));
5733 g_string_append_c (accum
, ';');
5739 if (state
->cur_format
.accum
->len
== 0)
5740 g_string_append (accum
, "General");
5742 g_string_append (accum
, state
->cur_format
.accum
->str
);
5744 g_string_free (state
->cur_format
.accum
, TRUE
);
5745 state
->cur_format
.accum
= accum
;
5748 g_hash_table_insert (state
->formats
, state
->cur_format
.name
,
5749 oo_canonical_format (state
->cur_format
.accum
->str
));
5750 g_string_free (state
->cur_format
.accum
, TRUE
);
5751 state
->cur_format
.accum
= NULL
;
5752 state
->cur_format
.name
= NULL
;
5753 g_slist_free_full (state
->conditions
, g_free
);
5754 state
->conditions
= NULL
;
5755 g_slist_free_full (state
->cond_formats
, g_free
);
5756 state
->cond_formats
= NULL
;
5759 /*****************************************************************************************************/
5761 static GtkPaperSize
*
5762 odf_get_paper_size (gnm_float width
, gnm_float height
, gint orient
)
5764 GtkPaperSize
*size
= NULL
;
5765 char *name
, *display_name
;
5767 GList
*plist
= gtk_paper_size_get_paper_sizes (TRUE
), *l
;
5769 for (l
= plist
; l
!= NULL
; l
= l
->next
) {
5770 GtkPaperSize
*n_size
= l
->data
;
5771 double n_width
= gtk_paper_size_get_width (n_size
, GTK_UNIT_POINTS
);
5772 double n_height
= gtk_paper_size_get_height (n_size
, GTK_UNIT_POINTS
);
5776 if (orient
== GTK_PAGE_ORIENTATION_PORTRAIT
||
5777 orient
== GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT
) {
5778 w_diff
= n_width
- width
;
5779 h_diff
= n_height
- height
;
5781 w_diff
= n_height
- width
;
5782 h_diff
= n_width
- height
;
5785 if (w_diff
> -2. && w_diff
< 2. && h_diff
> -2 && h_diff
< 2) {
5786 size
= gtk_paper_size_copy (n_size
);
5790 g_list_free_full (plist
, (GDestroyNotify
)gtk_paper_size_free
);
5795 name
= g_strdup_printf ("odf_%ix%i", (int)width
, (int)height
);
5796 display_name
= g_strdup_printf (_("Paper from ODF file: %ipt\xE2\xA8\x89%ipt"), (int)width
, (int)height
);
5797 size
= gtk_paper_size_new_custom (name
, display_name
, width
, height
, GTK_UNIT_POINTS
);
5799 g_free (display_name
);
5804 odf_header_properties (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5806 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5807 gboolean height_set
= FALSE
;
5812 if (state
->print
.cur_pi
== NULL
)
5814 gps
= gnm_print_info_get_page_setup (state
->print
.cur_pi
);
5815 page_margin
= gtk_page_setup_get_top_margin (gps
, GTK_UNIT_POINTS
);
5817 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5818 if (oo_attr_distance (xin
, attrs
, OO_NS_SVG
, "height", &pts
)) {
5819 print_info_set_edge_to_below_header (state
->print
.cur_pi
, pts
+ page_margin
);
5821 } else if (oo_attr_distance (xin
, attrs
, OO_NS_FO
, "min-height", &pts
))
5823 print_info_set_edge_to_below_header
5824 (state
->print
.cur_pi
, pts
+ page_margin
);
5828 odf_footer_properties (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5830 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5831 gboolean height_set
= FALSE
;
5836 if (state
->print
.cur_pi
== NULL
)
5838 gps
= gnm_print_info_get_page_setup (state
->print
.cur_pi
);
5839 page_margin
= gtk_page_setup_get_bottom_margin (gps
, GTK_UNIT_POINTS
);
5841 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5842 if (oo_attr_distance (xin
, attrs
, OO_NS_SVG
, "height", &pts
)) {
5843 print_info_set_edge_to_above_footer (state
->print
.cur_pi
, pts
+ page_margin
);
5845 } else if (oo_attr_distance (xin
, attrs
, OO_NS_FO
, "min-height", &pts
))
5847 print_info_set_edge_to_above_footer
5848 (state
->print
.cur_pi
, pts
+ page_margin
);
5853 odf_page_layout_properties (GsfXMLIn
*xin
, xmlChar
const **attrs
)
5855 static OOEnum
const centre_type
[] = {
5862 static OOEnum
const print_order_type
[] = {
5867 static OOEnum
const print_orientation_type
[] = {
5868 {"portrait" , GTK_PAGE_ORIENTATION_PORTRAIT
},
5869 {"landscape" , GTK_PAGE_ORIENTATION_LANDSCAPE
},
5873 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
5874 gnm_float pts
, height
, width
;
5875 gboolean h_set
= FALSE
, w_set
= FALSE
;
5878 gint orient
= GTK_PAGE_ORIENTATION_PORTRAIT
;
5879 gboolean gnm_style_print
= FALSE
;
5880 gboolean annotations_at_end
= FALSE
;
5881 gnm_float scale_to
= 1.;
5882 gint scale_to_x
= 0;
5883 gint scale_to_y
= 0;
5884 GnmPrintInformation
*pi
= state
->print
.cur_pi
;
5888 gps
= gnm_print_info_get_page_setup (state
->print
.cur_pi
);
5889 gtk_page_setup_set_orientation (gps
, GTK_PAGE_ORIENTATION_PORTRAIT
);
5891 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
5892 if (oo_attr_distance (xin
, attrs
, OO_NS_FO
, "margin-left", &pts
))
5893 gtk_page_setup_set_left_margin (gps
, pts
, GTK_UNIT_POINTS
);
5894 else if (oo_attr_distance (xin
, attrs
, OO_NS_FO
, "margin-right", &pts
))
5895 gtk_page_setup_set_right_margin (gps
, pts
, GTK_UNIT_POINTS
);
5896 else if (oo_attr_distance (xin
, attrs
, OO_NS_FO
, "margin-top", &pts
))
5897 gtk_page_setup_set_top_margin (gps
, pts
, GTK_UNIT_POINTS
);
5898 else if (oo_attr_distance (xin
, attrs
, OO_NS_FO
, "margin-bottom", &pts
))
5899 gtk_page_setup_set_bottom_margin (gps
, pts
, GTK_UNIT_POINTS
);
5900 else if (oo_attr_distance (xin
, attrs
, OO_NS_FO
, "page-height", &height
))
5902 else if (oo_attr_distance (xin
, attrs
, OO_NS_FO
, "page-width", &width
))
5904 else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "table-centering",
5905 centre_type
, &tmp
)) {
5906 pi
->center_horizontally
= ((1 & tmp
) != 0);
5907 pi
->center_vertically
= ((2 & tmp
) != 0);
5908 } else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "print-page-order",
5909 print_order_type
, &tmp
)) {
5910 pi
->print_across_then_down
= (tmp
== 0);
5911 } else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "print-orientation",
5912 print_orientation_type
, &orient
)) {
5913 gtk_page_setup_set_orientation (gps
, orient
);
5914 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
5915 OO_NS_STYLE
, "print")) {
5916 gchar
**items
= g_strsplit (CXML2C (attrs
[1]), " ", 0);
5917 gchar
**items_c
= items
;
5918 pi
->print_grid_lines
= 0;
5919 pi
->print_titles
= 0;
5920 pi
->comment_placement
= GNM_PRINT_COMMENTS_NONE
;
5921 for (;items
!= NULL
&& *items
; items
++)
5922 if (0 == strcmp (*items
, "grid"))
5923 pi
->print_grid_lines
= 1;
5924 else if (0 == strcmp (*items
, "headers"))
5925 pi
->print_titles
= 1;
5926 else if (0 == strcmp (*items
, "annotations"))
5927 /* ODF does not distinguish AT_END and IN_PLACE */
5928 pi
->comment_placement
= GNM_PRINT_COMMENTS_AT_END
;
5929 g_strfreev (items_c
);
5930 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
5931 OO_GNUM_NS_EXT
, "style-print")) {
5932 gchar
**items
= g_strsplit (CXML2C (attrs
[1]), " ", 0);
5933 gchar
**items_c
= items
;
5934 gnm_style_print
= TRUE
;
5935 pi
->print_black_and_white
= 0;
5936 pi
->print_as_draft
= 0;
5937 pi
->print_even_if_only_styles
= 0;
5938 pi
->error_display
= GNM_PRINT_ERRORS_AS_DISPLAYED
;
5939 for (;items
!= NULL
&& *items
; items
++)
5940 if (0 == strcmp (*items
, "annotations_at_end"))
5941 annotations_at_end
= TRUE
;
5942 else if (0 == strcmp (*items
, "black_n_white"))
5943 pi
->print_black_and_white
= 1;
5944 else if (0 == strcmp (*items
, "draft"))
5945 pi
->print_as_draft
= 1;
5946 else if (0 == strcmp (*items
, "errors_as_blank"))
5947 pi
->error_display
= GNM_PRINT_ERRORS_AS_BLANK
;
5948 else if (0 == strcmp (*items
, "errors_as_dashes"))
5949 pi
->error_display
= GNM_PRINT_ERRORS_AS_DASHES
;
5950 else if (0 == strcmp (*items
, "errors_as_na"))
5951 pi
->error_display
= GNM_PRINT_ERRORS_AS_NA
;
5952 else if (0 == strcmp (*items
, "print_even_if_only_styles"))
5953 pi
->print_even_if_only_styles
= 1;
5954 g_strfreev (items_c
);
5955 } else if (oo_attr_int_range (xin
, attrs
, OO_NS_STYLE
, "scale-to-pages",
5956 &scale_to_x
, 1, INT_MAX
)) {
5957 scale_to_y
= scale_to_x
;
5959 } else if (oo_attr_int_range (xin
, attrs
, OO_NS_STYLE
, "scale-to-X",
5960 &scale_to_x
, 1, INT_MAX
)) {
5962 } else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
, "scale-to-X",
5963 &scale_to_x
, 1, INT_MAX
)) {
5965 } else if (oo_attr_int_range (xin
, attrs
, OO_NS_STYLE
, "scale-to-Y",
5966 &scale_to_y
, 1, INT_MAX
)) {
5968 } else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
, "scale-to-Y",
5969 &scale_to_y
, 1, INT_MAX
)) {
5971 } else if (oo_attr_percent (xin
, attrs
, OO_NS_STYLE
, "scale-to", &scale_to
))
5974 pi
->scaling
.dim
.cols
= scale_to_x
;
5975 pi
->scaling
.dim
.rows
= scale_to_y
;
5976 pi
->scaling
.type
= PRINT_SCALE_FIT_PAGES
;
5978 pi
->scaling
.type
= PRINT_SCALE_PERCENTAGE
;
5979 pi
->scaling
.percentage
.x
= pi
->scaling
.percentage
.y
= scale_to
* 100;
5982 if (gnm_style_print
&& pi
->comment_placement
!= GNM_PRINT_COMMENTS_NONE
)
5983 pi
->comment_placement
= annotations_at_end
? GNM_PRINT_COMMENTS_AT_END
:
5984 GNM_PRINT_COMMENTS_IN_PLACE
;
5986 /* STYLE "writing-mode" is being ignored since we can't store it anywhere atm */
5988 if (h_set
&& w_set
) {
5990 size
= odf_get_paper_size (width
, height
, orient
);
5991 gtk_page_setup_set_paper_size (gps
, size
);
5992 gtk_paper_size_free (size
);
5998 odf_page_layout (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6000 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6001 char const *name
= NULL
;
6003 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6004 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "name"))
6005 name
= CXML2C (attrs
[1]);
6008 oo_warning (xin
, _("Missing page layout identifier"));
6009 name
= "Missing page layout identifier";
6011 state
->print
.cur_pi
= gnm_print_information_new (TRUE
);
6012 g_hash_table_insert (state
->styles
.page_layouts
, g_strdup (name
),
6013 state
->print
.cur_pi
);
6017 odf_page_layout_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
6019 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6021 state
->print
.cur_pi
= NULL
;
6025 odf_header_footer_left (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
6027 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6028 gboolean display
= TRUE
;
6030 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6031 if (oo_attr_bool (xin
, attrs
, OO_NS_STYLE
, "display",
6034 if (display
&& !state
->hd_ft_left_warned
) {
6035 oo_warning (xin
, _("Gnumeric does not support having a different "
6036 "style for left pages. This style is ignored."));
6037 state
->hd_ft_left_warned
= TRUE
;
6042 odf_master_page (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6044 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6045 char const *name
= NULL
;
6046 char const *pl_name
= NULL
;
6047 GnmPrintInformation
*pi
= NULL
;
6049 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6050 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "name"))
6051 name
= CXML2C (attrs
[1]);
6052 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
6053 OO_NS_STYLE
, "page-layout-name"))
6054 pl_name
= CXML2C (attrs
[1]);
6056 if (pl_name
!= NULL
)
6057 pi
= g_hash_table_lookup (state
->styles
.page_layouts
, pl_name
);
6059 if (state
->ver
!= OOO_VER_1
) /* For OOO_VER_1 this may be acceptable */
6060 oo_warning (xin
, _("Master page style without page layout encountered!"));
6061 state
->print
.cur_pi
= gnm_print_information_new (TRUE
);
6063 state
->print
.cur_pi
= gnm_print_info_dup (pi
);
6066 oo_warning (xin
, _("Master page style without name encountered!"));
6067 name
= "Master page style without name encountered!";
6070 gnm_print_hf_free (state
->print
.cur_pi
->header
);
6071 gnm_print_hf_free (state
->print
.cur_pi
->footer
);
6072 state
->print
.cur_pi
->header
= gnm_print_hf_new (NULL
, NULL
, NULL
);
6073 state
->print
.cur_pi
->footer
= gnm_print_hf_new (NULL
, NULL
, NULL
);
6075 g_hash_table_insert (state
->styles
.master_pages
, g_strdup (name
), state
->print
.cur_pi
);
6079 odf_master_page_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
6081 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6083 state
->print
.cur_pi
= NULL
;
6084 state
->print
.cur_hf
= NULL
;
6085 state
->print
.cur_hf_format
= NULL
;
6089 odf_header_footer_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
6091 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6093 if (state
->text_p_stack
) {
6094 oo_text_p_t
*ptr
= state
->text_p_stack
->data
;
6096 g_free (*(state
->print
.cur_hf_format
));
6097 *(state
->print
.cur_hf_format
) = g_string_free (ptr
->gstr
, FALSE
);
6102 odf_pop_text_p (state
);
6106 odf_header_footer (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6108 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6109 gboolean display
= TRUE
;
6113 if (state
->print
.cur_pi
== NULL
)
6115 gps
= gnm_print_info_get_page_setup (state
->print
.cur_pi
);
6117 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6118 if (oo_attr_bool (xin
, attrs
, OO_NS_STYLE
, "display",
6120 if (xin
->node
->user_data
.v_int
== 0) {
6121 state
->print
.cur_hf
= state
->print
.cur_pi
->header
;
6122 margin
= gtk_page_setup_get_top_margin (gps
, GTK_UNIT_POINTS
);
6124 if (margin
>= state
->print
.cur_pi
->edge_to_below_header
)
6125 print_info_set_edge_to_below_header (state
->print
.cur_pi
, margin
+ 1);
6127 print_info_set_edge_to_below_header (state
->print
.cur_pi
, margin
);
6129 state
->print
.cur_hf
= state
->print
.cur_pi
->footer
;
6130 margin
= gtk_page_setup_get_bottom_margin (gps
, GTK_UNIT_POINTS
);
6132 if (margin
>= state
->print
.cur_pi
->edge_to_above_footer
)
6133 print_info_set_edge_to_above_footer (state
->print
.cur_pi
, margin
+ 1);
6135 print_info_set_edge_to_above_footer (state
->print
.cur_pi
, margin
);
6137 state
->print
.cur_hf_format
= &state
->print
.cur_hf
->middle_format
;
6139 odf_push_text_p (state
, FALSE
);
6143 odf_hf_region_end (GsfXMLIn
*xin
, GsfXMLBlob
*blob
)
6145 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6147 odf_header_footer_end (xin
, blob
);
6148 state
->print
.cur_hf_format
= &state
->print
.cur_hf
->middle_format
;
6152 odf_hf_region (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
6154 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6156 if (state
->print
.cur_hf
!= NULL
)
6157 switch (xin
->node
->user_data
.v_int
) {
6159 state
->print
.cur_hf_format
= &state
->print
.cur_hf
->left_format
;
6162 state
->print
.cur_hf_format
= &state
->print
.cur_hf
->middle_format
;
6165 state
->print
.cur_hf_format
= &state
->print
.cur_hf
->right_format
;
6168 odf_push_text_p (state
, FALSE
);
6172 odf_hf_item_start (GsfXMLIn
*xin
)
6174 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6176 if (xin
->content
->str
!= NULL
&& *xin
->content
->str
!= 0) {
6177 oo_text_p_t
*ptr
= state
->text_p_stack
->data
;
6178 odf_text_p_add_text (state
, xin
->content
->str
+ ptr
->offset
);
6179 ptr
->offset
= strlen (xin
->content
->str
);
6184 odf_hf_item (GsfXMLIn
*xin
, char const *item
)
6186 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6188 odf_text_p_add_text (state
, "&[");
6189 odf_text_p_add_text (state
, item
);
6190 odf_text_p_add_text (state
, "]");
6194 odf_hf_sheet_name (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
6196 odf_hf_item_start (xin
);
6197 odf_hf_item (xin
, _("TAB"));
6201 odf_hf_item_w_data_style (GsfXMLIn
*xin
, xmlChar
const **attrs
, char const *item
)
6203 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6204 char const *data_style_name
= NULL
;
6206 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6207 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "data-style-name"))
6208 data_style_name
= CXML2C (attrs
[1]);
6210 odf_hf_item_start (xin
);
6211 if (data_style_name
== NULL
)
6212 odf_hf_item (xin
, item
);
6214 GOFormat
const *fmt
=
6215 g_hash_table_lookup (state
->formats
, data_style_name
);
6217 char const *fmt_str
= go_format_as_XL (fmt
);
6218 char *str
= g_strconcat (item
, ":", fmt_str
, NULL
);
6219 odf_hf_item (xin
, str
);
6226 odf_hf_date (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6228 odf_hf_item_start (xin
);
6229 odf_hf_item_w_data_style (xin
, attrs
, _("DATE"));
6233 odf_hf_time (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6235 odf_hf_item_start (xin
);
6236 odf_hf_item_w_data_style (xin
, attrs
, _("TIME"));
6240 odf_hf_page_number (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
6242 odf_hf_item_start (xin
);
6243 odf_hf_item (xin
, _("PAGE"));
6247 odf_hf_page_count (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
6249 odf_hf_item_start (xin
);
6250 odf_hf_item (xin
, _("PAGES"));
6254 odf_hf_file (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6256 static OOEnum
const display_types
[] = {
6260 { "name-and-extension", 2 },
6263 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6266 if (state
->print
.cur_hf_format
== NULL
)
6269 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6270 if (oo_attr_enum (xin
, attrs
, OO_NS_TEXT
, "display", display_types
, &tmp
)) ;
6272 odf_hf_item_start (xin
);
6275 odf_hf_item (xin
, _("PATH"));
6276 odf_text_p_add_text (state
, "/");
6277 odf_hf_item (xin
, _("FILE"));
6280 odf_hf_item (xin
, _("PATH"));
6284 odf_hf_item (xin
, _("FILE"));
6290 odf_hf_expression (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6292 static OOEnum
const display_types
[] = {
6298 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6299 char const *formula
= NULL
;
6302 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6303 if (oo_attr_enum (xin
, attrs
, OO_NS_TEXT
, "display", display_types
, &tmp
)) ;
6304 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TEXT
, "formula"))
6305 formula
= CXML2C (attrs
[1]);
6310 if (formula
== NULL
|| *formula
== '\0') {
6311 oo_warning (xin
, _("Missing expression"));
6314 /* Since we have no sheets we postpone parsing the expression */
6315 gchar
const *str
= odf_string_id (state
, formula
);
6317 new = g_strconcat ((tmp
== 1) ? "cellt" : "cell", ":", str
, NULL
);
6318 odf_hf_item_start (xin
);
6319 odf_hf_item (xin
, new);
6325 odf_hf_title (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
6327 odf_hf_item_start (xin
);
6328 odf_hf_item (xin
, _("TITLE"));
6331 /*****************************************************************************************************/
6336 oo_set_gnm_border (G_GNUC_UNUSED GsfXMLIn
*xin
, GnmStyle
*style
,
6337 xmlChar
const *str
, GnmStyleElement location
)
6339 GnmStyleBorderType border_style
;
6340 GnmBorder
*old_border
, *new_border
;
6341 GnmStyleBorderLocation
const loc
=
6342 GNM_STYLE_BORDER_TOP
+ (int)(location
- MSTYLE_BORDER_TOP
);
6344 if (!strcmp ((char const *)str
, "hair"))
6345 border_style
= GNM_STYLE_BORDER_HAIR
;
6346 else if (!strcmp ((char const *)str
, "medium-dash"))
6347 border_style
= GNM_STYLE_BORDER_MEDIUM_DASH
;
6348 else if (!strcmp ((char const *)str
, "dash-dot"))
6349 border_style
= GNM_STYLE_BORDER_DASH_DOT
;
6350 else if (!strcmp ((char const *)str
, "medium-dash-dot"))
6351 border_style
= GNM_STYLE_BORDER_MEDIUM_DASH_DOT
;
6352 else if (!strcmp ((char const *)str
, "dash-dot-dot"))
6353 border_style
= GNM_STYLE_BORDER_DASH_DOT_DOT
;
6354 else if (!strcmp ((char const *)str
, "medium-dash-dot-dot"))
6355 border_style
= GNM_STYLE_BORDER_MEDIUM_DASH_DOT_DOT
;
6356 else if (!strcmp ((char const *)str
, "slanted-dash-dot"))
6357 border_style
= GNM_STYLE_BORDER_SLANTED_DASH_DOT
;
6359 oo_warning (xin
, _("Unknown Gnumeric border style \'%s\' "
6360 "encountered."), (char const *)str
);
6364 old_border
= gnm_style_get_border (style
, location
);
6365 new_border
= gnm_style_border_fetch (border_style
,
6367 style_color_ref(old_border
->color
)
6368 : style_color_black (),
6369 gnm_style_border_get_orientation (loc
));
6370 gnm_style_set_border (style
, location
, new_border
);
6374 oo_parse_border (GsfXMLIn
*xin
, GnmStyle
*style
,
6375 xmlChar
const *str
, GnmStyleElement location
)
6378 char const *end
= oo_parse_distance (xin
, str
, "border", &pts
);
6379 GnmBorder
*border
= NULL
;
6380 GnmColor
*color
= NULL
;
6381 const char *border_color
= NULL
;
6382 GnmStyleBorderType border_style
;
6383 GnmStyleBorderLocation
const loc
=
6384 GNM_STYLE_BORDER_TOP
+ (int)(location
- MSTYLE_BORDER_TOP
);
6386 if (end
== NULL
|| end
== CXML2C (str
))
6390 /* "0.035cm solid #000000" */
6391 border_color
= strchr (end
, '#');
6393 char *border_type
= g_strndup (end
, border_color
- end
);
6394 color
= oo_parse_color (xin
, CC2XML (border_color
), "color");
6397 if (g_str_has_prefix (border_type
, "none")||
6398 g_str_has_prefix (border_type
, "hidden"))
6399 border_style
= GNM_STYLE_BORDER_NONE
;
6400 else if (g_str_has_prefix (border_type
, "solid") ||
6401 g_str_has_prefix (border_type
, "groove") ||
6402 g_str_has_prefix (border_type
, "ridge") ||
6403 g_str_has_prefix (border_type
, "inset") ||
6404 g_str_has_prefix (border_type
, "outset")) {
6405 if (pts
<= OD_BORDER_THIN
)
6406 border_style
= GNM_STYLE_BORDER_THIN
;
6407 else if (pts
<= OD_BORDER_MEDIUM
)
6408 border_style
= GNM_STYLE_BORDER_MEDIUM
;
6410 border_style
= GNM_STYLE_BORDER_THICK
;
6411 } else if (g_str_has_prefix (border_type
, "dashed"))
6412 border_style
= GNM_STYLE_BORDER_DASHED
;
6413 else if (g_str_has_prefix (border_type
, "dotted"))
6414 border_style
= GNM_STYLE_BORDER_DOTTED
;
6416 border_style
= GNM_STYLE_BORDER_DOUBLE
;
6418 border
= gnm_style_border_fetch (border_style
, color
,
6419 gnm_style_border_get_orientation (loc
));
6420 border
->width
= pts
;
6421 gnm_style_set_border (style
, location
, border
);
6423 g_free (border_type
);
6428 odf_style_set_align_h (GnmStyle
*style
, gint h_align_is_valid
, gboolean repeat_content
,
6429 int text_align
, int gnm_halign
)
6432 gnm_style_set_align_h (style
, GNM_HALIGN_FILL
);
6433 else switch (h_align_is_valid
) {
6435 if (gnm_halign
> -1)
6436 gnm_style_set_align_h (style
, gnm_halign
);
6438 gnm_style_set_align_h (style
, (text_align
< 0) ? GNM_HALIGN_LEFT
: text_align
);
6441 gnm_style_set_align_h (style
, GNM_HALIGN_GENERAL
);
6449 oo_style_prop_cell (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6451 static OOEnum
const underline_styles
[] = {
6455 { "dot-dot-dash", 2 },
6462 static OOEnum
const underline_types
[] = {
6468 static OOEnum
const text_line_through_styles
[] = {
6472 { "dot-dot-dash", 1 },
6479 static OOEnum
const text_line_through_types
[] = {
6485 static OOEnum
const h_alignments
[] = {
6486 { "start", -1 }, /* see below, we may have a gnm:GnmHAlign attribute */
6487 { "left", GNM_HALIGN_LEFT
},
6488 { "center", GNM_HALIGN_CENTER
},
6489 { "end", GNM_HALIGN_RIGHT
}, /* This really depends on the text direction */
6490 { "right", GNM_HALIGN_RIGHT
},
6491 { "justify", GNM_HALIGN_JUSTIFY
},
6492 { "automatic", GNM_HALIGN_GENERAL
},
6495 static OOEnum
const v_alignments
[] = {
6496 { "bottom", GNM_VALIGN_BOTTOM
},
6497 { "top", GNM_VALIGN_TOP
},
6498 { "middle", GNM_VALIGN_CENTER
},
6499 { "automatic", -1 }, /* see below, we may have a gnm:GnmVAlign attribute */
6502 static OOEnum
const protections
[] = {
6504 { "hidden-and-protected", 1 | 2 },
6506 { "formula-hidden", 1 },
6507 { "protected formula-hidden", 1 | 2 },
6508 { "formula-hidden protected", 1 | 2 },
6511 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6512 GnmColor
*color
, *gnm_b_color
= NULL
, *gnm_p_color
= NULL
;
6513 int gnm_pattern
= 0;
6514 GnmStyle
*style
= state
->cur_style
.cells
->style
;
6518 gboolean v_alignment_is_fixed
= FALSE
;
6519 int strike_through_type
= -1, strike_through_style
= -1;
6520 int underline_type
= 0;
6521 int underline_style
= 0;
6522 gboolean underline_bold
= FALSE
;
6523 gboolean underline_low
= FALSE
;
6525 g_return_if_fail (style
!= NULL
);
6527 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6528 if ((color
= oo_attr_color (xin
, attrs
, OO_NS_FO
, "background-color"))) {
6529 gnm_style_set_back_color (style
, color
);
6530 if (color
== magic_transparent
)
6531 gnm_style_set_pattern (style
, 0);
6533 gnm_style_set_pattern (style
, 1);
6534 } else if ((color
= oo_attr_color (xin
, attrs
, OO_GNUM_NS_EXT
, "background-colour"))) {
6535 gnm_b_color
= color
;
6536 } else if ((color
= oo_attr_color (xin
, attrs
, OO_GNUM_NS_EXT
, "pattern-colour"))) {
6537 gnm_p_color
= color
;
6538 } else if (oo_attr_int (xin
, attrs
, OO_GNUM_NS_EXT
, "pattern", &gnm_pattern
)) {
6539 } else if ((color
= oo_attr_color (xin
, attrs
, OO_NS_FO
, "color")))
6540 gnm_style_set_font_color (style
, color
);
6541 else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "cell-protect", protections
, &tmp
)) {
6542 gnm_style_set_contents_locked (style
, (tmp
& 2) != 0);
6543 gnm_style_set_contents_hidden (style
, (tmp
& 1) != 0);
6544 } else if (oo_attr_enum (xin
, attrs
,
6545 (state
->ver
>= OOO_VER_OPENDOC
) ? OO_NS_FO
: OO_NS_STYLE
,
6546 "text-align", h_alignments
, &(state
->text_align
))) {
6547 /* Note that style:text-align-source, style:text_align, style:repeat-content */
6548 /* and gnm:GnmHAlign interact but can appear in any order and arrive from different */
6549 /* elements, so we can't use local variables */
6550 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "text-align-source")) {
6551 state
->h_align_is_valid
= attr_eq (attrs
[1], "fix") ? 1 : 2;
6552 } else if (oo_attr_bool (xin
, attrs
, OO_NS_STYLE
, "repeat-content", &(state
->repeat_content
))) {
6553 } else if (oo_attr_int (xin
,attrs
, OO_GNUM_NS_EXT
, "GnmHAlign", &(state
->gnm_halign
))) {
6554 }else if (oo_attr_enum (xin
, attrs
,
6555 (state
->ver
>= OOO_VER_OPENDOC
) ? OO_NS_STYLE
: OO_NS_FO
,
6556 "vertical-align", v_alignments
, &tmp
)) {
6558 gnm_style_set_align_v (style
, tmp
);
6559 v_alignment_is_fixed
= TRUE
;
6560 } else if (!v_alignment_is_fixed
)
6561 /* This should depend on the rotation */
6562 gnm_style_set_align_v (style
, GNM_VALIGN_BOTTOM
);
6563 } else if (oo_attr_int (xin
,attrs
, OO_GNUM_NS_EXT
, "GnmVAlign", &tmp
)) {
6564 if (!v_alignment_is_fixed
) {
6565 gnm_style_set_align_v (style
, tmp
);
6566 v_alignment_is_fixed
= TRUE
;
6568 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "wrap-option"))
6569 gnm_style_set_wrap_text (style
, attr_eq (attrs
[1], "wrap"));
6570 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "border-bottom"))
6571 oo_parse_border (xin
, style
, attrs
[1], MSTYLE_BORDER_BOTTOM
);
6572 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "border-left"))
6573 oo_parse_border (xin
, style
, attrs
[1], MSTYLE_BORDER_LEFT
);
6574 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "border-right"))
6575 oo_parse_border (xin
, style
, attrs
[1], MSTYLE_BORDER_RIGHT
);
6576 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "border-top"))
6577 oo_parse_border (xin
, style
, attrs
[1], MSTYLE_BORDER_TOP
);
6578 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "border")) {
6579 oo_parse_border (xin
, style
, attrs
[1], MSTYLE_BORDER_BOTTOM
);
6580 oo_parse_border (xin
, style
, attrs
[1], MSTYLE_BORDER_LEFT
);
6581 oo_parse_border (xin
, style
, attrs
[1], MSTYLE_BORDER_RIGHT
);
6582 oo_parse_border (xin
, style
, attrs
[1], MSTYLE_BORDER_TOP
);
6583 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "diagonal-bl-tr"))
6584 oo_parse_border (xin
, style
, attrs
[1], MSTYLE_BORDER_DIAGONAL
);
6585 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "diagonal-tl-br"))
6586 oo_parse_border (xin
, style
, attrs
[1], MSTYLE_BORDER_REV_DIAGONAL
);
6587 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "border-line-style-bottom"))
6588 oo_set_gnm_border (xin
, style
, attrs
[1], MSTYLE_BORDER_BOTTOM
);
6589 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "border-line-style-top"))
6590 oo_set_gnm_border (xin
, style
, attrs
[1], MSTYLE_BORDER_TOP
);
6591 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "border-line-style-left"))
6592 oo_set_gnm_border (xin
, style
, attrs
[1], MSTYLE_BORDER_LEFT
);
6593 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "border-line-style-right"))
6594 oo_set_gnm_border (xin
, style
, attrs
[1], MSTYLE_BORDER_RIGHT
);
6595 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "diagonal-bl-tr-line-style"))
6596 oo_set_gnm_border (xin
, style
, attrs
[1], MSTYLE_BORDER_DIAGONAL
);
6597 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "diagonal-tl-br-line-style"))
6598 oo_set_gnm_border (xin
, style
, attrs
[1], MSTYLE_BORDER_REV_DIAGONAL
);
6599 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "font-name"))
6600 /* According to the ODF standards, this name is just a reference to a */
6601 /* <style:font-face> element. So this may not be an acceptable font name! */
6602 gnm_style_set_font_name (style
, CXML2C (attrs
[1]));
6603 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "font-family"))
6604 gnm_style_set_font_name (style
, CXML2C (attrs
[1]));
6605 else if (oo_attr_distance (xin
, attrs
, OO_NS_FO
, "font-size", &tmp_f
))
6606 gnm_style_set_font_size (style
, tmp_f
);
6607 else if (oo_attr_bool (xin
, attrs
, OO_NS_STYLE
, "shrink-to-fit", &btmp
))
6608 gnm_style_set_shrink_to_fit (style
, btmp
);
6609 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "direction"))
6610 gnm_style_set_text_dir (style
, attr_eq (attrs
[1], "rtl") ? GNM_TEXT_DIR_RTL
: GNM_TEXT_DIR_LTR
);
6611 else if (oo_attr_int (xin
, attrs
, OO_NS_STYLE
, "rotation-angle", &tmp
)) {
6613 gnm_style_set_rotation (style
, tmp
);
6614 } else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "text-underline-style",
6615 underline_styles
, &underline_style
)) {
6616 } else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "text-underline-type",
6617 underline_types
, &underline_type
)) {
6618 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
6619 OO_NS_STYLE
, "text-underline-width")) {
6620 underline_bold
= attr_eq (attrs
[1], "bold");
6621 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
6622 OO_GNUM_NS_EXT
, "text-underline-placement")) {
6623 underline_low
= attr_eq (attrs
[1], "low");
6624 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "font-style"))
6625 gnm_style_set_font_italic (style
, attr_eq (attrs
[1], "italic"));
6626 else if (oo_attr_font_weight (xin
, attrs
, &tmp
))
6627 gnm_style_set_font_bold (style
, tmp
>= PANGO_WEIGHT_SEMIBOLD
);
6628 else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "text-line-through-style",
6629 text_line_through_styles
, &strike_through_style
));
6630 else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "text-line-through-type",
6631 text_line_through_types
, &strike_through_type
));
6632 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
6633 OO_NS_STYLE
, "text-position")) {
6634 if (g_str_has_prefix (attrs
[1],"super"))
6635 gnm_style_set_font_script (style
, GO_FONT_SCRIPT_SUPER
);
6636 else if (g_str_has_prefix (attrs
[1], "sub"))
6637 gnm_style_set_font_script (style
, GO_FONT_SCRIPT_SUB
);
6639 gnm_style_set_font_script (style
, GO_FONT_SCRIPT_STANDARD
);
6640 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "margin-left")) {
6642 oo_parse_distance (xin
, attrs
[1], "margin-left", &tmp_f
);
6643 gnm_style_set_indent (style
, tmp_f
);
6646 if (strike_through_style
!= -1 || strike_through_type
!= -1)
6647 gnm_style_set_font_strike (style
, strike_through_style
> 0 ||
6648 (strike_through_type
> 0 && strike_through_style
== -1));
6651 if (underline_style
> 0) {
6652 GnmUnderline underline
= UNDERLINE_NONE
;
6653 if (underline_style
> 1) {
6654 switch (underline_type
) {
6656 underline
= UNDERLINE_NONE
;
6659 if (underline_low
) {
6660 underline
= UNDERLINE_DOUBLE_LOW
;
6662 underline
= UNDERLINE_DOUBLE
;
6667 if (underline_low
) {
6668 underline
= underline_bold
? UNDERLINE_DOUBLE_LOW
: UNDERLINE_SINGLE_LOW
;
6670 underline
= underline_bold
? UNDERLINE_DOUBLE
: UNDERLINE_SINGLE
;
6675 gnm_style_set_font_uline (style
, underline
);
6678 if (gnm_pattern
> 0)
6679 gnm_style_set_pattern (style
, gnm_pattern
);
6681 gnm_style_set_back_color (style
, gnm_b_color
);
6683 gnm_style_set_pattern_color (style
, gnm_p_color
);
6686 static OOPageBreakType
6687 oo_page_break_type (GsfXMLIn
*xin
, xmlChar
const *attr
)
6689 /* Note that truly automatic of soft page breaks are stored */
6690 /* via text:soft-page-break tags */
6691 if (!strcmp (attr
, "page"))
6692 return OO_PAGE_BREAK_MANUAL
;
6693 if (!strcmp (attr
, "column"))
6694 return OO_PAGE_BREAK_MANUAL
;
6695 if (!strcmp (attr
, "auto"))
6696 return OO_PAGE_BREAK_NONE
;
6698 _("Unknown break type '%s' defaulting to NONE"), attr
);
6699 return OO_PAGE_BREAK_NONE
;
6703 oo_style_prop_col_row (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6705 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6706 char const * const size_tag
= (state
->cur_style
.type
== OO_STYLE_COL
)
6707 ? "column-width" : "row-height";
6708 char const * const use_optimal
= (state
->cur_style
.type
== OO_STYLE_COL
)
6709 ? "use-optimal-column-width" : "use-optimal-row-height";
6713 g_return_if_fail (state
->cur_style
.col_rows
!= NULL
);
6715 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6716 if (NULL
!= oo_attr_distance (xin
, attrs
, OO_NS_STYLE
, size_tag
, &pts
))
6717 state
->cur_style
.col_rows
->size_pts
= pts
;
6718 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "break-before"))
6719 state
->cur_style
.col_rows
->break_before
=
6720 oo_page_break_type (xin
, attrs
[1]);
6721 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "break-after"))
6722 state
->cur_style
.col_rows
->break_after
=
6723 oo_page_break_type (xin
, attrs
[1]);
6724 else if (oo_attr_bool (xin
, attrs
, OO_NS_STYLE
, use_optimal
, &auto_size
))
6725 state
->cur_style
.col_rows
->manual
= !auto_size
;
6729 oo_style_prop_table (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6731 static OOEnum
const modes
[] = {
6738 { "tb", 0 }, /* what do tb and page imply in this context ? */
6742 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6743 OOSheetStyle
*style
= state
->cur_style
.sheets
;
6747 g_return_if_fail (style
!= NULL
);
6749 style
->visibility
= GNM_SHEET_VISIBILITY_VISIBLE
;
6750 style
->is_rtl
= FALSE
;
6752 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6753 if (oo_attr_bool (xin
, attrs
, OO_NS_TABLE
, "display", &tmp_b
)) {
6755 style
->visibility
= GNM_SHEET_VISIBILITY_HIDDEN
;
6756 } else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "display-formulas",
6757 &style
->display_formulas
)) {
6758 } else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "display-col-header",
6760 style
->hide_col_header
= !tmp_b
;
6761 } else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "display-row-header",
6763 style
->hide_row_header
= !tmp_b
;
6764 } else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "writing-mode", modes
, &tmp_i
))
6765 style
->is_rtl
= tmp_i
;
6766 else if ((!style
->tab_color_set
&&
6767 /* Gnumeric's version */
6768 gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
6769 OO_GNUM_NS_EXT
, "tab-color")) ||
6770 (!style
->tab_color_set
&&
6771 /* Used by LO 3.3.3 and later */
6772 gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
6773 OO_NS_TABLE_OOO
, "tab-color")) ||
6774 /* For ODF 1.3 etc. */
6775 (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
6776 OO_NS_TABLE
, "tab-color"))) {
6777 /* For ODF 1.3 etc. */
6779 if (gdk_rgba_parse (&rgba
, CXML2C (attrs
[1]))) {
6780 go_color_from_gdk_rgba (&rgba
, &style
->tab_color
);
6781 style
->tab_color_set
= TRUE
;
6783 oo_warning (xin
, _("Unable to parse "
6784 "tab color \'%s\'"),
6786 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
6788 "tab-text-color")) {
6790 if (gdk_rgba_parse (&rgba
, CXML2C (attrs
[1]))) {
6791 go_color_from_gdk_rgba (&rgba
, &style
->tab_text_color
);
6792 style
->tab_text_color_set
= TRUE
;
6794 oo_warning (xin
, _("Unable to parse tab "
6795 "text color \'%s\'"),
6803 oo_style_map (GsfXMLIn
*xin
, xmlChar
const **attrs
)
6805 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6806 char const *style_name
= NULL
, *base
= NULL
;
6807 char const *condition
= NULL
;
6808 OOCellStyle
*style
= NULL
;
6810 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
6811 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "condition"))
6812 condition
= attrs
[1];
6813 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "apply-style-name"))
6814 style_name
= attrs
[1];
6815 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_STYLE
, "base-cell-address"))
6817 if (style_name
== NULL
|| condition
== NULL
)
6820 style
= g_hash_table_lookup (state
->styles
.cell
, style_name
);
6821 odf_oo_cell_style_attach_condition(state
->cur_style
.cells
, style
, condition
, base
);
6825 oo_prop_new_double (char const *name
, gnm_float val
)
6827 OOProp
*res
= g_new0 (OOProp
, 1);
6829 g_value_init (&res
->value
, G_TYPE_DOUBLE
);
6830 g_value_set_double (&res
->value
, val
);
6834 oo_prop_new_bool (char const *name
, gboolean val
)
6836 OOProp
*res
= g_new0 (OOProp
, 1);
6838 g_value_init (&res
->value
, G_TYPE_BOOLEAN
);
6839 g_value_set_boolean (&res
->value
, val
);
6843 oo_prop_new_int (char const *name
, int val
)
6845 OOProp
*res
= g_new0 (OOProp
, 1);
6847 g_value_init (&res
->value
, G_TYPE_INT
);
6848 g_value_set_int (&res
->value
, val
);
6852 oo_prop_new_string (char const *name
, char const *val
)
6854 OOProp
*res
= g_new0 (OOProp
, 1);
6856 g_value_init (&res
->value
, G_TYPE_STRING
);
6857 g_value_set_string (&res
->value
, val
);
6861 oo_prop_free (OOProp
*prop
)
6863 g_value_unset (&prop
->value
);
6868 oo_prop_list_free (GSList
*props
)
6870 g_slist_free_full (props
, (GDestroyNotify
)oo_prop_free
);
6874 oo_prop_list_apply (GSList
*props
, GObject
*obj
)
6878 GObjectClass
*klass
;
6882 klass
= G_OBJECT_GET_CLASS (obj
);
6884 for (ptr
= props
; ptr
; ptr
= ptr
->next
) {
6886 if (NULL
!= g_object_class_find_property (klass
, prop
->name
))
6887 g_object_set_property (obj
, prop
->name
, &prop
->value
);
6892 odf_apply_expression (GsfXMLIn
*xin
, gint dim
, GObject
*obj
, gchar
const *expression
)
6894 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6897 GnmExprTop
const *expr
;
6898 parse_pos_init (&pp
, state
->pos
.wb
, state
->pos
.sheet
, 0, 0);
6899 expr
= oo_expr_parse_str
6900 (xin
, expression
, &pp
,
6901 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
,
6902 FORMULA_OPENFORMULA
);
6904 data
= gnm_go_data_scalar_new_expr (state
->pos
.sheet
, expr
);
6905 gog_dataset_set_dim (GOG_DATASET (obj
), dim
, data
, NULL
);
6910 oo_prop_list_apply_to_axisline (GsfXMLIn
*xin
, GSList
*props
, GObject
*obj
)
6914 gchar
const *pos_str_expression
= NULL
;
6915 gchar
const *pos_str_val
= NULL
;
6917 oo_prop_list_apply (props
, obj
);
6919 for (ptr
= props
; ptr
; ptr
= ptr
->next
) {
6921 if (0 == strcmp ("pos-str-expr", prop
->name
))
6922 pos_str_expression
= g_value_get_string (&prop
->value
);
6923 else if (0 == strcmp ("pos-str-val", prop
->name
))
6924 pos_str_val
= g_value_get_string (&prop
->value
);
6927 if (pos_str_expression
)
6928 odf_apply_expression (xin
, 4, obj
, pos_str_expression
);
6929 else if (pos_str_val
)
6930 odf_apply_expression (xin
, 4, obj
, pos_str_val
);
6935 oo_prop_list_apply_to_axis (GsfXMLIn
*xin
, GSList
*props
, GObject
*obj
)
6937 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
6943 double minimum
= go_ninf
, maximum
= go_pinf
;
6944 double interval_major
= 0.;
6945 double interval_minor_divisor
= 0.;
6946 gchar
const *minimum_expression
= NULL
;
6947 gchar
const *maximum_expression
= NULL
;
6948 gboolean logarithmic
= FALSE
;
6951 oo_prop_list_apply_to_axisline (xin
, props
, obj
);
6953 for (ptr
= props
; ptr
; ptr
= ptr
->next
) {
6955 if (0 == strcmp ("minimum", prop
->name
))
6956 minimum
= g_value_get_double (&prop
->value
);
6957 else if (0 == strcmp ("maximum", prop
->name
))
6958 maximum
= g_value_get_double (&prop
->value
);
6959 else if (0 == strcmp ("interval-major", prop
->name
))
6960 interval_major
= g_value_get_double (&prop
->value
);
6961 else if (0 == strcmp ("interval-minor-divisor", prop
->name
))
6962 interval_minor_divisor
6963 = g_value_get_double (&prop
->value
);
6964 else if (0 == strcmp ("minimum-expression", prop
->name
))
6965 minimum_expression
= g_value_get_string (&prop
->value
);
6966 else if (0 == strcmp ("maximum-expression", prop
->name
))
6967 maximum_expression
= g_value_get_string (&prop
->value
);
6968 else if (0 == strcmp ("map-name", prop
->name
))
6969 logarithmic
= (0 == strcmp (g_value_get_string (&prop
->value
), "Log"));
6972 gog_axis_set_bounds (GOG_AXIS (obj
), minimum
, maximum
);
6973 if (minimum_expression
)
6974 odf_apply_expression (xin
, 0, obj
, minimum_expression
);
6975 if (maximum_expression
)
6976 odf_apply_expression (xin
, 1, obj
, maximum_expression
);
6978 if (interval_major
> 0) {
6979 data
= gnm_go_data_scalar_new_expr
6980 (state
->chart
.src_sheet
, gnm_expr_top_new_constant
6981 (value_new_float(interval_major
)));
6982 gog_dataset_set_dim (GOG_DATASET (obj
), 2, data
, NULL
);
6983 if (interval_minor_divisor
> 1) {
6985 data
= gnm_go_data_scalar_new_expr
6986 (state
->chart
.src_sheet
,
6987 gnm_expr_top_new_constant
6988 (value_new_float (interval_minor_divisor
- 1)));
6990 data
= gnm_go_data_scalar_new_expr
6991 (state
->chart
.src_sheet
,
6992 gnm_expr_top_new_constant
6993 (value_new_float (interval_major
/interval_minor_divisor
)));
6994 gog_dataset_set_dim (GOG_DATASET (obj
), 3, data
, NULL
);
7000 oo_chart_style_to_series (GsfXMLIn
*xin
, OOChartStyle
*oostyle
, GObject
*obj
)
7002 GOStyle
*style
= NULL
;
7004 if (oostyle
== NULL
)
7007 oo_prop_list_apply (oostyle
->plot_props
, obj
);
7009 style
= go_styled_object_get_style (GO_STYLED_OBJECT (obj
));
7010 if (style
!= NULL
) {
7011 style
= go_style_dup (style
);
7012 odf_apply_style_props (xin
, oostyle
->style_props
, style
, TRUE
);
7013 go_styled_object_set_style (GO_STYLED_OBJECT (obj
), style
);
7014 g_object_unref (style
);
7019 oo_prop_list_has (GSList
*props
, gboolean
*threed
, char const *tag
)
7023 for (ptr
= props
; ptr
; ptr
= ptr
->next
) {
7024 OOProp
*prop
= ptr
->data
;
7025 if (0 == strcmp (prop
->name
, tag
) &&
7026 ((res
= g_value_get_boolean (&prop
->value
))))
7032 oo_style_has_property (OOChartStyle
**style
, char const *prop
, gboolean def
)
7035 gboolean has_prop
= def
;
7036 for (i
= 0; i
< OO_CHART_STYLE_INHERITANCE
; i
++)
7037 if (style
[i
] != NULL
)
7038 oo_prop_list_has (style
[i
]->other_props
,
7044 oo_style_has_plot_property (OOChartStyle
**style
, char const *prop
, gboolean def
)
7047 gboolean has_prop
= def
;
7048 for (i
= 0; i
< OO_CHART_STYLE_INHERITANCE
; i
++)
7049 if (style
[i
] != NULL
)
7050 oo_prop_list_has (style
[i
]->plot_props
,
7056 odf_scale_initial_angle (int angle
)
7062 return (angle
% 360);
7066 od_style_prop_chart (GsfXMLIn
*xin
, xmlChar
const **attrs
)
7068 static OOEnum
const symbol_type
[] = {
7069 {"automatic" , OO_SYMBOL_TYPE_AUTO
},
7070 {"none" , OO_SYMBOL_TYPE_NONE
},
7071 {"named-symbol", OO_SYMBOL_TYPE_NAMED
},
7074 static OOEnum
const named_symbols
[] = {
7075 { "square", GO_MARKER_SQUARE
},
7076 { "diamond", GO_MARKER_DIAMOND
},
7077 { "arrow-down", GO_MARKER_TRIANGLE_DOWN
},
7078 { "arrow-up", GO_MARKER_TRIANGLE_UP
},
7079 { "arrow-right", GO_MARKER_TRIANGLE_RIGHT
},
7080 { "arrow-left", GO_MARKER_TRIANGLE_LEFT
},
7081 { "circle", GO_MARKER_CIRCLE
},
7082 { "x", GO_MARKER_X
},
7083 { "plus", GO_MARKER_CROSS
},
7084 { "asterisk", GO_MARKER_ASTERISK
},
7085 { "horizontal-bar", GO_MARKER_BAR
},
7086 { "bow-tie", GO_MARKER_BUTTERFLY
},
7087 { "hourglass", GO_MARKER_HOURGLASS
},
7088 { "star", GO_MARKER_LEFT_HALF_BAR
},
7089 { "vertical-bar", GO_MARKER_HALF_BAR
},
7093 static OOEnum
const font_variants
[] = {
7094 {"normal", PANGO_VARIANT_NORMAL
},
7095 {"small-caps", PANGO_VARIANT_SMALL_CAPS
},
7099 static OOEnum
const font_styles
[] = {
7100 { "normal", PANGO_STYLE_NORMAL
},
7101 { "oblique", PANGO_STYLE_OBLIQUE
},
7102 { "italic", PANGO_STYLE_ITALIC
},
7106 static OOEnum
const image_fill_types
[] = {
7107 {"stretch", GO_IMAGE_STRETCHED
},
7108 {"repeat", GO_IMAGE_WALLPAPER
},
7109 {"no-repeat", GO_IMAGE_CENTERED
},
7113 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
7114 OOChartStyle
*style
= state
->chart
.cur_graph_style
;
7118 gboolean default_style_has_lines_set
= FALSE
;
7119 gboolean draw_stroke_set
= FALSE
;
7120 gboolean draw_stroke
= FALSE
; /* to avoid a warning only */
7121 gboolean stacked_set
= FALSE
;
7122 gboolean stacked_unset
= FALSE
;
7123 gboolean overlap_set
= FALSE
;
7124 gboolean percentage_set
= FALSE
;
7125 gboolean regression_force_intercept_set
= FALSE
;
7126 gboolean regression_force_intercept
= FALSE
;
7127 gnm_float regression_force_intercept_value
= 0.;
7128 char const *interpolation
= NULL
;
7129 gboolean local_style
= FALSE
;
7132 g_return_if_fail (style
!= NULL
||
7133 state
->default_style
.cells
!= NULL
);
7135 if (style
== NULL
&& state
->default_style
.cells
!= NULL
) {
7137 style
= g_new0 (OOChartStyle
, 1);
7141 style
->grid
= FALSE
;
7142 style
->src_in_rows
= FALSE
;
7143 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
7144 if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "logarithmic", &btmp
)) {
7146 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7147 oo_prop_new_string ("map-name", "Log"));
7148 } else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "link-data-style-to-source", &btmp
)) {
7150 style
->other_props
= g_slist_prepend
7151 (style
->other_props
,
7152 oo_prop_new_bool ("ignore-axis-data-style", btmp
));
7153 } else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "vertical", &btmp
)) {
7154 /* This is backwards from my intuition */
7155 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7156 oo_prop_new_bool ("horizontal", btmp
));
7157 /* This is for BoxPlots */
7158 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7159 oo_prop_new_bool ("vertical", btmp
));
7160 } else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "outliers", &btmp
))
7161 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7162 oo_prop_new_bool ("outliers", btmp
));
7163 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "reverse-direction", &btmp
))
7164 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7165 oo_prop_new_bool ("invert-axis", btmp
));
7166 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
,
7167 "reverse-direction", &btmp
))
7168 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7169 oo_prop_new_bool ("invert-axis", btmp
));
7170 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
,
7171 "vary-style-by-element", &btmp
))
7172 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7173 oo_prop_new_bool ("vary-style-by-element",
7175 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
,
7176 "show-negatives", &btmp
))
7177 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7178 oo_prop_new_bool ("show-negatives", btmp
));
7179 else if (oo_attr_float (xin
, attrs
, OO_NS_CHART
,
7181 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7182 oo_prop_new_double ("minimum", ftmp
));
7183 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
,
7184 "chart-minimum-expression"))
7185 style
->axis_props
= g_slist_prepend
7187 oo_prop_new_string ("minimum-expression",
7189 else if (oo_attr_float (xin
, attrs
, OO_NS_CHART
,
7191 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7192 oo_prop_new_double ("maximum", ftmp
));
7193 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
,
7194 "chart-maximum-expression"))
7195 style
->axis_props
= g_slist_prepend
7197 oo_prop_new_string ("maximum-expression",
7199 else if (oo_attr_float (xin
, attrs
, OO_NS_CHART
,
7200 "interval-major", &ftmp
))
7201 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7202 oo_prop_new_double ("interval-major", ftmp
));
7203 else if (oo_attr_float (xin
, attrs
, OO_NS_CHART
,
7204 "interval-minor-divisor", &ftmp
))
7205 style
->axis_props
= g_slist_prepend
7207 oo_prop_new_double ("interval-minor-divisor",
7209 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
,
7211 if (0 == strcmp (CXML2C(attrs
[1]), "start"))
7212 style
->axis_props
= g_slist_prepend
7214 oo_prop_new_string ("pos-str",
7216 else if (0 == strcmp (CXML2C(attrs
[1]), "end"))
7217 style
->axis_props
= g_slist_prepend
7219 oo_prop_new_string ("pos-str",
7222 style
->axis_props
= g_slist_prepend
7224 oo_prop_new_string ("pos-str", "cross"));
7225 style
->axis_props
= g_slist_prepend
7226 (style
->axis_props
, oo_prop_new_string ("pos-str-val",
7229 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
,
7230 "axis-position-expression"))
7231 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7232 oo_prop_new_string ("pos-str-expr",
7234 else if (oo_attr_float (xin
, attrs
, OO_GNUM_NS_EXT
,
7235 "radius-ratio", &ftmp
))
7236 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7237 oo_prop_new_double ("radius-ratio", ftmp
));
7238 else if (oo_attr_percent (xin
, attrs
, OO_GNUM_NS_EXT
,
7239 "default-separation", &ftmp
))
7240 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7241 oo_prop_new_double ("default-separation", ftmp
));
7242 else if (oo_attr_int_range (xin
, attrs
, OO_NS_CHART
,
7243 "pie-offset", &tmp
, 0, 500)) {
7244 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7245 oo_prop_new_double ("default-separation",
7247 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7248 oo_prop_new_double ("separation",
7250 } else if (oo_attr_percent (xin
, attrs
, OO_NS_CHART
,
7251 "hole-size", &ftmp
))
7252 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7253 oo_prop_new_double ("center-size", ftmp
));
7254 else if (oo_attr_angle (xin
, attrs
, OO_NS_CHART
,
7255 "angle-offset", &tmp
))
7256 style
->plot_props
= g_slist_prepend
7257 (style
->plot_props
, oo_prop_new_double ("plot-initial-angle",
7258 (double) odf_scale_initial_angle (tmp
)));
7259 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
,
7260 "reverse-direction", &btmp
))
7261 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7262 oo_prop_new_bool ("invert-axis", btmp
));
7263 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "stacked",
7266 style
->plot_props
= g_slist_prepend
7268 oo_prop_new_string ("type",
7272 stacked_unset
= TRUE
;
7273 } else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "percentage",
7276 style
->plot_props
= g_slist_prepend
7278 oo_prop_new_string ("type",
7280 percentage_set
= TRUE
;
7282 } else if (oo_attr_int_range (xin
, attrs
, OO_NS_CHART
,
7283 "overlap", &tmp
, -150, 150)) {
7284 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7285 oo_prop_new_int ("overlap-percentage", tmp
));
7287 } else if (oo_attr_int_range (xin
, attrs
, OO_NS_CHART
,
7288 "gap-width", &tmp
, 0, 500))
7289 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7290 oo_prop_new_int ("gap-percentage", tmp
));
7291 else if (oo_attr_enum (xin
, attrs
, OO_NS_CHART
, "symbol-type",
7292 symbol_type
, &tmp
)) {
7293 style
->plot_props
= g_slist_prepend
7295 oo_prop_new_bool ("default-style-has-markers",
7296 tmp
!= OO_SYMBOL_TYPE_NONE
));
7297 style
->style_props
= g_slist_prepend
7298 (style
->style_props
,
7299 oo_prop_new_int ("symbol-type", tmp
));
7300 } else if (oo_attr_enum (xin
, attrs
, OO_NS_CHART
,
7302 named_symbols
, &tmp
)) {
7303 style
->style_props
= g_slist_prepend
7304 (style
->style_props
,
7305 oo_prop_new_int ("symbol-name", tmp
));
7306 } else if (oo_attr_distance (xin
, attrs
, OO_NS_CHART
, "symbol-width",
7308 style
->style_props
= g_slist_prepend
7309 (style
->style_props
,
7310 oo_prop_new_double ("symbol-width", ftmp
));
7311 } else if (oo_attr_distance (xin
, attrs
, OO_NS_CHART
, "symbol-height",
7313 style
->style_props
= g_slist_prepend
7314 (style
->style_props
,
7315 oo_prop_new_double ("symbol-height", ftmp
));
7316 } else if ((interpolation
== NULL
) &&
7317 (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7318 OO_NS_CHART
, "interpolation") ||
7319 gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7320 OO_GNUM_NS_EXT
, "interpolation"))) {
7321 if (attr_eq (attrs
[1], "none"))
7322 interpolation
= "linear";
7323 else if (attr_eq (attrs
[1], "b-spline")) {
7324 interpolation
= "spline";
7326 (xin
, _("Unknown interpolation type "
7327 "encountered: \'%s\', using "
7328 "Bezier cubic spline instead."),
7330 } else if (attr_eq (attrs
[1], "cubic-spline"))
7331 interpolation
= "odf-spline";
7332 else if (g_str_has_prefix (CXML2C(attrs
[1]), "gnm:"))
7333 interpolation
= CXML2C(attrs
[1]) + 4;
7335 (xin
, _("Unknown interpolation type "
7338 if (interpolation
!= NULL
)
7339 style
->plot_props
= g_slist_prepend
7342 ("interpolation", interpolation
));
7343 } else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "interpolation-skip-invalid", &btmp
))
7344 style
->plot_props
= g_slist_prepend
7346 oo_prop_new_bool ("interpolation-skip-invalid", btmp
));
7347 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7348 OO_GNUM_NS_EXT
, "fill-type"))
7349 style
->plot_props
= g_slist_prepend
7351 oo_prop_new_string ("fill-type",
7353 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7354 OO_NS_DRAW
, "stroke")) {
7355 draw_stroke
= !attr_eq (attrs
[1], "none");
7356 draw_stroke_set
= TRUE
;
7357 style
->style_props
= g_slist_prepend
7358 (style
->style_props
,
7359 oo_prop_new_string ("stroke",
7361 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7362 OO_NS_DRAW
, "stroke-dash")) {
7363 style
->style_props
= g_slist_prepend
7364 (style
->style_props
,
7365 oo_prop_new_string ("stroke-dash",
7367 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7368 OO_NS_SVG
, "stroke-color")) {
7369 style
->style_props
= g_slist_prepend
7370 (style
->style_props
,
7371 oo_prop_new_string ("stroke-color",
7373 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7374 OO_GNUM_NS_EXT
, "marker-outline-colour")) {
7375 style
->style_props
= g_slist_prepend
7376 (style
->style_props
,
7377 oo_prop_new_string ("marker-outline-colour",
7379 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7380 OO_GNUM_NS_EXT
, "marker-fill-colour")) {
7381 style
->style_props
= g_slist_prepend
7382 (style
->style_props
,
7383 oo_prop_new_string ("marker-fill-colour",
7385 } else if (NULL
!= oo_attr_distance (xin
, attrs
, OO_NS_SVG
,
7386 "stroke-width", &ftmp
))
7387 style
->style_props
= g_slist_prepend
7388 (style
->style_props
,
7389 oo_prop_new_double ("stroke-width",
7391 else if (NULL
!= oo_attr_distance (xin
, attrs
, OO_GNUM_NS_EXT
,
7392 "stroke-width", &ftmp
))
7393 style
->style_props
= g_slist_prepend
7394 (style
->style_props
,
7395 oo_prop_new_double ("gnm-stroke-width",
7397 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "lines", &btmp
)) {
7398 style
->style_props
= g_slist_prepend
7399 (style
->style_props
,
7400 oo_prop_new_bool ("lines", btmp
));
7401 style
->plot_props
= g_slist_prepend
7403 oo_prop_new_bool ("default-style-has-lines", btmp
));
7404 default_style_has_lines_set
= TRUE
;
7405 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "series-source"))
7406 style
->src_in_rows
= attr_eq (attrs
[1], "rows");
7407 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "three-dimensional", &btmp
))
7408 style
->other_props
= g_slist_prepend (style
->other_props
,
7409 oo_prop_new_bool ("three-dimensional", btmp
));
7410 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "fill"))
7411 style
->style_props
= g_slist_prepend
7412 (style
->style_props
,
7413 oo_prop_new_string ("fill",
7415 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "foreground-solid", &btmp
))
7416 style
->style_props
= g_slist_prepend
7417 (style
->style_props
,
7418 oo_prop_new_bool ("gnm-foreground-solid", btmp
));
7419 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "auto-type", &btmp
))
7420 style
->style_props
= g_slist_prepend
7421 (style
->style_props
,
7422 oo_prop_new_bool ("gnm-auto-type", btmp
));
7423 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "fill-color"))
7424 style
->style_props
= g_slist_prepend
7425 (style
->style_props
,
7426 oo_prop_new_string ("fill-color",
7428 else if (oo_attr_percent (xin
, attrs
, OO_NS_DRAW
, "opacity", &ftmp
))
7429 style
->style_props
= g_slist_prepend (style
->style_props
,
7430 oo_prop_new_double ("opacity", ftmp
));
7431 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "fill-hatch-name"))
7432 style
->style_props
= g_slist_prepend
7433 (style
->style_props
,
7434 oo_prop_new_string ("fill-hatch-name",
7436 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "fill-image-name"))
7437 style
->style_props
= g_slist_prepend
7438 (style
->style_props
,
7439 oo_prop_new_string ("fill-image-name",
7441 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "fill-gradient-name"))
7442 style
->style_props
= g_slist_prepend
7443 (style
->style_props
,
7444 oo_prop_new_string ("fill-gradient-name",
7446 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "fill-hatch-solid", &btmp
))
7447 style
->other_props
= g_slist_prepend (style
->other_props
,
7448 oo_prop_new_bool ("fill-hatch-solid", btmp
));
7449 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
,
7451 GO_PATTERN_GREY75
, GO_PATTERN_MAX
- 1))
7452 style
->style_props
= g_slist_prepend
7453 (style
->style_props
,
7454 oo_prop_new_int ("gnm-pattern", tmp
));
7455 else if (oo_attr_angle (xin
, attrs
, OO_NS_STYLE
,
7456 "text-rotation-angle", &tmp
)) {
7457 style
->style_props
= g_slist_prepend
7458 (style
->style_props
,
7459 oo_prop_new_int ("text-rotation-angle", tmp
));
7460 } else if (oo_attr_angle (xin
, attrs
, OO_NS_STYLE
,
7461 "rotation-angle", &tmp
)) {
7462 style
->style_props
= g_slist_prepend
7463 (style
->style_props
,
7464 oo_prop_new_int ("text-rotation-angle", tmp
));
7465 style
->plot_props
= g_slist_prepend
7467 oo_prop_new_int ("rotation-angle", tmp
));
7468 } else if (NULL
!= oo_attr_distance (xin
, attrs
, OO_NS_FO
, "font-size", &ftmp
))
7469 style
->style_props
= g_slist_prepend
7470 (style
->style_props
,
7471 oo_prop_new_double ("font-size", ftmp
));
7472 else if (oo_attr_font_weight (xin
, attrs
, &tmp
))
7473 style
->style_props
= g_slist_prepend
7474 (style
->style_props
,
7475 oo_prop_new_int ("font-weight", tmp
));
7476 else if (oo_attr_enum (xin
, attrs
, OO_NS_FO
, "font-variant",
7477 font_variants
, &tmp
))
7478 style
->style_props
= g_slist_prepend
7479 (style
->style_props
,
7480 oo_prop_new_int ("font-variant", tmp
));
7481 else if (oo_attr_enum (xin
, attrs
, OO_NS_FO
, "font-style",
7483 style
->style_props
= g_slist_prepend
7484 (style
->style_props
,
7485 oo_prop_new_int ("font-style", tmp
));
7486 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "font-family"))
7487 style
->style_props
= g_slist_prepend
7488 (style
->style_props
,
7489 oo_prop_new_string ("font-family",
7491 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "auto-font",
7493 style
->style_props
= g_slist_prepend (style
->style_props
,
7494 oo_prop_new_bool ("gnm-auto-font", btmp
));
7495 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
,
7496 "font-stretch-pango", &tmp
,
7497 0, PANGO_STRETCH_ULTRA_EXPANDED
))
7498 style
->style_props
= g_slist_prepend
7499 (style
->style_props
,
7500 oo_prop_new_int ("font-stretch-pango", tmp
));
7501 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
,
7502 "font-gravity-pango", &tmp
,
7503 0, PANGO_GRAVITY_WEST
))
7504 style
->style_props
= g_slist_prepend
7505 (style
->style_props
,
7506 oo_prop_new_int ("font-gravity-pango", tmp
));
7507 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_FO
, "color"))
7508 style
->style_props
= g_slist_prepend
7509 (style
->style_props
,
7510 oo_prop_new_string ("color",
7512 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
,
7514 style
->other_props
= g_slist_prepend
7515 (style
->other_props
,
7516 oo_prop_new_string ("regression-type",
7518 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
,
7519 "regression-polynomial-dims", &tmp
,
7521 style
->other_props
= g_slist_prepend
7522 (style
->other_props
,
7523 oo_prop_new_int ("dims", tmp
));
7524 #if HAVE_OO_NS_LOCALC_EXT
7525 else if (oo_attr_int_range (xin
, attrs
, OO_NS_LOCALC_EXT
,
7526 "regression-max-degree", &tmp
,
7528 style
->other_props
= g_slist_prepend
7529 (style
->other_props
,
7530 oo_prop_new_int ("lo-dims", tmp
));
7531 else if (oo_attr_bool (xin
, attrs
, OO_NS_LOCALC_EXT
, "regression-force-intercept",
7532 ®ression_force_intercept
))
7534 regression_force_intercept_set
= TRUE
;
7536 else if (oo_attr_float (xin
, attrs
, OO_NS_LOCALC_EXT
,
7537 "regression-intercept-value", &ftmp
))
7538 regression_force_intercept_value
= ftmp
;
7540 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "regression-affine",
7542 style
->other_props
= g_slist_prepend (style
->other_props
,
7543 oo_prop_new_bool ("affine", btmp
));
7544 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
,
7546 style
->other_props
= g_slist_prepend
7547 (style
->other_props
,
7548 oo_prop_new_string ("regression-name-expression",
7550 #if HAVE_OO_NS_LOCALC_EXT
7551 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_LOCALC_EXT
,
7553 style
->other_props
= g_slist_prepend
7554 (style
->other_props
,
7555 oo_prop_new_string ("regression-name-constant",
7558 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
,
7559 "is-position-manual",
7561 style
->plot_props
= g_slist_prepend
7564 ("is-position-manual", btmp
));
7565 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7568 style
->plot_props
= g_slist_prepend
7571 ("position", CXML2C(attrs
[1])));
7572 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7575 style
->plot_props
= g_slist_prepend
7578 ("anchor", CXML2C(attrs
[1])));
7579 else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "repeat",
7580 image_fill_types
, &tmp
))
7581 style
->style_props
= g_slist_prepend
7582 (style
->style_props
,
7583 oo_prop_new_int ("repeat", tmp
));
7584 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7587 style
->other_props
= g_slist_prepend
7588 (style
->other_props
,
7590 ("marker-start", CXML2C(attrs
[1])));
7591 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7594 style
->other_props
= g_slist_prepend
7595 (style
->other_props
,
7597 ("marker-end", CXML2C(attrs
[1])));
7598 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7601 style
->other_props
= g_slist_prepend
7602 (style
->other_props
,
7604 ("border", CXML2C(attrs
[1])));
7605 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "auto-marker-outline-colour", &btmp
))
7606 style
->style_props
= g_slist_prepend (style
->style_props
,
7607 oo_prop_new_bool ("gnm-auto-marker-outline-colour", btmp
));
7608 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "auto-color", &btmp
))
7609 style
->style_props
= g_slist_prepend (style
->style_props
,
7610 oo_prop_new_bool ("gnm-auto-color", btmp
));
7611 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "auto-marker-fill-colour", &btmp
))
7612 style
->style_props
= g_slist_prepend (style
->style_props
,
7613 oo_prop_new_bool ("gnm-auto-marker-fill-colour", btmp
));
7614 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "auto-dash", &btmp
))
7615 style
->style_props
= g_slist_prepend (style
->style_props
,
7616 oo_prop_new_bool ("gnm-auto-dash", btmp
));
7617 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "auto-width", &btmp
))
7618 style
->style_props
= g_slist_prepend (style
->style_props
,
7619 oo_prop_new_bool ("gnm-auto-width", btmp
));
7620 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "tick-marks-major-inner", &btmp
))
7621 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7622 oo_prop_new_bool ("major-tick-in", btmp
));
7623 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "tick-marks-major-outer", &btmp
))
7624 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7625 oo_prop_new_bool ("major-tick-out", btmp
));
7626 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "tick-marks-minor-inner", &btmp
))
7627 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7628 oo_prop_new_bool ("minor-tick-in", btmp
));
7629 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "tick-marks-minor-outer", &btmp
))
7630 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7631 oo_prop_new_bool ("minor-tick-out", btmp
));
7632 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "display-label", &btmp
))
7633 style
->axis_props
= g_slist_prepend (style
->axis_props
,
7634 oo_prop_new_bool ("major-tick-labeled", btmp
));
7637 if (regression_force_intercept_set
) {
7638 btmp
= regression_force_intercept
&& (regression_force_intercept_value
== 0);
7639 style
->other_props
= g_slist_prepend (style
->other_props
,
7640 oo_prop_new_bool ("affine", btmp
));
7643 if ((stacked_set
&& !overlap_set
) ||
7644 (percentage_set
&& !stacked_unset
&& !overlap_set
))
7645 style
->plot_props
= g_slist_prepend (style
->plot_props
,
7646 oo_prop_new_int ("overlap-percentage", 100));
7648 if (!default_style_has_lines_set
)
7649 style
->plot_props
= g_slist_prepend
7651 oo_prop_new_bool ("default-style-has-lines", draw_stroke_set
&& draw_stroke
));
7654 /* odf_apply_style_props (xin, style->style_props, state->default_style.cells, TRUE);*/
7655 /* We should apply the styles to this GnmStyle */
7656 oo_chart_style_free (style
);
7661 od_style_prop_text (GsfXMLIn
*xin
, xmlChar
const **attrs
)
7663 static OOEnum
const style_types
[] = {
7664 { "normal", PANGO_STYLE_NORMAL
},
7665 { "italic", PANGO_STYLE_ITALIC
},
7666 { "oblique", PANGO_STYLE_OBLIQUE
},
7669 static OOEnum
const underline_styles
[] = {
7673 { "dot-dot-dash", 2 },
7680 static OOEnum
const underline_types
[] = {
7686 static OOEnum
const line_through_styles
[] = {
7693 { "dot-dot-dash",6},
7698 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
7699 PangoAttribute
*attr
;
7701 gnm_float size
= -1.0;
7702 int underline_type
= 0;
7703 int underline_style
= 0;
7704 gboolean underline_bold
= FALSE
;
7707 g_return_if_fail (state
->cur_style
.text
!= NULL
);
7708 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
7709 if (NULL
!= oo_attr_distance (xin
, attrs
, OO_NS_FO
, "font-size", &size
) && size
>= 0.) {
7710 attr
= pango_attr_size_new ((int) gnm_floor (size
* PANGO_SCALE
+ 0.5));
7711 attr
->start_index
= 0;
7712 attr
->end_index
= 0;
7713 pango_attr_list_insert (state
->cur_style
.text
, attr
); ;
7714 } else if (oo_attr_font_weight (xin
, attrs
, &tmp
)) {
7715 attr
= pango_attr_weight_new (tmp
);
7716 attr
->start_index
= 0;
7717 attr
->end_index
= 0;
7718 pango_attr_list_insert (state
->cur_style
.text
, attr
);
7719 } else if (oo_attr_enum (xin
, attrs
, OO_NS_FO
, "font-style", style_types
, &tmp
)) {
7720 attr
= pango_attr_style_new (tmp
);
7721 attr
->start_index
= 0;
7722 attr
->end_index
= 0;
7723 pango_attr_list_insert (state
->cur_style
.text
, attr
);
7724 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7725 OO_NS_STYLE
, "text-position")) {
7727 if (g_str_has_prefix (attrs
[1],"super"))
7728 attr
= go_pango_attr_superscript_new (1);
7729 else if (g_str_has_prefix (attrs
[1], "sub"))
7730 attr
= go_pango_attr_subscript_new (1);
7731 else if (g_str_has_prefix (attrs
[1], "0")) {
7732 attr
= go_pango_attr_superscript_new (0);
7733 attr
->start_index
= 0;
7734 attr
->end_index
= 0;
7735 pango_attr_list_insert (state
->cur_style
.text
, attr
);
7736 attr
= go_pango_attr_subscript_new (0);
7739 attr
->start_index
= 0;
7740 attr
->end_index
= 0;
7741 pango_attr_list_insert (state
->cur_style
.text
, attr
);
7743 } else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "text-underline-style",
7744 underline_styles
, &underline_style
)) {
7745 } else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "text-underline-type",
7746 underline_types
, &underline_type
)) {
7747 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
7748 OO_NS_STYLE
, "text-underline-width"))
7749 underline_bold
= attr_eq (attrs
[1], "bold");
7750 else if (oo_attr_enum (xin
, attrs
, OO_NS_STYLE
, "text-line-through-style",
7751 line_through_styles
, &tmp
)) {
7752 attr
= pango_attr_strikethrough_new (tmp
> 0);
7753 attr
->start_index
= 0;
7754 attr
->end_index
= 0;
7755 pango_attr_list_insert (state
->cur_style
.text
, attr
);
7756 } else if ((color
= oo_attr_color (xin
, attrs
, OO_NS_FO
, "color"))) {
7757 attr
= go_color_to_pango (color
->go_color
, TRUE
);
7758 style_color_unref (color
);
7759 attr
->start_index
= 0;
7760 attr
->end_index
= 0;
7761 pango_attr_list_insert (state
->cur_style
.text
, attr
);
7762 } else if ((color
= oo_attr_color (xin
, attrs
, OO_NS_FO
, "background-color"))) {
7763 attr
= go_color_to_pango (color
->go_color
, FALSE
);
7764 style_color_unref (color
);
7765 attr
->start_index
= 0;
7766 attr
->end_index
= 0;
7767 pango_attr_list_insert (state
->cur_style
.text
, attr
);
7770 if (underline_style
> 0) {
7771 PangoUnderline underline
;
7772 if (underline_style
== 1)
7773 underline
= PANGO_UNDERLINE_NONE
;
7774 else if (underline_style
== 4)
7775 underline
= PANGO_UNDERLINE_ERROR
;
7776 else if (underline_bold
)
7777 underline
= PANGO_UNDERLINE_LOW
;
7778 else if (underline_type
== 2)
7779 underline
= PANGO_UNDERLINE_DOUBLE
;
7781 underline
= PANGO_UNDERLINE_SINGLE
;
7783 attr
= pango_attr_underline_new (underline
);
7784 attr
->start_index
= 0;
7785 attr
->end_index
= 0;
7786 pango_attr_list_insert (state
->cur_style
.text
, attr
);
7791 oo_style_prop (GsfXMLIn
*xin
, xmlChar
const **attrs
)
7793 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
7794 switch (state
->cur_style
.type
) {
7795 case OO_STYLE_CELL
: oo_style_prop_cell (xin
, attrs
); break;
7797 case OO_STYLE_ROW
: oo_style_prop_col_row (xin
, attrs
); break;
7798 case OO_STYLE_SHEET
: oo_style_prop_table (xin
, attrs
); break;
7799 case OO_STYLE_TEXT
: od_style_prop_text (xin
, attrs
); break;
7800 case OO_STYLE_CHART
:
7801 case OO_STYLE_GRAPHICS
:
7802 od_style_prop_chart (xin
, attrs
); break;
7810 oo_named_expr_common (GsfXMLIn
*xin
, xmlChar
const **attrs
, gboolean preparse
)
7812 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
7813 char const *name
= NULL
;
7814 char const *base_str
= NULL
;
7815 char const *expr_str
= NULL
;
7816 char const *scope
= NULL
;
7817 char *range_str
= NULL
;
7819 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
7820 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "name"))
7821 name
= CXML2C (attrs
[1]);
7822 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "base-cell-address"))
7823 base_str
= CXML2C (attrs
[1]);
7824 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "expression"))
7825 expr_str
= CXML2C (attrs
[1]);
7826 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "cell-range-address"))
7827 expr_str
= range_str
= g_strconcat ("[", CXML2C (attrs
[1]), "]", NULL
);
7828 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "scope"))
7829 scope
= CXML2C (attrs
[1]);
7832 g_printerr ("%s: %s [sheet=%s] [%s]\n",
7833 (preparse
? "preparse" : "parse"),
7835 state
->pos
.sheet
? state
->pos
.sheet
->name_unquoted
: "-",
7840 expr_str
= "of:=#REF!";
7844 if (name
&& expr_str
&&
7845 g_str_equal (name
, "Print_Area") &&
7846 g_str_equal (expr_str
, "of:=[.#REF!]")) {
7847 // Deal with XL nonsense
7851 if (name
!= NULL
&& expr_str
!= NULL
) {
7853 GnmExprTop
const *texpr
;
7856 parse_pos_init (&pp
, state
->pos
.wb
, NULL
, 0, 0);
7858 /* Note that base_str is not required */
7859 if (base_str
!= NULL
) {
7860 char *tmp
= g_strconcat ("[", base_str
, "]", NULL
);
7862 texpr
= oo_expr_parse_str
7864 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
,
7865 FORMULA_OPENFORMULA
);
7868 if (texpr
== NULL
||
7869 !gnm_expr_top_get_cellref (texpr
)) {
7870 oo_warning (xin
, _("expression '%s' @ '%s' "
7871 "is not a cellref"),
7874 GnmCellRef
const *ref
=
7875 &texpr
->expr
->cellref
.ref
;
7876 parse_pos_init (&pp
, state
->pos
.wb
, ref
->sheet
,
7877 ref
->col
, ref
->row
);
7880 gnm_expr_top_unref (texpr
);
7883 f_type
= odf_get_formula_type (xin
, &expr_str
);
7884 if (f_type
== FORMULA_NOT_SUPPORTED
) {
7886 (xin
, _("Expression '%s' has "
7887 "unknown namespace"),
7891 /* Note that an = sign is only required if a */
7892 /* name space is given. */
7893 if (*expr_str
== '=')
7897 texpr
= gnm_expr_top_new_constant (value_new_error_REF (NULL
));
7899 texpr
= oo_expr_parse_str (xin
, expr_str
,
7900 &pp
, GNM_EXPR_PARSE_DEFAULT
,
7902 if (texpr
!= NULL
) {
7903 pp
.sheet
= state
->pos
.sheet
;
7904 if (pp
.sheet
== NULL
&& scope
!= NULL
)
7905 pp
.sheet
= workbook_sheet_by_name (pp
.wb
, scope
);
7908 gnm_expr_top_unref (texpr
);
7912 expr_name_add (&pp
, name
, texpr
, NULL
,
7922 oo_named_expr (GsfXMLIn
*xin
, xmlChar
const **attrs
)
7924 oo_named_expr_common (xin
, attrs
, FALSE
);
7928 oo_db_range_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
7930 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
7931 gboolean buttons
= FALSE
;
7932 char const *name
= NULL
;
7933 GnmExpr
const *expr
= NULL
;
7934 gchar
const *target
= NULL
;
7936 g_return_if_fail (state
->filter
== NULL
);
7938 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
7939 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "target-range-address"))
7940 target
= CXML2C (attrs
[1]);
7941 else if (oo_attr_bool (xin
, attrs
, OO_NS_TABLE
, "display-filter-buttons", &buttons
))
7943 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "name"))
7944 name
= CXML2C (attrs
[1]);
7949 char const *ptr
= oo_cellref_parse
7950 (&ref
.a
, target
, &state
->pos
, NULL
);
7951 if (ref
.a
.sheet
!= invalid_sheet
&&
7953 '\0' == *oo_cellref_parse (&ref
.b
, ptr
+1, &state
->pos
, NULL
) &&
7954 ref
.b
.sheet
!= invalid_sheet
) {
7955 range_init_rangeref (&r
, &ref
);
7957 state
->filter
= gnm_filter_new (ref
.a
.sheet
, &r
);
7958 expr
= gnm_expr_new_constant
7959 (value_new_cellrange_r (ref
.a
.sheet
, &r
));
7961 oo_warning (xin
, _("Invalid DB range '%s'"), target
);
7964 /* It appears that OOo likes to use the names it assigned to filters as named-ranges */
7965 /* This really violates ODF/OpenFormula. So we make sure that there isn't already a named */
7966 /* expression or range with that name. */
7968 GnmNamedExpr
*nexpr
= NULL
;
7971 (NULL
== (nexpr
= expr_name_lookup
7972 (parse_pos_init (&pp
, state
->pos
.wb
, NULL
, 0, 0), name
)) ||
7973 expr_name_is_placeholder (nexpr
))) {
7974 GnmExprTop
const *texpr
= gnm_expr_top_new (expr
);
7975 expr_name_add (&pp
, name
, texpr
, NULL
, TRUE
, NULL
);
7977 gnm_expr_free (expr
);
7982 oo_db_range_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
7984 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
7986 if (state
->filter
!= NULL
) {
7987 gnm_filter_reapply (state
->filter
);
7988 state
->filter
= NULL
;
7993 odf_filter_or (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
7995 oo_warning (xin
, _("Gnumeric does not support 'or'-ed autofilter conditions."));
7999 oo_filter_cond (GsfXMLIn
*xin
, xmlChar
const **attrs
)
8001 static OOEnum
const datatypes
[] = {
8002 { "text", VALUE_STRING
},
8003 { "number", VALUE_FLOAT
},
8006 static OOEnum
const operators
[] = {
8007 { "=", GNM_FILTER_OP_EQUAL
},
8008 { "!=", GNM_FILTER_OP_NOT_EQUAL
},
8009 { "<", GNM_FILTER_OP_LT
},
8010 { "<=", GNM_FILTER_OP_LTE
},
8011 { ">", GNM_FILTER_OP_GT
},
8012 { ">=", GNM_FILTER_OP_GTE
},
8014 { "match", GNM_FILTER_OP_MATCH
},
8015 { "!match", GNM_FILTER_OP_NO_MATCH
},
8016 { "empty", GNM_FILTER_OP_BLANKS
},
8017 { "!empty", GNM_FILTER_OP_NON_BLANKS
},
8018 { "bottom percent", GNM_FILTER_OP_BOTTOM_N_PERCENT_N
},
8019 { "bottom values", GNM_FILTER_OP_BOTTOM_N
},
8020 { "top percent", GNM_FILTER_OP_TOP_N_PERCENT_N
},
8021 { "top values", GNM_FILTER_OP_TOP_N
},
8025 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8026 int field_num
= 0, type
= -1, op
= -1;
8027 char const *val_str
= NULL
;
8029 if (NULL
== state
->filter
)
8032 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
8033 if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
, "field-number", &field_num
, 0, INT_MAX
)) ;
8034 else if (oo_attr_enum (xin
, attrs
, OO_NS_TABLE
, "data-type", datatypes
, &type
)) ;
8035 else if (oo_attr_enum (xin
, attrs
, OO_NS_TABLE
, "operator", operators
, &op
)) ;
8036 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "value"))
8037 val_str
= CXML2C (attrs
[1]);
8039 if (field_num
>= 0 && op
>= 0) {
8040 GnmFilterCondition
*cond
= NULL
;
8043 if (type
>= 0 && val_str
!= NULL
)
8044 v
= value_new_from_string (type
, val_str
, NULL
, FALSE
);
8047 case GNM_FILTER_OP_EQUAL
:
8048 case GNM_FILTER_OP_NOT_EQUAL
:
8049 case GNM_FILTER_OP_LT
:
8050 case GNM_FILTER_OP_LTE
:
8051 case GNM_FILTER_OP_GT
:
8052 case GNM_FILTER_OP_GTE
:
8053 case GNM_FILTER_OP_MATCH
:
8054 case GNM_FILTER_OP_NO_MATCH
:
8056 cond
= gnm_filter_condition_new_single (op
, v
);
8061 case GNM_FILTER_OP_BLANKS
:
8062 cond
= gnm_filter_condition_new_single (
8063 GNM_FILTER_OP_BLANKS
, NULL
);
8065 case GNM_FILTER_OP_NON_BLANKS
:
8066 cond
= gnm_filter_condition_new_single (
8067 GNM_FILTER_OP_NON_BLANKS
, NULL
);
8070 case GNM_FILTER_OP_BOTTOM_N_PERCENT
:
8071 case GNM_FILTER_OP_BOTTOM_N
:
8072 case GNM_FILTER_OP_TOP_N_PERCENT
:
8073 case GNM_FILTER_OP_TOP_N
:
8074 if (v
&& VALUE_IS_NUMBER(v
))
8075 cond
= gnm_filter_condition_new_bucket (
8076 0 == (op
& GNM_FILTER_OP_BOTTOM_MASK
),
8077 0 == (op
& GNM_FILTER_OP_PERCENT_MASK
),
8078 0 == (op
& GNM_FILTER_OP_REL_N_MASK
),
8079 value_get_as_float (v
));
8084 gnm_filter_set_condition (state
->filter
, field_num
, cond
, FALSE
);
8089 odf_draw_frame_store_location (OOParseState
*state
, double *frame_offset
, gdouble height
, gdouble width
)
8091 state
->chart
.width
= width
;
8092 state
->chart
.height
= height
;
8094 state
->chart
.plot_area_x
= 0;
8095 state
->chart
.plot_area_y
= 0;
8096 state
->chart
.plot_area_width
= width
;
8097 state
->chart
.plot_area_height
=height
;
8099 /* Column width and row heights are not correct */
8100 /* yet so we need to save this */
8101 /* info and adjust later. */
8102 state
->chart
.frame_offset
[0] = frame_offset
[0];
8103 state
->chart
.frame_offset
[1] = frame_offset
[1];
8104 state
->chart
.frame_offset
[2] = frame_offset
[2];
8105 state
->chart
.frame_offset
[3] = frame_offset
[3];
8109 od_draw_frame_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
8111 /* Note that in ODF spreadsheet files svg:height and svg:width are */
8112 /* ignored. We only consider */
8113 /* table:end-x and table:end-y together with table:end-cell-address */
8115 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8117 double frame_offset
[4];
8118 gdouble height
= 0., width
= 0., x
= 0., y
= 0., end_x
= 0., end_y
= 0.;
8119 GnmExprTop
const *texpr
= NULL
;
8121 GnmSOAnchorMode mode
;
8122 int last_row
= gnm_sheet_get_last_row (state
->pos
.sheet
);
8123 int last_col
= gnm_sheet_get_last_col (state
->pos
.sheet
);
8125 state
->chart
.name
= NULL
;
8127 height
= width
= x
= y
= 0.;
8128 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2){
8129 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "width"))
8130 oo_parse_distance (xin
, attrs
[1], "width", &width
);
8131 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "height"))
8132 oo_parse_distance (xin
, attrs
[1], "height", &height
);
8133 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "x"))
8134 oo_parse_distance (xin
, attrs
[1], "x", &x
);
8135 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "y"))
8136 oo_parse_distance (xin
, attrs
[1], "y", &y
);
8137 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "end-x"))
8138 oo_parse_distance (xin
, attrs
[1], "end-x", &end_x
);
8139 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "end-y"))
8140 oo_parse_distance (xin
, attrs
[1], "end-y", &end_y
);
8141 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "end-cell-address")) {
8143 char *end_str
= g_strconcat ("[", CXML2C (attrs
[1]), "]", NULL
);
8144 parse_pos_init (&pp
, state
->pos
.wb
, NULL
, 0, 0);
8145 texpr
= oo_expr_parse_str (xin
, end_str
, &pp
,
8146 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
,
8147 FORMULA_OPENFORMULA
);
8149 } else if (oo_attr_int_range (xin
,attrs
, OO_NS_DRAW
, "z-index",
8152 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "name"))
8153 state
->chart
.name
= g_strdup (CXML2C (attrs
[1]));
8156 frame_offset
[0] = x
;
8157 frame_offset
[1] = y
;
8158 if (state
->pos
.eval
.col
>= 0) {
8159 cell_base
.start
.col
= cell_base
.end
.col
= state
->pos
.eval
.col
;
8160 cell_base
.start
.row
= cell_base
.end
.row
= state
->pos
.eval
.row
;
8162 if (texpr
== NULL
|| (GNM_EXPR_GET_OPER (texpr
->expr
) != GNM_EXPR_OP_CELLREF
)) {
8163 cell_base
.end
.col
= cell_base
.start
.col
;
8164 cell_base
.end
.row
= cell_base
.start
.row
;
8165 frame_offset
[2] = width
;
8166 frame_offset
[3] = height
;
8167 mode
= GNM_SO_ANCHOR_ONE_CELL
;
8170 GnmCellRef
const *ref
= &texpr
->expr
->cellref
.ref
;
8171 cell_base
.end
.col
= ref
->col
;
8172 cell_base
.end
.row
= ref
->row
;
8173 frame_offset
[2] = end_x
;
8174 frame_offset
[3] = end_y
;
8175 mode
= GNM_SO_ANCHOR_TWO_CELLS
;
8178 gnm_expr_top_unref (texpr
);
8180 cell_base
.end
.col
= cell_base
.start
.col
=
8181 cell_base
.end
.row
= cell_base
.start
.row
= 0; /* actually not needed */
8182 frame_offset
[2] = width
;
8183 frame_offset
[3] = height
;
8184 mode
= GNM_SO_ANCHOR_ABSOLUTE
;
8187 odf_draw_frame_store_location (state
, frame_offset
,
8188 (height
> 0) ? height
: go_nan
,
8189 (width
> 0) ? width
: go_nan
);
8191 if (cell_base
.start
.col
> last_col
|| cell_base
.start
.row
> last_row
) {
8192 oo_warning (xin
, _("Moving sheet object from column %i and row %i"),
8193 cell_base
.start
.col
, cell_base
.start
.row
);
8194 cell_base
.start
.col
= cell_base
.start
.row
= 0;
8195 range_ensure_sanity (&cell_base
, state
->pos
.sheet
);
8198 sheet_object_anchor_init (&state
->chart
.anchor
, &cell_base
, frame_offset
,
8199 GOD_ANCHOR_DIR_DOWN_RIGHT
, mode
);
8200 state
->chart
.so
= NULL
;
8201 state
->chart
.z_index
= z
;
8205 od_draw_frame_end_full (GsfXMLIn
*xin
, gboolean absolute_distance
, char const *control_name
)
8207 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8209 if (state
->chart
.so
!= NULL
) {
8210 /* Column width and row heights are not correct yet, z-index meaningless, */
8211 /* so we need to save this info and adjust later. */
8212 object_offset_t
*ob_off
= g_new (object_offset_t
, 1);
8214 sheet_object_set_anchor (state
->chart
.so
, &state
->chart
.anchor
);
8215 ob_off
->so
= state
->chart
.so
;
8216 ob_off
->absolute_distance
= absolute_distance
;
8217 ob_off
->z_index
= state
->chart
.z_index
;
8218 ob_off
->control
= g_strdup (control_name
);
8219 ob_off
->frame_offset
[0] = state
->chart
.frame_offset
[0];
8220 ob_off
->frame_offset
[1] = state
->chart
.frame_offset
[1];
8221 ob_off
->frame_offset
[2] = state
->chart
.frame_offset
[2];
8222 ob_off
->frame_offset
[3] = state
->chart
.frame_offset
[3];
8223 state
->chart_list
= g_slist_prepend ( state
->chart_list
, ob_off
);
8225 state
->chart
.so
= NULL
;
8227 g_free (state
->chart
.name
);
8228 state
->chart
.name
= NULL
;
8232 od_draw_frame_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
8234 od_draw_frame_end_full (xin
, FALSE
, NULL
);
8237 od_draw_text_frame_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
8239 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8242 if (state
->text_p_stack
!= NULL
&& (NULL
!= (ptr
= state
->text_p_stack
->data
))
8243 && ptr
->gstr
!= NULL
)
8244 g_object_set (state
->chart
.so
, "text", ptr
->gstr
->str
, "markup", ptr
->attrs
, NULL
);
8245 od_draw_frame_end_full (xin
, FALSE
, NULL
);
8246 odf_pop_text_p (state
);
8250 odf_line_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
8252 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8255 if (state
->text_p_stack
!= NULL
&& (NULL
!= (ptr
= state
->text_p_stack
->data
))
8256 && ptr
->gstr
!= NULL
)
8257 oo_warning (xin
, _("Gnumeric's sheet object lines do not support attached text. "
8258 "The text \"%s\" has been dropped."), ptr
->gstr
->str
);
8259 od_draw_frame_end_full (xin
, TRUE
, NULL
);
8260 odf_pop_text_p (state
);
8264 od_draw_control_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
8266 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8267 char const *name
= NULL
;
8269 od_draw_frame_start (xin
, attrs
);
8271 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
8272 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_DRAW
, "control"))
8273 name
= CXML2C (attrs
[1]);
8276 OOControl
*oc
= g_hash_table_lookup (state
->controls
, name
);
8278 SheetObject
*so
= NULL
;
8279 if (oc
->t
== sheet_widget_scrollbar_get_type () ||
8280 oc
->t
== sheet_widget_spinbutton_get_type () ||
8281 oc
->t
== sheet_widget_slider_get_type ()) {
8283 int min_real
= (oc
->min
< oc
->max
) ? oc
->min
: oc
->max
;
8284 int max_real
= (oc
->min
< oc
->max
) ? oc
->max
: oc
->min
;
8285 gnm_float value_real
;
8287 if (oc
->value
!= NULL
) {
8289 value_real
= gnm_strto (oc
->value
, &end
);
8291 oo_warning (xin
, _("Invalid attribute 'form:value', "
8292 "expected number, received '%s'"), oc
->value
);
8295 if (oc
->value_type
!= NULL
&& 0 != strcmp (oc
->value_type
, "float"))
8296 oo_warning (xin
, _("Invalid value-type '%s' advertised for "
8297 "'form:value' attribute in 'form:value-range' "
8300 } else value_real
= 0.;
8302 if (value_real
< (gnm_float
)min_real
)
8303 value_real
= min_real
;
8304 if (value_real
> (gnm_float
)max_real
)
8305 value_real
= max_real
;
8307 so
= state
->chart
.so
= g_object_new
8308 (oc
->t
, "horizontal", oc
->horizontal
, NULL
);
8309 adj
= sheet_widget_adjustment_get_adjustment (so
);
8311 gtk_adjustment_configure (adj
,
8318 } else if (oc
->t
== sheet_widget_radio_button_get_type ()) {
8319 so
= state
->chart
.so
= g_object_new
8320 (oc
->t
, "text", oc
->label
, NULL
);
8321 if (oc
->value
!= NULL
) {
8322 GnmValue
*val
= NULL
;
8323 if (oc
->value_type
== NULL
||
8324 0 == strcmp (oc
->value_type
, "string"))
8325 val
= value_new_string (oc
->value
);
8326 else if (0 == strcmp (oc
->value_type
, "float")) {
8328 gnm_float value_real
= gnm_strto (oc
->value
, &end
);
8330 oo_warning (xin
, _("Invalid attribute 'form:value', "
8331 "expected number, received '%s'"), oc
->value
);
8332 val
= value_new_string (oc
->value
);
8334 val
= value_new_float (value_real
);
8335 } else if (0 == strcmp (oc
->value_type
, "boolean")) {
8336 gboolean b
= (g_ascii_strcasecmp (oc
->value
, "false") &&
8337 strcmp (oc
->value
, "0"));
8338 val
= value_new_bool (b
);
8340 val
= value_new_string (oc
->value
);
8341 sheet_widget_radio_button_set_value (so
, val
);
8342 value_release (val
);
8344 } else if (oc
->t
== sheet_widget_checkbox_get_type ()) {
8345 state
->chart
.so
= g_object_new
8346 (oc
->t
, "text", oc
->label
, NULL
);
8347 } else if (oc
->t
== sheet_widget_list_get_type () ||
8348 oc
->t
== sheet_widget_combo_get_type ()) {
8349 state
->chart
.so
= g_object_new
8351 } else if (oc
->t
== sheet_widget_button_get_type ()) {
8352 state
->chart
.so
= g_object_new
8353 (oc
->t
, "text", oc
->label
, NULL
);
8354 } else if (oc
->t
== sheet_widget_frame_get_type ()) {
8355 state
->chart
.so
= g_object_new
8356 (oc
->t
, "text", oc
->label
, NULL
);
8359 oo_warning (xin
, "Undefined control '%s' encountered!", name
);
8361 od_draw_frame_end_full (xin
, FALSE
, name
);
8365 pop_hash (GSList
**list
, GHashTable
**hash
)
8367 g_hash_table_destroy (*hash
);
8371 *hash
= (*list
)->data
;
8372 *list
= g_slist_delete_link (*list
, *list
);
8377 odf_clear_conventions (OOParseState
*state
)
8380 for (i
= 0; i
< NUM_FORMULAE_SUPPORTED
; i
++)
8381 if (state
->convs
[i
] != NULL
) {
8382 gnm_conventions_unref (state
->convs
[i
]);
8383 state
->convs
[i
] = NULL
;
8388 od_draw_object (GsfXMLIn
*xin
, xmlChar
const **attrs
)
8390 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8391 gchar
const *name_start
= NULL
;
8394 GsfInput
*content
= NULL
;
8397 if (state
->chart
.so
!= NULL
) {
8398 if (GNM_IS_SO_GRAPH (state
->chart
.so
))
8399 /* Only one object per frame! */
8401 /* We prefer objects over images etc. */
8402 /* We probably should figure out though whether */
8403 /* we in fact understand this object. */
8404 g_object_unref (state
->chart
.so
);
8405 state
->chart
.so
= NULL
;
8408 state
->chart
.so
= sheet_object_graph_new (NULL
);
8409 state
->chart
.graph
= sheet_object_graph_get_gog (state
->chart
.so
);
8411 state
->chart
.saved_graph_styles
8412 = g_slist_prepend (state
->chart
.saved_graph_styles
,
8413 state
->chart
.graph_styles
);
8414 state
->chart
.saved_hatches
8415 = g_slist_prepend (state
->chart
.saved_hatches
,
8416 state
->chart
.hatches
);
8417 state
->chart
.saved_dash_styles
8418 = g_slist_prepend (state
->chart
.saved_dash_styles
,
8419 state
->chart
.dash_styles
);
8420 state
->chart
.saved_fill_image_styles
8421 = g_slist_prepend (state
->chart
.saved_fill_image_styles
,
8422 state
->chart
.fill_image_styles
);
8423 state
->chart
.saved_gradient_styles
8424 = g_slist_prepend (state
->chart
.saved_gradient_styles
,
8425 state
->chart
.gradient_styles
);
8427 for (i
= 0; i
< OO_CHART_STYLE_INHERITANCE
; i
++)
8428 state
->chart
.i_plot_styles
[i
] = NULL
;
8430 state
->chart
.graph_styles
= g_hash_table_new_full
8431 (g_str_hash
, g_str_equal
,
8432 (GDestroyNotify
) g_free
,
8433 (GDestroyNotify
) oo_chart_style_free
);
8434 state
->chart
.hatches
= g_hash_table_new_full
8435 (g_str_hash
, g_str_equal
,
8436 (GDestroyNotify
) g_free
,
8437 (GDestroyNotify
) g_free
);
8438 state
->chart
.dash_styles
= g_hash_table_new_full
8439 (g_str_hash
, g_str_equal
,
8440 (GDestroyNotify
) g_free
,
8442 state
->chart
.fill_image_styles
= g_hash_table_new_full
8443 (g_str_hash
, g_str_equal
,
8444 (GDestroyNotify
) g_free
,
8445 (GDestroyNotify
) g_free
);
8446 state
->chart
.gradient_styles
= g_hash_table_new_full
8447 (g_str_hash
, g_str_equal
,
8448 (GDestroyNotify
) g_free
,
8449 (GDestroyNotify
) g_free
);
8451 odf_free_cur_style (state
);
8453 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
8454 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_XLINK
, "href")) {
8455 name_start
= CXML2C (attrs
[1]);
8456 if (strncmp (CXML2C (attrs
[1]), "./", 2) == 0)
8458 if (strncmp (CXML2C (attrs
[1]), "/", 1) == 0)
8465 name_len
= strlen (name_start
);
8466 if (*(name_start
+ name_len
- 1) == '/') /* OOo does not append a / */
8468 name
= g_strndup (name_start
, name_len
);
8469 state
->object_name
= name
;
8471 /* We should be saving/protecting some info to avoid it being overwritten. */
8474 g_print ("START %s\n", name
);
8476 content
= gsf_infile_child_by_vname (state
->zip
, name
, "styles.xml", NULL
);
8477 if (content
!= NULL
) {
8479 gsf_xml_in_doc_new (get_styles_dtd (),
8481 gsf_xml_in_doc_parse (doc
, content
, state
);
8482 gsf_xml_in_doc_free (doc
);
8483 odf_clear_conventions (state
); /* contain references to xin */
8484 g_object_unref (content
);
8487 content
= gsf_infile_child_by_vname (state
->zip
, name
, "content.xml", NULL
);
8488 if (content
!= NULL
) {
8490 gsf_xml_in_doc_new (get_dtd (), gsf_odf_get_ns ());
8491 gsf_xml_in_doc_parse (doc
, content
, state
);
8492 gsf_xml_in_doc_free (doc
);
8493 odf_clear_conventions (state
); /* contain references to xin */
8494 g_object_unref (content
);
8497 g_print ("END %s\n", name
);
8498 state
->object_name
= NULL
;
8501 odf_free_cur_style (state
);
8503 for (i
= 0; i
< OO_CHART_STYLE_INHERITANCE
; i
++)
8504 state
->chart
.i_plot_styles
[i
] = NULL
;
8506 if (state
->chart
.width
!= go_nan
)
8507 g_object_set (state
->chart
.graph
, "width-pts", state
->chart
.width
, NULL
);
8508 if (state
->chart
.height
!= go_nan
)
8509 g_object_set (state
->chart
.graph
, "height-pts", state
->chart
.height
, NULL
);
8511 pop_hash (&state
->chart
.saved_graph_styles
, &state
->chart
.graph_styles
);
8512 pop_hash (&state
->chart
.saved_hatches
, &state
->chart
.hatches
);
8513 pop_hash (&state
->chart
.saved_dash_styles
, &state
->chart
.dash_styles
);
8514 pop_hash (&state
->chart
.saved_fill_image_styles
,
8515 &state
->chart
.fill_image_styles
);
8516 pop_hash (&state
->chart
.saved_gradient_styles
,
8517 &state
->chart
.gradient_styles
);
8521 od_draw_image (GsfXMLIn
*xin
, xmlChar
const **attrs
)
8525 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8526 gchar
const *file
= NULL
;
8529 if (state
->chart
.so
!= NULL
)
8530 /* We only use images if there is no object available. */
8533 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
8534 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
8535 OO_NS_XLINK
, "href")) {
8536 file
= CXML2C (attrs
[1]);
8543 path
= g_strsplit (file
, "/", -1);
8544 input
= gsf_infile_child_by_aname (state
->zip
, (const char **) path
);
8547 if (input
!= NULL
) {
8548 SheetObjectImage
*soi
;
8549 gsf_off_t len
= gsf_input_size (input
);
8550 guint8
const *data
= gsf_input_read (input
, len
, NULL
);
8551 soi
= g_object_new (GNM_SO_IMAGE_TYPE
, NULL
);
8552 state
->chart
.so
= GNM_SO (soi
);
8553 sheet_object_image_set_image (soi
, "", data
, len
);
8554 g_object_unref (input
);
8555 if (state
->chart
.name
!= NULL
) {
8556 GOImage
*image
= NULL
;
8557 g_object_get (G_OBJECT (soi
),
8560 go_image_set_name (image
, state
->chart
.name
);
8561 g_object_unref (image
);
8564 oo_warning (xin
, _("Unable to load "
8565 "the file \'%s\'."),
8571 od_draw_text_box (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
8573 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8576 if (state
->chart
.so
!= NULL
)
8577 /* We have already created frame content */
8580 style
= go_style_new ();
8582 style
->line
.width
= 0;
8583 style
->line
.dash_type
= GO_LINE_NONE
;
8584 style
->line
.auto_dash
= FALSE
;
8585 style
->fill
.type
= GO_STYLE_FILL_NONE
;
8586 style
->fill
.auto_type
= FALSE
;
8588 state
->chart
.so
= g_object_new (GNM_SO_FILLED_TYPE
, "is-oval", FALSE
, "style", style
, NULL
);
8589 g_object_unref (style
);
8591 odf_push_text_p (state
, FALSE
);
8594 /* oo_chart_title is used both for chart titles and legend titles */
8595 /* 0: title, 1: subtitle, 2:footer, 3: axis */
8597 oo_chart_title (GsfXMLIn
*xin
, xmlChar
const **attrs
)
8599 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8601 state
->chart
.title_expr
= NULL
;
8602 state
->chart
.title_style
= NULL
;
8603 state
->chart
.title_position
= NULL
;
8604 state
->chart
.title_anchor
= NULL
;
8605 state
->chart
.title_manual_pos
= TRUE
;
8606 state
->chart
.title_x
= go_nan
;
8607 state
->chart
.title_y
= go_nan
;
8609 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2){
8610 if ((gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
8611 OO_NS_TABLE
, "cell-address" ) ||
8612 gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
8613 OO_NS_TABLE
, "cell-range" ))
8614 && state
->chart
.title_expr
== NULL
) {
8616 char *end_str
= g_strconcat ("[", CXML2C (attrs
[1]), "]", NULL
);
8618 parse_pos_init (&pp
, state
->pos
.wb
, NULL
, 0, 0);
8619 state
->chart
.title_expr
8622 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
,
8623 FORMULA_OPENFORMULA
);
8625 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
8626 OO_GNUM_NS_EXT
, "expression")) {
8629 if (state
->chart
.title_expr
!= NULL
)
8630 gnm_expr_top_unref (state
->chart
.title_expr
);
8632 parse_pos_init (&pp
, state
->pos
.wb
, NULL
, 0, 0);
8633 state
->chart
.title_expr
8635 (xin
, CXML2C (attrs
[1]), &pp
,
8636 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
,
8637 FORMULA_OPENFORMULA
);
8638 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
8639 OO_NS_CHART
, "style-name")) {
8640 state
->chart
.title_style
= g_strdup (CXML2C (attrs
[1]));
8641 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
8642 OO_GNUM_NS_EXT
, "compass"))
8643 state
->chart
.title_position
= g_strdup (CXML2C (attrs
[1]));
8644 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
8645 OO_GNUM_NS_EXT
, "anchor"))
8646 state
->chart
.title_anchor
= g_strdup (CXML2C (attrs
[1]));
8647 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "is-position-manual",
8648 &state
->chart
.title_manual_pos
))
8650 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "x"))
8651 oo_parse_distance (xin
, attrs
[1], "x", &state
->chart
.title_x
);
8652 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "y"))
8653 oo_parse_distance (xin
, attrs
[1], "y", &state
->chart
.title_y
);
8656 if (!(go_finite (state
->chart
.title_x
) && go_finite (state
->chart
.title_y
)))
8657 state
->chart
.title_manual_pos
= FALSE
;
8658 if (state
->chart
.title_position
== NULL
)
8659 state
->chart
.title_position
= g_strdup ((xin
->node
->user_data
.v_int
== 2) ? "bottom" : "top");
8661 odf_push_text_p (state
, FALSE
);
8665 oo_chart_title_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
8667 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8669 gboolean use_markup
= FALSE
;
8671 g_return_if_fail (state
->text_p_stack
!= NULL
);
8672 ptr
= state
->text_p_stack
->data
;
8673 g_return_if_fail (ptr
!= NULL
);
8675 if (state
->chart
.title_expr
== NULL
&& ptr
->gstr
) {
8676 state
->chart
.title_expr
= gnm_expr_top_new_constant
8677 (value_new_string_nocopy
8678 (go_pango_attrs_to_markup (ptr
->attrs
, ptr
->gstr
->str
)));
8679 use_markup
= (ptr
->attrs
!= NULL
&&
8680 !go_pango_attr_list_is_empty (ptr
->attrs
));
8683 if (state
->chart
.title_expr
) {
8684 GOData
*data
= gnm_go_data_scalar_new_expr
8685 (state
->chart
.src_sheet
, state
->chart
.title_expr
);
8690 if (state
->chart
.axis
!= NULL
&& xin
->node
->user_data
.v_int
== 3) {
8691 obj
= (GogObject
*)state
->chart
.axis
;
8693 } else if (state
->chart
.legend
!= NULL
) {
8694 obj
= (GogObject
*)state
->chart
.legend
;
8696 } else if (xin
->node
->user_data
.v_int
== 0) {
8697 obj
= (GogObject
*)state
->chart
.graph
;
8700 obj
= (GogObject
*)state
->chart
.chart
;
8704 label
= gog_object_add_by_name (obj
, tag
, NULL
);
8705 gog_dataset_set_dim (GOG_DATASET (label
), 0, data
, NULL
);
8706 state
->chart
.title_expr
= NULL
;
8707 if (state
->chart
.title_style
!= NULL
) {
8708 OOChartStyle
*oostyle
= g_hash_table_lookup
8709 (state
->chart
.graph_styles
, state
->chart
.title_style
);
8711 go_styled_object_get_style (GO_STYLED_OBJECT (label
));
8712 if (oostyle
&& style
) {
8713 style
= go_style_dup (style
);
8714 odf_apply_style_props (xin
, oostyle
->style_props
, style
, TRUE
);
8715 go_styled_object_set_style (GO_STYLED_OBJECT (label
), style
);
8716 g_object_unref (style
);
8718 g_free (state
->chart
.title_style
);
8719 state
->chart
.title_style
= NULL
;
8722 g_object_set (label
, "allow-markup", TRUE
, NULL
);
8723 if (xin
->node
->user_data
.v_int
!= 3) {
8724 if (state
->chart
.title_anchor
)
8725 g_object_set (label
, "anchor", state
->chart
.title_anchor
, NULL
);
8726 g_object_set (label
,
8727 "compass", state
->chart
.title_position
,
8728 "is-position-manual", state
->chart
.title_manual_pos
,
8731 g_object_set (label
,
8732 "is-position-manual", state
->chart
.title_manual_pos
,
8735 if (state
->chart
.title_manual_pos
) {
8736 if (go_finite (state
->chart
.width
) && go_finite (state
->chart
.height
)) {
8737 GogViewAllocation alloc
;
8738 alloc
.x
= state
->chart
.title_x
/ state
->chart
.width
;
8740 alloc
.y
= state
->chart
.title_y
/ state
->chart
.height
;
8743 gog_object_set_position_flags (label
, GOG_POSITION_MANUAL
, GOG_POSITION_ANY_MANUAL
);
8744 gog_object_set_manual_position (label
, &alloc
);
8746 g_object_set (label
,
8747 "is-position-manual", FALSE
,
8749 oo_warning (xin
, _("Unable to determine manual position for a chart component!"));
8754 g_free (state
->chart
.title_position
);
8755 state
->chart
.title_position
= NULL
;
8756 g_free (state
->chart
.title_anchor
);
8757 state
->chart
.title_anchor
= NULL
;
8758 odf_pop_text_p (state
);
8762 od_chart_axis_categories (GsfXMLIn
*xin
, xmlChar
const **attrs
)
8764 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8766 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
8767 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
8768 OO_NS_TABLE
, "cell-range-address")) {
8769 if (state
->chart
.cat_expr
== NULL
)
8770 state
->chart
.cat_expr
8771 = g_strdup (CXML2C (attrs
[1]));
8777 oo_chart_axis (GsfXMLIn
*xin
, xmlChar
const **attrs
)
8779 static OOEnum
const types
[] = {
8780 { "x", GOG_AXIS_X
},
8781 { "y", GOG_AXIS_Y
},
8782 { "z", GOG_AXIS_Z
},
8785 static OOEnum
const types_bar
[] = {
8786 { "x", GOG_AXIS_Y
},
8787 { "y", GOG_AXIS_X
},
8788 { "z", GOG_AXIS_Z
},
8791 static OOEnum
const types_contour
[] = {
8792 { "x", GOG_AXIS_X
},
8793 { "y", GOG_AXIS_Y
},
8794 { "z", GOG_AXIS_PSEUDO_3D
},
8797 static OOEnum
const types_radar
[] = {
8798 { "x", GOG_AXIS_CIRCULAR
},
8799 { "y", GOG_AXIS_RADIAL
},
8804 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8805 OOChartStyle
*style
= NULL
;
8806 gchar
const *style_name
= NULL
;
8807 gchar
const *chart_name
= NULL
;
8808 gchar
const *color_map_name
= NULL
;
8809 GogAxisType axis_type
;
8812 OOEnum
const *axes_types
;
8814 switch (state
->chart
.plot_type
) {
8816 case OO_PLOT_RADARAREA
:
8818 axes_types
= types_radar
;
8821 if (oo_style_has_plot_property (state
->chart
.i_plot_styles
, "horizontal", FALSE
))
8822 axes_types
= types_bar
;
8826 case OO_PLOT_CIRCLE
:
8829 case OO_PLOT_XL_CONTOUR
:
8830 case OO_PLOT_CONTOUR
:
8831 if (oo_style_has_property (state
->chart
.i_plot_styles
, "three-dimensional", FALSE
))
8833 else axes_types
= types_contour
;
8840 axis_type
= GOG_AXIS_UNKNOWN
;
8841 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
8842 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "style-name"))
8843 style_name
= CXML2C (attrs
[1]);
8844 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "name"))
8845 chart_name
= CXML2C (attrs
[1]);
8846 else if (oo_attr_enum (xin
, attrs
, OO_NS_CHART
, "dimension", axes_types
, &tmp
))
8848 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
, "id", &gnm_id
, 1, INT_MAX
))
8850 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "color-map-name"))
8851 color_map_name
= CXML2C (attrs
[1]);
8854 switch (axis_type
) {
8856 gnm_id
= ++(state
->chart
.x_axis_count
);
8859 gnm_id
= ++(state
->chart
.y_axis_count
);
8862 gnm_id
= ++(state
->chart
.z_axis_count
);
8864 case GOG_AXIS_CIRCULAR
:
8865 case GOG_AXIS_RADIAL
:
8866 case GOG_AXIS_UNKNOWN
:
8873 axes
= gog_chart_get_axes (state
->chart
.chart
, axis_type
);
8874 for (l
= axes
; NULL
!= l
; l
= l
->next
) {
8875 if (((unsigned)gnm_id
) == gog_object_get_id (GOG_OBJECT (l
->data
))) {
8876 state
->chart
.axis
= l
->data
;
8880 g_slist_free (axes
);
8881 if (NULL
== state
->chart
.axis
&& (axis_type
== GOG_AXIS_X
|| axis_type
== GOG_AXIS_Y
8882 || axis_type
== GOG_AXIS_Z
)) {
8883 GogObject
*axis
= GOG_OBJECT (g_object_new (GOG_TYPE_AXIS
, "type", axis_type
, NULL
));
8884 gog_object_add_by_name (GOG_OBJECT (state
->chart
.chart
),
8885 axis_type
== GOG_AXIS_X
? "X-Axis" :
8886 (axis_type
== GOG_AXIS_Y
? "Y-Axis" : "Z-Axis"), axis
);
8887 axes
= gog_chart_get_axes (state
->chart
.chart
, axis_type
);
8888 for (l
= axes
; NULL
!= l
; l
= l
->next
) {
8889 if (((unsigned)gnm_id
) == gog_object_get_id (GOG_OBJECT (l
->data
))) {
8890 state
->chart
.axis
= l
->data
;
8894 g_slist_free (axes
);
8896 if (NULL
== state
->chart
.axis
)
8897 g_print ("Did not find axis with type %i and id %i.\n", axis_type
, gnm_id
);
8899 if (NULL
!= style_name
&&
8900 NULL
!= (style
= g_hash_table_lookup (state
->chart
.graph_styles
, style_name
))) {
8901 if (NULL
!= state
->chart
.axis
) {
8903 g_object_get (G_OBJECT (state
->chart
.axis
), "style", &gostyle
, NULL
);
8905 oo_prop_list_apply_to_axis (xin
, style
->axis_props
,
8906 G_OBJECT (state
->chart
.axis
));
8907 odf_apply_style_props (xin
, style
->style_props
, gostyle
, TRUE
);
8908 g_object_unref (gostyle
);
8911 gboolean has_prop
= FALSE
;
8912 oo_prop_list_has (style
->other_props
, &has_prop
, "ignore-axis-data-style");
8914 gog_axis_set_format (GOG_AXIS (state
->chart
.axis
),
8915 go_format_ref (style
->fmt
));
8919 if (NULL
!= state
->chart
.plot
&& (state
->ver
== OOO_VER_1
))
8920 oo_prop_list_apply (style
->plot_props
, G_OBJECT (state
->chart
.plot
));
8922 if (NULL
!= chart_name
&& NULL
!= state
->chart
.axis
)
8923 g_hash_table_replace (state
->chart
.named_axes
,
8924 g_strdup (chart_name
),
8926 if (NULL
!= color_map_name
&& NULL
!= state
->chart
.axis
)
8927 g_object_set (G_OBJECT(state
->chart
.axis
), "color-map-name", color_map_name
, NULL
);
8931 oo_chart_axis_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
8933 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8934 state
->chart
.axis
= NULL
;
8938 gog_series_map_dim (GogSeries
const *series
, GogMSDimType ms_type
)
8940 GogSeriesDesc
const *desc
= &series
->plot
->desc
.series
;
8941 unsigned i
= desc
->num_dim
;
8943 if (ms_type
== GOG_MS_DIM_LABELS
)
8946 if (desc
->dim
[i
].ms_type
== ms_type
)
8952 gog_series_map_dim_by_name (GogSeries
const *series
, char const *dim_name
)
8954 GogSeriesDesc
const *desc
= &series
->plot
->desc
.series
;
8955 unsigned i
= desc
->num_dim
;
8958 if (desc
->dim
[i
].name
!= NULL
&& strcmp (desc
->dim
[i
].name
, dim_name
) == 0)
8963 /* If range == %NULL use an implicit range */
8964 /* If general_expr, then range contains an expression not necessarily a range. */
8966 oo_plot_assign_dim (GsfXMLIn
*xin
, xmlChar
const *range
, int dim_type
, char const *dim_name
,
8967 gboolean general_expr
)
8969 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
8971 /* force relative to A1, not the containing cell */
8972 GnmExprTop
const *texpr
;
8975 gboolean set_default_labels
= FALSE
;
8976 gboolean set_default_series_name
= FALSE
;
8978 if (NULL
== state
->chart
.series
)
8981 dim
= - (1 + dim_type
);
8982 else if (dim_name
== NULL
)
8983 dim
= gog_series_map_dim (state
->chart
.series
, dim_type
);
8985 dim
= gog_series_map_dim_by_name (state
->chart
.series
, dim_name
);
8989 if (NULL
!= range
) {
8991 texpr
= odf_parse_range_address_or_expr (xin
, CXML2C (range
));
8993 g_print ("%d = rangeref (%s) -- general expression\n", dim
, range
);
8995 char const *range_list
= CXML2C (range
);
8997 GnmExprList
*args
= NULL
;
8998 GnmExpr
const *expr
;
9000 parse_pos_init_sheet (&pp
, state
->pos
.sheet
);
9001 while (*range_list
!= 0) {
9003 char const *ptr
= oo_rangeref_parse
9004 (&ref
, range_list
, &pp
, NULL
);
9005 if (ptr
== range_list
|| ref
.a
.sheet
== invalid_sheet
) {
9008 v
= value_new_cellrange (&ref
.a
, &ref
.b
, 0, 0);
9009 expr
= gnm_expr_new_constant (v
);
9010 args
= gnm_expr_list_append (args
, expr
);
9012 while (*range_list
== ' ')
9015 if (1 == gnm_expr_list_length (args
)) {
9017 gnm_expr_list_free (args
);
9019 expr
= gnm_expr_new_set (args
);
9020 texpr
= gnm_expr_top_new (expr
);
9022 g_print ("%d = rangeref (%s)\n", dim
, range
);
9024 } else if (NULL
!= gog_dataset_get_dim (GOG_DATASET (state
->chart
.series
), dim
))
9025 return; /* implicit does not overwrite existing */
9026 else if (state
->chart
.src_n_vectors
<= 0) {
9028 _("Not enough data in the supplied range (%s) for all the requests"), CXML2C (range
));
9031 v
= value_new_cellrange_r (
9032 state
->chart
.src_sheet
,
9033 &state
->chart
.src_range
);
9036 g_print ("%d = implicit (%s)\n", dim
,
9037 range_as_string (&state
->chart
.src_range
));
9039 state
->chart
.src_n_vectors
--;
9040 if (state
->chart
.src_in_rows
)
9041 state
->chart
.src_range
.end
.row
= ++state
->chart
.src_range
.start
.row
;
9043 state
->chart
.src_range
.end
.col
= ++state
->chart
.src_range
.start
.col
;
9045 set_default_labels
= state
->chart
.src_abscissa_set
;
9046 set_default_series_name
= state
->chart
.src_label_set
;
9047 texpr
= gnm_expr_top_new_constant (v
);
9051 gog_series_set_dim (state
->chart
.series
, dim
,
9052 (dim_type
!= GOG_MS_DIM_LABELS
)
9053 ? gnm_go_data_vector_new_expr (state
->pos
.sheet
, texpr
)
9054 : gnm_go_data_scalar_new_expr (state
->pos
.sheet
, texpr
),
9056 if (set_default_labels
) {
9057 v
= value_new_cellrange_r (state
->chart
.src_sheet
,
9058 &state
->chart
.src_abscissa
);
9059 texpr
= gnm_expr_top_new_constant (v
);
9061 gog_series_set_dim (state
->chart
.series
, GOG_DIM_LABEL
,
9062 gnm_go_data_vector_new_expr
9063 (state
->pos
.sheet
, texpr
),
9066 if (set_default_series_name
) {
9067 v
= value_new_cellrange_r (state
->chart
.src_sheet
,
9068 &state
->chart
.src_label
);
9069 texpr
= gnm_expr_top_new_constant (v
);
9071 gog_series_set_name (state
->chart
.series
,
9072 GO_DATA_SCALAR (gnm_go_data_scalar_new_expr
9073 (state
->pos
.sheet
, texpr
)),
9075 if (state
->chart
.src_in_rows
)
9076 state
->chart
.src_label
.end
.row
= ++state
->chart
.src_label
.start
.row
;
9078 state
->chart
.src_label
.end
.col
= ++state
->chart
.src_label
.start
.col
;
9083 odf_gog_check_position (GsfXMLIn
*xin
, xmlChar
const **attrs
, GSList
**list
)
9087 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
9088 if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "is-position-manual", &b
))
9089 *list
= g_slist_prepend (*list
, oo_prop_new_bool("is-position-manual",
9091 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "position"))
9092 *list
= g_slist_prepend (*list
, oo_prop_new_string ("position",
9094 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "anchor"))
9095 *list
= g_slist_prepend (*list
, oo_prop_new_string ("anchor",
9100 odf_gog_plot_area_check_position (GsfXMLIn
*xin
, xmlChar
const **attrs
, GSList
**list
)
9104 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
9105 if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "is-position-manual", &b
))
9106 *list
= g_slist_prepend (*list
, oo_prop_new_bool("is-plot-area-manual",
9108 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "position"))
9109 *list
= g_slist_prepend (*list
, oo_prop_new_string ("plot-area",
9115 oo_legend_set_position (OOParseState
*state
)
9117 GogObject
*legend
= state
->chart
.legend
;
9122 if (go_finite (state
->chart
.legend_x
) && go_finite (state
->chart
.legend_y
) &&
9123 go_finite (state
->chart
.width
) && go_finite (state
->chart
.height
)) {
9124 GogViewAllocation alloc
;
9125 alloc
.x
= (state
->chart
.legend_x
- state
->chart
.plot_area_x
) / state
->chart
.plot_area_width
;
9127 alloc
.y
= (state
->chart
.legend_y
- state
->chart
.plot_area_y
) / state
->chart
.plot_area_height
;
9130 gog_object_set_position_flags (legend
, GOG_POSITION_MANUAL
, GOG_POSITION_ANY_MANUAL
);
9131 gog_object_set_manual_position (legend
, &alloc
);
9133 gog_object_set_position_flags (legend
, state
->chart
.legend_flag
,
9134 GOG_POSITION_COMPASS
| GOG_POSITION_ALIGNMENT
);
9138 *odf_find_plot_type (OOParseState
*state
, OOPlotType
*oo_type
)
9141 case OO_PLOT_AREA
: return "GogAreaPlot"; break;
9142 case OO_PLOT_BAR
: return "GogBarColPlot"; break;
9143 case OO_PLOT_CIRCLE
: return "GogPiePlot"; break;
9144 case OO_PLOT_LINE
: return "GogLinePlot"; break;
9145 case OO_PLOT_RADAR
: return "GogRadarPlot"; break;
9146 case OO_PLOT_RADARAREA
: return "GogRadarAreaPlot";break;
9147 case OO_PLOT_RING
: return "GogRingPlot"; break;
9148 case OO_PLOT_SCATTER
: return "GogXYPlot"; break;
9149 case OO_PLOT_STOCK
: return "GogMinMaxPlot"; break; /* This is not quite right! */
9150 case OO_PLOT_CONTOUR
:
9151 if (oo_style_has_property (state
->chart
.i_plot_styles
,
9152 "three-dimensional", FALSE
)) {
9153 *oo_type
= OO_PLOT_SURFACE
;
9154 return "GogSurfacePlot";
9156 return "GogContourPlot";
9158 case OO_PLOT_BUBBLE
: return "GogBubblePlot"; break;
9159 case OO_PLOT_GANTT
: return "GogDropBarPlot"; break;
9160 case OO_PLOT_POLAR
: return "GogPolarPlot"; break;
9161 case OO_PLOT_XYZ_SURFACE
:
9162 if (oo_style_has_property (state
->chart
.i_plot_styles
,
9163 "three-dimensional", FALSE
))
9164 return "GogXYZSurfacePlot";
9166 return "GogXYZContourPlot";
9168 case OO_PLOT_SURFACE
: return "GogSurfacePlot"; break;
9169 case OO_PLOT_SCATTER_COLOUR
: return "GogXYColorPlot"; break;
9170 case OO_PLOT_XL_SURFACE
: return "XLSurfacePlot"; break;
9171 case OO_PLOT_XL_CONTOUR
: return "XLContourPlot"; break;
9172 case OO_PLOT_BOX
: return "GogBoxPlot"; break;
9173 case OO_PLOT_UNKNOWN
:
9175 return "GogLinePlot";
9176 /* It is simpler to create a plot than to check that we don't have one */
9182 oo_prop_list_has_double (GSList
*props
, double *d
, char const *tag
)
9185 for (ptr
= props
; ptr
; ptr
= ptr
->next
) {
9186 OOProp
*prop
= ptr
->data
;
9187 if (0 == strcmp (prop
->name
, tag
)) {
9188 *d
= g_value_get_double (&prop
->value
);
9196 static GogPlot
*odf_create_plot (OOParseState
*state
, OOPlotType
*oo_type
)
9201 type
= odf_find_plot_type (state
, oo_type
);
9202 plot
= gog_plot_new_by_name (type
);
9204 gog_object_add_by_name (GOG_OBJECT (state
->chart
.chart
),
9205 "Plot", GOG_OBJECT (plot
));
9207 if (state
->chart
.i_plot_styles
[OO_CHART_STYLE_PLOTAREA
] != NULL
)
9208 oo_prop_list_apply (state
->chart
.i_plot_styles
[OO_CHART_STYLE_PLOTAREA
]->
9209 plot_props
, G_OBJECT (plot
));
9211 if (0 == strcmp (type
, "GogPiePlot") || 0 == strcmp (type
, "GogRingPlot")) {
9212 /* Note we cannot use the oo_prop_list_apply method since series also have a */
9213 /* initial-angle property */
9215 if (!((state
->chart
.i_plot_styles
[OO_CHART_STYLE_PLOTAREA
] != NULL
) &&
9216 oo_prop_list_has_double (state
->chart
.i_plot_styles
[OO_CHART_STYLE_PLOTAREA
]->
9217 plot_props
, &angle
, "plot-initial-angle")))
9218 angle
= odf_scale_initial_angle (90);
9219 g_object_set (plot
, "initial-angle", angle
, NULL
);
9226 oo_plot_area (GsfXMLIn
*xin
, xmlChar
const **attrs
)
9228 static OOEnum
const labels
[] = {
9236 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9237 xmlChar
const *source_range_str
= NULL
;
9238 int label_flags
= 0;
9239 GSList
*prop_list
= NULL
;
9240 double x
= go_nan
, y
= go_nan
, width
= go_nan
, height
= go_nan
;
9242 odf_gog_plot_area_check_position (xin
, attrs
, &prop_list
);
9244 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
9245 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
9246 OO_NS_CHART
, "style-name"))
9247 state
->chart
.i_plot_styles
[OO_CHART_STYLE_PLOTAREA
] = g_hash_table_lookup
9248 (state
->chart
.graph_styles
, CXML2C (attrs
[1]));
9249 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "cell-range-address"))
9250 source_range_str
= attrs
[1];
9251 else if (oo_attr_enum (xin
, attrs
, OO_NS_CHART
, "data-source-has-labels", labels
, &label_flags
))
9253 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "x"))
9254 oo_parse_distance (xin
, attrs
[1], "x", &x
);
9255 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "y"))
9256 oo_parse_distance (xin
, attrs
[1], "y", &y
);
9257 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "width"))
9258 oo_parse_distance (xin
, attrs
[1], "width", &width
);
9259 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "height"))
9260 oo_parse_distance (xin
, attrs
[1], "height", &height
);
9262 state
->chart
.src_n_vectors
= -1;
9263 state
->chart
.src_in_rows
= TRUE
;
9264 state
->chart
.src_abscissa_set
= FALSE
;
9265 state
->chart
.src_label_set
= FALSE
;
9266 state
->chart
.series
= NULL
;
9267 state
->chart
.series_count
= 0;
9268 state
->chart
.x_axis_count
= 0;
9269 state
->chart
.y_axis_count
= 0;
9270 state
->chart
.z_axis_count
= 0;
9271 state
->chart
.list
= NULL
;
9272 state
->chart
.named_axes
= g_hash_table_new_full
9273 (g_str_hash
, g_str_equal
,
9274 (GDestroyNotify
) g_free
,
9276 if (NULL
!= source_range_str
) {
9281 char const *ptr
= oo_rangeref_parse
9282 (&ref
, CXML2C (source_range_str
),
9283 parse_pos_init_sheet (&pp
, state
->pos
.sheet
), NULL
);
9284 if (ptr
!= CXML2C (source_range_str
)
9285 && ref
.a
.sheet
!= invalid_sheet
) {
9286 gnm_rangeref_normalize (&ref
,
9287 eval_pos_init_sheet (&ep
, state
->pos
.sheet
),
9288 &state
->chart
.src_sheet
, &dummy
,
9289 &state
->chart
.src_range
);
9291 if (label_flags
& 1)
9292 state
->chart
.src_range
.start
.row
++;
9293 if (label_flags
& 2)
9294 state
->chart
.src_range
.start
.col
++;
9296 if (state
->chart
.i_plot_styles
[OO_CHART_STYLE_PLOTAREA
] != NULL
)
9297 state
->chart
.src_in_rows
= state
->chart
.i_plot_styles
9298 [OO_CHART_STYLE_PLOTAREA
]->src_in_rows
;
9300 if (state
->chart
.src_in_rows
) {
9301 state
->chart
.src_n_vectors
= range_height (&state
->chart
.src_range
);
9302 state
->chart
.src_range
.end
.row
= state
->chart
.src_range
.start
.row
;
9303 if (label_flags
& 1) {
9304 state
->chart
.src_abscissa
= state
->chart
.src_range
;
9305 state
->chart
.src_abscissa
.end
.row
= --state
->chart
.src_abscissa
.start
.row
;
9306 state
->chart
.src_abscissa_set
= TRUE
;
9308 if (label_flags
& 2) {
9309 state
->chart
.src_label
= state
->chart
.src_range
;
9310 state
->chart
.src_label
.end
.col
= --state
->chart
.src_label
.start
.col
;
9311 state
->chart
.src_label
.end
.row
= state
->chart
.src_label
.start
.row
;
9312 state
->chart
.src_label_set
= TRUE
;
9315 state
->chart
.src_n_vectors
= range_width (&state
->chart
.src_range
);
9316 state
->chart
.src_range
.end
.col
= state
->chart
.src_range
.start
.col
;
9317 if (label_flags
& 2) {
9318 state
->chart
.src_abscissa
= state
->chart
.src_range
;
9319 state
->chart
.src_abscissa
.end
.col
= --state
->chart
.src_abscissa
.start
.col
;
9320 state
->chart
.src_abscissa_set
= TRUE
;
9322 if (label_flags
& 1) {
9323 state
->chart
.src_label
= state
->chart
.src_range
;
9324 state
->chart
.src_label
.end
.row
= --state
->chart
.src_label
.start
.row
;
9325 state
->chart
.src_label
.end
.col
= state
->chart
.src_label
.start
.col
;
9326 state
->chart
.src_label_set
= TRUE
;
9332 state
->chart
.plot
= odf_create_plot (state
, &state
->chart
.plot_type
);
9334 if (go_finite (x
) && go_finite (y
) &&
9335 go_finite (width
) && go_finite (height
) &&
9336 go_finite (state
->chart
.width
) && go_finite (state
->chart
.height
)) {
9337 GogViewAllocation alloc
;
9338 alloc
.x
= x
/ state
->chart
.width
;
9339 alloc
.w
= width
/ state
->chart
.width
;
9340 alloc
.y
= y
/ state
->chart
.height
;
9341 alloc
.h
= height
/ state
->chart
.height
;
9343 gog_object_set_position_flags (GOG_OBJECT (state
->chart
.chart
),
9344 GOG_POSITION_MANUAL
, GOG_POSITION_ANY_MANUAL
);
9345 gog_object_set_manual_position (GOG_OBJECT (state
->chart
.chart
), &alloc
);
9346 g_object_set (G_OBJECT (state
->chart
.chart
), "manual-size", "size", NULL
);
9348 state
->chart
.plot_area_x
= x
;
9349 state
->chart
.plot_area_y
= y
;
9350 state
->chart
.plot_area_width
= width
;
9351 state
->chart
.plot_area_height
= height
;
9353 /* Since the plot area has changed we need to fix the legend position */
9354 oo_legend_set_position (state
);
9357 oo_prop_list_apply (prop_list
, G_OBJECT (state
->chart
.chart
));
9358 oo_prop_list_free (prop_list
);
9360 if (state
->chart
.plot_type
== OO_PLOT_GANTT
) {
9361 GogObject
*yaxis
= gog_object_get_child_by_name (GOG_OBJECT (state
->chart
.chart
),
9363 if (yaxis
!= NULL
) {
9364 GValue
*val
= g_value_init (g_new0 (GValue
, 1), G_TYPE_BOOLEAN
);
9365 g_value_set_boolean (val
, TRUE
);
9366 g_object_set_property (G_OBJECT (yaxis
), "invert-axis", val
);
9367 g_value_unset (val
);
9374 odf_create_stock_plot (GsfXMLIn
*xin
)
9376 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9377 GSList
*series_addresses
= state
->chart
.list
;
9378 int len
= g_slist_length (series_addresses
);
9381 series_addresses
= series_addresses
->next
;
9386 state
->chart
.series
= gog_plot_new_series (state
->chart
.plot
);
9387 oo_plot_assign_dim (xin
, series_addresses
->data
, GOG_MS_DIM_LOW
, NULL
, FALSE
);
9390 series_addresses
= series_addresses
->next
;
9391 oo_plot_assign_dim (xin
, series_addresses
->data
, GOG_MS_DIM_HIGH
, NULL
, FALSE
);
9396 oo_plot_area_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
9398 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9399 if (state
->chart
.plot_type
== OO_PLOT_STOCK
) {
9400 odf_create_stock_plot (xin
);
9401 g_slist_free_full (state
->chart
.list
, g_free
);
9402 state
->chart
.list
= NULL
;
9404 if (state
->chart
.series_count
== 0 && state
->chart
.series
== NULL
)
9405 state
->chart
.series
= gog_plot_new_series (state
->chart
.plot
);
9406 if (state
->chart
.series
!= NULL
) {
9407 oo_plot_assign_dim (xin
, NULL
, GOG_MS_DIM_VALUES
, NULL
, FALSE
);
9408 state
->chart
.series
= NULL
;
9411 state
->chart
.plot
= NULL
;
9412 state
->chart
.i_plot_styles
[OO_CHART_STYLE_PLOTAREA
] = NULL
;
9413 g_hash_table_destroy (state
->chart
.named_axes
);
9414 state
->chart
.named_axes
= NULL
;
9419 oo_plot_series (GsfXMLIn
*xin
, xmlChar
const **attrs
)
9421 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9422 xmlChar
const *label
= NULL
;
9423 OOPlotType plot_type
= state
->chart
.plot_type
;
9424 gboolean ignore_type_change
= (state
->chart
.plot_type
== OO_PLOT_SURFACE
||
9425 state
->chart
.plot_type
== OO_PLOT_CONTOUR
||
9426 state
->chart
.plot_type
== OO_PLOT_XL_SURFACE
||
9427 state
->chart
.plot_type
== OO_PLOT_XL_CONTOUR
);
9428 gboolean plot_type_set
= FALSE
;
9431 gchar
const *cell_range_address
= NULL
;
9432 gchar
const *cell_range_expression
= NULL
;
9433 GogObject
*attached_axis
= NULL
;
9434 gboolean general_expression
;
9437 g_print ("<<<<< Start\n");
9439 state
->chart
.plot_type_default
= state
->chart
.plot_type
;
9440 state
->chart
.series_count
++;
9441 state
->chart
.domain_count
= 0;
9442 state
->chart
.data_pt_count
= 0;
9444 /* Now check the attributes */
9445 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
9446 if (oo_attr_enum (xin
, attrs
, OO_NS_CHART
, "class", odf_chart_classes
, &tmp
)) {
9447 if (!ignore_type_change
) {
9448 state
->chart
.plot_type
= plot_type
= tmp
;
9449 plot_type_set
= TRUE
;
9451 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "values-cell-range-address"))
9452 cell_range_address
= CXML2C (attrs
[1]);
9453 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "values-cell-range-expression"))
9454 cell_range_expression
= CXML2C (attrs
[1]);
9455 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "label-cell-address")) {
9458 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "label-cell-expression"))
9460 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
9461 OO_NS_CHART
, "style-name"))
9462 state
->chart
.i_plot_styles
[OO_CHART_STYLE_SERIES
] = g_hash_table_lookup
9463 (state
->chart
.graph_styles
, CXML2C (attrs
[1]));
9464 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
9465 OO_NS_CHART
, "attached-axis"))
9466 attached_axis
= g_hash_table_lookup (state
->chart
.named_axes
, CXML2C (attrs
[1]));
9470 plot
= odf_create_plot (state
, &plot_type
);
9472 plot
= state
->chart
.plot
;
9474 general_expression
= (NULL
!= cell_range_expression
);
9476 if (ignore_type_change
&& !general_expression
&& state
->chart
.series_count
== 1 && NULL
!= cell_range_address
) {
9477 /* We need to check whether this is type 2 of the contour/surface plots. */
9478 GnmExprTop
const *texpr
;
9479 texpr
= odf_parse_range_address_or_expr (xin
, cell_range_address
);
9480 if (NULL
!= texpr
) {
9481 GnmValue
*val
= gnm_expr_top_get_range (texpr
);
9484 gnm_sheet_range_from_value (&r
, val
);
9485 value_release (val
);
9486 if ((range_width (&r
.range
) == 1) || (range_height (&r
.range
) == 1)) {
9487 if (state
->chart
.plot_type
== OO_PLOT_SURFACE
)
9488 plot_type
= state
->chart
.plot_type_default
= state
->chart
.plot_type
9489 = OO_PLOT_XL_SURFACE
;
9491 plot_type
= state
->chart
.plot_type_default
= state
->chart
.plot_type
9492 = OO_PLOT_XL_CONTOUR
;
9493 /* We need to get rid of the original state->chart.plot */
9494 plot
= state
->chart
.plot
;
9495 state
->chart
.plot
= odf_create_plot (state
, &state
->chart
.plot_type
);
9496 gog_object_clear_parent (GOG_OBJECT (plot
));
9497 g_object_unref (G_OBJECT (plot
));
9498 plot
= state
->chart
.plot
;
9499 plot_type_set
= TRUE
;
9502 gnm_expr_top_unref (texpr
);
9506 /* Create the series */
9507 switch (plot_type
) {
9508 case OO_PLOT_STOCK
: /* We need to construct the series later. */
9510 case OO_PLOT_SURFACE
:
9511 case OO_PLOT_CONTOUR
:
9512 if (state
->chart
.series
== NULL
)
9513 state
->chart
.series
= gog_plot_new_series (plot
);
9515 case OO_PLOT_XL_SURFACE
:
9516 case OO_PLOT_XL_CONTOUR
:
9517 /* if (state->chart.series == NULL) */
9518 state
->chart
.series
= gog_plot_new_series (plot
);
9521 if (state
->chart
.series
== NULL
) {
9522 state
->chart
.series
= gog_plot_new_series (plot
);
9523 /* In ODF by default we skip invalid data for interpolation */
9524 g_object_set (state
->chart
.series
, "interpolation-skip-invalid", TRUE
, NULL
);
9525 if (state
->chart
.cat_expr
!= NULL
) {
9527 (xin
, state
->chart
.cat_expr
,
9528 GOG_MS_DIM_CATEGORIES
, NULL
, FALSE
);
9533 if (NULL
!= attached_axis
&& NULL
!= plot
)
9534 gog_plot_set_axis (plot
, GOG_AXIS (attached_axis
));
9536 if (general_expression
)
9537 cell_range_address
= cell_range_expression
;
9539 if (NULL
!= cell_range_address
) {
9540 switch (plot_type
) {
9542 state
->chart
.list
= g_slist_append (state
->chart
.list
,
9543 g_strdup (cell_range_address
));
9545 case OO_PLOT_SURFACE
:
9546 case OO_PLOT_CONTOUR
:
9548 GnmExprTop
const *texpr
;
9549 texpr
= odf_parse_range_address_or_expr (xin
, cell_range_address
);
9551 gog_series_set_dim (state
->chart
.series
, 2,
9552 gnm_go_data_matrix_new_expr
9553 (state
->pos
.sheet
, texpr
), NULL
);
9556 case OO_PLOT_XL_SURFACE
:
9557 case OO_PLOT_XL_CONTOUR
:
9559 GnmExprTop
const *texpr
;
9560 texpr
= odf_parse_range_address_or_expr (xin
, cell_range_address
);
9562 gog_series_set_XL_dim (state
->chart
.series
,
9564 gnm_go_data_vector_new_expr (state
->pos
.sheet
, texpr
),
9569 oo_plot_assign_dim (xin
, cell_range_address
,
9570 (state
->chart
.series_count
% 2 == 1) ? GOG_MS_DIM_START
: GOG_MS_DIM_END
,
9571 NULL
, general_expression
);
9573 case OO_PLOT_BUBBLE
:
9574 oo_plot_assign_dim (xin
, cell_range_address
, GOG_MS_DIM_BUBBLES
, NULL
, general_expression
);
9576 case OO_PLOT_SCATTER_COLOUR
:
9577 oo_plot_assign_dim (xin
, cell_range_address
, GOG_MS_DIM_EXTRA1
, NULL
, general_expression
);
9580 oo_plot_assign_dim (xin
, cell_range_address
, GOG_MS_DIM_VALUES
, NULL
, general_expression
);
9586 if (label
!= NULL
) {
9587 GnmExprTop
const *texpr
= odf_parse_range_address_or_expr (xin
, label
);
9589 gog_series_set_name (state
->chart
.series
,
9590 GO_DATA_SCALAR (gnm_go_data_scalar_new_expr
9591 (state
->pos
.sheet
, texpr
)),
9594 if (plot_type_set
&& state
->chart
.i_plot_styles
[OO_CHART_STYLE_SERIES
] != NULL
)
9595 oo_prop_list_apply (state
->chart
.i_plot_styles
[OO_CHART_STYLE_SERIES
]->
9596 plot_props
, G_OBJECT (plot
));
9597 oo_chart_style_to_series (xin
, state
->chart
.i_plot_styles
[OO_CHART_STYLE_PLOTAREA
],
9598 G_OBJECT (state
->chart
.series
));
9599 oo_chart_style_to_series (xin
, state
->chart
.i_plot_styles
[OO_CHART_STYLE_SERIES
],
9600 G_OBJECT (state
->chart
.series
));
9604 oo_plot_series_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
9606 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9608 switch (state
->chart
.plot_type
) {
9610 case OO_PLOT_CONTOUR
:
9613 if ((state
->chart
.series_count
% 2) != 0)
9617 oo_plot_assign_dim (xin
, NULL
, GOG_MS_DIM_VALUES
, NULL
, FALSE
);
9618 state
->chart
.series
= NULL
;
9621 state
->chart
.plot_type
= state
->chart
.plot_type_default
;
9622 state
->chart
.i_plot_styles
[OO_CHART_STYLE_SERIES
] = NULL
;
9624 g_print (">>>>> end\n");
9628 oo_series_domain (GsfXMLIn
*xin
, xmlChar
const **attrs
)
9630 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9631 xmlChar
const *src
= NULL
;
9632 xmlChar
const *cell_range_expression
= NULL
;
9633 int dim
= GOG_MS_DIM_VALUES
;
9634 char const *name
= NULL
;
9636 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
9637 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "cell-range-address"))
9639 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "cell-range-expression"))
9640 cell_range_expression
= attrs
[1];
9642 switch (state
->chart
.plot_type
) {
9643 case OO_PLOT_BUBBLE
:
9644 case OO_PLOT_SCATTER_COLOUR
:
9645 dim
= (state
->chart
.domain_count
== 0) ? GOG_MS_DIM_VALUES
: GOG_MS_DIM_CATEGORIES
;
9647 case OO_PLOT_XYZ_SURFACE
:
9648 case OO_PLOT_SURFACE
:
9649 name
= (state
->chart
.domain_count
== 0) ? "Y" : "X";
9651 case OO_PLOT_CONTOUR
:
9652 /* y-values first, then x-values */
9653 dim
= (state
->chart
.domain_count
== 0) ? GOG_MS_DIM_CATEGORIES
: -1;
9656 dim
= GOG_MS_DIM_CATEGORIES
;
9659 oo_plot_assign_dim (xin
, (cell_range_expression
!= NULL
) ? cell_range_expression
: src
, dim
, name
,
9660 cell_range_expression
!= NULL
);
9661 state
->chart
.domain_count
++;
9665 oo_series_pt (GsfXMLIn
*xin
, xmlChar
const **attrs
)
9667 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9668 char const *style_name
= NULL
;
9669 guint repeat_count
= 1;
9670 OOChartStyle
*style
= NULL
;
9672 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
9673 if (oo_attr_int_range (xin
, attrs
, OO_NS_CHART
, "repeated", &repeat_count
, 0, INT_MAX
))
9675 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "style-name")) {
9676 style_name
= attrs
[1];
9678 if (repeat_count
== 0)
9679 return; /* Why does ODF allow repeat counts of 0 ??*/
9681 if (style_name
!= NULL
&&
9682 NULL
!= (style
= g_hash_table_lookup (state
->chart
.graph_styles
, style_name
))) {
9683 guint index
= state
->chart
.data_pt_count
;
9684 state
->chart
.data_pt_count
+= repeat_count
;
9685 for (; index
< state
->chart
.data_pt_count
; index
++) {
9686 GogObject
*element
= gog_object_add_by_name (GOG_OBJECT (state
->chart
.series
), "Point", NULL
);
9687 if (element
!= NULL
) {
9689 g_object_set (G_OBJECT (element
), "index", index
, NULL
);
9690 oo_prop_list_apply (style
->plot_props
, G_OBJECT (element
));
9691 g_object_get (G_OBJECT (element
), "style", &gostyle
, NULL
);
9692 if (gostyle
!= NULL
) {
9693 GOStyle
*nstyle
= go_style_dup (gostyle
);
9694 OOChartStyle
*astyle
= state
->chart
.i_plot_styles
[OO_CHART_STYLE_PLOTAREA
];
9696 odf_apply_style_props
9697 (xin
, astyle
->style_props
, nstyle
, TRUE
);
9698 astyle
= state
->chart
.i_plot_styles
[OO_CHART_STYLE_SERIES
];
9700 odf_apply_style_props
9701 (xin
, astyle
->style_props
, nstyle
, TRUE
);
9702 odf_apply_style_props (xin
, style
->style_props
, nstyle
, TRUE
);
9703 g_object_set (element
, "style", nstyle
, NULL
);
9704 g_object_unref (gostyle
);
9705 g_object_unref (nstyle
);
9710 state
->chart
.data_pt_count
+= repeat_count
;
9714 od_series_reg_equation (GsfXMLIn
*xin
, xmlChar
const **attrs
)
9716 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9717 char const *style_name
= NULL
;
9718 GogObject
*equation
;
9719 gboolean automatic_content
= TRUE
;
9720 gboolean dispay_equation
= TRUE
;
9721 gboolean display_r_square
= TRUE
;
9722 GSList
*prop_list
= NULL
;
9724 g_return_if_fail (state
->chart
.regression
!= NULL
);
9726 odf_gog_check_position (xin
, attrs
, &prop_list
);
9728 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
9729 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "style-name"))
9730 style_name
= CXML2C (attrs
[1]);
9731 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "automatic-content",
9732 &automatic_content
));
9733 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "automatic-content",
9734 &automatic_content
));
9735 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "display-equation",
9737 else if (oo_attr_bool (xin
, attrs
, OO_GNUM_NS_EXT
, "display-equation",
9739 else if (oo_attr_bool (xin
, attrs
, OO_NS_CHART
, "display-r-square",
9740 &display_r_square
));
9743 equation
= gog_object_add_by_name (GOG_OBJECT (state
->chart
.regression
),
9746 g_object_set (G_OBJECT (equation
),
9747 "show-eq", dispay_equation
,
9748 "show-r2", display_r_square
,
9751 oo_prop_list_apply (prop_list
, G_OBJECT (equation
));
9752 oo_prop_list_free (prop_list
);
9754 if (!automatic_content
)
9755 oo_warning (xin
, _("Gnumeric does not support non-automatic"
9756 " regression equations. Using automatic"
9757 " equation instead."));
9759 if (style_name
!= NULL
) {
9760 OOChartStyle
*chart_style
= g_hash_table_lookup
9761 (state
->chart
.graph_styles
, style_name
);
9764 go_styled_object_get_style (GO_STYLED_OBJECT (equation
));
9765 if (style
!= NULL
) {
9766 style
= go_style_dup (style
);
9767 odf_apply_style_props (xin
, chart_style
->style_props
, style
, TRUE
);
9768 go_styled_object_set_style (GO_STYLED_OBJECT (equation
), style
);
9769 g_object_unref (style
);
9771 /* In the moment we don't need this. */
9772 /* oo_prop_list_apply (chart_style->plot_props, G_OBJECT (equation)); */
9774 oo_warning (xin
, _("The chart style \"%s\" is not defined!"), style_name
);
9779 odf_store_data (OOParseState
*state
, gchar
const *str
, GogObject
*obj
, int dim
)
9784 char const *ptr
= oo_rangeref_parse
9785 (&ref
, CXML2C (str
),
9786 parse_pos_init (&pp
, state
->pos
.wb
, NULL
, 0, 0),
9788 if (ptr
!= CXML2C (str
) && ref
.a
.sheet
!= invalid_sheet
) {
9789 GnmValue
*v
= value_new_cellrange (&ref
.a
, &ref
.b
, 0, 0);
9790 GnmExprTop
const *texpr
= gnm_expr_top_new_constant (v
);
9791 if (NULL
!= texpr
) {
9792 gog_dataset_set_dim (GOG_DATASET (obj
), dim
,
9793 gnm_go_data_scalar_new_expr
9794 (state
->pos
.sheet
, texpr
),
9802 od_series_regression (GsfXMLIn
*xin
, xmlChar
const **attrs
)
9804 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9805 char const *style_name
= NULL
;
9806 gchar
const *lower_bd
= NULL
;
9807 gchar
const *upper_bd
= NULL
;
9809 state
->chart
.regression
= NULL
;
9811 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
9812 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "style-name"))
9813 style_name
= CXML2C (attrs
[1]);
9814 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "lower-bound"))
9815 lower_bd
= CXML2C (attrs
[1]);
9816 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_GNUM_NS_EXT
, "upper-bound"))
9817 upper_bd
= CXML2C (attrs
[1]);
9819 if (style_name
!= NULL
) {
9820 OOChartStyle
*chart_style
= g_hash_table_lookup
9821 (state
->chart
.graph_styles
, style_name
);
9825 GOStyle
*style
= NULL
;
9826 GogObject
*regression
;
9827 gchar
const *type_name
= "GogLinRegCurve";
9828 gchar
const *regression_name
= NULL
;
9829 gchar
const *regression_name_c
= NULL
;
9830 gboolean write_lo_dims
= FALSE
;
9831 GValue
*lo_dim
= NULL
;
9832 for (l
= chart_style
->other_props
; l
!= NULL
; l
= l
->next
) {
9833 OOProp
*prop
= l
->data
;
9834 if (0 == strcmp ("regression-type", prop
->name
)) {
9835 char const *reg_type
= g_value_get_string (&prop
->value
);
9836 if (0 == strcmp (reg_type
, "linear"))
9837 type_name
= "GogLinRegCurve";
9838 else if (0 == strcmp (reg_type
, "power"))
9839 type_name
= "GogPowerRegCurve";
9840 else if (0 == strcmp (reg_type
, "exponential"))
9841 type_name
= "GogExpRegCurve";
9842 else if (0 == strcmp (reg_type
, "logarithmic"))
9843 type_name
= "GogLogRegCurve";
9844 else if (0 == strcmp
9845 (reg_type
, "gnm:exponential-smoothed"))
9846 type_name
= "GogExpSmooth";
9847 else if (0 == strcmp
9848 (reg_type
, "gnm:logfit"))
9849 type_name
= "GogLogFitCurve";
9850 else if (0 == strcmp
9851 (reg_type
, "gnm:polynomial")) {
9852 type_name
= "GogPolynomRegCurve";
9853 write_lo_dims
= TRUE
;
9854 } else if (0 == strcmp
9855 (reg_type
, "gnm:moving-average"))
9856 type_name
= "GogMovingAvg";
9857 } else if (0 == strcmp ("regression-name-expression", prop
->name
)) {
9858 regression_name
= g_value_get_string (&prop
->value
);
9859 } else if (0 == strcmp ("regression-name-constant", prop
->name
)) {
9860 regression_name_c
= g_value_get_string (&prop
->value
);
9861 } else if (0 == strcmp ("lo-dims", prop
->name
)) {
9862 lo_dim
= &prop
->value
;
9866 state
->chart
.regression
= regression
=
9867 GOG_OBJECT (gog_trend_line_new_by_name (type_name
));
9868 regression
= gog_object_add_by_name (GOG_OBJECT (state
->chart
.series
),
9869 "Trend line", regression
);
9870 if (write_lo_dims
&& lo_dim
!= NULL
)
9871 g_object_set_property ( G_OBJECT (regression
), "dims", lo_dim
);
9872 oo_prop_list_apply (chart_style
->other_props
, G_OBJECT (regression
));
9874 style
= go_styled_object_get_style (GO_STYLED_OBJECT (regression
));
9875 if (style
!= NULL
) {
9876 style
= go_style_dup (style
);
9877 odf_apply_style_props (xin
, chart_style
->style_props
, style
, TRUE
);
9878 go_styled_object_set_style (GO_STYLED_OBJECT (regression
), style
);
9879 g_object_unref (style
);
9882 if (regression_name
!= NULL
) {
9885 GnmExprTop
const *expr
;
9886 parse_pos_init (&pp
, state
->pos
.wb
, state
->pos
.sheet
, 0, 0);
9887 expr
= oo_expr_parse_str
9888 (xin
, regression_name
, &pp
,
9889 GNM_EXPR_PARSE_FORCE_EXPLICIT_SHEET_REFERENCES
,
9890 FORMULA_OPENFORMULA
);
9892 data
= gnm_go_data_scalar_new_expr (state
->pos
.sheet
, expr
);
9893 gog_dataset_set_dim (GOG_DATASET (regression
), -1, data
, NULL
);
9895 } else if (regression_name_c
!= NULL
) {
9897 data
= gnm_go_data_scalar_new_expr
9898 (state
->pos
.sheet
, gnm_expr_top_new_constant
9899 (value_new_string (regression_name_c
)));
9900 gog_dataset_set_dim (GOG_DATASET (regression
), -1, data
, NULL
);
9903 odf_store_data (state
, lower_bd
, regression
, 0);
9904 odf_store_data (state
, upper_bd
, regression
, 1);
9911 oo_series_droplines (GsfXMLIn
*xin
, xmlChar
const **attrs
)
9913 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9914 char const *style_name
= NULL
;
9915 gboolean vertical
= TRUE
;
9916 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
9917 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "style-name"))
9918 style_name
= CXML2C (attrs
[1]);
9919 if (style_name
!= NULL
) {
9920 OOChartStyle
*chart_style
= g_hash_table_lookup
9921 (state
->chart
.graph_styles
, style_name
);
9923 GOStyle
*style
= NULL
;
9925 char const *role_name
= NULL
;
9926 GogObject
const *lines
;
9928 for (l
= chart_style
->plot_props
; l
!= NULL
; l
= l
->next
) {
9929 OOProp
*prop
= l
->data
;
9930 if (0 == strcmp ("vertical", prop
->name
))
9931 vertical
= g_value_get_boolean (&prop
->value
);
9934 switch (state
->chart
.plot_type
) {
9936 role_name
= "Drop lines";
9938 case OO_PLOT_SCATTER
:
9939 role_name
= vertical
? "Vertical drop lines" : "Horizontal drop lines";
9942 oo_warning (xin
, _("Encountered drop lines in a plot not supporting them."));
9946 lines
= gog_object_add_by_name (GOG_OBJECT (state
->chart
.series
), role_name
, NULL
);
9948 style
= go_styled_object_get_style (GO_STYLED_OBJECT (lines
));
9949 if (style
!= NULL
) {
9950 style
= go_style_dup (style
);
9951 odf_apply_style_props (xin
, chart_style
->style_props
, style
, TRUE
);
9952 go_styled_object_set_style (GO_STYLED_OBJECT (lines
), style
);
9953 g_object_unref (style
);
9960 oo_series_serieslines (GsfXMLIn
*xin
, xmlChar
const **attrs
)
9962 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9963 char const *style_name
= NULL
;
9964 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
9965 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "style-name"))
9966 style_name
= CXML2C (attrs
[1]);
9967 if (style_name
!= NULL
) {
9968 OOChartStyle
*chart_style
= g_hash_table_lookup (state
->chart
.graph_styles
, style_name
);
9970 GogObject
const *lines
;
9972 lines
= gog_object_add_by_name (GOG_OBJECT (state
->chart
.series
), "Series lines", NULL
);
9973 style
= go_styled_object_get_style (GO_STYLED_OBJECT (lines
));
9974 if (chart_style
&& style
) {
9975 style
= go_style_dup (style
);
9976 odf_apply_style_props (xin
, chart_style
->style_props
, style
, TRUE
);
9977 go_styled_object_set_style (GO_STYLED_OBJECT (lines
), style
);
9978 g_object_unref (style
);
9984 oo_chart_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
9986 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
9988 g_free (state
->chart
.cat_expr
);
9989 state
->chart
.cat_expr
= NULL
;
9991 state
->chart
.legend
= NULL
;
9995 odf_chart_set_default_style (GogObject
*chart
)
9999 style
= go_styled_object_get_style (GO_STYLED_OBJECT (chart
));
10001 style
->line
.width
= -1.0;
10002 style
->line
.dash_type
= GO_LINE_NONE
;
10004 go_styled_object_style_changed (GO_STYLED_OBJECT (chart
));
10008 oo_chart (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10010 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10012 OOPlotType type
= OO_PLOT_UNKNOWN
;
10013 OOChartStyle
*style
= NULL
;
10015 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
10016 if (oo_attr_enum (xin
, attrs
, OO_NS_CHART
, "class", odf_chart_classes
, &tmp
))
10018 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10019 OO_NS_CHART
, "style-name"))
10020 style
= g_hash_table_lookup
10021 (state
->chart
.graph_styles
, CXML2C (attrs
[1]));
10022 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10023 OO_GNUM_NS_EXT
, "theme-name")) {
10024 GValue
*val
= g_value_init (g_new0 (GValue
, 1), G_TYPE_STRING
);
10025 g_value_set_string (val
, CXML2C (attrs
[0]));
10026 g_object_set_property (G_OBJECT (state
->chart
.graph
), "theme-name", val
);
10027 g_value_unset (val
);
10031 state
->chart
.plot_type
= type
;
10032 state
->chart
.chart
= GOG_CHART (gog_object_add_by_name (
10033 GOG_OBJECT (state
->chart
.graph
), "Chart", NULL
));
10034 odf_chart_set_default_style (GOG_OBJECT (state
->chart
.chart
));
10035 state
->chart
.plot
= NULL
;
10036 state
->chart
.series
= NULL
;
10037 state
->chart
.axis
= NULL
;
10038 state
->chart
.legend
= NULL
;
10039 state
->chart
.cat_expr
= NULL
;
10040 if (NULL
!= style
) {
10042 state
->chart
.src_in_rows
= style
->src_in_rows
;
10043 for (ptr
= style
->other_props
; ptr
; ptr
= ptr
->next
) {
10044 OOProp
*prop
= ptr
->data
;
10045 if (0 == strcmp (prop
->name
, "border")) {
10046 gnm_float pts
= 0.;
10047 const char *border
= g_value_get_string (&prop
->value
);
10050 while (*border
== ' ')
10052 end
= oo_parse_spec_distance (border
, &pts
);
10054 if (end
== GINT_TO_POINTER(1) || end
== NULL
) {
10055 if (0 == strncmp (border
, "thin", 4)) {
10058 } else if (0 == strncmp (border
, "medium", 6)) {
10061 } else if (0 == strncmp (border
, "thick", 5)) {
10067 if (end
!= GINT_TO_POINTER(1) && end
!= NULL
&& end
> border
) {
10068 /* pts should be valid */
10069 GOStyle
*go_style
= go_styled_object_get_style (GO_STYLED_OBJECT (state
->chart
.chart
));
10070 go_style
->line
.width
= pts
;
10071 go_style
->line
.dash_type
= GO_LINE_SOLID
;
10072 go_styled_object_style_changed (GO_STYLED_OBJECT (state
->chart
.chart
));
10078 if (type
== OO_PLOT_UNKNOWN
)
10079 oo_warning (xin
, _("Encountered an unknown chart type, "
10080 "trying to create a line plot."));
10084 oo_color_scale (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
10086 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10087 gog_object_add_by_name ((GogObject
*)state
->chart
.chart
, "Color-Scale", NULL
);
10091 oo_legend (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10093 static OOEnum
const positions
[] = {
10094 { "top", GOG_POSITION_N
},
10095 { "bottom", GOG_POSITION_S
},
10096 { "start", GOG_POSITION_W
},
10097 { "end", GOG_POSITION_E
},
10098 { "top-start", GOG_POSITION_N
| GOG_POSITION_W
},
10099 { "bottom-start", GOG_POSITION_S
| GOG_POSITION_W
},
10100 { "top-end", GOG_POSITION_N
| GOG_POSITION_E
},
10101 { "bottom-end", GOG_POSITION_S
| GOG_POSITION_E
},
10104 static OOEnum
const alignments
[] = {
10105 { "start", GOG_POSITION_ALIGN_START
},
10106 { "center", GOG_POSITION_ALIGN_CENTER
},
10107 { "end", GOG_POSITION_ALIGN_END
},
10110 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10111 GogObjectPosition pos
= GOG_POSITION_W
| GOG_POSITION_ALIGN_CENTER
;
10112 GogObjectPosition align
= GOG_POSITION_ALIGN_CENTER
;
10115 char const *style_name
= NULL
;
10116 double x
= go_nan
, y
= go_nan
;
10118 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
10119 if (oo_attr_enum (xin
, attrs
, OO_NS_CHART
, "legend-position", positions
, &tmp
))
10121 else if (oo_attr_enum (xin
, attrs
, OO_NS_CHART
, "legend-align", alignments
, &tmp
))
10123 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "style-name"))
10124 style_name
= CXML2C (attrs
[1]);
10125 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "x"))
10126 oo_parse_distance (xin
, attrs
[1], "x", &x
);
10127 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_SVG
, "y"))
10128 oo_parse_distance (xin
, attrs
[1], "y", &y
);
10130 legend
= gog_object_add_by_name ((GogObject
*)state
->chart
.chart
, "Legend", NULL
);
10131 state
->chart
.legend
= legend
;
10132 if (legend
!= NULL
) {
10133 GOStyle
*style
= go_styled_object_get_style (GO_STYLED_OBJECT (legend
));
10134 if (style_name
&& style
) {
10135 OOChartStyle
*chart_style
= g_hash_table_lookup
10136 (state
->chart
.graph_styles
, style_name
);
10137 style
= go_style_dup (style
);
10139 odf_apply_style_props (xin
, chart_style
->style_props
, style
, TRUE
);
10141 oo_warning (xin
, _("Chart style with name '%s' is missing."),
10143 go_styled_object_set_style (GO_STYLED_OBJECT (legend
), style
);
10144 g_object_unref (style
);
10146 state
->chart
.legend_x
= x
;
10147 state
->chart
.legend_y
= y
;
10148 state
->chart
.legend_flag
= pos
| align
;
10150 /* We will need to redo this if we encounter a plot-area specification later */
10151 oo_legend_set_position (state
);
10156 oo_chart_grid (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10158 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10159 gchar
const *style_name
= NULL
;
10160 GogObject
*grid
= NULL
;
10162 if (state
->chart
.axis
== NULL
)
10164 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
10165 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "class")) {
10166 if (attr_eq (attrs
[1], "major"))
10167 grid
= gog_object_add_by_name (state
->chart
.axis
, "MajorGrid", NULL
);
10168 else if (attr_eq (attrs
[1], "minor"))
10169 grid
= gog_object_add_by_name (state
->chart
.axis
, "MinorGrid", NULL
);
10170 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "style-name"))
10171 style_name
= CXML2C (attrs
[1]);
10173 if (grid
!= NULL
&& style_name
!= NULL
) {
10174 GOStyle
*style
= go_styled_object_get_style (GO_STYLED_OBJECT (grid
));
10176 OOChartStyle
*chart_style
= g_hash_table_lookup
10177 (state
->chart
.graph_styles
, style_name
);
10178 style
= go_style_dup (style
);
10180 odf_apply_style_props (xin
, chart_style
->style_props
, style
, TRUE
);
10182 oo_warning (xin
, _("Chart style with name '%s' is missing."),
10184 go_styled_object_set_style (GO_STYLED_OBJECT (grid
), style
);
10185 g_object_unref (style
);
10191 oo_chart_wall (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10193 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10194 GogObject
*backplane
;
10195 gchar
const *style_name
= NULL
;
10197 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
10198 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "style-name"))
10199 style_name
= CXML2C (attrs
[1]);
10201 backplane
= gog_object_add_by_name (GOG_OBJECT (state
->chart
.chart
), "Backplane", NULL
);
10203 if (style_name
!= NULL
&& backplane
!= NULL
) {
10204 GOStyle
*style
= go_styled_object_get_style (GO_STYLED_OBJECT (backplane
));
10205 if (style
!= NULL
) {
10206 OOChartStyle
*chart_style
= g_hash_table_lookup
10207 (state
->chart
.graph_styles
, style_name
);
10208 style
= go_style_dup (style
);
10210 odf_apply_style_props (xin
, chart_style
->style_props
, style
, TRUE
);
10212 oo_warning (xin
, _("Chart style with name '%s' is missing."),
10214 go_styled_object_set_style (GO_STYLED_OBJECT (backplane
), style
);
10215 g_object_unref (style
);
10221 oo_chart_axisline (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10223 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10224 gchar
const *style_name
= NULL
;
10225 GogObject
*axisline
;
10227 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
10228 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CHART
, "style-name"))
10229 style_name
= CXML2C (attrs
[1]);
10231 axisline
= gog_object_add_by_name (GOG_OBJECT (state
->chart
.axis
), "AxisLine", NULL
);
10233 if (style_name
!= NULL
&& axisline
!= NULL
) {
10234 GOStyle
*style
= go_styled_object_get_style (GO_STYLED_OBJECT (axisline
));
10235 if (style
!= NULL
) {
10236 OOChartStyle
*chart_style
= g_hash_table_lookup
10237 (state
->chart
.graph_styles
, style_name
);
10238 style
= go_style_dup (style
);
10240 oo_prop_list_apply_to_axisline (xin
, chart_style
->axis_props
,
10241 G_OBJECT (axisline
));
10242 odf_apply_style_props (xin
, chart_style
->style_props
, style
, TRUE
);
10244 oo_warning (xin
, _("Chart style with name '%s' is missing."),
10246 go_styled_object_set_style (GO_STYLED_OBJECT (axisline
), style
);
10247 g_object_unref (style
);
10253 oo_chart_style_free (OOChartStyle
*cstyle
)
10255 if (cstyle
== NULL
)
10257 oo_prop_list_free (cstyle
->axis_props
);
10258 oo_prop_list_free (cstyle
->style_props
);
10259 oo_prop_list_free (cstyle
->plot_props
);
10260 oo_prop_list_free (cstyle
->other_props
);
10261 go_format_unref (cstyle
->fmt
);
10266 oo_control_free (OOControl
*ctrl
)
10268 g_free (ctrl
->value
);
10269 g_free (ctrl
->value_type
);
10270 g_free (ctrl
->label
);
10271 g_free (ctrl
->current_state
);
10272 g_free (ctrl
->linked_cell
);
10273 g_free (ctrl
->implementation
);
10274 g_free (ctrl
->source_cell_range
);
10279 oo_marker_free (OOMarker
*m
)
10281 g_free (m
->view_box
);
10288 odf_annotation_start (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
10290 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10292 state
->cell_comment
= cell_set_comment (state
->pos
.sheet
, &state
->pos
.eval
,
10294 odf_push_text_p (state
, FALSE
);
10298 odf_annotation_author_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
10300 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10302 cell_comment_author_set (state
->cell_comment
, xin
->content
->str
);
10306 odf_annotation_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
10308 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10311 if (state
->text_p_stack
!= NULL
&& (NULL
!= (ptr
= state
->text_p_stack
->data
)))
10312 g_object_set (G_OBJECT (state
->cell_comment
),
10313 "text", ptr
->gstr
? ptr
->gstr
->str
: "",
10314 "markup", ptr
->attrs
, NULL
);
10315 state
->cell_comment
= NULL
;
10316 odf_pop_text_p (state
);
10319 /****************************************************************************/
10320 /******************************** graphic sheet objects *********************/
10323 odf_so_filled (GsfXMLIn
*xin
, xmlChar
const **attrs
, gboolean is_oval
)
10325 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10326 char const *style_name
= NULL
;
10329 od_draw_frame_start (xin
, attrs
);
10330 state
->chart
.so
= g_object_new (GNM_SO_FILLED_TYPE
,
10331 "is-oval", is_oval
, NULL
);
10332 g_object_get (state
->chart
.so
, "style", &style0
, NULL
);
10333 if (style0
!= NULL
) {
10334 GOStyle
*style
= go_style_dup (style0
);
10335 if (state
->default_style
.graphics
)
10336 odf_apply_style_props
10337 (xin
, state
->default_style
.graphics
->style_props
,
10340 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
10341 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10342 OO_NS_DRAW
, "style-name"))
10343 style_name
= CXML2C (attrs
[1]);
10344 if (style_name
!= NULL
) {
10345 OOChartStyle
*oostyle
= g_hash_table_lookup
10346 (state
->chart
.graph_styles
, style_name
);
10347 if (oostyle
!= NULL
)
10348 odf_apply_style_props (xin
, oostyle
->style_props
,
10351 g_object_set (state
->chart
.so
, "style", style
, NULL
);
10352 g_object_unref (style
);
10353 g_object_unref (style0
);
10358 odf_caption (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10360 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10362 oo_warning (xin
, _("An unsupported caption was encountered and "
10363 "converted to a text rectangle."));
10364 odf_so_filled (xin
, attrs
, FALSE
);
10365 odf_push_text_p (state
, FALSE
);
10369 odf_rect (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10371 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10373 odf_so_filled (xin
, attrs
, FALSE
);
10374 odf_push_text_p (state
, FALSE
);
10378 odf_ellipse (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10380 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10382 odf_so_filled (xin
, attrs
, TRUE
);
10383 odf_push_text_p (state
, FALSE
);
10387 odf_custom_shape_replace_object (OOParseState
*state
, SheetObject
*so
)
10389 GObjectClass
*klass
= G_OBJECT_GET_CLASS (G_OBJECT (so
));
10391 if (NULL
!= g_object_class_find_property (klass
, "text")) {
10393 g_object_get (state
->chart
.so
, "text", &text
, NULL
);
10394 g_object_set (so
, "text", text
, NULL
);
10397 if (NULL
!= g_object_class_find_property (klass
, "style")) {
10398 GOStyle
*style
= NULL
;
10399 g_object_get (state
->chart
.so
, "style", &style
, NULL
);
10400 g_object_set (so
, "style", style
, NULL
);
10401 g_object_unref (style
);
10403 if (NULL
!= g_object_class_find_property (klass
, "markup")) {
10404 PangoAttrList
*attrs
= NULL
;
10405 g_object_get (state
->chart
.so
, "markup", &attrs
, NULL
);
10406 g_object_set (so
, "markup", attrs
, NULL
);
10407 pango_attr_list_unref (attrs
);
10409 g_object_unref (state
->chart
.so
);
10410 state
->chart
.so
= so
;
10414 odf_get_cs_formula_value (GsfXMLIn
*xin
, char const *key
, GHashTable
*vals
, gint level
)
10416 double *x
= g_hash_table_lookup (vals
, key
);
10417 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10418 gchar
*formula
, *o_formula
;
10420 GnmConventions
const *convs
= gnm_conventions_default
;
10421 GnmExprTop
const *texpr
;
10422 GnmLocale
*oldlocale
= NULL
;
10423 double x_ret
= level
;
10424 double viewbox_left
= 0.;
10425 double viewbox_top
= 0.;
10426 double viewbox_width
= 0.;
10427 double viewbox_height
= 0.;
10432 o_formula
= formula
= g_hash_table_lookup (state
->chart
.cs_variables
, key
);
10435 oo_warning (xin
, _("Infinite loop encountered while parsing formula '%s' "
10441 g_return_val_if_fail (formula
!= NULL
, level
);
10443 if (state
->chart
.cs_viewbox
) {
10446 In ODF 1.2 part 1 19.570 svg:viewBox we have:
10447 "The syntax for using this attribute is the same as the [SVG] syntax.
10448 The value of the attribute are four numbers separated by white spaces,
10449 which define the left, top, right, and bottom dimensions of the user
10450 coordinate system."
10451 but [SVG] specifies:
10452 "The value of the viewBox attribute is a list of four numbers <min-x>,
10453 <min-y>, <width> and <height>"
10454 Since so far we have only seen cases with left == top == 0, We don't know which
10455 version is really used. We are implementing the [SVG] version.
10458 viewbox_left
= go_strtod (state
->chart
.cs_viewbox
, &end
);
10459 viewbox_top
= go_strtod (end
, &end
);
10460 viewbox_width
= go_strtod (end
, &end
);
10461 viewbox_height
= go_strtod (end
, &end
);
10464 gstr
= g_string_new ("");
10466 while (*formula
!= 0) {
10471 switch (*formula
) {
10477 here
= formula
+ 1;
10478 /* ODF 1.2 is quite clear that:
10479 --------------------------
10480 function_reference::= "?" name
10481 name::= [^#x20#x9]+
10482 --------------------------
10483 so we should grab all non-space, non-tab characters
10484 as a function_reference name.
10486 The problem is that LO creates files in which these
10487 function reference are not terminated by space or tab!
10489 So if we want to read them correctly we should only use
10493 /* while (*here != ' ' && *here != '\t') */
10496 while (g_ascii_isalnum (*here
))
10499 name
= g_strndup (formula
, here
- formula
);
10501 fval
= odf_get_cs_formula_value (xin
, name
, vals
, level
- 1);
10502 g_string_append_printf (gstr
, "%.12" GNM_FORMAT_g
, fval
);
10506 here
= formula
+ 1;
10507 while (g_ascii_isdigit (*here
))
10509 name
= g_strndup (formula
, here
- formula
);
10511 val
= g_hash_table_lookup (vals
, name
);
10514 g_string_append_c (gstr
, '0');
10516 g_string_append_printf (gstr
, "%.12" GNM_FORMAT_g
, *val
);
10519 if (g_str_has_prefix (formula
, "pi")) {
10521 g_string_append (gstr
, "pi()");
10523 g_string_append_c (gstr
, *formula
);
10528 if (g_str_has_prefix (formula
, "top")) {
10530 g_string_append_printf (gstr
, "%.12" GNM_FORMAT_g
, viewbox_top
);
10532 g_string_append_c (gstr
, *formula
);
10537 if (g_str_has_prefix (formula
, "bottom")) {
10539 g_string_append_printf (gstr
, "%.12" GNM_FORMAT_g
,
10540 viewbox_top
+ viewbox_height
);
10542 g_string_append_c (gstr
, *formula
);
10547 if (g_str_has_prefix (formula
, "left")) {
10549 g_string_append_printf (gstr
, "%.12" GNM_FORMAT_g
, viewbox_left
);
10551 g_string_append_c (gstr
, *formula
);
10556 if (g_str_has_prefix (formula
, "right")) {
10558 g_string_append_printf (gstr
, "%.12" GNM_FORMAT_g
,
10559 viewbox_left
+ viewbox_width
);
10561 g_string_append_c (gstr
, *formula
);
10566 if (g_str_has_prefix (formula
, "height")) {
10568 g_string_append_printf (gstr
, "%.12" GNM_FORMAT_g
, viewbox_height
);
10570 g_string_append_c (gstr
, *formula
);
10575 if (g_str_has_prefix (formula
, "width")) {
10577 g_string_append_printf (gstr
, "%.12" GNM_FORMAT_g
, viewbox_width
);
10579 g_string_append_c (gstr
, *formula
);
10585 /* The ODF specs says (in ODF 1.2 part 1 item 19.171):
10586 "sin(n) returns the trigonometric sine of n, where n is an angle
10587 specified in degrees"
10588 but LibreOffice clearly uses sin(n) with n in radians
10591 /* if (g_str_has_prefix (formula, "cos(")) { */
10592 /* formula += 4; */
10593 /* /\* FIXME: this does not work in general, eg. if the argument *\/ */
10594 /* /\* to cos is a sum *\/ */
10595 /* g_string_append (gstr, "cos(pi()/180*"); */
10597 /* g_string_append_c (gstr, *formula); */
10602 /* if (g_str_has_prefix (formula, "sin(")) { */
10603 /* formula += 4; */
10604 /* /\* FIXME: this does not work in general, eg. if the argument *\/ */
10605 /* /\* to sin is a sum *\/ */
10606 /* g_string_append (gstr, "sin(pi()/180*"); */
10608 /* g_string_append_c (gstr, *formula); */
10613 g_string_append_c (gstr
, *formula
);
10619 oldlocale
= gnm_push_C_locale ();
10620 texpr
= gnm_expr_parse_str (gstr
->str
, &state
->pos
,
10621 GNM_EXPR_PARSE_DEFAULT
,
10624 gnm_pop_C_locale (oldlocale
);
10629 eval_pos_init_sheet (&ep
, state
->pos
.sheet
);
10630 val
= gnm_expr_top_eval
10631 (texpr
, &ep
, GNM_EXPR_EVAL_PERMIT_NON_SCALAR
);
10632 if (VALUE_IS_NUMBER (val
)) {
10633 x_ret
= value_get_as_float (val
);
10634 x
= g_new (double, 1);
10636 g_hash_table_insert (vals
, g_strdup (key
), x
);
10638 oo_warning (xin
, _("Unable to evaluate formula '%s' ('%s') of name '%s'"),
10639 o_formula
, gstr
->str
, key
);
10640 value_release (val
);
10641 gnm_expr_top_unref (texpr
);
10643 oo_warning (xin
, _("Unable to parse formula '%s' ('%s') of name '%s'"),
10644 o_formula
, gstr
->str
, key
);
10645 g_string_free (gstr
, TRUE
);
10650 odf_custom_shape_end (GsfXMLIn
*xin
, GsfXMLBlob
*blob
)
10652 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10653 GHashTable
*vals
= NULL
;
10654 char **strs
, **cur
;
10657 if (state
->chart
.cs_variables
|| state
->chart
.cs_modifiers
) {
10658 vals
= g_hash_table_new_full
10659 (g_str_hash
, g_str_equal
,
10660 (GDestroyNotify
) g_free
, (GDestroyNotify
) g_free
);
10661 if (state
->chart
.cs_modifiers
) {
10663 char *next
= state
->chart
.cs_modifiers
;
10665 while (*next
!= 0) {
10667 gnm_float x
= gnm_strto (next
, &end
);
10669 double *xp
= g_new (double, 1);
10670 char *name
= g_strdup_printf ("$%i", i
);
10672 g_hash_table_insert (vals
, name
, xp
);
10674 while (*end
== ' ')
10680 if (state
->chart
.cs_variables
) {
10681 GList
*keys
= g_hash_table_get_keys (state
->chart
.cs_variables
);
10683 gint level
= g_hash_table_size (state
->chart
.cs_variables
);
10684 for (l
= keys
; l
!= NULL
; l
= l
->next
)
10685 odf_get_cs_formula_value (xin
, l
->data
, vals
, level
);
10686 g_list_free (keys
);
10690 paths
= g_ptr_array_new_with_free_func ((GDestroyNotify
) go_path_free
);
10692 if (state
->chart
.cs_enhanced_path
!= NULL
) {
10693 strs
= g_strsplit (state
->chart
.cs_enhanced_path
, " N", 0);
10694 for (cur
= strs
; *cur
!= NULL
; cur
++) {
10696 path
= go_path_new_from_odf_enhanced_path (*cur
, vals
);
10698 g_ptr_array_add (paths
, path
);
10704 g_hash_table_unref (vals
);
10706 /* Note that we have already created a rectangle */
10708 if (paths
->len
== 1) {
10709 odf_custom_shape_replace_object
10710 (state
, g_object_new (GNM_SO_PATH_TYPE
,
10711 "path", g_ptr_array_index (paths
, 0), NULL
));
10712 } else if (paths
->len
> 1) {
10713 odf_custom_shape_replace_object
10714 (state
, g_object_new (GNM_SO_PATH_TYPE
,
10715 "paths", paths
, NULL
));
10716 } else if (state
->chart
.cs_type
) {
10717 /* ignoring "ellipse" and "rectangle" since they will be handled by the GOPath */
10718 if (0 == g_ascii_strcasecmp (state
->chart
.cs_type
, "frame") &&
10719 g_str_has_prefix (state
->chart
.cs_enhanced_path
, "M ")) {
10720 odf_custom_shape_replace_object
10721 (state
, g_object_new (GNM_SOW_FRAME_TYPE
, NULL
));
10722 } else if (0 == g_ascii_strcasecmp (state
->chart
.cs_type
, "round-rectangle") ||
10723 0 == g_ascii_strcasecmp (state
->chart
.cs_type
, "paper") ||
10724 0 == g_ascii_strcasecmp (state
->chart
.cs_type
, "parallelogram") ||
10725 0 == g_ascii_strcasecmp (state
->chart
.cs_type
, "trapezoid")) {
10726 /* We have already created the rectangle */
10727 oo_warning (xin
, _("An unsupported custom shape of type '%s' was encountered and "
10728 "converted to a rectangle."), state
->chart
.cs_type
);
10730 oo_warning (xin
, _("An unsupported custom shape of type '%s' was encountered and "
10731 "converted to a rectangle."), state
->chart
.cs_type
);
10733 oo_warning (xin
, _("An unsupported custom shape was encountered and "
10734 "converted to a rectangle."));
10735 g_ptr_array_unref (paths
);
10737 od_draw_text_frame_end (xin
, blob
);
10739 g_free (state
->chart
.cs_enhanced_path
);
10740 g_free (state
->chart
.cs_modifiers
);
10741 g_free (state
->chart
.cs_viewbox
);
10742 g_free (state
->chart
.cs_type
);
10743 state
->chart
.cs_enhanced_path
= NULL
;
10744 state
->chart
.cs_modifiers
= NULL
;
10745 state
->chart
.cs_viewbox
= NULL
;
10746 state
->chart
.cs_type
= NULL
;
10747 if (state
->chart
.cs_variables
)
10748 g_hash_table_remove_all (state
->chart
.cs_variables
);
10752 odf_custom_shape_equation (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10754 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10755 gchar
const *name
= NULL
, *meaning
= NULL
;
10756 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
10757 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10758 OO_NS_DRAW
, "name"))
10759 name
= CXML2C (attrs
[1]);
10760 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10761 OO_NS_DRAW
, "formula"))
10762 meaning
= CXML2C (attrs
[1]);
10763 if (name
&& meaning
) {
10764 if (state
->chart
.cs_variables
== NULL
)
10765 state
->chart
.cs_variables
= g_hash_table_new_full
10766 (g_str_hash
, g_str_equal
,
10767 (GDestroyNotify
) g_free
, (GDestroyNotify
) g_free
);
10768 g_hash_table_insert (state
->chart
.cs_variables
,
10769 g_strdup_printf ("?%s", name
), g_strdup (meaning
));
10774 odf_custom_shape (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10776 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10778 /* to avoid spill over */
10779 g_free (state
->chart
.cs_enhanced_path
);
10780 g_free (state
->chart
.cs_type
);
10781 state
->chart
.cs_enhanced_path
= NULL
;
10782 state
->chart
.cs_type
= NULL
;
10784 odf_so_filled (xin
, attrs
, FALSE
);
10785 odf_push_text_p (state
, FALSE
);
10789 odf_custom_shape_enhanced_geometry (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10791 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10793 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
10794 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10795 OO_NS_DRAW
, "type"))
10796 state
->chart
.cs_type
= g_strdup (CXML2C (attrs
[1]));
10797 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10798 OO_NS_DRAW
, "enhanced-path"))
10799 state
->chart
.cs_enhanced_path
= g_strdup (CXML2C (attrs
[1]));
10800 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10801 OO_NS_DRAW
, "modifiers"))
10802 state
->chart
.cs_modifiers
= g_strdup (CXML2C (attrs
[1]));
10803 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10804 OO_NS_SVG
, "viewBox"))
10805 state
->chart
.cs_viewbox
= g_strdup (CXML2C (attrs
[1]));
10809 odf_get_arrow_marker (OOParseState
*state
, char const *name
)
10811 OOMarker
*m
= g_hash_table_lookup (state
->chart
.arrow_markers
, name
);
10814 if (m
->arrow
== NULL
) {
10815 m
->arrow
= g_new0 (GOArrow
, 1);
10816 go_arrow_init_kite (m
->arrow
, 8, 10, 3);
10818 return go_arrow_dup (m
->arrow
);
10820 GOArrow
*arrow
= g_new0 (GOArrow
, 1);
10821 go_arrow_init_kite (arrow
, 8, 10, 3);
10827 odf_line (GsfXMLIn
*xin
, xmlChar
const **attrs
)
10829 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10830 gnm_float x1
= 0., x2
= 0., y1
= 0., y2
= 0.;
10831 GODrawingAnchorDir direction
;
10832 GnmRange cell_base
;
10833 double frame_offset
[4];
10834 char const *style_name
= NULL
;
10835 gdouble height
, width
;
10837 GnmSOAnchorMode mode
;
10838 cell_base
.start
.col
= state
->pos
.eval
.col
;
10839 cell_base
.start
.row
= state
->pos
.eval
.row
;
10840 cell_base
.end
.col
= cell_base
.end
.row
= -1;
10842 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
10843 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10844 OO_NS_DRAW
, "style-name"))
10845 style_name
= CXML2C (attrs
[1]);
10846 else if (NULL
!= oo_attr_distance (xin
, attrs
,
10849 else if (NULL
!= oo_attr_distance (xin
, attrs
,
10852 else if (NULL
!= oo_attr_distance (xin
, attrs
,
10855 else if (NULL
!= oo_attr_distance (xin
, attrs
,
10858 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
10859 OO_NS_TABLE
, "end-cell-address")) {
10862 char const *ptr
= oo_rangeref_parse
10863 (&ref
, CXML2C (attrs
[1]),
10864 parse_pos_init_sheet (&pp
, state
->pos
.sheet
),
10866 if (ptr
!= CXML2C (attrs
[1])
10867 && ref
.a
.sheet
!= invalid_sheet
) {
10868 cell_base
.end
.col
= ref
.a
.col
;
10869 cell_base
.end
.row
= ref
.a
.row
;
10871 } else if (oo_attr_int_range (xin
,attrs
, OO_NS_DRAW
, "z-index",
10877 direction
= GOD_ANCHOR_DIR_DOWN_RIGHT
;
10879 direction
= GOD_ANCHOR_DIR_UP_RIGHT
;
10880 frame_offset
[0] = x1
;
10881 frame_offset
[2] = x2
;
10885 direction
= GOD_ANCHOR_DIR_DOWN_LEFT
;
10887 direction
= GOD_ANCHOR_DIR_UP_LEFT
;
10888 frame_offset
[0] = x2
;
10889 frame_offset
[2] = x1
;
10893 frame_offset
[1] = y1
;
10894 frame_offset
[3] = y2
;
10897 frame_offset
[1] = y2
;
10898 frame_offset
[3] = y1
;
10902 if (state
->pos
.eval
.col
>= 0) {
10903 if (cell_base
.end
.col
>= 0) {
10904 mode
= GNM_SO_ANCHOR_TWO_CELLS
;
10906 cell_base
.end
.col
= cell_base
.start
.col
;
10907 cell_base
.end
.row
= cell_base
.start
.row
;
10908 frame_offset
[2] = width
;
10909 frame_offset
[3] = height
;
10910 mode
= GNM_SO_ANCHOR_ONE_CELL
;
10913 cell_base
.end
.col
= cell_base
.start
.col
=
10914 cell_base
.end
.row
= cell_base
.start
.row
= 0; /* actually not needed */
10915 frame_offset
[2] = width
;
10916 frame_offset
[3] = height
;
10917 mode
= GNM_SO_ANCHOR_ABSOLUTE
;
10920 odf_draw_frame_store_location (state
, frame_offset
,
10923 sheet_object_anchor_init (&state
->chart
.anchor
, &cell_base
,
10927 state
->chart
.so
= g_object_new (GNM_SO_LINE_TYPE
, NULL
);
10929 if (style_name
!= NULL
) {
10930 OOChartStyle
*oostyle
= g_hash_table_lookup
10931 (state
->chart
.graph_styles
, style_name
);
10932 if (oostyle
!= NULL
) {
10934 char const *start_marker
= NULL
;
10935 char const *end_marker
= NULL
;
10938 g_object_get (state
->chart
.so
, "style", &style0
, NULL
);
10939 if (style0
!= NULL
) {
10940 GOStyle
*style
= go_style_dup (style0
);
10941 odf_apply_style_props (xin
, oostyle
->style_props
,
10943 g_object_set (state
->chart
.so
, "style", style
, NULL
);
10944 g_object_unref (style
);
10945 g_object_unref (style0
);
10948 for (l
= oostyle
->other_props
; l
!= NULL
; l
= l
->next
) {
10949 OOProp
*prop
= l
->data
;
10950 if (0 == strcmp ("marker-start", prop
->name
))
10951 start_marker
= g_value_get_string (&prop
->value
);
10952 else if (0 == strcmp ("marker-end", prop
->name
))
10953 end_marker
= g_value_get_string (&prop
->value
);
10956 if (start_marker
!= NULL
) {
10957 GOArrow
*arrow
= odf_get_arrow_marker (state
, start_marker
);
10959 if (arrow
!= NULL
) {
10960 g_object_set (G_OBJECT (state
->chart
.so
),
10961 "start-arrow", arrow
, NULL
);
10965 if (end_marker
!= NULL
) {
10966 GOArrow
*arrow
= odf_get_arrow_marker (state
, end_marker
);
10968 if (arrow
!= NULL
) {
10969 g_object_set (G_OBJECT (state
->chart
.so
),
10970 "end-arrow", arrow
, NULL
);
10976 odf_push_text_p (state
, FALSE
);
10977 state
->chart
.z_index
= z
;
10980 /****************************************************************************/
10981 /******************************** controls ******************************/
10984 odf_form_control (GsfXMLIn
*xin
, xmlChar
const **attrs
, GType t
)
10986 OOControl
*oc
= g_new0 (OOControl
, 1);
10987 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
10989 static OOEnum
const orientations
[] = {
10991 { "horizontal", 1},
10994 static OOEnum
const list_linkages
[] = {
10996 { "selection-indexes", 1},
10997 { "selection-indices", 1},
11002 state
->cur_control
= NULL
;
11003 oc
->step
= oc
->page_step
= 1;
11004 oc
->as_index
= TRUE
;
11006 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11007 /* ODF does not declare an xml: namespace but uses this attribute */
11008 if (0 == strcmp (CXML2C (attrs
[0]), "xml:id")) {
11010 name
= g_strdup (CXML2C (attrs
[1]));
11011 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11012 OO_NS_FORM
, "id")) {
11014 name
= g_strdup (CXML2C (attrs
[1]));
11015 } else if (oo_attr_enum (xin
, attrs
, OO_NS_FORM
, "orientation", orientations
,
11017 oc
->horizontal
= (tmp
!= 0);
11018 else if (oo_attr_int (xin
, attrs
, OO_NS_FORM
, "min-value",
11020 else if (oo_attr_int (xin
, attrs
, OO_NS_FORM
, "max-value",
11022 else if (oo_attr_int_range (xin
, attrs
, OO_NS_FORM
, "step-size",
11023 &(oc
->step
), 0, INT_MAX
));
11024 else if (oo_attr_int_range (xin
, attrs
, OO_NS_FORM
, "page-step-size",
11025 &(oc
->page_step
), 0, INT_MAX
));
11026 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11027 OO_NS_FORM
, "value")) {
11028 g_free (oc
->value
);
11029 oc
->value
= g_strdup (CXML2C (attrs
[1]));
11030 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11031 OO_GNUM_NS_EXT
, "value-type")) {
11032 g_free (oc
->value_type
);
11033 oc
->value_type
= g_strdup (CXML2C (attrs
[1]));
11034 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11035 OO_NS_FORM
, "linked-cell")) {
11036 g_free (oc
->linked_cell
);
11037 oc
->linked_cell
= g_strdup (CXML2C (attrs
[1]));
11038 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11039 OO_GNUM_NS_EXT
, "linked-cell")) {
11040 g_free (oc
->linked_cell
);
11041 oc
->linked_cell
= g_strdup (CXML2C (attrs
[1]));
11042 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11043 OO_NS_FORM
, "current-state")) {
11044 g_free (oc
->current_state
);
11045 oc
->current_state
= g_strdup (CXML2C (attrs
[1]));
11046 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11047 OO_NS_FORM
, "current-selected")) {
11048 g_free (oc
->current_state
);
11049 oc
->current_state
= g_strdup (CXML2C (attrs
[1]));
11050 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11051 OO_NS_FORM
, "label")) {
11052 g_free (oc
->label
);
11053 oc
->label
= g_strdup (CXML2C (attrs
[1]));
11054 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11055 OO_NS_FORM
, "control-implementation")) {
11056 g_free (oc
->implementation
);
11057 oc
->implementation
= g_strdup (CXML2C (attrs
[1]));
11058 } else if (oo_attr_enum (xin
, attrs
, OO_NS_FORM
, "list-linkage-type", list_linkages
,
11060 oc
->as_index
= (tmp
!= 0);
11061 else if (oo_attr_enum (xin
, attrs
, OO_GNUM_NS_EXT
, "list-linkage-type", list_linkages
,
11063 oc
->as_index
= (tmp
!= 0);
11064 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11065 OO_NS_FORM
, "source-cell-range")) {
11066 g_free (oc
->source_cell_range
);
11067 oc
->source_cell_range
= g_strdup (CXML2C (attrs
[1]));
11068 } else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11069 OO_GNUM_NS_EXT
, "source-cell-range")) {
11070 if (oc
->source_cell_range
== NULL
)
11071 oc
->source_cell_range
= g_strdup (CXML2C (attrs
[1]));
11072 } else if (oo_attr_int (xin
, attrs
, OO_NS_FORM
, "bound-column",
11075 oo_warning (xin
, _("Attribute '%s' has "
11076 "the unsupported value '%s'."),
11077 "form:bound-column", CXML2C (attrs
[1]));
11080 if (name
!= NULL
) {
11081 if (oc
->implementation
!= NULL
&&
11082 t
== sheet_widget_slider_get_type ()) {
11083 if (0 == strcmp (oc
->implementation
, "gnm:scrollbar"))
11084 oc
->t
= sheet_widget_scrollbar_get_type ();
11085 else if (0 == strcmp (oc
->implementation
,
11087 oc
->t
= sheet_widget_spinbutton_get_type ();
11088 else if (0 == strcmp (oc
->implementation
,
11090 oc
->t
= sheet_widget_slider_get_type ();
11091 else if (0 == strcmp (oc
->implementation
,
11092 "ooo:com.sun.star.form."
11093 "component.ScrollBar"))
11094 oc
->t
= sheet_widget_scrollbar_get_type ();
11095 } else if (t
== sheet_widget_frame_get_type ()) {
11096 if (oc
->implementation
== NULL
||
11097 0 != strcmp (oc
->implementation
, "gnm:frame")) {
11098 oo_control_free (oc
);
11104 g_hash_table_replace (state
->controls
, name
, oc
);
11106 oo_control_free (oc
);
11110 if (t
== sheet_widget_button_get_type () ||
11111 t
== sheet_widget_frame_get_type ())
11112 state
->cur_control
= oc
;
11117 odf_form_value_range (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11120 odf_form_control (xin
, attrs
, sheet_widget_slider_get_type ());
11124 odf_form_checkbox (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11126 odf_form_control (xin
, attrs
, sheet_widget_checkbox_get_type ());
11130 odf_form_radio (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11132 odf_form_control (xin
, attrs
, sheet_widget_radio_button_get_type ());
11136 odf_form_generic (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11138 odf_form_control (xin
, attrs
, sheet_widget_frame_get_type ());
11142 odf_form_listbox (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11144 odf_form_control (xin
, attrs
, sheet_widget_list_get_type ());
11148 odf_form_combobox (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11150 odf_form_control (xin
, attrs
, sheet_widget_combo_get_type ());
11154 odf_form_button (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11156 odf_form_control (xin
, attrs
, sheet_widget_button_get_type ());
11160 odf_form_control_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
11162 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11163 state
->cur_control
= NULL
;
11167 odf_button_event_listener (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11169 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11170 char const *event_name
= NULL
;
11171 char const *language
= NULL
;
11172 char const *macro_name
= NULL
;
11174 if (state
->cur_control
== NULL
)
11177 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11178 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11179 OO_NS_SCRIPT
, "event-name"))
11180 event_name
= CXML2C (attrs
[1]);
11181 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11182 OO_NS_SCRIPT
, "language"))
11183 language
= CXML2C (attrs
[1]);
11184 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11185 OO_NS_SCRIPT
, "macro-name"))
11186 macro_name
= CXML2C (attrs
[1]);
11188 if (event_name
&& (0 == strcmp (event_name
, "dom:mousedown")) &&
11189 language
&& (0 == strcmp (language
, "gnm:short-macro")) &&
11190 g_str_has_prefix (macro_name
, "set-to-TRUE:"))
11191 state
->cur_control
->linked_cell
= g_strdup (macro_name
+ 12);
11195 odf_control_property (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11197 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11198 char const *property_name
= NULL
;
11199 char const *value
= NULL
;
11201 if (state
->cur_control
== NULL
)
11204 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11205 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11206 OO_NS_FORM
, "property-name"))
11207 property_name
= CXML2C (attrs
[1]);
11208 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11209 OO_NS_OFFICE
, "string-value"))
11210 value
= CXML2C (attrs
[1]);
11212 if ((property_name
!= NULL
) &&
11213 (0 == strcmp (property_name
, "gnm:label")) &&
11215 state
->cur_control
->label
= g_strdup (value
);
11219 odf_selection_range (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11221 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11223 if (odf_attr_range (xin
, attrs
, state
->pos
.sheet
, &r
))
11224 sv_selection_add_range (sheet_get_view (state
->pos
.sheet
, state
->wb_view
), &r
);
11228 odf_selection (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11230 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11231 Sheet
*sheet
= state
->pos
.sheet
;
11232 int col
= -1, row
= -1;
11234 sv_selection_reset (sheet_get_view (sheet
, state
->wb_view
));
11236 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11237 if (oo_attr_int_range
11238 (xin
, attrs
, OO_GNUM_NS_EXT
, "cursor-col", &col
,
11239 0, gnm_sheet_get_last_col(sheet
))) {
11240 } else if (oo_attr_int_range
11241 (xin
, attrs
, OO_GNUM_NS_EXT
, "cursor-row", &row
,
11242 0, gnm_sheet_get_last_row(sheet
))) {};
11244 state
->pos
.eval
.col
= col
;
11245 state
->pos
.eval
.row
= row
;
11249 odf_selection_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
11251 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11253 gnm_sheet_view_set_edit_pos (sheet_get_view (state
->pos
.sheet
, state
->wb_view
), &state
->pos
.eval
);
11258 /****************************************************************************/
11259 /******************************** settings.xml ******************************/
11262 destroy_gvalue (gpointer data
)
11264 g_value_unset (data
);
11269 odf_config_item_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
11271 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11272 GHashTable
*parent_hash
;
11274 if (state
->settings
.stack
== NULL
)
11275 parent_hash
= state
->settings
.settings
;
11277 parent_hash
= state
->settings
.stack
->data
;
11279 if (parent_hash
!= NULL
&& state
->settings
.config_item_name
!= NULL
) {
11280 GValue
*val
= NULL
;
11281 switch (state
->settings
.type
) {
11282 case G_TYPE_BOOLEAN
: {
11283 gboolean b
= (g_ascii_strcasecmp (xin
->content
->str
, "false") &&
11284 strcmp (xin
->content
->str
, "0"));
11285 val
= g_value_init (g_new0 (GValue
, 1), G_TYPE_BOOLEAN
);
11286 g_value_set_boolean (val
, b
);
11293 errno
= 0; /* strtol sets errno, but does not clear it. */
11294 n
= strtol (xin
->content
->str
, &end
, 10);
11295 if (!(*end
|| errno
!= 0 || n
< INT_MIN
|| n
> INT_MAX
)) {
11296 val
= g_value_init (g_new0 (GValue
, 1), G_TYPE_INT
);
11297 g_value_set_int (val
, (int)n
);
11301 case G_TYPE_LONG
: {
11305 errno
= 0; /* strtol sets errno, but does not clear it. */
11306 n
= strtol (xin
->content
->str
, &end
, 10);
11307 if (!(*end
|| errno
!= 0)) {
11308 val
= g_value_init (g_new0 (GValue
, 1), G_TYPE_LONG
);
11309 g_value_set_long (val
, n
);
11313 case G_TYPE_STRING
:
11314 val
= g_value_init (g_new0 (GValue
, 1), G_TYPE_STRING
);
11315 g_value_set_string (val
, (xin
->content
->str
));
11321 g_hash_table_replace
11322 (parent_hash
, g_strdup (state
->settings
.config_item_name
),
11326 g_free (state
->settings
.config_item_name
);
11327 state
->settings
.config_item_name
= NULL
;
11332 odf_config_item (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11334 static OOEnum
const config_types
[] = {
11335 {"base64Binary", G_TYPE_INVALID
},
11336 {"boolean", G_TYPE_BOOLEAN
},
11337 {"datetime", G_TYPE_INVALID
},
11338 {"double", G_TYPE_INVALID
},
11339 {"int", G_TYPE_INT
},
11340 {"long", G_TYPE_LONG
},
11341 {"short", G_TYPE_INT
},
11342 {"string", G_TYPE_STRING
},
11345 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11347 state
->settings
.config_item_name
= NULL
;
11348 state
->settings
.type
= G_TYPE_INVALID
;
11350 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
11353 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CONFIG
, "name"))
11354 state
->settings
.config_item_name
= g_strdup (CXML2C (attrs
[1]));
11355 else if (oo_attr_enum (xin
, attrs
, OO_NS_CONFIG
, "type", config_types
, &i
))
11356 state
->settings
.type
= i
;
11361 odf_config_stack_pop (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
11363 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11365 g_return_if_fail (state
->settings
.stack
!= NULL
);
11367 g_hash_table_unref (state
->settings
.stack
->data
);
11368 state
->settings
.stack
= g_slist_delete_link
11369 (state
->settings
.stack
, state
->settings
.stack
);
11373 odf_config_item_set (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11375 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11376 GHashTable
*set
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
11377 (GDestroyNotify
) g_free
,
11378 (GDestroyNotify
) destroy_gvalue
);
11379 GHashTable
*parent_hash
;
11380 gchar
*name
= NULL
;
11383 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11384 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_CONFIG
, "name"))
11385 name
= g_strdup (CXML2C (attrs
[1]));
11387 if (state
->settings
.stack
== NULL
)
11388 parent_hash
= state
->settings
.settings
;
11390 parent_hash
= state
->settings
.stack
->data
;
11392 if (name
== NULL
) {
11396 name
= g_strdup_printf ("Unnamed_Config_Set-%i", i
++);
11397 } while (NULL
!= g_hash_table_lookup (parent_hash
, name
));
11400 state
->settings
.stack
= g_slist_prepend (state
->settings
.stack
, set
);
11402 val
= g_value_init (g_new0 (GValue
, 1), G_TYPE_HASH_TABLE
);
11403 g_value_set_boxed (val
, set
);
11405 g_hash_table_replace (parent_hash
, name
, val
);
11409 dump_settings_hash (char const *key
, GValue
*val
, char const *prefix
)
11411 gchar
*content
= g_strdup_value_contents (val
);
11412 g_print ("%s Settings \'%s\' has \'%s\'\n", prefix
, key
, content
);
11415 if (G_VALUE_HOLDS(val
,G_TYPE_HASH_TABLE
)) {
11416 char *pre
= g_strconcat (prefix
, ">>", NULL
);
11417 GHashTable
*hash
= g_value_get_boxed (val
);
11418 g_hash_table_foreach (hash
, (GHFunc
)dump_settings_hash
, pre
);
11424 odf_created_by_gnumeric (OOParseState
*state
)
11426 GsfDocMetaData
*meta_data
= go_doc_get_meta_data (GO_DOC (state
->pos
.wb
));
11427 GsfDocProp
*prop
= gsf_doc_meta_data_lookup (meta_data
,
11431 return (prop
!= NULL
&&
11432 (NULL
!= (str
= g_value_get_string
11433 (gsf_doc_prop_get_val (prop
)))) &&
11434 g_str_has_prefix (str
, "gnumeric"));
11438 odf_has_gnm_foreign (OOParseState
*state
)
11441 if ((state
->settings
.settings
!= NULL
) &&
11442 NULL
!= (val
= g_hash_table_lookup (state
->settings
.settings
, "gnm:settings")) &&
11443 G_VALUE_HOLDS(val
,G_TYPE_HASH_TABLE
)) {
11444 GHashTable
*hash
= g_value_get_boxed (val
);
11445 val
= g_hash_table_lookup (hash
, "gnm:has_foreign");
11446 if (val
!= NULL
&& G_VALUE_HOLDS(val
, G_TYPE_BOOLEAN
))
11447 return g_value_get_boolean (val
);
11453 odf_apply_gnm_config (OOParseState
*state
)
11456 if ((state
->settings
.settings
!= NULL
) &&
11457 NULL
!= (val
= g_hash_table_lookup (state
->settings
.settings
, "gnm:settings")) &&
11458 G_VALUE_HOLDS(val
,G_TYPE_HASH_TABLE
)) {
11459 int width
= 0, height
= 0;
11460 GHashTable
*hash
= g_value_get_boxed (val
);
11461 val
= g_hash_table_lookup (hash
, "gnm:active-sheet");
11462 if (val
!= NULL
&& G_VALUE_HOLDS(val
, G_TYPE_STRING
)) {
11463 const gchar
*name
= g_value_get_string (val
);
11464 Sheet
*sheet
= workbook_sheet_by_name (state
->pos
.wb
, name
);
11466 wb_view_sheet_focus (state
->wb_view
, sheet
);
11468 val
= g_hash_table_lookup (hash
, "gnm:geometry-width");
11469 if (val
!= NULL
&& G_VALUE_HOLDS(val
, G_TYPE_INT
)) {
11470 width
= g_value_get_int (val
);
11472 val
= g_hash_table_lookup (hash
, "gnm:geometry-height");
11473 if (val
!= NULL
&& G_VALUE_HOLDS(val
, G_TYPE_INT
)) {
11474 height
= g_value_get_int (val
);
11476 if (width
> 0 && height
> 0)
11477 wb_view_preferred_size (state
->wb_view
, width
, height
);
11482 odf_apply_ooo_table_config (char const *key
, GValue
*val
, OOParseState
*state
)
11484 if (G_VALUE_HOLDS(val
,G_TYPE_HASH_TABLE
)) {
11485 GHashTable
*hash
= g_value_get_boxed (val
);
11486 Sheet
*sheet
= workbook_sheet_by_name (state
->pos
.wb
, key
);
11488 if (hash
!= NULL
&& sheet
!= NULL
) {
11489 SheetView
*sv
= sheet_get_view (sheet
, state
->wb_view
);
11492 int pos_left
= 0, pos_bottom
= 0;
11493 int vsm
= 0, hsm
= 0, vsp
= -1, hsp
= -1;
11495 if (!odf_has_gnm_foreign (state
)) {
11496 item
= g_hash_table_lookup (hash
, "TabColor");
11497 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_INT
)) {
11498 GOColor color
= g_value_get_int (item
);
11499 color
= color
<< 8;
11500 sheet
->tab_color
= gnm_color_new_go (color
);
11502 item
= g_hash_table_lookup (hash
, "CursorPositionX");
11503 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_INT
)) {
11504 GValue
*itemy
= g_hash_table_lookup (hash
, "CursorPositionY");
11505 if (itemy
!= NULL
&& G_VALUE_HOLDS(itemy
, G_TYPE_INT
)) {
11507 pos
.col
= g_value_get_int (item
);
11508 pos
.row
= g_value_get_int (itemy
);
11512 sv_selection_reset (sv
);
11513 sv_selection_add_range (sv
, &r
);
11514 gnm_sheet_view_set_edit_pos
11515 (sheet_get_view (sheet
, state
->wb_view
),
11519 item
= g_hash_table_lookup (hash
, "HasColumnRowHeaders");
11520 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_BOOLEAN
)) {
11521 gboolean val
= g_value_get_boolean (item
);
11522 g_object_set (sheet
, "display-row-header", val
, NULL
);
11523 g_object_set (sheet
, "display-column-header", val
, NULL
);
11527 item
= g_hash_table_lookup (hash
, "ShowGrid");
11528 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_BOOLEAN
))
11529 g_object_set (sheet
, "display-grid", g_value_get_boolean (item
), NULL
);
11531 item
= g_hash_table_lookup (hash
, "ShowZeroValues");
11532 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_BOOLEAN
))
11533 g_object_set (sheet
, "display-zeros", g_value_get_boolean (item
), NULL
);
11535 item
= g_hash_table_lookup (hash
, "ZoomValue");
11536 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_INT
))
11537 g_object_set (sheet
, "zoom-factor", g_value_get_int (item
)/100., NULL
);
11539 item
= g_hash_table_lookup (hash
, "HorizontalSplitMode");
11540 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_INT
))
11541 vsm
= g_value_get_int (item
);
11542 item
= g_hash_table_lookup (hash
, "VerticalSplitMode");
11543 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_INT
))
11544 hsm
= g_value_get_int (item
);
11546 if (vsm
> 0 || hsm
> 0) {
11547 item
= g_hash_table_lookup (hash
, "VerticalSplitPosition");
11548 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_INT
))
11549 vsp
= g_value_get_int (item
);
11550 item
= g_hash_table_lookup (hash
, "HorizontalSplitPosition");
11551 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_INT
))
11552 hsp
= g_value_get_int (item
);
11553 if (vsp
> 0 || hsp
> 0) {
11554 GnmCellPos fpos
= {0, 0};
11557 gnm_sheet_view_freeze_panes (sv
, &fpos
, &pos
);
11560 item
= g_hash_table_lookup (hash
, "PositionRight");
11562 item
= g_hash_table_lookup (hash
, "PositionLeft");
11564 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_INT
))
11565 pos_left
= g_value_get_int (item
);
11567 item
= g_hash_table_lookup (hash
, "PositionBottom");
11568 if (item
!= NULL
&& G_VALUE_HOLDS(item
, G_TYPE_INT
))
11569 pos_bottom
= g_value_get_int (item
);
11571 gnm_sheet_view_set_initial_top_left (sv
, pos_left
, pos_bottom
);
11577 odf_apply_ooo_config (OOParseState
*state
)
11582 if ((state
->settings
.settings
== NULL
) ||
11583 NULL
== (val
= g_hash_table_lookup (state
->settings
.settings
, "ooo:view-settings")) ||
11584 !G_VALUE_HOLDS(val
,G_TYPE_HASH_TABLE
))
11586 hash
= g_value_get_boxed (val
);
11588 if ((hash
== NULL
) ||
11589 NULL
== (val
= g_hash_table_lookup (hash
, "Views")) ||
11590 !G_VALUE_HOLDS(val
,G_TYPE_HASH_TABLE
))
11592 hash
= g_value_get_boxed (val
);
11594 if ((hash
== NULL
) ||
11595 NULL
== (val
= g_hash_table_lookup (hash
, "Unnamed_Config_Set-0")) ||
11596 !G_VALUE_HOLDS(val
,G_TYPE_HASH_TABLE
))
11598 hash
= g_value_get_boxed (val
);
11603 val
= g_hash_table_lookup (hash
, "ActiveTable");
11605 if (NULL
!= val
&& G_VALUE_HOLDS(val
,G_TYPE_STRING
)) {
11606 const gchar
*name
= g_value_get_string (val
);
11607 Sheet
*sheet
= workbook_sheet_by_name (state
->pos
.wb
, name
);
11609 wb_view_sheet_focus (state
->wb_view
, sheet
);
11612 if (NULL
== (val
= g_hash_table_lookup (hash
, "Tables")) ||
11613 !G_VALUE_HOLDS(val
,G_TYPE_HASH_TABLE
))
11615 hash
= g_value_get_boxed (val
);
11620 g_hash_table_foreach (hash
, (GHFunc
) odf_apply_ooo_table_config
, state
);
11623 /**************************************************************************/
11626 oo_marker (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11628 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11629 OOMarker
*marker
= g_new0 (OOMarker
, 1);
11630 int type
= GO_ARROW_NONE
;
11631 double a
= 0., b
= 0., c
= 0.;
11632 char const *name
= NULL
;
11634 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11635 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11636 OO_NS_DRAW
, "name"))
11637 name
= CXML2C (attrs
[1]);
11638 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11639 OO_NS_SVG
, "viewBox"))
11640 marker
->view_box
= g_strdup (CXML2C (attrs
[1]));
11641 else if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]),
11643 marker
->d
= g_strdup (CXML2C (attrs
[1]));
11644 else if (oo_attr_int_range (xin
, attrs
, OO_GNUM_NS_EXT
, "arrow-type", &type
,
11645 GO_ARROW_KITE
, GO_ARROW_OVAL
));
11646 else if (oo_attr_float (xin
, attrs
, OO_GNUM_NS_EXT
,
11648 else if (oo_attr_float (xin
, attrs
, OO_GNUM_NS_EXT
,
11650 else if (oo_attr_float (xin
, attrs
, OO_GNUM_NS_EXT
,
11652 if (type
!= GO_ARROW_NONE
) {
11653 marker
->arrow
= g_new0 (GOArrow
, 1);
11654 go_arrow_init (marker
->arrow
, type
, a
, b
, c
);
11656 if (name
!= NULL
) {
11657 g_hash_table_replace (state
->chart
.arrow_markers
,
11658 g_strdup (name
), marker
);
11660 oo_marker_free (marker
);
11664 /****************** These are the preparse functions ***********************/
11667 odf_sheet_suggest_size (GsfXMLIn
*xin
, int *cols
, int *rows
)
11669 int c
= GNM_MIN_COLS
;
11670 int r
= GNM_MIN_ROWS
;
11672 while (c
< *cols
&& c
< GNM_MAX_COLS
)
11675 while (r
< *rows
&& r
< GNM_MAX_ROWS
)
11678 while (!gnm_sheet_valid_size (c
, r
))
11679 gnm_sheet_suggest_size (&c
, &r
);
11681 if (xin
!= NULL
&& (*cols
> c
|| *rows
> r
))
11682 oo_warning (xin
, _("The sheet size of %i columns and %i rows used in this file "
11683 "exceeds Gnumeric's maximum supported sheet size"), *cols
, *rows
);
11690 odf_preparse_create_sheet (GsfXMLIn
*xin
)
11692 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11694 char *table_name
= state
->object_name
;
11696 sheet_order_t
*sot
= g_new(sheet_order_t
, 1);
11698 cols
= state
->extent_data
.col
+ 1;
11699 rows
= state
->extent_data
.row
+ 1;
11702 odf_sheet_suggest_size (xin
, &cols
, &rows
);
11704 if (table_name
!= NULL
) {
11705 sheet
= workbook_sheet_by_name (state
->pos
.wb
, table_name
);
11706 if (NULL
== sheet
) {
11707 sheet
= sheet_new (state
->pos
.wb
, table_name
, cols
, rows
);
11708 workbook_sheet_attach (state
->pos
.wb
, sheet
);
11710 /* We have a corrupted file with a duplicate sheet name */
11711 char *new_name
, *base
;
11713 base
= g_strdup_printf (_("%s_IN_CORRUPTED_FILE"), table_name
);
11714 new_name
= workbook_sheet_get_free_name (state
->pos
.wb
,
11715 base
, FALSE
, FALSE
);
11718 oo_warning (xin
, _("This file is corrupted with a "
11719 "duplicate sheet name \"%s\", "
11720 "now renamed to \"%s\"."),
11721 table_name
, new_name
);
11722 sheet
= sheet_new (state
->pos
.wb
, new_name
, cols
, rows
);
11723 workbook_sheet_attach (state
->pos
.wb
, sheet
);
11727 table_name
= workbook_sheet_get_free_name (state
->pos
.wb
,
11728 _("SHEET_IN_CORRUPTED_FILE"),
11730 sheet
= sheet_new (state
->pos
.wb
, table_name
, cols
, rows
);
11731 workbook_sheet_attach (state
->pos
.wb
, sheet
);
11733 /* We are missing the table name. This is bad! */
11734 oo_warning (xin
, _("This file is corrupted with an "
11736 "now named \"%s\"."),
11739 g_free (table_name
);
11740 state
->object_name
= NULL
;
11742 /* Store sheets in correct order in case we implicitly
11743 * created one out of order */
11744 sot
->sheet
= sheet
;
11745 state
->sheet_order
= g_slist_prepend
11746 (state
->sheet_order
, sot
);
11748 state
->pos
.sheet
= sheet
;
11751 g_printerr ("Created sheet %s\n", sheet
->name_unquoted
);
11757 oo_named_exprs_preparse (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11759 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11761 if (state
->pos
.sheet
== NULL
&& state
->object_name
!= NULL
) {
11762 // Create sheet, but not for global name section
11763 odf_preparse_create_sheet (xin
);
11768 oo_named_expr_preparse (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11770 oo_named_expr_common (xin
, attrs
, TRUE
);
11774 odf_preparse_table_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11776 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11778 state
->pos
.eval
.col
= 0;
11779 state
->pos
.eval
.row
= 0;
11780 state
->pos
.sheet
= NULL
;
11781 state
->extent_data
.col
= 0;
11782 state
->extent_data
.row
= 0;
11783 state
->object_name
= NULL
;
11785 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11786 if (gsf_xml_in_namecmp (xin
, CXML2C (attrs
[0]), OO_NS_TABLE
, "name"))
11787 state
->object_name
= g_strdup (CXML2C (attrs
[1]));
11791 odf_preparse_spreadsheet_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
11796 odf_preparse_table_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
11798 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11800 if (state
->pos
.sheet
== NULL
)
11801 odf_preparse_create_sheet (xin
);
11803 state
->pos
.sheet
= NULL
;
11808 odf_preparse_row_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11810 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11812 state
->pos
.eval
.col
= 0;
11813 state
->row_inc
= 1;
11815 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11816 if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
, "number-rows-repeated", &state
->row_inc
,
11817 0, INT_MAX
- state
->pos
.eval
.row
));
11821 odf_preparse_row_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
11823 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11824 state
->pos
.eval
.row
+= state
->row_inc
;
11828 odf_preparse_cell_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11830 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11832 state
->col_inc
= 1;
11834 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11835 if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
, "number-columns-repeated",
11836 &state
->col_inc
, 0, INT_MAX
- state
->pos
.eval
.col
));
11838 oo_update_data_extent (state
, state
->col_inc
, state
->row_inc
);
11839 state
->pos
.eval
.col
+= state
->col_inc
;
11843 odf_preparse_covered_cell_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11845 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11847 state
->col_inc
= 1;
11848 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11849 if (oo_attr_int_range (xin
, attrs
, OO_NS_TABLE
, "number-columns-repeated",
11850 &state
->col_inc
, 0, INT_MAX
- state
->pos
.eval
.col
));
11851 state
->pos
.eval
.col
+= state
->col_inc
;
11856 /**************************************************************************/
11859 odf_find_version (GsfXMLIn
*xin
, xmlChar
const **attrs
)
11861 OOParseState
*state
= (OOParseState
*)xin
->user_state
;
11863 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
11864 if (oo_attr_float (xin
, attrs
, OO_NS_OFFICE
,
11865 "version", &state
->ver_odf
));
11868 /**************************************************************************/
11870 static GsfXMLInNode
const styles_dtd
[] = {
11871 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
11874 GSF_XML_IN_NODE (START
, OFFICE_FONTS_OOO1
, OO_NS_OFFICE
, "font-decls", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11875 GSF_XML_IN_NODE (OFFICE_FONTS_OOO1
, FONT_DECL_OOO1
, OO_NS_STYLE
, "font-decl", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11877 /* ooo-2.x, ooo-3.x */
11878 GSF_XML_IN_NODE (START
, OFFICE_DOC_STYLES
, OO_NS_OFFICE
, "document-styles", GSF_XML_NO_CONTENT
, &odf_find_version
, NULL
),
11879 GSF_XML_IN_NODE (OFFICE_DOC_STYLES
, OFFICE_FONTS_OOO1
, OO_NS_OFFICE
, "font-decls", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11880 GSF_XML_IN_NODE (OFFICE_DOC_STYLES
, OFFICE_FONTS
, OO_NS_OFFICE
, "font-face-decls", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11881 GSF_XML_IN_NODE (OFFICE_FONTS
, FONT_DECL
, OO_NS_STYLE
, "font-face", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11883 GSF_XML_IN_NODE (OFFICE_DOC_STYLES
, OFFICE_STYLES
, OO_NS_OFFICE
, "styles", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11884 GSF_XML_IN_NODE (OFFICE_STYLES
, FILLIMAGE
, OO_NS_DRAW
, "fill-image", GSF_XML_NO_CONTENT
, &oo_fill_image
, NULL
),
11885 GSF_XML_IN_NODE (OFFICE_STYLES
, DASH
, OO_NS_DRAW
, "stroke-dash", GSF_XML_NO_CONTENT
, &oo_dash
, NULL
),
11886 GSF_XML_IN_NODE (OFFICE_STYLES
, HATCH
, OO_NS_DRAW
, "hatch", GSF_XML_NO_CONTENT
, &oo_hatch
, NULL
),
11887 GSF_XML_IN_NODE (OFFICE_STYLES
, GRADIENT
, OO_NS_DRAW
, "gradient", GSF_XML_NO_CONTENT
, &oo_gradient
, NULL
),
11888 GSF_XML_IN_NODE (OFFICE_STYLES
, MARKER
, OO_NS_DRAW
, "marker", GSF_XML_NO_CONTENT
, &oo_marker
, NULL
),
11889 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE
, OO_NS_STYLE
, "style", GSF_XML_NO_CONTENT
, &oo_style
, &oo_style_end
),
11890 GSF_XML_IN_NODE (STYLE
, TABLE_CELL_PROPS
, OO_NS_STYLE
, "table-cell-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
11891 GSF_XML_IN_NODE (STYLE
, TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
11892 GSF_XML_IN_NODE (STYLE
, PARAGRAPH_PROPS
, OO_NS_STYLE
, "paragraph-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
11893 GSF_XML_IN_NODE (PARAGRAPH_PROPS
, PARA_TABS
, OO_NS_STYLE
, "tab-stops", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11894 GSF_XML_IN_NODE (STYLE
, STYLE_PROP
, OO_NS_STYLE
, "properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
11895 GSF_XML_IN_NODE (STYLE_PROP
, STYLE_TAB_STOPS
, OO_NS_STYLE
, "tab-stops", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11897 GSF_XML_IN_NODE (OFFICE_STYLES
, DEFAULT_STYLE
, OO_NS_STYLE
, "default-style", GSF_XML_NO_CONTENT
, &oo_style
, &oo_style_end
),
11898 GSF_XML_IN_NODE (DEFAULT_STYLE
, DEFAULT_TABLE_CELL_PROPS
, OO_NS_STYLE
, "table-cell-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
11899 GSF_XML_IN_NODE (DEFAULT_STYLE
, DEFAULT_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11900 GSF_XML_IN_NODE (DEFAULT_STYLE
, DEFAULT_GRAPHIC_PROPS
, OO_NS_STYLE
, "graphic-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
11901 GSF_XML_IN_NODE (DEFAULT_STYLE
, DEFAULT_PARAGRAPH_PROPS
, OO_NS_STYLE
, "paragraph-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
11902 GSF_XML_IN_NODE (DEFAULT_PARAGRAPH_PROPS
, DEFAULT_PARA_TABS
, OO_NS_STYLE
, "tab-stops", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11903 GSF_XML_IN_NODE (DEFAULT_STYLE
, DEFAULT_STYLE_PROP
, OO_NS_STYLE
, "properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
11904 GSF_XML_IN_NODE (DEFAULT_STYLE_PROP
, STYLE_TAB_STOPS
, OO_NS_STYLE
, "tab-stops", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11905 GSF_XML_IN_NODE (DEFAULT_STYLE
, DEFAULT_TABLE_COL_PROPS
, OO_NS_STYLE
, "table-column-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
11906 GSF_XML_IN_NODE (DEFAULT_STYLE
, DEFAULT_TABLE_ROW_PROPS
, OO_NS_STYLE
, "table-row-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
11908 GSF_XML_IN_NODE (OFFICE_STYLES
, NUMBER_STYLE
, OO_NS_NUMBER
, "number-style", GSF_XML_NO_CONTENT
, &odf_number_style
, &odf_number_style_end
),
11909 #if HAVE_OO_NS_LOCALC_EXT
11910 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_NUMBERFILL_CHARACTER
, OO_NS_LOCALC_EXT
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11911 GSF_XML_IN_NODE (NUMBER_STYLE
, LOEXT_TEXT
, OO_NS_LOCALC_EXT
, "text", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11913 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_NUMBER
, OO_NS_NUMBER
, "number", GSF_XML_NO_CONTENT
, &odf_number
, NULL
),
11914 GSF_XML_IN_NODE (NUMBER_STYLE_NUMBER
, NUMBER_EMBEDDED_TEXT
, OO_NS_NUMBER
, "embedded-text", GSF_XML_CONTENT
, &odf_embedded_text_start
, &odf_embedded_text_end
),
11915 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
11916 GSF_XML_IN_NODE (NUMBER_STYLE_TEXT
, FORMAT_TEXT_INVISIBLE
, OO_GNUM_NS_EXT
, "invisible", GSF_XML_NO_CONTENT
, &odf_format_invisible_text
, NULL
),
11917 GSF_XML_IN_NODE (NUMBER_STYLE_TEXT
, FORMAT_TEXT_REPEATED
, OO_GNUM_NS_EXT
, "repeated", GSF_XML_NO_CONTENT
, NULL
, &odf_format_repeated_text_end
),
11918 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_FRACTION
, OO_NS_NUMBER
, "fraction", GSF_XML_NO_CONTENT
, &odf_fraction
, NULL
),
11919 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_SCI_STYLE_PROP
, OO_NS_NUMBER
, "scientific-number", GSF_XML_NO_CONTENT
, &odf_scientific
, NULL
),
11920 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_PROP
, OO_NS_STYLE
, "properties", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11921 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, &odf_map
, NULL
),
11922 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
11923 GSF_XML_IN_NODE (NUMBER_STYLE
, FORMAT_TEXT_INVISIBLE
, OO_GNUM_NS_EXT
, "invisible", GSF_XML_2ND
, NULL
, NULL
),
11924 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11926 GSF_XML_IN_NODE (OFFICE_STYLES
, DATE_STYLE
, OO_NS_NUMBER
, "date-style", GSF_XML_NO_CONTENT
, &oo_date_style
, &oo_date_style_end
),
11927 GSF_XML_IN_NODE (DATE_STYLE
, DATE_DAY
, OO_NS_NUMBER
, "day", GSF_XML_NO_CONTENT
, &oo_date_day
, NULL
),
11928 GSF_XML_IN_NODE (DATE_STYLE
, DATE_MONTH
, OO_NS_NUMBER
, "month", GSF_XML_NO_CONTENT
, &oo_date_month
, NULL
),
11929 GSF_XML_IN_NODE (DATE_STYLE
, DATE_YEAR
, OO_NS_NUMBER
, "year", GSF_XML_NO_CONTENT
, &oo_date_year
, NULL
),
11930 GSF_XML_IN_NODE (DATE_STYLE
, DATE_ERA
, OO_NS_NUMBER
, "era", GSF_XML_NO_CONTENT
, &oo_date_era
, NULL
),
11931 GSF_XML_IN_NODE (DATE_STYLE
, DATE_DAY_OF_WEEK
, OO_NS_NUMBER
, "day-of-week", GSF_XML_NO_CONTENT
, &oo_date_day_of_week
, NULL
),
11932 GSF_XML_IN_NODE (DATE_STYLE
, DATE_WEEK_OF_YEAR
, OO_NS_NUMBER
, "week-of-year", GSF_XML_NO_CONTENT
, &oo_date_week_of_year
, NULL
),
11933 GSF_XML_IN_NODE (DATE_STYLE
, DATE_QUARTER
, OO_NS_NUMBER
, "quarter", GSF_XML_NO_CONTENT
, &oo_date_quarter
, NULL
),
11934 GSF_XML_IN_NODE (DATE_STYLE
, DATE_HOURS
, OO_NS_NUMBER
, "hours", GSF_XML_NO_CONTENT
, &oo_date_hours
, NULL
),
11935 GSF_XML_IN_NODE (DATE_STYLE
, DATE_MINUTES
, OO_NS_NUMBER
, "minutes", GSF_XML_NO_CONTENT
, &oo_date_minutes
, NULL
),
11936 GSF_XML_IN_NODE (DATE_STYLE
, DATE_SECONDS
, OO_NS_NUMBER
, "seconds", GSF_XML_NO_CONTENT
, &oo_date_seconds
, NULL
),
11937 GSF_XML_IN_NODE (DATE_STYLE
, DATE_AM_PM
, OO_NS_NUMBER
, "am-pm", GSF_XML_NO_CONTENT
, &oo_date_am_pm
, NULL
),
11938 GSF_XML_IN_NODE (DATE_STYLE
, DATE_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
11939 GSF_XML_IN_NODE (DATE_STYLE
, DATE_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
11940 GSF_XML_IN_NODE (DATE_STYLE
, DATE_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11941 GSF_XML_IN_NODE (DATE_STYLE
, DATE_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11943 GSF_XML_IN_NODE (OFFICE_STYLES
, TIME_STYLE
, OO_NS_NUMBER
, "time-style", GSF_XML_NO_CONTENT
, &oo_date_style
, &oo_date_style_end
),
11944 GSF_XML_IN_NODE (TIME_STYLE
, TIME_HOURS
, OO_NS_NUMBER
, "hours", GSF_XML_NO_CONTENT
, &oo_date_hours
, NULL
),
11945 GSF_XML_IN_NODE (TIME_STYLE
, TIME_MINUTES
, OO_NS_NUMBER
, "minutes", GSF_XML_NO_CONTENT
, &oo_date_minutes
, NULL
),
11946 GSF_XML_IN_NODE (TIME_STYLE
, TIME_SECONDS
, OO_NS_NUMBER
, "seconds", GSF_XML_NO_CONTENT
, &oo_date_seconds
, NULL
),
11947 GSF_XML_IN_NODE (TIME_STYLE
, TIME_AM_PM
, OO_NS_NUMBER
, "am-pm", GSF_XML_NO_CONTENT
, &oo_date_am_pm
, NULL
),
11948 GSF_XML_IN_NODE (TIME_STYLE
, TIME_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
11949 GSF_XML_IN_NODE (TIME_STYLE
, TIME_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
11950 GSF_XML_IN_NODE (TIME_STYLE
, TIME_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11951 GSF_XML_IN_NODE (TIME_STYLE
, TIME_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11953 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_BOOL
, OO_NS_NUMBER
, "boolean-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11954 GSF_XML_IN_NODE (STYLE_BOOL
, BOOL_PROP
, OO_NS_NUMBER
, "boolean", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11956 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_CURRENCY
, OO_NS_NUMBER
, "currency-style", GSF_XML_NO_CONTENT
, &odf_number_style
, &odf_number_style_end
),
11957 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_STYLE
, OO_NS_NUMBER
, "number", GSF_XML_NO_CONTENT
, &odf_number
, NULL
),
11958 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_STYLE_PROP
, OO_NS_STYLE
, "properties", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11959 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, &odf_map
, NULL
),
11960 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_SYMBOL
, OO_NS_NUMBER
, "currency-symbol", GSF_XML_CONTENT
, NULL
, &odf_currency_symbol_end
),
11961 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
11962 GSF_XML_IN_NODE (CURRENCY_TEXT
, FORMAT_TEXT_INVISIBLE
, OO_GNUM_NS_EXT
, "invisible", GSF_XML_2ND
, NULL
, NULL
),
11963 GSF_XML_IN_NODE (CURRENCY_TEXT
, FORMAT_TEXT_REPEATED
, OO_GNUM_NS_EXT
, "repeated", GSF_XML_2ND
, NULL
, NULL
),
11964 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
11965 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11967 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_PERCENTAGE
, OO_NS_NUMBER
, "percentage-style", GSF_XML_NO_CONTENT
, &odf_number_percentage_style
, &odf_number_style_end
),
11968 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_STYLE_PROP
, OO_NS_NUMBER
, "number", GSF_XML_NO_CONTENT
, &odf_number
, NULL
),
11969 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
11970 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, &odf_map
, NULL
),
11971 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
11972 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11974 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_TEXT
, OO_NS_NUMBER
, "text-style", GSF_XML_NO_CONTENT
, &odf_number_style
, &odf_number_style_end
),
11975 GSF_XML_IN_NODE (STYLE_TEXT
, STYLE_TEXT_CONTENT
, OO_NS_NUMBER
, "text-content", GSF_XML_NO_CONTENT
, &odf_text_content
, NULL
),
11976 GSF_XML_IN_NODE (STYLE_TEXT
, STYLE_TEXT_PROP
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
11977 GSF_XML_IN_NODE (STYLE_TEXT_PROP
, FORMAT_TEXT_INVISIBLE
, OO_GNUM_NS_EXT
, "invisible", GSF_XML_2ND
, NULL
, NULL
),
11978 GSF_XML_IN_NODE (STYLE_TEXT
, STYLE_TEXT_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, &odf_map
, NULL
),
11979 GSF_XML_IN_NODE (STYLE_TEXT
, STYLE_TEXT_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
11981 GSF_XML_IN_NODE (OFFICE_DOC_STYLES
, AUTOMATIC_STYLES
, OO_NS_OFFICE
, "automatic-styles", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11982 GSF_XML_IN_NODE (AUTOMATIC_STYLES
, PAGE_MASTER
, OO_NS_STYLE
, "page-master", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* ooo1 */
11983 GSF_XML_IN_NODE (PAGE_MASTER
, PAGE_MASTER_PROPS
, OO_NS_STYLE
, "properties", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11984 GSF_XML_IN_NODE (PAGE_MASTER_PROPS
, PAGE_MASTER_BG_IMAGE
, OO_NS_STYLE
, "background-image", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11985 GSF_XML_IN_NODE (PAGE_MASTER
, PAGE_MASTER_HEADER
, OO_NS_STYLE
, "header-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11986 GSF_XML_IN_NODE (PAGE_MASTER_HEADER
, PAGE_MASTER_PROPS
, OO_NS_STYLE
, "properties", GSF_XML_2ND
, NULL
, NULL
),
11987 GSF_XML_IN_NODE (PAGE_MASTER
, PAGE_MASTER_FOOTER
, OO_NS_STYLE
, "footer-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11988 GSF_XML_IN_NODE (PAGE_MASTER_FOOTER
, PAGE_MASTER_PROPS
, OO_NS_STYLE
, "properties", GSF_XML_2ND
, NULL
, NULL
),
11990 GSF_XML_IN_NODE (AUTOMATIC_STYLES
, STYLE
, OO_NS_STYLE
, "style", GSF_XML_2ND
, NULL
, NULL
),
11991 GSF_XML_IN_NODE (AUTOMATIC_STYLES
, PAGE_LAYOUT
, OO_NS_STYLE
, "page-layout", GSF_XML_NO_CONTENT
, &odf_page_layout
, &odf_page_layout_end
),
11992 GSF_XML_IN_NODE (PAGE_LAYOUT
, PAGE_LAYOUT_PROPS
, OO_NS_STYLE
, "page-layout-properties", GSF_XML_NO_CONTENT
, &odf_page_layout_properties
, NULL
),
11993 GSF_XML_IN_NODE (PAGE_LAYOUT_PROPS
, BACK_IMAGE
, OO_NS_STYLE
, "background-image", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11994 GSF_XML_IN_NODE (PAGE_LAYOUT
, HEADER_STYLE
, OO_NS_STYLE
, "header-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11995 GSF_XML_IN_NODE (HEADER_STYLE
, HEADER_PROPERTIES
, OO_NS_STYLE
, "header-footer-properties", GSF_XML_NO_CONTENT
, odf_header_properties
, NULL
),
11996 GSF_XML_IN_NODE (HEADER_PROPERTIES
, HF_BACK_IMAGE
, OO_NS_STYLE
, "background-image", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11997 GSF_XML_IN_NODE (PAGE_LAYOUT
, FOOTER_STYLE
, OO_NS_STYLE
, "footer-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
11998 GSF_XML_IN_NODE (FOOTER_STYLE
, FOOTER_PROPERTIES
, OO_NS_STYLE
, "header-footer-properties", GSF_XML_NO_CONTENT
, odf_footer_properties
, NULL
),
11999 GSF_XML_IN_NODE (FOOTER_PROPERTIES
, HF_BACK_IMAGE
, OO_NS_STYLE
, "background-image", GSF_XML_2ND
, NULL
, NULL
),
12000 GSF_XML_IN_NODE (AUTOMATIC_STYLES
, NUMBER_STYLE
, OO_NS_NUMBER
, "number-style", GSF_XML_2ND
, NULL
, NULL
),
12001 GSF_XML_IN_NODE (AUTOMATIC_STYLES
, DATE_STYLE
, OO_NS_NUMBER
, "date-style", GSF_XML_2ND
, NULL
, NULL
),
12002 GSF_XML_IN_NODE (AUTOMATIC_STYLES
, TIME_STYLE
, OO_NS_NUMBER
, "time-style", GSF_XML_2ND
, NULL
, NULL
),
12003 GSF_XML_IN_NODE (AUTOMATIC_STYLES
, STYLE_BOOL
, OO_NS_NUMBER
, "boolean-style", GSF_XML_2ND
, NULL
, NULL
),
12004 GSF_XML_IN_NODE (AUTOMATIC_STYLES
, STYLE_CURRENCY
, OO_NS_NUMBER
, "currency-style", GSF_XML_2ND
, NULL
, NULL
),
12005 GSF_XML_IN_NODE (AUTOMATIC_STYLES
, STYLE_PERCENTAGE
, OO_NS_NUMBER
, "percentage-style", GSF_XML_2ND
, NULL
, NULL
),
12006 GSF_XML_IN_NODE (AUTOMATIC_STYLES
, STYLE_TEXT
, OO_NS_NUMBER
, "text-style", GSF_XML_2ND
, NULL
, NULL
),
12008 GSF_XML_IN_NODE (OFFICE_DOC_STYLES
, MASTER_STYLES
, OO_NS_OFFICE
, "master-styles", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12009 GSF_XML_IN_NODE (MASTER_STYLES
, MASTER_PAGE
, OO_NS_STYLE
, "master-page", GSF_XML_NO_CONTENT
, &odf_master_page
, &odf_master_page_end
),
12010 GSF_XML_IN_NODE (MASTER_PAGE
, MASTER_PAGE_HEADER_LEFT
, OO_NS_STYLE
, "header-left", GSF_XML_NO_CONTENT
, &odf_header_footer_left
, NULL
),
12011 GSF_XML_IN_NODE (MASTER_PAGE_HEADER_LEFT
, MASTER_PAGE_HEADER_FOOTER_LEFT_P
, OO_NS_TEXT
, "p", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12012 GSF_XML_IN_NODE (MASTER_PAGE_HEADER_FOOTER_LEFT_P
, MASTER_PAGE_HEADER_FOOTER_LEFT_SPAN
, OO_NS_TEXT
, "span", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12013 GSF_XML_IN_NODE (MASTER_PAGE_HEADER_FOOTER_LEFT_SPAN
, MASTER_PAGE_HEADER_FOOTER_LEFT_PAGE_NUMBER
, OO_NS_TEXT
, "page-number", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12014 GSF_XML_IN_NODE (MASTER_PAGE_HEADER_FOOTER_LEFT_SPAN
, MASTER_PAGE_HEADER_FOOTER_LEFT_SHEET_NAME
, OO_NS_TEXT
, "sheet-name", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12015 GSF_XML_IN_NODE (MASTER_PAGE
, MASTER_PAGE_FOOTER_LEFT
, OO_NS_STYLE
, "footer-left", GSF_XML_NO_CONTENT
, &odf_header_footer_left
, NULL
),
12016 GSF_XML_IN_NODE (MASTER_PAGE_FOOTER_LEFT
, MASTER_PAGE_HEADER_FOOTER_LEFT_P
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12017 GSF_XML_IN_NODE_FULL (MASTER_PAGE
, MASTER_PAGE_HEADER
, OO_NS_STYLE
, "header", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &odf_header_footer
, &odf_header_footer_end
, 0),
12018 GSF_XML_IN_NODE_FULL (MASTER_PAGE_HEADER
, MASTER_PAGE_HF_R_LEFT
, OO_NS_STYLE
, "region-left", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &odf_hf_region
, &odf_hf_region_end
, 0),
12019 GSF_XML_IN_NODE (MASTER_PAGE_HF_R_LEFT
, MASTER_PAGE_HF_P
, OO_NS_TEXT
, "p", GSF_XML_CONTENT
, &odf_text_content_start
, &odf_text_content_end
),
12020 GSF_XML_IN_NODE (MASTER_PAGE_HF_P
, TEXT_S
, OO_NS_TEXT
, "s", GSF_XML_NO_CONTENT
, &odf_text_space
, NULL
),
12021 GSF_XML_IN_NODE_FULL (MASTER_PAGE_HF_P
, TEXT_LINE_BREAK
, OO_NS_TEXT
, "line-break", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &odf_text_symbol
, NULL
, .v_str
= "\n"),
12022 GSF_XML_IN_NODE_FULL (MASTER_PAGE_HF_P
, TEXT_TAB
, OO_NS_TEXT
, "tab", GSF_XML_SHARED_CONTENT
, FALSE
, FALSE
, odf_text_symbol
, NULL
, .v_str
= "\t"),
12023 GSF_XML_IN_NODE (MASTER_PAGE_HF_P
, HF_TITLE
, OO_NS_TEXT
, "title", GSF_XML_NO_CONTENT
, &odf_hf_title
, NULL
),
12024 GSF_XML_IN_NODE (MASTER_PAGE_HF_P
, HF_DATE
, OO_NS_TEXT
, "date", GSF_XML_NO_CONTENT
, &odf_hf_date
, NULL
),
12025 GSF_XML_IN_NODE (MASTER_PAGE_HF_P
, HF_TIME
, OO_NS_TEXT
, "time", GSF_XML_NO_CONTENT
, &odf_hf_time
, NULL
),
12026 GSF_XML_IN_NODE (MASTER_PAGE_HF_P
, HF_SHEET_NAME
, OO_NS_TEXT
, "sheet-name", GSF_XML_NO_CONTENT
, &odf_hf_sheet_name
, NULL
),
12027 GSF_XML_IN_NODE (MASTER_PAGE_HF_P
, HF_PAGE_NUMBER
, OO_NS_TEXT
, "page-number", GSF_XML_NO_CONTENT
, &odf_hf_page_number
, NULL
),
12028 GSF_XML_IN_NODE (MASTER_PAGE_HF_P
, HF_PAGE_COUNT
, OO_NS_TEXT
, "page-count", GSF_XML_NO_CONTENT
, &odf_hf_page_count
, NULL
),
12029 GSF_XML_IN_NODE (MASTER_PAGE_HF_P
, HF_FILE_NAME
, OO_NS_TEXT
, "file-name", GSF_XML_NO_CONTENT
, &odf_hf_file
, NULL
),
12030 GSF_XML_IN_NODE (MASTER_PAGE_HF_P
, HF_EXPRESSION
, OO_NS_TEXT
, "expression", GSF_XML_NO_CONTENT
, &odf_hf_expression
, NULL
),
12031 GSF_XML_IN_NODE (MASTER_PAGE_HF_P
, TEXT_SPAN
, OO_NS_TEXT
, "span", GSF_XML_SHARED_CONTENT
, &odf_text_span_start
, &odf_text_span_end
),
12032 GSF_XML_IN_NODE (TEXT_SPAN
, TEXT_SPAN
, OO_NS_TEXT
, "span", GSF_XML_2ND
, NULL
, NULL
),
12033 GSF_XML_IN_NODE (TEXT_SPAN
, TEXT_S
, OO_NS_TEXT
, "s", GSF_XML_2ND
, NULL
, NULL
),
12034 GSF_XML_IN_NODE (TEXT_SPAN
, TEXT_LINE_BREAK
, OO_NS_TEXT
, "line-break", GSF_XML_2ND
, NULL
, NULL
),
12035 GSF_XML_IN_NODE (TEXT_SPAN
, TEXT_TAB
, OO_NS_TEXT
, "tab", GSF_XML_2ND
, NULL
, NULL
),
12036 GSF_XML_IN_NODE (TEXT_SPAN
, HF_SHEET_NAME
, OO_NS_TEXT
, "sheet-name", GSF_XML_2ND
, NULL
, NULL
),
12037 GSF_XML_IN_NODE (TEXT_SPAN
, HF_PAGE_NUMBER
, OO_NS_TEXT
, "page-number", GSF_XML_2ND
, NULL
, NULL
),
12038 GSF_XML_IN_NODE (TEXT_SPAN
, HF_PAGE_COUNT
, OO_NS_TEXT
, "page-count", GSF_XML_2ND
, NULL
, NULL
),
12039 GSF_XML_IN_NODE (TEXT_SPAN
, HF_FILE_NAME
, OO_NS_TEXT
, "file-name", GSF_XML_2ND
, NULL
, NULL
),
12040 GSF_XML_IN_NODE (TEXT_SPAN
, HF_EXPRESSION
, OO_NS_TEXT
, "expression", GSF_XML_2ND
, NULL
, NULL
),
12042 GSF_XML_IN_NODE_FULL (MASTER_PAGE_HEADER
, MASTER_PAGE_HF_R_RIGHT
, OO_NS_STYLE
, "region-right", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &odf_hf_region
, &odf_hf_region_end
, 2),
12043 GSF_XML_IN_NODE (MASTER_PAGE_HF_R_RIGHT
, MASTER_PAGE_HF_P
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12044 GSF_XML_IN_NODE_FULL (MASTER_PAGE_HEADER
, MASTER_PAGE_HF_R_CENTER
, OO_NS_STYLE
, "region-center", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &odf_hf_region
, &odf_hf_region_end
, 1),
12045 GSF_XML_IN_NODE (MASTER_PAGE_HF_R_CENTER
, MASTER_PAGE_HF_P
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12046 GSF_XML_IN_NODE (MASTER_PAGE_HEADER
, MASTER_PAGE_HF_P
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12047 GSF_XML_IN_NODE_FULL (MASTER_PAGE
, MASTER_PAGE_FOOTER
, OO_NS_STYLE
, "footer", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &odf_header_footer
, &odf_header_footer_end
, 1),
12048 GSF_XML_IN_NODE (MASTER_PAGE_FOOTER
, MASTER_PAGE_HF_R_LEFT
, OO_NS_STYLE
, "region-left", GSF_XML_2ND
, NULL
, NULL
),
12049 GSF_XML_IN_NODE (MASTER_PAGE_FOOTER
, MASTER_PAGE_HF_R_RIGHT
, OO_NS_STYLE
, "region-right", GSF_XML_2ND
, NULL
, NULL
),
12050 GSF_XML_IN_NODE (MASTER_PAGE_FOOTER
, MASTER_PAGE_HF_R_CENTER
, OO_NS_STYLE
, "region-center", GSF_XML_2ND
, NULL
, NULL
),
12051 GSF_XML_IN_NODE (MASTER_PAGE_FOOTER
, MASTER_PAGE_HF_P
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12052 GSF_XML_IN_NODE_END
12055 static GsfXMLInNode
const ooo1_content_dtd
[] = {
12056 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
12057 GSF_XML_IN_NODE (START
, OFFICE
, OO_NS_OFFICE
, "document-content", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12058 GSF_XML_IN_NODE (OFFICE
, SCRIPT
, OO_NS_OFFICE
, "script", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12059 GSF_XML_IN_NODE (OFFICE
, OFFICE_FONTS
, OO_NS_OFFICE
, "font-decls", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12060 GSF_XML_IN_NODE (OFFICE_FONTS
, FONT_DECL
, OO_NS_STYLE
, "font-decl", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12061 GSF_XML_IN_NODE (OFFICE
, OFFICE_STYLES
, OO_NS_OFFICE
, "automatic-styles", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12062 GSF_XML_IN_NODE (OFFICE_STYLES
, PAGE_MASTER
, OO_NS_STYLE
, "page-master", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12063 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE
, OO_NS_STYLE
, "style", GSF_XML_NO_CONTENT
, &oo_style
, &oo_style_end
),
12064 GSF_XML_IN_NODE (STYLE
, STYLE_PROP
, OO_NS_STYLE
, "properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
12065 GSF_XML_IN_NODE (STYLE_PROP
, STYLE_TAB_STOPS
, OO_NS_STYLE
, "tab-stops", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12067 GSF_XML_IN_NODE (OFFICE_STYLES
, NUMBER_STYLE
, OO_NS_NUMBER
, "number-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12068 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_NUMBER
, OO_NS_NUMBER
, "number", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12069 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12070 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_FRACTION
, OO_NS_NUMBER
, "fraction", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12071 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_SCI_STYLE_PROP
, OO_NS_NUMBER
, "scientific-number", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12072 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_PROP
, OO_NS_STYLE
, "properties", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12073 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12074 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12076 GSF_XML_IN_NODE (OFFICE_STYLES
, DATE_STYLE
, OO_NS_NUMBER
, "date-style", GSF_XML_NO_CONTENT
, &oo_date_style
, &oo_date_style_end
),
12077 GSF_XML_IN_NODE (DATE_STYLE
, DATE_DAY
, OO_NS_NUMBER
, "day", GSF_XML_NO_CONTENT
, &oo_date_day
, NULL
),
12078 GSF_XML_IN_NODE (DATE_STYLE
, DATE_MONTH
, OO_NS_NUMBER
, "month", GSF_XML_NO_CONTENT
, &oo_date_month
, NULL
),
12079 GSF_XML_IN_NODE (DATE_STYLE
, DATE_YEAR
, OO_NS_NUMBER
, "year", GSF_XML_NO_CONTENT
, &oo_date_year
, NULL
),
12080 GSF_XML_IN_NODE (DATE_STYLE
, DATE_ERA
, OO_NS_NUMBER
, "era", GSF_XML_NO_CONTENT
, &oo_date_era
, NULL
),
12081 GSF_XML_IN_NODE (DATE_STYLE
, DATE_DAY_OF_WEEK
, OO_NS_NUMBER
, "day-of-week", GSF_XML_NO_CONTENT
, &oo_date_day_of_week
, NULL
),
12082 GSF_XML_IN_NODE (DATE_STYLE
, DATE_WEEK_OF_YEAR
, OO_NS_NUMBER
, "week-of-year", GSF_XML_NO_CONTENT
, &oo_date_week_of_year
, NULL
),
12083 GSF_XML_IN_NODE (DATE_STYLE
, DATE_QUARTER
, OO_NS_NUMBER
, "quarter", GSF_XML_NO_CONTENT
, &oo_date_quarter
, NULL
),
12084 GSF_XML_IN_NODE (DATE_STYLE
, DATE_HOURS
, OO_NS_NUMBER
, "hours", GSF_XML_NO_CONTENT
, &oo_date_hours
, NULL
),
12085 GSF_XML_IN_NODE (DATE_STYLE
, DATE_MINUTES
, OO_NS_NUMBER
, "minutes", GSF_XML_NO_CONTENT
, &oo_date_minutes
, NULL
),
12086 GSF_XML_IN_NODE (DATE_STYLE
, DATE_SECONDS
, OO_NS_NUMBER
, "seconds", GSF_XML_NO_CONTENT
, &oo_date_seconds
, NULL
),
12087 GSF_XML_IN_NODE (DATE_STYLE
, DATE_AM_PM
, OO_NS_NUMBER
, "am-pm", GSF_XML_NO_CONTENT
, &oo_date_am_pm
, NULL
),
12088 GSF_XML_IN_NODE (DATE_STYLE
, DATE_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
12089 GSF_XML_IN_NODE (DATE_STYLE
, DATE_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12090 GSF_XML_IN_NODE (DATE_STYLE
, DATE_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12091 GSF_XML_IN_NODE (DATE_STYLE
, DATE_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12093 GSF_XML_IN_NODE (OFFICE_STYLES
, TIME_STYLE
, OO_NS_NUMBER
, "time-style", GSF_XML_NO_CONTENT
, &oo_date_style
, &oo_date_style_end
),
12094 GSF_XML_IN_NODE (TIME_STYLE
, TIME_HOURS
, OO_NS_NUMBER
, "hours", GSF_XML_NO_CONTENT
, &oo_date_hours
, NULL
),
12095 GSF_XML_IN_NODE (TIME_STYLE
, TIME_MINUTES
, OO_NS_NUMBER
, "minutes", GSF_XML_NO_CONTENT
, &oo_date_minutes
, NULL
),
12096 GSF_XML_IN_NODE (TIME_STYLE
, TIME_SECONDS
, OO_NS_NUMBER
, "seconds", GSF_XML_NO_CONTENT
, &oo_date_seconds
, NULL
),
12097 GSF_XML_IN_NODE (TIME_STYLE
, TIME_AM_PM
, OO_NS_NUMBER
, "am-pm", GSF_XML_NO_CONTENT
, &oo_date_am_pm
, NULL
),
12098 GSF_XML_IN_NODE (TIME_STYLE
, TIME_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
12099 GSF_XML_IN_NODE (TIME_STYLE
, TIME_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12100 GSF_XML_IN_NODE (TIME_STYLE
, TIME_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12101 GSF_XML_IN_NODE (TIME_STYLE
, TIME_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12103 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_BOOL
, OO_NS_NUMBER
, "boolean-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12104 GSF_XML_IN_NODE (STYLE_BOOL
, BOOL_PROP
, OO_NS_NUMBER
, "boolean", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12105 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_CURRENCY
, OO_NS_NUMBER
, "currency-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12106 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_STYLE
, OO_NS_NUMBER
, "number", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12107 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_STYLE_PROP
, OO_NS_STYLE
, "properties", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12108 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12109 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_SYMBOL
, OO_NS_NUMBER
, "currency-symbol", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12110 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12111 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12112 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_PERCENTAGE
, OO_NS_NUMBER
, "percentage-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12113 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_STYLE_PROP
, OO_NS_NUMBER
, "number", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12114 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12115 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12116 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_TEXT
, OO_NS_NUMBER
, "text-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12117 GSF_XML_IN_NODE (STYLE_TEXT
, STYLE_TEXT_CONTENT
, OO_NS_NUMBER
, "text-content", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12118 GSF_XML_IN_NODE (STYLE_TEXT
, STYLE_TEXT_PROP
, OO_NS_NUMBER
, "text", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12119 GSF_XML_IN_NODE (STYLE_TEXT
, STYLE_TEXT_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12121 GSF_XML_IN_NODE (OFFICE
, OFFICE_BODY
, OO_NS_OFFICE
, "body", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12122 GSF_XML_IN_NODE (OFFICE_BODY
, TABLE_CALC_SETTINGS
, OO_NS_TABLE
, "calculation-settings", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12123 GSF_XML_IN_NODE (TABLE_CALC_SETTINGS
, DATE_CONVENTION
, OO_NS_TABLE
, "null-date", GSF_XML_NO_CONTENT
, &oo_date_convention
, NULL
),
12124 GSF_XML_IN_NODE (TABLE_CALC_SETTINGS
, ITERATION
, OO_NS_TABLE
, "iteration", GSF_XML_NO_CONTENT
, oo_iteration
, NULL
),
12125 GSF_XML_IN_NODE (OFFICE_BODY
, VALIDATIONS
, OO_NS_TABLE
, "content-validations", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12126 GSF_XML_IN_NODE (VALIDATIONS
, VALIDATION
, OO_NS_TABLE
, "content-validation", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12127 GSF_XML_IN_NODE (VALIDATION
, VALIDATION_MSG
, OO_NS_TABLE
, "error-message", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12129 GSF_XML_IN_NODE (OFFICE_BODY
, TABLE
, OO_NS_TABLE
, "table", GSF_XML_NO_CONTENT
, &oo_table_start
, &oo_table_end
),
12130 GSF_XML_IN_NODE (TABLE
, FORMS
, OO_NS_OFFICE
, "forms", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12131 GSF_XML_IN_NODE (TABLE
, TABLE_COL
, OO_NS_TABLE
, "table-column", GSF_XML_NO_CONTENT
, &oo_col_start
, NULL
),
12132 GSF_XML_IN_NODE (TABLE
, TABLE_ROW
, OO_NS_TABLE
, "table-row", GSF_XML_NO_CONTENT
, &oo_row_start
, &oo_row_end
),
12133 GSF_XML_IN_NODE (TABLE_ROW
, TABLE_CELL
, OO_NS_TABLE
, "table-cell", GSF_XML_NO_CONTENT
, &oo_cell_start
, &oo_cell_end
),
12134 GSF_XML_IN_NODE (TABLE_CELL
, CELL_CONTROL
, OO_NS_DRAW
, "control", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12135 GSF_XML_IN_NODE (TABLE_CELL
, CELL_TEXT
, OO_NS_TEXT
, "p", GSF_XML_CONTENT
, &oo_cell_content_start
, &oo_cell_content_end
),
12136 GSF_XML_IN_NODE (CELL_TEXT
, CELL_TEXT_S
, OO_NS_TEXT
, "s", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12137 GSF_XML_IN_NODE (CELL_TEXT
, CELL_TEXT_SPAN
, OO_NS_TEXT
, "span", GSF_XML_SHARED_CONTENT
, NULL
, NULL
),
12138 GSF_XML_IN_NODE (TABLE_CELL
, CELL_OBJECT
, OO_NS_DRAW
, "object", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* ignore for now */
12139 GSF_XML_IN_NODE (TABLE_CELL
, CELL_GRAPHIC
, OO_NS_DRAW
, "g", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* ignore for now */
12140 GSF_XML_IN_NODE (CELL_GRAPHIC
, CELL_GRAPHIC
, OO_NS_DRAW
, "g", GSF_XML_2ND
, NULL
, NULL
),
12141 GSF_XML_IN_NODE (CELL_GRAPHIC
, DRAW_POLYLINE
, OO_NS_DRAW
, "polyline", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12142 GSF_XML_IN_NODE (TABLE_CELL
, DRAW_LINE
, OO_NS_DRAW
, "line", GSF_XML_NO_CONTENT
, &odf_line
, &odf_line_end
),
12143 GSF_XML_IN_NODE (DRAW_LINE
, IGNORED_TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* ignore for now */
12144 GSF_XML_IN_NODE (TABLE_ROW
, TABLE_COVERED_CELL
, OO_NS_TABLE
, "covered-table-cell", GSF_XML_NO_CONTENT
, &oo_covered_cell_start
, &oo_covered_cell_end
),
12145 GSF_XML_IN_NODE (TABLE_COVERED_CELL
, DRAW_LINE
, OO_NS_DRAW
, "line", GSF_XML_2ND
, NULL
, NULL
),
12146 GSF_XML_IN_NODE (TABLE
, TABLE_COL_GROUP
, OO_NS_TABLE
, "table-column-group", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12147 GSF_XML_IN_NODE (TABLE_COL_GROUP
, TABLE_COL_GROUP
, OO_NS_TABLE
, "table-column-group", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12148 GSF_XML_IN_NODE (TABLE_COL_GROUP
, TABLE_COL
, OO_NS_TABLE
, "table-column", GSF_XML_2ND
, NULL
, NULL
),
12149 GSF_XML_IN_NODE (TABLE
, TABLE_ROW_GROUP
, OO_NS_TABLE
, "table-row-group", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12150 GSF_XML_IN_NODE (TABLE_ROW_GROUP
, TABLE_ROW_GROUP
, OO_NS_TABLE
, "table-row-group", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12151 GSF_XML_IN_NODE (TABLE_ROW_GROUP
, TABLE_ROW
, OO_NS_TABLE
, "table-row", GSF_XML_2ND
, NULL
, NULL
),
12152 GSF_XML_IN_NODE (OFFICE_BODY
, NAMED_EXPRS
, OO_NS_TABLE
, "named-expressions", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12153 GSF_XML_IN_NODE (NAMED_EXPRS
, NAMED_EXPR
, OO_NS_TABLE
, "named-expression", GSF_XML_NO_CONTENT
, &oo_named_expr
, NULL
),
12154 GSF_XML_IN_NODE (NAMED_EXPRS
, NAMED_RANGE
, OO_NS_TABLE
, "named-range", GSF_XML_NO_CONTENT
, &oo_named_expr
, NULL
),
12155 GSF_XML_IN_NODE (OFFICE_BODY
, DB_RANGES
, OO_NS_TABLE
, "database-ranges", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12156 GSF_XML_IN_NODE (DB_RANGES
, DB_RANGE
, OO_NS_TABLE
, "database-range", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12157 GSF_XML_IN_NODE (DB_RANGE
, TABLE_SORT
, OO_NS_TABLE
, "sort", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12158 GSF_XML_IN_NODE (TABLE_SORT
, SORT_BY
, OO_NS_TABLE
, "sort-by", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12160 GSF_XML_IN_NODE_END
12163 /****************************************************************************/
12165 static GsfXMLInNode
const opendoc_settings_dtd
[] = {
12166 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
12167 GSF_XML_IN_NODE (START
, OFFICE
, OO_NS_OFFICE
, "document-settings", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12168 GSF_XML_IN_NODE (OFFICE
, SETTINGS
, OO_NS_OFFICE
, "settings", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12169 GSF_XML_IN_NODE (SETTINGS
, CONFIG_ITEM_SET
, OO_NS_CONFIG
, "config-item-set", GSF_XML_NO_CONTENT
, &odf_config_item_set
, &odf_config_stack_pop
),
12170 GSF_XML_IN_NODE (CONFIG_ITEM_SET
, CONFIG_ITEM_SET
, OO_NS_CONFIG
, "config-item-set", GSF_XML_2ND
, NULL
, NULL
),
12171 GSF_XML_IN_NODE (CONFIG_ITEM_SET
, CONFIG_ITEM
, OO_NS_CONFIG
, "config-item", GSF_XML_CONTENT
, &odf_config_item
, &odf_config_item_end
),
12172 GSF_XML_IN_NODE (CONFIG_ITEM_SET
, CONFIG_ITEM_MAP_INDEXED
, OO_NS_CONFIG
, "config-item-map-indexed", GSF_XML_NO_CONTENT
, &odf_config_item_set
, &odf_config_stack_pop
),
12173 GSF_XML_IN_NODE (CONFIG_ITEM_MAP_INDEXED
, CONFIG_ITEM_MAP_ENTRY
, OO_NS_CONFIG
, "config-item-map-entry", GSF_XML_NO_CONTENT
, &odf_config_item_set
, &odf_config_stack_pop
),
12174 GSF_XML_IN_NODE (CONFIG_ITEM_MAP_ENTRY
, CONFIG_ITEM_MAP_INDEXED
, OO_NS_CONFIG
, "config-item-map-indexed", GSF_XML_2ND
, NULL
, NULL
),
12175 GSF_XML_IN_NODE (CONFIG_ITEM_MAP_ENTRY
, CONFIG_ITEM
, OO_NS_CONFIG
, "config-item", GSF_XML_2ND
, NULL
, NULL
),
12176 GSF_XML_IN_NODE (CONFIG_ITEM_MAP_ENTRY
, CONFIG_ITEM_MAP_NAMED
, OO_NS_CONFIG
, "config-item-map-named", GSF_XML_NO_CONTENT
, &odf_config_item_set
, &odf_config_stack_pop
),
12177 GSF_XML_IN_NODE (CONFIG_ITEM_MAP_ENTRY
, CONFIG_ITEM_SET
, OO_NS_CONFIG
, "config-item-set", GSF_XML_2ND
, NULL
, NULL
),
12178 GSF_XML_IN_NODE (CONFIG_ITEM_SET
, CONFIG_ITEM_MAP_NAMED
, OO_NS_CONFIG
, "config-item-map-named", GSF_XML_2ND
, NULL
, NULL
),
12179 GSF_XML_IN_NODE (CONFIG_ITEM_MAP_NAMED
, CONFIG_ITEM_MAP_ENTRY
, OO_NS_CONFIG
, "config-item-map-entry", GSF_XML_2ND
, NULL
, NULL
),
12181 GSF_XML_IN_NODE_END
12184 /****************************************************************************/
12185 /* Generated based on:
12186 * http://www.oasis-open.org/committees/download.php/12572/OpenDocument-v1.0-os.pdf */
12187 static GsfXMLInNode
const opendoc_content_dtd
[] =
12189 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
12190 GSF_XML_IN_NODE (START
, OFFICE
, OO_NS_OFFICE
, "document-content", GSF_XML_NO_CONTENT
, &odf_find_version
, NULL
),
12191 GSF_XML_IN_NODE (OFFICE
, SCRIPT
, OO_NS_OFFICE
, "scripts", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12192 GSF_XML_IN_NODE (OFFICE
, OFFICE_FONTS
, OO_NS_OFFICE
, "font-face-decls", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12193 GSF_XML_IN_NODE (OFFICE_FONTS
, FONT_FACE
, OO_NS_STYLE
, "font-face", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12194 GSF_XML_IN_NODE (OFFICE
, OFFICE_STYLES
, OO_NS_OFFICE
, "automatic-styles", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12195 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE
, OO_NS_STYLE
, "style", GSF_XML_NO_CONTENT
, &oo_style
, &oo_style_end
),
12196 GSF_XML_IN_NODE (STYLE
, TABLE_CELL_PROPS
, OO_NS_STYLE
, "table-cell-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
12197 GSF_XML_IN_NODE (STYLE
, TABLE_COL_PROPS
, OO_NS_STYLE
, "table-column-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
12198 GSF_XML_IN_NODE (STYLE
, TABLE_ROW_PROPS
, OO_NS_STYLE
, "table-row-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
12199 GSF_XML_IN_NODE (STYLE
, CHART_PROPS
, OO_NS_STYLE
, "chart-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
12200 GSF_XML_IN_NODE (STYLE
, TEXT_PROPS
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
12201 GSF_XML_IN_NODE (STYLE
, TABLE_PROPS
, OO_NS_STYLE
, "table-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
12202 GSF_XML_IN_NODE (STYLE
, PARAGRAPH_PROPS
, OO_NS_STYLE
, "paragraph-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
12203 GSF_XML_IN_NODE (PARAGRAPH_PROPS
, PARA_TABS
, OO_NS_STYLE
, "tab-stops", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12204 GSF_XML_IN_NODE (STYLE
, GRAPHIC_PROPS
, OO_NS_STYLE
, "graphic-properties", GSF_XML_NO_CONTENT
, &oo_style_prop
, NULL
),
12205 GSF_XML_IN_NODE (STYLE
, STYLE_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, &oo_style_map
, NULL
),
12206 GSF_XML_IN_NODE (OFFICE_STYLES
, NUMBER_STYLE
, OO_NS_NUMBER
, "number-style", GSF_XML_NO_CONTENT
, &odf_number_style
, &odf_number_style_end
),
12207 #if HAVE_OO_NS_LOCALC_EXT
12208 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_NUMBERFILL_CHARACTER
, OO_NS_LOCALC_EXT
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12209 GSF_XML_IN_NODE (NUMBER_STYLE
, LOEXT_TEXT
, OO_NS_LOCALC_EXT
, "text", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12211 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_NUMBER
, OO_NS_NUMBER
, "number", GSF_XML_NO_CONTENT
, &odf_number
, NULL
),
12212 GSF_XML_IN_NODE (NUMBER_STYLE_NUMBER
, NUMBER_EMBEDDED_TEXT
, OO_NS_NUMBER
, "embedded-text", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12213 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
12214 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_STYLE_FRACTION
, OO_NS_NUMBER
, "fraction", GSF_XML_NO_CONTENT
, &odf_fraction
, NULL
),
12215 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_SCI_STYLE_PROP
, OO_NS_NUMBER
, "scientific-number", GSF_XML_NO_CONTENT
, &odf_scientific
, NULL
),
12216 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, &odf_map
, NULL
),
12217 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
12218 GSF_XML_IN_NODE (NUMBER_STYLE
, NUMBER_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12219 GSF_XML_IN_NODE (OFFICE_STYLES
, DATE_STYLE
, OO_NS_NUMBER
, "date-style", GSF_XML_NO_CONTENT
, &oo_date_style
, &oo_date_style_end
),
12220 GSF_XML_IN_NODE (DATE_STYLE
, DATE_DAY
, OO_NS_NUMBER
, "day", GSF_XML_NO_CONTENT
, &oo_date_day
, NULL
),
12221 GSF_XML_IN_NODE (DATE_STYLE
, DATE_MONTH
, OO_NS_NUMBER
, "month", GSF_XML_NO_CONTENT
, &oo_date_month
, NULL
),
12222 GSF_XML_IN_NODE (DATE_STYLE
, DATE_YEAR
, OO_NS_NUMBER
, "year", GSF_XML_NO_CONTENT
, &oo_date_year
, NULL
),
12223 GSF_XML_IN_NODE (DATE_STYLE
, DATE_ERA
, OO_NS_NUMBER
, "era", GSF_XML_NO_CONTENT
, &oo_date_era
, NULL
),
12224 GSF_XML_IN_NODE (DATE_STYLE
, DATE_DAY_OF_WEEK
, OO_NS_NUMBER
, "day-of-week", GSF_XML_NO_CONTENT
, &oo_date_day_of_week
, NULL
),
12225 GSF_XML_IN_NODE (DATE_STYLE
, DATE_WEEK_OF_YEAR
, OO_NS_NUMBER
, "week-of-year", GSF_XML_NO_CONTENT
, &oo_date_week_of_year
, NULL
),
12226 GSF_XML_IN_NODE (DATE_STYLE
, DATE_QUARTER
, OO_NS_NUMBER
, "quarter", GSF_XML_NO_CONTENT
, &oo_date_quarter
, NULL
),
12227 GSF_XML_IN_NODE (DATE_STYLE
, DATE_HOURS
, OO_NS_NUMBER
, "hours", GSF_XML_NO_CONTENT
, &oo_date_hours
, NULL
),
12228 GSF_XML_IN_NODE (DATE_STYLE
, DATE_MINUTES
, OO_NS_NUMBER
, "minutes", GSF_XML_NO_CONTENT
, &oo_date_minutes
, NULL
),
12229 GSF_XML_IN_NODE (DATE_STYLE
, DATE_SECONDS
, OO_NS_NUMBER
, "seconds", GSF_XML_NO_CONTENT
, &oo_date_seconds
, NULL
),
12230 GSF_XML_IN_NODE (DATE_STYLE
, DATE_AM_PM
, OO_NS_NUMBER
, "am-pm", GSF_XML_NO_CONTENT
, &oo_date_am_pm
, NULL
),
12231 GSF_XML_IN_NODE (DATE_STYLE
, DATE_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
12232 GSF_XML_IN_NODE (DATE_STYLE
, DATE_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
12233 GSF_XML_IN_NODE (DATE_STYLE
, DATE_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12234 GSF_XML_IN_NODE (DATE_STYLE
, DATE_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12235 GSF_XML_IN_NODE (OFFICE_STYLES
, TIME_STYLE
, OO_NS_NUMBER
, "time-style", GSF_XML_NO_CONTENT
, &oo_date_style
, &oo_date_style_end
),
12236 GSF_XML_IN_NODE (TIME_STYLE
, TIME_HOURS
, OO_NS_NUMBER
, "hours", GSF_XML_NO_CONTENT
, &oo_date_hours
, NULL
),
12237 GSF_XML_IN_NODE (TIME_STYLE
, TIME_MINUTES
, OO_NS_NUMBER
, "minutes", GSF_XML_NO_CONTENT
, &oo_date_minutes
, NULL
),
12238 GSF_XML_IN_NODE (TIME_STYLE
, TIME_SECONDS
, OO_NS_NUMBER
, "seconds", GSF_XML_NO_CONTENT
, &oo_date_seconds
, NULL
),
12239 GSF_XML_IN_NODE (TIME_STYLE
, TIME_AM_PM
, OO_NS_NUMBER
, "am-pm", GSF_XML_NO_CONTENT
, &oo_date_am_pm
, NULL
),
12240 GSF_XML_IN_NODE (TIME_STYLE
, TIME_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
12241 GSF_XML_IN_NODE (TIME_STYLE
, TIME_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
12242 GSF_XML_IN_NODE (TIME_STYLE
, TIME_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12243 GSF_XML_IN_NODE (TIME_STYLE
, TIME_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12244 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_BOOL
, OO_NS_NUMBER
, "boolean-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12245 GSF_XML_IN_NODE (STYLE_BOOL
, BOOL_PROP
, OO_NS_NUMBER
, "boolean", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12246 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_CURRENCY
, OO_NS_NUMBER
, "currency-style", GSF_XML_NO_CONTENT
, &odf_number_style
, &odf_number_style_end
),
12247 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_STYLE
, OO_NS_NUMBER
, "number", GSF_XML_NO_CONTENT
, &odf_number
, NULL
),
12248 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_STYLE_PROP
, OO_NS_STYLE
,"properties", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12249 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, &odf_map
, NULL
),
12250 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_SYMBOL
, OO_NS_NUMBER
, "currency-symbol", GSF_XML_CONTENT
, NULL
, &odf_currency_symbol_end
),
12251 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
12252 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
12253 GSF_XML_IN_NODE (STYLE_CURRENCY
, CURRENCY_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12254 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_PERCENTAGE
, OO_NS_NUMBER
, "percentage-style", GSF_XML_NO_CONTENT
, &odf_number_percentage_style
, &odf_number_style_end
),
12255 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_STYLE_PROP
, OO_NS_NUMBER
, "number", GSF_XML_NO_CONTENT
, &odf_number
, NULL
),
12256 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_TEXT
, OO_NS_NUMBER
, "text", GSF_XML_CONTENT
, &odf_date_text_start
, &oo_date_text_end
),
12257 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, &odf_map
, NULL
),
12258 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_TEXT_PROP
, OO_NS_STYLE
, "text-properties", GSF_XML_NO_CONTENT
, &odf_number_color
, NULL
),
12259 GSF_XML_IN_NODE (STYLE_PERCENTAGE
, PERCENTAGE_FILL_CHARACTER
, OO_NS_NUMBER
, "fill-character", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12260 GSF_XML_IN_NODE (OFFICE_STYLES
, STYLE_TEXT
, OO_NS_NUMBER
, "text-style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12261 GSF_XML_IN_NODE (STYLE_TEXT
, STYLE_TEXT_CONTENT
, OO_NS_NUMBER
, "text-content", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12262 GSF_XML_IN_NODE (STYLE_TEXT
, STYLE_TEXT_PROP
, OO_NS_NUMBER
, "text", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12263 GSF_XML_IN_NODE (STYLE_TEXT
, STYLE_TEXT_MAP
, OO_NS_STYLE
, "map", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12265 GSF_XML_IN_NODE (OFFICE
, OFFICE_BODY
, OO_NS_OFFICE
, "body", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12266 GSF_XML_IN_NODE (OFFICE_BODY
, SPREADSHEET
, OO_NS_OFFICE
, "spreadsheet", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12267 GSF_XML_IN_NODE (SPREADSHEET
, DATA_PILOT_TABLES
, OO_NS_TABLE
, "data-pilot-tables", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12268 GSF_XML_IN_NODE (DATA_PILOT_TABLES
, DATA_PILOT_TABLE
, OO_NS_TABLE
, "data-pilot-table", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12269 GSF_XML_IN_NODE (DATA_PILOT_TABLE
, DPT_SOURCE_CELL_RANGE
, OO_NS_TABLE
, "source-cell-range", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12270 GSF_XML_IN_NODE (DATA_PILOT_TABLE
, DATA_PILOT_FIELD
, OO_NS_TABLE
, "data-pilot-field", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12271 GSF_XML_IN_NODE (DATA_PILOT_FIELD
, DATA_PILOT_LEVEL
, OO_NS_TABLE
, "data-pilot-level", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12272 GSF_XML_IN_NODE (DATA_PILOT_LEVEL
, DATA_PILOT_LAYOUT_INFO
, OO_NS_TABLE
, "data-pilot-layout-info", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12273 GSF_XML_IN_NODE (DATA_PILOT_LEVEL
, DATA_PILOT_SORT_INFO
, OO_NS_TABLE
, "data-pilot-sort-info", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12274 GSF_XML_IN_NODE (DATA_PILOT_LEVEL
, DATA_PILOT_DISPLAY_INFO
, OO_NS_TABLE
, "data-pilot-display-info", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12275 GSF_XML_IN_NODE (DATA_PILOT_LEVEL
, DATA_PILOT_MEMBERS
, OO_NS_TABLE
, "data-pilot-members", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12276 GSF_XML_IN_NODE (DATA_PILOT_MEMBERS
, DATA_PILOT_MEMBER
, OO_NS_TABLE
, "data-pilot-member", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12277 GSF_XML_IN_NODE (DATA_PILOT_LEVEL
, DATA_PILOT_SUBTOTALS
, OO_NS_TABLE
, "data-pilot-subtotals", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12278 GSF_XML_IN_NODE (DATA_PILOT_SUBTOTALS
, DATA_PILOT_SUBTOTAL
, OO_NS_TABLE
, "data-pilot-subtotal", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12279 GSF_XML_IN_NODE (DATA_PILOT_FIELD
, DATA_PILOT_GROUPS
, OO_NS_TABLE
, "data-pilot-groups", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12280 GSF_XML_IN_NODE (SPREADSHEET
, CONTENT_VALIDATIONS
, OO_NS_TABLE
, "content-validations", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12281 GSF_XML_IN_NODE (CONTENT_VALIDATIONS
, CONTENT_VALIDATION
, OO_NS_TABLE
, "content-validation", GSF_XML_NO_CONTENT
, &odf_validation
, NULL
),
12282 GSF_XML_IN_NODE (CONTENT_VALIDATION
, ERROR_MESSAGE
, OO_NS_TABLE
, "error-message", GSF_XML_NO_CONTENT
, &odf_validation_error_message
, &odf_validation_error_message_end
),
12283 GSF_XML_IN_NODE (ERROR_MESSAGE
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_CONTENT
, &odf_text_content_start
, &odf_text_content_end
),
12284 GSF_XML_IN_NODE (TEXT_CONTENT
, TEXT_S
, OO_NS_TEXT
, "s", GSF_XML_NO_CONTENT
, &odf_text_space
, NULL
),
12285 GSF_XML_IN_NODE_FULL (TEXT_CONTENT
, TEXT_LINE_BREAK
, OO_NS_TEXT
, "line-break", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &odf_text_symbol
, NULL
, .v_str
= "\n"),
12286 GSF_XML_IN_NODE_FULL (TEXT_CONTENT
, TEXT_TAB
, OO_NS_TEXT
, "tab", GSF_XML_SHARED_CONTENT
, FALSE
, FALSE
, odf_text_symbol
, NULL
, .v_str
= "\t"),
12287 GSF_XML_IN_NODE (TEXT_CONTENT
, TEXT_SPAN
, OO_NS_TEXT
, "span", GSF_XML_SHARED_CONTENT
, &odf_text_span_start
, &odf_text_span_end
),
12288 GSF_XML_IN_NODE (TEXT_SPAN
, TEXT_SPAN
, OO_NS_TEXT
, "span", GSF_XML_2ND
, NULL
, NULL
),
12289 GSF_XML_IN_NODE (TEXT_SPAN
, TEXT_S
, OO_NS_TEXT
, "s", GSF_XML_2ND
, NULL
, NULL
),
12290 GSF_XML_IN_NODE (TEXT_SPAN
, TEXT_LINE_BREAK
, OO_NS_TEXT
, "line-break", GSF_XML_2ND
, NULL
, NULL
),
12291 GSF_XML_IN_NODE (TEXT_SPAN
, TEXT_TAB
, OO_NS_TEXT
, "tab", GSF_XML_2ND
, NULL
, NULL
),
12292 GSF_XML_IN_NODE (TEXT_SPAN
, TEXT_ADDR
, OO_NS_TEXT
, "a", GSF_XML_SHARED_CONTENT
, &oo_cell_content_link
, NULL
),
12293 GSF_XML_IN_NODE (TEXT_ADDR
, TEXT_S
, OO_NS_TEXT
, "s", GSF_XML_2ND
, NULL
, NULL
),
12294 GSF_XML_IN_NODE (TEXT_ADDR
, TEXT_TAB
, OO_NS_TEXT
, "tab", GSF_XML_2ND
, NULL
, NULL
),
12295 GSF_XML_IN_NODE (TEXT_ADDR
, TEXT_SPAN
, OO_NS_TEXT
, "span", GSF_XML_2ND
, NULL
, NULL
),
12296 GSF_XML_IN_NODE (CONTENT_VALIDATION
, HELP_MESSAGE
, OO_NS_TABLE
, "help-message", GSF_XML_NO_CONTENT
, &odf_validation_help_message
, &odf_validation_help_message_end
),
12297 GSF_XML_IN_NODE (HELP_MESSAGE
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12298 GSF_XML_IN_NODE (SPREADSHEET
, CALC_SETTINGS
, OO_NS_TABLE
, "calculation-settings", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12299 GSF_XML_IN_NODE (CALC_SETTINGS
, ITERATION
, OO_NS_TABLE
, "iteration", GSF_XML_NO_CONTENT
, &oo_iteration
, NULL
),
12300 GSF_XML_IN_NODE (CALC_SETTINGS
, DATE_CONVENTION
, OO_NS_TABLE
, "null-date", GSF_XML_NO_CONTENT
, &oo_date_convention
, NULL
),
12301 GSF_XML_IN_NODE (SPREADSHEET
, CHART
, OO_NS_CHART
, "chart", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12302 GSF_XML_IN_NODE (OFFICE_BODY
, OFFICE_CHART
, OO_NS_OFFICE
, "chart", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12303 GSF_XML_IN_NODE (OFFICE_CHART
, CHART_CHART
, OO_NS_CHART
, "chart", GSF_XML_NO_CONTENT
, &oo_chart
, &oo_chart_end
),
12304 GSF_XML_IN_NODE (CHART_CHART
, CHART_TABLE
, OO_NS_TABLE
, "table", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12305 GSF_XML_IN_NODE (CHART_TABLE
, CHART_TABLE_ROWS
, OO_NS_TABLE
, "table-rows", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12306 GSF_XML_IN_NODE (CHART_TABLE_ROWS
, CHART_TABLE_ROW
, OO_NS_TABLE
, "table-row", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12307 GSF_XML_IN_NODE (CHART_TABLE_ROW
, CHART_TABLE_CELL
, OO_NS_TABLE
, "table-cell", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12308 GSF_XML_IN_NODE (CHART_TABLE_CELL
, CHART_CELL_P
, OO_NS_TEXT
, "p", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12309 GSF_XML_IN_NODE (CHART_TABLE_CELL
, CHART_CELL_DRAW_G
, OO_NS_DRAW
, "g", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12310 GSF_XML_IN_NODE (CHART_CELL_DRAW_G
, CHART_CELL_SVG_DESC
, OO_NS_SVG
, "desc", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12311 GSF_XML_IN_NODE (CHART_TABLE
, CHART_TABLE_COLS
, OO_NS_TABLE
, "table-columns", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12312 GSF_XML_IN_NODE (CHART_TABLE_COLS
, CHART_TABLE_COL
, OO_NS_TABLE
, "table-column", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12313 GSF_XML_IN_NODE (CHART_TABLE
, CHART_TABLE_HROWS
, OO_NS_TABLE
, "table-header-rows", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12314 GSF_XML_IN_NODE (CHART_TABLE_HROWS
, CHART_TABLE_HROW
, OO_NS_TABLE
, "table-header-row", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12315 GSF_XML_IN_NODE (CHART_TABLE_HROWS
, CHART_TABLE_ROW
, OO_NS_TABLE
, "table-row", GSF_XML_2ND
, NULL
, NULL
),
12316 GSF_XML_IN_NODE (CHART_TABLE
, CHART_TABLE_HCOLS
, OO_NS_TABLE
, "table-header-columns", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12317 GSF_XML_IN_NODE (CHART_TABLE_HCOLS
, CHART_TABLE_HCOL
, OO_NS_TABLE
, "table-header-column", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12318 GSF_XML_IN_NODE (CHART_TABLE_HCOLS
, CHART_TABLE_COL
, OO_NS_TABLE
, "table-column", GSF_XML_2ND
, NULL
, NULL
),
12320 GSF_XML_IN_NODE_FULL (CHART_CHART
, CHART_TITLE
, OO_NS_CHART
, "title", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &oo_chart_title
, &oo_chart_title_end
, .v_int
= 0),
12321 GSF_XML_IN_NODE (CHART_TITLE
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12322 GSF_XML_IN_NODE_FULL (CHART_CHART
, CHART_SUBTITLE
, OO_NS_CHART
, "subtitle", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &oo_chart_title
, &oo_chart_title_end
, .v_int
= 1),
12323 GSF_XML_IN_NODE (CHART_SUBTITLE
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12324 GSF_XML_IN_NODE_FULL (CHART_CHART
, CHART_FOOTER
, OO_NS_CHART
, "footer", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &oo_chart_title
, &oo_chart_title_end
, .v_int
= 2),
12325 GSF_XML_IN_NODE (CHART_FOOTER
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12326 GSF_XML_IN_NODE (CHART_CHART
, CHART_LEGEND
, OO_NS_CHART
, "legend", GSF_XML_NO_CONTENT
, &oo_legend
, NULL
),
12327 GSF_XML_IN_NODE (CHART_LEGEND
, CHART_LEGEND_TITLE
, OO_GNUM_NS_EXT
, "title", GSF_XML_NO_CONTENT
, &oo_chart_title
, &oo_chart_title_end
),
12328 GSF_XML_IN_NODE (CHART_LEGEND_TITLE
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12329 GSF_XML_IN_NODE (CHART_CHART
, CHART_COLOR_SCALE
, OO_GNUM_NS_EXT
, "color-scale", GSF_XML_NO_CONTENT
, &oo_color_scale
, NULL
),
12330 GSF_XML_IN_NODE (CHART_CHART
, CHART_PLOT_AREA
, OO_NS_CHART
, "plot-area", GSF_XML_NO_CONTENT
, &oo_plot_area
, &oo_plot_area_end
),
12331 GSF_XML_IN_NODE (CHART_PLOT_AREA
, CHART_SERIES
, OO_NS_CHART
, "series", GSF_XML_NO_CONTENT
, &oo_plot_series
, &oo_plot_series_end
),
12332 GSF_XML_IN_NODE (CHART_SERIES
, SERIES_DOMAIN
, OO_NS_CHART
, "domain", GSF_XML_NO_CONTENT
, &oo_series_domain
, NULL
),
12333 GSF_XML_IN_NODE (CHART_SERIES
, SERIES_DATA_PT
, OO_NS_CHART
, "data-point", GSF_XML_NO_CONTENT
, &oo_series_pt
, NULL
),
12334 GSF_XML_IN_NODE (CHART_SERIES
, SERIES_DATA_ERR
, OO_NS_CHART
, "error-indicator", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12335 GSF_XML_IN_NODE (CHART_SERIES
, SERIES_REGRESSION
, OO_NS_CHART
, "regression-curve", GSF_XML_NO_CONTENT
, &od_series_regression
, NULL
),
12336 GSF_XML_IN_NODE (SERIES_REGRESSION
, SERIES_REG_EQ
, OO_NS_CHART
, "equation", GSF_XML_NO_CONTENT
, &od_series_reg_equation
, NULL
),
12337 GSF_XML_IN_NODE (SERIES_REGRESSION
, SERIES_REG_EQ_GNM
, OO_GNUM_NS_EXT
, "equation", GSF_XML_NO_CONTENT
, &od_series_reg_equation
, NULL
),
12338 GSF_XML_IN_NODE (CHART_SERIES
, SERIES_REGRESSION_MULTIPLE
, OO_GNUM_NS_EXT
, "regression-curve", GSF_XML_NO_CONTENT
, &od_series_regression
, NULL
),
12339 GSF_XML_IN_NODE (SERIES_REGRESSION_MULTIPLE
, SERIES_REG_EQ
, OO_NS_CHART
, "equation", GSF_XML_2ND
, NULL
, NULL
),
12340 GSF_XML_IN_NODE (SERIES_REGRESSION_MULTIPLE
, SERIES_REG_EQ_GNM
, OO_GNUM_NS_EXT
, "equation", GSF_XML_2ND
, NULL
, NULL
),
12341 GSF_XML_IN_NODE (CHART_SERIES
, SERIES_DROPLINES
, OO_GNUM_NS_EXT
, "droplines", GSF_XML_NO_CONTENT
, &oo_series_droplines
, NULL
),
12342 GSF_XML_IN_NODE (CHART_SERIES
, SERIES_SERIESLINES
, OO_GNUM_NS_EXT
, "serieslines", GSF_XML_NO_CONTENT
, &oo_series_serieslines
, NULL
),
12343 GSF_XML_IN_NODE (CHART_PLOT_AREA
, CHART_WALL
, OO_NS_CHART
, "wall", GSF_XML_NO_CONTENT
, &oo_chart_wall
, NULL
),
12344 GSF_XML_IN_NODE (CHART_PLOT_AREA
, CHART_FLOOR
, OO_NS_CHART
, "floor", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12345 GSF_XML_IN_NODE (CHART_PLOT_AREA
, CHART_AXIS
, OO_NS_CHART
, "axis", GSF_XML_NO_CONTENT
, &oo_chart_axis
, &oo_chart_axis_end
),
12346 GSF_XML_IN_NODE (CHART_PLOT_AREA
, GNM_CHART_AXIS
, OO_GNUM_NS_EXT
, "axis", GSF_XML_NO_CONTENT
, &oo_chart_axis
, &oo_chart_axis_end
),
12347 GSF_XML_IN_NODE (CHART_AXIS
, CHART_AXIS_LINE
, OO_GNUM_NS_EXT
, "axisline", GSF_XML_NO_CONTENT
, &oo_chart_axisline
, NULL
),
12348 GSF_XML_IN_NODE (CHART_AXIS
, CHART_GRID
, OO_NS_CHART
, "grid", GSF_XML_NO_CONTENT
, &oo_chart_grid
, NULL
),
12349 GSF_XML_IN_NODE (CHART_AXIS
, CHART_AXIS_CAT
, OO_NS_CHART
, "categories", GSF_XML_NO_CONTENT
, &od_chart_axis_categories
, NULL
),
12350 GSF_XML_IN_NODE_FULL (CHART_AXIS
, CHART_AXIS_TITLE
, OO_NS_CHART
, "title", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &oo_chart_title
, &oo_chart_title_end
, .v_int
= 3),
12351 GSF_XML_IN_NODE (GNM_CHART_AXIS
, GNM_CHART_AXIS_LINE
, OO_GNUM_NS_EXT
, "axisline", GSF_XML_NO_CONTENT
, &oo_chart_axisline
, NULL
),
12352 GSF_XML_IN_NODE (GNM_CHART_AXIS
, GNM_CHART_GRID
, OO_NS_CHART
, "grid", GSF_XML_NO_CONTENT
, &oo_chart_grid
, NULL
),
12353 GSF_XML_IN_NODE (GNM_CHART_AXIS
, GNM_CHART_AXIS_CAT
, OO_NS_CHART
, "categories", GSF_XML_NO_CONTENT
, &od_chart_axis_categories
, NULL
),
12354 GSF_XML_IN_NODE_FULL (GNM_CHART_AXIS
, GNM_CHART_AXIS_TITLE
, OO_NS_CHART
, "title", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &oo_chart_title
, &oo_chart_title_end
, .v_int
= 3),
12355 GSF_XML_IN_NODE (CHART_AXIS_TITLE
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12356 GSF_XML_IN_NODE (CHART_PLOT_AREA
, CHART_OOO_COORDINATE_REGION
, OO_NS_CHART_OOO
, "coordinate-region", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12357 GSF_XML_IN_NODE (SPREADSHEET
, TABLE
, OO_NS_TABLE
, "table", GSF_XML_NO_CONTENT
, &oo_table_start
, &oo_table_end
),
12358 GSF_XML_IN_NODE (TABLE
, SHEET_SELECTIONS
, OO_GNUM_NS_EXT
, "selections", GSF_XML_NO_CONTENT
, &odf_selection
, &odf_selection_end
),
12359 GSF_XML_IN_NODE (SHEET_SELECTIONS
, SELECTION
, OO_GNUM_NS_EXT
, "selection", GSF_XML_NO_CONTENT
, &odf_selection_range
, NULL
),
12360 GSF_XML_IN_NODE (TABLE
, TABLE_SOURCE
, OO_NS_TABLE
, "table-source", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12361 GSF_XML_IN_NODE (TABLE
, TABLE_SHAPES
, OO_NS_TABLE
, "shapes", GSF_XML_NO_CONTENT
, &odf_shapes
, &odf_shapes_end
),
12362 GSF_XML_IN_NODE (TABLE_SHAPES
, DRAW_FRAME
, OO_NS_DRAW
, "frame", GSF_XML_NO_CONTENT
, &od_draw_frame_start
, &od_draw_frame_end
),
12363 GSF_XML_IN_NODE (TABLE_SHAPES
, DRAW_CAPTION
, OO_NS_DRAW
, "caption", GSF_XML_NO_CONTENT
, &odf_caption
, &od_draw_text_frame_end
),
12364 GSF_XML_IN_NODE (DRAW_CAPTION
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12365 GSF_XML_IN_NODE (TABLE_SHAPES
, DRAW_CUSTOM_SHAPE
, OO_NS_DRAW
, "custom-shape", GSF_XML_NO_CONTENT
, &odf_custom_shape
, &odf_custom_shape_end
),
12366 GSF_XML_IN_NODE (DRAW_CUSTOM_SHAPE
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12367 GSF_XML_IN_NODE (DRAW_CUSTOM_SHAPE
, DRAW_ENHANCED_GEOMETRY
, OO_NS_DRAW
, "enhanced-geometry", GSF_XML_NO_CONTENT
, &odf_custom_shape_enhanced_geometry
, NULL
),
12368 GSF_XML_IN_NODE (DRAW_ENHANCED_GEOMETRY
, DRAW_ENHANCED_GEOMETRY_EQUATION
, OO_NS_DRAW
, "equation", GSF_XML_NO_CONTENT
, odf_custom_shape_equation
, NULL
),
12369 GSF_XML_IN_NODE (DRAW_ENHANCED_GEOMETRY
, DRAW_ENHANCED_GEOMETRY_HANDLE
, OO_NS_DRAW
, "handle", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12370 GSF_XML_IN_NODE (TABLE_SHAPES
, DRAW_ELLIPSE
, OO_NS_DRAW
, "ellipse", GSF_XML_NO_CONTENT
, &odf_ellipse
, &od_draw_text_frame_end
),
12371 GSF_XML_IN_NODE (DRAW_ELLIPSE
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12372 GSF_XML_IN_NODE (TABLE_SHAPES
, DRAW_LINE
, OO_NS_DRAW
, "line", GSF_XML_NO_CONTENT
, &odf_line
, &odf_line_end
),
12373 GSF_XML_IN_NODE (DRAW_LINE
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12374 GSF_XML_IN_NODE (TABLE_SHAPES
, DRAW_RECT
, OO_NS_DRAW
, "rect", GSF_XML_NO_CONTENT
, &odf_rect
, &od_draw_text_frame_end
),
12375 GSF_XML_IN_NODE (DRAW_RECT
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12376 GSF_XML_IN_NODE (TABLE
, FORMS
, OO_NS_OFFICE
, "forms", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12377 GSF_XML_IN_NODE (FORMS
, FORM
, OO_NS_FORM
, "form", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12378 GSF_XML_IN_NODE (FORM
, FORM_PROPERTIES
, OO_NS_FORM
, "properties", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12379 GSF_XML_IN_NODE (FORM_PROPERTIES
, FORM_PROPERTY
, OO_NS_FORM
, "property", GSF_XML_NO_CONTENT
, &odf_control_property
, NULL
),
12380 GSF_XML_IN_NODE (FORM_PROPERTIES
, FORM_LIST_PROPERTY
, OO_NS_FORM
, "list-property", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12381 GSF_XML_IN_NODE (FORM
, FORM_BUTTON
, OO_NS_FORM
, "button", GSF_XML_NO_CONTENT
, &odf_form_button
, &odf_form_control_end
),
12382 GSF_XML_IN_NODE (FORM_BUTTON
, FORM_PROPERTIES
, OO_NS_FORM
, "properties", GSF_XML_2ND
, NULL
, NULL
),
12383 GSF_XML_IN_NODE (FORM_BUTTON
, BUTTON_OFFICE_EVENT_LISTENERS
, OO_NS_OFFICE
, "event-listeners", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12384 GSF_XML_IN_NODE (BUTTON_OFFICE_EVENT_LISTENERS
, BUTTON_EVENT_LISTENER
, OO_NS_SCRIPT
, "event-listener", GSF_XML_NO_CONTENT
, &odf_button_event_listener
, NULL
),
12385 GSF_XML_IN_NODE (FORM
, FORM_VALUE_RANGE
, OO_NS_FORM
, "value-range", GSF_XML_NO_CONTENT
, &odf_form_value_range
, NULL
),
12386 GSF_XML_IN_NODE (FORM_VALUE_RANGE
, FORM_PROPERTIES
, OO_NS_FORM
, "properties", GSF_XML_2ND
, NULL
, NULL
),
12387 GSF_XML_IN_NODE (FORM
, FORM_CHECKBOX
, OO_NS_FORM
, "checkbox", GSF_XML_NO_CONTENT
, &odf_form_checkbox
, NULL
),
12388 GSF_XML_IN_NODE (FORM_CHECKBOX
, FORM_PROPERTIES
, OO_NS_FORM
, "properties", GSF_XML_2ND
, NULL
, NULL
),
12389 GSF_XML_IN_NODE (FORM
, FORM_RADIO
, OO_NS_FORM
, "radio", GSF_XML_NO_CONTENT
, &odf_form_radio
, NULL
),
12390 GSF_XML_IN_NODE (FORM_RADIO
, FORM_PROPERTIES
, OO_NS_FORM
, "properties", GSF_XML_2ND
, NULL
, NULL
),
12391 GSF_XML_IN_NODE (FORM
, FORM_LISTBOX
, OO_NS_FORM
, "listbox", GSF_XML_NO_CONTENT
, &odf_form_listbox
, NULL
),
12392 GSF_XML_IN_NODE (FORM_LISTBOX
, FORM_PROPERTIES
, OO_NS_FORM
, "properties", GSF_XML_2ND
, NULL
, NULL
),
12393 GSF_XML_IN_NODE (FORM
, FORM_COMBOBOX
, OO_NS_FORM
, "combobox", GSF_XML_NO_CONTENT
, &odf_form_combobox
, NULL
),
12394 GSF_XML_IN_NODE (FORM_COMBOBOX
, FORM_PROPERTIES
, OO_NS_FORM
, "properties", GSF_XML_2ND
, NULL
, NULL
),
12395 GSF_XML_IN_NODE (FORM
, FORM_GENERIC
, OO_NS_FORM
, "generic-control", GSF_XML_NO_CONTENT
, &odf_form_generic
, &odf_form_control_end
),
12396 GSF_XML_IN_NODE (FORM_GENERIC
, FORM_PROPERTIES
, OO_NS_FORM
, "properties", GSF_XML_2ND
, NULL
, NULL
),
12397 GSF_XML_IN_NODE (TABLE
, TABLE_ROWS
, OO_NS_TABLE
, "table-rows", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12398 GSF_XML_IN_NODE (TABLE
, TABLE_H_ROWS
, OO_NS_TABLE
, "table-header-rows", GSF_XML_NO_CONTENT
, &odf_table_header_rows
, &odf_table_header_rows_end
),
12399 GSF_XML_IN_NODE (TABLE
, TABLE_COL
, OO_NS_TABLE
, "table-column", GSF_XML_NO_CONTENT
, &oo_col_start
, NULL
),
12400 GSF_XML_IN_NODE (TABLE
, TABLE_COLS
, OO_NS_TABLE
, "table-columns", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12401 GSF_XML_IN_NODE (TABLE
, TABLE_H_COLS
, OO_NS_TABLE
, "table-header-columns", GSF_XML_NO_CONTENT
, &odf_table_header_cols
, &odf_table_header_cols_end
),
12402 GSF_XML_IN_NODE (TABLE_H_COLS
, TABLE_COL
, OO_NS_TABLE
, "table-column", GSF_XML_2ND
, NULL
, NULL
),
12403 GSF_XML_IN_NODE (TABLE_COLS
, TABLE_COL
, OO_NS_TABLE
, "table-column", GSF_XML_2ND
, NULL
, NULL
),
12404 GSF_XML_IN_NODE (TABLE
, TABLE_ROW
, OO_NS_TABLE
, "table-row", GSF_XML_NO_CONTENT
, &oo_row_start
, &oo_row_end
),
12405 GSF_XML_IN_NODE (TABLE
, SOFTPAGEBREAK
, OO_NS_TEXT
, "soft-page-break", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12406 GSF_XML_IN_NODE (TABLE_ROWS
, TABLE_ROW
, OO_NS_TABLE
, "table-row", GSF_XML_2ND
, NULL
, NULL
),
12407 GSF_XML_IN_NODE (TABLE_H_ROWS
, TABLE_ROW
, OO_NS_TABLE
, "table-row", GSF_XML_2ND
, NULL
, NULL
),
12408 GSF_XML_IN_NODE (TABLE_ROWS
, SOFTPAGEBREAK
, OO_NS_TEXT
, "soft-page-break", GSF_XML_2ND
, NULL
, NULL
),
12409 GSF_XML_IN_NODE (TABLE_H_ROWS
, SOFTPAGEBREAK
, OO_NS_TEXT
, "soft-page-break", GSF_XML_2ND
, NULL
, NULL
),
12410 GSF_XML_IN_NODE (TABLE_ROW
, TABLE_CELL
, OO_NS_TABLE
, "table-cell", GSF_XML_NO_CONTENT
, &oo_cell_start
, &oo_cell_end
),
12411 GSF_XML_IN_NODE (TABLE_CELL
, DETECTIVE
, OO_NS_TABLE
, "detective", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12412 GSF_XML_IN_NODE (DETECTIVE
, DETECTIVE_OPERATION
, OO_NS_TABLE
, "operation", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12413 GSF_XML_IN_NODE (TABLE_CELL
, DRAW_CUSTOM_SHAPE
, OO_NS_DRAW
, "custom-shape", GSF_XML_2ND
, NULL
, NULL
),
12414 GSF_XML_IN_NODE (TABLE_CELL
, CELL_TEXT
, OO_NS_TEXT
, "p", GSF_XML_CONTENT
, &oo_cell_content_start
, &oo_cell_content_end
),
12415 GSF_XML_IN_NODE (CELL_TEXT
, DRAW_CUSTOM_SHAPE
, OO_NS_DRAW
, "custom-shape", GSF_XML_2ND
, NULL
, NULL
),
12416 GSF_XML_IN_NODE (CELL_TEXT
, TEXT_S
, OO_NS_TEXT
, "s", GSF_XML_2ND
, NULL
, NULL
),
12417 GSF_XML_IN_NODE (CELL_TEXT
, TEXT_ADDR
, OO_NS_TEXT
, "a", GSF_XML_2ND
, NULL
, NULL
),
12418 GSF_XML_IN_NODE (CELL_TEXT
, TEXT_LINE_BREAK
, OO_NS_TEXT
, "line-break", GSF_XML_2ND
, NULL
, NULL
),
12419 GSF_XML_IN_NODE (CELL_TEXT
, TEXT_TAB
, OO_NS_TEXT
, "tab", GSF_XML_2ND
,NULL
, NULL
),
12420 GSF_XML_IN_NODE (CELL_TEXT
, TEXT_SPAN
, OO_NS_TEXT
, "span", GSF_XML_2ND
, NULL
, NULL
),
12421 GSF_XML_IN_NODE (TABLE_CELL
, CELL_OBJECT
, OO_NS_DRAW
, "object", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* ignore for now */
12422 GSF_XML_IN_NODE (TABLE_CELL
, CELL_GRAPHIC
, OO_NS_DRAW
, "g", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* ignore for now */
12423 GSF_XML_IN_NODE (CELL_GRAPHIC
, CELL_GRAPHIC
, OO_NS_DRAW
, "g", GSF_XML_2ND
, NULL
, NULL
),
12424 GSF_XML_IN_NODE (CELL_GRAPHIC
, DRAW_POLYLINE
, OO_NS_DRAW
, "polyline", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12425 GSF_XML_IN_NODE (TABLE_CELL
, DRAW_CONTROL
, OO_NS_DRAW
, "control", GSF_XML_NO_CONTENT
, &od_draw_control_start
, NULL
),
12426 GSF_XML_IN_NODE (TABLE_CELL
, DRAW_RECT
, OO_NS_DRAW
, "rect", GSF_XML_2ND
, NULL
, NULL
),
12427 GSF_XML_IN_NODE (TABLE_CELL
, DRAW_LINE
, OO_NS_DRAW
, "line", GSF_XML_2ND
, NULL
, NULL
),
12428 GSF_XML_IN_NODE (TABLE_CELL
, DRAW_ELLIPSE
, OO_NS_DRAW
, "ellipse", GSF_XML_2ND
, NULL
, NULL
),
12429 GSF_XML_IN_NODE (TABLE_CELL
, DRAW_FRAME
, OO_NS_DRAW
, "frame", GSF_XML_2ND
, NULL
, NULL
),
12430 GSF_XML_IN_NODE (DRAW_FRAME
, DRAW_OBJECT
, OO_NS_DRAW
, "object", GSF_XML_NO_CONTENT
, &od_draw_object
, NULL
),
12431 GSF_XML_IN_NODE (DRAW_OBJECT
, DRAW_OBJECT_TEXT
, OO_NS_TEXT
, "p", GSF_XML_CONTENT
, NULL
, NULL
),
12433 GSF_XML_IN_NODE (DRAW_FRAME
, DRAW_IMAGE
, OO_NS_DRAW
, "image", GSF_XML_NO_CONTENT
, &od_draw_image
, NULL
),
12434 GSF_XML_IN_NODE (DRAW_IMAGE
, DRAW_IMAGE_TEXT
,OO_NS_TEXT
, "p", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12435 GSF_XML_IN_NODE (DRAW_FRAME
, SVG_DESC
, OO_NS_SVG
, "desc", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12436 GSF_XML_IN_NODE (DRAW_FRAME
, SVG_TITLE
, OO_NS_SVG
, "title", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12437 GSF_XML_IN_NODE (DRAW_FRAME
, DRAW_TEXT_BOX
, OO_NS_DRAW
, "text-box", GSF_XML_NO_CONTENT
, &od_draw_text_box
, od_draw_text_frame_end
),
12438 GSF_XML_IN_NODE (DRAW_TEXT_BOX
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12439 GSF_XML_IN_NODE (TABLE_CELL
, CELL_ANNOTATION
, OO_NS_OFFICE
, "annotation", GSF_XML_NO_CONTENT
, &odf_annotation_start
, &odf_annotation_end
),
12440 GSF_XML_IN_NODE (CELL_ANNOTATION
, TEXT_CONTENT
, OO_NS_TEXT
, "p", GSF_XML_2ND
, NULL
, NULL
),
12441 GSF_XML_IN_NODE (CELL_ANNOTATION
, CELL_ANNOTATION_AUTHOR
, OO_NS_DC
, "creator", GSF_XML_CONTENT
, NULL
, &odf_annotation_author_end
),
12442 GSF_XML_IN_NODE (CELL_ANNOTATION
, CELL_ANNOTATION_DATE
, OO_NS_DC
, "date", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12444 GSF_XML_IN_NODE (TABLE_ROW
, TABLE_COVERED_CELL
, OO_NS_TABLE
, "covered-table-cell", GSF_XML_NO_CONTENT
, &oo_covered_cell_start
, &oo_covered_cell_end
),
12445 GSF_XML_IN_NODE (TABLE_COVERED_CELL
, COVERED_CELL_TEXT
, OO_NS_TEXT
, "p", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12446 GSF_XML_IN_NODE (COVERED_CELL_TEXT
, COVERED_CELL_TEXT_S
, OO_NS_TEXT
, "s", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12447 GSF_XML_IN_NODE (TABLE_COVERED_CELL
, DRAW_CONTROL
, OO_NS_DRAW
, "control", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12449 GSF_XML_IN_NODE (TABLE
, TABLE_COL_GROUP
, OO_NS_TABLE
, "table-column-group", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12450 GSF_XML_IN_NODE (TABLE_COL_GROUP
, TABLE_COL_GROUP
, OO_NS_TABLE
, "table-column-group", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12451 GSF_XML_IN_NODE (TABLE_COL_GROUP
, TABLE_H_COLS
, OO_NS_TABLE
, "table-header-columns", GSF_XML_2ND
, NULL
, NULL
),
12452 GSF_XML_IN_NODE (TABLE_COL_GROUP
, TABLE_COL
, OO_NS_TABLE
, "table-column", GSF_XML_2ND
, NULL
, NULL
),
12453 GSF_XML_IN_NODE (TABLE_ROW_GROUP
, TABLE_ROW_GROUP
, OO_NS_TABLE
, "table-row-group", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12454 GSF_XML_IN_NODE (TABLE
, TABLE_ROW_GROUP
, OO_NS_TABLE
, "table-row-group", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12455 GSF_XML_IN_NODE (TABLE_ROW_GROUP
, TABLE_ROW
, OO_NS_TABLE
, "table-row", GSF_XML_2ND
, NULL
, NULL
),
12456 GSF_XML_IN_NODE (TABLE
, NAMED_EXPRS
, OO_NS_TABLE
, "named-expressions", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12457 GSF_XML_IN_NODE (SPREADSHEET
, NAMED_EXPRS
, OO_NS_TABLE
, "named-expressions", GSF_XML_2ND
, NULL
, NULL
),
12458 GSF_XML_IN_NODE (NAMED_EXPRS
, NAMED_EXPR
, OO_NS_TABLE
, "named-expression", GSF_XML_NO_CONTENT
, &oo_named_expr
, NULL
),
12459 GSF_XML_IN_NODE (NAMED_EXPRS
, NAMED_RANGE
, OO_NS_TABLE
, "named-range", GSF_XML_NO_CONTENT
, &oo_named_expr
, NULL
),
12461 GSF_XML_IN_NODE (SPREADSHEET
, DB_RANGES
, OO_NS_TABLE
, "database-ranges", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12462 GSF_XML_IN_NODE (DB_RANGES
, DB_RANGE
, OO_NS_TABLE
, "database-range", GSF_XML_NO_CONTENT
, &oo_db_range_start
, &oo_db_range_end
),
12463 GSF_XML_IN_NODE (DB_RANGE
, FILTER
, OO_NS_TABLE
, "filter", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12464 GSF_XML_IN_NODE (FILTER
, FILTER_COND
, OO_NS_TABLE
, "filter-condition", GSF_XML_NO_CONTENT
, &oo_filter_cond
, NULL
),
12465 GSF_XML_IN_NODE (FILTER
, FILTER_AND
, OO_NS_TABLE
, "filter-and", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12466 GSF_XML_IN_NODE (FILTER_AND
, FILTER_OR
, OO_NS_TABLE
, "filter-or", GSF_XML_NO_CONTENT
, &odf_filter_or
, NULL
),
12467 GSF_XML_IN_NODE (FILTER_OR
, FILTER_COND_IGNORE
, OO_NS_TABLE
, "filter-condition", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12468 GSF_XML_IN_NODE (FILTER_OR
, FILTER_AND_IGNORE
, OO_NS_TABLE
, "filter-or", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12469 GSF_XML_IN_NODE (FILTER_AND
, FILTER_COND
, OO_NS_TABLE
, "filter-condition", GSF_XML_2ND
, NULL
, NULL
),
12470 GSF_XML_IN_NODE (FILTER
, FILTER_OR
, OO_NS_TABLE
, "filter-or", GSF_XML_2ND
, NULL
, NULL
),
12471 GSF_XML_IN_NODE (DB_RANGE
, TABLE_SORT
, OO_NS_TABLE
, "sort", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12472 GSF_XML_IN_NODE (TABLE_SORT
, SORT_BY
, OO_NS_TABLE
, "sort-by", GSF_XML_NO_CONTENT
, NULL
, NULL
),
12474 GSF_XML_IN_NODE_END
12477 static GsfXMLInNode
const opendoc_content_preparse_overrides
[] =
12479 GSF_XML_IN_NODE (OFFICE_BODY
, SPREADSHEET
, OO_NS_OFFICE
, "spreadsheet", GSF_XML_NO_CONTENT
, NULL
, &odf_preparse_spreadsheet_end
),
12480 GSF_XML_IN_NODE (SPREADSHEET
, TABLE
, OO_NS_TABLE
, "table", GSF_XML_NO_CONTENT
, &odf_preparse_table_start
, &odf_preparse_table_end
),
12481 GSF_XML_IN_NODE (TABLE
, TABLE_ROW
, OO_NS_TABLE
, "table-row", GSF_XML_NO_CONTENT
, &odf_preparse_row_start
, &odf_preparse_row_end
),
12482 GSF_XML_IN_NODE (TABLE_ROW
, TABLE_CELL
, OO_NS_TABLE
, "table-cell", GSF_XML_NO_CONTENT
, &odf_preparse_cell_start
, NULL
),
12483 GSF_XML_IN_NODE (TABLE_ROW
, TABLE_COVERED_CELL
, OO_NS_TABLE
, "covered-table-cell", GSF_XML_NO_CONTENT
, &odf_preparse_covered_cell_start
, NULL
),
12484 GSF_XML_IN_NODE (TABLE
, NAMED_EXPRS
, OO_NS_TABLE
, "named-expressions", GSF_XML_NO_CONTENT
, &oo_named_exprs_preparse
, NULL
),
12485 GSF_XML_IN_NODE (NAMED_EXPRS
, NAMED_EXPR
, OO_NS_TABLE
, "named-expression", GSF_XML_NO_CONTENT
, &oo_named_expr_preparse
, NULL
),
12486 GSF_XML_IN_NODE (NAMED_EXPRS
, NAMED_RANGE
, OO_NS_TABLE
, "named-range", GSF_XML_NO_CONTENT
, &oo_named_expr_preparse
, NULL
),
12487 GSF_XML_IN_NODE_END
12489 static GsfXMLInNode
const *opendoc_content_preparse_dtd
;
12492 static GsfXMLInNode
const ooo1_content_preparse_overrides
[] =
12494 GSF_XML_IN_NODE (OFFICE_BODY
, TABLE
, OO_NS_TABLE
, "table", GSF_XML_NO_CONTENT
, &odf_preparse_table_start
, &odf_preparse_table_end
),
12495 GSF_XML_IN_NODE (TABLE
, TABLE_ROW
, OO_NS_TABLE
, "table-row", GSF_XML_NO_CONTENT
, &odf_preparse_row_start
, &odf_preparse_row_end
),
12496 GSF_XML_IN_NODE (TABLE_ROW
, TABLE_CELL
, OO_NS_TABLE
, "table-cell", GSF_XML_NO_CONTENT
, &odf_preparse_cell_start
, NULL
),
12497 GSF_XML_IN_NODE (TABLE_ROW
, TABLE_COVERED_CELL
, OO_NS_TABLE
, "covered-table-cell", GSF_XML_NO_CONTENT
, &odf_preparse_covered_cell_start
, NULL
),
12498 GSF_XML_IN_NODE_END
12500 static GsfXMLInNode
const *ooo1_content_preparse_dtd
;
12503 static GsfXMLInNode
const *get_dtd () { return opendoc_content_dtd
; }
12504 static GsfXMLInNode
const *get_styles_dtd () { return styles_dtd
; }
12506 /****************************************************************************/
12508 static GnmExpr
const *
12509 odf_func_address_handler (GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
12511 guint argc
= gnm_expr_list_length (args
);
12513 if (argc
== 4 && convs
->sheet_name_sep
== '!') {
12514 /* Openoffice was missing the A1 parameter */
12515 GnmExprList
*new_args
;
12516 GnmFunc
*f
= gnm_func_lookup_or_add_placeholder ("ADDRESS");
12518 new_args
= g_slist_insert ((GSList
*) args
,
12519 (gpointer
) gnm_expr_new_constant (value_new_int (1)),
12521 return gnm_expr_new_funcall (f
, new_args
);
12526 static GnmExpr
const *
12527 odf_func_phi_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
12529 GnmFunc
*f
= gnm_func_lookup_or_add_placeholder ("NORMDIST");
12531 args
= g_slist_append (args
,
12532 (gpointer
) gnm_expr_new_constant (value_new_int (0)));
12533 args
= g_slist_append (args
,
12534 (gpointer
) gnm_expr_new_constant (value_new_int (1)));
12536 args
= g_slist_append (args
,
12537 (gpointer
) gnm_expr_new_funcall
12538 (gnm_func_lookup_or_add_placeholder ("FALSE"), NULL
));
12540 return gnm_expr_new_funcall (f
, args
);
12543 static GnmExpr
const *
12544 odf_func_gauss_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
12546 guint argc
= gnm_expr_list_length (args
);
12547 GnmFunc
*f
= gnm_func_lookup_or_add_placeholder ("ERF");
12548 GnmFunc
*fs
= gnm_func_lookup_or_add_placeholder ("SQRT");
12549 GnmExpr
const * expr
;
12554 expr
= gnm_expr_new_binary (gnm_expr_new_funcall1
12555 (f
, gnm_expr_new_binary ((gnm_expr_copy ((GnmExpr
const *)(args
->data
))),
12557 gnm_expr_new_funcall1 (fs
,
12558 gnm_expr_new_constant
12559 (value_new_int (2))))),
12561 gnm_expr_new_constant (value_new_int (2)));
12562 gnm_expr_list_unref (args
);
12566 static GnmExpr
const *
12567 odf_func_floor_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
12569 guint argc
= gnm_expr_list_length (args
);
12570 GnmExpr
const *expr_x
;
12571 GnmExpr
const *expr_sig
;
12572 GnmExpr
const *expr_mode
;
12573 GnmExpr
const *expr_mode_zero
;
12574 GnmExpr
const *expr_mode_one
;
12575 GnmExpr
const *expr_if
;
12576 GnmFunc
*fd_ceiling
;
12580 if (argc
== 0 || argc
> 3)
12583 fd_ceiling
= gnm_func_lookup_or_add_placeholder ("CEILING");
12584 fd_floor
= gnm_func_lookup_or_add_placeholder ("FLOOR");
12585 fd_if
= gnm_func_lookup_or_add_placeholder ("IF");
12587 expr_x
= g_slist_nth_data ((GSList
*) args
, 0);
12589 expr_sig
= gnm_expr_copy (g_slist_nth_data ((GSList
*) args
, 1));
12591 GnmFunc
*fd_sign
= gnm_func_lookup_or_add_placeholder ("SIGN");
12592 expr_sig
= gnm_expr_new_funcall1 (fd_sign
, gnm_expr_copy (expr_x
));
12595 expr_mode_zero
= gnm_expr_new_funcall3
12597 gnm_expr_new_binary
12598 (gnm_expr_copy (expr_x
),
12600 gnm_expr_new_constant (value_new_int (0))),
12601 gnm_expr_new_funcall2
12603 gnm_expr_copy (expr_x
),
12604 gnm_expr_copy (expr_sig
)),
12605 gnm_expr_new_funcall2
12607 gnm_expr_copy (expr_x
),
12608 gnm_expr_copy (expr_sig
)));
12610 gnm_expr_free (expr_sig
);
12611 gnm_expr_list_unref (args
);
12612 return expr_mode_zero
;
12616 gnm_expr_new_funcall2
12618 gnm_expr_copy (expr_x
),
12619 gnm_expr_copy (expr_sig
));
12621 expr_mode
= g_slist_nth_data ((GSList
*) args
, 2);
12622 if (GNM_EXPR_GET_OPER (expr_mode
) == GNM_EXPR_OP_CONSTANT
) {
12623 GnmValue
const * val
= expr_mode
->constant
.value
;
12624 if (VALUE_IS_NUMBER (val
)) {
12625 gnm_float value
= value_get_as_float (val
);
12627 gnm_expr_free (expr_mode_one
);
12628 gnm_expr_list_unref (args
);
12629 gnm_expr_free (expr_sig
);
12630 return expr_mode_zero
;
12632 gnm_expr_free (expr_mode_zero
);
12633 gnm_expr_list_unref (args
);
12634 gnm_expr_free (expr_sig
);
12635 return expr_mode_one
;
12639 expr_if
= gnm_expr_new_funcall3
12641 gnm_expr_new_binary
12642 (gnm_expr_new_constant (value_new_int (0)),
12644 gnm_expr_copy (expr_mode
)),
12648 gnm_expr_free (expr_sig
);
12649 gnm_expr_list_unref (args
);
12653 static GnmExpr
const *
12654 odf_func_ceiling_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
12656 guint argc
= gnm_expr_list_length (args
);
12659 GnmFunc
*f
= gnm_func_lookup_or_add_placeholder ("CEIL");
12660 return gnm_expr_new_funcall (f
, args
);
12663 GnmExpr
const *expr_mode_zero
;
12664 GnmExpr
const *expr_mode_one
;
12665 GnmExpr
const *expr_if
;
12666 GnmExpr
const *expr_mode
;
12667 GnmExpr
const *expr_x
= g_slist_nth_data ((GSList
*) args
, 0);
12668 GnmExpr
const *expr_sig
= g_slist_nth_data ((GSList
*) args
, 1);
12670 GnmFunc
*fd_ceiling
= gnm_func_lookup_or_add_placeholder ("CEILING");
12671 GnmFunc
*fd_floor
= gnm_func_lookup_or_add_placeholder ("FLOOR");
12672 GnmFunc
*fd_if
= gnm_func_lookup_or_add_placeholder ("IF");
12674 expr_mode_zero
= gnm_expr_new_funcall3
12676 gnm_expr_new_binary
12677 (gnm_expr_copy (expr_x
),
12679 gnm_expr_new_constant (value_new_int (0))),
12680 gnm_expr_new_funcall2
12682 gnm_expr_copy (expr_x
),
12683 gnm_expr_copy (expr_sig
)),
12684 gnm_expr_new_funcall2
12686 gnm_expr_copy (expr_x
),
12687 gnm_expr_copy (expr_sig
)));
12689 gnm_expr_list_unref (args
);
12690 return expr_mode_zero
;
12694 gnm_expr_new_funcall2
12696 gnm_expr_copy (expr_x
),
12697 gnm_expr_copy (expr_sig
));
12699 expr_mode
= g_slist_nth_data ((GSList
*) args
, 2);
12700 if (GNM_EXPR_GET_OPER (expr_mode
) == GNM_EXPR_OP_CONSTANT
) {
12701 GnmValue
const * val
= expr_mode
->constant
.value
;
12702 if (VALUE_IS_NUMBER (val
)) {
12703 gnm_float value
= value_get_as_float (val
);
12705 gnm_expr_free (expr_mode_one
);
12706 gnm_expr_list_unref (args
);
12707 return expr_mode_zero
;
12709 gnm_expr_free (expr_mode_zero
);
12710 gnm_expr_list_unref (args
);
12711 return expr_mode_one
;
12715 expr_if
= gnm_expr_new_funcall3
12717 gnm_expr_new_binary
12718 (gnm_expr_new_constant (value_new_int (0)),
12720 gnm_expr_copy (expr_mode
)),
12723 gnm_expr_list_unref (args
);
12732 static GnmExpr
const *
12733 odf_func_chisqdist_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
12735 switch (gnm_expr_list_length (args
)) {
12737 GnmFunc
*f
= gnm_func_lookup_or_add_placeholder ("R.PCHISQ");
12738 return gnm_expr_new_funcall (f
, args
);
12741 GnmExpr
const *arg0
= args
->data
;
12742 GnmExpr
const *arg1
= args
->next
->data
;
12743 GnmExpr
const *arg2
= args
->next
->next
->data
;
12745 GnmFunc
*fd_pchisq
;
12746 GnmFunc
*fd_dchisq
;
12747 GnmExpr
const *expr_pchisq
;
12748 GnmExpr
const *expr_dchisq
;
12749 GnmExpr
const *res
, *simp
;
12751 fd_if
= gnm_func_lookup_or_add_placeholder ("IF");
12752 fd_pchisq
= gnm_func_lookup_or_add_placeholder ("R.PCHISQ");
12753 fd_dchisq
= gnm_func_lookup_or_add_placeholder ("R.DCHISQ");
12754 expr_pchisq
= gnm_expr_new_funcall2
12756 gnm_expr_copy (arg0
),
12757 gnm_expr_copy (arg1
));
12758 expr_dchisq
= gnm_expr_new_funcall2
12762 res
= gnm_expr_new_funcall3
12768 simp
= gnm_expr_simplify_if (res
);
12770 gnm_expr_free (res
);
12774 g_slist_free (args
);
12783 static GnmExpr
const *
12784 odf_func_f_dist_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
12786 switch (gnm_expr_list_length (args
)) {
12788 GnmExpr
const *arg0
= args
->data
;
12789 GnmExpr
const *arg1
= args
->next
->data
;
12790 GnmExpr
const *arg2
= args
->next
->next
->data
;
12791 GnmExpr
const *arg3
= args
->next
->next
->next
->data
;
12795 GnmExpr
const *expr_pf
;
12796 GnmExpr
const *expr_df
;
12797 GnmExpr
const *res
, *simp
;
12799 fd_if
= gnm_func_lookup_or_add_placeholder ("IF");
12800 fd_pf
= gnm_func_lookup_or_add_placeholder ("R.PF");
12801 fd_df
= gnm_func_lookup_or_add_placeholder ("R.DF");
12802 expr_pf
= gnm_expr_new_funcall3
12804 gnm_expr_copy (arg0
),
12805 gnm_expr_copy (arg1
),
12806 gnm_expr_copy (arg2
));
12807 expr_df
= gnm_expr_new_funcall3
12812 res
= gnm_expr_new_funcall3
12818 simp
= gnm_expr_simplify_if (res
);
12820 gnm_expr_free (res
);
12824 g_slist_free (args
);
12833 static GnmExpr
const *
12834 odf_func_dist4_handler (GnmExprList
*args
, char const *fd_p_name
, char const *fd_d_name
)
12836 switch (gnm_expr_list_length (args
)) {
12838 GnmExpr
const *arg0
= args
->data
;
12839 GnmExpr
const *arg1
= args
->next
->data
;
12840 GnmExpr
const *arg2
= args
->next
->next
->data
;
12841 GnmExpr
const *arg3
= args
->next
->next
->next
->data
;
12845 GnmExpr
const *expr_p
;
12846 GnmExpr
const *expr_d
;
12847 GnmExpr
const *res
, *simp
;
12849 fd_if
= gnm_func_lookup_or_add_placeholder ("IF");
12850 fd_p
= gnm_func_lookup_or_add_placeholder (fd_p_name
);
12851 fd_d
= gnm_func_lookup_or_add_placeholder (fd_d_name
);
12852 expr_p
= gnm_expr_new_funcall3
12854 gnm_expr_copy (arg0
),
12855 gnm_expr_copy (arg1
),
12856 gnm_expr_copy (arg2
));
12857 expr_d
= gnm_expr_new_funcall3
12862 res
= gnm_expr_new_funcall3
12868 simp
= gnm_expr_simplify_if (res
);
12870 gnm_expr_free (res
);
12874 g_slist_free (args
);
12883 static GnmExpr
const *
12884 odf_func_dist3_handler (GnmExprList
*args
, char const *fd_p_name
, char const *fd_d_name
)
12886 switch (gnm_expr_list_length (args
)) {
12888 GnmExpr
const *arg0
= args
->data
;
12889 GnmExpr
const *arg1
= args
->next
->data
;
12890 GnmExpr
const *arg2
= args
->next
->next
->data
;
12894 GnmExpr
const *expr_p
;
12895 GnmExpr
const *expr_d
;
12896 GnmExpr
const *res
, *simp
;
12898 fd_if
= gnm_func_lookup_or_add_placeholder ("IF");
12899 fd_p
= gnm_func_lookup_or_add_placeholder (fd_p_name
);
12900 fd_d
= gnm_func_lookup_or_add_placeholder (fd_d_name
);
12901 expr_p
= gnm_expr_new_funcall2
12903 gnm_expr_copy (arg0
),
12904 gnm_expr_copy (arg1
));
12905 expr_d
= gnm_expr_new_funcall2
12909 res
= gnm_expr_new_funcall3
12915 simp
= gnm_expr_simplify_if (res
);
12917 gnm_expr_free (res
);
12921 g_slist_free (args
);
12930 static GnmExpr
const *
12931 odf_func_norm_s_dist_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
12933 switch (gnm_expr_list_length (args
)) {
12935 GnmExpr
const *arg0
= args
->data
;
12936 GnmExpr
const *arg1
= args
->next
->data
;
12940 GnmExpr
const *expr_p
;
12941 GnmExpr
const *expr_d
;
12942 GnmExpr
const *res
, *simp
;
12944 fd_if
= gnm_func_lookup_or_add_placeholder ("IF");
12945 fd_p
= gnm_func_lookup_or_add_placeholder ("R.DNORM");
12946 fd_d
= gnm_func_lookup_or_add_placeholder ("NORMSDIST");
12947 expr_p
= gnm_expr_new_funcall3
12949 gnm_expr_copy (arg0
),
12950 gnm_expr_new_constant (value_new_int (0)),
12951 gnm_expr_new_constant (value_new_int (1)));
12952 expr_d
= gnm_expr_new_funcall1
12955 res
= gnm_expr_new_funcall3
12961 simp
= gnm_expr_simplify_if (res
);
12963 gnm_expr_free (res
);
12967 g_slist_free (args
);
12977 odf_func_concatenate_handler_cb (gpointer data
, gpointer user_data
)
12979 GnmExpr
const *expr
= data
;
12980 gboolean
*check
= (gboolean
*)(user_data
);
12982 if (gnm_expr_is_rangeref (expr
))
12983 (*check
) = (*check
) || (GNM_EXPR_GET_OPER (expr
) != GNM_EXPR_OP_CELLREF
);
12986 static GnmExpr
const *
12987 odf_func_concatenate_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
12989 gboolean has_range
= FALSE
;
12992 g_slist_foreach ((GSList
*) args
, odf_func_concatenate_handler_cb
, (gpointer
) &has_range
);
12997 fd
= gnm_func_lookup_or_add_placeholder ("CONCATENATE");
12999 return gnm_expr_new_funcall (fd
, args
);
13002 static GnmExpr
const *
13003 odf_func_t_dist_tail_handler (GnmExprList
*args
, int tails
)
13005 switch (gnm_expr_list_length (args
)) {
13007 GnmExpr
const *arg0
= args
->data
;
13008 GnmExpr
const *arg1
= args
->next
->data
;
13010 GnmExpr
const *res
;
13012 fd
= gnm_func_lookup_or_add_placeholder ("TDIST");
13013 res
= gnm_expr_new_funcall3
13017 gnm_expr_new_constant (value_new_int (tails
)));
13019 g_slist_free (args
);
13028 static GnmExpr
const *
13029 odf_func_t_dist_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
13031 return odf_func_dist3_handler (args
, "R.PT", "R.DT");
13034 static GnmExpr
const *
13035 odf_func_t_dist_rt_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
13037 return odf_func_t_dist_tail_handler (args
, 1);
13040 static GnmExpr
const *
13041 odf_func_t_dist_2t_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
13043 return odf_func_t_dist_tail_handler (args
, 2);
13046 static GnmExpr
const *
13047 odf_func_lognorm_dist_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
13049 return odf_func_dist4_handler (args
, "LOGNORMDIST", "R.DLNORM");
13052 static GnmExpr
const *
13053 odf_func_negbinom_dist_handler (G_GNUC_UNUSED GnmConventions
const *convs
, G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
13055 return odf_func_dist4_handler (args
, "R.PNBINOM", "NEGBINOMDIST");
13058 static GnmExpr
const *
13059 odf_func_true_handler (G_GNUC_UNUSED GnmConventions
const *convs
,
13060 G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
13062 return args
? NULL
: gnm_expr_new_constant (value_new_bool (TRUE
));
13065 static GnmExpr
const *
13066 odf_func_false_handler (G_GNUC_UNUSED GnmConventions
const *convs
,
13067 G_GNUC_UNUSED Workbook
*scope
, GnmExprList
*args
)
13069 return args
? NULL
: gnm_expr_new_constant (value_new_bool (FALSE
));
13072 static GnmExpr
const *
13073 oo_func_map_in (GnmConventions
const *convs
, Workbook
*scope
,
13074 char const *name
, GnmExprList
*args
)
13077 char const *gnm_name
;
13079 } const sc_func_handlers
[] = {
13080 {"CHISQDIST", odf_func_chisqdist_handler
},
13081 {"CEILING", odf_func_ceiling_handler
},
13082 {"FLOOR", odf_func_floor_handler
},
13083 {"ADDRESS", odf_func_address_handler
},
13084 {"PHI", odf_func_phi_handler
},
13085 {"GAUSS", odf_func_gauss_handler
},
13086 {"TRUE", odf_func_true_handler
},
13087 {"FALSE", odf_func_false_handler
},
13088 {"CONCATENATE", odf_func_concatenate_handler
},
13089 {"COM.MICROSOFT.F.DIST", odf_func_f_dist_handler
},
13090 {"COM.MICROSOFT.LOGNORM.DIST", odf_func_lognorm_dist_handler
},
13091 {"COM.MICROSOFT.NEGBINOM.DIST", odf_func_negbinom_dist_handler
},
13092 {"COM.MICROSOFT.T.DIST", odf_func_t_dist_handler
},
13093 {"COM.MICROSOFT.T.DIST.RT", odf_func_t_dist_rt_handler
},
13094 {"COM.MICROSOFT.T.DIST.2T", odf_func_t_dist_2t_handler
},
13095 {"COM.MICROSOFT.NORM.S.DIST", odf_func_norm_s_dist_handler
},
13100 char const *oo_name
;
13101 char const *gnm_name
;
13102 } const sc_func_renames
[] = {
13103 /* The next functions are or were used by OpenOffice but are not in ODF OpenFormula draft 20090508 */
13105 { "INDIRECT_XL", "INDIRECT" },
13106 { "ADDRESS_XL", "ADDRESS" },
13107 { "ERRORTYPE", "ERROR.TYPE" },
13108 { "EASTERSUNDAY", "EASTERSUNDAY" }, /* OOo stores this without prefix! */
13109 { "ORG.OPENOFFICE.EASTERSUNDAY", "EASTERSUNDAY" },
13111 /* The following is a list of the functions defined in ODF OpenFormula draft 20090508 */
13112 /* where we do not have a function with the same name */
13114 { "CONCATENATE","ODF.CONCATENATE" },
13115 { "DDE","ODF.DDE" },
13116 { "MULTIPLE.OPERATIONS","ODF.MULTIPLE.OPERATIONS" },
13118 /* The following is a complete list of the functions defined in ODF OpenFormula draft 20090508 */
13119 /* We should determine whether any mapping is needed. */
13121 { "B","BINOM.DIST.RANGE" },
13122 { "CEILING","ODF.CEILING" }, /* see handler */
13123 { "CHISQINV","R.QCHISQ" },
13124 { "CHISQDIST","ODF.CHISQDIST" }, /* see handler */
13125 { "FALSE","FALSE" }, /* see handler */
13126 { "FLOOR","ODF.FLOOR" }, /* see handler */
13127 { "FORMULA","GET.FORMULA" },
13128 { "GAUSS","ODF.GAUSS" }, /* see handler */
13129 { "LEGACY.CHIDIST","CHIDIST" },
13130 { "LEGACY.CHIINV","CHIINV" },
13131 { "LEGACY.CHITEST","CHITEST" },
13132 { "LEGACY.FDIST","FDIST" },
13133 { "LEGACY.FINV","FINV" },
13134 { "LEGACY.NORMSDIST","NORMSDIST" },
13135 { "LEGACY.NORMSINV","NORMSINV" },
13136 { "LEGACY.TDIST","TDIST" },
13137 { "PDURATION","G_DURATION" },
13138 { "PHI","NORMDIST" }, /* see handler */
13139 { "SUMPRODUCT","ODF.SUMPRODUCT" },
13140 { "TIME","ODF.TIME" },
13141 { "TRUE","TRUE" }, /* see handler */
13142 { "USDOLLAR","DOLLAR" },
13144 /* The following are known to have appeared (usually with a COM.MICROSOFT prefix. */
13146 { "BETA.DIST","BETA.DIST" }, /* We need this mapping to satisfy */
13147 /* the COM.MICROSOFT prefix */
13148 { "BETA.INV","BETAINV" },
13149 { "BINOM.DIST","BINOMDIST" },
13150 { "BINOM.INV","CRITBINOM" },
13151 { "CHISQ.DIST","R.PCHISQ" },
13152 { "CHISQ.DIST.RT","CHIDIST" },
13153 { "CHISQ.INV","R.QCHISQ" },
13154 { "CHISQ.INV.RT","CHIINV" },
13155 { "CHISQ.TEST","CHITEST" },
13156 { "CONCAT", "CONCAT" },
13157 { "CONFIDENCE.NORM","CONFIDENCE" },
13158 { "CONFIDENCE.T","CONFIDENCE.T" },
13159 { "COVARIANCE.P","COVAR" },
13160 { "COVARIANCE.S","COVARIANCE.S" },
13161 { "EXPON.DIST","EXPONDIST" },
13162 { "F.DIST.RT","FDIST" },
13163 { "F.INV.RT","FINV" },
13164 { "F.TEST","FTEST" },
13165 { "GAMMA.DIST","GAMMADIST" },
13166 { "GAMMA.INV","GAMMAINV" },
13167 { "GAMMALN.PRECISE","GAMMALN" },
13168 { "HYPGEOM.DIST","HYPGEOMDIST" },
13170 { "LOGNORM.INV","LOGINV" },
13171 { "MINIFS", "MINIFS" },
13172 { "MAXIFS", "MAXIFS" },
13173 { "MODE.SNGL","MODE" },
13174 { "MODE.MULT","MODE.MULT" },
13175 { "NORM.DIST","NORMDIST" },
13176 { "NORM.INV","NORMINV" },
13177 { "NORM.S.INV","NORMSINV" },
13178 { "PERCENTILE.INC","PERCENTILE" },
13179 { "PERCENTILE.EXC","PERCENTILE.EXC" },
13180 { "PERCENTRANK.INC","PERCENTRANK" },
13181 { "PERCENTRANK.EXC","PERCENTRANK.EXC" },
13182 { "POISSON.DIST","POISSON" },
13183 { "QUARTILE.INC","QUARTILE" },
13184 { "QUARTILE.EXC","QUARTILE.EXC" },
13185 { "RANK.EQ","RANK" },
13186 { "RANK.AVG","RANK.AVG" },
13187 { "STDEV.S","STDEV" },
13188 { "STDEV.P","STDEVP" },
13189 { "SWITCH", "SWITCH" },
13190 { "T.INV","R.QT" },
13191 { "T.INV.2T","TINV" },
13192 { "T.TEST","TTEST" },
13193 { "TEXTJOIN", "TEXTJOIN" },
13195 { "VAR.P","VARP" },
13196 { "WEIBULL.DIST","WEIBULL" },
13197 { "Z.TEST","ZTEST" },
13199 /* { "ADDRESS","ADDRESS" }, also see handler */
13200 /* { "ABS","ABS" }, */
13201 /* { "ACCRINT","ACCRINT" }, */
13202 /* { "ACCRINTM","ACCRINTM" }, */
13203 /* { "ACOS","ACOS" }, */
13204 /* { "ACOSH","ACOSH" }, */
13205 /* { "ACOT","ACOT" }, */
13206 /* { "ACOTH","ACOTH" }, */
13207 /* { "AMORDEGRC","AMORDEGRC" }, */
13208 /* { "AMORLINC","AMORLINC" }, */
13209 /* { "AND","AND" }, */
13210 /* { "ARABIC","ARABIC" }, */
13211 /* { "AREAS","AREAS" }, */
13212 /* { "ASC","ASC" }, */
13213 /* { "ASIN","ASIN" }, */
13214 /* { "ASINH","ASINH" }, */
13215 /* { "ATAN","ATAN" }, */
13216 /* { "ATAN2","ATAN2" }, */
13217 /* { "ATANH","ATANH" }, */
13218 /* { "AVEDEV","AVEDEV" }, */
13219 /* { "AVERAGE","AVERAGE" }, */
13220 /* { "AVERAGEA","AVERAGEA" }, */
13221 /* { "AVERAGEIF","AVERAGEIF" }, */
13222 /* { "AVERAGEIFS","AVERAGEIFS" }, */
13223 /* { "BASE","BASE" }, */
13224 /* { "BESSELI","BESSELI" }, */
13225 /* { "BESSELJ","BESSELJ" }, */
13226 /* { "BESSELK","BESSELK" }, */
13227 /* { "BESSELY","BESSELY" }, */
13228 /* { "BETADIST","BETADIST" }, */
13229 /* { "BETAINV","BETAINV" }, */
13230 /* { "BIN2DEC","BIN2DEC" }, */
13231 /* { "BIN2HEX","BIN2HEX" }, */
13232 /* { "BIN2OCT","BIN2OCT" }, */
13233 /* { "BINOMDIST","BINOMDIST" }, */
13234 /* { "BITAND","BITAND" }, */
13235 /* { "BITLSHIFT","BITLSHIFT" }, */
13236 /* { "BITOR","BITOR" }, */
13237 /* { "BITRSHIFT","BITRSHIFT" }, */
13238 /* { "BITXOR","BITXOR" }, */
13239 /* { "CHAR","CHAR" }, */
13240 /* { "CHOOSE","CHOOSE" }, */
13241 /* { "CLEAN","CLEAN" }, */
13242 /* { "CODE","CODE" }, */
13243 /* { "COLUMN","COLUMN" }, */
13244 /* { "COLUMNS","COLUMNS" }, */
13245 /* { "COMBIN","COMBIN" }, */
13246 /* { "COMBINA","COMBINA" }, */
13247 /* { "COMPLEX","COMPLEX" }, */
13248 /* { "CONFIDENCE","CONFIDENCE" }, */
13249 /* { "CONVERT","CONVERT" }, */
13250 /* { "CORREL","CORREL" }, */
13251 /* { "COS","COS" }, */
13252 /* { "COSH","COSH" }, */
13253 /* { "COT","COT" }, */
13254 /* { "COTH","COTH" }, */
13255 /* { "COUNT","COUNT" }, */
13256 /* { "COUNTA","COUNTA" }, */
13257 /* { "COUNTBLANK","COUNTBLANK" }, */
13258 /* { "COUNTIF","COUNTIF" }, */
13259 /* { "COUNTIFS","COUNTIFS" }, */
13260 /* { "COUPDAYBS","COUPDAYBS" }, */
13261 /* { "COUPDAYS","COUPDAYS" }, */
13262 /* { "COUPDAYSNC","COUPDAYSNC" }, */
13263 /* { "COUPNCD","COUPNCD" }, */
13264 /* { "COUPNUM","COUPNUM" }, */
13265 /* { "COUPPCD","COUPPCD" }, */
13266 /* { "COVAR","COVAR" }, */
13267 /* { "CRITBINOM","CRITBINOM" }, */
13268 /* { "CSC","CSC" }, */
13269 /* { "CSCH","CSCH" }, */
13270 /* { "CUMIPMT","CUMIPMT" }, */
13271 /* { "CUMPRINC","CUMPRINC" }, */
13272 /* { "DATE","DATE" }, */
13273 /* { "DATEDIF","DATEDIF" }, */
13274 /* { "DATEVALUE","DATEVALUE" }, */
13275 /* { "DAVERAGE","DAVERAGE" }, */
13276 /* { "DAY","DAY" }, */
13277 /* { "DAYS","DAYS" }, */
13278 /* { "DAYS360","DAYS360" }, */
13279 /* { "DB","DB" }, */
13280 /* { "DCOUNT","DCOUNT" }, */
13281 /* { "DCOUNTA","DCOUNTA" }, */
13282 /* { "DDB","DDB" }, */
13283 /* { "DDE","DDE" }, */
13284 /* { "DEC2BIN","DEC2BIN" }, */
13285 /* { "DEC2HEX","DEC2HEX" }, */
13286 /* { "DEC2OCT","DEC2OCT" }, */
13287 /* { "DECIMAL","DECIMAL" }, */
13288 /* { "DEGREES","DEGREES" }, */
13289 /* { "DELTA","DELTA" }, */
13290 /* { "DEVSQ","DEVSQ" }, */
13291 /* { "DGET","DGET" }, */
13292 /* { "DISC","DISC" }, */
13293 /* { "DMAX","DMAX" }, */
13294 /* { "DMIN","DMIN" }, */
13295 /* { "DOLLARDE","DOLLARDE" }, */
13296 /* { "DOLLARFR","DOLLARFR" }, */
13297 /* { "DPRODUCT","DPRODUCT" }, */
13298 /* { "DSTDEV","DSTDEV" }, */
13299 /* { "DSTDEVP","DSTDEVP" }, */
13300 /* { "DSUM","DSUM" }, */
13301 /* { "DURATION","DURATION" }, */
13302 /* { "DVAR","DVAR" }, */
13303 /* { "DVARP","DVARP" }, */
13304 /* { "EDATE","EDATE" }, */
13305 /* { "EFFECT","EFFECT" }, */
13306 /* { "EOMONTH","EOMONTH" }, */
13307 /* { "ERF","ERF" }, */
13308 /* { "ERFC","ERFC" }, */
13309 /* { "ERROR.TYPE","ERROR.TYPE" }, */
13310 /* { "EUROCONVERT","EUROCONVERT" }, */
13311 /* { "EVEN","EVEN" }, */
13312 /* { "EXACT","EXACT" }, */
13313 /* { "EXP","EXP" }, */
13314 /* { "EXPONDIST","EXPONDIST" }, */
13315 /* { "FACT","FACT" }, */
13316 /* { "FACTDOUBLE","FACTDOUBLE" }, */
13317 /* { "FDIST","FDIST" }, */
13318 /* { "FIND","FIND" }, */
13319 /* { "FINDB","FINDB" }, */
13320 /* { "FINV","FINV" }, */
13321 /* { "FISHER","FISHER" }, */
13322 /* { "FISHERINV","FISHERINV" }, */
13323 /* { "FIXED","FIXED" }, */
13324 /* { "FORECAST","FORECAST" }, */
13325 /* { "FREQUENCY","FREQUENCY" }, */
13326 /* { "FTEST","FTEST" }, */
13327 /* { "FV","FV" }, */
13328 /* { "FVSCHEDULE","FVSCHEDULE" }, */
13329 /* { "GAMMA","GAMMA" }, */
13330 /* { "GAMMADIST","GAMMADIST" }, */
13331 /* { "GAMMAINV","GAMMAINV" }, */
13332 /* { "GAMMALN","GAMMALN" }, */
13333 /* { "GCD","GCD" }, */
13334 /* { "GEOMEAN","GEOMEAN" }, */
13335 /* { "GESTEP","GESTEP" }, */
13336 /* { "GETPIVOTDATA","GETPIVOTDATA" }, */
13337 /* { "GROWTH","GROWTH" }, */
13338 /* { "HARMEAN","HARMEAN" }, */
13339 /* { "HEX2BIN","HEX2BIN" }, */
13340 /* { "HEX2DEC","HEX2DEC" }, */
13341 /* { "HEX2OCT","HEX2OCT" }, */
13342 /* { "HLOOKUP","HLOOKUP" }, */
13343 /* { "HOUR","HOUR" }, */
13344 /* { "HYPERLINK","HYPERLINK" }, */
13345 /* { "HYPGEOMDIST","HYPGEOMDIST" }, */
13346 /* { "IF","IF" }, */
13347 /* { "IFERROR","IFERROR" }, */
13348 /* { "IFNA","IFNA" }, */
13349 /* { "IMABS","IMABS" }, */
13350 /* { "IMAGINARY","IMAGINARY" }, */
13351 /* { "IMARGUMENT","IMARGUMENT" }, */
13352 /* { "IMCONJUGATE","IMCONJUGATE" }, */
13353 /* { "IMCOS","IMCOS" }, */
13354 /* { "IMCOT","IMCOT" }, */
13355 /* { "IMCSC","IMCSC" }, */
13356 /* { "IMCSCH","IMCSCH" }, */
13357 /* { "IMDIV","IMDIV" }, */
13358 /* { "IMEXP","IMEXP" }, */
13359 /* { "IMLN","IMLN" }, */
13360 /* { "IMLOG10","IMLOG10" }, */
13361 /* { "IMLOG2","IMLOG2" }, */
13362 /* { "IMPOWER","IMPOWER" }, */
13363 /* { "IMPRODUCT","IMPRODUCT" }, */
13364 /* { "IMREAL","IMREAL" }, */
13365 /* { "IMSEC","IMSEC" }, */
13366 /* { "IMSECH","IMSECH" }, */
13367 /* { "IMSIN","IMSIN" }, */
13368 /* { "IMSQRT","IMSQRT" }, */
13369 /* { "IMSUB","IMSUB" }, */
13370 /* { "IMSUM","IMSUM" }, */
13371 /* { "IMTAN","IMTAN" }, */
13372 /* { "INDEX","INDEX" }, */
13373 /* { "INDIRECT","INDIRECT" }, */
13374 /* { "INFO","INFO" }, */
13375 /* { "INT","INT" }, */
13376 /* { "INTERCEPT","INTERCEPT" }, */
13377 /* { "INTRATE","INTRATE" }, */
13378 /* { "IPMT","IPMT" }, */
13379 /* { "IRR","IRR" }, */
13380 /* { "ISBLANK","ISBLANK" }, */
13381 /* { "ISERR","ISERR" }, */
13382 /* { "ISERROR","ISERROR" }, */
13383 /* { "ISEVEN","ISEVEN" }, */
13384 /* { "ISFORMULA","ISFORMULA" }, */
13385 /* { "ISLOGICAL","ISLOGICAL" }, */
13386 /* { "ISNA","ISNA" }, */
13387 /* { "ISNONTEXT","ISNONTEXT" }, */
13388 /* { "ISNUMBER","ISNUMBER" }, */
13389 /* { "ISODD","ISODD" }, */
13390 /* { "ISOWEEKNUM","ISOWEEKNUM" }, */
13391 /* { "ISPMT","ISPMT" }, */
13392 /* { "ISREF","ISREF" }, */
13393 /* { "ISTEXT","ISTEXT" }, */
13394 /* { "JIS","JIS" }, */
13395 /* { "KURT","KURT" }, */
13396 /* { "LARGE","LARGE" }, */
13397 /* { "LCM","LCM" }, */
13398 /* { "LEFT","LEFT" }, */
13399 /* { "LEFTB","LEFTB" }, */
13400 /* { "LEN","LEN" }, */
13401 /* { "LENB","LENB" }, */
13402 /* { "LINEST","LINEST" }, */
13403 /* { "LN","LN" }, */
13404 /* { "LOG","LOG" }, */
13405 /* { "LOG10","LOG10" }, */
13406 /* { "LOGEST","LOGEST" }, */
13407 /* { "LOGINV","LOGINV" }, */
13408 /* { "LOGNORMDIST","LOGNORMDIST" }, */
13409 /* { "LOOKUP","LOOKUP" }, */
13410 /* { "LOWER","LOWER" }, */
13411 /* { "MATCH","MATCH" }, */
13412 /* { "MAX","MAX" }, */
13413 /* { "MAXA","MAXA" }, */
13414 /* { "MDETERM","MDETERM" }, */
13415 /* { "MDURATION","MDURATION" }, */
13416 /* { "MEDIAN","MEDIAN" }, */
13417 /* { "MID","MID" }, */
13418 /* { "MIDB","MIDB" }, */
13419 /* { "MIN","MIN" }, */
13420 /* { "MINA","MINA" }, */
13421 /* { "MINUTE","MINUTE" }, */
13422 /* { "MINVERSE","MINVERSE" }, */
13423 /* { "MIRR","MIRR" }, */
13424 /* { "MMULT","MMULT" }, */
13425 /* { "MOD","MOD" }, */
13426 /* { "MODE","MODE" }, */
13427 /* { "MONTH","MONTH" }, */
13428 /* { "MROUND","MROUND" }, */
13429 /* { "MULTINOMIAL","MULTINOMIAL" }, */
13430 /* { "MULTIPLE.OPERATIONS","MULTIPLE.OPERATIONS" }, */
13431 /* { "MUNIT","MUNIT" }, */
13433 /* { "NA","NA" }, */
13434 /* { "NEGBINOMDIST","NEGBINOMDIST" }, */
13435 /* { "NETWORKDAYS","NETWORKDAYS" }, */
13436 /* { "NOMINAL","NOMINAL" }, */
13437 /* { "NORMDIST","NORMDIST" }, */
13438 /* { "NORMINV","NORMINV" }, */
13439 /* { "NOT","NOT" }, */
13440 /* { "NOW","NOW" }, */
13441 /* { "NPER","NPER" }, */
13442 /* { "NPV","NPV" }, */
13443 /* { "NUMBERVALUE","NUMBERVALUE" }, */
13444 /* { "OCT2BIN","OCT2BIN" }, */
13445 /* { "OCT2DEC","OCT2DEC" }, */
13446 /* { "OCT2HEX","OCT2HEX" }, */
13447 /* { "ODD","ODD" }, */
13448 /* { "ODDFPRICE","ODDFPRICE" }, */
13449 /* { "ODDFYIELD","ODDFYIELD" }, */
13450 /* { "ODDLPRICE","ODDLPRICE" }, */
13451 /* { "ODDLYIELD","ODDLYIELD" }, */
13452 /* { "OFFSET","OFFSET" }, */
13453 /* { "OR","OR" }, */
13454 /* { "PEARSON","PEARSON" }, */
13455 /* { "PERCENTILE","PERCENTILE" }, */
13456 /* { "PERCENTRANK","PERCENTRANK" }, */
13457 /* { "PERMUT","PERMUT" }, */
13458 /* { "PERMUTATIONA","PERMUTATIONA" }, */
13459 /* { "PI","PI" }, */
13460 /* { "PMT","PMT" }, */
13461 /* { "POISSON","POISSON" }, */
13462 /* { "POWER","POWER" }, */
13463 /* { "PPMT","PPMT" }, */
13464 /* { "PRICE","PRICE" }, */
13465 /* { "PRICEDISC","PRICEDISC" }, */
13466 /* { "PRICEMAT","PRICEMAT" }, */
13467 /* { "PROB","PROB" }, */
13468 /* { "PRODUCT","PRODUCT" }, */
13469 /* { "PROPER","PROPER" }, */
13470 /* { "PV","PV" }, */
13471 /* { "QUARTILE","QUARTILE" }, */
13472 /* { "QUOTIENT","QUOTIENT" }, */
13473 /* { "RADIANS","RADIANS" }, */
13474 /* { "RAND","RAND" }, */
13475 /* { "RANDBETWEEN","RANDBETWEEN" }, */
13476 /* { "RANK","RANK" }, */
13477 /* { "RATE","RATE" }, */
13478 /* { "RECEIVED","RECEIVED" }, */
13479 /* { "REPLACE","REPLACE" }, */
13480 /* { "REPLACEB","REPLACEB" }, */
13481 /* { "REPT","REPT" }, */
13482 /* { "RIGHT","RIGHT" }, */
13483 /* { "RIGHTB","RIGHTB" }, */
13484 /* { "ROMAN","ROMAN" }, */
13485 /* { "ROUND","ROUND" }, */
13486 /* { "ROUNDDOWN","ROUNDDOWN" }, */
13487 /* { "ROUNDUP","ROUNDUP" }, */
13488 /* { "ROW","ROW" }, */
13489 /* { "ROWS","ROWS" }, */
13490 /* { "RRI","RRI" }, */
13491 /* { "RSQ","RSQ" }, */
13492 /* { "SEARCH","SEARCH" }, */
13493 /* { "SEARCHB","SEARCHB" }, */
13494 /* { "SEC","SEC" }, */
13495 /* { "SECH","SECH" }, */
13496 /* { "SECOND","SECOND" }, */
13497 /* { "SERIESSUM","SERIESSUM" }, */
13498 /* { "SHEET","SHEET" }, */
13499 /* { "SHEETS","SHEETS" }, */
13500 /* { "SIGN","SIGN" }, */
13501 /* { "SIN","SIN" }, */
13502 /* { "SINH","SINH" }, */
13503 /* { "SKEW","SKEW" }, */
13504 /* { "SKEWP","SKEWP" }, */
13505 /* { "SLN","SLN" }, */
13506 /* { "SLOPE","SLOPE" }, */
13507 /* { "SMALL","SMALL" }, */
13508 /* { "SQRT","SQRT" }, */
13509 /* { "SQRTPI","SQRTPI" }, */
13510 /* { "STANDARDIZE","STANDARDIZE" }, */
13511 /* { "STDEV","STDEV" }, */
13512 /* { "STDEVA","STDEVA" }, */
13513 /* { "STDEVP","STDEVP" }, */
13514 /* { "STDEVPA","STDEVPA" }, */
13515 /* { "STEYX","STEYX" }, */
13516 /* { "SUBSTITUTE","SUBSTITUTE" }, */
13517 /* { "SUBTOTAL","SUBTOTAL" }, */
13518 /* { "SUM","SUM" }, */
13519 /* { "SUMIF","SUMIF" }, */
13520 /* { "SUMIFS","SUMIFS" }, */
13521 /* { "SUMPRODUCT","SUMPRODUCT" }, */
13522 /* { "SUMSQ","SUMSQ" }, */
13523 /* { "SUMX2MY2","SUMX2MY2" }, */
13524 /* { "SUMX2PY2","SUMX2PY2" }, */
13525 /* { "SUMXMY2","SUMXMY2" }, */
13526 /* { "SYD","SYD" }, */
13528 /* { "TAN","TAN" }, */
13529 /* { "TANH","TANH" }, */
13530 /* { "TBILLEQ","TBILLEQ" }, */
13531 /* { "TBILLPRICE","TBILLPRICE" }, */
13532 /* { "TBILLYIELD","TBILLYIELD" }, */
13533 /* { "TEXT","TEXT" }, */
13534 /* { "TIME","TIME" }, */
13535 /* { "TIMEVALUE","TIMEVALUE" }, */
13536 /* { "TINV","TINV" }, */
13537 /* { "TODAY","TODAY" }, */
13538 /* { "TRANSPOSE","TRANSPOSE" }, */
13539 /* { "TREND","TREND" }, */
13540 /* { "TRIM","TRIM" }, */
13541 /* { "TRIMMEAN","TRIMMEAN" }, */
13542 /* { "TRUNC","TRUNC" }, */
13543 /* { "TTEST","TTEST" }, */
13544 /* { "TYPE","TYPE" }, */
13545 /* { "UNICHAR","UNICHAR" }, */
13546 /* { "UNICODE","UNICODE" }, */
13547 /* { "UPPER","UPPER" }, */
13548 /* { "VALUE","VALUE" }, */
13549 /* { "VAR","VAR" }, */
13550 /* { "VARA","VARA" }, */
13551 /* { "VARP","VARP" }, */
13552 /* { "VARPA","VARPA" }, */
13553 /* { "VDB","VDB" }, */
13554 /* { "VLOOKUP","VLOOKUP" }, */
13555 /* { "WEEKDAY","WEEKDAY" }, */
13556 /* { "WEEKNUM","WEEKNUM" }, */
13557 /* { "WEIBULL","WEIBULL" }, */
13558 /* { "WORKDAY","WORKDAY" }, */
13559 /* { "XIRR","XIRR" }, */
13560 /* { "XNPV","XNPV" }, */
13561 /* { "XOR","XOR" }, */
13562 /* { "YEAR","YEAR" }, */
13563 /* { "YEARFRAC","YEARFRAC" }, */
13564 /* { "YIELD","YIELD" }, */
13565 /* { "YIELDDISC","YIELDDISC" }, */
13566 /* { "YIELDMAT","YIELDMAT" }, */
13567 /* { "ZTEST","ZTEST" }, */
13570 static char const OOoAnalysisPrefix
[] = "com.sun.star.sheet.addin.Analysis.get";
13571 static char const GnumericPrefix
[] = "ORG.GNUMERIC.";
13572 static char const MicrosoftPrefix
[] = "COM.MICROSOFT.";
13576 GnmExpr
const * (*handler
) (GnmConventions
const *convs
, Workbook
*scope
, GnmExprList
*args
);
13577 ODFConventions
*oconv
= (ODFConventions
*)convs
;
13578 GHashTable
*namemap
;
13579 GHashTable
*handlermap
;
13581 if (NULL
== oconv
->state
->openformula_namemap
) {
13582 namemap
= g_hash_table_new (go_ascii_strcase_hash
,
13583 go_ascii_strcase_equal
);
13584 for (i
= 0; sc_func_renames
[i
].oo_name
; i
++)
13585 g_hash_table_insert (namemap
,
13586 (gchar
*) sc_func_renames
[i
].oo_name
,
13587 (gchar
*) sc_func_renames
[i
].gnm_name
);
13588 oconv
->state
->openformula_namemap
= namemap
;
13590 namemap
= oconv
->state
->openformula_namemap
;
13592 if (NULL
== oconv
->state
->openformula_handlermap
) {
13594 handlermap
= g_hash_table_new (go_ascii_strcase_hash
,
13595 go_ascii_strcase_equal
);
13596 for (i
= 0; sc_func_handlers
[i
].gnm_name
; i
++)
13597 g_hash_table_insert (handlermap
,
13598 (gchar
*) sc_func_handlers
[i
].gnm_name
,
13599 sc_func_handlers
[i
].handler
);
13600 oconv
->state
->openformula_handlermap
= handlermap
;
13602 handlermap
= oconv
->state
->openformula_handlermap
;
13604 handler
= g_hash_table_lookup (handlermap
, name
);
13605 if (handler
!= NULL
) {
13606 GnmExpr
const * res
= handler (convs
, scope
, args
);
13611 if (0 == g_ascii_strncasecmp (name
, GnumericPrefix
, sizeof (GnumericPrefix
)-1)) {
13612 f
= gnm_func_lookup_or_add_placeholder (name
+sizeof (GnumericPrefix
)-1);
13613 } else if (0 == g_ascii_strncasecmp (name
, OOoAnalysisPrefix
, sizeof (OOoAnalysisPrefix
)-1)) {
13614 f
= gnm_func_lookup_or_add_placeholder (name
+sizeof (OOoAnalysisPrefix
)-1);
13615 } else if (0 == g_ascii_strncasecmp (name
, MicrosoftPrefix
, sizeof (MicrosoftPrefix
)-1)) {
13616 char const *new_name
;
13617 if (NULL
!= namemap
&&
13618 NULL
!= (new_name
= g_hash_table_lookup (namemap
, name
+sizeof (MicrosoftPrefix
)-1)))
13619 f
= gnm_func_lookup_or_add_placeholder (new_name
);
13623 char const *new_name
;
13624 if (NULL
!= namemap
&&
13625 NULL
!= (new_name
= g_hash_table_lookup (namemap
, name
)))
13627 f
= gnm_func_lookup_or_add_placeholder (name
);
13630 return gnm_expr_new_funcall (f
, args
);
13634 identified_google_docs (GsfInfile
*zip
)
13636 /* As of 2011/10/1 google-docs does not store any generator info so */
13637 /* we cannot use that for identification */
13638 gboolean google_docs
= FALSE
;
13639 GsfInput
*content
= gsf_infile_child_by_name
13640 (zip
, "content.xml");
13642 /* pick arbitrary size limit of 0.5k for the manifest to avoid
13643 * potential of any funny business */
13644 size_t size
= MIN (gsf_input_size (content
), 512);
13645 char const *mf
= gsf_input_read (content
, size
, NULL
);
13648 (NULL
!= g_strstr_len
13650 "urn:oasis:names:tc:opendocument:xmlns:office:1.0"));
13651 g_object_unref (content
);
13653 return google_docs
;
13657 determine_oo_version (GsfInfile
*zip
, OOVer def
)
13659 char const *header
;
13661 GsfInput
*mimetype
= gsf_infile_child_by_name (zip
, "mimetype");
13663 /* Google-docs is the mimetype so we need to check that */
13664 if (identified_google_docs (zip
))
13665 return OOO_VER_OPENDOC
;
13666 /* Really old versions also had no mimetype. Allow that,
13667 except in the probe. */
13671 /* pick arbitrary size limit of 2k for the mimetype to avoid
13672 * potential of any funny business */
13673 size
= MIN (gsf_input_size (mimetype
), 2048);
13674 header
= gsf_input_read (mimetype
, size
, NULL
);
13679 for (ui
= 0 ; ui
< G_N_ELEMENTS (OOVersions
) ; ui
++)
13680 if (size
== strlen (OOVersions
[ui
].mime_type
) &&
13681 !memcmp (OOVersions
[ui
].mime_type
, header
, size
)) {
13682 g_object_unref (mimetype
);
13683 return OOVersions
[ui
].version
;
13687 g_object_unref (mimetype
);
13688 return OOO_VER_UNKNOWN
;
13692 openoffice_file_open (GOFileOpener
const *fo
, GOIOContext
*io_context
,
13693 WorkbookView
*wb_view
, GsfInput
*input
);
13694 G_MODULE_EXPORT
void
13695 openoffice_file_open (G_GNUC_UNUSED GOFileOpener
const *fo
, GOIOContext
*io_context
,
13696 WorkbookView
*wb_view
, GsfInput
*input
)
13699 GsfInput
*contents
= NULL
;
13700 GsfInput
*styles
= NULL
;
13701 GsfDocMetaData
*meta_data
;
13704 OOParseState state
;
13705 GError
*err
= NULL
;
13707 gboolean content_malformed
= FALSE
;
13709 zip
= gsf_infile_zip_new (input
, &err
);
13711 g_return_if_fail (err
!= NULL
);
13712 go_cmd_context_error_import (GO_CMD_CONTEXT (io_context
),
13714 g_error_free (err
);
13718 state
.ver
= determine_oo_version (zip
, OOO_VER_1
);
13719 if (state
.ver
== OOO_VER_UNKNOWN
) {
13720 /* TODO : include the unknown type in the message when
13721 * we move the error handling into the importer object */
13722 go_cmd_context_error_import (GO_CMD_CONTEXT (io_context
),
13723 _("Unknown mimetype for openoffice file."));
13724 g_object_unref (zip
);
13726 } else if (state
.ver
== OOO_VER_OPENDOC
)
13727 state
.ver_odf
= 1.2; /* Probably most common at this time */
13728 else state
.ver_odf
= 0.;
13730 contents
= gsf_infile_child_by_name (zip
, "content.xml");
13731 if (contents
== NULL
) {
13732 go_cmd_context_error_import (GO_CMD_CONTEXT (io_context
),
13733 _("No stream named content.xml found."));
13734 g_object_unref (zip
);
13738 styles
= gsf_infile_child_by_name (zip
, "styles.xml");
13739 if (styles
== NULL
) {
13740 go_cmd_context_error_import (GO_CMD_CONTEXT (io_context
),
13741 _("No stream named styles.xml found."));
13742 g_object_unref (contents
);
13743 g_object_unref (zip
);
13747 locale
= gnm_push_C_locale ();
13750 state
.debug
= gnm_debug_flag ("opendocumentimport");
13751 state
.hd_ft_left_warned
= FALSE
;
13752 state
.context
= io_context
;
13753 state
.wb_view
= wb_view
;
13754 state
.pos
.wb
= wb_view_get_workbook (wb_view
);
13756 state
.pos
.sheet
= NULL
;
13757 state
.pos
.eval
.col
= -1;
13758 state
.pos
.eval
.row
= -1;
13759 state
.cell_comment
= NULL
;
13760 state
.sharer
= gnm_expr_sharer_new ();
13761 state
.chart
.name
= NULL
;
13762 state
.chart
.cs_enhanced_path
= NULL
;
13763 state
.chart
.cs_modifiers
= NULL
;
13764 state
.chart
.cs_viewbox
= NULL
;
13765 state
.chart
.cs_type
= NULL
;
13766 state
.chart
.cs_variables
= NULL
;
13767 for (i
= 0; i
< OO_CHART_STYLE_INHERITANCE
; i
++)
13768 state
.chart
.i_plot_styles
[i
] = NULL
;
13769 state
.styles
.sheet
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13770 (GDestroyNotify
) g_free
,
13771 (GDestroyNotify
) oo_sheet_style_free
);
13772 state
.styles
.text
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13773 (GDestroyNotify
) g_free
,
13774 (GDestroyNotify
) pango_attr_list_unref
);
13775 state
.styles
.col
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13776 (GDestroyNotify
) g_free
,
13777 (GDestroyNotify
) g_free
);
13778 state
.styles
.row
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13779 (GDestroyNotify
) g_free
,
13780 (GDestroyNotify
) g_free
);
13781 state
.styles
.cell
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13782 (GDestroyNotify
) g_free
,
13783 (GDestroyNotify
) odf_oo_cell_style_unref
);
13784 state
.styles
.cell_datetime
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13785 (GDestroyNotify
) g_free
,
13786 (GDestroyNotify
) odf_oo_cell_style_unref
);
13787 state
.styles
.cell_date
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13788 (GDestroyNotify
) g_free
,
13789 (GDestroyNotify
) odf_oo_cell_style_unref
);
13790 state
.styles
.cell_time
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13791 (GDestroyNotify
) g_free
,
13792 (GDestroyNotify
) odf_oo_cell_style_unref
);
13793 state
.styles
.master_pages
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13794 (GDestroyNotify
) g_free
,
13795 (GDestroyNotify
) gnm_print_info_free
);
13796 state
.styles
.page_layouts
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13797 (GDestroyNotify
) g_free
,
13798 (GDestroyNotify
) gnm_print_info_free
);
13799 state
.formats
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13800 (GDestroyNotify
) g_free
,
13801 (GDestroyNotify
) go_format_unref
);
13802 state
.validations
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
13803 (GDestroyNotify
) g_free
,
13804 (GDestroyNotify
) odf_validation_free
);
13805 state
.chart
.so
= NULL
;
13806 state
.chart
.saved_graph_styles
= NULL
;
13807 state
.chart
.saved_hatches
= NULL
;
13808 state
.chart
.saved_dash_styles
= NULL
;
13809 state
.chart
.saved_fill_image_styles
= NULL
;
13810 state
.chart
.saved_gradient_styles
= NULL
;
13811 state
.chart
.graph_styles
= g_hash_table_new_full
13812 (g_str_hash
, g_str_equal
,
13813 (GDestroyNotify
) g_free
,
13814 (GDestroyNotify
) oo_chart_style_free
);
13815 state
.chart
.hatches
= g_hash_table_new_full
13816 (g_str_hash
, g_str_equal
,
13817 (GDestroyNotify
) g_free
,
13818 (GDestroyNotify
) g_free
);
13819 state
.chart
.dash_styles
= g_hash_table_new_full
13820 (g_str_hash
, g_str_equal
,
13821 (GDestroyNotify
) g_free
,
13823 state
.chart
.fill_image_styles
= g_hash_table_new_full
13824 (g_str_hash
, g_str_equal
,
13825 (GDestroyNotify
) g_free
,
13826 (GDestroyNotify
) g_free
);
13827 state
.chart
.gradient_styles
= g_hash_table_new_full
13828 (g_str_hash
, g_str_equal
,
13829 (GDestroyNotify
) g_free
,
13830 (GDestroyNotify
) g_free
);
13831 state
.controls
= g_hash_table_new_full
13832 (g_str_hash
, g_str_equal
,
13833 (GDestroyNotify
) g_free
,
13834 (GDestroyNotify
) oo_control_free
);
13835 state
.chart
.arrow_markers
= g_hash_table_new_full
13836 (g_str_hash
, g_str_equal
,
13837 (GDestroyNotify
) g_free
,
13838 (GDestroyNotify
) oo_marker_free
);
13839 state
.strings
= g_hash_table_new_full
13840 (g_str_hash
, g_str_equal
,
13841 (GDestroyNotify
) g_free
,
13842 (GDestroyNotify
) g_free
);
13843 state
.cur_style
.cells
= NULL
;
13844 state
.cur_style
.col_rows
= NULL
;
13845 state
.cur_style
.sheets
= NULL
;
13846 state
.default_style
.cells
= NULL
;
13847 state
.default_style
.rows
= NULL
;
13848 state
.default_style
.columns
= NULL
;
13849 state
.default_style
.graphics
= NULL
;
13850 state
.cur_style
.type
= OO_STYLE_UNKNOWN
;
13851 state
.cur_style
.requires_disposal
= FALSE
;
13852 state
.sheet_order
= NULL
;
13853 for (i
= 0; i
<NUM_FORMULAE_SUPPORTED
; i
++)
13854 state
.convs
[i
] = NULL
;
13855 state
.openformula_namemap
= NULL
;
13856 state
.openformula_handlermap
= NULL
;
13857 state
.cur_format
.accum
= NULL
;
13858 state
.cur_format
.percentage
= FALSE
;
13859 state
.filter
= NULL
;
13860 state
.print
.page_breaks
.h
= state
.print
.page_breaks
.v
= NULL
;
13861 state
.last_progress_update
= 0;
13862 state
.last_error
= NULL
;
13863 state
.cur_control
= NULL
;
13864 state
.chart_list
= NULL
;
13866 state
.text_p_stack
= NULL
;
13867 state
.text_p_for_cell
.permanent
= TRUE
;
13868 state
.text_p_for_cell
.span_style_stack
= NULL
;
13869 state
.text_p_for_cell
.span_style_list
= NULL
;
13870 state
.text_p_for_cell
.gstr
= NULL
;
13871 state
.text_p_for_cell
.attrs
= NULL
;
13873 state
.table_n
= -1;
13875 go_io_progress_message (state
.context
, _("Reading file..."));
13876 go_io_value_progress_set (state
.context
, gsf_input_size (contents
), 0);
13878 if (state
.ver
== OOO_VER_OPENDOC
) {
13879 GsfInput
*meta_file
= gsf_infile_child_by_name (zip
, "meta.xml");
13880 if (NULL
!= meta_file
) {
13881 meta_data
= gsf_doc_meta_data_new ();
13882 err
= gsf_doc_meta_data_read_from_odf (meta_data
, meta_file
);
13884 go_io_warning (io_context
,
13885 _("Invalid metadata '%s'"), err
->message
);
13886 g_error_free (err
);
13888 go_doc_set_meta_data (GO_DOC (state
.pos
.wb
), meta_data
);
13890 g_object_unref (meta_data
);
13891 g_object_unref (meta_file
);
13895 doc
= gsf_xml_in_doc_new ((state
.ver
== OOO_VER_1
)
13896 ? ooo1_content_preparse_dtd
13897 : opendoc_content_preparse_dtd
,
13898 gsf_odf_get_ns ());
13899 content_malformed
= !gsf_xml_in_doc_parse (doc
, contents
, &state
);
13900 gsf_xml_in_doc_free (doc
);
13901 odf_clear_conventions (&state
); /* contain references to xin */
13902 state
.sheet_order
= g_slist_reverse (state
.sheet_order
);
13904 if (NULL
!= styles
) {
13905 GsfXMLInDoc
*doc
= gsf_xml_in_doc_new (styles_dtd
,
13906 gsf_odf_get_ns ());
13907 gsf_xml_in_doc_parse (doc
, styles
, &state
);
13908 gsf_xml_in_doc_free (doc
);
13909 odf_clear_conventions (&state
); /* contain references to xin */
13910 g_object_unref (styles
);
13913 if (!content_malformed
) {
13914 gsf_input_seek (contents
, 0, G_SEEK_SET
);
13915 doc
= gsf_xml_in_doc_new ((state
.ver
== OOO_VER_1
)
13917 : opendoc_content_dtd
,
13918 gsf_odf_get_ns ());
13919 content_malformed
= !gsf_xml_in_doc_parse (doc
, contents
, &state
);
13920 gsf_xml_in_doc_free (doc
);
13921 odf_clear_conventions (&state
);
13923 odf_fix_expr_names (&state
);
13927 if (!content_malformed
) {
13928 GsfInput
*settings
;
13929 char const *filesaver
;
13931 /* look for the view settings */
13932 state
.settings
.settings
13933 = g_hash_table_new_full (g_str_hash
, g_str_equal
,
13934 (GDestroyNotify
) g_free
,
13935 (GDestroyNotify
) destroy_gvalue
);
13936 state
.settings
.stack
= NULL
;
13937 settings
= gsf_infile_child_by_name (zip
, "settings.xml");
13938 if (settings
!= NULL
) {
13939 GsfXMLInDoc
*sdoc
= gsf_xml_in_doc_new
13940 (opendoc_settings_dtd
, gsf_odf_get_ns ());
13941 gsf_xml_in_doc_parse (sdoc
, settings
, &state
);
13942 gsf_xml_in_doc_free (sdoc
);
13943 odf_clear_conventions (&state
); /* contain references to xin */
13944 g_object_unref (settings
);
13946 if (state
.settings
.stack
!= NULL
) {
13947 go_cmd_context_error_import (GO_CMD_CONTEXT (io_context
),
13948 _("settings.xml stream is malformed!"));
13949 g_slist_free_full (state
.settings
.stack
,
13950 (GDestroyNotify
) g_hash_table_unref
);
13951 state
.settings
.stack
= NULL
;
13954 /* Use the settings here! */
13956 g_hash_table_foreach (state
.settings
.settings
,
13957 (GHFunc
)dump_settings_hash
, (char *)"");
13958 if (!odf_has_gnm_foreign (&state
)) {
13959 filesaver
= odf_created_by_gnumeric (&state
) ?
13960 "Gnumeric_OpenCalc:openoffice"
13961 : "Gnumeric_OpenCalc:odf";
13963 filesaver
= "Gnumeric_OpenCalc:odf";
13965 odf_apply_ooo_config (&state
);
13966 odf_apply_gnm_config (&state
);
13968 workbook_set_saveinfo (state
.pos
.wb
, GO_FILE_FL_AUTO
,
13969 go_file_saver_for_id
13972 g_hash_table_destroy (state
.settings
.settings
);
13973 state
.settings
.settings
= NULL
;
13977 go_io_progress_unset (state
.context
);
13978 g_free (state
.last_error
);
13980 /* This should be empty! */
13981 while (state
.text_p_stack
)
13982 odf_pop_text_p (&state
);
13984 if (state
.default_style
.cells
)
13985 odf_oo_cell_style_unref (state
.default_style
.cells
);
13986 g_free (state
.default_style
.rows
);
13987 g_free (state
.default_style
.columns
);
13988 oo_chart_style_free (state
.default_style
.graphics
);
13989 odf_free_cur_style (&state
);
13990 g_hash_table_destroy (state
.styles
.sheet
);
13991 g_hash_table_destroy (state
.styles
.text
);
13992 g_hash_table_destroy (state
.styles
.col
);
13993 g_hash_table_destroy (state
.styles
.row
);
13994 g_hash_table_destroy (state
.styles
.cell
);
13995 g_hash_table_destroy (state
.styles
.cell_datetime
);
13996 g_hash_table_destroy (state
.styles
.cell_date
);
13997 g_hash_table_destroy (state
.styles
.cell_time
);
13998 g_hash_table_destroy (state
.styles
.master_pages
);
13999 g_hash_table_destroy (state
.styles
.page_layouts
);
14000 g_slist_free_full (state
.chart
.saved_graph_styles
,
14001 (GDestroyNotify
)g_hash_table_destroy
);
14002 g_hash_table_destroy (state
.chart
.graph_styles
);
14003 g_hash_table_destroy (state
.chart
.hatches
);
14004 g_hash_table_destroy (state
.chart
.dash_styles
);
14005 g_hash_table_destroy (state
.chart
.fill_image_styles
);
14006 g_hash_table_destroy (state
.chart
.gradient_styles
);
14007 g_hash_table_destroy (state
.formats
);
14008 g_hash_table_destroy (state
.controls
);
14009 g_hash_table_destroy (state
.validations
);
14010 g_hash_table_destroy (state
.strings
);
14011 g_hash_table_destroy (state
.chart
.arrow_markers
);
14012 g_slist_free_full (state
.sheet_order
, (GDestroyNotify
)g_free
);
14013 if (state
.openformula_namemap
)
14014 g_hash_table_destroy (state
.openformula_namemap
);
14015 if (state
.openformula_handlermap
)
14016 g_hash_table_destroy (state
.openformula_handlermap
);
14017 g_object_unref (contents
);
14018 gnm_expr_sharer_destroy (state
.sharer
);
14019 g_free (state
.chart
.cs_enhanced_path
);
14020 g_free (state
.chart
.cs_modifiers
);
14021 g_free (state
.chart
.cs_viewbox
);
14022 g_free (state
.chart
.cs_type
);
14023 if (state
.chart
.so
)
14024 g_object_unref (state
.chart
.so
);
14025 if (state
.chart_list
)
14026 g_slist_free_full (state
.chart_list
, odf_destroy_object_offset
);
14027 if (state
.chart
.cs_variables
)
14028 g_hash_table_destroy (state
.chart
.cs_variables
);
14029 g_slist_free (state
.text_p_for_cell
.span_style_stack
);
14030 g_slist_free_full (state
.text_p_for_cell
.span_style_list
, g_free
);
14031 if (state
.text_p_for_cell
.gstr
)
14032 g_string_free (state
.text_p_for_cell
.gstr
, TRUE
);
14033 if (state
.text_p_for_cell
.attrs
)
14034 pango_attr_list_unref (state
.text_p_for_cell
.attrs
);
14036 g_object_unref (zip
);
14038 if (content_malformed
)
14039 go_io_error_string (io_context
, _("XML document not well formed!"));
14041 i
= workbook_sheet_count (state
.pos
.wb
);
14043 sheet_flag_recompute_spans (workbook_sheet_by_index (state
.pos
.wb
, i
));
14044 workbook_queue_all_recalc (state
.pos
.wb
);
14046 gnm_pop_C_locale (locale
);
14050 openoffice_file_probe (GOFileOpener
const *fo
, GsfInput
*input
, GOFileProbeLevel pl
);
14053 openoffice_file_probe (G_GNUC_UNUSED GOFileOpener
const *fo
, GsfInput
*input
, G_GNUC_UNUSED GOFileProbeLevel pl
)
14058 gboolean old_ext_ok
= FALSE
;
14059 char const *name
= gsf_input_name (input
);
14061 name
= gsf_extension_pointer (name
);
14062 old_ext_ok
= (name
!= NULL
&&
14063 (g_ascii_strcasecmp (name
, "sxc") == 0 ||
14064 g_ascii_strcasecmp (name
, "stc") == 0));
14067 zip
= gsf_infile_zip_new (input
, NULL
);
14071 ver
= determine_oo_version
14072 (zip
, old_ext_ok
? OOO_VER_1
: OOO_VER_UNKNOWN
);
14074 g_object_unref (zip
);
14076 return ver
!= OOO_VER_UNKNOWN
;
14080 make_node_id (GsfXMLInNode
const *node
)
14082 return g_strconcat (node
->id
, " -- ", node
->parent_id
, NULL
);
14085 static GsfXMLInNode
const *
14086 create_preparse_dtd (const GsfXMLInNode
*orig
, const GsfXMLInNode
*overrides
)
14089 GHashTable
*loc_hash
=
14090 g_hash_table_new_full (g_str_hash
, g_str_equal
, g_free
, NULL
);
14093 for (N
= 0; orig
[N
].id
!= NULL
; N
++) {
14094 g_hash_table_replace (loc_hash
, make_node_id (orig
+ N
),
14095 GINT_TO_POINTER (N
));
14099 res
= g_memdup (orig
, (N
+ 1) * sizeof (GsfXMLInNode
));
14100 for (i
= 0; i
< N
; i
++) {
14101 res
[i
].start
= NULL
;
14103 res
[i
].has_content
= GSF_XML_NO_CONTENT
;
14106 for (i
= 0; overrides
[i
].id
!= NULL
; i
++) {
14107 char *id
= make_node_id (overrides
+ i
);
14108 int loc
= GPOINTER_TO_INT (g_hash_table_lookup (loc_hash
, id
));
14110 res
[loc
] = overrides
[i
];
14114 g_hash_table_destroy (loc_hash
);
14119 G_MODULE_EXPORT
void
14120 go_plugin_init (G_GNUC_UNUSED GOPlugin
*plugin
, G_GNUC_UNUSED GOCmdContext
*cc
)
14122 magic_transparent
= style_color_auto_back ();
14124 opendoc_content_preparse_dtd
=
14125 create_preparse_dtd (opendoc_content_dtd
, opendoc_content_preparse_overrides
);
14127 ooo1_content_preparse_dtd
=
14128 create_preparse_dtd (ooo1_content_dtd
, ooo1_content_preparse_overrides
);
14131 G_MODULE_EXPORT
void
14132 go_plugin_shutdown (G_GNUC_UNUSED GOPlugin
*plugin
, G_GNUC_UNUSED GOCmdContext
*cc
)
14134 style_color_unref (magic_transparent
);
14135 magic_transparent
= NULL
;
14136 g_free ((gpointer
)opendoc_content_preparse_dtd
);
14137 opendoc_content_preparse_dtd
= NULL
;
14138 g_free ((gpointer
)ooo1_content_preparse_dtd
);
14139 ooo1_content_preparse_dtd
= NULL
;