comparison pidgin/gtkblist.c @ 23395:7076f4e965c5

merge of '34ebad1a339cefdab142795e0b3a045ad7016658' and '868098fbe53290a8abcc3307c6fec2c6054a5e00'
author Casey Harkins <charkins@pidgin.im>
date Fri, 27 Jun 2008 00:01:59 +0000
parents 5d833ca5a265 dd146aa7d74d
children 1242a922a4bc fd0e8c6ffa4b 28a7992d37b2
comparison
equal deleted inserted replaced
22898:5d833ca5a265 23395:7076f4e965c5
55 #include "gtkprefs.h" 55 #include "gtkprefs.h"
56 #include "gtkprivacy.h" 56 #include "gtkprivacy.h"
57 #include "gtkroomlist.h" 57 #include "gtkroomlist.h"
58 #include "gtkstatusbox.h" 58 #include "gtkstatusbox.h"
59 #include "gtkscrollbook.h" 59 #include "gtkscrollbook.h"
60 #include "gtksmiley.h"
60 #include "gtkutils.h" 61 #include "gtkutils.h"
61 #include "pidgin/minidialog.h" 62 #include "pidgin/minidialog.h"
62 #include "pidgin/pidgintooltip.h" 63 #include "pidgin/pidgintooltip.h"
63 64
64 #include <gdk/gdkkeysyms.h> 65 #include <gdk/gdkkeysyms.h>
1527 } 1528 }
1528 1529
1529 return FALSE; 1530 return FALSE;
1530 } 1531 }
1531 1532
1533 static void
1534 set_node_custom_icon_cb(const gchar *filename, gpointer data)
1535 {
1536 if (filename) {
1537 PurpleBlistNode *node = (PurpleBlistNode*)data;
1538
1539 purple_buddy_icons_node_set_custom_icon_from_file(node,
1540 filename);
1541 }
1542 }
1543
1544 static void
1545 set_node_custom_icon(GtkWidget *w, PurpleBlistNode *node)
1546 {
1547 /* This doesn't keep track of the returned dialog (so that successive
1548 * calls could be made to re-display that dialog). Do we want that? */
1549 GtkWidget *win = pidgin_buddy_icon_chooser_new(NULL, set_node_custom_icon_cb, node);
1550 gtk_widget_show_all(win);
1551 }
1552
1553 static void
1554 remove_node_custom_icon(GtkWidget *w, PurpleBlistNode *node)
1555 {
1556 purple_buddy_icons_node_set_custom_icon(node, NULL, 0);
1557 }
1558
1559 static void
1560 add_buddy_icon_menu_items(GtkWidget *menu, PurpleBlistNode *node)
1561 {
1562 GtkWidget *item;
1563
1564 pidgin_new_item_from_stock(menu, _("Set Custom Icon"), NULL,
1565 G_CALLBACK(set_node_custom_icon), node, 0,
1566 0, NULL);
1567
1568 item = pidgin_new_item_from_stock(menu, _("Remove Custom Icon"), NULL,
1569 G_CALLBACK(remove_node_custom_icon), node,
1570 0, 0, NULL);
1571 if (!purple_buddy_icons_node_has_custom_icon(node))
1572 gtk_widget_set_sensitive(item, FALSE);
1573 }
1574
1532 static GtkWidget * 1575 static GtkWidget *
1533 create_group_menu (PurpleBlistNode *node, PurpleGroup *g) 1576 create_group_menu (PurpleBlistNode *node, PurpleGroup *g)
1534 { 1577 {
1535 GtkWidget *menu; 1578 GtkWidget *menu;
1536 GtkWidget *item; 1579 GtkWidget *item;
1550 gboolean show_offline = purple_blist_node_get_bool(node, "show_offline"); 1593 gboolean show_offline = purple_blist_node_get_bool(node, "show_offline");
1551 pidgin_new_item_from_stock(menu, show_offline ? _("Hide when offline") : _("Show when offline"), 1594 pidgin_new_item_from_stock(menu, show_offline ? _("Hide when offline") : _("Show when offline"),
1552 NULL, G_CALLBACK(gtk_blist_menu_showoffline_cb), node, 0, 0, NULL); 1595 NULL, G_CALLBACK(gtk_blist_menu_showoffline_cb), node, 0, 0, NULL);
1553 } 1596 }
1554 1597
1598 add_buddy_icon_menu_items(menu, node);
1599
1555 pidgin_append_blist_node_extended_menu(menu, node); 1600 pidgin_append_blist_node_extended_menu(menu, node);
1556 1601
1557 return menu; 1602 return menu;
1558 } 1603 }
1559
1560 1604
1561 static GtkWidget * 1605 static GtkWidget *
1562 create_chat_menu(PurpleBlistNode *node, PurpleChat *c) 1606 create_chat_menu(PurpleBlistNode *node, PurpleChat *c)
1563 { 1607 {
1564 GtkWidget *menu; 1608 GtkWidget *menu;
1588 pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS, 1632 pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS,
1589 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); 1633 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL);
1590 pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, 1634 pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE,
1591 G_CALLBACK(pidgin_blist_remove_cb), node, 0, 0, NULL); 1635 G_CALLBACK(pidgin_blist_remove_cb), node, 0, 0, NULL);
1592 1636
1637 add_buddy_icon_menu_items(menu, node);
1638
1593 return menu; 1639 return menu;
1594 } 1640 }
1595 1641
1596 static GtkWidget * 1642 static GtkWidget *
1597 create_contact_menu (PurpleBlistNode *node) 1643 create_contact_menu (PurpleBlistNode *node)
1609 pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS, 1655 pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS,
1610 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL); 1656 G_CALLBACK(gtk_blist_menu_alias_cb), node, 0, 0, NULL);
1611 pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, 1657 pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE,
1612 G_CALLBACK(pidgin_blist_remove_cb), node, 0, 0, NULL); 1658 G_CALLBACK(pidgin_blist_remove_cb), node, 0, 0, NULL);
1613 1659
1660 add_buddy_icon_menu_items(menu, node);
1661
1614 pidgin_separator(menu); 1662 pidgin_separator(menu);
1615 1663
1616 pidgin_new_item_from_stock(menu, _("_Collapse"), GTK_STOCK_ZOOM_OUT, 1664 pidgin_new_item_from_stock(menu, _("_Collapse"), GTK_STOCK_ZOOM_OUT,
1617 G_CALLBACK(pidgin_blist_collapse_contact_cb), 1665 G_CALLBACK(pidgin_blist_collapse_contact_cb),
1618 node, 0, 0, NULL); 1666 node, 0, 0, NULL);
1632 menu = gtk_menu_new(); 1680 menu = gtk_menu_new();
1633 pidgin_blist_make_buddy_menu(menu, b, FALSE); 1681 pidgin_blist_make_buddy_menu(menu, b, FALSE);
1634 1682
1635 if(PURPLE_BLIST_NODE_IS_CONTACT(node)) { 1683 if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
1636 pidgin_separator(menu); 1684 pidgin_separator(menu);
1685
1686 add_buddy_icon_menu_items(menu, node);
1637 1687
1638 if(gtknode->contact_expanded) { 1688 if(gtknode->contact_expanded) {
1639 pidgin_new_item_from_stock(menu, _("_Collapse"), 1689 pidgin_new_item_from_stock(menu, _("_Collapse"),
1640 GTK_STOCK_ZOOM_OUT, 1690 GTK_STOCK_ZOOM_OUT,
1641 G_CALLBACK(pidgin_blist_collapse_contact_cb), 1691 G_CALLBACK(pidgin_blist_collapse_contact_cb),
1717 1767
1718 menu = create_buddy_menu(node, b); 1768 menu = create_buddy_menu(node, b);
1719 } 1769 }
1720 1770
1721 #ifdef _WIN32 1771 #ifdef _WIN32
1772 pidgin_blist_tooltip_destroy();
1773
1722 /* Unhook the tooltip-timeout since we don't want a tooltip 1774 /* Unhook the tooltip-timeout since we don't want a tooltip
1723 * to appear and obscure the context menu we are about to show 1775 * to appear and obscure the context menu we are about to show
1724 This is a workaround for GTK+ bug 107320. */ 1776 This is a workaround for GTK+ bug 107320. */
1725 if (gtkblist->timeout) { 1777 if (gtkblist->timeout) {
1726 g_source_remove(gtkblist->timeout); 1778 g_source_remove(gtkblist->timeout);
2490 } 2542 }
2491 } 2543 }
2492 2544
2493 2545
2494 static GdkPixbuf *pidgin_blist_get_buddy_icon(PurpleBlistNode *node, 2546 static GdkPixbuf *pidgin_blist_get_buddy_icon(PurpleBlistNode *node,
2495 gboolean scaled, gboolean greyed) 2547 gboolean scaled, gboolean greyed)
2496 { 2548 {
2549 gsize len;
2550 GdkPixbufLoader *loader;
2551 PurpleBuddy *buddy = NULL;
2552 PurpleGroup *group = NULL;
2553 const guchar *data = NULL;
2497 GdkPixbuf *buf, *ret = NULL; 2554 GdkPixbuf *buf, *ret = NULL;
2498 GdkPixbufLoader *loader;
2499 PurpleBuddyIcon *icon = NULL; 2555 PurpleBuddyIcon *icon = NULL;
2500 const guchar *data = NULL;
2501 gsize len;
2502 PurpleBuddy *buddy = NULL;
2503 PurpleAccount *account = NULL; 2556 PurpleAccount *account = NULL;
2557 PurpleContact *contact = NULL;
2558 PurpleStoredImage *custom_img;
2504 PurplePluginProtocolInfo *prpl_info = NULL; 2559 PurplePluginProtocolInfo *prpl_info = NULL;
2505 PurpleStoredImage *custom_img; 2560 gint orig_width, orig_height, scale_width, scale_height;
2506 2561
2507 if(PURPLE_BLIST_NODE_IS_CONTACT(node)) { 2562 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
2508 buddy = purple_contact_get_priority_buddy((PurpleContact*)node); 2563 buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
2509 } else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { 2564 contact = (PurpleContact*)node;
2565 } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
2510 buddy = (PurpleBuddy*)node; 2566 buddy = (PurpleBuddy*)node;
2567 contact = purple_buddy_get_contact(buddy);
2568 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
2569 group = (PurpleGroup*)node;
2570 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
2571 /* We don't need to do anything here. We just need to not fall
2572 * into the else block and return. */
2511 } else { 2573 } else {
2512 return NULL; 2574 return NULL;
2513 } 2575 }
2514 2576
2515 if(buddy == NULL) 2577 if (buddy) {
2516 return NULL; 2578 account = purple_buddy_get_account(buddy);
2517 2579 }
2518 account = purple_buddy_get_account(buddy); 2580
2519 2581 if(account && account->gc) {
2520 if(account && account->gc)
2521 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl); 2582 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
2583 }
2522 2584
2523 #if 0 2585 #if 0
2524 if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons")) 2586 if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"))
2525 return NULL; 2587 return NULL;
2526 #endif 2588 #endif
2527 2589
2528 custom_img = purple_buddy_icons_find_custom_icon(purple_buddy_get_contact(buddy)); 2590 /* If we have a contact then this is either a contact or a buddy and
2529 if (custom_img) 2591 * we want to fetch the custom icon for the contact. If we don't have
2530 { 2592 * a contact then this is a group or some other type of node and we
2593 * want to use that directly. */
2594 if (contact) {
2595 custom_img = purple_buddy_icons_node_find_custom_icon((PurpleBlistNode*)contact);
2596 } else {
2597 custom_img = purple_buddy_icons_node_find_custom_icon(node);
2598 }
2599
2600 if (custom_img) {
2531 data = purple_imgstore_get_data(custom_img); 2601 data = purple_imgstore_get_data(custom_img);
2532 len = purple_imgstore_get_size(custom_img); 2602 len = purple_imgstore_get_size(custom_img);
2533 } 2603 }
2534 2604
2535 if (data == NULL) { 2605 if (data == NULL) {
2536 /* Not sure I like this...*/ 2606 if (buddy) {
2537 if (!(icon = purple_buddy_icons_find(buddy->account, buddy->name))) 2607 /* Not sure I like this...*/
2538 return NULL; 2608 if (!(icon = purple_buddy_icons_find(buddy->account, buddy->name)))
2539 data = purple_buddy_icon_get_data(icon, &len); 2609 return NULL;
2610 data = purple_buddy_icon_get_data(icon, &len);
2611 }
2540 2612
2541 if(data == NULL) 2613 if(data == NULL)
2542 return NULL; 2614 return NULL;
2543 } 2615 }
2544 2616
2552 buf = gdk_pixbuf_loader_get_pixbuf(loader); 2624 buf = gdk_pixbuf_loader_get_pixbuf(loader);
2553 if (buf) 2625 if (buf)
2554 g_object_ref(G_OBJECT(buf)); 2626 g_object_ref(G_OBJECT(buf));
2555 g_object_unref(G_OBJECT(loader)); 2627 g_object_unref(G_OBJECT(loader));
2556 2628
2557 if (buf) { 2629 if (!buf) {
2558 int orig_width, orig_height; 2630 return NULL;
2559 int scale_width, scale_height; 2631 }
2560 2632
2561 if (greyed) { 2633 if (greyed) {
2634 gboolean offline = FALSE, idle = FALSE;
2635
2636 if (buddy) {
2562 PurplePresence *presence = purple_buddy_get_presence(buddy); 2637 PurplePresence *presence = purple_buddy_get_presence(buddy);
2563 if (!PURPLE_BUDDY_IS_ONLINE(buddy)) 2638 if (!PURPLE_BUDDY_IS_ONLINE(buddy))
2564 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.0, FALSE); 2639 offline = TRUE;
2565 if (purple_presence_is_idle(presence)) 2640 if (purple_presence_is_idle(presence))
2566 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.25, FALSE); 2641 idle = TRUE;
2567 } 2642 } else if (group) {
2568 2643 if (purple_blist_get_group_online_count(group) == 0)
2569 /* i'd use the pidgin_buddy_icon_get_scale_size() thing, 2644 offline = TRUE;
2570 * but it won't tell me the original size, which I need for scaling 2645 }
2571 * purposes */ 2646
2572 scale_width = orig_width = gdk_pixbuf_get_width(buf); 2647 if (offline)
2573 scale_height = orig_height = gdk_pixbuf_get_height(buf); 2648 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.0, FALSE);
2574 2649
2575 if (prpl_info && prpl_info->icon_spec.scale_rules & PURPLE_ICON_SCALE_DISPLAY) 2650 if (idle)
2576 purple_buddy_icon_get_scale_size(&prpl_info->icon_spec, &scale_width, &scale_height); 2651 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0.25, FALSE);
2577 2652 }
2578 if (scaled || scale_height > 200 || scale_width > 200) { 2653
2579 GdkPixbuf *tmpbuf; 2654 /* I'd use the pidgin_buddy_icon_get_scale_size() thing, but it won't
2580 float scale_size = scaled ? 32.0 : 200.0; 2655 * tell me the original size, which I need for scaling purposes. */
2581 if(scale_height > scale_width) { 2656 scale_width = orig_width = gdk_pixbuf_get_width(buf);
2582 scale_width = scale_size * (double)scale_width / (double)scale_height; 2657 scale_height = orig_height = gdk_pixbuf_get_height(buf);
2583 scale_height = scale_size; 2658
2584 } else { 2659 if (prpl_info && prpl_info->icon_spec.scale_rules & PURPLE_ICON_SCALE_DISPLAY)
2585 scale_height = scale_size * (double)scale_height / (double)scale_width; 2660 purple_buddy_icon_get_scale_size(&prpl_info->icon_spec, &scale_width, &scale_height);
2586 scale_width = scale_size; 2661
2587 } 2662 if (scaled || scale_height > 200 || scale_width > 200) {
2588 /* scale & round before making square, so rectangular (but non-square) 2663 GdkPixbuf *tmpbuf;
2589 * images get rounded corners too */ 2664 float scale_size = scaled ? 32.0 : 200.0;
2590 tmpbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_width, scale_height); 2665 if(scale_height > scale_width) {
2591 gdk_pixbuf_fill(tmpbuf, 0x00000000); 2666 scale_width = scale_size * (double)scale_width / (double)scale_height;
2592 gdk_pixbuf_scale(buf, tmpbuf, 0, 0, scale_width, scale_height, 0, 0, (double)scale_width/(double)orig_width, (double)scale_height/(double)orig_height, GDK_INTERP_BILINEAR); 2667 scale_height = scale_size;
2593 if (pidgin_gdk_pixbuf_is_opaque(tmpbuf))
2594 pidgin_gdk_pixbuf_make_round(tmpbuf);
2595 ret = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_size, scale_size);
2596 gdk_pixbuf_fill(ret, 0x00000000);
2597 gdk_pixbuf_copy_area(tmpbuf, 0, 0, scale_width, scale_height, ret, (scale_size-scale_width)/2, (scale_size-scale_height)/2);
2598 g_object_unref(G_OBJECT(tmpbuf));
2599 } else { 2668 } else {
2600 ret = gdk_pixbuf_scale_simple(buf,scale_width,scale_height, GDK_INTERP_BILINEAR); 2669 scale_height = scale_size * (double)scale_height / (double)scale_width;
2601 } 2670 scale_width = scale_size;
2602 g_object_unref(G_OBJECT(buf)); 2671 }
2603 } 2672 /* Scale & round before making square, so rectangular (but
2673 * non-square) images get rounded corners too. */
2674 tmpbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_width, scale_height);
2675 gdk_pixbuf_fill(tmpbuf, 0x00000000);
2676 gdk_pixbuf_scale(buf, tmpbuf, 0, 0, scale_width, scale_height, 0, 0, (double)scale_width/(double)orig_width, (double)scale_height/(double)orig_height, GDK_INTERP_BILINEAR);
2677 if (pidgin_gdk_pixbuf_is_opaque(tmpbuf))
2678 pidgin_gdk_pixbuf_make_round(tmpbuf);
2679 ret = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, scale_size, scale_size);
2680 gdk_pixbuf_fill(ret, 0x00000000);
2681 gdk_pixbuf_copy_area(tmpbuf, 0, 0, scale_width, scale_height, ret, (scale_size-scale_width)/2, (scale_size-scale_height)/2);
2682 g_object_unref(G_OBJECT(tmpbuf));
2683 } else {
2684 ret = gdk_pixbuf_scale_simple(buf,scale_width,scale_height, GDK_INTERP_BILINEAR);
2685 }
2686 g_object_unref(G_OBJECT(buf));
2604 2687
2605 return ret; 2688 return ret;
2606 } 2689 }
2690
2607 /* # - Status Icon 2691 /* # - Status Icon
2608 * P - Protocol Icon 2692 * P - Protocol Icon
2609 * A - Buddy Icon 2693 * A - Buddy Icon
2610 * [ - SMALL_SPACE 2694 * [ - SMALL_SPACE
2611 * = - LARGE_SPACE 2695 * = - LARGE_SPACE
2650 int avatar_height; 2734 int avatar_height;
2651 int name_height; 2735 int name_height;
2652 int name_width; 2736 int name_width;
2653 int width; 2737 int width;
2654 int height; 2738 int height;
2739 int padding;
2655 }; 2740 };
2656 2741
2657 static PangoLayout * create_pango_layout(const char *markup, int *width, int *height) 2742 static PangoLayout * create_pango_layout(const char *markup, int *width, int *height)
2658 { 2743 {
2659 PangoLayout *layout; 2744 PangoLayout *layout;
2678 td->status_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); 2763 td->status_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
2679 /* Yes, status_icon, not prpl_icon */ 2764 /* Yes, status_icon, not prpl_icon */
2680 if (purple_account_is_disconnected(account)) 2765 if (purple_account_is_disconnected(account))
2681 gdk_pixbuf_saturate_and_pixelate(td->status_icon, td->status_icon, 0.0, FALSE); 2766 gdk_pixbuf_saturate_and_pixelate(td->status_icon, td->status_icon, 0.0, FALSE);
2682 td->layout = create_pango_layout(purple_account_get_username(account), &td->width, &td->height); 2767 td->layout = create_pango_layout(purple_account_get_username(account), &td->width, &td->height);
2768 td->padding = SMALL_SPACE;
2683 return td; 2769 return td;
2684 } 2770 }
2685 2771
2686 static struct tooltip_data * create_tip_for_node(PurpleBlistNode *node, gboolean full) 2772 static struct tooltip_data * create_tip_for_node(PurpleBlistNode *node, gboolean full)
2687 { 2773 {
2693 account = ((PurpleBuddy*)(node))->account; 2779 account = ((PurpleBuddy*)(node))->account;
2694 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { 2780 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
2695 account = ((PurpleChat*)(node))->account; 2781 account = ((PurpleChat*)(node))->account;
2696 } 2782 }
2697 2783
2784 td->padding = TOOLTIP_BORDER;
2698 td->status_icon = pidgin_blist_get_status_icon(node, PIDGIN_STATUS_ICON_LARGE); 2785 td->status_icon = pidgin_blist_get_status_icon(node, PIDGIN_STATUS_ICON_LARGE);
2699 td->avatar = pidgin_blist_get_buddy_icon(node, !full, FALSE); 2786 td->avatar = pidgin_blist_get_buddy_icon(node, !full, FALSE);
2700 if (account != NULL) { 2787 if (account != NULL) {
2701 td->prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); 2788 td->prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
2702 } 2789 }
2715 /* I don't believe this can happen currently, I think 2802 /* I don't believe this can happen currently, I think
2716 * everything that calls this function checks for one of the 2803 * everything that calls this function checks for one of the
2717 * above node types first. */ 2804 * above node types first. */
2718 tmp = g_strdup(_("Unknown node type")); 2805 tmp = g_strdup(_("Unknown node type"));
2719 } 2806 }
2720 node_name = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>", tmp); 2807 node_name = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>",
2808 tmp ? tmp : "");
2721 g_free(tmp); 2809 g_free(tmp);
2722 2810
2723 td->name_layout = create_pango_layout(node_name, &td->name_width, &td->name_height); 2811 td->name_layout = create_pango_layout(node_name, &td->name_width, &td->name_height);
2724 td->name_width += SMALL_SPACE + PRPL_SIZE; 2812 td->name_width += SMALL_SPACE + PRPL_SIZE;
2725 td->name_height = MAX(td->name_height, PRPL_SIZE + SMALL_SPACE); 2813 td->name_height = MAX(td->name_height, PRPL_SIZE + SMALL_SPACE);
2857 current_height + td->name_height, 2945 current_height + td->name_height,
2858 td->layout); 2946 td->layout);
2859 } 2947 }
2860 } 2948 }
2861 2949
2862 current_height += MAX(td->name_height + td->height, td->avatar_height) + TOOLTIP_BORDER; 2950 current_height += MAX(td->name_height + td->height, td->avatar_height) + td->padding;
2863 } 2951 }
2864 return FALSE; 2952 return FALSE;
2865 } 2953 }
2866 2954
2867 static void 2955 static void
2948 height = width = 0; 3036 height = width = 0;
2949 for (list = gtkblist->tooltipdata; list; list = list->next) { 3037 for (list = gtkblist->tooltipdata; list; list = list->next) {
2950 struct tooltip_data *td = list->data; 3038 struct tooltip_data *td = list->data;
2951 max_text_width = MAX(max_text_width, MAX(td->width, td->name_width)); 3039 max_text_width = MAX(max_text_width, MAX(td->width, td->name_width));
2952 max_avatar_width = MAX(max_avatar_width, td->avatar_width); 3040 max_avatar_width = MAX(max_avatar_width, td->avatar_width);
2953 height += MAX(TOOLTIP_BORDER + MAX(STATUS_SIZE, td->avatar_height), 3041 height += MAX(MAX(STATUS_SIZE, td->avatar_height), td->height + td->name_height) + td->padding;
2954 TOOLTIP_BORDER + td->height + td->name_height);
2955 if (td->status_icon) 3042 if (td->status_icon)
2956 status_size = MAX(status_size, STATUS_SIZE); 3043 status_size = MAX(status_size, STATUS_SIZE);
2957 } 3044 }
2958 height += TOOLTIP_BORDER; 3045 height += TOOLTIP_BORDER;
2959 width = TOOLTIP_BORDER + status_size + SMALL_SPACE + max_text_width + SMALL_SPACE + max_avatar_width + TOOLTIP_BORDER; 3046 width = TOOLTIP_BORDER + status_size + SMALL_SPACE + max_text_width + SMALL_SPACE + max_avatar_width + TOOLTIP_BORDER;
3151 static GtkItemFactoryEntry blist_menu[] = 3238 static GtkItemFactoryEntry blist_menu[] =
3152 { 3239 {
3153 /* Buddies menu */ 3240 /* Buddies menu */
3154 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>", NULL }, 3241 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>", NULL },
3155 { N_("/Buddies/New Instant _Message..."), "<CTL>M", pidgin_dialogs_im, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW }, 3242 { N_("/Buddies/New Instant _Message..."), "<CTL>M", pidgin_dialogs_im, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW },
3156 { N_("/Buddies/Join a _Chat..."), "<CTL>C", pidgin_blist_joinchat_show, 0, "<Item>", NULL }, 3243 { N_("/Buddies/Join a _Chat..."), "<CTL>C", pidgin_blist_joinchat_show, 0, "<StockItem>", PIDGIN_STOCK_CHAT },
3157 { N_("/Buddies/Get User _Info..."), "<CTL>I", pidgin_dialogs_info, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO }, 3244 { N_("/Buddies/Get User _Info..."), "<CTL>I", pidgin_dialogs_info, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO },
3158 { N_("/Buddies/View User _Log..."), "<CTL>L", pidgin_dialogs_log, 0, "<Item>", NULL }, 3245 { N_("/Buddies/View User _Log..."), "<CTL>L", pidgin_dialogs_log, 0, "<Item>", NULL },
3159 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>", NULL }, 3246 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>", NULL },
3160 { N_("/Buddies/Sh_ow"), NULL, NULL, 0, "<Branch>", NULL}, 3247 { N_("/Buddies/Sh_ow"), NULL, NULL, 0, "<Branch>", NULL},
3161 { N_("/Buddies/Show/_Offline Buddies"), NULL, pidgin_blist_edit_mode_cb, 1, "<CheckItem>", NULL }, 3248 { N_("/Buddies/Show/_Offline Buddies"), NULL, pidgin_blist_edit_mode_cb, 1, "<CheckItem>", NULL },
3171 { "/Buddies/sep3", NULL, NULL, 0, "<Separator>", NULL }, 3258 { "/Buddies/sep3", NULL, NULL, 0, "<Separator>", NULL },
3172 { N_("/Buddies/_Quit"), "<CTL>Q", purple_core_quit, 0, "<StockItem>", GTK_STOCK_QUIT }, 3259 { N_("/Buddies/_Quit"), "<CTL>Q", purple_core_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
3173 3260
3174 /* Accounts menu */ 3261 /* Accounts menu */
3175 { N_("/_Accounts"), NULL, NULL, 0, "<Branch>", NULL }, 3262 { N_("/_Accounts"), NULL, NULL, 0, "<Branch>", NULL },
3176 { N_("/Accounts/Manage"), "<CTL>A", pidgin_accounts_window_show, 0, "<Item>", NULL }, 3263 { N_("/Accounts/Manage Accounts"), "<CTL>A", pidgin_accounts_window_show, 0, "<Item>", NULL },
3177 3264
3178 /* Tools */ 3265 /* Tools */
3179 { N_("/_Tools"), NULL, NULL, 0, "<Branch>", NULL }, 3266 { N_("/_Tools"), NULL, NULL, 0, "<Branch>", NULL },
3180 { N_("/Tools/Buddy _Pounces"), NULL, pidgin_pounces_manager_show, 1, "<Item>", NULL }, 3267 { N_("/Tools/Buddy _Pounces"), NULL, pidgin_pounces_manager_show, 1, "<Item>", NULL },
3181 { N_("/Tools/_Certificates"), NULL, pidgin_certmgr_show, 0, "<Item>", NULL }, 3268 { N_("/Tools/_Certificates"), NULL, pidgin_certmgr_show, 0, "<Item>", NULL },
3182 { N_("/Tools/Plu_gins"), "<CTL>U", pidgin_plugin_dialog_show, 2, "<StockItem>", PIDGIN_STOCK_TOOLBAR_PLUGINS }, 3269 { N_("/Tools/Plu_gins"), "<CTL>U", pidgin_plugin_dialog_show, 2, "<StockItem>", PIDGIN_STOCK_TOOLBAR_PLUGINS },
3183 { N_("/Tools/Pr_eferences"), "<CTL>P", pidgin_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES }, 3270 { N_("/Tools/Pr_eferences"), "<CTL>P", pidgin_prefs_show, 0, "<StockItem>", GTK_STOCK_PREFERENCES },
3184 { N_("/Tools/Pr_ivacy"), NULL, pidgin_privacy_dialog_show, 0, "<Item>", NULL }, 3271 { N_("/Tools/Pr_ivacy"), NULL, pidgin_privacy_dialog_show, 0, "<Item>", NULL },
3272 { N_("/Tools/Smile_y"), "<CTL>Y", pidgin_smiley_manager_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SMILEY },
3185 { "/Tools/sep2", NULL, NULL, 0, "<Separator>", NULL }, 3273 { "/Tools/sep2", NULL, NULL, 0, "<Separator>", NULL },
3186 { N_("/Tools/_File Transfers"), "<CTL>T", pidgin_xfer_dialog_show, 0, "<Item>", NULL }, 3274 { N_("/Tools/_File Transfers"), "<CTL>T", pidgin_xfer_dialog_show, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_TRANSFER },
3187 { N_("/Tools/R_oom List"), NULL, pidgin_roomlist_dialog_show, 0, "<Item>", NULL }, 3275 { N_("/Tools/R_oom List"), NULL, pidgin_roomlist_dialog_show, 0, "<Item>", NULL },
3188 { N_("/Tools/System _Log"), NULL, gtk_blist_show_systemlog_cb, 3, "<Item>", NULL }, 3276 { N_("/Tools/System _Log"), NULL, gtk_blist_show_systemlog_cb, 3, "<Item>", NULL },
3189 { "/Tools/sep3", NULL, NULL, 0, "<Separator>", NULL }, 3277 { "/Tools/sep3", NULL, NULL, 0, "<Separator>", NULL },
3190 { N_("/Tools/Mute _Sounds"), "<CTL>S", pidgin_blist_mute_sounds_cb, 0, "<CheckItem>", NULL }, 3278 { N_("/Tools/Mute _Sounds"), "<CTL>S", pidgin_blist_mute_sounds_cb, 0, "<CheckItem>", NULL },
3191 /* Help */ 3279 /* Help */
3247 if (conv && !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) { 3335 if (conv && !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) {
3248 g_string_append_printf(str, _("\n<b>Occupants:</b> %d"), 3336 g_string_append_printf(str, _("\n<b>Occupants:</b> %d"),
3249 g_list_length(purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv)))); 3337 g_list_length(purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv))));
3250 3338
3251 if (prpl_info && (prpl_info->options & OPT_PROTO_CHAT_TOPIC)) { 3339 if (prpl_info && (prpl_info->options & OPT_PROTO_CHAT_TOPIC)) {
3252 char *topic = g_markup_escape_text(purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv)), -1); 3340 const char *chattopic = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv));
3341 char *topic = chattopic ? g_markup_escape_text(chattopic, -1) : NULL;
3253 g_string_append_printf(str, _("\n<b>Topic:</b> %s"), topic ? topic : _("(no topic set)")); 3342 g_string_append_printf(str, _("\n<b>Topic:</b> %s"), topic ? topic : _("(no topic set)"));
3254 g_free(topic); 3343 g_free(topic);
3255 } 3344 }
3256 } 3345 }
3257 3346
5222 5311
5223 /* Translators: Please maintain the use of -> and <- to refer to menu heirarchy */ 5312 /* Translators: Please maintain the use of -> and <- to refer to menu heirarchy */
5224 tmp = g_strdup_printf(_("<span weight='bold' size='larger'>Welcome to %s!</span>\n\n" 5313 tmp = g_strdup_printf(_("<span weight='bold' size='larger'>Welcome to %s!</span>\n\n"
5225 5314
5226 "You have no accounts enabled. Enable your IM accounts from the " 5315 "You have no accounts enabled. Enable your IM accounts from the "
5227 "<b>Accounts</b> window at <b>Accounts->Manage</b>. Once you " 5316 "<b>Accounts</b> window at <b>Accounts->Manage Accounts</b>. Once you "
5228 "enable accounts, you'll be able to sign on, set your status, " 5317 "enable accounts, you'll be able to sign on, set your status, "
5229 "and talk to your friends."), PIDGIN_NAME); 5318 "and talk to your friends."), PIDGIN_NAME);
5230 pretty = pidgin_make_pretty_arrows(tmp); 5319 pretty = pidgin_make_pretty_arrows(tmp);
5231 g_free(tmp); 5320 g_free(tmp);
5232 label = gtk_label_new(NULL); 5321 label = gtk_label_new(NULL);
5823 } 5912 }
5824 } 5913 }
5825 return FALSE; 5914 return FALSE;
5826 } 5915 }
5827 5916
5828 /*This version of pidgin_blist_update_group can take the original buddy 5917 /* This version of pidgin_blist_update_group can take the original buddy or a
5829 or a group, but has much better algorithmic performance with a pre-known buddy*/ 5918 * group, but has much better algorithmic performance with a pre-known buddy.
5830 static void pidgin_blist_update_group(PurpleBuddyList *list, PurpleBlistNode *node) 5919 */
5831 { 5920 static void pidgin_blist_update_group(PurpleBuddyList *list,
5921 PurpleBlistNode *node)
5922 {
5923 gint count;
5832 PurpleGroup *group; 5924 PurpleGroup *group;
5833 int count; 5925 PurpleBlistNode* gnode;
5834 gboolean show = FALSE, show_offline = FALSE; 5926 gboolean show = FALSE, show_offline = FALSE;
5835 PurpleBlistNode* gnode;
5836 5927
5837 g_return_if_fail(node != NULL); 5928 g_return_if_fail(node != NULL);
5838 5929
5839 if (editing_blist) 5930 if (editing_blist)
5840 return; 5931 return;
5865 } else if (!show_offline && PURPLE_BLIST_NODE_IS_GROUP(node)) { 5956 } else if (!show_offline && PURPLE_BLIST_NODE_IS_GROUP(node)) {
5866 show = pidgin_blist_group_has_show_offline_buddy(group); 5957 show = pidgin_blist_group_has_show_offline_buddy(group);
5867 } 5958 }
5868 5959
5869 if (show) { 5960 if (show) {
5961 gchar *title;
5962 gboolean biglist;
5870 GtkTreeIter iter; 5963 GtkTreeIter iter;
5871 GtkTreePath *path; 5964 GtkTreePath *path;
5872 gboolean expanded; 5965 gboolean expanded;
5873 GdkColor bgcolor; 5966 GdkColor bgcolor;
5874 char *title; 5967 GdkPixbuf *avatar = NULL;
5875
5876 5968
5877 if(!insert_node(list, gnode, &iter)) 5969 if(!insert_node(list, gnode, &iter))
5878 return; 5970 return;
5879 5971
5880 bgcolor = gtkblist->treeview->style->bg[GTK_STATE_ACTIVE]; 5972 bgcolor = gtkblist->treeview->style->bg[GTK_STATE_ACTIVE];
5882 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter); 5974 path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), &iter);
5883 expanded = gtk_tree_view_row_expanded(GTK_TREE_VIEW(gtkblist->treeview), path); 5975 expanded = gtk_tree_view_row_expanded(GTK_TREE_VIEW(gtkblist->treeview), path);
5884 gtk_tree_path_free(path); 5976 gtk_tree_path_free(path);
5885 5977
5886 title = pidgin_get_group_title(gnode, expanded); 5978 title = pidgin_get_group_title(gnode, expanded);
5979 biglist = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons");
5980
5981 if (biglist) {
5982 avatar = pidgin_blist_get_buddy_icon(gnode, TRUE, TRUE);
5983 }
5887 5984
5888 gtk_tree_store_set(gtkblist->treemodel, &iter, 5985 gtk_tree_store_set(gtkblist->treemodel, &iter,
5889 STATUS_ICON_VISIBLE_COLUMN, FALSE, 5986 STATUS_ICON_VISIBLE_COLUMN, FALSE,
5890 STATUS_ICON_COLUMN, NULL, 5987 STATUS_ICON_COLUMN, NULL,
5891 NAME_COLUMN, title, 5988 NAME_COLUMN, title,
5892 NODE_COLUMN, gnode, 5989 NODE_COLUMN, gnode,
5893 /* BGCOLOR_COLUMN, &bgcolor, */ 5990 /* BGCOLOR_COLUMN, &bgcolor, */
5894 GROUP_EXPANDER_COLUMN, TRUE, 5991 GROUP_EXPANDER_COLUMN, TRUE,
5895 GROUP_EXPANDER_VISIBLE_COLUMN, TRUE, 5992 GROUP_EXPANDER_VISIBLE_COLUMN, TRUE,
5896 CONTACT_EXPANDER_VISIBLE_COLUMN, FALSE, 5993 CONTACT_EXPANDER_VISIBLE_COLUMN, FALSE,
5897 BUDDY_ICON_VISIBLE_COLUMN, FALSE, 5994 BUDDY_ICON_COLUMN, avatar,
5995 BUDDY_ICON_VISIBLE_COLUMN, biglist,
5898 IDLE_VISIBLE_COLUMN, FALSE, 5996 IDLE_VISIBLE_COLUMN, FALSE,
5899 EMBLEM_VISIBLE_COLUMN, FALSE, 5997 EMBLEM_VISIBLE_COLUMN, FALSE,
5900 -1); 5998 -1);
5901 g_free(title); 5999 g_free(title);
5902 } else { 6000 } else {
6182 6280
6183 gtk_tree_store_set(gtkblist->treemodel, &iter, 6281 gtk_tree_store_set(gtkblist->treemodel, &iter,
6184 STATUS_ICON_COLUMN, status, 6282 STATUS_ICON_COLUMN, status,
6185 STATUS_ICON_VISIBLE_COLUMN, TRUE, 6283 STATUS_ICON_VISIBLE_COLUMN, TRUE,
6186 BUDDY_ICON_COLUMN, avatar ? avatar : gtkblist->empty_avatar, 6284 BUDDY_ICON_COLUMN, avatar ? avatar : gtkblist->empty_avatar,
6187 BUDDY_ICON_VISIBLE_COLUMN, purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"), 6285 BUDDY_ICON_VISIBLE_COLUMN, showicons,
6188 EMBLEM_COLUMN, emblem, 6286 EMBLEM_COLUMN, emblem,
6189 EMBLEM_VISIBLE_COLUMN, emblem != NULL, 6287 EMBLEM_VISIBLE_COLUMN, emblem != NULL,
6190 PROTOCOL_ICON_COLUMN, prpl_icon, 6288 PROTOCOL_ICON_COLUMN, prpl_icon,
6191 PROTOCOL_ICON_VISIBLE_COLUMN, purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"), 6289 PROTOCOL_ICON_VISIBLE_COLUMN, purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons"),
6192 NAME_COLUMN, mark, 6290 NAME_COLUMN, mark,
6381 } 6479 }
6382 6480
6383 b = purple_buddy_new(data->account, who, whoalias); 6481 b = purple_buddy_new(data->account, who, whoalias);
6384 purple_blist_add_buddy(b, NULL, g, NULL); 6482 purple_blist_add_buddy(b, NULL, g, NULL);
6385 purple_account_add_buddy(data->account, b); 6483 purple_account_add_buddy(data->account, b);
6484
6485 /* Offer to merge people with the same alias. */
6486 if (whoalias != NULL)
6487 gtk_blist_auto_personize((PurpleBlistNode *)g, whoalias);
6386 6488
6387 /* 6489 /*
6388 * XXX 6490 * XXX
6389 * It really seems like it would be better if the call to 6491 * It really seems like it would be better if the call to
6390 * purple_account_add_buddy() and purple_conversation_update() were done in 6492 * purple_account_add_buddy() and purple_conversation_update() were done in
7524 7626
7525 /* Clear the old Accounts menu */ 7627 /* Clear the old Accounts menu */
7526 for (l = gtk_container_get_children(GTK_CONTAINER(accountmenu)); l; l = g_list_delete_link(l, l)) { 7628 for (l = gtk_container_get_children(GTK_CONTAINER(accountmenu)); l; l = g_list_delete_link(l, l)) {
7527 menuitem = l->data; 7629 menuitem = l->data;
7528 7630
7529 if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Manage"))) 7631 if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Manage Accounts")))
7530 gtk_widget_destroy(menuitem); 7632 gtk_widget_destroy(menuitem);
7531 } 7633 }
7634
7635 for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
7636 char *buf = NULL;
7637 GtkWidget *image = NULL;
7638 PurpleAccount *account = NULL;
7639 GdkPixbuf *pixbuf = NULL;
7640
7641 account = accounts->data;
7642
7643 if(!purple_account_get_enabled(account, PIDGIN_UI)) {
7644 if (!disabled_accounts) {
7645 menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
7646 gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
7647 gtk_widget_show(menuitem);
7648
7649 submenu = gtk_menu_new();
7650 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
7651 gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account"));
7652 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
7653 gtk_widget_show(submenu);
7654
7655 disabled_accounts = TRUE;
7656 }
7657
7658 buf = g_strconcat(purple_account_get_username(account), " (",
7659 purple_account_get_protocol_name(account), ")", NULL);
7660 menuitem = gtk_image_menu_item_new_with_label(buf);
7661 g_free(buf);
7662 pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
7663 if (pixbuf != NULL)
7664 {
7665 if (!purple_account_is_connected(account))
7666 gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
7667 image = gtk_image_new_from_pixbuf(pixbuf);
7668 g_object_unref(G_OBJECT(pixbuf));
7669 gtk_widget_show(image);
7670 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
7671 }
7672 g_signal_connect(G_OBJECT(menuitem), "activate",
7673 G_CALLBACK(enable_account_cb), account);
7674 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
7675 gtk_widget_show(menuitem);
7676 }
7677 }
7678
7679 pidgin_separator(accountmenu);
7532 7680
7533 for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) { 7681 for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
7534 char *buf = NULL; 7682 char *buf = NULL;
7535 char *accel_path_buf = NULL; 7683 char *accel_path_buf = NULL;
7536 GtkWidget *image = NULL; 7684 GtkWidget *image = NULL;
7599 } else { 7747 } else {
7600 disabled_accounts = TRUE; 7748 disabled_accounts = TRUE;
7601 } 7749 }
7602 } 7750 }
7603 7751
7604 if(disabled_accounts) {
7605 pidgin_separator(accountmenu);
7606 menuitem = gtk_menu_item_new_with_label(_("Enable Account"));
7607 gtk_menu_shell_append(GTK_MENU_SHELL(accountmenu), menuitem);
7608 gtk_widget_show(menuitem);
7609
7610 submenu = gtk_menu_new();
7611 gtk_menu_set_accel_group(GTK_MENU(submenu), accel_group);
7612 gtk_menu_set_accel_path(GTK_MENU(submenu), N_("<PurpleMain>/Accounts/Enable Account"));
7613 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
7614 gtk_widget_show(submenu);
7615
7616 for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
7617 char *buf = NULL;
7618 GtkWidget *image = NULL;
7619 PurpleAccount *account = NULL;
7620 GdkPixbuf *pixbuf = NULL;
7621
7622 account = accounts->data;
7623
7624 if(!purple_account_get_enabled(account, PIDGIN_UI)) {
7625
7626 disabled_accounts = TRUE;
7627
7628 buf = g_strconcat(purple_account_get_username(account), " (",
7629 purple_account_get_protocol_name(account), ")", NULL);
7630 menuitem = gtk_image_menu_item_new_with_label(buf);
7631 g_free(buf);
7632 pixbuf = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL);
7633 if (pixbuf != NULL)
7634 {
7635 if (!purple_account_is_connected(account))
7636 gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE);
7637 image = gtk_image_new_from_pixbuf(pixbuf);
7638 g_object_unref(G_OBJECT(pixbuf));
7639 gtk_widget_show(image);
7640 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
7641 }
7642 g_signal_connect(G_OBJECT(menuitem), "activate",
7643 G_CALLBACK(enable_account_cb), account);
7644 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem);
7645 gtk_widget_show(menuitem);
7646 }
7647 }
7648 }
7649 } 7752 }
7650 7753
7651 static GList *plugin_submenus = NULL; 7754 static GList *plugin_submenus = NULL;
7652 7755
7653 void 7756 void