finch/gntblist.c

changeset 22285
203b8d12f1ca
parent 22282
a964668bd7e4
child 22286
c97b158bd4f4
equal deleted inserted replaced
22284:1eaf3526de19 22285:203b8d12f1ca
79 79
80 GntWidget *menu; 80 GntWidget *menu;
81 /* These are the menuitems that get regenerated */ 81 /* These are the menuitems that get regenerated */
82 GntMenuItem *accounts; 82 GntMenuItem *accounts;
83 GntMenuItem *plugins; 83 GntMenuItem *plugins;
84
85 FinchBlistManager *manager;
84 } FinchBlist; 86 } FinchBlist;
85 87
86 typedef struct 88 typedef struct
87 { 89 {
88 gpointer row; /* the row in the GntTree */ 90 gpointer row; /* the row in the GntTree */
113 static void add_contact(PurpleContact *contact, FinchBlist *ggblist); 115 static void add_contact(PurpleContact *contact, FinchBlist *ggblist);
114 static void add_group(PurpleGroup *group, FinchBlist *ggblist); 116 static void add_group(PurpleGroup *group, FinchBlist *ggblist);
115 static void add_chat(PurpleChat *chat, FinchBlist *ggblist); 117 static void add_chat(PurpleChat *chat, FinchBlist *ggblist);
116 static void add_node(PurpleBlistNode *node, FinchBlist *ggblist); 118 static void add_node(PurpleBlistNode *node, FinchBlist *ggblist);
117 static void node_update(PurpleBuddyList *list, PurpleBlistNode *node); 119 static void node_update(PurpleBuddyList *list, PurpleBlistNode *node);
120 static gboolean is_contact_online(PurpleContact *contact);
121 static gboolean is_group_online(PurpleGroup *group);
118 static void draw_tooltip(FinchBlist *ggblist); 122 static void draw_tooltip(FinchBlist *ggblist);
123 static void tooltip_for_buddy(PurpleBuddy *buddy, GString *str, gboolean full);
119 static gboolean remove_typing_cb(gpointer null); 124 static gboolean remove_typing_cb(gpointer null);
120 static void remove_peripherals(FinchBlist *ggblist); 125 static void remove_peripherals(FinchBlist *ggblist);
121 static const char * get_display_name(PurpleBlistNode *node); 126 static const char * get_display_name(PurpleBlistNode *node);
122 static void savedstatus_changed(PurpleSavedStatus *now, PurpleSavedStatus *old); 127 static void savedstatus_changed(PurpleSavedStatus *now, PurpleSavedStatus *old);
123 static void blist_show(PurpleBuddyList *list); 128 static void blist_show(PurpleBuddyList *list);
134 139
135 static int color_available; 140 static int color_available;
136 static int color_away; 141 static int color_away;
137 static int color_offline; 142 static int color_offline;
138 static int color_idle; 143 static int color_idle;
144
145 /**
146 * Buddy List Manager functions.
147 */
148
149 static gboolean default_can_add_node(PurpleBlistNode *node)
150 {
151 gboolean offline = purple_prefs_get_bool(PREF_ROOT "/showoffline");
152
153 if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
154 PurpleBuddy *buddy = (PurpleBuddy*)node;
155 if (!purple_buddy_get_contact(buddy))
156 return FALSE; /* When a new buddy is added and show-offline is set */
157 if (PURPLE_BUDDY_IS_ONLINE(buddy))
158 return TRUE; /* The buddy is online */
159 if (!purple_account_is_connected(purple_buddy_get_account(buddy)))
160 return FALSE; /* The account is disconnected. Do not show */
161 if (offline)
162 return TRUE; /* We want to see offline buddies too */
163 } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
164 PurpleContact *contact = (PurpleContact*)node;
165 if (contact->currentsize < 1)
166 return FALSE; /* No online accounts in this contact */
167 if (!offline && !is_contact_online(contact))
168 return FALSE; /* Don't want to see offline buddies */
169 return TRUE;
170 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
171 PurpleChat *chat = (PurpleChat*)node;
172 if (purple_account_is_connected(purple_chat_get_account(chat)))
173 return TRUE; /* Show whenever the account is online */
174 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
175 PurpleGroup *group = (PurpleGroup*)node;
176 gboolean empty = purple_prefs_get_bool(PREF_ROOT "/emptygroups");
177 if (empty)
178 return TRUE; /* If we want to see empty groups, we can show any group */
179
180 if (group->currentsize < 1)
181 return FALSE; /* No online accounts for this group */
182
183 if (!offline && !is_group_online(group))
184 return FALSE; /* Do not want to see group only with offline buddies */
185
186 return TRUE;
187 }
188
189 return FALSE;
190 }
191
192 static gpointer default_find_parent(PurpleBlistNode *node)
193 {
194 gpointer ret = NULL;
195 switch (purple_blist_node_get_type(node)) {
196 case PURPLE_BLIST_BUDDY_NODE:
197 case PURPLE_BLIST_CONTACT_NODE:
198 case PURPLE_BLIST_CHAT_NODE:
199 ret = purple_blist_node_get_parent(node);
200 break;
201 default:
202 break;
203 }
204 if (ret)
205 add_node(ret, ggblist);
206 return ret;
207 }
208
209 static gboolean default_create_tooltip(gpointer selected_row, GString **body, char **tool_title)
210 {
211 GString *str;
212 PurpleBlistNode *node = selected_row;
213 int lastseen = 0;
214 char *title;
215
216 if (!node ||
217 purple_blist_node_get_type(node) == PURPLE_BLIST_OTHER_NODE)
218 return FALSE;
219
220 str = g_string_new("");
221
222 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
223 PurpleBuddy *pr = purple_contact_get_priority_buddy((PurpleContact*)node);
224 gboolean offline = !PURPLE_BUDDY_IS_ONLINE(pr);
225 gboolean showoffline = purple_prefs_get_bool(PREF_ROOT "/showoffline");
226 const char *name = purple_buddy_get_name(pr);
227
228 title = g_strdup(name);
229 tooltip_for_buddy(pr, str, TRUE);
230 for (node = purple_blist_node_get_first_child(node); node; node = purple_blist_node_get_sibling_next(node)) {
231 PurpleBuddy *buddy = (PurpleBuddy*)node;
232 if (offline) {
233 int value = purple_blist_node_get_int(node, "last_seen");
234 if (value > lastseen)
235 lastseen = value;
236 }
237 if (node == (PurpleBlistNode*)pr)
238 continue;
239 if (!purple_account_is_connected(buddy->account))
240 continue;
241 if (!showoffline && !PURPLE_BUDDY_IS_ONLINE(buddy))
242 continue;
243 str = g_string_append(str, "\n----------\n");
244 tooltip_for_buddy(buddy, str, FALSE);
245 }
246 } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
247 PurpleBuddy *buddy = (PurpleBuddy *)node;
248 tooltip_for_buddy(buddy, str, TRUE);
249 title = g_strdup(purple_buddy_get_name(buddy));
250 if (!PURPLE_BUDDY_IS_ONLINE((PurpleBuddy*)node))
251 lastseen = purple_blist_node_get_int(node, "last_seen");
252 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
253 PurpleGroup *group = (PurpleGroup *)node;
254
255 g_string_append_printf(str, _("Online: %d\nTotal: %d"),
256 purple_blist_get_group_online_count(group),
257 purple_blist_get_group_size(group, FALSE));
258
259 title = g_strdup(group->name);
260 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
261 PurpleChat *chat = (PurpleChat *)node;
262 PurpleAccount *account = chat->account;
263
264 g_string_append_printf(str, _("Account: %s (%s)"),
265 purple_account_get_username(account),
266 purple_account_get_protocol_name(account));
267
268 title = g_strdup(purple_chat_get_name(chat));
269 } else {
270 g_string_free(str, TRUE);
271 return FALSE;
272 }
273
274 if (lastseen > 0) {
275 char *tmp = purple_str_seconds_to_string(time(NULL) - lastseen);
276 g_string_append_printf(str, _("\nLast Seen: %s ago"), tmp);
277 g_free(tmp);
278 }
279
280 if (tool_title)
281 *tool_title = title;
282 else
283 g_free(title);
284
285 if (body)
286 *body = str;
287 else
288 g_string_free(str, TRUE);
289
290 return TRUE;
291 }
292
293 static FinchBlistManager default_manager =
294 {
295 "default",
296 N_("Default"),
297 default_can_add_node,
298 default_find_parent,
299 default_create_tooltip,
300 {NULL, NULL, NULL, NULL}
301 };
302 static GList *managers;
139 303
140 static FinchBlistNode * 304 static FinchBlistNode *
141 create_finch_blist_node(PurpleBlistNode *node, gpointer row) 305 create_finch_blist_node(PurpleBlistNode *node, gpointer row)
142 { 306 {
143 FinchBlistNode *fnode = node->ui_data; 307 FinchBlistNode *fnode = node->ui_data;
246 static void 410 static void
247 new_node(PurpleBlistNode *node) 411 new_node(PurpleBlistNode *node)
248 { 412 {
249 } 413 }
250 414
251 static void add_node(PurpleBlistNode *node, FinchBlist *ggblist) 415 static void
252 { 416 add_node(PurpleBlistNode *node, FinchBlist *ggblist)
417 {
418 if (!ggblist->manager->can_add_node(node))
419 return;
420
253 if (PURPLE_BLIST_NODE_IS_BUDDY(node)) 421 if (PURPLE_BLIST_NODE_IS_BUDDY(node))
254 add_buddy((PurpleBuddy*)node, ggblist); 422 add_buddy((PurpleBuddy*)node, ggblist);
255 else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) 423 else if (PURPLE_BLIST_NODE_IS_CONTACT(node))
256 add_contact((PurpleContact*)node, ggblist); 424 add_contact((PurpleContact*)node, ggblist);
257 else if (PURPLE_BLIST_NODE_IS_GROUP(node)) 425 else if (PURPLE_BLIST_NODE_IS_GROUP(node))
258 add_group((PurpleGroup*)node, ggblist); 426 add_group((PurpleGroup*)node, ggblist);
259 else if (PURPLE_BLIST_NODE_IS_CHAT(node)) 427 else if (PURPLE_BLIST_NODE_IS_CHAT(node))
260 add_chat((PurpleChat *)node, ggblist); 428 add_chat((PurpleChat *)node, ggblist);
261 draw_tooltip(ggblist); 429 draw_tooltip(ggblist);
430 }
431
432 void finch_blist_manager_add_node(PurpleBlistNode *node)
433 {
434 add_node(node, ggblist);
262 } 435 }
263 436
264 static void 437 static void
265 remove_tooltip(FinchBlist *ggblist) 438 remove_tooltip(FinchBlist *ggblist)
266 { 439 {
321 if (node->ui_data != NULL) { 494 if (node->ui_data != NULL) {
322 gnt_tree_change_text(GNT_TREE(ggblist->tree), node, 495 gnt_tree_change_text(GNT_TREE(ggblist->tree), node,
323 0, get_display_name(node)); 496 0, get_display_name(node));
324 gnt_tree_sort_row(GNT_TREE(ggblist->tree), node); 497 gnt_tree_sort_row(GNT_TREE(ggblist->tree), node);
325 blist_update_row_flags(node); 498 blist_update_row_flags(node);
499 if (gnt_tree_get_parent_key(GNT_TREE(ggblist->tree), node) !=
500 ggblist->manager->find_parent(node))
501 node_remove(list, node);
326 } 502 }
327 503
328 if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { 504 if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
329 PurpleBuddy *buddy = (PurpleBuddy*)node; 505 PurpleBuddy *buddy = (PurpleBuddy*)node;
330 add_node((PurpleBlistNode*)buddy, list->ui_data); 506 add_node((PurpleBlistNode*)buddy, list->ui_data);
331
332 node_update(list, purple_blist_node_get_parent(node)); 507 node_update(list, purple_blist_node_get_parent(node));
333 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { 508 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
334 add_chat((PurpleChat *)node, list->ui_data); 509 add_node(node, list->ui_data);
335 } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { 510 } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
336 PurpleContact *contact = (PurpleContact*)node; 511 if (node->ui_data == NULL) {
337 if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_contact_online(contact)) || 512 /* The core seems to expect the UI to add the buddies. */
338 contact->currentsize < 1) 513 for (node = purple_blist_node_get_first_child(node); node; node = purple_blist_node_get_sibling_next(node))
339 /* nothing */; 514 add_node(node, list->ui_data);
340 else {
341 if (node->ui_data == NULL) {
342 /* The core seems to expect the UI to add the buddies. */
343 for (node = purple_blist_node_get_first_child(node); node; node = purple_blist_node_get_sibling_next(node))
344 add_node(node, list->ui_data);
345 }
346 } 515 }
347 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { 516 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
348 PurpleGroup *group = (PurpleGroup*)node; 517 PurpleGroup *group = (PurpleGroup*)node;
349 if (!purple_prefs_get_bool(PREF_ROOT "/emptygroups") && 518 if (!purple_prefs_get_bool(PREF_ROOT "/emptygroups") &&
350 ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) || 519 ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) ||
361 if (ggblist) 530 if (ggblist)
362 return; 531 return;
363 532
364 ggblist = g_new0(FinchBlist, 1); 533 ggblist = g_new0(FinchBlist, 1);
365 list->ui_data = ggblist; 534 list->ui_data = ggblist;
535 ggblist->manager = &default_manager;
366 } 536 }
367 537
368 static void 538 static void
369 add_buddy_cb(void *data, PurpleRequestFields *allfields) 539 add_buddy_cb(void *data, PurpleRequestFields *allfields)
370 { 540 {
578 } 748 }
579 749
580 static void 750 static void
581 add_group(PurpleGroup *group, FinchBlist *ggblist) 751 add_group(PurpleGroup *group, FinchBlist *ggblist)
582 { 752 {
753 gpointer parent;
583 PurpleBlistNode *node = (PurpleBlistNode *)group; 754 PurpleBlistNode *node = (PurpleBlistNode *)group;
584 if (node->ui_data) 755 if (node->ui_data)
585 return; 756 return;
757 parent = ggblist->manager->find_parent((PurpleBlistNode*)group);
586 create_finch_blist_node(node, gnt_tree_add_row_after(GNT_TREE(ggblist->tree), group, 758 create_finch_blist_node(node, gnt_tree_add_row_after(GNT_TREE(ggblist->tree), group,
587 gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)), NULL, NULL)); 759 gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)),
760 parent, NULL));
588 gnt_tree_set_expanded(GNT_TREE(ggblist->tree), node, 761 gnt_tree_set_expanded(GNT_TREE(ggblist->tree), node,
589 !purple_blist_node_get_bool(node, "collapsed")); 762 !purple_blist_node_get_bool(node, "collapsed"));
590 } 763 }
591 764
592 static const char * 765 static const char *
648 } 821 }
649 822
650 static void 823 static void
651 add_chat(PurpleChat *chat, FinchBlist *ggblist) 824 add_chat(PurpleChat *chat, FinchBlist *ggblist)
652 { 825 {
653 PurpleGroup *group; 826 gpointer parent;
654 PurpleBlistNode *node = (PurpleBlistNode *)chat; 827 PurpleBlistNode *node = (PurpleBlistNode *)chat;
655 if (node->ui_data) 828 if (node->ui_data)
656 return; 829 return;
657 if (!purple_account_is_connected(chat->account)) 830 if (!purple_account_is_connected(chat->account))
658 return; 831 return;
659 832
660 group = purple_chat_get_group(chat); 833 parent = ggblist->manager->find_parent((PurpleBlistNode*)chat);
661 add_node((PurpleBlistNode*)group, ggblist);
662 834
663 create_finch_blist_node(node, gnt_tree_add_row_after(GNT_TREE(ggblist->tree), chat, 835 create_finch_blist_node(node, gnt_tree_add_row_after(GNT_TREE(ggblist->tree), chat,
664 gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)), 836 gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)),
665 group, NULL)); 837 parent, NULL));
666 } 838 }
667 839
668 static void 840 static void
669 add_contact(PurpleContact *contact, FinchBlist *ggblist) 841 add_contact(PurpleContact *contact, FinchBlist *ggblist)
670 { 842 {
671 PurpleGroup *group; 843 gpointer parent;
672 PurpleBlistNode *node = (PurpleBlistNode*)contact; 844 PurpleBlistNode *node = (PurpleBlistNode*)contact;
673 const char *name; 845 const char *name;
674 846
675 if (node->ui_data) 847 if (node->ui_data)
676 return; 848 return;
677 849
678 name = get_display_name(node); 850 name = get_display_name(node);
679 if (name == NULL) 851 if (name == NULL)
680 return; 852 return;
681 853
682 group = (PurpleGroup*)purple_blist_node_get_parent(node); 854 parent = ggblist->manager->find_parent((PurpleBlistNode*)contact);
683 add_node((PurpleBlistNode*)group, ggblist);
684 855
685 create_finch_blist_node(node, gnt_tree_add_row_after(GNT_TREE(ggblist->tree), contact, 856 create_finch_blist_node(node, gnt_tree_add_row_after(GNT_TREE(ggblist->tree), contact,
686 gnt_tree_create_row(GNT_TREE(ggblist->tree), name), 857 gnt_tree_create_row(GNT_TREE(ggblist->tree), name),
687 group, NULL)); 858 parent, NULL));
688 859
689 gnt_tree_set_expanded(GNT_TREE(ggblist->tree), contact, FALSE); 860 gnt_tree_set_expanded(GNT_TREE(ggblist->tree), contact, FALSE);
690 } 861 }
691 862
692 static void 863 static void
693 add_buddy(PurpleBuddy *buddy, FinchBlist *ggblist) 864 add_buddy(PurpleBuddy *buddy, FinchBlist *ggblist)
694 { 865 {
866 gpointer parent;
867 PurpleBlistNode *node = (PurpleBlistNode *)buddy;
695 PurpleContact *contact; 868 PurpleContact *contact;
696 PurpleBlistNode *node = (PurpleBlistNode *)buddy;
697 869
698 if (node->ui_data) 870 if (node->ui_data)
699 return; 871 return;
700 872
701 if (!purple_account_is_connected(buddy->account)) 873 contact = purple_buddy_get_contact(buddy);
702 return; 874 parent = ggblist->manager->find_parent((PurpleBlistNode*)buddy);
703
704 if (!PURPLE_BUDDY_IS_ONLINE(buddy) && !purple_prefs_get_bool(PREF_ROOT "/showoffline"))
705 return;
706
707 contact = (PurpleContact*)purple_blist_node_get_parent(node);
708 if (!contact) /* When a new buddy is added and show-offline is set */
709 return;
710 add_node((PurpleBlistNode*)contact, ggblist);
711 875
712 create_finch_blist_node(node, gnt_tree_add_row_after(GNT_TREE(ggblist->tree), buddy, 876 create_finch_blist_node(node, gnt_tree_add_row_after(GNT_TREE(ggblist->tree), buddy,
713 gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)), 877 gnt_tree_create_row(GNT_TREE(ggblist->tree), get_display_name(node)),
714 contact, NULL)); 878 parent, NULL));
715 879
716 blist_update_row_flags((PurpleBlistNode*)buddy); 880 blist_update_row_flags((PurpleBlistNode*)buddy);
717 if (buddy == purple_contact_get_priority_buddy(contact)) 881 if (buddy == purple_contact_get_priority_buddy(contact))
718 blist_update_row_flags((PurpleBlistNode*)contact); 882 blist_update_row_flags((PurpleBlistNode*)contact);
719 } 883 }
1219 finch_blist_place_tagged(PurpleBlistNode *target) 1383 finch_blist_place_tagged(PurpleBlistNode *target)
1220 { 1384 {
1221 PurpleGroup *tg = NULL; 1385 PurpleGroup *tg = NULL;
1222 PurpleContact *tc = NULL; 1386 PurpleContact *tc = NULL;
1223 1387
1224 if (target == NULL) 1388 if (target == NULL ||
1389 purple_blist_node_get_type(target) == PURPLE_BLIST_OTHER_NODE)
1225 return; 1390 return;
1226 1391
1227 if (PURPLE_BLIST_NODE_IS_GROUP(target)) 1392 if (PURPLE_BLIST_NODE_IS_GROUP(target))
1228 tg = (PurpleGroup*)target; 1393 tg = (PurpleGroup*)target;
1229 else if (PURPLE_BLIST_NODE_IS_BUDDY(target)) { 1394 else if (PURPLE_BLIST_NODE_IS_BUDDY(target)) {
1445 static gboolean 1610 static gboolean
1446 draw_tooltip_real(FinchBlist *ggblist) 1611 draw_tooltip_real(FinchBlist *ggblist)
1447 { 1612 {
1448 PurpleBlistNode *node; 1613 PurpleBlistNode *node;
1449 int x, y, top, width, w, h; 1614 int x, y, top, width, w, h;
1450 GString *str; 1615 GString *str = NULL;
1451 GntTree *tree; 1616 GntTree *tree;
1452 GntWidget *widget, *box, *tv; 1617 GntWidget *widget, *box, *tv;
1453 char *title = NULL; 1618 char *title = NULL;
1454 int lastseen = 0;
1455 1619
1456 widget = ggblist->tree; 1620 widget = ggblist->tree;
1457 tree = GNT_TREE(widget); 1621 tree = GNT_TREE(widget);
1458 1622
1459 if (!gnt_widget_has_focus(ggblist->tree) || 1623 if (!gnt_widget_has_focus(ggblist->tree) ||
1460 (ggblist->context && !GNT_WIDGET_IS_FLAG_SET(ggblist->context, GNT_WIDGET_INVISIBLE))) 1624 (ggblist->context && !GNT_WIDGET_IS_FLAG_SET(ggblist->context, GNT_WIDGET_INVISIBLE)))
1461 return FALSE; 1625 return FALSE;
1462 1626
1463 if (ggblist->tooltip) 1627 if (ggblist->tooltip)
1464 { 1628 {
1469 1633
1470 node = gnt_tree_get_selection_data(tree); 1634 node = gnt_tree_get_selection_data(tree);
1471 if (!node) 1635 if (!node)
1472 return FALSE; 1636 return FALSE;
1473 1637
1474 str = g_string_new(""); 1638 if (!ggblist->manager->create_tooltip(node, &str, &title))
1475
1476 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
1477 PurpleBuddy *pr = purple_contact_get_priority_buddy((PurpleContact*)node);
1478 gboolean offline = !PURPLE_BUDDY_IS_ONLINE(pr);
1479 gboolean showoffline = purple_prefs_get_bool(PREF_ROOT "/showoffline");
1480 const char *name = purple_buddy_get_name(pr);
1481
1482 title = g_strdup(name);
1483 tooltip_for_buddy(pr, str, TRUE);
1484 for (node = purple_blist_node_get_first_child(node); node; node = purple_blist_node_get_sibling_next(node)) {
1485 PurpleBuddy *buddy = (PurpleBuddy*)node;
1486 if (offline) {
1487 int value = purple_blist_node_get_int(node, "last_seen");
1488 if (value > lastseen)
1489 lastseen = value;
1490 }
1491 if (node == (PurpleBlistNode*)pr)
1492 continue;
1493 if (!purple_account_is_connected(buddy->account))
1494 continue;
1495 if (!showoffline && !PURPLE_BUDDY_IS_ONLINE(buddy))
1496 continue;
1497 str = g_string_append(str, "\n----------\n");
1498 tooltip_for_buddy(buddy, str, FALSE);
1499 }
1500 } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
1501 PurpleBuddy *buddy = (PurpleBuddy *)node;
1502 tooltip_for_buddy(buddy, str, TRUE);
1503 title = g_strdup(purple_buddy_get_name(buddy));
1504 if (!PURPLE_BUDDY_IS_ONLINE((PurpleBuddy*)node))
1505 lastseen = purple_blist_node_get_int(node, "last_seen");
1506 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
1507 PurpleGroup *group = (PurpleGroup *)node;
1508
1509 g_string_append_printf(str, _("Online: %d\nTotal: %d"),
1510 purple_blist_get_group_online_count(group),
1511 purple_blist_get_group_size(group, FALSE));
1512
1513 title = g_strdup(group->name);
1514 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
1515 PurpleChat *chat = (PurpleChat *)node;
1516 PurpleAccount *account = chat->account;
1517
1518 g_string_append_printf(str, _("Account: %s (%s)"),
1519 purple_account_get_username(account),
1520 purple_account_get_protocol_name(account));
1521
1522 title = g_strdup(purple_chat_get_name(chat));
1523 } else {
1524 g_string_free(str, TRUE);
1525 return FALSE; 1639 return FALSE;
1526 }
1527
1528 if (lastseen > 0) {
1529 char *tmp = purple_str_seconds_to_string(time(NULL) - lastseen);
1530 g_string_append_printf(str, _("\nLast Seen: %s ago"), tmp);
1531 g_free(tmp);
1532 }
1533 1640
1534 gnt_widget_get_position(widget, &x, &y); 1641 gnt_widget_get_position(widget, &x, &y);
1535 gnt_widget_get_size(widget, &width, NULL); 1642 gnt_widget_get_size(widget, &width, NULL);
1536 top = gnt_tree_get_selection_visible_line(tree); 1643 top = gnt_tree_get_selection_visible_line(tree);
1537 1644
1846 purple_prefs_connect_callback(finch_blist_get_handle(), 1953 purple_prefs_connect_callback(finch_blist_get_handle(),
1847 PREF_ROOT "/sort_type", redraw_blist, NULL); 1954 PREF_ROOT "/sort_type", redraw_blist, NULL);
1848 1955
1849 purple_signal_connect(purple_connections_get_handle(), "signed-on", purple_blist_get_handle(), 1956 purple_signal_connect(purple_connections_get_handle(), "signed-on", purple_blist_get_handle(),
1850 G_CALLBACK(account_signed_on_cb), NULL); 1957 G_CALLBACK(account_signed_on_cb), NULL);
1958
1959 finch_blist_install_manager(&default_manager);
1960
1851 return; 1961 return;
1852 } 1962 }
1853 1963
1854 static gboolean 1964 static gboolean
1855 remove_typing_cb(gpointer null) 1965 remove_typing_cb(gpointer null)
2442 { 2552 {
2443 purple_blist_request_add_group(); 2553 purple_blist_request_add_group();
2444 } 2554 }
2445 2555
2446 static void 2556 static void
2557 menu_group_set_cb(GntMenuItem *item, gpointer null)
2558 {
2559 const char *id = g_object_get_data(G_OBJECT(item), "grouping-id");
2560 FinchBlistManager *manager;
2561
2562 manager = finch_blist_manager_find(id);
2563 if (!manager)
2564 return;
2565
2566 ggblist->manager = manager;
2567 if (ggblist->manager->can_add_node == NULL)
2568 ggblist->manager->can_add_node = default_can_add_node;
2569 if (ggblist->manager->find_parent == NULL)
2570 ggblist->manager->find_parent = default_find_parent;
2571 if (ggblist->manager->create_tooltip == NULL)
2572 ggblist->manager->create_tooltip = default_create_tooltip;
2573
2574 redraw_blist(NULL, 0, NULL, NULL);
2575 }
2576
2577 static void
2447 create_menu(void) 2578 create_menu(void)
2448 { 2579 {
2449 GntWidget *menu, *sub, *subsub; 2580 GntWidget *menu, *sub, *subsub;
2450 GntMenuItem *item; 2581 GntMenuItem *item;
2451 GntWindow *window; 2582 GntWindow *window;
2583 GList *iter;
2452 2584
2453 if (!ggblist) 2585 if (!ggblist)
2454 return; 2586 return;
2455 2587
2456 window = GNT_WINDOW(ggblist->window); 2588 window = GNT_WINDOW(ggblist->window);
2530 2662
2531 item = gnt_menuitem_new("Group"); 2663 item = gnt_menuitem_new("Group");
2532 gnt_menuitem_set_id(GNT_MENU_ITEM(item), "add-group"); 2664 gnt_menuitem_set_id(GNT_MENU_ITEM(item), "add-group");
2533 gnt_menu_add_item(GNT_MENU(subsub), item); 2665 gnt_menu_add_item(GNT_MENU(subsub), item);
2534 gnt_menuitem_set_callback(item, menu_add_group_cb, NULL); 2666 gnt_menuitem_set_callback(item, menu_add_group_cb, NULL);
2667
2668 item = gnt_menuitem_new(_("Grouping"));
2669 gnt_menu_add_item(GNT_MENU(sub), item);
2670
2671 subsub = gnt_menu_new(GNT_MENU_POPUP);
2672 gnt_menuitem_set_submenu(item, GNT_MENU(subsub));
2673
2674 for (iter = managers; iter; iter = iter->next) {
2675 char menuid[128];
2676 FinchBlistManager *manager = iter->data;
2677 item = gnt_menuitem_new(_(manager->name));
2678 snprintf(menuid, sizeof(menuid), "grouping-%s", manager->id);
2679 gnt_menuitem_set_id(GNT_MENU_ITEM(item), menuid);
2680 gnt_menu_add_item(GNT_MENU(subsub), item);
2681 g_object_set_data_full(G_OBJECT(item), "grouping-id", g_strdup(manager->id), g_free);
2682 gnt_menuitem_set_callback(item, menu_group_set_cb, NULL);
2683 }
2535 2684
2536 reconstruct_accounts_menu(); 2685 reconstruct_accounts_menu();
2537 gnt_menu_add_item(GNT_MENU(menu), ggblist->accounts); 2686 gnt_menu_add_item(GNT_MENU(menu), ggblist->accounts);
2538 2687
2539 reconstruct_plugins_menu(); 2688 reconstruct_plugins_menu();
2682 2831
2683 void finch_blist_set_size(int width, int height) 2832 void finch_blist_set_size(int width, int height)
2684 { 2833 {
2685 gnt_widget_set_size(ggblist->window, width, height); 2834 gnt_widget_set_size(ggblist->window, width, height);
2686 } 2835 }
2836
2837 void finch_blist_install_manager(const FinchBlistManager *manager)
2838 {
2839 if (!g_list_find(managers, manager))
2840 managers = g_list_append(managers, (gpointer)manager);
2841 }
2842
2843 void finch_blist_uninstall_manager(const FinchBlistManager *manager)
2844 {
2845 managers = g_list_remove(managers, manager);
2846 }
2847
2848 FinchBlistManager * finch_blist_manager_find(const char *id)
2849 {
2850 GList *iter = managers;
2851 if (!id)
2852 return NULL;
2853
2854 for (; iter; iter = iter->next) {
2855 FinchBlistManager *m = iter->data;
2856 if (strcmp(id, m->id) == 0)
2857 return m;
2858 }
2859 return NULL;
2860 }
2861
2862 GntTree * finch_blist_get_tree(void)
2863 {
2864 return ggblist ? GNT_TREE(ggblist->tree) : NULL;
2865 }
2866

mercurial