* @file grouping.c Provides different grouping options. * Copyright (C) 2008 Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA static FinchBlistManager *default_manager; static PurpleBlistNode online = {.type = PURPLE_BLIST_OTHER_NODE}, offline = {.type = PURPLE_BLIST_OTHER_NODE}; static gboolean on_offline_init() GntTree *tree = finch_blist_get_tree(); gnt_tree_add_row_after(tree, &online, gnt_tree_create_row(tree, _("Online")), NULL, NULL); gnt_tree_add_row_after(tree, &offline, gnt_tree_create_row(tree, _("Offline")), NULL, &online); static gboolean on_offline_can_add_node(PurpleBlistNode *node) switch (purple_blist_node_get_type(node)) { case PURPLE_BLIST_CONTACT_NODE: PurpleContact *contact = (PurpleContact*)node; if (contact->currentsize > 0) case PURPLE_BLIST_BUDDY_NODE: PurpleBuddy *buddy = (PurpleBuddy*)node; if (PURPLE_BUDDY_IS_ONLINE(buddy)) if (purple_prefs_get_bool("/finch/blist/showoffline") && purple_account_is_connected(purple_buddy_get_account(buddy))) case PURPLE_BLIST_CHAT_NODE: PurpleChat *chat = (PurpleChat*)node; return purple_account_is_connected(purple_chat_get_account(chat)); static gpointer on_offline_find_parent(PurpleBlistNode *node) switch (purple_blist_node_get_type(node)) { case PURPLE_BLIST_CONTACT_NODE: node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node))); ret = PURPLE_BUDDY_IS_ONLINE((PurpleBuddy*)node) ? &online : &offline; case PURPLE_BLIST_BUDDY_NODE: ret = purple_blist_node_get_parent(node); finch_blist_manager_add_node(ret); case PURPLE_BLIST_CHAT_NODE: static gboolean on_offline_create_tooltip(gpointer selected_row, GString **body, char **tool_title) PurpleBlistNode *node = selected_row; if (purple_blist_node_get_type(node) == PURPLE_BLIST_OTHER_NODE) { /* There should be some easy way of getting the total online count, * or total number of chats. Doing a loop here will probably be pretty *body = g_string_new(node == &online ? _("Online Buddies") : _("Offline Buddies")); return default_manager ? default_manager->create_tooltip(selected_row, body, tool_title) : FALSE; static FinchBlistManager on_offline = on_offline_create_tooltip, static PurpleBlistNode meebo = {.type = PURPLE_BLIST_OTHER_NODE}; static gboolean meebo_init() GntTree *tree = finch_blist_get_tree(); if (!g_list_find(gnt_tree_get_rows(tree), &meebo)) { gnt_tree_add_row_last(tree, &meebo, gnt_tree_create_row(tree, _("Offline")), NULL); static gpointer meebo_find_parent(PurpleBlistNode *node) if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { PurpleBuddy *buddy = purple_contact_get_priority_buddy((PurpleContact*)node); if (buddy && !PURPLE_BUDDY_IS_ONLINE(buddy)) { return default_manager->find_parent(node); static FinchBlistManager meebo_group = static gboolean no_group_init() GntTree *tree = finch_blist_get_tree(); g_object_set(G_OBJECT(tree), "expander-level", 0, NULL); static gboolean no_group_uninit() GntTree *tree = finch_blist_get_tree(); g_object_set(G_OBJECT(tree), "expander-level", 1, NULL); static gboolean no_group_can_add_node(PurpleBlistNode *node) return on_offline_can_add_node(node); /* These happen to be the same */ static gpointer no_group_find_parent(PurpleBlistNode *node) switch (purple_blist_node_get_type(node)) { case PURPLE_BLIST_BUDDY_NODE: ret = purple_blist_node_get_parent(node); finch_blist_manager_add_node(ret); static FinchBlistManager no_group = static GHashTable *groups; groups = g_hash_table_new_full(g_str_hash, g_str_equal, nested_group_uninit(void) g_hash_table_destroy(groups); nested_group_find_parent(PurpleBlistNode *node) PurpleBlistNode *ret, *parent; if (!PURPLE_BLIST_NODE_IS_GROUP(node)) return default_manager->find_parent(node); group = (PurpleGroup *)node; name = g_strdup(purple_group_get_name(group)); if (!(sep = strchr(name, '/'))) { return default_manager->find_parent(node); tree = finch_blist_get_tree(); if (*(sep + 1) && (ret = (PurpleBlistNode *)purple_find_group(name))) { finch_blist_manager_add_node(ret); } else if (!(ret = g_hash_table_lookup(groups, name))) { ret = g_new0(PurpleBlistNode, 1); g_hash_table_insert(groups, g_strdup(name), ret); ret->type = PURPLE_BLIST_OTHER_NODE; gnt_tree_add_row_last(tree, ret, gnt_tree_create_row(tree, name), parent); sep = strchr(sep + 1, '/'); nested_group_create_tooltip(gpointer selected_row, GString **body, char **title) PurpleBlistNode *node = selected_row; purple_blist_node_get_type(node) != PURPLE_BLIST_OTHER_NODE) return default_manager->create_tooltip(selected_row, body, title); *body = g_string_new(_("Nested Subgroup")); /* Perhaps list the child groups/subgroups? */ nested_group_can_add_node(PurpleBlistNode *node) if (!PURPLE_BLIST_NODE_IS_GROUP(node)) return default_manager->can_add_node(node); if (default_manager->can_add_node(node)) len = strlen(purple_group_get_name((PurpleGroup*)node)); group = purple_blist_get_root(); for (; group; group = purple_blist_node_get_sibling_next(group)) { if (strncmp(purple_group_get_name((PurpleGroup *)node), purple_group_get_name((PurpleGroup *)group), len) == 0 && default_manager->can_add_node(group)) static FinchBlistManager nested_group = N_("Nested Grouping (experimental)"), .init = nested_group_init, .uninit = nested_group_uninit, .find_parent = nested_group_find_parent, .create_tooltip = nested_group_create_tooltip, .can_add_node = nested_group_can_add_node, plugin_load(PurplePlugin *plugin) default_manager = finch_blist_manager_find("default"); finch_blist_install_manager(&on_offline); finch_blist_install_manager(&meebo_group); finch_blist_install_manager(&no_group); finch_blist_install_manager(&nested_group); plugin_unload(PurplePlugin *plugin) finch_blist_uninstall_manager(&on_offline); finch_blist_uninstall_manager(&meebo_group); finch_blist_uninstall_manager(&no_group); finch_blist_uninstall_manager(&nested_group); static PurplePluginInfo info = N_("Provides alternate buddylist grouping options."), N_("Provides alternate buddylist grouping options."), "Sadrul H Chowdhury <sadrul@users.sourceforge.net>", init_plugin(PurplePlugin *plugin) PURPLE_INIT_PLUGIN(grouping, init_plugin, info)