1
/* ATK -  Accessibility Toolkit
2
 * Copyright 2001, 2002, 2003 Sun Microsystems Inc.
3
 *
4
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
6
 * License as published by the Free Software Foundation; either
7
 * version 2 of the License, or (at your option) any later version.
8
 *
9
 * This library is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
15
 * License along with this library; if not, write to the
16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
 * Boston, MA 02111-1307, USA.
18
 */
19

            
20
#include "config.h"
21

            
22
#include <glib/gi18n-lib.h>
23

            
24
#include "atkhyperlink.h"
25

            
26
/**
27
 * AtkHyperlink:
28
 *
29
 * An ATK object which encapsulates a link or set of links in a hypertext document.
30
 *
31
 * An ATK object which encapsulates a link or set of links (for
32
 * instance in the case of client-side image maps) in a hypertext
33
 * document.  It may implement the AtkAction interface.  AtkHyperlink
34
 * may also be used to refer to inline embedded content, since it
35
 * allows specification of a start and end offset within the host
36
 * AtkHypertext object.
37
 */
38

            
39
enum
40
{
41
  LINK_ACTIVATED,
42

            
43
  LAST_SIGNAL
44
};
45

            
46
enum
47
{
48
  PROP_0, /* gobject convention */
49

            
50
  PROP_SELECTED_LINK,
51
  PROP_NUMBER_ANCHORS,
52
  PROP_END_INDEX,
53
  PROP_START_INDEX,
54
  PROP_LAST
55
};
56

            
57
static void atk_hyperlink_class_init (AtkHyperlinkClass *klass);
58
static void atk_hyperlink_init (AtkHyperlink *link,
59
                                AtkHyperlinkClass *klass);
60

            
61
static void atk_hyperlink_real_get_property (GObject *object,
62
                                             guint prop_id,
63
                                             GValue *value,
64
                                             GParamSpec *pspec);
65

            
66
static void atk_hyperlink_action_iface_init (AtkActionIface *iface);
67

            
68
static guint atk_hyperlink_signals[LAST_SIGNAL] = {
69
  0,
70
};
71

            
72
static gpointer parent_class = NULL;
73

            
74
GType
75
72
atk_hyperlink_get_type (void)
76
{
77
  static GType type = 0;
78

            
79
72
  if (!type)
80
    {
81
      static const GTypeInfo typeInfo = {
82
        sizeof (AtkHyperlinkClass),
83
        (GBaseInitFunc) NULL,
84
        (GBaseFinalizeFunc) NULL,
85
        (GClassInitFunc) atk_hyperlink_class_init,
86
        (GClassFinalizeFunc) NULL,
87
        NULL,
88
        sizeof (AtkHyperlink),
89
        0,
90
        (GInstanceInitFunc) atk_hyperlink_init,
91
      };
92

            
93
      static const GInterfaceInfo action_info = {
94
        (GInterfaceInitFunc) atk_hyperlink_action_iface_init,
95
        (GInterfaceFinalizeFunc) NULL,
96
        NULL
97
      };
98

            
99
10
      type = g_type_register_static (G_TYPE_OBJECT, "AtkHyperlink", &typeInfo, 0);
100
10
      g_type_add_interface_static (type, ATK_TYPE_ACTION, &action_info);
101
    }
102
72
  return type;
103
}
104

            
105
static void
106
10
atk_hyperlink_class_init (AtkHyperlinkClass *klass)
107
{
108
10
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
109

            
110
10
  parent_class = g_type_class_peek_parent (klass);
111

            
112
10
  gobject_class->get_property = atk_hyperlink_real_get_property;
113

            
114
10
  klass->link_activated = NULL;
115

            
116
  /**
117
   * AtkHyperlink:selected-link:
118
   *
119
   * Selected link
120
   *
121
   * Deprecated: 1.8: Please use ATK_STATE_FOCUSABLE for all links, and
122
   * ATK_STATE_FOCUSED for focused links.
123
   */
124
10
  g_object_class_install_property (gobject_class,
125
                                   PROP_SELECTED_LINK,
126
                                   g_param_spec_boolean ("selected-link",
127
                                                         _ ("Selected Link"),
128
                                                         _ ("Specifies whether the AtkHyperlink object is selected"),
129
                                                         FALSE,
130
                                                         G_PARAM_READABLE));
131
10
  g_object_class_install_property (gobject_class,
132
                                   PROP_NUMBER_ANCHORS,
133
                                   g_param_spec_int ("number-of-anchors",
134
                                                     _ ("Number of Anchors"),
135
                                                     _ ("The number of anchors associated with the AtkHyperlink object"),
136
                                                     0,
137
                                                     G_MAXINT,
138
                                                     0,
139
                                                     G_PARAM_READABLE));
140
10
  g_object_class_install_property (gobject_class,
141
                                   PROP_END_INDEX,
142
                                   g_param_spec_int ("end-index",
143
                                                     _ ("End index"),
144
                                                     _ ("The end index of the AtkHyperlink object"),
145
                                                     0,
146
                                                     G_MAXINT,
147
                                                     0,
148
                                                     G_PARAM_READABLE));
149
10
  g_object_class_install_property (gobject_class,
150
                                   PROP_START_INDEX,
151
                                   g_param_spec_int ("start-index",
152
                                                     _ ("Start index"),
153
                                                     _ ("The start index of the AtkHyperlink object"),
154
                                                     0,
155
                                                     G_MAXINT,
156
                                                     0,
157
                                                     G_PARAM_READABLE));
158

            
159
  /**
160
   * AtkHyperlink::link-activated:
161
   * @atkhyperlink: the object which received the signal.
162
   *
163
   * The signal link-activated is emitted when a link is activated.
164
   */
165
10
  atk_hyperlink_signals[LINK_ACTIVATED] =
166
10
      g_signal_new ("link_activated",
167
                    G_TYPE_FROM_CLASS (klass),
168
                    G_SIGNAL_RUN_LAST,
169
                    G_STRUCT_OFFSET (AtkHyperlinkClass, link_activated),
170
                    NULL, NULL,
171
                    g_cclosure_marshal_VOID__VOID,
172
                    G_TYPE_NONE,
173
                    0);
174
10
}
175

            
176
static void
177
20
atk_hyperlink_init (AtkHyperlink *link,
178
                    AtkHyperlinkClass *klass)
