Mercurial > pidgin
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 } |