pidgin: e8a47ed8: Install a custom GtkIMHtml procol handle...
qulogic at pidgin.im
qulogic at pidgin.im
Tue Jul 7 02:35:37 EDT 2009
-----------------------------------------------------------------
Revision: e8a47ed8f3d26fc7dc9061c94197fa11562517f9
Ancestor: a85d02f1b4038b6a119e8a89cf5b6564ac2022d7
Author: qulogic at pidgin.im
Date: 2009-07-07T06:25:33
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/e8a47ed8f3d26fc7dc9061c94197fa11562517f9
Modified files:
pidgin/gtkutils.c
ChangeLog:
Install a custom GtkIMHtml procol handler for the "file://" type which
opens the file by default, and also has a menu for opening the file or the
directory that contains it.
Someone should figure out the correct handle to use for purple_notify_error
because GtkIMHtml doesn't close them (that I can see).
Fixes #8254.
-------------- next part --------------
============================================================
--- pidgin/gtkutils.c 372f8890135c07794106e97afcf9f8c08ccfbada
+++ pidgin/gtkutils.c 98499c6dce28d488dc575a3d17211451f7d1e511
@@ -3578,6 +3578,135 @@ copy_email_address(GtkIMHtml *imhtml, Gt
return TRUE;
}
+static void
+file_open_uri(GtkIMHtml *imhtml, const char *uri)
+{
+ /* Copied from gtkft.c:open_button_cb */
+#ifdef _WIN32
+ /* If using Win32... */
+ int code;
+ if (G_WIN32_HAVE_WIDECHAR_API()) {
+ wchar_t *wc_filename = g_utf8_to_utf16(
+ uri, -1, NULL, NULL, NULL);
+
+ code = (int)ShellExecuteW(NULL, NULL, wc_filename, NULL, NULL,
+ SW_SHOW);
+
+ g_free(wc_filename);
+ } else {
+ char *l_filename = g_locale_from_utf8(
+ uri, -1, NULL, NULL, NULL);
+
+ code = (int)ShellExecuteA(NULL, NULL, l_filename, NULL, NULL,
+ SW_SHOW);
+
+ g_free(l_filename);
+ }
+
+ if (code == SE_ERR_ASSOCINCOMPLETE || code == SE_ERR_NOASSOC)
+ {
+ purple_notify_error(imhtml, NULL,
+ _("There is no application configured to open this type of file."), NULL);
+ }
+ else if (code < 32)
+ {
+ purple_notify_error(imhtml, NULL,
+ _("An error occurred while opening the file."), NULL);
+ purple_debug_warning("gtkutils", "filename: %s; code: %d\n", uri, code);
+ }
+#else
+ char *command = NULL;
+ char *tmp = NULL;
+ GError *error = NULL;
+
+ if (purple_running_gnome())
+ {
+ char *escaped = g_shell_quote(uri);
+ command = g_strdup_printf("gnome-open %s", escaped);
+ g_free(escaped);
+ }
+ else if (purple_running_kde())
+ {
+ char *escaped = g_shell_quote(uri);
+
+ if (purple_str_has_suffix(uri, ".desktop"))
+ command = g_strdup_printf("kfmclient openURL %s 'text/plain'", escaped);
+ else
+ command = g_strdup_printf("kfmclient openURL %s", escaped);
+ g_free(escaped);
+ }
+ else
+ {
+ purple_notify_uri(NULL, uri);
+ return;
+ }
+
+ if (purple_program_is_valid(command))
+ {
+ gint exit_status;
+ if (!g_spawn_command_line_sync(command, NULL, NULL, &exit_status, &error))
+ {
+ tmp = g_strdup_printf(_("Error launching %s: %s"),
+ uri, error->message);
+ purple_notify_error(imhtml, NULL, _("Unable to open file."), tmp);
+ g_free(tmp);
+ g_error_free(error);
+ }
+ if (exit_status != 0)
+ {
+ char *primary = g_strdup_printf(_("Error running %s"), command);
+ char *secondary = g_strdup_printf(_("Process returned error code %d"),
+ exit_status);
+ purple_notify_error(imhtml, NULL, primary, secondary);
+ g_free(tmp);
+ }
+ }
+#endif
+}
+
+#define FILELINKSIZE (sizeof("file://") - 1)
+static gboolean
+file_clicked_cb(GtkIMHtml *imhtml, GtkIMHtmlLink *link)
+{
+ const char *uri = gtk_imhtml_link_get_url(link) + FILELINKSIZE;
+ file_open_uri(imhtml, uri);
+ return TRUE;
+}
+
+static gboolean
+open_containing_cb(GtkIMHtml *imhtml, const char *url)
+{
+ char *dir = g_path_get_dirname(url + FILELINKSIZE);
+ file_open_uri(imhtml, dir);
+ g_free(dir);
+ return TRUE;
+}
+
+static gboolean
+file_context_menu(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu)
+{
+ GtkWidget *img, *item;
+ const char *url;
+
+ url = gtk_imhtml_link_get_url(link);
+
+ /* Open File */
+ img = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU);
+ item = gtk_image_menu_item_new_with_mnemonic(_("_Open File"));
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img);
+ g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(gtk_imhtml_link_activate), link);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+
+ /* Open Containing Directory */
+ img = gtk_image_new_from_stock(GTK_STOCK_COPY, GTK_ICON_SIZE_MENU);
+ item = gtk_image_menu_item_new_with_mnemonic(_("Open _Containing Directory"));
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img);
+ g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(open_containing_cb), (gpointer)url);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+
+ return TRUE;
+}
+
/* XXX: The following two functions are for demonstration purposes only! */
static gboolean
open_dialog(GtkIMHtml *imhtml, GtkIMHtmlLink *link)
@@ -3684,6 +3813,8 @@ void pidgin_utils_init(void)
gtk_imhtml_class_register_protocol("gopher://", url_clicked_cb, link_context_menu);
gtk_imhtml_class_register_protocol("mailto:", url_clicked_cb, copy_email_address);
+ gtk_imhtml_class_register_protocol("file://", file_clicked_cb, file_context_menu);
+
/* Example custom URL handler. */
gtk_imhtml_class_register_protocol("open://", open_dialog, dummy);
More information about the Commits
mailing list