179
{
180
20
}
181

            
182
static void
183
atk_hyperlink_real_get_property (GObject *object,
184
                                 guint prop_id,
185
                                 GValue *value,
186
                                 GParamSpec *pspec)
187
{
188
  AtkHyperlink *link;
189

            
190
  link = ATK_HYPERLINK (object);
191

            
192
  switch (prop_id)
193
    {
194
    case PROP_SELECTED_LINK:
195
      // This property is deprecated, also the method to get the value
196
      g_value_set_boolean (value, FALSE);
197
      break;
198
    case PROP_NUMBER_ANCHORS:
199
      g_value_set_int (value, atk_hyperlink_get_n_anchors (link));
200
      break;
201
    case PROP_END_INDEX:
202
      g_value_set_int (value, atk_hyperlink_get_end_index (link));
203
      break;
204
    case PROP_START_INDEX:
205
      g_value_set_int (value, atk_hyperlink_get_start_index (link));
206
      break;
207
    default:
208
      break;
209
    }
210
}
211

            
212
/**
213
 * atk_hyperlink_get_uri:
214
 * @link_: an #AtkHyperlink
215
 * @i: a (zero-index) integer specifying the desired anchor
216
 *
217
 * Get a the URI associated with the anchor specified
218
 * by @i of @link_.
219
 *
220
 * Multiple anchors are primarily used by client-side image maps.
221
 *
222
 * Returns: a string specifying the URI
223
 **/
224
gchar *
225
3
atk_hyperlink_get_uri (AtkHyperlink *link,
226
                       gint i)
227
{
228
  AtkHyperlinkClass *klass;
229

            
230
3
  g_return_val_if_fail (ATK_IS_HYPERLINK (link), NULL);
231

            
232
3
  klass = ATK_HYPERLINK_GET_CLASS (link);
233
3
  if (klass->get_uri)
234
3
    return (klass->get_uri) (link, i);
235
  else
236
    return NULL;
237
}
238

            
239
/**
240
 * atk_hyperlink_get_object:
241
 * @link_: an #AtkHyperlink
242
 * @i: a (zero-index) integer specifying the desired anchor
243
 *
244
 * Returns the item associated with this hyperlinks nth anchor.
245
 * For instance, the returned #AtkObject will implement #AtkText
246
 * if @link_ is a text hyperlink, #AtkImage if @link_ is an image
247
 * hyperlink etc.
248
 *
249
 * Multiple anchors are primarily used by client-side image maps.
250
 *
251
 * Returns: (transfer none): an #AtkObject associated with this hyperlinks
252
 * i-th anchor
253
 **/
254
AtkObject *
255
1
atk_hyperlink_get_object (AtkHyperlink *link,
256
                          gint i)
257
{
258
  AtkHyperlinkClass *klass;
259

            
260
1
  g_return_val_if_fail (ATK_IS_HYPERLINK (link), NULL);
261

            
262
1
  klass = ATK_HYPERLINK_GET_CLASS (link);
263
1
  if (klass->get_object)
264
1
    return (klass->get_object) (link, i);
265
  else
266
    return NULL;
267
}
268

            
269
/**
270
 * atk_hyperlink_get_end_index:
271
 * @link_: an #AtkHyperlink
272
 *
273
 * Gets the index with the hypertext document at which this link ends.
274
 *
275
 * Returns: the index with the hypertext document at which this link ends
276
 **/
