586
599
if (idx == 1 || idx == 65)
587
return style_color_white ();
589
602
case 0: /* black */
590
603
case 64 : /* system text ? */
591
604
case 81 : /* tooltip text */
592
605
case 0x7fff : /* system text ? */
593
return style_color_black ();
594
608
case 1 : /* white */
595
609
case 65 : /* system back ? */
596
return style_color_white ();
598
612
case 80 : /* tooltip background */
599
return style_color_new_gdk (&gs_yellow);
601
case 2 : return style_color_new_i8 (0xff, 0, 0); /* red */
602
case 3 : return style_color_new_i8 ( 0, 0xff, 0); /* green */
603
case 4 : return style_color_new_i8 ( 0, 0, 0xff); /* blue */
604
case 5 : return style_color_new_i8 (0xff, 0xff, 0); /* yellow */
605
case 6 : return style_color_new_i8 (0xff, 0, 0xff); /* magenta */
606
case 7 : return style_color_new_i8 ( 0, 0xff, 0xff); /* cyan */
615
case 2 : return RGBA_RED;
616
case 3 : return RGBA_GREEN;
617
case 4 : return RGBA_BLUE;
618
case 5 : return RGBA_YELLOW;
619
case 6 : return RGBA_VIOLET;
620
case 7 : return RGBA_CYAN;
612
627
if (idx < 0 || (int) G_N_ELEMENTS (excel_default_palette_v8) <= idx) {
613
628
g_warning ("EXCEL: color index (%d) is out of range (8..%d). Defaulting to black",
614
629
idx + 8, (int)G_N_ELEMENTS (excel_default_palette_v8) + 8);
615
return style_color_black ();
618
633
/* TODO cache and ref */
619
return style_color_new_i8 (excel_default_palette_v8[idx].r,
620
excel_default_palette_v8[idx].g,
621
excel_default_palette_v8[idx].b);
634
return RGBA_TO_UINT (excel_default_palette_v8[idx].r,
635
excel_default_palette_v8[idx].g,
636
excel_default_palette_v8[idx].b, 0xff);
639
themed_color (GsfXMLIn *xin, gint idx)
641
static char const * const theme_elements [] = {
642
"lt1", "dk1", "lt2", "dk2",
643
"accent1", "accent2", "accent3", "accent4", "accent5", "accent6",
646
XLSXReadState *state = (XLSXReadState *)xin->user_state;
649
* looks like the indicies map to hard coded names rather than the
650
* order in the file. Indeed the order in the file seems wrong
651
* it inverts the first to pairs
652
* 1,0,3,2, 4,5,6.....
653
* see: http://openxmldeveloper.org/forums/thread/1306.aspx
654
* OOo seems to do something similar
656
* I'll make the assumption we should work by name rather than
658
if (idx >= 0 && idx < (int) G_N_ELEMENTS (theme_elements)) {
659
gpointer color = g_hash_table_lookup (state->theme_colors_by_name,
660
theme_elements [idx]);
662
return GPOINTER_TO_UINT (color);
664
xlsx_warning (xin, _("Unknown theme color %d"), idx);
666
xlsx_warning (xin, "Color index (%d) is out of range (0..%d). Defaulting to black",
667
idx, (int) G_N_ELEMENTS (theme_elements));
624
673
static GOFormat *
1648
1713
GSF_XML_IN_NODE (CAT_AXIS, AXIS_POS, XL_NS_CHART, "axPos", GSF_XML_NO_CONTENT, &xlsx_axis_pos, NULL),
1649
1714
GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_TICKLBLPOS, XL_NS_CHART, "tickLblPos", GSF_XML_NO_CONTENT, NULL, NULL),
1650
1715
GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_AUTO, XL_NS_CHART, "auto", GSF_XML_NO_CONTENT, NULL, NULL),
1651
GSF_XML_IN_NODE (CAT_AXIS, AXIS_CROSSAX, XL_NS_CHART, "crossAx", GSF_XML_NO_CONTENT, NULL, NULL),
1716
GSF_XML_IN_NODE (CAT_AXIS, AXIS_CROSSAX, XL_NS_CHART, "crossAx", GSF_XML_NO_CONTENT, &xlsx_axis_crossax, NULL),
1652
1717
GSF_XML_IN_NODE (CAT_AXIS, AXIS_CROSSES, XL_NS_CHART, "crosses", GSF_XML_NO_CONTENT, &xlsx_axis_crosses, NULL),
1654
1719
GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_LBLALGN, XL_NS_CHART, "lblAlgn", GSF_XML_NO_CONTENT, NULL, NULL),
1907
1972
cb_axis_set_position (GObject *axis, XLSXAxisInfo *info,
1908
G_GNUC_UNUSED gpointer accum)
1973
XLSXReadState *state)
1910
g_object_set (axis, "pos", info->cross, NULL);
1975
if (info->deleted) {
1976
GSList *l = gog_chart_get_axes (state->chart, gog_axis_get_atype (GOG_AXIS (axis))), *cur;
1977
GogAxis *visible = NULL;
1979
for (cur = l; cur; cur = cur->next) {
1981
g_object_get (cur->data, "invisible", &invisible, NULL);
1983
visible = GOG_AXIS (cur->data);
1990
l1 = g_slist_copy ((GSList *) gog_axis_contributors (GOG_AXIS (axis)));
1991
for (cur1 = l1; cur1; cur1 = cur1->next) {
1992
if (GOG_IS_PLOT (cur1->data))
1993
gog_plot_set_axis (GOG_PLOT (cur1->data), visible);
1996
/* now reparent the children of the hidden axis */
1997
l1 = gog_object_get_children (GOG_OBJECT (axis), NULL);
1998
for (cur1 = l1; cur1; cur1 = cur1->next) {
1999
GogObject *obj = GOG_OBJECT (cur1->data);
2000
GogObjectRole const *role = obj->role;
2001
gog_object_clear_parent (obj);
2002
gog_object_set_parent (obj, GOG_OBJECT (visible), role, obj->id);
2007
XLSXAxisInfo *cross_info = g_hash_table_lookup (state->axis.by_id, info->cross_id);
2008
g_return_if_fail (cross_info != NULL);
2009
g_object_set (axis, "pos", info->cross, "cross-axis-id", gog_object_get_id (GOG_OBJECT (cross_info->axis)), NULL);
2122
2222
/***********************************************************************/
2224
/* RGBMAX, HLSMAX must each fit in a byte. */
2225
/* HLSMAX BEST IF DIVISIBLE BY 6 */
2226
#define HLSMAX 240 /* H,L, and S vary over 0-HLSMAX */
2227
#define RGBMAX 255 /* R,G, and B vary over 0-RGBMAX */
2229
/* Hue is undefined if Saturation is 0 (grey-scale) */
2230
/* This value determines where the Hue scrollbar is */
2231
/* initially set for achromatic colors */
2232
#define UNDEFINED (HLSMAX*2/3)
2234
/* utility routine for HLStoRGB */
2236
hue_to_color (int m1, int m2, int h)
2243
/* return r,g, or b value from this tridrant */
2245
return m1 + (((m2 - m1)*h + (HLSMAX/12))/(HLSMAX/6));
2248
if (h < ((HLSMAX*2)/3))
2249
return m1 + (((m2 - m1)*(((HLSMAX*2)/3)-h)+(HLSMAX/12))/(HLSMAX/6));
2255
apply_tint (GOColor orig, float tint)
2257
int r = UINT_RGBA_R (orig);
2258
int g = UINT_RGBA_G (orig);
2259
int b = UINT_RGBA_B (orig);
2260
int a = UINT_RGBA_A (orig);
2261
int maxC = b, minC = b, delta, sum, h, l, s, m1, m2;
2263
if (fabs (tint) < .005)
2266
maxC = MAX (MAX (r,g),b);
2267
minC = MIN (MIN (r,g),b);
2268
l = (((maxC + minC)*HLSMAX) + RGBMAX)/(2*RGBMAX);
2270
delta = maxC - minC;
2273
if (l <= (HLSMAX/2))
2274
s = ( (delta*HLSMAX) + (sum/2) ) / sum;
2276
s = ( (delta*HLSMAX) + ((2*RGBMAX - sum)/2) ) / (2*RGBMAX - sum);
2279
h = ((g - b) * HLSMAX) / (6 * delta);
2281
h = ( HLSMAX/3) + ((b - r) * HLSMAX) / (6 * delta);
2283
h = (2*HLSMAX/3) + ((r - g) * HLSMAX) / (6 * delta);
2287
else if (h >= HLSMAX)
2295
l = l * (1. + tint);
2297
l = l * (1. - tint) + (HLSMAX - HLSMAX * (1.0 - tint));
2299
if (s == 0) { /* achromatic case */
2300
r = (l * RGBMAX) / HLSMAX;
2301
return RGBA_TO_UINT(r, r, r, a);
2304
if (l <= (HLSMAX/2))
2305
m2 = (l*(HLSMAX + s) + (HLSMAX/2))/HLSMAX;
2307
m2 = l + s - ((l*s) + (HLSMAX/2))/HLSMAX;
2310
r = (hue_to_color (m1, m2, h + (HLSMAX/3))*RGBMAX + (HLSMAX/2)) / HLSMAX;
2311
g = (hue_to_color (m1, m2, h )*RGBMAX + (HLSMAX/2)) / HLSMAX;
2312
b = (hue_to_color (m1, m2, h - (HLSMAX/3))*RGBMAX + (HLSMAX/2)) / HLSMAX;
2314
return RGBA_TO_UINT(r,g,b,a);
2124
2317
static GnmColor *
2125
2318
elem_color (GsfXMLIn *xin, xmlChar const **attrs)
2320
XLSXReadState *state = (XLSXReadState *)xin->user_state;
2324
gboolean has_color = FALSE;
2130
2326
for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2) {
2131
2327
if (0 == strcmp (attrs[0], "rgb")) {
2132
2329
if (4 != sscanf (attrs[1], "%02x%02x%02x%02x", &a, &r, &g, &b)) {
2133
2330
xlsx_warning (xin,
2134
2331
_("Invalid color '%s' for attribute rgb"),
2139
return style_color_new_i8 (r, g, b);
2140
} else if (attr_int (xin, attrs, "indexed", &indx))
2141
return indexed_color (indx);
2143
"type" opt rgb {auto, icv, rgb, theme }
2336
c = RGBA_TO_UINT(r,g,b,a);
2337
} else if (attr_int (xin, attrs, "indexed", &indx)) {
2339
c = indexed_color (state, indx);
2340
} else if (attr_int (xin, attrs, "theme", &indx)) {
2342
c = themed_color (xin, indx);
2343
} else if (attr_float (xin, attrs, "tint", &tint))
2344
tint = CLAMP (tint, -1., 1.);
2349
c = apply_tint (c, tint);
2350
return style_color_new_go (c);
2354
xlsx_get_style_xf (GsfXMLIn *xin, int xf)
2356
XLSXReadState *state = (XLSXReadState *)xin->user_state;
2357
if (0 <= xf && NULL != state->style_xfs && xf < (int)state->style_xfs->len)
2358
return g_ptr_array_index (state->style_xfs, xf);
2359
xlsx_warning (xin, _("Undefined style record '%d'"), xf);
2151
2362
static GnmStyle *
2152
2363
xlsx_get_xf (GsfXMLIn *xin, int xf)
3362
3589
g_slist_free (accum);
3594
xlsx_CT_PivotSelection (GsfXMLIn *xin, xmlChar const **attrs)
3597
XLSXReadState *state = (XLSXReadState *)xin->user_state;
3598
<xsd:attribute name="pane" type="ST_Pane" use="optional" default="topLeft">
3599
<xsd:attribute name="showHeader" type="xsd:boolean" default="false">
3600
<xsd:attribute name="label" type="xsd:boolean" default="false">
3601
<xsd:attribute name="data" type="xsd:boolean" default="false">
3602
<xsd:attribute name="extendable" type="xsd:boolean" default="false">
3603
<xsd:attribute name="count" type="xsd:unsignedInt" default="0">
3604
<xsd:attribute name="axis" type="ST_Axis" use="optional">
3605
<xsd:attribute name="dimension" type="xsd:unsignedInt" default="0">
3606
<xsd:attribute name="start" type="xsd:unsignedInt" default="0">
3607
<xsd:attribute name="min" type="xsd:unsignedInt" default="0">
3608
<xsd:attribute name="max" type="xsd:unsignedInt" default="0">
3609
<xsd:attribute name="activeRow" type="xsd:unsignedInt" default="0">
3610
<xsd:attribute name="activeCol" type="xsd:unsignedInt" default="0">
3611
<xsd:attribute name="previousRow" type="xsd:unsignedInt" default="0">
3612
<xsd:attribute name="previousCol" type="xsd:unsignedInt" default="0">
3613
<xsd:attribute name="click" type="xsd:unsignedInt" default="0">
3614
<xsd:attribute ref="r:id" use="optional">
3619
xlsx_CT_PivotArea (GsfXMLIn *xin, xmlChar const **attrs)
3622
XLSXReadState *state = (XLSXReadState *)xin->user_state;
3623
<xsd:attribute name="field" use="optional" type="xsd:int">
3624
<xsd:attribute name="type" type="ST_PivotAreaType" default="normal">
3625
<xsd:attribute name="dataOnly" type="xsd:boolean" default="true">
3626
<xsd:attribute name="labelOnly" type="xsd:boolean" default="false">
3627
<xsd:attribute name="grandRow" type="xsd:boolean" default="false">
3628
<xsd:attribute name="grandCol" type="xsd:boolean" default="false">
3629
<xsd:attribute name="cacheIndex" type="xsd:boolean" default="false">
3630
<xsd:attribute name="outline" type="xsd:boolean" default="true">
3631
<xsd:attribute name="offset" type="ST_Ref">
3632
<xsd:attribute name="collapsedLevelsAreSubtotals" type="xsd:boolean" default="false">
3633
<xsd:attribute name="axis" type="ST_Axis" use="optional">
3634
<xsd:attribute name="fieldPosition" type="xsd:unsignedInt" use="optional">
3638
xlsx_CT_PivotAreaReferences (GsfXMLIn *xin, xmlChar const **attrs)
3641
XLSXReadState *state = (XLSXReadState *)xin->user_state;
3645
xlsx_CT_PivotAreaReference (GsfXMLIn *xin, xmlChar const **attrs)
3648
XLSXReadState *state = (XLSXReadState *)xin->user_state;
3649
<xsd:attribute name="field" use="optional" type="xsd:unsignedInt">
3650
<xsd:attribute name="count" type="xsd:unsignedInt">
3651
<xsd:attribute name="selected" type="xsd:boolean" default="true">
3652
<xsd:attribute name="byPosition" type="xsd:boolean" default="false">
3653
<xsd:attribute name="relative" type="xsd:boolean" default="false">
3654
<xsd:attribute name="defaultSubtotal" type="xsd:boolean" default="false">
3655
<xsd:attribute name="sumSubtotal" type="xsd:boolean" default="false">
3656
<xsd:attribute name="countASubtotal" type="xsd:boolean" default="false">
3657
<xsd:attribute name="avgSubtotal" type="xsd:boolean" default="false">
3658
<xsd:attribute name="maxSubtotal" type="xsd:boolean" default="false">
3659
<xsd:attribute name="minSubtotal" type="xsd:boolean" default="false">
3660
<xsd:attribute name="productSubtotal" type="xsd:boolean" default="false">
3661
<xsd:attribute name="countSubtotal" type="xsd:boolean" default="false">
3662
<xsd:attribute name="stdDevSubtotal" type="xsd:boolean" default="false">
3663
<xsd:attribute name="stdDevPSubtotal" type="xsd:boolean" default="false">
3664
<xsd:attribute name="varSubtotal" type="xsd:boolean" default="false">
3665
<xsd:attribute name="varPSubtotal" type="xsd:boolean" default="false">
3366
3670
xlsx_CT_Pane (GsfXMLIn *xin, xmlChar const **attrs)
3475
3779
sheet_style_apply_range (state->sheet, &r, style);
3478
static GsfXMLInNode const xlsx_sheet_dtd[] =
3782
#ifdef HAVE_GSF_OPEN_PKG_FOREACH_REL
3784
cb_find_pivots (GsfInput *opkg, GsfOpenPkgRel const *rel, gpointer user_data)
3786
XLSXReadState *state = user_data;
3787
GsfInput *part_stream;
3788
char const *t = gsf_open_pkg_rel_get_type (rel);
3791
0 == strcmp (t, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable") &&
3792
NULL != (part_stream = gsf_open_pkg_open_rel (opkg, rel, NULL)))
3793
xlsx_parse_stream (state, part_stream, xlsx_pivot_table_dtd);
3798
xlsx_CT_worksheet (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
3800
#ifdef HAVE_GSF_OPEN_PKG_FOREACH_REL
3801
gsf_open_pkg_foreach_rel (gsf_xml_in_get_input (xin),
3802
&cb_find_pivots, (XLSXReadState *)xin->user_state);
3806
static GsfXMLInNode const xlsx_sheet_dtd[] = {
3480
3807
GSF_XML_IN_NODE_FULL (START, START, -1, NULL, GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
3481
GSF_XML_IN_NODE_FULL (START, SHEET, XL_NS_SS, "worksheet", GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
3482
GSF_XML_IN_NODE (SHEET, PROPS, XL_NS_SS, "sheetPr", GSF_XML_NO_CONTENT, NULL, NULL),
3808
GSF_XML_IN_NODE_FULL (START, SHEET, XL_NS_SS, "worksheet", GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, &xlsx_CT_worksheet, 0),
3809
GSF_XML_IN_NODE (SHEET, PROPS, XL_NS_SS, "sheetPr", GSF_XML_NO_CONTENT, &xlsx_CT_SheetPr, NULL),
3483
3810
GSF_XML_IN_NODE (PROPS, OUTLINE_PROPS, XL_NS_SS, "outlinePr", GSF_XML_NO_CONTENT, NULL, NULL),
3484
3811
GSF_XML_IN_NODE (PROPS, TAB_COLOR, XL_NS_SS, "tabColor", GSF_XML_NO_CONTENT, &xlsx_sheet_tabcolor, NULL),
3485
3812
GSF_XML_IN_NODE (PROPS, PAGE_SETUP, XL_NS_SS, "pageSetUpPr", GSF_XML_NO_CONTENT, &xlsx_sheet_page_setup, NULL),
3486
3813
GSF_XML_IN_NODE (SHEET, DIMENSION, XL_NS_SS, "dimension", GSF_XML_NO_CONTENT, NULL, NULL),
3487
3814
GSF_XML_IN_NODE (SHEET, VIEWS, XL_NS_SS, "sheetViews", GSF_XML_NO_CONTENT, NULL, NULL),
3488
3815
GSF_XML_IN_NODE (VIEWS, VIEW, XL_NS_SS, "sheetView", GSF_XML_NO_CONTENT, &xlsx_CT_SheetView_begin, &xlsx_CT_SheetView_end),
3816
GSF_XML_IN_NODE (VIEW, PANE, XL_NS_SS, "pane", GSF_XML_NO_CONTENT, &xlsx_CT_Pane, NULL),
3489
3817
GSF_XML_IN_NODE (VIEW, SELECTION, XL_NS_SS, "selection", GSF_XML_NO_CONTENT, &xlsx_CT_Selection, NULL),
3490
GSF_XML_IN_NODE (VIEW, PANE, XL_NS_SS, "pane", GSF_XML_NO_CONTENT, &xlsx_CT_Pane, NULL),
3818
GSF_XML_IN_NODE (VIEW, PIV_SELECTION, XL_NS_SS, "pivotSelection", GSF_XML_NO_CONTENT, &xlsx_CT_PivotSelection, NULL),
3819
GSF_XML_IN_NODE (PIV_SELECTION, PIV_AREA, XL_NS_SS, "pivotArea", GSF_XML_NO_CONTENT, &xlsx_CT_PivotArea, NULL),
3820
GSF_XML_IN_NODE (PIV_AREA, PIV_AREA_REFS, XL_NS_SS, "references", GSF_XML_NO_CONTENT, &xlsx_CT_PivotAreaReferences, NULL),
3821
GSF_XML_IN_NODE (PIV_AREA_REFS, PIV_AREA_REF, XL_NS_SS, "reference", GSF_XML_NO_CONTENT, &xlsx_CT_PivotAreaReference, NULL),
3492
3823
GSF_XML_IN_NODE (SHEET, DEFAULT_FMT, XL_NS_SS, "sheetFormatPr", GSF_XML_NO_CONTENT, &xlsx_CT_SheetFormatPr, NULL),
3500
3831
GSF_XML_IN_NODE (CELL, VALUE, XL_NS_SS, "v", GSF_XML_CONTENT, NULL, &xlsx_cell_val_end),
3501
3832
GSF_XML_IN_NODE (CELL, FMLA, XL_NS_SS, "f", GSF_XML_CONTENT, &xlsx_cell_expr_begin, &xlsx_cell_expr_end),
3834
GSF_XML_IN_NODE (SHEET, CALC_PR, XL_NS_SS, "sheetCalcPr", GSF_XML_NO_CONTENT, NULL, NULL),
3503
3835
GSF_XML_IN_NODE (SHEET, CT_SortState, XL_NS_SS, "sortState", GSF_XML_NO_CONTENT, NULL, NULL),
3504
3836
GSF_XML_IN_NODE (CT_SortState, CT_SortCondition, XL_NS_SS, "sortCondition", GSF_XML_NO_CONTENT, NULL, NULL),
3837
GSF_XML_IN_NODE (SHEET, SCENARIOS, XL_NS_SS, "scenarios", GSF_XML_NO_CONTENT, NULL, NULL),
3838
GSF_XML_IN_NODE (SCENARIOS, INPUT_CELLS, XL_NS_SS, "inputCells", GSF_XML_NO_CONTENT, NULL, NULL),
3839
GSF_XML_IN_NODE (SHEET, PROTECTED_RANGES, XL_NS_SS, "protectedRanges", GSF_XML_NO_CONTENT, NULL, NULL),
3840
GSF_XML_IN_NODE (SHEET, PROTECTED_RANGE, XL_NS_SS, "protectedRange", GSF_XML_NO_CONTENT, NULL, NULL),
3506
3842
GSF_XML_IN_NODE (SHEET, CT_AutoFilter, XL_NS_SS, "autoFilter", GSF_XML_NO_CONTENT,
3507
3843
&xlsx_CT_AutoFilter_begin, &xlsx_CT_AutoFilter_end),
3644
3990
(GDestroyNotify) g_free);
3993
/**************************************************************************************************/
3996
xlsx_read_external_book (GsfXMLIn *xin, xmlChar const **attrs)
3998
XLSXReadState *state = (XLSXReadState *)xin->user_state;
3999
GsfOpenPkgRel const *rel = gsf_open_pkg_lookup_rel_by_type (
4000
gsf_xml_in_get_input (xin),
4001
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath");
4002
if (NULL != rel && gsf_open_pkg_rel_is_extern (rel))
4003
state->external_ref = xlsx_conventions_add_extern_ref (
4004
state->convs, gsf_open_pkg_rel_get_target (rel));
4007
xlsx_read_external_book_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
4009
XLSXReadState *state = (XLSXReadState *)xin->user_state;
4010
state->external_ref = NULL;
4013
xlsx_read_external_sheetname (GsfXMLIn *xin, xmlChar const **attrs)
4015
XLSXReadState *state = (XLSXReadState *)xin->user_state;
4016
for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
4017
if (0 == strcmp (attrs[0], "val"))
4018
workbook_sheet_attach (state->external_ref,
4019
state->external_ref_sheet = sheet_new (state->external_ref, attrs[1], 256, 65536));
4022
xlsx_read_external_sheetname_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
4024
XLSXReadState *state = (XLSXReadState *)xin->user_state;
4025
state->external_ref_sheet = NULL;
4028
static GsfXMLInNode const xlsx_extern_dtd[] = {
4029
GSF_XML_IN_NODE_FULL (START, START, -1, NULL, GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
4030
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),
4031
GSF_XML_IN_NODE (LINK, BOOK, XL_NS_SS, "externalBook", GSF_XML_NO_CONTENT, NULL, NULL),
4032
GSF_XML_IN_NODE (BOOK, SHEET_NAMES, XL_NS_SS, "sheetNames", GSF_XML_NO_CONTENT, NULL, NULL),
4033
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),
4034
GSF_XML_IN_NODE (BOOK, SHEET_DATASET, XL_NS_SS, "sheetDataSet", GSF_XML_NO_CONTENT, NULL, NULL),
4035
GSF_XML_IN_NODE (SHEET_DATASET, SHEET_DATA, XL_NS_SS, "sheetData", GSF_XML_NO_CONTENT, NULL, NULL),
4036
GSF_XML_IN_NODE (SHEET_DATA, ROW, XL_NS_SS, "row", GSF_XML_NO_CONTENT, NULL, NULL),
4037
GSF_XML_IN_NODE (ROW, CELL, XL_NS_SS, "cell", GSF_XML_NO_CONTENT, NULL, NULL),
4038
GSF_XML_IN_NODE (CELL, VAL, XL_NS_SS, "v", GSF_XML_NO_CONTENT, NULL, NULL),
4044
xlsx_wb_external_ref (GsfXMLIn *xin, xmlChar const **attrs)
4046
for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
4047
if (gsf_xml_in_namecmp (xin, attrs[0], XL_NS_DOC_REL, "id"))
4048
xlsx_parse_rel_by_id (xin, attrs[1], xlsx_extern_dtd, xlsx_ns);
4051
/**************************************************************************************************/
3648
4054
xlsx_wb_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
3684
4090
GSF_XML_IN_NODE (WORKBOOK, VERSION, XL_NS_SS, "fileVersion", GSF_XML_NO_CONTENT, NULL, NULL),
3685
4091
GSF_XML_IN_NODE (WORKBOOK, PROPERTIES, XL_NS_SS, "workbookPr", GSF_XML_NO_CONTENT, NULL, NULL),
3686
4092
GSF_XML_IN_NODE (WORKBOOK, CALC_PROPS, XL_NS_SS, "calcPr", GSF_XML_NO_CONTENT, &xlsx_CT_CalcPr, NULL),
3687
4094
GSF_XML_IN_NODE (WORKBOOK, VIEWS, XL_NS_SS, "bookViews", GSF_XML_NO_CONTENT, NULL, NULL),
3688
4095
GSF_XML_IN_NODE (VIEWS, VIEW, XL_NS_SS, "workbookView", GSF_XML_NO_CONTENT, NULL, NULL),
4096
GSF_XML_IN_NODE (WORKBOOK, CUSTOMWVIEWS, XL_NS_SS, "customWorkbookViews", GSF_XML_NO_CONTENT, NULL, NULL),
4097
GSF_XML_IN_NODE (CUSTOMWVIEWS, CUSTOMWVIEW , XL_NS_SS, "customWorkbookView", GSF_XML_NO_CONTENT, NULL, NULL),
4098
GSF_XML_IN_NODE (CUSTOMWVIEW, EXTLST, XL_NS_SS, "extLst", GSF_XML_NO_CONTENT, NULL, NULL),
3689
4100
GSF_XML_IN_NODE (WORKBOOK, SHEETS, XL_NS_SS, "sheets", GSF_XML_NO_CONTENT, NULL, NULL),
3690
4101
GSF_XML_IN_NODE (SHEETS, SHEET, XL_NS_SS, "sheet", GSF_XML_NO_CONTENT, &xlsx_sheet_begin, NULL),
4102
GSF_XML_IN_NODE (WORKBOOK, FGROUPS, XL_NS_SS, "functionGroups", GSF_XML_NO_CONTENT, NULL, NULL),
4103
GSF_XML_IN_NODE (FGROUPS, FGROUP, XL_NS_SS, "functionGroup", GSF_XML_NO_CONTENT, NULL, NULL),
3691
4104
GSF_XML_IN_NODE (WORKBOOK, WEB_PUB, XL_NS_SS, "webPublishing", GSF_XML_NO_CONTENT, NULL, NULL),
3692
4105
GSF_XML_IN_NODE (WORKBOOK, EXTERNS, XL_NS_SS, "externalReferences", GSF_XML_NO_CONTENT, NULL, NULL),
3693
GSF_XML_IN_NODE (EXTERNS, EXTERN, XL_NS_SS, "externalReference", GSF_XML_NO_CONTENT, NULL, NULL),
4106
GSF_XML_IN_NODE (EXTERNS, EXTERN, XL_NS_SS, "externalReference", GSF_XML_NO_CONTENT, xlsx_wb_external_ref, NULL),
3694
4107
GSF_XML_IN_NODE (WORKBOOK, NAMES, XL_NS_SS, "definedNames", GSF_XML_NO_CONTENT, NULL, NULL),
3695
4108
GSF_XML_IN_NODE (NAMES, NAME, XL_NS_SS, "definedName", GSF_XML_NO_CONTENT, NULL, NULL),
4109
GSF_XML_IN_NODE (WORKBOOK, PIVOTCACHES, XL_NS_SS, "pivotCaches", GSF_XML_NO_CONTENT, NULL, NULL),
4110
GSF_XML_IN_NODE (PIVOTCACHES, PIVOTCACHE, XL_NS_SS, "pivotCache", GSF_XML_NO_CONTENT, &xlsx_CT_PivotCache, NULL),
3696
4112
GSF_XML_IN_NODE (WORKBOOK, RECOVERY, XL_NS_SS, "fileRecoveryPr", GSF_XML_NO_CONTENT, NULL, NULL),
4113
GSF_XML_IN_NODE (WORKBOOK, OLESIZE, XL_NS_SS, "oleSize", GSF_XML_NO_CONTENT, NULL, NULL),
4114
GSF_XML_IN_NODE (WORKBOOK, SMARTTAGPR, XL_NS_SS, "smartTagPr", GSF_XML_NO_CONTENT, NULL, NULL),
4115
GSF_XML_IN_NODE (WORKBOOK, SMARTTTYPES, XL_NS_SS, "smartTagTypes", GSF_XML_NO_CONTENT, NULL, NULL),
4116
GSF_XML_IN_NODE (SMARTTTYPES, SMARTTTYPE, XL_NS_SS, "smartTagType", GSF_XML_NO_CONTENT, NULL, NULL),
4117
GSF_XML_IN_NODE (WORKBOOK, WEB_PUB_OBJS, XL_NS_SS, "webPublishObjects", GSF_XML_NO_CONTENT, NULL, NULL),
4118
GSF_XML_IN_NODE (WEB_PUB_OBJS, WEB_PUB_OBJ, XL_NS_SS, "webPublishObject", GSF_XML_NO_CONTENT, NULL, NULL),
3698
4120
GSF_XML_IN_NODE_END
3993
4414
gnm_style_set_pattern (state->style_accum, val);
3996
xlsx_pattern_fg (GsfXMLIn *xin, xmlChar const **attrs)
4417
xlsx_pattern_fg_bg (GsfXMLIn *xin, xmlChar const **attrs)
3998
4419
XLSXReadState *state = (XLSXReadState *)xin->user_state;
4421
* Looks like pattern background and forground colours are inverted for
4422
* dxfs with solid fills for no apparent reason. */
4423
gboolean const invert = state->style_accum_partial
4424
&& gnm_style_is_element_set (state->style_accum, MSTYLE_PATTERN)
4425
&& (1 == gnm_style_get_pattern (state->style_accum));
3999
4426
GnmColor *color = elem_color (xin, attrs);
4001
if (NULL != color) {
4002
if (gnm_style_is_element_set (state->style_accum, MSTYLE_COLOR_PATTERN) &&
4003
gnm_style_get_pattern (state->style_accum) == 1)
4004
gnm_style_set_back_color (state->style_accum, color);
4006
gnm_style_set_pattern_color (state->style_accum, color);
4430
if (xin->node->user_data.v_int ^ invert)
4431
gnm_style_set_back_color (state->style_accum, color);
4433
gnm_style_set_pattern_color (state->style_accum, color);
4010
xlsx_pattern_bg (GsfXMLIn *xin, xmlChar const **attrs)
4437
xlsx_CT_GradientFill (GsfXMLIn *xin, xmlChar const **attrs)
4012
4440
XLSXReadState *state = (XLSXReadState *)xin->user_state;
4013
GnmColor *color = elem_color (xin, attrs);
4014
if (NULL != color) {
4015
if (!gnm_style_is_element_set (state->style_accum, MSTYLE_COLOR_PATTERN) ||
4016
gnm_style_get_pattern (state->style_accum) != 1)
4017
gnm_style_set_back_color (state->style_accum, color);
4019
gnm_style_set_pattern_color (state->style_accum, color);
4441
<xsd:attribute name="type" type="ST_GradientType" use="optional" default="linear">
4442
<xsd:attribute name="degree" type="xsd:double" use="optional" default="0">
4443
<xsd:attribute name="left" type="xsd:double" use="optional" default="0">
4444
<xsd:attribute name="right" type="xsd:double" use="optional" default="0">
4445
<xsd:attribute name="top" type="xsd:double" use="optional" default="0">
4446
<xsd:attribute name="bottom" type="xsd:double" use="optional" default="0">
4084
4517
if (0 == strcmp (attrs[0], "numFmtId")) {
4085
4518
GOFormat *fmt = xlsx_get_num_fmt (xin, attrs[1]);
4086
4519
if (NULL != fmt)
4087
gnm_style_set_format (style, fmt);
4520
gnm_style_set_format (accum, fmt);
4088
4521
} else if (attr_int (xin, attrs, "fontId", &indx))
4089
4522
elem = state->fonts;
4090
4523
else if (attr_int (xin, attrs, "fillId", &indx))
4091
4524
elem = state->fills;
4092
4525
else if (attr_int (xin, attrs, "borderId", &indx))
4093
4526
elem = state->borders;
4527
else if (attr_int (xin, attrs, "xfId", &indx))
4528
parent = xlsx_get_style_xf (xin, indx);
4095
4530
if (NULL != elem) {
4096
GnmStyle *existing = NULL;
4531
GnmStyle const *component = NULL;
4097
4532
if (0 <= indx && indx < (int)elem->len)
4098
existing = g_ptr_array_index (elem, indx);
4099
if (NULL != existing) {
4100
GnmStyle *merged = gnm_style_new_merged (existing, style);
4101
gnm_style_unref (style);
4533
component = g_ptr_array_index (elem, indx);
4534
if (NULL != component) {
4536
gnm_style_merge (accum, component);
4538
GnmStyle *merged = gnm_style_new_merged (accum, component);
4539
gnm_style_unref (accum);
4104
xlsx_warning (xin, _("Missing record '%d'"), indx);
4543
xlsx_warning (xin, "Missing record '%d' for %s", indx, attrs[0]);
4108
state->style_accum = style;
4547
if (NULL == parent) {
4548
result = gnm_style_new_default ();
4549
gnm_style_merge (result, accum);
4551
result = gnm_style_new_merged (parent, accum);
4552
gnm_style_unref (accum);
4554
state->style_accum = result;
4110
"xfId" parent style ??
4111
4556
"quotePrefix" ??
4113
4558
"applyNumberFormat"
4256
4701
FALSE, FALSE, &xlsx_collection_begin, &xlsx_collection_end, XLSX_COLLECT_FILLS),
4257
4702
GSF_XML_IN_NODE (FILLS, FILL, XL_NS_SS, "fill", GSF_XML_NO_CONTENT, &xlsx_col_elem_begin, &xlsx_col_elem_end),
4258
4703
GSF_XML_IN_NODE (FILL, PATTERN_FILL, XL_NS_SS, "patternFill", GSF_XML_NO_CONTENT, &xlsx_pattern, NULL),
4259
GSF_XML_IN_NODE (PATTERN_FILL, PATTERN_FILL_FG, XL_NS_SS, "fgColor", GSF_XML_NO_CONTENT, &xlsx_pattern_fg, NULL),
4260
GSF_XML_IN_NODE (PATTERN_FILL, PATTERN_FILL_BG, XL_NS_SS, "bgColor", GSF_XML_NO_CONTENT, &xlsx_pattern_bg, NULL),
4704
GSF_XML_IN_NODE_FULL (PATTERN_FILL, PATTERN_FILL_FG, XL_NS_SS, "fgColor", GSF_XML_NO_CONTENT,
4705
FALSE, FALSE, &xlsx_pattern_fg_bg, NULL, TRUE),
4706
GSF_XML_IN_NODE_FULL (PATTERN_FILL, PATTERN_FILL_BG, XL_NS_SS, "bgColor", GSF_XML_NO_CONTENT,
4707
FALSE, FALSE, &xlsx_pattern_fg_bg, NULL, FALSE),
4261
4708
GSF_XML_IN_NODE (FILL, IMAGE_FILL, XL_NS_SS, "image", GSF_XML_NO_CONTENT, NULL, NULL),
4262
GSF_XML_IN_NODE (FILL, GRADIENT_FILL, XL_NS_SS, "gradient", GSF_XML_NO_CONTENT, NULL, NULL),
4709
GSF_XML_IN_NODE (FILL, GRADIENT_FILL, XL_NS_SS, "gradientFill", GSF_XML_NO_CONTENT, &xlsx_CT_GradientFill, NULL),
4263
4710
GSF_XML_IN_NODE (GRADIENT_FILL, GRADIENT_STOPS, XL_NS_SS, "stop", GSF_XML_NO_CONTENT, NULL, NULL),
4265
4712
GSF_XML_IN_NODE_FULL (STYLE_INFO, BORDERS, XL_NS_SS, "borders", GSF_XML_NO_CONTENT,
4349
4796
for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
4350
4797
if (attr_gocolor (xin, attrs, "val", &c)) {
4351
g_hash_table_replace (state->theme_colors,
4798
g_hash_table_replace (state->theme_colors_by_name,
4352
4799
g_strdup (((GsfXMLInNode *)xin->node_stack->data)->name),
4353
4800
GUINT_TO_POINTER (c));
4357
xlsx_theme_start (GsfXMLIn *xin, xmlChar const **attrs)
4359
XLSXReadState *state = (XLSXReadState *)xin->user_state;
4360
state->theme_colors = g_hash_table_new_full (g_str_hash, g_str_equal,
4361
(GDestroyNotify)g_free, NULL);
4364
4804
static GsfXMLInNode const xlsx_theme_dtd[] = {
4365
4805
GSF_XML_IN_NODE_FULL (START, START, -1, NULL, GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
4366
GSF_XML_IN_NODE_FULL (START, THEME, XL_NS_DRAW, "theme", GSF_XML_NO_CONTENT, FALSE, TRUE, &xlsx_theme_start, NULL, 0),
4806
GSF_XML_IN_NODE_FULL (START, THEME, XL_NS_DRAW, "theme", GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
4367
4807
GSF_XML_IN_NODE (THEME, ELEMENTS, XL_NS_DRAW, "themeElements", GSF_XML_NO_CONTENT, NULL, NULL),
4368
4808
GSF_XML_IN_NODE (ELEMENTS, COLOR_SCHEME, XL_NS_DRAW, "clrScheme", GSF_XML_NO_CONTENT, NULL, NULL),
4369
4809
GSF_XML_IN_NODE (COLOR_SCHEME, dk1, XL_NS_DRAW, "dk1", GSF_XML_NO_CONTENT, NULL, NULL),
4526
4966
state.num_fmts = g_hash_table_new_full (g_str_hash, g_str_equal,
4527
4967
(GDestroyNotify)g_free, (GDestroyNotify) go_format_unref);
4528
4968
state.convs = xlsx_conventions_new ();
4529
state.theme_colors = NULL;
4969
state.theme_colors_by_name = g_hash_table_new_full (g_str_hash, g_str_equal,
4970
(GDestroyNotify)g_free, NULL);
4531
4972
locale = gnm_push_C_locale ();
4533
4974
if (NULL != (state.zip = gsf_infile_zip_new (input, NULL))) {
4535
GsfInput *wb_part = gsf_open_pkg_get_rel_by_type (GSF_INPUT (state.zip),
4536
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument");
4976
GsfInput *wb_part = gsf_open_pkg_open_rel_by_type (GSF_INPUT (state.zip),
4977
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", NULL);
4538
4979
if (NULL != wb_part) {
4541
in = gsf_open_pkg_get_rel_by_type (wb_part,
4542
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings");
4982
in = gsf_open_pkg_open_rel_by_type (wb_part,
4983
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings", NULL);
4543
4984
xlsx_parse_stream (&state, in, xlsx_shared_strings_dtd);
4545
in = gsf_open_pkg_get_rel_by_type (wb_part,
4546
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles");
4986
in = gsf_open_pkg_open_rel_by_type (wb_part,
4987
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme", NULL);
4988
xlsx_parse_stream (&state, in, xlsx_theme_dtd);
4990
in = gsf_open_pkg_open_rel_by_type (wb_part,
4991
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", NULL);
4547
4992
xlsx_parse_stream (&state, in, xlsx_styles_dtd);
4549
in = gsf_open_pkg_get_rel_by_type (wb_part,
4550
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme");
4551
xlsx_parse_stream (&state, in, xlsx_theme_dtd);
4553
4994
xlsx_parse_stream (&state, wb_part, xlsx_workbook_dtd);
4555
4996
go_cmd_context_error_import (GO_CMD_CONTEXT (context),