~ubuntu-branches/ubuntu/quantal/gnumeric/quantal

« back to all changes in this revision

Viewing changes to plugins/excel/xlsx-read.c

  • Committer: Bazaar Package Importer
  • Author(s): Gauvain Pocentek
  • Date: 2009-06-07 11:10:47 UTC
  • mfrom: (1.1.19 upstream) (2.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090607111047-l3rtbzfjxvmi1kx0
Tags: 1.9.8-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Promoted gnumeric-doc to Recommends in gnumeric package for help to be
    installed automatically
  - gnumeric-gtk is a transitional package
  - gnumeric conflicts with gnumeric-gtk << 1.8.3-3ubuntu1
  - call initltool-update in po*
  - remove psiconv support (psiconv is in universe):
    o debian/control: remove B-D on libpsiconv-dev
    o debian/rules: don't pass --with-psiconv to ./configure

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include "gnm-format.h"
34
34
#include "cell.h"
35
35
#include "position.h"
 
36
#include "str.h"
36
37
#include "expr.h"
37
38
#include "expr-name.h"
38
39
#include "print-info.h"
55
56
#include <goffice/utils/datetime.h>
56
57
#include <goffice/utils/go-units.h>
57
58
#include <goffice/utils/go-marker.h>
 
59
#include <goffice/utils/go-style.h>
 
60
#include <goffice/utils/go-styled-object.h>
58
61
#include <goffice/data/go-data-simple.h>
59
62
 
60
63
#include <goffice/graph/gog-object.h>
61
64
#include <goffice/graph/gog-chart.h>
62
65
#include <goffice/graph/gog-plot.h>
63
66
#include <goffice/graph/gog-series.h>
64
 
#include <goffice/graph/gog-style.h>
65
67
#include <goffice/graph/gog-data-set.h>
66
68
 
67
69
#include <gsf/gsf-libxml.h>
106
108
        XLSXAxisType type;
107
109
        GogObjectPosition compass;
108
110
        GogAxisPosition   cross;
 
111
        char    *cross_id;
109
112
 
110
 
        gboolean deleted;       /* TODO how to use this */
 
113
        gboolean deleted;
111
114
} XLSXAxisInfo;
112
115
 
113
116
typedef struct {
146
149
        GnmStyleBorderType  border_style;
147
150
        GnmColor        *border_color;
148
151
 
 
152
        GHashTable      *theme_colors_by_name;
 
153
 
149
154
        GPtrArray       *collection;    /* utility for the shared collection handlers */
150
155
        unsigned         count;
151
156
        XLSXPanePos      pane_pos;
177
182
        int               dim_type;
178
183
        GogObject        *series_pt;
179
184
        gboolean          series_pt_has_index;
180
 
        GogStyle         *cur_style;
 
185
        GOStyle  *cur_style;
181
186
        GOColor           gocolor;
182
187
        GOMarker         *marker;
183
188
        GOMarkerShape     marker_symbol;
194
199
                XLSXAxisInfo *info;
195
200
        } axis;
196
201
 
197
 
        GHashTable *theme_colors;
 
202
        /* external refs */
 
203
        Workbook *external_ref;
 
204
        Sheet    *external_ref_sheet;
198
205
} XLSXReadState;
199
206
typedef struct {
200
207
        GnmString       *str;
201
208
        GOFormat        *markup;
202
209
} XLSXStr;
203
210
 
204
 
enum {
205
 
        XL_NS_SS,
206
 
        XL_NS_SS_DRAW,
207
 
        XL_NS_CHART,
208
 
        XL_NS_DRAW,
209
 
        XL_NS_DOC_REL,
210
 
        XL_NS_PKG_REL
211
 
};
212
 
 
213
211
static GsfXMLInNS const xlsx_ns[] = {
214
212
        GSF_XML_IN_NS (XL_NS_SS,        "http://schemas.openxmlformats.org/spreadsheetml/2006/main"),             /* Office 12 */
215
213
        GSF_XML_IN_NS (XL_NS_SS,        "http://schemas.openxmlformats.org/spreadsheetml/2006/7/main"),           /* Office 12 BETA-2 Technical Refresh */
252
250
                      GsfXMLInNode const *dtd,
253
251
                      GsfXMLInNS const *ns)
254
252
{
255
 
        GError *err = gsf_open_pkg_parse_rel_by_id (xin, part_id, dtd, ns);
 
253
        GError *err;
 
254
 
 
255
#ifdef DEBUG_PARSER
 
256
        g_print ("{ /* Parsing  : %s :: %s */\n",
 
257
                 gsf_input_name (gsf_xml_in_get_input (xin)), part_id);
 
258
#endif
 
259
 
 
260
        err = gsf_open_pkg_parse_rel_by_id (xin, part_id, dtd, ns);
256
261
        if (NULL != err) {
257
262
                XLSXReadState *state = (XLSXReadState *)xin->user_state;
258
263
                gnm_io_warning (state->context, "%s", err->message);
259
264
                g_error_free (err);
260
265
        }
 
266
 
 
267
#ifdef DEBUG_PARSER
 
268
        g_print ("} /* DONE : %s :: %s */\n",
 
269
                 gsf_input_name (gsf_xml_in_get_input (xin)), part_id);
 
270
#endif
261
271
}
262
272
 
263
273
/****************************************************************************/
463
473
          char const *target,
464
474
          GnmCellPos *res)
