Commit ae94c371 authored by Matthias Clasen's avatar Matthias Clasen
Browse files

Add a separate keybinding signal for activating links

Keeping the keybinding signal and the regular signal separate is
cleaner and allows us to pass the uri as a parameter to the
activate-link signal.
parent 2f60e18c
...@@ -16,13 +16,10 @@ response_cb (GtkWidget *dialog, ...@@ -16,13 +16,10 @@ response_cb (GtkWidget *dialog,
} }
static gboolean static gboolean
activate_link (GtkWidget *label, activate_link (GtkWidget *label,
gpointer data) const gchar *uri,
gpointer data)
{ {
const gchar *uri;
uri = gtk_label_get_current_uri (GTK_LABEL (label));
if (g_strcmp0 (uri, "keynav") == 0) if (g_strcmp0 (uri, "keynav") == 0)
{ {
GtkWidget *dialog; GtkWidget *dialog;
......
...@@ -18,9 +18,7 @@ ...@@ -18,9 +18,7 @@
<para> <para>
One difference between the two APIs is that the ::url-activated signal One difference between the two APIs is that the ::url-activated signal
from SexyUrlLabel has been replaced by the #GtkLabel::activate-link from SexyUrlLabel has been replaced by the #GtkLabel::activate-link
signal. The activated URI is no longer passed as an argument to the signal. The need for connecting to this signal is greatly reduced,
signal handler. Instead, call gtk_label_get_current_uri() to obtain it.
However, the need for connecting to this signal is greatly reduced,
since GtkLabel has a default handler that calls gtk_show_uri(). since GtkLabel has a default handler that calls gtk_show_uri().
</para> </para>
</chapter> </chapter>
...@@ -174,8 +174,8 @@ attribute is displayed as a tooltip on the link. An example looks like this: ...@@ -174,8 +174,8 @@ attribute is displayed as a tooltip on the link. An example looks like this:
<informalexample><programlisting> <informalexample><programlisting>
gtk_label_set_markup (label, "Go to the &lt;a href=\"http://www.gtk.org\" title=\"&amp;lt;i&amp;gt;Our&amp;/i&amp;gt; website\"&gt;GTK+ website</a> for more..."); gtk_label_set_markup (label, "Go to the &lt;a href=\"http://www.gtk.org\" title=\"&amp;lt;i&amp;gt;Our&amp;/i&amp;gt; website\"&gt;GTK+ website</a> for more...");
</programlisting></informalexample> </programlisting></informalexample>
It is possible to implement custom handling for links with the It is possible to implement custom handling for links and their tooltips with
#GtkLabel::activate-link signal and the gtk_label_get_current_uri() function. the #GtkLabel::activate-link signal and the gtk_label_get_current_uri() function.
</para> </para>
</refsect2> </refsect2>
......
...@@ -124,6 +124,7 @@ enum { ...@@ -124,6 +124,7 @@ enum {
COPY_CLIPBOARD, COPY_CLIPBOARD,
POPULATE_POPUP, POPULATE_POPUP,
ACTIVATE_LINK, ACTIVATE_LINK,
ACTIVATE_CURRENT_LINK,
LAST_SIGNAL LAST_SIGNAL
}; };
...@@ -279,11 +280,15 @@ static gint gtk_label_move_backward_word (GtkLabel *label, ...@@ -279,11 +280,15 @@ static gint gtk_label_move_backward_word (GtkLabel *label,
/* For links: */ /* For links: */
static void gtk_label_rescan_links (GtkLabel *label); static void gtk_label_rescan_links (GtkLabel *label);
static void gtk_label_clear_links (GtkLabel *label); static void gtk_label_clear_links (GtkLabel *label);
static gboolean gtk_label_activate_link (GtkLabel *label); static gboolean gtk_label_activate_link (GtkLabel *label,
const gchar *uri);
static void gtk_label_activate_current_link (GtkLabel *label);
static GtkLabelLink *gtk_label_get_current_link (GtkLabel *label); static GtkLabelLink *gtk_label_get_current_link (GtkLabel *label);
static void gtk_label_get_link_colors (GtkWidget *widget, static void gtk_label_get_link_colors (GtkWidget *widget,
GdkColor **link_color, GdkColor **link_color,
GdkColor **visited_link_color); GdkColor **visited_link_color);
static void emit_activate_link (GtkLabel *label,
GtkLabelLink *link);
static GQuark quark_angle = 0; static GQuark quark_angle = 0;
...@@ -440,21 +445,37 @@ gtk_label_class_init (GtkLabelClass *class) ...@@ -440,21 +445,37 @@ gtk_label_class_init (GtkLabelClass *class)
GTK_TYPE_MENU); GTK_TYPE_MENU);
/** /**
* GtkLabel::activate-link: * GtkLabel::activate-current-link:
* @label: The label on which the signal was emitted. * @label: The label on which the signal was emitted
* *
* A <link linkend="keybinding-signals">keybinding signal</link> * A <link linkend="keybinding-signals">keybinding signal</link>
* which gets emitted when the user activates a link in the label. * which gets emitted when the user activates a link in the label.
* *
* Applications may connect to it to override the default behaviour,
* which is to call gtk_show_uri(). To obtain the URI that is being
* activated, use gtk_label_get_current_uri().
*
* Applications may also emit the signal with g_signal_emit_by_name() * Applications may also emit the signal with g_signal_emit_by_name()
* if they need to control activation of URIs programmatically. * if they need to control activation of URIs programmatically.
* *
* The default bindings for this signal are all forms of the Enter key. * The default bindings for this signal are all forms of the Enter key.
* *
* Since: 2.18
*/
signals[ACTIVATE_CURRENT_LINK] =
g_signal_new_class_handler ("activate-current-link",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_CALLBACK (gtk_label_activate_current_link),
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* GtkLabel::activate-link:
* @label: The label on which the signal was emitted
* @uri: the URI that is activated
*
* The signal which gets emitted to activate a URI.
* Applications may connect to it to override the default behaviour,
* which is to call gtk_show_uri().
*
* Returns: %TRUE if the link has been activated * Returns: %TRUE if the link has been activated
* *
* Since: 2.18 * Since: 2.18
...@@ -462,11 +483,11 @@ gtk_label_class_init (GtkLabelClass *class) ...@@ -462,11 +483,11 @@ gtk_label_class_init (GtkLabelClass *class)
signals[ACTIVATE_LINK] = signals[ACTIVATE_LINK] =
g_signal_new ("activate-link", g_signal_new ("activate-link",
G_TYPE_FROM_CLASS (object_class), G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkLabelClass, activate_link), G_STRUCT_OFFSET (GtkLabelClass, activate_link),
_gtk_boolean_handled_accumulator, NULL, _gtk_boolean_handled_accumulator, NULL,
_gtk_marshal_BOOLEAN__VOID, _gtk_marshal_BOOLEAN__STRING,
G_TYPE_BOOLEAN, 0); G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_LABEL, PROP_LABEL,
...@@ -799,11 +820,11 @@ gtk_label_class_init (GtkLabelClass *class) ...@@ -799,11 +820,11 @@ gtk_label_class_init (GtkLabelClass *class)
"copy-clipboard", 0); "copy-clipboard", 0);
gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
"activate-link", 0); "activate-current-link", 0);
gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0, gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
"activate-link", 0); "activate-current-link", 0);
gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
"activate-link", 0); "activate-current-link", 0);
gtk_settings_install_property (g_param_spec_boolean ("gtk-label-select-on-focus", gtk_settings_install_property (g_param_spec_boolean ("gtk-label-select-on-focus",
P_("Select on focus"), P_("Select on focus"),
...@@ -4105,16 +4126,7 @@ gtk_label_button_release (GtkWidget *widget, ...@@ -4105,16 +4126,7 @@ gtk_label_button_release (GtkWidget *widget,
info->selection_anchor == info->selection_end && info->selection_anchor == info->selection_end &&
info->link_clicked) info->link_clicked)
{ {
gboolean handled; emit_activate_link (label, info->active_link);
g_signal_emit (label, signals[ACTIVATE_LINK], 0, &handled);
if (handled && !info->active_link->visited)
{
info->active_link->visited = TRUE;
/* FIXME: shouldn't have to redo everything here */
gtk_label_recalculate (label);
}
info->link_clicked = 0; info->link_clicked = 0;
return TRUE; return TRUE;
...@@ -5406,20 +5418,11 @@ open_link_activate_cb (GtkMenuItem *menu_item, ...@@ -5406,20 +5418,11 @@ open_link_activate_cb (GtkMenuItem *menu_item,
GtkLabel *label) GtkLabel *label)
{ {
GtkLabelLink *link; GtkLabelLink *link;
gboolean handled;
link = gtk_label_get_current_link (label); link = gtk_label_get_current_link (label);
if (link) if (link)
{ emit_activate_link (label, link);
g_signal_emit (label, signals[ACTIVATE_LINK], 0, &handled);
if (handled && !link->visited)
{
link->visited = TRUE;
/* FIXME: shouldn't have to redo everything here */
gtk_label_recalculate (label);
}
}
} }
static void static void
...@@ -5608,25 +5611,48 @@ gtk_label_rescan_links (GtkLabel *label) ...@@ -5608,25 +5611,48 @@ gtk_label_rescan_links (GtkLabel *label)
} }
static gboolean static gboolean
gtk_label_activate_link (GtkLabel *label) gtk_label_activate_link (GtkLabel *label,
const gchar *uri)
{ {
GtkWidget *widget = GTK_WIDGET (label); GtkWidget *widget = GTK_WIDGET (label);
GtkLabelLink *link;
const gchar *uri;
GError *error = NULL; GError *error = NULL;
link = gtk_label_get_current_link (label); if (!gtk_show_uri (gtk_widget_get_screen (widget),
uri, gtk_get_current_event_time (), &error))
{
g_warning ("Unable to show '%s': %s", uri, error->message);
g_error_free (error);
}
if (link) return TRUE;
}
static void
emit_activate_link (GtkLabel *label,
GtkLabelLink *link)
{
gboolean handled;
g_signal_emit (label, signals[ACTIVATE_LINK], 0, link->uri, &handled);
if (handled && !link->visited)
{ {
uri = link->uri; link->visited = TRUE;
/* FIXME: shouldn't have to redo everything here */
gtk_label_recalculate (label);
}
}
if (!gtk_show_uri (gtk_widget_get_screen (widget), static void
uri, gtk_get_current_event_time (), &error)) gtk_label_activate_current_link (GtkLabel *label)
{ {
g_warning ("Unable to show '%s': %s", uri, error->message); GtkLabelLink *link;
g_error_free (error); GtkWidget *widget = GTK_WIDGET (label);
}
link = gtk_label_get_focus_link (label);
if (link)
{
emit_activate_link (label, link);
} }
else else
{ {
...@@ -5645,8 +5671,6 @@ gtk_label_activate_link (GtkLabel *label) ...@@ -5645,8 +5671,6 @@ gtk_label_activate_link (GtkLabel *label)
gtk_window_activate_default (window); gtk_window_activate_default (window);
} }
} }
return TRUE;
} }
static GtkLabelLink * static GtkLabelLink *
......
...@@ -96,7 +96,8 @@ struct _GtkLabelClass ...@@ -96,7 +96,8 @@ struct _GtkLabelClass
void (* populate_popup) (GtkLabel *label, void (* populate_popup) (GtkLabel *label,
GtkMenu *menu); GtkMenu *menu);
gboolean (*activate_link) (GtkLabel *label); gboolean (*activate_link) (GtkLabel *label,
const gchar *uri);
/* Padding for future expansion */ /* Padding for future expansion */
void (*_gtk_reserved1) (void); void (*_gtk_reserved1) (void);
......
...@@ -2976,12 +2976,8 @@ dialog_response (GtkWidget *dialog, gint response_id, GtkLabel *label) ...@@ -2976,12 +2976,8 @@ dialog_response (GtkWidget *dialog, gint response_id, GtkLabel *label)
} }
static gboolean static gboolean
activate_link (GtkWidget *label, gpointer data) activate_link (GtkWidget *label, const gchar *uri, gpointer data)
{ {
const gchar *uri;
uri = gtk_label_get_current_uri (GTK_LABEL (label));
if (g_strcmp0 (uri, "keynav") == 0) if (g_strcmp0 (uri, "keynav") == 0)
{ {
GtkWidget *dialog; GtkWidget *dialog;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment