gtk2/gtk/a11y/gtklinkbuttonaccessible.c
Matthias Clasen e375b564fb GtkLinkButtonAccessible: fix broken AtkHyperlink implementation
The get_end_index implementation was casting the accessible
to AtkText even though GtkLinkButtonAccessible does not
implement this interface. This did not show up in the a11y
tests because the they were not dumping the affected AtkHyperlinkImpl
properties. Oops.
2014-01-04 10:54:03 -05:00

235 lines
6.5 KiB
C

/* GTK+ - accessibility implementations
* Copyright 2011 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "gtklinkbuttonaccessible.h"
typedef struct _GtkLinkButtonAccessibleLink GtkLinkButtonAccessibleLink;
typedef struct _GtkLinkButtonAccessibleLinkClass GtkLinkButtonAccessibleLinkClass;
struct _GtkLinkButtonAccessiblePrivate
{
AtkHyperlink *link;
};
struct _GtkLinkButtonAccessibleLink
{
AtkHyperlink parent;
GtkLinkButtonAccessible *button;
};
struct _GtkLinkButtonAccessibleLinkClass
{
AtkHyperlinkClass parent_class;
};
static void atk_action_interface_init (AtkActionIface *iface);
GType _gtk_link_button_accessible_link_get_type (void);
G_DEFINE_TYPE_WITH_CODE (GtkLinkButtonAccessibleLink, _gtk_link_button_accessible_link, ATK_TYPE_HYPERLINK,
G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init))
static AtkHyperlink *
gtk_link_button_accessible_link_new (GtkLinkButtonAccessible *button)
{
GtkLinkButtonAccessibleLink *l;
l = g_object_new (_gtk_link_button_accessible_link_get_type (), NULL);
l->button = button;
return ATK_HYPERLINK (l);
}
static gchar *
gtk_link_button_accessible_link_get_uri (AtkHyperlink *atk_link,
gint i)
{
GtkLinkButtonAccessibleLink *l = (GtkLinkButtonAccessibleLink *)atk_link;
GtkWidget *widget;
const gchar *uri;
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (l->button));
uri = gtk_link_button_get_uri (GTK_LINK_BUTTON (widget));
return g_strdup (uri);
}
static gint
gtk_link_button_accessible_link_get_n_anchors (AtkHyperlink *atk_link)
{
return 1;
}
static gboolean
gtk_link_button_accessible_link_is_valid (AtkHyperlink *atk_link)
{
return TRUE;
}
static AtkObject *
gtk_link_button_accessible_link_get_object (AtkHyperlink *atk_link,
gint i)
{
GtkLinkButtonAccessibleLink *l = (GtkLinkButtonAccessibleLink *)atk_link;
return ATK_OBJECT (l->button);
}
static void
_gtk_link_button_accessible_link_init (GtkLinkButtonAccessibleLink *l)
{
}
static void
_gtk_link_button_accessible_link_class_init (GtkLinkButtonAccessibleLinkClass *class)
{
AtkHyperlinkClass *atk_link_class = ATK_HYPERLINK_CLASS (class);
atk_link_class->get_uri = gtk_link_button_accessible_link_get_uri;
atk_link_class->get_n_anchors = gtk_link_button_accessible_link_get_n_anchors;
atk_link_class->is_valid = gtk_link_button_accessible_link_is_valid;
atk_link_class->get_object = gtk_link_button_accessible_link_get_object;
}
static gboolean
gtk_link_button_accessible_link_do_action (AtkAction *action,
gint i)
{
GtkLinkButtonAccessibleLink *l = (GtkLinkButtonAccessibleLink *)action;
GtkWidget *widget;
widget = GTK_WIDGET (l->button);
if (widget == NULL)
return FALSE;
if (i != 0)
return FALSE;
if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
return FALSE;
gtk_button_clicked (GTK_BUTTON (widget));
return TRUE;
}
static gint
gtk_link_button_accessible_link_get_n_actions (AtkAction *action)
{
return 1;
}
static const gchar *
gtk_link_button_accessible_link_get_name (AtkAction *action,
gint i)
{
if (i != 0)
return NULL;
return "activate";
}
static void
atk_action_interface_init (AtkActionIface *iface)
{
iface->do_action = gtk_link_button_accessible_link_do_action;
iface->get_n_actions = gtk_link_button_accessible_link_get_n_actions;
iface->get_name = gtk_link_button_accessible_link_get_name;
}
static gboolean
activate_link (GtkLinkButton *button,
AtkHyperlink *atk_link)
{
g_signal_emit_by_name (atk_link, "link-activated");
return FALSE;
}
static AtkHyperlink *
gtk_link_button_accessible_get_hyperlink (AtkHyperlinkImpl *impl)
{
GtkLinkButtonAccessible *button = GTK_LINK_BUTTON_ACCESSIBLE (impl);
if (!button->priv->link)
{
button->priv->link = gtk_link_button_accessible_link_new (button);
g_signal_connect (gtk_accessible_get_widget (GTK_ACCESSIBLE (button)),
"activate-link", G_CALLBACK (activate_link), button->priv->link);
}
return g_object_ref (button->priv->link);
}
static void atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface);
G_DEFINE_TYPE_WITH_CODE (GtkLinkButtonAccessible, gtk_link_button_accessible, GTK_TYPE_BUTTON_ACCESSIBLE,
G_ADD_PRIVATE (GtkLinkButtonAccessible)
G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERLINK_IMPL, atk_hypertext_impl_interface_init))
static void
gtk_link_button_accessible_init (GtkLinkButtonAccessible *button)
{
button->priv = gtk_link_button_accessible_get_instance_private (button);
}
static void
gtk_link_button_accessible_finalize (GObject *object)
{
GtkLinkButtonAccessible *button = GTK_LINK_BUTTON_ACCESSIBLE (object);
if (button->priv->link)
g_object_unref (button->priv->link);
G_OBJECT_CLASS (gtk_link_button_accessible_parent_class)->finalize (object);
}
static AtkStateSet *
gtk_link_button_ref_state_set (AtkObject *accessible)
{
AtkStateSet *state_set;
GtkWidget *widget;
state_set = ATK_OBJECT_CLASS (gtk_link_button_accessible_parent_class)->ref_state_set (accessible);
widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible));
if (widget != NULL)
{
if (gtk_link_button_get_visited (GTK_LINK_BUTTON (widget)))
atk_state_set_add_state (state_set, ATK_STATE_VISITED);
}
return state_set;
}
static void
gtk_link_button_accessible_class_init (GtkLinkButtonAccessibleClass *klass)
{
G_OBJECT_CLASS (klass)->finalize = gtk_link_button_accessible_finalize;
ATK_OBJECT_CLASS (klass)->ref_state_set = gtk_link_button_ref_state_set;
}
static void
atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface)
{
iface->get_hyperlink = gtk_link_button_accessible_get_hyperlink;
}