1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
4 * hlink.c: hyperlink support
6 * Copyright (C) 2000-2005 Jody Goldberg (jody@gnome.org)
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) version 3.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 #include <gnumeric-config.h>
24 #include <glib/gi18n-lib.h>
27 #include "hlink-impl.h"
28 #include "command-context.h"
29 #include "workbook-control.h"
30 #include "workbook-view.h"
31 #include "selection.h"
33 #include "sheet-view.h"
34 #include "sheet-style.h"
37 #include "expr-name.h"
42 #include <goffice/goffice.h>
43 #include <gsf/gsf-impl-utils.h>
45 #define GET_CLASS(instance) G_TYPE_INSTANCE_GET_CLASS (instance, GNM_HLINK_TYPE, GnmHLinkClass)
48 * WARNING WARNING WARNING
50 * The type names are used in the xml persistence DO NOT CHANGE THEM
55 * @wbcg: the wbcg that activated the link
57 * Returns: TRUE if the link successfully activated.
60 gnm_hlink_activate (GnmHLink
*lnk
, WBCGtk
*wbcg
)
62 g_return_val_if_fail (IS_GNM_HLINK (lnk
), FALSE
);
64 return GET_CLASS (lnk
)->Activate (lnk
, wbcg
);
72 * Returns: (transfer none): the found #GnmHLink.
75 sheet_hlink_find (Sheet
const *sheet
, GnmCellPos
const *pos
)
77 GnmStyle
const *style
= sheet_style_get (sheet
, pos
->col
, pos
->row
);
78 return gnm_style_get_hlink (style
);
82 gnm_hlink_finalize (GObject
*obj
)
84 GObjectClass
*parent_class
;
85 GnmHLink
*lnk
= (GnmHLink
*)obj
;
93 parent_class
= g_type_class_peek (G_TYPE_OBJECT
);
94 parent_class
->finalize (obj
);
98 gnm_hlink_class_init (GObjectClass
*object_class
)
100 object_class
->finalize
= gnm_hlink_finalize
;
103 gnm_hlink_init (GObject
*obj
)
105 GnmHLink
*lnk
= (GnmHLink
* )obj
;
109 GSF_CLASS_ABSTRACT (GnmHLink
, gnm_hlink
,
110 gnm_hlink_class_init
, gnm_hlink_init
, G_TYPE_OBJECT
)
113 gnm_hlink_get_target (GnmHLink
const *lnk
)
115 g_return_val_if_fail (IS_GNM_HLINK (lnk
), NULL
);
120 gnm_hlink_set_target (GnmHLink
*lnk
, gchar
const *target
)
124 g_return_if_fail (IS_GNM_HLINK (lnk
));
126 tmp
= g_strdup (target
);
127 g_free (lnk
->target
);
132 gnm_hlink_get_tip (GnmHLink
const *lnk
)
134 g_return_val_if_fail (IS_GNM_HLINK (lnk
), NULL
);
139 gnm_hlink_set_tip (GnmHLink
*lnk
, gchar
const *tip
)
143 g_return_if_fail (IS_GNM_HLINK (lnk
));
145 tmp
= g_strdup (tip
);
150 /***************************************************************************/
151 /* Link to named regions within the current workbook */
152 typedef struct { GnmHLinkClass hlink
; } GnmHLinkCurWBClass
;
156 #define GNM_HLINK_CUR_WB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), gnm_hlink_cur_wb_get_type (), GnmHLinkCurWB))
159 gnm_hlink_cur_wb_activate (GnmHLink
*lnk
, WBCGtk
*wbcg
)
161 GnmRangeRef
const *r
;
164 WorkbookControl
*wbc
= WORKBOOK_CONTROL (wbcg
);
165 Sheet
*sheet
= wbcg_cur_sheet (wbcg
);
170 go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbcg
),
171 _("Link target"), _("(none)"));
175 target
= value_new_cellrange_str (sheet
, lnk
->target
);
176 /* not an address, is it a name ? */
177 if (target
== NULL
) {
179 GnmNamedExpr
*nexpr
= expr_name_lookup (
180 parse_pos_init_sheet (&pp
, sheet
), lnk
->target
);
183 target
= gnm_expr_top_get_range (nexpr
->texpr
);
185 if (target
== NULL
) {
186 go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbcg
),
187 _("Link target"), lnk
->target
);
191 r
= &target
->v_range
.cell
;
195 target_sheet
= r
->a
.sheet
? r
->a
.sheet
: sheet
;
196 sv
= sheet_get_view (target_sheet
, wb_control_view (wbc
));
197 sv_selection_set (sv
, &tmp
, r
->a
.col
, r
->a
.row
, r
->b
.col
, r
->b
.row
);
198 sv_make_cell_visible (sv
, r
->a
.col
, r
->a
.row
, FALSE
);
199 if (sheet
!= target_sheet
)
200 wb_view_sheet_focus (wb_control_view (wbc
), target_sheet
);
201 value_release (target
);
206 gnm_hlink_cur_wb_class_init (GObjectClass
*object_class
)
208 GnmHLinkClass
*hlink_class
= (GnmHLinkClass
*) object_class
;
210 hlink_class
->Activate
= gnm_hlink_cur_wb_activate
;
213 GSF_CLASS (GnmHLinkCurWB
, gnm_hlink_cur_wb
,
214 gnm_hlink_cur_wb_class_init
, NULL
,
217 /***************************************************************************/
218 /* Link to arbitrary urls */
219 typedef struct { GnmHLinkClass hlink
; } GnmHLinkURLClass
;
225 gnm_hlink_url_activate (GnmHLink
*lnk
, WBCGtk
*wbcg
)
230 if (lnk
->target
== NULL
)
233 screen
= gtk_window_get_screen (wbcg_toplevel (wbcg
));
234 err
= go_gtk_url_show (lnk
->target
, screen
);
237 char *msg
= g_strdup_printf (_("Unable to activate the url '%s'"), lnk
->target
);
238 go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbcg
),
248 gnm_hlink_url_class_init (GObjectClass
*object_class
)
250 GnmHLinkClass
*hlink_class
= (GnmHLinkClass
*) object_class
;
252 hlink_class
->Activate
= gnm_hlink_url_activate
;
255 GSF_CLASS (GnmHLinkURL
, gnm_hlink_url
,
256 gnm_hlink_url_class_init
, NULL
,
259 /***************************************************************************/
260 /* email is just a url, but it is cleaner to stick it in a distinct type */
261 typedef struct { GnmHLinkURLClass hlink
; } GnmHLinkEMailClass
;
266 GSF_CLASS (GnmHLinkEMail
, gnm_hlink_email
,
268 gnm_hlink_url_get_type ())
270 /***************************************************************************/
271 /* Link to arbitrary urls */
272 typedef struct { GnmHLinkClass hlink
; } GnmHLinkExternalClass
;
278 gnm_hlink_external_activate (GnmHLink
*lnk
, WBCGtk
*wbcg
)
281 gboolean res
= FALSE
;
285 if (lnk
->target
== NULL
)
288 cmd
= go_shell_arg_to_uri (lnk
->target
);
289 screen
= gtk_window_get_screen (wbcg_toplevel (wbcg
));
290 err
= go_gtk_url_show (cmd
, screen
);
294 char *msg
= g_strdup_printf(_("Unable to open '%s'"), lnk
->target
);
295 go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbcg
),
305 gnm_hlink_external_class_init (GObjectClass
*object_class
)
307 GnmHLinkClass
*hlink_class
= (GnmHLinkClass
*) object_class
;
309 hlink_class
->Activate
= gnm_hlink_external_activate
;
312 GSF_CLASS (GnmHLinkExternal
, gnm_hlink_external
,
313 gnm_hlink_external_class_init
, NULL
,
317 _gnm_hlink_init (void)
319 /* make sure that all hlink types are registered */
320 gnm_hlink_cur_wb_get_type ();
321 gnm_hlink_url_get_type ();
322 gnm_hlink_email_get_type ();
323 gnm_hlink_external_get_type ();