comparison console/gntblist.c @ 14977:e601bc7880a6

[gaim-migrate @ 17756] Make it easy to move buddies around. Press 't' in the buddylist to tag/untag buddies/contacts (more than one if necessary). Then select the target contact or group and press 'a' to attach the tagged nodes. This should also fix LSchiere's earlier crash, if the bug I thought I was seeing. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Thu, 16 Nov 2006 00:27:30 +0000
parents ef80d4c30a90
children fb98e9c45607
comparison
equal deleted inserted replaced
14976:1c0772f7260b 14977:e601bc7880a6
59 GntWidget *window; 59 GntWidget *window;
60 GntWidget *tree; 60 GntWidget *tree;
61 61
62 GntWidget *tooltip; 62 GntWidget *tooltip;
63 GaimBlistNode *tnode; /* Who is the tooltip being displayed for? */ 63 GaimBlistNode *tnode; /* Who is the tooltip being displayed for? */
64 GaimBuddy *tagged; 64 GList *tagged; /* A list of tagged blistnodes */
65 65
66 GntWidget *context; 66 GntWidget *context;
67 GaimBlistNode *cnode; 67 GaimBlistNode *cnode;
68 68
69 /* XXX: I am KISSing */ 69 /* XXX: I am KISSing */
106 static gboolean remove_typing_cb(gpointer null); 106 static gboolean remove_typing_cb(gpointer null);
107 static void remove_peripherals(GGBlist *ggblist); 107 static void remove_peripherals(GGBlist *ggblist);
108 static const char * get_display_name(GaimBlistNode *node); 108 static const char * get_display_name(GaimBlistNode *node);
109 static void savedstatus_changed(GaimSavedStatus *now, GaimSavedStatus *old); 109 static void savedstatus_changed(GaimSavedStatus *now, GaimSavedStatus *old);
110 static void blist_show(GaimBuddyList *list); 110 static void blist_show(GaimBuddyList *list);
111 static void update_buddy_display(GaimBuddy *buddy, GGBlist *ggblist);
111 112
112 /* Sort functions */ 113 /* Sort functions */
113 static int blist_node_compare_text(GaimBlistNode *n1, GaimBlistNode *n2); 114 static int blist_node_compare_text(GaimBlistNode *n1, GaimBlistNode *n2);
114 static int blist_node_compare_status(GaimBlistNode *n1, GaimBlistNode *n2); 115 static int blist_node_compare_status(GaimBlistNode *n1, GaimBlistNode *n2);
115 static int blist_node_compare_log(GaimBlistNode *n1, GaimBlistNode *n2); 116 static int blist_node_compare_log(GaimBlistNode *n1, GaimBlistNode *n2);
172 if (ggblist == NULL || node->ui_data == NULL) 173 if (ggblist == NULL || node->ui_data == NULL)
173 return; 174 return;
174 175
175 gnt_tree_remove(GNT_TREE(ggblist->tree), node); 176 gnt_tree_remove(GNT_TREE(ggblist->tree), node);
176 node->ui_data = NULL; 177 node->ui_data = NULL;
178 if (ggblist->tagged)
179 ggblist->tagged = g_list_remove(ggblist->tagged, node);
177 180
178 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { 181 if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
179 GaimContact *contact = (GaimContact*)node->parent; 182 GaimContact *contact = (GaimContact*)node->parent;
180 if ((!gaim_prefs_get_bool(PREF_ROOT "/showoffline") && !is_contact_online(contact)) || 183 if ((!gaim_prefs_get_bool(PREF_ROOT "/showoffline") && !is_contact_online(contact)) ||
181 contact->currentsize < 1) 184 contact->currentsize < 1)
183 } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) { 186 } else if (GAIM_BLIST_NODE_IS_CONTACT(node)) {
184 GaimGroup *group = (GaimGroup*)node->parent; 187 GaimGroup *group = (GaimGroup*)node->parent;
185 if ((!gaim_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) || 188 if ((!gaim_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) ||
186 group->currentsize < 1) 189 group->currentsize < 1)
187 node_remove(list, node->parent); 190 node_remove(list, node->parent);
191 for (node = node->child; node; node = node->next)
192 node->ui_data = NULL;
188 } 193 }
189 194
190 draw_tooltip(ggblist); 195 draw_tooltip(ggblist);
191 } 196 }
192 197
996 _("Cancel"), NULL); 1001 _("Cancel"), NULL);
997 g_free(primary); 1002 g_free(primary);
998 } 1003 }
999 1004
1000 static void 1005 static void
1001 gg_blist_tag_buddy(GaimBlistNode *node) 1006 gg_blist_toggle_tag_buddy(GaimBlistNode *node)
1002 { 1007 {
1003 ggblist->tagged = (GaimBuddy *)node; 1008 GList *iter;
1009 if (ggblist->tagged && (iter = g_list_find(ggblist->tagged, node)) != NULL) {
1010 ggblist->tagged = g_list_delete_link(ggblist->tagged, iter);
1011 } else {
1012 ggblist->tagged = g_list_prepend(ggblist->tagged, node);
1013 }
1014 if (GAIM_BLIST_NODE_IS_CONTACT(node))
1015 node = (GaimBlistNode*)gaim_contact_get_priority_buddy((GaimContact*)node);
1016 update_buddy_display((GaimBuddy*)node, ggblist);
1004 gaim_debug_info("blist", "Tagged buddy\n"); 1017 gaim_debug_info("blist", "Tagged buddy\n");
1005 } 1018 }
1006 1019
1007 static void 1020 static void
1008 gg_blist_place_tagged(GaimBlistNode *node) 1021 gg_blist_place_tagged(GaimBlistNode *target)
1009 { 1022 {
1010 if (GAIM_BLIST_NODE_IS_GROUP(node)) { 1023 GaimGroup *tg = NULL;
1011 gaim_blist_add_buddy(ggblist->tagged, NULL, (GaimGroup *)node, NULL); 1024 GaimContact *tc = NULL;
1012 } else { 1025
1013 GaimContact *contact = (GaimContact *)node; 1026 if (GAIM_BLIST_NODE_IS_GROUP(target))
1014 gaim_blist_add_buddy(ggblist->tagged, contact, 1027 tg = (GaimGroup*)target;
1015 gaim_buddy_get_group(gaim_contact_get_priority_buddy(contact)), NULL); 1028 else
1016 } 1029 tc = (GaimContact*)target;
1017 ggblist->tagged = NULL; 1030
1031 if (ggblist->tagged) {
1032 GList *list = ggblist->tagged;
1033 ggblist->tagged = NULL;
1034
1035 while (list) {
1036 GaimBlistNode *node = list->data;
1037 list = g_list_delete_link(list, list);
1038 if (tg) {
1039 if (GAIM_BLIST_NODE_IS_CONTACT(node))
1040 gaim_blist_add_contact((GaimContact*)node, tg, NULL);
1041 else
1042 gaim_blist_add_buddy((GaimBuddy*)node, NULL, tg, NULL);
1043 } else {
1044 if (GAIM_BLIST_NODE_IS_BUDDY(node))
1045 gaim_blist_add_buddy((GaimBuddy*)node, tc,
1046 gaim_buddy_get_group(gaim_contact_get_priority_buddy(tc)), NULL);
1047 else if (GAIM_BLIST_NODE_IS_CONTACT(node))
1048 gaim_blist_merge_contact((GaimContact*)node, target);
1049 }
1050 }
1051 }
1018 gaim_debug_info("blist", "Placed buddy\n"); 1052 gaim_debug_info("blist", "Placed buddy\n");
1019 } 1053 }
1020 1054
1021 static void 1055 static void
1022 context_menu_destroyed(GntWidget *widget, GGBlist *ggblist) 1056 context_menu_destroyed(GntWidget *widget, GGBlist *ggblist)
1072 if (node) { 1106 if (node) {
1073 add_custom_action(GNT_MENU(context), _("Rename"), 1107 add_custom_action(GNT_MENU(context), _("Rename"),
1074 GAIM_CALLBACK(gg_blist_rename_node_cb), node); 1108 GAIM_CALLBACK(gg_blist_rename_node_cb), node);
1075 add_custom_action(GNT_MENU(context), _("Remove"), 1109 add_custom_action(GNT_MENU(context), _("Remove"),
1076 GAIM_CALLBACK(gg_blist_remove_node_cb), node); 1110 GAIM_CALLBACK(gg_blist_remove_node_cb), node);
1111
1077 if (ggblist->tagged && (GAIM_BLIST_NODE_IS_CONTACT(node) 1112 if (ggblist->tagged && (GAIM_BLIST_NODE_IS_CONTACT(node)
1078 || GAIM_BLIST_NODE_IS_GROUP(node))) { 1113 || GAIM_BLIST_NODE_IS_GROUP(node))) {
1079 add_custom_action(GNT_MENU(context), _("Place tagged"), 1114 add_custom_action(GNT_MENU(context), _("Place tagged"),
1080 GAIM_CALLBACK(gg_blist_place_tagged), node); 1115 GAIM_CALLBACK(gg_blist_place_tagged), node);
1081 } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) { 1116 }
1082 add_custom_action(GNT_MENU(context), _("Tag"), 1117
1083 GAIM_CALLBACK(gg_blist_tag_buddy), node); 1118 if (GAIM_BLIST_NODE_IS_BUDDY(node) || GAIM_BLIST_NODE_IS_CONTACT(node)) {
1119 add_custom_action(GNT_MENU(context), _("Toggle Tag"),
1120 GAIM_CALLBACK(gg_blist_toggle_tag_buddy), node);
1084 } 1121 }
1085 } 1122 }
1086 1123
1087 /* Set the position for the popup */ 1124 /* Set the position for the popup */
1088 gnt_widget_get_position(GNT_WIDGET(tree), &x, &y); 1125 gnt_widget_get_position(GNT_WIDGET(tree), &x, &y);
1283 /* When an account has signed off, it removes one buddy at a time. 1320 /* When an account has signed off, it removes one buddy at a time.
1284 * Drawing the tooltip after removing each buddy is expensive. On 1321 * Drawing the tooltip after removing each buddy is expensive. On
1285 * top of that, if the selected buddy belongs to the disconnected 1322 * top of that, if the selected buddy belongs to the disconnected
1286 * account, then retreiving the tooltip for that causes crash. So 1323 * account, then retreiving the tooltip for that causes crash. So
1287 * let's make sure we wait for all the buddies to be removed first.*/ 1324 * let's make sure we wait for all the buddies to be removed first.*/
1288 int id = g_timeout_add(0, draw_tooltip_real, ggblist); 1325 int id = g_timeout_add(0, (GSourceFunc)draw_tooltip_real, ggblist);
1289 g_object_set_data_full(G_OBJECT(ggblist->window), "draw_tooltip_calback", 1326 g_object_set_data_full(G_OBJECT(ggblist->window), "draw_tooltip_calback",
1290 GINT_TO_POINTER(id), (GDestroyNotify)g_source_remove); 1327 GINT_TO_POINTER(id), (GDestroyNotify)g_source_remove);
1291 } 1328 }
1292 1329
1293 static void 1330 static void
1304 } 1341 }
1305 1342
1306 static gboolean 1343 static gboolean
1307 key_pressed(GntWidget *widget, const char *text, GGBlist *ggblist) 1344 key_pressed(GntWidget *widget, const char *text, GGBlist *ggblist)
1308 { 1345 {
1309 gboolean stop = FALSE, ret = FALSE; 1346 if (text[0] == 27 && text[1] == 0) {
1310 if (text[0] == 27 && text[1] == 0)
1311 {
1312 /* Escape was pressed */ 1347 /* Escape was pressed */
1313 remove_peripherals(ggblist); 1348 remove_peripherals(ggblist);
1314 stop = TRUE; 1349 } else if (strcmp(text, GNT_KEY_CTRL_O) == 0) {
1315 ret = TRUE;
1316 }
1317
1318 if (strcmp(text, GNT_KEY_CTRL_O) == 0)
1319 {
1320 gaim_prefs_set_bool(PREF_ROOT "/showoffline", 1350 gaim_prefs_set_bool(PREF_ROOT "/showoffline",
1321 !gaim_prefs_get_bool(PREF_ROOT "/showoffline")); 1351 !gaim_prefs_get_bool(PREF_ROOT "/showoffline"));
1322 ret = TRUE; 1352 } else if (strcmp(text, "t") == 0) {
1323 stop = TRUE; 1353 gg_blist_toggle_tag_buddy(gnt_tree_get_selection_data(GNT_TREE(ggblist->tree)));
1324 } 1354 } else if (strcmp(text, "a") == 0) {
1325 1355 gg_blist_place_tagged(gnt_tree_get_selection_data(GNT_TREE(ggblist->tree)));
1326 if (stop) 1356 } else
1327 g_signal_stop_emission_by_name(G_OBJECT(widget), "key_pressed"); 1357 return FALSE;
1328 1358
1329 return ret; 1359 return TRUE;
1330 } 1360 }
1331 1361
1332 static void 1362 static void
1333 update_buddy_display(GaimBuddy *buddy, GGBlist *ggblist) 1363 update_buddy_display(GaimBuddy *buddy, GGBlist *ggblist)
1334 { 1364 {
1335 GaimContact *contact; 1365 GaimContact *contact;
1366 GntTextFormatFlags bflag = 0, cflag = 0;
1336 1367
1337 contact = gaim_buddy_get_contact(buddy); 1368 contact = gaim_buddy_get_contact(buddy);
1338 1369
1370 gaim_debug_fatal("sadrul", "updating display for %s\n", gaim_buddy_get_name(buddy));
1371 g_printerr("sadrul: updating display for %s\n", gaim_buddy_get_name(buddy));
1372
1339 gnt_tree_change_text(GNT_TREE(ggblist->tree), buddy, 0, get_display_name((GaimBlistNode*)buddy)); 1373 gnt_tree_change_text(GNT_TREE(ggblist->tree), buddy, 0, get_display_name((GaimBlistNode*)buddy));
1340 gnt_tree_change_text(GNT_TREE(ggblist->tree), contact, 0, get_display_name((GaimBlistNode*)contact)); 1374 gnt_tree_change_text(GNT_TREE(ggblist->tree), contact, 0, get_display_name((GaimBlistNode*)contact));
1341 1375
1376 if (ggblist->tagged && g_list_find(ggblist->tagged, buddy))
1377 bflag |= GNT_TEXT_FLAG_BOLD;
1378 if (ggblist->tagged && g_list_find(ggblist->tagged, contact))
1379 cflag |= GNT_TEXT_FLAG_BOLD;
1380
1342 if (ggblist->tnode == (GaimBlistNode*)buddy) 1381 if (ggblist->tnode == (GaimBlistNode*)buddy)
1343 draw_tooltip(ggblist); 1382 draw_tooltip(ggblist);
1344 1383
1345 if (gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) { 1384 if (gaim_presence_is_idle(gaim_buddy_get_presence(buddy))) {
1346 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, GNT_TEXT_FLAG_DIM); 1385 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag | GNT_TEXT_FLAG_DIM);
1347 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, GNT_TEXT_FLAG_DIM); 1386 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag | GNT_TEXT_FLAG_DIM);
1348 } else { 1387 } else {
1349 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, 0); 1388 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), buddy, bflag);
1350 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, 0); 1389 gnt_tree_set_row_flags(GNT_TREE(ggblist->tree), contact, cflag);
1351 } 1390 }
1352 } 1391 }
1353 1392
1354 static void 1393 static void
1355 buddy_status_changed(GaimBuddy *buddy, GaimStatus *old, GaimStatus *now, GGBlist *ggblist) 1394 buddy_status_changed(GaimBuddy *buddy, GaimStatus *old, GaimStatus *now, GGBlist *ggblist)