465
475
{
 
476
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
466
477
        char const *end;
467
478
        GnmCellPos tmp;
468
479
 
473
484
        if (strcmp (attrs[0], target))
474
485
                return FALSE;
475
486
 
476
 
        end = cellpos_parse (attrs[1], &tmp, TRUE);
 
487
        end = cellpos_parse (attrs[1], gnm_sheet_get_size (state->sheet), &tmp, TRUE);
477
488
        if (NULL == end || *end != '\0')
478
489
                return xlsx_warning (xin,
479
490
                        _("Invalid cell position '%s' for attribute %s"),
487
498
            char const *target,
488
499
            GnmRange *res)
489
500
{
 
501
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
 
502
 
490
503
        g_return_val_if_fail (attrs != NULL, FALSE);
491
504
        g_return_val_if_fail (attrs[0] != NULL, FALSE);
492
505
        g_return_val_if_fail (attrs[1] != NULL, FALSE);
494
507
        if (strcmp (attrs[0], target))
495
508
                return FALSE;
496
509
 
497
 
        if (!range_parse (res, attrs[1]))
 
510
        if (!range_parse (res, attrs[1], gnm_sheet_get_size (state->sheet)))
498
511
                xlsx_warning (xin, _("Invalid range '%s' for attribute %s"),
499
512
                        attrs[1], target);
500
513
        return TRUE;
566
579
        {153, 51,  0}, {153, 51,102}, { 51, 51,153}, { 51, 51, 51}
567
580
};
568
581
 
569
 
static GnmColor *
570
 
indexed_color (gint idx)
 
582
static GOColor
 
583
indexed_color (XLSXReadState *state, gint idx)
571
584
{
572
585
        /* NOTE: not documented but seems close
573
586
         * If you find a normative reference please forward it.
584
597
         */
585
598
 
586
599
        if (idx == 1 || idx == 65)
587
 
                return style_color_white ();
 
600
                return RGBA_WHITE;
588
601
        switch (idx) {
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 ();
 
606
                return RGBA_BLACK;
 
607
 
594
608
        case 1 :  /* white */
595
609
        case 65 : /* system back ? */
596
 
                return style_color_white ();
 
610
                return RGBA_WHITE;
597
611
 
598
612
        case 80 : /* tooltip background */
599
 
                return style_color_new_gdk (&gs_yellow);
600
 
 
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 */
 
613
                return RGBA_YELLOW;
 
614
 
 
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;
 
621
 
607
622
        default :
608
623
                 break;
609
624
        }
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 ();
 
630
                return RGBA_BLACK;
616
631
        }
617
632
 
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);
 
637
}
 
638
static GOColor
 
639
themed_color (GsfXMLIn *xin, gint idx)
 
640
{
 
641
        static char const * const theme_elements [] = {
 
642
                "lt1",  "dk1", "lt2", "dk2",
 
643
                "accent1", "accent2", "accent3", "accent4", "accent5", "accent6",
 
644
                "hlink", "folHlink"
 
645
        };
 
646
        XLSXReadState   *state = (XLSXReadState *)xin->user_state;
 
647
 
 
648
        /* MAGIC :
 
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
 
655
         *
 
656
         * I'll make the assumption we should work by name rather than
 
657
         * index. */
 
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]);
 
661
                if (NULL != color)
 
662
                        return GPOINTER_TO_UINT (color);
 
663
 
 
664
                xlsx_warning (xin, _("Unknown theme color %d"), idx);
 
665
        } else {
 
666
                xlsx_warning (xin, "Color index (%d) is out of range (0..%d). Defaulting to black",
 
667
                              idx, (int) G_N_ELEMENTS (theme_elements));
 
668
        }
 
669
 
 
670
        return RGBA_BLACK;
622
671
}
623
672
 
