[gnumeric] ods: fix link export syntax.



commit 2d9d5c5b241f6dac1ad7e54a304d8b69e1f8c3bf
Author: Morten Welinder <terra gnome org>
Date:   Fri Mar 10 09:55:03 2017 -0500

    ods: fix link export syntax.
    
    This reveals that we don't understand the right syntax on import.

 plugins/openoffice/ChangeLog          |    5 ++
 plugins/openoffice/openoffice-write.c |   91 +++++++++++++++++++--------------
 src/hlink.c                           |   17 ++----
 src/hlink.h                           |    2 +-
 4 files changed, 65 insertions(+), 50 deletions(-)
---
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 0578018..14cd90a 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,8 @@
+2017-03-10  Morten Welinder  <terra gnome org>
+
+       * openoffice-write.c (odf_write_link_start): Write internal links
+       in the format Sheet1.A4 as both Excel and LO do.
+
 2017-03-09  Morten Welinder  <terra gnome org>
 
        * openoffice-write.c (odf_write_named_expression): Don't write
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 88b5d20..fc957a7 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -3316,35 +3316,50 @@ odf_write_objects (GnmOOExport *state, GSList *objects)
 }
 
 static void
-odf_write_link_start (GnmOOExport *state, GnmHLink *link)
+odf_write_link_start (GnmOOExport *state, GnmHLink *lnk)
 {
-       char const *link_text;
-       if (link == NULL)
-               return;
-       link_text = gnm_hlink_get_target (link);
+       GType const t = G_OBJECT_TYPE (lnk);
+       char *link_text = NULL;
 
        gsf_xml_out_start_element (state->xml, TEXT "a");
        gsf_xml_out_add_cstr (state->xml, XLINK "type", "simple");
        gsf_xml_out_add_cstr (state->xml, XLINK "actuate", "onRequest");
 
-       if (g_str_has_prefix (link_text, "http") ||
-           g_str_has_prefix (link_text, "mail") ||
-           g_str_has_prefix (link_text, "file"))
-               gsf_xml_out_add_cstr (state->xml, XLINK "href", link_text);
-       else {
-               gchar *link_text_complete = g_strconcat ("#",link_text,NULL);
-               gsf_xml_out_add_cstr (state->xml, XLINK "href", link_text_complete);
-               g_free (link_text_complete);
+       if (g_type_is_a (t, gnm_hlink_url_get_type ())) {
+               // This includes email
+               link_text = g_strdup (gnm_hlink_get_target (lnk));
+       } else if (g_type_is_a (t, gnm_hlink_cur_wb_get_type ())) {
+               GnmExprTop const *texpr = gnm_hlink_get_target_expr (lnk);
+               GnmSheetRange sr;
+
+               if (texpr && GNM_EXPR_GET_OPER (texpr->expr) == GNM_EXPR_OP_NAME) {
+                       GnmParsePos pp;
+                       char *s;
+                       parse_pos_init_sheet (&pp, gnm_hlink_get_sheet (lnk));
+                       s = gnm_expr_top_as_string (texpr, &pp, state->conv);
+                       link_text = g_strconcat ("#", s, NULL);
+                       g_free (s);
+               } else if (gnm_hlink_get_range_target (lnk, &sr)) {
+                       link_text = g_strconcat
+                               ("#",
+                                sr.sheet->name_unquoted, ".",
+                                range_as_string (&sr.range),
+                                NULL);
+               }
+       } else {
+               g_warning ("Unexpected hyperlink type");
        }
 
-       gsf_xml_out_add_cstr (state->xml, OFFICE "title", gnm_hlink_get_tip (link));
+       gsf_xml_out_add_cstr (state->xml, XLINK "href", link_text ? link_text : "#");
+       g_free (link_text);
+
+       gsf_xml_out_add_cstr (state->xml, OFFICE "title", gnm_hlink_get_tip (lnk));
 }
 
 static void
-odf_write_link_end (GnmOOExport *state, GnmHLink *link)
+odf_write_link_end (GnmOOExport *state, GnmHLink *lnk)
 {
-       if (link != NULL)
-               gsf_xml_out_end_element (state->xml);  /* a */
+       gsf_xml_out_end_element (state->xml);  /* a */
 }
 
 
@@ -3425,7 +3440,7 @@ odf_write_cell (GnmOOExport *state, GnmCell *cell, GnmRange const *merge_range,
                GnmStyle const *style, GSList *objects)
 {
        int rows_spanned = 0, cols_spanned = 0;
-       GnmHLink *link = NULL;
+       GnmHLink *lnk = NULL;
        gboolean col_spanned_fake = FALSE;
 
        if (merge_range != NULL) {
@@ -3480,7 +3495,7 @@ odf_write_cell (GnmOOExport *state, GnmCell *cell, GnmRange const *merge_range,
                                              TABLE "content-validation-name", vname);
                        g_free (vname);
                }
-               link = gnm_style_get_hlink (style);
+               lnk = gnm_style_get_hlink (style);
        }
 
        if (cell != NULL) {
@@ -3614,11 +3629,11 @@ odf_write_cell (GnmOOExport *state, GnmCell *cell, GnmRange const *merge_range,
                        gboolean white_written = TRUE;
 
                        gsf_xml_out_start_element (state->xml, TEXT "p");
-                       odf_write_link_start (state, link);
+                       if (lnk) odf_write_link_start (state, lnk);
                        if (*rendered_string != '\0')
                                odf_add_chars (state, rendered_string, strlen (rendered_string),
                                               &white_written);
-                       odf_write_link_end (state, link);
+                       if (lnk) odf_write_link_end (state, lnk);
                        gsf_xml_out_end_element (state->xml);   /* p */
                        g_free (rendered_string);
                } else {
@@ -3629,9 +3644,9 @@ odf_write_cell (GnmOOExport *state, GnmCell *cell, GnmRange const *merge_range,
                        markup = go_format_get_markup (VALUE_FMT (cell->value));
 
                        gsf_xml_out_start_element (state->xml, TEXT "p");
-                       odf_write_link_start (state, link);
+                       if (lnk) odf_write_link_start (state, lnk);
                        odf_new_markup (state, markup, str->str);
-                       odf_write_link_end (state, link);
+                       if (lnk) odf_write_link_end (state, lnk);
                        gsf_xml_out_end_element (state->xml);   /* p */
 
                        g_string_free (str, TRUE);
@@ -4039,21 +4054,21 @@ static void
 odf_write_sheet_control_content (GnmOOExport *state, GnmExprTop const *texpr)
 {
        if (texpr && gnm_expr_top_is_rangeref (texpr)) {
-               char *link = NULL;
+               char *lnk = NULL;
                GnmParsePos pp;
 
                parse_pos_init_sheet (&pp, state->sheet);
-               link = gnm_expr_top_as_string (texpr, &pp, state->conv);
+               lnk = gnm_expr_top_as_string (texpr, &pp, state->conv);
 
                if (state->odf_version > 101)
                        gsf_xml_out_add_cstr (state->xml,
                                              FORM "source-cell-range",
-                                             odf_strip_brackets (link));
+                                             odf_strip_brackets (lnk));
                else
                        gsf_xml_out_add_cstr (state->xml,
                                              GNMSTYLE "source-cell-range",
-                                             odf_strip_brackets (link));
-               g_free (link);
+                                             odf_strip_brackets (lnk));
+               g_free (lnk);
                gnm_expr_top_unref (texpr);
        }
 }
@@ -4062,19 +4077,19 @@ static void
 odf_write_sheet_control_linked_cell (GnmOOExport *state, GnmExprTop const *texpr)
 {
        if (texpr && gnm_expr_top_is_rangeref (texpr)) {
-               char *link = NULL;
+               char *lnk = NULL;
                GnmParsePos pp;
 
                parse_pos_init_sheet (&pp, state->sheet);
-               link = gnm_expr_top_as_string (texpr, &pp, state->conv);
+               lnk = gnm_expr_top_as_string (texpr, &pp, state->conv);
 
                if (state->odf_version > 101)
                        gsf_xml_out_add_cstr (state->xml, FORM "linked-cell",
-                                             odf_strip_brackets (link));
+                                             odf_strip_brackets (lnk));
                else
                        gsf_xml_out_add_cstr (state->xml, GNMSTYLE "linked-cell",
-                                             odf_strip_brackets (link));
-               g_free (link);
+                                             odf_strip_brackets (lnk));
+               g_free (lnk);
                gnm_expr_top_unref (texpr);
        }
 }
