]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtklinkbutton.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / gtk / gtklinkbutton.c
index 81b8b657d61a553db8b395edad1292cdd0aac09f..b5981c741f5ea55192dd40ddbeb9d8fb5e7b5f94 100644 (file)
@@ -1,12 +1,12 @@
 /* GTK - The GIMP Toolkit
  * gtklinkbutton.c - an hyperlink-enabled button
- * 
+ *
  * Copyright (C) 2006 Emmanuele Bassi <ebassi@gmail.com>
  * All rights reserved.
  *
  * Based on gnome-href code by:
- *     James Henstridge <james@daa.com.au>
- * 
+ *      James Henstridge <james@daa.com.au>
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * License as published by the Free Software Foundation; either
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:gtklinkbutton
+ * @Title: GtkLinkButton
+ * @Short_description: Create buttons bound to a URL
+ * @See_also: #GtkButton
+ *
+ * A GtkLinkButton is a #GtkButton with a hyperlink, similar to the one
+ * used by web browsers, which triggers an action when clicked. It is useful
+ * to show quick links to resources.
+ *
+ * A link button is created by calling either gtk_link_button_new() or
+ * gtk_link_button_new_with_label(). If using the former, the URI you pass
+ * to the constructor is used as a label for the widget.
+ *
+ * The URI bound to a GtkLinkButton can be set specifically using
+ * gtk_link_button_set_uri(), and retrieved using gtk_link_button_get_uri().
+ *
+ * By default, GtkLinkButton calls gtk_show_uri() when the button is
+ * clicked. This behaviour can be overridden by connecting to the
+ * #GtkLinkButton::activate-link signal and returning %TRUE from the
+ * signal handler.
  */
 
 #include "config.h"
 
-#include <string.h>
+#include "gtklinkbutton.h"
 
-#include <gdk/gdkcolor.h>
-#include <gdk/gdkcursor.h>
-#include <gdk/gdkdisplay.h>
+#include <string.h>
 
 #include "gtkclipboard.h"
 #include "gtkdnd.h"
 #include "gtkimagemenuitem.h"
 #include "gtklabel.h"
 #include "gtkmain.h"
+#include "gtkmarshalers.h"
 #include "gtkmenu.h"
 #include "gtkmenuitem.h"
+#include "gtksizerequest.h"
 #include "gtkstock.h"
-
-#include "gtklinkbutton.h"
-
+#include "gtkshow.h"
+#include "gtktooltip.h"
+#include "gtkprivate.h"
 #include "gtkintl.h"
-#include "gtkalias.h"
 
