pidgin  2.13.0
About: Pidgin is a chat program (multi-protocol instant messaging client) which lets you log in to accounts on multiple chat networks simultaneously (old name "gaim").
  Fossies Dox: pidgin-2.13.0.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

gntblist.c
Go to the documentation of this file.
1 
6 /* finch
7  *
8  * Finch is the legal property of its developers, whose names are too numerous
9  * to list here. Please refer to the COPYRIGHT file distributed with this
10  * source distribution.
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
25  */
26 #include <internal.h>
27 #include "finch.h"
28 
29 #include <account.h>
30 #include <blist.h>
31 #include <log.h>
32 #include <notify.h>
33 #include <privacy.h>
34 #include <request.h>
35 #include <savedstatuses.h>
36 #include <server.h>
37 #include <signal.h>
38 #include <status.h>
39 #include <util.h>
40 #include "debug.h"
41 
42 #include "gntbox.h"
43 #include "gntcolors.h"
44 #include "gntcombobox.h"
45 #include "gntentry.h"
46 #include "gntft.h"
47 #include "gntlabel.h"
48 #include "gntline.h"
49 #include "gntlog.h"
50 #include "gntmenu.h"
51 #include "gntmenuitem.h"
52 #include "gntmenuitemcheck.h"
53 #include "gntpounce.h"
54 #include "gntstyle.h"
55 #include "gnttree.h"
56 #include "gntutils.h"
57 #include "gntwindow.h"
58 
59 #include "gntblist.h"
60 #include "gntconv.h"
61 #include "gntstatus.h"
62 #include <string.h>
63 
64 #define PREF_ROOT "/finch/blist"
65 #define TYPING_TIMEOUT_S 4
66 
67 #define SHOW_EMPTY_GROUP_TIMEOUT 60
68 
69 typedef struct
70 {
73 
75  PurpleBlistNode *tnode; /* Who is the tooltip being displayed for? */
76  GList *tagged; /* A list of tagged blistnodes */
77 
80 
81  /* XXX: I am KISSing */
82  GntWidget *status; /* Dropdown with the statuses */
83  GntWidget *statustext; /* Status message */
84  int typing;
85 
87  /* These are the menuitems that get regenerated */
91 
92  /* When a new group is manually added, it is empty, but we still want to show it
93  * for a while (SHOW_EMPTY_GROUP_TIMEOUT seconds) even if 'show empty groups' is
94  * not selected.
95  */
96  GList *new_group;
98 
100 } FinchBlist;
101 
102 typedef struct
103 {
104  gpointer row; /* the row in the GntTree */
105  guint signed_timer; /* used when 'recently' signed on/off */
107 
108 typedef enum
109 {
114 } StatusType;
115 
116 typedef struct
117 {
119  union
120  {
123  } u;
124 } StatusBoxItem;
125 
127 
128 static void add_buddy(PurpleBuddy *buddy, FinchBlist *ggblist);
129 static void add_contact(PurpleContact *contact, FinchBlist *ggblist);
131 static void add_chat(PurpleChat *chat, FinchBlist *ggblist);
133 static void node_update(PurpleBuddyList *list, PurpleBlistNode *node);
134 #if 0
135 static gboolean is_contact_online(PurpleContact *contact);
136 static gboolean is_group_online(PurpleGroup *group);
137 #endif
138 static void draw_tooltip(FinchBlist *ggblist);
139 static void tooltip_for_buddy(PurpleBuddy *buddy, GString *str, gboolean full);
140 static gboolean remove_typing_cb(gpointer null);
142 static const char * get_display_name(PurpleBlistNode *node);
144 static void blist_show(PurpleBuddyList *list);
146 static void update_buddy_display(PurpleBuddy *buddy, FinchBlist *ggblist);
147 static gboolean account_autojoin_cb(PurpleConnection *pc, gpointer null);
148 static void finch_request_add_buddy(PurpleAccount *account, const char *username, const char *grp, const char *alias);
149 static void menu_group_set_cb(GntMenuItem *item, gpointer null);
150 
151 /* Sort functions */
156 
157 static int color_available;
158 static int color_away;
159 static int color_offline;
160 static int color_idle;
161 
167 {
168  gboolean offline = purple_prefs_get_bool(PREF_ROOT "/showoffline");
169 
171  PurpleBuddy *buddy = (PurpleBuddy*)node;
173  if (!purple_buddy_get_contact(buddy))
174  return FALSE; /* When a new buddy is added and show-offline is set */
175  if (PURPLE_BUDDY_IS_ONLINE(buddy))
176  return TRUE; /* The buddy is online */
178  return FALSE; /* The account is disconnected. Do not show */
179  if (offline)
180  return TRUE; /* We want to see offline buddies too */
181  if (fnode && fnode->signed_timer)
182  return TRUE; /* Show if the buddy just signed off */
183  if (purple_blist_node_get_bool(node, "show_offline"))
184  return TRUE;
185  } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
186  PurpleBlistNode *nd;
188  nd; nd = purple_blist_node_get_sibling_next(nd)) {
189  if (default_can_add_node(nd))
190  return TRUE;
191  }
192  } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
193  PurpleChat *chat = (PurpleChat*)node;
195  return TRUE; /* Show whenever the account is online */
196  } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
197  PurpleBlistNode *nd;
198  gboolean empty = purple_prefs_get_bool(PREF_ROOT "/emptygroups");
199  if (empty)
200  return TRUE; /* If we want to see empty groups, we can show any group */
201 
203  nd; nd = purple_blist_node_get_sibling_next(nd)) {
204  if (default_can_add_node(nd))
205  return TRUE;
206  }
207 
208  if (ggblist && ggblist->new_group && g_list_find(ggblist->new_group, node))
209  return TRUE;
210  }
211 
212  return FALSE;
213 }
214 
216 {
217  gpointer ret = NULL;
218  switch (purple_blist_node_get_type(node)) {
223  break;
224  default:
225  break;
226  }
227  if (ret)
228  add_node(ret, ggblist);
229  return ret;
230 }
231 
232 static gboolean default_create_tooltip(gpointer selected_row, GString **body, char **tool_title)
233 {
234  GString *str;
235  PurpleBlistNode *node = selected_row;
236  int lastseen = 0;
237  char *title;
238 
239  if (!node ||
241  return FALSE;
242 
243  str = g_string_new("");
244 
247  gboolean offline = !PURPLE_BUDDY_IS_ONLINE(pr);
248  gboolean showoffline = purple_prefs_get_bool(PREF_ROOT "/showoffline");
249  const char *name = purple_buddy_get_name(pr);
250 
251  title = g_strdup(name);
252  tooltip_for_buddy(pr, str, TRUE);
254  PurpleBuddy *buddy = (PurpleBuddy*)node;
255  if (offline) {
256  int value = purple_blist_node_get_int(node, "last_seen");
257  if (value > lastseen)
258  lastseen = value;
259  }
260  if (node == (PurpleBlistNode*)pr)
261  continue;
263  continue;
264  if (!showoffline && !PURPLE_BUDDY_IS_ONLINE(buddy))
265  continue;
266  str = g_string_append(str, "\n----------\n");
267  tooltip_for_buddy(buddy, str, FALSE);
268  }
269  } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
270  PurpleBuddy *buddy = (PurpleBuddy *)node;
271  tooltip_for_buddy(buddy, str, TRUE);
272  title = g_strdup(purple_buddy_get_name(buddy));
274  lastseen = purple_blist_node_get_int(node, "last_seen");
275  } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
277 
278  g_string_append_printf(str, _("Online: %d\nTotal: %d"),
281 
282  title = g_strdup(purple_group_get_name(group));
283  } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
284  PurpleChat *chat = (PurpleChat *)node;
286 
287  g_string_append_printf(str, _("Account: %s (%s)"),
290 
291  title = g_strdup(purple_chat_get_name(chat));
292  } else {
293  g_string_free(str, TRUE);
294  return FALSE;
295  }
296 
297  if (lastseen > 0) {
298  char *tmp = purple_str_seconds_to_string(time(NULL) - lastseen);
299  g_string_append_printf(str, _("\nLast Seen: %s ago"), tmp);
300  g_free(tmp);
301  }
302 
303  if (tool_title)
304  *tool_title = title;
305  else
306  g_free(title);
307 
308  if (body)
309  *body = str;
310  else
311  g_string_free(str, TRUE);
312 
313  return TRUE;
314 }
315 
317 {
318  "default",
319  N_("Default"),
320  NULL,
321  NULL,
325  {NULL, NULL, NULL, NULL}
326 };
327 static GList *managers;
328 
329 static FinchBlistNode *
331 {
333  if (!fnode) {
334  fnode = g_new0(FinchBlistNode, 1);
335  fnode->signed_timer = 0;
336  FINCH_SET_DATA(node, fnode);
337  }
338  fnode->row = row;
339  return fnode;
340 }
341 
342 static void
344 {
346  if (fnode == NULL)
347  return;
348  if (fnode->signed_timer)
350  g_free(fnode);
352 }
353 
354 static int
356 {
357  PurpleBuddy *buddy;
358  int color = 0;
359 
363  return 0;
364 
365  buddy = (PurpleBuddy*)node;
367  color = color_idle;
369  color = color_available;
372  color = color_away;
374  color = color_offline;
375  }
376 
377  return color;
378 }
379 
380 static GntTextFormatFlags
382 {
385 
386  if (ggblist->tagged && g_list_find(ggblist->tagged, node))
388 
389  if (fnode && fnode->signed_timer)
393  fnode = FINCH_GET_DATA(node);
394  if (fnode && fnode->signed_timer)
396  } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
397  /* If the node is collapsed, then check to see if any of the priority buddies of
398  * any of the contacts within this group recently signed on/off, and set the blink
399  * flag appropriately. */
400  /* XXX: Refs #5444 */
401  /* XXX: there's no way I can ask if the node is expanded or not? *sigh*
402  * API addition would be necessary */
403 #if 0
404  if (!gnt_tree_get_expanded(GNT_TREE(ggblist->tree), node)) {
407  PurpleBlistNode *pnode;
409  fnode = FINCH_GET_DATA(node);
410  if (fnode && fnode->signed_timer) {
412  break;
413  }
414  }
415  }
416 #endif
417  }
418 
419  return flag;
420 }
421 
422 static void
424 {
427 }
428 
429 #if 0
430 static gboolean
431 is_contact_online(PurpleContact *contact)
432 {
438  (fnode && fnode->signed_timer))
439  return TRUE;
440  }
441  return FALSE;
442 }
443 
444 static gboolean
445 is_group_online(PurpleGroup *group)
446 {
452  return TRUE;
453  else if (is_contact_online((PurpleContact*)node))
454  return TRUE;
455  }
456  return FALSE;
457 }
458 #endif
459 
460 static void
462 {
463 }
464 
465 static void
467 {
468  if (FINCH_GET_DATA(node))
469  return;
470 
472  return;
473 
482 
484 }
485 
487 {
489 }
490 
491 static void
493 {
495  ggblist->tooltip = NULL;
496  ggblist->tnode = NULL;
497 }
498 
499 static void
501 {
503  PurpleBlistNode *parent;
504 
505  if (ggblist == NULL || FINCH_GET_DATA(node) == NULL)
506  return;
507 
509  ggblist->new_group = g_list_remove(ggblist->new_group, node);
510  }
511 
514  if (ggblist->tagged)
515  ggblist->tagged = g_list_remove(ggblist->tagged, node);
516 
520  node_remove(list, node);
521 
522  if (parent) {
523  if (!ggblist->manager->can_add_node(parent))
524  node_remove(list, parent);
525  else
526  node_update(list, parent);
527  }
528 
530 }
531 
532 static void
534 {
535  /* It really looks like this should never happen ... but it does.
536  This will at least emit a warning to the log when it
537  happens, so maybe someone will figure it out. */
538  g_return_if_fail(node != NULL);
539 
540  if (FINCH_GET_DATA(list)== NULL)
541  return; /* XXX: this is probably the place to auto-join chats */
542 
543  if (ggblist->window == NULL)
544  return;
545 
546  if (FINCH_GET_DATA(node)!= NULL) {
548  0, get_display_name(node));
553  node_remove(list, node);
554  }
555 
557  PurpleBuddy *buddy = (PurpleBuddy*)node;
558  add_node((PurpleBlistNode*)buddy, FINCH_GET_DATA(list));
560  } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
561  add_node(node, FINCH_GET_DATA(list));
562  } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
563  if (FINCH_GET_DATA(node)== NULL) {
564  /* The core seems to expect the UI to add the buddies. */
566  add_node(node, FINCH_GET_DATA(list));
567  }
568  } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
570  node_remove(list, node);
571  else
572  add_node(node, FINCH_GET_DATA(list));
573  }
574  if (ggblist->tnode == node) {
576  }
577 }
578 
579 static void
581 {
582  if (ggblist)
583  return;
584 
585  ggblist = g_new0(FinchBlist, 1);
586  FINCH_SET_DATA(list, ggblist);
588  if (!ggblist->manager)
590 }
591 
592 static void destroy_list(PurpleBuddyList *list)
593 {
594  if (ggblist == NULL)
595  return;
596 
598  g_free(ggblist);
599  ggblist = NULL;
600 }
601 
602 static gboolean
604 {
605  PurpleBuddyList *list;
606 
607  if (!ggblist)
608  return FALSE;
609 
610  list = purple_get_blist();
611  g_return_val_if_fail(list, FALSE);
612 
614  while (ggblist->new_group) {
616  ggblist->new_group = g_list_delete_link(ggblist->new_group, ggblist->new_group);
617  node_update(list, group);
618  }
619 
620  return FALSE;
621 }
622 
623 static void
625 {
626  const char *username = purple_request_fields_get_string(allfields, "screenname");
627  const char *alias = purple_request_fields_get_string(allfields, "alias");
628  const char *group = purple_request_fields_get_string(allfields, "group");
629  const char *invite = purple_request_fields_get_string(allfields, "invite");
631  const char *error = NULL;
632  PurpleGroup *grp;
633  PurpleBuddy *buddy;
634 
635  if (!username)
636  error = _("You must provide a username for the buddy.");
637  else if (!group)
638  error = _("You must provide a group.");
639  else if (!account)
640  error = _("You must select an account.");
642  error = _("The selected account is not online.");
643 
644  if (error)
645  {
646  finch_request_add_buddy(account, username, group, alias);
647  purple_notify_error(NULL, _("Error"), _("Error adding buddy"), error);
648  return;
649  }
650 
651  grp = purple_find_group(group);
652  if (!grp)
653  {
654  grp = purple_group_new(group);
656  }
657 
658  /* XXX: Ask to merge if there's already a buddy with the same alias in the same group (#4553) */
659 
660  if ((buddy = purple_find_buddy_in_group(account, username, grp)) == NULL)
661  {
662  buddy = purple_buddy_new(account, username, alias);
663  purple_blist_add_buddy(buddy, NULL, grp, NULL);
664  }
665 
667 }
668 
669 static void
670 finch_request_add_buddy(PurpleAccount *account, const char *username, const char *grp, const char *alias)
671 {
674  PurpleRequestField *field;
675 
677 
678  field = purple_request_field_string_new("screenname", _("Username"), username, FALSE);
680 
681  field = purple_request_field_string_new("alias", _("Alias (optional)"), alias, FALSE);
683 
684  field = purple_request_field_string_new("invite", _("Invite message (optional)"), NULL, FALSE);
686 
687  field = purple_request_field_string_new("group", _("Add in group"), grp, FALSE);
689  purple_request_field_set_type_hint(field, "group");
690 
691  field = purple_request_field_account_new("account", _("Account"), NULL);
693  if (account)
696 
697  purple_request_fields(NULL, _("Add Buddy"), NULL, _("Please enter buddy information."),
698  fields,
699  _("Add"), G_CALLBACK(add_buddy_cb),
700  _("Cancel"), NULL,
701  account, NULL, NULL,
702  NULL);
703 }
704 
705 static void
707 {
709  const char *name;
710  PurpleConversation *conv;
711  const char *alias;
712 
713  /* This hack here is to work around the fact that there's no good way of
714  * getting the actual name of a chat. I don't understand why we return
715  * the alias for a chat when all we want is the name. */
716  alias = chat->alias;
717  chat->alias = NULL;
718  name = purple_chat_get_name(chat);
721  chat->alias = (char *)alias;
722 
723  if (!conv || purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv))) {
726  } else if (conv) {
728  }
729 }
730 
731 static void
733 {
735  const char *alias, *name, *group;
736  PurpleChat *chat;
737  PurpleGroup *grp;
738  GHashTable *hash = NULL;
739  PurpleConnection *gc;
740  gboolean autojoin;
742 
743  account = purple_request_fields_get_account(allfields, "account");
744  name = purple_request_fields_get_string(allfields, "name");
745  alias = purple_request_fields_get_string(allfields, "alias");
746  group = purple_request_fields_get_string(allfields, "group");
747  autojoin = purple_request_fields_get_bool(allfields, "autojoin");
748 
750  return;
751 
752  if (!group || !*group)
753  group = _("Chats");
754 
757  if (info->chat_info_defaults != NULL)
758  hash = info->chat_info_defaults(gc, name);
759 
760  chat = purple_chat_new(account, name, hash);
761 
762  if (chat != NULL) {
763  if ((grp = purple_find_group(group)) == NULL) {
764  grp = purple_group_new(group);
766  }
767  purple_blist_add_chat(chat, grp, NULL);
768  purple_blist_alias_chat(chat, alias);
769  purple_blist_node_set_bool((PurpleBlistNode*)chat, "gnt-autojoin", autojoin);
770  if (autojoin) {
771  join_chat(chat);
772  }
773  }
774 }
775 
776 static void
777 finch_request_add_chat(PurpleAccount *account, PurpleGroup *grp, const char *alias, const char *name)
778 {
781  PurpleRequestField *field;
782 
784 
785  field = purple_request_field_account_new("account", _("Account"), NULL);
787  if (account)
790 
791  field = purple_request_field_string_new("name", _("Name"), name, FALSE);
793 
794  field = purple_request_field_string_new("alias", _("Alias"), alias, FALSE);
796 
797  field = purple_request_field_string_new("group", _("Group"), grp ? purple_group_get_name(grp) : NULL, FALSE);
799  purple_request_field_set_type_hint(field, "group");
800 
801  field = purple_request_field_bool_new("autojoin", _("Auto-join"), FALSE);
803 
804  purple_request_fields(NULL, _("Add Chat"), NULL,
805  _("You can edit more information from the context menu later."),
806  fields, _("Add"), G_CALLBACK(add_chat_cb), _("Cancel"), NULL,
807  NULL, NULL, NULL,
808  NULL);
809 }
810 
811 static void
812 add_group_cb(gpointer null, const char *group)
813 {
814  PurpleGroup *grp;
815 
816  if (!group || !*group) {
817  purple_notify_error(NULL, _("Error"), _("Error adding group"),
818  _("You must give a name for the group to add."));
819  return;
820  }
821 
822  grp = purple_find_group(group);
823  if (!grp) {
824  grp = purple_group_new(group);
826  }
827 
828  if (!ggblist)
829  return;
830 
831  /* Treat the group as a new group even if it had existed before. This should
832  * make things easier to add buddies to empty groups (new or old) without having
833  * to turn on 'show empty groups' setting */
834  ggblist->new_group = g_list_prepend(ggblist->new_group, grp);
839 
840  /* Select the group */
841  if (ggblist->tree) {
843  if (!fnode)
846  }
847 }
848 
849 static void
851 {
852  purple_request_input(NULL, _("Add Group"), NULL, _("Enter the name of the group"),
853  NULL, FALSE, FALSE, NULL,
854  _("Add"), G_CALLBACK(add_group_cb), _("Cancel"), NULL,
855  NULL, NULL, NULL,
856  NULL);
857 }
858 
860 {
861  new_list,
862  new_node,
863  blist_show,
864  node_update,
865  node_remove,
866  destroy_list,
867  NULL,
871  NULL,
872  NULL,
873  NULL,
874  NULL
875 };
876 
877 static gpointer
879 {
880  static int handle;
881 
882  return &handle;
883 }
884 
885 static void
887 {
888  gpointer parent;
890  if (FINCH_GET_DATA(node))
891  return;
895  parent, NULL));
897  !purple_blist_node_get_bool(node, "collapsed"));
898 }
899 
900 static const char *
902 {
903  static char text[2096];
904  char status[8] = " ";
905  const char *name = NULL;
906 
908  node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node))); /* XXX: this can return NULL?! */
909 
910  if (node == NULL)
911  return NULL;
912 
914  {
915  PurpleBuddy *buddy = (PurpleBuddy *)node;
917  PurplePresence *presence;
918  PurpleStatus *now;
919  gboolean ascii = gnt_ascii_only();
920 
921  presence = purple_buddy_get_presence(buddy);
923  strncpy(status, ascii ? ":" : "☎", sizeof(status) - 1);
924  else {
925  now = purple_presence_get_active_status(presence);
926 
928 
929  switch(prim) {
931  strncpy(status, ascii ? "x" : "⊗", sizeof(status) - 1);
932  break;
934  strncpy(status, ascii ? "o" : "◯", sizeof(status) - 1);
935  break;
936  default:
937  strncpy(status, ascii ? "." : "⊖", sizeof(status) - 1);
938  break;
939  }
940  }
941  name = purple_buddy_get_alias(buddy);
942  }
944  {
945  PurpleChat *chat = (PurpleChat*)node;
946  name = purple_chat_get_name(chat);
947 
948  strncpy(status, "~", sizeof(status) - 1);
949  }
952 
953  g_snprintf(text, sizeof(text) - 1, "%s %s", status, name);
954 
955  return text;
956 }
957 
958 static void
960 {
961  gpointer parent;
963  if (FINCH_GET_DATA(node))
964  return;
966  return;
967 
968  parent = ggblist->manager->find_parent((PurpleBlistNode*)chat);
969 
972  parent, NULL));
973 }
974 
975 static void
977 {
978  gpointer parent;
979  PurpleBlistNode *node = (PurpleBlistNode*)contact;
980  const char *name;
981 
982  if (FINCH_GET_DATA(node))
983  return;
984 
986  if (name == NULL)
987  return;
988 
989  parent = ggblist->manager->find_parent((PurpleBlistNode*)contact);
990 
993  parent, NULL));
994 
996 }
997 
998 static void
1000 {
1001  gpointer parent;
1002  PurpleBlistNode *node = (PurpleBlistNode *)buddy;
1003  PurpleContact *contact;
1004 
1005  if (FINCH_GET_DATA(node))
1006  return;
1007 
1008  contact = purple_buddy_get_contact(buddy);
1009  parent = ggblist->manager->find_parent((PurpleBlistNode*)buddy);
1010 
1013  parent, NULL));
1014 
1016  if (buddy == purple_contact_get_priority_buddy(contact))
1018 }
1019 
1020 #if 0
1021 static void
1023 {
1024  add_node((PurpleBlistNode*)buddy, ggblist);
1025 }
1026 
1027 static void
1029 {
1031 }
1032 #endif
1033 
1035 {
1036  return &blist_ui_ops;
1037 }
1038 
1039 static void
1041 {
1044 
1045  if (!node)
1046  return;
1047 
1050 
1052  {
1053  PurpleBuddy *buddy = (PurpleBuddy *)node;
1054  PurpleConversation *conv;
1056  purple_buddy_get_name(buddy),
1057  purple_buddy_get_account(buddy));
1058  if (!conv) {
1060  purple_buddy_get_account(buddy),
1061  purple_buddy_get_name(buddy));
1062  } else {
1063  FinchConv *ggconv = FINCH_GET_DATA(conv);
1064  gnt_window_present(ggconv->window);
1065  }
1067  }
1068  else if (PURPLE_BLIST_NODE_IS_CHAT(node))
1069  {
1071  }
1072 }
1073 
1074 static void
1076 {
1077  PurpleMenuAction *action = data;
1079  if (action) {
1080  void (*callback)(PurpleBlistNode *, gpointer);
1081  callback = (void (*)(PurpleBlistNode *, gpointer))action->callback;
1082  if (callback)
1083  callback(node, action->data);
1084  else
1085  return;
1086  }
1087 }
1088 
1089 static void
1090 gnt_append_menu_action(GntMenu *menu, PurpleMenuAction *action, gpointer parent)
1091 {
1092  GList *list;
1093  GntMenuItem *item;
1094 
1095  if (action == NULL)
1096  return;
1097 
1098  item = gnt_menuitem_new(action->label);
1099  if (action->callback)
1101  gnt_menu_add_item(menu, GNT_MENU_ITEM(item));
1102 
1103  if (action->children) {
1105  gnt_menuitem_set_submenu(item, GNT_MENU(sub));
1106  for (list = action->children; list; list = list->next)
1107  gnt_append_menu_action(GNT_MENU(sub), list->data, action);
1108  }
1109 }
1110 
1111 static void
1113 {
1114  GList *list;
1116 
1118  return;
1119 
1120  for(list = prpl_info->blist_node_menu(node); list;
1121  list = g_list_delete_link(list, list))
1122  {
1123  PurpleMenuAction *act = (PurpleMenuAction *) list->data;
1124  if (!act)
1125  continue;
1126  act->data = node;
1128  g_signal_connect_swapped(G_OBJECT(menu), "destroy",
1129  G_CALLBACK(purple_menu_action_free), act);
1130  }
1131 }
1132 
1133 static void
1134 add_custom_action(GntMenu *menu, const char *label, PurpleCallback callback,
1135  gpointer data)
1136 {
1137  PurpleMenuAction *action = purple_menu_action_new(label, callback, data, NULL);
1138  gnt_append_menu_action(menu, action, NULL);
1139  g_signal_connect_swapped(G_OBJECT(menu), "destroy",
1140  G_CALLBACK(purple_menu_action_free), action);
1141 }
1142 
1143 static void
1145 {
1146  GList *groups, *fields;
1147 
1148  for (groups = purple_request_fields_get_groups(allfields); groups; groups = groups->next) {
1150  for (; fields; fields = fields->next) {
1151  PurpleRequestField *field = fields->data;
1152  const char *id;
1153  char *val;
1154 
1155  id = purple_request_field_get_id(field);
1157  val = g_strdup_printf("%d", purple_request_field_int_get_value(field));
1158  else
1159  val = g_strdup(purple_request_field_string_get_value(field));
1160 
1161  if (!val) {
1162  g_hash_table_remove(purple_chat_get_components(chat), id);
1163  } else {
1164  g_hash_table_replace(purple_chat_get_components(chat), g_strdup(id), val); /* val should not be free'd */
1165  }
1166  }
1167  }
1168 }
1169 
1170 static void
1172 {
1175  PurpleRequestField *field;
1176  GList *parts, *iter;
1177  struct proto_chat_entry *pce;
1178  PurpleConnection *gc;
1179 
1181 
1183  parts = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc))->chat_info(gc);
1184 
1185  for (iter = parts; iter; iter = iter->next) {
1186  pce = iter->data;
1187  if (pce->is_int) {
1188  int val;
1189  const char *str = g_hash_table_lookup(purple_chat_get_components(chat), pce->identifier);
1190  if (!str || sscanf(str, "%d", &val) != 1)
1191  val = pce->min;
1192  field = purple_request_field_int_new(pce->identifier, pce->label, val);
1193  } else {
1195  g_hash_table_lookup(purple_chat_get_components(chat), pce->identifier), FALSE);
1196  if (pce->secret)
1198  }
1199 
1200  if (pce->required)
1202 
1204  g_free(pce);
1205  }
1206 
1207  g_list_free(parts);
1208 
1209  purple_request_fields(NULL, _("Edit Chat"), NULL, _("Please Update the necessary fields."),
1210  fields, _("Edit"), G_CALLBACK(chat_components_edit_ok), _("Cancel"), NULL,
1211  NULL, NULL, NULL,
1212  chat);
1213 }
1214 
1215 static void
1217 {
1218  PurpleMenuAction *action = data;
1219  purple_blist_node_set_bool(action->data, "gnt-autojoin",
1221 }
1222 
1223 static void
1225 {
1226  PurpleMenuAction *action = purple_menu_action_new(_("Auto-join"), NULL, chat, NULL);
1229  purple_blist_node_get_bool((PurpleBlistNode*)chat, "gnt-autojoin"));
1230  gnt_menu_add_item(menu, check);
1232  g_signal_connect_swapped(G_OBJECT(menu), "destroy",
1233  G_CALLBACK(purple_menu_action_free), action);
1234 
1235  add_custom_action(menu, _("Edit Settings"), (PurpleCallback)chat_components_edit, chat);
1236 }
1237 
1238 static void
1240 {
1242 }
1243 
1244 static void
1246 {
1248 }
1249 
1250 static void
1252 {
1254 }
1255 
1256 static void
1258 {
1259  add_custom_action(menu, _("Add Buddy"),
1261  add_custom_action(menu, _("Add Chat"),
1263  add_custom_action(menu, _("Add Group"),
1265 }
1266 
1267 gpointer finch_retrieve_user_info(PurpleConnection *conn, const char *name)
1268 {
1270  gpointer uihandle;
1271  purple_notify_user_info_add_pair(info, _("Information"), _("Retrieving..."));
1272  uihandle = purple_notify_userinfo(conn, name, info, NULL, NULL);
1274 
1275  serv_get_info(conn, name);
1276  return uihandle;
1277 }
1278 
1279 static void
1281 {
1283 }
1284 
1285 static void
1287 {
1289 }
1290 
1291 static void
1293 {
1294  PurpleBuddy *b;
1297  else
1298  b = (PurpleBuddy *)node;
1300 }
1301 
1302 static void
1303 toggle_block_buddy(GntMenuItem *item, gpointer buddy)
1304 {
1305  gboolean block = gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item));
1307  const char *name = purple_buddy_get_name(buddy);
1308 
1311 }
1312 
1313 static void
1314 toggle_show_offline(GntMenuItem *item, gpointer buddy)
1315 {
1316  purple_blist_node_set_bool(buddy, "show_offline",
1317  !purple_blist_node_get_bool(buddy, "show_offline"));
1318  if (!ggblist->manager->can_add_node(buddy))
1319  node_remove(purple_get_blist(), buddy);
1320  else
1321  node_update(purple_get_blist(), buddy);
1322 }
1323 
1324 static void
1326 {
1328  gboolean permitted;
1329  GntMenuItem *item;
1332 
1334  if (prpl_info && prpl_info->get_info)
1335  {
1336  add_custom_action(menu, _("Get Info"),
1338  }
1339 
1340  add_custom_action(menu, _("Add Buddy Pounce"),
1342 
1343  if (prpl_info && prpl_info->send_file)
1344  {
1345  if (!prpl_info->can_receive_file ||
1347  add_custom_action(menu, _("Send File"),
1349  }
1350 
1352  permitted = purple_privacy_check(account, purple_buddy_get_name(buddy));
1353 
1354  item = gnt_menuitem_check_new(_("Blocked"));
1357  gnt_menu_add_item(menu, item);
1358 
1359  item = gnt_menuitem_check_new(_("Show when offline"));
1362  gnt_menu_add_item(menu, item);
1363 
1364  /* Protocol actions */
1365  append_proto_menu(menu,
1367  (PurpleBlistNode*)buddy);
1368 }
1369 
1370 static void
1372 {
1373  GList *iter;
1374 
1376  iter; iter = g_list_delete_link(iter, iter))
1377  {
1378  gnt_append_menu_action(menu, iter->data, NULL);
1379  g_signal_connect_swapped(G_OBJECT(menu), "destroy",
1380  G_CALLBACK(purple_menu_action_free), iter->data);
1381  }
1382 }
1383 
1384 /* Xerox'd from gtkdialogs.c:purple_gtkdialogs_remove_contact_cb */
1385 static void
1387 {
1388  PurpleBlistNode *bnode, *cnode;
1389  PurpleGroup *group;
1390 
1391  cnode = (PurpleBlistNode *)contact;
1393  for (bnode = purple_blist_node_get_first_child(cnode); bnode; bnode = purple_blist_node_get_sibling_next(bnode)) {
1394  PurpleBuddy *buddy = (PurpleBuddy*)bnode;
1398  }
1399  purple_blist_remove_contact(contact);
1400 }
1401 
1402 static void
1404 {
1405  const char *name = newname;
1406  if (name && !*name)
1407  name = NULL;
1408 
1410  PurpleContact *contact = (PurpleContact*)node;
1412  purple_blist_alias_contact(contact, name);
1414  serv_alias_buddy(buddy);
1415  } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
1418  } else if (PURPLE_BLIST_NODE_IS_CHAT(node))
1420  else if (PURPLE_BLIST_NODE_IS_GROUP(node) && (name != NULL))
1422  else
1423  g_return_if_reached();
1424 }
1425 
1426 static void
1428 {
1429  const char *name = NULL;
1430  char *prompt;
1431  const char *text;
1432 
1435  else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
1437  else if (PURPLE_BLIST_NODE_IS_CHAT(node))
1439  else if (PURPLE_BLIST_NODE_IS_GROUP(node))
1441  else
1442  g_return_if_reached();
1443 
1444  prompt = g_strdup_printf(_("Please enter the new name for %s"), name);
1445 
1446  text = PURPLE_BLIST_NODE_IS_GROUP(node) ? _("Rename") : _("Set Alias");
1447  purple_request_input(node, text, prompt, _("Enter empty string to reset the name."),
1448  name, FALSE, FALSE, NULL, text, G_CALLBACK(rename_blist_node),
1449  _("Cancel"), NULL,
1450  NULL, NULL, NULL,
1451  node);
1452 
1453  g_free(prompt);
1454 }
1455 
1456 
1458 {
1461  char *name = NULL;
1462 
1464  PurpleBuddy *b = (PurpleBuddy*) node;
1465  type = PURPLE_LOG_IM;
1466  name = g_strdup(purple_buddy_get_name(b));
1468  } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
1469  PurpleChat *c = (PurpleChat*) node;
1474  if (prpl_info && prpl_info->get_chat_name) {
1476  }
1477  } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
1479  return;
1480  } else {
1481  /* This callback should not have been registered for a node
1482  * that doesn't match the type of one of the blocks above. */
1483  g_return_if_reached();
1484  }
1485 
1486  if (name && account) {
1488  g_free(name);
1489  }
1490 }
1491 
1492 
1493 /* Xeroxed from gtkdialogs.c:purple_gtkdialogs_remove_group_cb*/
1494 static void
1496 {
1497  PurpleBlistNode *cnode, *bnode;
1498 
1500 
1501  while (cnode) {
1502  if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
1503  bnode = purple_blist_node_get_first_child(cnode);
1504  cnode = purple_blist_node_get_sibling_next(cnode);
1505  while (bnode) {
1506  PurpleBuddy *buddy;
1507  if (PURPLE_BLIST_NODE_IS_BUDDY(bnode)) {
1509  buddy = (PurpleBuddy*)bnode;
1510  bnode = purple_blist_node_get_sibling_next(bnode);
1515  }
1516  } else {
1517  bnode = purple_blist_node_get_sibling_next(bnode);
1518  }
1519  }
1520  } else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) {
1521  PurpleChat *chat = (PurpleChat *)cnode;
1522  cnode = purple_blist_node_get_sibling_next(cnode);
1525  } else {
1526  cnode = purple_blist_node_get_sibling_next(cnode);
1527  }
1528  }
1529 
1531 }
1532 
1533 static void
1535 {
1538  } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
1539  PurpleBuddy *buddy = (PurpleBuddy*)node;
1543  } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
1545  } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
1547  }
1548 }
1549 
1550 static void
1552 {
1554  char *primary;
1555  const char *name, *sec = NULL;
1556 
1560  if (c->totalsize > 1)
1561  sec = _("Removing this contact will also remove all the buddies in the contact");
1562  } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
1565  } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
1567  } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
1569  sec = _("Removing this group will also remove all the buddies in the group");
1570  }
1571  else
1572  return;
1573 
1574  primary = g_strdup_printf(_("Are you sure you want to remove %s?"), name);
1575 
1576  /* XXX: anything to do with the returned ui-handle? */
1577  purple_request_action(node, _("Confirm Remove"),
1578  primary, sec,
1579  1,
1580  account, name, NULL,
1581  node, 2,
1582  _("Remove"), finch_blist_remove_node,
1583  _("Cancel"), NULL);
1584  g_free(primary);
1585 }
1586 
1587 static void
1589 {
1590  GList *iter;
1591  if (node == NULL)
1592  return;
1593  if (ggblist->tagged && (iter = g_list_find(ggblist->tagged, node)) != NULL) {
1594  ggblist->tagged = g_list_delete_link(ggblist->tagged, iter);
1595  } else {
1596  ggblist->tagged = g_list_prepend(ggblist->tagged, node);
1597  }
1600  else if (PURPLE_BLIST_NODE_IS_BUDDY(node))
1602  else
1604 }
1605 
1606 static void
1608 {
1609  PurpleGroup *tg = NULL;
1610  PurpleContact *tc = NULL;
1611 
1612  if (target == NULL ||
1614  return;
1615 
1616  if (PURPLE_BLIST_NODE_IS_GROUP(target))
1617  tg = (PurpleGroup*)target;
1618  else if (PURPLE_BLIST_NODE_IS_BUDDY(target)) {
1621  } else {
1622  if (PURPLE_BLIST_NODE_IS_CONTACT(target))
1623  tc = (PurpleContact*)target;
1625  }
1626 
1627  if (ggblist->tagged) {
1628  GList *list = ggblist->tagged;
1629  ggblist->tagged = NULL;
1630  while (list) {
1631  PurpleBlistNode *node = list->data;
1632  list = g_list_delete_link(list, list);
1633 
1636  /* Add the group after the current group */
1638  } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
1640  if (PURPLE_BLIST_NODE(tg) == target) {
1641  /* The target is a group, just add the contact to the group. */
1643  } else if (tc) {
1644  /* The target is either a buddy, or a contact. Merge with that contact. */
1646  } else {
1647  /* The target is a chat. Add the contact to the group after this chat. */
1649  }
1650  } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
1652  if (PURPLE_BLIST_NODE(tg) == target) {
1653  /* The target is a group. Add this buddy in a new contact under this group. */
1655  } else if (PURPLE_BLIST_NODE_IS_CONTACT(target)) {
1656  /* Add to the contact. */
1658  } else if (PURPLE_BLIST_NODE_IS_BUDDY(target)) {
1659  /* Add to the contact after the selected buddy. */
1661  } else if (PURPLE_BLIST_NODE_IS_CHAT(target)) {
1662  /* Add to the selected chat's group. */
1664  }
1665  } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
1667  if (PURPLE_BLIST_NODE(tg) == target)
1669  else
1671  }
1672  }
1673  }
1674 }
1675 
1676 static void
1678 {
1679  ggblist->context = NULL;
1680 }
1681 
1682 static void
1684 {
1686  GntWidget *context = NULL;
1687  GntTree *tree = NULL;
1688  int x, y, top, width;
1689  char *title = NULL;
1690 
1691  if (ggblist->context)
1692  return;
1693 
1694  tree = GNT_TREE(ggblist->tree);
1695 
1698  return;
1699 
1700  if (ggblist->tooltip)
1702 
1703  ggblist->cnode = node;
1704 
1706  g_signal_connect(G_OBJECT(context), "destroy", G_CALLBACK(context_menu_destroyed), ggblist);
1707  g_signal_connect(G_OBJECT(context), "hide", G_CALLBACK(gnt_widget_destroy), NULL);
1708 
1709  if (!node) {
1710  create_group_menu(GNT_MENU(context), NULL);
1711  title = g_strdup(_("Buddy List"));
1712  } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
1715  title = g_strdup(purple_contact_get_alias((PurpleContact*)node));
1716  } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
1717  PurpleBuddy *buddy = (PurpleBuddy *)node;
1718  create_buddy_menu(GNT_MENU(context), buddy);
1719  title = g_strdup(purple_buddy_get_name(buddy));
1720  } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
1721  PurpleChat *chat = (PurpleChat*)node;
1722  create_chat_menu(GNT_MENU(context), chat);
1723  title = g_strdup(purple_chat_get_name(chat));
1724  } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
1726  create_group_menu(GNT_MENU(context), group);
1727  title = g_strdup(purple_group_get_name(group));
1728  }
1729 
1730  append_extended_menu(GNT_MENU(context), node);
1731 
1732  /* These are common for everything */
1733  if (node) {
1734  add_custom_action(GNT_MENU(context),
1735  PURPLE_BLIST_NODE_IS_GROUP(node) ? _("Rename") : _("Alias"),
1737  add_custom_action(GNT_MENU(context), _("Remove"),
1739 
1742  add_custom_action(GNT_MENU(context), _("Place tagged"),
1744  }
1745 
1747  add_custom_action(GNT_MENU(context), _("Toggle Tag"),
1749  }
1751  add_custom_action(GNT_MENU(context), _("View Log"),
1753  }
1754  }
1755 
1756  /* Set the position for the popup */
1760 
1761  x += width;
1762  y += top - 1;
1763 
1764  gnt_widget_set_position(context, x, y);
1765  gnt_screen_menu_show(GNT_MENU(context));
1766  g_free(title);
1767 }
1768 
1769 static void
1770 tooltip_for_buddy(PurpleBuddy *buddy, GString *str, gboolean full)
1771 {
1772  PurplePlugin *prpl;
1775  PurpleNotifyUserInfo *user_info;
1776  PurplePresence *presence;
1777  const char *alias = purple_buddy_get_alias(buddy);
1778  char *tmp, *strip;
1779 
1780  user_info = purple_notify_user_info_new();
1781 
1783  presence = purple_buddy_get_presence(buddy);
1784 
1785  if (!full || g_utf8_collate(purple_buddy_get_name(buddy), alias)) {
1786  char *esc = g_markup_escape_text(alias, -1);
1787  purple_notify_user_info_add_pair(user_info, _("Nickname"), esc);
1788  g_free(esc);
1789  }
1790 
1791  tmp = g_strdup_printf("%s (%s)",
1794  purple_notify_user_info_add_pair(user_info, _("Account"), tmp);
1795  g_free(tmp);
1796 
1799  if (prpl_info && prpl_info->tooltip_text) {
1800  prpl_info->tooltip_text(buddy, user_info, full);
1801  }
1802 
1803  if (purple_prefs_get_bool("/finch/blist/idletime")) {
1805  if (purple_presence_is_idle(pre)) {
1806  time_t idle = purple_presence_get_idle_time(pre);
1807  if (idle > 0) {
1808  char *st = purple_str_seconds_to_string(time(NULL) - idle);
1809  purple_notify_user_info_add_pair(user_info, _("Idle"), st);
1810  g_free(st);
1811  }
1812  }
1813  }
1814 
1815  tmp = purple_notify_user_info_get_text_with_newline(user_info, "<BR>");
1817 
1818  strip = purple_markup_strip_html(tmp);
1819  g_string_append(str, strip);
1820 
1822  g_string_append(str, "\n");
1823  g_string_append(str, _("On Mobile"));
1824  }
1825 
1826  g_free(strip);
1827  g_free(tmp);
1828 }
1829 
1830 static GString*
1831 make_sure_text_fits(GString *string)
1832 {
1833  int maxw = getmaxx(stdscr) - 3;
1834  char *str = gnt_util_onscreen_fit_string(string->str, maxw);
1835  string = g_string_assign(string, str);
1836  g_free(str);
1837  return string;
1838 }
1839 
1840 static gboolean
1842 {
1844  int x, y, top, width, w, h;
1845  GString *str = NULL;
1846  GntTree *tree;
1847  GntWidget *widget, *box, *tv;
1848  char *title = NULL;
1849 
1850  widget = ggblist->tree;
1851  tree = GNT_TREE(widget);
1852 
1855  return FALSE;
1856 
1857  if (ggblist->tooltip)
1858  {
1859  /* XXX: Once we can properly redraw on expose events, this can be removed at the end
1860  * to avoid the blinking*/
1862  }
1863 
1865  if (!node)
1866  return FALSE;
1867 
1868  if (!ggblist->manager->create_tooltip(node, &str, &title))
1869  return FALSE;
1870 
1872  gnt_widget_get_size(widget, &width, NULL);
1874 
1875  x += width;
1876  y += top - 1;
1877 
1878  box = gnt_box_new(FALSE, FALSE);
1881  gnt_box_set_title(GNT_BOX(box), title);
1882 
1884  gnt_util_get_text_bound(str->str, &w, &h);
1885  h = MAX(1, h);
1886  tv = gnt_text_view_new();
1887  gnt_widget_set_size(tv, w + 1, h);
1889  gnt_box_add_widget(GNT_BOX(box), tv);
1890 
1891  if (x + w >= getmaxx(stdscr))
1892  x -= w + width + 2;
1893  gnt_widget_set_position(box, x, y);
1896  gnt_widget_draw(box);
1897 
1900 
1901  g_free(title);
1902  g_string_free(str, TRUE);
1903  ggblist->tooltip = box;
1904  ggblist->tnode = node;
1905 
1906  gnt_widget_set_name(ggblist->tooltip, "tooltip");
1907  return FALSE;
1908 }
1909 
1910 static void
1912 {
1913  /* When an account has signed off, it removes one buddy at a time.
1914  * Drawing the tooltip after removing each buddy is expensive. On
1915  * top of that, if the selected buddy belongs to the disconnected
1916  * account, then retreiving the tooltip for that causes crash. So
1917  * let's make sure we wait for all the buddies to be removed first.*/
1918  int id = g_timeout_add(0, (GSourceFunc)draw_tooltip_real, ggblist);
1919  g_object_set_data_full(G_OBJECT(ggblist->window), "draw_tooltip_calback",
1920  GINT_TO_POINTER(id), (GDestroyNotify)g_source_remove);
1921 }
1922 
1923 static void
1924 selection_changed(GntWidget *widget, gpointer old, gpointer current, FinchBlist *ggblist)
1925 {
1928 }
1929 
1930 static gboolean
1932 {
1934  return TRUE;
1935 }
1936 
1937 static gboolean
1939 {
1940  if (text[0] == 27 && text[1] == 0) {
1941  /* Escape was pressed */
1945  } else if (purple_strequal(text, GNT_KEY_INS)) {
1949  NULL);
1950  } else if (!gnt_tree_is_searching(GNT_TREE(ggblist->tree))) {
1951  if (purple_strequal(text, "t")) {
1954  } else if (purple_strequal(text, "a")) {
1956  } else
1957  return FALSE;
1958  } else
1959  return FALSE;
1960 
1961  return TRUE;
1962 }
1963 
1964 static void
1966 {
1969 }
1970 
1971 static void
1973 {
1974  PurpleContact *contact;
1975 
1976  contact = purple_buddy_get_contact(buddy);
1977 
1980 
1982  if (buddy == purple_contact_get_priority_buddy(contact))
1984 
1985  if (ggblist->tnode == (PurpleBlistNode*)buddy)
1987 }
1988 
1989 static void
1991 {
1992  update_buddy_display(buddy, ggblist);
1993 }
1994 
1995 static void
1997 {
1998  update_buddy_display(buddy, ggblist);
1999 }
2000 
2001 static void
2003 {
2004  if (ggblist->tooltip)
2006  else if (ggblist->context)
2008 }
2009 
2010 static void
2011 size_changed_cb(GntWidget *w, int wi, int h)
2012 {
2013  int width, height;
2014  gnt_widget_get_size(w, &width, &height);
2015  purple_prefs_set_int(PREF_ROOT "/size/width", width);
2016  purple_prefs_set_int(PREF_ROOT "/size/height", height);
2017 }
2018 
2019 static void
2020 save_position_cb(GntWidget *w, int x, int y)
2021 {
2022  purple_prefs_set_int(PREF_ROOT "/position/x", x);
2023  purple_prefs_set_int(PREF_ROOT "/position/y", y);
2024 }
2025 
2026 static void
2028 {
2032 
2034  while (node) {
2037  }
2038 
2039  if (ggblist->typing)
2042  if (ggblist->tagged)
2043  g_list_free(ggblist->tagged);
2044 
2047  if (ggblist->new_group)
2048  g_list_free(ggblist->new_group);
2049 
2050  g_free(ggblist);
2051  ggblist = NULL;
2052 }
2053 
2054 static void
2056 {
2058  PurpleBuddyList *list;
2059 
2060  if (ggblist->manager->init)
2061  ggblist->manager->init();
2062 
2063  if (purple_strequal(purple_prefs_get_string(PREF_ROOT "/sort_type"), "text")) {
2065  (GCompareFunc)blist_node_compare_text);
2066  } else if (purple_strequal(purple_prefs_get_string(PREF_ROOT "/sort_type"), "status")) {
2068  (GCompareFunc)blist_node_compare_status);
2069  } else if (purple_strequal(purple_prefs_get_string(PREF_ROOT "/sort_type"), "log")) {
2071  (GCompareFunc)blist_node_compare_log);
2072  }
2073 
2074  list = purple_get_blist();
2076  while (node)
2077  {
2078  node_update(list, node);
2080  }
2081 }
2082 
2083 static void
2085 {
2086  g_list_foreach(list, (GFunc)g_free, NULL);
2087  g_list_free(list);
2088 }
2089 
2090 static void
2092 {
2093  int i;
2094  GList *iter;
2095  GList *items = NULL;
2096  StatusBoxItem *item = NULL;
2097 
2098  /* First the primitives */
2101 
2103 
2104  for (i = 0; prims[i] != PURPLE_STATUS_UNSET; i++)
2105  {
2106  item = g_new0(StatusBoxItem, 1);
2107  item->type = STATUS_PRIMITIVE;
2108  item->u.prim = prims[i];
2109  items = g_list_prepend(items, item);
2112  }
2113 
2114  /* Now the popular statuses */
2115  for (iter = purple_savedstatuses_get_popular(6); iter; iter = g_list_delete_link(iter, iter))
2116  {
2117  item = g_new0(StatusBoxItem, 1);
2118  item->type = STATUS_SAVED_POPULAR;
2119  item->u.saved = iter->data;
2120  items = g_list_prepend(items, item);
2122  purple_savedstatus_get_title(iter->data));
2123  }
2124 
2125  /* New savedstatus */
2126  item = g_new0(StatusBoxItem, 1);
2127  item->type = STATUS_SAVED_NEW;
2128  items = g_list_prepend(items, item);
2130  _("New..."));
2131 
2132  /* More savedstatuses */
2133  item = g_new0(StatusBoxItem, 1);
2134  item->type = STATUS_SAVED_ALL;
2135  items = g_list_prepend(items, item);
2137  _("Saved..."));
2138 
2139  /* The keys for the combobox are created here, and never used
2140  * anywhere else. So make sure the keys are freed when the widget
2141  * is destroyed. */
2142  g_object_set_data_full(G_OBJECT(ggblist->status), "list of statuses",
2143  items, (GDestroyNotify)destroy_status_list);
2144 }
2145 
2146 static void
2147 redraw_blist(const char *name, PurplePrefType type, gconstpointer val, gpointer data)
2148 {
2149  PurpleBlistNode *node, *sel;
2150  FinchBlistManager *manager;
2151 
2152  if (ggblist == NULL)
2153  return;
2154 
2156  if (manager == NULL)
2157  manager = &default_manager;
2158  if (ggblist->manager != manager) {
2159  if (ggblist->manager->uninit)
2160  ggblist->manager->uninit();
2161 
2162  ggblist->manager = manager;
2163  if (manager->can_add_node == NULL)
2165  if (manager->find_parent == NULL)
2166  manager->find_parent = default_find_parent;
2167  if (manager->create_tooltip == NULL)
2169  }
2170 
2171  if (ggblist->window == NULL)
2172  return;
2173 
2176 
2183 }
2184 
2186 {
2187  color_available = gnt_style_get_color(NULL, "color-available");
2188  if (!color_available)
2189  color_available = gnt_color_add_pair(COLOR_GREEN, -1);
2190  color_away = gnt_style_get_color(NULL, "color-away");
2191  if (!color_away)
2192  color_away = gnt_color_add_pair(COLOR_BLUE, -1);
2193  color_idle = gnt_style_get_color(NULL, "color-idle");
2194  if (!color_idle)
2195  color_idle = gnt_color_add_pair(COLOR_CYAN, -1);
2196  color_offline = gnt_style_get_color(NULL, "color-offline");
2197  if (!color_offline)
2198  color_offline = gnt_color_add_pair(COLOR_RED, -1);
2199 
2202  purple_prefs_add_int(PREF_ROOT "/size/width", 20);
2203  purple_prefs_add_int(PREF_ROOT "/size/height", 17);
2204  purple_prefs_add_none(PREF_ROOT "/position");
2205  purple_prefs_add_int(PREF_ROOT "/position/x", 0);
2206  purple_prefs_add_int(PREF_ROOT "/position/y", 0);
2207  purple_prefs_add_bool(PREF_ROOT "/idletime", TRUE);
2208  purple_prefs_add_bool(PREF_ROOT "/showoffline", FALSE);
2209  purple_prefs_add_bool(PREF_ROOT "/emptygroups", FALSE);
2210  purple_prefs_add_string(PREF_ROOT "/sort_type", "text");
2211  purple_prefs_add_string(PREF_ROOT "/grouping", "default");
2212 
2214  PREF_ROOT "/emptygroups", redraw_blist, NULL);
2216  PREF_ROOT "/showoffline", redraw_blist, NULL);
2218  PREF_ROOT "/sort_type", redraw_blist, NULL);
2220  PREF_ROOT "/grouping", redraw_blist, NULL);
2221 
2223  "autojoin", purple_blist_get_handle(),
2224  G_CALLBACK(account_autojoin_cb), NULL,
2226 
2228 
2229  return;
2230 }
2231 
2232 static gboolean
2233 remove_typing_cb(gpointer null)
2234 {
2235  PurpleSavedStatus *current;
2236  const char *message, *newmessage;
2237  char *escnewmessage;
2238  PurpleStatusPrimitive prim, newprim;
2239  StatusBoxItem *item;
2240 
2241  current = purple_savedstatus_get_current();
2242  message = purple_savedstatus_get_message(current);
2243  prim = purple_savedstatus_get_type(current);
2244 
2247  escnewmessage = newmessage ? g_markup_escape_text(newmessage, -1) : NULL;
2248 
2249  switch (item->type) {
2250  case STATUS_PRIMITIVE:
2251  newprim = item->u.prim;
2252  break;
2253  case STATUS_SAVED_POPULAR:
2254  newprim = purple_savedstatus_get_type(item->u.saved);
2255  break;
2256  default:
2257  goto end; /* 'New' or 'Saved' is selected, but this should never happen. */
2258  }
2259 
2260  if (newprim != prim || ((message && !escnewmessage) ||
2261  (!message && escnewmessage) ||
2262  (message && escnewmessage && g_utf8_collate(message, escnewmessage) != 0)))
2263  {
2265  /* Holy Crap! That's a LAWNG function name */
2266  if (status == NULL)
2267  {
2268  status = purple_savedstatus_new(NULL, newprim);
2269  purple_savedstatus_set_message(status, escnewmessage);
2270  }
2271 
2273  }
2274 
2276 end:
2277  g_free(escnewmessage);
2278  if (ggblist->typing)
2280  ggblist->typing = 0;
2281  return FALSE;
2282 }
2283 
2284 static void
2286 {
2288  if (now->type == STATUS_SAVED_POPULAR)
2289  {
2290  /* Set the status immediately */
2292  }
2293  else if (now->type == STATUS_PRIMITIVE)
2294  {
2295  /* Move the focus to the entry box */
2296  /* XXX: Make sure the selected status can have a message */
2299  }
2300  else if (now->type == STATUS_SAVED_ALL)
2301  {
2302  /* Restore the selection to reflect current status. */
2306  }
2307  else if (now->type == STATUS_SAVED_NEW)
2308  {
2312  }
2313  else
2314  g_return_if_reached();
2315 }
2316 
2317 static gboolean
2318 status_text_changed(GntEntry *entry, const char *text, gpointer null)
2319 {
2320  if ((text[0] == 27 || (text[0] == '\t' && text[1] == '\0')) && ggblist->typing == 0)
2321  return FALSE;
2322 
2323  if (ggblist->typing)
2325  ggblist->typing = 0;
2326 
2327  if (text[0] == '\r' && text[1] == 0)
2328  {
2329  /* Set the status only after you press 'Enter' */
2331  return TRUE;
2332  }
2333 
2335  return FALSE;
2336 }
2337 
2338 static void
2340 {
2341  GList *list;
2342  PurpleStatusPrimitive prim;
2343  const char *message;
2344  gboolean found = FALSE, saved = TRUE;
2345 
2346  if (!ggblist)
2347  return;
2348 
2349  /* Block the signals we don't want to emit */
2350  g_signal_handlers_block_matched(ggblist->status, G_SIGNAL_MATCH_FUNC,
2352  g_signal_handlers_block_matched(ggblist->statustext, G_SIGNAL_MATCH_FUNC,
2353  0, 0, NULL, status_text_changed, NULL);
2354 
2355  prim = purple_savedstatus_get_type(now);
2356  message = purple_savedstatus_get_message(now);
2357 
2358  /* Rebuild the status dropdown */
2360 
2361  while (!found) {
2362  list = g_object_get_data(G_OBJECT(ggblist->status), "list of statuses");
2363  for (; list; list = list->next)
2364  {
2365  StatusBoxItem *item = list->data;
2366  if ((saved && item->type != STATUS_PRIMITIVE && item->u.saved == now) ||
2367  (!saved && item->type == STATUS_PRIMITIVE && item->u.prim == prim))
2368  {
2369  char *mess = purple_unescape_html(message);
2373  g_free(mess);
2374  found = TRUE;
2375  break;
2376  }
2377  }
2378  if (!saved)
2379  break;
2380  saved = FALSE;
2381  }
2382 
2383  g_signal_handlers_unblock_matched(ggblist->status, G_SIGNAL_MATCH_FUNC,
2385  g_signal_handlers_unblock_matched(ggblist->statustext, G_SIGNAL_MATCH_FUNC,
2386  0, 0, NULL, status_text_changed, NULL);
2387 }
2388 
2389 static int
2391 {
2392  while ((n1 = purple_blist_node_get_sibling_prev(n1)) != NULL)
2393  if (n1 == n2)
2394  return 1;
2395  return -1;
2396 }
2397 
2398 static int
2400 {
2401  const char *s1, *s2;
2402  char *us1, *us2;
2403  int ret;
2404 
2406  return blist_node_compare_position(n1, n2);
2407 
2408  switch (purple_blist_node_get_type(n1))
2409  {
2411  s1 = purple_chat_get_name((PurpleChat*)n1);
2412  s2 = purple_chat_get_name((PurpleChat*)n2);
2413  break;
2417  break;
2421  break;
2422  default:
2423  return blist_node_compare_position(n1, n2);
2424  }
2425 
2426  us1 = g_utf8_strup(s1, -1);
2427  us2 = g_utf8_strup(s2, -1);
2428  ret = g_utf8_collate(us1, us2);
2429  g_free(us1);
2430  g_free(us2);
2431 
2432  return ret;
2433 }
2434 
2435 static int
2437 {
2438  int ret;
2439 
2441  return blist_node_compare_position(n1, n2);
2442 
2443  switch (purple_blist_node_get_type(n1)) {
2447  /* now compare the presence of the priority buddies */
2451  if (ret != 0)
2452  return ret;
2453  break;
2454  default:
2455  return blist_node_compare_position(n1, n2);
2456  break;
2457  }
2458 
2459  /* Sort alphabetically if presence is not comparable */
2460  ret = blist_node_compare_text(n1, n2);
2461 
2462  return ret;
2463 }
2464 
2465 static int
2467 {
2468  int log = 0;
2470 
2475  }
2476 
2477  return log;
2478 }
2479 
2480 static int
2482 {
2483  int ret;
2484  PurpleBuddy *b1, *b2;
2485 
2487  return blist_node_compare_position(n1, n2);
2488 
2489  switch (purple_blist_node_get_type(n1)) {
2491  b1 = (PurpleBuddy*)n1;
2492  b2 = (PurpleBuddy*)n2;
2495  if (ret != 0)
2496  return ret;
2497  break;
2500  if (ret != 0)
2501  return ret;
2502  break;
2503  default:
2504  return blist_node_compare_position(n1, n2);
2505  }
2506  ret = blist_node_compare_text(n1, n2);
2507  return ret;
2508 }
2509 
2510 static void
2512 {
2513  PurplePluginAction *action = data;
2514  if (action && action->callback)
2515  action->callback(action);
2516 }
2517 
2518 static void
2519 build_plugin_actions(GntMenuItem *item, PurplePlugin *plugin, gpointer context)
2520 {
2522  GList *actions;
2523  GntMenuItem *menuitem;
2524 
2525  gnt_menuitem_set_submenu(item, GNT_MENU(sub));
2526  for (actions = PURPLE_PLUGIN_ACTIONS(plugin, context); actions;
2527  actions = g_list_delete_link(actions, actions)) {
2528  if (actions->data) {
2529  PurplePluginAction *action = actions->data;
2530  action->plugin = plugin;
2531  action->context = context;
2532  menuitem = gnt_menuitem_new(action->label);
2533  gnt_menu_add_item(GNT_MENU(sub), menuitem);
2534 
2535  gnt_menuitem_set_callback(menuitem, plugin_action, action);
2536  g_object_set_data_full(G_OBJECT(menuitem), "plugin_action",
2537  action, (GDestroyNotify)purple_plugin_action_free);
2538  }
2539  }
2540 }
2541 
2542 static gboolean
2544 {
2547 
2549  fnode->signed_timer = 0;
2550 
2551  if (!ggblist->manager->can_add_node(node)) {
2553  } else {
2557  }
2558 
2559  return FALSE;
2560 }
2561 
2562 static gboolean
2564 {
2567  if (!ggblist || !fnode)
2568  return FALSE;
2569 
2570  if (fnode->signed_timer)
2576  return FALSE;
2577 }
2578 
2579 static void
2580 buddy_signed_on_off(PurpleBuddy* buddy, gpointer null)
2581 {
2582  g_idle_add(buddy_signed_on_off_cb, buddy);
2583 }
2584 
2585 static void
2587 {
2588  GntWidget *sub;
2589  GntMenuItem *plg;
2590  GList *iter;
2591 
2592  if (!ggblist)
2593  return;
2594 
2595  if (ggblist->plugins == NULL)
2596  ggblist->plugins = gnt_menuitem_new(_("Plugins"));
2597 
2598  plg = ggblist->plugins;
2601 
2602  for (iter = purple_plugins_get_loaded(); iter; iter = iter->next) {
2603  PurplePlugin *plugin = iter->data;
2604  GntMenuItem *item;
2605  if (PURPLE_IS_PROTOCOL_PLUGIN(plugin))
2606  continue;
2607 
2608  if (!PURPLE_PLUGIN_HAS_ACTIONS(plugin))
2609  continue;
2610 
2611  item = gnt_menuitem_new(_(plugin->info->name));
2612  gnt_menu_add_item(GNT_MENU(sub), item);
2613  build_plugin_actions(item, plugin, NULL);
2614  }
2615 }
2616 
2617 static void
2619 {
2620  GntWidget *sub;
2621  GntMenuItem *acc, *item;
2622  GList *iter;
2623 
2624  if (!ggblist)
2625  return;
2626 
2627  if (ggblist->accounts == NULL)
2628  ggblist->accounts = gnt_menuitem_new(_("Accounts"));
2629 
2630  acc = ggblist->accounts;
2633 
2634  for (iter = purple_accounts_get_all_active(); iter;
2635  iter = g_list_delete_link(iter, iter)) {
2636  PurpleAccount *account = iter->data;
2638  PurplePlugin *prpl;
2639 
2640  if (!gc || !PURPLE_CONNECTION_IS_CONNECTED(gc))
2641  continue;
2642  prpl = purple_connection_get_prpl(gc);
2643 
2644  if (PURPLE_PLUGIN_HAS_ACTIONS(prpl)) {
2646  gnt_menu_add_item(GNT_MENU(sub), item);
2647  build_plugin_actions(item, prpl, gc);
2648  }
2649  }
2650 }
2651 
2652 static void
2654 {
2655  GList *iter;
2656  GntWidget *subsub;
2657 
2658  if (!ggblist || !ggblist->grouping)
2659  return;
2660 
2661  subsub = gnt_menu_new(GNT_MENU_POPUP);
2663 
2664  for (iter = managers; iter; iter = iter->next) {
2665  char menuid[128];
2666  FinchBlistManager *manager = iter->data;
2667  GntMenuItem *item = gnt_menuitem_new(_(manager->name));
2668  g_snprintf(menuid, sizeof(menuid), "grouping-%s", manager->id);
2669  gnt_menuitem_set_id(GNT_MENU_ITEM(item), menuid);
2670  gnt_menu_add_item(GNT_MENU(subsub), item);
2671  g_object_set_data_full(G_OBJECT(item), "grouping-id", g_strdup(manager->id), g_free);
2673  }
2674 }
2675 
2676 static gboolean
2678 {
2680  PurpleConnection *pc = data;
2682 
2683  for (node = purple_blist_get_root(); node;
2686  PurpleChat *chat = (PurpleChat*)node;
2687  if (purple_chat_get_account(chat) == account &&
2688  purple_blist_node_get_bool(node, "gnt-autojoin"))
2690  }
2691  }
2692  return FALSE;
2693 }
2694 
2695 static gboolean
2697 {
2698  g_idle_add(auto_join_chats, gc);
2699  return TRUE;
2700 }
2701 
2702 static void toggle_pref_cb(GntMenuItem *item, gpointer n)
2703 {
2705 }
2706 
2707 static void sort_blist_change_cb(GntMenuItem *item, gpointer n)
2708 {
2709  purple_prefs_set_string(PREF_ROOT "/sort_type", n);
2710 }
2711 
2712 static void
2714 {
2716  const char *name = purple_request_fields_get_string(fields, "screenname");
2717  if (account && name && *name != '\0') {
2718  if (purple_request_fields_get_choice(fields, "block") == 1) {
2720  } else {
2722  }
2723  }
2724 }
2725 
2726 static void
2727 block_select(GntMenuItem *item, gpointer n)
2728 {
2729  PurpleRequestFields *fields;
2731  PurpleRequestField *field;
2732 
2733  fields = purple_request_fields_new();
2734 
2737 
2738  field = purple_request_field_string_new("screenname", _("Name"), NULL, FALSE);
2739  purple_request_field_set_type_hint(field, "screenname");
2742 
2743  field = purple_request_field_account_new("account", _("Account"), NULL);
2744  purple_request_field_set_type_hint(field, "account");
2747  purple_connections_get_all()->next != NULL));
2750 
2751  field = purple_request_field_choice_new("block", _("Block/Unblock"), 1);
2752  purple_request_field_choice_add(field, _("Block"));
2753  purple_request_field_choice_add(field, _("Unblock"));
2755 
2756  purple_request_fields(purple_get_blist(), _("Block/Unblock"),
2757  NULL,
2758  _("Please enter the username or alias of the person "
2759  "you would like to Block/Unblock."),
2760  fields,
2761  _("OK"), G_CALLBACK(block_select_cb),
2762  _("Cancel"), NULL,
2763  NULL, NULL, NULL,
2764  NULL);
2765 }
2766 
2767 /* send_im_select* -- Xerox */
2768 static void
2770 {
2772  const char *username;
2773  PurpleConversation *conv;
2774 
2775  account = purple_request_fields_get_account(fields, "account");
2776  username = purple_request_fields_get_string(fields, "screenname");
2777 
2780 }
2781 
2782 static void
2783 send_im_select(GntMenuItem *item, gpointer n)
2784 {
2785  PurpleRequestFields *fields;
2787  PurpleRequestField *field;
2788 
2789  fields = purple_request_fields_new();
2790 
2793 
2794  field = purple_request_field_string_new("screenname", _("Name"), NULL, FALSE);
2795  purple_request_field_set_type_hint(field, "screenname");
2798 
2799  field = purple_request_field_account_new("account", _("Account"), NULL);
2800  purple_request_field_set_type_hint(field, "account");
2803  purple_connections_get_all()->next != NULL));
2806 
2807  purple_request_fields(purple_get_blist(), _("New Instant Message"),
2808  NULL,
2809  _("Please enter the username or alias of the person "
2810  "you would like to IM."),
2811  fields,
2812  _("OK"), G_CALLBACK(send_im_select_cb),
2813  _("Cancel"), NULL,
2814  NULL, NULL, NULL,
2815  NULL);
2816 }
2817 
2818 static void
2820 {
2822  const char *name;
2823  PurpleConnection *gc;
2824  PurpleChat *chat;
2825  GHashTable *hash = NULL;
2826  PurpleConversation *conv;
2827 
2828  account = purple_request_fields_get_account(fields, "account");
2829  name = purple_request_fields_get_string(fields, "chat");
2830 
2832  return;
2833 
2835  /* Create a new conversation now. This will give focus to the new window.
2836  * But it's necessary to pretend that we left the chat, because otherwise
2837  * a new conversation window will pop up when we finally join the chat. */
2841  } else {
2843  }
2844 
2846  if (chat == NULL) {
2848  if (info->chat_info_defaults != NULL)
2849  hash = info->chat_info_defaults(gc, name);
2850  } else {
2852  }
2853  serv_join_chat(gc, hash);
2854  if (chat == NULL && hash != NULL)
2855  g_hash_table_destroy(hash);
2856 }
2857 
2858 static void
2859 join_chat_select(GntMenuItem *item, gpointer n)
2860 {
2861  PurpleRequestFields *fields;
2863  PurpleRequestField *field;
2864 
2865  fields = purple_request_fields_new();
2866 
2869 
2870  field = purple_request_field_string_new("chat", _("Channel"), NULL, FALSE);
2873 
2874  field = purple_request_field_account_new("account", _("Account"), NULL);
2875  purple_request_field_set_type_hint(field, "account");
2878  purple_connections_get_all()->next != NULL));
2881 
2882  purple_request_fields(purple_get_blist(), _("Join a Chat"),
2883  NULL,
2884  _("Please enter the name of the chat you want to join."),
2885  fields,
2886  _("Join"), G_CALLBACK(join_chat_select_cb),
2887  _("Cancel"), NULL,
2888  NULL, NULL, NULL,
2889  NULL);
2890 }
2891 
2892 static void
2894 {
2896  const char *name;
2897  PurpleBuddy *buddy;
2898  PurpleContact *contact;
2899 
2900  account = purple_request_fields_get_account(fields, "account");
2901  name = purple_request_fields_get_string(fields, "screenname");
2902 
2903  buddy = purple_find_buddy(account, name);
2904  if (buddy) {
2905  contact = purple_buddy_get_contact(buddy);
2906  } else {
2907  contact = NULL;
2908  }
2909 
2910  if (contact) {
2911  finch_log_show_contact(contact);
2912  } else {
2914  }
2915 }
2916 
2917 static void
2918 view_log_cb(GntMenuItem *item, gpointer n)
2919 {
2920  PurpleRequestFields *fields;
2922  PurpleRequestField *field;
2923 
2924  fields = purple_request_fields_new();
2925 
2928 
2929  field = purple_request_field_string_new("screenname", _("Name"), NULL, FALSE);
2930  purple_request_field_set_type_hint(field, "screenname-all");
2933 
2934  field = purple_request_field_account_new("account", _("Account"), NULL);
2935  purple_request_field_set_type_hint(field, "account");
2937  (purple_accounts_get_all() != NULL &&
2938  purple_accounts_get_all()->next != NULL));
2942 
2943  purple_request_fields(purple_get_blist(), _("View Log"),
2944  NULL,
2945  _("Please enter the username or alias of the person "
2946  "whose log you would like to view."),
2947  fields,
2948  _("OK"), G_CALLBACK(view_log_select_cb),
2949  _("Cancel"), NULL,
2950  NULL, NULL, NULL,
2951  NULL);
2952 }
2953 
2954 static void
2955 view_all_logs_cb(GntMenuItem *item, gpointer n)
2956 {
2958 }
2959 
2960 static void
2961 menu_add_buddy_cb(GntMenuItem *item, gpointer null)
2962 {
2964 }
2965 
2966 static void
2967 menu_add_chat_cb(GntMenuItem *item, gpointer null)
2968 {
2970 }
2971 
2972 static void
2973 menu_add_group_cb(GntMenuItem *item, gpointer null)
2974 {
2976 }
2977 
2978 static void
2979 menu_group_set_cb(GntMenuItem *item, gpointer null)
2980 {
2981  const char *id = g_object_get_data(G_OBJECT(item), "grouping-id");
2982  purple_prefs_set_string(PREF_ROOT "/grouping", id);
2983 }
2984 
2985 static void
2987 {
2988  GntWidget *menu, *sub, *subsub;
2989  GntMenuItem *item;
2990  GntWindow *window;
2991 
2992  if (!ggblist)
2993  return;
2994 
2998 
2999  item = gnt_menuitem_new(_("Options"));
3000  gnt_menu_add_item(GNT_MENU(menu), item);
3001 
3003  gnt_menuitem_set_submenu(item, GNT_MENU(sub));
3004 
3005  item = gnt_menuitem_new(_("Send IM..."));
3006  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "send-im");
3007  gnt_menu_add_item(GNT_MENU(sub), item);
3009 
3010  item = gnt_menuitem_new(_("Block/Unblock..."));
3011  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "block-unblock");
3012  gnt_menu_add_item(GNT_MENU(sub), item);
3014 
3015  item = gnt_menuitem_new(_("Join Chat..."));
3016  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "join-chat");
3017  gnt_menu_add_item(GNT_MENU(sub), item);
3019 
3020  item = gnt_menuitem_new(_("View Log..."));
3021  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "view-log");
3022  gnt_menu_add_item(GNT_MENU(sub), item);
3024 
3025  item = gnt_menuitem_new(_("View All Logs"));
3026  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "view-all-logs");
3027  gnt_menu_add_item(GNT_MENU(sub), item);
3029 
3030  item = gnt_menuitem_new(_("Show"));
3031  gnt_menu_add_item(GNT_MENU(sub), item);
3032  subsub = gnt_menu_new(GNT_MENU_POPUP);
3033  gnt_menuitem_set_submenu(item, GNT_MENU(subsub));
3034 
3035  item = gnt_menuitem_check_new(_("Empty groups"));
3036  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "show-empty-groups");
3038  purple_prefs_get_bool(PREF_ROOT "/emptygroups"));
3039  gnt_menu_add_item(GNT_MENU(subsub), item);
3041 
3042  item = gnt_menuitem_check_new(_("Offline buddies"));
3043  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "show-offline-buddies");
3045  purple_prefs_get_bool(PREF_ROOT "/showoffline"));
3046  gnt_menu_add_item(GNT_MENU(subsub), item);
3048 
3049  item = gnt_menuitem_new(_("Sort"));
3050  gnt_menu_add_item(GNT_MENU(sub), item);
3051  subsub = gnt_menu_new(GNT_MENU_POPUP);
3052  gnt_menuitem_set_submenu(item, GNT_MENU(subsub));
3053 
3054  item = gnt_menuitem_new(_("By Status"));
3055  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "sort-status");
3056  gnt_menu_add_item(GNT_MENU(subsub), item);
3058 
3059  item = gnt_menuitem_new(_("Alphabetically"));
3060  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "sort-alpha");
3061  gnt_menu_add_item(GNT_MENU(subsub), item);
3063 
3064  item = gnt_menuitem_new(_("By Log Size"));
3065  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "sort-log");
3066  gnt_menu_add_item(GNT_MENU(subsub), item);
3068 
3069  item = gnt_menuitem_new(_("Add"));
3070  gnt_menu_add_item(GNT_MENU(sub), item);
3071 
3072  subsub = gnt_menu_new(GNT_MENU_POPUP);
3073  gnt_menuitem_set_submenu(item, GNT_MENU(subsub));
3074 
3075  item = gnt_menuitem_new(_("Buddy"));
3076  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "add-buddy");
3077  gnt_menu_add_item(GNT_MENU(subsub), item);
3079 
3080  item = gnt_menuitem_new(_("Chat"));
3081  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "add-chat");
3082  gnt_menu_add_item(GNT_MENU(subsub), item);
3084 
3085  item = gnt_menuitem_new(_("Group"));
3086  gnt_menuitem_set_id(GNT_MENU_ITEM(item), "add-group");
3087  gnt_menu_add_item(GNT_MENU(subsub), item);
3089 
3090  ggblist->grouping = item = gnt_menuitem_new(_("Grouping"));
3091  gnt_menu_add_item(GNT_MENU(sub), item);
3093 
3096 
3099 }
3100 
3102 {
3104 }
3105 
3106 static void
3107 group_collapsed(GntWidget *widget, PurpleBlistNode *node, gboolean collapsed, gpointer null)
3108 {
3110  purple_blist_node_set_bool(node, "collapsed", collapsed);
3111 }
3112 
3113 static void
3115 {
3116  if (ggblist == NULL)
3117  new_list(list);
3118  else if (ggblist->window) {
3120  return;
3121  }
3122 
3124  gnt_widget_set_name(ggblist->window, "buddylist");
3126  gnt_box_set_title(GNT_BOX(ggblist->window), _("Buddy List"));
3128 
3129  ggblist->tree = gnt_tree_new();
3130 
3133  purple_prefs_get_int(PREF_ROOT "/size/height"));
3135  purple_prefs_get_int(PREF_ROOT "/position/y"));
3136 
3138 
3143 
3145 
3156 
3161 
3166 
3167 #if 0
3168  /* These I plan to use to indicate unread-messages etc. */
3173 
3176 #endif
3177 
3178  g_signal_connect(G_OBJECT(ggblist->tree), "selection_changed", G_CALLBACK(selection_changed), ggblist);
3179  g_signal_connect(G_OBJECT(ggblist->tree), "key_pressed", G_CALLBACK(key_pressed), ggblist);
3180  g_signal_connect(G_OBJECT(ggblist->tree), "context-menu", G_CALLBACK(context_menu), ggblist);
3181  g_signal_connect(G_OBJECT(ggblist->tree), "collapse-toggled", G_CALLBACK(group_collapsed), NULL);
3182  g_signal_connect(G_OBJECT(ggblist->tree), "activate", G_CALLBACK(selection_activate), ggblist);
3183  g_signal_connect_data(G_OBJECT(ggblist->tree), "gained-focus", G_CALLBACK(draw_tooltip),
3184  ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
3185  g_signal_connect_data(G_OBJECT(ggblist->tree), "lost-focus", G_CALLBACK(remove_peripherals),
3186  ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
3187  g_signal_connect_data(G_OBJECT(ggblist->window), "workspace-hidden", G_CALLBACK(remove_peripherals),
3188  ggblist, 0, G_CONNECT_AFTER | G_CONNECT_SWAPPED);
3189  g_signal_connect(G_OBJECT(ggblist->tree), "size_changed", G_CALLBACK(size_changed_cb), NULL);
3190  g_signal_connect(G_OBJECT(ggblist->window), "position_set", G_CALLBACK(save_position_cb), NULL);
3191  g_signal_connect(G_OBJECT(ggblist->window), "destroy", G_CALLBACK(reset_blist_window), NULL);
3192 
3193  /* Status signals */
3196  g_signal_connect(G_OBJECT(ggblist->status), "selection_changed",
3197  G_CALLBACK(status_selection_changed), NULL);
3198  g_signal_connect(G_OBJECT(ggblist->statustext), "key_pressed",
3199  G_CALLBACK(status_text_changed), NULL);
3200 
3201  create_menu();
3202 
3204 
3206 }
3207 
3209 {
3210 }
3211 
3212 gboolean finch_blist_get_position(int *x, int *y)
3213 {
3214  if (!ggblist || !ggblist->window)
3215  return FALSE;
3217  return TRUE;
3218 }
3219 
3220 void finch_blist_set_position(int x, int y)
3221 {
3223 }
3224 
3225 gboolean finch_blist_get_size(int *width, int *height)
3226 {
3227  if (!ggblist || !ggblist->window)
3228  return FALSE;
3229  gnt_widget_get_size(ggblist->window, width, height);
3230  return TRUE;
3231 }
3232 
3233 void finch_blist_set_size(int width, int height)
3234 {
3235  gnt_widget_set_size(ggblist->window, width, height);
3236 }
3237 
3239 {
3240  if (!g_list_find(managers, manager)) {
3241  managers = g_list_append(managers, (gpointer)manager);
3243  if (purple_strequal(manager->id, purple_prefs_get_string(PREF_ROOT "/grouping")))
3245  }
3246 }
3247 
3249 {
3250  if (g_list_find(managers, manager)) {
3251  managers = g_list_remove(managers, manager);
3253  if (purple_strequal(manager->id, purple_prefs_get_string(PREF_ROOT "/grouping")))
3255  }
3256 }
3257 
3259 {
3260  GList *iter = managers;
3261  if (!id)
3262  return NULL;
3263 
3264  for (; iter; iter = iter->next) {
3265  FinchBlistManager *m = iter->data;
3266  if (purple_strequal(id, m->id))
3267  return m;
3268  }
3269  return NULL;
3270 }
3271 
3273 {
3274  return ggblist ? GNT_TREE(ggblist->tree) : NULL;
3275 }
3276 
destroy_list
static void destroy_list(PurpleBuddyList *list)
Definition: gntblist.c:592
purple_prefs_set_string
void purple_prefs_set_string(const char *name, const char *value)
Definition: prefs.c:948
buddy_idle_changed
static void buddy_idle_changed(PurpleBuddy *buddy, int old, int new, FinchBlist *ggblist)
Definition: gntblist.c:1996
autojoin_toggled
static void autojoin_toggled(GntMenuItem *item, gpointer data)
Definition: gntblist.c:1216
check
static int check
Definition: filectl.c:29
gnt_widget_set_size
gboolean gnt_widget_set_size(GntWidget *widget, int width, int height)
Definition: gntwidget.c:515
purple_blist_node_get_int
int purple_blist_node_get_int(PurpleBlistNode *node, const char *key)
Definition: blist.c:2998
gnt_tree_sort_row
void gnt_tree_sort_row(GntTree *tree, gpointer key)
Definition: gnttree.c:1275
info
static PurplePluginInfo info
Definition: gntclipboard.c:147
GNT_WIDGET_NO_BORDER
Definition: gntwidget.h:59
size_changed_cb
static void size_changed_cb(GntWidget *w, int wi, int h)
Definition: gntblist.c:2011
purple_request_action
void * purple_request_action(void *handle, const char *title, const char *primary, const char *secondary, int default_action, PurpleAccount *account, const char *who, PurpleConversation *conv, void *user_data, size_t action_count,...)
Definition: request.c:1300
view_all_logs_cb
static void view_all_logs_cb(GntMenuItem *item, gpointer n)
Definition: gntblist.c:2955
chat_components_edit
static void chat_components_edit(PurpleBlistNode *selected, PurpleChat *chat)
Definition: gntblist.c:1171
purple_savedstatus_get_message
const char * purple_savedstatus_get_message(const PurpleSavedStatus *saved_status)
Definition: savedstatuses.c:1041
purple_log_get_total_size
int purple_log_get_total_size(PurpleLogType type, const char *name, PurpleAccount *account)
Definition: log.c:226
_FinchConv::window
GntWidget * window
Definition: gntconv.h:56
draw_context_menu
static void draw_context_menu(FinchBlist *ggblist)
Definition: gntblist.c:1683
name
char * name
Definition: gntbindable.c:47
purple_savedstatus_set_message
void purple_savedstatus_set_message(PurpleSavedStatus *status, const char *message)
Definition: savedstatuses.c:611
join_chat_select
static void join_chat_select(GntMenuItem *item, gpointer n)
Definition: gntblist.c:2859
GNT_MENU_TOPLEVEL
Definition: gntmenu.h:58
purple_blist_add_group
void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node)
Definition: blist.c:2008
GNT_MENU
#define GNT_MENU(obj)
Definition: gntmenu.h:35
gnt_append_menu_action
static void gnt_append_menu_action(GntMenu *menu, PurpleMenuAction *action, gpointer parent)
Definition: gntblist.c:1090
_PurplePluginAction::callback
void(* callback)(PurplePluginAction *)
Definition: plugin.h:197
FinchBlistManager::name
const char * name
Definition: gntblist.h:44
finch_blist_get_size
gboolean finch_blist_get_size(int *width, int *height)
Definition: gntblist.c:3225
purple_request_field_int_get_value
int purple_request_field_int_get_value(const PurpleRequestField *field)
Definition: request.c:664
finch_blist_set_size
void finch_blist_set_size(int width, int height)
Definition: gntblist.c:3233
STATUS_PRIMITIVE
Definition: gntblist.c:110
PURPLE_BUDDY_IS_ONLINE
gboolean PURPLE_BUDDY_IS_ONLINE(PurpleBuddy *buddy)
gnt_box_move_focus
void gnt_box_move_focus(GntBox *box, int dir)
Definition: gntbox.c:854
purple_buddy_get_contact
PurpleContact * purple_buddy_get_contact(PurpleBuddy *buddy)
Definition: blist.c:2605
gnt_box_set_pad
void gnt_box_set_pad(GntBox *box, int pad)
Definition: gntbox.c:695
purple_blist_node_next
PurpleBlistNode * purple_blist_node_next(PurpleBlistNode *node, gboolean offline)
Definition: blist.c:845
account
static PurpleAccount * account
Definition: raw.c:45
PURPLE_CONTACT
#define PURPLE_CONTACT(obj)
Definition: blist.h:97
purple_conversations_get_handle
void * purple_conversations_get_handle(void)
Definition: conversation.c:2343
FinchBlist::accounts
GntMenuItem * accounts
Definition: gntblist.c:88
PURPLE_BLIST_BUDDY_NODE
Definition: blist.h:57
FinchBlist::grouping
GntMenuItem * grouping
Definition: gntblist.c:90
purple_strequal
gboolean purple_strequal(const gchar *left, const gchar *right)
purple_notify_error
#define purple_notify_error(handle, title, primary, secondary)
Definition: notify.h:756
PREF_ROOT
#define PREF_ROOT
Definition: gntblist.c:64
account_autojoin_cb
static gboolean account_autojoin_cb(PurpleConnection *pc, gpointer null)
Definition: gntblist.c:2696
gnt_widget_get_size
void gnt_widget_get_size(GntWidget *wid, int *width, int *height)
Definition: gntwidget.c:464
purple_account_is_connected
gboolean purple_account_is_connected(const PurpleAccount *account)
Definition: account.c:2207
new_list
static void new_list(PurpleBuddyList *list)
Definition: gntblist.c:580
gnt_text_view_scroll
void gnt_text_view_scroll(GntTextView *view, int scroll)
Definition: gnttextview.c:618
plugin_action
static void plugin_action(GntMenuItem *item, gpointer data)
Definition: gntblist.c:2511
gnt_entry_set_text
void gnt_entry_set_text(GntEntry *entry, const char *text)
Definition: gntentry.c:1140
reconstruct_accounts_menu
static void reconstruct_accounts_menu(void)
Definition: gntblist.c:2618
group
#define group
Definition: module.h:7
default_create_tooltip
static gboolean default_create_tooltip(gpointer selected_row, GString **body, char **tool_title)
Definition: gntblist.c:232
gnt_util_get_text_bound
void gnt_util_get_text_bound(const char *text, int *width, int *height)
Definition: gntutils.c:49
purple_prefs_add_bool
void purple_prefs_add_bool(const char *name, gboolean value)
Definition: prefs.c:646
add_node
static void add_node(PurpleBlistNode *node, FinchBlist *ggblist)
Definition: gntblist.c:466
purple_account_get_username
const char * purple_account_get_username(const PurpleAccount *account)
Definition: account.c:2225
gnt_menuitem_set_submenu
void gnt_menuitem_set_submenu(GntMenuItem *item, GntMenu *menu)
Definition: gntmenuitem.c:116
purple_request_fields_get_choice
int purple_request_fields_get_choice(const PurpleRequestFields *fields, const char *id)
Definition: request.c:246
N_
#define N_(String)
Definition: internal.h:59
STATUS_SAVED_ALL
Definition: gntblist.c:112
gnt_widget_show
void gnt_widget_show(GntWidget *widget)
Definition: gntwidget.c:326
purple_blist_node_get_first_child
PurpleBlistNode * purple_blist_node_get_first_child(PurpleBlistNode *node)
Definition: blist.c:865
purple_prefs_add_string
void purple_prefs_add_string(const char *name, const char *value)
Definition: prefs.c:676
purple_buddy_get_account
PurpleAccount * purple_buddy_get_account(const PurpleBuddy *buddy)
Definition: blist.c:1441
finch_conversation_set_active
void finch_conversation_set_active(PurpleConversation *conv)
Definition: gntconv.c:1495
GNT_TEXT_VIEW_NO_SCROLL
Definition: gnttextview.h:52
purple_contact_get_alias
const char * purple_contact_get_alias(PurpleContact *contact)
Definition: blist.c:1754
finch_blist_get_handle
static gpointer finch_blist_get_handle(void)
Definition: gntblist.c:878
gntbox.h
purple_savedstatus_new
PurpleSavedStatus * purple_savedstatus_new(const char *title, PurpleStatusPrimitive type)
Definition: savedstatuses.c:557
gnt_tree_set_row_color
void gnt_tree_set_row_color(GntTree *tree, void *key, int color)
Definition: gnttree.c:1645
rename_blist_node
static void rename_blist_node(PurpleBlistNode *node, const char *newname)
Definition: gntblist.c:1403
GNT_MENU_ITEM
#define GNT_MENU_ITEM(obj)
Definition: gntmenuitem.h:34
purple_privacy_deny
void purple_privacy_deny(PurpleAccount *account, const char *who, gboolean local, gboolean restore)
Definition: privacy.c:315
blist_update_row_flags
static void blist_update_row_flags(PurpleBlistNode *node)
Definition: gntblist.c:423
purple_request_field_account_set_value
void purple_request_field_account_set_value(PurpleRequestField *field, PurpleAccount *value)
Definition: request.c:1114
_PurplePluginProtocolInfo::get_chat_name
char *(* get_chat_name)(GHashTable *components)
Definition: prpl.h:384
_PurpleStatus
Definition: status.c:107
_GntMenu
Definition: gntmenu.h:62
finch_request_add_buddy
static void finch_request_add_buddy(PurpleAccount *account, const char *username, const char *grp, const char *alias)
Definition: gntblist.c:670
gnt_combo_box_new
GntWidget * gnt_combo_box_new()
Definition: gntcombobox.c:350
gnt_tree_get_selection_visible_line
int gnt_tree_get_selection_visible_line(GntTree *tree)
Definition: gnttree.c:1554
gnt_menuitem_new
GntMenuItem * gnt_menuitem_new(const char *text)
Definition: gntmenuitem.c:100
finch_blist_toggle_tag_buddy
static void finch_blist_toggle_tag_buddy(PurpleBlistNode *node)
Definition: gntblist.c:1588
account.h
StatusBoxItem::u
union StatusBoxItem::@1 u
purple_blist_request_add_group
void purple_blist_request_add_group(void)
Definition: blist.c:2840
purple_find_conversation_with_account
PurpleConversation * purple_find_conversation_with_account(PurpleConversationType type, const char *name, const PurpleAccount *account)
Definition: conversation.c:893
purple_blist_add_contact
void purple_blist_add_contact(PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node)
Definition: blist.c:1827
buddy_signed_on_off_cb
static gboolean buddy_signed_on_off_cb(gpointer data)
Definition: gntblist.c:2563
purple_request_field_group_add_field
void purple_request_field_group_add_field(PurpleRequestFieldGroup *group, PurpleRequestField *field)
Definition: request.c:300
FinchBlist::statustext
GntWidget * statustext
Definition: gntblist.c:83
save_position_cb
static void save_position_cb(GntWidget *w, int x, int y)
Definition: gntblist.c:2020
GNT_COMBO_BOX
#define GNT_COMBO_BOX(obj)
Definition: gntcombobox.h:36
SHOW_EMPTY_GROUP_TIMEOUT
#define SHOW_EMPTY_GROUP_TIMEOUT
Definition: gntblist.c:67
notify.h
purple_prefs_get_string
const char * purple_prefs_get_string(const char *name)
Definition: prefs.c:1155
status
static PurpleStatusPrimitive status
Definition: gtkdocklet.c:53
join_chat_select_cb
static void join_chat_select_cb(gpointer data, PurpleRequestFields *fields)
Definition: gntblist.c:2819
purple_notify_user_info_get_text_with_newline
char * purple_notify_user_info_get_text_with_newline(PurpleNotifyUserInfo *user_info, const char *newline)
Definition: notify.c:505
gntpounce.h
update_buddy_display
static void update_buddy_display(PurpleBuddy *buddy, FinchBlist *ggblist)
Definition: gntblist.c:1972
StatusBoxItem::type
StatusType type
Definition: gntblist.c:118
gnt_tree_remove
void gnt_tree_remove(GntTree *tree, gpointer key)
Definition: gnttree.c:1479
purple_plugins_get_handle
void * purple_plugins_get_handle(void)
Definition: plugin.c:1170
send_im_select_cb
static void send_im_select_cb(gpointer data, PurpleRequestFields *fields)
Definition: gntblist.c:2769
widget
GtkWidget * widget
Definition: pidgintooltip.c:38
purple_signal_connect
gulong purple_signal_connect(void *instance, const char *signal, void *handle, PurpleCallback func, void *data)
Definition: signals.c:305
FinchBlistNode
Definition: gntblist.c:102
purple_chat_get_components
GHashTable * purple_chat_get_components(PurpleChat *chat)
Definition: blist.c:2598
_GntWidget
Definition: gntwidget.h:98
gnt_tree_set_compare_func
void gnt_tree_set_compare_func(GntTree *tree, GCompareFunc func)
Definition: gnttree.c:1783
gnt_tree_set_selected
void gnt_tree_set_selected(GntTree *tree, void *key)
Definition: gnttree.c:1655
purple_blist_get_handle
void * purple_blist_get_handle(void)
Definition: blist.c:3122
purple_presence_is_online
gboolean purple_presence_is_online(const PurplePresence *presence)
Definition: status.c:1495
GNT_WINDOW
#define GNT_WINDOW(obj)
Definition: gntwindow.h:37
finch_savedstatus_edit
void finch_savedstatus_edit(PurpleSavedStatus *saved)
Definition: gntstatus.c:506
gnt_style_get_color
int gnt_style_get_color(char *group, char *key)
Definition: gntstyle.c:67
finch_blist_menu_send_file_cb
static void finch_blist_menu_send_file_cb(PurpleBlistNode *selected, PurpleBuddy *buddy)
Definition: gntblist.c:1286
purple_request_fields_get_bool
gboolean purple_request_fields_get_bool(const PurpleRequestFields *fields, const char *id)
Definition: request.c:232
purple_buddy_get_name
const char * purple_buddy_get_name(const PurpleBuddy *buddy)
Definition: blist.c:1449
purple_group_get_name
const char * purple_group_get_name(PurpleGroup *group)
Definition: blist.c:2808
send_im_select
static void send_im_select(GntMenuItem *item, gpointer n)
Definition: gntblist.c:2783
purple_request_field_get_type
PurpleRequestFieldType purple_request_field_get_type(const PurpleRequestField *field)
Definition: request.c:458
_PurpleNotifyUserInfo
Definition: notify.c:54
window
GntWidget * window
Definition: gntcertmgr.c:45
purple_request_field_set_required
void purple_request_field_set_required(PurpleRequestField *field, gboolean required)
Definition: request.c:431
finch_retrieve_user_info
gpointer finch_retrieve_user_info(PurpleConnection *conn, const char *name)
Definition: gntblist.c:1267
purple_blist_alias_buddy
void purple_blist_alias_buddy(PurpleBuddy *buddy, const char *alias)
Definition: blist.c:1098
finch_blist_uninit
void finch_blist_uninit()
Definition: gntblist.c:3208
purple_prefs_connect_callback
guint purple_prefs_connect_callback(void *handle, const char *name, PurplePrefCallback func, gpointer data)
Definition: prefs.c:1396
gnt_tree_new
GntWidget * gnt_tree_new()
Definition: gnttree.c:1194
showlog_cb
static void showlog_cb(PurpleBlistNode *sel, PurpleBlistNode *node)
Definition: gntblist.c:1457
purple_presence_is_status_primitive_active
gboolean purple_presence_is_status_primitive_active(const PurplePresence *presence, PurpleStatusPrimitive primitive)
Definition: status.c:1522
purple_blist_request_add_chat
void purple_blist_request_add_chat(PurpleAccount *account, PurpleGroup *group, const char *alias, const char *name)
Definition: blist.c:2828
PURPLE_BLIST_OTHER_NODE
Definition: blist.h:59
serv_get_info
void serv_get_info(PurpleConnection *gc, const char *name)
Definition: server.c:167
gnt_bindable_perform_action_named
gboolean gnt_bindable_perform_action_named(GntBindable *bindable, const char *name,...)
Definition: gntbindable.c:310
_PurplePluginAction::label
char * label
Definition: plugin.h:196
gntutils.h
purple_timeout_add_seconds
guint purple_timeout_add_seconds(guint interval, GSourceFunc function, gpointer data)
Definition: eventloop.c:40
purple_request_field_set_visible
void purple_request_field_set_visible(PurpleRequestField *field, gboolean visible)
Definition: request.c:413
PURPLE_CONV_TYPE_IM
Definition: conversation.h:54
FinchBlistManager
Definition: gntblist.h:40
sort_blist_change_cb
static void sort_blist_change_cb(GntMenuItem *item, gpointer n)
Definition: gntblist.c:2707
purple_presence_get_active_status
PurpleStatus * purple_presence_get_active_status(const PurplePresence *presence)
Definition: status.c:1474
PurpleLogType
PurpleLogType
Definition: log.h:41
FinchBlist::context
GntWidget * context
Definition: gntblist.c:78
proto_chat_entry::is_int
gboolean is_int
Definition: prpl.h:108
PURPLE_BLIST_NODE_IS_CONTACT
gboolean PURPLE_BLIST_NODE_IS_CONTACT(PurpleBlistNode *node)
create_menu
static void create_menu(void)
Definition: gntblist.c:2986
FinchBlist::tooltip
GntWidget * tooltip
Definition: gntblist.c:74
groups
static GHashTable * groups
Definition: grouping.c:223
gnt_ascii_only
gboolean gnt_ascii_only(void)
Definition: gntmain.c:628
gnt_combo_box_set_selected
void gnt_combo_box_set_selected(GntComboBox *box, gpointer key)
Definition: gntcombobox.c:370
purple_request_field_account_set_show_all
void purple_request_field_account_set_show_all(PurpleRequestField *field, gboolean show_all)
Definition: request.c:1124
blist_ui_ops
static PurpleBlistUiOps blist_ui_ops
Definition: gntblist.c:859
blist_node_compare_status
static int blist_node_compare_status(PurpleBlistNode *n1, PurpleBlistNode *n2)
Definition: gntblist.c:2436
purple_blist_node_get_parent
PurpleBlistNode * purple_blist_node_get_parent(PurpleBlistNode *node)
Definition: blist.c:860
gnt_menuitem_set_id
void gnt_menuitem_set_id(GntMenuItem *item, const char *id)
Definition: gntmenuitem.c:138
finch_add_group
static void finch_add_group(PurpleBlistNode *selected, PurpleGroup *grp)
Definition: gntblist.c:1245
purple_notify_user_info_new
PurpleNotifyUserInfo * purple_notify_user_info_new()
Definition: notify.c:469
_
void boot_DynaLoader _((pTHX_ CV *cv))
finch_request_add_chat
static void finch_request_add_chat(PurpleAccount *account, PurpleGroup *grp, const char *alias, const char *name)
Definition: gntblist.c:777
purple_prefs_get_int
int purple_prefs_get_int(const char *name)
Definition: prefs.c:1133
_PurpleMenuAction
Definition: util.h:54
remove_new_empty_group
static gboolean remove_new_empty_group(gpointer data)
Definition: gntblist.c:603
proto_chat_entry::secret
gboolean secret
Definition: prpl.h:111
PURPLE_STATUS_MOBILE
Definition: status.h:126
gnt_window_present
void gnt_window_present(GntWidget *window)
Definition: gntmain.c:548
FINCH_GET_DATA
#define FINCH_GET_DATA(obj)
Definition: finch.h:31
add_custom_action
static void add_custom_action(GntMenu *menu, const char *label, PurpleCallback callback, gpointer data)
Definition: gntblist.c:1134
FinchBlist::window
GntWidget * window
Definition: gntblist.c:71
finch_blist_get_tree
GntTree * finch_blist_get_tree(void)
Definition: gntblist.c:3272
GNT_BOX
#define GNT_BOX(obj)
Definition: gntbox.h:34
purple_account_get_connection
PurpleConnection * purple_account_get_connection(const PurpleAccount *account)
Definition: account.c:2284
gntentry.h
blist.h
gnt_box_add_widget
void gnt_box_add_widget(GntBox *b, GntWidget *widget)
Definition: gntbox.c:674
view_log_select_cb
static void view_log_select_cb(gpointer data, PurpleRequestFields *fields)
Definition: gntblist.c:2893
gntmenu.h
get_contact_log_size
static int get_contact_log_size(PurpleBlistNode *c)
Definition: gntblist.c:2466
blist_node_compare_log
static int blist_node_compare_log(PurpleBlistNode *n1, PurpleBlistNode *n2)
Definition: gntblist.c:2481
savedstatus_changed
static void savedstatus_changed(PurpleSavedStatus *now, PurpleSavedStatus *old)
Definition: gntblist.c:2339
purple_request_field_choice_add
void purple_request_field_choice_add(PurpleRequestField *field, const char *label)
Definition: request.c:744
handle
static PurplePlugin * handle
Definition: nss-prefs.c:61
gnt_text_view_new
GntWidget * gnt_text_view_new()
Definition: gnttextview.c:499
_GntComboBox
Definition: gntcombobox.h:50
purple_savedstatuses_get_handle
void * purple_savedstatuses_get_handle(void)
Definition: savedstatuses.c:1175
purple_request_field_string_set_masked
void purple_request_field_string_set_masked(PurpleRequestField *field, gboolean masked)
Definition: request.c:555
default_find_parent
static gpointer default_find_parent(PurpleBlistNode *node)
Definition: gntblist.c:215
GNT_WIDGET_IS_FLAG_SET
#define GNT_WIDGET_IS_FLAG_SET(obj, flags)
Definition: gntwidget.h:46
gntmenuitem.h
build_plugin_actions
static void build_plugin_actions(GntMenuItem *item, PurplePlugin *plugin, gpointer context)
Definition: gntblist.c:2519
gntstatus.h
purple_presence_is_idle
gboolean purple_presence_is_idle(const PurplePresence *presence)
Definition: status.c:1544
_PurpleMenuAction::data
gpointer data
Definition: util.h:58
GNT_WIDGET_INVISIBLE
Definition: gntwidget.h:66
_PurplePluginProtocolInfo::get_info
void(* get_info)(PurpleConnection *, const char *who)
Definition: prpl.h:330
FinchBlist::tnode
PurpleBlistNode * tnode
Definition: gntblist.c:75
gnt_util_onscreen_fit_string
char * gnt_util_onscreen_fit_string(const char *string, int maxw)
Definition: gntutils.c:119
populate_status_dropdown
static void populate_status_dropdown(void)
Definition: gntblist.c:2091
purple_buddy_get_group
PurpleGroup * purple_buddy_get_group(PurpleBuddy *buddy)
Definition: blist.c:2630
purple_menu_action_new
PurpleMenuAction * purple_menu_action_new(const char *label, PurpleCallback callback, gpointer data, GList *children)
Definition: util.c:88
actions
static GList * actions(PurplePlugin *plugin, gpointer context)
Definition: idle.c:249
blist_node_compare_position
static int blist_node_compare_position(PurpleBlistNode *n1, PurpleBlistNode *n2)
Definition: gntblist.c:2390
purple_prefs_set_bool
void purple_prefs_set_bool(const char *name, gboolean value)
Definition: prefs.c:898
finch_blist_init
void finch_blist_init()
Definition: gntblist.c:2185
reconstruct_grouping_menu
static void reconstruct_grouping_menu(void)
Definition: gntblist.c:2653
purple_blist_get_root
PurpleBlistNode * purple_blist_get_root()
Definition: blist.c:769
purple_conv_chat_has_left
gboolean purple_conv_chat_has_left(PurpleConvChat *chat)
Definition: conversation.c:2150
FinchBlist::menu
GntWidget * menu
Definition: gntblist.c:86
purple_blist_get_group_online_count
int purple_blist_get_group_online_count(PurpleGroup *group)
Definition: blist.c:3076
serv_join_chat
void serv_join_chat(PurpleConnection *gc, GHashTable *data)
Definition: server.c:449
gnt_widget_set_position
void gnt_widget_set_position(GntWidget *wid, int x, int y)
Definition: gntwidget.c:440
_PurplePluginProtocolInfo
Definition: prpl.h:223
join_chat
static void join_chat(PurpleChat *chat)
Definition: gntblist.c:706
_PurpleMenuAction::callback
PurpleCallback callback
Definition: util.h:57
chat_components_edit_ok
static void chat_components_edit_ok(PurpleChat *chat, PurpleRequestFields *allfields)
Definition: gntblist.c:1144
add_group_cb
static void add_group_cb(gpointer null, const char *group)
Definition: gntblist.c:812
str
static char str[256]
Definition: util.c:28
gnt_tree_change_text
void gnt_tree_change_text(GntTree *tree, gpointer key, int colno, const char *text)
Definition: gnttree.c:1560
FinchBlist::plugins
GntMenuItem * plugins
Definition: gntblist.c:89
gnt_widget_set_name
void gnt_widget_set_name(GntWidget *widget, const char *name)
Definition: gntwidget.c:589
purple_find_buddy
PurpleBuddy * purple_find_buddy(PurpleAccount *account, const char *name)
Definition: blist.c:2427
purple_presence_compare
gint purple_presence_compare(const PurplePresence *presence1, const PurplePresence *presence2)
Definition: status.c:1593
purple_blist_node_get_sibling_next
PurpleBlistNode * purple_blist_node_get_sibling_next(PurpleBlistNode *node)
Definition: blist.c:870
create_group_menu
static void create_group_menu(GntMenu *menu, PurpleGroup *group)
Definition: gntblist.c:1257
_PurplePlugin
Definition: plugin.h:151
PurplePrefType
enum _PurplePrefType PurplePrefType
gntlabel.h
GNT_TEXT_FLAG_NORMAL
Definition: gnttextview.h:70
purple_request_fields_new
PurpleRequestFields * purple_request_fields_new(void)
Definition: request.c:47
GNT_TEXT_FLAG_BLINK
Definition: gnttextview.h:73
_PurpleContact::totalsize
int totalsize
Definition: blist.h:156
data
gpointer data
Definition: gntwm.c:1781
GNT_TEXT_FLAG_BOLD
Definition: gnttextview.h:71
finch_pounce_editor_show
void finch_pounce_editor_show(PurpleAccount *account, const char *name, PurplePounce *cur_pounce)
Definition: gntpounce.c:296
_PurpleChat::alias
char * alias
Definition: blist.h:181
_PurplePluginProtocolInfo::can_receive_file
gboolean(* can_receive_file)(PurpleConnection *, const char *who)
Definition: prpl.h:505
context_menu
static gboolean context_menu(GntWidget *widget, FinchBlist *ggblist)
Definition: gntblist.c:1931
view_log_cb
static void view_log_cb(GntMenuItem *item, gpointer n)
Definition: gntblist.c:2918
new_node
static void new_node(PurpleBlistNode *node)
Definition: gntblist.c:461
buddy_status_changed
static void buddy_status_changed(PurpleBuddy *buddy, PurpleStatus *old, PurpleStatus *now, FinchBlist *ggblist)
Definition: gntblist.c:1990
FinchBlistManager::init
gboolean(* init)(void)
Definition: gntblist.h:45
gnt_menuitem_check_set_checked
void gnt_menuitem_check_set_checked(GntMenuItemCheck *item, gboolean set)
Definition: gntmenuitemcheck.c:86
prpl_info
static PurplePluginProtocolInfo prpl_info
Definition: bonjour.c:464
gnt_tree_add_row_after
GntTreeRow * gnt_tree_add_row_after(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro)
Definition: gnttree.c:1344
purple_request_fields_get_account
PurpleAccount * purple_request_fields_get_account(const PurpleRequestFields *fields, const char *id)
Definition: request.c:260
proto_chat_entry::identifier
const char * identifier
Definition: prpl.h:106
offline
static PurpleBlistNode offline
Definition: grouping.c:37
finch_blist_manager_add_node
void finch_blist_manager_add_node(PurpleBlistNode *node)
Definition: gntblist.c:486
NULL
#define NULL
Definition: getopt1.c:52
StatusType
StatusType
Definition: gntblist.c:108
PURPLE_BLIST_CHAT_NODE
Definition: blist.h:58
status_selection_changed
static void status_selection_changed(GntComboBox *box, StatusBoxItem *old, StatusBoxItem *now, gpointer null)
Definition: gntblist.c:2285
purple_blist_add_buddy
void purple_blist_add_buddy(PurpleBuddy *buddy, PurpleContact *contact, PurpleGroup *group, PurpleBlistNode *node)
Definition: blist.c:1566
PURPLE_REQUEST_FIELD_INTEGER
Definition: request.h:61
_GntTree
Definition: gnttree.h:57
purple_conversation_present
void purple_conversation_present(PurpleConversation *conv)
Definition: conversation.c:611
purple_signals_disconnect_by_handle
void purple_signals_disconnect_by_handle(void *handle)
Definition: signals.c:417
PURPLE_SIGNAL_PRIORITY_HIGHEST
#define PURPLE_SIGNAL_PRIORITY_HIGHEST
Definition: signals.h:58
StatusBoxItem::prim
PurpleStatusPrimitive prim
Definition: gntblist.c:121
reconstruct_plugins_menu
static void reconstruct_plugins_menu(void)
Definition: gntblist.c:2586
populate_buddylist
static void populate_buddylist(void)
Definition: gntblist.c:2055
purple_account_remove_buddy
void purple_account_remove_buddy(PurpleAccount *account, PurpleBuddy *buddy, PurpleGroup *group)
Definition: account.c:2751
_PurpleMenuAction::label
char * label
Definition: util.h:56
remove_contact
static void remove_contact(PurpleContact *contact)
Definition: gntblist.c:1386
purple_timeout_remove
gboolean purple_timeout_remove(guint tag)
Definition: eventloop.c:51
FinchBlistNode::signed_timer
guint signed_timer
Definition: gntblist.c:105
blist_node_compare_text
static int blist_node_compare_text(PurpleBlistNode *n1, PurpleBlistNode *n2)
Definition: gntblist.c:2399
GNT_WIDGET_UNSET_FLAGS
#define GNT_WIDGET_UNSET_FLAGS(obj, flags)
Definition: gntwidget.h:45
FinchBlist::cnode
PurpleBlistNode * cnode
Definition: gntblist.c:79
GNT_TREE
#define GNT_TREE(obj)
Definition: gnttree.h:37
_PurplePluginAction::context
gpointer context
Definition: plugin.h:204
purple_request_fields_get_string
const char * purple_request_fields_get_string(const PurpleRequestFields *fields, const char *id)
Definition: request.c:203
GNT_WIDGET_TRANSIENT
Definition: gntwidget.h:67
FinchBlistManager::uninit
gboolean(* uninit)(void)
Definition: gntblist.h:46
finch_blist_manager_find
FinchBlistManager * finch_blist_manager_find(const char *id)
Definition: gntblist.c:3258
purple_get_blist
PurpleBuddyList * purple_get_blist()
Definition: blist.c:763
finch_add_chat
static void finch_add_chat(PurpleBlistNode *selected, PurpleGroup *grp)
Definition: gntblist.c:1251
purple_request_field_account_new
PurpleRequestField * purple_request_field_account_new(const char *id, const char *text, PurpleAccount *account)
Definition: request.c:1081
PURPLE_STATUS_INVISIBLE
Definition: status.h:123
color_available
static int color_available
Definition: gntblist.c:157
purple_savedstatus_get_type
PurpleStatusPrimitive purple_savedstatus_get_type(const PurpleSavedStatus *saved_status)
Definition: savedstatuses.c:1033
gntcombobox.h
purple_status_get_type
PurpleStatusType * purple_status_get_type(const PurpleStatus *status)
Definition: status.c:923
purple_blist_rename_group
void purple_blist_rename_group(PurpleGroup *source, const char *name)
Definition: blist.c:1185
gnt_menuitem_set_callback
void gnt_menuitem_set_callback(GntMenuItem *item, GntMenuItemCallback callback, gpointer data)
Definition: gntmenuitem.c:110
gnt_box_give_focus_to_child
void gnt_box_give_focus_to_child(GntBox *box, GntWidget *widget)
Definition: gntbox.c:881
purple_blist_alias_contact
void purple_blist_alias_contact(PurpleContact *contact, const char *alias)
Definition: blist.c:1014
purple_find_prpl
PurplePlugin * purple_find_prpl(const char *id)
Definition: prpl.c:624
purple_group_new
PurpleGroup * purple_group_new(const char *name)
Definition: blist.c:1791
gnt_box_set_toplevel
void gnt_box_set_toplevel(GntBox *box, gboolean set)
Definition: gntbox.c:701
menu_add_chat_cb
static void menu_add_chat_cb(GntMenuItem *item, gpointer null)
Definition: gntblist.c:2967
GNT_TEXT_VIEW
#define GNT_TEXT_VIEW(obj)
Definition: gnttextview.h:36
PURPLE_CALLBACK
#define PURPLE_CALLBACK(func)
Definition: signals.h:32
GNT_WIDGET_SET_FLAGS
#define GNT_WIDGET_SET_FLAGS(obj, flags)
Definition: gntwidget.h:44
GNT_MENU_ITEM_CHECK
#define GNT_MENU_ITEM_CHECK(obj)
Definition: gntmenuitemcheck.h:36
purple_account_get_protocol_id
const char * purple_account_get_protocol_id(const PurpleAccount *account)
Definition: account.c:2265
purple_prefs_trigger_callback
void purple_prefs_trigger_callback(const char *name)
Definition: prefs.c:860
purple_signal_connect_priority
gulong purple_signal_connect_priority(void *instance, const char *signal, void *handle, PurpleCallback func, void *data, int priority)
Definition: signals.c:298
purple_privacy_check
gboolean purple_privacy_check(PurpleAccount *account, const char *who)
Definition: privacy.c:361
default_manager
static FinchBlistManager default_manager
Definition: gntblist.c:316
purple_blist_node_set_bool
void purple_blist_node_set_bool(PurpleBlistNode *node, const char *key, gboolean data)
Definition: blist.c:2939
PURPLE_GROUP
#define PURPLE_GROUP(obj)
Definition: blist.h:92
finch_blist_rename_node_cb
static void finch_blist_rename_node_cb(PurpleBlistNode *selected, PurpleBlistNode *node)
Definition: gntblist.c:1427
PURPLE_CONV_CHAT
PurpleConvIm * PURPLE_CONV_CHAT(const PurpleConversation *conversation)
purple_unescape_html
char * purple_unescape_html(const char *html)
destroy_status_list
static void destroy_status_list(GList *list)
Definition: gntblist.c:2084
purple_blist_node_get_type
PurpleBlistNodeType purple_blist_node_get_type(PurpleBlistNode *node)
Definition: blist.c:2932
finch_blist_get_position
gboolean finch_blist_get_position(int *x, int *y)
Definition: gntblist.c:3212
purple_request_field_int_new
PurpleRequestField * purple_request_field_int_new(const char *id, const char *text, int default_value)
Definition: request.c:619
default_can_add_node
static gboolean default_can_add_node(PurpleBlistNode *node)
Definition: gntblist.c:166
toggle_pref_cb
static void toggle_pref_cb(GntMenuItem *item, gpointer n)
Definition: gntblist.c:2702
finch_add_buddy
static void finch_add_buddy(PurpleBlistNode *selected, PurpleGroup *grp)
Definition: gntblist.c:1239
purple_blist_request_add_buddy
void purple_blist_request_add_buddy(PurpleAccount *account, const char *username, const char *group, const char *alias)
Definition: blist.c:2816
purple_accounts_get_handle
void * purple_accounts_get_handle(void)
Definition: account.c:3180
purple_plugin_action_free
void purple_plugin_action_free(PurplePluginAction *action)
Definition: plugin.c:1666
STATUS_SAVED_NEW
Definition: gntblist.c:113
flag
guint64 flag
Definition: family_locate.c:48
purple_menu_action_free
void purple_menu_action_free(PurpleMenuAction *act)
Definition: util.c:100
purple_connections_get_handle
void * purple_connections_get_handle(void)
Definition: connection.c:734
purple_presence_get_idle_time
time_t purple_presence_get_idle_time(const PurplePresence *presence)
Definition: status.c:1552
context_menu_destroyed
static void context_menu_destroyed(GntWidget *widget, FinchBlist *ggblist)
Definition: gntblist.c:1677
purple_blist_get_group_size
int purple_blist_get_group_size(PurpleGroup *group, gboolean offline)
Definition: blist.c:3068
purple_request_field_bool_new
PurpleRequestField * purple_request_field_bool_new(const char *id, const char *text, gboolean default_value)
Definition: request.c:673
gnt_text_view_append_text_with_flags
void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextFormatFlags flags)
Definition: gnttextview.c:506
gntcolors.h
GNT_WIDGET
#define GNT_WIDGET(obj)
Definition: gntwidget.h:37
finch_blist_install_manager
void finch_blist_install_manager(const FinchBlistManager *manager)
Definition: gntblist.c:3238
buddy_recent_signed_on_off
static gboolean buddy_recent_signed_on_off(gpointer data)
Definition: gntblist.c:2543
PURPLE_STATUS_AWAY
Definition: status.h:124
purple_savedstatus_get_current
PurpleSavedStatus * purple_savedstatus_get_current(void)
Definition: savedstatuses.c:791
append_extended_menu
static void append_extended_menu(GntMenu *menu, PurpleBlistNode *node)
Definition: gntblist.c:1371
gnt_widget_get_position
void gnt_widget_get_position(GntWidget *wid, int *x, int *y)
Definition: gntwidget.c:449
TRUE
#define TRUE
Definition: protobuf-c.c:56
managers
static GList * managers
Definition: gntblist.c:327
_PurplePluginInfo::name
char * name
Definition: plugin.h:90
_PurpleAccount
Definition: account.h:169
dbus-analyze-signals.type
string type
Definition: dbus-analyze-signals.py:42
_PurpleBlistNode
Definition: blist.h:124
finch_savedstatus_show_all
void finch_savedstatus_show_all()
Definition: gntstatus.c:167
purple_blist_node_get_bool
gboolean purple_blist_node_get_bool(PurpleBlistNode *node, const char *key)
Definition: blist.c:2959
add_chat_cb
static void add_chat_cb(void *data, PurpleRequestFields *allfields)
Definition: gntblist.c:732
add_contact
static void add_contact(PurpleContact *contact, FinchBlist *ggblist)
Definition: gntblist.c:976
purple_markup_strip_html
char * purple_markup_strip_html(const char *str)
purple_blist_remove_buddy
void purple_blist_remove_buddy(PurpleBuddy *buddy)
Definition: blist.c:2123
gnt_box_new
GntWidget * gnt_box_new(gboolean homo, gboolean vert)
Definition: gntbox.c:662
FinchBlistManager::id
const char * id
Definition: gntblist.h:43
purple_conversation_new
PurpleConversation * purple_conversation_new(PurpleConversationType type, PurpleAccount *account, const char *name)
Definition: conversation.c:330
FALSE
#define FALSE
Definition: protobuf-c.c:57
purple_buddy_get_alias
const char * purple_buddy_get_alias(PurpleBuddy *buddy)
Definition: blist.c:2348
ggblist
static FinchBlist * ggblist
Definition: gntblist.c:126
FINCH_SET_DATA
#define FINCH_SET_DATA(obj, data)
Definition: finch.h:32
proto_chat_entry
Definition: prpl.h:104
color_offline
static int color_offline
Definition: gntblist.c:159
_PurplePluginProtocolInfo::tooltip_text
void(* tooltip_text)(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full)
Definition: prpl.h:257
serv_alias_buddy
void serv_alias_buddy(PurpleBuddy *b)
Definition: server.c:209
add_chat
static void add_chat(PurpleChat *chat, FinchBlist *ggblist)
Definition: gntblist.c:959
purple_request_fields_get_groups
GList * purple_request_fields_get_groups(const PurpleRequestFields *fields)
Definition: request.c:103
request.h
get_blist_node_flag
static GntTextFormatFlags get_blist_node_flag(PurpleBlistNode *node)
Definition: gntblist.c:381
gnt_menu_new
GntWidget * gnt_menu_new(GntMenuType type)
Definition: gntmenu.c:478
PURPLE_BLIST_CONTACT_NODE
Definition: blist.h:56
purple_blist_node_get_sibling_prev
PurpleBlistNode * purple_blist_node_get_sibling_prev(PurpleBlistNode *node)
Definition: blist.c:875
purple_request_fields_add_group
void purple_request_fields_add_group(PurpleRequestFields *fields, PurpleRequestFieldGroup *group)
Definition: request.c:72
create_buddy_menu
static void create_buddy_menu(GntMenu *menu, PurpleBuddy *buddy)
Definition: gntblist.c:1325
purple_connection_get_prpl
PurplePlugin * purple_connection_get_prpl(const PurpleConnection *gc)
Definition: connection.c:448
reset_blist_window
static void reset_blist_window(GntWidget *window, gpointer null)
Definition: gntblist.c:2027
purple_prefs_add_int
void purple_prefs_add_int(const char *name, int value)
Definition: prefs.c:661
PurpleStatusPrimitive
PurpleStatusPrimitive
Definition: status.h:117
_PurplePluginAction
Definition: plugin.h:195
purple_request_field_choice_new
PurpleRequestField * purple_request_field_choice_new(const char *id, const char *text, int default_value)
Definition: request.c:727
gnt_box_set_title
void gnt_box_set_title(GntBox *b, const char *title)
Definition: gntbox.c:680
finch_log_show_contact
void finch_log_show_contact(PurpleContact *contact)
Definition: gntlog.c:436
draw_tooltip
static void draw_tooltip(FinchBlist *ggblist)
Definition: gntblist.c:1911
hash
static GHashTable * hash
Definition: gntconn.c:53
purple_prefs_add_none
void purple_prefs_add_none(const char *name)
Definition: prefs.c:638
GNT_MENU_POPUP
Definition: gntmenu.h:59
group_collapsed
static void group_collapsed(GntWidget *widget, PurpleBlistNode *node, gboolean collapsed, gpointer null)
Definition: gntblist.c:3107
add_buddy_cb
static void add_buddy_cb(void *data, PurpleRequestFields *allfields)
Definition: gntblist.c:624
purple_contact_get_priority_buddy
PurpleBuddy * purple_contact_get_priority_buddy(PurpleContact *contact)
Definition: blist.c:2297
text
static char * text[]
Definition: zephyr_err.c:10
FinchBlistManager::can_add_node
gboolean(* can_add_node)(PurpleBlistNode *node)
Definition: gntblist.h:47
gnt_screen_menu_show
gboolean gnt_screen_menu_show(gpointer menu)
Definition: gntmain.c:665
b
short b
Definition: gntcolors.c:44
menu_group_set_cb
static void menu_group_set_cb(GntMenuItem *item, gpointer null)
Definition: gntblist.c:2979
gnt_tree_get_parent_key
gpointer gnt_tree_get_parent_key(GntTree *tree, gpointer key)
Definition: gnttree.c:1922
label
const char * label
Definition: jabber.c:1321
FinchBlistNode::row
gpointer row
Definition: gntblist.c:104
purple_savedstatus_activate
void purple_savedstatus_activate(PurpleSavedStatus *saved_status)
Definition: savedstatuses.c:1101
purple_prefs_get_bool
gboolean purple_prefs_get_bool(const char *name)
Definition: prefs.c:1111
purple_request_field_group_new
PurpleRequestFieldGroup * purple_request_field_group_new(const char *title)
Definition: request.c:275
purple_buddy_new
PurpleBuddy * purple_buddy_new(PurpleAccount *account, const char *name, const char *alias)
Definition: blist.c:1362
PURPLE_BLIST_NODE_IS_BUDDY
gboolean PURPLE_BLIST_NODE_IS_BUDDY(PurpleBlistNode *node)
_PurpleGroup
Definition: blist.h:167
_GntWindow
Definition: gntwindow.h:57
purple_primitive_get_name_from_type
const char * purple_primitive_get_name_from_type(PurpleStatusPrimitive type)
Definition: status.c:187
_GntMenuItem
Definition: gntmenuitem.h:61
finch_blist_remove_node_cb
static void finch_blist_remove_node_cb(PurpleBlistNode *selected, PurpleBlistNode *node)
Definition: gntblist.c:1551
PURPLE_PLUGIN_ACTIONS
#define PURPLE_PLUGIN_ACTIONS(plugin, context)
Definition: plugin.h:212
purple_accounts_get_all_active
GList * purple_accounts_get_all_active(void)
Definition: account.c:3088
purple_request_field_get_id
const char * purple_request_field_get_id(const PurpleRequestField *field)
Definition: request.c:474
finch_blist_set_position
void finch_blist_set_position(int x, int y)
Definition: gntblist.c:3220
PURPLE_STATUS_OFFLINE
Definition: status.h:120
PURPLE_PLUGIN_HAS_ACTIONS
#define PURPLE_PLUGIN_HAS_ACTIONS(plugin)
Definition: plugin.h:209
gntconv.h
reset_blist_node_ui_data
static void reset_blist_node_ui_data(PurpleBlistNode *node)
Definition: gntblist.c:343
gnt_combo_box_get_selected_data
gpointer gnt_combo_box_get_selected_data(GntComboBox *box)
Definition: gntcombobox.c:365
finch_log_show
void finch_log_show(PurpleLogType type, const char *username, PurpleAccount *account)
Definition: gntlog.c:369
gnt_menuitem_check_new
GntMenuItem * gnt_menuitem_check_new(const char *text)
Definition: gntmenuitemcheck.c:72
gntstyle.h
purple_connection_get_account
PurpleAccount * purple_connection_get_account(const PurpleConnection *gc)
Definition: connection.c:440
log.h
purple_request_field_group_get_fields
GList * purple_request_field_group_get_fields(const PurpleRequestFieldGroup *group)
Definition: request.c:333
update_node_display
static void update_node_display(PurpleBlistNode *buddy, FinchBlist *ggblist)
Definition: gntblist.c:1965
_PurpleRequestField
Definition: request.h:103
PURPLE_LOG_IM
Definition: log.h:42
node_remove
static void node_remove(PurpleBuddyList *list, PurpleBlistNode *node)
Definition: gntblist.c:500
finch_blist_get_ui_ops
PurpleBlistUiOps * finch_blist_get_ui_ops()
Definition: gntblist.c:1034
PURPLE_STATUS_AVAILABLE
Definition: status.h:121
purple_notify_user_info_add_pair
void purple_notify_user_info_add_pair(PurpleNotifyUserInfo *user_info, const char *label, const char *value)
Definition: notify.c:596
purple_prefs_set_int
void purple_prefs_set_int(const char *name, int value)
Definition: prefs.c:923
PURPLE_CONNECTION_IS_CONNECTED
gboolean PURPLE_CONNECTION_IS_CONNECTED(PurpleConnection *connection)
GNT_WIDGET_CAN_TAKE_FOCUS
Definition: gntwidget.h:55
purple_blist_remove_contact
void purple_blist_remove_contact(PurpleContact *contact)
Definition: blist.c:2074
purple_account_get_protocol_name
const char * purple_account_get_protocol_name(const PurpleAccount *account)
Definition: account.c:2272
PurpleCallback
void(* PurpleCallback)(void)
Definition: signals.h:34
_PurpleMenuAction::children
GList * children
Definition: util.h:59
purple_buddy_get_presence
PurplePresence * purple_buddy_get_presence(const PurpleBuddy *buddy)
Definition: blist.c:2612
gnt_menuitem_check_get_checked
gboolean gnt_menuitem_check_get_checked(GntMenuItemCheck *item)
Definition: gntmenuitemcheck.c:81
savedstatuses.h
key_pressed
static gboolean key_pressed(GntWidget *widget, const char *text, FinchBlist *ggblist)
Definition: gntblist.c:1938
_PurplePlugin::info
PurplePluginInfo * info
Definition: plugin.h:157
draw_tooltip_real
static gboolean draw_tooltip_real(FinchBlist *ggblist)
Definition: gntblist.c:1841
finch_blist_get_buddy_info_cb
static void finch_blist_get_buddy_info_cb(PurpleBlistNode *selected, PurpleBuddy *buddy)
Definition: gntblist.c:1280
purple_plugins_get_loaded
GList * purple_plugins_get_loaded(void)
Definition: plugin.c:1636
auto_join_chats
static gboolean auto_join_chats(gpointer data)
Definition: gntblist.c:2677
tree
GntWidget * tree
Definition: gntcertmgr.c:46
finch_blist_remove_node
static void finch_blist_remove_node(PurpleBlistNode *node)
Definition: gntblist.c:1534
StatusBoxItem::saved
PurpleSavedStatus * saved
Definition: gntblist.c:122
gnt_widget_destroy
void gnt_widget_destroy(GntWidget *obj)
Definition: gntwidget.c:312
PurpleRequestFields
Definition: request.h:74
purple_chat_new
PurpleChat * purple_chat_new(PurpleAccount *account, const char *alias, GHashTable *components)
Definition: blist.c:1329
gntblist.h
blist_show
static void blist_show(PurpleBuddyList *list)
Definition: gntblist.c:3114
purple_blist_node_get_extended_menu
GList * purple_blist_node_get_extended_menu(PurpleBlistNode *n)
Definition: blist.c:3056
purple_blist_alias_chat
void purple_blist_alias_chat(PurpleChat *chat, const char *alias)
Definition: blist.c:1062
purple_status_type_get_primitive
PurpleStatusPrimitive purple_status_type_get_primitive(const PurpleStatusType *status_type)
Definition: status.c:369
PurpleRequestFieldGroup
Definition: request.h:89
context_menu_callback
static void context_menu_callback(GntMenuItem *item, gpointer data)
Definition: gntblist.c:1075
redraw_blist
static void redraw_blist(const char *name, PurplePrefType type, gconstpointer val, gpointer data)
Definition: gntblist.c:2147
FinchBlist::typing
int typing
Definition: gntblist.c:84
menu_add_buddy_cb
static void menu_add_buddy_cb(GntMenuItem *item, gpointer null)
Definition: gntblist.c:2961
gnt_widget_draw
void gnt_widget_draw(GntWidget *widget)
Definition: gntwidget.c:335
purple_request_field_string_new
PurpleRequestField * purple_request_field_string_new(const char *id, const char *text, const char *default_value, gboolean multiline)
Definition: request.c:514
FinchBlistManager::find_parent
gpointer(* find_parent)(PurpleBlistNode *node)
Definition: gntblist.h:48
received_chat_msg
static void received_chat_msg(PurpleAccount *account, const char *sender, const char *msg, PurpleConversation *conv, PurpleMessageFlags flags, gpointer null)
Definition: gntgf.c:251
PURPLE_CONV_TYPE_CHAT
Definition: conversation.h:55
_PurpleContact
Definition: blist.h:153
purple_blist_remove_group
void purple_blist_remove_group(PurpleGroup *group)
Definition: blist.c:2247
purple_str_seconds_to_string
char * purple_str_seconds_to_string(guint sec)
gnt_window_set_menu
void gnt_window_set_menu(GntWindow *window, GntMenu *menu)
Definition: gntwindow.c:193
_PurplePluginAction::plugin
PurplePlugin * plugin
Definition: plugin.h:200
_PurplePluginProtocolInfo::blist_node_menu
GList *(* blist_node_menu)(PurpleBlistNode *node)
Definition: prpl.h:271
make_sure_text_fits
static GString * make_sure_text_fits(GString *string)
Definition: gntblist.c:1831
color_idle
static int color_idle
Definition: gntblist.c:160
gnt_menu_add_item
void gnt_menu_add_item(GntMenu *menu, GntMenuItem *item)
Definition: gntmenu.c:502
gnt_combo_box_remove_all
void gnt_combo_box_remove_all(GntComboBox *box)
Definition: gntcombobox.c:382
act
static GList * act
Definition: gntwm.c:111
_PurpleChat
Definition: blist.h:179
purple_accounts_get_all
GList * purple_accounts_get_all(void)
Definition: account.c:3082
FinchBlist::status
GntWidget * status
Definition: gntblist.c:82
error
const char * error
Definition: auth_scram.c:51
gnt_tree_is_searching
gboolean gnt_tree_is_searching(GntTree *tree)
Definition: gnttree.c:1911
purple_savedstatus_find_transient_by_type_and_message
PurpleSavedStatus * purple_savedstatus_find_transient_by_type_and_message(PurpleStatusPrimitive type, const char *message)
Definition: savedstatuses.c:965
menu_add_group_cb
static void menu_add_group_cb(GntMenuItem *item, gpointer null)
Definition: gntblist.c:2973
purple_request_input
void * purple_request_input(void *handle, const char *title, const char *primary, const char *secondary, const char *default_value, gboolean multiline, gboolean masked, gchar *hint, const char *ok_text, GCallback ok_cb, const char *cancel_text, GCallback cancel_cb, PurpleAccount *account, const char *who, PurpleConversation *conv, void *user_data)
Definition: request.c:1200
_PurpleBlistUiOps
Definition: blist.h:203
create_finch_blist_node
static FinchBlistNode * create_finch_blist_node(PurpleBlistNode *node, gpointer row)
Definition: gntblist.c:330
purple_privacy_allow
void purple_privacy_allow(PurpleAccount *account, const char *who, gboolean local, gboolean restore)
Definition: privacy.c:263
gnt_widget_has_focus
gboolean gnt_widget_has_focus(GntWidget *widget)
Definition: gntmain.c:572
FinchBlist::tagged
GList * tagged
Definition: gntblist.c:76
privacy.h
purple_blist_remove_chat
void purple_blist_remove_chat(PurpleChat *chat)
Definition: blist.c:2202
purple_request_field_set_type_hint
void purple_request_field_set_type_hint(PurpleRequestField *field, const char *type_hint)
Definition: request.c:421
buddy_signed_on_off
static void buddy_signed_on_off(PurpleBuddy *buddy, gpointer null)
Definition: gntblist.c:2580
purple_savedstatuses_get_popular
GList * purple_savedstatuses_get_popular(unsigned int how_many)
Definition: savedstatuses.c:760
STATUS_SAVED_POPULAR
Definition: gntblist.c:111
_PurpleConversation
Definition: conversation.h:338
tooltip_for_buddy
static void tooltip_for_buddy(PurpleBuddy *buddy, GString *str, gboolean full)
Definition: gntblist.c:1770
node_update
static void node_update(PurpleBuddyList *list, PurpleBlistNode *node)
Definition: gntblist.c:533
finch_blist_show
void finch_blist_show()
Definition: gntblist.c:3101
gnt_entry_get_text
const char * gnt_entry_get_text(GntEntry *entry)
Definition: gntentry.c:1163
selection_changed
static void selection_changed(GntWidget *widget, gpointer old, gpointer current, FinchBlist *ggblist)
Definition: gntblist.c:1924
_PurplePluginProtocolInfo::send_file
void(* send_file)(PurpleConnection *, const char *who, const char *filename)
Definition: prpl.h:506
PURPLE_LOG_CHAT
Definition: log.h:43
PURPLE_STATUS_UNSET
Definition: status.h:119
finch.h
TYPING_TIMEOUT_S
#define TYPING_TIMEOUT_S
Definition: gntblist.c:65
proto_chat_entry::min
int min
Definition: prpl.h:109
GNT_WIDGET_NO_SHADOW
Definition: gntwidget.h:60
gnt_text_view_set_flag
void gnt_text_view_set_flag(GntTextView *view, GntTextViewFlag flag)
Definition: gnttextview.c:846
proto_chat_entry::required
gboolean required
Definition: prpl.h:107
PURPLE_BLIST_NODE_IS_GROUP
gboolean PURPLE_BLIST_NODE_IS_GROUP(PurpleBlistNode *node)
remove_group
static void remove_group(PurpleGroup *group)
Definition: gntblist.c:1495
get_display_name
static const char * get_display_name(PurpleBlistNode *node)
Definition: gntblist.c:901
tv
GntTextView * tv
Definition: gnttextview.c:854
gnt_tree_remove_all
void gnt_tree_remove_all(GntTree *tree)
Definition: gnttree.c:1545
block_select
static void block_select(GntMenuItem *item, gpointer n)
Definition: gntblist.c:2727
gntline.h
idle
static Prefs idle[]
Definition: gntprefs.c:208
purple_blist_find_chat
PurpleChat * purple_blist_find_chat(PurpleAccount *account, const char *name)
Definition: blist.c:2526
received_im_msg
static void received_im_msg(PurpleAccount *account, const char *sender, const char *msg, PurpleConversation *conv, PurpleMessageFlags flags, gpointer null)
Definition: gntgf.c:243
gnt_vwindow_new
#define gnt_vwindow_new(homo)
Definition: gntwindow.h:81
remove_tooltip
static void remove_tooltip(FinchBlist *ggblist)
Definition: gntblist.c:492
create_chat_menu
static void create_chat_menu(GntMenu *menu, PurpleChat *chat)
Definition: gntblist.c:1224
toggle_show_offline
static void toggle_show_offline(GntMenuItem *item, gpointer buddy)
Definition: gntblist.c:1314
_PurpleConnection
Definition: connection.h:245
FinchBlist
Definition: gntblist.c:69
purple_blist_add_chat
void purple_blist_add_chat(PurpleChat *chat, PurpleGroup *group, PurpleBlistNode *node)
Definition: blist.c:1481
status_text_changed
static gboolean status_text_changed(GntEntry *entry, const char *text, gpointer null)
Definition: gntblist.c:2318
finch_blist_place_tagged
static void finch_blist_place_tagged(PurpleBlistNode *target)
Definition: gntblist.c:1607
purple_account_add_buddy_with_invite
void purple_account_add_buddy_with_invite(PurpleAccount *account, PurpleBuddy *buddy, const char *message)
Definition: account.c:2628
PURPLE_BLIST_NODE_IS_CHAT
gboolean PURPLE_BLIST_NODE_IS_CHAT(PurpleBlistNode *node)
buddy_signed_off
static void buddy_signed_off(PurpleBuddy *buddy, gpointer null)
Definition: gntgf.c:236
purple_buddy_get_contact_alias
const char * purple_buddy_get_contact_alias(PurpleBuddy *buddy)
Definition: blist.c:2323
value
gpointer value
Definition: gntwm.c:1782
gnt_color_add_pair
int gnt_color_add_pair(int fg, int bg)
Definition: gntcolors.c:305
serv_send_file
void serv_send_file(PurpleConnection *gc, const char *who, const char *file)
Definition: server.c:980
_PurplePresence
Definition: status.c:69
selection_activate
static void selection_activate(GntWidget *widget, FinchBlist *ggblist)
Definition: gntblist.c:1040
purple_request_fields
void * purple_request_fields(void *handle, const char *title, const char *primary, const char *secondary, PurpleRequestFields *fields, const char *ok_text, GCallback ok_cb, const char *cancel_text, GCallback cancel_cb, PurpleAccount *account, const char *who, PurpleConversation *conv, void *user_data)
Definition: request.c:1414
purple_savedstatus_get_title
const char * purple_savedstatus_get_title(const PurpleSavedStatus *saved_status)
Definition: savedstatuses.c:994
purple_chat_get_name
const char * purple_chat_get_name(PurpleChat *chat)
Definition: blist.c:2401
add_buddy
static void add_buddy(PurpleBuddy *buddy, FinchBlist *ggblist)
Definition: gntblist.c:999
StatusBoxItem
Definition: gntblist.c:116
FinchBlist::tree
GntWidget * tree
Definition: gntblist.c:72
server.h
dbus-buddyicons-example.node
node
Definition: dbus-buddyicons-example.py:32
purple_chat_get_account
PurpleAccount * purple_chat_get_account(PurpleChat *chat)
Definition: blist.c:2590
sent_im_msg
static void sent_im_msg(PurpleAccount *account, const char *receiver, const char *message)
Definition: cap.c:347
purple_find_group
PurpleGroup * purple_find_group(const char *name)
Definition: blist.c:2510
GntTextFormatFlags
GntTextFormatFlags
Definition: gnttextview.h:68
append_proto_menu
static void append_proto_menu(GntMenu *menu, PurpleConnection *gc, PurpleBlistNode *node)
Definition: gntblist.c:1112
purple_notify_user_info_destroy
void purple_notify_user_info_destroy(PurpleNotifyUserInfo *user_info)
Definition: notify.c:481
GNT_BINDABLE
#define GNT_BINDABLE(obj)
Definition: gntbindable.h:36
PURPLE_BLIST_NODE
#define PURPLE_BLIST_NODE(obj)
Definition: blist.h:81
gnttree.h
GNT_ENTRY
#define GNT_ENTRY(obj)
Definition: gntentry.h:36
gnt_tree_create_row
GntTreeRow * gnt_tree_create_row(GntTree *tree,...)
Definition: gnttree.c:1728
purple_request_field_string_get_value
const char * purple_request_field_string_get_value(const PurpleRequestField *field)
Definition: request.c:583
purple_find_buddy_in_group
PurpleBuddy * purple_find_buddy_in_group(PurpleAccount *account, const char *name, PurpleGroup *group)
Definition: blist.c:2453
FinchBlist::new_group
GList * new_group
Definition: gntblist.c:96
util.h
PURPLE_IS_PROTOCOL_PLUGIN
#define PURPLE_IS_PROTOCOL_PLUGIN(plugin)
Definition: prpl.h:657
gntlog.h
purple_presence_is_available
gboolean purple_presence_is_available(const PurplePresence *presence)
Definition: status.c:1482
remove_peripherals
static void remove_peripherals(FinchBlist *ggblist)
Definition: gntblist.c:2002
_PurpleBuddy
Definition: blist.h:138
FinchBlistManager::create_tooltip
gboolean(* create_tooltip)(gpointer selected_row, GString **body, char **title)
Definition: gntblist.h:49
time
time_t time(void)
block_select_cb
static void block_select_cb(gpointer data, PurpleRequestFields *fields)
Definition: gntblist.c:2713
finch_blist_uninstall_manager
void finch_blist_uninstall_manager(const FinchBlistManager *manager)
Definition: gntblist.c:3248
finch_blist_pounce_node_cb
static void finch_blist_pounce_node_cb(PurpleBlistNode *selected, PurpleBlistNode *node)
Definition: gntblist.c:1292
remove_typing_cb
static gboolean remove_typing_cb(gpointer null)
Definition: gntblist.c:2233
gnt_tree_set_row_flags
void gnt_tree_set_row_flags(GntTree *tree, void *key, GntTextFormatFlags flags)
Definition: gnttree.c:1635
gnt_combo_box_add_data
void gnt_combo_box_add_data(GntComboBox *box, gpointer key, const char *text)
Definition: gntcombobox.c:357
purple_blist_merge_contact
void purple_blist_merge_contact(PurpleContact *source, PurpleBlistNode *node)
Definition: blist.c:1974
toggle_block_buddy
static void toggle_block_buddy(GntMenuItem *item, gpointer buddy)
Definition: gntblist.c:1303
purple_connections_get_all
GList * purple_connections_get_all(void)
Definition: connection.c:665
gnt_tree_get_selection_data
gpointer gnt_tree_get_selection_data(GntTree *tree)
Definition: gnttree.c:1441
purple_notify_userinfo
void * purple_notify_userinfo(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info, PurpleNotifyCloseCallback cb, gpointer user_data)
Definition: notify.c:405
gnt_entry_new
GntWidget * gnt_entry_new(const char *text)
Definition: gntentry.c:1093
color_away
static int color_away
Definition: gntblist.c:158
proto_chat_entry::label
const char * label
Definition: prpl.h:105
FinchBlist::new_group_timeout
guint new_group_timeout
Definition: gntblist.c:97
status.h
buddy_signed_on
static void buddy_signed_on(PurpleBuddy *buddy, gpointer null)
Definition: gntgf.c:229
_PurpleSavedStatus
Definition: savedstatuses.c:61
FinchBlist::manager
FinchBlistManager * manager
Definition: gntblist.c:99
add_group
static void add_group(PurpleGroup *group, FinchBlist *ggblist)
Definition: gntblist.c:886
GNT_KEY_INS
#define GNT_KEY_INS
Definition: gntkeys.h:67
_PurpleBuddyList
Definition: blist.h:189
gntwindow.h
gnt_tree_set_expanded
void gnt_tree_set_expanded(GntTree *tree, void *key, gboolean expanded)
Definition: gnttree.c:1788
_FinchConv
Definition: gntconv.h:51
finch_request_add_group
static void finch_request_add_group(void)
Definition: gntblist.c:850
purple_conv_chat_left
void purple_conv_chat_left(PurpleConvChat *chat)
Definition: conversation.c:2081
_GntEntry
Definition: gntentry.h:65
gntmenuitemcheck.h
PURPLE_PLUGIN_PROTOCOL_INFO
#define PURPLE_PLUGIN_PROTOCOL_INFO(plugin)
Definition: prpl.h:660
gntft.h
get_display_color
static int get_display_color(PurpleBlistNode *node)
Definition: gntblist.c:355