[gnumeric] Hlink: store internal links as dependents.



commit 72fa6e3a47ecbea39025a80627172ede7c752f1f
Author: Morten Welinder <terra gnome org>
Date:   Sun Mar 5 20:28:53 2017 -0500

    Hlink: store internal links as dependents.

 ChangeLog                            |   13 ++
 NEWS                                 |    1 +
 plugins/excel/ms-excel-read.c        |   13 +-
 plugins/excel/xlsx-read.c            |    8 +-
 plugins/openoffice/openoffice-read.c |    2 +-
 src/dialogs/dialog-hyperlink.c       |   17 ++-
 src/hlink-impl.h                     |    5 +-
 src/hlink.c                          |  229 +++++++++++++++++++++++++++++-----
 src/hlink.h                          |   13 ++-
 src/mstyle.c                         |   34 +++++-
 src/xml-sax-read.c                   |   11 +-
 11 files changed, 280 insertions(+), 66 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 77d1a08..ec44f08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2017-03-05  Morten Welinder  <terra gnome org>
+
+       * src/hlink.c (GnmHLinkCurWB): Store location as dependent.
+       (gnm_hlink_cur_wb_activate): Move string parsing from here...
+       (gnm_hlink_cur_wb_set_target): ...to here.  Check name first as
+       value_new_cellrange_str will resolve a name.
+
+       * src/mstyle.c (gnm_style_linked_sheet_changed): Handle changed
+       sheet for hlinks too.
+
+       * src/hlink.c (gnm_hlink_new, gnm_hlink_dup, gnm_hlink_get_sheet)
+       (gnm_hlink_set_sheet): New functions.
+
 2017-01-30  Morten Welinder <terra gnome org>
 
        * configure.ac: Post-release bump.
diff --git a/NEWS b/NEWS
index 3ae97e0..25f2439 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Morten:
        * Minor xlsx import improvements with alias colors.
        * Test suite improvements.
        * Improve Excel handling of hyperlinks.
+       * Hyperlinks improvements.  [#706671]
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.33
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index 320687b..055dd93 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -5918,9 +5918,9 @@ excel_read_HLINK (BiffQuery *q, ExcelReadSheet *esheet)
                XL_NEED_BYTES (len);
                url = read_utf16_str (len/2, data);
                if (NULL != url && 0 == g_ascii_strncasecmp (url,  "mailto:";, 7))
-                       link = g_object_new (gnm_hlink_email_get_type (), NULL);
+                       link = gnm_hlink_new (gnm_hlink_email_get_type (), esheet->sheet);
                else
-                       link = g_object_new (gnm_hlink_url_get_type (), NULL);
+                       link = gnm_hlink_new (gnm_hlink_url_get_type (), esheet->sheet);
                gnm_hlink_set_target (link, url);
                g_free (url);
 
@@ -5954,7 +5954,7 @@ excel_read_HLINK (BiffQuery *q, ExcelReadSheet *esheet)
                        g_string_append (accum, "..\\");
                g_string_append (accum, path);
                g_free (path);
-               link = g_object_new (gnm_hlink_external_get_type (), NULL);
+               link = gnm_hlink_new (gnm_hlink_external_get_type (), esheet->sheet);
                gnm_hlink_set_target (link, accum->str);
                g_string_free (accum, TRUE);
 
@@ -5968,12 +5968,12 @@ excel_read_HLINK (BiffQuery *q, ExcelReadSheet *esheet)
 
                XL_NEED_BYTES (len);
                path = read_utf16_str (len/2, data);
-               link = g_object_new (gnm_hlink_external_get_type (), NULL);
+               link = gnm_hlink_new (gnm_hlink_external_get_type (), esheet->sheet);
                gnm_hlink_set_target (link, path);
                g_free (path);
 
        } else if ((options & 0x1eb) == 0x008) {
-               link = g_object_new (gnm_hlink_cur_wb_get_type (), NULL);
+               link = gnm_hlink_new (gnm_hlink_cur_wb_get_type (), esheet->sheet);
                gnm_hlink_set_target (link, mark);
        } else {
                g_warning ("Unknown hlink type 0x%x", options);
@@ -5989,10 +5989,9 @@ excel_read_HLINK (BiffQuery *q, ExcelReadSheet *esheet)
 
        if (link != NULL) {
                GnmStyle *style = gnm_style_new ();
+               gnm_hlink_set_tip  (link, tip);
                gnm_style_set_hlink (style, link);
                sheet_style_apply_range (esheet->sheet, &r, style);
-               if (tip != NULL)
-                       gnm_hlink_set_tip  (link, tip);
        }
 
        g_free (tip);
diff --git a/plugins/excel/xlsx-read.c b/plugins/excel/xlsx-read.c
index 77b069d..0214170 100644
--- a/plugins/excel/xlsx-read.c
+++ b/plugins/excel/xlsx-read.c
@@ -3181,11 +3181,9 @@ xlsx_CT_HyperLinks (GsfXMLIn *xin, xmlChar const **attrs)
                return;
        }
 
