1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * xlsx-read.c : Read MS Excel 2007 Office Open xml
5 * Copyright (C) 2006-2007 Jody Goldberg (jody@gnome.org)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) version 3.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
22 #include <gnumeric-config.h>
23 #include "xlsx-utils.h"
24 #include "ms-excel-write.h"
26 #include "sheet-view.h"
27 #include "sheet-style.h"
28 #include "sheet-merge.h"
32 #include "style-border.h"
33 #include "style-color.h"
34 #include "style-conditions.h"
35 #include "gnm-format.h"
39 #include "expr-name.h"
40 #include "print-info.h"
41 #include "validation.h"
42 #include "input-msg.h"
44 #include "sheet-filter.h"
46 #include "selection.h"
47 #include "command-context.h"
48 #include "workbook-view.h"
52 #include "sheet-object-graph.h"
53 #include "sheet-object-cell-comment.h"
54 #include "gnm-sheet-slicer.h"
55 #include "gnm-so-filled.h"
56 #include "gnm-so-line.h"
57 #include "sheet-object-image.h"
58 #include "number-match.h"
59 #include "dead-kittens.h"
61 #include <goffice/goffice.h>
64 #include "goffice-data.h" /* MOVE TO GOFFCE with slicer code */
65 #include "go-data-slicer-field.h" /* MOVE TO GOFFCE with slicer code */
67 #include <gsf/gsf-libxml.h>
68 #include <gsf/gsf-input.h>
69 #include <gsf/gsf-infile.h>
70 #include <gsf/gsf-infile-zip.h>
71 #include <gsf/gsf-open-pkg-utils.h>
72 #include <gsf/gsf-meta-names.h>
73 #include <gsf/gsf-doc-meta-data.h>
74 #include <gsf/gsf-docprop-vector.h>
75 #include <gsf/gsf-timestamp.h>
77 #include <glib/gi18n-lib.h>
83 /*****************************************************************************/
85 #define CXML2C(s) ((char const *)(s))
94 XLXS_TYPE_SST_STR
, /* 0 based index into sst */
97 XLXS_TYPE_INLINE_STR
, /* inline string */
98 /* How is this different from inlineStr ?? */
102 XLSX_PANE_TOP_LEFT
= 0,
103 XLSX_PANE_TOP_RIGHT
= 1,
104 XLSX_PANE_BOTTOM_LEFT
= 2,
105 XLSX_PANE_BOTTOM_RIGHT
= 3
119 GogObjectPosition compass
;
120 GogAxisPosition cross
;
122 gnm_float cross_value
;
123 gboolean invert_axis
;
126 double axis_elements
[GOG_AXIS_ELEM_MAX_ENTRY
];
127 guint8 axis_element_set
[GOG_AXIS_ELEM_MAX_ENTRY
];
137 GOIOContext
*context
; /* The IOcontext managing things */
138 WorkbookView
*wb_view
; /* View for the new workbook */
139 Workbook
*wb
; /* The new workbook */
141 Sheet
*sheet
; /* current sheet */
142 GnmCellPos pos
; /* current cell */
143 XLSXValueType pos_type
;
145 GnmExprTop
const *texpr
;
148 GHashTable
*shared_exprs
;
149 GnmConventions
*convs
;
151 SheetView
*sv
; /* current sheetview */
155 GHashTable
*num_fmts
;
157 GHashTable
*cell_styles
;
162 GPtrArray
*style_xfs
;
164 GPtrArray
*table_styles
;
165 GnmStyle
*style_accum
;
166 gboolean style_accum_partial
;
167 GnmStyleBorderType border_style
;
168 GnmColor
*border_color
;
170 GHashTable
*theme_colors_by_name
;
172 GPtrArray
*collection
; /* utility for the shared collection handlers */
174 XLSXPanePos pane_pos
;
176 GnmStyleConditions
*conditions
;
177 GSList
*cond_regions
;
181 int filter_cur_field
;
182 GSList
*filter_items
; /* an accumulator */
184 GSList
*validation_regions
;
185 GnmValidation
*validation
;
186 GnmInputMsg
*input_msg
;
188 GnmPageBreaks
*page_breaks
;
190 /* Rows/Cols state */
191 GnmStyle
*pending_rowcol_style
;
192 GnmRange pending_rowcol_range
;
196 gint64 drawing_pos
[8];
197 int drawing_pos_flags
;
198 GODrawingAnchorDir so_direction
;
199 GnmSOAnchorMode so_anchor_mode
;
200 GnmExprTop
const *link_texpr
;
202 /* Legacy drawing state */
203 double grp_offset
[4];
212 GogObject
*series_pt
;
213 gboolean series_pt_has_index
;
216 guint32 chart_color_state
;
222 unsigned int sp_type
;
224 gboolean inhibit_text_pop
;
225 gnm_float chart_pos
[4]; /* x, w, y, h */
226 gboolean chart_pos_mode
[4]; /* false: "factor", true: "edge" */
227 gboolean chart_pos_target
; /* true if "inner" */
240 Sheet
*defined_name_sheet
;
241 GList
*delayed_names
;
243 GSList
*pending_objects
;
247 Workbook
*external_ref
;
248 Sheet
*external_ref_sheet
;
252 GnmSheetSlicer
*slicer
;
253 GODataSlicerField
*slicer_field
;
255 GHashTable
*cache_by_id
;
257 GODataCacheSource
*cache_src
;
258 GODataCacheField
*cache_field
;
259 GPtrArray
*cache_field_values
;
261 unsigned int field_count
, record_count
;
262 char *cache_record_part_id
;
269 /* Document Properties */
270 GsfDocMetaData
*metadata
;
271 char *meta_prop_name
;
273 /* Rich Text handling */
275 PangoAttrList
*rich_attrs
;
276 PangoAttrList
*run_attrs
;
283 static GsfXMLInNS
const xlsx_ns
[] = {
284 GSF_XML_IN_NS (XL_NS_SS
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main"), /* Office 12 */
285 GSF_XML_IN_NS (XL_NS_SS
, "http://schemas.openxmlformats.org/spreadsheetml/2006/7/main"), /* Office 12 BETA-2 Technical Refresh */
286 GSF_XML_IN_NS (XL_NS_SS
, "http://schemas.openxmlformats.org/spreadsheetml/2006/5/main"), /* Office 12 BETA-2 */
287 GSF_XML_IN_NS (XL_NS_SS
, "http://schemas.microsoft.com/office/excel/2006/2"), /* Office 12 BETA-1 Technical Refresh */
288 GSF_XML_IN_NS (XL_NS_SS_DRAW
, "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"), /* Office 12 BETA-2 */
289 GSF_XML_IN_NS (XL_NS_SS_DRAW
, "http://schemas.openxmlformats.org/drawingml/2006/3/spreadsheetDrawing"), /* Office 12 BETA-2 Technical Refresh */
290 GSF_XML_IN_NS (XL_NS_CHART
, "http://schemas.openxmlformats.org/drawingml/2006/3/chart"), /* Office 12 BETA-2 */
291 GSF_XML_IN_NS (XL_NS_CHART
, "http://schemas.openxmlformats.org/drawingml/2006/chart"), /* Office 12 BETA-2 Technical Refresh */
292 GSF_XML_IN_NS (XL_NS_CHART_DRAW
, "http://schemas.openxmlformats.org/drawingml/2006/chartDrawing"),
293 GSF_XML_IN_NS (XL_NS_DRAW
, "http://schemas.openxmlformats.org/drawingml/2006/3/main"), /* Office 12 BETA-2 */
294 GSF_XML_IN_NS (XL_NS_DRAW
, "http://schemas.openxmlformats.org/drawingml/2006/main"), /* Office 12 BETA-2 Technical Refresh */
295 GSF_XML_IN_NS (XL_NS_GNM_EXT
, "http://www.gnumeric.org/ext/spreadsheetml"),
296 GSF_XML_IN_NS (XL_NS_DOC_REL
, "http://schemas.openxmlformats.org/officeDocument/2006/relationships"),
297 GSF_XML_IN_NS (XL_NS_PKG_REL
, "http://schemas.openxmlformats.org/package/2006/relationships"),
298 GSF_XML_IN_NS (XL_NS_LEG_OFF
, "urn:schemas-microsoft-com:office:office"),
299 GSF_XML_IN_NS (XL_NS_LEG_XL
, "urn:schemas-microsoft-com:office:excel"),
300 GSF_XML_IN_NS (XL_NS_LEG_VML
, "urn:schemas-microsoft-com:vml"),
301 GSF_XML_IN_NS (XL_NS_PROP_CP
, "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"),
302 GSF_XML_IN_NS (XL_NS_PROP_DC
, "http://purl.org/dc/elements/1.1/"),
303 GSF_XML_IN_NS (XL_NS_PROP_DCMITYPE
, "http://purl.org/dc/dcmitype"),
304 GSF_XML_IN_NS (XL_NS_PROP_DCTERMS
, "http://purl.org/dc/terms/"),
305 GSF_XML_IN_NS (XL_NS_PROP_XSI
, "http://www.w3.org/2001/XMLSchema-instance"),
306 GSF_XML_IN_NS (XL_NS_PROP
, "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"),
307 GSF_XML_IN_NS (XL_NS_PROP_VT
, "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"),
308 GSF_XML_IN_NS (XL_NS_PROP_CUSTOM
, "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"),
322 maybe_update_progress (GsfXMLIn
*xin
)
324 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
325 GsfInput
*input
= gsf_xml_in_get_input (xin
);
326 gsf_off_t pos
= gsf_input_tell (input
);
328 go_io_value_progress_update (state
->context
, pos
);
332 start_update_progress (XLSXReadState
*state
, GsfInput
*xin
,
333 char const *message
, double min
, double max
)
335 go_io_progress_range_push (state
->context
, min
, max
);
337 go_io_value_progress_set (state
->context
,
338 gsf_input_size (xin
), 10000);
339 go_io_progress_message (state
->context
, message
);
344 end_update_progress (XLSXReadState
*state
)
346 go_io_progress_range_pop (state
->context
);
350 xlsx_parse_stream (XLSXReadState
*state
, GsfInput
*in
, GsfXMLInNode
const *dtd
)
352 gboolean success
= FALSE
;
355 GsfXMLInDoc
*doc
= gsf_xml_in_doc_new (dtd
, xlsx_ns
);
357 success
= gsf_xml_in_doc_parse (doc
, in
, state
);
360 go_io_warning (state
->context
,
361 _("'%s' is corrupt!"),
362 gsf_input_name (in
));
364 gsf_xml_in_doc_free (doc
);
371 xlsx_parse_rel_by_id (GsfXMLIn
*xin
, char const *part_id
,
372 GsfXMLInNode
const *dtd
,
373 GsfXMLInNS
const *ns
)
376 gboolean debug
= gnm_debug_flag ("xlsx-parsing");
379 g_printerr ("{ /* Parsing : %s :: %s */\n",
380 gsf_input_name (gsf_xml_in_get_input (xin
)), part_id
);
382 err
= gsf_open_pkg_parse_rel_by_id (xin
, part_id
, dtd
, ns
);
384 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
385 go_io_warning (state
->context
, "%s", err
->message
);
390 g_printerr ("} /* DONE : %s :: %s */\n",
391 gsf_input_name (gsf_xml_in_get_input (xin
)), part_id
);
394 /****************************************************************************/
396 static gboolean
xlsx_warning (GsfXMLIn
*xin
, char const *fmt
, ...)
397 G_GNUC_PRINTF (2, 3);
400 xlsx_warning (GsfXMLIn
*xin
, char const *fmt
, ...)
402 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
406 va_start (args
, fmt
);
407 msg
= g_strdup_vprintf (fmt
, args
);
410 if (IS_SHEET (state
->sheet
)) {
412 if (state
->pos
.col
>= 0 && state
->pos
.row
>= 0)
413 tmp
= g_strdup_printf ("%s!%s : %s",
414 state
->sheet
->name_quoted
,
415 cellpos_as_string (&state
->pos
), msg
);
417 tmp
= g_strdup_printf ("%s : %s",
418 state
->sheet
->name_quoted
, msg
);
423 go_io_warning (state
->context
, "%s", msg
);
424 g_printerr ("%s\n", msg
);
427 return FALSE
; /* convenience */
431 char const * const name
;
436 attr_enum (GsfXMLIn
*xin
, xmlChar
const **attrs
,
437 char const *target
, EnumVal
const *enums
,
440 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
441 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
442 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
444 if (strcmp (attrs
[0], target
))
447 for (; enums
->name
!= NULL
; enums
++)
448 if (!strcmp (enums
->name
, attrs
[1])) {
452 return xlsx_warning (xin
,
453 _("Unknown enum value '%s' for attribute %s"),
458 * Take an _int_ as a result to allow the caller to use -1 as an undefined state.
461 attr_bool (G_GNUC_UNUSED GsfXMLIn
*xin
, xmlChar
const **attrs
,
465 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
466 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
467 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
469 if (strcmp (attrs
[0], target
))
472 *res
= (0 == strcmp (attrs
[1], "1") || 0 == strcmp (attrs
[1], "true")) ;
478 attr_int (GsfXMLIn
*xin
, xmlChar
const **attrs
,
485 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
486 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
487 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
489 if (strcmp (attrs
[0], target
))
493 tmp
= strtol (attrs
[1], &end
, 10);
494 if (errno
== ERANGE
|| tmp
> G_MAXINT
|| tmp
< G_MININT
)
495 return xlsx_warning (xin
,
496 _("Integer '%s' is out of range, for attribute %s"),
499 return xlsx_warning (xin
,
500 _("Invalid integer '%s' for attribute %s"),
508 attr_uint (GsfXMLIn
*xin
, xmlChar
const **attrs
,
509 char const *target
, unsigned *res
)
514 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
515 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
516 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
518 if (strcmp (attrs
[0], target
))
522 tmp
= strtoul (attrs
[1], &end
, 10);
523 if (errno
== ERANGE
|| tmp
!= (unsigned)tmp
)
524 return xlsx_warning (xin
,
525 _("Unisgned integer '%s' is out of range, for attribute %s"),
528 return xlsx_warning (xin
,
529 _("Invalid unsigned integer '%s' for attribute %s"),
537 attr_int64 (GsfXMLIn
*xin
, xmlChar
const **attrs
,
544 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
545 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
546 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
548 if (strcmp (attrs
[0], target
))
552 tmp
= g_ascii_strtoll (attrs
[1], &end
, 10);
554 return xlsx_warning (xin
,
555 _("Integer '%s' is out of range, for attribute %s"),
558 return xlsx_warning (xin
,
559 _("Invalid integer '%s' for attribute %s"),
567 attr_gocolor (GsfXMLIn
*xin
, xmlChar
const **attrs
,
574 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
575 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
576 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
578 if (strcmp (attrs
[0], target
))
582 rgb
= strtoul (attrs
[1], &end
, 16);
583 if (errno
== ERANGE
|| *end
)
584 return xlsx_warning (xin
,
585 _("Invalid RRGGBB color '%s' for attribute %s"),
589 guint8
const r
= (rgb
>> 16) & 0xff;
590 guint8
const g
= (rgb
>> 8) & 0xff;
591 guint8
const b
= (rgb
>> 0) & 0xff;
592 *res
= GO_COLOR_FROM_RGB (r
, g
, b
);
599 attr_float (GsfXMLIn
*xin
, xmlChar
const **attrs
,
606 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
607 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
608 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
610 if (strcmp (attrs
[0], target
))
613 tmp
= gnm_strto (attrs
[1], &end
);
615 return xlsx_warning (xin
,
616 _("Invalid number '%s' for attribute %s"),
623 * Either an integer scaled so 100000 means 100%, or something like "50%"
624 * which we'll return as 50*1000.
626 * The first seems off-spec, but is what Excel produces.
629 attr_percent (GsfXMLIn
*xin
, xmlChar
const **attrs
,
630 char const *target
, int *res
)
635 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
636 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
637 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
639 if (strcmp (attrs
[0], target
))
643 tmp
= strtol (attrs
[1], &end
, 10);
644 if (errno
== ERANGE
|| tmp
> G_MAXINT
/ 1000 || tmp
< G_MININT
/ 1000)
645 return xlsx_warning (xin
,
646 _("Integer '%s' is out of range, for attribute %s"),
650 else if (strcmp (end
, "%") == 0)
653 return xlsx_warning (xin
,
654 _("Invalid integer '%s' for attribute %s"),
662 attr_pos (GsfXMLIn
*xin
, xmlChar
const **attrs
,
666 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
670 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
671 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
672 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
674 if (strcmp (attrs
[0], target
))
677 end
= cellpos_parse (attrs
[1], gnm_sheet_get_size (state
->sheet
), &tmp
, TRUE
);
678 if (NULL
== end
|| *end
!= '\0')
679 return xlsx_warning (xin
,
680 _("Invalid cell position '%s' for attribute %s"),
687 attr_range (GsfXMLIn
*xin
, xmlChar
const **attrs
,
691 static const GnmSheetSize xlsx_size
= {
692 XLSX_MaxCol
, XLSX_MaxRow
695 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
696 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
697 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
699 if (strcmp (attrs
[0], target
))
702 if (!range_parse (res
, attrs
[1], &xlsx_size
))
703 xlsx_warning (xin
, _("Invalid range '%s' for attribute %s"),
709 attr_datetime (GsfXMLIn
*xin
, xmlChar
const **attrs
,
712 unsigned y
, m
, d
, h
, mi
, n
;
713 GnmValue
*res
= NULL
;
716 g_return_val_if_fail (attrs
!= NULL
, NULL
);
717 g_return_val_if_fail (attrs
[0] != NULL
, NULL
);
718 g_return_val_if_fail (attrs
[1] != NULL
, NULL
);
720 if (strcmp (attrs
[0], target
))
723 n
= sscanf (attrs
[1], "%u-%u-%uT%u:%u:%" GNM_SCANF_g
,
724 &y
, &m
, &d
, &h
, &mi
, &s
);
728 g_date_set_dmy (&date
, d
, m
, y
);
729 if (g_date_valid (&date
)) {
730 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
731 unsigned d_serial
= go_date_g_to_serial (&date
,
732 workbook_date_conv (state
->wb
));
734 double time_frac
= h
+ (gnm_float
)mi
/ 60 + s
/ 3600;
735 res
= value_new_float (d_serial
+ time_frac
/ 24.);
736 value_set_fmt (res
, state
->date_fmt
);
738 res
= value_new_int (d_serial
);
739 value_set_fmt (res
, go_format_default_date ());
749 xlsx_parse_distance (GsfXMLIn
*xin
, xmlChar
const *str
,
750 char const *name
, gnm_float
*pts
)
755 g_return_val_if_fail (str
!= NULL
, FALSE
);
757 num
= go_strtod (CXML2C (str
), &end
);
758 if (CXML2C (str
) != end
) {
759 if (0 == strncmp (end
, "mm", 2)) {
760 num
= GO_CM_TO_PT (num
/10.);
762 } else if (0 == strncmp (end
, "cm", 2)) {
763 num
= GO_CM_TO_PT (num
);
765 } else if (0 == strncmp (end
, "pt", 2)) {
767 } else if (0 == strncmp (end
, "pc", 2)) { /* pica 12pt == 1 pica */
770 } else if (0 == strncmp (end
, "pi", 2)) { /* pica 12pt == 1 pica */
773 } else if (0 == strncmp (end
, "in", 2)) {
774 num
= GO_IN_TO_PT (num
);
777 xlsx_warning (xin
, _("Invalid attribute '%s', unknown unit '%s'"),
782 xlsx_warning (xin
, _("Invalid attribute '%s', expected distance, received '%s'"),
788 return xlsx_warning (xin
,
789 _("Invalid attribute '%s', expected distance, received '%s'"),
800 attr_distance (GsfXMLIn
*xin
, xmlChar
const **attrs
,
801 char const *target
, gnm_float
*pts
)
803 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
804 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
805 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
807 if (strcmp (attrs
[0], target
))
810 return xlsx_parse_distance (xin
, attrs
[1], target
, pts
);
813 /***********************************************************************/
816 simple_bool (GsfXMLIn
*xin
, xmlChar
const **attrs
, int *res
)
818 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
819 if (attr_bool (xin
, attrs
, "val", res
))
826 simple_int (GsfXMLIn
*xin
, xmlChar
const **attrs
, int *res
)
828 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
829 if (attr_int (xin
, attrs
, "val", res
))
837 simple_uint (GsfXMLIn
*xin
, xmlChar
const **attrs
, unsigned *res
)
839 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
840 if (attr_uint (xin
, attrs
, "val", res
))
846 simple_float (GsfXMLIn
*xin
, xmlChar
const **attrs
, gnm_float
*res
)
848 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
849 if (attr_float (xin
, attrs
, "val", res
))
855 simple_enum (GsfXMLIn
*xin
, xmlChar
const **attrs
, EnumVal
const *enums
, int *res
)
857 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
858 if (attr_enum (xin
, attrs
, "val", enums
, res
))
864 simple_string (G_GNUC_UNUSED GsfXMLIn
*xin
, xmlChar
const **attrs
)
866 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
867 if (strcmp (attrs
[0], "val") == 0)
868 return CXML2C (attrs
[1]);
872 /***********************************************************************
873 * These indexes look like the values in xls. Dup some code from there.
874 * TODO : Can we merge the code ?
875 * Will the 'indexedColors' look like a palette ?
879 } xlsx_default_palette_v8
[] = {
880 { 0, 0, 0}, {255,255,255}, {255, 0, 0}, { 0,255, 0},
881 { 0, 0,255}, {255,255, 0}, {255, 0,255}, { 0,255,255},
883 {128, 0, 0}, { 0,128, 0}, { 0, 0,128}, {128,128, 0},
884 {128, 0,128}, { 0,128,128}, {192,192,192}, {128,128,128},
886 {153,153,255}, {153, 51,102}, {255,255,204}, {204,255,255},
887 {102, 0,102}, {255,128,128}, { 0,102,204}, {204,204,255},
889 { 0, 0,128}, {255, 0,255}, {255,255, 0}, { 0,255,255},
890 {128, 0,128}, {128, 0, 0}, { 0,128,128}, { 0, 0,255},
892 { 0,204,255}, {204,255,255}, {204,255,204}, {255,255,153},
893 {153,204,255}, {255,153,204}, {204,153,255}, {255,204,153},
895 { 51,102,255}, { 51,204,204}, {153,204, 0}, {255,204, 0},
896 {255,153, 0}, {255,102, 0}, {102,102,153}, {150,150,150},
898 { 0, 51,102}, { 51,153,102}, { 0, 51, 0}, { 51, 51, 0},
899 {153, 51, 0}, {153, 51,102}, { 51, 51,153}, { 51, 51, 51}
903 indexed_color (G_GNUC_UNUSED XLSXReadState
*state
, gint idx
)
905 /* NOTE: not documented but seems close
906 * If you find a normative reference please forward it.
908 * The color index field seems to use
909 * 8-63 = Palette index 0-55
910 * 64 = auto pattern, auto border
911 * 65 = auto background
914 * 65 is always white, and 127 always black. 64 is black
915 * if the fDefaultHdr flag in WINDOW2 is unset, otherwise it's
916 * the grid color from WINDOW2.
919 if (idx
== 1 || idx
== 65)
920 return GO_COLOR_WHITE
;
923 case 64 : /* system text ? */
924 case 81 : /* tooltip text */
925 case 0x7fff : /* system text ? */
926 return GO_COLOR_BLACK
;
929 case 65 : /* system back ? */
930 return GO_COLOR_WHITE
;
932 case 80 : /* tooltip background */
933 return GO_COLOR_YELLOW
;
935 case 2 : return GO_COLOR_RED
;
936 case 3 : return GO_COLOR_GREEN
;
937 case 4 : return GO_COLOR_BLUE
;
938 case 5 : return GO_COLOR_YELLOW
;
939 case 6 : return GO_COLOR_VIOLET
;
940 case 7 : return GO_COLOR_CYAN
;
947 if (idx
< 0 || (int) G_N_ELEMENTS (xlsx_default_palette_v8
) <= idx
) {
948 g_warning ("EXCEL: color index (%d) is out of range (8..%d). Defaulting to black",
949 idx
+ 8, (int)G_N_ELEMENTS (xlsx_default_palette_v8
) + 8);
950 return GO_COLOR_BLACK
;
953 /* TODO cache and ref */
954 return GO_COLOR_FROM_RGB (xlsx_default_palette_v8
[idx
].r
,
955 xlsx_default_palette_v8
[idx
].g
,
956 xlsx_default_palette_v8
[idx
].b
);
960 themed_color (GsfXMLIn
*xin
, gint idx
)
962 static char const * const theme_elements
[] = {
963 "lt1", "dk1", "lt2", "dk2",
964 "accent1", "accent2", "accent3", "accent4", "accent5", "accent6",
967 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
970 * looks like the indicies map to hard coded names rather than the
971 * order in the file. Indeed the order in the file seems wrong
972 * it inverts the first to pairs
973 * 1,0,3,2, 4,5,6.....
974 * see: http://openxmldeveloper.org/forums/thread/1306.aspx
975 * OOo seems to do something similar
977 * I'll make the assumption we should work by name rather than
979 if (idx
>= 0 && idx
< (int) G_N_ELEMENTS (theme_elements
)) {
980 gpointer color
= g_hash_table_lookup (state
->theme_colors_by_name
,
981 theme_elements
[idx
]);
983 return GPOINTER_TO_UINT (color
);
985 xlsx_warning (xin
, _("Unknown theme color %d"), idx
);
987 xlsx_warning (xin
, "Color index (%d) is out of range (0..%d). Defaulting to black",
988 idx
, (int) G_N_ELEMENTS (theme_elements
));
991 return GO_COLOR_BLACK
;
995 xlsx_get_num_fmt (GsfXMLIn
*xin
, char const *id
)
997 static char const * const std_builtins
[] = {
1009 /* 11 */ "0.00E+00",
1011 /* 13 */ "# ?""?/?""?", /* silly trick to avoid using a trigraph */
1012 /* 14 */ "mm-dd-yy",
1013 /* 15 */ "d-mmm-yy",
1016 /* 18 */ "h:mm AM/PM",
1017 /* 19 */ "h:mm:ss AM/PM",
1020 /* 22 */ "m/d/yy h:mm",
1035 /* 37 */ "#,##0 ;(#,##0)",
1036 /* 38 */ "#,##0 ;[Red](#,##0)",
1037 /* 39 */ "#,##0.00;(#,##0.00)",
1038 /* 40 */ "#,##0.00;[Red](#,##0.00)",
1044 /* 46 */ "[h]:mm:ss",
1046 /* 48 */ "##0.0E+0",
1052 27 [$
-404]e
/m
/d yyyy
"5E74"m
"6708"
1053 28 [$
-404]e
"5E74"m
"6708"d
"65E5" m
"6708"d
"65E5"
1054 29 [$
-404]e
"5E74"m
"6708"d
"65E5" m
"6708"d
"65E5"
1056 31 yyyy
"5E74"m
"6708"d
"65E5" yyyy
"5E74"m
"6708"d
"65E5"
1057 32 hh
"6642"mm
"5206" h
"65F6"mm
"5206"
1058 33 hh
"6642"mm
"5206"ss
"79D2" h
"65F6"mm
"5206"ss
"79D2"
1059 34 4E0A5348
/4E0B5348hh
"6642"mm
"5206" 4E0A5348
/4E0B5348h
"65F6"mm
"5206"
1060 35 4E0A5348
/4E0B5348hh
"6642"mm
"5206"ss
"79D2" 4E0A5348
/4E0B5348h
"65F6"mm
"5206"ss
"79D2"
1061 36 [$
-404]e
/m
/d yyyy
"5E74"m
"6708"
1062 50 [$
-404]e
/m
/d yyyy
"5E74"m
"6708"
1063 51 [$
-404]e
"5E74"m
"6708"d
"65E5" m
"6708"d
"65E5"
1064 52 4E0A5348
/4E0B5348hh
"6642"mm
"5206" yyyy
"5E74"m
"6708"
1065 53 4E0A5348
/4E0B5348hh
"6642"mm
"5206"ss
"79D2" m
"6708"d
"65E5"
1066 54 [$
-404]e
"5E74"m
"6708"d
"65E5" m
"6708"d
"65E5"
1067 55 4E0A5348
/4E0B5348hh
"6642"mm
"5206" 4E0A5348
/4E0B5348h
"65F6"mm
"5206"
1068 56 4E0A5348
/4E0B5348hh
"6642"mm
"5206"ss
"79D2" 4E0A5348
/4E0B5348h
"65F6"mm
"5206"ss
"79D2"
1069 57 [$
-404]e
/m
/d yyyy
"5E74"m
"6708"
1070 58 [$
-404]e
"5E74"m
"6708"d
"65E5" m
"6708"d
"65E5"
1073 27 [$
-411]ge
.m
.d yyyy
"5E74" mm
"6708" dd
"65E5"
1074 28 [$
-411]ggge
"5E74"m
"6708"d
"65E5" mm
-dd
1075 29 [$
-411]ggge
"5E74"m
"6708"d
"65E5" mm
-dd
1077 31 yyyy
"5E74"m
"6708"d
"65E5" yyyy
"B144" mm
"C6D4" dd
"C77C"
1078 32 h
"6642"mm
"5206" h
"C2DC" mm
"BD84"
1079 33 h
"6642"mm
"5206"ss
"79D2" h
"C2DC" mm
"BD84" ss
"CD08"
1080 34 yyyy
"5E74"m
"6708" yyyy
-mm
-dd
1081 35 m
"6708"d
"65E5" yyyy
-mm
-dd
1082 36 [$
-411]ge
.m
.d yyyy
"5E74" mm
"6708" dd
"65E5"
1083 50 [$
-411]ge
.m
.d yyyy
"5E74" mm
"6708" dd
"65E5"
1084 51 [$
-411]ggge
"5E74"m
"6708"d
"65E5" mm
-dd
1085 52 yyyy
"5E74"m
"6708" yyyy
-mm
-dd
1086 53 m
"6708"d
"65E5" yyyy
-mm
-dd
1087 54 [$
-411]ggge
"5E74"m
"6708"d
"65E5" mm
-dd
1088 55 yyyy
"5E74"m
"6708" yyyy
-mm
-dd
1089 56 m
"6708"d
"65E5" yyyy
-mm
-dd
1090 57 [$
-411]ge
.m
.d yyyy
"5E74" mm
"6708" dd
"65E5"
1091 58 [$
-411]ggge
"5E74"m
"6708"d
"65E5" mm
-dd
1101 70 "t# ?""?/?""?" /* silly trick to avoid using a trigraph */
1102 71 0E27
/0E14
/0E1B0E1B0E1B0E1B
1103 72 0E27
-0E140E140E14
-0E1B0E1B
1104 73 0E27
-0E140E140E14
1105 74 0E140E140E14
-0E1B0E1B
1107 76 0E0A
:0E190E19
:0E170E17
1108 77 0E27
/0E14
/0E1B0E1B0E1B0E1B
0E0A
:0E190E19
1109 78 0E190E19
:0E170E17
1110 79 [0E0A
]:0E190E19
:0E170E17
1111 80 0E190E19
:0E170E17
.0
1115 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1116 GOFormat
*res
= g_hash_table_lookup (state
->num_fmts
, id
);
1124 i
= strtol (id
, &end
, 10);
1125 if (end
!= id
&& *end
== '\0' &&
1126 i
>= 0 && i
< (int) G_N_ELEMENTS (std_builtins
) &&
1127 std_builtins
[i
] != NULL
) {
1128 res
= go_format_new_from_XL (std_builtins
[i
]);
1129 g_hash_table_replace (state
->num_fmts
, g_strdup (id
), res
);
1131 xlsx_warning (xin
, _("Undefined number format id '%s'"), id
);
1135 static GnmExprTop
const *
1136 xlsx_parse_expr (GsfXMLIn
*xin
, xmlChar
const *expr_str
,
1137 GnmParsePos
const *pp
)
1139 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1141 GnmExprTop
const *texpr
;
1143 /* Odd, some time IF and CHOOSE show up with leading spaces ??
1146 * I wonder if it is related to some of the funky old
1147 * optimizations in * xls ? */
1148 while (' ' == *expr_str
)
1151 texpr
= gnm_expr_parse_str (expr_str
, pp
,
1152 GNM_EXPR_PARSE_DEFAULT
, state
->convs
,
1153 parse_error_init (&err
));
1155 xlsx_warning (xin
, "At %s: '%s' %s",
1156 parsepos_as_string (pp
),
1157 expr_str
, err
.err
->message
);
1158 parse_error_free (&err
);
1163 /* Returns: a GSList of GnmRange in _reverse_ order
1164 * caller frees the list and the content */
1166 xlsx_parse_sqref (GsfXMLIn
*xin
, xmlChar
const *refs
)
1168 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1173 while (NULL
!= refs
&& *refs
) {
1174 if (NULL
== (tmp
= cellpos_parse (refs
, gnm_sheet_get_size (state
->sheet
), &r
.start
, FALSE
))) {
1175 xlsx_warning (xin
, "unable to parse reference list '%s'", refs
);
1180 if (*refs
== '\0' || *refs
== ' ')
1182 else if (*refs
!= ':' ||
1183 NULL
== (tmp
= cellpos_parse (refs
+ 1, gnm_sheet_get_size (state
->sheet
), &r
.end
, FALSE
))) {
1184 xlsx_warning (xin
, "unable to parse reference list '%s'", refs
);
1188 range_normalize (&r
); /* be anal */
1189 res
= g_slist_prepend (res
, gnm_range_dup (&r
));
1191 for (refs
= tmp
; *refs
== ' ' ; refs
++ ) ;
1197 /***********************************************************************/
1199 #include "xlsx-read-pivot.c"
1201 /***********************************************************************/
1203 static void xlsx_ext_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
);
1204 static void xlsx_ext_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
);
1206 #include "xlsx-read-drawing.c"
1208 /***********************************************************************/
1210 /* RGBMAX, HLSMAX must each fit in a byte. */
1211 /* HLSMAX BEST IF DIVISIBLE BY 6 */
1212 #define HLSMAX 240 /* H,L, and S vary over 0-HLSMAX */
1213 #define RGBMAX 255 /* R,G, and B vary over 0-RGBMAX */
1215 /* Hue is undefined if Saturation is 0 (grey-scale) */
1216 /* This value determines where the Hue scrollbar is */
1217 /* initially set for achromatic colors */
1218 #define UNDEFINED (HLSMAX*2/3)
1220 /* utility routine for HLStoRGB */
1222 hue_to_color (int m1
, int m2
, int h
)
1229 /* return r,g, or b value from this tridrant */
1231 return m1
+ (((m2
- m1
)*h
+ (HLSMAX
/12))/(HLSMAX
/6));
1234 if (h
< ((HLSMAX
*2)/3))
1235 return m1
+ (((m2
- m1
)*(((HLSMAX
*2)/3)-h
)+(HLSMAX
/12))/(HLSMAX
/6));
1241 apply_tint (GOColor orig
, double tint
)
1243 int r
= GO_COLOR_UINT_R (orig
);
1244 int g
= GO_COLOR_UINT_G (orig
);
1245 int b
= GO_COLOR_UINT_B (orig
);
1246 int a
= GO_COLOR_UINT_A (orig
);
1247 int maxC
= b
, minC
= b
, delta
, sum
, h
= 0, l
, s
, m1
, m2
;
1249 if (fabs (tint
) < .005)
1252 maxC
= MAX (MAX (r
,g
),b
);
1253 minC
= MIN (MIN (r
,g
),b
);
1254 l
= (((maxC
+ minC
)*HLSMAX
) + RGBMAX
)/(2*RGBMAX
);
1256 delta
= maxC
- minC
;
1259 if (l
<= (HLSMAX
/2))
1260 s
= ( (delta
*HLSMAX
) + (sum
/2) ) / sum
;
1262 s
= ( (delta
*HLSMAX
) + ((2*RGBMAX
- sum
)/2) ) / (2*RGBMAX
- sum
);
1265 h
= ((g
- b
) * HLSMAX
) / (6 * delta
);
1267 h
= ( HLSMAX
/3) + ((b
- r
) * HLSMAX
) / (6 * delta
);
1269 h
= (2*HLSMAX
/3) + ((r
- g
) * HLSMAX
) / (6 * delta
);
1273 else if (h
>= HLSMAX
)
1281 l
= l
* (1. + tint
);
1283 l
= l
* (1. - tint
) + (HLSMAX
- HLSMAX
* (1.0 - tint
));
1285 if (s
== 0) { /* achromatic case */
1286 r
= (l
* RGBMAX
) / HLSMAX
;
1287 return GO_COLOR_FROM_RGBA (r
, r
, r
, a
);
1290 if (l
<= (HLSMAX
/2))
1291 m2
= (l
*(HLSMAX
+ s
) + (HLSMAX
/2))/HLSMAX
;
1293 m2
= l
+ s
- ((l
*s
) + (HLSMAX
/2))/HLSMAX
;
1296 r
= (hue_to_color (m1
, m2
, h
+ (HLSMAX
/3))*RGBMAX
+ (HLSMAX
/2)) / HLSMAX
;
1297 g
= (hue_to_color (m1
, m2
, h
)*RGBMAX
+ (HLSMAX
/2)) / HLSMAX
;
1298 b
= (hue_to_color (m1
, m2
, h
- (HLSMAX
/3))*RGBMAX
+ (HLSMAX
/2)) / HLSMAX
;
1300 return GO_COLOR_FROM_RGBA (r
,g
,b
,a
);
1304 elem_color (GsfXMLIn
*xin
, xmlChar
const **attrs
, gboolean allow_alpha
)
1306 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1308 GOColor c
= GO_COLOR_BLACK
;
1309 gnm_float tint
= 0.;
1310 gboolean has_color
= FALSE
;
1312 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
1313 if (0 == strcmp (attrs
[0], "rgb")) {
1315 if (4 != sscanf (attrs
[1], "%02x%02x%02x%02x", &a
, &r
, &g
, &b
)) {
1317 _("Invalid color '%s' for attribute rgb"),
1322 c
= GO_COLOR_FROM_RGBA (r
,g
,b
,a
);
1323 } else if (attr_int (xin
, attrs
, "indexed", &indx
)) {
1325 c
= indexed_color (state
, indx
);
1326 } else if (attr_int (xin
, attrs
, "theme", &indx
)) {
1328 c
= themed_color (xin
, indx
);
1329 } else if (attr_float (xin
, attrs
, "tint", &tint
))
1330 tint
= CLAMP (tint
, -1., 1.);
1335 c
= apply_tint (c
, tint
);
1338 return gnm_color_new_go (c
);
1342 xlsx_get_style_xf (GsfXMLIn
*xin
, int xf
)
1344 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1345 if (0 <= xf
&& NULL
!= state
->style_xfs
&& xf
< (int)state
->style_xfs
->len
)
1346 return g_ptr_array_index (state
->style_xfs
, xf
);
1347 xlsx_warning (xin
, _("Undefined style record '%d'"), xf
);
1351 xlsx_get_xf (GsfXMLIn
*xin
, int xf
)
1353 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1354 if (0 <= xf
&& NULL
!= state
->xfs
&& xf
< (int)state
->xfs
->len
)
1355 return g_ptr_array_index (state
->xfs
, xf
);
1356 xlsx_warning (xin
, _("Undefined style record '%d'"), xf
);
1360 xlsx_get_dxf (GsfXMLIn
*xin
, int dxf
)
1362 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1363 if (0 <= dxf
&& NULL
!= state
->dxfs
&& dxf
< (int)state
->dxfs
->len
)
1364 return g_ptr_array_index (state
->dxfs
, dxf
);
1365 xlsx_warning (xin
, _("Undefined partial style record '%d'"), dxf
);
1369 /****************************************************************************/
1372 xlsx_cell_val_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1374 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1375 XLSXStr
const *entry
;
1379 switch (state
->pos_type
) {
1380 case XLXS_TYPE_NUM
:
1381 if (*xin
->content
->str
)
1382 state
->val
= value_new_float (gnm_strto (xin
->content
->str
, &end
));
1384 case XLXS_TYPE_SST_STR
:
1385 i
= strtol (xin
->content
->str
, &end
, 10);
1386 if (end
!= xin
->content
->str
&& *end
== '\0' &&
1387 0 <= i
&& i
< (int)state
->sst
->len
) {
1388 entry
= &g_array_index (state
->sst
, XLSXStr
, i
);
1389 go_string_ref (entry
->str
);
1390 state
->val
= value_new_string_str (entry
->str
);
1391 if (NULL
!= entry
->markup
)
1392 value_set_fmt (state
->val
, entry
->markup
);
1394 xlsx_warning (xin
, _("Invalid sst ref '%s'"), xin
->content
->str
);
1397 case XLXS_TYPE_BOOL
:
1398 if (*xin
->content
->str
)
1399 state
->val
= value_new_bool (*xin
->content
->str
!= '0');
1401 case XLXS_TYPE_ERR
:
1402 if (*xin
->content
->str
)
1403 state
->val
= value_new_error (NULL
, xin
->content
->str
);
1406 case XLXS_TYPE_STR2
: /* What is this ? */
1407 case XLXS_TYPE_INLINE_STR
:
1408 state
->val
= value_new_string (xin
->content
->str
);
1411 g_warning ("Unknown val type %d", state
->pos_type
);
1416 xlsx_cell_inline_text_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1418 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1419 go_string_append_gstring (state
->r_text
, xin
->content
);
1424 xlsx_cell_inline_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1426 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1428 state
->r_text
= g_string_new ("");
1432 xlsx_cell_inline_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1434 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1436 state
->val
= value_new_string_nocopy (g_string_free (state
->r_text
, FALSE
));
1437 state
->r_text
= NULL
;
1439 if (state
->rich_attrs
) {
1440 GOFormat
*fmt
= go_format_new_markup (state
->rich_attrs
, FALSE
);
1441 state
->rich_attrs
= NULL
;
1442 value_set_fmt (state
->val
, fmt
);
1443 go_format_unref (fmt
);
1449 xlsx_cell_expr_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1451 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1452 gboolean has_range
= FALSE
, is_array
= FALSE
, is_shared
= FALSE
;
1454 xmlChar
const *shared_id
= NULL
;
1456 /* See https://bugzilla.gnome.org/show_bug.cgi?id=642850 */
1457 /* for some of the issues surrounding shared formulas. */
1459 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
1460 if (0 == strcmp (attrs
[0], "t")) {
1461 if (0 == strcmp (attrs
[1], "array"))
1463 else if (0 == strcmp (attrs
[1], "shared"))
1465 } else if (0 == strcmp (attrs
[0], "si"))
1466 shared_id
= attrs
[1];
1467 else if (attr_range (xin
, attrs
, "ref", &range
))
1470 state
->shared_id
= NULL
;
1471 if (is_shared
&& NULL
!= shared_id
) {
1473 state
->texpr
= g_hash_table_lookup (state
->shared_exprs
, shared_id
);
1474 if (NULL
!= state
->texpr
)
1475 gnm_expr_top_ref (state
->texpr
);
1477 state
->shared_id
= g_strdup (shared_id
);
1479 state
->texpr
= NULL
;
1481 /* if the shared expr is already parsed expression do not even collect content */
1482 ((GsfXMLInNode
*)(xin
->node
))->has_content
=
1483 (NULL
!= state
->texpr
) ? GSF_XML_NO_CONTENT
: GSF_XML_CONTENT
;
1485 if (is_array
&& has_range
)
1486 state
->array
= range
;
1490 xlsx_cell_expr_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1492 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1495 if (NULL
== state
->texpr
) {
1496 parse_pos_init (&pp
, NULL
, state
->sheet
,
1497 state
->pos
.col
, state
->pos
.row
);
1498 state
->texpr
= xlsx_parse_expr (xin
, xin
->content
->str
, &pp
);
1499 if (NULL
!= state
->texpr
&&
1500 NULL
!= state
->shared_id
) {
1501 gnm_expr_top_ref (state
->texpr
);
1502 g_hash_table_replace (state
->shared_exprs
,
1503 state
->shared_id
, (gpointer
)state
->texpr
);
1504 state
->shared_id
= NULL
;
1507 g_free (state
->shared_id
);
1508 state
->shared_id
= NULL
;
1512 xlsx_cell_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1514 static EnumVal
const types
[] = {
1515 { "n", XLXS_TYPE_NUM
},
1516 { "s", XLXS_TYPE_SST_STR
},
1517 { "str", XLXS_TYPE_STR2
},
1518 { "b", XLXS_TYPE_BOOL
},
1519 { "inlineStr", XLXS_TYPE_INLINE_STR
},
1520 { "e", XLXS_TYPE_ERR
},
1523 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1525 GnmStyle
*style
= NULL
;
1527 state
->pos
.col
= state
->pos
.row
= -1;
1528 state
->pos_type
= XLXS_TYPE_NUM
; /* the default */
1530 state
->texpr
= NULL
;
1531 range_init (&state
->array
, -1, -1, -1, -1); /* invalid */
1533 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
1534 if (attr_pos (xin
, attrs
, "r", &state
->pos
)) ;
1535 else if (attr_enum (xin
, attrs
, "t", types
, &tmp
))
1536 state
->pos_type
= tmp
;
1537 else if (attr_int (xin
, attrs
, "s", &tmp
))
1538 style
= xlsx_get_xf (xin
, tmp
);
1540 if (NULL
!= style
) {
1541 gnm_style_ref (style
);
1542 /* There may already be a row style set!*/
1543 sheet_style_apply_pos (state
->sheet
,
1544 state
->pos
.col
, state
->pos
.row
, style
);
1548 xlsx_cell_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1550 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1553 if (state
->texpr
== NULL
&& state
->val
== NULL
) {
1554 /* A cell with only style. */
1558 cell
= sheet_cell_fetch (state
->sheet
, state
->pos
.col
, state
->pos
.row
);
1561 xlsx_warning (xin
, _("Invalid cell %s"),
1562 cellpos_as_string (&state
->pos
));
1563 value_release (state
->val
);
1564 if (NULL
!= state
->texpr
)
1565 gnm_expr_top_unref (state
->texpr
);
1566 } else if (NULL
!= state
->texpr
) {
1567 if (state
->array
.start
.col
>= 0) {
1568 gnm_cell_set_array (state
->sheet
,
1571 gnm_expr_top_unref (state
->texpr
);
1572 if (NULL
!= state
->val
)
1573 gnm_cell_assign_value (cell
, state
->val
);
1574 } else if (NULL
!= state
->val
) {
1575 gnm_cell_set_expr_and_value (cell
,
1576 state
->texpr
, state
->val
, TRUE
);
1577 gnm_expr_top_unref (state
->texpr
);
1579 gnm_cell_set_expr (cell
, state
->texpr
);
1580 gnm_expr_top_unref (state
->texpr
);
1582 } else if (NULL
!= state
->val
)
1583 gnm_cell_assign_value (cell
, state
->val
);
1585 state
->texpr
= NULL
;
1590 xlsx_CT_Row (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1592 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1593 int row
= -1, xf_index
;
1595 int cust_fmt
= FALSE
, cust_height
= FALSE
, collapsed
= FALSE
;
1598 GnmStyle
*style
= NULL
;
1600 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
1601 if (attr_int (xin
, attrs
, "r", &row
)) ;
1602 else if (attr_float (xin
, attrs
, "ht", &h
)) ;
1603 else if (attr_bool (xin
, attrs
, "customFormat", &cust_fmt
)) ;
1604 else if (attr_bool (xin
, attrs
, "customHeight", &cust_height
)) ;
1605 else if (attr_int (xin
, attrs
, "s", &xf_index
))
1606 style
= xlsx_get_xf (xin
, xf_index
);
1607 else if (attr_int (xin
, attrs
, "outlineLevel", &outline
)) ;
1608 else if (attr_bool (xin
, attrs
, "hidden", &hidden
)) ;
1609 else if (attr_bool (xin
, attrs
, "collapsed", &collapsed
)) ;
1614 sheet_row_set_size_pts (state
->sheet
, row
, h
, cust_height
);
1616 colrow_set_visibility (state
->sheet
, FALSE
, FALSE
, row
, row
);
1618 colrow_set_outline (sheet_row_fetch (state
->sheet
, row
),
1619 outline
, collapsed
);
1621 if (NULL
!= style
&& cust_fmt
) {
1623 r
.start
.row
= r
.end
.row
= row
;
1625 r
.end
.col
= gnm_sheet_get_max_cols (state
->sheet
) - 1;
1626 gnm_style_ref (style
);
1627 sheet_style_set_range (state
->sheet
, &r
, style
);
1631 maybe_update_progress (xin
);
1635 xlsx_CT_RowsCols_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1637 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1639 if (!state
->pending_rowcol_style
)
1642 sheet_style_set_range (state
->sheet
,
1643 &state
->pending_rowcol_range
,
1644 state
->pending_rowcol_style
);
1646 state
->pending_rowcol_style
= NULL
;
1648 maybe_update_progress (xin
);
1652 xlsx_CT_Col (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1654 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1655 int first
= -1, last
= -1, xf_index
;
1657 gboolean cust_width
= FALSE
, best_fit
= FALSE
, collapsed
= FALSE
;
1660 GnmStyle
*style
= NULL
;
1662 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
1663 if (attr_int (xin
, attrs
, "min", &first
)) ;
1664 else if (attr_int (xin
, attrs
, "max", &last
)) ;
1665 else if (attr_float (xin
, attrs
, "width", &width
))
1666 /* FIXME FIXME FIXME arbitrary map from 130 pixels to
1667 * the value stored for a column with 130 pixel width*/
1668 width
*= (130. / 18.5703125) * (72./96.);
1669 else if (attr_bool (xin
, attrs
, "customWidth", &cust_width
)) ;
1670 else if (attr_bool (xin
, attrs
, "bestFit", &best_fit
)) ;
1671 else if (attr_int (xin
, attrs
, "style", &xf_index
))
1672 style
= xlsx_get_xf (xin
, xf_index
);
1673 else if (attr_int (xin
, attrs
, "outlineLevel", &outline
)) ;
1674 else if (attr_bool (xin
, attrs
, "hidden", &hidden
)) ;
1675 else if (attr_bool (xin
, attrs
, "collapsed", &collapsed
)) ;
1679 xlsx_warning (xin
, _("Ignoring column information that does not specify first or last."));
1683 } else if (last
< 0)
1690 first
= CLAMP (first
, 0, gnm_sheet_get_last_col (state
->sheet
));
1691 last
= CLAMP (last
, 0, gnm_sheet_get_last_col (state
->sheet
));
1693 for (i
= first
; i
<= last
; i
++) {
1695 sheet_col_set_size_pts (state
->sheet
, i
, width
,
1696 cust_width
&& !best_fit
);
1698 colrow_set_outline (sheet_col_fetch (state
->sheet
, i
),
1699 outline
, collapsed
);
1701 if (NULL
!= style
) {
1703 range_init_cols (&r
, state
->sheet
, first
, last
);
1706 * Sometimes we see a lot of columns with the same style.
1707 * We delay applying the style because applying column
1708 * by column leads to style fragmentation. #622365
1711 if (style
!= state
->pending_rowcol_style
||
1712 state
->pending_rowcol_range
.start
.row
!= r
.start
.row
||
1713 state
->pending_rowcol_range
.end
.row
!= r
.end
.row
||
1714 state
->pending_rowcol_range
.end
.col
+ 1 != r
.start
.col
)
1715 xlsx_CT_RowsCols_end (xin
, NULL
);
1717 if (state
->pending_rowcol_style
)
1718 state
->pending_rowcol_range
.end
.col
= r
.end
.col
;
1720 gnm_style_ref (style
);
1721 state
->pending_rowcol_style
= style
;
1722 state
->pending_rowcol_range
= r
;
1726 colrow_set_visibility (state
->sheet
, TRUE
, FALSE
, first
, last
);
1730 xlsx_CT_SheetPr (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
1733 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1734 <xsd
:attribute name
="syncHorizontal" type
="xsd:boolean" use
="optional" default="false">
1735 <xsd
:attribute name
="syncVertical" type
="xsd:boolean" use
="optional" default="false">
1736 <xsd
:attribute name
="syncRef" type
="ST_Ref" use
="optional">
1737 <xsd
:attribute name
="transitionEvaluation" type
="xsd:boolean" use
="optional" default="false">
1738 <xsd
:attribute name
="transitionEntry" type
="xsd:boolean" use
="optional" default="false">
1739 <xsd
:attribute name
="published" type
="xsd:boolean" use
="optional" default="true">
1740 <xsd
:attribute name
="codeName" type
="xsd:string" use
="optional">
1741 <xsd
:attribute name
="filterMode" type
="xsd:boolean" use
="optional" default="false">
1742 <xsd
:attribute name
="enableFormatConditionsCalculation" type
="xsd:boolean" use
="optional" default="true">
1747 xlsx_sheet_tabcolor (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1749 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1750 GnmColor
*text_color
, *color
= elem_color (xin
, attrs
, TRUE
);
1751 if (NULL
!= color
) {
1753 GO_COLOR_UINT_R (color
->go_color
) +
1754 GO_COLOR_UINT_G (color
->go_color
) +
1755 GO_COLOR_UINT_B (color
->go_color
);
1756 if (contrast
>= 0x180)
1757 text_color
= style_color_black ();
1759 text_color
= style_color_white ();
1760 g_object_set (state
->sheet
,
1761 "tab-foreground", text_color
,
1762 "tab-background", color
,
1764 style_color_unref (text_color
);
1765 style_color_unref (color
);
1770 xlsx_sheet_page_setup (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
1772 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1773 GnmPrintInformation
*pi
= state
->sheet
->print_info
;
1776 if (pi
->page_setup
== NULL
)
1777 gnm_print_info_load_defaults (pi
);
1779 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
1780 if (attr_bool (xin
, attrs
, "fitToPage", &tmp
))
1781 pi
->scaling
.type
= tmp
? PRINT_SCALE_FIT_PAGES
: PRINT_SCALE_PERCENTAGE
;
1785 xlsx_CT_SheetFormatPr (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1787 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1791 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
1792 if (attr_float (xin
, attrs
, "defaultRowHeight", &h
))
1793 sheet_row_set_default_size_pts (state
->sheet
, h
);
1794 else if (attr_int (xin
, attrs
, "outlineLevelRow", &i
)) {
1796 sheet_colrow_gutter (state
->sheet
, FALSE
, i
);
1797 } else if (attr_int (xin
, attrs
, "outlineLevelCol", &i
)) {
1799 sheet_colrow_gutter (state
->sheet
, TRUE
, i
);
1803 static GtkPaperSize
*
1804 xlsx_paper_size (gdouble width
, gdouble height
, GtkUnit unit
, int code
)
1808 gchar
*display_name
;
1811 name
= g_strdup_printf ("xlsx_%ix%i", (int)width
, (int)height
);
1812 display_name
= g_strdup_printf (_("Paper from XLSX file: %ipt\xE2\xA8\x89%ipt"),
1813 (int)width
, (int)height
);
1815 name
= g_strdup_printf ("xlsx_%i", code
);
1816 display_name
= g_strdup_printf (_("Paper from XLSX file, #%i"), code
);
1818 size
= gtk_paper_size_new_custom (name
, display_name
, width
, height
, unit
);
1820 g_free (display_name
);
1825 xlsx_set_paper_from_code (GnmPrintInformation
*pi
, int code
)
1827 XLSXPaperDefs paper
[] =
1828 {{ 0 , 0 , 0 , GTK_UNIT_MM
, NULL
},
1829 { 1 , 8.5 , 11 , GTK_UNIT_INCH
, GTK_PAPER_NAME_LETTER
},
1830 { 2 , 8.5 , 11 , GTK_UNIT_INCH
, GTK_PAPER_NAME_LETTER
},
1831 { 3 , 11 , 17 , GTK_UNIT_INCH
, "na_ledger_11x17in" },
1832 { 4 , 17 , 11 , GTK_UNIT_INCH
, NULL
},
1833 { 5 , 8.5 , 14 , GTK_UNIT_INCH
, GTK_PAPER_NAME_LEGAL
},
1834 { 6 , 5.5 , 8.5 , GTK_UNIT_INCH
, "na_invoice_5.5x8.5in" },
1835 { 7 , 7.25 , 10.5 , GTK_UNIT_INCH
, GTK_PAPER_NAME_EXECUTIVE
},
1836 { 8 , 297 , 420 , GTK_UNIT_MM
, GTK_PAPER_NAME_A3
},
1837 { 9 , 210 , 297 , GTK_UNIT_MM
, GTK_PAPER_NAME_A4
},
1838 { 10 , 210 , 297 , GTK_UNIT_MM
, GTK_PAPER_NAME_A4
},
1839 { 11 , 148 , 210 , GTK_UNIT_MM
, GTK_PAPER_NAME_A5
},
1840 { 12 , 250 , 353 , GTK_UNIT_MM
, "iso_b4_250x353mm" },
1841 { 13 , 176 , 250 , GTK_UNIT_MM
, GTK_PAPER_NAME_B5
},
1842 { 14 , 8.5 , 13 , GTK_UNIT_INCH
, "na_foolscap_8.5x13in" },
1843 { 15 , 215 , 275 , GTK_UNIT_MM
, NULL
},
1844 { 16 , 10 , 14 , GTK_UNIT_INCH
, "na_10x14_10x14in" },
1845 { 17 , 11 , 17 , GTK_UNIT_INCH
, "na_ledger_11x17in" },
1846 { 18 , 8.5 , 11 , GTK_UNIT_INCH
, GTK_PAPER_NAME_LETTER
},
1847 { 19 , 3.875 , 8.875 , GTK_UNIT_INCH
, "na_number-9_3.875x8.875in" },
1848 { 20 , 4.125 , 9.5 , GTK_UNIT_INCH
, "na_number-10_4.125x9.5in" },
1849 { 21 , 4.5 , 10.375 , GTK_UNIT_INCH
, "na_number-11_4.5x10.375in" },
1850 { 22 , 4.75 , 11 , GTK_UNIT_INCH
, "na_number-12_4.75x11in" },
1851 { 23 , 5 , 11.5 , GTK_UNIT_INCH
, "na_number-14_5x11.5in" },
1852 { 24 , 17 , 22 , GTK_UNIT_INCH
, "na_c_17x22in" },
1853 { 25 , 22 , 34 , GTK_UNIT_INCH
, "na_d_22x34in" },
1854 { 26 , 34 , 44 , GTK_UNIT_INCH
, "na_e_34x44in" },
1855 { 27 , 110 , 220 , GTK_UNIT_MM
, "iso_dl_110x220mm" },
1856 { 28 , 162 , 229 , GTK_UNIT_MM
, "iso_c5_162x229mm" },
1857 { 29 , 324 , 458 , GTK_UNIT_MM
, "iso_c3_324x458mm" },
1858 { 30 , 229 , 324 , GTK_UNIT_MM
, "iso_c4_229x324mm" },
1859 { 31 , 114 , 162 , GTK_UNIT_MM
, "iso_c6_114x162mm" },
1860 { 32 , 114 , 229 , GTK_UNIT_MM
, "iso_c6c5_114x229mm" },
1861 { 33 , 250 , 353 , GTK_UNIT_MM
, "iso_b4_250x353mm" },
1862 { 34 , 176 , 250 , GTK_UNIT_MM
, GTK_PAPER_NAME_B5
},
1863 { 35 , 176 , 125 , GTK_UNIT_MM
, NULL
},
1864 { 36 , 110 , 230 , GTK_UNIT_MM
, "om_italian_110x230mm" },
1865 { 37 , 3.875 , 7.5 , GTK_UNIT_INCH
, "na_monarch_3.875x7.5in" },
1866 { 38 , 3.625 , 6.5 , GTK_UNIT_INCH
, "na_personal_3.625x6.5in" },
1867 { 39 , 14.875 , 11 , GTK_UNIT_INCH
, NULL
},
1868 { 40 , 8.5 , 12 , GTK_UNIT_INCH
, "na_fanfold-eur_8.5x12in" },
1869 { 41 , 8.5 , 13 , GTK_UNIT_INCH
, "na_foolscap_8.5x13in" },
1870 { 42 , 250 , 353 , GTK_UNIT_MM
, "iso_b4_250x353mm" },
1871 { 43 , 200 , 148 , GTK_UNIT_MM
, NULL
},
1872 { 44 , 9 , 11 , GTK_UNIT_INCH
, "na_9x11_9x11in" },
1873 { 45 , 10 , 11 , GTK_UNIT_INCH
, "na_10x11_10x11in" },
1874 { 46 , 15 , 11 , GTK_UNIT_INCH
, NULL
},
1875 { 47 , 220 , 220 , GTK_UNIT_MM
, "om_invite_220x220mm" },
1876 { 48 , 0 , 0 , GTK_UNIT_MM
, NULL
},
1877 { 49 , 0 , 0 , GTK_UNIT_MM
, NULL
},
1878 { 50 , 9.275 , 12 , GTK_UNIT_INCH
, NULL
},
1879 { 51 , 9.275 , 15 , GTK_UNIT_INCH
, NULL
},
1880 { 52 , 11.69 , 18 , GTK_UNIT_INCH
, NULL
},
1881 { 53 , 236 , 322 , GTK_UNIT_MM
, "iso_a4-extra_235.5x322.3" },
1882 { 54 , 8.275 , 11 , GTK_UNIT_INCH
, NULL
},
1883 { 55 , 210 , 297 , GTK_UNIT_MM
, GTK_PAPER_NAME_A4
},
1884 { 56 , 9.275 , 12 , GTK_UNIT_INCH
, NULL
},
1885 { 57 , 227 , 356 , GTK_UNIT_MM
, NULL
},
1886 { 58 , 305 , 487 , GTK_UNIT_MM
, NULL
},
1887 { 59 , 8.5 , 12.69 , GTK_UNIT_INCH
, "na_letter-plus_8.5x12.69in" },
1888 { 60 , 210 , 330 , GTK_UNIT_MM
, "om_folio_210x330mm" },
1889 { 61 , 148 , 210 , GTK_UNIT_MM
, GTK_PAPER_NAME_A5
},
1890 { 62 , 182 , 257 , GTK_UNIT_MM
, "jis_b5_182x257mm" },
1891 { 63 , 322 , 445 , GTK_UNIT_MM
, "iso_a3-extra_322x445mm" },
1892 { 64 , 174 , 235 , GTK_UNIT_MM
, "iso_a5-extra_174x235mm" },
1893 { 65 , 201 , 276 , GTK_UNIT_MM
, "iso_b5-extra_201x276mm" },
1894 { 66 , 420 , 594 , GTK_UNIT_MM
, "iso_a2_420x594mm" },
1895 { 67 , 297 , 420 , GTK_UNIT_MM
, GTK_PAPER_NAME_A3
},
1896 { 68 , 322 , 445 , GTK_UNIT_MM
, "iso_a3-extra_322x445mm" },
1897 { 69 , 200 , 148 , GTK_UNIT_MM
, NULL
},
1898 { 70 , 105 , 148 , GTK_UNIT_MM
, "iso_a6_105x148mm" },
1899 { 71 , 240 , 332 , GTK_UNIT_MM
, "jpn_kaku2_240x332mm" },
1900 { 72 , 216 , 277 , GTK_UNIT_MM
, NULL
},
1901 { 73 , 120 , 235 , GTK_UNIT_MM
, "jpn_chou3_120x235mm" },
1902 { 74 , 90 , 205 , GTK_UNIT_MM
, "jpn_chou4_90x205mm" },
1903 { 75 , 11 , 8.5 , GTK_UNIT_INCH
, NULL
},
1904 { 76 , 420 , 297 , GTK_UNIT_MM
, NULL
},
1905 { 77 , 297 , 210 , GTK_UNIT_MM
, NULL
},
1906 { 78 , 210 , 148 , GTK_UNIT_MM
, NULL
},
1907 { 79 , 364 , 257 , GTK_UNIT_MM
, NULL
},
1908 { 80 , 257 , 182 , GTK_UNIT_MM
, NULL
},
1909 { 81 , 148 , 100 , GTK_UNIT_MM
, NULL
},
1910 { 82 , 148 , 200 , GTK_UNIT_MM
, "jpn_oufuku_148x200mm" },
1911 { 83 , 148 , 105 , GTK_UNIT_MM
, NULL
},
1912 { 84 , 332 , 240 , GTK_UNIT_MM
, NULL
},
1913 { 85 , 277 , 216 , GTK_UNIT_MM
, NULL
},
1914 { 86 , 235 , 120 , GTK_UNIT_MM
, NULL
},
1915 { 87 , 205 , 90 , GTK_UNIT_MM
, NULL
},
1916 { 88 , 128 , 182 , GTK_UNIT_MM
, "jis_b6_128x182mm" },
1917 { 89 , 182 , 128 , GTK_UNIT_MM
, NULL
},
1918 { 90 , 12 , 11 , GTK_UNIT_INCH
, NULL
},
1919 { 91 , 235 , 105 , GTK_UNIT_MM
, NULL
},
1920 { 92 , 105 , 235 , GTK_UNIT_MM
, "jpn_you4_105x235mm" },
1921 { 93 , 146 , 215 , GTK_UNIT_MM
, "prc_16k_146x215mm" },
1922 { 94 , 97 , 151 , GTK_UNIT_MM
, "prc_32k_97x151mm" },
1923 { 95 , 97 , 151 , GTK_UNIT_MM
, "prc_32k_97x151mm" },
1924 { 96 , 102 , 165 , GTK_UNIT_MM
, "prc_1_102x165mm" },
1925 { 97 , 102 , 176 , GTK_UNIT_MM
, "prc_2_102x176mm" },
1926 { 98 , 125 , 176 , GTK_UNIT_MM
, "prc_3_125x176mm" },
1927 { 99 , 110 , 208 , GTK_UNIT_MM
, "prc_4_110x208mm" },
1928 { 100 , 110 , 220 , GTK_UNIT_MM
, "prc_5_110x220mm" },
1929 { 101 , 120 , 230 , GTK_UNIT_MM
, "prc_6_120x230mm" },
1930 { 102 , 160 , 230 , GTK_UNIT_MM
, "prc_7_160x230mm" },
1931 { 103 , 120 , 309 , GTK_UNIT_MM
, "prc_8_120x309mm" },
1932 { 104 , 229 , 324 , GTK_UNIT_MM
, "iso_c4_229x324mm" },
1933 { 105 , 324 , 458 , GTK_UNIT_MM
, "prc_10_324x458mm" },
1934 { 106 , 215 , 146 , GTK_UNIT_MM
, NULL
},
1935 { 107 , 151 , 97 , GTK_UNIT_MM
, NULL
},
1936 { 108 , 151 , 97 , GTK_UNIT_MM
, NULL
},
1937 { 109 , 165 , 102 , GTK_UNIT_MM
, NULL
},
1938 { 110 , 176 , 102 , GTK_UNIT_MM
, NULL
},
1939 { 111 , 176 , 125 , GTK_UNIT_MM
, NULL
},
1940 { 112 , 208 , 110 , GTK_UNIT_MM
, NULL
},
1941 { 113 , 220 , 110 , GTK_UNIT_MM
, NULL
},
1942 { 114 , 230 , 120 , GTK_UNIT_MM
, NULL
},
1943 { 115 , 230 , 160 , GTK_UNIT_MM
, NULL
},
1944 { 116 , 309 , 120 , GTK_UNIT_MM
, NULL
},
1945 { 117 , 324 , 229 , GTK_UNIT_MM
, NULL
},
1946 { 118 , 458 , 324 , GTK_UNIT_MM
, NULL
}};
1948 if (code
< 1 || ((guint
) code
) >= G_N_ELEMENTS (paper
) || paper
[code
].code
== 0)
1950 g_return_val_if_fail (paper
[code
].code
== code
, FALSE
);
1952 if (paper
[code
].name
!= NULL
) {
1953 GtkPaperSize
*ps
= gtk_paper_size_new (paper
[code
].name
);
1955 gtk_page_setup_set_paper_size (pi
->page_setup
, ps
);
1959 if (paper
[code
].width
> 0.0 && paper
[code
].height
> 0.0) {
1960 GtkPaperSize
*ps
= xlsx_paper_size (paper
[code
].width
, paper
[code
].height
, paper
[code
].unit
, code
);
1962 gtk_page_setup_set_paper_size (pi
->page_setup
, ps
);
1971 xlsx_CT_PageSetup (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1973 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1974 GnmPrintInformation
*pi
= state
->sheet
->print_info
;
1975 int orient
, paper_code
= 0, scale
, tmp_int
;
1976 gboolean orient_set
= FALSE
, first_page_number
= TRUE
, tmp_bool
;
1977 gnm_float width
= 0., height
= 0.;
1978 static EnumVal
const orientation_types
[] = {
1979 { "default", GTK_PAGE_ORIENTATION_PORTRAIT
},
1980 { "portrait", GTK_PAGE_ORIENTATION_PORTRAIT
},
1981 { "landscape", GTK_PAGE_ORIENTATION_LANDSCAPE
},
1984 static EnumVal
const comment_types
[] = {
1985 { "asDisplayed", GNM_PRINT_COMMENTS_IN_PLACE
},
1986 { "atEnd", GNM_PRINT_COMMENTS_AT_END
},
1987 { "none", GNM_PRINT_COMMENTS_NONE
},
1990 static EnumVal
const error_types
[] = {
1991 { "blank", GNM_PRINT_ERRORS_AS_BLANK
},
1992 { "dash", GNM_PRINT_ERRORS_AS_DASHES
},
1993 { "NA", GNM_PRINT_ERRORS_AS_NA
},
1994 { "displayed", GNM_PRINT_ERRORS_AS_DISPLAYED
},
1997 static EnumVal
const page_order_types
[] = {
1998 { "overThenDown", 1 },
1999 { "downThenOver", 0 },
2003 if (pi
->page_setup
== NULL
)
2004 gnm_print_info_load_defaults (pi
);
2006 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2007 if (attr_enum (xin
, attrs
, "orientation", orientation_types
, &orient
))
2009 else if (attr_enum (xin
, attrs
, "cellComments", comment_types
, &tmp_int
))
2010 pi
->comment_placement
= tmp_int
;
2011 else if (attr_enum (xin
, attrs
, "errors", error_types
, &tmp_int
))
2012 pi
->error_display
= tmp_int
;
2013 else if (attr_enum (xin
, attrs
, "pageOrder", page_order_types
, &tmp_int
))
2014 pi
->print_across_then_down
= (tmp_int
!= 0);
2015 else if (attr_int (xin
, attrs
, "paperSize", &paper_code
))
2017 else if (attr_distance (xin
, attrs
, "paperWidth", &width
))
2019 else if (attr_distance (xin
, attrs
, "paperHeight", &height
))
2021 else if (attr_bool (xin
, attrs
, "blackAndWhite", &tmp_bool
))
2022 pi
->print_black_and_white
= tmp_bool
;
2023 else if (attr_int (xin
, attrs
, "copies", &(pi
->n_copies
)))
2025 else if (attr_bool (xin
, attrs
, "draft", &tmp_bool
))
2026 pi
->print_as_draft
= tmp_bool
;
2027 else if (attr_int (xin
, attrs
, "firstPageNumber", &(pi
->start_page
)))
2029 else if (attr_int (xin
, attrs
, "fitToHeight", &(pi
->scaling
.dim
.rows
)))
2031 else if (attr_int (xin
, attrs
, "fitToWidth", &(pi
->scaling
.dim
.cols
)))
2033 else if (attr_int (xin
, attrs
, "scale", &scale
)) {
2034 pi
->scaling
.percentage
.x
= scale
;
2035 pi
->scaling
.percentage
.y
= scale
;
2036 } else if (attr_bool (xin
, attrs
, "useFirstPageNumber", &first_page_number
))
2039 if (!first_page_number
)
2040 pi
->start_page
= -1;
2042 if (!xlsx_set_paper_from_code (pi
, paper_code
) && width
> 0.0 && height
> 0.0)
2043 gtk_page_setup_set_paper_size (pi
->page_setup
,
2044 xlsx_paper_size (width
, height
, GTK_UNIT_POINTS
, 0));
2046 print_info_set_paper_orientation (pi
, orient
);
2050 xlsx_CT_PageMargins (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2052 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2054 GnmPrintInformation
*pi
= state
->sheet
->print_info
;
2056 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2057 if (attr_float (xin
, attrs
, "left", &margin
))
2058 print_info_set_margin_left (pi
, GO_IN_TO_PT (margin
));
2059 else if (attr_float (xin
, attrs
, "right", &margin
))
2060 print_info_set_margin_right (pi
, GO_IN_TO_PT (margin
));
2061 else if (attr_float (xin
, attrs
, "top", &margin
))
2062 print_info_set_edge_to_below_header (pi
, GO_IN_TO_PT (margin
));
2063 else if (attr_float (xin
, attrs
, "bottom", &margin
))
2064 print_info_set_edge_to_above_footer (pi
, GO_IN_TO_PT (margin
));
2065 else if (attr_float (xin
, attrs
, "header", &margin
))
2066 print_info_set_margin_header (pi
, GO_IN_TO_PT (margin
));
2067 else if (attr_float (xin
, attrs
, "footer", &margin
))
2068 print_info_set_margin_footer (pi
, GO_IN_TO_PT (margin
));
2073 xlsx_CT_oddheader_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2075 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2076 GnmPrintInformation
*pi
= state
->sheet
->print_info
;
2077 xls_header_footer_import (pi
->header
, xin
->content
->str
);
2081 xlsx_CT_oddfooter_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2083 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2084 GnmPrintInformation
*pi
= state
->sheet
->print_info
;
2085 xls_header_footer_import (pi
->footer
, xin
->content
->str
);
2089 xlsx_CT_PageBreak (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2091 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2092 GnmPageBreakType type
= GNM_PAGE_BREAK_AUTO
;
2096 if (NULL
== state
->page_breaks
)
2101 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2102 if (attr_int (xin
, attrs
, "id", &pos
)) ;
2103 else if (attr_bool (xin
, attrs
, "man", &tmp
)) { if (tmp
) type
= GNM_PAGE_BREAK_MANUAL
; }
2104 else if (attr_bool (xin
, attrs
, "pt", &tmp
)) { if (tmp
) type
= GNM_PAGE_BREAK_DATA_SLICE
; }
2106 else if (attr_int (xin
, attrs
, "min", &first
)) ;
2107 else if (attr_int (xin
, attrs
, "max", &last
)) ;
2110 gnm_page_breaks_append_break (state
->page_breaks
, pos
, type
);
2114 xlsx_CT_PageBreaks_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2116 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2119 g_return_if_fail (state
->page_breaks
== NULL
);
2121 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2122 if (attr_int (xin
, attrs
, "count", &count
)) ;
2124 else if (attr_int (xin
, attrs
, "manualBreakCount", &manual_count
)) ;
2127 state
->page_breaks
= gnm_page_breaks_new (xin
->node
->user_data
.v_int
);
2131 xlsx_CT_PageBreaks_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2133 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2135 if (NULL
!= state
->page_breaks
) {
2136 print_info_set_breaks (state
->sheet
->print_info
,
2137 state
->page_breaks
);
2138 state
->page_breaks
= NULL
;
2143 xlsx_CT_DataValidation_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2145 static EnumVal
const val_styles
[] = {
2146 { "stop", GNM_VALIDATION_STYLE_STOP
},
2147 { "warning", GNM_VALIDATION_STYLE_WARNING
},
2148 { "information", GNM_VALIDATION_STYLE_INFO
},
2151 static EnumVal
const val_types
[] = {
2152 { "none", GNM_VALIDATION_TYPE_ANY
},
2153 { "whole", GNM_VALIDATION_TYPE_AS_INT
},
2154 { "decimal", GNM_VALIDATION_TYPE_AS_NUMBER
},
2155 { "list", GNM_VALIDATION_TYPE_IN_LIST
},
2156 { "date", GNM_VALIDATION_TYPE_AS_DATE
},
2157 { "time", GNM_VALIDATION_TYPE_AS_TIME
},
2158 { "textLength", GNM_VALIDATION_TYPE_TEXT_LENGTH
},
2159 { "custom", GNM_VALIDATION_TYPE_CUSTOM
},
2162 static EnumVal
const val_ops
[] = {
2163 { "between", GNM_VALIDATION_OP_BETWEEN
},
2164 { "notBetween", GNM_VALIDATION_OP_NOT_BETWEEN
},
2165 { "equal", GNM_VALIDATION_OP_EQUAL
},
2166 { "notEqual", GNM_VALIDATION_OP_NOT_EQUAL
},
2167 { "lessThan", GNM_VALIDATION_OP_LT
},
2168 { "lessThanOrEqual", GNM_VALIDATION_OP_LTE
},
2169 { "greaterThan", GNM_VALIDATION_OP_GT
},
2170 { "greaterThanOrEqual", GNM_VALIDATION_OP_GTE
},
2174 /* Get docs on this */
2175 "imeMode" default="noControl"
2189 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2192 ValidationStyle val_style
= GNM_VALIDATION_STYLE_STOP
;
2193 ValidationType val_type
= GNM_VALIDATION_TYPE_ANY
;
2194 ValidationOp val_op
= GNM_VALIDATION_OP_BETWEEN
;
2195 gboolean allowBlank
= FALSE
;
2196 gboolean showDropDown
= FALSE
;
2197 gboolean showInputMessage
= FALSE
;
2198 gboolean showErrorMessage
= FALSE
;
2199 xmlChar
const *errorTitle
= NULL
;
2200 xmlChar
const *error
= NULL
;
2201 xmlChar
const *promptTitle
= NULL
;
2202 xmlChar
const *prompt
= NULL
;
2203 xmlChar
const *refs
= NULL
;
2206 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2207 if (0 == strcmp (attrs
[0], "sqref"))
2209 else if (attr_enum (xin
, attrs
, "errorStyle", val_styles
, &tmp
))
2211 else if (attr_enum (xin
, attrs
, "type", val_types
, &tmp
))
2213 else if (attr_enum (xin
, attrs
, "operator", val_ops
, &tmp
))
2216 else if (attr_bool (xin
, attrs
, "allowBlank", &allowBlank
)) ;
2217 else if (attr_bool (xin
, attrs
, "showDropDown", &showDropDown
)) ;
2218 else if (attr_bool (xin
, attrs
, "showInputMessage", &showInputMessage
)) ;
2219 else if (attr_bool (xin
, attrs
, "showErrorMessage", &showErrorMessage
)) ;
2221 else if (0 == strcmp (attrs
[0], "errorTitle"))
2222 errorTitle
= attrs
[1];
2223 else if (0 == strcmp (attrs
[0], "error"))
2225 else if (0 == strcmp (attrs
[0], "promptTitle"))
2226 promptTitle
= attrs
[1];
2227 else if (0 == strcmp (attrs
[0], "prompt"))
2230 /* order matters, we need the 1st item */
2231 state
->validation_regions
= g_slist_reverse (
2232 xlsx_parse_sqref (xin
, refs
));
2234 if (NULL
== state
->validation_regions
)
2237 if (showErrorMessage
) {
2238 GnmRange
const *r
= state
->validation_regions
->data
;
2239 state
->pos
= r
->start
;
2240 state
->validation
= gnm_validation_new
2241 (val_style
, val_type
, val_op
,
2244 NULL
, NULL
, allowBlank
, showDropDown
);
2247 if (showInputMessage
&& (NULL
!= promptTitle
|| NULL
!= prompt
))
2248 state
->input_msg
= gnm_input_msg_new (prompt
, promptTitle
);
2252 xlsx_CT_DataValidation_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2254 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2256 GnmStyle
*style
= NULL
;
2259 if (NULL
!= state
->validation
&&
2260 NULL
!= (err
= gnm_validation_is_ok (state
->validation
))) {
2261 xlsx_warning (xin
, _("Ignoring invalid data validation because : %s"),
2263 gnm_validation_unref (state
->validation
);
2264 state
->validation
= NULL
;
2267 if (NULL
!= state
->validation
) {
2268 style
= gnm_style_new ();
2269 gnm_style_set_validation (style
, state
->validation
);
2270 state
->validation
= NULL
;
2273 if (NULL
!= state
->input_msg
) {
2275 style
= gnm_style_new ();
2276 gnm_style_set_input_msg (style
, state
->input_msg
);
2277 state
->input_msg
= NULL
;
2280 for (ptr
= state
->validation_regions
; ptr
!= NULL
; ptr
= ptr
->next
) {
2281 if (NULL
!= style
) {
2282 gnm_style_ref (style
);
2283 sheet_style_apply_range (state
->sheet
, ptr
->data
, style
);
2288 gnm_style_unref (style
);
2289 g_slist_free (state
->validation_regions
);
2290 state
->validation_regions
= NULL
;
2291 state
->pos
.col
= state
->pos
.row
= -1;
2295 xlsx_validation_expr (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2297 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2299 GnmExprTop
const *texpr
;
2301 if (state
->validation
== NULL
)
2304 /* Sneaky buggers, parse relative to the 1st sqRef */
2305 parse_pos_init (&pp
, NULL
, state
->sheet
,
2306 state
->pos
.col
, state
->pos
.row
);
2307 texpr
= xlsx_parse_expr (xin
, xin
->content
->str
, &pp
);
2308 if (NULL
!= texpr
) {
2309 gnm_validation_set_expr (state
->validation
, texpr
,
2310 xin
->node
->user_data
.v_int
);
2311 gnm_expr_top_unref (texpr
);
2316 xlsx_CT_AutoFilter_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2318 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2321 g_return_if_fail (state
->filter
== NULL
);
2323 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2324 if (attr_range (xin
, attrs
, "ref", &r
))
2325 state
->filter
= gnm_filter_new (state
->sheet
, &r
);
2329 xlsx_CT_AutoFilter_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2331 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2332 g_return_if_fail (state
->filter
!= NULL
);
2333 state
->filter
= NULL
;
2337 xlsx_CT_FilterColumn_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2339 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2341 gboolean hidden
= FALSE
;
2342 gboolean show
= TRUE
;
2344 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2345 if (attr_int (xin
, attrs
, "colId", &id
)) ;
2346 else if (attr_bool (xin
, attrs
, "hiddenButton", &hidden
)) ;
2347 else if (attr_bool (xin
, attrs
, "showButton", &show
)) ;
2349 state
->filter_cur_field
= id
;
2353 xlsx_CT_Filters_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2355 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2357 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2358 if (0 == strcmp (attrs
[0], "val")) {
2360 state
->filter_items
= NULL
;
2363 xlsx_CT_Filters_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2365 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2366 state
->filter_items
= NULL
;
2369 xlsx_CT_Filter (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
2372 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2374 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2375 if (0 == strcmp (attrs
[0], "val")) {
2381 xlsx_CT_CustomFilters_begin (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
2383 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2386 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2387 if (0 == strcmp (attrs
[0], "val")) {
2390 state
->filter_items
= NULL
;
2393 xlsx_CT_CustomFilters_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2395 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2396 state
->filter_items
= NULL
;
2400 xlsx_CT_CustomFilter (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
2402 static EnumVal
const ops
[] = {
2403 { "lessThan", GNM_FILTER_OP_LT
},
2404 { "lessThanOrEqual", GNM_FILTER_OP_LTE
},
2405 { "equal", GNM_FILTER_OP_EQUAL
},
2406 { "notEqual", GNM_FILTER_OP_NOT_EQUAL
},
2407 { "greaterThanOrEqual", GNM_FILTER_OP_GTE
},
2408 { "greaterThan", GNM_FILTER_OP_GT
},
2411 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2413 GnmFilterOp op
= GNM_FILTER_OP_EQUAL
;
2415 GnmFilterCondition
*cond
;
2416 GODateConventions
const *date_conv
= workbook_date_conv (state
->wb
);
2418 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2419 if (0 == strcmp (attrs
[0], "val")) {
2420 const char *txt
= CXML2C (attrs
[1]);
2422 v
= format_match (txt
, NULL
, date_conv
);
2424 v
= value_new_string (txt
);
2425 } else if (attr_enum (xin
, attrs
, "operator", ops
, &tmp
)) {
2429 cond
= gnm_filter_condition_new_single (op
, v
);
2431 gnm_filter_set_condition (state
->filter
, state
->filter_cur_field
,
2436 xlsx_CT_Top10 (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2438 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2439 gboolean top
= TRUE
;
2440 gboolean percent
= FALSE
;
2441 gnm_float val
= -1.;
2442 GnmFilterCondition
*cond
;
2444 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2445 if (attr_float (xin
, attrs
, "val", &val
)) ;
2446 else if (attr_bool (xin
, attrs
, "top", &top
)) ;
2447 else if (attr_bool (xin
, attrs
, "percent", &percent
)) ;
2449 if (NULL
!= (cond
= gnm_filter_condition_new_bucket (top
, !percent
, FALSE
, val
)))
2450 gnm_filter_set_condition (state
->filter
, state
->filter_cur_field
,
2455 xlsx_CT_DynamicFilter (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
2458 static EnumVal
const types
[] = {
2460 { "aboveAverage", 0 },
2461 { "belowAverage", 0 },
2471 { "nextQuarter", 0 },
2472 { "thisQuarter", 0 },
2473 { "lastQuarter", 0 },
2477 { "yearToDate", 0 },
2496 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2499 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2500 if (attr_enum (xin
, attrs
, "type", types
, &type
)) ;
2505 xlsx_CT_MergeCell (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2507 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2510 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2511 if (attr_range (xin
, attrs
, "ref", &r
))
2512 gnm_sheet_merge_add (state
->sheet
, &r
, FALSE
,
2513 GO_CMD_CONTEXT (state
->context
));
2517 xlsx_CT_SheetProtection (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2519 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2520 gboolean sheet
= FALSE
;
2521 gboolean objects
= FALSE
;
2522 gboolean scenarios
= FALSE
;
2523 gboolean formatCells
= TRUE
;
2524 gboolean formatColumns
= TRUE
;
2525 gboolean formatRows
= TRUE
;
2526 gboolean insertColumns
= TRUE
;
2527 gboolean insertRows
= TRUE
;
2528 gboolean insertHyperlinks
= TRUE
;
2529 gboolean deleteColumns
= TRUE
;
2530 gboolean deleteRows
= TRUE
;
2531 gboolean selectLockedCells
= FALSE
;
2532 gboolean sort
= TRUE
;
2533 gboolean autoFilter
= TRUE
;
2534 gboolean pivotTables
= TRUE
;
2535 gboolean selectUnlockedCells
= FALSE
;
2537 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2538 if (attr_bool (xin
, attrs
, "sheet", &sheet
)) ;
2539 else if (attr_bool (xin
, attrs
, "objects", &objects
)) ;
2540 else if (attr_bool (xin
, attrs
, "scenarios", &scenarios
)) ;
2541 else if (attr_bool (xin
, attrs
, "formatCells", &formatCells
)) ;
2542 else if (attr_bool (xin
, attrs
, "formatColumns", &formatColumns
)) ;
2543 else if (attr_bool (xin
, attrs
, "formatRows", &formatRows
)) ;
2544 else if (attr_bool (xin
, attrs
, "insertColumns", &insertColumns
)) ;
2545 else if (attr_bool (xin
, attrs
, "insertRows", &insertRows
)) ;
2546 else if (attr_bool (xin
, attrs
, "insertHyperlinks", &insertHyperlinks
)) ;
2547 else if (attr_bool (xin
, attrs
, "deleteColumns", &deleteColumns
)) ;
2548 else if (attr_bool (xin
, attrs
, "deleteRows", &deleteRows
)) ;
2549 else if (attr_bool (xin
, attrs
, "selectLockedCells", &selectLockedCells
)) ;
2550 else if (attr_bool (xin
, attrs
, "sort", &sort
)) ;
2551 else if (attr_bool (xin
, attrs
, "autoFilter", &autoFilter
)) ;
2552 else if (attr_bool (xin
, attrs
, "pivotTables", &pivotTables
)) ;
2553 else if (attr_bool (xin
, attrs
, "selectUnlockedCells", &selectUnlockedCells
)) ;
2555 g_object_set (state
->sheet
,
2557 "protected-allow-edit-objects", objects
,
2558 "protected-allow-edit-scenarios", scenarios
,
2559 "protected-allow-cell-formatting", formatCells
,
2560 "protected-allow-column-formatting", formatColumns
,
2561 "protected-allow-row-formatting", formatRows
,
2562 "protected-allow-insert-columns", insertColumns
,
2563 "protected-allow-insert-rows", insertRows
,
2564 "protected-allow-insert-hyperlinks", insertHyperlinks
,
2565 "protected-allow-delete-columns", deleteColumns
,
2566 "protected-allow-delete-rows", deleteRows
,
2567 "protected-allow-select-locked-cells", selectLockedCells
,
2568 "protected-allow-sort-ranges", sort
,
2569 "protected-allow-edit-auto-filters", autoFilter
,
2570 "protected-allow-edit-pivottable", pivotTables
,
2571 "protected-allow-select-unlocked-cells", selectUnlockedCells
,
2576 xlsx_cond_fmt_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2578 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2579 char const *refs
= NULL
;
2581 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2582 if (0 == strcmp (attrs
[0], "sqref"))
2585 state
->cond_regions
= xlsx_parse_sqref (xin
, refs
);
2587 /* create in first call xlsx_cond_rule to avoid creating condition with
2589 state
->conditions
= NULL
;
2593 xlsx_cond_fmt_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2595 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2596 GnmStyle
*style
= NULL
;
2599 if (NULL
!= state
->conditions
) {
2600 style
= gnm_style_new ();
2601 gnm_style_set_conditions (style
, state
->conditions
);
2602 for (ptr
= state
->cond_regions
; ptr
!= NULL
; ptr
= ptr
->next
) {
2603 gnm_style_ref (style
);
2604 sheet_style_apply_range (state
->sheet
, ptr
->data
, style
);
2607 gnm_style_unref (style
);
2608 } else for (ptr
= state
->cond_regions
; ptr
!= NULL
; ptr
= ptr
->next
)
2610 g_slist_free (state
->cond_regions
);
2611 state
->cond_regions
= NULL
;
2615 XLSX_CF_TYPE_UNDEFINED
,
2617 XLSX_CF_TYPE_EXPRESSION
,
2618 XLSX_CF_TYPE_CELL_IS
,
2619 XLSX_CF_TYPE_COLOR_SCALE
,
2620 XLSX_CF_TYPE_DATA_BAR
,
2621 XLSX_CF_TYPE_ICON_SET
,
2623 XLSX_CF_TYPE_UNIQUE_VALUES
,
2624 XLSX_CF_TYPE_DUPLICATE_VALUES
,
2625 XLSX_CF_TYPE_CONTAINS_STR
,
2626 XLSX_CF_TYPE_NOT_CONTAINS_STR
,
2627 XLSX_CF_TYPE_BEGINS_WITH
,
2628 XLSX_CF_TYPE_ENDS_WITH
,
2629 XLSX_CF_TYPE_CONTAINS_BLANKS
,
2630 XLSX_CF_TYPE_NOT_CONTAINS_BLANKS
,
2631 XLSX_CF_TYPE_CONTAINS_ERRORS
,
2632 XLSX_CF_TYPE_NOT_CONTAINS_ERRORS
,
2633 XLSX_CF_TYPE_COMPARE_COLUMNS
,
2634 XLSX_CF_TYPE_TIME_PERIOD
,
2635 XLSX_CF_TYPE_ABOVE_AVERAGE
2638 xlsx_cond_fmt_rule_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2640 static EnumVal
const ops
[] = {
2641 { "lessThan", GNM_STYLE_COND_LT
},
2642 { "lessThanOrEqual", GNM_STYLE_COND_LTE
},
2643 { "equal", GNM_STYLE_COND_EQUAL
},
2644 { "notEqual", GNM_STYLE_COND_NOT_EQUAL
},
2645 { "greaterThanOrEqual", GNM_STYLE_COND_GTE
},
2646 { "greaterThan", GNM_STYLE_COND_GT
},
2647 { "between", GNM_STYLE_COND_BETWEEN
},
2648 { "notBetween", GNM_STYLE_COND_NOT_BETWEEN
},
2649 { "containsText", GNM_STYLE_COND_CONTAINS_STR
},
2650 { "notContainsText", GNM_STYLE_COND_NOT_CONTAINS_STR
},
2651 { "beginsWith", GNM_STYLE_COND_BEGINS_WITH_STR
},
2652 { "endsWith", GNM_STYLE_COND_ENDS_WITH_STR
},
2653 { "notContain", GNM_STYLE_COND_NOT_CONTAINS_STR
},
2657 static EnumVal
const types
[] = {
2658 { "expression", XLSX_CF_TYPE_EXPRESSION
},
2659 { "cellIs", XLSX_CF_TYPE_CELL_IS
},
2660 { "colorScale", XLSX_CF_TYPE_COLOR_SCALE
},
2661 { "dataBar", XLSX_CF_TYPE_DATA_BAR
},
2662 { "iconSet", XLSX_CF_TYPE_ICON_SET
},
2663 { "top10", XLSX_CF_TYPE_TOP10
},
2664 { "uniqueValues", XLSX_CF_TYPE_UNIQUE_VALUES
},
2665 { "duplicateValues", XLSX_CF_TYPE_DUPLICATE_VALUES
},
2666 { "containsText", XLSX_CF_TYPE_CONTAINS_STR
},
2667 { "doesNotContainText", XLSX_CF_TYPE_NOT_CONTAINS_STR
}, /* ??? */
2668 { "notContainsText", XLSX_CF_TYPE_NOT_CONTAINS_STR
},
2669 { "beginsWith", XLSX_CF_TYPE_BEGINS_WITH
},
2670 { "endsWith", XLSX_CF_TYPE_ENDS_WITH
},
2671 { "containsBlanks", XLSX_CF_TYPE_CONTAINS_BLANKS
},
2672 { "containsNoBlanks", XLSX_CF_TYPE_NOT_CONTAINS_BLANKS
}, /* ??? */
2673 { "notContainsBlanks", XLSX_CF_TYPE_NOT_CONTAINS_BLANKS
},
2674 { "containsErrors", XLSX_CF_TYPE_CONTAINS_ERRORS
},
2675 { "containsNoErrors", XLSX_CF_TYPE_NOT_CONTAINS_ERRORS
}, /* ??? */
2676 { "notContainsErrors", XLSX_CF_TYPE_NOT_CONTAINS_ERRORS
},
2677 { "compareColumns", XLSX_CF_TYPE_COMPARE_COLUMNS
},
2678 { "timePeriod", XLSX_CF_TYPE_TIME_PERIOD
},
2679 { "aboveAverage", XLSX_CF_TYPE_ABOVE_AVERAGE
},
2683 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2684 gboolean formatRow
= FALSE
;
2685 gboolean stopIfTrue
= FALSE
;
2686 gboolean above
= TRUE
;
2687 gboolean percent
= FALSE
;
2688 gboolean bottom
= FALSE
;
2690 /* use custom invalid flag, it is not in MS enum */
2691 GnmStyleCondOp op
= GNM_STYLE_COND_CUSTOM
;
2692 XlsxCFTypes type
= XLSX_CF_TYPE_UNDEFINED
;
2693 char const *type_str
= "-";
2694 GnmStyle
*overlay
= NULL
;
2696 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2697 if (attr_bool (xin
, attrs
, "formatRow", &formatRow
)) ;
2698 else if (attr_bool (xin
, attrs
, "stopIfTrue", &stopIfTrue
)) ;
2699 else if (attr_bool (xin
, attrs
, "above", &above
)) ;
2700 else if (attr_bool (xin
, attrs
, "percent", &percent
)) ;
2701 else if (attr_bool (xin
, attrs
, "bottom", &bottom
)) ;
2702 else if (attr_int (xin
, attrs
, "dxfId", &dxf
)) ;
2703 else if (attr_enum (xin
, attrs
, "operator", ops
, &tmp
))
2705 else if (attr_enum (xin
, attrs
, "type", types
, &tmp
)) {
2707 type_str
= attrs
[1];
2712 "numFmtId" ="ST_NumFmtId" use="optional">
2713 "priority" ="xs:int" use="required">
2714 "text" ="xs:string" use="optional">
2715 "timePeriod" ="ST_TimePeriod" use="optional">
2716 "col1" ="xs:unsignedInt" use="optional">
2717 "col2" ="xs:unsignedInt" use="optional">
2722 overlay
= xlsx_get_dxf (xin
, dxf
);
2725 case XLSX_CF_TYPE_CELL_IS
:
2728 case XLSX_CF_TYPE_CONTAINS_STR
:
2729 case XLSX_CF_TYPE_NOT_CONTAINS_STR
:
2730 case XLSX_CF_TYPE_BEGINS_WITH
:
2731 case XLSX_CF_TYPE_ENDS_WITH
:
2732 case XLSX_CF_TYPE_CONTAINS_BLANKS
:
2733 case XLSX_CF_TYPE_NOT_CONTAINS_BLANKS
:
2734 case XLSX_CF_TYPE_CONTAINS_ERRORS
:
2735 case XLSX_CF_TYPE_NOT_CONTAINS_ERRORS
:
2736 /* The expressions stored for these are the full
2737 expressions, not just what we search for. */
2738 op
= GNM_STYLE_COND_CUSTOM
;
2741 case XLSX_CF_TYPE_EXPRESSION
:
2742 op
= GNM_STYLE_COND_CUSTOM
;
2746 xlsx_warning (xin
, _("Ignoring unhandled conditional format of type '%s'"), type_str
);
2749 state
->cond
= gnm_style_cond_new (op
, state
->sheet
);
2750 gnm_style_cond_set_overlay (state
->cond
, overlay
);
2756 xlsx_cond_fmt_rule_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2758 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2760 if (gnm_style_cond_is_valid (state
->cond
)) {
2761 if (NULL
== state
->conditions
)
2762 state
->conditions
= gnm_style_conditions_new (state
->sheet
);
2763 /* Reverse the alternate-expression treatment. */
2764 gnm_style_cond_canonicalize (state
->cond
);
2766 gnm_style_conditions_insert (state
->conditions
,
2769 gnm_style_cond_free (state
->cond
);
2775 xlsx_cond_fmt_formula_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2777 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2779 GnmExprTop
const *texpr
;
2780 GnmCellPos
const *cp
;
2782 if (!state
->cond
|| state
->count
> 1 || state
->cond_regions
== NULL
)
2785 cp
= g_slist_last (state
->cond_regions
)->data
;
2786 parse_pos_init (&pp
, state
->sheet
->workbook
, state
->sheet
, cp
->col
, cp
->row
);
2787 texpr
= xlsx_parse_expr (xin
, xin
->content
->str
, &pp
);
2789 gnm_style_cond_set_expr (state
->cond
, texpr
, state
->count
);
2790 gnm_expr_top_unref (texpr
);
2797 xlsx_CT_SheetView_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2799 /* static EnumVal const view_types[] = { */
2800 /* { "normal", GNM_SHEET_VIEW_NORMAL_MODE }, */
2801 /* { "pageBreakPreview", GNM_SHEET_VIEW_PAGE_BREAK_MODE }, */
2802 /* { "pageLayout", GNM_SHEET_VIEW_LAYOUT_MODE }, */
2806 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2807 int showGridLines
= TRUE
;
2808 int showFormulas
= FALSE
;
2809 int showRowColHeaders
= TRUE
;
2810 int showZeros
= TRUE
;
2812 int frozenSplit
= TRUE
;
2813 int rightToLeft
= FALSE
;
2814 int tabSelected
= FALSE
;
2816 int showRuler
= TRUE
;
2817 int showOutlineSymbols
= TRUE
;
2818 int defaultGridColor
= TRUE
;
2819 int showWhiteSpace
= TRUE
;
2821 int grid_color_index
= -1;
2823 /* GnmSheetViewMode view_mode = GNM_SHEET_VIEW_NORMAL_MODE; */
2824 GnmCellPos topLeft
= { -1, -1 };
2826 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2827 if (attr_pos (xin
, attrs
, "topLeftCell", &topLeft
)) ;
2828 else if (attr_bool (xin
, attrs
, "showGridLines", &showGridLines
)) ;
2829 else if (attr_bool (xin
, attrs
, "showFormulas", &showFormulas
)) ;
2830 else if (attr_bool (xin
, attrs
, "showRowColHeaders", &showRowColHeaders
)) ;
2831 else if (attr_bool (xin
, attrs
, "showZeros", &showZeros
)) ;
2832 else if (attr_bool (xin
, attrs
, "frozen", &frozen
)) ;
2833 else if (attr_bool (xin
, attrs
, "frozenSplit", &frozenSplit
)) ;
2834 else if (attr_bool (xin
, attrs
, "rightToLeft", &rightToLeft
)) ;
2835 else if (attr_bool (xin
, attrs
, "tabSelected", &tabSelected
)) ;
2836 else if (attr_bool (xin
, attrs
, "active", &active
)) ;
2837 else if (attr_bool (xin
, attrs
, "showRuler", &showRuler
)) ;
2838 else if (attr_bool (xin
, attrs
, "showOutlineSymbols", &showOutlineSymbols
)) ;
2839 else if (attr_bool (xin
, attrs
, "defaultGridColor", &defaultGridColor
)) ;
2840 else if (attr_bool (xin
, attrs
, "showWhiteSpace", &showWhiteSpace
)) ;
2841 else if (attr_int (xin
, attrs
, "zoomScale", &scale
)) ;
2842 else if (attr_int (xin
, attrs
, "colorId", &grid_color_index
)) ;
2843 /* else if (attr_enum (xin, attrs, "view", view_types, &tmp)) */
2844 /* view_mode = tmp; */
2846 "zoomScaleNormal" type
="xs:unsignedInt" use
="optional" default="0"
2847 "zoomScaleSheetLayoutView" type
="xs:unsignedInt" use
="optional" default="0"
2848 "zoomScalePageLayoutView" type
="xs:unsignedInt" use
="optional" default="0"
2849 "workbookViewId" type
="xs:unsignedInt" use
="required"
2852 /* get this from the workbookViewId */
2853 g_return_if_fail (state
->sv
== NULL
);
2854 state
->sv
= sheet_get_view (state
->sheet
, state
->wb_view
);
2855 state
->pane_pos
= XLSX_PANE_TOP_LEFT
;
2857 /* until we import multiple views unfreeze just in case a previous view
2859 sv_freeze_panes (state
->sv
, NULL
, NULL
);
2861 if (topLeft
.col
>= 0)
2862 sv_set_initial_top_left (state
->sv
, topLeft
.col
, topLeft
.row
);
2863 g_object_set (state
->sheet
,
2864 "text-is-rtl", rightToLeft
,
2865 "display-formulas", showFormulas
,
2866 "display-zeros", showZeros
,
2867 "display-grid", showGridLines
,
2868 "display-column-header", showRowColHeaders
,
2869 "display-row-header", showRowColHeaders
,
2870 "display-outlines", showOutlineSymbols
,
2871 "zoom-factor", ((double)scale
) / 100.,
2874 gboolean active
= FALSE
;
2875 gboolean showRuler
= TRUE
;
2876 gboolean showWhiteSpace
= TRUE
;
2880 g_object_set (state
->sv
,
2881 "displayMode", view_mode
,
2885 if (!defaultGridColor
&& grid_color_index
>= 0)
2886 sheet_style_set_auto_pattern_color (state
->sheet
,
2887 gnm_color_new_go (indexed_color (state
, grid_color_index
)));
2889 wb_view_sheet_focus (state
->wb_view
, state
->sheet
);
2892 xlsx_CT_SheetView_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2894 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2895 g_return_if_fail (state
->sv
!= NULL
);
2899 static EnumVal
const pane_types
[] = {
2900 { "topLeft", XLSX_PANE_TOP_LEFT
},
2901 { "topRight", XLSX_PANE_TOP_RIGHT
},
2902 { "bottomLeft", XLSX_PANE_BOTTOM_LEFT
},
2903 { "bottomRight", XLSX_PANE_BOTTOM_RIGHT
},
2907 xlsx_CT_Selection (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2909 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2910 GnmCellPos edit_pos
= { -1, -1 };
2911 int i
, sel_with_edit_pos
= 0;
2912 char const *refs
= NULL
;
2913 XLSXPanePos pane_pos
= XLSX_PANE_TOP_LEFT
;
2915 GSList
*ptr
, *accum
= NULL
;
2917 g_return_if_fail (state
->sv
!= NULL
);
2919 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2920 if (0 == strcmp (attrs
[0], "sqref"))
2922 else if (attr_enum (xin
, attrs
, "activePane", pane_types
, &i
))
2924 else if (attr_pos (xin
, attrs
, "activeCell", &edit_pos
)) ;
2925 else if (attr_int (xin
, attrs
, "activeCellId", &sel_with_edit_pos
))
2928 if (pane_pos
!= state
->pane_pos
)
2931 for (i
= 0 ; NULL
!= refs
&& *refs
; i
++) {
2932 if (NULL
== (refs
= cellpos_parse (refs
, gnm_sheet_get_size (state
->sheet
), &r
.start
, FALSE
)))
2935 if (*refs
== '\0' || *refs
== ' ')
2937 else if (*refs
!= ':' ||
2938 NULL
== (refs
= cellpos_parse (refs
+ 1, gnm_sheet_get_size (state
->sheet
), &r
.end
, FALSE
)))
2942 sv_selection_reset (state
->sv
);
2944 /* gnumeric assumes the edit_pos is in the last selected range.
2945 * We need to re-order the selection list. */
2946 if (i
<= sel_with_edit_pos
&& edit_pos
.col
>= 0)
2947 accum
= g_slist_prepend (accum
, gnm_range_dup (&r
));
2949 sv_selection_add_range (state
->sv
, &r
);
2950 while (*refs
== ' ')
2954 if (NULL
!= accum
) {
2955 accum
= g_slist_reverse (accum
);
2956 for (ptr
= accum
; ptr
!= NULL
; ptr
= ptr
->next
) {
2957 sv_selection_add_range (state
->sv
, ptr
->data
);
2960 sv_set_edit_pos (state
->sv
, &edit_pos
);
2961 g_slist_free (accum
);
2966 xlsx_CT_PivotSelection (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
2969 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2970 <xsd
:attribute name
="pane" type
="ST_Pane" use
="optional" default="topLeft">
2971 <xsd
:attribute name
="showHeader" type
="xsd:boolean" default="false">
2972 <xsd
:attribute name
="label" type
="xsd:boolean" default="false">
2973 <xsd
:attribute name
="data" type
="xsd:boolean" default="false">
2974 <xsd
:attribute name
="extendable" type
="xsd:boolean" default="false">
2975 <xsd
:attribute name
="count" type
="xsd:unsignedInt" default="0">
2976 <xsd
:attribute name
="axis" type
="ST_Axis" use
="optional">
2977 <xsd
:attribute name
="dimension" type
="xsd:unsignedInt" default="0">
2978 <xsd
:attribute name
="start" type
="xsd:unsignedInt" default="0">
2979 <xsd
:attribute name
="min" type
="xsd:unsignedInt" default="0">
2980 <xsd
:attribute name
="max" type
="xsd:unsignedInt" default="0">
2981 <xsd
:attribute name
="activeRow" type
="xsd:unsignedInt" default="0">
2982 <xsd
:attribute name
="activeCol" type
="xsd:unsignedInt" default="0">
2983 <xsd
:attribute name
="previousRow" type
="xsd:unsignedInt" default="0">
2984 <xsd
:attribute name
="previousCol" type
="xsd:unsignedInt" default="0">
2985 <xsd
:attribute name
="click" type
="xsd:unsignedInt" default="0">
2986 <xsd
:attribute ref
="r:id" use
="optional">
2991 xlsx_CT_PivotArea (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
2994 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2995 <xsd
:attribute name
="field" use
="optional" type
="xsd:int">
2996 <xsd
:attribute name
="type" type
="ST_PivotAreaType" default="normal">
2997 <xsd
:attribute name
="dataOnly" type
="xsd:boolean" default="true">
2998 <xsd
:attribute name
="labelOnly" type
="xsd:boolean" default="false">
2999 <xsd
:attribute name
="grandRow" type
="xsd:boolean" default="false">
3000 <xsd
:attribute name
="grandCol" type
="xsd:boolean" default="false">
3001 <xsd
:attribute name
="cacheIndex" type
="xsd:boolean" default="false">
3002 <xsd
:attribute name
="outline" type
="xsd:boolean" default="true">
3003 <xsd
:attribute name
="offset" type
="ST_Ref">
3004 <xsd
:attribute name
="collapsedLevelsAreSubtotals" type
="xsd:boolean" default="false">
3005 <xsd
:attribute name
="axis" type
="ST_Axis" use
="optional">
3006 <xsd
:attribute name
="fieldPosition" type
="xsd:unsignedInt" use
="optional">
3010 xlsx_CT_PivotAreaReferences (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3013 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3017 xlsx_CT_PivotAreaReference (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3020 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3021 <xsd
:attribute name
="field" use
="optional" type
="xsd:unsignedInt">
3022 <xsd
:attribute name
="count" type
="xsd:unsignedInt">
3023 <xsd
:attribute name
="selected" type
="xsd:boolean" default="true">
3024 <xsd
:attribute name
="byPosition" type
="xsd:boolean" default="false">
3025 <xsd
:attribute name
="relative" type
="xsd:boolean" default="false">
3026 <xsd
:attribute name
="defaultSubtotal" type
="xsd:boolean" default="false">
3027 <xsd
:attribute name
="sumSubtotal" type
="xsd:boolean" default="false">
3028 <xsd
:attribute name
="countASubtotal" type
="xsd:boolean" default="false">
3029 <xsd
:attribute name
="avgSubtotal" type
="xsd:boolean" default="false">
3030 <xsd
:attribute name
="maxSubtotal" type
="xsd:boolean" default="false">
3031 <xsd
:attribute name
="minSubtotal" type
="xsd:boolean" default="false">
3032 <xsd
:attribute name
="productSubtotal" type
="xsd:boolean" default="false">
3033 <xsd
:attribute name
="countSubtotal" type
="xsd:boolean" default="false">
3034 <xsd
:attribute name
="stdDevSubtotal" type
="xsd:boolean" default="false">
3035 <xsd
:attribute name
="stdDevPSubtotal" type
="xsd:boolean" default="false">
3036 <xsd
:attribute name
="varSubtotal" type
="xsd:boolean" default="false">
3037 <xsd
:attribute name
="varPSubtotal" type
="xsd:boolean" default="false">
3042 xlsx_CT_Pane (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3044 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3045 GnmCellPos topLeft
= { 0, 0 };
3047 gnm_float xSplit
= -1., ySplit
= -1.;
3048 gboolean frozen
= FALSE
;
3050 g_return_if_fail (state
->sv
!= NULL
);
3052 /* <pane xSplit="2" ySplit="3" topLeftCell="J15" activePane="bottomRight" state="frozen"/> */
3053 state
->pane_pos
= XLSX_PANE_TOP_LEFT
;
3054 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3055 if (0 == strcmp (attrs
[0], "state"))
3056 frozen
= (0 == strcmp (attrs
[1], "frozen"));
3057 else if (attr_pos (xin
, attrs
, "topLeftCell", &topLeft
)) ;
3058 else if (attr_float (xin
, attrs
, "xSplit", &xSplit
)) ;
3059 else if (attr_float (xin
, attrs
, "ySplit", &ySplit
)) ;
3060 else if (attr_enum (xin
, attrs
, "pane", pane_types
, &tmp
))
3061 state
->pane_pos
= tmp
;
3064 GnmCellPos frozen
, unfrozen
;
3065 frozen
= unfrozen
= state
->sv
->initial_top_left
;
3067 unfrozen
.col
+= xSplit
;
3069 topLeft
.col
= state
->sv
->initial_top_left
.col
;
3071 unfrozen
.row
+= ySplit
;
3073 topLeft
.row
= state
->sv
->initial_top_left
.row
;
3074 sv_freeze_panes (state
->sv
, &frozen
, &unfrozen
);
3075 sv_set_initial_top_left (state
->sv
, topLeft
.col
, topLeft
.row
);
3080 xlsx_ole_object (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3083 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3085 /* <oleObject progId="Wordpad.Document.1" shapeId="1032" r:id="rId5"/> */
3086 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3092 xlsx_CT_HyperLinks (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3094 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3095 gboolean has_ref
= FALSE
;
3098 GType link_type
= 0;
3099 GnmHLink
*link
= NULL
;
3100 xmlChar
const *target
= NULL
;
3101 xmlChar
const *tooltip
= NULL
;
3102 xmlChar
const *extern_id
= NULL
;
3104 /* <hyperlink ref="A42" r:id="rId1"/> */
3105 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3106 if (attr_range (xin
, attrs
, "ref", &r
))
3108 else if (0 == strcmp (attrs
[0], "location"))
3110 else if (0 == strcmp (attrs
[0], "tooltip"))
3112 else if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_DOC_REL
, "id"))
3113 extern_id
= attrs
[1];
3114 #if 0 /* ignore "display" on import, it always seems to be the cell content */
3115 else if (0 == strcmp (attrs
[0], "display"))
3121 link_type
= gnm_hlink_cur_wb_get_type ();
3122 else if (NULL
!= extern_id
) {
3123 GsfOpenPkgRel
const *rel
= gsf_open_pkg_lookup_rel_by_id (
3124 gsf_xml_in_get_input (xin
), extern_id
);
3126 gsf_open_pkg_rel_is_extern (rel
) &&
3127 0 == strcmp (gsf_open_pkg_rel_get_type (rel
),
3128 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink")) {
3129 target
= gsf_open_pkg_rel_get_target (rel
);
3130 if (NULL
!= target
) {
3131 if (0 == strncmp (target
, "mailto:", 7))
3132 link_type
= gnm_hlink_email_get_type ();
3134 link_type
= gnm_hlink_url_get_type ();
3139 if (0 == link_type
) {
3140 xlsx_warning (xin
, _("Unknown type of hyperlink"));
3144 link
= g_object_new (link_type
, NULL
);
3146 gnm_hlink_set_target (link
, target
);
3147 if (NULL
!= tooltip
)
3148 gnm_hlink_set_tip (link
, tooltip
);
3149 style
= gnm_style_new ();
3150 gnm_style_set_hlink (style
, link
);
3151 sheet_style_apply_range (state
->sheet
, &r
, style
);
3155 cb_find_pivots (GsfInput
*opkg
, GsfOpenPkgRel
const *rel
, gpointer user_data
)
3157 XLSXReadState
*state
= user_data
;
3158 GsfInput
*part_stream
;
3159 char const *t
= gsf_open_pkg_rel_get_type (rel
);
3162 0 == strcmp (t
, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable") &&
3163 NULL
!= (part_stream
= gsf_open_pkg_open_rel (opkg
, rel
, NULL
)))
3164 xlsx_parse_stream (state
, part_stream
, xlsx_pivot_table_dtd
);
3168 xlsx_CT_worksheet (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3170 gsf_open_pkg_foreach_rel (gsf_xml_in_get_input (xin
),
3171 &cb_find_pivots
, (XLSXReadState
*)xin
->user_state
);
3176 xlsx_ext_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3178 gboolean warned
= FALSE
;
3179 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3180 if (0 == strcmp (attrs
[0], "uri")) {
3183 _("Encountered uninterpretable \"ext\" extension in namespace \"%s\""),
3190 _("Encountered uninterpretable \"ext\" extension with missing namespace"));
3191 gsf_xml_in_set_silent_unknowns (xin
, TRUE
);
3195 xlsx_ext_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3197 gsf_xml_in_set_silent_unknowns (xin
, FALSE
);
3203 add_attr (XLSXReadState
*state
, PangoAttribute
*attr
)
3205 attr
->start_index
= 0;
3206 attr
->end_index
= -1;
3208 if (state
->run_attrs
== NULL
)
3209 state
->run_attrs
= pango_attr_list_new ();
3211 pango_attr_list_insert (state
->run_attrs
, attr
);
3215 xlsx_run_weight (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3217 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3218 PangoWeight wt
= PANGO_WEIGHT_BOLD
; /* Default */
3220 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3222 if (attr_bool (xin
, attrs
, "val", &i
))
3223 wt
= i
? PANGO_WEIGHT_BOLD
: PANGO_WEIGHT_NORMAL
;
3226 add_attr (state
, pango_attr_weight_new (wt
));
3230 xlsx_run_style (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3232 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3233 PangoStyle st
= PANGO_STYLE_ITALIC
;
3235 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3237 if (attr_bool (xin
, attrs
, "val", &i
))
3238 st
= i
? PANGO_STYLE_ITALIC
: PANGO_STYLE_NORMAL
;
3241 add_attr (state
, pango_attr_style_new (st
));
3245 xlsx_run_family (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3247 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3248 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3249 if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_SS
, "val")) {
3250 PangoAttribute
*attr
= pango_attr_family_new (attrs
[1]);
3251 add_attr (state
, attr
);
3256 xlsx_run_size (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3258 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3259 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3260 if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_SS
, "val")) {
3261 PangoAttribute
*attr
= pango_attr_size_new (atoi (attrs
[1]) * PANGO_SCALE
);
3262 add_attr (state
, attr
);
3268 xlsx_run_strikethrough (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3270 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3271 gboolean st
= TRUE
; /* Default */
3273 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3275 if (attr_bool (xin
, attrs
, "val", &i
))
3279 add_attr (state
, pango_attr_strikethrough_new (st
));
3283 xlsx_run_underline (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3285 static EnumVal
const types
[] = {
3286 { "single", PANGO_UNDERLINE_SINGLE
},
3287 { "double", PANGO_UNDERLINE_DOUBLE
},
3288 { "singleAccounting", PANGO_UNDERLINE_LOW
},
3289 { "doubleAccounting", PANGO_UNDERLINE_LOW
}, /* fixme? */
3290 { "none", PANGO_UNDERLINE_NONE
},
3293 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3294 int u
= PANGO_UNDERLINE_SINGLE
;
3296 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3297 if (attr_enum (xin
, attrs
, "val", types
, &u
))
3301 add_attr (state
, pango_attr_underline_new (u
));
3305 xlsx_run_vertalign (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3307 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3308 static EnumVal
const types
[] = {
3309 { "subscript", GO_FONT_SCRIPT_SUB
},
3310 { "baseline", GO_FONT_SCRIPT_STANDARD
},
3311 { "superscript", GO_FONT_SCRIPT_SUPER
},
3314 int v
= GO_FONT_SCRIPT_STANDARD
;
3316 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3317 if (attr_enum (xin
, attrs
, "val", types
, &v
))
3322 case GO_FONT_SCRIPT_SUB
:
3323 add_attr (state
, go_pango_attr_subscript_new (TRUE
));
3325 case GO_FONT_SCRIPT_SUPER
:
3326 add_attr (state
, go_pango_attr_superscript_new (TRUE
));
3335 xlsx_run_color (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3337 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3338 GOColor c
= GO_COLOR_BLACK
;
3340 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3341 if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_SS
, "rgb")) {
3342 unsigned r
, g
, b
, a
;
3343 if (4 != sscanf (attrs
[1], "%02x%02x%02x%02x", &a
, &r
, &g
, &b
)) {
3345 _("Invalid color '%s' for attribute rgb"),
3350 c
= GO_COLOR_FROM_RGBA (r
, g
, b
, a
);
3351 } else if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_SS
, "indexed")) {
3352 int idx
= atoi (CXML2C (attrs
[1]));
3353 c
= indexed_color (state
, idx
);
3357 add_attr (state
, go_color_to_pango (c
, TRUE
));
3361 cb_trunc_attributes (PangoAttribute
*a
, gpointer plen
)
3363 a
->end_index
= GPOINTER_TO_UINT (plen
);
3368 xlsx_rich_text (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3370 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3371 const char *s
= xin
->content
->str
;
3373 if (state
->run_attrs
) {
3374 unsigned len
= strlen (s
);
3375 unsigned start
= state
->r_text
->len
, end
= start
+ len
;
3376 pango_attr_list_filter (state
->run_attrs
,
3377 (PangoAttrFilterFunc
) cb_trunc_attributes
,
3378 GUINT_TO_POINTER (len
));
3379 if (state
->rich_attrs
== NULL
)
3380 state
->rich_attrs
= pango_attr_list_new ();
3381 pango_attr_list_splice (state
->rich_attrs
, state
->run_attrs
, start
, end
);
3382 pango_attr_list_unref (state
->run_attrs
);
3383 state
->run_attrs
= NULL
;
3385 g_string_append (state
->r_text
, s
);
3389 * Rich text is used in multiple dtds. We don't hanadle that with
3390 * particular elegance, but we've got macros.
3392 #define RICH_TEXT_NODES \
3393 GSF_XML_IN_NODE (RICH, RICH_TEXT, XL_NS_SS, "t", GSF_XML_CONTENT, NULL, xlsx_rich_text), \
3394 GSF_XML_IN_NODE (RICH, RICH_PROPS, XL_NS_SS, "rPr", GSF_XML_NO_CONTENT, NULL, NULL), \
3395 /* GSF_XML_IN_NODE (RICH_PROPS, RICH_FONT, XL_NS_SS, "font", GSF_XML_NO_CONTENT, NULL, NULL), */ \
3396 /* docs say 'font' xl is generating rFont */ \
3397 GSF_XML_IN_NODE (RICH_PROPS, RICH_FONT, XL_NS_SS, "rFont", GSF_XML_NO_CONTENT, NULL, NULL), \
3399 GSF_XML_IN_NODE (RICH_PROPS, RICH_CHARSET, XL_NS_SS, "charset", GSF_XML_NO_CONTENT, NULL, NULL), \
3400 GSF_XML_IN_NODE (RICH_PROPS, RICH_FAMILY, XL_NS_SS, "family", GSF_XML_NO_CONTENT, xlsx_run_family, NULL), \
3401 GSF_XML_IN_NODE (RICH_PROPS, RICH_BOLD, XL_NS_SS, "b", GSF_XML_NO_CONTENT, xlsx_run_weight, NULL), \
3402 GSF_XML_IN_NODE (RICH_PROPS, RICH_ITALIC, XL_NS_SS, "i", GSF_XML_NO_CONTENT, xlsx_run_style, NULL), \
3403 GSF_XML_IN_NODE (RICH_PROPS, RICH_STRIKE, XL_NS_SS, "strike", GSF_XML_NO_CONTENT, xlsx_run_strikethrough, NULL), \
3404 GSF_XML_IN_NODE (RICH_PROPS, RICH_OUTLINE, XL_NS_SS, "outline", GSF_XML_NO_CONTENT, NULL, NULL), \
3405 GSF_XML_IN_NODE (RICH_PROPS, RICH_SHADOW, XL_NS_SS, "shadow", GSF_XML_NO_CONTENT, NULL, NULL), \
3406 GSF_XML_IN_NODE (RICH_PROPS, RICH_CONDENSE, XL_NS_SS, "condense", GSF_XML_NO_CONTENT, NULL, NULL), \
3407 GSF_XML_IN_NODE (RICH_PROPS, RICH_EXTEND, XL_NS_SS, "extend", GSF_XML_NO_CONTENT, NULL, NULL), \
3408 GSF_XML_IN_NODE (RICH_PROPS, RICH_COLOR, XL_NS_SS, "color", GSF_XML_NO_CONTENT, xlsx_run_color, NULL), \
3409 GSF_XML_IN_NODE (RICH_PROPS, RICH_SZ, XL_NS_SS, "sz", GSF_XML_NO_CONTENT, xlsx_run_size, NULL), \
3410 GSF_XML_IN_NODE (RICH_PROPS, RICH_ULINE, XL_NS_SS, "u", GSF_XML_NO_CONTENT, xlsx_run_underline, NULL), \
3411 GSF_XML_IN_NODE (RICH_PROPS, RICH_VALIGN, XL_NS_SS, "vertAlign", GSF_XML_NO_CONTENT, xlsx_run_vertalign, NULL), \
3412 GSF_XML_IN_NODE (RICH_PROPS, RICH_SCHEME, XL_NS_SS, "scheme", GSF_XML_NO_CONTENT, NULL, NULL)
3417 static GsfXMLInNode
const xlsx_sheet_dtd
[] = {
3418 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
3419 GSF_XML_IN_NODE_FULL (START
, SHEET
, XL_NS_SS
, "worksheet", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, &xlsx_CT_worksheet
, 0),
3420 GSF_XML_IN_NODE (SHEET
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3421 GSF_XML_IN_NODE (EXTLST
, EXTITEM
, XL_NS_SS
, "ext", GSF_XML_NO_CONTENT
, &xlsx_ext_begin
, &xlsx_ext_end
),
3422 GSF_XML_IN_NODE (SHEET
, PROPS
, XL_NS_SS
, "sheetPr", GSF_XML_NO_CONTENT
, &xlsx_CT_SheetPr
, NULL
),
3423 GSF_XML_IN_NODE (PROPS
, OUTLINE_PROPS
, XL_NS_SS
, "outlinePr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3424 GSF_XML_IN_NODE (PROPS
, TAB_COLOR
, XL_NS_SS
, "tabColor", GSF_XML_NO_CONTENT
, &xlsx_sheet_tabcolor
, NULL
),
3425 GSF_XML_IN_NODE (PROPS
, PAGE_SETUP
, XL_NS_SS
, "pageSetUpPr", GSF_XML_NO_CONTENT
, &xlsx_sheet_page_setup
, NULL
),
3426 GSF_XML_IN_NODE (SHEET
, DIMENSION
, XL_NS_SS
, "dimension", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3427 GSF_XML_IN_NODE (SHEET
, VIEWS
, XL_NS_SS
, "sheetViews", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3428 GSF_XML_IN_NODE (VIEWS
, VIEW
, XL_NS_SS
, "sheetView", GSF_XML_NO_CONTENT
, &xlsx_CT_SheetView_begin
, &xlsx_CT_SheetView_end
),
3429 GSF_XML_IN_NODE (VIEW
, PANE
, XL_NS_SS
, "pane", GSF_XML_NO_CONTENT
, &xlsx_CT_Pane
, NULL
),
3430 GSF_XML_IN_NODE (VIEW
, SELECTION
, XL_NS_SS
, "selection", GSF_XML_NO_CONTENT
, &xlsx_CT_Selection
, NULL
),
3431 GSF_XML_IN_NODE (VIEW
, PIV_SELECTION
, XL_NS_SS
, "pivotSelection", GSF_XML_NO_CONTENT
, &xlsx_CT_PivotSelection
, NULL
),
3432 GSF_XML_IN_NODE (PIV_SELECTION
, PIV_AREA
, XL_NS_SS
, "pivotArea", GSF_XML_NO_CONTENT
, &xlsx_CT_PivotArea
, NULL
),
3433 GSF_XML_IN_NODE (PIV_AREA
, PIV_AREA_REFS
, XL_NS_SS
, "references", GSF_XML_NO_CONTENT
, &xlsx_CT_PivotAreaReferences
, NULL
),
3434 GSF_XML_IN_NODE (PIV_AREA_REFS
, PIV_AREA_REF
, XL_NS_SS
, "reference", GSF_XML_NO_CONTENT
, &xlsx_CT_PivotAreaReference
, NULL
),
3436 GSF_XML_IN_NODE (SHEET
, DEFAULT_FMT
, XL_NS_SS
, "sheetFormatPr", GSF_XML_NO_CONTENT
, &xlsx_CT_SheetFormatPr
, NULL
),
3438 GSF_XML_IN_NODE (SHEET
, COLS
, XL_NS_SS
, "cols", GSF_XML_NO_CONTENT
, NULL
, xlsx_CT_RowsCols_end
),
3439 GSF_XML_IN_NODE (COLS
, COL
, XL_NS_SS
, "col", GSF_XML_NO_CONTENT
, &xlsx_CT_Col
, NULL
),
3441 GSF_XML_IN_NODE (SHEET
, CONTENT
, XL_NS_SS
, "sheetData", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3442 GSF_XML_IN_NODE (CONTENT
, ROW
, XL_NS_SS
, "row", GSF_XML_NO_CONTENT
, &xlsx_CT_Row
, NULL
),
3443 GSF_XML_IN_NODE (ROW
, CELL
, XL_NS_SS
, "c", GSF_XML_NO_CONTENT
, &xlsx_cell_begin
, &xlsx_cell_end
),
3444 GSF_XML_IN_NODE (CELL
, VALUE
, XL_NS_SS
, "v", GSF_XML_CONTENT
, NULL
, &xlsx_cell_val_end
),
3445 GSF_XML_IN_NODE (CELL
, FMLA
, XL_NS_SS
, "f", GSF_XML_CONTENT
, &xlsx_cell_expr_begin
, &xlsx_cell_expr_end
),
3446 GSF_XML_IN_NODE (CELL
, TEXTINLINE
, XL_NS_SS
, "is", GSF_XML_NO_CONTENT
, &xlsx_cell_inline_begin
, &xlsx_cell_inline_end
),
3447 GSF_XML_IN_NODE (TEXTINLINE
, TEXTRUN
, XL_NS_SS
, "t", GSF_XML_CONTENT
, NULL
, &xlsx_cell_inline_text_end
),
3448 GSF_XML_IN_NODE (TEXTINLINE
, RICH
, XL_NS_SS
, "r", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3450 GSF_XML_IN_NODE (CELL
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd */
3452 GSF_XML_IN_NODE (SHEET
, CALC_PR
, XL_NS_SS
, "sheetCalcPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3453 GSF_XML_IN_NODE (SHEET
, CT_SortState
, XL_NS_SS
, "sortState", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3454 GSF_XML_IN_NODE (CT_SortState
, CT_SortCondition
, XL_NS_SS
, "sortCondition", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3455 GSF_XML_IN_NODE (SHEET
, SCENARIOS
, XL_NS_SS
, "scenarios", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3456 GSF_XML_IN_NODE (SCENARIOS
, INPUT_CELLS
, XL_NS_SS
, "inputCells", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3457 GSF_XML_IN_NODE (SHEET
, PROTECTED_RANGES
, XL_NS_SS
, "protectedRanges", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3458 GSF_XML_IN_NODE (PROTECTED_RANGES
, PROTECTED_RANGE
, XL_NS_SS
, "protectedRange", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3460 GSF_XML_IN_NODE (SHEET
, CT_AutoFilter
, XL_NS_SS
, "autoFilter", GSF_XML_NO_CONTENT
,
3461 &xlsx_CT_AutoFilter_begin
, &xlsx_CT_AutoFilter_end
),
3462 GSF_XML_IN_NODE (CT_AutoFilter
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
3463 GSF_XML_IN_NODE (CT_AutoFilter
, CT_SortState
, XL_NS_SS
, "sortState", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
3464 GSF_XML_IN_NODE (CT_AutoFilter
, CT_FilterColumn
, XL_NS_SS
, "filterColumn", GSF_XML_NO_CONTENT
,
3465 &xlsx_CT_FilterColumn_begin
, NULL
),
3466 GSF_XML_IN_NODE (CT_FilterColumn
, CT_Filters
, XL_NS_SS
, "filters", GSF_XML_NO_CONTENT
,
3467 &xlsx_CT_Filters_begin
, &xlsx_CT_Filters_end
),
3468 GSF_XML_IN_NODE (CT_Filters
, CT_Filter
, XL_NS_SS
, "filter", GSF_XML_NO_CONTENT
, &xlsx_CT_Filter
, NULL
),
3469 GSF_XML_IN_NODE (CT_FilterColumn
, CT_CustomFilters
, XL_NS_SS
, "customFilters", GSF_XML_NO_CONTENT
,
3470 &xlsx_CT_CustomFilters_begin
, &xlsx_CT_CustomFilters_end
),
3471 GSF_XML_IN_NODE (CT_CustomFilters
, CT_CustomFilter
, XL_NS_SS
, "customFilter", GSF_XML_NO_CONTENT
, &xlsx_CT_CustomFilter
, NULL
),
3472 GSF_XML_IN_NODE (CT_FilterColumn
, CT_Top10
, XL_NS_SS
, "top10", GSF_XML_NO_CONTENT
, &xlsx_CT_Top10
, NULL
),
3473 GSF_XML_IN_NODE (CT_FilterColumn
, CT_DynamicFilter
, XL_NS_SS
, "dynamicFilter", GSF_XML_NO_CONTENT
, &xlsx_CT_DynamicFilter
, NULL
),
3474 GSF_XML_IN_NODE (CT_FilterColumn
, CT_ColorFilter
, XL_NS_SS
, "colorFilter", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3475 GSF_XML_IN_NODE (CT_FilterColumn
, CT_IconFilter
, XL_NS_SS
, "iconFilter", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3477 GSF_XML_IN_NODE (SHEET
, CT_DataValidations
, XL_NS_SS
, "dataValidations", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3478 GSF_XML_IN_NODE (CT_DataValidations
, CT_DataValidation
, XL_NS_SS
, "dataValidation", GSF_XML_NO_CONTENT
,
3479 &xlsx_CT_DataValidation_begin
, &xlsx_CT_DataValidation_end
),
3480 GSF_XML_IN_NODE_FULL (CT_DataValidation
, VAL_FORMULA1
, XL_NS_SS
, "formula1", GSF_XML_CONTENT
, FALSE
, FALSE
, NULL
, &xlsx_validation_expr
, 0),
3481 GSF_XML_IN_NODE_FULL (CT_DataValidation
, VAL_FORMULA2
, XL_NS_SS
, "formula2", GSF_XML_CONTENT
, FALSE
, FALSE
, NULL
, &xlsx_validation_expr
, 1),
3483 GSF_XML_IN_NODE (SHEET
, MERGES
, XL_NS_SS
, "mergeCells", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3484 GSF_XML_IN_NODE (MERGES
, MERGE
, XL_NS_SS
, "mergeCell", GSF_XML_NO_CONTENT
, &xlsx_CT_MergeCell
, NULL
),
3486 GSF_XML_IN_NODE (SHEET
, DRAWING
, XL_NS_SS
, "drawing", GSF_XML_NO_CONTENT
, &xlsx_sheet_drawing
, NULL
),
3488 GSF_XML_IN_NODE (SHEET
, PROTECTION
, XL_NS_SS
, "sheetProtection", GSF_XML_NO_CONTENT
, &xlsx_CT_SheetProtection
, NULL
),
3489 GSF_XML_IN_NODE (SHEET
, PHONETIC
, XL_NS_SS
, "phoneticPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3490 GSF_XML_IN_NODE (SHEET
, COND_FMTS
, XL_NS_SS
, "conditionalFormatting", GSF_XML_NO_CONTENT
,
3491 &xlsx_cond_fmt_begin
, &xlsx_cond_fmt_end
),
3492 GSF_XML_IN_NODE (COND_FMTS
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
3493 GSF_XML_IN_NODE (COND_FMTS
, COND_RULE
, XL_NS_SS
, "cfRule", GSF_XML_NO_CONTENT
,
3494 &xlsx_cond_fmt_rule_begin
, &xlsx_cond_fmt_rule_end
),
3495 GSF_XML_IN_NODE (COND_RULE
, COND_FMLA
, XL_NS_SS
, "formula", GSF_XML_CONTENT
, NULL
, &xlsx_cond_fmt_formula_end
),
3496 GSF_XML_IN_NODE (COND_RULE
, COND_COLOR_SCALE
, XL_NS_SS
, "colorScale", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3497 GSF_XML_IN_NODE (COND_COLOR_SCALE
, CFVO
, XL_NS_SS
, "cfvo", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3498 GSF_XML_IN_NODE (COND_COLOR_SCALE
, COND_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3499 GSF_XML_IN_NODE (COND_RULE
, COND_DATA_BAR
, XL_NS_SS
, "dataBar", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3500 GSF_XML_IN_NODE (COND_RULE
, COND_ICON_SET
, XL_NS_SS
, "iconSet", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3501 GSF_XML_IN_NODE (COND_ICON_SET
, CFVO
, XL_NS_SS
, "cfvo", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
3503 GSF_XML_IN_NODE (SHEET
, HYPERLINKS
, XL_NS_SS
, "hyperlinks", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3504 GSF_XML_IN_NODE (HYPERLINKS
, HYPERLINK
, XL_NS_SS
, "hyperlink", GSF_XML_NO_CONTENT
, &xlsx_CT_HyperLinks
, NULL
),
3506 GSF_XML_IN_NODE (SHEET
, PRINT_OPTS
, XL_NS_SS
, "printOptions", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3507 GSF_XML_IN_NODE (SHEET
, PRINT_MARGINS
, XL_NS_SS
, "pageMargins", GSF_XML_NO_CONTENT
, &xlsx_CT_PageMargins
, NULL
),
3508 GSF_XML_IN_NODE (SHEET
, PRINT_SETUP
, XL_NS_SS
, "pageSetup", GSF_XML_NO_CONTENT
, &xlsx_CT_PageSetup
, NULL
),
3509 GSF_XML_IN_NODE (SHEET
, PRINT_HEADER_FOOTER
, XL_NS_SS
, "headerFooter", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3510 GSF_XML_IN_NODE (PRINT_HEADER_FOOTER
, ODD_HEADER
, XL_NS_SS
, "oddHeader", GSF_XML_CONTENT
, NULL
, &xlsx_CT_oddheader_end
),
3511 GSF_XML_IN_NODE (PRINT_HEADER_FOOTER
, ODD_FOOTER
, XL_NS_SS
, "oddFooter", GSF_XML_CONTENT
, NULL
, &xlsx_CT_oddfooter_end
),
3513 GSF_XML_IN_NODE_FULL (SHEET
, ROW_BREAKS
, XL_NS_SS
, "rowBreaks", GSF_XML_NO_CONTENT
,
3514 FALSE
, FALSE
, &xlsx_CT_PageBreaks_begin
, &xlsx_CT_PageBreaks_end
, 1),
3515 GSF_XML_IN_NODE (ROW_BREAKS
, CT_PageBreak
, XL_NS_SS
, "brk", GSF_XML_NO_CONTENT
, &xlsx_CT_PageBreak
, NULL
),
3516 GSF_XML_IN_NODE_FULL (SHEET
, COL_BREAKS
, XL_NS_SS
, "colBreaks", GSF_XML_NO_CONTENT
,
3517 FALSE
, FALSE
, &xlsx_CT_PageBreaks_begin
, &xlsx_CT_PageBreaks_end
, 0),
3518 GSF_XML_IN_NODE (COL_BREAKS
, CT_PageBreak
, XL_NS_SS
, "brk", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
3520 GSF_XML_IN_NODE (SHEET
, LEGACY_DRAW
, XL_NS_SS
, "legacyDrawing", GSF_XML_NO_CONTENT
, &xlsx_sheet_legacy_drawing
, NULL
),
3521 GSF_XML_IN_NODE (SHEET
, OLE_OBJECTS
, XL_NS_SS
, "oleObjects", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3522 GSF_XML_IN_NODE (OLE_OBJECTS
, OLE_OBJECT
, XL_NS_SS
, "oleObject", GSF_XML_NO_CONTENT
, &xlsx_ole_object
, NULL
),
3527 /****************************************************************************/
3530 xlsx_CT_PivotCache (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3532 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3533 xmlChar
const *id
= NULL
;
3534 xmlChar
const *cacheId
= NULL
;
3536 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3537 if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_DOC_REL
, "id"))
3539 else if (0 == strcmp (attrs
[0], "cacheId"))
3542 if (NULL
!= id
&& NULL
!= cacheId
) {
3543 g_return_if_fail (NULL
== state
->pivot
.cache
);
3545 xlsx_parse_rel_by_id (xin
, id
,
3546 xlsx_pivot_cache_def_dtd
, xlsx_ns
);
3548 g_return_if_fail (NULL
!= state
->pivot
.cache
);
3550 /* absorb the reference to the cache */
3551 g_hash_table_replace (state
->pivot
.cache_by_id
,
3552 g_strdup (cacheId
), state
->pivot
.cache
);
3553 state
->pivot
.cache
= NULL
;
3558 xlsx_CT_WorkbookPr (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3560 static EnumVal
const switchModes
[] = {
3570 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3572 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3573 if (attr_enum (xin
, attrs
, "date1904", switchModes
, &tmp
))
3574 workbook_set_1904 (state
->wb
, tmp
);
3578 xlsx_CT_CalcPr (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3580 static EnumVal
const calcModes
[] = {
3581 { "manual", FALSE
},
3583 { "autoNoTable", TRUE
},
3586 static EnumVal
const refModes
[] = {
3593 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3595 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3596 if (attr_enum (xin
, attrs
, "calcMode", calcModes
, &tmp
))
3597 workbook_set_recalcmode (state
->wb
, tmp
);
3598 else if (attr_bool (xin
, attrs
, "fullCalcOnLoad", &tmp
))
3600 else if (attr_enum (xin
, attrs
, "refMode", refModes
, &tmp
))
3602 else if (attr_bool (xin
, attrs
, "iterate", &tmp
))
3603 workbook_iteration_enabled (state
->wb
, tmp
);
3604 else if (attr_int (xin
, attrs
, "iterateCount", &tmp
))
3605 workbook_iteration_max_number (state
->wb
, tmp
);
3606 else if (attr_float (xin
, attrs
, "iterateDelta", &delta
))
3607 workbook_iteration_tolerance (state
->wb
, delta
);
3608 else if (attr_bool (xin
, attrs
, "fullPrecision", &tmp
))
3610 else if (attr_bool (xin
, attrs
, "calcCompleted", &tmp
))
3612 else if (attr_bool (xin
, attrs
, "calcOnSave", &tmp
))
3614 else if (attr_bool (xin
, attrs
, "conncurrentCalc", &tmp
))
3616 else if (attr_bool (xin
, attrs
, "forceFullCalc", &tmp
))
3618 else if (attr_int (xin
, attrs
, "concurrentManualCalc", &tmp
))
3623 xlsx_CT_workbookView (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3625 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3626 int active_tab
= -1;
3627 int width
= -1, height
= -1;
3628 const int scale
= 10; /* Guess */
3630 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3631 if (attr_int (xin
, attrs
, "activeTab", &active_tab
))
3633 else if (attr_int (xin
, attrs
, "windowHeight", &height
))
3635 else if (attr_int (xin
, attrs
, "windowWidth", &width
))
3639 if (width
> scale
/ 2 && height
> scale
/ 2)
3640 wb_view_preferred_size (state
->wb_view
,
3641 (width
+ scale
/ 2) / scale
,
3642 (height
+ scale
/ 2) / scale
);
3646 xlsx_sheet_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3648 static EnumVal
const visibilities
[] = {
3649 { "visible", GNM_SHEET_VISIBILITY_VISIBLE
},
3650 { "hidden", GNM_SHEET_VISIBILITY_HIDDEN
},
3651 { "veryHidden", GNM_SHEET_VISIBILITY_VERY_HIDDEN
},
3654 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3655 char const *name
= NULL
;
3656 char const *part_id
= NULL
;
3658 int viz
= (int)GNM_SHEET_VISIBILITY_VISIBLE
;
3660 maybe_update_progress (xin
);
3662 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3663 if (0 == strcmp (attrs
[0], "name"))
3665 else if (attr_enum (xin
, attrs
, "state", visibilities
, &viz
))
3667 else if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_DOC_REL
, "id"))
3671 xlsx_warning (xin
, _("Ignoring a sheet without a name"));
3675 sheet
= workbook_sheet_by_name (state
->wb
, name
);
3676 if (NULL
== sheet
) {
3677 sheet
= sheet_new (state
->wb
, name
, XLSX_MaxCol
, XLSX_MaxRow
);
3678 workbook_sheet_attach (state
->wb
, sheet
);
3680 g_object_set (sheet
, "visibility", viz
, NULL
);
3682 g_object_set_data_full (G_OBJECT (sheet
), "_XLSX_RelID", g_strdup (part_id
),
3683 (GDestroyNotify
) g_free
);
3687 xlsx_wb_name_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3689 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3690 const char *name
= NULL
;
3693 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3694 if (0 == strcmp (attrs
[0], "name"))
3696 else if (attr_int (xin
, attrs
, "localSheetId", &sheet_idx
))
3700 state
->defined_name
= g_strdup (name
);
3701 state
->defined_name_sheet
=
3703 ? workbook_sheet_by_index (state
->wb
, sheet_idx
)
3708 xlsx_wb_name_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3710 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3712 Sheet
*sheet
= state
->defined_name_sheet
;
3713 GnmNamedExpr
*nexpr
;
3714 char *error_msg
= NULL
;
3716 g_return_if_fail (state
->defined_name
!= NULL
);
3718 parse_pos_init (&pp
, state
->wb
, sheet
, 0, 0);
3720 if (g_str_has_prefix (state
->defined_name
, "_xlnm.")) {
3721 gboolean editable
= (0 == strcmp (state
->defined_name
+ 6, "Sheet_Title"));
3722 nexpr
= expr_name_add (&pp
, state
->defined_name
+ 6,
3723 gnm_expr_top_new_constant (value_new_empty ()),
3724 &error_msg
, TRUE
, NULL
);
3725 nexpr
->is_permanent
= TRUE
;
3726 nexpr
->is_editable
= editable
;
3728 nexpr
= expr_name_add (&pp
, state
->defined_name
,
3729 gnm_expr_top_new_constant (value_new_empty ()),
3730 &error_msg
, TRUE
, NULL
);
3733 state
->delayed_names
=
3734 g_list_prepend (state
->delayed_names
, sheet
);
3735 state
->delayed_names
=
3736 g_list_prepend (state
->delayed_names
,
3737 g_strdup (xin
->content
->str
));
3738 state
->delayed_names
=
3739 g_list_prepend (state
->delayed_names
, nexpr
);
3741 xlsx_warning (xin
, _("Failed to define name: %s"), error_msg
);
3745 g_free (state
->defined_name
);
3746 state
->defined_name
= NULL
;
3750 handle_delayed_names (GsfXMLIn
*xin
)
3752 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3755 for (l
= state
->delayed_names
; l
; l
= l
->next
->next
->next
) {
3756 GnmNamedExpr
*nexpr
= l
->data
;
3757 char *expr_str
= l
->next
->data
;
3758 Sheet
*sheet
= l
->next
->next
->data
;
3759 GnmExprTop
const *texpr
;
3762 parse_pos_init (&pp
, state
->wb
, sheet
, 0, 0);
3764 texpr
= gnm_expr_top_new_constant (value_new_error_REF (NULL
));
3766 texpr
= xlsx_parse_expr (xin
, expr_str
, &pp
);
3768 expr_name_set_expr (nexpr
, texpr
);
3773 g_list_free (state
->delayed_names
);
3774 state
->delayed_names
= NULL
;
3778 xlsx_wb_names_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3780 handle_delayed_names (xin
);
3784 /**************************************************************************************************/
3787 xlsx_read_external_book (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3789 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3790 GsfOpenPkgRel
const *rel
= gsf_open_pkg_lookup_rel_by_type
3791 (gsf_xml_in_get_input (xin
),
3792 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/"
3795 rel
= gsf_open_pkg_lookup_rel_by_type
3796 (gsf_xml_in_get_input (xin
),
3797 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/"
3798 "externalLinkPath");
3799 if (NULL
!= rel
&& gsf_open_pkg_rel_is_extern (rel
))
3800 state
->external_ref
= xlsx_conventions_add_extern_ref (
3801 state
->convs
, gsf_open_pkg_rel_get_target (rel
));
3803 xlsx_warning (xin
, _("Unable to resolve external relationship"));
3806 xlsx_read_external_book_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3808 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3809 state
->external_ref
= NULL
;
3812 xlsx_read_external_sheetname (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3814 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3815 if (state
->external_ref
)
3816 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3817 if (0 == strcmp (attrs
[0], "val"))
3818 workbook_sheet_attach
3819 (state
->external_ref
,
3820 state
->external_ref_sheet
=
3821 sheet_new (state
->external_ref
, attrs
[1], 256, 65536));
3824 xlsx_read_external_sheetname_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3826 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3827 state
->external_ref_sheet
= NULL
;
3830 static GsfXMLInNode
const xlsx_extern_dtd
[] = {
3831 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
3832 GSF_XML_IN_NODE_FULL (START
, LINK
, XL_NS_SS
, "externalLink", GSF_XML_NO_CONTENT
, TRUE
, TRUE
, xlsx_read_external_book
, xlsx_read_external_book_end
, 0),
3833 GSF_XML_IN_NODE (LINK
, BOOK
, XL_NS_SS
, "externalBook", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3834 GSF_XML_IN_NODE (BOOK
, SHEET_NAMES
, XL_NS_SS
, "sheetNames", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3835 GSF_XML_IN_NODE (SHEET_NAMES
, SHEET_NAME
, XL_NS_SS
, "sheetName", GSF_XML_NO_CONTENT
, xlsx_read_external_sheetname
, xlsx_read_external_sheetname_end
),
3836 GSF_XML_IN_NODE (BOOK
, SHEET_DATASET
, XL_NS_SS
, "sheetDataSet", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3837 GSF_XML_IN_NODE (SHEET_DATASET
, SHEET_DATA
, XL_NS_SS
, "sheetData", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3838 GSF_XML_IN_NODE (SHEET_DATA
, ROW
, XL_NS_SS
, "row", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3839 GSF_XML_IN_NODE (ROW
, CELL
, XL_NS_SS
, "cell", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3840 GSF_XML_IN_NODE (CELL
, VAL
, XL_NS_SS
, "v", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3846 xlsx_wb_external_ref (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3848 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3849 if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_DOC_REL
, "id"))
3850 xlsx_parse_rel_by_id (xin
, attrs
[1], xlsx_extern_dtd
, xlsx_ns
);
3853 /**************************************************************************************************/
3856 xlsx_comments_start (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3858 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3859 state
->authors
= g_ptr_array_new_with_free_func ((GDestroyNotify
) g_free
);
3863 xlsx_comments_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3865 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3866 g_ptr_array_unref (state
->authors
);
3867 state
->authors
= NULL
;
3871 xlsx_comment_author_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3873 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3874 int i
= strlen (xin
->content
->str
);
3875 char *name
= xin
->content
->str
;
3876 /* remove any trailing white space */
3877 /* not sure this is correct, we might be careful about encoding */
3878 while (i
> 0 && g_ascii_isspace (name
[i
-1]))
3880 name
= g_new (char, i
+ 1);
3881 memcpy (name
, xin
->content
->str
, i
);
3883 g_ptr_array_add (state
->authors
, name
);
3887 xlsx_comment_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3889 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3893 state
->comment
= g_object_new (cell_comment_get_type (), NULL
);
3894 so
= GNM_SO (state
->comment
);
3895 anchor_r
= sheet_object_get_anchor (so
)->cell_bound
;
3897 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3898 if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_SS
, "ref"))
3899 range_parse (&anchor_r
, attrs
[1], gnm_sheet_get_size (state
->sheet
));
3900 else if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_SS
, "authorId")) {
3901 unsigned id
= atoi (attrs
[1]);
3903 if (id
< state
->authors
->len
) {
3904 name
= g_ptr_array_index (state
->authors
, id
);
3905 if (*name
) /* do not set an empty name */
3906 g_object_set (state
->comment
, "author", name
, NULL
);
3910 cell_comment_set_pos (GNM_CELL_COMMENT (so
), &anchor_r
.start
);
3911 state
->r_text
= g_string_new ("");
3915 xlsx_comment_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3917 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3918 char *text
= g_string_free (state
->r_text
, FALSE
);
3919 state
->r_text
= NULL
;
3920 g_object_set (state
->comment
, "text", text
, NULL
);
3922 if (state
->rich_attrs
) {
3923 g_object_set (state
->comment
, "markup", state
->rich_attrs
, NULL
);
3924 pango_attr_list_unref (state
->rich_attrs
);
3925 state
->rich_attrs
= NULL
;
3927 sheet_object_set_sheet (GNM_SO (state
->comment
), state
->sheet
);
3928 g_object_unref (state
->comment
);
3929 state
->comment
= NULL
;
3931 maybe_update_progress (xin
);
3935 xlsx_r_text (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3937 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3938 g_string_append (state
->r_text
, xin
->content
->str
);
3941 static GsfXMLInNode
const xlsx_comments_dtd
[] = {
3942 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
3943 GSF_XML_IN_NODE_FULL (START
, COMMENTS
, XL_NS_SS
, "comments", GSF_XML_NO_CONTENT
, TRUE
, TRUE
, xlsx_comments_start
, xlsx_comments_end
, 0),
3944 GSF_XML_IN_NODE (COMMENTS
, AUTHORS
, XL_NS_SS
, "authors", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3945 GSF_XML_IN_NODE (AUTHORS
, AUTHOR
, XL_NS_SS
, "author", GSF_XML_CONTENT
, NULL
, xlsx_comment_author_end
),
3946 GSF_XML_IN_NODE (COMMENTS
, COMMENTLIST
, XL_NS_SS
, "commentList", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3947 GSF_XML_IN_NODE (COMMENTLIST
, COMMENT
, XL_NS_SS
, "comment", GSF_XML_NO_CONTENT
, xlsx_comment_start
, xlsx_comment_end
),
3948 GSF_XML_IN_NODE (COMMENT
, TEXTITEM
, XL_NS_SS
, "text", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3949 GSF_XML_IN_NODE (TEXTITEM
, TEXT
, XL_NS_SS
, "t", GSF_XML_CONTENT
, NULL
, xlsx_r_text
),
3950 GSF_XML_IN_NODE (TEXTITEM
, RICH
, XL_NS_SS
, "r", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3952 GSF_XML_IN_NODE (TEXTITEM
, ITEM_PHONETIC_RUN
, XL_NS_SS
, "rPh", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3953 GSF_XML_IN_NODE (ITEM_PHONETIC_RUN
, PHONETIC_TEXT
, XL_NS_SS
, "t", GSF_XML_CONTENT
, NULL
, NULL
),
3954 GSF_XML_IN_NODE (TEXTITEM
, ITEM_PHONETIC
, XL_NS_SS
, "phoneticPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3959 /**************************************************************************************************/
3962 cb_by_zorder (gconstpointer a
, gconstpointer b
, gpointer data
)
3964 GHashTable
*zorder
= data
;
3965 int za
= GPOINTER_TO_UINT (g_hash_table_lookup (zorder
, a
));
3966 int zb
= GPOINTER_TO_UINT (g_hash_table_lookup (zorder
, b
));
3967 return zb
- za
; /* descending */
3972 xlsx_wb_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3974 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3975 int i
, n
= workbook_sheet_count (state
->wb
);
3976 char const *part_id
;
3978 GsfInput
*sin
, *cin
;
3981 end_update_progress (state
);
3983 /* Load sheets after setting up the workbooks to give us time to create
3984 * all of them and parse names */
3985 for (i
= 0 ; i
< n
; i
++, state
->sheet
= NULL
) {
3990 if (NULL
== (state
->sheet
= workbook_sheet_by_index (state
->wb
, i
)))
3992 if (NULL
== (part_id
= g_object_get_data (G_OBJECT (state
->sheet
), "_XLSX_RelID"))) {
3993 xlsx_warning (xin
, _("Missing part-id for sheet '%s'"),
3994 state
->sheet
->name_unquoted
);
3998 /* Apply the 'Normal' style (aka builtin 0) to the entire sheet */
3999 if (NULL
!= (style
= g_hash_table_lookup(state
->cell_styles
, "0"))) {
4001 gnm_style_ref (style
);
4002 range_init_full_sheet (&r
, state
->sheet
);
4003 sheet_style_set_range (state
->sheet
, &r
, style
);
4006 sin
= gsf_open_pkg_open_rel_by_id (gsf_xml_in_get_input (xin
), part_id
, &err
);
4008 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4009 go_io_warning (state
->context
, "%s", err
->message
);
4016 cin
= gsf_open_pkg_open_rel_by_type (sin
,
4017 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments", NULL
);
4018 message
= g_strdup_printf (_("Reading sheet '%s'..."), state
->sheet
->name_unquoted
);
4019 start_update_progress (state
, sin
, message
,
4020 0.3 + i
*0.6/n
, 0.3 + i
*0.6/n
+ 0.5/n
);
4022 xlsx_parse_stream (state
, sin
, xlsx_sheet_dtd
);
4023 end_update_progress (state
);
4026 start_update_progress (state
, cin
, _("Reading comments..."),
4027 0.3 + i
*0.6/n
+ 0.5/n
, 0.3 + i
*0.6/n
+ 0.6/n
);
4028 xlsx_parse_stream (state
, cin
, xlsx_comments_dtd
);
4029 end_update_progress (state
);
4032 zoffset
= (g_slist_length (state
->pending_objects
) -
4033 g_hash_table_size (state
->zorder
));
4034 for (j
= zoffset
, l
= state
->pending_objects
; l
; l
= l
->next
) {
4035 SheetObject
*so
= l
->data
;
4036 int z
= GPOINTER_TO_UINT (g_hash_table_lookup (state
->zorder
, so
));
4041 g_hash_table_insert (state
->zorder
, so
, GINT_TO_POINTER (z
));
4043 state
->pending_objects
= g_slist_sort_with_data
4044 (state
->pending_objects
, cb_by_zorder
, state
->zorder
);
4046 while (state
->pending_objects
) {
4047 SheetObject
*obj
= state
->pending_objects
->data
;
4048 state
->pending_objects
= g_slist_delete_link (state
->pending_objects
,
4049 state
->pending_objects
);
4050 sheet_object_set_sheet (obj
, state
->sheet
);
4051 g_object_unref (obj
);
4054 /* Flag a respan here in case nothing else does */
4055 sheet_flag_recompute_spans (state
->sheet
);
4060 xlsx_webpub_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4062 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4063 if (strcmp (attrs
[0], "characterSet") == 0) {
4064 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4065 state
->version
= ECMA_376_2008
;
4069 static GsfXMLInNode
const xlsx_workbook_dtd
[] = {
4070 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4071 GSF_XML_IN_NODE_FULL (START
, WORKBOOK
, XL_NS_SS
, "workbook", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, &xlsx_wb_end
, 0),
4072 GSF_XML_IN_NODE (WORKBOOK
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4073 GSF_XML_IN_NODE (EXTLST
, EXTITEM
, XL_NS_SS
, "ext", GSF_XML_NO_CONTENT
, &xlsx_ext_begin
, &xlsx_ext_end
),
4074 GSF_XML_IN_NODE (WORKBOOK
, VERSION
, XL_NS_SS
, "fileVersion", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4075 GSF_XML_IN_NODE (WORKBOOK
, PROPERTIES
, XL_NS_SS
, "workbookPr", GSF_XML_NO_CONTENT
, &xlsx_CT_WorkbookPr
, NULL
),
4076 GSF_XML_IN_NODE (WORKBOOK
, CALC_PROPS
, XL_NS_SS
, "calcPr", GSF_XML_NO_CONTENT
, &xlsx_CT_CalcPr
, NULL
),
4078 GSF_XML_IN_NODE (WORKBOOK
, VIEWS
, XL_NS_SS
, "bookViews", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4079 GSF_XML_IN_NODE (VIEWS
, VIEW
, XL_NS_SS
, "workbookView", GSF_XML_NO_CONTENT
, &xlsx_CT_workbookView
, NULL
),
4080 GSF_XML_IN_NODE (WORKBOOK
, CUSTOMWVIEWS
, XL_NS_SS
, "customWorkbookViews", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4081 GSF_XML_IN_NODE (CUSTOMWVIEWS
, CUSTOMWVIEW
, XL_NS_SS
, "customWorkbookView", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4082 GSF_XML_IN_NODE (CUSTOMWVIEW
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd */
4083 GSF_XML_IN_NODE (WORKBOOK
, SHEETS
, XL_NS_SS
, "sheets", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4084 GSF_XML_IN_NODE (SHEETS
, SHEET
, XL_NS_SS
, "sheet", GSF_XML_NO_CONTENT
, &xlsx_sheet_begin
, NULL
),
4085 GSF_XML_IN_NODE (WORKBOOK
, FGROUPS
, XL_NS_SS
, "functionGroups", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4086 GSF_XML_IN_NODE (FGROUPS
, FGROUP
, XL_NS_SS
, "functionGroup", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4087 GSF_XML_IN_NODE (WORKBOOK
, WEB_PUB
, XL_NS_SS
, "webPublishing", GSF_XML_NO_CONTENT
, xlsx_webpub_begin
, NULL
),
4088 GSF_XML_IN_NODE (WORKBOOK
, EXTERNS
, XL_NS_SS
, "externalReferences", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4089 GSF_XML_IN_NODE (EXTERNS
, EXTERN
, XL_NS_SS
, "externalReference", GSF_XML_NO_CONTENT
, xlsx_wb_external_ref
, NULL
),
4090 GSF_XML_IN_NODE (WORKBOOK
, NAMES
, XL_NS_SS
, "definedNames", GSF_XML_NO_CONTENT
, NULL
, xlsx_wb_names_end
),
4091 GSF_XML_IN_NODE (NAMES
, NAME
, XL_NS_SS
, "definedName", GSF_XML_CONTENT
, xlsx_wb_name_begin
, xlsx_wb_name_end
),
4092 GSF_XML_IN_NODE (WORKBOOK
, PIVOTCACHES
, XL_NS_SS
, "pivotCaches", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4093 GSF_XML_IN_NODE (PIVOTCACHES
, PIVOTCACHE
, XL_NS_SS
, "pivotCache", GSF_XML_NO_CONTENT
, &xlsx_CT_PivotCache
, NULL
),
4095 GSF_XML_IN_NODE (WORKBOOK
, RECOVERY
, XL_NS_SS
, "fileRecoveryPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4096 GSF_XML_IN_NODE (WORKBOOK
, OLESIZE
, XL_NS_SS
, "oleSize", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4097 GSF_XML_IN_NODE (WORKBOOK
, SMARTTAGPR
, XL_NS_SS
, "smartTagPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4098 GSF_XML_IN_NODE (WORKBOOK
, SMARTTTYPES
, XL_NS_SS
, "smartTagTypes", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4099 GSF_XML_IN_NODE (SMARTTTYPES
, SMARTTTYPE
, XL_NS_SS
, "smartTagType", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4100 GSF_XML_IN_NODE (WORKBOOK
, WEB_PUB_OBJS
, XL_NS_SS
, "webPublishObjects", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4101 GSF_XML_IN_NODE (WEB_PUB_OBJS
, WEB_PUB_OBJ
, XL_NS_SS
, "webPublishObject", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4106 /****************************************************************************/
4109 xlsx_sst_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4111 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4114 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4115 if (attr_int (xin
, attrs
, "uniqueCount", &count
))
4116 g_array_set_size (state
->sst
, count
);
4121 xlsx_sstitem_start (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4123 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4124 state
->r_text
= g_string_new ("");
4128 xlsx_sstitem_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4130 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4132 char *text
= g_string_free (state
->r_text
, FALSE
);
4133 state
->r_text
= NULL
;
4135 if (state
->count
>= state
->sst
->len
)
4136 g_array_set_size (state
->sst
, state
->count
+1);
4137 entry
= &g_array_index (state
->sst
, XLSXStr
, state
->count
);
4139 entry
->str
= go_string_new_nocopy (text
);
4141 if (state
->rich_attrs
) {
4142 entry
->markup
= go_format_new_markup (state
->rich_attrs
, FALSE
);
4143 state
->rich_attrs
= NULL
;
4147 static GsfXMLInNode
const xlsx_shared_strings_dtd
[] = {
4148 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4149 GSF_XML_IN_NODE_FULL (START
, SST
, XL_NS_SS
, "sst", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, &xlsx_sst_begin
, NULL
, 0),
4150 GSF_XML_IN_NODE (SST
, ITEM
, XL_NS_SS
, "si", GSF_XML_NO_CONTENT
, &xlsx_sstitem_start
, &xlsx_sstitem_end
), /* beta2 */
4151 GSF_XML_IN_NODE (ITEM
, TEXT
, XL_NS_SS
, "t", GSF_XML_CONTENT
, NULL
, xlsx_r_text
),
4152 GSF_XML_IN_NODE (ITEM
, RICH
, XL_NS_SS
, "r", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4154 GSF_XML_IN_NODE (ITEM
, ITEM_PHONETIC_RUN
, XL_NS_SS
, "rPh", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4155 GSF_XML_IN_NODE (ITEM_PHONETIC_RUN
, PHONETIC_TEXT
, XL_NS_SS
, "t", GSF_XML_SHARED_CONTENT
, NULL
, NULL
),
4156 GSF_XML_IN_NODE (ITEM
, ITEM_PHONETIC
, XL_NS_SS
, "phoneticPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4161 /****************************************************************************/
4164 xlsx_numfmt_common (GsfXMLIn
*xin
, xmlChar
const **attrs
, gboolean apply
)
4166 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4167 xmlChar
const *fmt
= NULL
;
4168 xmlChar
const *id
= NULL
;
4170 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4171 if (0 == strcmp (attrs
[0], "numFmtId"))
4173 else if (0 == strcmp (attrs
[0], "formatCode"))
4176 if (NULL
!= id
&& NULL
!= fmt
) {
4177 GOFormat
*gfmt
= go_format_new_from_XL (fmt
);
4179 gnm_style_set_format (state
->style_accum
, gfmt
);
4180 g_hash_table_replace (state
->num_fmts
, g_strdup (id
), gfmt
);
4185 xlsx_style_numfmt (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4187 xlsx_numfmt_common (xin
, attrs
, FALSE
);
4193 XLSX_COLLECT_BORDERS
,
4195 XLSX_COLLECT_STYLE_XFS
,
4197 XLSX_COLLECT_TABLE_STYLES
4201 xlsx_collection_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4203 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4206 g_return_if_fail (NULL
== state
->collection
);
4209 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4210 if (attr_int (xin
, attrs
, "count", &count
))
4212 state
->collection
= g_ptr_array_new ();
4213 g_ptr_array_set_size (state
->collection
, count
);
4215 switch (xin
->node
->user_data
.v_int
) {
4216 case XLSX_COLLECT_FONT
: state
->fonts
= state
->collection
; break;
4217 case XLSX_COLLECT_FILLS
: state
->fills
= state
->collection
; break;
4218 case XLSX_COLLECT_BORDERS
: state
->borders
= state
->collection
; break;
4219 case XLSX_COLLECT_XFS
: state
->xfs
= state
->collection
; break;
4220 case XLSX_COLLECT_STYLE_XFS
: state
->style_xfs
= state
->collection
; break;
4221 case XLSX_COLLECT_DXFS
: state
->dxfs
= state
->collection
; break;
4222 case XLSX_COLLECT_TABLE_STYLES
: state
->table_styles
= state
->collection
; break;
4227 xlsx_collection_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4229 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4231 /* resize just in case the count hint was wrong */
4232 g_ptr_array_set_size (state
->collection
, state
->count
);
4234 state
->collection
= NULL
;
4238 xlsx_col_elem_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4240 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4242 if (!state
->style_accum_partial
) {
4243 GnmStyle
*res
= state
->style_accum
;
4244 state
->style_accum
= NULL
;
4245 if (state
->count
>= state
->collection
->len
)
4246 g_ptr_array_add (state
->collection
, res
);
4247 else if (NULL
!= g_ptr_array_index (state
->collection
, state
->count
)) {
4248 g_warning ("dup @ %d = %p", state
->count
, res
);
4249 gnm_style_unref (res
);
4251 g_ptr_array_index (state
->collection
, state
->count
) = res
;
4257 xlsx_col_elem_begin (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4259 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4260 if (!state
->style_accum_partial
) {
4261 g_return_if_fail (NULL
== state
->style_accum
);
4262 state
->style_accum
= gnm_style_new ();
4267 xlsx_col_border_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4269 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4270 gboolean diagonal_down
= FALSE
, diagonal_up
= FALSE
;
4272 xlsx_col_elem_begin (xin
, attrs
);
4273 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4274 if (attr_bool (xin
, attrs
, "diagonalDown", &diagonal_down
)) ;
4275 else (attr_bool (xin
, attrs
, "diagonalUp", &diagonal_up
)) ;
4278 GnmBorder
*border
= gnm_style_border_fetch
4279 (GNM_STYLE_BORDER_THIN
, style_color_black (), GNM_STYLE_BORDER_DIAGONAL
);
4280 gnm_style_set_border (state
->style_accum
,
4281 MSTYLE_BORDER_DIAGONAL
,
4284 if (diagonal_down
) {
4285 GnmBorder
*border
= gnm_style_border_fetch
4286 (GNM_STYLE_BORDER_HAIR
, style_color_black (), GNM_STYLE_BORDER_DIAGONAL
);
4287 gnm_style_set_border (state
->style_accum
,
4288 MSTYLE_BORDER_REV_DIAGONAL
,
4294 xlsx_font_name (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4296 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4298 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4299 if (0 == strcmp (attrs
[0], "val"))
4300 gnm_style_set_font_name (state
->style_accum
, attrs
[1]);
4303 xlsx_font_bold (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4305 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4307 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4308 if (attr_bool (xin
, attrs
, "val", &val
)) ;
4310 gnm_style_set_font_bold (state
->style_accum
, val
);
4313 xlsx_font_italic (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4315 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4317 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4318 if (attr_bool (xin
, attrs
, "val", &val
)) ;
4320 gnm_style_set_font_italic (state
->style_accum
, val
);
4323 xlsx_font_strike (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4325 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4327 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4328 if (attr_bool (xin
, attrs
, "val", &val
))
4330 gnm_style_set_font_strike (state
->style_accum
, val
);
4333 xlsx_font_color (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4335 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4336 /* LibreOffice 3.3.2 sets the alpha to 0, so text becomes invisible */
4337 /* (Excel drops the alpha too it seems.) */
4338 GnmColor
*color
= elem_color (xin
, attrs
, FALSE
);
4340 gnm_style_set_font_color (state
->style_accum
, color
);
4343 xlsx_CT_FontSize (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4345 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4348 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4349 if (attr_float (xin
, attrs
, "val", &val
))
4350 gnm_style_set_font_size (state
->style_accum
, val
);
4353 xlsx_CT_vertAlign (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4355 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4356 static EnumVal
const types
[] = {
4357 { "subscript", GO_FONT_SCRIPT_SUB
},
4358 { "baseline", GO_FONT_SCRIPT_STANDARD
},
4359 { "superscript", GO_FONT_SCRIPT_SUPER
},
4362 int val
= GO_FONT_SCRIPT_STANDARD
;
4364 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4365 if (attr_enum (xin
, attrs
, "val", types
, &val
))
4368 gnm_style_set_font_script (state
->style_accum
, val
);
4371 xlsx_font_uline (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4373 static EnumVal
const types
[] = {
4374 { "single", UNDERLINE_SINGLE
},
4375 { "double", UNDERLINE_DOUBLE
},
4376 { "singleAccounting", UNDERLINE_SINGLE_LOW
},
4377 { "doubleAccounting", UNDERLINE_DOUBLE_LOW
},
4378 { "none", UNDERLINE_NONE
},
4381 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4382 int val
= UNDERLINE_SINGLE
;
4384 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4385 if (attr_enum (xin
, attrs
, "val", types
, &val
))
4387 gnm_style_set_font_uline (state
->style_accum
, val
);
4391 xlsx_font_valign (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4393 static EnumVal
const types
[] = {
4394 { "baseline", GO_FONT_SCRIPT_STANDARD
},
4395 { "superscript", GO_FONT_SCRIPT_SUPER
},
4396 { "subscript", GO_FONT_SCRIPT_SUB
},
4399 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4400 int val
= GO_FONT_SCRIPT_STANDARD
;
4402 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4403 if (attr_enum (xin
, attrs
, "val", types
, &val
))
4404 gnm_style_set_font_script (state
->style_accum
, val
);
4408 xlsx_pattern (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4410 static EnumVal
const patterns
[] = {
4413 { "mediumGray", 3 },
4416 { "darkHorizontal", 7 },
4417 { "darkVertical", 8 },
4421 { "darkTrellis", 12 },
4422 { "lightHorizontal", 13 },
4423 { "lightVertical", 14 },
4424 { "lightDown", 15 },
4426 { "lightGrid", 17 },
4427 { "lightTrellis", 18 },
4432 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4433 int val
= 0; /* none */
4435 /* we are setting a default pattern of solid, see bug #702615 */
4436 /* Note that this conflicts with ECMA 376: "This element is used
4437 to specify cell fill information for pattern and solid color
4438 cell fills. For solid cell fills (no pattern), fgColor is used.
4439 For cell fills with patterns specified, then the cell fill color
4440 is specified by the bgColor element." */
4441 /* As the above bug report shows Excel 2010 creates: */
4442 /* <dxf><font><color rgb="FF9C0006"/></font><fill><patternFill>
4443 <bgColor rgb="FFFFC7CE"/></patternFill></fill></dxf> */
4445 gnm_style_set_pattern (state
->style_accum
, 1);
4447 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4448 if (attr_enum (xin
, attrs
, "patternType", patterns
, &val
))
4449 gnm_style_set_pattern (state
->style_accum
, val
);
4452 xlsx_pattern_fg_bg (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4454 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4455 gboolean solid_pattern
= gnm_style_is_element_set (state
->style_accum
, MSTYLE_PATTERN
)
4456 && (1 == gnm_style_get_pattern (state
->style_accum
));
4458 * Looks like pattern background and forground colours are inverted for
4459 * dxfs with solid fills for no apparent reason. */
4460 gboolean
const invert
= state
->style_accum_partial
4462 /* LibreOffice 3.3.2 sets the alpha to 0, so solid fill becomes invisible */
4463 /* (Excel drops the alpha too it seems.) */
4464 GnmColor
*color
= elem_color (xin
, attrs
, !solid_pattern
);
4468 if (xin
->node
->user_data
.v_int
^ invert
)
4469 gnm_style_set_back_color (state
->style_accum
, color
);
4471 gnm_style_set_pattern_color (state
->style_accum
, color
);
4475 xlsx_CT_GradientFill (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4477 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4479 gnm_style_set_pattern (state
->style_accum
, 1);
4482 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4483 <xsd
:attribute name
="type" type
="ST_GradientType" use
="optional" default="linear">
4484 <xsd
:attribute name
="degree" type
="xsd:double" use
="optional" default="0">
4485 <xsd
:attribute name
="left" type
="xsd:double" use
="optional" default="0">
4486 <xsd
:attribute name
="right" type
="xsd:double" use
="optional" default="0">
4487 <xsd
:attribute name
="top" type
="xsd:double" use
="optional" default="0">
4488 <xsd
:attribute name
="bottom" type
="xsd:double" use
="optional" default="0">
4493 xlsx_border_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4495 static EnumVal
const borders
[] = {
4496 { "none", GNM_STYLE_BORDER_NONE
},
4497 { "thin", GNM_STYLE_BORDER_THIN
},
4498 { "medium", GNM_STYLE_BORDER_MEDIUM
},
4499 { "dashed", GNM_STYLE_BORDER_DASHED
},
4500 { "dotted", GNM_STYLE_BORDER_DOTTED
},
4501 { "thick", GNM_STYLE_BORDER_THICK
},
4502 { "double", GNM_STYLE_BORDER_DOUBLE
},
4503 { "hair", GNM_STYLE_BORDER_HAIR
},
4504 { "mediumDashed", GNM_STYLE_BORDER_MEDIUM_DASH
},
4505 { "dashDot", GNM_STYLE_BORDER_DASH_DOT
},
4506 { "mediumDashDot", GNM_STYLE_BORDER_MEDIUM_DASH_DOT
},
4507 { "dashDotDot", GNM_STYLE_BORDER_DASH_DOT_DOT
},
4508 { "mediumDashDotDot", GNM_STYLE_BORDER_MEDIUM_DASH_DOT_DOT
},
4509 { "slantDashDot", GNM_STYLE_BORDER_SLANTED_DASH_DOT
},
4512 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4513 int border_style
= GNM_STYLE_BORDER_NONE
;
4515 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4516 if (attr_enum (xin
, attrs
, "style", borders
, &border_style
))
4518 state
->border_style
= border_style
;
4519 state
->border_color
= NULL
;
4523 xlsx_border_begin_v2 (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4525 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4526 state
->version
= ECMA_376_2008
;
4527 xlsx_border_begin (xin
, attrs
);
4531 xlsx_border_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4533 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4535 GnmStyleBorderLocation
const loc
= xin
->node
->user_data
.v_int
;
4537 if (NULL
== state
->border_color
)
4538 state
->border_color
= style_color_black ();
4539 border
= gnm_style_border_fetch (state
->border_style
,
4540 state
->border_color
, gnm_style_border_get_orientation (loc
));
4541 gnm_style_set_border (state
->style_accum
,
4542 GNM_STYLE_BORDER_LOCATION_TO_STYLE_ELEMENT (loc
),
4544 state
->border_color
= NULL
;
4548 xlsx_border_diagonal_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4550 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4551 GnmBorder
*border
, *new_border
;
4553 if (NULL
== state
->border_color
)
4554 state
->border_color
= style_color_black ();
4555 new_border
= gnm_style_border_fetch
4556 (state
->border_style
, state
->border_color
, GNM_STYLE_BORDER_DIAGONAL
);
4558 border
= gnm_style_get_border (state
->style_accum
, MSTYLE_BORDER_REV_DIAGONAL
);
4559 if (border
!= NULL
&& border
->line_type
!= GNM_STYLE_BORDER_NONE
) {
4560 gnm_style_border_ref (new_border
);
4561 gnm_style_set_border (state
->style_accum
,
4562 MSTYLE_BORDER_REV_DIAGONAL
,
4565 border
= gnm_style_get_border (state
->style_accum
, MSTYLE_BORDER_DIAGONAL
);
4566 if (border
!= NULL
&& border
->line_type
!= GNM_STYLE_BORDER_NONE
) {
4567 gnm_style_border_ref (new_border
);
4568 gnm_style_set_border (state
->style_accum
,
4569 MSTYLE_BORDER_DIAGONAL
,
4572 gnm_style_border_unref (new_border
);
4573 state
->border_color
= NULL
;
4577 xlsx_border_color (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4579 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4580 GnmColor
*color
= elem_color (xin
, attrs
, TRUE
);
4581 if (state
->border_color
)
4582 style_color_unref (state
->border_color
);
4583 state
->border_color
= color
;
4587 xlsx_xf_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4589 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4590 GnmStyle
*accum
= gnm_style_new ();
4591 GnmStyle
*parent
= NULL
;
4593 GPtrArray
*elem
= NULL
;
4596 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4597 if (0 == strcmp (attrs
[0], "numFmtId")) {
4598 GOFormat
*fmt
= xlsx_get_num_fmt (xin
, attrs
[1]);
4600 gnm_style_set_format (accum
, fmt
);
4601 } else if (attr_int (xin
, attrs
, "fontId", &indx
))
4602 elem
= state
->fonts
;
4603 else if (attr_int (xin
, attrs
, "fillId", &indx
))
4604 elem
= state
->fills
;
4605 else if (attr_int (xin
, attrs
, "borderId", &indx
))
4606 elem
= state
->borders
;
4607 else if (attr_int (xin
, attrs
, "xfId", &indx
))
4608 parent
= xlsx_get_style_xf (xin
, indx
);
4611 GnmStyle
const *component
= NULL
;
4612 if (0 <= indx
&& indx
< (int)elem
->len
)
4613 component
= g_ptr_array_index (elem
, indx
);
4614 if (NULL
!= component
) {
4616 gnm_style_merge (accum
, component
);
4618 GnmStyle
*merged
= gnm_style_new_merged (accum
, component
);
4619 gnm_style_unref (accum
);
4623 xlsx_warning (xin
, "Missing record '%d' for %s", indx
, attrs
[0]);
4627 if (NULL
== parent
) {
4628 result
= gnm_style_new_default ();
4629 gnm_style_merge (result
, accum
);
4631 result
= gnm_style_new_merged (parent
, accum
);
4632 gnm_style_unref (accum
);
4634 state
->style_accum
= result
;
4647 xlsx_xf_end (GsfXMLIn
*xin
, GsfXMLBlob
*blob
)
4649 xlsx_col_elem_end (xin
, blob
);
4653 xlsx_xf_align (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4655 static EnumVal
const haligns
[] = {
4656 { "general" , GNM_HALIGN_GENERAL
},
4657 { "left" , GNM_HALIGN_LEFT
},
4658 { "center" , GNM_HALIGN_CENTER
},
4659 { "right" , GNM_HALIGN_RIGHT
},
4660 { "fill" , GNM_HALIGN_FILL
},
4661 { "justify" , GNM_HALIGN_JUSTIFY
},
4662 { "centerContinuous" , GNM_HALIGN_CENTER_ACROSS_SELECTION
},
4663 { "distributed" , GNM_HALIGN_DISTRIBUTED
},
4667 static EnumVal
const valigns
[] = {
4668 { "top", GNM_VALIGN_TOP
},
4669 { "center", GNM_VALIGN_CENTER
},
4670 { "bottom", GNM_VALIGN_BOTTOM
},
4671 { "justify", GNM_VALIGN_JUSTIFY
},
4672 { "distributed", GNM_VALIGN_DISTRIBUTED
},
4676 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4677 int halign
= GNM_HALIGN_GENERAL
;
4678 int valign
= GNM_VALIGN_BOTTOM
;
4679 int rotation
= 0, indent
= 0;
4680 int wrapText
= FALSE
, justifyLastLine
= FALSE
, shrinkToFit
= FALSE
;
4682 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4683 if (attr_enum (xin
, attrs
, "horizontal", haligns
, &halign
)) ;
4684 else if (attr_enum (xin
, attrs
, "vertical", valigns
, &valign
)) ;
4685 else if (attr_int (xin
, attrs
, "textRotation", &rotation
));
4686 else if (attr_bool (xin
, attrs
, "wrapText", &wrapText
)) ;
4687 else if (attr_int (xin
, attrs
, "indent", &indent
)) ;
4688 else if (attr_bool (xin
, attrs
, "justifyLastLine", &justifyLastLine
)) ;
4689 else if (attr_bool (xin
, attrs
, "shrinkToFit", &shrinkToFit
)) ;
4690 /* "mergeCell" type="xs:boolean" use="optional" default="false" */
4691 /* "readingOrder" type="xs:unsignedInt" use="optional" default="0" */
4693 gnm_style_set_align_h (state
->style_accum
, halign
);
4694 gnm_style_set_align_v (state
->style_accum
, valign
);
4695 gnm_style_set_rotation (state
->style_accum
,
4696 (rotation
== 0xff) ? -1 : ((rotation
> 90) ? (360 + 90 - rotation
) : rotation
));
4697 gnm_style_set_wrap_text (state
->style_accum
, wrapText
);
4698 gnm_style_set_indent (state
->style_accum
, indent
);
4699 gnm_style_set_shrink_to_fit (state
->style_accum
, shrinkToFit
);
4702 xlsx_xf_protect (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4704 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4708 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4709 if (attr_bool (xin
, attrs
, "locked", &locked
)) ;
4710 else if (attr_bool (xin
, attrs
, "hidden", &hidden
)) ;
4711 gnm_style_set_contents_locked (state
->style_accum
, locked
);
4712 gnm_style_set_contents_hidden (state
->style_accum
, hidden
);
4716 xlsx_cell_style (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4718 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4719 /* xmlChar const *name = NULL; */
4720 xmlChar
const *id
= NULL
;
4721 GnmStyle
*style
= NULL
;
4724 /* cellStyle name="Normal" xfId="0" builtinId="0" */
4725 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4726 if (attr_int (xin
, attrs
, "xfId", &tmp
))
4727 style
= xlsx_get_style_xf (xin
, tmp
);
4728 else /* if (0 == strcmp (attrs[0], "name")) */
4729 /* name = attrs[1]; */
4730 /* else */ if (0 == strcmp (attrs
[0], "builtinId"))
4733 if (NULL
!= style
&& NULL
!= id
) {
4734 gnm_style_ref (style
);
4735 g_hash_table_replace (state
->cell_styles
, g_strdup (id
), style
);
4740 xlsx_dxf_begin (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4742 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4743 state
->style_accum_partial
= TRUE
;
4744 state
->style_accum
= gnm_style_new ();
4747 xlsx_dxf_end (GsfXMLIn
*xin
, GsfXMLBlob
*blob
)
4749 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4750 state
->style_accum_partial
= FALSE
;
4751 xlsx_col_elem_end (xin
, blob
);
4755 xlsx_dxf_numfmt (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4757 xlsx_numfmt_common (xin
, attrs
, TRUE
);
4761 static GsfXMLInNode
const xlsx_styles_dtd
[] = {
4762 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4763 GSF_XML_IN_NODE_FULL (START
, STYLE_INFO
, XL_NS_SS
, "styleSheet", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4764 GSF_XML_IN_NODE (STYLE_INFO
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4765 GSF_XML_IN_NODE (EXTLST
, EXTITEM
, XL_NS_SS
, "ext", GSF_XML_NO_CONTENT
, &xlsx_ext_begin
, &xlsx_ext_end
),
4766 GSF_XML_IN_NODE (STYLE_INFO
, NUM_FMTS
, XL_NS_SS
, "numFmts", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4767 GSF_XML_IN_NODE (NUM_FMTS
, NUM_FMT
, XL_NS_SS
, "numFmt", GSF_XML_NO_CONTENT
, &xlsx_style_numfmt
, NULL
),
4769 GSF_XML_IN_NODE_FULL (STYLE_INFO
, FONTS
, XL_NS_SS
, "fonts", GSF_XML_NO_CONTENT
,
4770 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_FONT
),
4771 GSF_XML_IN_NODE (FONTS
, FONT
, XL_NS_SS
, "font", GSF_XML_NO_CONTENT
, &xlsx_col_elem_begin
, &xlsx_col_elem_end
),
4772 GSF_XML_IN_NODE (FONT
, FONT_NAME
, XL_NS_SS
, "name", GSF_XML_NO_CONTENT
, &xlsx_font_name
, NULL
),
4773 GSF_XML_IN_NODE (FONT
, FONT_CHARSET
, XL_NS_SS
, "charset", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4774 GSF_XML_IN_NODE (FONT
, FONT_FAMILY
, XL_NS_SS
, "family", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4775 GSF_XML_IN_NODE (FONT
, FONT_BOLD
, XL_NS_SS
, "b", GSF_XML_NO_CONTENT
, &xlsx_font_bold
, NULL
),
4776 GSF_XML_IN_NODE (FONT
, FONT_ITALIC
, XL_NS_SS
, "i", GSF_XML_NO_CONTENT
, &xlsx_font_italic
, NULL
),
4777 GSF_XML_IN_NODE (FONT
, FONT_STRIKE
, XL_NS_SS
, "strike", GSF_XML_NO_CONTENT
, &xlsx_font_strike
, NULL
),
4778 GSF_XML_IN_NODE (FONT
, FONT_OUTLINE
, XL_NS_SS
, "outline", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4779 GSF_XML_IN_NODE (FONT
, FONT_SHADOW
, XL_NS_SS
, "shadow", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4780 GSF_XML_IN_NODE (FONT
, FONT_CONDENSE
, XL_NS_SS
, "condense", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4781 GSF_XML_IN_NODE (FONT
, FONT_EXTEND
, XL_NS_SS
, "extend", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4782 GSF_XML_IN_NODE (FONT
, FONT_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_font_color
, NULL
),
4783 GSF_XML_IN_NODE (FONT
, FONT_SZ
, XL_NS_SS
, "sz", GSF_XML_NO_CONTENT
, &xlsx_CT_FontSize
, NULL
),
4784 GSF_XML_IN_NODE (FONT
, FONT_SCRIPT
, XL_NS_SS
, "vertAlign", GSF_XML_NO_CONTENT
, &xlsx_CT_vertAlign
, NULL
),
4785 GSF_XML_IN_NODE (FONT
, FONT_ULINE
, XL_NS_SS
, "u", GSF_XML_NO_CONTENT
, &xlsx_font_uline
, NULL
),
4786 GSF_XML_IN_NODE (FONT
, FONT_VERTALIGN
, XL_NS_SS
, "vertAlign", GSF_XML_NO_CONTENT
, &xlsx_font_valign
, NULL
),
4787 GSF_XML_IN_NODE (FONT
, FONT_SCHEME
, XL_NS_SS
, "scheme", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4789 GSF_XML_IN_NODE_FULL (STYLE_INFO
, FILLS
, XL_NS_SS
, "fills", GSF_XML_NO_CONTENT
,
4790 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_FILLS
),
4791 GSF_XML_IN_NODE (FILLS
, FILL
, XL_NS_SS
, "fill", GSF_XML_NO_CONTENT
, &xlsx_col_elem_begin
, &xlsx_col_elem_end
),
4792 GSF_XML_IN_NODE (FILL
, PATTERN_FILL
, XL_NS_SS
, "patternFill", GSF_XML_NO_CONTENT
, &xlsx_pattern
, NULL
),
4793 GSF_XML_IN_NODE_FULL (PATTERN_FILL
, PATTERN_FILL_FG
, XL_NS_SS
, "fgColor", GSF_XML_NO_CONTENT
,
4794 FALSE
, FALSE
, &xlsx_pattern_fg_bg
, NULL
, TRUE
),
4795 GSF_XML_IN_NODE_FULL (PATTERN_FILL
, PATTERN_FILL_BG
, XL_NS_SS
, "bgColor", GSF_XML_NO_CONTENT
,
4796 FALSE
, FALSE
, &xlsx_pattern_fg_bg
, NULL
, FALSE
),
4797 GSF_XML_IN_NODE (FILL
, IMAGE_FILL
, XL_NS_SS
, "image", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4798 GSF_XML_IN_NODE (FILL
, GRADIENT_FILL
, XL_NS_SS
, "gradientFill", GSF_XML_NO_CONTENT
, &xlsx_CT_GradientFill
, NULL
),
4799 GSF_XML_IN_NODE (GRADIENT_FILL
, GRADIENT_STOPS
, XL_NS_SS
, "stop", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4800 GSF_XML_IN_NODE_FULL (GRADIENT_STOPS
, GRADIENT_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, FALSE
, FALSE
, &xlsx_pattern_fg_bg
, NULL
, TRUE
),
4802 GSF_XML_IN_NODE_FULL (STYLE_INFO
, BORDERS
, XL_NS_SS
, "borders", GSF_XML_NO_CONTENT
,
4803 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_BORDERS
),
4804 GSF_XML_IN_NODE (BORDERS
, BORDER
, XL_NS_SS
, "border", GSF_XML_NO_CONTENT
, &xlsx_col_border_begin
, &xlsx_col_elem_end
),
4805 GSF_XML_IN_NODE_FULL (BORDER
, LEFT_B
, XL_NS_SS
, "left", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4806 &xlsx_border_begin
, &xlsx_border_end
, GNM_STYLE_BORDER_LEFT
),
4807 GSF_XML_IN_NODE (LEFT_B
, LEFT_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4808 GSF_XML_IN_NODE_FULL (BORDER
, START_B
, XL_NS_SS
, "start", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4809 &xlsx_border_begin_v2
, &xlsx_border_end
, GNM_STYLE_BORDER_LEFT
),
4810 GSF_XML_IN_NODE (START_B
, START_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4811 GSF_XML_IN_NODE_FULL (BORDER
, RIGHT_B
, XL_NS_SS
, "right", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4812 &xlsx_border_begin
, &xlsx_border_end
, GNM_STYLE_BORDER_RIGHT
),
4813 GSF_XML_IN_NODE (RIGHT_B
, RIGHT_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4814 GSF_XML_IN_NODE_FULL (BORDER
, END_B
, XL_NS_SS
, "end", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4815 &xlsx_border_begin_v2
, &xlsx_border_end
, GNM_STYLE_BORDER_RIGHT
),
4816 GSF_XML_IN_NODE (END_B
, END_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4817 GSF_XML_IN_NODE_FULL (BORDER
, TOP_B
, XL_NS_SS
, "top", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4818 &xlsx_border_begin
, &xlsx_border_end
, GNM_STYLE_BORDER_TOP
),
4819 GSF_XML_IN_NODE (TOP_B
, TOP_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4820 GSF_XML_IN_NODE_FULL (BORDER
, BOTTOM_B
, XL_NS_SS
, "bottom", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4821 &xlsx_border_begin
, &xlsx_border_end
, GNM_STYLE_BORDER_BOTTOM
),
4822 GSF_XML_IN_NODE (BOTTOM_B
, BOTTOM_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4823 GSF_XML_IN_NODE (BORDER
, DIAG_B
, XL_NS_SS
, "diagonal", GSF_XML_NO_CONTENT
,
4824 &xlsx_border_begin
, &xlsx_border_diagonal_end
),
4825 GSF_XML_IN_NODE (DIAG_B
, DIAG_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4827 GSF_XML_IN_NODE (BORDER
, BORDER_VERT
, XL_NS_SS
, "vertical", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4828 GSF_XML_IN_NODE (BORDER_VERT
, VERT_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4829 GSF_XML_IN_NODE (BORDER
, BORDER_HORIZ
, XL_NS_SS
, "horizontal", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4830 GSF_XML_IN_NODE (BORDER_HORIZ
, HORIZ_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4832 GSF_XML_IN_NODE_FULL (STYLE_INFO
, XFS
, XL_NS_SS
, "cellXfs", GSF_XML_NO_CONTENT
,
4833 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_XFS
),
4834 GSF_XML_IN_NODE (XFS
, XF
, XL_NS_SS
, "xf", GSF_XML_NO_CONTENT
, &xlsx_xf_begin
, &xlsx_xf_end
),
4835 GSF_XML_IN_NODE (XF
, ALIGNMENT
, XL_NS_SS
, "alignment", GSF_XML_NO_CONTENT
, &xlsx_xf_align
, NULL
),
4836 GSF_XML_IN_NODE (XF
, PROTECTION
, XL_NS_SS
, "protection", GSF_XML_NO_CONTENT
, &xlsx_xf_protect
, NULL
),
4838 GSF_XML_IN_NODE_FULL (STYLE_INFO
, STYLE_XFS
, XL_NS_SS
, "cellStyleXfs", GSF_XML_NO_CONTENT
,
4839 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_STYLE_XFS
),
4840 GSF_XML_IN_NODE (STYLE_XFS
, STYLE_XF
, XL_NS_SS
, "xf", GSF_XML_NO_CONTENT
, &xlsx_xf_begin
, &xlsx_xf_end
),
4841 GSF_XML_IN_NODE (STYLE_XF
, STYLE_ALIGNMENT
, XL_NS_SS
, "alignment", GSF_XML_NO_CONTENT
, &xlsx_xf_align
, NULL
),
4842 GSF_XML_IN_NODE (STYLE_XF
, STYLE_PROTECTION
, XL_NS_SS
, "protection", GSF_XML_NO_CONTENT
, &xlsx_xf_protect
, NULL
),
4844 GSF_XML_IN_NODE (STYLE_INFO
, STYLE_NAMES
, XL_NS_SS
, "cellStyles", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4845 GSF_XML_IN_NODE (STYLE_NAMES
, STYLE_NAME
, XL_NS_SS
, "cellStyle", GSF_XML_NO_CONTENT
, &xlsx_cell_style
, NULL
),
4846 GSF_XML_IN_NODE (STYLE_NAME
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4847 GSF_XML_IN_NODE_FULL (STYLE_INFO
, PARTIAL_XFS
, XL_NS_SS
, "dxfs", GSF_XML_NO_CONTENT
,
4848 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_DXFS
),
4849 GSF_XML_IN_NODE (PARTIAL_XFS
, PARTIAL_XF
, XL_NS_SS
, "dxf", GSF_XML_NO_CONTENT
, &xlsx_dxf_begin
, &xlsx_dxf_end
),
4850 GSF_XML_IN_NODE (PARTIAL_XF
, DXF_NUM_FMT
, XL_NS_SS
, "numFmt", GSF_XML_NO_CONTENT
, &xlsx_dxf_numfmt
, NULL
),
4851 GSF_XML_IN_NODE (PARTIAL_XF
, FONT
, XL_NS_SS
, "font", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4852 GSF_XML_IN_NODE (PARTIAL_XF
, FILL
, XL_NS_SS
, "fill", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4853 GSF_XML_IN_NODE (PARTIAL_XF
, BORDER
, XL_NS_SS
, "border", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4854 GSF_XML_IN_NODE (PARTIAL_XF
, DXF_ALIGNMENT
, XL_NS_SS
, "alignment", GSF_XML_NO_CONTENT
, &xlsx_xf_align
, NULL
),
4855 GSF_XML_IN_NODE (PARTIAL_XF
, DXF_PROTECTION
, XL_NS_SS
, "protection", GSF_XML_NO_CONTENT
, &xlsx_xf_protect
, NULL
),
4856 GSF_XML_IN_NODE (PARTIAL_XF
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4858 GSF_XML_IN_NODE_FULL (STYLE_INFO
, TABLE_STYLES
, XL_NS_SS
, "tableStyles", GSF_XML_NO_CONTENT
,
4859 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_TABLE_STYLES
),
4860 GSF_XML_IN_NODE (TABLE_STYLES
, TABLE_STYLE
, XL_NS_SS
, "tableStyle", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4862 GSF_XML_IN_NODE (STYLE_INFO
, COLORS
, XL_NS_SS
, "colors", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4863 GSF_XML_IN_NODE (COLORS
, INDEXED_COLORS
, XL_NS_SS
, "indexedColors", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4864 GSF_XML_IN_NODE (INDEXED_COLORS
, INDEXED_RGB
, XL_NS_SS
, "rgbColor", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4865 GSF_XML_IN_NODE (COLORS
, THEME_COLORS
, XL_NS_SS
, "themeColors", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4866 GSF_XML_IN_NODE (THEME_COLORS
, THEMED_RGB
, XL_NS_SS
, "rgbColor", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4867 GSF_XML_IN_NODE (COLORS
, MRU_COLORS
, XL_NS_SS
, "mruColors", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4868 GSF_XML_IN_NODE (MRU_COLORS
, MRU_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4873 /****************************************************************************/
4876 xlsx_theme_color_sys (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4878 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4880 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4881 if (attr_gocolor (xin
, attrs
, "lastClr", &c
)) {
4882 g_hash_table_replace (state
->theme_colors_by_name
,
4883 g_strdup (((GsfXMLInNode
*)xin
->node_stack
->data
)->name
),
4884 GUINT_TO_POINTER (c
));
4888 xlsx_theme_color_rgb (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4890 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4892 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
4893 if (attr_gocolor (xin
, attrs
, "val", &c
)) {
4894 g_hash_table_replace (state
->theme_colors_by_name
,
4895 g_strdup (((GsfXMLInNode
*)xin
->node_stack
->data
)->name
),
4896 GUINT_TO_POINTER (c
));
4900 static GsfXMLInNode
const xlsx_theme_dtd
[] = {
4901 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4902 GSF_XML_IN_NODE_FULL (START
, THEME
, XL_NS_DRAW
, "theme", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4903 GSF_XML_IN_NODE (THEME
, ELEMENTS
, XL_NS_DRAW
, "themeElements", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4904 GSF_XML_IN_NODE (ELEMENTS
, COLOR_SCHEME
, XL_NS_DRAW
, "clrScheme", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4905 GSF_XML_IN_NODE (COLOR_SCHEME
, dk1
, XL_NS_DRAW
, "dk1", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4906 GSF_XML_IN_NODE (dk1
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, &xlsx_theme_color_sys
, NULL
),
4907 GSF_XML_IN_NODE (dk1
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, &xlsx_theme_color_rgb
, NULL
),
4908 GSF_XML_IN_NODE (RGB_COLOR
, COLOR_ALPHA
, XL_NS_DRAW
, "alpha", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4909 GSF_XML_IN_NODE (COLOR_SCHEME
, lt1
, XL_NS_DRAW
, "lt1", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4910 GSF_XML_IN_NODE (lt1
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4911 GSF_XML_IN_NODE (lt1
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4912 GSF_XML_IN_NODE (COLOR_SCHEME
, lt2
, XL_NS_DRAW
, "lt2", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4913 GSF_XML_IN_NODE (lt2
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4914 GSF_XML_IN_NODE (lt2
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4915 GSF_XML_IN_NODE (COLOR_SCHEME
, dk2
, XL_NS_DRAW
, "dk2", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4916 GSF_XML_IN_NODE (dk2
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4917 GSF_XML_IN_NODE (dk2
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4918 GSF_XML_IN_NODE (COLOR_SCHEME
, accent1
, XL_NS_DRAW
, "accent1", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4919 GSF_XML_IN_NODE (accent1
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4920 GSF_XML_IN_NODE (accent1
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4921 GSF_XML_IN_NODE (COLOR_SCHEME
, accent2
, XL_NS_DRAW
, "accent2", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4922 GSF_XML_IN_NODE (accent2
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4923 GSF_XML_IN_NODE (accent2
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4924 GSF_XML_IN_NODE (COLOR_SCHEME
, accent3
, XL_NS_DRAW
, "accent3", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4925 GSF_XML_IN_NODE (accent3
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4926 GSF_XML_IN_NODE (accent3
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4927 GSF_XML_IN_NODE (COLOR_SCHEME
, accent4
, XL_NS_DRAW
, "accent4", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4928 GSF_XML_IN_NODE (accent4
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4929 GSF_XML_IN_NODE (accent4
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4930 GSF_XML_IN_NODE (COLOR_SCHEME
, accent5
, XL_NS_DRAW
, "accent5", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4931 GSF_XML_IN_NODE (accent5
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4932 GSF_XML_IN_NODE (accent5
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4933 GSF_XML_IN_NODE (COLOR_SCHEME
, accent6
, XL_NS_DRAW
, "accent6", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4934 GSF_XML_IN_NODE (accent6
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4935 GSF_XML_IN_NODE (accent6
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4936 GSF_XML_IN_NODE (COLOR_SCHEME
, hlink
, XL_NS_DRAW
, "hlink", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4937 GSF_XML_IN_NODE (hlink
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4938 GSF_XML_IN_NODE (hlink
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4939 GSF_XML_IN_NODE (COLOR_SCHEME
, folHlink
, XL_NS_DRAW
, "folHlink", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4940 GSF_XML_IN_NODE (folHlink
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4941 GSF_XML_IN_NODE (folHlink
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd Def */
4943 GSF_XML_IN_NODE (ELEMENTS
, FONT_SCHEME
, XL_NS_DRAW
, "fontScheme", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4944 GSF_XML_IN_NODE (FONT_SCHEME
, MAJOR_FONT
, XL_NS_DRAW
, "majorFont", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4945 GSF_XML_IN_NODE (MAJOR_FONT
, FONT_CS
, XL_NS_DRAW
, "cs", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4946 GSF_XML_IN_NODE (MAJOR_FONT
, FONT_EA
, XL_NS_DRAW
, "ea", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4947 GSF_XML_IN_NODE (MAJOR_FONT
, FONT_FONT
, XL_NS_DRAW
, "font", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4948 GSF_XML_IN_NODE (MAJOR_FONT
, FONT_LATIN
, XL_NS_DRAW
, "latin", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4949 GSF_XML_IN_NODE (FONT_SCHEME
, MINOR_FONT
, XL_NS_DRAW
, "minorFont", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4950 GSF_XML_IN_NODE (MINOR_FONT
, FONT_CS
, XL_NS_DRAW
, "cs", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4951 GSF_XML_IN_NODE (MINOR_FONT
, FONT_EA
, XL_NS_DRAW
, "ea", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4952 GSF_XML_IN_NODE (MINOR_FONT
, FONT_FONT
, XL_NS_DRAW
, "font", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4953 GSF_XML_IN_NODE (MINOR_FONT
, FONT_LATIN
, XL_NS_DRAW
, "latin", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4955 GSF_XML_IN_NODE (ELEMENTS
, FORMAT_SCHEME
, XL_NS_DRAW
, "fmtScheme", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4956 GSF_XML_IN_NODE (FORMAT_SCHEME
, FILL_STYLE_LIST
, XL_NS_DRAW
, "fillStyleLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4957 GSF_XML_IN_NODE (FILL_STYLE_LIST
, SOLID_FILL
, XL_NS_DRAW
, "solidFill", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4958 GSF_XML_IN_NODE (SOLID_FILL
, SCHEME_COLOR
, XL_NS_DRAW
, "schemeClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4959 GSF_XML_IN_NODE (SCHEME_COLOR
, COLOR_TINT
, XL_NS_DRAW
, "tint", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4960 GSF_XML_IN_NODE (SCHEME_COLOR
, COLOR_LUM
, XL_NS_DRAW
, "lumMod", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4961 GSF_XML_IN_NODE (SCHEME_COLOR
, COLOR_SAT
, XL_NS_DRAW
, "satMod", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4962 GSF_XML_IN_NODE (SCHEME_COLOR
, COLOR_SHADE
, XL_NS_DRAW
, "shade", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4963 GSF_XML_IN_NODE (FILL_STYLE_LIST
, GRAD_FILL
, XL_NS_DRAW
, "gradFill", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4964 GSF_XML_IN_NODE (GRAD_FILL
, GRAD_PATH
, XL_NS_DRAW
, "path", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4965 GSF_XML_IN_NODE (GRAD_PATH
, GRAD_PATH_RECT
, XL_NS_DRAW
, "fillToRect", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4966 GSF_XML_IN_NODE (GRAD_FILL
, GRAD_LIST
, XL_NS_DRAW
, "gsLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4967 GSF_XML_IN_NODE (GRAD_LIST
, GRAD_LIST_ITEM
, XL_NS_DRAW
, "gs", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4968 GSF_XML_IN_NODE (GRAD_LIST_ITEM
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4969 GSF_XML_IN_NODE (GRAD_LIST_ITEM
, SCHEME_COLOR
, XL_NS_DRAW
, "schemeClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4970 GSF_XML_IN_NODE (GRAD_FILL
, GRAD_LINE
, XL_NS_DRAW
, "lin", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4972 GSF_XML_IN_NODE (FORMAT_SCHEME
, BG_FILL_STYLE_LIST
, XL_NS_DRAW
, "bgFillStyleLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4973 GSF_XML_IN_NODE (BG_FILL_STYLE_LIST
, GRAD_FILL
, XL_NS_DRAW
, "gradFill", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4974 GSF_XML_IN_NODE (BG_FILL_STYLE_LIST
, SOLID_FILL
, XL_NS_DRAW
, "solidFill", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4975 GSF_XML_IN_NODE (FORMAT_SCHEME
, LINE_STYLE_LIST
, XL_NS_DRAW
, "lnStyleLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4976 GSF_XML_IN_NODE (LINE_STYLE_LIST
, LINE_STYLE
, XL_NS_DRAW
, "ln", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4977 GSF_XML_IN_NODE (LINE_STYLE
, LN_NOFILL
, XL_NS_DRAW
, "noFill", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4978 GSF_XML_IN_NODE (LINE_STYLE
, LN_DASH
, XL_NS_DRAW
, "prstDash", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4979 GSF_XML_IN_NODE (LINE_STYLE
, SOLID_FILL
, XL_NS_DRAW
, "solidFill", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4980 GSF_XML_IN_NODE (LINE_STYLE
, FILL_PATT
, XL_NS_DRAW
, "pattFill", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4981 GSF_XML_IN_NODE (FORMAT_SCHEME
, EFFECT_STYLE_LIST
, XL_NS_DRAW
, "effectStyleLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4982 GSF_XML_IN_NODE (EFFECT_STYLE_LIST
, EFFECT_STYLE
, XL_NS_DRAW
, "effectStyle", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4983 GSF_XML_IN_NODE (EFFECT_STYLE
, EFFECT_PROP
, XL_NS_DRAW
, "sp3d", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4984 GSF_XML_IN_NODE (EFFECT_PROP
, CONTOUR_CLR
, XL_NS_DRAW
, "contourClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4985 GSF_XML_IN_NODE (CONTOUR_CLR
, SCHEME_CLR
, XL_NS_DRAW
, "schemeClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4986 GSF_XML_IN_NODE (EFFECT_PROP
, PROP_BEVEL
, XL_NS_DRAW
, "bevelT", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4987 GSF_XML_IN_NODE (EFFECT_STYLE
, EFFECT_LIST
, XL_NS_DRAW
, "effectLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4988 GSF_XML_IN_NODE (EFFECT_LIST
, REFLECTION
, XL_NS_DRAW
, "reflection", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4989 GSF_XML_IN_NODE (EFFECT_LIST
, OUTER_SHADOW
, XL_NS_DRAW
, "outerShdw", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4990 GSF_XML_IN_NODE (OUTER_SHADOW
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd Def */
4991 GSF_XML_IN_NODE (EFFECT_STYLE
, EFFECT_SCENE_3D
, XL_NS_DRAW
, "scene3d", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4992 GSF_XML_IN_NODE (EFFECT_SCENE_3D
, 3D_CAMERA
, XL_NS_DRAW
, "camera", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4993 GSF_XML_IN_NODE (3D_CAMERA
, 3D_ROT
, XL_NS_DRAW
, "rot", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4994 GSF_XML_IN_NODE (EFFECT_SCENE_3D
, 3D_LIGHT
, XL_NS_DRAW
, "lightRig", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4995 GSF_XML_IN_NODE (3D_LIGHT
, 3D_ROT
, XL_NS_DRAW
, "rot", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4997 GSF_XML_IN_NODE (THEME
, OBJ_DEFAULTS
, XL_NS_DRAW
, "objectDefaults", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4998 GSF_XML_IN_NODE (OBJ_DEFAULTS
, SP_DEF
, XL_NS_DRAW
, "spDef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4999 GSF_XML_IN_NODE (SP_DEF
, SHAPE_PR
, XL_NS_DRAW
, "spPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5000 GSF_XML_IN_NODE (SHAPE_PR
, XFRM
, XL_NS_DRAW
, "xfrm", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5001 GSF_XML_IN_NODE (SHAPE_PR
, CUST_GEOM
, XL_NS_DRAW
, "custGeom", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5002 GSF_XML_IN_NODE (SHAPE_PR
, EXTLST
, XL_NS_DRAW
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5003 GSF_XML_IN_NODE (SHAPE_PR
, SOLID_FILL
, XL_NS_DRAW
, "solidFill", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5004 GSF_XML_IN_NODE (SP_DEF
, BODY_PR
, XL_NS_DRAW
, "bodyPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5005 GSF_XML_IN_NODE (SP_DEF
, LST_STYLE
, XL_NS_DRAW
, "lstStyle", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5006 GSF_XML_IN_NODE (SP_DEF
, STYLE
, XL_NS_DRAW
, "style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5007 GSF_XML_IN_NODE (STYLE
, EFFECT_REF
, XL_NS_DRAW
, "effectRef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5008 GSF_XML_IN_NODE (EFFECT_REF
, HSL_CLR
, XL_NS_DRAW
, "hslClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5009 GSF_XML_IN_NODE (EFFECT_REF
, PRST_CLR
, XL_NS_DRAW
, "prstClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5010 GSF_XML_IN_NODE (EFFECT_REF
, SCHEME_CLR
, XL_NS_DRAW
, "schemeClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5011 GSF_XML_IN_NODE (EFFECT_REF
, SCRGB_CLR
, XL_NS_DRAW
, "scrgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5012 GSF_XML_IN_NODE (EFFECT_REF
, SRGB_CLR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5013 GSF_XML_IN_NODE (EFFECT_REF
, SYS_CLR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5014 GSF_XML_IN_NODE (STYLE
, FILL_REF
, XL_NS_DRAW
, "fillRef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5015 GSF_XML_IN_NODE (FILL_REF
, HSL_CLR
, XL_NS_DRAW
, "hslClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5016 GSF_XML_IN_NODE (FILL_REF
, PRST_CLR
, XL_NS_DRAW
, "prstClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5017 GSF_XML_IN_NODE (FILL_REF
, SCHEME_CLR
, XL_NS_DRAW
, "schemeClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5018 GSF_XML_IN_NODE (FILL_REF
, SCRGB_CLR
, XL_NS_DRAW
, "scrgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5019 GSF_XML_IN_NODE (FILL_REF
, SRGB_CLR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5020 GSF_XML_IN_NODE (FILL_REF
, SYS_CLR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5021 GSF_XML_IN_NODE (STYLE
, FONT_REF
, XL_NS_DRAW
, "fontRef", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5022 GSF_XML_IN_NODE (FONT_REF
, HSL_CLR
, XL_NS_DRAW
, "hslClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5023 GSF_XML_IN_NODE (FONT_REF
, PRST_CLR
, XL_NS_DRAW
, "prstClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5024 GSF_XML_IN_NODE (FONT_REF
, SCHEME_CLR
, XL_NS_DRAW
, "schemeClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5025 GSF_XML_IN_NODE (FONT_REF
, SCRGB_CLR
, XL_NS_DRAW
, "scrgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5026 GSF_XML_IN_NODE (FONT_REF
, SRGB_CLR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5027 GSF_XML_IN_NODE (FONT_REF
, SYS_CLR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5028 GSF_XML_IN_NODE (STYLE
, LN_REF
, XL_NS_DRAW
, "lnRef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5029 GSF_XML_IN_NODE (LN_REF
, HSL_CLR
, XL_NS_DRAW
, "hslClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5030 GSF_XML_IN_NODE (LN_REF
, PRST_CLR
, XL_NS_DRAW
, "prstClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5031 GSF_XML_IN_NODE (LN_REF
, SCHEME_CLR
, XL_NS_DRAW
, "schemeClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5032 GSF_XML_IN_NODE (LN_REF
, SCRGB_CLR
, XL_NS_DRAW
, "scrgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5033 GSF_XML_IN_NODE (LN_REF
, SRGB_CLR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5034 GSF_XML_IN_NODE (LN_REF
, SYS_CLR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),/* 2nd */
5035 GSF_XML_IN_NODE (SP_DEF
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd */
5036 GSF_XML_IN_NODE (OBJ_DEFAULTS
, LN_DEF
, XL_NS_DRAW
, "lnDef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5037 GSF_XML_IN_NODE (LN_DEF
, BODY_PR
, XL_NS_DRAW
, "bodyPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5038 GSF_XML_IN_NODE (LN_DEF
, LST_STYLE
, XL_NS_DRAW
, "lstStyle", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5039 GSF_XML_IN_NODE (LN_DEF
, SP_PR
, XL_NS_DRAW
, "spPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5040 GSF_XML_IN_NODE (LN_DEF
, STYLE
, XL_NS_DRAW
, "style", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd */
5041 GSF_XML_IN_NODE (LN_DEF
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd */
5042 GSF_XML_IN_NODE (OBJ_DEFAULTS
, TX_DEF
, XL_NS_DRAW
, "txDef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5043 GSF_XML_IN_NODE (OBJ_DEFAULTS
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
), /* 2nd */
5044 GSF_XML_IN_NODE (THEME
, EXTRA_COLOR_SCHEME
, XL_NS_DRAW
, "extraClrSchemeLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5049 /****************************************************************************/
5051 G_MODULE_EXPORT gboolean
5052 xlsx_file_probe (GOFileOpener
const *fo
, GsfInput
*input
, GOFileProbeLevel pl
);
5055 xlsx_file_probe (G_GNUC_UNUSED GOFileOpener
const *fo
, GsfInput
*input
, G_GNUC_UNUSED GOFileProbeLevel pl
)
5059 gboolean res
= FALSE
;
5061 if (NULL
!= (zip
= gsf_infile_zip_new (input
, NULL
))) {
5062 if (NULL
!= (stream
= gsf_infile_child_by_vname (zip
, "xl", "workbook.xml", NULL
))) {
5063 g_object_unref (stream
);
5066 g_object_unref (zip
);
5072 xlsx_style_array_free (GPtrArray
*styles
)
5074 if (styles
!= NULL
) {
5075 unsigned i
= styles
->len
;
5078 if (NULL
!= (style
= g_ptr_array_index (styles
, i
)))
5079 gnm_style_unref (style
);
5081 g_ptr_array_free (styles
, TRUE
);
5085 #include "xlsx-read-docprops.c"
5087 G_MODULE_EXPORT
void
5088 xlsx_file_open (GOFileOpener
const *fo
, GOIOContext
*context
,
5089 WorkbookView
*wb_view
, GsfInput
*input
);
5092 xlsx_file_open (G_GNUC_UNUSED GOFileOpener
const *fo
, GOIOContext
*context
,
5093 WorkbookView
*wb_view
, GsfInput
*input
)
5095 XLSXReadState state
;
5098 memset (&state
, 0, sizeof (XLSXReadState
));
5099 state
.version
= ECMA_376_2006
;
5100 state
.context
= context
;
5101 state
.wb_view
= wb_view
;
5102 state
.wb
= wb_view_get_workbook (wb_view
);
5104 state
.run_attrs
= NULL
;
5105 state
.rich_attrs
= NULL
;
5106 state
.sst
= g_array_new (FALSE
, TRUE
, sizeof (XLSXStr
));
5107 state
.shared_exprs
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
5108 (GDestroyNotify
)g_free
, (GDestroyNotify
) gnm_expr_top_unref
);
5109 state
.cell_styles
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
5110 (GDestroyNotify
)g_free
, (GDestroyNotify
) gnm_style_unref
);
5111 state
.num_fmts
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
5112 (GDestroyNotify
)g_free
, (GDestroyNotify
) go_format_unref
);
5113 state
.date_fmt
= xlsx_pivot_date_fmt ();
5114 state
.convs
= xlsx_conventions_new (FALSE
);
5115 state
.theme_colors_by_name
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
5116 (GDestroyNotify
)g_free
, NULL
);
5117 /* fill in some default colors (when theme is absent */
5118 g_hash_table_replace (state
.theme_colors_by_name
, g_strdup ("bg1"), GUINT_TO_POINTER (GO_COLOR_WHITE
));
5119 state
.pivot
.cache_by_id
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
5120 (GDestroyNotify
)g_free
, (GDestroyNotify
) g_object_unref
);
5121 state
.zorder
= g_hash_table_new (g_direct_hash
, g_direct_equal
);
5123 locale
= gnm_push_C_locale ();
5125 if (NULL
!= (state
.zip
= gsf_infile_zip_new (input
, NULL
))) {
5127 GsfInput
*wb_part
= gsf_open_pkg_open_rel_by_type (GSF_INPUT (state
.zip
),
5128 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", NULL
);
5130 if (NULL
!= wb_part
) {
5133 in
= gsf_open_pkg_open_rel_by_type (wb_part
,
5134 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", NULL
);
5136 start_update_progress (&state
, in
, _("Reading shared strings..."),
5138 xlsx_parse_stream (&state
, in
, xlsx_shared_strings_dtd
);
5139 end_update_progress (&state
);
5142 in
= gsf_open_pkg_open_rel_by_type (wb_part
,
5143 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", NULL
);
5145 start_update_progress (&state
, in
, _("Reading theme..."),
5147 xlsx_parse_stream (&state
, in
, xlsx_theme_dtd
);
5148 end_update_progress (&state
);
5151 in
= gsf_open_pkg_open_rel_by_type (wb_part
,
5152 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", NULL
);
5154 start_update_progress (&state
, in
, _("Reading styles..."), 0.1, 0.2);
5155 xlsx_parse_stream (&state
, in
, xlsx_styles_dtd
);
5156 end_update_progress (&state
);
5159 start_update_progress (&state
, wb_part
, _("Reading workbook..."),
5161 xlsx_parse_stream (&state
, wb_part
, xlsx_workbook_dtd
);
5162 /* end_update_progress (&state); moved into xlsx_wb_end */
5163 /* MW 20111121: why? If parsing fails, I don't think that will ever be called. */
5165 xlsx_read_docprops (&state
);
5168 go_cmd_context_error_import (GO_CMD_CONTEXT (context
),
5169 _("No workbook stream found."));
5171 g_object_unref (state
.zip
);
5174 gnm_pop_C_locale (locale
);
5176 if (NULL
!= state
.sst
) {
5177 unsigned i
= state
.sst
->len
;
5180 entry
= &g_array_index (state
.sst
, XLSXStr
, i
);
5181 go_string_unref (entry
->str
);
5182 go_format_unref (entry
->markup
);
5184 g_array_free (state
.sst
, TRUE
);
5186 g_hash_table_destroy (state
.pivot
.cache_by_id
);
5187 xlsx_conventions_free (state
.convs
);
5188 go_format_unref (state
.date_fmt
);
5189 g_hash_table_destroy (state
.num_fmts
);
5190 g_hash_table_destroy (state
.cell_styles
);
5191 g_hash_table_destroy (state
.shared_exprs
);
5192 xlsx_style_array_free (state
.fonts
);
5193 xlsx_style_array_free (state
.fills
);
5194 xlsx_style_array_free (state
.borders
);
5195 xlsx_style_array_free (state
.xfs
);
5196 xlsx_style_array_free (state
.style_xfs
);
5197 xlsx_style_array_free (state
.dxfs
);
5198 xlsx_style_array_free (state
.table_styles
);
5199 g_hash_table_destroy (state
.theme_colors_by_name
);
5200 g_hash_table_destroy (state
.zorder
);
5201 value_release (state
.val
);
5202 if (state
.texpr
) gnm_expr_top_unref (state
.texpr
);
5203 if (state
.comment
) g_object_unref (state
.comment
);
5204 if (state
.cur_style
) g_object_unref (state
.cur_style
);
5206 workbook_set_saveinfo (state
.wb
, GO_FILE_FL_AUTO
,
5207 go_file_saver_for_id ((state
.version
== ECMA_376_2006
) ?
5208 "Gnumeric_Excel:xlsx" :
5209 "Gnumeric_Excel:xlsx2"));
5212 /* TODO * TODO * TODO
5215 * - column widths : Don't use hard coded font size
5217 * - conditional formats
5218 * : other condition types
5219 * : check binary operators
5221 * ".xlam", "application/vnd.ms-excel.addin.macroEnabled.12" ,
5222 * ".xlsb", "application/vnd.ms-excel.sheet.binary.macroEnabled.12" ,
5223 * ".xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12" ,
5224 * ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ,
5225 * ".xltm", "application/vnd.ms-excel.template.macroEnabled.12" ,
5226 * ".xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"