277
gint
278
1
atk_hyperlink_get_end_index (AtkHyperlink *link)
279
{
280
  AtkHyperlinkClass *klass;
281

            
282
1
  g_return_val_if_fail (ATK_IS_HYPERLINK (link), 0);
283

            
284
1
  klass = ATK_HYPERLINK_GET_CLASS (link);
285
1
  if (klass->get_end_index)
286
1
    return (klass->get_end_index) (link);
287
  else
288
    return 0;
289
}
290

            
291
/**
292
 * atk_hyperlink_get_start_index:
293
 * @link_: an #AtkHyperlink
294
 *
295
 * Gets the index with the hypertext document at which this link begins.
296
 *
297
 * Returns: the index with the hypertext document at which this link begins
298
 **/
299
gint
300
1
atk_hyperlink_get_start_index (AtkHyperlink *link)
301
{
302
  AtkHyperlinkClass *klass;
303

            
304
1
  g_return_val_if_fail (ATK_IS_HYPERLINK (link), 0);
305

            
306
1
  klass = ATK_HYPERLINK_GET_CLASS (link);
307
1
  if (klass->get_start_index)
308
1
    return (klass->get_start_index) (link);
309
  else
310
    return 0;
311
}
312

            
313
/**
314
 * atk_hyperlink_is_valid:
315
 * @link_: an #AtkHyperlink
316
 *
317
 * Since the document that a link is associated with may have changed
318
 * this method returns %TRUE if the link is still valid (with
319
 * respect to the document it references) and %FALSE otherwise.
320
 *
321
 * Returns: whether or not this link is still valid
322
 **/
323
gboolean
324
1
atk_hyperlink_is_valid (AtkHyperlink *link)
325
{
326
  AtkHyperlinkClass *klass;
327

            
328
1
  g_return_val_if_fail (ATK_IS_HYPERLINK (link), FALSE);
329

            
330
1
  klass = ATK_HYPERLINK_GET_CLASS (link);
331
1
  if (klass->is_valid)
332
1
    return (klass->is_valid) (link);
333
  else
334
    return FALSE;
335
}
336

            
337
/**
338
 * atk_hyperlink_is_inline:
339
 * @link_: an #AtkHyperlink
340
 *
341
 * Indicates whether the link currently displays some or all of its
342
 *           content inline.  Ordinary HTML links will usually return
343
 *           %FALSE, but an inline &lt;src&gt; HTML element will return
344
 *           %TRUE.
345
 *
346
 * Returns: whether or not this link displays its content inline.
347
 *
348
 **/
349
gboolean
350
atk_hyperlink_is_inline (AtkHyperlink *link)
351
{
352
  AtkHyperlinkClass *klass;
353

            
354
  g_return_val_if_fail (ATK_IS_HYPERLINK (link), FALSE);
355

            
356
  klass = ATK_HYPERLINK_GET_CLASS (link);
357
  if (klass->link_state)
358
    return (klass->link_state (link) & ATK_HYPERLINK_IS_INLINE);
359
  else
360
    return FALSE;
361
}
362

            
363
/**
364
 * atk_hyperlink_get_n_anchors:
365
 * @link_: an #AtkHyperlink
366
 *
367
 * Gets the number of anchors associated with this hyperlink.
368
 *
369
 * Returns: the number of anchors associated with this hyperlink
370
 **/
371
gint
372
1
atk_hyperlink_get_n_anchors (AtkHyperlink *link)
373
{
374
  AtkHyperlinkClass *klass;
375

            
376
1
  g_return_val_if_fail (ATK_IS_HYPERLINK (link), 0);
377

            
378
1
  klass = ATK_HYPERLINK_GET_CLASS (link);
379
1
  if (klass->get_n_anchors)
380
1
    return (klass->get_n_anchors) (link);
381
  else
382
    return 0;
383
}
384

            
385
/**
386
 * atk_hyperlink_is_selected_link:
387
 * @link_: an #AtkHyperlink
388
 *
389
 * Determines whether this AtkHyperlink is selected
390
 *
391
 * Since: 1.4
392
 *
393
 * Deprecated: 1.8: Please use ATK_STATE_FOCUSABLE for all links,
394
 * and ATK_STATE_FOCUSED for focused links.
395
 *
396
 * Returns: True if the AtkHyperlink is selected, False otherwise
397
 **/
398
gboolean
399
atk_hyperlink_is_selected_link (AtkHyperlink *link)
400
{
401
  AtkHyperlinkClass *klass;
402

            
403
  g_return_val_if_fail (ATK_IS_HYPERLINK (link), FALSE);
404

            
405
  klass = ATK_HYPERLINK_GET_CLASS (link);
406
  if (klass->is_selected_link)
407
    return (klass->is_selected_link) (link);
408
  else
409
    return FALSE;
410
}
411

            
412
static void
413
10
atk_hyperlink_action_iface_init (AtkActionIface *iface)
414
{
415
  /*
416
   * We do nothing here
417
   *
418
   * When we come to derive a class from AtkHyperlink we will provide an
419
   * implementation of the AtkAction interface.
420
   */
421
10
}