[gnumeric] xlsx: handle zorder when reading legacy objects.



commit 9b07fa2339414fea5cea52c59d031e3418965a5e
Author: Morten Welinder <terra gnome org>
Date:   Mon Feb 23 13:18:03 2015 -0500

    xlsx: handle zorder when reading legacy objects.

 plugins/excel/xlsx-read-drawing.c |   17 ++++++++++++-----
 plugins/excel/xlsx-read.c         |   30 ++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 5 deletions(-)
---
diff --git a/plugins/excel/xlsx-read-drawing.c b/plugins/excel/xlsx-read-drawing.c
index 88f74d3..07f1404 100644
--- a/plugins/excel/xlsx-read-drawing.c
+++ b/plugins/excel/xlsx-read-drawing.c
@@ -3293,7 +3293,7 @@ xlsx_vml_group (GsfXMLIn *xin, xmlChar const **attrs)
 {
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
        char **elts, **cur, *key, *value, *end;
-       double coords[4], local_coords[4], *cur_offs, dim;
+       double coords[4], local_coords[4], *cur_offs;
        int i;
        for (i = 0; i < 4; i++)
                coords[i] = local_coords[i] = 0.;
@@ -3313,22 +3313,22 @@ xlsx_vml_group (GsfXMLIn *xin, xmlChar const **attrs)
                                /* for now we get only left, top, width and height, assuming they are in 
pixels */
                                /* FIXME: scaling just like in xlsx_CT_Col */
                                if (!strcmp (key, "margin-left") || !strcmp (key, "left")) {
-                                       dim = g_ascii_strtod (value, &end);
+                                       double dim = g_ascii_strtod (value, &end);
                                        if (!strcmp (end, "pt"))
                                                dim *= 4./3.;
                                        coords[0] = (double) dim * XLSX_SHEET_HSCALE;
                                } else if (!strcmp (key, "margin-top") || !strcmp (key, "top")) {
-                                       dim = g_ascii_strtod (value, &end);
+                                       double dim = g_ascii_strtod (value, &end);
                                        if (!strcmp (end, "pt"))
                                                dim *= 4./3.;
                                        coords[1] = dim;
                                } else if (!strcmp (key, "width")) {
-                                       dim = g_ascii_strtod (value, &end);
+                                       double dim = g_ascii_strtod (value, &end);
                                        if (!strcmp (end, "pt"))
                                                dim *= 4./3.;
                                        coords[2] = (double) dim * XLSX_SHEET_HSCALE;
                                } else if (!strcmp (key, "height")) {
-                                       dim = g_ascii_strtod (value, &end);
+                                       double dim = g_ascii_strtod (value, &end);
                                        if (!strcmp (end, "pt"))
                                                dim *= 4./3.;
                                        coords[3] = dim;
@@ -3377,6 +3377,7 @@ static void
 xlsx_vml_shape (GsfXMLIn *xin, xmlChar const **attrs)
 {
        XLSXReadState *state = (XLSXReadState *)xin->user_state;
+       int z = -1;
 
        xlsx_reset_chart_pos (state);
 
@@ -3409,6 +3410,8 @@ xlsx_vml_shape (GsfXMLIn *xin, xmlChar const **attrs)
                                } else if (!strcmp (key, "height")) {
                                        dim = g_ascii_strtod (value, &end);
                                        state->chart_pos[3] = dim;
+                               } else if (!strcmp (key, "z-index")) {
+                                       z = strtol (value, &end, 10);
                                }
                        }
                        g_strfreev (elts);
@@ -3422,6 +3425,8 @@ xlsx_vml_shape (GsfXMLIn *xin, xmlChar const **attrs)
                        state->chart_pos[3] += state->chart_pos[1];
                }
        }
+
+       state->zindex = z;
 }
 
 static void
@@ -3504,6 +3509,8 @@ xlsx_vml_client_data_start (GsfXMLIn *xin, xmlChar const **attrs)
                state->so = SHEET_OBJECT (g_object_new (typ, NULL));
                state->so_direction = GOD_ANCHOR_DIR_DOWN_RIGHT;
                state->pending_objects = g_slist_prepend (state->pending_objects, state->so);
