Updated Czech translation
[gnumeric.git] / src / hlink.c
blob393f2da6692bd115d013e2634cb9efc769b37c04
1 /* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /*
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
21 * USA
23 #include <gnumeric-config.h>
24 #include <glib/gi18n-lib.h>
25 #include "gnumeric.h"
26 #include "hlink.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"
32 #include "sheet.h"
33 #include "sheet-view.h"
34 #include "sheet-style.h"
35 #include "ranges.h"
36 #include "position.h"
37 #include "expr-name.h"
38 #include "expr.h"
39 #include "value.h"
40 #include "mstyle.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
52 /**
53 * gnm_hlink_activate:
54 * @lnk:
55 * @wbcg: the wbcg that activated the link
57 * Returns: TRUE if the link successfully activated.
58 **/
59 gboolean
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);
67 /**
68 * sheet_hlink_find:
69 * @sheet: #Sheet
70 * @pos: #GcmCellPos
72 * Returns: (transfer none): the found #GnmHLink.
73 **/
74 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);
81 static void
82 gnm_hlink_finalize (GObject *obj)
84 GObjectClass *parent_class;
85 GnmHLink *lnk = (GnmHLink *)obj;
87 g_free (lnk->target);
88 lnk->target = NULL;
90 g_free (lnk->tip);
91 lnk->tip = NULL;
93 parent_class = g_type_class_peek (G_TYPE_OBJECT);
94 parent_class->finalize (obj);
97 static void
98 gnm_hlink_class_init (GObjectClass *object_class)
100 object_class->finalize = gnm_hlink_finalize;
102 static void
103 gnm_hlink_init (GObject *obj)
105 GnmHLink *lnk = (GnmHLink * )obj;
106 lnk->target = NULL;
107 lnk->tip = NULL;
109 GSF_CLASS_ABSTRACT (GnmHLink, gnm_hlink,
110 gnm_hlink_class_init, gnm_hlink_init, G_TYPE_OBJECT)
112 gchar const *
113 gnm_hlink_get_target (GnmHLink const *lnk)
115 g_return_val_if_fail (IS_GNM_HLINK (lnk), NULL);
116 return lnk->target;
119 void
120 gnm_hlink_set_target (GnmHLink *lnk, gchar const *target)
122 gchar *tmp;
124 g_return_if_fail (IS_GNM_HLINK (lnk));
126 tmp = g_strdup (target);
127 g_free (lnk->target);
128 lnk->target = tmp;
131 gchar const *
132 gnm_hlink_get_tip (GnmHLink const *lnk)
134 g_return_val_if_fail (IS_GNM_HLINK (lnk), NULL);
135 return lnk->tip;
138 void
139 gnm_hlink_set_tip (GnmHLink *lnk, gchar const *tip)
141 gchar *tmp;
143 g_return_if_fail (IS_GNM_HLINK (lnk));
145 tmp = g_strdup (tip);
146 g_free (lnk->tip);
147 lnk->tip = tmp;
150 /***************************************************************************/
151 /* Link to named regions within the current workbook */
152 typedef struct { GnmHLinkClass hlink; } GnmHLinkCurWBClass;
153 typedef struct {
154 GnmHLink hlink;
155 } GnmHLinkCurWB;
156 #define GNM_HLINK_CUR_WB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), gnm_hlink_cur_wb_get_type (), GnmHLinkCurWB))
158 static gboolean
159 gnm_hlink_cur_wb_activate (GnmHLink *lnk, WBCGtk *wbcg)
161 GnmRangeRef const *r;
162 GnmCellPos tmp;
163 Sheet *target_sheet;
164 WorkbookControl *wbc = WORKBOOK_CONTROL (wbcg);
165 Sheet *sheet = wbcg_cur_sheet (wbcg);
166 SheetView *sv;
167 GnmValue *target;
169 if (!lnk->target) {
170 go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbcg),
171 _("Link target"), _("(none)"));
172 return FALSE;
175 target = value_new_cellrange_str (sheet, lnk->target);
176 /* not an address, is it a name ? */
177 if (target == NULL) {
178 GnmParsePos pp;
179 GnmNamedExpr *nexpr = expr_name_lookup (
180 parse_pos_init_sheet (&pp, sheet), lnk->target);
182 if (nexpr != NULL)
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);
188 return FALSE;
191 r = &target->v_range.cell;
192 tmp.col = r->a.col;
193 tmp.row = r->a.row;
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);
202 return TRUE;
205 static void
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,
215 GNM_HLINK_TYPE)
217 /***************************************************************************/
218 /* Link to arbitrary urls */
219 typedef struct { GnmHLinkClass hlink; } GnmHLinkURLClass;
220 typedef struct {
221 GnmHLink hlink;
222 } GnmHLinkURL;
224 static gboolean
225 gnm_hlink_url_activate (GnmHLink *lnk, WBCGtk *wbcg)
227 GError *err = NULL;
228 GdkScreen *screen;
230 if (lnk->target == NULL)
231 return FALSE;
233 screen = gtk_window_get_screen (wbcg_toplevel (wbcg));
234 err = go_gtk_url_show (lnk->target, screen);
236 if (err != NULL) {
237 char *msg = g_strdup_printf (_("Unable to activate the url '%s'"), lnk->target);
238 go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbcg),
239 msg, err->message);
240 g_free (msg);
241 g_error_free (err);
244 return err == NULL;
247 static void
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,
257 GNM_HLINK_TYPE)
259 /***************************************************************************/
260 /* email is just a url, but it is cleaner to stick it in a distinct type */
261 typedef struct { GnmHLinkURLClass hlink; } GnmHLinkEMailClass;
262 typedef struct {
263 GnmHLinkURL hlink;
264 } GnmHLinkEMail;
266 GSF_CLASS (GnmHLinkEMail, gnm_hlink_email,
267 NULL, NULL,
268 gnm_hlink_url_get_type ())
270 /***************************************************************************/
271 /* Link to arbitrary urls */
272 typedef struct { GnmHLinkClass hlink; } GnmHLinkExternalClass;
273 typedef struct {
274 GnmHLink hlink;
275 } GnmHLinkExternal;
277 static gboolean
278 gnm_hlink_external_activate (GnmHLink *lnk, WBCGtk *wbcg)
280 GError *err = NULL;
281 gboolean res = FALSE;
282 char *cmd;
283 GdkScreen *screen;
285 if (lnk->target == NULL)
286 return FALSE;
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);
291 g_free (cmd);
293 if (err != NULL) {
294 char *msg = g_strdup_printf(_("Unable to open '%s'"), lnk->target);
295 go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbcg),
296 msg, err->message);
297 g_free (msg);
298 g_error_free (err);
301 return res;
304 static void
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,
314 GNM_HLINK_TYPE)
316 void
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 ();