]> Pileus Git - ~andy/gtk/blob - modules/other/gail/gaillinkbutton.c
Hypertext does not really make sense for GtkLinkButton
[~andy/gtk] / modules / other / gail / gaillinkbutton.c
1 /* GAIL - The GNOME Accessibility Implementation Library
2  * Copyright 2011 Red Hat, 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 <gtk/gtk.h>
23 #include "gaillinkbutton.h"
24
25 typedef struct _GailLinkButtonLink GailLinkButtonLink;
26 typedef struct _GailLinkButtonLinkClass GailLinkButtonLinkClass;
27
28 struct _GailLinkButtonLink
29 {
30   AtkHyperlink parent;
31
32   GailLinkButton *button;
33   gchar *description;
34 };
35
36 struct _GailLinkButtonLinkClass
37 {
38   AtkHyperlinkClass parent_class;
39 };
40
41 static void atk_action_interface_init (AtkActionIface *iface);
42
43 G_DEFINE_TYPE_WITH_CODE (GailLinkButtonLink, gail_link_button_link, ATK_TYPE_HYPERLINK,
44                          G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
45
46 static gchar *
47 gail_link_button_link_get_uri (AtkHyperlink *link,
48                                gint          i)
49 {
50   GailLinkButtonLink *l = (GailLinkButtonLink *)link;
51   GtkWidget *widget;
52   const gchar *uri;
53
54   widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (l->button));
55   uri = gtk_link_button_get_uri (GTK_LINK_BUTTON (widget));
56
57   return g_strdup (uri);
58 }
59
60 static gint
61 gail_link_button_link_get_n_anchors (AtkHyperlink *link)
62 {
63   return 1;
64 }
65
66 static gboolean
67 gail_link_button_link_is_valid (AtkHyperlink *link)
68 {
69   return TRUE;
70 }
71
72 static AtkObject *
73 gail_link_button_link_get_object (AtkHyperlink *link,
74                                   gint          i)
75 {
76   GailLinkButtonLink *l = (GailLinkButtonLink *)link;
77
78   return ATK_OBJECT (l->button);
79 }
80
81 static gint
82 gail_link_button_link_get_start_index (AtkHyperlink *link)
83 {
84   return 0;
85 }
86
87 static gint
88 gail_link_button_link_get_end_index (AtkHyperlink *link)
89 {
90   GailLinkButtonLink *l = (GailLinkButtonLink *)link;
91
92   return atk_text_get_character_count (ATK_TEXT (l->button));
93 }
94
95 static void
96 gail_link_button_link_init (GailLinkButtonLink *link)
97 {
98   link->description = NULL;
99 }
100
101 static void
102 gail_link_button_link_finalize (GObject *obj)
103 {
104   GailLinkButtonLink *link = (GailLinkButtonLink *)obj;
105
106   g_free (link->description);
107
108   G_OBJECT_CLASS (gail_link_button_link_parent_class)->finalize (obj);
109 }
110
111 static void
112 gail_link_button_link_class_init (GailLinkButtonLinkClass *class)
113 {
114   GObjectClass *object_class = G_OBJECT_CLASS (class);
115   AtkHyperlinkClass *hyperlink_class = ATK_HYPERLINK_CLASS (class);
116
117   object_class->finalize = gail_link_button_link_finalize;
118
119   hyperlink_class->get_uri = gail_link_button_link_get_uri;
120   hyperlink_class->get_n_anchors = gail_link_button_link_get_n_anchors;
121   hyperlink_class->is_valid = gail_link_button_link_is_valid;
122   hyperlink_class->get_object = gail_link_button_link_get_object;
123   hyperlink_class->get_start_index = gail_link_button_link_get_start_index;
124   hyperlink_class->get_end_index = gail_link_button_link_get_end_index;
125 }
126
127 static gboolean
128 gail_link_button_link_do_action (AtkAction *action,
129                                  gint       i)
130 {
131   GailLinkButtonLink *link = (GailLinkButtonLink *)action;
132   GtkWidget *widget;
133
134   widget = GTK_WIDGET (link->button);
135   if (widget == NULL)
136     /*
137      * State is defunct
138      */
139     return FALSE;
140
141   if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
142     return FALSE;
143
144   gtk_button_clicked (GTK_BUTTON (widget));
145
146   return TRUE;
147 }
148
149 static gint
150 gail_link_button_link_get_n_actions (AtkAction *action)
151 {
152   return 1;
153 }
154
155 static const gchar *
156 gail_link_button_link_get_name (AtkAction *action,
157                                 gint i)
158 {
159   g_return_val_if_fail (i == 0, NULL);
160
161   return "activate";
162 }
163
164 static const gchar *
165 gail_link_button_link_get_description (AtkAction *action,
166                                        gint       i)
167 {
168   GailLinkButtonLink *link = (GailLinkButtonLink *)action;
169
170   g_return_val_if_fail (i == 0, NULL);
171
172   return link->description;
173 }
174
175 static gboolean
176 gail_link_button_link_set_description (AtkAction   *action,
177                                        gint         i,
178                                        const gchar *description)
179 {
180   GailLinkButtonLink *link = (GailLinkButtonLink *)action;
181
182   g_return_val_if_fail (i == 0, FALSE);
183
184   g_free (link->description);
185   link->description = g_strdup (description);
186
187   return TRUE;
188 }
189
190
191 static void
192 atk_action_interface_init (AtkActionIface *iface)
193 {
194   iface->do_action = gail_link_button_link_do_action;
195   iface->get_n_actions = gail_link_button_link_get_n_actions;
196   iface->get_name = gail_link_button_link_get_name;
197   iface->get_description = gail_link_button_link_get_description;
198   iface->set_description = gail_link_button_link_set_description;
199 }
200
201 static gboolean
202 activate_link (GtkLinkButton *button, AtkHyperlink *link)
203 {
204   g_signal_emit_by_name (link, "link-activated");
205
206   return FALSE;
207 }
208
209 static AtkHyperlink *
210 gail_link_button_get_hyperlink (AtkHyperlinkImpl *impl)
211 {
212   GailLinkButton *button = GAIL_LINK_BUTTON (impl);
213
214   if (!button->link)
215     {
216       button->link = g_object_new (gail_link_button_link_get_type (), NULL);
217       g_signal_connect (gtk_accessible_get_widget (GTK_ACCESSIBLE (button)),
218                         "activate-link", G_CALLBACK (activate_link), button->link);
219     }
220
221   return button->link;
222 }
223
224 static void atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface);
225
226 G_DEFINE_TYPE_WITH_CODE (GailLinkButton, gail_link_button, GAIL_TYPE_BUTTON,
227                          G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERLINK_IMPL, atk_hypertext_impl_interface_init))
228
229 static void
230 gail_link_button_init (GailLinkButton *button)
231 {
232 }
233
234 static void
235 gail_link_button_finalize (GObject *object)
236 {
237   GailLinkButton *button = GAIL_LINK_BUTTON (object);
238
239   if (button->link)
240     g_object_unref (button->link);
241
242   G_OBJECT_CLASS (gail_link_button_parent_class)->finalize (object);
243 }
244
245 static void
246 gail_link_button_class_init (GailLinkButtonClass *klass)
247 {
248   G_OBJECT_CLASS (klass)->finalize = gail_link_button_finalize;
249 }
250
251 static void
252 atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface)
253 {
254   iface->get_hyperlink = gail_link_button_get_hyperlink;
255 }