624
673
static GOFormat *
793
842
static GSList *
794
843
xlsx_parse_sqref (GsfXMLIn *xin, xmlChar const *refs)
795
844
{
 
845
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
796
846
        GnmRange  r;
797
847
        xmlChar const *tmp;
798
848
        GSList   *res = NULL;
799
849
 
800
850
        while (NULL != refs && *refs) {
801
 
                if (NULL == (tmp = cellpos_parse (refs, &r.start, FALSE))) {
 
851
                if (NULL == (tmp = cellpos_parse (refs, gnm_sheet_get_size (state->sheet), &r.start, FALSE))) {
802
852
                        xlsx_warning (xin, "unable to parse reference list '%s'", refs);
803
853
                        return res;
804
854
                }
807
857
                if (*refs == '\0' || *refs == ' ')
808
858
                        r.end = r.start;
809
859
                else if (*refs != ':' ||
810
 
                         NULL == (tmp = cellpos_parse (refs + 1, &r.end, FALSE))) {
 
860
                         NULL == (tmp = cellpos_parse (refs + 1, gnm_sheet_get_size (state->sheet), &r.end, FALSE))) {
811
861
                        xlsx_warning (xin, "unable to parse reference list '%s'", refs);
812
862
                        return res;
813
863
                }
823
873
 
824
874
/***********************************************************************/
825
875
 
 
876
#include "xlsx-read-pivot.c"
 
877
 
 
878
/***********************************************************************/
 
879
/* TO DO MOVE INTO xlsx-read-chart.c */
 
880
 
826
881
static void
827
882
xlsx_chart_push_obj (XLSXReadState *state, GogObject *obj)
828
883
{
951
1006
xlsx_axis_info_free (XLSXAxisInfo *info)
952
1007
{
953
1008
        g_free (info->id);
 
1009
        g_free (info->cross_id);
954
1010
        if (NULL != info->axis)
955
1011
                g_object_unref (info->axis);
956
1012
        g_free (info);
990
1046
xlsx_axis_start (GsfXMLIn *xin, xmlChar const **attrs)
991
1047
{
992
1048
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
993
 
        state->axis.obj  = g_object_new (GOG_AXIS_TYPE, NULL);
 
1049
        state->axis.obj  = g_object_new (GOG_TYPE_AXIS, NULL);
994
1050
        state->axis.type = xin->node->user_data.v_int;
995
1051
        state->axis.info = NULL;
996
1052
        xlsx_chart_push_obj (state, GOG_OBJECT (state->axis.obj));
1018
1074
xlsx_axis_delete (GsfXMLIn *xin, xmlChar const **attrs)
1019
1075
{
1020
1076
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
1021
 
        int del;
 
1077
        int del = 0;
1022
1078
        if (state->axis.info && simple_bool (xin, attrs, &del))
1023
1079
                state->axis.info->deleted = del;
 
1080
        if (state->axis.info && del)
 
1081
                g_object_set (state->axis.info->axis, "invisible", TRUE, NULL);
1024
1082
}
1025
1083
static void
1026
1084
xlsx_axis_orientation (GsfXMLIn *xin, xmlChar const **attrs)
1092
1150
}
1093
1151
 
1094
1152
static void
 
1153
xlsx_axis_crossax (GsfXMLIn *xin, xmlChar const **attrs)
 
1154
{
 
1155
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
 
1156
        if (state->axis.info && !strcmp ((char const*) attrs[0], "val"))
 
1157
                state->axis.info->cross_id = g_strdup (attrs[1]);
 
1158
}
 
1159
 
 
1160
static void
1095
1161
xlsx_chart_gridlines (GsfXMLIn *xin, xmlChar const **attrs)
1096
1162
{
1097
1163
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
1296
1362
{
1297
1363
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
1298
1364
        if (NULL != state->cur_obj &&
1299
 
            IS_GOG_STYLED_OBJECT (state->cur_obj) &&
 
1365
            GOG_IS_STYLED_OBJECT (state->cur_obj) &&
1300
1366
            NULL == state->marker) {
1301
1367
                g_return_if_fail (state->cur_style == NULL);
1302
 
                state->cur_style = gog_style_dup (
1303
 
                        gog_styled_object_get_style (GOG_STYLED_OBJECT (state->cur_obj)));
 
1368
                state->cur_style = go_style_dup (
 
1369
                        go_styled_object_get_style (GO_STYLED_OBJECT (state->cur_obj)));
1304
1370
        }
1305
1371
}
1306
1372
static void
1309
1375
        XLSXReadState   *state = (XLSXReadState *)xin->user_state;
1310
1376
 
1311
1377
        if (NULL != state->cur_style) {
1312
 
                gog_styled_object_set_style (GOG_STYLED_OBJECT (state->cur_obj),
 
1378
                go_styled_object_set_style (GO_STYLED_OBJECT (state->cur_obj),
1313
1379
                        state->cur_style);
1314
1380
                g_object_unref (state->cur_style);
1315
1381
                state->cur_style = NULL;
1319
1385
xlsx_style_line_start (GsfXMLIn *xin, xmlChar const **attrs)
1320
1386
{
1321
1387
        XLSXReadState   *state = (XLSXReadState *)xin->user_state;
1322
 
        state->sp_type |= GOG_STYLE_LINE;
 
1388
        state->sp_type |= GO_STYLE_LINE;
1323
1389
}
1324
1390
 
1325
1391
static void
1326
1392
xlsx_style_line_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
1327
1393
{
1328
1394
        XLSXReadState   *state = (XLSXReadState *)xin->user_state;
1329
 
        state->sp_type &= ~GOG_STYLE_LINE;
 
1395
        state->sp_type &= ~GO_STYLE_LINE;
1330
1396
}
1331
1397
 
1332
1398
static void
1336
1402
        if (NULL != state->marker)
1337
1403
                ;
1338
1404
        else if (NULL != state->cur_style) {
1339
 
                if (!(state->sp_type & GOG_STYLE_LINE)) {
1340
 
                        state->cur_style->fill.type = GOG_FILL_STYLE_NONE;
 
1405
                if (!(state->sp_type & GO_STYLE_LINE)) {
 
1406
                        state->cur_style->fill.type = GO_STYLE_FILL_NONE;
1341
1407
                        state->cur_style->fill.auto_type = FALSE;
1342
1408
                }
1343
1409
        }
1349
1415
        if (NULL != state->marker)
1350
1416
                ;
1351
1417
        else if (NULL != state->cur_style) {
1352
 
                if (!(state->sp_type & GOG_STYLE_LINE)) {
1353
 
                        state->cur_style->fill.type = GOG_FILL_STYLE_PATTERN;
 
1418
                if (!(state->sp_type & GO_STYLE_LINE)) {
 
1419
                        state->cur_style->fill.type = GO_STYLE_FILL_PATTERN;
1354
1420
                        state->cur_style->fill.auto_type = FALSE;
1355
1421
                }
1356
1422
        }
1359
1425
static void
1360
1426
xlsx_draw_color_themed (GsfXMLIn *xin, xmlChar const **attrs)
1361
1427
{
 
1428
#if 0
1362
1429
        static EnumVal const colors[] = {
1363
1430
                { "bg1",         0 }, /* Background Color 1 */
1364
1431
                { "tx1",         1 }, /* Text Color 1 */
1379
1446
                { "lt2",        16 }, /* Light Color 2 */
1380
1447
                { NULL, 0 }
1381
1448
        };
 
1449
#endif
1382
1450
 
1383
1451
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
1384
1452
        gpointer val = NULL;
1385
 
        if (NULL != state->theme_colors) {
1386
 
                for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
1387
 
                        if (0 == strcmp (attrs[0], "val")) {
1388
 
                                val = g_hash_table_lookup (state->theme_colors, attrs[1]);
1389
 
                                if (NULL == val)
1390
 
                                        xlsx_warning (xin, _("Unknown color '%s'"), attrs[1]);
1391
 
                        }
1392
 
        } else
1393
 
                xlsx_warning (xin, _("Missing theme"));
 
1453
        for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
 
1454
                if (0 == strcmp (attrs[0], "val")) {
 
1455
                        val = g_hash_table_lookup (state->theme_colors_by_name, attrs[1]);
 
1456
                        if (NULL == val)
 
1457
                                xlsx_warning (xin, _("Unknown color '%s'"), attrs[1]);
 
1458
                }
1394
1459
 
1395
1460
        state->gocolor = GPOINTER_TO_UINT (val);
1396
1461
}
1424
1489
        if (NULL != state->marker)
1425
1490
                go_marker_set_fill_color (state->marker, state->gocolor);
1426
1491
        else if (NULL != state->cur_style) {
1427
 
                if (state->sp_type & GOG_STYLE_LINE) {
 
1492
                if (state->sp_type & GO_STYLE_LINE) {
1428
1493
                        state->cur_style->line.color = state->gocolor;
1429
1494
                        state->cur_style->line.auto_color = FALSE;
1430
1495
                } else {
1462
1527
        if (NULL != state->marker)
1463
1528
                ; /* what goes here ?*/
1464
1529
        else if (NULL != state->cur_style) {
1465
 
                if (state->sp_type & GOG_STYLE_LINE) {
 
1530
                if (state->sp_type & GO_STYLE_LINE) {
1466
1531
                        state->cur_style->line.auto_dash = FALSE;
1467
1532
                        state->cur_style->line.dash_type = dash;
1468
1533
                        state->cur_style->outline.auto_dash = FALSE;
1507
1572
xlsx_chart_marker_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
1508
1573
{
1509
1574
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
1510
 
        if (NULL != state->cur_obj && IS_GOG_STYLED_OBJECT (state->cur_obj)) {
1511
 
                GogStyle *style = gog_styled_object_get_style (
1512
 
                        GOG_STYLED_OBJECT (state->cur_obj));
 
1575
        if (NULL != state->cur_obj && GOG_IS_STYLED_OBJECT (state->cur_obj)) {
 
1576
                GOStyle *style = go_styled_object_get_style (
 
1577
                        GO_STYLED_OBJECT (state->cur_obj));
1513
1578
                if (state->marker_symbol != GO_MARKER_MAX) {
1514
1579
                        style->marker.auto_shape = FALSE;
1515
1580
                        go_marker_set_shape (state->marker, state->marker_symbol);
1516
1581
                }
1517
 
                gog_style_set_marker (style, state->marker);
 
1582
                go_style_set_marker (style, state->marker);
1518
1583
                state->marker = NULL;
1519
1584
        }
1520
1585
}
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),
1653
1718
 
1654
1719
        GSF_XML_IN_NODE (CAT_AXIS, CAT_AXIS_LBLALGN, XL_NS_CHART, "lblAlgn", GSF_XML_NO_CONTENT, NULL, NULL),
1905
1970
 
1906
1971
static void
1907
1972
cb_axis_set_position (GObject *axis, XLSXAxisInfo *info,
1908
 
                      G_GNUC_UNUSED gpointer accum)
 
1973
                      XLSXReadState *state)
1909
1974
{
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;
 
1978
 
 
1979
                for (cur = l; cur; cur = cur->next) {
 
1980
                        gboolean invisible;
 
1981
                        g_object_get (cur->data, "invisible", &invisible, NULL);
 
1982
                        if (!invisible) {
 
1983
                                visible = GOG_AXIS (cur->data);
 
1984
                                break;
 
1985
                        }
 
1986
                }
 
1987
                if (visible) {
 
1988
                        GSList *l1, *cur1;
 
1989
 
 
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);
 
1994
                        }
 
1995
                        g_slist_free (l1);
 
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);
 
2003
                        }
 
2004
                        g_slist_free (l1);
 
2005
                }
 
2006
        } else {
 
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);
 
2010
        }
1911
2011
}
1912
2012
 
1913
2013
static void
1918
2018
        /* clean out axis that were auto created */
1919
2019
        list = gog_object_get_children (GOG_OBJECT (state->chart), NULL);
1920
2020
        for (ptr = list; ptr != NULL ; ptr = ptr->next)
1921
 
                if (IS_GOG_AXIS (ptr->data) &&
 
2021
                if (GOG_IS_AXIS (ptr->data) &&
1922
2022
                    NULL == g_hash_table_lookup (state->axis.by_obj, ptr->data)) {
1923
2023
                        if (gog_object_is_deletable (GOG_OBJECT (ptr->data))) {
1924
2024
                                gog_object_clear_parent (GOG_OBJECT (ptr->data));
1928
2028
        g_slist_free (list);
1929
2029
 
1930
2030
        g_hash_table_foreach (state->axis.by_obj,
1931
 
                (GHFunc)cb_axis_set_position, NULL);
 
2031
                (GHFunc)cb_axis_set_position, state);
1932
2032
        g_hash_table_destroy (state->axis.by_obj);
1933
2033
        g_hash_table_destroy (state->axis.by_id);
1934
2034
        state->axis.by_obj = state->axis.by_id = NULL;
2121
2221
 
2122
2222
/***********************************************************************/
2123
2223
 
 
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 */ 
 
2228
 
 
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)
 
2233
 
 
2234
/* utility routine for HLStoRGB */ 
 
2235
static int
 
2236
hue_to_color (int m1, int m2, int h)
 
2237
{
 
2238
        if (h < 0)
 
2239
                h += HLSMAX;
 
2240
        if (h > HLSMAX)
 
2241
                h -= HLSMAX;
 
2242
 
 
2243
        /* return r,g, or b value from this tridrant */ 
 
2244
        if (h < (HLSMAX/6))
 
2245
                return m1 + (((m2 - m1)*h + (HLSMAX/12))/(HLSMAX/6));
 
2246
        if (h < (HLSMAX/2))
 
2247
                return m2;
 
2248
        if (h < ((HLSMAX*2)/3))
 
2249
                return m1 + (((m2 - m1)*(((HLSMAX*2)/3)-h)+(HLSMAX/12))/(HLSMAX/6));
 
2250
 
 
2251
        return m1;
 
2252
}
 
2253
 
 
2254
static GOColor
 
2255
apply_tint (GOColor orig, float tint)
 
2256
{
 
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;
 
2262
 
 
2263
        if (fabs (tint) < .005)
 
2264
                return orig;
 
2265
 
 
2266
        maxC = MAX (MAX (r,g),b);
 
2267
        minC = MIN (MIN (r,g),b);
 
2268
        l = (((maxC + minC)*HLSMAX) + RGBMAX)/(2*RGBMAX);
 
2269
 
 
2270
        delta = maxC - minC;
 
2271
        sum   = maxC + minC;
 
2272
        if (delta != 0) {
 
2273
                if (l <= (HLSMAX/2))
 
2274
                        s = ( (delta*HLSMAX) + (sum/2) ) / sum;
 
2275
                else
 
2276
                        s = ( (delta*HLSMAX) + ((2*RGBMAX - sum)/2) ) / (2*RGBMAX - sum);
 
2277
 
 
2278
                if (r == maxC)
 
2279
                        h =                ((g - b) * HLSMAX) / (6 * delta);
 
2280
                else if (g == maxC)
 
2281
                        h = (  HLSMAX/3) + ((b - r) * HLSMAX) / (6 * delta);
 
2282
                else if (b == maxC)
 
2283
                        h = (2*HLSMAX/3) + ((r - g) * HLSMAX) / (6 * delta);
 
2284
 
 
2285
                if (h < 0)
 
2286
                        h += HLSMAX;
 
2287
                else if (h >= HLSMAX)
 
2288
                        h -= HLSMAX;
 
2289
        } else {
 
2290
                h = 0;
 
2291
                s = 0;
 
2292
        }
 
2293
 
 
2294
        if (tint < 0.)
 
2295
                l = l * (1. + tint);
 
2296
        else
 
2297
                l = l * (1. - tint) + (HLSMAX - HLSMAX * (1.0 - tint));
 
2298
 
 
2299
        if (s == 0) {            /* achromatic case */ 
 
2300
                r = (l * RGBMAX) / HLSMAX;
 
2301
                return RGBA_TO_UINT(r, r, r, a);
 
2302
        }
 
2303
 
 
2304
        if (l <= (HLSMAX/2))
 
2305
                m2 = (l*(HLSMAX + s) + (HLSMAX/2))/HLSMAX;
 
2306
        else
 
2307
                m2 = l + s - ((l*s) + (HLSMAX/2))/HLSMAX;
 
2308
        m1 = 2*l - m2;
 
2309
 
 
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;
 
2313
 
 
2314
        return RGBA_TO_UINT(r,g,b,a);
 
2315
}
 
2316
                                
2124
2317
static GnmColor *
2125
2318
elem_color (GsfXMLIn *xin, xmlChar const **attrs)
2126
2319
{
 
2320
        XLSXReadState   *state = (XLSXReadState *)xin->user_state;
2127
2321
        int indx;
2128
 
        guint a, r, g, b;
 
2322
        GOColor c;
 
2323
        double tint = 0.;
 
2324
        gboolean has_color = FALSE;
2129
2325
 
2130
2326
        for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2) {
2131
2327
                if (0 == strcmp (attrs[0], "rgb")) {
 
2328
                        guint a, r, g, b;
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"),
2135
2332
                                        attrs[1]);
2136
2333
                                return NULL;
2137
2334
                        }
2138
 
 
2139
 
                        return style_color_new_i8 (r, g, b);
2140
 
                } else if (attr_int (xin, attrs, "indexed", &indx))
2141
 
                        return indexed_color (indx);
2142
 
#if 0
2143
 
        "type"  opt rgb {auto, icv, rgb, theme }
2144
 
        "val"   opt ??
2145
 
        "tint"  opt 0.
2146
 
#endif
 
2335
                        has_color = TRUE;
 
2336
                        c = RGBA_TO_UINT(r,g,b,a);
 
2337
                } else if (attr_int (xin, attrs, "indexed", &indx)) {
 
2338
                        has_color = TRUE;
 
2339
                        c = indexed_color (state, indx);
 
2340
                } else if (attr_int (xin, attrs, "theme", &indx)) {
 
2341
                        has_color = TRUE;
 
2342
                        c = themed_color (xin, indx);
 
2343
                } else if (attr_float (xin, attrs, "tint", &tint))
 
2344
                        tint = CLAMP (tint, -1., 1.);
2147
2345
        }
 
2346
 
 
2347
        if (!has_color)
 
2348
                return NULL;
 
2349
        c = apply_tint (c, tint);
 
2350
        return style_color_new_go (c);
 
2351
}
 
2352
 
 
2353
static GnmStyle *
 
2354
xlsx_get_style_xf (GsfXMLIn *xin, int xf)
 
2355
{
 
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);
2148
2360
        return NULL;
2149
2361
}
2150
 
 
2151
2362
static GnmStyle *
2152
2363
xlsx_get_xf (GsfXMLIn *xin, int xf)
2153
2364
{
2450
2661
}
2451
2662
 
2452
2663
static void
 
2664
xlsx_CT_SheetPr (GsfXMLIn *xin, xmlChar const **attrs)
 
2665
{
 
2666
#if 0
 
2667
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
 
2668
    <xsd:attribute name="syncHorizontal" type="xsd:boolean" use="optional" default="false">
 
2669
    <xsd:attribute name="syncVertical" type="xsd:boolean" use="optional" default="false">
 
2670
    <xsd:attribute name="syncRef" type="ST_Ref" use="optional">
 
2671
    <xsd:attribute name="transitionEvaluation" type="xsd:boolean" use="optional" default="false">
 
2672
    <xsd:attribute name="transitionEntry" type="xsd:boolean" use="optional" default="false">
 
2673
    <xsd:attribute name="published" type="xsd:boolean" use="optional" default="true">
 
2674
    <xsd:attribute name="codeName" type="xsd:string" use="optional">
 
2675
    <xsd:attribute name="filterMode" type="xsd:boolean" use="optional" default="false">
 
2676
    <xsd:attribute name="enableFormatConditionsCalculation" type="xsd:boolean" use="optional" default="true">
 
2677
#endif
 
2678
}
 
2679
 
 
2680
static void
2453
2681
xlsx_sheet_tabcolor (GsfXMLIn *xin, xmlChar const **attrs)
2454
2682
{
2455
2683
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
2557
2785
                else if (attr_int  (xin, attrs, "manualBreakCount", &manual_count)) ;
2558
2786
#endif
2559
2787
 
2560
 
        state->page_breaks = gnm_page_breaks_new (count,
2561
 
                xin->node->user_data.v_int);
 
2788
        state->page_breaks = gnm_page_breaks_new (xin->node->user_data.v_int);
2562
2789
}
2563
2790
 
2564
2791
static void
3285
3512
 
3286
3513
        if (!defaultGridColor && grid_color_index >= 0)
3287
3514
                sheet_style_set_auto_pattern_color (state->sheet,
3288
 
                        indexed_color (grid_color_index));
 
3515
                        style_color_new_go (indexed_color (state, grid_color_index)));
3289
3516
        if (tabSelected)
3290
3517
                wb_view_sheet_focus (state->wb_view, state->sheet);
3291
3518
}
3330
3557
                return;
3331
3558
 
3332
3559
        for (i = 0 ; NULL != refs && *refs ; i++) {
3333
 
                if (NULL == (refs = cellpos_parse (refs, &r.start, FALSE)))
 
3560
                if (NULL == (refs = cellpos_parse (refs, gnm_sheet_get_size (state->sheet), &r.start, FALSE)))
3334
3561
                        return;
3335
3562
 
3336
3563
                if (*refs == '\0' || *refs == ' ')
3337
3564
                        r.end = r.start;
3338
3565
                else if (*refs != ':' ||
3339
 
                         NULL == (refs = cellpos_parse (refs + 1, &r.end, FALSE)))
 
3566
                         NULL == (refs = cellpos_parse (refs + 1, gnm_sheet_get_size (state->sheet), &r.end, FALSE)))
3340
3567
                        return;
3341
3568
 
3342
3569
                if (i == 0)
3362
3589
                g_slist_free (accum);
3363
3590
        }
3364
3591
}
 
3592
 
 
3593
static void
 
3594
xlsx_CT_PivotSelection (GsfXMLIn *xin, xmlChar const **attrs)
 
3595
{
 
3596
#if 0
 
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">
 
3615
#endif
 
3616
}
 
3617
 
 
3618
static void
 
3619
xlsx_CT_PivotArea (GsfXMLIn *xin, xmlChar const **attrs)
 
3620
{
 
3621
#if 0
 
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">
 
3635
#endif
 
3636
}
 
3637
static void
 
3638
xlsx_CT_PivotAreaReferences (GsfXMLIn *xin, xmlChar const **attrs)
 
3639
{
 
3640
#if 0
 
3641
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
 
3642
#endif
 
3643
}
 
3644
static void
 
3645
xlsx_CT_PivotAreaReference (GsfXMLIn *xin, xmlChar const **attrs)
 
3646
{
 
3647
#if 0
 
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">
 
3666
#endif
 
3667
}
 
3668
 
3365
3669
static void
3366
3670
xlsx_CT_Pane (GsfXMLIn *xin, xmlChar const **attrs)
3367
3671
{
3475
3779
        sheet_style_apply_range (state->sheet, &r, style);
3476
3780
}
3477
3781
 
3478
 
static GsfXMLInNode const xlsx_sheet_dtd[] =
3479
 
{
 
3782
#ifdef HAVE_GSF_OPEN_PKG_FOREACH_REL
 
3783
static void
 
3784
cb_find_pivots (GsfInput *opkg, GsfOpenPkgRel const *rel, gpointer    user_data)
 
3785
{
 
3786
        XLSXReadState *state = user_data;
 
3787
        GsfInput *part_stream;
 
3788
        char const *t = gsf_open_pkg_rel_get_type (rel);
 
3789
 
 
3790
        if (NULL != t &&
 
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);
 
3794
}
 
3795
#endif
 
3796
 
 
3797
static void
 
3798
xlsx_CT_worksheet (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 
3799
{
 
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);
 
3803
#endif
 
3804
}
 
3805
 
 
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),
3491
3822
 
3492
3823
  GSF_XML_IN_NODE (SHEET, DEFAULT_FMT, XL_NS_SS, "sheetFormatPr", GSF_XML_NO_CONTENT, &xlsx_CT_SheetFormatPr, NULL),
3493
3824
 
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),
3502
3833
 
 
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),
3505
3841
 
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),
3571
3907
/****************************************************************************/
3572
3908
 
