From 405955749103dcfdf582b6ae4f053c66837a6281 Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Fri, 3 Apr 2009 02:10:55 +0200 Subject: [PATCH] Add default URL and Email hooks to GtkAboutDialog Adds default URL and Email hooks which use gtk_show_uri(). It is still possible to provide one's own hooks, and one can disable the default hooks by setting NULL hooks. Bug #577793. --- docs/reference/gtk/tmpl/gtkaboutdialog.sgml | 12 +- gtk/gtkaboutdialog.c | 126 ++++++++++++++++++-- 2 files changed, 121 insertions(+), 17 deletions(-) diff --git a/docs/reference/gtk/tmpl/gtkaboutdialog.sgml b/docs/reference/gtk/tmpl/gtkaboutdialog.sgml index ebecec0b4e..6aac589c90 100644 --- a/docs/reference/gtk/tmpl/gtkaboutdialog.sgml +++ b/docs/reference/gtk/tmpl/gtkaboutdialog.sgml @@ -24,16 +24,20 @@ recognized by looking for http://url, with url extending to the next space, tab or line break. -When setting the website and email hooks for the #GtkAboutDialog widget, -you should remember that the order is important: you should set the hook -functions before setting the website and email URL properties, like this: +Since 2.18 #GtkAboutDialog provides default website and email hooks that use +gtk_show_uri(). + + +If you want provide your own hooks overriding the default ones, it is important +to do so before setting the website and email URL properties, like this: gtk_about_dialog_set_url_hook (GTK_ABOUT_DIALOG (dialog), launch_url, NULL, NULL); gtk_about_dialog_set_website (GTK_ABOUT_DIALOG (dialog), app_url); -Otherwise the GtkAboutDialog widget will not display the website and the +To disable the default hooks, you can pass %NULL as the hook func. Then, +the #GtkAboutDialog widget will not display the website or the email addresses as clickable. diff --git a/gtk/gtkaboutdialog.c b/gtk/gtkaboutdialog.c index 349d35e276..5b5dbabeb9 100644 --- a/gtk/gtkaboutdialog.c +++ b/gtk/gtkaboutdialog.c @@ -49,6 +49,9 @@ #include "gtktextview.h" #include "gtkvbox.h" #include "gtkiconfactory.h" +#include "gtkshow.h" +#include "gtkmain.h" +#include "gtkmessagedialog.h" #include "gtkprivate.h" #include "gtkintl.h" @@ -142,16 +145,68 @@ static void display_credits_dialog (GtkWidget static void display_license_dialog (GtkWidget *button, gpointer data); static void close_cb (GtkAboutDialog *about); - - +static void default_url_hook (GtkAboutDialog *about, + const gchar *uri, + gpointer user_data); +static void default_email_hook (GtkAboutDialog *about, + const gchar *email_address, + gpointer user_data); + +static gboolean activate_email_hook_set = FALSE; static GtkAboutDialogActivateLinkFunc activate_email_hook = NULL; static gpointer activate_email_hook_data = NULL; static GDestroyNotify activate_email_hook_destroy = NULL; +static gboolean activate_url_hook_set = FALSE; static GtkAboutDialogActivateLinkFunc activate_url_hook = NULL; static gpointer activate_url_hook_data = NULL; static GDestroyNotify activate_url_hook_destroy = NULL; +static void +default_url_hook (GtkAboutDialog *about, + const gchar *uri, + gpointer user_data G_GNUC_UNUSED) +{ + GdkScreen *screen; + GError *error = NULL; + + screen = gtk_widget_get_screen (GTK_WIDGET (about)); + + if (!gtk_show_uri (screen, uri, gtk_get_current_event_time (), &error)) { + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (GTK_WINDOW (about), + GTK_DIALOG_DESTROY_WITH_PARENT | + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "%s", _("Could not show link")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + "%s", error->message); + g_error_free (error); + + g_signal_connect (dialog, "response", + G_CALLBACK (gtk_widget_destroy), NULL); + + gtk_window_present (GTK_WINDOW (dialog)); + } +} + +static void +default_email_hook (GtkAboutDialog *about, + const gchar *email_address, + gpointer user_data) +{ + char *escaped, *uri; + + escaped = g_uri_escape_string (email_address, NULL, FALSE); + uri = g_strdup_printf ("mailto:%s", escaped); + g_free (escaped); + + default_url_hook (about, uri, user_data); + g_free (uri); +} + G_DEFINE_TYPE (GtkAboutDialog, gtk_about_dialog, GTK_TYPE_DIALOG) static void @@ -688,7 +743,7 @@ update_website (GtkAboutDialog *about) { GtkAboutDialogPrivate *priv = (GtkAboutDialogPrivate *)about->private_data; - if (priv->website_url && activate_url_hook) + if (priv->website_url && (!activate_url_hook_set || activate_url_hook != NULL)) { gtk_widget_show (priv->website_button); gtk_widget_hide (priv->website_label); @@ -1647,9 +1702,22 @@ activate_url (GtkWidget *widget, { GtkAboutDialog *about = GTK_ABOUT_DIALOG (data); const gchar *url = gtk_link_button_get_uri (GTK_LINK_BUTTON (widget)); - - if (activate_url_hook != NULL) - (* activate_url_hook) (about, url, activate_url_hook_data); + GtkAboutDialogActivateLinkFunc url_hook; + gpointer url_hook_data; + + if (activate_url_hook_set) + { + url_hook = activate_url_hook; + url_hook_data = activate_url_hook_data; + } + else + { + url_hook = default_url_hook; + url_hook_data = NULL; + } + + if (url_hook) + url_hook (about, url, url_hook_data); } static void @@ -1660,24 +1728,48 @@ follow_if_link (GtkAboutDialog *about, GSList *tags = NULL, *tagp = NULL; GtkAboutDialogPrivate *priv = (GtkAboutDialogPrivate *)about->private_data; gchar *url = NULL; + GtkAboutDialogActivateLinkFunc email_hook, url_hook; + gpointer email_hook_data, url_hook_data; + + if (activate_email_hook_set) + { + email_hook = activate_email_hook; + email_hook_data = activate_email_hook_data; + } + else + { + email_hook = default_email_hook; + email_hook_data = NULL; + } + + if (activate_url_hook_set) + { + url_hook = activate_url_hook; + url_hook_data = activate_url_hook_data; + } + else + { + url_hook = default_url_hook; + url_hook_data = NULL; + } tags = gtk_text_iter_get_tags (iter); for (tagp = tags; tagp != NULL && !url; tagp = tagp->next) { GtkTextTag *tag = tagp->data; - if (activate_email_hook != NULL) + if (email_hook != NULL) { url = g_object_get_data (G_OBJECT (tag), "email"); - if (url) - (* activate_email_hook) (about, url, activate_email_hook_data); + if (url) + email_hook (about, url, email_hook_data); } - if (!url && activate_url_hook != NULL) + if (!url && url_hook != NULL) { url = g_object_get_data (G_OBJECT (tag), "url"); if (url) - (* activate_url_hook) (about, url, activate_url_hook_data); + url_hook (about, url, url_hook_data); } if (url && !g_slist_find_custom (priv->visited_links, url, (GCompareFunc)strcmp)) @@ -1866,8 +1958,8 @@ text_view_new (GtkAboutDialog *about, GdkColor visited_link_color; GtkAboutDialogPrivate *priv = (GtkAboutDialogPrivate *)about->private_data; - linkify_email = (activate_email_hook != NULL); - linkify_urls = (activate_url_hook != NULL); + linkify_email = (!activate_email_hook_set || activate_email_hook != NULL); + linkify_urls = (!activate_url_hook_set || activate_url_hook != NULL); gtk_widget_ensure_style (GTK_WIDGET (about)); gtk_widget_style_get (GTK_WIDGET (about), @@ -2176,6 +2268,9 @@ gtk_about_dialog_new (void) * * Installs a global function to be called whenever the user activates an * email link in an about dialog. + * + * Since 2.18 there exists a default function which uses gtk_show_uri(). To + * deactivate it, you can pass %NULL for @func. * * Return value: the previous email hook. * @@ -2193,6 +2288,7 @@ gtk_about_dialog_set_email_hook (GtkAboutDialogActivateLinkFunc func, old = activate_email_hook; + activate_email_hook_set = TRUE; activate_email_hook = func; activate_email_hook_data = data; activate_email_hook_destroy = destroy; @@ -2209,6 +2305,9 @@ gtk_about_dialog_set_email_hook (GtkAboutDialogActivateLinkFunc func, * Installs a global function to be called whenever the user activates a * URL link in an about dialog. * + * Since 2.18 here exists a default function which uses gtk_show_uri(). To + * deactivate it, you can pass %NULL for @func. + * * Return value: the previous URL hook. * * Since: 2.6 @@ -2225,6 +2324,7 @@ gtk_about_dialog_set_url_hook (GtkAboutDialogActivateLinkFunc func, old = activate_url_hook; + activate_url_hook_set = TRUE; activate_url_hook = func; activate_url_hook_data = data; activate_url_hook_destroy = destroy;