@@ -4277,11 +4292,11 @@ odf_write_sheet_control_button (GnmOOExport *state, SheetObject *so)
        gsf_xml_out_add_cstr_unchecked (state->xml, FORM "button-type", "push");
 
        if (texpr != NULL ) {
-               char *link = NULL, *name = NULL;
+               char *lnk = NULL, *name = NULL;
                GnmParsePos pp;
 
                parse_pos_init_sheet (&pp, state->sheet);
-               link = gnm_expr_top_as_string (texpr, &pp, state->conv);
+               lnk = gnm_expr_top_as_string (texpr, &pp, state->conv);
 
                gsf_xml_out_start_element (state->xml, OFFICE "event-listeners");
 
@@ -4290,7 +4305,7 @@ odf_write_sheet_control_button (GnmOOExport *state, SheetObject *so)
                                                "dom:mousedown");
                gsf_xml_out_add_cstr_unchecked (state->xml, SCRIPT "language",
                                                GNMSTYLE "short-macro");
-               name = g_strdup_printf ("set-to-TRUE:%s", odf_strip_brackets (link));
+               name = g_strdup_printf ("set-to-TRUE:%s", odf_strip_brackets (lnk));
                gsf_xml_out_add_cstr (state->xml, SCRIPT "macro-name", name);
                g_free (name);
                gsf_xml_out_end_element (state->xml); /* script:event-listener */
@@ -4300,14 +4315,14 @@ odf_write_sheet_control_button (GnmOOExport *state, SheetObject *so)
                                                "dom:mouseup");
                gsf_xml_out_add_cstr_unchecked (state->xml, SCRIPT "language",
                                                GNMSTYLE "short-macro");
-               name = g_strdup_printf ("set-to-FALSE:%s", odf_strip_brackets (link));
+               name = g_strdup_printf ("set-to-FALSE:%s", odf_strip_brackets (lnk));
                gsf_xml_out_add_cstr (state->xml, SCRIPT "macro-name", name);
                g_free (name);
                gsf_xml_out_end_element (state->xml); /* script:event-listener */
 
                gsf_xml_out_end_element (state->xml); /* office:event-listeners */
 
-               g_free (link);
+               g_free (lnk);
                gnm_expr_top_unref (texpr);
 
        }
diff --git a/src/hlink.c b/src/hlink.c
index 4d6af13..f8aa85f 100644
--- a/src/hlink.c
+++ b/src/hlink.c
@@ -417,24 +417,19 @@ gnm_hlink_get_range_target (GnmHLink const *lnk, GnmSheetRange *sr)
 }
 
 
-GnmNamedExpr const *
-gnm_hlink_get_name_target (GnmHLink const *lnk)
+GnmExprTop const *
+gnm_hlink_get_target_expr (GnmHLink const *lnk)
 {
+
        GnmHLinkCurWB *hlcwb;
-       GnmExprTop const *texpr;
 
-       g_return_val_if_fail (GNM_IS_HLINK (lnk), FALSE);
+       g_return_val_if_fail (GNM_IS_HLINK (lnk), NULL);
 
        if (!GNM_IS_HLINK_CUR_WB (lnk))
-               return FALSE;
+               return NULL;
 
        hlcwb = (GnmHLinkCurWB *)lnk;
-       texpr = hlcwb->dep.texpr;
-
-       if (!texpr || GNM_EXPR_GET_OPER (texpr->expr) != GNM_EXPR_OP_NAME)
-               return FALSE;
-
-       return texpr->expr->name.name;
+       return hlcwb->dep.texpr;
 }
 
 
diff --git a/src/hlink.h b/src/hlink.h
index 66a5aea..8d753a0 100644
--- a/src/hlink.h
+++ b/src/hlink.h
@@ -41,7 +41,7 @@ GType gnm_hlink_external_get_type (void);
 
 // For internal links only
 gboolean gnm_hlink_get_range_target (GnmHLink const *lnk, GnmSheetRange *sr);
-GnmNamedExpr const *gnm_hlink_get_name_target (GnmHLink const *lnk);
+GnmExprTop const *gnm_hlink_get_target_expr (GnmHLink const *lnk);
 
 /* Protected. */
 void _gnm_hlink_init (void);


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