3573
3909
static void
 
3910
xlsx_CT_PivotCache (GsfXMLIn *xin, xmlChar const **attrs)
 
3911
{
 
3912
        /*XLSXReadState *state = (XLSXReadState *)xin->user_state; */
 
3913
        for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
 
3914
                if (gsf_xml_in_namecmp (xin, attrs[0], XL_NS_DOC_REL, "id"))
 
3915
                        xlsx_parse_rel_by_id (xin, attrs[1],
 
3916
                                xlsx_pivot_cache_def_dtd, xlsx_ns);
 
3917
}
 
3918
 
 
3919
static void
3574
3920
xlsx_CT_CalcPr (GsfXMLIn *xin, xmlChar const **attrs)
3575
3921
{
3576
3922
        static EnumVal const calcModes[] = {
3636
3982
 
3637
3983
        sheet =  workbook_sheet_by_name (state->wb, name);
3638
3984
        if (NULL == sheet) {
3639
 
                sheet = sheet_new (state->wb, name);
 
3985
                sheet = sheet_new (state->wb, name, 256, 65536);  /* FIXME! */
3640
3986
                workbook_sheet_attach (state->wb, sheet);
3641
3987
        }
3642
3988
 
3644
3990
                        (GDestroyNotify) g_free);
3645
3991
}
3646
3992
 
 
3993
/**************************************************************************************************/
 
