comparison console/gntblist.c @ 14712:b15c2eaeb67f

[gaim-migrate @ 17466] Patch #1573404 from Richard Nelson (wabz): "This patch keeps the blist sorted (sorts rows at the current depth when the text for a given row changes). Adds a menu "Options" to the blist and adds the options to sort by status, alphabetically and toggle offline buddies." I changed some of the stuff from the patch. Hopefully I didn't break anything. I also added a "Sort by log size" option. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Thu, 12 Oct 2006 03:26:33 +0000
parents ef94c6b853ab
children 52022b0a9405
comparison
equal deleted inserted replaced
14711:556a112ab6ca 14712:b15c2eaeb67f
97 static gboolean remove_typing_cb(gpointer null); 97 static gboolean remove_typing_cb(gpointer null);
98 static void remove_peripherals(GGBlist *ggblist); 98 static void remove_peripherals(GGBlist *ggblist);
99 static const char * get_display_name(GaimBlistNode *node); 99 static const char * get_display_name(GaimBlistNode *node);
100 static void savedstatus_changed(GaimSavedStatus *now, GaimSavedStatus *old); 100 static void savedstatus_changed(GaimSavedStatus *now, GaimSavedStatus *old);
101 101
102 /* Sort functions */
103 static int blist_node_compare_text(GaimBlistNode *n1, GaimBlistNode *n2);
104 static int blist_node_compare_status(GaimBlistNode *n1, GaimBlistNode *n2);
105 static int blist_node_compare_log(GaimBlistNode *n1, GaimBlistNode *n2);
106
102 static gboolean 107 static gboolean
103 is_contact_online(GaimContact *contact) 108 is_contact_online(GaimContact *contact)
104 { 109 {
105 GaimBlistNode *node; 110 GaimBlistNode *node;
106 for (node = ((GaimBlistNode*)contact)->child; node; node = node->next) { 111 for (node = ((GaimBlistNode*)contact)->child; node; node = node->next) {
186 return; /* XXX: this is probably the place to auto-join chats */ 191 return; /* XXX: this is probably the place to auto-join chats */
187 192
188 if (node->ui_data != NULL) { 193 if (node->ui_data != NULL) {
189 gnt_tree_change_text(GNT_TREE(ggblist->tree), node, 194 gnt_tree_change_text(GNT_TREE(ggblist->tree), node,
190 0, get_display_name(node)); 195 0, get_display_name(node));
196 gnt_tree_sort_row(GNT_TREE(ggblist->tree), node);
191 } 197 }
192 198
193 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { 199 if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
194 GaimBuddy *buddy = (GaimBuddy*)node; 200 GaimBuddy *buddy = (GaimBuddy*)node;
195 if (gaim_account_is_connected(buddy->account) && 201 if (gaim_account_is_connected(buddy->account) &&
1373 populate_buddylist() 1379 populate_buddylist()
1374 { 1380 {
1375 GaimBlistNode *node; 1381 GaimBlistNode *node;
1376 GaimBuddyList *list; 1382 GaimBuddyList *list;
1377 1383
1384 if (strcmp(gaim_prefs_get_string(PREF_ROOT "/sort_type"), "text") == 0) {
1385 gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
1386 (GCompareFunc)blist_node_compare_text);
1387 } else if (strcmp(gaim_prefs_get_string(PREF_ROOT "/sort_type"), "status") == 0) {
1388 gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
1389 (GCompareFunc)blist_node_compare_status);
1390 } else if (strcmp(gaim_prefs_get_string(PREF_ROOT "/sort_type"), "log") == 0) {
1391 gnt_tree_set_compare_func(GNT_TREE(ggblist->tree),
1392 (GCompareFunc)blist_node_compare_log);
1393 }
1394
1378 list = gaim_get_blist(); 1395 list = gaim_get_blist();
1379 node = gaim_blist_get_root(); 1396 node = gaim_blist_get_root();
1380 while (node) 1397 while (node)
1381 { 1398 {
1382 node_update(list, node); 1399 node_update(list, node);
1473 gaim_prefs_add_none(PREF_ROOT "/position"); 1490 gaim_prefs_add_none(PREF_ROOT "/position");
1474 gaim_prefs_add_int(PREF_ROOT "/position/x", 0); 1491 gaim_prefs_add_int(PREF_ROOT "/position/x", 0);
1475 gaim_prefs_add_int(PREF_ROOT "/position/y", 0); 1492 gaim_prefs_add_int(PREF_ROOT "/position/y", 0);
1476 gaim_prefs_add_bool(PREF_ROOT "/idletime", TRUE); 1493 gaim_prefs_add_bool(PREF_ROOT "/idletime", TRUE);
1477 gaim_prefs_add_bool(PREF_ROOT "/showoffline", FALSE); 1494 gaim_prefs_add_bool(PREF_ROOT "/showoffline", FALSE);
1495 gaim_prefs_add_string(PREF_ROOT "/sort_type", "text");
1478 1496
1479 gg_blist_show(); 1497 gg_blist_show();
1480 1498
1481 gaim_prefs_connect_callback(gg_blist_get_handle(), 1499 gaim_prefs_connect_callback(gg_blist_get_handle(),
1482 PREF_ROOT "/showoffline", redraw_blist, NULL); 1500 PREF_ROOT "/showoffline", redraw_blist, NULL);
1501 gaim_prefs_connect_callback(gg_blist_get_handle(),
1502 PREF_ROOT "/sort_type", redraw_blist, NULL);
1483 1503
1484 return; 1504 return;
1485 } 1505 }
1486 1506
1487 static gboolean 1507 static gboolean
1619 g_signal_handlers_unblock_matched(ggblist->statustext, G_SIGNAL_MATCH_FUNC, 1639 g_signal_handlers_unblock_matched(ggblist->statustext, G_SIGNAL_MATCH_FUNC,
1620 0, 0, NULL, status_text_changed, NULL); 1640 0, 0, NULL, status_text_changed, NULL);
1621 } 1641 }
1622 1642
1623 static int 1643 static int
1624 blist_node_compare(GaimBlistNode *n1, GaimBlistNode *n2) 1644 blist_node_compare_text(GaimBlistNode *n1, GaimBlistNode *n2)
1625 { 1645 {
1626 const char *s1, *s2; 1646 const char *s1, *s2;
1627 char *us1, *us2; 1647 char *us1, *us2;
1628 int ret; 1648 int ret;
1629 1649
1638 case GAIM_BLIST_CHAT_NODE: 1658 case GAIM_BLIST_CHAT_NODE:
1639 s1 = gaim_chat_get_name((GaimChat*)n1); 1659 s1 = gaim_chat_get_name((GaimChat*)n1);
1640 s2 = gaim_chat_get_name((GaimChat*)n2); 1660 s2 = gaim_chat_get_name((GaimChat*)n2);
1641 break; 1661 break;
1642 case GAIM_BLIST_BUDDY_NODE: 1662 case GAIM_BLIST_BUDDY_NODE:
1643 /* XXX: reordering existing rows don't do well in GntTree */
1644 return gaim_presence_compare(gaim_buddy_get_presence((GaimBuddy*)n1), 1663 return gaim_presence_compare(gaim_buddy_get_presence((GaimBuddy*)n1),
1645 gaim_buddy_get_presence((GaimBuddy*)n2)); 1664 gaim_buddy_get_presence((GaimBuddy*)n2));
1646 break; 1665 break;
1647 case GAIM_BLIST_CONTACT_NODE: 1666 case GAIM_BLIST_CONTACT_NODE:
1648 s1 = gaim_contact_get_alias((GaimContact*)n1); 1667 s1 = gaim_contact_get_alias((GaimContact*)n1);
1659 g_free(us2); 1678 g_free(us2);
1660 1679
1661 return ret; 1680 return ret;
1662 } 1681 }
1663 1682
1683 static int
1684 blist_node_compare_status(GaimBlistNode *n1, GaimBlistNode *n2)
1685 {
1686 int ret;
1687
1688 g_return_val_if_fail(n1->type == n2->type, -1);
1689
1690 switch (n1->type) {
1691 case GAIM_BLIST_CONTACT_NODE:
1692 n1 = (GaimBlistNode*)gaim_contact_get_priority_buddy((GaimContact*)n1);
1693 n2 = (GaimBlistNode*)gaim_contact_get_priority_buddy((GaimContact*)n2);
1694 /* now compare the presence of the priority buddies */
1695 case GAIM_BLIST_BUDDY_NODE:
1696 ret = gaim_presence_compare(gaim_buddy_get_presence((GaimBuddy*)n1),
1697 gaim_buddy_get_presence((GaimBuddy*)n2));
1698 if (ret != 0)
1699 return ret;
1700 break;
1701 default:
1702 break;
1703 }
1704
1705 /* Sort alphabetically if presence is not comparable */
1706 ret = blist_node_compare_text(n1, n2);
1707
1708 return ret;
1709 }
1710
1711 static int
1712 get_contact_log_size(GaimBlistNode *c)
1713 {
1714 int log = 0;
1715 GaimBlistNode *node;
1716
1717 for (node = c->child; node; node = node->next) {
1718 GaimBuddy *b = (GaimBuddy*)node;
1719 log += gaim_log_get_total_size(GAIM_LOG_IM, b->name, b->account);
1720 }
1721
1722 return log;
1723 }
1724
1725 static int
1726 blist_node_compare_log(GaimBlistNode *n1, GaimBlistNode *n2)
1727 {
1728 int ret;
1729 GaimBuddy *b1, *b2;
1730
1731 g_return_val_if_fail(n1->type == n2->type, -1);
1732
1733 switch (n1->type) {
1734 case GAIM_BLIST_BUDDY_NODE:
1735 b1 = (GaimBuddy*)n1;
1736 b2 = (GaimBuddy*)n2;
1737 ret = gaim_log_get_total_size(GAIM_LOG_IM, b2->name, b2->account) -
1738 gaim_log_get_total_size(GAIM_LOG_IM, b1->name, b1->account);
1739 if (ret != 0)
1740 return ret;
1741 break;
1742 case GAIM_BLIST_CONTACT_NODE:
1743 ret = get_contact_log_size(n2) - get_contact_log_size(n1);
1744 if (ret != 0)
1745 return ret;
1746 break;
1747 default:
1748 break;
1749 }
1750 ret = blist_node_compare_text(n1, n2);
1751 return ret;
1752 }
1753
1664 static gboolean 1754 static gboolean
1665 blist_clicked(GntTree *tree, GntMouseEvent event, int x, int y, gpointer ggblist) 1755 blist_clicked(GntTree *tree, GntMouseEvent event, int x, int y, gpointer ggblist)
1666 { 1756 {
1667 if (event == GNT_RIGHT_MOUSE_DOWN) { 1757 if (event == GNT_RIGHT_MOUSE_DOWN) {
1668 draw_context_menu(ggblist); 1758 draw_context_menu(ggblist);
1676 GaimPluginAction *action = data; 1766 GaimPluginAction *action = data;
1677 if (action && action->callback) 1767 if (action && action->callback)
1678 action->callback(action); 1768 action->callback(action);
1679 } 1769 }
1680 1770
1681 static void 1771 static GntMenuItem *reconstruct_accounts_menu()
1682 reconstruct_accounts_menu() 1772 {
1683 { 1773 GntWidget *sub;
1684 GntWidget *menu, *sub; 1774 GntMenuItem *acc, *item;
1685 GntMenuItem *item;
1686 GntWindow *window;
1687 GList *iter; 1775 GList *iter;
1688 1776
1689 if (!ggblist) 1777 if (!ggblist)
1690 return; 1778 return NULL;
1691 1779
1692 window = GNT_WINDOW(ggblist->window); 1780 acc = gnt_menuitem_new(_("Accounts"));
1693
1694 menu = gnt_menu_new(GNT_MENU_TOPLEVEL);
1695 gnt_window_set_menu(window, GNT_MENU(menu));
1696
1697 item = gnt_menuitem_new(_("Accounts"));
1698 gnt_menu_add_item(GNT_MENU(menu), item);
1699 1781
1700 sub = gnt_menu_new(GNT_MENU_POPUP); 1782 sub = gnt_menu_new(GNT_MENU_POPUP);
1701 gnt_menuitem_set_submenu(item, GNT_MENU(sub)); 1783 gnt_menuitem_set_submenu(acc, GNT_MENU(sub));
1702 1784
1703 for (iter = gaim_accounts_get_all_active(); iter; 1785 for (iter = gaim_accounts_get_all_active(); iter;
1704 iter = g_list_delete_link(iter, iter)) { 1786 iter = g_list_delete_link(iter, iter)) {
1705 GaimAccount *account = iter->data; 1787 GaimAccount *account = iter->data;
1706 GaimConnection *gc = gaim_account_get_connection(account); 1788 GaimConnection *gc = gaim_account_get_connection(account);
1735 (GDestroyNotify)gaim_plugin_action_free); 1817 (GDestroyNotify)gaim_plugin_action_free);
1736 gnt_menu_add_item(GNT_MENU(s), item); 1818 gnt_menu_add_item(GNT_MENU(s), item);
1737 } 1819 }
1738 } 1820 }
1739 } 1821 }
1822 return acc;
1823 }
1824
1825 static void show_offline_cb(GntMenuItem *item, gpointer n)
1826 {
1827 gaim_prefs_set_bool(PREF_ROOT "/showoffline",
1828 !gaim_prefs_get_bool(PREF_ROOT "/showoffline"));
1829 }
1830
1831 static void sort_blist_change_cb(GntMenuItem *item, gpointer n)
1832 {
1833 gaim_prefs_set_string(PREF_ROOT "/sort_type", n);
1834 }
1835
1836 static void
1837 create_menu()
1838 {
1839 GntWidget *menu, *sub;
1840 GntMenuItem *item;
1841 GntWindow *window;
1842
1843 if (!ggblist)
1844 return;
1845
1846 window = GNT_WINDOW(ggblist->window);
1847 menu = gnt_menu_new(GNT_MENU_TOPLEVEL);
1848 gnt_window_set_menu(window, GNT_MENU(menu));
1849
1850 item = gnt_menuitem_new(_("Options"));
1851 gnt_menu_add_item(GNT_MENU(menu), item);
1852
1853 sub = gnt_menu_new(GNT_MENU_POPUP);
1854 gnt_menuitem_set_submenu(item, GNT_MENU(sub));
1855
1856 item = gnt_menuitem_new(_("Toggle offline buddies"));
1857 gnt_menu_add_item(GNT_MENU(sub), item);
1858 gnt_menuitem_set_callback(GNT_MENUITEM(item), show_offline_cb, NULL);
1859
1860 item = gnt_menuitem_new(_("Sort by status"));
1861 gnt_menu_add_item(GNT_MENU(sub), item);
1862 gnt_menuitem_set_callback(GNT_MENUITEM(item), sort_blist_change_cb, "status");
1863
1864 item = gnt_menuitem_new(_("Sort alphabetically"));
1865 gnt_menu_add_item(GNT_MENU(sub), item);
1866 gnt_menuitem_set_callback(GNT_MENUITEM(item), sort_blist_change_cb, "text");
1867
1868 item = gnt_menuitem_new(_("Sort by log size"));
1869 gnt_menu_add_item(GNT_MENU(sub), item);
1870 gnt_menuitem_set_callback(GNT_MENUITEM(item), sort_blist_change_cb, "log");
1871
1872 item = reconstruct_accounts_menu();
1873 gnt_menu_add_item(GNT_MENU(menu), item);
1740 } 1874 }
1741 1875
1742 void gg_blist_show() 1876 void gg_blist_show()
1743 { 1877 {
1744 if (ggblist) 1878 if (ggblist)
1753 gnt_box_set_toplevel(GNT_BOX(ggblist->window), TRUE); 1887 gnt_box_set_toplevel(GNT_BOX(ggblist->window), TRUE);
1754 gnt_box_set_title(GNT_BOX(ggblist->window), _("Buddy List")); 1888 gnt_box_set_title(GNT_BOX(ggblist->window), _("Buddy List"));
1755 gnt_box_set_pad(GNT_BOX(ggblist->window), 0); 1889 gnt_box_set_pad(GNT_BOX(ggblist->window), 0);
1756 1890
1757 ggblist->tree = gnt_tree_new(); 1891 ggblist->tree = gnt_tree_new();
1758 gnt_tree_set_compare_func(GNT_TREE(ggblist->tree), (GCompareFunc)blist_node_compare); 1892
1759 GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER); 1893 GNT_WIDGET_SET_FLAGS(ggblist->tree, GNT_WIDGET_NO_BORDER);
1760 gnt_tree_set_col_width(GNT_TREE(ggblist->tree), 0, 25); 1894 gnt_tree_set_col_width(GNT_TREE(ggblist->tree), 0, 25);
1761 gnt_widget_set_size(ggblist->tree, gaim_prefs_get_int(PREF_ROOT "/size/width"), 1895 gnt_widget_set_size(ggblist->tree, gaim_prefs_get_int(PREF_ROOT "/size/width"),
1762 gaim_prefs_get_int(PREF_ROOT "/size/height")); 1896 gaim_prefs_get_int(PREF_ROOT "/size/height"));
1763 gnt_widget_set_position(ggblist->window, gaim_prefs_get_int(PREF_ROOT "/position/x"), 1897 gnt_widget_set_position(ggblist->window, gaim_prefs_get_int(PREF_ROOT "/position/x"),
1771 gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->statustext); 1905 gnt_box_add_widget(GNT_BOX(ggblist->window), ggblist->statustext);
1772 1906
1773 gnt_widget_show(ggblist->window); 1907 gnt_widget_show(ggblist->window);
1774 1908
1775 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", gg_blist_get_handle(), 1909 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", gg_blist_get_handle(),
1776 GAIM_CALLBACK(reconstruct_accounts_menu), NULL); 1910 GAIM_CALLBACK(create_menu), NULL);
1777 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", gg_blist_get_handle(), 1911 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", gg_blist_get_handle(),
1778 GAIM_CALLBACK(reconstruct_accounts_menu), NULL); 1912 GAIM_CALLBACK(create_menu), NULL);
1779 gaim_signal_connect(gaim_blist_get_handle(), "buddy-status-changed", gg_blist_get_handle(), 1913 gaim_signal_connect(gaim_blist_get_handle(), "buddy-status-changed", gg_blist_get_handle(),
1780 GAIM_CALLBACK(buddy_status_changed), ggblist); 1914 GAIM_CALLBACK(buddy_status_changed), ggblist);
1781 gaim_signal_connect(gaim_blist_get_handle(), "buddy-idle-changed", gg_blist_get_handle(), 1915 gaim_signal_connect(gaim_blist_get_handle(), "buddy-idle-changed", gg_blist_get_handle(),
1782 GAIM_CALLBACK(buddy_idle_changed), ggblist); 1916 GAIM_CALLBACK(buddy_idle_changed), ggblist);
1783 1917
1815 g_signal_connect(G_OBJECT(ggblist->status), "selection_changed", 1949 g_signal_connect(G_OBJECT(ggblist->status), "selection_changed",
1816 G_CALLBACK(status_selection_changed), NULL); 1950 G_CALLBACK(status_selection_changed), NULL);
1817 g_signal_connect(G_OBJECT(ggblist->statustext), "key_pressed", 1951 g_signal_connect(G_OBJECT(ggblist->statustext), "key_pressed",
1818 G_CALLBACK(status_text_changed), NULL); 1952 G_CALLBACK(status_text_changed), NULL);
1819 1953
1820 reconstruct_accounts_menu(ggblist); 1954 create_menu();
1821 1955
1822 populate_buddylist(); 1956 populate_buddylist();
1823 1957
1824 savedstatus_changed(gaim_savedstatus_get_current(), NULL); 1958 savedstatus_changed(gaim_savedstatus_get_current(), NULL);
1825 } 1959 }