2 * @file grouping.c Provides different grouping options.
4 * Copyright (C) 2008 Sadrul Habib Chowdhury <sadrul@users.sourceforge.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "gntplugin.h"
31 static FinchBlistManager
*default_manager
;
36 static PurpleBlistNode online
= {.type
= PURPLE_BLIST_OTHER_NODE
},
37 offline
= {.type
= PURPLE_BLIST_OTHER_NODE
};
39 static gboolean
on_offline_init()
41 GntTree
*tree
= finch_blist_get_tree();
43 gnt_tree_add_row_after(tree
, &online
,
44 gnt_tree_create_row(tree
, _("Online")), NULL
, NULL
);
45 gnt_tree_add_row_after(tree
, &offline
,
46 gnt_tree_create_row(tree
, _("Offline")), NULL
, &online
);
51 static gboolean
on_offline_can_add_node(PurpleBlistNode
*node
)
53 switch (purple_blist_node_get_type(node
)) {
54 case PURPLE_BLIST_CONTACT_NODE
:
56 PurpleContact
*contact
= (PurpleContact
*)node
;
57 if (contact
->currentsize
> 0)
62 case PURPLE_BLIST_BUDDY_NODE
:
64 PurpleBuddy
*buddy
= (PurpleBuddy
*)node
;
65 if (PURPLE_BUDDY_IS_ONLINE(buddy
))
67 if (purple_prefs_get_bool("/finch/blist/showoffline") &&
68 purple_account_is_connected(purple_buddy_get_account(buddy
)))
73 case PURPLE_BLIST_CHAT_NODE
:
75 PurpleChat
*chat
= (PurpleChat
*)node
;
76 return purple_account_is_connected(purple_chat_get_account(chat
));
84 static gpointer
on_offline_find_parent(PurpleBlistNode
*node
)
88 switch (purple_blist_node_get_type(node
)) {
89 case PURPLE_BLIST_CONTACT_NODE
:
90 node
= PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node
)));
91 ret
= PURPLE_BUDDY_IS_ONLINE((PurpleBuddy
*)node
) ? &online
: &offline
;
93 case PURPLE_BLIST_BUDDY_NODE
:
94 ret
= purple_blist_node_get_parent(node
);
95 finch_blist_manager_add_node(ret
);
97 case PURPLE_BLIST_CHAT_NODE
:
106 static gboolean
on_offline_create_tooltip(gpointer selected_row
, GString
**body
, char **tool_title
)
108 PurpleBlistNode
*node
= selected_row
;
110 if (purple_blist_node_get_type(node
) == PURPLE_BLIST_OTHER_NODE
) {
111 /* There should be some easy way of getting the total online count,
112 * or total number of chats. Doing a loop here will probably be pretty
115 *body
= g_string_new(node
== &online
? _("Online Buddies") : _("Offline Buddies"));
118 return default_manager
? default_manager
->create_tooltip(selected_row
, body
, tool_title
) : FALSE
;
122 static FinchBlistManager on_offline
=
125 N_("Online/Offline"),
128 on_offline_can_add_node
,
129 on_offline_find_parent
,
130 on_offline_create_tooltip
,
131 {NULL
, NULL
, NULL
, NULL
}
135 * Meebo-like Grouping.
137 static PurpleBlistNode meebo
= {.type
= PURPLE_BLIST_OTHER_NODE
};
138 static gboolean
meebo_init()
140 GntTree
*tree
= finch_blist_get_tree();
141 if (!g_list_find(gnt_tree_get_rows(tree
), &meebo
)) {
142 gnt_tree_add_row_last(tree
, &meebo
,
143 gnt_tree_create_row(tree
, _("Offline")), NULL
);
148 static gpointer
meebo_find_parent(PurpleBlistNode
*node
)
150 if (PURPLE_BLIST_NODE_IS_CONTACT(node
)) {
151 PurpleBuddy
*buddy
= purple_contact_get_priority_buddy((PurpleContact
*)node
);
152 if (buddy
&& !PURPLE_BUDDY_IS_ONLINE(buddy
)) {
156 return default_manager
->find_parent(node
);
159 static FinchBlistManager meebo_group
=
168 {NULL
, NULL
, NULL
, NULL
}
174 static gboolean
no_group_init()
176 GntTree
*tree
= finch_blist_get_tree();
177 g_object_set(G_OBJECT(tree
), "expander-level", 0, NULL
);
181 static gboolean
no_group_uninit()
183 GntTree
*tree
= finch_blist_get_tree();
184 g_object_set(G_OBJECT(tree
), "expander-level", 1, NULL
);
188 static gboolean
no_group_can_add_node(PurpleBlistNode
*node
)
190 return on_offline_can_add_node(node
); /* These happen to be the same */
193 static gpointer
no_group_find_parent(PurpleBlistNode
*node
)
197 switch (purple_blist_node_get_type(node
)) {
198 case PURPLE_BLIST_BUDDY_NODE
:
199 ret
= purple_blist_node_get_parent(node
);
200 finch_blist_manager_add_node(ret
);
208 static FinchBlistManager no_group
=
214 no_group_can_add_node
,
215 no_group_find_parent
,
217 {NULL
, NULL
, NULL
, NULL
}
223 static GHashTable
*groups
;
226 nested_group_init(void)
228 groups
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
234 nested_group_uninit(void)
236 g_hash_table_destroy(groups
);
242 nested_group_find_parent(PurpleBlistNode
*node
)
247 PurpleBlistNode
*ret
, *parent
;
250 if (!PURPLE_BLIST_NODE_IS_GROUP(node
))
251 return default_manager
->find_parent(node
);
253 group
= (PurpleGroup
*)node
;
254 name
= g_strdup(purple_group_get_name(group
));
255 if (!(sep
= strchr(name
, '/'))) {
257 return default_manager
->find_parent(node
);
260 tree
= finch_blist_get_tree();
265 if (*(sep
+ 1) && (ret
= (PurpleBlistNode
*)purple_find_group(name
))) {
266 finch_blist_manager_add_node(ret
);
268 } else if (!(ret
= g_hash_table_lookup(groups
, name
))) {
269 ret
= g_new0(PurpleBlistNode
, 1);
270 g_hash_table_insert(groups
, g_strdup(name
), ret
);
271 ret
->type
= PURPLE_BLIST_OTHER_NODE
;
272 gnt_tree_add_row_last(tree
, ret
,
273 gnt_tree_create_row(tree
, name
), parent
);
277 sep
= strchr(sep
+ 1, '/');
285 nested_group_create_tooltip(gpointer selected_row
, GString
**body
, char **title
)
287 PurpleBlistNode
*node
= selected_row
;
289 purple_blist_node_get_type(node
) != PURPLE_BLIST_OTHER_NODE
)
290 return default_manager
->create_tooltip(selected_row
, body
, title
);
292 *body
= g_string_new(_("Nested Subgroup")); /* Perhaps list the child groups/subgroups? */
297 nested_group_can_add_node(PurpleBlistNode
*node
)
299 PurpleBlistNode
*group
;
302 if (!PURPLE_BLIST_NODE_IS_GROUP(node
))
303 return default_manager
->can_add_node(node
);
305 if (default_manager
->can_add_node(node
))
308 len
= strlen(purple_group_get_name((PurpleGroup
*)node
));
309 group
= purple_blist_get_root();
310 for (; group
; group
= purple_blist_node_get_sibling_next(group
)) {
313 if (strncmp(purple_group_get_name((PurpleGroup
*)node
),
314 purple_group_get_name((PurpleGroup
*)group
), len
) == 0 &&
315 default_manager
->can_add_node(group
))
321 static FinchBlistManager nested_group
=
324 N_("Nested Grouping (experimental)"),
325 .init
= nested_group_init
,
326 .uninit
= nested_group_uninit
,
327 .find_parent
= nested_group_find_parent
,
328 .create_tooltip
= nested_group_create_tooltip
,
329 .can_add_node
= nested_group_can_add_node
,
333 plugin_load(PurplePlugin
*plugin
)
335 default_manager
= finch_blist_manager_find("default");
337 finch_blist_install_manager(&on_offline
);
338 finch_blist_install_manager(&meebo_group
);
339 finch_blist_install_manager(&no_group
);
340 finch_blist_install_manager(&nested_group
);
345 plugin_unload(PurplePlugin
*plugin
)
347 finch_blist_uninstall_manager(&on_offline
);
348 finch_blist_uninstall_manager(&meebo_group
);
349 finch_blist_uninstall_manager(&no_group
);
350 finch_blist_uninstall_manager(&nested_group
);
354 static PurplePluginInfo info
=
357 PURPLE_MAJOR_VERSION
,
358 PURPLE_MINOR_VERSION
,
359 PURPLE_PLUGIN_STANDARD
,
363 PURPLE_PRIORITY_DEFAULT
,
367 N_("Provides alternate buddylist grouping options."),
368 N_("Provides alternate buddylist grouping options."),
369 "Sadrul H Chowdhury <sadrul@users.sourceforge.net>",
382 init_plugin(PurplePlugin
*plugin
)
386 PURPLE_INIT_PLUGIN(grouping
, init_plugin
, info
)