3994
 
 
3995
static void
 
3996
xlsx_read_external_book (GsfXMLIn *xin, xmlChar const **attrs)
 
3997
{
 
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));
 
4005
}
 
4006
static void
 
4007
xlsx_read_external_book_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 
4008
{
 
4009
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
 
4010
        state->external_ref = NULL;
 
4011
}
 
4012
static void
 
4013
xlsx_read_external_sheetname (GsfXMLIn *xin, xmlChar const **attrs)
 
4014
{
 
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));
 
4020
}
 
4021
static void
 
4022
xlsx_read_external_sheetname_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 
4023
{
 
4024
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
 
4025
        state->external_ref_sheet = NULL;
 
4026
}
 
4027
 
 
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),
 
4039
 
 
4040
GSF_XML_IN_NODE_END
 
4041
};
 
4042
 
 
4043
static void
 
4044
xlsx_wb_external_ref (GsfXMLIn *xin, xmlChar const **attrs)
 
4045
{
 
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);
 
4049
}
 
4050
 
 
4051
/**************************************************************************************************/
 
4052
 
3647
4053
static void
3648
4054
xlsx_wb_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
3649
4055
{
3667
4073
                if (NULL != (style = g_hash_table_lookup(state->cell_styles, "0"))) {
3668
4074
                        GnmRange r;
3669
4075
                        gnm_style_ref (style);
3670
 
                        sheet_style_set_range (state->sheet,
3671
 
                                range_init_full_sheet (&r), style);
 
4076
                        range_init_full_sheet (&r, state->sheet);
 
4077
                        sheet_style_set_range (state->sheet, &r, style);
3672
4078
                }
3673
4079
 
3674
4080
                xlsx_parse_rel_by_id (xin, part_id, xlsx_sheet_dtd, xlsx_ns);
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),
 
