comparison finch/gntblist.c @ 16567:7b692d5dd704

This makes it possible to rearrange chats and groups using the tag+attach system. Thanks a bunch to wabz for testing this. Fixes #379.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sat, 28 Apr 2007 09:35:44 +0000
parents 0b97b224a829
children 1c9835f8b29c
comparison
equal deleted inserted replaced
16566:45773df910e0 16567:7b692d5dd704
108 static gboolean remove_typing_cb(gpointer null); 108 static gboolean remove_typing_cb(gpointer null);
109 static void remove_peripherals(FinchBlist *ggblist); 109 static void remove_peripherals(FinchBlist *ggblist);
110 static const char * get_display_name(PurpleBlistNode *node); 110 static const char * get_display_name(PurpleBlistNode *node);
111 static void savedstatus_changed(PurpleSavedStatus *now, PurpleSavedStatus *old); 111 static void savedstatus_changed(PurpleSavedStatus *now, PurpleSavedStatus *old);
112 static void blist_show(PurpleBuddyList *list); 112 static void blist_show(PurpleBuddyList *list);
113 static void update_node_display(PurpleBlistNode *buddy, FinchBlist *ggblist);
113 static void update_buddy_display(PurpleBuddy *buddy, FinchBlist *ggblist); 114 static void update_buddy_display(PurpleBuddy *buddy, FinchBlist *ggblist);
114 static void account_signed_on_cb(void); 115 static void account_signed_on_cb(void);
115 116
116 /* Sort functions */ 117 /* Sort functions */
117 static int blist_node_compare_position(PurpleBlistNode *n1, PurpleBlistNode *n2); 118 static int blist_node_compare_position(PurpleBlistNode *n1, PurpleBlistNode *n2);
185 if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { 186 if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
186 PurpleContact *contact = (PurpleContact*)node->parent; 187 PurpleContact *contact = (PurpleContact*)node->parent;
187 if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_contact_online(contact)) || 188 if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_contact_online(contact)) ||
188 contact->currentsize < 1) 189 contact->currentsize < 1)
189 node_remove(list, (PurpleBlistNode*)contact); 190 node_remove(list, (PurpleBlistNode*)contact);
190 } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { 191 } else if (!PURPLE_BLIST_NODE_IS_GROUP(node)) {
191 PurpleGroup *group = (PurpleGroup*)node->parent; 192 PurpleGroup *group = (PurpleGroup*)node->parent;
192 if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) || 193 if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) ||
193 group->currentsize < 1) 194 group->currentsize < 1)
194 node_remove(list, node->parent); 195 node_remove(list, node->parent);
195 for (node = node->child; node; node = node->next) 196 for (node = node->child; node; node = node->next)
196 node->ui_data = NULL; 197 node->ui_data = NULL;
198 } else {
199 for (node = node->child; node; node = node->next)
200 node_remove(list, node);
197 } 201 }
198 202
199 draw_tooltip(ggblist); 203 draw_tooltip(ggblist);
200 } 204 }
201 205
230 } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { 234 } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
231 PurpleContact *contact = (PurpleContact*)node; 235 PurpleContact *contact = (PurpleContact*)node;
232 if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_contact_online(contact)) || 236 if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_contact_online(contact)) ||
233 contact->currentsize < 1) 237 contact->currentsize < 1)
234 node_remove(purple_get_blist(), node); 238 node_remove(purple_get_blist(), node);
235 else 239 else {
236 add_node(node, list->ui_data); 240 if (node->ui_data == NULL) {
241 /* The core seems to expect the UI to add the buddies. */
242 for (node = node->child; node; node = node->next)
243 add_node(node, list->ui_data);
244 }
245 }
237 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { 246 } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
238 PurpleGroup *group = (PurpleGroup*)node; 247 PurpleGroup *group = (PurpleGroup*)node;
239 if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) || 248 if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) ||
240 group->currentsize < 1) 249 group->currentsize < 1)
241 node_remove(list, node); 250 node_remove(list, node);
251 else
252 add_node(node, list->ui_data);
242 } 253 }
243 } 254 }
244 255
245 static void 256 static void
246 new_list(PurpleBuddyList *list) 257 new_list(PurpleBuddyList *list)
1042 finch_blist_toggle_tag_buddy(PurpleBlistNode *node) 1053 finch_blist_toggle_tag_buddy(PurpleBlistNode *node)
1043 { 1054 {
1044 GList *iter; 1055 GList *iter;
1045 if (node == NULL) 1056 if (node == NULL)
1046 return; 1057 return;
1047 if (PURPLE_BLIST_NODE_IS_CHAT(node) || PURPLE_BLIST_NODE_IS_GROUP(node))
1048 return;
1049 if (ggblist->tagged && (iter = g_list_find(ggblist->tagged, node)) != NULL) { 1058 if (ggblist->tagged && (iter = g_list_find(ggblist->tagged, node)) != NULL) {
1050 ggblist->tagged = g_list_delete_link(ggblist->tagged, iter); 1059 ggblist->tagged = g_list_delete_link(ggblist->tagged, iter);
1051 } else { 1060 } else {
1052 ggblist->tagged = g_list_prepend(ggblist->tagged, node); 1061 ggblist->tagged = g_list_prepend(ggblist->tagged, node);
1053 } 1062 }
1054 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) 1063 if (PURPLE_BLIST_NODE_IS_CONTACT(node))
1055 node = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact*)node); 1064 node = (PurpleBlistNode*)purple_contact_get_priority_buddy((PurpleContact*)node);
1056 update_buddy_display((PurpleBuddy*)node, ggblist); 1065 if (PURPLE_BLIST_NODE_IS_BUDDY(node))
1066 update_buddy_display((PurpleBuddy*)node, ggblist);
1067 else
1068 update_node_display(node, ggblist);
1057 } 1069 }
1058 1070
1059 static void 1071 static void
1060 finch_blist_place_tagged(PurpleBlistNode *target) 1072 finch_blist_place_tagged(PurpleBlistNode *target)
1061 { 1073 {
1063 PurpleContact *tc = NULL; 1075 PurpleContact *tc = NULL;
1064 1076
1065 if (target == NULL) 1077 if (target == NULL)
1066 return; 1078 return;
1067 1079
1068 /* This target resolution probably needs more clarification; for
1069 * example, if I tag a buddy in a contact, then place on
1070 * another buddy in the same contact, I probably intend to
1071 * place the tagged buddy immediately after (before?) the
1072 * target buddy -- this will simply move the tagged buddy
1073 * within the same contact without reference to position. */
1074 if (PURPLE_BLIST_NODE_IS_GROUP(target)) 1080 if (PURPLE_BLIST_NODE_IS_GROUP(target))
1075 tg = (PurpleGroup*)target; 1081 tg = (PurpleGroup*)target;
1076 else if (PURPLE_BLIST_NODE_IS_CONTACT(target)) 1082 else if (PURPLE_BLIST_NODE_IS_BUDDY(target)) {
1077 tc = (PurpleContact*)target;
1078 else /* Buddy or Chat */
1079 tc = (PurpleContact*)target->parent; 1083 tc = (PurpleContact*)target->parent;
1084 tg = (PurpleGroup*)target->parent->parent;
1085 } else {
1086 if (PURPLE_BLIST_NODE_IS_CONTACT(target))
1087 tc = (PurpleContact*)target;
1088 tg = (PurpleGroup*)target->parent;
1089 }
1080 1090
1081 if (ggblist->tagged) { 1091 if (ggblist->tagged) {
1082 GList *list = ggblist->tagged; 1092 GList *list = ggblist->tagged;
1083 ggblist->tagged = NULL; 1093 ggblist->tagged = NULL;
1084
1085 while (list) { 1094 while (list) {
1086 PurpleBlistNode *node = list->data; 1095 PurpleBlistNode *node = list->data;
1087 list = g_list_delete_link(list, list); 1096 list = g_list_delete_link(list, list);
1088 if (tg) { 1097
1089 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) 1098 if (PURPLE_BLIST_NODE_IS_GROUP(node)) {
1099 update_node_display(node, ggblist);
1100 /* Add the group after the current group */
1101 purple_blist_add_group((PurpleGroup*)node, (PurpleBlistNode*)tg);
1102 } else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
1103 update_buddy_display(purple_contact_get_priority_buddy((PurpleContact*)node), ggblist);
1104 if ((PurpleBlistNode*)tg == target) {
1105 /* The target is a group, just add the contact to the group. */
1090 purple_blist_add_contact((PurpleContact*)node, tg, NULL); 1106 purple_blist_add_contact((PurpleContact*)node, tg, NULL);
1107 } else if (tc) {
1108 /* The target is either a buddy, or a contact. Merge with that contact. */
1109 purple_blist_merge_contact((PurpleContact*)node, (PurpleBlistNode*)tc);
1110 } else {
1111 /* The target is a chat. Add the contact to the group after this chat. */
1112 purple_blist_add_contact((PurpleContact*)node, NULL, target);
1113 }
1114 } else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
1115 update_buddy_display((PurpleBuddy*)node, ggblist);
1116 if ((PurpleBlistNode*)tg == target) {
1117 /* The target is a group. Add this buddy in a new contact under this group. */
1118 purple_blist_add_buddy((PurpleBuddy*)node, NULL, tg, NULL);
1119 } else if (PURPLE_BLIST_NODE_IS_CONTACT(target)) {
1120 /* Add to the contact. */
1121 purple_blist_add_buddy((PurpleBuddy*)node, tc, NULL, NULL);
1122 } else if (PURPLE_BLIST_NODE_IS_BUDDY(target)) {
1123 /* Add to the contact after the selected buddy. */
1124 purple_blist_add_buddy((PurpleBuddy*)node, NULL, NULL, target);
1125 } else if (PURPLE_BLIST_NODE_IS_CHAT(target)) {
1126 /* Add to the selected chat's group. */
1127 purple_blist_add_buddy((PurpleBuddy*)node, NULL, tg, NULL);
1128 }
1129 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
1130 update_node_display(node, ggblist);
1131 if ((PurpleBlistNode*)tg == target)
1132 purple_blist_add_chat((PurpleChat*)node, tg, NULL);
1091 else 1133 else
1092 purple_blist_add_buddy((PurpleBuddy*)node, NULL, tg, NULL); 1134 purple_blist_add_chat((PurpleChat*)node, NULL, target);
1093 } else {
1094 if (PURPLE_BLIST_NODE_IS_BUDDY(node))
1095 purple_blist_add_buddy((PurpleBuddy*)node, tc,
1096 purple_buddy_get_group(purple_contact_get_priority_buddy(tc)), NULL);
1097 else if (PURPLE_BLIST_NODE_IS_CONTACT(node))
1098 purple_blist_merge_contact((PurpleContact*)node, target);
1099 } 1135 }
1100 } 1136 }
1101 } 1137 }
1102 } 1138 }
1103 1139
1417 1453
1418 return TRUE; 1454 return TRUE;
1419 } 1455 }
1420 1456
1421 static void 1457 static void
1458 update_node_display(PurpleBlistNode *node, FinchBlist *ggblist)
1459 {
1460 GntTextFormatFlags flag = 0;
1461 if (ggblist->tagged && g_list_find(ggblist->tagged, node))
1462 flag |= GNT_TEXT_FLAG_BOLD;
1463 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), node, flag);
1464 }
1465
1466 static void
1422 update_buddy_display(PurpleBuddy *buddy, FinchBlist *ggblist) 1467 update_buddy_display(PurpleBuddy *buddy, FinchBlist *ggblist)
1423 { 1468 {
1424 PurpleContact *contact; 1469 PurpleContact *contact;
1425 GntTextFormatFlags bflag = 0, cflag = 0; 1470 GntTextFormatFlags bflag = 0, cflag = 0;
1426 1471
1437 if (ggblist->tnode == (PurpleBlistNode*)buddy) 1482 if (ggblist->tnode == (PurpleBlistNode*)buddy)
1438 draw_tooltip(ggblist); 1483 draw_tooltip(ggblist);
1439 1484
1440 if (purple_presence_is_idle(purple_buddy_get_presence(buddy))) { 1485 if (purple_presence_is_idle(purple_buddy_get_presence(buddy))) {
1441 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag | GNT_TEXT_FLAG_DIM); 1486 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag | GNT_TEXT_FLAG_DIM);
1442 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag | GNT_TEXT_FLAG_DIM); 1487 if (buddy == purple_contact_get_priority_buddy(contact))
1488 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag | GNT_TEXT_FLAG_DIM);
1489 else
1490 update_buddy_display(purple_contact_get_priority_buddy(contact), ggblist);
1443 } else { 1491 } else {
1444 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag); 1492 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag);
1445 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag); 1493 if (buddy == purple_contact_get_priority_buddy(contact))
1494 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag);
1495 else
1496 update_buddy_display(purple_contact_get_priority_buddy(contact), ggblist);
1446 } 1497 }
1447 } 1498 }
1448 1499
1449 static void 1500 static void
1450 buddy_status_changed(PurpleBuddy *buddy, PurpleStatus *old, PurpleStatus *now, FinchBlist *ggblist) 1501 buddy_status_changed(PurpleBuddy *buddy, PurpleStatus *old, PurpleStatus *now, FinchBlist *ggblist)
1888 if (ret != 0) 1939 if (ret != 0)
1889 return ret; 1940 return ret;
1890 break; 1941 break;
1891 default: 1942 default:
1892 return blist_node_compare_position(n1, n2); 1943 return blist_node_compare_position(n1, n2);
1893 break;
1894 } 1944 }
1895 ret = blist_node_compare_text(n1, n2); 1945 ret = blist_node_compare_text(n1, n2);
1896 return ret; 1946 return ret;
1897 } 1947 }
1898 1948