+#include "a11y/gtklinkbuttonaccessible.h"
 
 struct _GtkLinkButtonPrivate
 {
@@ -57,11 +79,16 @@ struct _GtkLinkButtonPrivate
 enum
 {
   PROP_0,
-  
   PROP_URI,
+  PROP_VISITED
 };
 
-#define GTK_LINK_BUTTON_GET_PRIVATE(obj)       (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_LINK_BUTTON, GtkLinkButtonPrivate))
+enum
+{
+  ACTIVATE_LINK,
+
+  LAST_SIGNAL
+};
 
 static void     gtk_link_button_finalize     (GObject          *object);
 static void     gtk_link_button_get_property (GObject          *object,
@@ -78,8 +105,8 @@ static gboolean gtk_link_button_button_press (GtkWidget        *widget,
                                              GdkEventButton   *event);
 static void     gtk_link_button_clicked      (GtkButton        *button);
 static gboolean gtk_link_button_popup_menu   (GtkWidget        *widget);
-static void     gtk_link_button_style_set    (GtkWidget        *widget,
-                                             GtkStyle         *old_style);
+static void     gtk_link_button_style_updated (GtkWidget        *widget);
+static void     gtk_link_button_unrealize    (GtkWidget        *widget);
 static gboolean gtk_link_button_enter_cb     (GtkWidget        *widget,
                                              GdkEventCrossing *event,
                                              gpointer          user_data);
@@ -92,21 +119,25 @@ static void gtk_link_button_drag_data_get_cb (GtkWidget        *widget,
                                              guint             _info,
                                              guint             _time,
                                              gpointer          user_data);
-
+static gboolean gtk_link_button_query_tooltip_cb (GtkWidget    *widget,
+                                                  gint          x,
+                                                  gint          y,
+                                                  gboolean      keyboard_tip,
+                                                  GtkTooltip   *tooltip,
+                                                  gpointer      data);
+static gboolean gtk_link_button_activate_link (GtkLinkButton *link_button);
 
 static const GtkTargetEntry link_drop_types[] = {
   { "text/uri-list", 0, 0 },
   { "_NETSCAPE_URL", 0, 0 }
 };
 
-static GdkColor default_link_color = { 0, 0, 0, 0xeeee };
-static GdkColor default_visited_link_color = { 0, 0x5555, 0x1a1a, 0x8b8b };
+static const GdkColor default_link_color = { 0, 0, 0, 0xeeee };
+static const GdkColor default_visited_link_color = { 0, 0x5555, 0x1a1a, 0x8b8b };
 
-static GtkLinkButtonUriFunc uri_func = NULL;
-static gpointer uri_func_data = NULL;
-static GDestroyNotify uri_func_destroy = NULL;
+static guint link_signals[LAST_SIGNAL] = { 0, };
 
-G_DEFINE_TYPE (GtkLinkButton, gtk_link_button, GTK_TYPE_BUTTON);
+G_DEFINE_TYPE (GtkLinkButton, gtk_link_button, GTK_TYPE_BUTTON)
 
 static void
 gtk_link_button_class_init (GtkLinkButtonClass *klass)
@@ -122,15 +153,18 @@ gtk_link_button_class_init (GtkLinkButtonClass *klass)
   
   widget_class->button_press_event = gtk_link_button_button_press;
   widget_class->popup_menu = gtk_link_button_popup_menu;
-  widget_class->style_set = gtk_link_button_style_set;
+  widget_class->style_updated = gtk_link_button_style_updated;
+  widget_class->unrealize = gtk_link_button_unrealize;
   
   container_class->add = gtk_link_button_add;
 
   button_class->clicked = gtk_link_button_clicked;
 
+  klass->activate_link = gtk_link_button_activate_link;
+
   /**
-   * GtkLinkButton:uri
-   * 
+   * GtkLinkButton:uri:
+   *
    * The URI bound to this button.
    *
    * Since: 2.10
@@ -138,19 +172,61 @@ gtk_link_button_class_init (GtkLinkButtonClass *klass)
   g_object_class_install_property (gobject_class,
                                   PROP_URI,
                                   g_param_spec_string ("uri",
-                                                       _("URI"),
-                                                       _("The URI bound to this button"),
-                                                       "http://www.gtk.org",
+                                                       P_("URI"),
+                                                       P_("The URI bound to this button"),
+                                                       NULL,
                                                        G_PARAM_READWRITE));
+  /**
+   * GtkLinkButton:visited:
+   *
+   * The 'visited' state of this button. A visited link is drawn in a
+   * different color.
+   *
+   * Since: 2.14
+   */
+  g_object_class_install_property (gobject_class,
+                                  PROP_VISITED,
+                                  g_param_spec_boolean ("visited",
+                                                         P_("Visited"),
+                                                         P_("Whether this link has been visited."),
+                                                         FALSE,
+                                                         G_PARAM_READWRITE));
   
   g_type_class_add_private (gobject_class, sizeof (GtkLinkButtonPrivate));
+
+  /**
+   * GtkLinkButton::activate-link:
+   * @button: the #GtkLinkButton that emitted the signal
+   *
+   * The ::activate-link signal is emitted each time the #GtkLinkButton
+   * has been clicked.
+   *
+   * The default handler will call gtk_show_uri() with the URI stored inside
+   * the #GtkLinkButton:uri property.
+   *
+   * To override the default behavior, you can connect to the ::activate-link
+   * signal and stop the propagation of the signal by returning %TRUE from
+   * your handler.
+   */
+  link_signals[ACTIVATE_LINK] =
+    g_signal_new (I_("activate-link"),
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkLinkButtonClass, activate_link),
+                  _gtk_boolean_handled_accumulator, NULL,
+                  _gtk_marshal_BOOLEAN__VOID,
+                  G_TYPE_BOOLEAN, 0);
+
+  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_LINK_BUTTON_ACCESSIBLE);
 }
 
 static void
 gtk_link_button_init (GtkLinkButton *link_button)
 {
-  link_button->priv = GTK_LINK_BUTTON_GET_PRIVATE (link_button),
-  
+  link_button->priv = G_TYPE_INSTANCE_GET_PRIVATE (link_button,
+                                                   GTK_TYPE_LINK_BUTTON,
+                                                   GtkLinkButtonPrivate);
+
   gtk_button_set_relief (GTK_BUTTON (link_button), GTK_RELIEF_NONE);
   
   g_signal_connect (link_button, "enter-notify-event",
@@ -159,6 +235,10 @@ gtk_link_button_init (GtkLinkButton *link_button)
                    G_CALLBACK (gtk_link_button_leave_cb), NULL);
   g_signal_connect (link_button, "drag-data-get",
                    G_CALLBACK (gtk_link_button_drag_data_get_cb), NULL);
+
+  g_object_set (link_button, "has-tooltip", TRUE, NULL);
+  g_signal_connect (link_button, "query-tooltip",
+                    G_CALLBACK (gtk_link_button_query_tooltip_cb), NULL);
   
   /* enable drag source */
   gtk_drag_source_set (GTK_WIDGET (link_button),
@@ -190,6 +270,9 @@ gtk_link_button_get_property (GObject    *object,
     case PROP_URI:
       g_value_set_string (value, link_button->priv->uri);
       break;
+    case PROP_VISITED:
+      g_value_set_boolean (value, link_button->priv->visited);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -209,6 +292,9 @@ gtk_link_button_set_property (GObject      *object,
     case PROP_URI:
       gtk_link_button_set_uri (link_button, g_value_get_string (value));
       break;
+    case PROP_VISITED:
+      gtk_link_button_set_visited (link_button, g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -220,28 +306,35 @@ set_link_color (GtkLinkButton *link_button)
 {
   GdkColor *link_color = NULL;
   GtkWidget *label;
+  GdkRGBA rgba;
 
   label = gtk_bin_get_child (GTK_BIN (link_button));
+  if (!GTK_IS_LABEL (label))
+    return;
 
   if (link_button->priv->visited)
     {
-      gtk_widget_style_get (GTK_WIDGET (link_button), 
+      gtk_widget_style_get (GTK_WIDGET (link_button),
                            "visited-link-color", &link_color, NULL);
       if (!link_color)
-       link_color = &default_visited_link_color;
+       link_color = (GdkColor *) &default_visited_link_color;
     }
   else
     {
-      gtk_widget_style_get (GTK_WIDGET (link_button), 
+      gtk_widget_style_get (GTK_WIDGET (link_button),
                            "link-color", &link_color, NULL);
       if (!link_color)
-       link_color = &default_link_color;
+       link_color = (GdkColor *) &default_link_color;
     }
-  
-  gtk_widget_modify_fg (label, GTK_STATE_NORMAL, link_color);
-  gtk_widget_modify_fg (label, GTK_STATE_ACTIVE, link_color);
-  gtk_widget_modify_fg (label, GTK_STATE_PRELIGHT, link_color);
-  gtk_widget_modify_fg (label, GTK_STATE_SELECTED, link_color);
+
+  rgba.red = link_color->red / 65535.;
+  rgba.green = link_color->green / 65535.;
+  rgba.blue = link_color->blue / 65535.;
+  rgba.alpha = 1;
+  gtk_widget_override_color (label, GTK_STATE_FLAG_NORMAL, &rgba);
+  gtk_widget_override_color (label, GTK_STATE_FLAG_ACTIVE, &rgba);
+  gtk_widget_override_color (label, GTK_STATE_FLAG_PRELIGHT, &rgba);
+  gtk_widget_override_color (label, GTK_STATE_FLAG_SELECTED, &rgba);
 
   if (link_color != &default_link_color &&
       link_color != &default_visited_link_color)
@@ -265,6 +358,7 @@ set_link_underline (GtkLinkButton *link_button)
       attributes = pango_attr_list_new ();
       pango_attr_list_insert (attributes, uline); 
       gtk_label_set_attributes (GTK_LABEL (label), attributes);
+      pango_attr_list_unref (attributes);
     }
 }
 
@@ -274,16 +368,16 @@ gtk_link_button_add (GtkContainer *container,
 {
   GTK_CONTAINER_CLASS (gtk_link_button_parent_class)->add (container, widget);
 
+  set_link_color (GTK_LINK_BUTTON (container));
   set_link_underline (GTK_LINK_BUTTON (container));
 }
 
 static void
-gtk_link_button_style_set (GtkWidget *widget,
-                          GtkStyle  *old_style)
+gtk_link_button_style_updated (GtkWidget *widget)
 {
-  GtkLinkButton *link_button = GTK_LINK_BUTTON (widget);
+  GTK_WIDGET_CLASS (gtk_link_button_parent_class)->style_updated (widget);
 
-  set_link_color (link_button);
+  set_link_color (GTK_LINK_BUTTON (widget));
 }
 
 static void
@@ -299,11 +393,19 @@ set_hand_cursor (GtkWidget *widget,
   if (show_hand)
     cursor = gdk_cursor_new_for_display (display, GDK_HAND2);
 
-  gdk_window_set_cursor (widget->window, cursor);
+  gdk_window_set_cursor (gtk_widget_get_window (widget), cursor);
   gdk_display_flush (display);
 
   if (cursor)
-    gdk_cursor_unref (cursor);
+    g_object_unref (cursor);
+}
+
+static void
+gtk_link_button_unrealize (GtkWidget *widget)
+{
+  set_hand_cursor (widget, FALSE);
+
+  GTK_WIDGET_CLASS (gtk_link_button_parent_class)->unrealize (widget);
 }
 
 static void
@@ -324,24 +426,26 @@ popup_position_func (GtkMenu  *menu,
 {
   GtkLinkButton *link_button = GTK_LINK_BUTTON (user_data);
   GtkLinkButtonPrivate *priv = link_button->priv;
+  GtkAllocation allocation;
   GtkWidget *widget = GTK_WIDGET (link_button);
   GdkScreen *screen = gtk_widget_get_screen (widget);
   GtkRequisition req;
   gint monitor_num;
   GdkRectangle monitor;
   
-  g_return_if_fail (GTK_WIDGET_REALIZED (link_button));
+  g_return_if_fail (gtk_widget_get_realized (widget));
 
-  gdk_window_get_origin (widget->window, x, y);
+  gdk_window_get_origin (gtk_widget_get_window (widget), x, y);
 
-  gtk_widget_size_request (priv->popup_menu, &req);
+  gtk_widget_get_preferred_size (priv->popup_menu, &req, NULL);
 
-  *x += widget->allocation.width / 2;
-  *y += widget->allocation.height;
+  gtk_widget_get_allocation (widget, &allocation);
+  *x += allocation.width / 2;
+  *y += allocation.height;
 
   monitor_num = gdk_screen_get_monitor_at_point (screen, *x, *y);
   gtk_menu_set_monitor (menu, monitor_num);
-  gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
+  gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
 
   *x = CLAMP (*x, monitor.x, monitor.x + MAX (0, monitor.width - req.width));
   *y = CLAMP (*y, monitor.y, monitor.y + MAX (0, monitor.height - req.height));
@@ -379,7 +483,7 @@ gtk_link_button_do_popup (GtkLinkButton  *link_button,
       time = gtk_get_current_event_time ();
     }
 
-  if (GTK_WIDGET_REALIZED (link_button))
+  if (gtk_widget_get_realized (GTK_WIDGET (link_button)))
     {
       GtkWidget *menu_item;
       
@@ -419,33 +523,59 @@ static gboolean
 gtk_link_button_button_press (GtkWidget      *widget,
                              GdkEventButton *event)
 {
-  if (!GTK_WIDGET_HAS_FOCUS (widget))
+  if (!gtk_widget_has_focus (widget))
     gtk_widget_grab_focus (widget);
 
-  if ((event->button == 3) && (event->type == GDK_BUTTON_PRESS))
+  /* Don't popup the menu if there's no URI set,
+   * otherwise the menu item will trigger a warning */
+  if (gdk_event_triggers_context_menu ((GdkEvent *) event) &&
+      GTK_LINK_BUTTON (widget)->priv->uri != NULL)
     {
       gtk_link_button_do_popup (GTK_LINK_BUTTON (widget), event);
-      
+
       return TRUE;
     }
 
   if (GTK_WIDGET_CLASS (gtk_link_button_parent_class)->button_press_event)
-    return (* GTK_WIDGET_CLASS (gtk_link_button_parent_class)->button_press_event) (widget, event);
+    return GTK_WIDGET_CLASS (gtk_link_button_parent_class)->button_press_event (widget, event);
   
   return FALSE;
 }
 
-static void
-gtk_link_button_clicked (GtkButton *button)
+static gboolean
+gtk_link_button_activate_link (GtkLinkButton *link_button)
 {
-  GtkLinkButton *link_button = GTK_LINK_BUTTON (button);
+  GdkScreen *screen;
+  GError *error;
+
+  if (gtk_widget_has_screen (GTK_WIDGET (link_button)))
+    screen = gtk_widget_get_screen (GTK_WIDGET (link_button));
+  else
+    screen = NULL;
 
-  if (uri_func)
-    (* uri_func) (button, link_button->priv->uri, uri_func_data);
+  error = NULL;
+  gtk_show_uri (screen, link_button->priv->uri, GDK_CURRENT_TIME, &error);
+  if (error)
+    {
+      g_warning ("Unable to show '%s': %s",
+                 link_button->priv->uri,
+                 error->message);
+      g_error_free (error);
+
+      return FALSE;
+    }
 
-  link_button->priv->visited = TRUE;
+  gtk_link_button_set_visited (link_button, TRUE);
+
+  return TRUE;
+}
+
+static void
+gtk_link_button_clicked (GtkButton *button)
+{
+  gboolean retval = FALSE;
 
-  set_link_color (link_button);
+  g_signal_emit (button, link_signals[ACTIVATE_LINK], 0, &retval);
 }
 
 static gboolean
@@ -489,7 +619,7 @@ gtk_link_button_drag_data_get_cb (GtkWidget        *widget,
   
   uri = g_strdup_printf ("%s\r\n", link_button->priv->uri);
   gtk_selection_data_set (selection,
-                         selection->target,
+                          gtk_selection_data_get_target (selection),
                          8,
                          (guchar *) uri,
                          strlen (uri));
@@ -537,8 +667,8 @@ gtk_link_button_new (const gchar *uri)
     }
   
   retval = g_object_new (GTK_TYPE_LINK_BUTTON,
-                        "uri", uri,
                         "label", utf8_uri,
+                        "uri", uri,
                         NULL);
   
   g_free (utf8_uri);
@@ -549,11 +679,11 @@ gtk_link_button_new (const gchar *uri)
 /**
  * gtk_link_button_new_with_label:
  * @uri: a valid URI
- * @label: the text of the button
+ * @label: (allow-none): the text of the button
  *
  * Creates a new #GtkLinkButton containing a label.
  *
- * Return value: a new link button widget.
+ * Return value: (transfer none): a new link button widget.
  *
  * Since: 2.10
  */
@@ -576,12 +706,39 @@ gtk_link_button_new_with_label (const gchar *uri,
   return retval;
 }
 
+static gboolean 
+gtk_link_button_query_tooltip_cb (GtkWidget    *widget,
+                                  gint          x,
+                                  gint          y,
+                                  gboolean      keyboard_tip,
+                                  GtkTooltip   *tooltip,
+                                  gpointer      data)
+{
+  GtkLinkButton *link_button = GTK_LINK_BUTTON (widget);
+  const gchar *label, *uri;
+
+  label = gtk_button_get_label (GTK_BUTTON (link_button));
+  uri = link_button->priv->uri;
+
+  if (!gtk_widget_get_tooltip_text (widget)
+    && !gtk_widget_get_tooltip_markup (widget)
+    && label && *label != '\0' && uri && strcmp (label, uri) != 0)
+    {
+      gtk_tooltip_set_text (tooltip, uri);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+
 /**
  * gtk_link_button_set_uri:
  * @link_button: a #GtkLinkButton
  * @uri: a valid URI
  *
- * Sets @uri as the URI where the #GtkLinkButton points.
+ * Sets @uri as the URI where the #GtkLinkButton points. As a side-effect
+ * this unsets the 'visited' state of the button.
  *
  * Since: 2.10
  */
@@ -589,18 +746,19 @@ void
 gtk_link_button_set_uri (GtkLinkButton *link_button,
                         const gchar   *uri)
 {
-  gchar *tmp;
+  GtkLinkButtonPrivate *priv;
 
   g_return_if_fail (GTK_IS_LINK_BUTTON (link_button));
   g_return_if_fail (uri != NULL);
-  
-  tmp = link_button->priv->uri;
-  link_button->priv->uri = g_strdup (uri);
-  g_free (tmp);
 
-  link_button->priv->visited = FALSE;
-  
+  priv = link_button->priv;
+
+  g_free (priv->uri);
+  priv->uri = g_strdup (uri);
+
   g_object_notify (G_OBJECT (link_button), "uri");
+
+  gtk_link_button_set_visited (link_button, FALSE);
 }
 
 /**
@@ -614,7 +772,7 @@ gtk_link_button_set_uri (GtkLinkButton *link_button,
  *
  * Since: 2.10
  */
-G_CONST_RETURN gchar *
+const gchar *
 gtk_link_button_get_uri (GtkLinkButton *link_button)
 {
   g_return_val_if_fail (GTK_IS_LINK_BUTTON (link_button), NULL);
@@ -623,37 +781,51 @@ gtk_link_button_get_uri (GtkLinkButton *link_button)
 }
 
 /**
- * gtk_link_button_set_uri_hook:
- * @func: a function called each time a #GtkLinkButton is clicked, or %NULL
- * @data: user data to be passed to @func, or %NULL
- * @destroy: a #GDestroyNotify that gets called when @data is no longer needed, or %NULL
- *
- * Sets @func as the function that should be invoked every time a user clicks
- * a #GtkLinkButton. This function is called before every callback registered
- * for the "clicked" signal.
+ * gtk_link_button_set_visited:
+ * @link_button: a #GtkLinkButton
+ * @visited: the new 'visited' state
  *
- * Return value: the previously set hook function.
+ * Sets the 'visited' state of the URI where the #GtkLinkButton
+ * points.  See gtk_link_button_get_visited() for more details.
  *
- * Since: 2.10
+ * Since: 2.14
  */
-GtkLinkButtonUriFunc
-gtk_link_button_set_uri_hook (GtkLinkButtonUriFunc func,
-                             gpointer             data,
-                             GDestroyNotify       destroy)
+void
+gtk_link_button_set_visited (GtkLinkButton *link_button,
+                             gboolean       visited)
 {
-  GtkLinkButtonUriFunc old_uri_func;
+  g_return_if_fail (GTK_IS_LINK_BUTTON (link_button));
 
-  if (uri_func_destroy)
-    (* uri_func_destroy) (uri_func_data);
+  visited = visited != FALSE;
 
-  old_uri_func = uri_func;
+  if (link_button->priv->visited != visited)
+    {
+      link_button->priv->visited = visited;
 
-  uri_func = func;
-  uri_func_data = data;
-  uri_func_destroy = destroy;
+      set_link_color (link_button);
 
-  return old_uri_func;
+      g_object_notify (G_OBJECT (link_button), "visited");
+    }
 }
 
-#define __GTK_LINK_BUTTON_C__
-#include "gtkaliasdef.c"
+/**
+ * gtk_link_button_get_visited:
+ * @link_button: a #GtkLinkButton
+ *
+ * Retrieves the 'visited' state of the URI where the #GtkLinkButton
+ * points. The button becomes visited when it is clicked. If the URI
+ * is changed on the button, the 'visited' state is unset again.
+ *
+ * The state may also be changed using gtk_link_button_set_visited().
+ *
+ * Return value: %TRUE if the link has been visited, %FALSE otherwise
+ *
+ * Since: 2.14
+ */
+gboolean
+gtk_link_button_get_visited (GtkLinkButton *link_button)
+{
+  g_return_val_if_fail (GTK_IS_LINK_BUTTON (link_button), FALSE);
+  
+  return link_button->priv->visited;
+}