4093
 
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),
 
4099
 
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),
 
4111
 
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),
3697
4119
 
3698
4120
GSF_XML_IN_NODE_END
3699
4121
};
3909
4331
{
3910
4332
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
3911
4333
        GnmColor *color = elem_color (xin, attrs);
3912
 
 
3913
4334
        if (NULL != color)
3914
4335
                gnm_style_set_font_color (state->style_accum, color);
3915
4336
}
3993
4414
                        gnm_style_set_pattern (state->style_accum, val);
3994
4415
}
3995
4416
static void
3996
 
xlsx_pattern_fg (GsfXMLIn *xin, xmlChar const **attrs)
 
4417
xlsx_pattern_fg_bg (GsfXMLIn *xin, xmlChar const **attrs)
3997
4418
{
3998
4419
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
 
4420
        /* MAGIC :
 
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);
 
4427
        if (NULL == color)
 
4428
                return;
4000
4429
 
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);
4005
 
                else
4006
 
                        gnm_style_set_pattern_color (state->style_accum, color);
4007
 
        }
 
4430
        if (xin->node->user_data.v_int ^ invert)
 
4431
                gnm_style_set_back_color (state->style_accum, color);
 
4432
        else
 
4433
                gnm_style_set_pattern_color (state->style_accum, color);
4008
4434
}
 
4435
 
4009
4436
static void
4010
 
xlsx_pattern_bg (GsfXMLIn *xin, xmlChar const **attrs)
 
4437
xlsx_CT_GradientFill (GsfXMLIn *xin, xmlChar const **attrs)
4011
4438
{
 
4439
#if 0
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);
4018
 
                else
4019
 
                        gnm_style_set_pattern_color (state->style_accum, color);
4020
 
        }
 
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">
 
4447
#endif
4021
4448
}
4022
4449
 
4023
4450
static void
4054
4481
xlsx_border_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
4055
4482
{
4056
4483
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
 
4484
        GnmBorder *border;
4057
4485
        GnmStyleBorderLocation const loc = xin->node->user_data.v_int;
4058
 
        GnmBorder *border = gnm_style_border_fetch (state->border_style,
 
4486
       
 
4487
        if (NULL == state->border_color)
 
4488
                state->border_color = style_color_black ();
 
4489
        border = gnm_style_border_fetch (state->border_style,
4059
4490
                state->border_color, gnm_style_border_get_orientation (loc));
4060
4491
        gnm_style_set_border (state->style_accum,
4061
4492
                GNM_STYLE_BORDER_LOCATION_TO_STYLE_ELEMENT (loc),
4076
4507
xlsx_xf_begin (GsfXMLIn *xin, xmlChar const **attrs)
4077
4508
{
4078
4509
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
4079
 
        GnmStyle *style = gnm_style_new_default ();
 
4510
        GnmStyle *accum = gnm_style_new ();
 
4511
        GnmStyle *parent = NULL;
 
4512
        GnmStyle *result;
4080
4513
        GPtrArray *elem = NULL;
4081
4514
        int indx;
4082
4515
 
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);
4094
4529
 
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);
4102
 
                                style = merged;
 
4533
                                component = g_ptr_array_index (elem, indx);
 
4534
                        if (NULL != component) {
 
4535
#if 0
 
4536
                                gnm_style_merge (accum, component);
 
4537
#else
 
4538
                                GnmStyle *merged = gnm_style_new_merged (accum, component);
 
4539
                                gnm_style_unref (accum);
 
4540
                                accum = merged;
 
4541
#endif
4103
4542
                        } else
4104
 
                                xlsx_warning (xin, _("Missing record '%d'"), indx);
 
4543
                                xlsx_warning (xin, "Missing record '%d' for %s", indx, attrs[0]);
4105
4544
                        elem = NULL;
4106
4545
                }
4107
4546
        }
4108
 
        state->style_accum = style;
 
4547
        if (NULL == parent) {
 
4548
                result = gnm_style_new_default ();
 
4549
                gnm_style_merge (result, accum);
 
4550
        } else
 
4551
                result = gnm_style_new_merged (parent, accum);
 
4552
        gnm_style_unref (accum);
 
4553
 
 
4554
        state->style_accum = result;
4109
4555
#if 0
4110
 
                "xfId"                  parent style ??
4111
4556
                "quotePrefix"                   ??
4112
4557
 
4113
4558
                "applyNumberFormat"
4199
4644
        /* cellStyle name="Normal" xfId="0" builtinId="0" */
4200
4645
        for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
4201
4646
                if (attr_int (xin, attrs, "xfId", &tmp))
4202
 
                        style = xlsx_get_xf (xin, tmp);
 
4647
                        style = xlsx_get_style_xf (xin, tmp);
4203
4648
                else if (0 == strcmp (attrs[0], "name"))
4204
4649
                        name = attrs[1];
4205
4650
                else if (0 == strcmp (attrs[0], "builtinId"))
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),
4264
4711
 
