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
120 GogObjectPosition compass
;
121 GogAxisPosition cross
;
123 gnm_float cross_value
;
124 gboolean invert_axis
;
127 double axis_elements
[GOG_AXIS_ELEM_MAX_ENTRY
];
128 guint8 axis_element_set
[GOG_AXIS_ELEM_MAX_ENTRY
];
138 GOIOContext
*context
; /* The IOcontext managing things */
139 WorkbookView
*wb_view
; /* View for the new workbook */
140 Workbook
*wb
; /* The new workbook */
142 Sheet
*sheet
; /* current sheet */
143 GnmCellPos pos
; /* current cell */
144 XLSXValueType pos_type
;
146 GnmExprTop
const *texpr
;
149 GHashTable
*shared_exprs
;
150 GnmConventions
*convs
;
152 SheetView
*sv
; /* current sheetview */
156 GHashTable
*num_fmts
;
158 GHashTable
*cell_styles
;
163 GPtrArray
*style_xfs
;
165 GPtrArray
*table_styles
;
166 GnmStyle
*style_accum
;
167 gboolean style_accum_partial
;
168 GnmStyleBorderType border_style
;
169 GnmColor
*border_color
;
171 GHashTable
*theme_colors_by_name
;
173 GPtrArray
*collection
; /* utility for the shared collection handlers */
175 XLSXPanePos pane_pos
;
177 GnmStyleConditions
*conditions
;
178 GSList
*cond_regions
;
182 int filter_cur_field
;
183 GSList
*filter_items
; /* an accumulator */
185 GSList
*validation_regions
;
186 GnmValidation
*validation
;
187 GnmInputMsg
*input_msg
;
189 GnmPageBreaks
*page_breaks
;
191 /* Rows/Cols state */
192 GnmStyle
*pending_rowcol_style
;
193 GnmRange pending_rowcol_range
;
197 gint64 drawing_pos
[8];
198 int drawing_pos_flags
;
199 GODrawingAnchorDir so_direction
;
200 GnmSOAnchorMode so_anchor_mode
;
201 GnmExprTop
const *link_texpr
;
203 /* Legacy drawing state */
204 double grp_offset
[4];
213 GogObject
*series_pt
;
214 gboolean series_pt_has_index
;
217 guint32 chart_color_state
;
223 unsigned int sp_type
;
225 gboolean inhibit_text_pop
;
226 gnm_float chart_pos
[4]; /* x, w, y, h */
227 gboolean chart_pos_mode
[4]; /* false: "factor", true: "edge" */
228 gboolean chart_pos_target
; /* true if "inner" */
241 Sheet
*defined_name_sheet
;
242 GList
*delayed_names
;
244 GSList
*pending_objects
;
248 Workbook
*external_ref
;
249 Sheet
*external_ref_sheet
;
253 GnmSheetSlicer
*slicer
;
254 GODataSlicerField
*slicer_field
;
256 GHashTable
*cache_by_id
;
258 GODataCacheSource
*cache_src
;
259 GODataCacheField
*cache_field
;
260 GPtrArray
*cache_field_values
;
262 unsigned int field_count
, record_count
;
263 char *cache_record_part_id
;
270 /* Document Properties */
271 GsfDocMetaData
*metadata
;
272 char *meta_prop_name
;
274 /* Rich Text handling */
276 PangoAttrList
*rich_attrs
;
277 PangoAttrList
*run_attrs
;
284 static GsfXMLInNS
const xlsx_ns
[] = {
285 GSF_XML_IN_NS (XL_NS_SS
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main"), /* Office 12 */
286 GSF_XML_IN_NS (XL_NS_SS
, "http://schemas.openxmlformats.org/spreadsheetml/2006/7/main"), /* Office 12 BETA-2 Technical Refresh */
287 GSF_XML_IN_NS (XL_NS_SS
, "http://schemas.openxmlformats.org/spreadsheetml/2006/5/main"), /* Office 12 BETA-2 */
288 GSF_XML_IN_NS (XL_NS_SS
, "http://schemas.microsoft.com/office/excel/2006/2"), /* Office 12 BETA-1 Technical Refresh */
289 GSF_XML_IN_NS (XL_NS_SS_DRAW
, "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"), /* Office 12 BETA-2 */
290 GSF_XML_IN_NS (XL_NS_SS_DRAW
, "http://schemas.openxmlformats.org/drawingml/2006/3/spreadsheetDrawing"), /* Office 12 BETA-2 Technical Refresh */
291 GSF_XML_IN_NS (XL_NS_CHART
, "http://schemas.openxmlformats.org/drawingml/2006/3/chart"), /* Office 12 BETA-2 */
292 GSF_XML_IN_NS (XL_NS_CHART
, "http://schemas.openxmlformats.org/drawingml/2006/chart"), /* Office 12 BETA-2 Technical Refresh */
293 GSF_XML_IN_NS (XL_NS_CHART_DRAW
, "http://schemas.openxmlformats.org/drawingml/2006/chartDrawing"),
294 GSF_XML_IN_NS (XL_NS_DRAW
, "http://schemas.openxmlformats.org/drawingml/2006/3/main"), /* Office 12 BETA-2 */
295 GSF_XML_IN_NS (XL_NS_DRAW
, "http://schemas.openxmlformats.org/drawingml/2006/main"), /* Office 12 BETA-2 Technical Refresh */
296 GSF_XML_IN_NS (XL_NS_GNM_EXT
, "http://www.gnumeric.org/ext/spreadsheetml"),
297 GSF_XML_IN_NS (XL_NS_DOC_REL
, "http://schemas.openxmlformats.org/officeDocument/2006/relationships"),
298 GSF_XML_IN_NS (XL_NS_PKG_REL
, "http://schemas.openxmlformats.org/package/2006/relationships"),
299 GSF_XML_IN_NS (XL_NS_LEG_OFF
, "urn:schemas-microsoft-com:office:office"),
300 GSF_XML_IN_NS (XL_NS_LEG_XL
, "urn:schemas-microsoft-com:office:excel"),
301 GSF_XML_IN_NS (XL_NS_LEG_VML
, "urn:schemas-microsoft-com:vml"),
302 GSF_XML_IN_NS (XL_NS_PROP_CP
, "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"),
303 GSF_XML_IN_NS (XL_NS_PROP_DC
, "http://purl.org/dc/elements/1.1/"),
304 GSF_XML_IN_NS (XL_NS_PROP_DCMITYPE
, "http://purl.org/dc/dcmitype"),
305 GSF_XML_IN_NS (XL_NS_PROP_DCTERMS
, "http://purl.org/dc/terms/"),
306 GSF_XML_IN_NS (XL_NS_PROP_XSI
, "http://www.w3.org/2001/XMLSchema-instance"),
307 GSF_XML_IN_NS (XL_NS_PROP
, "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"),
308 GSF_XML_IN_NS (XL_NS_PROP_VT
, "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"),
309 GSF_XML_IN_NS (XL_NS_PROP_CUSTOM
, "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"),
323 wrap_sheet_new (Workbook
*wb
, char const *name
, int columns
, int rows
)
325 Sheet
*sheet
= sheet_new_with_type (wb
, name
, GNM_SHEET_DATA
, columns
, rows
);
326 GnmPrintInformation
*pi
= sheet
->print_info
;
328 // Force a load of defaults here.
329 gnm_print_info_load_defaults (pi
);
331 // We have different defaults for header and footer (namely blank)
332 xls_header_footer_import (&pi
->header
, NULL
);
333 xls_header_footer_import (&pi
->footer
, NULL
);
340 maybe_update_progress (GsfXMLIn
*xin
)
342 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
343 GsfInput
*input
= gsf_xml_in_get_input (xin
);
344 gsf_off_t pos
= gsf_input_tell (input
);
346 go_io_value_progress_update (state
->context
, pos
);
350 start_update_progress (XLSXReadState
*state
, GsfInput
*xin
,
351 char const *message
, double min
, double max
)
353 go_io_progress_range_push (state
->context
, min
, max
);
355 go_io_value_progress_set (state
->context
,
356 gsf_input_size (xin
), 10000);
357 go_io_progress_message (state
->context
, message
);
362 end_update_progress (XLSXReadState
*state
)
364 go_io_progress_range_pop (state
->context
);
368 xlsx_parse_stream (XLSXReadState
*state
, GsfInput
*in
, GsfXMLInNode
const *dtd
)
370 gboolean success
= FALSE
;
373 GsfXMLInDoc
*doc
= gsf_xml_in_doc_new (dtd
, xlsx_ns
);
375 success
= gsf_xml_in_doc_parse (doc
, in
, state
);
378 go_io_warning (state
->context
,
379 _("'%s' is corrupt!"),
380 gsf_input_name (in
));
382 gsf_xml_in_doc_free (doc
);
389 xlsx_parse_rel_by_id (GsfXMLIn
*xin
, char const *part_id
,
390 GsfXMLInNode
const *dtd
,
391 GsfXMLInNS
const *ns
)
394 gboolean debug
= gnm_debug_flag ("xlsx-parsing");
397 g_printerr ("{ /* Parsing : %s :: %s */\n",
398 gsf_input_name (gsf_xml_in_get_input (xin
)), part_id
);
400 err
= gsf_open_pkg_parse_rel_by_id (xin
, part_id
, dtd
, ns
);
402 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
403 go_io_warning (state
->context
, "%s", err
->message
);
408 g_printerr ("} /* DONE : %s :: %s */\n",
409 gsf_input_name (gsf_xml_in_get_input (xin
)), part_id
);
412 /****************************************************************************/
414 static gboolean
xlsx_warning (GsfXMLIn
*xin
, char const *fmt
, ...)
415 G_GNUC_PRINTF (2, 3);
418 xlsx_warning (GsfXMLIn
*xin
, char const *fmt
, ...)
420 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
424 va_start (args
, fmt
);
425 msg
= g_strdup_vprintf (fmt
, args
);
428 if (IS_SHEET (state
->sheet
)) {
430 if (state
->pos
.col
>= 0 && state
->pos
.row
>= 0)
431 tmp
= g_strdup_printf ("%s!%s : %s",
432 state
->sheet
->name_quoted
,
433 cellpos_as_string (&state
->pos
), msg
);
435 tmp
= g_strdup_printf ("%s : %s",
436 state
->sheet
->name_quoted
, msg
);
441 go_io_warning (state
->context
, "%s", msg
);
442 g_printerr ("%s\n", msg
);
445 return FALSE
; /* convenience */
449 char const * const name
;
454 attr_enum (GsfXMLIn
*xin
, xmlChar
const **attrs
,
455 char const *target
, EnumVal
const *enums
,
458 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
459 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
460 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
462 if (strcmp (attrs
[0], target
))
465 for (; enums
->name
!= NULL
; enums
++)
466 if (!strcmp (enums
->name
, attrs
[1])) {
470 return xlsx_warning (xin
,
471 _("Unknown enum value '%s' for attribute %s"),
476 * Take an _int_ as a result to allow the caller to use -1 as an undefined state.
479 attr_bool (G_GNUC_UNUSED GsfXMLIn
*xin
, xmlChar
const **attrs
,
483 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
484 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
485 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
487 if (strcmp (attrs
[0], target
))
490 *res
= (0 == strcmp (attrs
[1], "1") || 0 == strcmp (attrs
[1], "true")) ;
496 attr_int (GsfXMLIn
*xin
, xmlChar
const **attrs
,
503 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
504 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
505 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
507 if (strcmp (attrs
[0], target
))
511 tmp
= strtol (attrs
[1], &end
, 10);
512 if (errno
== ERANGE
|| tmp
> G_MAXINT
|| tmp
< G_MININT
)
513 return xlsx_warning (xin
,
514 _("Integer '%s' is out of range, for attribute %s"),
517 return xlsx_warning (xin
,
518 _("Invalid integer '%s' for attribute %s"),
526 attr_uint (GsfXMLIn
*xin
, xmlChar
const **attrs
,
527 char const *target
, unsigned *res
)
532 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
533 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
534 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
536 if (strcmp (attrs
[0], target
))
540 tmp
= strtoul (attrs
[1], &end
, 10);
541 if (errno
== ERANGE
|| tmp
!= (unsigned)tmp
)
542 return xlsx_warning (xin
,
543 _("Unsigned integer '%s' is out of range, for attribute %s"),
546 return xlsx_warning (xin
,
547 _("Invalid unsigned integer '%s' for attribute %s"),
555 attr_int64 (GsfXMLIn
*xin
, xmlChar
const **attrs
,
562 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
563 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
564 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
566 if (strcmp (attrs
[0], target
))
570 tmp
= g_ascii_strtoll (attrs
[1], &end
, 10);
572 return xlsx_warning (xin
,
573 _("Integer '%s' is out of range, for attribute %s"),
576 return xlsx_warning (xin
,
577 _("Invalid integer '%s' for attribute %s"),
585 attr_gocolor (GsfXMLIn
*xin
, xmlChar
const **attrs
,
592 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
593 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
594 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
596 if (strcmp (attrs
[0], target
))
600 rgb
= strtoul (attrs
[1], &end
, 16);
601 if (errno
== ERANGE
|| *end
)
602 return xlsx_warning (xin
,
603 _("Invalid RRGGBB color '%s' for attribute %s"),
607 guint8
const r
= (rgb
>> 16) & 0xff;
608 guint8
const g
= (rgb
>> 8) & 0xff;
609 guint8
const b
= (rgb
>> 0) & 0xff;
610 *res
= GO_COLOR_FROM_RGB (r
, g
, b
);
617 attr_float (GsfXMLIn
*xin
, xmlChar
const **attrs
,
624 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
625 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
626 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
628 if (strcmp (attrs
[0], target
))
631 tmp
= gnm_strto (attrs
[1], &end
);
633 return xlsx_warning (xin
,
634 _("Invalid number '%s' for attribute %s"),
641 * Either an integer scaled so 100000 means 100%, or something like "50%"
642 * which we'll return as 50*1000.
644 * The first seems off-spec, but is what Excel produces.
647 attr_percent (GsfXMLIn
*xin
, xmlChar
const **attrs
,
648 char const *target
, int *res
)
653 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
654 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
655 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
657 if (strcmp (attrs
[0], target
))
661 tmp
= strtol (attrs
[1], &end
, 10);
662 if (errno
== ERANGE
|| tmp
> G_MAXINT
/ 1000 || tmp
< G_MININT
/ 1000)
663 return xlsx_warning (xin
,
664 _("Integer '%s' is out of range, for attribute %s"),
668 else if (strcmp (end
, "%") == 0)
671 return xlsx_warning (xin
,
672 _("Invalid integer '%s' for attribute %s"),
680 attr_pos (GsfXMLIn
*xin
, xmlChar
const **attrs
,
684 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
688 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
689 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
690 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
692 if (strcmp (attrs
[0], target
))
695 end
= cellpos_parse (attrs
[1], gnm_sheet_get_size (state
->sheet
), &tmp
, TRUE
);
696 if (NULL
== end
|| *end
!= '\0')
697 return xlsx_warning (xin
,
698 _("Invalid cell position '%s' for attribute %s"),
705 attr_range (GsfXMLIn
*xin
, xmlChar
const **attrs
,
709 static const GnmSheetSize xlsx_size
= {
710 XLSX_MaxCol
, XLSX_MaxRow
713 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
714 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
715 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
717 if (strcmp (attrs
[0], target
))
720 if (!range_parse (res
, attrs
[1], &xlsx_size
))
721 xlsx_warning (xin
, _("Invalid range '%s' for attribute %s"),
727 attr_datetime (GsfXMLIn
*xin
, xmlChar
const **attrs
,
730 unsigned y
, m
, d
, h
, mi
, n
;
731 GnmValue
*res
= NULL
;
734 g_return_val_if_fail (attrs
!= NULL
, NULL
);
735 g_return_val_if_fail (attrs
[0] != NULL
, NULL
);
736 g_return_val_if_fail (attrs
[1] != NULL
, NULL
);
738 if (strcmp (attrs
[0], target
))
741 n
= sscanf (attrs
[1], "%u-%u-%uT%u:%u:%" GNM_SCANF_g
,
742 &y
, &m
, &d
, &h
, &mi
, &s
);
746 g_date_set_dmy (&date
, d
, m
, y
);
747 if (g_date_valid (&date
)) {
748 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
749 unsigned d_serial
= go_date_g_to_serial (&date
,
750 workbook_date_conv (state
->wb
));
752 double time_frac
= h
+ (gnm_float
)mi
/ 60 + s
/ 3600;
753 res
= value_new_float (d_serial
+ time_frac
/ 24.);
754 value_set_fmt (res
, state
->date_fmt
);
756 res
= value_new_int (d_serial
);
757 value_set_fmt (res
, go_format_default_date ());
767 xlsx_parse_distance (GsfXMLIn
*xin
, xmlChar
const *str
,
768 char const *name
, gnm_float
*pts
)
773 g_return_val_if_fail (str
!= NULL
, FALSE
);
775 num
= go_strtod (CXML2C (str
), &end
);
776 if (CXML2C (str
) != end
) {
777 if (0 == strncmp (end
, "mm", 2)) {
778 num
= GO_CM_TO_PT (num
/10.);
780 } else if (0 == strncmp (end
, "cm", 2)) {
781 num
= GO_CM_TO_PT (num
);
783 } else if (0 == strncmp (end
, "pt", 2)) {
785 } else if (0 == strncmp (end
, "pc", 2)) { /* pica 12pt == 1 pica */
788 } else if (0 == strncmp (end
, "pi", 2)) { /* pica 12pt == 1 pica */
791 } else if (0 == strncmp (end
, "in", 2)) {
792 num
= GO_IN_TO_PT (num
);
795 xlsx_warning (xin
, _("Invalid attribute '%s', unknown unit '%s'"),
800 xlsx_warning (xin
, _("Invalid attribute '%s', expected distance, received '%s'"),
806 return xlsx_warning (xin
,
807 _("Invalid attribute '%s', expected distance, received '%s'"),
818 attr_distance (GsfXMLIn
*xin
, xmlChar
const **attrs
,
819 char const *target
, gnm_float
*pts
)
821 g_return_val_if_fail (attrs
!= NULL
, FALSE
);
822 g_return_val_if_fail (attrs
[0] != NULL
, FALSE
);
823 g_return_val_if_fail (attrs
[1] != NULL
, FALSE
);
825 if (strcmp (attrs
[0], target
))
828 return xlsx_parse_distance (xin
, attrs
[1], target
, pts
);
831 /***********************************************************************/
834 simple_bool (GsfXMLIn
*xin
, xmlChar
const **attrs
, int *res
)
836 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
837 if (attr_bool (xin
, attrs
, "val", res
))
843 simple_int (GsfXMLIn
*xin
, xmlChar
const **attrs
, int *res
)
845 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
846 if (attr_int (xin
, attrs
, "val", res
))
852 simple_uint (GsfXMLIn
*xin
, xmlChar
const **attrs
, unsigned *res
)
854 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
855 if (attr_uint (xin
, attrs
, "val", res
))
861 simple_float (GsfXMLIn
*xin
, xmlChar
const **attrs
, gnm_float
*res
)
863 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
864 if (attr_float (xin
, attrs
, "val", res
))
870 simple_enum (GsfXMLIn
*xin
, xmlChar
const **attrs
, EnumVal
const *enums
, int *res
)
872 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
873 if (attr_enum (xin
, attrs
, "val", enums
, res
))
879 simple_string (G_GNUC_UNUSED GsfXMLIn
*xin
, xmlChar
const **attrs
)
881 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
882 if (strcmp (attrs
[0], "val") == 0)
883 return CXML2C (attrs
[1]);
887 /***********************************************************************
888 * These indexes look like the values in xls. Dup some code from there.
889 * TODO : Can we merge the code ?
890 * Will the 'indexedColors' look like a palette ?
894 } xlsx_default_palette_v8
[] = {
895 { 0, 0, 0}, {255,255,255}, {255, 0, 0}, { 0,255, 0},
896 { 0, 0,255}, {255,255, 0}, {255, 0,255}, { 0,255,255},
898 {128, 0, 0}, { 0,128, 0}, { 0, 0,128}, {128,128, 0},
899 {128, 0,128}, { 0,128,128}, {192,192,192}, {128,128,128},
901 {153,153,255}, {153, 51,102}, {255,255,204}, {204,255,255},
902 {102, 0,102}, {255,128,128}, { 0,102,204}, {204,204,255},
904 { 0, 0,128}, {255, 0,255}, {255,255, 0}, { 0,255,255},
905 {128, 0,128}, {128, 0, 0}, { 0,128,128}, { 0, 0,255},
907 { 0,204,255}, {204,255,255}, {204,255,204}, {255,255,153},
908 {153,204,255}, {255,153,204}, {204,153,255}, {255,204,153},
910 { 51,102,255}, { 51,204,204}, {153,204, 0}, {255,204, 0},
911 {255,153, 0}, {255,102, 0}, {102,102,153}, {150,150,150},
913 { 0, 51,102}, { 51,153,102}, { 0, 51, 0}, { 51, 51, 0},
914 {153, 51, 0}, {153, 51,102}, { 51, 51,153}, { 51, 51, 51}
918 indexed_color (G_GNUC_UNUSED XLSXReadState
*state
, gint idx
)
920 /* NOTE: not documented but seems close
921 * If you find a normative reference please forward it.
923 * The color index field seems to use
924 * 8-63 = Palette index 0-55
925 * 64 = auto pattern, auto border
926 * 65 = auto background
929 * 65 is always white, and 127 always black. 64 is black
930 * if the fDefaultHdr flag in WINDOW2 is unset, otherwise it's
931 * the grid color from WINDOW2.
934 if (idx
== 1 || idx
== 65)
935 return GO_COLOR_WHITE
;
938 case 64 : /* system text ? */
939 case 81 : /* tooltip text */
940 case 0x7fff : /* system text ? */
941 return GO_COLOR_BLACK
;
944 case 65 : /* system back ? */
945 return GO_COLOR_WHITE
;
947 case 80 : /* tooltip background */
948 return GO_COLOR_YELLOW
;
950 case 2 : return GO_COLOR_RED
;
951 case 3 : return GO_COLOR_GREEN
;
952 case 4 : return GO_COLOR_BLUE
;
953 case 5 : return GO_COLOR_YELLOW
;
954 case 6 : return GO_COLOR_VIOLET
;
955 case 7 : return GO_COLOR_CYAN
;
962 if (idx
< 0 || (int) G_N_ELEMENTS (xlsx_default_palette_v8
) <= idx
) {
963 g_warning ("EXCEL: color index (%d) is out of range (8..%d). Defaulting to black",
964 idx
+ 8, (int)G_N_ELEMENTS (xlsx_default_palette_v8
) + 8);
965 return GO_COLOR_BLACK
;
968 /* TODO cache and ref */
969 return GO_COLOR_FROM_RGB (xlsx_default_palette_v8
[idx
].r
,
970 xlsx_default_palette_v8
[idx
].g
,
971 xlsx_default_palette_v8
[idx
].b
);
975 themed_color_from_name (XLSXReadState
*state
, const char *name
, GOColor
*color
)
978 gboolean dark
= FALSE
; // FIXME: refers to theme; from where?
979 static const struct {
981 const char *dark
; // Color name when theme is dark
982 const char *light
; // Color name when theme is light
984 { "tx1", "lt1", "dk1" },
985 { "tx2", "lt2", "dk2" },
986 { "bg1", "dk1", "lt1" },
987 { "bg2", "dk2", "lt2" }
991 if (g_hash_table_lookup_extended (state
->theme_colors_by_name
, name
, NULL
, &val
)) {
992 *color
= GPOINTER_TO_UINT (val
);
996 for (ui
= 0; ui
< G_N_ELEMENTS (aliases
); ui
++) {
997 if (strcmp (name
, aliases
[ui
].name
) == 0) {
998 name
= dark
? aliases
[ui
].dark
: aliases
[ui
].light
;
999 return themed_color_from_name (state
, name
, color
);
1008 themed_color (GsfXMLIn
*xin
, gint idx
)
1010 static char const * const theme_elements
[] = {
1011 "lt1", "dk1", "lt2", "dk2",
1012 "accent1", "accent2", "accent3", "accent4", "accent5", "accent6",
1015 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1018 * looks like the indicies map to hard coded names rather than the
1019 * order in the file. Indeed the order in the file seems wrong
1020 * it inverts the first to pairs
1021 * 1,0,3,2, 4,5,6.....
1022 * see: http://openxmldeveloper.org/forums/thread/1306.aspx
1023 * OOo seems to do something similar
1025 * I'll make the assumption we should work by name rather than
1027 if (idx
>= 0 && idx
< (int) G_N_ELEMENTS (theme_elements
)) {
1029 if (themed_color_from_name (state
, theme_elements
[idx
], &color
))
1032 xlsx_warning (xin
, _("Unknown theme color %d"), idx
);
1034 xlsx_warning (xin
, "Color index (%d) is out of range (0..%d). Defaulting to black",
1035 idx
, (int) G_N_ELEMENTS (theme_elements
));
1038 return GO_COLOR_BLACK
;
1042 xlsx_get_num_fmt (GsfXMLIn
*xin
, char const *id
)
1044 static char const * const std_builtins
[] = {
1056 /* 11 */ "0.00E+00",
1058 /* 13 */ "# ?""?/?""?", /* silly trick to avoid using a trigraph */
1059 /* 14 */ "mm-dd-yy",
1060 /* 15 */ "d-mmm-yy",
1063 /* 18 */ "h:mm AM/PM",
1064 /* 19 */ "h:mm:ss AM/PM",
1067 /* 22 */ "m/d/yy h:mm",
1082 /* 37 */ "#,##0 ;(#,##0)",
1083 /* 38 */ "#,##0 ;[Red](#,##0)",
1084 /* 39 */ "#,##0.00;(#,##0.00)",
1085 /* 40 */ "#,##0.00;[Red](#,##0.00)",
1091 /* 46 */ "[h]:mm:ss",
1093 /* 48 */ "##0.0E+0",
1099 27 [$
-404]e
/m
/d yyyy
"5E74"m
"6708"
1100 28 [$
-404]e
"5E74"m
"6708"d
"65E5" m
"6708"d
"65E5"
1101 29 [$
-404]e
"5E74"m
"6708"d
"65E5" m
"6708"d
"65E5"
1103 31 yyyy
"5E74"m
"6708"d
"65E5" yyyy
"5E74"m
"6708"d
"65E5"
1104 32 hh
"6642"mm
"5206" h
"65F6"mm
"5206"
1105 33 hh
"6642"mm
"5206"ss
"79D2" h
"65F6"mm
"5206"ss
"79D2"
1106 34 4E0A5348
/4E0B5348hh
"6642"mm
"5206" 4E0A5348
/4E0B5348h
"65F6"mm
"5206"
1107 35 4E0A5348
/4E0B5348hh
"6642"mm
"5206"ss
"79D2" 4E0A5348
/4E0B5348h
"65F6"mm
"5206"ss
"79D2"
1108 36 [$
-404]e
/m
/d yyyy
"5E74"m
"6708"
1109 50 [$
-404]e
/m
/d yyyy
"5E74"m
"6708"
1110 51 [$
-404]e
"5E74"m
"6708"d
"65E5" m
"6708"d
"65E5"
1111 52 4E0A5348
/4E0B5348hh
"6642"mm
"5206" yyyy
"5E74"m
"6708"
1112 53 4E0A5348
/4E0B5348hh
"6642"mm
"5206"ss
"79D2" m
"6708"d
"65E5"
1113 54 [$
-404]e
"5E74"m
"6708"d
"65E5" m
"6708"d
"65E5"
1114 55 4E0A5348
/4E0B5348hh
"6642"mm
"5206" 4E0A5348
/4E0B5348h
"65F6"mm
"5206"
1115 56 4E0A5348
/4E0B5348hh
"6642"mm
"5206"ss
"79D2" 4E0A5348
/4E0B5348h
"65F6"mm
"5206"ss
"79D2"
1116 57 [$
-404]e
/m
/d yyyy
"5E74"m
"6708"
1117 58 [$
-404]e
"5E74"m
"6708"d
"65E5" m
"6708"d
"65E5"
1120 27 [$
-411]ge
.m
.d yyyy
"5E74" mm
"6708" dd
"65E5"
1121 28 [$
-411]ggge
"5E74"m
"6708"d
"65E5" mm
-dd
1122 29 [$
-411]ggge
"5E74"m
"6708"d
"65E5" mm
-dd
1124 31 yyyy
"5E74"m
"6708"d
"65E5" yyyy
"B144" mm
"C6D4" dd
"C77C"
1125 32 h
"6642"mm
"5206" h
"C2DC" mm
"BD84"
1126 33 h
"6642"mm
"5206"ss
"79D2" h
"C2DC" mm
"BD84" ss
"CD08"
1127 34 yyyy
"5E74"m
"6708" yyyy
-mm
-dd
1128 35 m
"6708"d
"65E5" yyyy
-mm
-dd
1129 36 [$
-411]ge
.m
.d yyyy
"5E74" mm
"6708" dd
"65E5"
1130 50 [$
-411]ge
.m
.d yyyy
"5E74" mm
"6708" dd
"65E5"
1131 51 [$
-411]ggge
"5E74"m
"6708"d
"65E5" mm
-dd
1132 52 yyyy
"5E74"m
"6708" yyyy
-mm
-dd
1133 53 m
"6708"d
"65E5" yyyy
-mm
-dd
1134 54 [$
-411]ggge
"5E74"m
"6708"d
"65E5" mm
-dd
1135 55 yyyy
"5E74"m
"6708" yyyy
-mm
-dd
1136 56 m
"6708"d
"65E5" yyyy
-mm
-dd
1137 57 [$
-411]ge
.m
.d yyyy
"5E74" mm
"6708" dd
"65E5"
1138 58 [$
-411]ggge
"5E74"m
"6708"d
"65E5" mm
-dd
1148 70 "t# ?""?/?""?" /* silly trick to avoid using a trigraph */
1149 71 0E27
/0E14
/0E1B0E1B0E1B0E1B
1150 72 0E27
-0E140E140E14
-0E1B0E1B
1151 73 0E27
-0E140E140E14
1152 74 0E140E140E14
-0E1B0E1B
1154 76 0E0A
:0E190E19
:0E170E17
1155 77 0E27
/0E14
/0E1B0E1B0E1B0E1B
0E0A
:0E190E19
1156 78 0E190E19
:0E170E17
1157 79 [0E0A
]:0E190E19
:0E170E17
1158 80 0E190E19
:0E170E17
.0
1162 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1163 GOFormat
*res
= g_hash_table_lookup (state
->num_fmts
, id
);
1171 i
= strtol (id
, &end
, 10);
1172 if (end
!= id
&& *end
== '\0' &&
1173 i
>= 0 && i
< (int) G_N_ELEMENTS (std_builtins
) &&
1174 std_builtins
[i
] != NULL
) {
1175 res
= go_format_new_from_XL (std_builtins
[i
]);
1176 g_hash_table_replace (state
->num_fmts
, g_strdup (id
), res
);
1178 xlsx_warning (xin
, _("Undefined number format id '%s'"), id
);
1182 static GnmExprTop
const *
1183 xlsx_parse_expr (GsfXMLIn
*xin
, xmlChar
const *expr_str
,
1184 GnmParsePos
const *pp
)
1186 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1188 GnmExprTop
const *texpr
;
1190 /* Odd, some time IF and CHOOSE show up with leading spaces ??
1193 * I wonder if it is related to some of the funky old
1194 * optimizations in * xls ? */
1195 while (' ' == *expr_str
)
1198 texpr
= gnm_expr_parse_str (expr_str
, pp
,
1199 GNM_EXPR_PARSE_DEFAULT
, state
->convs
,
1200 parse_error_init (&err
));
1202 xlsx_warning (xin
, "At %s: '%s' %s",
1203 parsepos_as_string (pp
),
1204 expr_str
, err
.err
->message
);
1205 parse_error_free (&err
);
1210 /* Returns: a GSList of GnmRange in _reverse_ order
1211 * caller frees the list and the content */
1213 xlsx_parse_sqref (GsfXMLIn
*xin
, xmlChar
const *refs
)
1215 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1220 while (NULL
!= refs
&& *refs
) {
1221 if (NULL
== (tmp
= cellpos_parse (refs
, gnm_sheet_get_size (state
->sheet
), &r
.start
, FALSE
))) {
1222 xlsx_warning (xin
, "unable to parse reference list '%s'", refs
);
1227 if (*refs
== '\0' || *refs
== ' ')
1229 else if (*refs
!= ':' ||
1230 NULL
== (tmp
= cellpos_parse (refs
+ 1, gnm_sheet_get_size (state
->sheet
), &r
.end
, FALSE
))) {
1231 xlsx_warning (xin
, "unable to parse reference list '%s'", refs
);
1235 range_normalize (&r
); /* be anal */
1236 res
= g_slist_prepend (res
, gnm_range_dup (&r
));
1238 for (refs
= tmp
; *refs
== ' ' ; refs
++ ) ;
1244 /***********************************************************************/
1246 #include "xlsx-read-pivot.c"
1248 /***********************************************************************/
1250 static void xlsx_ext_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
);
1251 static void xlsx_ext_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
);
1253 #include "xlsx-read-color.c"
1254 #include "xlsx-read-drawing.c"
1256 /***********************************************************************/
1259 elem_color (GsfXMLIn
*xin
, xmlChar
const **attrs
, gboolean allow_alpha
)
1261 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1263 GOColor c
= GO_COLOR_BLACK
;
1264 gnm_float tint
= 0.;
1265 gboolean has_color
= FALSE
;
1267 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
1268 if (0 == strcmp (attrs
[0], "rgb")) {
1270 if (4 != sscanf (attrs
[1], "%02x%02x%02x%02x", &a
, &r
, &g
, &b
)) {
1272 _("Invalid color '%s' for attribute rgb"),
1277 c
= GO_COLOR_FROM_RGBA (r
,g
,b
,a
);
1278 } else if (attr_int (xin
, attrs
, "indexed", &indx
)) {
1280 c
= indexed_color (state
, indx
);
1281 } else if (attr_int (xin
, attrs
, "theme", &indx
)) {
1283 c
= themed_color (xin
, indx
);
1284 } else if (attr_float (xin
, attrs
, "tint", &tint
))
1290 c
= gnm_go_color_apply_tint (c
, tint
);
1292 c
= GO_COLOR_CHANGE_A (c
, 0xFF);
1293 return gnm_color_new_go (c
);
1297 xlsx_get_style_xf (GsfXMLIn
*xin
, int xf
)
1299 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1300 if (0 <= xf
&& NULL
!= state
->style_xfs
&& xf
< (int)state
->style_xfs
->len
)
1301 return g_ptr_array_index (state
->style_xfs
, xf
);
1302 xlsx_warning (xin
, _("Undefined style record '%d'"), xf
);
1306 xlsx_get_xf (GsfXMLIn
*xin
, int xf
)
1308 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1309 if (0 <= xf
&& NULL
!= state
->xfs
&& xf
< (int)state
->xfs
->len
)
1310 return g_ptr_array_index (state
->xfs
, xf
);
1311 xlsx_warning (xin
, _("Undefined style record '%d'"), xf
);
1315 xlsx_get_dxf (GsfXMLIn
*xin
, int dxf
)
1317 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1318 if (0 <= dxf
&& NULL
!= state
->dxfs
&& dxf
< (int)state
->dxfs
->len
)
1319 return g_ptr_array_index (state
->dxfs
, dxf
);
1320 xlsx_warning (xin
, _("Undefined partial style record '%d'"), dxf
);
1324 /****************************************************************************/
1327 xlsx_cell_val_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1329 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1330 XLSXStr
const *entry
;
1334 switch (state
->pos_type
) {
1335 case XLXS_TYPE_NUM
:
1336 if (*xin
->content
->str
)
1337 state
->val
= value_new_float (gnm_strto (xin
->content
->str
, &end
));
1339 case XLXS_TYPE_SST_STR
:
1340 i
= xlsx_relaxed_strtol (xin
->content
->str
, &end
, 10);
1341 if (end
!= xin
->content
->str
&& *end
== '\0' &&
1342 0 <= i
&& i
< (int)state
->sst
->len
) {
1343 entry
= &g_array_index (state
->sst
, XLSXStr
, i
);
1344 go_string_ref (entry
->str
);
1345 state
->val
= value_new_string_str (entry
->str
);
1346 if (NULL
!= entry
->markup
)
1347 value_set_fmt (state
->val
, entry
->markup
);
1349 xlsx_warning (xin
, _("Invalid sst ref '%s'"), xin
->content
->str
);
1352 case XLXS_TYPE_BOOL
:
1353 if (*xin
->content
->str
)
1354 state
->val
= value_new_bool (*xin
->content
->str
!= '0');
1356 case XLXS_TYPE_ERR
:
1357 if (*xin
->content
->str
)
1358 state
->val
= value_new_error (NULL
, xin
->content
->str
);
1361 case XLXS_TYPE_STR2
: /* What is this ? */
1362 case XLXS_TYPE_INLINE_STR
:
1363 state
->val
= value_new_string (xin
->content
->str
);
1366 g_warning ("Unknown val type %d", state
->pos_type
);
1371 xlsx_cell_inline_text_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1373 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1374 go_string_append_gstring (state
->r_text
, xin
->content
);
1379 xlsx_cell_inline_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1381 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1383 state
->r_text
= g_string_new ("");
1387 xlsx_cell_inline_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1389 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1391 state
->val
= value_new_string_nocopy (g_string_free (state
->r_text
, FALSE
));
1392 state
->r_text
= NULL
;
1394 if (state
->rich_attrs
) {
1395 GOFormat
*fmt
= go_format_new_markup (state
->rich_attrs
, FALSE
);
1396 state
->rich_attrs
= NULL
;
1397 value_set_fmt (state
->val
, fmt
);
1398 go_format_unref (fmt
);
1404 xlsx_cell_expr_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1406 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1407 gboolean has_range
= FALSE
, is_array
= FALSE
, is_shared
= FALSE
;
1409 xmlChar
const *shared_id
= NULL
;
1411 /* See https://bugzilla.gnome.org/show_bug.cgi?id=642850 */
1412 /* for some of the issues surrounding shared formulas. */
1414 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
1415 if (0 == strcmp (attrs
[0], "t")) {
1416 if (0 == strcmp (attrs
[1], "array"))
1418 else if (0 == strcmp (attrs
[1], "shared"))
1420 } else if (0 == strcmp (attrs
[0], "si"))
1421 shared_id
= attrs
[1];
1422 else if (attr_range (xin
, attrs
, "ref", &range
))
1425 state
->shared_id
= NULL
;
1426 if (is_shared
&& NULL
!= shared_id
) {
1428 state
->texpr
= g_hash_table_lookup (state
->shared_exprs
, shared_id
);
1429 if (NULL
!= state
->texpr
)
1430 gnm_expr_top_ref (state
->texpr
);
1432 state
->shared_id
= g_strdup (shared_id
);
1434 state
->texpr
= NULL
;
1436 /* if the shared expr is already parsed expression do not even collect content */
1437 ((GsfXMLInNode
*)(xin
->node
))->has_content
=
1438 (NULL
!= state
->texpr
) ? GSF_XML_NO_CONTENT
: GSF_XML_CONTENT
;
1440 if (is_array
&& has_range
)
1441 state
->array
= range
;
1445 xlsx_cell_expr_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1447 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1450 if (NULL
== state
->texpr
) {
1451 parse_pos_init (&pp
, NULL
, state
->sheet
,
1452 state
->pos
.col
, state
->pos
.row
);
1453 state
->texpr
= xlsx_parse_expr (xin
, xin
->content
->str
, &pp
);
1454 if (NULL
!= state
->texpr
&&
1455 NULL
!= state
->shared_id
) {
1456 gnm_expr_top_ref (state
->texpr
);
1457 g_hash_table_replace (state
->shared_exprs
,
1458 state
->shared_id
, (gpointer
)state
->texpr
);
1459 state
->shared_id
= NULL
;
1462 g_free (state
->shared_id
);
1463 state
->shared_id
= NULL
;
1467 xlsx_cell_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1469 static EnumVal
const types
[] = {
1470 { "n", XLXS_TYPE_NUM
},
1471 { "s", XLXS_TYPE_SST_STR
},
1472 { "str", XLXS_TYPE_STR2
},
1473 { "b", XLXS_TYPE_BOOL
},
1474 { "inlineStr", XLXS_TYPE_INLINE_STR
},
1475 { "e", XLXS_TYPE_ERR
},
1478 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1480 GnmStyle
*style
= NULL
;
1482 state
->pos
.col
= state
->pos
.row
= -1;
1483 state
->pos_type
= XLXS_TYPE_NUM
; /* the default */
1485 state
->texpr
= NULL
;
1486 range_init (&state
->array
, -1, -1, -1, -1); /* invalid */
1488 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
1489 if (attr_pos (xin
, attrs
, "r", &state
->pos
)) ;
1490 else if (attr_enum (xin
, attrs
, "t", types
, &tmp
))
1491 state
->pos_type
= tmp
;
1492 else if (attr_int (xin
, attrs
, "s", &tmp
))
1493 style
= xlsx_get_xf (xin
, tmp
);
1495 if (NULL
!= style
) {
1496 gnm_style_ref (style
);
1497 /* There may already be a row style set!*/
1498 sheet_style_apply_pos (state
->sheet
,
1499 state
->pos
.col
, state
->pos
.row
, style
);
1503 xlsx_cell_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1505 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1508 if (state
->texpr
== NULL
&& state
->val
== NULL
) {
1509 /* A cell with only style. */
1513 cell
= sheet_cell_fetch (state
->sheet
, state
->pos
.col
, state
->pos
.row
);
1516 xlsx_warning (xin
, _("Invalid cell %s"),
1517 cellpos_as_string (&state
->pos
));
1518 value_release (state
->val
);
1519 if (NULL
!= state
->texpr
)
1520 gnm_expr_top_unref (state
->texpr
);
1521 } else if (NULL
!= state
->texpr
) {
1522 if (state
->array
.start
.col
>= 0) {
1523 gnm_cell_set_array (state
->sheet
,
1526 gnm_expr_top_unref (state
->texpr
);
1527 if (NULL
!= state
->val
)
1528 gnm_cell_assign_value (cell
, state
->val
);
1529 } else if (NULL
!= state
->val
) {
1530 gnm_cell_set_expr_and_value (cell
,
1531 state
->texpr
, state
->val
, TRUE
);
1532 gnm_expr_top_unref (state
->texpr
);
1534 gnm_cell_set_expr (cell
, state
->texpr
);
1535 gnm_expr_top_unref (state
->texpr
);
1537 } else if (NULL
!= state
->val
)
1538 gnm_cell_assign_value (cell
, state
->val
);
1540 state
->texpr
= NULL
;
1545 xlsx_CT_Row (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1547 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1548 int row
= -1, xf_index
;
1550 int cust_fmt
= FALSE
, cust_height
= FALSE
, collapsed
= FALSE
;
1553 GnmStyle
*style
= NULL
;
1555 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
1556 if (attr_int (xin
, attrs
, "r", &row
))
1558 else if (attr_float (xin
, attrs
, "ht", &h
))
1560 else if (attr_bool (xin
, attrs
, "customFormat", &cust_fmt
))
1562 else if (attr_bool (xin
, attrs
, "customHeight", &cust_height
))
1564 else if (attr_int (xin
, attrs
, "s", &xf_index
))
1565 style
= xlsx_get_xf (xin
, xf_index
);
1566 else if (attr_int (xin
, attrs
, "outlineLevel", &outline
))
1568 else if (attr_bool (xin
, attrs
, "hidden", &hidden
))
1570 else if (attr_bool (xin
, attrs
, "collapsed", &collapsed
))
1577 sheet_row_set_size_pts (state
->sheet
, row
, h
, cust_height
);
1579 colrow_set_visibility (state
->sheet
, FALSE
, FALSE
, row
, row
);
1581 col_row_info_set_outline (sheet_row_fetch (state
->sheet
, row
),
1582 outline
, collapsed
);
1584 if (NULL
!= style
&& cust_fmt
) {
1586 r
.start
.row
= r
.end
.row
= row
;
1588 r
.end
.col
= gnm_sheet_get_max_cols (state
->sheet
) - 1;
1589 gnm_style_ref (style
);
1590 sheet_style_set_range (state
->sheet
, &r
, style
);
1594 maybe_update_progress (xin
);
1598 xlsx_CT_RowsCols_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
1600 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1602 if (!state
->pending_rowcol_style
)
1605 sheet_style_set_range (state
->sheet
,
1606 &state
->pending_rowcol_range
,
1607 state
->pending_rowcol_style
);
1609 state
->pending_rowcol_style
= NULL
;
1611 maybe_update_progress (xin
);
1615 xlsx_CT_Col (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1617 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1618 int first
= -1, last
= -1, xf_index
;
1620 gboolean cust_width
= FALSE
, best_fit
= FALSE
, collapsed
= FALSE
;
1623 GnmStyle
*style
= NULL
;
1625 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
1626 if (attr_int (xin
, attrs
, "min", &first
))
1628 else if (attr_int (xin
, attrs
, "max", &last
))
1630 else if (attr_float (xin
, attrs
, "width", &width
))
1631 /* FIXME FIXME FIXME arbitrary map from 130 pixels to
1632 * the value stored for a column with 130 pixel width*/
1633 width
*= (130. / 18.5703125) * (72./96.);
1634 else if (attr_bool (xin
, attrs
, "customWidth", &cust_width
))
1636 else if (attr_bool (xin
, attrs
, "bestFit", &best_fit
))
1638 else if (attr_int (xin
, attrs
, "style", &xf_index
))
1639 style
= xlsx_get_xf (xin
, xf_index
);
1640 else if (attr_int (xin
, attrs
, "outlineLevel", &outline
))
1642 else if (attr_bool (xin
, attrs
, "hidden", &hidden
))
1644 else if (attr_bool (xin
, attrs
, "collapsed", &collapsed
))
1650 xlsx_warning (xin
, _("Ignoring column information that does not specify first or last."));
1654 } else if (last
< 0)
1661 first
= CLAMP (first
, 0, gnm_sheet_get_last_col (state
->sheet
));
1662 last
= CLAMP (last
, 0, gnm_sheet_get_last_col (state
->sheet
));
1664 for (i
= first
; i
<= last
; i
++) {
1666 sheet_col_set_size_pts (state
->sheet
, i
, width
,
1667 cust_width
&& !best_fit
);
1669 col_row_info_set_outline (sheet_col_fetch (state
->sheet
, i
),
1670 outline
, collapsed
);
1672 if (NULL
!= style
) {
1674 range_init_cols (&r
, state
->sheet
, first
, last
);
1677 * Sometimes we see a lot of columns with the same style.
1678 * We delay applying the style because applying column
1679 * by column leads to style fragmentation. #622365
1682 if (style
!= state
->pending_rowcol_style
||
1683 state
->pending_rowcol_range
.start
.row
!= r
.start
.row
||
1684 state
->pending_rowcol_range
.end
.row
!= r
.end
.row
||
1685 state
->pending_rowcol_range
.end
.col
+ 1 != r
.start
.col
)
1686 xlsx_CT_RowsCols_end (xin
, NULL
);
1688 if (state
->pending_rowcol_style
)
1689 state
->pending_rowcol_range
.end
.col
= r
.end
.col
;
1691 gnm_style_ref (style
);
1692 state
->pending_rowcol_style
= style
;
1693 state
->pending_rowcol_range
= r
;
1697 colrow_set_visibility (state
->sheet
, TRUE
, FALSE
, first
, last
);
1701 xlsx_CT_SheetPr (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
1704 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1705 <xsd
:attribute name
="syncHorizontal" type
="xsd:boolean" use
="optional" default="false">
1706 <xsd
:attribute name
="syncVertical" type
="xsd:boolean" use
="optional" default="false">
1707 <xsd
:attribute name
="syncRef" type
="ST_Ref" use
="optional">
1708 <xsd
:attribute name
="transitionEvaluation" type
="xsd:boolean" use
="optional" default="false">
1709 <xsd
:attribute name
="transitionEntry" type
="xsd:boolean" use
="optional" default="false">
1710 <xsd
:attribute name
="published" type
="xsd:boolean" use
="optional" default="true">
1711 <xsd
:attribute name
="codeName" type
="xsd:string" use
="optional">
1712 <xsd
:attribute name
="filterMode" type
="xsd:boolean" use
="optional" default="false">
1713 <xsd
:attribute name
="enableFormatConditionsCalculation" type
="xsd:boolean" use
="optional" default="true">
1718 xlsx_sheet_tab_fgbg (GsfXMLIn
*xin
, xmlChar
const **attrs
, gboolean fg
)
1720 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1721 GnmColor
*color
= elem_color (xin
, attrs
, TRUE
);
1723 g_object_set (state
->sheet
,
1724 (fg
? "tab-foreground" : "tab-background"), color
,
1726 style_color_unref (color
);
1731 xlsx_sheet_tabcolor (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1733 xlsx_sheet_tab_fgbg (xin
, attrs
, FALSE
);
1737 xlsx_ext_tabtextcolor (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1739 xlsx_sheet_tab_fgbg (xin
, attrs
, TRUE
);
1743 xlsx_sheet_page_setup (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
1745 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1746 GnmPrintInformation
*pi
= state
->sheet
->print_info
;
1749 if (pi
->page_setup
== NULL
)
1750 gnm_print_info_load_defaults (pi
);
1752 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
1753 if (attr_bool (xin
, attrs
, "fitToPage", &tmp
))
1754 pi
->scaling
.type
= tmp
? PRINT_SCALE_FIT_PAGES
: PRINT_SCALE_PERCENTAGE
;
1759 xlsx_CT_SheetFormatPr (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1761 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1765 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
1766 if (attr_float (xin
, attrs
, "defaultRowHeight", &h
))
1767 sheet_row_set_default_size_pts (state
->sheet
, h
);
1768 else if (attr_int (xin
, attrs
, "outlineLevelRow", &i
)) {
1770 sheet_colrow_gutter (state
->sheet
, FALSE
, i
);
1771 } else if (attr_int (xin
, attrs
, "outlineLevelCol", &i
)) {
1773 sheet_colrow_gutter (state
->sheet
, TRUE
, i
);
1778 static GtkPaperSize
*
1779 xlsx_paper_size (gdouble width
, gdouble height
, GtkUnit unit
, int code
)
1783 gchar
*display_name
;
1786 name
= g_strdup_printf ("xlsx_%ix%i", (int)width
, (int)height
);
1787 display_name
= g_strdup_printf (_("Paper from XLSX file: %ipt\xE2\xA8\x89%ipt"),
1788 (int)width
, (int)height
);
1790 name
= g_strdup_printf ("xlsx_%i", code
);
1791 display_name
= g_strdup_printf (_("Paper from XLSX file, #%i"), code
);
1793 size
= gtk_paper_size_new_custom (name
, display_name
, width
, height
, unit
);
1795 g_free (display_name
);
1800 xlsx_set_paper_from_code (GnmPrintInformation
*pi
, int code
)
1802 XLSXPaperDefs paper
[] =
1803 {{ 0 , 0 , 0 , GTK_UNIT_MM
, NULL
},
1804 { 1 , 8.5 , 11 , GTK_UNIT_INCH
, GTK_PAPER_NAME_LETTER
},
1805 { 2 , 8.5 , 11 , GTK_UNIT_INCH
, GTK_PAPER_NAME_LETTER
},
1806 { 3 , 11 , 17 , GTK_UNIT_INCH
, "na_ledger_11x17in" },
1807 { 4 , 17 , 11 , GTK_UNIT_INCH
, NULL
},
1808 { 5 , 8.5 , 14 , GTK_UNIT_INCH
, GTK_PAPER_NAME_LEGAL
},
1809 { 6 , 5.5 , 8.5 , GTK_UNIT_INCH
, "na_invoice_5.5x8.5in" },
1810 { 7 , 7.25 , 10.5 , GTK_UNIT_INCH
, GTK_PAPER_NAME_EXECUTIVE
},
1811 { 8 , 297 , 420 , GTK_UNIT_MM
, GTK_PAPER_NAME_A3
},
1812 { 9 , 210 , 297 , GTK_UNIT_MM
, GTK_PAPER_NAME_A4
},
1813 { 10 , 210 , 297 , GTK_UNIT_MM
, GTK_PAPER_NAME_A4
},
1814 { 11 , 148 , 210 , GTK_UNIT_MM
, GTK_PAPER_NAME_A5
},
1815 { 12 , 250 , 353 , GTK_UNIT_MM
, "iso_b4_250x353mm" },
1816 { 13 , 176 , 250 , GTK_UNIT_MM
, GTK_PAPER_NAME_B5
},
1817 { 14 , 8.5 , 13 , GTK_UNIT_INCH
, "na_foolscap_8.5x13in" },
1818 { 15 , 215 , 275 , GTK_UNIT_MM
, NULL
},
1819 { 16 , 10 , 14 , GTK_UNIT_INCH
, "na_10x14_10x14in" },
1820 { 17 , 11 , 17 , GTK_UNIT_INCH
, "na_ledger_11x17in" },
1821 { 18 , 8.5 , 11 , GTK_UNIT_INCH
, GTK_PAPER_NAME_LETTER
},
1822 { 19 , 3.875 , 8.875 , GTK_UNIT_INCH
, "na_number-9_3.875x8.875in" },
1823 { 20 , 4.125 , 9.5 , GTK_UNIT_INCH
, "na_number-10_4.125x9.5in" },
1824 { 21 , 4.5 , 10.375 , GTK_UNIT_INCH
, "na_number-11_4.5x10.375in" },
1825 { 22 , 4.75 , 11 , GTK_UNIT_INCH
, "na_number-12_4.75x11in" },
1826 { 23 , 5 , 11.5 , GTK_UNIT_INCH
, "na_number-14_5x11.5in" },
1827 { 24 , 17 , 22 , GTK_UNIT_INCH
, "na_c_17x22in" },
1828 { 25 , 22 , 34 , GTK_UNIT_INCH
, "na_d_22x34in" },
1829 { 26 , 34 , 44 , GTK_UNIT_INCH
, "na_e_34x44in" },
1830 { 27 , 110 , 220 , GTK_UNIT_MM
, "iso_dl_110x220mm" },
1831 { 28 , 162 , 229 , GTK_UNIT_MM
, "iso_c5_162x229mm" },
1832 { 29 , 324 , 458 , GTK_UNIT_MM
, "iso_c3_324x458mm" },
1833 { 30 , 229 , 324 , GTK_UNIT_MM
, "iso_c4_229x324mm" },
1834 { 31 , 114 , 162 , GTK_UNIT_MM
, "iso_c6_114x162mm" },
1835 { 32 , 114 , 229 , GTK_UNIT_MM
, "iso_c6c5_114x229mm" },
1836 { 33 , 250 , 353 , GTK_UNIT_MM
, "iso_b4_250x353mm" },
1837 { 34 , 176 , 250 , GTK_UNIT_MM
, GTK_PAPER_NAME_B5
},
1838 { 35 , 176 , 125 , GTK_UNIT_MM
, NULL
},
1839 { 36 , 110 , 230 , GTK_UNIT_MM
, "om_italian_110x230mm" },
1840 { 37 , 3.875 , 7.5 , GTK_UNIT_INCH
, "na_monarch_3.875x7.5in" },
1841 { 38 , 3.625 , 6.5 , GTK_UNIT_INCH
, "na_personal_3.625x6.5in" },
1842 { 39 , 14.875 , 11 , GTK_UNIT_INCH
, NULL
},
1843 { 40 , 8.5 , 12 , GTK_UNIT_INCH
, "na_fanfold-eur_8.5x12in" },
1844 { 41 , 8.5 , 13 , GTK_UNIT_INCH
, "na_foolscap_8.5x13in" },
1845 { 42 , 250 , 353 , GTK_UNIT_MM
, "iso_b4_250x353mm" },
1846 { 43 , 200 , 148 , GTK_UNIT_MM
, NULL
},
1847 { 44 , 9 , 11 , GTK_UNIT_INCH
, "na_9x11_9x11in" },
1848 { 45 , 10 , 11 , GTK_UNIT_INCH
, "na_10x11_10x11in" },
1849 { 46 , 15 , 11 , GTK_UNIT_INCH
, NULL
},
1850 { 47 , 220 , 220 , GTK_UNIT_MM
, "om_invite_220x220mm" },
1851 { 48 , 0 , 0 , GTK_UNIT_MM
, NULL
},
1852 { 49 , 0 , 0 , GTK_UNIT_MM
, NULL
},
1853 { 50 , 9.275 , 12 , GTK_UNIT_INCH
, NULL
},
1854 { 51 , 9.275 , 15 , GTK_UNIT_INCH
, NULL
},
1855 { 52 , 11.69 , 18 , GTK_UNIT_INCH
, NULL
},
1856 { 53 , 236 , 322 , GTK_UNIT_MM
, "iso_a4-extra_235.5x322.3" },
1857 { 54 , 8.275 , 11 , GTK_UNIT_INCH
, NULL
},
1858 { 55 , 210 , 297 , GTK_UNIT_MM
, GTK_PAPER_NAME_A4
},
1859 { 56 , 9.275 , 12 , GTK_UNIT_INCH
, NULL
},
1860 { 57 , 227 , 356 , GTK_UNIT_MM
, NULL
},
1861 { 58 , 305 , 487 , GTK_UNIT_MM
, NULL
},
1862 { 59 , 8.5 , 12.69 , GTK_UNIT_INCH
, "na_letter-plus_8.5x12.69in" },
1863 { 60 , 210 , 330 , GTK_UNIT_MM
, "om_folio_210x330mm" },
1864 { 61 , 148 , 210 , GTK_UNIT_MM
, GTK_PAPER_NAME_A5
},
1865 { 62 , 182 , 257 , GTK_UNIT_MM
, "jis_b5_182x257mm" },
1866 { 63 , 322 , 445 , GTK_UNIT_MM
, "iso_a3-extra_322x445mm" },
1867 { 64 , 174 , 235 , GTK_UNIT_MM
, "iso_a5-extra_174x235mm" },
1868 { 65 , 201 , 276 , GTK_UNIT_MM
, "iso_b5-extra_201x276mm" },
1869 { 66 , 420 , 594 , GTK_UNIT_MM
, "iso_a2_420x594mm" },
1870 { 67 , 297 , 420 , GTK_UNIT_MM
, GTK_PAPER_NAME_A3
},
1871 { 68 , 322 , 445 , GTK_UNIT_MM
, "iso_a3-extra_322x445mm" },
1872 { 69 , 200 , 148 , GTK_UNIT_MM
, NULL
},
1873 { 70 , 105 , 148 , GTK_UNIT_MM
, "iso_a6_105x148mm" },
1874 { 71 , 240 , 332 , GTK_UNIT_MM
, "jpn_kaku2_240x332mm" },
1875 { 72 , 216 , 277 , GTK_UNIT_MM
, NULL
},
1876 { 73 , 120 , 235 , GTK_UNIT_MM
, "jpn_chou3_120x235mm" },
1877 { 74 , 90 , 205 , GTK_UNIT_MM
, "jpn_chou4_90x205mm" },
1878 { 75 , 11 , 8.5 , GTK_UNIT_INCH
, NULL
},
1879 { 76 , 420 , 297 , GTK_UNIT_MM
, NULL
},
1880 { 77 , 297 , 210 , GTK_UNIT_MM
, NULL
},
1881 { 78 , 210 , 148 , GTK_UNIT_MM
, NULL
},
1882 { 79 , 364 , 257 , GTK_UNIT_MM
, NULL
},
1883 { 80 , 257 , 182 , GTK_UNIT_MM
, NULL
},
1884 { 81 , 148 , 100 , GTK_UNIT_MM
, NULL
},
1885 { 82 , 148 , 200 , GTK_UNIT_MM
, "jpn_oufuku_148x200mm" },
1886 { 83 , 148 , 105 , GTK_UNIT_MM
, NULL
},
1887 { 84 , 332 , 240 , GTK_UNIT_MM
, NULL
},
1888 { 85 , 277 , 216 , GTK_UNIT_MM
, NULL
},
1889 { 86 , 235 , 120 , GTK_UNIT_MM
, NULL
},
1890 { 87 , 205 , 90 , GTK_UNIT_MM
, NULL
},
1891 { 88 , 128 , 182 , GTK_UNIT_MM
, "jis_b6_128x182mm" },
1892 { 89 , 182 , 128 , GTK_UNIT_MM
, NULL
},
1893 { 90 , 12 , 11 , GTK_UNIT_INCH
, NULL
},
1894 { 91 , 235 , 105 , GTK_UNIT_MM
, NULL
},
1895 { 92 , 105 , 235 , GTK_UNIT_MM
, "jpn_you4_105x235mm" },
1896 { 93 , 146 , 215 , GTK_UNIT_MM
, "prc_16k_146x215mm" },
1897 { 94 , 97 , 151 , GTK_UNIT_MM
, "prc_32k_97x151mm" },
1898 { 95 , 97 , 151 , GTK_UNIT_MM
, "prc_32k_97x151mm" },
1899 { 96 , 102 , 165 , GTK_UNIT_MM
, "prc_1_102x165mm" },
1900 { 97 , 102 , 176 , GTK_UNIT_MM
, "prc_2_102x176mm" },
1901 { 98 , 125 , 176 , GTK_UNIT_MM
, "prc_3_125x176mm" },
1902 { 99 , 110 , 208 , GTK_UNIT_MM
, "prc_4_110x208mm" },
1903 { 100 , 110 , 220 , GTK_UNIT_MM
, "prc_5_110x220mm" },
1904 { 101 , 120 , 230 , GTK_UNIT_MM
, "prc_6_120x230mm" },
1905 { 102 , 160 , 230 , GTK_UNIT_MM
, "prc_7_160x230mm" },
1906 { 103 , 120 , 309 , GTK_UNIT_MM
, "prc_8_120x309mm" },
1907 { 104 , 229 , 324 , GTK_UNIT_MM
, "iso_c4_229x324mm" },
1908 { 105 , 324 , 458 , GTK_UNIT_MM
, "prc_10_324x458mm" },
1909 { 106 , 215 , 146 , GTK_UNIT_MM
, NULL
},
1910 { 107 , 151 , 97 , GTK_UNIT_MM
, NULL
},
1911 { 108 , 151 , 97 , GTK_UNIT_MM
, NULL
},
1912 { 109 , 165 , 102 , GTK_UNIT_MM
, NULL
},
1913 { 110 , 176 , 102 , GTK_UNIT_MM
, NULL
},
1914 { 111 , 176 , 125 , GTK_UNIT_MM
, NULL
},
1915 { 112 , 208 , 110 , GTK_UNIT_MM
, NULL
},
1916 { 113 , 220 , 110 , GTK_UNIT_MM
, NULL
},
1917 { 114 , 230 , 120 , GTK_UNIT_MM
, NULL
},
1918 { 115 , 230 , 160 , GTK_UNIT_MM
, NULL
},
1919 { 116 , 309 , 120 , GTK_UNIT_MM
, NULL
},
1920 { 117 , 324 , 229 , GTK_UNIT_MM
, NULL
},
1921 { 118 , 458 , 324 , GTK_UNIT_MM
, NULL
}};
1923 if (code
< 1 || ((guint
) code
) >= G_N_ELEMENTS (paper
) || paper
[code
].code
== 0)
1925 g_return_val_if_fail (paper
[code
].code
== code
, FALSE
);
1927 if (paper
[code
].name
!= NULL
) {
1928 GtkPaperSize
*ps
= gtk_paper_size_new (paper
[code
].name
);
1930 gtk_page_setup_set_paper_size (pi
->page_setup
, ps
);
1934 if (paper
[code
].width
> 0.0 && paper
[code
].height
> 0.0) {
1935 GtkPaperSize
*ps
= xlsx_paper_size (paper
[code
].width
, paper
[code
].height
, paper
[code
].unit
, code
);
1937 gtk_page_setup_set_paper_size (pi
->page_setup
, ps
);
1946 xlsx_CT_PageSetup (GsfXMLIn
*xin
, xmlChar
const **attrs
)
1948 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
1949 GnmPrintInformation
*pi
= state
->sheet
->print_info
;
1950 int orient
, paper_code
= 0, scale
, tmp_int
;
1951 gboolean orient_set
= FALSE
, first_page_number
= TRUE
, tmp_bool
;
1952 gnm_float width
= 0., height
= 0.;
1953 static EnumVal
const orientation_types
[] = {
1954 { "default", GTK_PAGE_ORIENTATION_PORTRAIT
},
1955 { "portrait", GTK_PAGE_ORIENTATION_PORTRAIT
},
1956 { "landscape", GTK_PAGE_ORIENTATION_LANDSCAPE
},
1959 static EnumVal
const comment_types
[] = {
1960 { "asDisplayed", GNM_PRINT_COMMENTS_IN_PLACE
},
1961 { "atEnd", GNM_PRINT_COMMENTS_AT_END
},
1962 { "none", GNM_PRINT_COMMENTS_NONE
},
1965 static EnumVal
const error_types
[] = {
1966 { "blank", GNM_PRINT_ERRORS_AS_BLANK
},
1967 { "dash", GNM_PRINT_ERRORS_AS_DASHES
},
1968 { "NA", GNM_PRINT_ERRORS_AS_NA
},
1969 { "displayed", GNM_PRINT_ERRORS_AS_DISPLAYED
},
1972 static EnumVal
const page_order_types
[] = {
1973 { "overThenDown", 1 },
1974 { "downThenOver", 0 },
1978 if (pi
->page_setup
== NULL
)
1979 gnm_print_info_load_defaults (pi
);
1980 /* In xlsx the default is 1 not 0 */
1981 pi
->scaling
.dim
.rows
= 1;
1982 pi
->scaling
.dim
.cols
= 1;
1984 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
1985 if (attr_enum (xin
, attrs
, "orientation", orientation_types
, &orient
))
1987 else if (attr_enum (xin
, attrs
, "cellComments", comment_types
, &tmp_int
))
1988 pi
->comment_placement
= tmp_int
;
1989 else if (attr_enum (xin
, attrs
, "errors", error_types
, &tmp_int
))
1990 pi
->error_display
= tmp_int
;
1991 else if (attr_enum (xin
, attrs
, "pageOrder", page_order_types
, &tmp_int
))
1992 pi
->print_across_then_down
= (tmp_int
!= 0);
1993 else if (attr_int (xin
, attrs
, "paperSize", &paper_code
))
1995 else if (attr_distance (xin
, attrs
, "paperWidth", &width
))
1997 else if (attr_distance (xin
, attrs
, "paperHeight", &height
))
1999 else if (attr_bool (xin
, attrs
, "blackAndWhite", &tmp_bool
))
2000 pi
->print_black_and_white
= tmp_bool
;
2001 else if (attr_int (xin
, attrs
, "copies", &(pi
->n_copies
)))
2003 else if (attr_bool (xin
, attrs
, "draft", &tmp_bool
))
2004 pi
->print_as_draft
= tmp_bool
;
2005 else if (attr_int (xin
, attrs
, "firstPageNumber", &(pi
->start_page
)))
2007 else if (attr_int (xin
, attrs
, "fitToHeight", &(pi
->scaling
.dim
.rows
)))
2009 else if (attr_int (xin
, attrs
, "fitToWidth", &(pi
->scaling
.dim
.cols
)))
2011 else if (attr_int (xin
, attrs
, "scale", &scale
)) {
2012 pi
->scaling
.percentage
.x
= scale
;
2013 pi
->scaling
.percentage
.y
= scale
;
2014 } else if (attr_bool (xin
, attrs
, "useFirstPageNumber", &first_page_number
))
2018 if (!first_page_number
)
2019 pi
->start_page
= -1;
2021 if (!xlsx_set_paper_from_code (pi
, paper_code
) && width
> 0.0 && height
> 0.0)
2022 gtk_page_setup_set_paper_size (pi
->page_setup
,
2023 xlsx_paper_size (width
, height
, GTK_UNIT_POINTS
, 0));
2025 print_info_set_paper_orientation (pi
, orient
);
2029 xlsx_CT_PageMargins (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2031 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2033 GnmPrintInformation
*pi
= state
->sheet
->print_info
;
2035 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2036 if (attr_float (xin
, attrs
, "left", &margin
))
2037 print_info_set_margin_left (pi
, GO_IN_TO_PT (margin
));
2038 else if (attr_float (xin
, attrs
, "right", &margin
))
2039 print_info_set_margin_right (pi
, GO_IN_TO_PT (margin
));
2040 else if (attr_float (xin
, attrs
, "top", &margin
))
2041 print_info_set_edge_to_below_header (pi
, GO_IN_TO_PT (margin
));
2042 else if (attr_float (xin
, attrs
, "bottom", &margin
))
2043 print_info_set_edge_to_above_footer (pi
, GO_IN_TO_PT (margin
));
2044 else if (attr_float (xin
, attrs
, "header", &margin
))
2045 print_info_set_margin_header (pi
, GO_IN_TO_PT (margin
));
2046 else if (attr_float (xin
, attrs
, "footer", &margin
))
2047 print_info_set_margin_footer (pi
, GO_IN_TO_PT (margin
));
2053 xlsx_CT_oddheader_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2055 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2056 GnmPrintInformation
*pi
= state
->sheet
->print_info
;
2057 xls_header_footer_import (&pi
->header
, xin
->content
->str
);
2061 xlsx_CT_oddfooter_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2063 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2064 GnmPrintInformation
*pi
= state
->sheet
->print_info
;
2065 xls_header_footer_import (&pi
->footer
, xin
->content
->str
);
2069 xlsx_CT_PageBreak (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2071 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2072 GnmPageBreakType type
= GNM_PAGE_BREAK_AUTO
;
2077 if (NULL
== state
->page_breaks
)
2082 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2083 if (attr_int (xin
, attrs
, "id", &pos
))
2085 else if (attr_bool (xin
, attrs
, "man", &tmp
)) {
2086 if (tmp
) type
= GNM_PAGE_BREAK_MANUAL
;
2087 } else if (attr_bool (xin
, attrs
, "pt", &tmp
)) {
2088 if (tmp
) type
= GNM_PAGE_BREAK_DATA_SLICE
;
2089 } else if (attr_int (xin
, attrs
, "min", &first
))
2091 else if (attr_int (xin
, attrs
, "max", &last
))
2095 gnm_page_breaks_append_break (state
->page_breaks
, pos
, type
);
2099 xlsx_CT_PageBreaks_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2101 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2105 g_return_if_fail (state
->page_breaks
== NULL
);
2107 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2108 if (attr_int (xin
, attrs
, "count", &count
))
2110 else if (attr_int (xin
, attrs
, "manualBreakCount", &manual_count
))
2114 state
->page_breaks
= gnm_page_breaks_new (xin
->node
->user_data
.v_int
);
2118 xlsx_CT_PageBreaks_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2120 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2122 if (NULL
!= state
->page_breaks
) {
2123 print_info_set_breaks (state
->sheet
->print_info
,
2124 state
->page_breaks
);
2125 state
->page_breaks
= NULL
;
2130 xlsx_CT_DataValidation_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2132 static EnumVal
const val_styles
[] = {
2133 { "stop", GNM_VALIDATION_STYLE_STOP
},
2134 { "warning", GNM_VALIDATION_STYLE_WARNING
},
2135 { "information", GNM_VALIDATION_STYLE_INFO
},
2138 static EnumVal
const val_types
[] = {
2139 { "none", GNM_VALIDATION_TYPE_ANY
},
2140 { "whole", GNM_VALIDATION_TYPE_AS_INT
},
2141 { "decimal", GNM_VALIDATION_TYPE_AS_NUMBER
},
2142 { "list", GNM_VALIDATION_TYPE_IN_LIST
},
2143 { "date", GNM_VALIDATION_TYPE_AS_DATE
},
2144 { "time", GNM_VALIDATION_TYPE_AS_TIME
},
2145 { "textLength", GNM_VALIDATION_TYPE_TEXT_LENGTH
},
2146 { "custom", GNM_VALIDATION_TYPE_CUSTOM
},
2149 static EnumVal
const val_ops
[] = {
2150 { "between", GNM_VALIDATION_OP_BETWEEN
},
2151 { "notBetween", GNM_VALIDATION_OP_NOT_BETWEEN
},
2152 { "equal", GNM_VALIDATION_OP_EQUAL
},
2153 { "notEqual", GNM_VALIDATION_OP_NOT_EQUAL
},
2154 { "lessThan", GNM_VALIDATION_OP_LT
},
2155 { "lessThanOrEqual", GNM_VALIDATION_OP_LTE
},
2156 { "greaterThan", GNM_VALIDATION_OP_GT
},
2157 { "greaterThanOrEqual", GNM_VALIDATION_OP_GTE
},
2161 /* Get docs on this */
2162 "imeMode" default="noControl"
2176 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2179 ValidationStyle val_style
= GNM_VALIDATION_STYLE_STOP
;
2180 ValidationType val_type
= GNM_VALIDATION_TYPE_ANY
;
2181 ValidationOp val_op
= GNM_VALIDATION_OP_BETWEEN
;
2182 gboolean allowBlank
= FALSE
;
2183 gboolean showDropDown
= FALSE
;
2184 gboolean showInputMessage
= FALSE
;
2185 gboolean showErrorMessage
= FALSE
;
2186 xmlChar
const *errorTitle
= NULL
;
2187 xmlChar
const *error
= NULL
;
2188 xmlChar
const *promptTitle
= NULL
;
2189 xmlChar
const *prompt
= NULL
;
2190 xmlChar
const *refs
= NULL
;
2193 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2194 if (0 == strcmp (attrs
[0], "sqref"))
2196 else if (attr_enum (xin
, attrs
, "errorStyle", val_styles
, &tmp
))
2198 else if (attr_enum (xin
, attrs
, "type", val_types
, &tmp
))
2200 else if (attr_enum (xin
, attrs
, "operator", val_ops
, &tmp
))
2203 else if (attr_bool (xin
, attrs
, "allowBlank", &allowBlank
))
2205 else if (attr_bool (xin
, attrs
, "showDropDown", &showDropDown
))
2207 else if (attr_bool (xin
, attrs
, "showInputMessage", &showInputMessage
))
2209 else if (attr_bool (xin
, attrs
, "showErrorMessage", &showErrorMessage
))
2211 else if (0 == strcmp (attrs
[0], "errorTitle"))
2212 errorTitle
= attrs
[1];
2213 else if (0 == strcmp (attrs
[0], "error"))
2215 else if (0 == strcmp (attrs
[0], "promptTitle"))
2216 promptTitle
= attrs
[1];
2217 else if (0 == strcmp (attrs
[0], "prompt"))
2221 /* order matters, we need the 1st item */
2222 state
->validation_regions
= g_slist_reverse (
2223 xlsx_parse_sqref (xin
, refs
));
2225 if (NULL
== state
->validation_regions
)
2228 if (showErrorMessage
) {
2229 GnmRange
const *r
= state
->validation_regions
->data
;
2230 state
->pos
= r
->start
;
2231 state
->validation
= gnm_validation_new
2232 (val_style
, val_type
, val_op
,
2235 NULL
, NULL
, allowBlank
, showDropDown
);
2238 if (showInputMessage
&& (NULL
!= promptTitle
|| NULL
!= prompt
))
2239 state
->input_msg
= gnm_input_msg_new (prompt
, promptTitle
);
2243 xlsx_CT_DataValidation_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2245 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2247 GnmStyle
*style
= NULL
;
2250 if (NULL
!= state
->validation
&&
2251 NULL
!= (err
= gnm_validation_is_ok (state
->validation
))) {
2252 xlsx_warning (xin
, _("Ignoring invalid data validation because : %s"),
2254 gnm_validation_unref (state
->validation
);
2255 state
->validation
= NULL
;
2258 if (NULL
!= state
->validation
) {
2259 style
= gnm_style_new ();
2260 gnm_style_set_validation (style
, state
->validation
);
2261 state
->validation
= NULL
;
2264 if (NULL
!= state
->input_msg
) {
2266 style
= gnm_style_new ();
2267 gnm_style_set_input_msg (style
, state
->input_msg
);
2268 state
->input_msg
= NULL
;
2271 for (ptr
= state
->validation_regions
; ptr
!= NULL
; ptr
= ptr
->next
) {
2272 if (NULL
!= style
) {
2273 gnm_style_ref (style
);
2274 sheet_style_apply_range (state
->sheet
, ptr
->data
, style
);
2279 gnm_style_unref (style
);
2280 g_slist_free (state
->validation_regions
);
2281 state
->validation_regions
= NULL
;
2282 state
->pos
.col
= state
->pos
.row
= -1;
2286 xlsx_validation_expr (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2288 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2290 GnmExprTop
const *texpr
;
2292 if (state
->validation
== NULL
)
2295 /* Sneaky buggers, parse relative to the 1st sqRef */
2296 parse_pos_init (&pp
, NULL
, state
->sheet
,
2297 state
->pos
.col
, state
->pos
.row
);
2298 texpr
= xlsx_parse_expr (xin
, xin
->content
->str
, &pp
);
2299 if (NULL
!= texpr
) {
2300 gnm_validation_set_expr (state
->validation
, texpr
,
2301 xin
->node
->user_data
.v_int
);
2302 gnm_expr_top_unref (texpr
);
2307 xlsx_CT_AutoFilter_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2309 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2312 g_return_if_fail (state
->filter
== NULL
);
2314 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2315 if (attr_range (xin
, attrs
, "ref", &r
))
2316 state
->filter
= gnm_filter_new (state
->sheet
, &r
);
2321 xlsx_CT_AutoFilter_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2323 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2324 g_return_if_fail (state
->filter
!= NULL
);
2325 state
->filter
= NULL
;
2329 xlsx_CT_FilterColumn_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2331 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2333 gboolean hidden
= FALSE
;
2334 gboolean show
= TRUE
;
2336 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2337 if (attr_int (xin
, attrs
, "colId", &id
))
2339 else if (attr_bool (xin
, attrs
, "hiddenButton", &hidden
))
2341 else if (attr_bool (xin
, attrs
, "showButton", &show
))
2345 state
->filter_cur_field
= id
;
2349 xlsx_CT_Filters_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2351 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2353 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2354 if (0 == strcmp (attrs
[0], "val")) {
2357 state
->filter_items
= NULL
;
2360 xlsx_CT_Filters_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2362 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2363 state
->filter_items
= NULL
;
2366 xlsx_CT_Filter (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
2369 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2371 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2372 if (0 == strcmp (attrs
[0], "val")) {
2378 xlsx_CT_CustomFilters_begin (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
2380 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2383 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
2384 if (0 == strcmp (attrs
[0], "val")) {
2387 state
->filter_items
= NULL
;
2390 xlsx_CT_CustomFilters_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2392 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2393 state
->filter_items
= NULL
;
2397 xlsx_CT_CustomFilter (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
2399 static EnumVal
const ops
[] = {
2400 { "lessThan", GNM_FILTER_OP_LT
},
2401 { "lessThanOrEqual", GNM_FILTER_OP_LTE
},
2402 { "equal", GNM_FILTER_OP_EQUAL
},
2403 { "notEqual", GNM_FILTER_OP_NOT_EQUAL
},
2404 { "greaterThanOrEqual", GNM_FILTER_OP_GTE
},
2405 { "greaterThan", GNM_FILTER_OP_GT
},
2408 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2410 GnmFilterOp op
= GNM_FILTER_OP_EQUAL
;
2412 GnmFilterCondition
*cond
;
2413 GODateConventions
const *date_conv
= workbook_date_conv (state
->wb
);
2415 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2416 if (0 == strcmp (attrs
[0], "val")) {
2417 const char *txt
= CXML2C (attrs
[1]);
2419 v
= format_match (txt
, NULL
, date_conv
);
2421 v
= value_new_string (txt
);
2422 } else if (attr_enum (xin
, attrs
, "operator", ops
, &tmp
)) {
2427 cond
= gnm_filter_condition_new_single (op
, v
);
2429 gnm_filter_set_condition (state
->filter
, state
->filter_cur_field
,
2434 xlsx_CT_Top10 (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2436 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2437 gboolean top
= TRUE
;
2438 gboolean percent
= FALSE
;
2439 gnm_float val
= -1.;
2440 GnmFilterCondition
*cond
;
2442 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2443 if (attr_float (xin
, attrs
, "val", &val
))
2445 else if (attr_bool (xin
, attrs
, "top", &top
))
2447 else if (attr_bool (xin
, attrs
, "percent", &percent
))
2451 if (NULL
!= (cond
= gnm_filter_condition_new_bucket (top
, !percent
, FALSE
, val
)))
2452 gnm_filter_set_condition (state
->filter
, state
->filter_cur_field
,
2457 xlsx_CT_DynamicFilter (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
2460 static EnumVal
const types
[] = {
2462 { "aboveAverage", 0 },
2463 { "belowAverage", 0 },
2473 { "nextQuarter", 0 },
2474 { "thisQuarter", 0 },
2475 { "lastQuarter", 0 },
2479 { "yearToDate", 0 },
2498 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2501 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2502 if (attr_enum (xin
, attrs
, "type", types
, &type
))
2509 xlsx_CT_MergeCell (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2511 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2514 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2515 if (attr_range (xin
, attrs
, "ref", &r
))
2516 gnm_sheet_merge_add (state
->sheet
, &r
, FALSE
,
2517 GO_CMD_CONTEXT (state
->context
));
2522 xlsx_CT_SheetProtection (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2524 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2525 gboolean sheet
= FALSE
;
2526 gboolean objects
= FALSE
;
2527 gboolean scenarios
= FALSE
;
2528 gboolean formatCells
= TRUE
;
2529 gboolean formatColumns
= TRUE
;
2530 gboolean formatRows
= TRUE
;
2531 gboolean insertColumns
= TRUE
;
2532 gboolean insertRows
= TRUE
;
2533 gboolean insertHyperlinks
= TRUE
;
2534 gboolean deleteColumns
= TRUE
;
2535 gboolean deleteRows
= TRUE
;
2536 gboolean selectLockedCells
= FALSE
;
2537 gboolean sort
= TRUE
;
2538 gboolean autoFilter
= TRUE
;
2539 gboolean pivotTables
= TRUE
;
2540 gboolean selectUnlockedCells
= FALSE
;
2542 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2543 if (attr_bool (xin
, attrs
, "sheet", &sheet
))
2545 else if (attr_bool (xin
, attrs
, "objects", &objects
))
2547 else if (attr_bool (xin
, attrs
, "scenarios", &scenarios
))
2549 else if (attr_bool (xin
, attrs
, "formatCells", &formatCells
))
2551 else if (attr_bool (xin
, attrs
, "formatColumns", &formatColumns
))
2553 else if (attr_bool (xin
, attrs
, "formatRows", &formatRows
))
2555 else if (attr_bool (xin
, attrs
, "insertColumns", &insertColumns
))
2557 else if (attr_bool (xin
, attrs
, "insertRows", &insertRows
))
2559 else if (attr_bool (xin
, attrs
, "insertHyperlinks", &insertHyperlinks
))
2561 else if (attr_bool (xin
, attrs
, "deleteColumns", &deleteColumns
))
2563 else if (attr_bool (xin
, attrs
, "deleteRows", &deleteRows
))
2565 else if (attr_bool (xin
, attrs
, "selectLockedCells", &selectLockedCells
))
2567 else if (attr_bool (xin
, attrs
, "sort", &sort
))
2569 else if (attr_bool (xin
, attrs
, "autoFilter", &autoFilter
))
2571 else if (attr_bool (xin
, attrs
, "pivotTables", &pivotTables
))
2573 else if (attr_bool (xin
, attrs
, "selectUnlockedCells", &selectUnlockedCells
))
2577 g_object_set (state
->sheet
,
2579 "protected-allow-edit-objects", objects
,
2580 "protected-allow-edit-scenarios", scenarios
,
2581 "protected-allow-cell-formatting", formatCells
,
2582 "protected-allow-column-formatting", formatColumns
,
2583 "protected-allow-row-formatting", formatRows
,
2584 "protected-allow-insert-columns", insertColumns
,
2585 "protected-allow-insert-rows", insertRows
,
2586 "protected-allow-insert-hyperlinks", insertHyperlinks
,
2587 "protected-allow-delete-columns", deleteColumns
,
2588 "protected-allow-delete-rows", deleteRows
,
2589 "protected-allow-select-locked-cells", selectLockedCells
,
2590 "protected-allow-sort-ranges", sort
,
2591 "protected-allow-edit-auto-filters", autoFilter
,
2592 "protected-allow-edit-pivottable", pivotTables
,
2593 "protected-allow-select-unlocked-cells", selectUnlockedCells
,
2598 xlsx_cond_fmt_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2600 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2601 char const *refs
= NULL
;
2603 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2604 if (0 == strcmp (attrs
[0], "sqref"))
2608 state
->cond_regions
= xlsx_parse_sqref (xin
, refs
);
2610 /* create in first call xlsx_cond_rule to avoid creating condition with
2612 state
->conditions
= NULL
;
2616 xlsx_cond_fmt_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2618 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2619 GnmStyle
*style
= NULL
;
2622 if (NULL
!= state
->conditions
) {
2623 style
= gnm_style_new ();
2624 gnm_style_set_conditions (style
, state
->conditions
);
2625 for (ptr
= state
->cond_regions
; ptr
!= NULL
; ptr
= ptr
->next
) {
2626 gnm_style_ref (style
);
2627 sheet_style_apply_range (state
->sheet
, ptr
->data
, style
);
2630 gnm_style_unref (style
);
2631 } else for (ptr
= state
->cond_regions
; ptr
!= NULL
; ptr
= ptr
->next
)
2633 g_slist_free (state
->cond_regions
);
2634 state
->cond_regions
= NULL
;
2638 XLSX_CF_TYPE_UNDEFINED
,
2640 XLSX_CF_TYPE_EXPRESSION
,
2641 XLSX_CF_TYPE_CELL_IS
,
2642 XLSX_CF_TYPE_COLOR_SCALE
,
2643 XLSX_CF_TYPE_DATA_BAR
,
2644 XLSX_CF_TYPE_ICON_SET
,
2646 XLSX_CF_TYPE_UNIQUE_VALUES
,
2647 XLSX_CF_TYPE_DUPLICATE_VALUES
,
2648 XLSX_CF_TYPE_CONTAINS_STR
,
2649 XLSX_CF_TYPE_NOT_CONTAINS_STR
,
2650 XLSX_CF_TYPE_BEGINS_WITH
,
2651 XLSX_CF_TYPE_ENDS_WITH
,
2652 XLSX_CF_TYPE_CONTAINS_BLANKS
,
2653 XLSX_CF_TYPE_NOT_CONTAINS_BLANKS
,
2654 XLSX_CF_TYPE_CONTAINS_ERRORS
,
2655 XLSX_CF_TYPE_NOT_CONTAINS_ERRORS
,
2656 XLSX_CF_TYPE_COMPARE_COLUMNS
,
2657 XLSX_CF_TYPE_TIME_PERIOD
,
2658 XLSX_CF_TYPE_ABOVE_AVERAGE
2661 xlsx_cond_fmt_rule_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2663 static EnumVal
const ops
[] = {
2664 { "lessThan", GNM_STYLE_COND_LT
},
2665 { "lessThanOrEqual", GNM_STYLE_COND_LTE
},
2666 { "equal", GNM_STYLE_COND_EQUAL
},
2667 { "notEqual", GNM_STYLE_COND_NOT_EQUAL
},
2668 { "greaterThanOrEqual", GNM_STYLE_COND_GTE
},
2669 { "greaterThan", GNM_STYLE_COND_GT
},
2670 { "between", GNM_STYLE_COND_BETWEEN
},
2671 { "notBetween", GNM_STYLE_COND_NOT_BETWEEN
},
2672 { "containsText", GNM_STYLE_COND_CONTAINS_STR
},
2673 { "notContainsText", GNM_STYLE_COND_NOT_CONTAINS_STR
},
2674 { "beginsWith", GNM_STYLE_COND_BEGINS_WITH_STR
},
2675 { "endsWith", GNM_STYLE_COND_ENDS_WITH_STR
},
2676 { "notContain", GNM_STYLE_COND_NOT_CONTAINS_STR
},
2680 static EnumVal
const types
[] = {
2681 { "expression", XLSX_CF_TYPE_EXPRESSION
},
2682 { "cellIs", XLSX_CF_TYPE_CELL_IS
},
2683 { "colorScale", XLSX_CF_TYPE_COLOR_SCALE
},
2684 { "dataBar", XLSX_CF_TYPE_DATA_BAR
},
2685 { "iconSet", XLSX_CF_TYPE_ICON_SET
},
2686 { "top10", XLSX_CF_TYPE_TOP10
},
2687 { "uniqueValues", XLSX_CF_TYPE_UNIQUE_VALUES
},
2688 { "duplicateValues", XLSX_CF_TYPE_DUPLICATE_VALUES
},
2689 { "containsText", XLSX_CF_TYPE_CONTAINS_STR
},
2690 { "doesNotContainText", XLSX_CF_TYPE_NOT_CONTAINS_STR
}, /* ??? */
2691 { "notContainsText", XLSX_CF_TYPE_NOT_CONTAINS_STR
},
2692 { "beginsWith", XLSX_CF_TYPE_BEGINS_WITH
},
2693 { "endsWith", XLSX_CF_TYPE_ENDS_WITH
},
2694 { "containsBlanks", XLSX_CF_TYPE_CONTAINS_BLANKS
},
2695 { "containsNoBlanks", XLSX_CF_TYPE_NOT_CONTAINS_BLANKS
}, /* ??? */
2696 { "notContainsBlanks", XLSX_CF_TYPE_NOT_CONTAINS_BLANKS
},
2697 { "containsErrors", XLSX_CF_TYPE_CONTAINS_ERRORS
},
2698 { "containsNoErrors", XLSX_CF_TYPE_NOT_CONTAINS_ERRORS
}, /* ??? */
2699 { "notContainsErrors", XLSX_CF_TYPE_NOT_CONTAINS_ERRORS
},
2700 { "compareColumns", XLSX_CF_TYPE_COMPARE_COLUMNS
},
2701 { "timePeriod", XLSX_CF_TYPE_TIME_PERIOD
},
2702 { "aboveAverage", XLSX_CF_TYPE_ABOVE_AVERAGE
},
2706 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2707 gboolean formatRow
= FALSE
;
2708 gboolean stopIfTrue
= FALSE
;
2709 gboolean above
= TRUE
;
2710 gboolean percent
= FALSE
;
2711 gboolean bottom
= FALSE
;
2713 /* use custom invalid flag, it is not in MS enum */
2714 GnmStyleCondOp op
= GNM_STYLE_COND_CUSTOM
;
2715 XlsxCFTypes type
= XLSX_CF_TYPE_UNDEFINED
;
2716 char const *type_str
= "-";
2717 GnmStyle
*overlay
= NULL
;
2719 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2720 if (attr_bool (xin
, attrs
, "formatRow", &formatRow
))
2722 else if (attr_bool (xin
, attrs
, "stopIfTrue", &stopIfTrue
))
2724 else if (attr_bool (xin
, attrs
, "above", &above
))
2726 else if (attr_bool (xin
, attrs
, "percent", &percent
))
2728 else if (attr_bool (xin
, attrs
, "bottom", &bottom
))
2730 else if (attr_int (xin
, attrs
, "dxfId", &dxf
))
2732 else if (attr_enum (xin
, attrs
, "operator", ops
, &tmp
))
2734 else if (attr_enum (xin
, attrs
, "type", types
, &tmp
)) {
2736 type_str
= attrs
[1];
2741 "numFmtId" ="ST_NumFmtId" use="optional">
2742 "priority" ="xs:int" use="required">
2743 "text" ="xs:string" use="optional">
2744 "timePeriod" ="ST_TimePeriod" use="optional">
2745 "col1" ="xs:unsignedInt" use="optional">
2746 "col2" ="xs:unsignedInt" use="optional">
2751 overlay
= xlsx_get_dxf (xin
, dxf
);
2754 case XLSX_CF_TYPE_CELL_IS
:
2757 case XLSX_CF_TYPE_CONTAINS_STR
:
2758 case XLSX_CF_TYPE_NOT_CONTAINS_STR
:
2759 case XLSX_CF_TYPE_BEGINS_WITH
:
2760 case XLSX_CF_TYPE_ENDS_WITH
:
2761 case XLSX_CF_TYPE_CONTAINS_BLANKS
:
2762 case XLSX_CF_TYPE_NOT_CONTAINS_BLANKS
:
2763 case XLSX_CF_TYPE_CONTAINS_ERRORS
:
2764 case XLSX_CF_TYPE_NOT_CONTAINS_ERRORS
:
2765 /* The expressions stored for these are the full
2766 expressions, not just what we search for. */
2767 op
= GNM_STYLE_COND_CUSTOM
;
2770 case XLSX_CF_TYPE_EXPRESSION
:
2771 op
= GNM_STYLE_COND_CUSTOM
;
2775 xlsx_warning (xin
, _("Ignoring unhandled conditional format of type '%s'"), type_str
);
2778 state
->cond
= gnm_style_cond_new (op
, state
->sheet
);
2779 gnm_style_cond_set_overlay (state
->cond
, overlay
);
2785 xlsx_cond_fmt_rule_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2787 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2789 if (gnm_style_cond_is_valid (state
->cond
)) {
2790 if (NULL
== state
->conditions
)
2791 state
->conditions
= gnm_style_conditions_new (state
->sheet
);
2792 /* Reverse the alternate-expression treatment. */
2793 gnm_style_cond_canonicalize (state
->cond
);
2795 gnm_style_conditions_insert (state
->conditions
,
2798 gnm_style_cond_free (state
->cond
);
2804 xlsx_cond_fmt_formula_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2806 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2808 GnmExprTop
const *texpr
;
2809 GnmCellPos
const *cp
;
2811 if (!state
->cond
|| state
->count
> 1 || state
->cond_regions
== NULL
)
2814 cp
= g_slist_last (state
->cond_regions
)->data
;
2815 parse_pos_init (&pp
, state
->sheet
->workbook
, state
->sheet
, cp
->col
, cp
->row
);
2816 texpr
= xlsx_parse_expr (xin
, xin
->content
->str
, &pp
);
2818 gnm_style_cond_set_expr (state
->cond
, texpr
, state
->count
);
2819 gnm_expr_top_unref (texpr
);
2826 xlsx_CT_SheetView_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2828 /* static EnumVal const view_types[] = { */
2829 /* { "normal", GNM_SHEET_VIEW_NORMAL_MODE }, */
2830 /* { "pageBreakPreview", GNM_SHEET_VIEW_PAGE_BREAK_MODE }, */
2831 /* { "pageLayout", GNM_SHEET_VIEW_LAYOUT_MODE }, */
2835 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2836 int showGridLines
= TRUE
;
2837 int showFormulas
= FALSE
;
2838 int showRowColHeaders
= TRUE
;
2839 int showZeros
= TRUE
;
2841 int frozenSplit
= TRUE
;
2842 int rightToLeft
= FALSE
;
2843 int tabSelected
= FALSE
;
2845 int showRuler
= TRUE
;
2846 int showOutlineSymbols
= TRUE
;
2847 int defaultGridColor
= TRUE
;
2848 int showWhiteSpace
= TRUE
;
2850 int grid_color_index
= -1;
2852 /* GnmSheetViewMode view_mode = GNM_SHEET_VIEW_NORMAL_MODE; */
2853 GnmCellPos topLeft
= { -1, -1 };
2855 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2856 if (attr_pos (xin
, attrs
, "topLeftCell", &topLeft
) ||
2857 attr_bool (xin
, attrs
, "showGridLines", &showGridLines
) ||
2858 attr_bool (xin
, attrs
, "showFormulas", &showFormulas
) ||
2859 attr_bool (xin
, attrs
, "showRowColHeaders", &showRowColHeaders
) ||
2860 attr_bool (xin
, attrs
, "showZeros", &showZeros
) ||
2861 attr_bool (xin
, attrs
, "frozen", &frozen
) ||
2862 attr_bool (xin
, attrs
, "frozenSplit", &frozenSplit
) ||
2863 attr_bool (xin
, attrs
, "rightToLeft", &rightToLeft
) ||
2864 attr_bool (xin
, attrs
, "tabSelected", &tabSelected
) ||
2865 attr_bool (xin
, attrs
, "active", &active
) ||
2866 attr_bool (xin
, attrs
, "showRuler", &showRuler
) ||
2867 attr_bool (xin
, attrs
, "showOutlineSymbols", &showOutlineSymbols
) ||
2868 attr_bool (xin
, attrs
, "defaultGridColor", &defaultGridColor
) ||
2869 attr_bool (xin
, attrs
, "showWhiteSpace", &showWhiteSpace
) ||
2870 attr_int (xin
, attrs
, "zoomScale", &scale
) ||
2871 attr_int (xin
, attrs
, "colorId", &grid_color_index
))
2873 /* else if (attr_enum (xin, attrs, "view", view_types, &tmp)) */
2874 /* view_mode = tmp; */
2876 "zoomScaleNormal" type
="xs:unsignedInt" use
="optional" default="0"
2877 "zoomScaleSheetLayoutView" type
="xs:unsignedInt" use
="optional" default="0"
2878 "zoomScalePageLayoutView" type
="xs:unsignedInt" use
="optional" default="0"
2879 "workbookViewId" type
="xs:unsignedInt" use
="required"
2883 /* get this from the workbookViewId */
2884 g_return_if_fail (state
->sv
== NULL
);
2885 state
->sv
= sheet_get_view (state
->sheet
, state
->wb_view
);
2886 state
->pane_pos
= XLSX_PANE_TOP_LEFT
;
2888 /* until we import multiple views unfreeze just in case a previous view
2890 sv_freeze_panes (state
->sv
, NULL
, NULL
);
2892 if (topLeft
.col
>= 0)
2893 sv_set_initial_top_left (state
->sv
, topLeft
.col
, topLeft
.row
);
2894 g_object_set (state
->sheet
,
2895 "text-is-rtl", rightToLeft
,
2896 "display-formulas", showFormulas
,
2897 "display-zeros", showZeros
,
2898 "display-grid", showGridLines
,
2899 "display-column-header", showRowColHeaders
,
2900 "display-row-header", showRowColHeaders
,
2901 "display-outlines", showOutlineSymbols
,
2902 "zoom-factor", ((double)scale
) / 100.,
2905 gboolean active
= FALSE
;
2906 gboolean showRuler
= TRUE
;
2907 gboolean showWhiteSpace
= TRUE
;
2911 g_object_set (state
->sv
,
2912 "displayMode", view_mode
,
2916 if (!defaultGridColor
&& grid_color_index
>= 0)
2917 sheet_style_set_auto_pattern_color (state
->sheet
,
2918 gnm_color_new_go (indexed_color (state
, grid_color_index
)));
2920 wb_view_sheet_focus (state
->wb_view
, state
->sheet
);
2923 xlsx_CT_SheetView_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
2925 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2926 g_return_if_fail (state
->sv
!= NULL
);
2930 static EnumVal
const pane_types
[] = {
2931 { "topLeft", XLSX_PANE_TOP_LEFT
},
2932 { "topRight", XLSX_PANE_TOP_RIGHT
},
2933 { "bottomLeft", XLSX_PANE_BOTTOM_LEFT
},
2934 { "bottomRight", XLSX_PANE_BOTTOM_RIGHT
},
2938 xlsx_CT_Selection (GsfXMLIn
*xin
, xmlChar
const **attrs
)
2940 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
2941 GnmCellPos edit_pos
= { -1, -1 };
2942 int i
, sel_with_edit_pos
= 0;
2943 char const *refs
= NULL
;
2944 XLSXPanePos pane_pos
= XLSX_PANE_TOP_LEFT
;
2946 GSList
*ptr
, *accum
= NULL
;
2948 g_return_if_fail (state
->sv
!= NULL
);
2950 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
2951 if (0 == strcmp (attrs
[0], "sqref"))
2953 else if (attr_enum (xin
, attrs
, "activePane", pane_types
, &i
))
2955 else if (attr_pos (xin
, attrs
, "activeCell", &edit_pos
))
2957 else if (attr_int (xin
, attrs
, "activeCellId", &sel_with_edit_pos
))
2961 if (pane_pos
!= state
->pane_pos
)
2964 for (i
= 0 ; NULL
!= refs
&& *refs
; i
++) {
2965 if (NULL
== (refs
= cellpos_parse (refs
, gnm_sheet_get_size (state
->sheet
), &r
.start
, FALSE
)))
2968 if (*refs
== '\0' || *refs
== ' ')
2970 else if (*refs
!= ':' ||
2971 NULL
== (refs
= cellpos_parse (refs
+ 1, gnm_sheet_get_size (state
->sheet
), &r
.end
, FALSE
)))
2975 sv_selection_reset (state
->sv
);
2977 /* gnumeric assumes the edit_pos is in the last selected range.
2978 * We need to re-order the selection list. */
2979 if (i
<= sel_with_edit_pos
&& edit_pos
.col
>= 0)
2980 accum
= g_slist_prepend (accum
, gnm_range_dup (&r
));
2982 sv_selection_add_range (state
->sv
, &r
);
2983 while (*refs
== ' ')
2987 if (NULL
!= accum
) {
2988 accum
= g_slist_reverse (accum
);
2989 for (ptr
= accum
; ptr
!= NULL
; ptr
= ptr
->next
) {
2990 sv_selection_add_range (state
->sv
, ptr
->data
);
2993 sv_set_edit_pos (state
->sv
, &edit_pos
);
2994 g_slist_free (accum
);
2999 xlsx_CT_PivotSelection (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3002 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3003 <xsd
:attribute name
="pane" type
="ST_Pane" use
="optional" default="topLeft">
3004 <xsd
:attribute name
="showHeader" type
="xsd:boolean" default="false">
3005 <xsd
:attribute name
="label" type
="xsd:boolean" default="false">
3006 <xsd
:attribute name
="data" type
="xsd:boolean" default="false">
3007 <xsd
:attribute name
="extendable" type
="xsd:boolean" default="false">
3008 <xsd
:attribute name
="count" type
="xsd:unsignedInt" default="0">
3009 <xsd
:attribute name
="axis" type
="ST_Axis" use
="optional">
3010 <xsd
:attribute name
="dimension" type
="xsd:unsignedInt" default="0">
3011 <xsd
:attribute name
="start" type
="xsd:unsignedInt" default="0">
3012 <xsd
:attribute name
="min" type
="xsd:unsignedInt" default="0">
3013 <xsd
:attribute name
="max" type
="xsd:unsignedInt" default="0">
3014 <xsd
:attribute name
="activeRow" type
="xsd:unsignedInt" default="0">
3015 <xsd
:attribute name
="activeCol" type
="xsd:unsignedInt" default="0">
3016 <xsd
:attribute name
="previousRow" type
="xsd:unsignedInt" default="0">
3017 <xsd
:attribute name
="previousCol" type
="xsd:unsignedInt" default="0">
3018 <xsd
:attribute name
="click" type
="xsd:unsignedInt" default="0">
3019 <xsd
:attribute ref
="r:id" use
="optional">
3024 xlsx_CT_PivotArea (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3027 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3028 <xsd
:attribute name
="field" use
="optional" type
="xsd:int">
3029 <xsd
:attribute name
="type" type
="ST_PivotAreaType" default="normal">
3030 <xsd
:attribute name
="dataOnly" type
="xsd:boolean" default="true">
3031 <xsd
:attribute name
="labelOnly" type
="xsd:boolean" default="false">
3032 <xsd
:attribute name
="grandRow" type
="xsd:boolean" default="false">
3033 <xsd
:attribute name
="grandCol" type
="xsd:boolean" default="false">
3034 <xsd
:attribute name
="cacheIndex" type
="xsd:boolean" default="false">
3035 <xsd
:attribute name
="outline" type
="xsd:boolean" default="true">
3036 <xsd
:attribute name
="offset" type
="ST_Ref">
3037 <xsd
:attribute name
="collapsedLevelsAreSubtotals" type
="xsd:boolean" default="false">
3038 <xsd
:attribute name
="axis" type
="ST_Axis" use
="optional">
3039 <xsd
:attribute name
="fieldPosition" type
="xsd:unsignedInt" use
="optional">
3043 xlsx_CT_PivotAreaReferences (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3046 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3050 xlsx_CT_PivotAreaReference (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3053 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3054 <xsd
:attribute name
="field" use
="optional" type
="xsd:unsignedInt">
3055 <xsd
:attribute name
="count" type
="xsd:unsignedInt">
3056 <xsd
:attribute name
="selected" type
="xsd:boolean" default="true">
3057 <xsd
:attribute name
="byPosition" type
="xsd:boolean" default="false">
3058 <xsd
:attribute name
="relative" type
="xsd:boolean" default="false">
3059 <xsd
:attribute name
="defaultSubtotal" type
="xsd:boolean" default="false">
3060 <xsd
:attribute name
="sumSubtotal" type
="xsd:boolean" default="false">
3061 <xsd
:attribute name
="countASubtotal" type
="xsd:boolean" default="false">
3062 <xsd
:attribute name
="avgSubtotal" type
="xsd:boolean" default="false">
3063 <xsd
:attribute name
="maxSubtotal" type
="xsd:boolean" default="false">
3064 <xsd
:attribute name
="minSubtotal" type
="xsd:boolean" default="false">
3065 <xsd
:attribute name
="productSubtotal" type
="xsd:boolean" default="false">
3066 <xsd
:attribute name
="countSubtotal" type
="xsd:boolean" default="false">
3067 <xsd
:attribute name
="stdDevSubtotal" type
="xsd:boolean" default="false">
3068 <xsd
:attribute name
="stdDevPSubtotal" type
="xsd:boolean" default="false">
3069 <xsd
:attribute name
="varSubtotal" type
="xsd:boolean" default="false">
3070 <xsd
:attribute name
="varPSubtotal" type
="xsd:boolean" default="false">
3075 xlsx_CT_Pane (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3077 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3078 GnmCellPos topLeft
= { 0, 0 };
3080 gnm_float xSplit
= -1., ySplit
= -1.;
3081 gboolean frozen
= FALSE
;
3083 g_return_if_fail (state
->sv
!= NULL
);
3085 /* <pane xSplit="2" ySplit="3" topLeftCell="J15" activePane="bottomRight" state="frozen"/> */
3086 state
->pane_pos
= XLSX_PANE_TOP_LEFT
;
3087 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3088 if (0 == strcmp (attrs
[0], "state"))
3089 frozen
= (0 == strcmp (attrs
[1], "frozen"));
3090 else if (attr_pos (xin
, attrs
, "topLeftCell", &topLeft
))
3092 else if (attr_float (xin
, attrs
, "xSplit", &xSplit
))
3094 else if (attr_float (xin
, attrs
, "ySplit", &ySplit
))
3096 else if (attr_enum (xin
, attrs
, "pane", pane_types
, &tmp
))
3097 state
->pane_pos
= tmp
;
3101 GnmCellPos frozen
, unfrozen
;
3102 frozen
= unfrozen
= state
->sv
->initial_top_left
;
3104 unfrozen
.col
+= xSplit
;
3106 topLeft
.col
= state
->sv
->initial_top_left
.col
;
3108 unfrozen
.row
+= ySplit
;
3110 topLeft
.row
= state
->sv
->initial_top_left
.row
;
3111 sv_freeze_panes (state
->sv
, &frozen
, &unfrozen
);
3112 sv_set_initial_top_left (state
->sv
, topLeft
.col
, topLeft
.row
);
3117 xlsx_ole_object (G_GNUC_UNUSED GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3120 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3122 /* <oleObject progId="Wordpad.Document.1" shapeId="1032" r:id="rId5"/> */
3123 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2)
3129 xlsx_CT_HyperLinks (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3131 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3132 gboolean has_ref
= FALSE
;
3135 GType link_type
= 0;
3136 GnmHLink
*lnk
= NULL
;
3137 char const *location
= NULL
;
3138 char const *tooltip
= NULL
;
3139 char const *extern_id
= NULL
;
3140 char *target
= NULL
;
3142 /* <hyperlink ref="A42" r:id="rId1"/> */
3143 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3144 if (attr_range (xin
, attrs
, "ref", &r
))
3146 else if (0 == strcmp (attrs
[0], "location"))
3147 location
= CXML2C (attrs
[1]);
3148 else if (0 == strcmp (attrs
[0], "tooltip"))
3149 tooltip
= CXML2C (attrs
[1]);
3150 else if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_DOC_REL
, "id"))
3151 extern_id
= CXML2C (attrs
[1]);
3152 #if 0 /* ignore "display" on import, it always seems to be the cell content */
3153 else if (0 == strcmp (attrs
[0], "display"))
3161 if (NULL
!= extern_id
) {
3162 GsfOpenPkgRel
const *rel
= gsf_open_pkg_lookup_rel_by_id (
3163 gsf_xml_in_get_input (xin
), extern_id
);
3165 gsf_open_pkg_rel_is_extern (rel
) &&
3166 0 == strcmp (gsf_open_pkg_rel_get_type (rel
),
3167 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink")) {
3168 const char *url
= gsf_open_pkg_rel_get_target (rel
);
3170 if (0 == strncmp (url
, "mailto:", 7))
3171 link_type
= gnm_hlink_email_get_type ();
3173 link_type
= gnm_hlink_url_get_type ();
3175 ? g_strconcat (url
, "#", location
, NULL
)
3179 } else if (location
) {
3180 target
= g_strdup (location
);
3181 link_type
= gnm_hlink_cur_wb_get_type ();
3184 if (0 == link_type
) {
3185 xlsx_warning (xin
, _("Unknown type of hyperlink"));
3190 lnk
= gnm_hlink_new (link_type
, state
->sheet
);
3191 gnm_hlink_set_target (lnk
, target
);
3192 gnm_hlink_set_tip (lnk
, tooltip
);
3193 style
= gnm_style_new ();
3194 gnm_style_set_hlink (style
, lnk
);
3195 sheet_style_apply_range (state
->sheet
, &r
, style
);
3200 cb_find_pivots (GsfInput
*opkg
, GsfOpenPkgRel
const *rel
, gpointer user_data
)
3202 XLSXReadState
*state
= user_data
;
3203 GsfInput
*part_stream
;
3204 char const *t
= gsf_open_pkg_rel_get_type (rel
);
3207 0 == strcmp (t
, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable") &&
3208 NULL
!= (part_stream
= gsf_open_pkg_open_rel (opkg
, rel
, NULL
)))
3209 xlsx_parse_stream (state
, part_stream
, xlsx_pivot_table_dtd
);
3213 xlsx_CT_worksheet (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3215 gsf_open_pkg_foreach_rel (gsf_xml_in_get_input (xin
),
3216 &cb_find_pivots
, (XLSXReadState
*)xin
->user_state
);
3221 xlsx_ext_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3223 gboolean warned
= FALSE
;
3224 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3225 if (0 == strcmp (attrs
[0], "uri")) {
3228 _("Encountered uninterpretable \"ext\" extension in namespace \"%s\""),
3237 _("Encountered uninterpretable \"ext\" extension with missing namespace"));
3238 gsf_xml_in_set_silent_unknowns (xin
, TRUE
);
3242 xlsx_ext_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3244 gsf_xml_in_set_silent_unknowns (xin
, FALSE
);
3250 add_attr (XLSXReadState
*state
, PangoAttribute
*attr
)
3252 attr
->start_index
= 0;
3253 attr
->end_index
= -1;
3255 if (state
->run_attrs
== NULL
)
3256 state
->run_attrs
= pango_attr_list_new ();
3258 pango_attr_list_insert (state
->run_attrs
, attr
);
3262 xlsx_run_weight (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3264 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3267 (void)simple_bool (xin
, attrs
, &b
);
3268 wt
= b
? PANGO_WEIGHT_BOLD
: PANGO_WEIGHT_NORMAL
;
3269 add_attr (state
, pango_attr_weight_new (wt
));
3273 xlsx_run_style (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3275 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3278 (void)simple_bool (xin
, attrs
, &it
);
3280 st
= it
? PANGO_STYLE_ITALIC
: PANGO_STYLE_NORMAL
;
3281 add_attr (state
, pango_attr_style_new (st
));
3285 xlsx_run_family (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3287 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3288 const char *fam
= simple_string (xin
, attrs
);
3290 PangoAttribute
*attr
= pango_attr_family_new (fam
);
3291 add_attr (state
, attr
);
3296 xlsx_run_size (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3298 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3300 if (simple_float (xin
, attrs
, &sz
)) {
3301 PangoAttribute
*attr
= pango_attr_size_new (CLAMP (sz
, 0.0, 1000.0) * PANGO_SCALE
);
3302 add_attr (state
, attr
);
3307 xlsx_run_strikethrough (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3309 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3310 int st
= TRUE
; /* Default */
3311 (void)simple_bool (xin
, attrs
, &st
);
3312 add_attr (state
, pango_attr_strikethrough_new (st
));
3316 xlsx_run_underline (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3318 static EnumVal
const types
[] = {
3319 { "single", PANGO_UNDERLINE_SINGLE
},
3320 { "double", PANGO_UNDERLINE_DOUBLE
},
3321 { "singleAccounting", PANGO_UNDERLINE_LOW
},
3322 { "doubleAccounting", PANGO_UNDERLINE_LOW
}, /* fixme? */
3323 { "none", PANGO_UNDERLINE_NONE
},
3326 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3327 int u
= PANGO_UNDERLINE_SINGLE
;
3328 (void)simple_enum (xin
, attrs
, types
, &u
);
3329 add_attr (state
, pango_attr_underline_new (u
));
3333 xlsx_run_vertalign (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3335 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3336 static EnumVal
const types
[] = {
3337 { "subscript", GO_FONT_SCRIPT_SUB
},
3338 { "baseline", GO_FONT_SCRIPT_STANDARD
},
3339 { "superscript", GO_FONT_SCRIPT_SUPER
},
3342 int v
= GO_FONT_SCRIPT_STANDARD
;
3343 (void)simple_enum (xin
, attrs
, types
, &v
);
3345 case GO_FONT_SCRIPT_SUB
:
3346 add_attr (state
, go_pango_attr_subscript_new (TRUE
));
3348 case GO_FONT_SCRIPT_SUPER
:
3349 add_attr (state
, go_pango_attr_superscript_new (TRUE
));
3358 xlsx_run_color (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3360 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3361 GOColor c
= GO_COLOR_BLACK
;
3363 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3364 if (strcmp (attrs
[0], "rgb") == 0) {
3365 unsigned r
, g
, b
, a
;
3366 if (4 != sscanf (attrs
[1], "%02x%02x%02x%02x", &a
, &r
, &g
, &b
)) {
3368 _("Invalid color '%s' for attribute rgb"),
3373 c
= GO_COLOR_FROM_RGBA (r
, g
, b
, a
);
3374 } else if (strcmp (attrs
[0], "indexed") == 0) {
3375 int idx
= atoi (CXML2C (attrs
[1]));
3376 c
= indexed_color (state
, idx
);
3380 add_attr (state
, go_color_to_pango (c
, TRUE
));
3384 cb_trunc_attributes (PangoAttribute
*a
, gpointer plen
)
3386 a
->end_index
= GPOINTER_TO_UINT (plen
);
3391 xlsx_rich_text (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3393 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3394 const char *s
= xin
->content
->str
;
3396 if (state
->run_attrs
) {
3397 unsigned len
= strlen (s
);
3398 unsigned start
= state
->r_text
->len
, end
= start
+ len
;
3399 pango_attr_list_filter (state
->run_attrs
,
3400 (PangoAttrFilterFunc
) cb_trunc_attributes
,
3401 GUINT_TO_POINTER (len
));
3402 if (state
->rich_attrs
== NULL
)
3403 state
->rich_attrs
= pango_attr_list_new ();
3404 pango_attr_list_splice (state
->rich_attrs
, state
->run_attrs
, start
, end
);
3405 pango_attr_list_unref (state
->run_attrs
);
3406 state
->run_attrs
= NULL
;
3408 g_string_append (state
->r_text
, s
);
3412 * Rich text is used in multiple dtds. We don't hanadle that with
3413 * particular elegance, but we've got macros.
3415 #define RICH_TEXT_NODES \
3416 GSF_XML_IN_NODE (RICH, RICH_TEXT, XL_NS_SS, "t", GSF_XML_CONTENT, NULL, xlsx_rich_text), \
3417 GSF_XML_IN_NODE (RICH, RICH_PROPS, XL_NS_SS, "rPr", GSF_XML_NO_CONTENT, NULL, NULL), \
3418 /* GSF_XML_IN_NODE (RICH_PROPS, RICH_FONT, XL_NS_SS, "font", GSF_XML_NO_CONTENT, NULL, NULL), */ \
3419 /* docs say 'font' xl is generating rFont */ \
3420 GSF_XML_IN_NODE (RICH_PROPS, RICH_FONT, XL_NS_SS, "rFont", GSF_XML_NO_CONTENT, NULL, NULL), \
3422 GSF_XML_IN_NODE (RICH_PROPS, RICH_CHARSET, XL_NS_SS, "charset", GSF_XML_NO_CONTENT, NULL, NULL), \
3423 GSF_XML_IN_NODE (RICH_PROPS, RICH_FAMILY, XL_NS_SS, "family", GSF_XML_NO_CONTENT, xlsx_run_family, NULL), \
3424 GSF_XML_IN_NODE (RICH_PROPS, RICH_BOLD, XL_NS_SS, "b", GSF_XML_NO_CONTENT, xlsx_run_weight, NULL), \
3425 GSF_XML_IN_NODE (RICH_PROPS, RICH_ITALIC, XL_NS_SS, "i", GSF_XML_NO_CONTENT, xlsx_run_style, NULL), \
3426 GSF_XML_IN_NODE (RICH_PROPS, RICH_STRIKE, XL_NS_SS, "strike", GSF_XML_NO_CONTENT, xlsx_run_strikethrough, NULL), \
3427 GSF_XML_IN_NODE (RICH_PROPS, RICH_OUTLINE, XL_NS_SS, "outline", GSF_XML_NO_CONTENT, NULL, NULL), \
3428 GSF_XML_IN_NODE (RICH_PROPS, RICH_SHADOW, XL_NS_SS, "shadow", GSF_XML_NO_CONTENT, NULL, NULL), \
3429 GSF_XML_IN_NODE (RICH_PROPS, RICH_CONDENSE, XL_NS_SS, "condense", GSF_XML_NO_CONTENT, NULL, NULL), \
3430 GSF_XML_IN_NODE (RICH_PROPS, RICH_EXTEND, XL_NS_SS, "extend", GSF_XML_NO_CONTENT, NULL, NULL), \
3431 GSF_XML_IN_NODE (RICH_PROPS, RICH_COLOR, XL_NS_SS, "color", GSF_XML_NO_CONTENT, xlsx_run_color, NULL), \
3432 GSF_XML_IN_NODE (RICH_PROPS, RICH_SZ, XL_NS_SS, "sz", GSF_XML_NO_CONTENT, xlsx_run_size, NULL), \
3433 GSF_XML_IN_NODE (RICH_PROPS, RICH_ULINE, XL_NS_SS, "u", GSF_XML_NO_CONTENT, xlsx_run_underline, NULL), \
3434 GSF_XML_IN_NODE (RICH_PROPS, RICH_VALIGN, XL_NS_SS, "vertAlign", GSF_XML_NO_CONTENT, xlsx_run_vertalign, NULL), \
3435 GSF_XML_IN_NODE (RICH_PROPS, RICH_SCHEME, XL_NS_SS, "scheme", GSF_XML_NO_CONTENT, NULL, NULL)
3440 static GsfXMLInNode
const xlsx_sheet_dtd
[] = {
3441 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
3442 GSF_XML_IN_NODE_FULL (START
, SHEET
, XL_NS_SS
, "worksheet", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, &xlsx_CT_worksheet
, 0),
3443 GSF_XML_IN_NODE (SHEET
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3444 GSF_XML_IN_NODE (EXTLST
, EXTITEM
, XL_NS_SS
, "ext", GSF_XML_NO_CONTENT
, &xlsx_ext_begin
, &xlsx_ext_end
),
3445 GSF_XML_IN_NODE (EXTITEM
, EXT_TABTEXTCOLOR
, XL_NS_GNM_EXT
, "tabTextColor", GSF_XML_NO_CONTENT
, &xlsx_ext_tabtextcolor
, NULL
),
3446 GSF_XML_IN_NODE (SHEET
, PROPS
, XL_NS_SS
, "sheetPr", GSF_XML_NO_CONTENT
, &xlsx_CT_SheetPr
, NULL
),
3447 GSF_XML_IN_NODE (PROPS
, OUTLINE_PROPS
, XL_NS_SS
, "outlinePr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3448 GSF_XML_IN_NODE (PROPS
, TAB_COLOR
, XL_NS_SS
, "tabColor", GSF_XML_NO_CONTENT
, &xlsx_sheet_tabcolor
, NULL
),
3449 GSF_XML_IN_NODE (PROPS
, PAGE_SETUP
, XL_NS_SS
, "pageSetUpPr", GSF_XML_NO_CONTENT
, &xlsx_sheet_page_setup
, NULL
),
3450 GSF_XML_IN_NODE (SHEET
, DIMENSION
, XL_NS_SS
, "dimension", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3451 GSF_XML_IN_NODE (SHEET
, VIEWS
, XL_NS_SS
, "sheetViews", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3452 GSF_XML_IN_NODE (VIEWS
, VIEW
, XL_NS_SS
, "sheetView", GSF_XML_NO_CONTENT
, &xlsx_CT_SheetView_begin
, &xlsx_CT_SheetView_end
),
3453 GSF_XML_IN_NODE (VIEW
, PANE
, XL_NS_SS
, "pane", GSF_XML_NO_CONTENT
, &xlsx_CT_Pane
, NULL
),
3454 GSF_XML_IN_NODE (VIEW
, SELECTION
, XL_NS_SS
, "selection", GSF_XML_NO_CONTENT
, &xlsx_CT_Selection
, NULL
),
3455 GSF_XML_IN_NODE (VIEW
, PIV_SELECTION
, XL_NS_SS
, "pivotSelection", GSF_XML_NO_CONTENT
, &xlsx_CT_PivotSelection
, NULL
),
3456 GSF_XML_IN_NODE (PIV_SELECTION
, PIV_AREA
, XL_NS_SS
, "pivotArea", GSF_XML_NO_CONTENT
, &xlsx_CT_PivotArea
, NULL
),
3457 GSF_XML_IN_NODE (PIV_AREA
, PIV_AREA_REFS
, XL_NS_SS
, "references", GSF_XML_NO_CONTENT
, &xlsx_CT_PivotAreaReferences
, NULL
),
3458 GSF_XML_IN_NODE (PIV_AREA_REFS
, PIV_AREA_REF
, XL_NS_SS
, "reference", GSF_XML_NO_CONTENT
, &xlsx_CT_PivotAreaReference
, NULL
),
3460 GSF_XML_IN_NODE (SHEET
, DEFAULT_FMT
, XL_NS_SS
, "sheetFormatPr", GSF_XML_NO_CONTENT
, &xlsx_CT_SheetFormatPr
, NULL
),
3462 GSF_XML_IN_NODE (SHEET
, COLS
, XL_NS_SS
, "cols", GSF_XML_NO_CONTENT
, NULL
, xlsx_CT_RowsCols_end
),
3463 GSF_XML_IN_NODE (COLS
, COL
, XL_NS_SS
, "col", GSF_XML_NO_CONTENT
, &xlsx_CT_Col
, NULL
),
3465 GSF_XML_IN_NODE (SHEET
, CONTENT
, XL_NS_SS
, "sheetData", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3466 GSF_XML_IN_NODE (CONTENT
, ROW
, XL_NS_SS
, "row", GSF_XML_NO_CONTENT
, &xlsx_CT_Row
, NULL
),
3467 GSF_XML_IN_NODE (ROW
, CELL
, XL_NS_SS
, "c", GSF_XML_NO_CONTENT
, &xlsx_cell_begin
, &xlsx_cell_end
),
3468 GSF_XML_IN_NODE (CELL
, VALUE
, XL_NS_SS
, "v", GSF_XML_CONTENT
, NULL
, &xlsx_cell_val_end
),
3469 GSF_XML_IN_NODE (CELL
, FMLA
, XL_NS_SS
, "f", GSF_XML_CONTENT
, &xlsx_cell_expr_begin
, &xlsx_cell_expr_end
),
3470 GSF_XML_IN_NODE (CELL
, TEXTINLINE
, XL_NS_SS
, "is", GSF_XML_NO_CONTENT
, &xlsx_cell_inline_begin
, &xlsx_cell_inline_end
),
3471 GSF_XML_IN_NODE (TEXTINLINE
, TEXTRUN
, XL_NS_SS
, "t", GSF_XML_CONTENT
, NULL
, &xlsx_cell_inline_text_end
),
3472 GSF_XML_IN_NODE (TEXTINLINE
, RICH
, XL_NS_SS
, "r", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3474 GSF_XML_IN_NODE (CELL
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_2ND
, NULL
, NULL
),
3476 GSF_XML_IN_NODE (SHEET
, CALC_PR
, XL_NS_SS
, "sheetCalcPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3477 GSF_XML_IN_NODE (SHEET
, CT_SortState
, XL_NS_SS
, "sortState", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3478 GSF_XML_IN_NODE (CT_SortState
, CT_SortCondition
, XL_NS_SS
, "sortCondition", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3479 GSF_XML_IN_NODE (SHEET
, SCENARIOS
, XL_NS_SS
, "scenarios", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3480 GSF_XML_IN_NODE (SCENARIOS
, INPUT_CELLS
, XL_NS_SS
, "inputCells", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3481 GSF_XML_IN_NODE (SHEET
, PROTECTED_RANGES
, XL_NS_SS
, "protectedRanges", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3482 GSF_XML_IN_NODE (PROTECTED_RANGES
, PROTECTED_RANGE
, XL_NS_SS
, "protectedRange", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3484 GSF_XML_IN_NODE (SHEET
, CT_AutoFilter
, XL_NS_SS
, "autoFilter", GSF_XML_NO_CONTENT
,
3485 &xlsx_CT_AutoFilter_begin
, &xlsx_CT_AutoFilter_end
),
3486 GSF_XML_IN_NODE (CT_AutoFilter
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_2ND
, NULL
, NULL
),
3487 GSF_XML_IN_NODE (CT_AutoFilter
, CT_SortState
, XL_NS_SS
, "sortState", GSF_XML_2ND
, NULL
, NULL
),
3488 GSF_XML_IN_NODE (CT_AutoFilter
, CT_FilterColumn
, XL_NS_SS
, "filterColumn", GSF_XML_NO_CONTENT
,
3489 &xlsx_CT_FilterColumn_begin
, NULL
),
3490 GSF_XML_IN_NODE (CT_FilterColumn
, CT_Filters
, XL_NS_SS
, "filters", GSF_XML_NO_CONTENT
,
3491 &xlsx_CT_Filters_begin
, &xlsx_CT_Filters_end
),
3492 GSF_XML_IN_NODE (CT_Filters
, CT_Filter
, XL_NS_SS
, "filter", GSF_XML_NO_CONTENT
, &xlsx_CT_Filter
, NULL
),
3493 GSF_XML_IN_NODE (CT_FilterColumn
, CT_CustomFilters
, XL_NS_SS
, "customFilters", GSF_XML_NO_CONTENT
,
3494 &xlsx_CT_CustomFilters_begin
, &xlsx_CT_CustomFilters_end
),
3495 GSF_XML_IN_NODE (CT_CustomFilters
, CT_CustomFilter
, XL_NS_SS
, "customFilter", GSF_XML_NO_CONTENT
, &xlsx_CT_CustomFilter
, NULL
),
3496 GSF_XML_IN_NODE (CT_FilterColumn
, CT_Top10
, XL_NS_SS
, "top10", GSF_XML_NO_CONTENT
, &xlsx_CT_Top10
, NULL
),
3497 GSF_XML_IN_NODE (CT_FilterColumn
, CT_DynamicFilter
, XL_NS_SS
, "dynamicFilter", GSF_XML_NO_CONTENT
, &xlsx_CT_DynamicFilter
, NULL
),
3498 GSF_XML_IN_NODE (CT_FilterColumn
, CT_ColorFilter
, XL_NS_SS
, "colorFilter", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3499 GSF_XML_IN_NODE (CT_FilterColumn
, CT_IconFilter
, XL_NS_SS
, "iconFilter", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3501 GSF_XML_IN_NODE (SHEET
, CT_DataValidations
, XL_NS_SS
, "dataValidations", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3502 GSF_XML_IN_NODE (CT_DataValidations
, CT_DataValidation
, XL_NS_SS
, "dataValidation", GSF_XML_NO_CONTENT
,
3503 &xlsx_CT_DataValidation_begin
, &xlsx_CT_DataValidation_end
),
3504 GSF_XML_IN_NODE_FULL (CT_DataValidation
, VAL_FORMULA1
, XL_NS_SS
, "formula1", GSF_XML_CONTENT
, FALSE
, FALSE
, NULL
, &xlsx_validation_expr
, 0),
3505 GSF_XML_IN_NODE_FULL (CT_DataValidation
, VAL_FORMULA2
, XL_NS_SS
, "formula2", GSF_XML_CONTENT
, FALSE
, FALSE
, NULL
, &xlsx_validation_expr
, 1),
3507 GSF_XML_IN_NODE (SHEET
, MERGES
, XL_NS_SS
, "mergeCells", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3508 GSF_XML_IN_NODE (MERGES
, MERGE
, XL_NS_SS
, "mergeCell", GSF_XML_NO_CONTENT
, &xlsx_CT_MergeCell
, NULL
),
3510 GSF_XML_IN_NODE (SHEET
, DRAWING
, XL_NS_SS
, "drawing", GSF_XML_NO_CONTENT
, &xlsx_sheet_drawing
, NULL
),
3512 GSF_XML_IN_NODE (SHEET
, PROTECTION
, XL_NS_SS
, "sheetProtection", GSF_XML_NO_CONTENT
, &xlsx_CT_SheetProtection
, NULL
),
3513 GSF_XML_IN_NODE (SHEET
, PHONETIC
, XL_NS_SS
, "phoneticPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3514 GSF_XML_IN_NODE (SHEET
, COND_FMTS
, XL_NS_SS
, "conditionalFormatting", GSF_XML_NO_CONTENT
,
3515 &xlsx_cond_fmt_begin
, &xlsx_cond_fmt_end
),
3516 GSF_XML_IN_NODE (COND_FMTS
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_2ND
, NULL
, NULL
),
3517 GSF_XML_IN_NODE (COND_FMTS
, COND_RULE
, XL_NS_SS
, "cfRule", GSF_XML_NO_CONTENT
,
3518 &xlsx_cond_fmt_rule_begin
, &xlsx_cond_fmt_rule_end
),
3519 GSF_XML_IN_NODE (COND_RULE
, COND_FMLA
, XL_NS_SS
, "formula", GSF_XML_CONTENT
, NULL
, &xlsx_cond_fmt_formula_end
),
3520 GSF_XML_IN_NODE (COND_RULE
, COND_COLOR_SCALE
, XL_NS_SS
, "colorScale", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3521 GSF_XML_IN_NODE (COND_COLOR_SCALE
, CFVO
, XL_NS_SS
, "cfvo", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3522 GSF_XML_IN_NODE (COND_COLOR_SCALE
, COND_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3523 GSF_XML_IN_NODE (COND_RULE
, COND_DATA_BAR
, XL_NS_SS
, "dataBar", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3524 GSF_XML_IN_NODE (COND_RULE
, COND_ICON_SET
, XL_NS_SS
, "iconSet", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3525 GSF_XML_IN_NODE (COND_ICON_SET
, CFVO
, XL_NS_SS
, "cfvo", GSF_XML_2ND
, NULL
, NULL
),
3527 GSF_XML_IN_NODE (SHEET
, HYPERLINKS
, XL_NS_SS
, "hyperlinks", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3528 GSF_XML_IN_NODE (HYPERLINKS
, HYPERLINK
, XL_NS_SS
, "hyperlink", GSF_XML_NO_CONTENT
, &xlsx_CT_HyperLinks
, NULL
),
3530 GSF_XML_IN_NODE (SHEET
, PRINT_OPTS
, XL_NS_SS
, "printOptions", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3531 GSF_XML_IN_NODE (SHEET
, PRINT_MARGINS
, XL_NS_SS
, "pageMargins", GSF_XML_NO_CONTENT
, &xlsx_CT_PageMargins
, NULL
),
3532 GSF_XML_IN_NODE (SHEET
, PRINT_SETUP
, XL_NS_SS
, "pageSetup", GSF_XML_NO_CONTENT
, &xlsx_CT_PageSetup
, NULL
),
3533 GSF_XML_IN_NODE (SHEET
, PRINT_HEADER_FOOTER
, XL_NS_SS
, "headerFooter", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3534 GSF_XML_IN_NODE (PRINT_HEADER_FOOTER
, ODD_HEADER
, XL_NS_SS
, "oddHeader", GSF_XML_CONTENT
, NULL
, &xlsx_CT_oddheader_end
),
3535 GSF_XML_IN_NODE (PRINT_HEADER_FOOTER
, ODD_FOOTER
, XL_NS_SS
, "oddFooter", GSF_XML_CONTENT
, NULL
, &xlsx_CT_oddfooter_end
),
3537 GSF_XML_IN_NODE_FULL (SHEET
, ROW_BREAKS
, XL_NS_SS
, "rowBreaks", GSF_XML_NO_CONTENT
,
3538 FALSE
, FALSE
, &xlsx_CT_PageBreaks_begin
, &xlsx_CT_PageBreaks_end
, 1),
3539 GSF_XML_IN_NODE (ROW_BREAKS
, CT_PageBreak
, XL_NS_SS
, "brk", GSF_XML_NO_CONTENT
, &xlsx_CT_PageBreak
, NULL
),
3540 GSF_XML_IN_NODE_FULL (SHEET
, COL_BREAKS
, XL_NS_SS
, "colBreaks", GSF_XML_NO_CONTENT
,
3541 FALSE
, FALSE
, &xlsx_CT_PageBreaks_begin
, &xlsx_CT_PageBreaks_end
, 0),
3542 GSF_XML_IN_NODE (COL_BREAKS
, CT_PageBreak
, XL_NS_SS
, "brk", GSF_XML_2ND
, NULL
, NULL
),
3544 GSF_XML_IN_NODE (SHEET
, LEGACY_DRAW
, XL_NS_SS
, "legacyDrawing", GSF_XML_NO_CONTENT
, &xlsx_sheet_legacy_drawing
, NULL
),
3545 GSF_XML_IN_NODE (SHEET
, OLE_OBJECTS
, XL_NS_SS
, "oleObjects", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3546 GSF_XML_IN_NODE (OLE_OBJECTS
, OLE_OBJECT
, XL_NS_SS
, "oleObject", GSF_XML_NO_CONTENT
, &xlsx_ole_object
, NULL
),
3551 /****************************************************************************/
3554 xlsx_CT_PivotCache (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3556 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3557 xmlChar
const *id
= NULL
;
3558 xmlChar
const *cacheId
= NULL
;
3560 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3561 if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_DOC_REL
, "id"))
3563 else if (0 == strcmp (attrs
[0], "cacheId"))
3567 if (NULL
!= id
&& NULL
!= cacheId
) {
3568 g_return_if_fail (NULL
== state
->pivot
.cache
);
3570 xlsx_parse_rel_by_id (xin
, id
,
3571 xlsx_pivot_cache_def_dtd
, xlsx_ns
);
3573 g_return_if_fail (NULL
!= state
->pivot
.cache
);
3575 /* absorb the reference to the cache */
3576 g_hash_table_replace (state
->pivot
.cache_by_id
,
3577 g_strdup (cacheId
), state
->pivot
.cache
);
3578 state
->pivot
.cache
= NULL
;
3583 xlsx_CT_WorkbookPr (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3585 static EnumVal
const switchModes
[] = {
3595 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3597 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3598 if (attr_enum (xin
, attrs
, "date1904", switchModes
, &tmp
))
3599 workbook_set_1904 (state
->wb
, tmp
);
3604 xlsx_CT_CalcPr (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3606 static EnumVal
const calcModes
[] = {
3607 { "manual", FALSE
},
3609 { "autoNoTable", TRUE
},
3612 static EnumVal
const refModes
[] = {
3619 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3621 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3622 if (attr_enum (xin
, attrs
, "calcMode", calcModes
, &tmp
))
3623 workbook_set_recalcmode (state
->wb
, tmp
);
3624 else if (attr_bool (xin
, attrs
, "fullCalcOnLoad", &tmp
))
3626 else if (attr_enum (xin
, attrs
, "refMode", refModes
, &tmp
))
3628 else if (attr_bool (xin
, attrs
, "iterate", &tmp
))
3629 workbook_iteration_enabled (state
->wb
, tmp
);
3630 else if (attr_int (xin
, attrs
, "iterateCount", &tmp
))
3631 workbook_iteration_max_number (state
->wb
, tmp
);
3632 else if (attr_float (xin
, attrs
, "iterateDelta", &delta
))
3633 workbook_iteration_tolerance (state
->wb
, delta
);
3634 else if (attr_bool (xin
, attrs
, "fullPrecision", &tmp
))
3636 else if (attr_bool (xin
, attrs
, "calcCompleted", &tmp
))
3638 else if (attr_bool (xin
, attrs
, "calcOnSave", &tmp
))
3640 else if (attr_bool (xin
, attrs
, "conncurrentCalc", &tmp
))
3642 else if (attr_bool (xin
, attrs
, "forceFullCalc", &tmp
))
3644 else if (attr_int (xin
, attrs
, "concurrentManualCalc", &tmp
))
3650 xlsx_CT_workbookView (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3652 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3653 int active_tab
= -1;
3654 int width
= -1, height
= -1;
3655 const int scale
= 10; /* Guess */
3657 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3658 if (attr_int (xin
, attrs
, "activeTab", &active_tab
))
3660 else if (attr_int (xin
, attrs
, "windowHeight", &height
))
3662 else if (attr_int (xin
, attrs
, "windowWidth", &width
))
3666 if (width
> scale
/ 2 && height
> scale
/ 2)
3667 wb_view_preferred_size (state
->wb_view
,
3668 (width
+ scale
/ 2) / scale
,
3669 (height
+ scale
/ 2) / scale
);
3673 xlsx_sheet_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3675 static EnumVal
const visibilities
[] = {
3676 { "visible", GNM_SHEET_VISIBILITY_VISIBLE
},
3677 { "hidden", GNM_SHEET_VISIBILITY_HIDDEN
},
3678 { "veryHidden", GNM_SHEET_VISIBILITY_VERY_HIDDEN
},
3681 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3682 char const *name
= NULL
;
3683 char const *part_id
= NULL
;
3685 int viz
= (int)GNM_SHEET_VISIBILITY_VISIBLE
;
3687 maybe_update_progress (xin
);
3689 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3690 if (0 == strcmp (attrs
[0], "name"))
3692 else if (attr_enum (xin
, attrs
, "state", visibilities
, &viz
))
3694 else if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_DOC_REL
, "id"))
3699 xlsx_warning (xin
, _("Ignoring a sheet without a name"));
3703 sheet
= workbook_sheet_by_name (state
->wb
, name
);
3704 if (NULL
== sheet
) {
3705 sheet
= wrap_sheet_new (state
->wb
, name
, XLSX_MaxCol
, XLSX_MaxRow
);
3706 workbook_sheet_attach (state
->wb
, sheet
);
3708 g_object_set (sheet
, "visibility", viz
, NULL
);
3710 g_object_set_data_full (G_OBJECT (sheet
), "_XLSX_RelID", g_strdup (part_id
),
3711 (GDestroyNotify
) g_free
);
3715 xlsx_wb_name_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3717 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3718 const char *name
= NULL
;
3721 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3722 if (0 == strcmp (attrs
[0], "name"))
3724 else if (attr_int (xin
, attrs
, "localSheetId", &sheet_idx
))
3728 state
->defined_name
= g_strdup (name
);
3729 state
->defined_name_sheet
=
3731 ? workbook_sheet_by_index (state
->wb
, sheet_idx
)
3736 xlsx_wb_name_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3738 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3740 Sheet
*sheet
= state
->defined_name_sheet
;
3741 GnmNamedExpr
*nexpr
;
3742 char *error_msg
= NULL
;
3743 const char *thename
= state
->defined_name
;
3744 const char *thevalue
= xin
->content
->str
;
3745 gboolean bogus
= FALSE
;
3747 g_return_if_fail (thename
!= NULL
);
3749 parse_pos_init (&pp
, state
->wb
, sheet
, 0, 0);
3751 if (g_str_has_prefix (thename
, "_xlnm.")) {
3755 editable
= g_str_equal (thename
, "Sheet_Title");
3756 bogus
= g_str_equal (thename
, "Print_Area") &&
3757 g_str_equal (thevalue
, "!#REF!");
3760 : expr_name_add (&pp
, thename
,
3761 gnm_expr_top_new_constant (value_new_empty ()),
3762 &error_msg
, TRUE
, NULL
);
3764 nexpr
->is_permanent
= TRUE
;
3765 nexpr
->is_editable
= editable
;
3768 nexpr
= expr_name_add (&pp
, thename
,
3769 gnm_expr_top_new_constant (value_new_empty ()),
3770 &error_msg
, TRUE
, NULL
);
3773 /* Silently ignore */
3775 state
->delayed_names
=
3776 g_list_prepend (state
->delayed_names
, sheet
);
3777 state
->delayed_names
=
3778 g_list_prepend (state
->delayed_names
,
3779 g_strdup (thevalue
));
3780 state
->delayed_names
=
3781 g_list_prepend (state
->delayed_names
, nexpr
);
3783 xlsx_warning (xin
, _("Failed to define name: %s"), error_msg
);
3787 g_free (state
->defined_name
);
3788 state
->defined_name
= NULL
;
3792 handle_delayed_names (GsfXMLIn
*xin
)
3794 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3797 for (l
= state
->delayed_names
; l
; l
= l
->next
->next
->next
) {
3798 GnmNamedExpr
*nexpr
= l
->data
;
3799 char *expr_str
= l
->next
->data
;
3800 Sheet
*sheet
= l
->next
->next
->data
;
3801 GnmExprTop
const *texpr
;
3804 parse_pos_init (&pp
, state
->wb
, sheet
, 0, 0);
3806 texpr
= gnm_expr_top_new_constant (value_new_error_REF (NULL
));
3808 texpr
= xlsx_parse_expr (xin
, expr_str
, &pp
);
3810 expr_name_set_expr (nexpr
, texpr
);
3815 g_list_free (state
->delayed_names
);
3816 state
->delayed_names
= NULL
;
3820 xlsx_wb_names_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3822 handle_delayed_names (xin
);
3826 /**************************************************************************************************/
3829 xlsx_read_external_book (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3831 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3832 GsfOpenPkgRel
const *rel
= gsf_open_pkg_lookup_rel_by_type
3833 (gsf_xml_in_get_input (xin
),
3834 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/"
3837 rel
= gsf_open_pkg_lookup_rel_by_type
3838 (gsf_xml_in_get_input (xin
),
3839 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/"
3840 "externalLinkPath");
3841 if (NULL
!= rel
&& gsf_open_pkg_rel_is_extern (rel
))
3842 state
->external_ref
= xlsx_conventions_add_extern_ref (
3843 state
->convs
, gsf_open_pkg_rel_get_target (rel
));
3845 xlsx_warning (xin
, _("Unable to resolve external relationship"));
3848 xlsx_read_external_book_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3850 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3851 state
->external_ref
= NULL
;
3854 xlsx_read_external_sheetname (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3856 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3857 if (state
->external_ref
)
3858 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3859 if (0 == strcmp (attrs
[0], "val"))
3860 workbook_sheet_attach
3861 (state
->external_ref
,
3862 state
->external_ref_sheet
=
3863 wrap_sheet_new (state
->external_ref
, attrs
[1], 256, 65536));
3867 xlsx_read_external_sheetname_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3869 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3870 state
->external_ref_sheet
= NULL
;
3873 static GsfXMLInNode
const xlsx_extern_dtd
[] = {
3874 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
3875 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),
3876 GSF_XML_IN_NODE (LINK
, BOOK
, XL_NS_SS
, "externalBook", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3877 GSF_XML_IN_NODE (BOOK
, SHEET_NAMES
, XL_NS_SS
, "sheetNames", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3878 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
),
3879 GSF_XML_IN_NODE (BOOK
, SHEET_DATASET
, XL_NS_SS
, "sheetDataSet", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3880 GSF_XML_IN_NODE (SHEET_DATASET
, SHEET_DATA
, XL_NS_SS
, "sheetData", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3881 GSF_XML_IN_NODE (SHEET_DATA
, ROW
, XL_NS_SS
, "row", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3882 GSF_XML_IN_NODE (ROW
, CELL
, XL_NS_SS
, "cell", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3883 GSF_XML_IN_NODE (CELL
, VAL
, XL_NS_SS
, "v", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3889 xlsx_wb_external_ref (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3891 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3892 if (gsf_xml_in_namecmp (xin
, attrs
[0], XL_NS_DOC_REL
, "id"))
3893 xlsx_parse_rel_by_id (xin
, attrs
[1], xlsx_extern_dtd
, xlsx_ns
);
3897 /**************************************************************************************************/
3900 xlsx_comments_start (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
3902 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3903 state
->authors
= g_ptr_array_new_with_free_func ((GDestroyNotify
) g_free
);
3907 xlsx_comments_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3909 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3910 g_ptr_array_unref (state
->authors
);
3911 state
->authors
= NULL
;
3915 xlsx_comment_author_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3917 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3918 int i
= strlen (xin
->content
->str
);
3919 char *name
= xin
->content
->str
;
3921 /* remove any trailing white space */
3922 /* not sure this is correct, we might be careful about encoding */
3923 while (i
> 0 && g_ascii_isspace (name
[i
-1]))
3925 name
= g_new (char, i
+ 1);
3926 memcpy (name
, xin
->content
->str
, i
);
3928 g_ptr_array_add (state
->authors
, name
);
3932 xlsx_comment_start (GsfXMLIn
*xin
, xmlChar
const **attrs
)
3934 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3938 state
->comment
= g_object_new (cell_comment_get_type (), NULL
);
3939 so
= GNM_SO (state
->comment
);
3940 anchor_r
= sheet_object_get_anchor (so
)->cell_bound
;
3942 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
3943 if (strcmp (attrs
[0], "ref") == 0)
3944 range_parse (&anchor_r
, attrs
[1], gnm_sheet_get_size (state
->sheet
));
3945 else if (strcmp (attrs
[0], "authorId") == 0) {
3946 unsigned id
= atoi (attrs
[1]);
3948 if (id
< state
->authors
->len
) {
3949 name
= g_ptr_array_index (state
->authors
, id
);
3950 if (*name
) /* do not set an empty name */
3951 g_object_set (state
->comment
, "author", name
, NULL
);
3956 cell_comment_set_pos (GNM_CELL_COMMENT (so
), &anchor_r
.start
);
3957 state
->r_text
= g_string_new ("");
3961 xlsx_comment_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3963 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3964 char *text
= g_string_free (state
->r_text
, FALSE
);
3965 state
->r_text
= NULL
;
3966 g_object_set (state
->comment
, "text", text
, NULL
);
3968 if (state
->rich_attrs
) {
3969 g_object_set (state
->comment
, "markup", state
->rich_attrs
, NULL
);
3970 pango_attr_list_unref (state
->rich_attrs
);
3971 state
->rich_attrs
= NULL
;
3973 sheet_object_set_sheet (GNM_SO (state
->comment
), state
->sheet
);
3974 g_object_unref (state
->comment
);
3975 state
->comment
= NULL
;
3977 maybe_update_progress (xin
);
3981 xlsx_r_text (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
3983 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
3984 g_string_append (state
->r_text
, xin
->content
->str
);
3987 static GsfXMLInNode
const xlsx_comments_dtd
[] = {
3988 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
3989 GSF_XML_IN_NODE_FULL (START
, COMMENTS
, XL_NS_SS
, "comments", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, xlsx_comments_start
, xlsx_comments_end
, 0),
3990 GSF_XML_IN_NODE (COMMENTS
, AUTHORS
, XL_NS_SS
, "authors", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3991 GSF_XML_IN_NODE (AUTHORS
, AUTHOR
, XL_NS_SS
, "author", GSF_XML_CONTENT
, NULL
, xlsx_comment_author_end
),
3992 GSF_XML_IN_NODE (COMMENTS
, COMMENTLIST
, XL_NS_SS
, "commentList", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3993 GSF_XML_IN_NODE (COMMENTLIST
, COMMENT
, XL_NS_SS
, "comment", GSF_XML_NO_CONTENT
, xlsx_comment_start
, xlsx_comment_end
),
3994 GSF_XML_IN_NODE (COMMENT
, TEXTITEM
, XL_NS_SS
, "text", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3995 GSF_XML_IN_NODE (TEXTITEM
, TEXT
, XL_NS_SS
, "t", GSF_XML_CONTENT
, NULL
, xlsx_r_text
),
3996 GSF_XML_IN_NODE (TEXTITEM
, RICH
, XL_NS_SS
, "r", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3998 GSF_XML_IN_NODE (TEXTITEM
, ITEM_PHONETIC_RUN
, XL_NS_SS
, "rPh", GSF_XML_NO_CONTENT
, NULL
, NULL
),
3999 GSF_XML_IN_NODE (ITEM_PHONETIC_RUN
, PHONETIC_TEXT
, XL_NS_SS
, "t", GSF_XML_CONTENT
, NULL
, NULL
),
4000 GSF_XML_IN_NODE (TEXTITEM
, ITEM_PHONETIC
, XL_NS_SS
, "phoneticPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4005 /**************************************************************************************************/
4008 cb_by_zorder (gconstpointer a
, gconstpointer b
, gpointer data
)
4010 GHashTable
*zorder
= data
;
4011 int za
= GPOINTER_TO_UINT (g_hash_table_lookup (zorder
, a
));
4012 int zb
= GPOINTER_TO_UINT (g_hash_table_lookup (zorder
, b
));
4013 return zb
- za
; /* descending */
4018 xlsx_wb_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4020 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4021 int i
, n
= workbook_sheet_count (state
->wb
);
4022 char const *part_id
;
4024 GsfInput
*sin
, *cin
;
4027 end_update_progress (state
);
4029 /* Load sheets after setting up the workbooks to give us time to create
4030 * all of them and parse names */
4031 for (i
= 0 ; i
< n
; i
++, state
->sheet
= NULL
) {
4036 if (NULL
== (state
->sheet
= workbook_sheet_by_index (state
->wb
, i
)))
4038 if (NULL
== (part_id
= g_object_get_data (G_OBJECT (state
->sheet
), "_XLSX_RelID"))) {
4039 xlsx_warning (xin
, _("Missing part-id for sheet '%s'"),
4040 state
->sheet
->name_unquoted
);
4044 /* Apply the 'Normal' style (aka builtin 0) to the entire sheet */
4045 if (NULL
!= (style
= g_hash_table_lookup(state
->cell_styles
, "0"))) {
4047 gnm_style_ref (style
);
4048 range_init_full_sheet (&r
, state
->sheet
);
4049 sheet_style_set_range (state
->sheet
, &r
, style
);
4052 sin
= gsf_open_pkg_open_rel_by_id (gsf_xml_in_get_input (xin
), part_id
, &err
);
4054 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4055 go_io_warning (state
->context
, "%s", err
->message
);
4062 cin
= gsf_open_pkg_open_rel_by_type (sin
,
4063 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments", NULL
);
4064 message
= g_strdup_printf (_("Reading sheet '%s'..."), state
->sheet
->name_unquoted
);
4065 start_update_progress (state
, sin
, message
,
4066 0.3 + i
*0.6/n
, 0.3 + i
*0.6/n
+ 0.5/n
);
4068 xlsx_parse_stream (state
, sin
, xlsx_sheet_dtd
);
4069 end_update_progress (state
);
4072 start_update_progress (state
, cin
, _("Reading comments..."),
4073 0.3 + i
*0.6/n
+ 0.5/n
, 0.3 + i
*0.6/n
+ 0.6/n
);
4074 xlsx_parse_stream (state
, cin
, xlsx_comments_dtd
);
4075 end_update_progress (state
);
4078 zoffset
= (g_slist_length (state
->pending_objects
) -
4079 g_hash_table_size (state
->zorder
));
4080 for (j
= zoffset
, l
= state
->pending_objects
; l
; l
= l
->next
) {
4081 SheetObject
*so
= l
->data
;
4082 int z
= GPOINTER_TO_UINT (g_hash_table_lookup (state
->zorder
, so
));
4087 g_hash_table_insert (state
->zorder
, so
, GINT_TO_POINTER (z
));
4089 state
->pending_objects
= g_slist_sort_with_data
4090 (state
->pending_objects
, cb_by_zorder
, state
->zorder
);
4092 while (state
->pending_objects
) {
4093 SheetObject
*obj
= state
->pending_objects
->data
;
4094 state
->pending_objects
= g_slist_delete_link (state
->pending_objects
,
4095 state
->pending_objects
);
4096 sheet_object_set_sheet (obj
, state
->sheet
);
4097 g_object_unref (obj
);
4100 /* Flag a respan here in case nothing else does */
4101 sheet_flag_recompute_spans (state
->sheet
);
4106 xlsx_webpub_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4108 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4109 if (strcmp (attrs
[0], "characterSet") == 0) {
4110 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4111 state
->version
= ECMA_376_2008
;
4116 static GsfXMLInNode
const xlsx_workbook_dtd
[] = {
4117 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4118 GSF_XML_IN_NODE_FULL (START
, WORKBOOK
, XL_NS_SS
, "workbook", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, &xlsx_wb_end
, 0),
4119 GSF_XML_IN_NODE (WORKBOOK
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4120 GSF_XML_IN_NODE (EXTLST
, EXTITEM
, XL_NS_SS
, "ext", GSF_XML_NO_CONTENT
, &xlsx_ext_begin
, &xlsx_ext_end
),
4121 GSF_XML_IN_NODE (WORKBOOK
, VERSION
, XL_NS_SS
, "fileVersion", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4122 GSF_XML_IN_NODE (WORKBOOK
, PROPERTIES
, XL_NS_SS
, "workbookPr", GSF_XML_NO_CONTENT
, &xlsx_CT_WorkbookPr
, NULL
),
4123 GSF_XML_IN_NODE (WORKBOOK
, CALC_PROPS
, XL_NS_SS
, "calcPr", GSF_XML_NO_CONTENT
, &xlsx_CT_CalcPr
, NULL
),
4125 GSF_XML_IN_NODE (WORKBOOK
, VIEWS
, XL_NS_SS
, "bookViews", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4126 GSF_XML_IN_NODE (VIEWS
, VIEW
, XL_NS_SS
, "workbookView", GSF_XML_NO_CONTENT
, &xlsx_CT_workbookView
, NULL
),
4127 GSF_XML_IN_NODE (WORKBOOK
, CUSTOMWVIEWS
, XL_NS_SS
, "customWorkbookViews", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4128 GSF_XML_IN_NODE (CUSTOMWVIEWS
, CUSTOMWVIEW
, XL_NS_SS
, "customWorkbookView", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4129 GSF_XML_IN_NODE (CUSTOMWVIEW
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_2ND
, NULL
, NULL
),
4130 GSF_XML_IN_NODE_FULL (WORKBOOK
, SHEETS
, XL_NS_SS
, "sheets", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4131 GSF_XML_IN_NODE (SHEETS
, SHEET
, XL_NS_SS
, "sheet", GSF_XML_NO_CONTENT
, &xlsx_sheet_begin
, NULL
),
4132 GSF_XML_IN_NODE (WORKBOOK
, FGROUPS
, XL_NS_SS
, "functionGroups", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4133 GSF_XML_IN_NODE (FGROUPS
, FGROUP
, XL_NS_SS
, "functionGroup", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4134 GSF_XML_IN_NODE (WORKBOOK
, WEB_PUB
, XL_NS_SS
, "webPublishing", GSF_XML_NO_CONTENT
, xlsx_webpub_begin
, NULL
),
4135 GSF_XML_IN_NODE (WORKBOOK
, EXTERNS
, XL_NS_SS
, "externalReferences", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4136 GSF_XML_IN_NODE (EXTERNS
, EXTERN
, XL_NS_SS
, "externalReference", GSF_XML_NO_CONTENT
, xlsx_wb_external_ref
, NULL
),
4137 GSF_XML_IN_NODE (WORKBOOK
, NAMES
, XL_NS_SS
, "definedNames", GSF_XML_NO_CONTENT
, NULL
, xlsx_wb_names_end
),
4138 GSF_XML_IN_NODE (NAMES
, NAME
, XL_NS_SS
, "definedName", GSF_XML_CONTENT
, xlsx_wb_name_begin
, xlsx_wb_name_end
),
4139 GSF_XML_IN_NODE (WORKBOOK
, PIVOTCACHES
, XL_NS_SS
, "pivotCaches", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4140 GSF_XML_IN_NODE (PIVOTCACHES
, PIVOTCACHE
, XL_NS_SS
, "pivotCache", GSF_XML_NO_CONTENT
, &xlsx_CT_PivotCache
, NULL
),
4142 GSF_XML_IN_NODE (WORKBOOK
, RECOVERY
, XL_NS_SS
, "fileRecoveryPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4143 GSF_XML_IN_NODE (WORKBOOK
, OLESIZE
, XL_NS_SS
, "oleSize", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4144 GSF_XML_IN_NODE (WORKBOOK
, SMARTTAGPR
, XL_NS_SS
, "smartTagPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4145 GSF_XML_IN_NODE (WORKBOOK
, SMARTTTYPES
, XL_NS_SS
, "smartTagTypes", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4146 GSF_XML_IN_NODE (SMARTTTYPES
, SMARTTTYPE
, XL_NS_SS
, "smartTagType", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4147 GSF_XML_IN_NODE (WORKBOOK
, WEB_PUB_OBJS
, XL_NS_SS
, "webPublishObjects", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4148 GSF_XML_IN_NODE (WEB_PUB_OBJS
, WEB_PUB_OBJ
, XL_NS_SS
, "webPublishObject", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4153 /****************************************************************************/
4156 xlsx_sst_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4158 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4161 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4162 if (attr_int (xin
, attrs
, "uniqueCount", &count
))
4163 g_array_set_size (state
->sst
, count
);
4169 xlsx_sstitem_start (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4171 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4172 state
->r_text
= g_string_new ("");
4176 xlsx_sstitem_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4178 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4180 char *text
= g_string_free (state
->r_text
, FALSE
);
4181 state
->r_text
= NULL
;
4183 if (state
->count
>= state
->sst
->len
)
4184 g_array_set_size (state
->sst
, state
->count
+1);
4185 entry
= &g_array_index (state
->sst
, XLSXStr
, state
->count
);
4187 entry
->str
= go_string_new_nocopy (text
);
4189 if (state
->rich_attrs
) {
4190 entry
->markup
= go_format_new_markup (state
->rich_attrs
, FALSE
);
4191 state
->rich_attrs
= NULL
;
4195 static GsfXMLInNode
const xlsx_shared_strings_dtd
[] = {
4196 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4197 GSF_XML_IN_NODE_FULL (START
, SST
, XL_NS_SS
, "sst", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, &xlsx_sst_begin
, NULL
, 0),
4198 GSF_XML_IN_NODE (SST
, ITEM
, XL_NS_SS
, "si", GSF_XML_NO_CONTENT
, &xlsx_sstitem_start
, &xlsx_sstitem_end
), /* beta2 */
4199 GSF_XML_IN_NODE (ITEM
, TEXT
, XL_NS_SS
, "t", GSF_XML_CONTENT
, NULL
, xlsx_r_text
),
4200 GSF_XML_IN_NODE (ITEM
, RICH
, XL_NS_SS
, "r", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4202 GSF_XML_IN_NODE (ITEM
, ITEM_PHONETIC_RUN
, XL_NS_SS
, "rPh", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4203 GSF_XML_IN_NODE (ITEM_PHONETIC_RUN
, PHONETIC_TEXT
, XL_NS_SS
, "t", GSF_XML_SHARED_CONTENT
, NULL
, NULL
),
4204 GSF_XML_IN_NODE (ITEM
, ITEM_PHONETIC
, XL_NS_SS
, "phoneticPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4209 /****************************************************************************/
4212 xlsx_numfmt_common (GsfXMLIn
*xin
, xmlChar
const **attrs
, gboolean apply
)
4214 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4215 xmlChar
const *fmt
= NULL
;
4216 xmlChar
const *id
= NULL
;
4218 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4219 if (0 == strcmp (attrs
[0], "numFmtId"))
4221 else if (0 == strcmp (attrs
[0], "formatCode"))
4225 if (NULL
!= id
&& NULL
!= fmt
) {
4226 GOFormat
*gfmt
= go_format_new_from_XL (fmt
);
4228 gnm_style_set_format (state
->style_accum
, gfmt
);
4229 g_hash_table_replace (state
->num_fmts
, g_strdup (id
), gfmt
);
4234 xlsx_style_numfmt (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4236 xlsx_numfmt_common (xin
, attrs
, FALSE
);
4242 XLSX_COLLECT_BORDERS
,
4244 XLSX_COLLECT_STYLE_XFS
,
4246 XLSX_COLLECT_TABLE_STYLES
4250 xlsx_collection_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4252 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4254 GPtrArray
**pcollection
;
4256 g_return_if_fail (NULL
== state
->collection
);
4258 switch (xin
->node
->user_data
.v_int
) {
4259 case XLSX_COLLECT_FONT
: pcollection
= &state
->fonts
; break;
4260 case XLSX_COLLECT_FILLS
: pcollection
= &state
->fills
; break;
4261 case XLSX_COLLECT_BORDERS
: pcollection
= &state
->borders
; break;
4262 case XLSX_COLLECT_XFS
: pcollection
= &state
->xfs
; break;
4263 case XLSX_COLLECT_STYLE_XFS
: pcollection
= &state
->style_xfs
; break;
4264 case XLSX_COLLECT_DXFS
: pcollection
= &state
->dxfs
; break;
4265 case XLSX_COLLECT_TABLE_STYLES
: pcollection
= &state
->table_styles
; break;
4267 g_assert_not_reached ();
4272 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4273 if (attr_uint (xin
, attrs
, "count", &count
))
4277 /* Don't trust huge counts. */
4278 count
= MIN (count
, 1000u);
4280 if (*pcollection
== NULL
) {
4281 *pcollection
= g_ptr_array_new ();
4282 g_ptr_array_set_size (*pcollection
, count
);
4285 state
->collection
= *pcollection
;
4289 xlsx_collection_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4291 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4293 /* resize just in case the count hint was wrong */
4294 g_ptr_array_set_size (state
->collection
, state
->count
);
4296 state
->collection
= NULL
;
4300 xlsx_col_elem_begin (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4302 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4303 if (!state
->style_accum_partial
) {
4304 g_return_if_fail (NULL
== state
->style_accum
);
4305 state
->style_accum
= gnm_style_new ();
4310 xlsx_col_elem_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4312 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4314 if (!state
->style_accum_partial
) {
4315 GnmStyle
*res
= state
->style_accum
;
4316 state
->style_accum
= NULL
;
4317 if (state
->count
>= state
->collection
->len
)
4318 g_ptr_array_add (state
->collection
, res
);
4319 else if (NULL
!= g_ptr_array_index (state
->collection
, state
->count
)) {
4320 g_warning ("dup @ %d = %p", state
->count
, res
);
4321 gnm_style_unref (res
);
4323 g_ptr_array_index (state
->collection
, state
->count
) = res
;
4329 xlsx_col_border_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4331 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4332 gboolean diagonal_down
= FALSE
, diagonal_up
= FALSE
;
4334 xlsx_col_elem_begin (xin
, attrs
);
4335 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4336 if (attr_bool (xin
, attrs
, "diagonalDown", &diagonal_down
))
4338 else (attr_bool (xin
, attrs
, "diagonalUp", &diagonal_up
))
4343 GnmBorder
*border
= gnm_style_border_fetch
4344 (GNM_STYLE_BORDER_THIN
, style_color_black (), GNM_STYLE_BORDER_DIAGONAL
);
4345 gnm_style_set_border (state
->style_accum
,
4346 MSTYLE_BORDER_DIAGONAL
,
4349 if (diagonal_down
) {
4350 GnmBorder
*border
= gnm_style_border_fetch
4351 (GNM_STYLE_BORDER_HAIR
, style_color_black (), GNM_STYLE_BORDER_DIAGONAL
);
4352 gnm_style_set_border (state
->style_accum
,
4353 MSTYLE_BORDER_REV_DIAGONAL
,
4359 xlsx_font_name (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4361 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4362 const char *name
= simple_string (xin
, attrs
);
4364 gnm_style_set_font_name (state
->style_accum
, name
);
4368 xlsx_font_bold (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4370 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4372 (void)simple_bool (xin
, attrs
, &val
);
4373 gnm_style_set_font_bold (state
->style_accum
, val
);
4377 xlsx_font_italic (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4379 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4381 (void)simple_bool (xin
, attrs
, &val
);
4382 gnm_style_set_font_italic (state
->style_accum
, val
);
4386 xlsx_font_strike (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4388 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4390 (void)simple_bool (xin
, attrs
, &val
);
4391 gnm_style_set_font_strike (state
->style_accum
, val
);
4395 xlsx_font_color (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4397 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4398 /* LibreOffice 3.3.2 sets the alpha to 0, so text becomes invisible */
4399 /* (Excel drops the alpha too it seems.) */
4400 GnmColor
*color
= elem_color (xin
, attrs
, FALSE
);
4402 gnm_style_set_font_color (state
->style_accum
, color
);
4405 xlsx_CT_FontSize (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4407 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4409 if (simple_float (xin
, attrs
, &val
))
4410 gnm_style_set_font_size (state
->style_accum
, val
);
4413 xlsx_CT_vertAlign (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4415 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4416 static EnumVal
const types
[] = {
4417 { "subscript", GO_FONT_SCRIPT_SUB
},
4418 { "baseline", GO_FONT_SCRIPT_STANDARD
},
4419 { "superscript", GO_FONT_SCRIPT_SUPER
},
4422 int val
= GO_FONT_SCRIPT_STANDARD
;
4423 (void)simple_enum (xin
, attrs
, types
, &val
);
4424 gnm_style_set_font_script (state
->style_accum
, val
);
4427 xlsx_font_uline (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4429 static EnumVal
const types
[] = {
4430 { "single", UNDERLINE_SINGLE
},
4431 { "double", UNDERLINE_DOUBLE
},
4432 { "singleAccounting", UNDERLINE_SINGLE_LOW
},
4433 { "doubleAccounting", UNDERLINE_DOUBLE_LOW
},
4434 { "none", UNDERLINE_NONE
},
4437 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4438 int val
= UNDERLINE_SINGLE
;
4439 (void)simple_enum (xin
, attrs
, types
, &val
);
4440 gnm_style_set_font_uline (state
->style_accum
, val
);
4444 xlsx_font_valign (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4446 static EnumVal
const types
[] = {
4447 { "baseline", GO_FONT_SCRIPT_STANDARD
},
4448 { "superscript", GO_FONT_SCRIPT_SUPER
},
4449 { "subscript", GO_FONT_SCRIPT_SUB
},
4452 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4453 int val
= GO_FONT_SCRIPT_STANDARD
;
4454 (void)simple_enum (xin
, attrs
, types
, &val
);
4455 gnm_style_set_font_script (state
->style_accum
, val
);
4459 xlsx_pattern (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4461 static EnumVal
const patterns
[] = {
4464 { "mediumGray", 3 },
4467 { "darkHorizontal", 7 },
4468 { "darkVertical", 8 },
4472 { "darkTrellis", 12 },
4473 { "lightHorizontal", 13 },
4474 { "lightVertical", 14 },
4475 { "lightDown", 15 },
4477 { "lightGrid", 17 },
4478 { "lightTrellis", 18 },
4483 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4484 int val
= 0; /* none */
4486 /* we are setting a default pattern of solid, see bug #702615 */
4487 /* Note that this conflicts with ECMA 376: "This element is used
4488 to specify cell fill information for pattern and solid color
4489 cell fills. For solid cell fills (no pattern), fgColor is used.
4490 For cell fills with patterns specified, then the cell fill color
4491 is specified by the bgColor element." */
4492 /* As the above bug report shows Excel 2010 creates: */
4493 /* <dxf><font><color rgb="FF9C0006"/></font><fill><patternFill>
4494 <bgColor rgb="FFFFC7CE"/></patternFill></fill></dxf> */
4496 gnm_style_set_pattern (state
->style_accum
, 1);
4498 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4499 if (attr_enum (xin
, attrs
, "patternType", patterns
, &val
))
4500 gnm_style_set_pattern (state
->style_accum
, val
);
4504 xlsx_pattern_fg_bg (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4506 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4507 gboolean solid_pattern
= gnm_style_is_element_set (state
->style_accum
, MSTYLE_PATTERN
)
4508 && (1 == gnm_style_get_pattern (state
->style_accum
));
4510 * Looks like pattern background and forground colours are inverted for
4511 * dxfs with solid fills for no apparent reason. */
4512 gboolean
const invert
= state
->style_accum_partial
4514 /* LibreOffice 3.3.2 sets the alpha to 0, so solid fill becomes invisible */
4515 /* (Excel drops the alpha too it seems.) */
4516 GnmColor
*color
= elem_color (xin
, attrs
, !solid_pattern
);
4520 if (xin
->node
->user_data
.v_int
^ invert
)
4521 gnm_style_set_back_color (state
->style_accum
, color
);
4523 gnm_style_set_pattern_color (state
->style_accum
, color
);
4527 xlsx_CT_GradientFill (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4529 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4531 gnm_style_set_pattern (state
->style_accum
, 1);
4534 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4535 <xsd
:attribute name
="type" type
="ST_GradientType" use
="optional" default="linear">
4536 <xsd
:attribute name
="degree" type
="xsd:double" use
="optional" default="0">
4537 <xsd
:attribute name
="left" type
="xsd:double" use
="optional" default="0">
4538 <xsd
:attribute name
="right" type
="xsd:double" use
="optional" default="0">
4539 <xsd
:attribute name
="top" type
="xsd:double" use
="optional" default="0">
4540 <xsd
:attribute name
="bottom" type
="xsd:double" use
="optional" default="0">
4545 xlsx_border_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4547 static EnumVal
const borders
[] = {
4548 { "none", GNM_STYLE_BORDER_NONE
},
4549 { "thin", GNM_STYLE_BORDER_THIN
},
4550 { "medium", GNM_STYLE_BORDER_MEDIUM
},
4551 { "dashed", GNM_STYLE_BORDER_DASHED
},
4552 { "dotted", GNM_STYLE_BORDER_DOTTED
},
4553 { "thick", GNM_STYLE_BORDER_THICK
},
4554 { "double", GNM_STYLE_BORDER_DOUBLE
},
4555 { "hair", GNM_STYLE_BORDER_HAIR
},
4556 { "mediumDashed", GNM_STYLE_BORDER_MEDIUM_DASH
},
4557 { "dashDot", GNM_STYLE_BORDER_DASH_DOT
},
4558 { "mediumDashDot", GNM_STYLE_BORDER_MEDIUM_DASH_DOT
},
4559 { "dashDotDot", GNM_STYLE_BORDER_DASH_DOT_DOT
},
4560 { "mediumDashDotDot", GNM_STYLE_BORDER_MEDIUM_DASH_DOT_DOT
},
4561 { "slantDashDot", GNM_STYLE_BORDER_SLANTED_DASH_DOT
},
4564 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4565 int border_style
= GNM_STYLE_BORDER_NONE
;
4567 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4568 if (attr_enum (xin
, attrs
, "style", borders
, &border_style
))
4571 state
->border_style
= border_style
;
4572 state
->border_color
= NULL
;
4576 xlsx_border_begin_v2 (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4578 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4579 state
->version
= ECMA_376_2008
;
4580 xlsx_border_begin (xin
, attrs
);
4584 xlsx_border_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4586 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4588 GnmStyleBorderLocation
const loc
= xin
->node
->user_data
.v_int
;
4590 if (NULL
== state
->border_color
)
4591 state
->border_color
= style_color_black ();
4592 border
= gnm_style_border_fetch (state
->border_style
,
4593 state
->border_color
, gnm_style_border_get_orientation (loc
));
4594 gnm_style_set_border (state
->style_accum
,
4595 GNM_STYLE_BORDER_LOCATION_TO_STYLE_ELEMENT (loc
),
4597 state
->border_color
= NULL
;
4601 xlsx_border_diagonal_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4603 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4604 GnmBorder
*border
, *new_border
;
4606 if (NULL
== state
->border_color
)
4607 state
->border_color
= style_color_black ();
4608 new_border
= gnm_style_border_fetch
4609 (state
->border_style
, state
->border_color
, GNM_STYLE_BORDER_DIAGONAL
);
4611 border
= gnm_style_get_border (state
->style_accum
, MSTYLE_BORDER_REV_DIAGONAL
);
4612 if (border
!= NULL
&& border
->line_type
!= GNM_STYLE_BORDER_NONE
) {
4613 gnm_style_border_ref (new_border
);
4614 gnm_style_set_border (state
->style_accum
,
4615 MSTYLE_BORDER_REV_DIAGONAL
,
4618 border
= gnm_style_get_border (state
->style_accum
, MSTYLE_BORDER_DIAGONAL
);
4619 if (border
!= NULL
&& border
->line_type
!= GNM_STYLE_BORDER_NONE
) {
4620 gnm_style_border_ref (new_border
);
4621 gnm_style_set_border (state
->style_accum
,
4622 MSTYLE_BORDER_DIAGONAL
,
4625 gnm_style_border_unref (new_border
);
4626 state
->border_color
= NULL
;
4630 xlsx_border_color (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4632 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4633 GnmColor
*color
= elem_color (xin
, attrs
, TRUE
);
4634 if (state
->border_color
)
4635 style_color_unref (state
->border_color
);
4636 state
->border_color
= color
;
4640 xlsx_xf_begin (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4642 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4643 GnmStyle
*accum
= gnm_style_new ();
4644 GnmStyle
*parent
= NULL
;
4646 GPtrArray
*elem
= NULL
;
4649 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4650 if (0 == strcmp (attrs
[0], "numFmtId")) {
4651 GOFormat
*fmt
= xlsx_get_num_fmt (xin
, attrs
[1]);
4653 gnm_style_set_format (accum
, fmt
);
4654 } else if (attr_int (xin
, attrs
, "fontId", &indx
))
4655 elem
= state
->fonts
;
4656 else if (attr_int (xin
, attrs
, "fillId", &indx
))
4657 elem
= state
->fills
;
4658 else if (attr_int (xin
, attrs
, "borderId", &indx
))
4659 elem
= state
->borders
;
4660 else if (attr_int (xin
, attrs
, "xfId", &indx
))
4661 parent
= xlsx_get_style_xf (xin
, indx
);
4664 GnmStyle
const *component
= NULL
;
4665 if (0 <= indx
&& indx
< (int)elem
->len
)
4666 component
= g_ptr_array_index (elem
, indx
);
4667 if (NULL
!= component
) {
4669 gnm_style_merge (accum
, component
);
4671 GnmStyle
*merged
= gnm_style_new_merged (accum
, component
);
4672 gnm_style_unref (accum
);
4676 xlsx_warning (xin
, "Missing record '%d' for %s", indx
, attrs
[0]);
4680 if (NULL
== parent
) {
4681 result
= gnm_style_new_default ();
4682 gnm_style_merge (result
, accum
);
4684 result
= gnm_style_new_merged (parent
, accum
);
4685 gnm_style_unref (accum
);
4687 state
->style_accum
= result
;
4700 xlsx_xf_end (GsfXMLIn
*xin
, GsfXMLBlob
*blob
)
4702 xlsx_col_elem_end (xin
, blob
);
4706 xlsx_xf_align (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4708 static EnumVal
const haligns
[] = {
4709 { "general" , GNM_HALIGN_GENERAL
},
4710 { "left" , GNM_HALIGN_LEFT
},
4711 { "center" , GNM_HALIGN_CENTER
},
4712 { "right" , GNM_HALIGN_RIGHT
},
4713 { "fill" , GNM_HALIGN_FILL
},
4714 { "justify" , GNM_HALIGN_JUSTIFY
},
4715 { "centerContinuous" , GNM_HALIGN_CENTER_ACROSS_SELECTION
},
4716 { "distributed" , GNM_HALIGN_DISTRIBUTED
},
4720 static EnumVal
const valigns
[] = {
4721 { "top", GNM_VALIGN_TOP
},
4722 { "center", GNM_VALIGN_CENTER
},
4723 { "bottom", GNM_VALIGN_BOTTOM
},
4724 { "justify", GNM_VALIGN_JUSTIFY
},
4725 { "distributed", GNM_VALIGN_DISTRIBUTED
},
4729 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4730 int halign
= GNM_HALIGN_GENERAL
;
4731 int valign
= GNM_VALIGN_BOTTOM
;
4732 int rotation
= 0, indent
= 0;
4733 int wrapText
= FALSE
, justifyLastLine
= FALSE
, shrinkToFit
= FALSE
;
4735 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4736 if (attr_enum (xin
, attrs
, "horizontal", haligns
, &halign
) ||
4737 attr_enum (xin
, attrs
, "vertical", valigns
, &valign
) ||
4738 attr_int (xin
, attrs
, "textRotation", &rotation
) ||
4739 attr_bool (xin
, attrs
, "wrapText", &wrapText
) ||
4740 attr_int (xin
, attrs
, "indent", &indent
) ||
4741 attr_bool (xin
, attrs
, "justifyLastLine", &justifyLastLine
) ||
4742 attr_bool (xin
, attrs
, "shrinkToFit", &shrinkToFit
)
4743 /* "mergeCell" type="xs:boolean" use="optional" default="false" */
4744 /* "readingOrder" type="xs:unsignedInt" use="optional" default="0" */
4748 gnm_style_set_align_h (state
->style_accum
, halign
);
4749 gnm_style_set_align_v (state
->style_accum
, valign
);
4750 gnm_style_set_rotation (state
->style_accum
,
4751 (rotation
== 0xff) ? -1 : ((rotation
> 90) ? (360 + 90 - rotation
) : rotation
));
4752 gnm_style_set_wrap_text (state
->style_accum
, wrapText
);
4753 gnm_style_set_indent (state
->style_accum
, indent
);
4754 gnm_style_set_shrink_to_fit (state
->style_accum
, shrinkToFit
);
4758 xlsx_xf_protect (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4760 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4764 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4765 if (attr_bool (xin
, attrs
, "locked", &locked
))
4767 else if (attr_bool (xin
, attrs
, "hidden", &hidden
))
4771 gnm_style_set_contents_locked (state
->style_accum
, locked
);
4772 gnm_style_set_contents_hidden (state
->style_accum
, hidden
);
4776 xlsx_cell_style (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4778 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4779 /* xmlChar const *name = NULL; */
4780 xmlChar
const *id
= NULL
;
4781 GnmStyle
*style
= NULL
;
4784 /* cellStyle name="Normal" xfId="0" builtinId="0" */
4785 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4786 if (attr_int (xin
, attrs
, "xfId", &tmp
))
4787 style
= xlsx_get_style_xf (xin
, tmp
);
4788 else /* if (0 == strcmp (attrs[0], "name")) */
4789 /* name = attrs[1]; */
4790 /* else */ if (0 == strcmp (attrs
[0], "builtinId"))
4794 if (NULL
!= style
&& NULL
!= id
) {
4795 gnm_style_ref (style
);
4796 g_hash_table_replace (state
->cell_styles
, g_strdup (id
), style
);
4801 xlsx_dxf_begin (GsfXMLIn
*xin
, G_GNUC_UNUSED xmlChar
const **attrs
)
4803 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4804 state
->style_accum_partial
= TRUE
;
4805 state
->style_accum
= gnm_style_new ();
4808 xlsx_dxf_end (GsfXMLIn
*xin
, GsfXMLBlob
*blob
)
4810 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4811 state
->style_accum_partial
= FALSE
;
4812 xlsx_col_elem_end (xin
, blob
);
4816 xlsx_dxf_numfmt (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4818 xlsx_numfmt_common (xin
, attrs
, TRUE
);
4822 static GsfXMLInNode
const xlsx_styles_dtd
[] = {
4823 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4824 GSF_XML_IN_NODE_FULL (START
, STYLE_INFO
, XL_NS_SS
, "styleSheet", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4825 GSF_XML_IN_NODE (STYLE_INFO
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4826 GSF_XML_IN_NODE (EXTLST
, EXTITEM
, XL_NS_SS
, "ext", GSF_XML_NO_CONTENT
, &xlsx_ext_begin
, &xlsx_ext_end
),
4827 GSF_XML_IN_NODE (STYLE_INFO
, NUM_FMTS
, XL_NS_SS
, "numFmts", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4828 GSF_XML_IN_NODE (NUM_FMTS
, NUM_FMT
, XL_NS_SS
, "numFmt", GSF_XML_NO_CONTENT
, &xlsx_style_numfmt
, NULL
),
4830 GSF_XML_IN_NODE_FULL (STYLE_INFO
, FONTS
, XL_NS_SS
, "fonts", GSF_XML_NO_CONTENT
,
4831 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_FONT
),
4832 GSF_XML_IN_NODE (FONTS
, FONT
, XL_NS_SS
, "font", GSF_XML_NO_CONTENT
, &xlsx_col_elem_begin
, &xlsx_col_elem_end
),
4833 GSF_XML_IN_NODE (FONT
, FONT_NAME
, XL_NS_SS
, "name", GSF_XML_NO_CONTENT
, &xlsx_font_name
, NULL
),
4834 GSF_XML_IN_NODE (FONT
, FONT_CHARSET
, XL_NS_SS
, "charset", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4835 GSF_XML_IN_NODE (FONT
, FONT_FAMILY
, XL_NS_SS
, "family", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4836 GSF_XML_IN_NODE (FONT
, FONT_BOLD
, XL_NS_SS
, "b", GSF_XML_NO_CONTENT
, &xlsx_font_bold
, NULL
),
4837 GSF_XML_IN_NODE (FONT
, FONT_ITALIC
, XL_NS_SS
, "i", GSF_XML_NO_CONTENT
, &xlsx_font_italic
, NULL
),
4838 GSF_XML_IN_NODE (FONT
, FONT_STRIKE
, XL_NS_SS
, "strike", GSF_XML_NO_CONTENT
, &xlsx_font_strike
, NULL
),
4839 GSF_XML_IN_NODE (FONT
, FONT_OUTLINE
, XL_NS_SS
, "outline", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4840 GSF_XML_IN_NODE (FONT
, FONT_SHADOW
, XL_NS_SS
, "shadow", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4841 GSF_XML_IN_NODE (FONT
, FONT_CONDENSE
, XL_NS_SS
, "condense", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4842 GSF_XML_IN_NODE (FONT
, FONT_EXTEND
, XL_NS_SS
, "extend", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4843 GSF_XML_IN_NODE (FONT
, FONT_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_font_color
, NULL
),
4844 GSF_XML_IN_NODE (FONT
, FONT_SZ
, XL_NS_SS
, "sz", GSF_XML_NO_CONTENT
, &xlsx_CT_FontSize
, NULL
),
4845 GSF_XML_IN_NODE (FONT
, FONT_SCRIPT
, XL_NS_SS
, "vertAlign", GSF_XML_NO_CONTENT
, &xlsx_CT_vertAlign
, NULL
),
4846 GSF_XML_IN_NODE (FONT
, FONT_ULINE
, XL_NS_SS
, "u", GSF_XML_NO_CONTENT
, &xlsx_font_uline
, NULL
),
4847 GSF_XML_IN_NODE (FONT
, FONT_VERTALIGN
, XL_NS_SS
, "vertAlign", GSF_XML_NO_CONTENT
, &xlsx_font_valign
, NULL
),
4848 GSF_XML_IN_NODE (FONT
, FONT_SCHEME
, XL_NS_SS
, "scheme", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4850 GSF_XML_IN_NODE_FULL (STYLE_INFO
, FILLS
, XL_NS_SS
, "fills", GSF_XML_NO_CONTENT
,
4851 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_FILLS
),
4852 GSF_XML_IN_NODE (FILLS
, FILL
, XL_NS_SS
, "fill", GSF_XML_NO_CONTENT
, &xlsx_col_elem_begin
, &xlsx_col_elem_end
),
4853 GSF_XML_IN_NODE (FILL
, PATTERN_FILL
, XL_NS_SS
, "patternFill", GSF_XML_NO_CONTENT
, &xlsx_pattern
, NULL
),
4854 GSF_XML_IN_NODE_FULL (PATTERN_FILL
, PATTERN_FILL_FG
, XL_NS_SS
, "fgColor", GSF_XML_NO_CONTENT
,
4855 FALSE
, FALSE
, &xlsx_pattern_fg_bg
, NULL
, TRUE
),
4856 GSF_XML_IN_NODE_FULL (PATTERN_FILL
, PATTERN_FILL_BG
, XL_NS_SS
, "bgColor", GSF_XML_NO_CONTENT
,
4857 FALSE
, FALSE
, &xlsx_pattern_fg_bg
, NULL
, FALSE
),
4858 GSF_XML_IN_NODE (FILL
, IMAGE_FILL
, XL_NS_SS
, "image", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4859 GSF_XML_IN_NODE (FILL
, GRADIENT_FILL
, XL_NS_SS
, "gradientFill", GSF_XML_NO_CONTENT
, &xlsx_CT_GradientFill
, NULL
),
4860 GSF_XML_IN_NODE (GRADIENT_FILL
, GRADIENT_STOPS
, XL_NS_SS
, "stop", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4861 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
),
4863 GSF_XML_IN_NODE_FULL (STYLE_INFO
, BORDERS
, XL_NS_SS
, "borders", GSF_XML_NO_CONTENT
,
4864 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_BORDERS
),
4865 GSF_XML_IN_NODE (BORDERS
, BORDER
, XL_NS_SS
, "border", GSF_XML_NO_CONTENT
, &xlsx_col_border_begin
, &xlsx_col_elem_end
),
4866 GSF_XML_IN_NODE_FULL (BORDER
, LEFT_B
, XL_NS_SS
, "left", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4867 &xlsx_border_begin
, &xlsx_border_end
, GNM_STYLE_BORDER_LEFT
),
4868 GSF_XML_IN_NODE (LEFT_B
, LEFT_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4869 GSF_XML_IN_NODE_FULL (BORDER
, START_B
, XL_NS_SS
, "start", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4870 &xlsx_border_begin_v2
, &xlsx_border_end
, GNM_STYLE_BORDER_LEFT
),
4871 GSF_XML_IN_NODE (START_B
, START_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4872 GSF_XML_IN_NODE_FULL (BORDER
, RIGHT_B
, XL_NS_SS
, "right", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4873 &xlsx_border_begin
, &xlsx_border_end
, GNM_STYLE_BORDER_RIGHT
),
4874 GSF_XML_IN_NODE (RIGHT_B
, RIGHT_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4875 GSF_XML_IN_NODE_FULL (BORDER
, END_B
, XL_NS_SS
, "end", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4876 &xlsx_border_begin_v2
, &xlsx_border_end
, GNM_STYLE_BORDER_RIGHT
),
4877 GSF_XML_IN_NODE (END_B
, END_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4878 GSF_XML_IN_NODE_FULL (BORDER
, TOP_B
, XL_NS_SS
, "top", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4879 &xlsx_border_begin
, &xlsx_border_end
, GNM_STYLE_BORDER_TOP
),
4880 GSF_XML_IN_NODE (TOP_B
, TOP_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4881 GSF_XML_IN_NODE_FULL (BORDER
, BOTTOM_B
, XL_NS_SS
, "bottom", GSF_XML_NO_CONTENT
, FALSE
, FALSE
,
4882 &xlsx_border_begin
, &xlsx_border_end
, GNM_STYLE_BORDER_BOTTOM
),
4883 GSF_XML_IN_NODE (BOTTOM_B
, BOTTOM_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4884 GSF_XML_IN_NODE (BORDER
, DIAG_B
, XL_NS_SS
, "diagonal", GSF_XML_NO_CONTENT
,
4885 &xlsx_border_begin
, &xlsx_border_diagonal_end
),
4886 GSF_XML_IN_NODE (DIAG_B
, DIAG_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, &xlsx_border_color
, NULL
),
4888 GSF_XML_IN_NODE (BORDER
, BORDER_VERT
, XL_NS_SS
, "vertical", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4889 GSF_XML_IN_NODE (BORDER_VERT
, VERT_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4890 GSF_XML_IN_NODE (BORDER
, BORDER_HORIZ
, XL_NS_SS
, "horizontal", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4891 GSF_XML_IN_NODE (BORDER_HORIZ
, HORIZ_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4893 GSF_XML_IN_NODE_FULL (STYLE_INFO
, XFS
, XL_NS_SS
, "cellXfs", GSF_XML_NO_CONTENT
,
4894 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_XFS
),
4895 GSF_XML_IN_NODE (XFS
, XF
, XL_NS_SS
, "xf", GSF_XML_NO_CONTENT
, &xlsx_xf_begin
, &xlsx_xf_end
),
4896 GSF_XML_IN_NODE (XF
, ALIGNMENT
, XL_NS_SS
, "alignment", GSF_XML_NO_CONTENT
, &xlsx_xf_align
, NULL
),
4897 GSF_XML_IN_NODE (XF
, PROTECTION
, XL_NS_SS
, "protection", GSF_XML_NO_CONTENT
, &xlsx_xf_protect
, NULL
),
4899 GSF_XML_IN_NODE_FULL (STYLE_INFO
, STYLE_XFS
, XL_NS_SS
, "cellStyleXfs", GSF_XML_NO_CONTENT
,
4900 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_STYLE_XFS
),
4901 GSF_XML_IN_NODE (STYLE_XFS
, STYLE_XF
, XL_NS_SS
, "xf", GSF_XML_NO_CONTENT
, &xlsx_xf_begin
, &xlsx_xf_end
),
4902 GSF_XML_IN_NODE (STYLE_XF
, STYLE_ALIGNMENT
, XL_NS_SS
, "alignment", GSF_XML_NO_CONTENT
, &xlsx_xf_align
, NULL
),
4903 GSF_XML_IN_NODE (STYLE_XF
, STYLE_PROTECTION
, XL_NS_SS
, "protection", GSF_XML_NO_CONTENT
, &xlsx_xf_protect
, NULL
),
4905 GSF_XML_IN_NODE (STYLE_INFO
, STYLE_NAMES
, XL_NS_SS
, "cellStyles", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4906 GSF_XML_IN_NODE (STYLE_NAMES
, STYLE_NAME
, XL_NS_SS
, "cellStyle", GSF_XML_NO_CONTENT
, &xlsx_cell_style
, NULL
),
4907 GSF_XML_IN_NODE (STYLE_NAME
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_2ND
, NULL
, NULL
),
4908 GSF_XML_IN_NODE_FULL (STYLE_INFO
, PARTIAL_XFS
, XL_NS_SS
, "dxfs", GSF_XML_NO_CONTENT
,
4909 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_DXFS
),
4910 GSF_XML_IN_NODE (PARTIAL_XFS
, PARTIAL_XF
, XL_NS_SS
, "dxf", GSF_XML_NO_CONTENT
, &xlsx_dxf_begin
, &xlsx_dxf_end
),
4911 GSF_XML_IN_NODE (PARTIAL_XF
, DXF_NUM_FMT
, XL_NS_SS
, "numFmt", GSF_XML_NO_CONTENT
, &xlsx_dxf_numfmt
, NULL
),
4912 GSF_XML_IN_NODE (PARTIAL_XF
, FONT
, XL_NS_SS
, "font", GSF_XML_2ND
, NULL
, NULL
),
4913 GSF_XML_IN_NODE (PARTIAL_XF
, FILL
, XL_NS_SS
, "fill", GSF_XML_2ND
, NULL
, NULL
),
4914 GSF_XML_IN_NODE (PARTIAL_XF
, BORDER
, XL_NS_SS
, "border", GSF_XML_2ND
, NULL
, NULL
),
4915 GSF_XML_IN_NODE (PARTIAL_XF
, DXF_ALIGNMENT
, XL_NS_SS
, "alignment", GSF_XML_NO_CONTENT
, &xlsx_xf_align
, NULL
),
4916 GSF_XML_IN_NODE (PARTIAL_XF
, DXF_PROTECTION
, XL_NS_SS
, "protection", GSF_XML_NO_CONTENT
, &xlsx_xf_protect
, NULL
),
4917 GSF_XML_IN_NODE (PARTIAL_XF
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_2ND
, NULL
, NULL
),
4919 GSF_XML_IN_NODE_FULL (STYLE_INFO
, TABLE_STYLES
, XL_NS_SS
, "tableStyles", GSF_XML_NO_CONTENT
,
4920 FALSE
, FALSE
, &xlsx_collection_begin
, &xlsx_collection_end
, XLSX_COLLECT_TABLE_STYLES
),
4921 GSF_XML_IN_NODE (TABLE_STYLES
, TABLE_STYLE
, XL_NS_SS
, "tableStyle", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4923 GSF_XML_IN_NODE (STYLE_INFO
, COLORS
, XL_NS_SS
, "colors", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4924 GSF_XML_IN_NODE (COLORS
, INDEXED_COLORS
, XL_NS_SS
, "indexedColors", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4925 GSF_XML_IN_NODE (INDEXED_COLORS
, INDEXED_RGB
, XL_NS_SS
, "rgbColor", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4926 GSF_XML_IN_NODE (COLORS
, THEME_COLORS
, XL_NS_SS
, "themeColors", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4927 GSF_XML_IN_NODE (THEME_COLORS
, THEMED_RGB
, XL_NS_SS
, "rgbColor", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4928 GSF_XML_IN_NODE (COLORS
, MRU_COLORS
, XL_NS_SS
, "mruColors", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4929 GSF_XML_IN_NODE (MRU_COLORS
, MRU_COLOR
, XL_NS_SS
, "color", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4934 /****************************************************************************/
4937 xlsx_theme_color_sys (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4939 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4940 GOColor c
= GO_COLOR_BLACK
;
4942 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4943 if (attr_gocolor (xin
, attrs
, "lastClr", &c
)) {
4950 xlsx_theme_color_rgb (GsfXMLIn
*xin
, xmlChar
const **attrs
)
4952 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4953 GOColor c
= GO_COLOR_BLACK
;
4955 for (; attrs
!= NULL
&& attrs
[0] && attrs
[1] ; attrs
+= 2) {
4956 if (attr_gocolor (xin
, attrs
, "val", &c
)) {
4964 xlsx_theme_color_end (GsfXMLIn
*xin
, G_GNUC_UNUSED GsfXMLBlob
*blob
)
4966 XLSXReadState
*state
= (XLSXReadState
*)xin
->user_state
;
4967 const char *name
= ((GsfXMLInNode
*)xin
->node_stack
->data
)->name
;
4969 g_hash_table_replace (state
->theme_colors_by_name
,
4971 GUINT_TO_POINTER (state
->color
));
4974 static GsfXMLInNode
const xlsx_theme_dtd
[] = {
4975 GSF_XML_IN_NODE_FULL (START
, START
, -1, NULL
, GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4976 GSF_XML_IN_NODE_FULL (START
, THEME
, XL_NS_DRAW
, "theme", GSF_XML_NO_CONTENT
, FALSE
, TRUE
, NULL
, NULL
, 0),
4977 GSF_XML_IN_NODE (THEME
, ELEMENTS
, XL_NS_DRAW
, "themeElements", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4978 GSF_XML_IN_NODE (ELEMENTS
, COLOR_SCHEME
, XL_NS_DRAW
, "clrScheme", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4979 GSF_XML_IN_NODE (COLOR_SCHEME
, dk1
, XL_NS_DRAW
, "dk1", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4980 GSF_XML_IN_NODE (dk1
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, &xlsx_theme_color_sys
, &xlsx_theme_color_end
),
4981 COLOR_MODIFIER_NODES(SYS_COLOR
,TRUE
),
4982 GSF_XML_IN_NODE (dk1
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, &xlsx_theme_color_rgb
, &xlsx_theme_color_end
),
4983 COLOR_MODIFIER_NODES(RGB_COLOR
,FALSE
),
4984 GSF_XML_IN_NODE (COLOR_SCHEME
, lt1
, XL_NS_DRAW
, "lt1", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4985 GSF_XML_IN_NODE (lt1
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
4986 GSF_XML_IN_NODE (lt1
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
4987 GSF_XML_IN_NODE (COLOR_SCHEME
, lt2
, XL_NS_DRAW
, "lt2", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4988 GSF_XML_IN_NODE (lt2
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
4989 GSF_XML_IN_NODE (lt2
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
4990 GSF_XML_IN_NODE (COLOR_SCHEME
, dk2
, XL_NS_DRAW
, "dk2", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4991 GSF_XML_IN_NODE (dk2
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
4992 GSF_XML_IN_NODE (dk2
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
4993 GSF_XML_IN_NODE (COLOR_SCHEME
, accent1
, XL_NS_DRAW
, "accent1", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4994 GSF_XML_IN_NODE (accent1
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
4995 GSF_XML_IN_NODE (accent1
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
4996 GSF_XML_IN_NODE (COLOR_SCHEME
, accent2
, XL_NS_DRAW
, "accent2", GSF_XML_NO_CONTENT
, NULL
, NULL
),
4997 GSF_XML_IN_NODE (accent2
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
4998 GSF_XML_IN_NODE (accent2
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
4999 GSF_XML_IN_NODE (COLOR_SCHEME
, accent3
, XL_NS_DRAW
, "accent3", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5000 GSF_XML_IN_NODE (accent3
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
5001 GSF_XML_IN_NODE (accent3
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5002 GSF_XML_IN_NODE (COLOR_SCHEME
, accent4
, XL_NS_DRAW
, "accent4", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5003 GSF_XML_IN_NODE (accent4
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
5004 GSF_XML_IN_NODE (accent4
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5005 GSF_XML_IN_NODE (COLOR_SCHEME
, accent5
, XL_NS_DRAW
, "accent5", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5006 GSF_XML_IN_NODE (accent5
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
5007 GSF_XML_IN_NODE (accent5
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5008 GSF_XML_IN_NODE (COLOR_SCHEME
, accent6
, XL_NS_DRAW
, "accent6", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5009 GSF_XML_IN_NODE (accent6
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
5010 GSF_XML_IN_NODE (accent6
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5011 GSF_XML_IN_NODE (COLOR_SCHEME
, hlink
, XL_NS_DRAW
, "hlink", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5012 GSF_XML_IN_NODE (hlink
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
5013 GSF_XML_IN_NODE (hlink
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5014 GSF_XML_IN_NODE (COLOR_SCHEME
, folHlink
, XL_NS_DRAW
, "folHlink", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5015 GSF_XML_IN_NODE (folHlink
, SYS_COLOR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
5016 GSF_XML_IN_NODE (folHlink
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5018 GSF_XML_IN_NODE (ELEMENTS
, FONT_SCHEME
, XL_NS_DRAW
, "fontScheme", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5019 GSF_XML_IN_NODE (FONT_SCHEME
, MAJOR_FONT
, XL_NS_DRAW
, "majorFont", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5020 GSF_XML_IN_NODE (MAJOR_FONT
, FONT_CS
, XL_NS_DRAW
, "cs", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5021 GSF_XML_IN_NODE (MAJOR_FONT
, FONT_EA
, XL_NS_DRAW
, "ea", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5022 GSF_XML_IN_NODE (MAJOR_FONT
, FONT_FONT
, XL_NS_DRAW
, "font", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5023 GSF_XML_IN_NODE (MAJOR_FONT
, FONT_LATIN
, XL_NS_DRAW
, "latin", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5024 GSF_XML_IN_NODE (FONT_SCHEME
, MINOR_FONT
, XL_NS_DRAW
, "minorFont", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5025 GSF_XML_IN_NODE (MINOR_FONT
, FONT_CS
, XL_NS_DRAW
, "cs", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5026 GSF_XML_IN_NODE (MINOR_FONT
, FONT_EA
, XL_NS_DRAW
, "ea", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5027 GSF_XML_IN_NODE (MINOR_FONT
, FONT_FONT
, XL_NS_DRAW
, "font", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5028 GSF_XML_IN_NODE (MINOR_FONT
, FONT_LATIN
, XL_NS_DRAW
, "latin", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5030 GSF_XML_IN_NODE (ELEMENTS
, FORMAT_SCHEME
, XL_NS_DRAW
, "fmtScheme", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5031 GSF_XML_IN_NODE (FORMAT_SCHEME
, FILL_STYLE_LIST
, XL_NS_DRAW
, "fillStyleLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5032 GSF_XML_IN_NODE (FILL_STYLE_LIST
, SOLID_FILL
, XL_NS_DRAW
, "solidFill", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5033 GSF_XML_IN_NODE (SOLID_FILL
, SCHEME_COLOR
, XL_NS_DRAW
, "schemeClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5034 COLOR_MODIFIER_NODES(SCHEME_COLOR
,FALSE
),
5035 GSF_XML_IN_NODE (FILL_STYLE_LIST
, GRAD_FILL
, XL_NS_DRAW
, "gradFill", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5036 GSF_XML_IN_NODE (GRAD_FILL
, GRAD_PATH
, XL_NS_DRAW
, "path", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5037 GSF_XML_IN_NODE (GRAD_PATH
, GRAD_PATH_RECT
, XL_NS_DRAW
, "fillToRect", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5038 GSF_XML_IN_NODE (GRAD_FILL
, GRAD_LIST
, XL_NS_DRAW
, "gsLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5039 GSF_XML_IN_NODE (GRAD_LIST
, GRAD_LIST_ITEM
, XL_NS_DRAW
, "gs", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5040 GSF_XML_IN_NODE (GRAD_LIST_ITEM
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5041 GSF_XML_IN_NODE (GRAD_LIST_ITEM
, SCHEME_COLOR
, XL_NS_DRAW
, "schemeClr", GSF_XML_2ND
, NULL
, NULL
),
5042 GSF_XML_IN_NODE (GRAD_FILL
, GRAD_LINE
, XL_NS_DRAW
, "lin", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5044 GSF_XML_IN_NODE (FORMAT_SCHEME
, BG_FILL_STYLE_LIST
, XL_NS_DRAW
, "bgFillStyleLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5045 GSF_XML_IN_NODE (BG_FILL_STYLE_LIST
, GRAD_FILL
, XL_NS_DRAW
, "gradFill", GSF_XML_2ND
, NULL
, NULL
),
5046 GSF_XML_IN_NODE (BG_FILL_STYLE_LIST
, SOLID_FILL
, XL_NS_DRAW
, "solidFill", GSF_XML_2ND
, NULL
, NULL
),
5047 GSF_XML_IN_NODE (FORMAT_SCHEME
, LINE_STYLE_LIST
, XL_NS_DRAW
, "lnStyleLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5048 GSF_XML_IN_NODE (LINE_STYLE_LIST
, LINE_STYLE
, XL_NS_DRAW
, "ln", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5049 GSF_XML_IN_NODE (LINE_STYLE
, LN_NOFILL
, XL_NS_DRAW
, "noFill", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5050 GSF_XML_IN_NODE (LINE_STYLE
, LN_DASH
, XL_NS_DRAW
, "prstDash", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5051 GSF_XML_IN_NODE (LINE_STYLE
, LN_MITER
, XL_NS_DRAW
, "miter", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5052 GSF_XML_IN_NODE (LINE_STYLE
, SOLID_FILL
, XL_NS_DRAW
, "solidFill", GSF_XML_2ND
, NULL
, NULL
),
5053 GSF_XML_IN_NODE (LINE_STYLE
, FILL_PATT
, XL_NS_DRAW
, "pattFill", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5054 GSF_XML_IN_NODE (FORMAT_SCHEME
, EFFECT_STYLE_LIST
, XL_NS_DRAW
, "effectStyleLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5055 GSF_XML_IN_NODE (EFFECT_STYLE_LIST
, EFFECT_STYLE
, XL_NS_DRAW
, "effectStyle", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5056 GSF_XML_IN_NODE (EFFECT_STYLE
, EFFECT_PROP
, XL_NS_DRAW
, "sp3d", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5057 GSF_XML_IN_NODE (EFFECT_PROP
, CONTOUR_CLR
, XL_NS_DRAW
, "contourClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5058 GSF_XML_IN_NODE (CONTOUR_CLR
, SCHEME_CLR
, XL_NS_DRAW
, "schemeClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5059 GSF_XML_IN_NODE (EFFECT_PROP
, PROP_BEVEL
, XL_NS_DRAW
, "bevelT", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5060 GSF_XML_IN_NODE (EFFECT_STYLE
, EFFECT_LIST
, XL_NS_DRAW
, "effectLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5061 GSF_XML_IN_NODE (EFFECT_LIST
, REFLECTION
, XL_NS_DRAW
, "reflection", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5062 GSF_XML_IN_NODE (EFFECT_LIST
, OUTER_SHADOW
, XL_NS_DRAW
, "outerShdw", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5063 GSF_XML_IN_NODE (OUTER_SHADOW
, RGB_COLOR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5064 GSF_XML_IN_NODE (EFFECT_STYLE
, EFFECT_SCENE_3D
, XL_NS_DRAW
, "scene3d", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5065 GSF_XML_IN_NODE (EFFECT_SCENE_3D
, 3D_CAMERA
, XL_NS_DRAW
, "camera", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5066 GSF_XML_IN_NODE (3D_CAMERA
, 3D_ROT
, XL_NS_DRAW
, "rot", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5067 GSF_XML_IN_NODE (EFFECT_SCENE_3D
, 3D_LIGHT
, XL_NS_DRAW
, "lightRig", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5068 GSF_XML_IN_NODE (3D_LIGHT
, 3D_ROT
, XL_NS_DRAW
, "rot", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5070 GSF_XML_IN_NODE (THEME
, OBJ_DEFAULTS
, XL_NS_DRAW
, "objectDefaults", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5071 GSF_XML_IN_NODE (OBJ_DEFAULTS
, SP_DEF
, XL_NS_DRAW
, "spDef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5072 GSF_XML_IN_NODE (SP_DEF
, SHAPE_PR
, XL_NS_DRAW
, "spPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5073 GSF_XML_IN_NODE (SHAPE_PR
, XFRM
, XL_NS_DRAW
, "xfrm", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5074 GSF_XML_IN_NODE (SHAPE_PR
, CUST_GEOM
, XL_NS_DRAW
, "custGeom", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5075 GSF_XML_IN_NODE (SHAPE_PR
, EXTLST
, XL_NS_DRAW
, "extLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5076 GSF_XML_IN_NODE (EXTLST
, EXTITEM
, XL_NS_DRAW
, "ext", GSF_XML_NO_CONTENT
, &xlsx_ext_begin
, &xlsx_ext_end
),
5077 GSF_XML_IN_NODE (SHAPE_PR
, SOLID_FILL
, XL_NS_DRAW
, "solidFill", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5078 GSF_XML_IN_NODE (SP_DEF
, BODY_PR
, XL_NS_DRAW
, "bodyPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5079 GSF_XML_IN_NODE (SP_DEF
, LST_STYLE
, XL_NS_DRAW
, "lstStyle", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5080 GSF_XML_IN_NODE (SP_DEF
, STYLE
, XL_NS_DRAW
, "style", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5081 GSF_XML_IN_NODE (STYLE
, EFFECT_REF
, XL_NS_DRAW
, "effectRef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5082 GSF_XML_IN_NODE (EFFECT_REF
, HSL_CLR
, XL_NS_DRAW
, "hslClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5083 GSF_XML_IN_NODE (EFFECT_REF
, PRST_CLR
, XL_NS_DRAW
, "prstClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5084 GSF_XML_IN_NODE (EFFECT_REF
, SCHEME_CLR
, XL_NS_DRAW
, "schemeClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5085 GSF_XML_IN_NODE (EFFECT_REF
, SCRGB_CLR
, XL_NS_DRAW
, "scrgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5086 GSF_XML_IN_NODE (EFFECT_REF
, SRGB_CLR
, XL_NS_DRAW
, "srgbClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5087 GSF_XML_IN_NODE (EFFECT_REF
, SYS_CLR
, XL_NS_DRAW
, "sysClr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5088 GSF_XML_IN_NODE (STYLE
, FILL_REF
, XL_NS_DRAW
, "fillRef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5089 GSF_XML_IN_NODE (FILL_REF
, HSL_CLR
, XL_NS_DRAW
, "hslClr", GSF_XML_2ND
, NULL
, NULL
),
5090 GSF_XML_IN_NODE (FILL_REF
, PRST_CLR
, XL_NS_DRAW
, "prstClr", GSF_XML_2ND
, NULL
, NULL
),
5091 GSF_XML_IN_NODE (FILL_REF
, SCHEME_CLR
, XL_NS_DRAW
, "schemeClr", GSF_XML_2ND
, NULL
, NULL
),
5092 GSF_XML_IN_NODE (FILL_REF
, SCRGB_CLR
, XL_NS_DRAW
, "scrgbClr", GSF_XML_2ND
, NULL
, NULL
),
5093 GSF_XML_IN_NODE (FILL_REF
, SRGB_CLR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5094 GSF_XML_IN_NODE (FILL_REF
, SYS_CLR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
5095 GSF_XML_IN_NODE (STYLE
, FONT_REF
, XL_NS_DRAW
, "fontRef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5096 GSF_XML_IN_NODE (FONT_REF
, HSL_CLR
, XL_NS_DRAW
, "hslClr", GSF_XML_2ND
, NULL
, NULL
),
5097 GSF_XML_IN_NODE (FONT_REF
, PRST_CLR
, XL_NS_DRAW
, "prstClr", GSF_XML_2ND
, NULL
, NULL
),
5098 GSF_XML_IN_NODE (FONT_REF
, SCHEME_CLR
, XL_NS_DRAW
, "schemeClr", GSF_XML_2ND
, NULL
, NULL
),
5099 GSF_XML_IN_NODE (FONT_REF
, SCRGB_CLR
, XL_NS_DRAW
, "scrgbClr", GSF_XML_2ND
, NULL
, NULL
),
5100 GSF_XML_IN_NODE (FONT_REF
, SRGB_CLR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5101 GSF_XML_IN_NODE (FONT_REF
, SYS_CLR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
5102 GSF_XML_IN_NODE (STYLE
, LN_REF
, XL_NS_DRAW
, "lnRef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5103 GSF_XML_IN_NODE (LN_REF
, HSL_CLR
, XL_NS_DRAW
, "hslClr", GSF_XML_2ND
, NULL
, NULL
),
5104 GSF_XML_IN_NODE (LN_REF
, PRST_CLR
, XL_NS_DRAW
, "prstClr", GSF_XML_2ND
, NULL
, NULL
),
5105 GSF_XML_IN_NODE (LN_REF
, SCHEME_CLR
, XL_NS_DRAW
, "schemeClr", GSF_XML_2ND
, NULL
, NULL
),
5106 GSF_XML_IN_NODE (LN_REF
, SCRGB_CLR
, XL_NS_DRAW
, "scrgbClr", GSF_XML_2ND
, NULL
, NULL
),
5107 GSF_XML_IN_NODE (LN_REF
, SRGB_CLR
, XL_NS_DRAW
, "srgbClr", GSF_XML_2ND
, NULL
, NULL
),
5108 GSF_XML_IN_NODE (LN_REF
, SYS_CLR
, XL_NS_DRAW
, "sysClr", GSF_XML_2ND
, NULL
, NULL
),
5109 GSF_XML_IN_NODE (SP_DEF
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_2ND
, NULL
, NULL
),
5110 GSF_XML_IN_NODE (OBJ_DEFAULTS
, LN_DEF
, XL_NS_DRAW
, "lnDef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5111 GSF_XML_IN_NODE (LN_DEF
, BODY_PR
, XL_NS_DRAW
, "bodyPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5112 GSF_XML_IN_NODE (LN_DEF
, LST_STYLE
, XL_NS_DRAW
, "lstStyle", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5113 GSF_XML_IN_NODE (LN_DEF
, SP_PR
, XL_NS_DRAW
, "spPr", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5114 GSF_XML_IN_NODE (LN_DEF
, STYLE
, XL_NS_DRAW
, "style", GSF_XML_2ND
, NULL
, NULL
),
5115 GSF_XML_IN_NODE (LN_DEF
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_2ND
, NULL
, NULL
),
5116 GSF_XML_IN_NODE (OBJ_DEFAULTS
, TX_DEF
, XL_NS_DRAW
, "txDef", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5117 GSF_XML_IN_NODE (OBJ_DEFAULTS
, EXTLST
, XL_NS_SS
, "extLst", GSF_XML_2ND
, NULL
, NULL
),
5118 GSF_XML_IN_NODE (THEME
, EXTRA_COLOR_SCHEME
, XL_NS_DRAW
, "extraClrSchemeLst", GSF_XML_NO_CONTENT
, NULL
, NULL
),
5120 GSF_XML_IN_NODE (THEME
, EXTLST
, XL_NS_DRAW
, "extLst", GSF_XML_2ND
, NULL
, NULL
),
5125 /****************************************************************************/
5127 G_MODULE_EXPORT gboolean
5128 xlsx_file_probe (GOFileOpener
const *fo
, GsfInput
*input
, GOFileProbeLevel pl
);
5131 xlsx_file_probe (G_GNUC_UNUSED GOFileOpener
const *fo
, GsfInput
*input
, G_GNUC_UNUSED GOFileProbeLevel pl
)
5135 gboolean res
= FALSE
;
5137 if (NULL
!= (zip
= gsf_infile_zip_new (input
, NULL
))) {
5138 if (NULL
!= (stream
= gsf_infile_child_by_vname (zip
, "xl", "workbook.xml", NULL
))) {
5139 g_object_unref (stream
);
5142 g_object_unref (zip
);
5148 xlsx_style_array_free (GPtrArray
*styles
)
5150 if (styles
!= NULL
) {
5151 unsigned i
= styles
->len
;
5154 if (NULL
!= (style
= g_ptr_array_index (styles
, i
)))
5155 gnm_style_unref (style
);
5157 g_ptr_array_free (styles
, TRUE
);
5161 #include "xlsx-read-docprops.c"
5163 G_MODULE_EXPORT
void
5164 xlsx_file_open (GOFileOpener
const *fo
, GOIOContext
*context
,
5165 WorkbookView
*wb_view
, GsfInput
*input
);
5168 xlsx_file_open (G_GNUC_UNUSED GOFileOpener
const *fo
, GOIOContext
*context
,
5169 WorkbookView
*wb_view
, GsfInput
*input
)
5171 XLSXReadState state
;
5174 memset (&state
, 0, sizeof (XLSXReadState
));
5175 state
.version
= ECMA_376_2006
;
5176 state
.context
= context
;
5177 state
.wb_view
= wb_view
;
5178 state
.wb
= wb_view_get_workbook (wb_view
);
5180 state
.run_attrs
= NULL
;
5181 state
.rich_attrs
= NULL
;
5182 state
.sst
= g_array_new (FALSE
, TRUE
, sizeof (XLSXStr
));
5183 state
.shared_exprs
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
5184 (GDestroyNotify
)g_free
, (GDestroyNotify
) gnm_expr_top_unref
);
5185 state
.cell_styles
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
5186 (GDestroyNotify
)g_free
, (GDestroyNotify
) gnm_style_unref
);
5187 state
.num_fmts
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
5188 (GDestroyNotify
)g_free
, (GDestroyNotify
) go_format_unref
);
5189 state
.date_fmt
= xlsx_pivot_date_fmt ();
5190 state
.convs
= xlsx_conventions_new (FALSE
);
5191 state
.theme_colors_by_name
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
5192 (GDestroyNotify
)g_free
, NULL
);
5193 /* fill in some default colors (when theme is absent */
5194 g_hash_table_replace (state
.theme_colors_by_name
, g_strdup ("lt1"), GUINT_TO_POINTER (GO_COLOR_WHITE
));
5195 g_hash_table_replace (state
.theme_colors_by_name
, g_strdup ("dk1"), GUINT_TO_POINTER (GO_COLOR_BLACK
));
5196 state
.pivot
.cache_by_id
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
5197 (GDestroyNotify
)g_free
, (GDestroyNotify
) g_object_unref
);
5198 state
.zorder
= g_hash_table_new (g_direct_hash
, g_direct_equal
);
5200 locale
= gnm_push_C_locale ();
5202 if (NULL
!= (state
.zip
= gsf_infile_zip_new (input
, NULL
))) {
5204 GsfInput
*wb_part
= gsf_open_pkg_open_rel_by_type (GSF_INPUT (state
.zip
),
5205 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", NULL
);
5207 if (NULL
!= wb_part
) {
5210 in
= gsf_open_pkg_open_rel_by_type (wb_part
,
5211 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", NULL
);
5213 start_update_progress (&state
, in
, _("Reading shared strings..."),
5215 xlsx_parse_stream (&state
, in
, xlsx_shared_strings_dtd
);
5216 end_update_progress (&state
);
5219 in
= gsf_open_pkg_open_rel_by_type (wb_part
,
5220 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", NULL
);
5222 start_update_progress (&state
, in
, _("Reading theme..."),
5224 xlsx_parse_stream (&state
, in
, xlsx_theme_dtd
);
5225 end_update_progress (&state
);
5228 in
= gsf_open_pkg_open_rel_by_type (wb_part
,
5229 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", NULL
);
5231 start_update_progress (&state
, in
, _("Reading styles..."), 0.1, 0.2);
5232 xlsx_parse_stream (&state
, in
, xlsx_styles_dtd
);
5233 end_update_progress (&state
);
5236 start_update_progress (&state
, wb_part
, _("Reading workbook..."),
5238 xlsx_parse_stream (&state
, wb_part
, xlsx_workbook_dtd
);
5239 /* end_update_progress (&state); moved into xlsx_wb_end */
5240 /* MW 20111121: why? If parsing fails, I don't think that will ever be called. */
5242 xlsx_read_docprops (&state
);
5245 go_cmd_context_error_import (GO_CMD_CONTEXT (context
),
5246 _("No workbook stream found."));
5248 g_object_unref (state
.zip
);
5251 gnm_pop_C_locale (locale
);
5253 if (NULL
!= state
.sst
) {
5254 unsigned i
= state
.sst
->len
;
5257 entry
= &g_array_index (state
.sst
, XLSXStr
, i
);
5258 go_string_unref (entry
->str
);
5259 go_format_unref (entry
->markup
);
5261 g_array_free (state
.sst
, TRUE
);
5263 if (state
.r_text
) g_string_free (state
.r_text
, TRUE
);
5264 if (state
.rich_attrs
) pango_attr_list_unref (state
.rich_attrs
);
5265 if (state
.run_attrs
) pango_attr_list_unref (state
.run_attrs
);
5266 g_hash_table_destroy (state
.pivot
.cache_by_id
);
5267 xlsx_conventions_free (state
.convs
);
5268 go_format_unref (state
.date_fmt
);
5269 g_hash_table_destroy (state
.num_fmts
);
5270 g_hash_table_destroy (state
.cell_styles
);
5271 g_hash_table_destroy (state
.shared_exprs
);
5272 xlsx_style_array_free (state
.fonts
);
5273 xlsx_style_array_free (state
.fills
);
5274 xlsx_style_array_free (state
.borders
);
5275 xlsx_style_array_free (state
.xfs
);
5276 xlsx_style_array_free (state
.style_xfs
);
5277 xlsx_style_array_free (state
.dxfs
);
5278 xlsx_style_array_free (state
.table_styles
);
5279 g_hash_table_destroy (state
.theme_colors_by_name
);
5280 g_hash_table_destroy (state
.zorder
);
5281 value_release (state
.val
);
5282 if (state
.texpr
) gnm_expr_top_unref (state
.texpr
);
5283 if (state
.comment
) g_object_unref (state
.comment
);
5284 if (state
.cur_style
) g_object_unref (state
.cur_style
);
5285 if (state
.style_accum
) gnm_style_unref (state
.style_accum
);
5286 if (state
.pending_rowcol_style
) gnm_style_unref (state
.pending_rowcol_style
);
5287 if (state
.border_color
) style_color_unref (state
.border_color
);
5289 workbook_set_saveinfo (state
.wb
, GO_FILE_FL_AUTO
,
5290 go_file_saver_for_id ((state
.version
== ECMA_376_2006
) ?
5291 "Gnumeric_Excel:xlsx" :
5292 "Gnumeric_Excel:xlsx2"));
5295 /* TODO * TODO * TODO
5298 * - column widths : Don't use hard coded font size
5300 * - conditional formats
5301 * : other condition types
5302 * : check binary operators
5304 * ".xlam", "application/vnd.ms-excel.addin.macroEnabled.12" ,
5305 * ".xlsb", "application/vnd.ms-excel.sheet.binary.macroEnabled.12" ,
5306 * ".xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12" ,
5307 * ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ,
5308 * ".xltm", "application/vnd.ms-excel.template.macroEnabled.12" ,
5309 * ".xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"