-       link = g_object_new (link_type, NULL);
-       if (NULL != target)
-               gnm_hlink_set_target (link, target);
-       if (NULL != tooltip)
-               gnm_hlink_set_tip  (link, tooltip);
+       link = gnm_hlink_new (link_type, state->sheet);
+       gnm_hlink_set_target (link, target);
+       gnm_hlink_set_tip (link, tooltip);
        style = gnm_style_new ();
        gnm_style_set_hlink (style, link);
        sheet_style_apply_range (state->sheet, &r, style);
diff --git a/plugins/openoffice/openoffice-read.c b/plugins/openoffice/openoffice-read.c
index 45c2af6..2a9bde9 100644
--- a/plugins/openoffice/openoffice-read.c
+++ b/plugins/openoffice/openoffice-read.c
@@ -4291,7 +4291,7 @@ oo_cell_content_link (GsfXMLIn *xin, xmlChar const **attrs)
                else
                        type = gnm_hlink_cur_wb_get_type ();
 
-               hlink = g_object_new (type, NULL);
+               hlink = gnm_hlink_new (type, state->pos.sheet);
                gnm_hlink_set_target (hlink, link);
                gnm_hlink_set_tip (hlink, tip);
                style = gnm_style_new ();
diff --git a/src/dialogs/dialog-hyperlink.c b/src/dialogs/dialog-hyperlink.c
index d79eedf..ce3f5a1 100644
--- a/src/dialogs/dialog-hyperlink.c
+++ b/src/dialogs/dialog-hyperlink.c
@@ -386,6 +386,7 @@ dhl_cb_ok (G_GNUC_UNUSED GtkWidget *button, HyperlinkState *state)
        wb_control_sheet_focus (GNM_WBC (state->wbcg), state->sheet);
 
        if (target) {
+               gnm_hlink_set_sheet (state->link, state->sheet);
                gnm_hlink_set_target (state->link, target);
                tip = dhl_get_tip (state, target);
                gnm_hlink_set_tip (state->link, tip);
@@ -444,7 +445,7 @@ dhl_set_type (HyperlinkState *state, GType type)
 {
        GnmHLink *old = state->link;
 
-       state->link = g_object_new (type, NULL);
+       state->link = gnm_hlink_new (type, state->sheet);
        if (old != NULL) {
                gnm_hlink_set_target (state->link, gnm_hlink_get_target (old));
                gnm_hlink_set_tip (state->link, gnm_hlink_get_tip (old));
@@ -595,20 +596,22 @@ dialog_hyperlink (WBCGtk *wbcg, SheetControl *sc)
         state->dialog = go_gtk_builder_get_widget (state->gui, "hyperlink-dialog");
 
        state->sheet = sc_sheet (sc);
-       for (ptr = sc_view (sc)->selections; ptr != NULL; ptr = ptr->next)
-               if (NULL != (link = sheet_style_region_contains_link (state->sheet, ptr->data)))
+       for (ptr = sc_view (sc)->selections; ptr != NULL; ptr = ptr->next) {
+               GnmRange const *r = ptr->data;
+               link = sheet_style_region_contains_link (state->sheet, r);
+               if (link)
                        break;
+       }
 
        /* We are creating a new link since the existing link */
        /* may be used in many places. */
        /* We are duplicating it here rather than in an ok handler in case */
-       /* The link is changed for a differnt cell in a different view. */
-       state->link = g_object_new (gnm_hlink_url_get_type (), NULL);
+       /* The link is changed for a differnet cell in a different view. */
        if (link == NULL) {
-               state->link = g_object_new (gnm_hlink_url_get_type (), NULL);
+               state->link = gnm_hlink_new (gnm_hlink_url_get_type (), state->sheet);
                state->is_new = TRUE;
        } else {
-               state->link = g_object_new (G_OBJECT_TYPE (link), NULL);
+               state->link = gnm_hlink_new (G_OBJECT_TYPE (link), state->sheet);
                state->is_new = FALSE;
                gnm_hlink_set_target (state->link, gnm_hlink_get_target (link));
                gnm_hlink_set_tip (state->link, gnm_hlink_get_tip (link));
diff --git a/src/hlink-impl.h b/src/hlink-impl.h
index 449f718..c4476c4 100644
--- a/src/hlink-impl.h
+++ b/src/hlink-impl.h
@@ -1,4 +1,3 @@
-/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 #ifndef _GNM_HLINK_IMPL_H_
 # define _GNM_HLINK_IMPL_H_
 
@@ -10,12 +9,16 @@ struct _GnmHLink {
        GObject obj;
        gchar *tip;
        gchar *target;
+       Sheet *sheet;
 };
 
 typedef struct {
        GObjectClass obj;
 
        gboolean (*Activate) (GnmHLink *link, WBCGtk *wbcg);
+       void (*set_sheet) (GnmHLink *link, Sheet *sheet);
+       void (*set_target) (GnmHLink *link, const char *target);
+       const char * (*get_target) (GnmHLink const *link);
 } GnmHLinkClass;
 
 G_END_DECLS
diff --git a/src/hlink.c b/src/hlink.c
index d2f5236..2822efc 100644
--- a/src/hlink.c
+++ b/src/hlink.c
@@ -44,6 +44,8 @@
 
 #define GET_CLASS(instance) G_TYPE_INSTANCE_GET_CLASS (instance, GNM_HLINK_TYPE, GnmHLinkClass)
 
+static GObjectClass *gnm_hlink_parent_class;
+
 /*
  * WARNING WARNING WARNING
  *
@@ -81,7 +83,6 @@ gnm_sheet_hlink_find (Sheet const *sheet, GnmCellPos const *pos)
 static void
 gnm_hlink_finalize (GObject *obj)
 {
-       GObjectClass *parent_class;
        GnmHLink *lnk = (GnmHLink *)obj;
 
        g_free (lnk->target);
@@ -90,15 +91,42 @@ gnm_hlink_finalize (GObject *obj)
        g_free (lnk->tip);
        lnk->tip = NULL;
 
-       parent_class = g_type_class_peek (G_TYPE_OBJECT);
-       parent_class->finalize (obj);
+       gnm_hlink_parent_class->finalize (obj);
+}
+
+static void
+gnm_hlink_base_set_sheet (GnmHLink *lnk, Sheet *sheet)
+{
+       lnk->sheet = sheet;
+}
+
+static void
+gnm_hlink_base_set_target (GnmHLink *lnk, gchar const *target)
+{
+       gchar *tmp = g_strdup (target);
+       g_free (lnk->target);
+       lnk->target = tmp;
+}
+
+static const char *
+gnm_hlink_base_get_target (GnmHLink const *lnk)
+{
+       return lnk->target;
 }
 
 static void
 gnm_hlink_class_init (GObjectClass *object_class)
 {
+       GnmHLinkClass *hlink_class = (GnmHLinkClass *)object_class;
+
+       gnm_hlink_parent_class = g_type_class_peek_parent (object_class);
+
        object_class->finalize = gnm_hlink_finalize;
+       hlink_class->set_sheet = gnm_hlink_base_set_sheet;
+       hlink_class->set_target = gnm_hlink_base_set_target;
+       hlink_class->get_target = gnm_hlink_base_get_target;
 }
+
 static void
 gnm_hlink_init (GObject *obj)
 {
@@ -106,29 +134,27 @@ gnm_hlink_init (GObject *obj)
        lnk->target = NULL;
        lnk->tip = NULL;
 }
+
 GSF_CLASS_ABSTRACT (GnmHLink, gnm_hlink,
                    gnm_hlink_class_init, gnm_hlink_init, G_TYPE_OBJECT)
 
-gchar const *
+const char *
 gnm_hlink_get_target (GnmHLink const *lnk)
 {
        g_return_val_if_fail (GNM_IS_HLINK (lnk), NULL);
-       return lnk->target;
+
+       return GET_CLASS (lnk)->get_target (lnk);
 }
 
 void
 gnm_hlink_set_target (GnmHLink *lnk, gchar const *target)
 {
-       gchar *tmp;
-
        g_return_if_fail (GNM_IS_HLINK (lnk));
 
-       tmp = g_strdup (target);
-       g_free (lnk->target);
-       lnk->target = tmp;
+       GET_CLASS (lnk)->set_target (lnk, target);
 }
 
-gchar const *
+const char *
 gnm_hlink_get_tip (GnmHLink const *lnk)
 {
        g_return_val_if_fail (GNM_IS_HLINK (lnk), NULL);
@@ -147,71 +173,208 @@ gnm_hlink_set_tip (GnmHLink *lnk, gchar const *tip)
        lnk->tip = tmp;
 }
 
+/**
+ * gnm_hlink_get_sheet:
+ * @lnk: link
+ *
+ * Returns: (transfer none): the sheet
+ */
+Sheet *
+gnm_hlink_get_sheet (GnmHLink *lnk)
+{
+       g_return_val_if_fail (GNM_IS_HLINK (lnk), NULL);
+       return lnk->sheet;
+}
+
+void
+gnm_hlink_set_sheet (GnmHLink *lnk, Sheet *sheet)
+{
+       g_return_if_fail (GNM_IS_HLINK (lnk));
+       GET_CLASS (lnk)->set_sheet (lnk, sheet);
+}
+
+GnmHLink *
+gnm_hlink_new (GType typ, Sheet *sheet)
+{
+       GnmHLink *lnk;
+
+       g_return_val_if_fail (typ != 0, NULL);
+       g_return_val_if_fail (g_type_is_a (typ, GNM_HLINK_TYPE), NULL);
+       g_return_val_if_fail (!G_TYPE_IS_ABSTRACT (typ), NULL);
+       g_return_val_if_fail (IS_SHEET (sheet), NULL);
+
+       lnk = g_object_new (typ, NULL);
+       gnm_hlink_set_sheet (lnk, sheet);
+       return lnk;
+}
+
+/**
+ * gnm_hlink_dup:
+ * @lnk: Existing link
+ *
+ * Returns: (transfer full): A duplicate link.
+ */
+GnmHLink *
+gnm_hlink_dup (GnmHLink *lnk)
+{
+       GnmHLink *new_lnk = g_object_new (G_OBJECT_TYPE (lnk), NULL);
+
+       gnm_hlink_set_sheet (new_lnk, lnk->sheet);
+       gnm_hlink_set_target (new_lnk, gnm_hlink_get_target (lnk));
+       gnm_hlink_set_tip (new_lnk, lnk->tip);
+
+       return new_lnk;
+}
+
 /***************************************************************************/
 /* Link to named regions within the current workbook */
 typedef struct { GnmHLinkClass hlink; } GnmHLinkCurWBClass;
 typedef struct {
        GnmHLink hlink;
+
+       GnmDependent dep;
 } GnmHLinkCurWB;
 #define GNM_HLINK_CUR_WB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), gnm_hlink_cur_wb_get_type (), GnmHLinkCurWB))
 
+static GObjectClass *gnm_hlink_cur_wb_parent_class;
+
 static gboolean
 gnm_hlink_cur_wb_activate (GnmHLink *lnk, WBCGtk *wbcg)
 {
+       GnmHLinkCurWB *hlcwb = (GnmHLinkCurWB *)lnk;
+       WorkbookControl *wbc = GNM_WBC (wbcg);
+       GnmExprTop const *texpr = hlcwb->dep.texpr;
+       GnmValue *vr;
        GnmRangeRef const *r;
        GnmCellPos tmp;
-       Sheet     *target_sheet;
-       WorkbookControl *wbc = GNM_WBC (wbcg);
-       Sheet     *sheet = wbcg_cur_sheet (wbcg);
+       Sheet *target_sheet;
        SheetView *sv;
-       GnmValue *target;
 
-       if (!lnk->target) {
+       if (!texpr) {
                go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbcg),
                        _("Link target"), _("(none)"));
                return FALSE;
        }
 
-       target = value_new_cellrange_str (sheet, lnk->target);
-       /* not an address, is it a name ? */
-       if (target == NULL) {
-               GnmParsePos pp;
-               GnmNamedExpr *nexpr = expr_name_lookup (
-                       parse_pos_init_sheet (&pp, sheet), lnk->target);
-
-               if (nexpr != NULL)
-                       target = gnm_expr_top_get_range (nexpr->texpr);
-       }
-       if (target == NULL) {
+       vr = gnm_expr_top_get_range (texpr);
+       if (!vr) {
                go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbcg),
                        _("Link target"), lnk->target);
                return FALSE;
        }
 
-       r = &target->v_range.cell;
+       r = value_get_rangeref (vr);
        tmp.col = r->a.col;
        tmp.row = r->a.row;
 
-       target_sheet = r->a.sheet ? r->a.sheet : sheet;
+       target_sheet = r->a.sheet ? r->a.sheet : lnk->sheet;
        sv = sheet_get_view (target_sheet,  wb_control_view (wbc));
        sv_selection_set (sv, &tmp, r->a.col, r->a.row, r->b.col, r->b.row);
        sv_make_cell_visible (sv, r->a.col, r->a.row, FALSE);
-       if (sheet != target_sheet)
+       if (wbcg_cur_sheet (wbcg) != target_sheet)
                wb_view_sheet_focus (wb_control_view (wbc), target_sheet);
-       value_release (target);
+       value_release (vr);
        return TRUE;
 }
 
 static void
+gnm_hlink_cur_wb_set_sheet (GnmHLink *lnk, Sheet *sheet)
+{
+       GnmHLinkCurWB *hlcwb = (GnmHLinkCurWB *)lnk;
+       ((GnmHLinkClass*)gnm_hlink_cur_wb_parent_class)
+               ->set_sheet (lnk, sheet);
+       dependent_managed_set_sheet (&hlcwb->dep, sheet);
+}
+
+static void
+gnm_hlink_cur_wb_set_target (GnmHLink *lnk, const char *target)
+{
+       GnmHLinkCurWB *hlcwb = (GnmHLinkCurWB *)lnk;
+       GnmExprTop const *texpr = NULL;
+
+       ((GnmHLinkClass*)gnm_hlink_cur_wb_parent_class)
+               ->set_target (lnk, NULL);
+
+       if (target && lnk->sheet) {
+               GnmParsePos pp;
+               GnmNamedExpr *nexpr;
+
+               // Try as name
+               parse_pos_init_sheet (&pp, lnk->sheet);
+               nexpr = expr_name_lookup (&pp, target);
+               if (nexpr != NULL)
+                       texpr = gnm_expr_top_new
+                               (gnm_expr_new_name (nexpr, NULL, NULL));
+
+               if (!texpr) {
+                       // Try as cell range
+                       GnmValue *v = value_new_cellrange_str (lnk->sheet, target);
+                       if (v)
+                               texpr = gnm_expr_top_new_constant (v);
+               }
+       }
+
+       dependent_managed_set_expr (&hlcwb->dep, texpr);
+       if (texpr)
+               gnm_expr_top_unref (texpr);
+}
+
+static const char *
+gnm_hlink_cur_wb_get_target (GnmHLink const *lnk)
+{
+       GnmHLinkCurWB *hlcwb = (GnmHLinkCurWB *)lnk;
+       GnmExprTop const *texpr = hlcwb->dep.texpr;
+       char *tgt = NULL;
+       Sheet *sheet = lnk->sheet;
+
+       if (texpr && sheet) {
+               GnmConventions const *convs = sheet_get_conventions (sheet);
+               GnmParsePos pp;
+               parse_pos_init_sheet (&pp, sheet);
+               tgt = gnm_expr_top_as_string (texpr, &pp, convs);
+       }
+
+       // Use parent class for storage.  Ick!
+       ((GnmHLinkClass*)gnm_hlink_cur_wb_parent_class)
+               ->set_target ((GnmHLink *)lnk, tgt);
+
+       return ((GnmHLinkClass*)gnm_hlink_cur_wb_parent_class)
+               ->get_target (lnk);
+}
+
+static void
+gnm_hlink_cur_wb_init (GObject *obj)
+{
+       GnmHLinkCurWB *hlcwb = (GnmHLinkCurWB *)obj;
+       dependent_managed_init (&hlcwb->dep, NULL);
+}
+
+static void
+gnm_hlink_cur_wb_finalize (GObject *obj)
+{
+       GnmHLinkCurWB *hlcwb = (GnmHLinkCurWB *)obj;
+
+       dependent_managed_set_expr (&hlcwb->dep, NULL);
+
+       gnm_hlink_cur_wb_parent_class->finalize (obj);
+}
+
+static void
 gnm_hlink_cur_wb_class_init (GObjectClass *object_class)
 {
        GnmHLinkClass *hlink_class = (GnmHLinkClass *) object_class;
 
-       hlink_class->Activate      = gnm_hlink_cur_wb_activate;
+       gnm_hlink_cur_wb_parent_class = g_type_class_peek_parent (object_class);
+
+       object_class->finalize = gnm_hlink_cur_wb_finalize;
+       hlink_class->Activate = gnm_hlink_cur_wb_activate;
+       hlink_class->set_sheet = gnm_hlink_cur_wb_set_sheet;
+       hlink_class->set_target = gnm_hlink_cur_wb_set_target;
+       hlink_class->get_target = gnm_hlink_cur_wb_get_target;
 }
 
 GSF_CLASS (GnmHLinkCurWB, gnm_hlink_cur_wb,
-          gnm_hlink_cur_wb_class_init, NULL,
+          gnm_hlink_cur_wb_class_init, gnm_hlink_cur_wb_init,
           GNM_HLINK_TYPE)
 
 /***************************************************************************/
diff --git a/src/hlink.h b/src/hlink.h
index 3a6368f..a7b9bfc 100644
--- a/src/hlink.h
+++ b/src/hlink.h
@@ -19,12 +19,21 @@ G_BEGIN_DECLS
 GnmHLink       *gnm_sheet_hlink_find   (Sheet const *sheet, GnmCellPos const *pos);
 
 GType gnm_hlink_get_type (void);
+
+GnmHLink *gnm_hlink_new (GType typ, Sheet *sheet);
+GnmHLink *gnm_hlink_dup (GnmHLink *lnk);
+
 gboolean         gnm_hlink_activate   (GnmHLink *lnk, WBCGtk *wbcg);
-gchar const    *gnm_hlink_get_target (GnmHLink const *lnk);
+
+const char     *gnm_hlink_get_target (GnmHLink const *lnk);
 void            gnm_hlink_set_target (GnmHLink *lnk, gchar const *url);
-gchar const    *gnm_hlink_get_tip    (GnmHLink const *lnk);
+
+const char     *gnm_hlink_get_tip    (GnmHLink const *lnk);
 void            gnm_hlink_set_tip    (GnmHLink *lnk, gchar const *tip);
 
+Sheet *gnm_hlink_get_sheet (GnmHLink *lnk);
+void gnm_hlink_set_sheet (GnmHLink *lnk, Sheet *sheet);
+
 GType gnm_hlink_cur_wb_get_type (void);
 GType gnm_hlink_url_get_type (void);
 GType gnm_hlink_email_get_type (void);
diff --git a/src/mstyle.c b/src/mstyle.c
index 67e8525..f6a5590 100644
--- a/src/mstyle.c
+++ b/src/mstyle.c
@@ -15,6 +15,7 @@
 #include "gnm-style-impl.h"
 #include "sheet-style.h"
 #include "style-conditions.h"
+#include "hlink.h"
 #include "application.h"
 #include "parse-util.h"
 #include "expr.h"
@@ -857,10 +858,17 @@ gnm_style_linked_sheet_changed (GnmStyle *style)
                gnm_style_set_validation (style, new_v);
        }
 
+       if (elem_is_set (style, MSTYLE_HLINK) &&
+           style->hlink &&
+           gnm_hlink_get_sheet (style->hlink) != sheet) {
+               GnmHLink *new_l = gnm_hlink_dup (style->hlink);
+               gnm_hlink_set_sheet (new_l, sheet);
+               gnm_style_set_hlink (style, new_l);
+       }
+
        if (elem_is_set (style, MSTYLE_CONDITIONS) &&
-           style->conditions
-           && gnm_style_conditions_get_sheet (style->conditions) != sheet
-               ) {
+           style->conditions &&
+           gnm_style_conditions_get_sheet (style->conditions) != sheet) {
                GnmStyleConditions *new_c = gnm_style_conditions_dup (style->conditions);
                gnm_style_conditions_set_sheet (new_c, sheet);
                gnm_style_set_conditions (style, new_c);
@@ -1777,6 +1785,11 @@ gnm_style_get_contents_hidden (GnmStyle const *style)
        return style->contents_hidden;
 }
 
+/**
+ * gnm_style_set_validation:
+ * @style: #GnmStyle
+ * @v: (transfer full): #GnmValidation
+ **/
 void
 gnm_style_set_validation (GnmStyle *style, GnmValidation *v)
 {
@@ -1803,6 +1816,11 @@ gnm_style_get_validation (GnmStyle const *style)
        return style->validation;
 }
 
+/**
+ * gnm_style_set_hlink:
+ * @style: #GnmStyle
+ * @link: (transfer full): #GnmHLink
+ **/
 void
 gnm_style_set_hlink (GnmStyle *style, GnmHLink *link)
 {
@@ -1829,6 +1847,11 @@ gnm_style_get_hlink (GnmStyle const *style)
        return style->hlink;
 }
 
+/**
+ * gnm_style_set_input_msg:
+ * @style: #GnmStyle
+ * @msg: (transfer full): #GnmInputMsg
+ **/
 void
 gnm_style_set_input_msg (GnmStyle *style, GnmInputMsg *msg)
 {
@@ -1855,6 +1878,11 @@ gnm_style_get_input_msg (GnmStyle const *style)
        return style->input_msg;
 }
 
+/**
+ * gnm_style_set_conditions:
+ * @style: #GnmStyle
+ * @sc: (transfer full): #GnmStyleConditions
+ **/
 void
 gnm_style_set_conditions (GnmStyle *style, GnmStyleConditions *sc)
 {
diff --git a/src/xml-sax-read.c b/src/xml-sax-read.c
index 7730659..f1c210d 100644
--- a/src/xml-sax-read.c
+++ b/src/xml-sax-read.c
@@ -1860,13 +1860,10 @@ xml_sax_hlink (GsfXMLIn *xin, xmlChar const **attrs)
 
        if (NULL != type && NULL != target) {
                GType typ = g_type_from_name (type);
-               if (typ != 0 && g_type_is_a (typ, GNM_HLINK_TYPE)) {
-                       GnmHLink *link = g_object_new (typ, NULL);
-                       gnm_hlink_set_target (link, target);
-                       if (tip != NULL)
-                               gnm_hlink_set_tip (link, tip);
-                       gnm_style_set_hlink (state->style, link);
-               }
+               GnmHLink *link = gnm_hlink_new (typ, state->sheet);
+               gnm_hlink_set_target (link, target);
+               gnm_hlink_set_tip (link, tip);
+               gnm_style_set_hlink (state->style, link);
        }
 
        g_free (type);


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