4265
4712
  GSF_XML_IN_NODE_FULL (STYLE_INFO, BORDERS, XL_NS_SS, "borders", GSF_XML_NO_CONTENT,
4336
4783
        GOColor c;
4337
4784
        for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
4338
4785
                if (attr_gocolor (xin, attrs, "lastClr", &c)) {
4339
 
                        g_hash_table_replace (state->theme_colors,
 
4786
                        g_hash_table_replace (state->theme_colors_by_name,
4340
4787
                                g_strdup (((GsfXMLInNode *)xin->node_stack->data)->name),
4341
4788
                                GUINT_TO_POINTER (c));
4342
4789
                }
4348
4795
        GOColor c;
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));
4354
4801
                }
4355
4802
}
4356
 
static void
4357
 
xlsx_theme_start (GsfXMLIn *xin, xmlChar const **attrs)
4358
 
{
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);
4362
 
}
4363
4803
 
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);
4530
4971
 
4531
4972
        locale = gnm_push_C_locale ();
4532
4973
 
4533
4974
        if (NULL != (state.zip = gsf_infile_zip_new (input, NULL))) {
4534
4975
                /* optional */
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);
4537
4978
 
4538
4979
                if (NULL != wb_part) {
4539
4980
                        GsfInput *in;
4540
4981
 
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);
4544
4985
 
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);
 
4989
 
 
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);
4548
4993
 
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);
4552
 
 
4553
4994
                        xlsx_parse_stream (&state, wb_part, xlsx_workbook_dtd);
4554
4995
                } else
4555
4996
                        go_cmd_context_error_import (GO_CMD_CONTEXT (context),
4581
5022
        xlsx_style_array_free (state.style_xfs);
4582
5023
        xlsx_style_array_free (state.dxfs);
4583
5024
        xlsx_style_array_free (state.table_styles);
4584
 
        if (state.theme_colors)
4585
 
                g_hash_table_destroy (state.theme_colors);
 
5025
        g_hash_table_destroy (state.theme_colors_by_name);
4586
5026
 
4587
5027
        workbook_set_saveinfo (state.wb, FILE_FL_AUTO,
4588
5028
                go_file_saver_for_id ("Gnumeric_Excel:xlsx"));
4594
5034
 *      - column widths : Don't use hard coded font size
4595
5035
 *      - share colours
4596
5036
 *      - conditional formats
4597
 
 *              : why do we need to flip fg and bg for solid in xf but not for dxf
4598
5037
 *              : other condition types
4599
5038
 *              : check binary operators
4600
5039
 *