+               if (state->zindex >= 1)
+                       g_hash_table_insert (state->zorder, state->so, GINT_TO_POINTER (state->zindex));
        }
 }
 
diff --git a/plugins/excel/xlsx-read.c b/plugins/excel/xlsx-read.c
index e270966..f79e85a 100644
--- a/plugins/excel/xlsx-read.c
+++ b/plugins/excel/xlsx-read.c
@@ -224,6 +224,7 @@ typedef struct {
        gboolean          chart_pos_mode[4]; /* false: "factor", true: "edge" */
        gboolean          chart_pos_target; /* true if "inner" */
        int               radio_value;
+       int               zindex;
 
        struct {
                GogAxis *obj;
@@ -238,6 +239,7 @@ typedef struct {
        GList *delayed_names;
 
        GSList *pending_objects;
+       GHashTable *zorder;
 
        /* external refs */
                Workbook *external_ref;
@@ -3891,6 +3893,16 @@ GSF_XML_IN_NODE_END
 
 /**************************************************************************************************/
 
+static gint
+cb_by_zorder (gconstpointer a, gconstpointer b, gpointer data)
+{
+       GHashTable *zorder = data;
+       int za = GPOINTER_TO_UINT (g_hash_table_lookup (zorder, a));
+       int zb = GPOINTER_TO_UINT (g_hash_table_lookup (zorder, b));
+       return zb - za; /* descending */
+}
+
+
 static void
 xlsx_wb_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 {
@@ -3907,6 +3919,8 @@ xlsx_wb_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
         * all of them and parse names */
        for (i = 0 ; i < n ; i++, state->sheet = NULL) {
                char *message;
+               int j, zoffset;
+               GSList *l;
 
                if (NULL == (state->sheet = workbook_sheet_by_index (state->wb, i)))
                        continue;
@@ -3950,6 +3964,20 @@ xlsx_wb_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
                        end_update_progress (state);
                }
 
+               zoffset = (g_slist_length (state->pending_objects) -
+                          g_hash_table_size (state->zorder));
+               for (j = zoffset, l = state->pending_objects; l; l = l->next) {
+                       SheetObject *so = l->data;
+                       int z = GPOINTER_TO_UINT (g_hash_table_lookup (state->zorder, so));
+                       if (z >= 1)
+                               z += zoffset;
+                       else
+                               z = j--;
+                       g_hash_table_insert (state->zorder, so, GINT_TO_POINTER (z));
+               }
+               state->pending_objects = g_slist_sort_with_data
+                       (state->pending_objects, cb_by_zorder, state->zorder);
+
                while (state->pending_objects) {
                        SheetObject *obj = state->pending_objects->data;
                        state->pending_objects = g_slist_delete_link (state->pending_objects,
@@ -5025,6 +5053,7 @@ xlsx_file_open (G_GNUC_UNUSED GOFileOpener const *fo, GOIOContext *context,
        g_hash_table_replace (state.theme_colors_by_name, g_strdup ("bg1"), GUINT_TO_POINTER 
(GO_COLOR_WHITE));
        state.pivot.cache_by_id = g_hash_table_new_full (g_str_hash, g_str_equal,
                (GDestroyNotify)g_free, (GDestroyNotify) g_object_unref);
+       state.zorder = g_hash_table_new (g_direct_hash, g_direct_equal);
 
        locale = gnm_push_C_locale ();
 
@@ -5103,6 +5132,7 @@ xlsx_file_open (G_GNUC_UNUSED GOFileOpener const *fo, GOIOContext *context,
        xlsx_style_array_free (state.dxfs);
        xlsx_style_array_free (state.table_styles);
        g_hash_table_destroy (state.theme_colors_by_name);
+       g_hash_table_destroy (state.zorder);
        value_release (state.val);
        if (state.texpr) gnm_expr_top_unref (state.texpr);
        if (state.comment) g_object_unref (state.comment);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]