Mercurial > pidgin.yaz
comparison pidgin/gtkutils.c @ 29471:d83ee160ffb6
propagate from branch 'im.pidgin.pidgin' (head eb9385f349a20856b9d3f9911dbc8024caa44052)
to branch 'im.pidgin.pidgin.next.minor' (head 439fb2dd7a285d9ca645f65f36ef0f037abe7311)
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Wed, 19 Aug 2009 00:46:04 +0000 |
parents | d4036e0f58d6 |
children | dfd8d82313be 07718e5eb8ce 2dcff225172e |
comparison
equal
deleted
inserted
replaced
29470:7a3458436140 | 29471:d83ee160ffb6 |
---|---|
52 #include "notify.h" | 52 #include "notify.h" |
53 #include "prefs.h" | 53 #include "prefs.h" |
54 #include "prpl.h" | 54 #include "prpl.h" |
55 #include "request.h" | 55 #include "request.h" |
56 #include "signals.h" | 56 #include "signals.h" |
57 #include "sound.h" | |
57 #include "util.h" | 58 #include "util.h" |
58 | 59 |
59 #include "gtkaccount.h" | 60 #include "gtkaccount.h" |
60 #include "gtkprefs.h" | 61 #include "gtkprefs.h" |
61 | 62 |
356 pidgin_set_accessible_label (menuitem, label); | 357 pidgin_set_accessible_label (menuitem, label); |
357 return menuitem; | 358 return menuitem; |
358 } | 359 } |
359 | 360 |
360 GtkWidget *pidgin_new_check_item(GtkWidget *menu, const char *str, | 361 GtkWidget *pidgin_new_check_item(GtkWidget *menu, const char *str, |
361 GtkSignalFunc sf, gpointer data, gboolean checked) | 362 GCallback cb, gpointer data, gboolean checked) |
362 { | 363 { |
363 GtkWidget *menuitem; | 364 GtkWidget *menuitem; |
364 menuitem = gtk_check_menu_item_new_with_mnemonic(str); | 365 menuitem = gtk_check_menu_item_new_with_mnemonic(str); |
365 | 366 |
366 if (menu) | 367 if (menu) |
367 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | 368 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
368 | 369 |
369 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), checked); | 370 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), checked); |
370 | 371 |
371 if (sf) | 372 if (cb) |
372 g_signal_connect(G_OBJECT(menuitem), "activate", sf, data); | 373 g_signal_connect(G_OBJECT(menuitem), "activate", cb, data); |
373 | 374 |
374 gtk_widget_show_all(menuitem); | 375 gtk_widget_show_all(menuitem); |
375 | 376 |
376 return menuitem; | 377 return menuitem; |
377 } | 378 } |
437 | 438 |
438 return button; | 439 return button; |
439 } | 440 } |
440 | 441 |
441 | 442 |
442 GtkWidget *pidgin_new_item_from_stock(GtkWidget *menu, const char *str, const char *icon, GtkSignalFunc sf, gpointer data, guint accel_key, guint accel_mods, char *mod) | 443 GtkWidget *pidgin_new_item_from_stock(GtkWidget *menu, const char *str, const char *icon, GCallback cb, gpointer data, guint accel_key, guint accel_mods, char *mod) |
443 { | 444 { |
444 GtkWidget *menuitem; | 445 GtkWidget *menuitem; |
445 /* | 446 /* |
446 GtkWidget *hbox; | 447 GtkWidget *hbox; |
447 GtkWidget *label; | 448 GtkWidget *label; |
454 menuitem = gtk_image_menu_item_new_with_mnemonic(str); | 455 menuitem = gtk_image_menu_item_new_with_mnemonic(str); |
455 | 456 |
456 if (menu) | 457 if (menu) |
457 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); | 458 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); |
458 | 459 |
459 if (sf) | 460 if (cb) |
460 g_signal_connect(G_OBJECT(menuitem), "activate", sf, data); | 461 g_signal_connect(G_OBJECT(menuitem), "activate", cb, data); |
461 | 462 |
462 if (icon != NULL) { | 463 if (icon != NULL) { |
463 image = gtk_image_new_from_stock(icon, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); | 464 image = gtk_image_new_from_stock(icon, gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); |
464 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); | 465 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); |
465 } | 466 } |
523 { | 524 { |
524 GtkWidget *menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)); | 525 GtkWidget *menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(optmenu)); |
525 GtkWidget *item = gtk_menu_get_active(GTK_MENU(menu)); | 526 GtkWidget *item = gtk_menu_get_active(GTK_MENU(menu)); |
526 if (p_item) | 527 if (p_item) |
527 (*p_item) = item; | 528 (*p_item) = item; |
528 return g_object_get_data(G_OBJECT(item), "aop_per_item_data"); | 529 return item ? g_object_get_data(G_OBJECT(item), "aop_per_item_data") : NULL; |
529 } | 530 } |
530 | 531 |
531 static void | 532 static void |
532 aop_menu_cb(GtkWidget *optmenu, GCallback cb) | 533 aop_menu_cb(GtkWidget *optmenu, GCallback cb) |
533 { | 534 { |
948 { | 949 { |
949 purple_debug(PURPLE_DEBUG_MISC, "accels", | 950 purple_debug(PURPLE_DEBUG_MISC, "accels", |
950 "accel changed, scheduling save.\n"); | 951 "accel changed, scheduling save.\n"); |
951 | 952 |
952 if (!accels_save_timer) | 953 if (!accels_save_timer) |
953 accels_save_timer = g_timeout_add(5000, pidgin_save_accels, | 954 accels_save_timer = purple_timeout_add_seconds(5, pidgin_save_accels, |
954 NULL); | 955 NULL); |
955 } | 956 } |
956 | 957 |
957 gboolean | 958 gboolean |
958 pidgin_save_accels(gpointer data) | 959 pidgin_save_accels(gpointer data) |
1462 purple_notify_error(NULL, NULL, | 1463 purple_notify_error(NULL, NULL, |
1463 _("Failed to load image"), | 1464 _("Failed to load image"), |
1464 str); | 1465 str); |
1465 g_free(str); | 1466 g_free(str); |
1466 | 1467 |
1467 return; | 1468 break; |
1468 } | 1469 } |
1469 | 1470 |
1470 buddy = purple_find_buddy(data->account, data->who); | 1471 buddy = purple_find_buddy(data->account, data->who); |
1471 if (!buddy) { | 1472 if (!buddy) { |
1472 purple_debug_info("custom-icon", "You can only set custom icons for people on your buddylist.\n"); | 1473 purple_debug_info("custom-icon", "You can only set custom icons for people on your buddylist.\n"); |
1492 str); | 1493 str); |
1493 | 1494 |
1494 g_error_free(err); | 1495 g_error_free(err); |
1495 g_free(str); | 1496 g_free(str); |
1496 | 1497 |
1497 return; | 1498 break; |
1498 } | 1499 } |
1499 id = purple_imgstore_add_with_id(filedata, size, data->filename); | 1500 id = purple_imgstore_add_with_id(filedata, size, data->filename); |
1500 | 1501 |
1501 gtk_text_buffer_get_iter_at_mark(GTK_IMHTML(gtkconv->entry)->text_buffer, &iter, | 1502 gtk_text_buffer_get_iter_at_mark(GTK_IMHTML(gtkconv->entry)->text_buffer, &iter, |
1502 gtk_text_buffer_get_insert(GTK_IMHTML(gtkconv->entry)->text_buffer)); | 1503 gtk_text_buffer_get_insert(GTK_IMHTML(gtkconv->entry)->text_buffer)); |
1625 account, who, NULL, | 1626 account, who, NULL, |
1626 data, | 1627 data, |
1627 _("Set as buddy icon"), DND_BUDDY_ICON, | 1628 _("Set as buddy icon"), DND_BUDDY_ICON, |
1628 (ft ? _("Send image file") : _("Insert in message")), (ft ? DND_FILE_TRANSFER : DND_IM_IMAGE), | 1629 (ft ? _("Send image file") : _("Insert in message")), (ft ? DND_FILE_TRANSFER : DND_IM_IMAGE), |
1629 NULL); | 1630 NULL); |
1630 gdk_pixbuf_unref(pb); | 1631 g_object_unref(G_OBJECT(pb)); |
1631 return; | 1632 return; |
1632 } | 1633 } |
1633 | 1634 |
1634 #ifndef _WIN32 | 1635 #ifndef _WIN32 |
1635 /* Are we trying to send a .desktop file? */ | 1636 /* Are we trying to send a .desktop file? */ |
1675 /* I don't know if we really want to do anything here. Most of the desktop item types are crap like | 1676 /* I don't know if we really want to do anything here. Most of the desktop item types are crap like |
1676 * "MIME Type" (I have no clue how that would be a desktop item) and "Comment"... nothing we can really | 1677 * "MIME Type" (I have no clue how that would be a desktop item) and "Comment"... nothing we can really |
1677 * send. The only logical one is "Application," but do we really want to send a binary and nothing else? | 1678 * send. The only logical one is "Application," but do we really want to send a binary and nothing else? |
1678 * Probably not. I'll just give an error and return. */ | 1679 * Probably not. I'll just give an error and return. */ |
1679 /* The original patch sent the icon used by the launcher. That's probably wrong */ | 1680 /* The original patch sent the icon used by the launcher. That's probably wrong */ |
1680 purple_notify_error(NULL, NULL, _("Cannot send launcher"), _("You dragged a desktop launcher. " | 1681 purple_notify_error(NULL, NULL, _("Cannot send launcher"), |
1681 "Most likely you wanted to send whatever this launcher points to instead of this launcher" | 1682 _("You dragged a desktop launcher. Most " |
1682 " itself.")); | 1683 "likely you wanted to send the target " |
1684 "of this launcher instead of this " | |
1685 "launcher itself.")); | |
1683 break; | 1686 break; |
1684 } | 1687 } |
1685 purple_desktop_item_unref(item); | 1688 purple_desktop_item_unref(item); |
1686 return; | 1689 return; |
1687 } | 1690 } |
1713 | 1716 |
1714 GdkPixbuf * pidgin_create_status_icon(PurpleStatusPrimitive prim, GtkWidget *w, const char *size) | 1717 GdkPixbuf * pidgin_create_status_icon(PurpleStatusPrimitive prim, GtkWidget *w, const char *size) |
1715 { | 1718 { |
1716 GtkIconSize icon_size = gtk_icon_size_from_name(size); | 1719 GtkIconSize icon_size = gtk_icon_size_from_name(size); |
1717 GdkPixbuf *pixbuf = NULL; | 1720 GdkPixbuf *pixbuf = NULL; |
1718 | 1721 const char *stock = pidgin_stock_id_from_status_primitive(prim); |
1719 if (prim == PURPLE_STATUS_UNAVAILABLE) | 1722 |
1720 pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_BUSY, | 1723 pixbuf = gtk_widget_render_icon (w, stock ? stock : PIDGIN_STOCK_STATUS_AVAILABLE, |
1721 icon_size, "GtkWidget"); | 1724 icon_size, "GtkWidget"); |
1722 else if (prim == PURPLE_STATUS_AWAY) | |
1723 pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_AWAY, | |
1724 icon_size, "GtkWidget"); | |
1725 else if (prim == PURPLE_STATUS_EXTENDED_AWAY) | |
1726 pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_XA, | |
1727 icon_size, "GtkWidget"); | |
1728 else if (prim == PURPLE_STATUS_INVISIBLE) | |
1729 pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_INVISIBLE, | |
1730 icon_size, "GtkWidget"); | |
1731 else if (prim == PURPLE_STATUS_OFFLINE) | |
1732 pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_OFFLINE, | |
1733 icon_size, "GtkWidget"); | |
1734 else | |
1735 pixbuf = gtk_widget_render_icon (w, PIDGIN_STOCK_STATUS_AVAILABLE, | |
1736 icon_size, "GtkWidget"); | |
1737 return pixbuf; | 1725 return pixbuf; |
1738 | 1726 } |
1739 } | 1727 |
1740 | 1728 static const char * |
1729 stock_id_from_status_primitive_idle(PurpleStatusPrimitive prim, gboolean idle) | |
1730 { | |
1731 const char *stock = NULL; | |
1732 switch (prim) { | |
1733 case PURPLE_STATUS_UNSET: | |
1734 stock = NULL; | |
1735 break; | |
1736 case PURPLE_STATUS_UNAVAILABLE: | |
1737 stock = idle ? PIDGIN_STOCK_STATUS_BUSY_I : PIDGIN_STOCK_STATUS_BUSY; | |
1738 break; | |
1739 case PURPLE_STATUS_AWAY: | |
1740 stock = idle ? PIDGIN_STOCK_STATUS_AWAY_I : PIDGIN_STOCK_STATUS_AWAY; | |
1741 break; | |
1742 case PURPLE_STATUS_EXTENDED_AWAY: | |
1743 stock = idle ? PIDGIN_STOCK_STATUS_XA_I : PIDGIN_STOCK_STATUS_XA; | |
1744 break; | |
1745 case PURPLE_STATUS_INVISIBLE: | |
1746 stock = PIDGIN_STOCK_STATUS_INVISIBLE; | |
1747 break; | |
1748 case PURPLE_STATUS_OFFLINE: | |
1749 stock = idle ? PIDGIN_STOCK_STATUS_OFFLINE_I : PIDGIN_STOCK_STATUS_OFFLINE; | |
1750 break; | |
1751 default: | |
1752 stock = idle ? PIDGIN_STOCK_STATUS_AVAILABLE_I : PIDGIN_STOCK_STATUS_AVAILABLE; | |
1753 break; | |
1754 } | |
1755 return stock; | |
1756 } | |
1757 | |
1758 const char * | |
1759 pidgin_stock_id_from_status_primitive(PurpleStatusPrimitive prim) | |
1760 { | |
1761 return stock_id_from_status_primitive_idle(prim, FALSE); | |
1762 } | |
1763 | |
1764 const char * | |
1765 pidgin_stock_id_from_presence(PurplePresence *presence) | |
1766 { | |
1767 PurpleStatus *status; | |
1768 PurpleStatusType *type; | |
1769 PurpleStatusPrimitive prim; | |
1770 gboolean idle; | |
1771 | |
1772 g_return_val_if_fail(presence, NULL); | |
1773 | |
1774 status = purple_presence_get_active_status(presence); | |
1775 type = purple_status_get_type(status); | |
1776 prim = purple_status_type_get_primitive(type); | |
1777 | |
1778 idle = purple_presence_is_idle(presence); | |
1779 | |
1780 return stock_id_from_status_primitive_idle(prim, idle); | |
1781 } | |
1741 | 1782 |
1742 GdkPixbuf * | 1783 GdkPixbuf * |
1743 pidgin_create_prpl_icon(PurpleAccount *account, PidginPrplIconSize size) | 1784 pidgin_create_prpl_icon(PurpleAccount *account, PidginPrplIconSize size) |
1744 { | 1785 { |
1745 PurplePlugin *prpl; | 1786 PurplePlugin *prpl; |
2448 #endif /* FILECHOOSER */ | 2489 #endif /* FILECHOOSER */ |
2449 const char *current_folder; | 2490 const char *current_folder; |
2450 | 2491 |
2451 dialog->callback = callback; | 2492 dialog->callback = callback; |
2452 dialog->data = data; | 2493 dialog->data = data; |
2453 | |
2454 if (dialog->icon_filesel != NULL) { | |
2455 gtk_window_present(GTK_WINDOW(dialog->icon_filesel)); | |
2456 return NULL; | |
2457 } | |
2458 | 2494 |
2459 current_folder = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/filelocations/last_icon_folder"); | 2495 current_folder = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/filelocations/last_icon_folder"); |
2460 #if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ | 2496 #if GTK_CHECK_VERSION(2,4,0) /* FILECHOOSER */ |
2461 | 2497 |
2462 dialog->icon_filesel = gtk_file_chooser_dialog_new(_("Buddy Icon"), | 2498 dialog->icon_filesel = gtk_file_chooser_dialog_new(_("Buddy Icon"), |
2946 #else | 2982 #else |
2947 /* do something else? */ | 2983 /* do something else? */ |
2948 #endif | 2984 #endif |
2949 } | 2985 } |
2950 | 2986 |
2951 GSList *minidialogs = NULL; | 2987 static GSList *minidialogs = NULL; |
2952 | 2988 |
2953 static void * | 2989 static void * |
2954 pidgin_utils_get_handle(void) | 2990 pidgin_utils_get_handle(void) |
2955 { | 2991 { |
2956 static int handle; | 2992 static int handle; |
3541 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | 3577 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
3542 | 3578 |
3543 return TRUE; | 3579 return TRUE; |
3544 } | 3580 } |
3545 | 3581 |
3582 static void | |
3583 file_open_uri(GtkIMHtml *imhtml, const char *uri) | |
3584 { | |
3585 /* Copied from gtkft.c:open_button_cb */ | |
3586 #ifdef _WIN32 | |
3587 /* If using Win32... */ | |
3588 int code; | |
3589 if (G_WIN32_HAVE_WIDECHAR_API()) { | |
3590 wchar_t *wc_filename = g_utf8_to_utf16( | |
3591 uri, -1, NULL, NULL, NULL); | |
3592 | |
3593 code = (int)ShellExecuteW(NULL, NULL, wc_filename, NULL, NULL, | |
3594 SW_SHOW); | |
3595 | |
3596 g_free(wc_filename); | |
3597 } else { | |
3598 char *l_filename = g_locale_from_utf8( | |
3599 uri, -1, NULL, NULL, NULL); | |
3600 | |
3601 code = (int)ShellExecuteA(NULL, NULL, l_filename, NULL, NULL, | |
3602 SW_SHOW); | |
3603 | |
3604 g_free(l_filename); | |
3605 } | |
3606 | |
3607 if (code == SE_ERR_ASSOCINCOMPLETE || code == SE_ERR_NOASSOC) | |
3608 { | |
3609 purple_notify_error(imhtml, NULL, | |
3610 _("There is no application configured to open this type of file."), NULL); | |
3611 } | |
3612 else if (code < 32) | |
3613 { | |
3614 purple_notify_error(imhtml, NULL, | |
3615 _("An error occurred while opening the file."), NULL); | |
3616 purple_debug_warning("gtkutils", "filename: %s; code: %d\n", uri, code); | |
3617 } | |
3618 #else | |
3619 char *command = NULL; | |
3620 char *tmp = NULL; | |
3621 GError *error = NULL; | |
3622 | |
3623 if (purple_running_gnome()) | |
3624 { | |
3625 char *escaped = g_shell_quote(uri); | |
3626 command = g_strdup_printf("gnome-open %s", escaped); | |
3627 g_free(escaped); | |
3628 } | |
3629 else if (purple_running_kde()) | |
3630 { | |
3631 char *escaped = g_shell_quote(uri); | |
3632 | |
3633 if (purple_str_has_suffix(uri, ".desktop")) | |
3634 command = g_strdup_printf("kfmclient openURL %s 'text/plain'", escaped); | |
3635 else | |
3636 command = g_strdup_printf("kfmclient openURL %s", escaped); | |
3637 g_free(escaped); | |
3638 } | |
3639 else | |
3640 { | |
3641 purple_notify_uri(NULL, uri); | |
3642 return; | |
3643 } | |
3644 | |
3645 if (purple_program_is_valid(command)) | |
3646 { | |
3647 gint exit_status; | |
3648 if (!g_spawn_command_line_sync(command, NULL, NULL, &exit_status, &error)) | |
3649 { | |
3650 tmp = g_strdup_printf(_("Error launching %s: %s"), | |
3651 uri, error->message); | |
3652 purple_notify_error(imhtml, NULL, _("Unable to open file."), tmp); | |
3653 g_free(tmp); | |
3654 g_error_free(error); | |
3655 } | |
3656 if (exit_status != 0) | |
3657 { | |
3658 char *primary = g_strdup_printf(_("Error running %s"), command); | |
3659 char *secondary = g_strdup_printf(_("Process returned error code %d"), | |
3660 exit_status); | |
3661 purple_notify_error(imhtml, NULL, primary, secondary); | |
3662 g_free(tmp); | |
3663 } | |
3664 } | |
3665 #endif | |
3666 } | |
3667 | |
3668 #define FILELINKSIZE (sizeof("file://") - 1) | |
3669 static gboolean | |
3670 file_clicked_cb(GtkIMHtml *imhtml, GtkIMHtmlLink *link) | |
3671 { | |
3672 const char *uri = gtk_imhtml_link_get_url(link) + FILELINKSIZE; | |
3673 file_open_uri(imhtml, uri); | |
3674 return TRUE; | |
3675 } | |
3676 | |
3677 static gboolean | |
3678 open_containing_cb(GtkIMHtml *imhtml, const char *url) | |
3679 { | |
3680 char *dir = g_path_get_dirname(url + FILELINKSIZE); | |
3681 file_open_uri(imhtml, dir); | |
3682 g_free(dir); | |
3683 return TRUE; | |
3684 } | |
3685 | |
3686 static gboolean | |
3687 file_context_menu(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu) | |
3688 { | |
3689 GtkWidget *img, *item; | |
3690 const char *url; | |
3691 | |
3692 url = gtk_imhtml_link_get_url(link); | |
3693 | |
3694 /* Open File */ | |
3695 img = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU); | |
3696 item = gtk_image_menu_item_new_with_mnemonic(_("_Open File")); | |
3697 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); | |
3698 g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(gtk_imhtml_link_activate), link); | |
3699 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
3700 | |
3701 /* Open Containing Directory */ | |
3702 #if GTK_CHECK_VERSION(2,6,0) | |
3703 img = gtk_image_new_from_stock(GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU); | |
3704 item = gtk_image_menu_item_new_with_mnemonic(_("Open _Containing Directory")); | |
3705 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); | |
3706 #else | |
3707 item = gtk_menu_item_new_with_mnemonic(_("Open _Containing Directory")); | |
3708 #endif | |
3709 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(open_containing_cb), (gpointer)url); | |
3710 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
3711 | |
3712 return TRUE; | |
3713 } | |
3714 | |
3715 #define AUDIOLINKSIZE (sizeof("audio://") - 1) | |
3716 static gboolean | |
3717 audio_clicked_cb(GtkIMHtml *imhtml, GtkIMHtmlLink *link) | |
3718 { | |
3719 const char *uri; | |
3720 PidginConversation *conv = g_object_get_data(G_OBJECT(imhtml), "gtkconv"); | |
3721 if (!conv) /* no playback in debug window */ | |
3722 return TRUE; | |
3723 uri = gtk_imhtml_link_get_url(link) + AUDIOLINKSIZE; | |
3724 purple_sound_play_file(uri, NULL); | |
3725 return TRUE; | |
3726 } | |
3727 | |
3728 static void | |
3729 savefile_write_cb(gpointer user_data, char *file) | |
3730 { | |
3731 char *temp_file = user_data; | |
3732 gchar *contents; | |
3733 gsize length; | |
3734 GError *error; | |
3735 | |
3736 if (!g_file_get_contents(temp_file, &contents, &length, &error)) { | |
3737 purple_debug_error("gtkutils", "Unable to read contents of %s: %s\n", | |
3738 temp_file, error->message); | |
3739 g_error_free(error); | |
3740 return; | |
3741 } | |
3742 | |
3743 if (!purple_util_write_data_to_file_absolute(file, contents, length)) { | |
3744 purple_debug_error("gtkutils", "Unable to write contents to %s\n", | |
3745 file); | |
3746 } | |
3747 } | |
3748 | |
3749 static gboolean | |
3750 save_file_cb(GtkWidget *item, const char *url) | |
3751 { | |
3752 PidginConversation *conv = g_object_get_data(G_OBJECT(item), "gtkconv"); | |
3753 if (!conv) | |
3754 return TRUE; | |
3755 purple_request_file(conv->active_conv, _("Save File"), NULL, TRUE, | |
3756 G_CALLBACK(savefile_write_cb), NULL, | |
3757 conv->active_conv->account, NULL, conv->active_conv, | |
3758 (void *)url); | |
3759 return TRUE; | |
3760 } | |
3761 | |
3762 static gboolean | |
3763 audio_context_menu(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu) | |
3764 { | |
3765 GtkWidget *img, *item; | |
3766 const char *url; | |
3767 PidginConversation *conv = g_object_get_data(G_OBJECT(imhtml), "gtkconv"); | |
3768 if (!conv) /* No menu in debug window */ | |
3769 return TRUE; | |
3770 | |
3771 url = gtk_imhtml_link_get_url(link); | |
3772 | |
3773 /* Play Sound */ | |
3774 #if GTK_CHECK_VERSION(2,6,0) | |
3775 img = gtk_image_new_from_stock(GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_MENU); | |
3776 item = gtk_image_menu_item_new_with_mnemonic(_("_Play Sound")); | |
3777 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); | |
3778 #else | |
3779 item = gtk_menu_item_new_with_mnemonic(_("_Play Sound")); | |
3780 #endif | |
3781 g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(gtk_imhtml_link_activate), link); | |
3782 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
3783 | |
3784 /* Save File */ | |
3785 img = gtk_image_new_from_stock(GTK_STOCK_SAVE, GTK_ICON_SIZE_MENU); | |
3786 item = gtk_image_menu_item_new_with_mnemonic(_("_Save File")); | |
3787 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); | |
3788 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(save_file_cb), (gpointer)(url+AUDIOLINKSIZE)); | |
3789 g_object_set_data(G_OBJECT(item), "gtkconv", conv); | |
3790 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
3791 | |
3792 return TRUE; | |
3793 } | |
3794 | |
3546 /* XXX: The following two functions are for demonstration purposes only! */ | 3795 /* XXX: The following two functions are for demonstration purposes only! */ |
3547 static gboolean | 3796 static gboolean |
3548 open_dialog(GtkIMHtml *imhtml, GtkIMHtmlLink *link) | 3797 open_dialog(GtkIMHtml *imhtml, GtkIMHtmlLink *link) |
3549 { | 3798 { |
3550 const char *url; | 3799 const char *url; |
3581 | 3830 |
3582 tmp = g_find_program_in_path("gconftool-2"); | 3831 tmp = g_find_program_in_path("gconftool-2"); |
3583 if (tmp == NULL) | 3832 if (tmp == NULL) |
3584 return FALSE; | 3833 return FALSE; |
3585 | 3834 |
3835 g_free(tmp); | |
3586 tmp = NULL; | 3836 tmp = NULL; |
3837 | |
3587 if (!g_spawn_command_line_sync("gconftool-2 --all-dirs /desktop/gnome/url-handlers", | 3838 if (!g_spawn_command_line_sync("gconftool-2 --all-dirs /desktop/gnome/url-handlers", |
3588 &tmp, &err, NULL, NULL)) | 3839 &tmp, &err, NULL, NULL)) |
3589 { | 3840 { |
3590 g_free(tmp); | 3841 g_free(tmp); |
3591 g_free(err); | 3842 g_free(err); |
3645 gtk_imhtml_class_register_protocol("https://", url_clicked_cb, link_context_menu); | 3896 gtk_imhtml_class_register_protocol("https://", url_clicked_cb, link_context_menu); |
3646 gtk_imhtml_class_register_protocol("ftp://", url_clicked_cb, link_context_menu); | 3897 gtk_imhtml_class_register_protocol("ftp://", url_clicked_cb, link_context_menu); |
3647 gtk_imhtml_class_register_protocol("gopher://", url_clicked_cb, link_context_menu); | 3898 gtk_imhtml_class_register_protocol("gopher://", url_clicked_cb, link_context_menu); |
3648 gtk_imhtml_class_register_protocol("mailto:", url_clicked_cb, copy_email_address); | 3899 gtk_imhtml_class_register_protocol("mailto:", url_clicked_cb, copy_email_address); |
3649 | 3900 |
3901 gtk_imhtml_class_register_protocol("file://", file_clicked_cb, file_context_menu); | |
3902 gtk_imhtml_class_register_protocol("audio://", audio_clicked_cb, audio_context_menu); | |
3903 | |
3650 /* Example custom URL handler. */ | 3904 /* Example custom URL handler. */ |
3651 gtk_imhtml_class_register_protocol("open://", open_dialog, dummy); | 3905 gtk_imhtml_class_register_protocol("open://", open_dialog, dummy); |
3652 | 3906 |
3653 /* If we're under GNOME, try registering the system URL handlers. */ | 3907 /* If we're under GNOME, try registering the system URL handlers. */ |
3654 if (purple_running_gnome()) | 3908 if (purple_running_gnome()) |
3671 g_list_free(gnome_url_handlers); | 3925 g_list_free(gnome_url_handlers); |
3672 gnome_url_handlers = NULL; | 3926 gnome_url_handlers = NULL; |
3673 return; | 3927 return; |
3674 } | 3928 } |
3675 | 3929 |
3930 gtk_imhtml_class_register_protocol("audio://", NULL, NULL); | |
3931 gtk_imhtml_class_register_protocol("file://", NULL, NULL); | |
3932 | |
3676 gtk_imhtml_class_register_protocol("http://", NULL, NULL); | 3933 gtk_imhtml_class_register_protocol("http://", NULL, NULL); |
3677 gtk_imhtml_class_register_protocol("https://", NULL, NULL); | 3934 gtk_imhtml_class_register_protocol("https://", NULL, NULL); |
3678 gtk_imhtml_class_register_protocol("ftp://", NULL, NULL); | 3935 gtk_imhtml_class_register_protocol("ftp://", NULL, NULL); |
3679 gtk_imhtml_class_register_protocol("mailto:", NULL, NULL); | 3936 gtk_imhtml_class_register_protocol("mailto:", NULL, NULL); |
3680 gtk_imhtml_class_register_protocol("gopher://", NULL, NULL); | 3937 gtk_imhtml_class_register_protocol("gopher://", NULL, NULL); |