diff --git a/modules/other/gail/gaillinkbutton.c b/modules/other/gail/gaillinkbutton.c index cfb212c5f0..16671f8279 100644 --- a/modules/other/gail/gaillinkbutton.c +++ b/modules/other/gail/gaillinkbutton.c @@ -30,6 +30,7 @@ struct _GailLinkButtonLink AtkHyperlink parent; GailLinkButton *button; + gchar *description; }; struct _GailLinkButtonLinkClass @@ -37,7 +38,10 @@ struct _GailLinkButtonLinkClass AtkHyperlinkClass parent_class; }; -G_DEFINE_TYPE (GailLinkButtonLink, gail_link_button_link, ATK_TYPE_HYPERLINK) +static void atk_action_interface_init (AtkActionIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GailLinkButtonLink, gail_link_button_link, ATK_TYPE_HYPERLINK, + G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)) static gchar * gail_link_button_link_get_uri (AtkHyperlink *link, @@ -91,13 +95,27 @@ gail_link_button_link_get_end_index (AtkHyperlink *link) static void gail_link_button_link_init (GailLinkButtonLink *link) { + link->description = NULL; +} + +static void +gail_link_button_link_finalize (GObject *obj) +{ + GailLinkButtonLink *link = (GailLinkButtonLink *)obj; + + g_free (link->description); + + G_OBJECT_CLASS (gail_link_button_link_parent_class)->finalize (obj); } static void gail_link_button_link_class_init (GailLinkButtonLinkClass *class) { + GObjectClass *object_class = G_OBJECT_CLASS (class); AtkHyperlinkClass *hyperlink_class = ATK_HYPERLINK_CLASS (class); + object_class->finalize = gail_link_button_link_finalize; + hyperlink_class->get_uri = gail_link_button_link_get_uri; hyperlink_class->get_n_anchors = gail_link_button_link_get_n_anchors; hyperlink_class->is_valid = gail_link_button_link_is_valid; @@ -106,6 +124,80 @@ gail_link_button_link_class_init (GailLinkButtonLinkClass *class) hyperlink_class->get_end_index = gail_link_button_link_get_end_index; } +static gboolean +gail_link_button_link_do_action (AtkAction *action, + gint i) +{ + GailLinkButtonLink *link = (GailLinkButtonLink *)action; + GtkWidget *widget; + + widget = GTK_WIDGET (link->button); + if (widget == NULL) + /* + * State is defunct + */ + 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 +gail_link_button_link_get_n_actions (AtkAction *action) +{ + return 1; +} + +static const gchar * +gail_link_button_link_get_name (AtkAction *action, + gint i) +{ + g_return_val_if_fail (i == 0, NULL); + + return "activate"; +} + +static const gchar * +gail_link_button_link_get_description (AtkAction *action, + gint i) +{ + GailLinkButtonLink *link = (GailLinkButtonLink *)action; + + g_return_val_if_fail (i == 0, NULL); + + return link->description; +} + +static gboolean +gail_link_button_link_set_description (AtkAction *action, + gint i, + const gchar *description) +{ + GailLinkButtonLink *link = (GailLinkButtonLink *)action; + + g_return_val_if_fail (i == 0, FALSE); + + g_free (link->description); + link->description = g_strdup (description); + + return TRUE; +} + + +static void +atk_action_interface_init (AtkActionIface *iface) +{ + iface->do_action = gail_link_button_link_do_action; + iface->get_n_actions = gail_link_button_link_get_n_actions; + iface->get_name = gail_link_button_link_get_name; + iface->get_description = gail_link_button_link_get_description; + iface->set_description = gail_link_button_link_set_description; +} + static gboolean activate_link (GtkLinkButton *button, AtkHyperlink *link) { @@ -115,22 +207,24 @@ activate_link (GtkLinkButton *button, AtkHyperlink *link) } static AtkHyperlink * -gail_link_button_link_new (GailLinkButton *button) +gail_link_button_get_hyperlink (AtkHyperlinkImpl *impl) { - GailLinkButtonLink *link; + GailLinkButton *button = GAIL_LINK_BUTTON (impl); - link = g_object_new (gail_link_button_link_get_type (), NULL); - link->button = button; - g_signal_connect (gtk_accessible_get_widget (GTK_ACCESSIBLE (button)), - "activate-link", G_CALLBACK (activate_link), link); + if (!button->link) + { + button->link = g_object_new (gail_link_button_link_get_type (), NULL); + g_signal_connect (gtk_accessible_get_widget (GTK_ACCESSIBLE (button)), + "activate-link", G_CALLBACK (activate_link), button->link); + } - return ATK_HYPERLINK (link); + return button->link; } -static void atk_hypertext_interface_init (AtkHypertextIface *iface); +static void atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface); G_DEFINE_TYPE_WITH_CODE (GailLinkButton, gail_link_button, GAIL_TYPE_BUTTON, - G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERTEXT, atk_hypertext_interface_init)) + G_IMPLEMENT_INTERFACE (ATK_TYPE_HYPERLINK_IMPL, atk_hypertext_impl_interface_init)) static void gail_link_button_init (GailLinkButton *button) @@ -154,35 +248,8 @@ gail_link_button_class_init (GailLinkButtonClass *klass) G_OBJECT_CLASS (klass)->finalize = gail_link_button_finalize; } -static gint -gail_link_button_get_n_links (AtkHypertext *hypertext) -{ - return 1; -} - -static gint -gail_link_button_get_link_index (AtkHypertext *hypertext, - gint char_index) -{ - return 0; -} - -static AtkHyperlink * -gail_link_button_get_link (AtkHypertext *hypertext, - gint link_index) -{ - GailLinkButton *button = GAIL_LINK_BUTTON (hypertext); - - if (!button->link) - button->link = gail_link_button_link_new (button); - - return button->link; -} - static void -atk_hypertext_interface_init (AtkHypertextIface *iface) +atk_hypertext_impl_interface_init (AtkHyperlinkImplIface *iface) { - iface->get_link = gail_link_button_get_link; - iface->get_n_links = gail_link_button_get_n_links; - iface->get_link_index = gail_link_button_get_link_index; + iface->get_hyperlink = gail_link_button_get_hyperlink; }