[gnumeric] xlsx: properly write uris with anchor component



commit 8977fd2aac100b29303c65ad2e09eabd88f13cf3
Author: Morten Welinder <terra gnome org>
Date:   Wed Mar 8 14:41:02 2017 -0500

    xlsx: properly write uris with anchor component

 plugins/excel/ChangeLog       |    5 ++++
 plugins/excel/ms-excel-util.c |   13 +++++++++++
 plugins/excel/xlsx-write.c    |   48 ++++++++++++++++++----------------------
 3 files changed, 40 insertions(+), 26 deletions(-)
---
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index 5727c7f..80c6fd1 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,5 +1,10 @@
 2017-03-08  Morten Welinder  <terra gnome org>
 
+       * xlsx-write.c (by_hlink_order): Simplify order.
+       (xlsx_write_hlink): Properly handle location.
+
+       * ms-excel-util.c (xls_collect_hlinks): Sort ranges.
+
        * xlsx-read.c (xlsx_CT_HyperLinks): Handle external links with
        anchors.
 
diff --git a/plugins/excel/ms-excel-util.c b/plugins/excel/ms-excel-util.c
index 63e78c4..cc4d700 100644
--- a/plugins/excel/ms-excel-util.c
+++ b/plugins/excel/ms-excel-util.c
@@ -923,6 +923,7 @@ xls_collect_hlinks (GnmStyleList *sl, int max_col, int max_row)
 {
        GHashTable *group = g_hash_table_new_full
                (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_slist_free);
+       GList *keys, *k;
 
        for (; sl != NULL ; sl = sl->next) {
                GnmStyleRegion const *sr = sl->data;
@@ -943,6 +944,18 @@ xls_collect_hlinks (GnmStyleList *sl, int max_col, int max_row)
                                     g_slist_prepend (ranges, (gpointer)&sr->range));
        }
 
+       keys = g_hash_table_get_keys (group);
+       for (k = keys; k ; k = k->next) {
+               GnmHLink *hlink = k->data;
+               GSList *ranges = g_hash_table_lookup (group, hlink);
+               GSList *nranges = g_slist_sort (ranges, (GCompareFunc)gnm_range_compare);
+               if (ranges != nranges) {
+                       g_hash_table_steal (group, hlink);
+                       g_hash_table_insert (group, hlink, nranges);
+               }
+       }
+       g_list_free (keys);
+
        return group;
 }
 
diff --git a/plugins/excel/xlsx-write.c b/plugins/excel/xlsx-write.c
index 902c07c..c539d46 100644
--- a/plugins/excel/xlsx-write.c
+++ b/plugins/excel/xlsx-write.c
@@ -2067,25 +2067,32 @@ xlsx_write_validations (XLSXWriteState *state, GsfXMLOut *xml, G_GNUC_UNUSED Gnm
 static void
 xlsx_write_hlink (GnmHLink const *lnk, GSList *ranges, XLSXClosure *info)
 {
-       gchar const *target = gnm_hlink_get_target (lnk);
+       gchar *target = g_strdup (gnm_hlink_get_target (lnk));
        gchar const *rid = NULL;
-       gchar const *location = NULL;
+       gchar *location = NULL;
        gchar const *tip = gnm_hlink_get_tip (lnk);
        GType const t = G_OBJECT_TYPE (lnk);
 
-       if (g_type_is_a (t, gnm_hlink_url_get_type ())) {
+       if (target && g_type_is_a (t, gnm_hlink_url_get_type ())) {
                // URLs, including email.
 
-               // FIXME: An anchor within the url should be extracted into
-               // location
+               char *hash = strchr (target, '#');
+               if (hash) {
+                       location = g_strdup (hash + 1);
+                       *hash = 0;
+               }
 
                rid = gsf_outfile_open_pkg_add_extern_rel (
                        GSF_OUTFILE_OPEN_PKG (gsf_xml_out_get_output (info->xml)),
                        target, ns_rel_hlink);
        } else if (t == gnm_hlink_cur_wb_get_type ()) {
                location = target;
-       } else
+               target = NULL;
+       } else {
+               g_free (target);
+               g_free (location);
                return;
+       }
 
        for (; ranges  != NULL ; ranges = ranges->next) {
                GnmRange const *range = ranges->data;
@@ -2096,37 +2103,26 @@ xlsx_write_hlink (GnmHLink const *lnk, GSList *ranges, XLSXClosure *info)
                if (rid)
                        gsf_xml_out_add_cstr (info->xml, "r:id", rid);
                if (location)
-                       gsf_xml_out_add_cstr (info->xml, "location", target);
+                       gsf_xml_out_add_cstr (info->xml, "location", location);
                if (tip)
                        gsf_xml_out_add_cstr (info->xml, "tooltip", tip);
 
                gsf_xml_out_end_element (info->xml); /*  </hyperlink> */
        }
+
+       g_free (target);
+       g_free (location);
 }
 
 static int
-by_hlink_order (gpointer link_a, G_GNUC_UNUSED gpointer val_a,
-               gpointer link_b, G_GNUC_UNUSED gpointer val_b,
+by_hlink_order (G_GNUC_UNUSED gpointer link_a, gpointer val_a,
+               G_GNUC_UNUSED gpointer link_b, gpointer val_b,
                G_GNUC_UNUSED gpointer user)
 {
-       GnmHLink const *a = link_a;
-       GnmHLink const *b = link_b;
-       int res;
-
-       res = g_strcmp0 (g_type_name (G_OBJECT_TYPE (a)), g_type_name (G_OBJECT_TYPE (b)));
-       if (res)
-               return res;
-
-       res = g_strcmp0 (gnm_hlink_get_target (a), gnm_hlink_get_target (b));
-       if (res)
-               return res;
-
-       res = g_strcmp0 (gnm_hlink_get_tip (a), gnm_hlink_get_tip (b));
-       if (res)
-               return res;
+       GList *ranges_a = val_a;
+       GList *ranges_b = val_b;
 
-       // Fallback
-       return a < b ? -1 : (a > b ? +1 : 0);
+       return gnm_range_compare (ranges_a->data, ranges_b->data);
 }
 
 static void


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