pidgin/gtkblist.c

changeset 20752
22ffec5874b4
parent 20747
c7494ef1530d
child 20879
157cd6ca3ab6
child 21203
182f920f98a0
equal deleted inserted replaced
20300:30f07afd658e 20752:22ffec5874b4
86 GtkWidget *account_menu; 86 GtkWidget *account_menu;
87 GtkWidget *alias_entry; 87 GtkWidget *alias_entry;
88 GtkWidget *group_combo; 88 GtkWidget *group_combo;
89 GtkWidget *entries_box; 89 GtkWidget *entries_box;
90 GtkSizeGroup *sg; 90 GtkSizeGroup *sg;
91 GtkWidget *autojoin;
92 GtkWidget *persistent;
91 93
92 GList *entries; 94 GList *entries;
93 95
94 } PidginAddChatData; 96 } PidginAddChatData;
95 97
136 static const char *item_factory_translate_func (const char *path, gpointer func_data); 138 static const char *item_factory_translate_func (const char *path, gpointer func_data);
137 static gboolean get_iter_from_node(PurpleBlistNode *node, GtkTreeIter *iter); 139 static gboolean get_iter_from_node(PurpleBlistNode *node, GtkTreeIter *iter);
138 static void redo_buddy_list(PurpleBuddyList *list, gboolean remove, gboolean rerender); 140 static void redo_buddy_list(PurpleBuddyList *list, gboolean remove, gboolean rerender);
139 static void pidgin_blist_collapse_contact_cb(GtkWidget *w, PurpleBlistNode *node); 141 static void pidgin_blist_collapse_contact_cb(GtkWidget *w, PurpleBlistNode *node);
140 static char *pidgin_get_group_title(PurpleBlistNode *gnode, gboolean expanded); 142 static char *pidgin_get_group_title(PurpleBlistNode *gnode, gboolean expanded);
141 143 static void pidgin_blist_expand_contact_cb(GtkWidget *w, PurpleBlistNode *node);
142 struct _pidgin_blist_node { 144
145 typedef enum {
146 PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE = 1 << 0, /* Whether there's pending message in a conversation */
147 } PidginBlistNodeFlags;
148
149 typedef struct _pidgin_blist_node {
143 GtkTreeRowReference *row; 150 GtkTreeRowReference *row;
144 gboolean contact_expanded; 151 gboolean contact_expanded;
145 gboolean recent_signonoff; 152 gboolean recent_signonoff;
146 gint recent_signonoff_timer; 153 gint recent_signonoff_timer;
147 }; 154 struct {
155 PurpleConversation *conv;
156 time_t last_message; /* timestamp for last displayed message */
157 PidginBlistNodeFlags flags;
158 } conv;
159 } PidginBlistNode;
148 160
149 static char dim_grey_string[8] = ""; 161 static char dim_grey_string[8] = "";
150 static char *dim_grey() 162 static char *dim_grey()
151 { 163 {
152 if (!gtkblist) 164 if (!gtkblist)
304 static void gtk_blist_menu_send_file_cb(GtkWidget *w, PurpleBuddy *b) 316 static void gtk_blist_menu_send_file_cb(GtkWidget *w, PurpleBuddy *b)
305 { 317 {
306 serv_send_file(b->account->gc, b->name, NULL); 318 serv_send_file(b->account->gc, b->name, NULL);
307 } 319 }
308 320
321 static void gtk_blist_menu_move_to_cb(GtkWidget *w, PurpleBlistNode *node)
322 {
323 PurpleGroup *group = g_object_get_data(G_OBJECT(w), "groupnode");
324 purple_blist_add_contact((PurpleContact *)node, group, NULL);
325
326 }
327
309 static void gtk_blist_menu_autojoin_cb(GtkWidget *w, PurpleChat *chat) 328 static void gtk_blist_menu_autojoin_cb(GtkWidget *w, PurpleChat *chat)
310 { 329 {
311 purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-autojoin", 330 purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-autojoin",
312 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w))); 331 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)));
332 }
333
334 static void gtk_blist_menu_persistent_cb(GtkWidget *w, PurpleChat *chat)
335 {
336 purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-persistent",
337 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)));
338 }
339
340 static PurpleConversation *
341 find_conversation_with_buddy(PurpleBuddy *buddy)
342 {
343 PidginBlistNode *ui = buddy->node.ui_data;
344 if (ui)
345 return ui->conv.conv;
346 return purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,
347 purple_buddy_get_name(buddy),
348 purple_buddy_get_account(buddy));
313 } 349 }
314 350
315 static void gtk_blist_join_chat(PurpleChat *chat) 351 static void gtk_blist_join_chat(PurpleChat *chat)
316 { 352 {
317 PurpleConversation *conv; 353 PurpleConversation *conv;
393 } 429 }
394 editing_blist = TRUE; 430 editing_blist = TRUE;
395 } 431 }
396 #endif 432 #endif
397 433
434 static void
435 gtk_blist_do_personize(GList *merges)
436 {
437 PurpleBlistNode *contact = NULL;
438 int max = 0;
439 GList *tmp;
440
441 /* First, we find the contact to merge the rest of the buddies into.
442 * This will be the contact with the most buddies in it; ties are broken
443 * by which contact is higher in the list
444 */
445 for (tmp = merges; tmp; tmp = tmp->next) {
446 PurpleBlistNode *node = tmp->data;
447 PurpleBlistNode *b;
448 int i = 0;
449
450 if (node->type == PURPLE_BLIST_BUDDY_NODE)
451 node = node->parent;
452
453 if (node->type != PURPLE_BLIST_CONTACT_NODE)
454 continue;
455
456
457 for (b = node->child; b; b = b->next)
458 i++;
459 if (i > max) {
460 contact = node;
461 max = i;
462 }
463 }
464
465 if (contact == NULL)
466 return;
467
468 /* Merge all those buddies into this contact */
469 for (tmp = merges; tmp; tmp = tmp->next) {
470 PurpleBlistNode *node = tmp->data;
471 if (node->type == PURPLE_BLIST_BUDDY_NODE)
472 node = node->parent;
473
474 if (node == contact)
475 continue;
476
477 purple_blist_merge_contact((PurpleContact *)node, contact);
478 }
479
480 /* And show the expanded contact, so the people know what's going on */
481 pidgin_blist_expand_contact_cb(NULL, contact);
482 g_list_free(merges);
483 }
484
485 static void
486 gtk_blist_auto_personize(PurpleBlistNode *group, const char *alias)
487 {
488 PurpleBlistNode *contact;
489 PurpleBlistNode *buddy;
490 GList *merges = NULL;
491 int i = 0;
492 char *a = g_utf8_casefold(alias, -1);
493
494 for (contact = group->child; contact; contact = contact->next) {
495 char *node_alias;
496 if (contact->type != PURPLE_BLIST_CONTACT_NODE)
497 continue;
498
499 node_alias = g_utf8_casefold(purple_contact_get_alias((PurpleContact *)contact), -1);
500 if (node_alias && !g_utf8_collate(node_alias, a)) {
501 merges = g_list_append(merges, contact);
502 i++;
503 g_free(node_alias);
504 continue;
505 }
506 g_free(node_alias);
507
508 for (buddy = contact->child; buddy; buddy = buddy->next) {
509 if (buddy->type != PURPLE_BLIST_BUDDY_NODE)
510 continue;
511
512 node_alias = g_utf8_casefold(purple_buddy_get_alias((PurpleBuddy *)buddy), -1);
513 if (node_alias && !g_utf8_collate(node_alias, a)) {
514 merges = g_list_append(merges, buddy);
515 i++;
516 }
517 g_free(node_alias);
518 }
519 }
520 g_free(a);
521
522 if (i > 1)
523 {
524 char *msg = g_strdup_printf(ngettext("You have %d contact named %s. Would you like to merge them?", "You currently have %d contacts named %s. Would you like to merge them?", i), i, alias);
525 purple_request_action(NULL, NULL, msg, _("Merging these contacts will cause them to share a single entry on the buddy list and use a single conversation window. "
526 "You can separate them again by choosing 'Expand' from the contact's context menu"), 0, NULL, NULL, NULL,
527 merges, 2, _("_Merge"), PURPLE_CALLBACK(gtk_blist_do_personize), _("_Cancel"), PURPLE_CALLBACK(g_list_free));
528 g_free(msg);
529 } else
530 g_list_free(merges);
531 }
532
398 static void gtk_blist_renderer_edited_cb(GtkCellRendererText *text_rend, char *arg1, 533 static void gtk_blist_renderer_edited_cb(GtkCellRendererText *text_rend, char *arg1,
399 char *arg2, PurpleBuddyList *list) 534 char *arg2, PurpleBuddyList *list)
400 { 535 {
401 GtkTreeIter iter; 536 GtkTreeIter iter;
402 GtkTreePath *path; 537 GtkTreePath *path;
419 case PURPLE_BLIST_CONTACT_NODE: 554 case PURPLE_BLIST_CONTACT_NODE:
420 { 555 {
421 PurpleContact *contact = (PurpleContact *)node; 556 PurpleContact *contact = (PurpleContact *)node;
422 struct _pidgin_blist_node *gtknode = (struct _pidgin_blist_node *)node->ui_data; 557 struct _pidgin_blist_node *gtknode = (struct _pidgin_blist_node *)node->ui_data;
423 558
424 if (contact->alias || gtknode->contact_expanded) 559 if (contact->alias || gtknode->contact_expanded) {
425 purple_blist_alias_contact(contact, arg2); 560 purple_blist_alias_contact(contact, arg2);
426 else 561 gtk_blist_auto_personize(node->parent, arg2);
427 { 562 } else {
428 PurpleBuddy *buddy = purple_contact_get_priority_buddy(contact); 563 PurpleBuddy *buddy = purple_contact_get_priority_buddy(contact);
429 purple_blist_alias_buddy(buddy, arg2); 564 purple_blist_alias_buddy(buddy, arg2);
430 serv_alias_buddy(buddy); 565 serv_alias_buddy(buddy);
566 gtk_blist_auto_personize(node->parent, arg2);
431 } 567 }
432 } 568 }
433 break; 569 break;
434 570
435 case PURPLE_BLIST_BUDDY_NODE: 571 case PURPLE_BLIST_BUDDY_NODE:
436 purple_blist_alias_buddy((PurpleBuddy*)node, arg2); 572 purple_blist_alias_buddy((PurpleBuddy*)node, arg2);
437 serv_alias_buddy((PurpleBuddy *)node); 573 serv_alias_buddy((PurpleBuddy *)node);
574 gtk_blist_auto_personize(node->parent->parent, arg2);
438 break; 575 break;
439 case PURPLE_BLIST_GROUP_NODE: 576 case PURPLE_BLIST_GROUP_NODE:
440 dest = purple_find_group(arg2); 577 dest = purple_find_group(arg2);
441 if (dest != NULL && strcmp(arg2, ((PurpleGroup*) node)->name)) { 578 if (dest != NULL && strcmp(arg2, ((PurpleGroup*) node)->name)) {
442 pidgin_dialogs_merge_groups((PurpleGroup*) node, arg2); 579 pidgin_dialogs_merge_groups((PurpleGroup*) node, arg2);
521 pidgin_log_show(type, name, account); 658 pidgin_log_show(type, name, account);
522 g_free(name); 659 g_free(name);
523 660
524 pidgin_clear_cursor(gtkblist->window); 661 pidgin_clear_cursor(gtkblist->window);
525 } 662 }
663 }
664
665 static void gtk_blist_menu_showoffline_cb(GtkWidget *w, PurpleBlistNode *node)
666 {
667 if (PURPLE_BLIST_NODE_IS_BUDDY(node))
668 {
669 purple_blist_node_set_bool(node, "show_offline",
670 !purple_blist_node_get_bool(node, "show_offline"));
671 }
672 else if (PURPLE_BLIST_NODE_IS_CONTACT(node))
673 {
674 PurpleBlistNode *bnode;
675 gboolean setting = !purple_blist_node_get_bool(node, "show_offline");
676
677 purple_blist_node_set_bool(node, "show_offline", setting);
678 for (bnode = node->child; bnode != NULL; bnode = bnode->next) {
679 purple_blist_node_set_bool(bnode, "show_offline", setting);
680 }
681 }
682 pidgin_blist_update(purple_get_blist(), node);
526 } 683 }
527 684
528 static void gtk_blist_show_systemlog_cb() 685 static void gtk_blist_show_systemlog_cb()
529 { 686 {
530 pidgin_syslog_show(); 687 pidgin_syslog_show();
1117 pidgin_append_menu_action(menu, act, node); 1274 pidgin_append_menu_action(menu, act, node);
1118 } 1275 }
1119 g_list_free(ll); 1276 g_list_free(ll);
1120 } 1277 }
1121 1278
1279
1280
1281 static void
1282 pidgin_append_blist_node_move_to_menu(GtkWidget *menu, PurpleBlistNode *node)
1283 {
1284 GtkWidget *submenu;
1285 GtkWidget *menuitem;
1286 PurpleBlistNode *group;
1287
1288 menuitem = gtk_menu_item_new_with_label(_("Move to"));
1289 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
1290 gtk_widget_show(menuitem);
1291
1292 submenu = gtk_menu_new();
1293 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
1294
1295 for (group = purple_blist_get_root(); group; group = group->next) {
1296 if (group->type != PURPLE_BLIST_GROUP_NODE)
1297 continue;
1298 if (group == node->parent)
1299 continue;
1300 menuitem = pidgin_new_item_from_stock(submenu, purple_group_get_name((PurpleGroup *)group), NULL,
1301 G_CALLBACK(gtk_blist_menu_move_to_cb), node, 0, 0, NULL);
1302 g_object_set_data(G_OBJECT(menuitem), "groupnode", group);
1303 }
1304 gtk_widget_show_all(submenu);
1305 }
1306
1122 void 1307 void
1123 pidgin_blist_make_buddy_menu(GtkWidget *menu, PurpleBuddy *buddy, gboolean sub) { 1308 pidgin_blist_make_buddy_menu(GtkWidget *menu, PurpleBuddy *buddy, gboolean sub) {
1124 PurplePluginProtocolInfo *prpl_info; 1309 PurplePluginProtocolInfo *prpl_info;
1125 PurpleContact *contact; 1310 PurpleContact *contact;
1311 PurpleBlistNode *node;
1126 gboolean contact_expanded = FALSE; 1312 gboolean contact_expanded = FALSE;
1313 gboolean show_offline = FALSE;
1127 1314
1128 g_return_if_fail(menu); 1315 g_return_if_fail(menu);
1129 g_return_if_fail(buddy); 1316 g_return_if_fail(buddy);
1130 1317
1131 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(buddy->account->gc->prpl); 1318 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(buddy->account->gc->prpl);
1319
1320 node = (PurpleBlistNode*)buddy;
1132 1321
1133 contact = purple_buddy_get_contact(buddy); 1322 contact = purple_buddy_get_contact(buddy);
1134 if (contact) { 1323 if (contact) {
1135 contact_expanded = ((struct _pidgin_blist_node *)(((PurpleBlistNode*)contact)->ui_data))->contact_expanded; 1324 contact_expanded = ((struct _pidgin_blist_node *)(((PurpleBlistNode*)contact)->ui_data))->contact_expanded;
1136 } 1325 }
1143 G_CALLBACK(gtk_blist_menu_im_cb), buddy, 0, 0, NULL); 1332 G_CALLBACK(gtk_blist_menu_im_cb), buddy, 0, 0, NULL);
1144 if (prpl_info && prpl_info->send_file) { 1333 if (prpl_info && prpl_info->send_file) {
1145 if (!prpl_info->can_receive_file || 1334 if (!prpl_info->can_receive_file ||
1146 prpl_info->can_receive_file(buddy->account->gc, buddy->name)) 1335 prpl_info->can_receive_file(buddy->account->gc, buddy->name))
1147 { 1336 {
1148 pidgin_new_item_from_stock(menu, _("_Send File"), 1337 pidgin_new_item_from_stock(menu, _("_Send File..."),
1149 PIDGIN_STOCK_TOOLBAR_SEND_FILE, 1338 PIDGIN_STOCK_TOOLBAR_SEND_FILE,
1150 G_CALLBACK(gtk_blist_menu_send_file_cb), 1339 G_CALLBACK(gtk_blist_menu_send_file_cb),
1151 buddy, 0, 0, NULL); 1340 buddy, 0, 0, NULL);
1152 } 1341 }
1153 } 1342 }
1154 1343
1155 pidgin_new_item_from_stock(menu, _("Add Buddy _Pounce"), NULL, 1344 pidgin_new_item_from_stock(menu, _("Add Buddy _Pounce..."), NULL,
1156 G_CALLBACK(gtk_blist_menu_bp_cb), buddy, 0, 0, NULL); 1345 G_CALLBACK(gtk_blist_menu_bp_cb), buddy, 0, 0, NULL);
1157 1346
1158 if (((PurpleBlistNode*)buddy)->parent && ((PurpleBlistNode*)buddy)->parent->child->next && 1347 if (node->parent && node->parent->child->next &&
1159 !sub && !contact_expanded) { 1348 !sub && !contact_expanded) {
1160 pidgin_new_item_from_stock(menu, _("View _Log"), NULL, 1349 pidgin_new_item_from_stock(menu, _("View _Log"), NULL,
1161 G_CALLBACK(gtk_blist_menu_showlog_cb), 1350 G_CALLBACK(gtk_blist_menu_showlog_cb),
1162 contact, 0, 0, NULL); 1351 contact, 0, 0, NULL);
1163 } else if (!sub) { 1352 } else if (!sub) {
1164 pidgin_new_item_from_stock(menu, _("View _Log"), NULL, 1353 pidgin_new_item_from_stock(menu, _("View _Log"), NULL,
1165 G_CALLBACK(gtk_blist_menu_showlog_cb), buddy, 0, 0, NULL); 1354 G_CALLBACK(gtk_blist_menu_showlog_cb), buddy, 0, 0, NULL);
1166 } 1355 }
1167 1356
1168 1357 if (!(purple_blist_node_get_flags(node) & PURPLE_BLIST_NODE_FLAG_NO_SAVE)) {
1169 pidgin_append_blist_node_proto_menu(menu, buddy->account->gc, 1358 show_offline = purple_blist_node_get_bool(node, "show_offline");
1170 (PurpleBlistNode *)buddy); 1359 pidgin_new_item_from_stock(menu, show_offline ? _("Hide when offline") : _("Show when offline"),
1171 pidgin_append_blist_node_extended_menu(menu, (PurpleBlistNode *)buddy); 1360 NULL, G_CALLBACK(gtk_blist_menu_showoffline_cb), node, 0, 0, NULL);
1172 1361 }
1173 if (((PurpleBlistNode*)buddy)->parent && ((PurpleBlistNode*)buddy)->parent->child->next && 1362
1363 pidgin_append_blist_node_proto_menu(menu, buddy->account->gc, node);
1364 pidgin_append_blist_node_extended_menu(menu, node);
1365
1366 if (!contact_expanded)
1367 pidgin_append_blist_node_move_to_menu(menu, (PurpleBlistNode *)contact);
1368
1369 if (node->parent && node->parent->child->next &&
1174 !sub && !contact_expanded) { 1370 !sub && !contact_expanded) {
1175 pidgin_separator(menu); 1371 pidgin_separator(menu);
1176 pidgin_append_blist_node_privacy_menu(menu, (PurpleBlistNode *)buddy); 1372 pidgin_append_blist_node_privacy_menu(menu, node);
1177 pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS, 1373 pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS,
1178 G_CALLBACK(gtk_blist_menu_alias_cb), 1374 G_CALLBACK(gtk_blist_menu_alias_cb),
1179 contact, 0, 0, NULL); 1375 contact, 0, 0, NULL);
1180 pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, 1376 pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE,
1181 G_CALLBACK(pidgin_blist_remove_cb), 1377 G_CALLBACK(pidgin_blist_remove_cb),
1182 contact, 0, 0, NULL); 1378 contact, 0, 0, NULL);
1183 } else if (!sub || contact_expanded) { 1379 } else if (!sub || contact_expanded) {
1184 pidgin_separator(menu); 1380 pidgin_separator(menu);
1185 pidgin_append_blist_node_privacy_menu(menu, (PurpleBlistNode *)buddy); 1381 pidgin_append_blist_node_privacy_menu(menu, node);
1186 pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS, 1382 pidgin_new_item_from_stock(menu, _("_Alias..."), PIDGIN_STOCK_ALIAS,
1187 G_CALLBACK(gtk_blist_menu_alias_cb), buddy, 0, 0, NULL); 1383 G_CALLBACK(gtk_blist_menu_alias_cb), buddy, 0, 0, NULL);
1188 pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE, 1384 pidgin_new_item_from_stock(menu, _("_Remove"), GTK_STOCK_REMOVE,
1189 G_CALLBACK(pidgin_blist_remove_cb), buddy, 1385 G_CALLBACK(pidgin_blist_remove_cb), buddy,
1190 0, 0, NULL); 1386 0, 0, NULL);
1233 { 1429 {
1234 GtkWidget *menu; 1430 GtkWidget *menu;
1235 GtkWidget *item; 1431 GtkWidget *item;
1236 1432
1237 menu = gtk_menu_new(); 1433 menu = gtk_menu_new();
1238 item = pidgin_new_item_from_stock(menu, _("Add a _Buddy"), GTK_STOCK_ADD, 1434 item = pidgin_new_item_from_stock(menu, _("Add _Buddy..."), GTK_STOCK_ADD,
1239 G_CALLBACK(pidgin_blist_add_buddy_cb), node, 0, 0, NULL); 1435 G_CALLBACK(pidgin_blist_add_buddy_cb), node, 0, 0, NULL);
1240 gtk_widget_set_sensitive(item, purple_connections_get_all() != NULL); 1436 gtk_widget_set_sensitive(item, purple_connections_get_all() != NULL);
1241 item = pidgin_new_item_from_stock(menu, _("Add a C_hat"), GTK_STOCK_ADD, 1437 item = pidgin_new_item_from_stock(menu, _("Add C_hat..."), GTK_STOCK_ADD,
1242 G_CALLBACK(pidgin_blist_add_chat_cb), node, 0, 0, NULL); 1438 G_CALLBACK(pidgin_blist_add_chat_cb), node, 0, 0, NULL);
1243 gtk_widget_set_sensitive(item, pidgin_blist_joinchat_is_showable()); 1439 gtk_widget_set_sensitive(item, pidgin_blist_joinchat_is_showable());
1244 pidgin_new_item_from_stock(menu, _("_Delete Group"), GTK_STOCK_REMOVE, 1440 pidgin_new_item_from_stock(menu, _("_Delete Group"), GTK_STOCK_REMOVE,
1245 G_CALLBACK(pidgin_blist_remove_cb), node, 0, 0, NULL); 1441 G_CALLBACK(pidgin_blist_remove_cb), node, 0, 0, NULL);
1246 pidgin_new_item_from_stock(menu, _("_Rename"), NULL, 1442 pidgin_new_item_from_stock(menu, _("_Rename"), NULL,
1254 1450
1255 static GtkWidget * 1451 static GtkWidget *
1256 create_chat_menu(PurpleBlistNode *node, PurpleChat *c) 1452 create_chat_menu(PurpleBlistNode *node, PurpleChat *c)
1257 { 1453 {
1258 GtkWidget *menu; 1454 GtkWidget *menu;
1259 gboolean autojoin; 1455 gboolean autojoin, persistent;
1260 1456
1261 menu = gtk_menu_new(); 1457 menu = gtk_menu_new();
1262 autojoin = (purple_blist_node_get_bool(node, "gtk-autojoin") || 1458 autojoin = (purple_blist_node_get_bool(node, "gtk-autojoin") ||
1263 (purple_blist_node_get_string(node, "gtk-autojoin") != NULL)); 1459 (purple_blist_node_get_string(node, "gtk-autojoin") != NULL));
1460 persistent = purple_blist_node_get_bool(node, "gtk-persistent");
1264 1461
1265 pidgin_new_item_from_stock(menu, _("_Join"), PIDGIN_STOCK_CHAT, 1462 pidgin_new_item_from_stock(menu, _("_Join"), PIDGIN_STOCK_CHAT,
1266 G_CALLBACK(gtk_blist_menu_join_cb), node, 0, 0, NULL); 1463 G_CALLBACK(gtk_blist_menu_join_cb), node, 0, 0, NULL);
1267 pidgin_new_check_item(menu, _("Auto-Join"), 1464 pidgin_new_check_item(menu, _("Auto-Join"),
1268 G_CALLBACK(gtk_blist_menu_autojoin_cb), node, autojoin); 1465 G_CALLBACK(gtk_blist_menu_autojoin_cb), node, autojoin);
1466 pidgin_new_check_item(menu, _("Persistent"),
1467 G_CALLBACK(gtk_blist_menu_persistent_cb), node, persistent);
1269 pidgin_new_item_from_stock(menu, _("View _Log"), NULL, 1468 pidgin_new_item_from_stock(menu, _("View _Log"), NULL,
1270 G_CALLBACK(gtk_blist_menu_showlog_cb), node, 0, 0, NULL); 1469 G_CALLBACK(gtk_blist_menu_showlog_cb), node, 0, 0, NULL);
1271 1470
1272 pidgin_append_blist_node_proto_menu(menu, c->account->gc, node); 1471 pidgin_append_blist_node_proto_menu(menu, c->account->gc, node);
1273 pidgin_append_blist_node_extended_menu(menu, node); 1472 pidgin_append_blist_node_extended_menu(menu, node);
1305 pidgin_new_item_from_stock(menu, _("_Collapse"), GTK_STOCK_ZOOM_OUT, 1504 pidgin_new_item_from_stock(menu, _("_Collapse"), GTK_STOCK_ZOOM_OUT,
1306 G_CALLBACK(pidgin_blist_collapse_contact_cb), 1505 G_CALLBACK(pidgin_blist_collapse_contact_cb),
1307 node, 0, 0, NULL); 1506 node, 0, 0, NULL);
1308 1507
1309 pidgin_append_blist_node_extended_menu(menu, node); 1508 pidgin_append_blist_node_extended_menu(menu, node);
1310
1311 return menu; 1509 return menu;
1312 } 1510 }
1313 1511
1314 static GtkWidget * 1512 static GtkWidget *
1315 create_buddy_menu(PurpleBlistNode *node, PurpleBuddy *b) 1513 create_buddy_menu(PurpleBlistNode *node, PurpleBuddy *b)
2886 { "/Buddies/sep3", NULL, NULL, 0, "<Separator>", NULL }, 3084 { "/Buddies/sep3", NULL, NULL, 0, "<Separator>", NULL },
2887 { N_("/Buddies/_Quit"), "<CTL>Q", purple_core_quit, 0, "<StockItem>", GTK_STOCK_QUIT }, 3085 { N_("/Buddies/_Quit"), "<CTL>Q", purple_core_quit, 0, "<StockItem>", GTK_STOCK_QUIT },
2888 3086
2889 /* Accounts menu */ 3087 /* Accounts menu */
2890 { N_("/_Accounts"), NULL, NULL, 0, "<Branch>", NULL }, 3088 { N_("/_Accounts"), NULL, NULL, 0, "<Branch>", NULL },
2891 { N_("/Accounts/Add\\/Edit"), "<CTL>A", pidgin_accounts_window_show, 0, "<Item>", NULL }, 3089 { N_("/Accounts/Manage"), "<CTL>A", pidgin_accounts_window_show, 0, "<Item>", NULL },
2892 3090
2893 /* Tools */ 3091 /* Tools */
2894 { N_("/_Tools"), NULL, NULL, 0, "<Branch>", NULL }, 3092 { N_("/_Tools"), NULL, NULL, 0, "<Branch>", NULL },
2895 { N_("/Tools/Buddy _Pounces"), NULL, pidgin_pounces_manager_show, 0, "<Item>", NULL }, 3093 { N_("/Tools/Buddy _Pounces"), NULL, pidgin_pounces_manager_show, 0, "<Item>", NULL },
2896 { N_("/Tools/_Certificates"), NULL, pidgin_certmgr_show, 0, "<Item>", NULL }, 3094 { N_("/Tools/_Certificates"), NULL, pidgin_certmgr_show, 0, "<Item>", NULL },
3143 const char *name = NULL; 3341 const char *name = NULL;
3144 char *filename, *path; 3342 char *filename, *path;
3145 GdkPixbuf *ret; 3343 GdkPixbuf *ret;
3146 PurplePresence *p; 3344 PurplePresence *p;
3147 3345
3148
3149
3150 if(PURPLE_BLIST_NODE_IS_CONTACT(node)) { 3346 if(PURPLE_BLIST_NODE_IS_CONTACT(node)) {
3151 if(!gtknode->contact_expanded) { 3347 if(!gtknode->contact_expanded) {
3152 buddy = purple_contact_get_priority_buddy((PurpleContact*)node); 3348 buddy = purple_contact_get_priority_buddy((PurpleContact*)node);
3153 gtkbuddynode = ((PurpleBlistNode*)buddy)->ui_data; 3349 gtkbuddynode = ((PurpleBlistNode*)buddy)->ui_data;
3154 } 3350 }
3186 ret = gdk_pixbuf_new_from_file(path, NULL); 3382 ret = gdk_pixbuf_new_from_file(path, NULL);
3187 g_free(path); 3383 g_free(path);
3188 return ret; 3384 return ret;
3189 } 3385 }
3190 3386
3387 if (purple_status_get_attr_string(purple_presence_get_active_status(p), PURPLE_TUNE_TITLE)) {
3388 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", "16", "music.png", NULL);
3389 ret = gdk_pixbuf_new_from_file(path, NULL);
3390 g_free(path);
3391 return ret;
3392 }
3393
3191 prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account)); 3394 prpl = purple_find_prpl(purple_account_get_protocol_id(buddy->account));
3192 if (!prpl) 3395 if (!prpl)
3193 return NULL; 3396 return NULL;
3194 3397
3195 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); 3398 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
3259 protoname = prpl_info->list_icon(account, buddy); 3462 protoname = prpl_info->list_icon(account, buddy);
3260 } 3463 }
3261 } 3464 }
3262 3465
3263 if(buddy) { 3466 if(buddy) {
3264 PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, 3467 PurpleConversation *conv = find_conversation_with_buddy(buddy);
3265 purple_buddy_get_name(buddy),
3266 purple_buddy_get_account(buddy));
3267 PurplePresence *p; 3468 PurplePresence *p;
3268 gboolean trans; 3469 gboolean trans;
3269 3470
3270 if(conv != NULL) { 3471 if(conv != NULL) {
3271 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 3472 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
3272 if((gtkconv == NULL || pidgin_conv_is_hidden(gtkconv)) && size == PIDGIN_STATUS_ICON_SMALL) { 3473 if (gtkconv == NULL && size == PIDGIN_STATUS_ICON_SMALL) {
3273 return gtk_widget_render_icon (GTK_WIDGET(gtkblist->treeview), PIDGIN_STOCK_STATUS_MESSAGE, 3474 PidginBlistNode *ui = buddy->node.ui_data;
3274 icon_size, "GtkTreeView"); 3475 if (ui == NULL || (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE))
3476 return gtk_widget_render_icon (GTK_WIDGET(gtkblist->treeview),
3477 PIDGIN_STOCK_STATUS_MESSAGE, icon_size, "GtkTreeView");
3275 } 3478 }
3276 } 3479 }
3277 3480
3278 p = purple_buddy_get_presence(buddy); 3481 p = purple_buddy_get_presence(buddy);
3279 trans = purple_presence_is_idle(p); 3482 trans = purple_presence_is_idle(p);
3325 PurpleContact *contact; 3528 PurpleContact *contact;
3326 PurplePresence *presence; 3529 PurplePresence *presence;
3327 struct _pidgin_blist_node *gtkcontactnode = NULL; 3530 struct _pidgin_blist_node *gtkcontactnode = NULL;
3328 char *idletime = NULL, *statustext = NULL; 3531 char *idletime = NULL, *statustext = NULL;
3329 time_t t; 3532 time_t t;
3330 PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, 3533 PurpleConversation *conv = find_conversation_with_buddy(b);
3331 purple_buddy_get_name(b),
3332 purple_buddy_get_account(b));
3333 PidginConversation *gtkconv;
3334 gboolean hidden_conv = FALSE; 3534 gboolean hidden_conv = FALSE;
3335 3535
3336 if(conv != NULL) { 3536 if (conv != NULL) {
3337 gtkconv = PIDGIN_CONVERSATION(conv); 3537 PidginBlistNode *ui = b->node.ui_data;
3338 if(gtkconv == NULL || pidgin_conv_is_hidden(gtkconv)) { 3538 if (ui) {
3339 hidden_conv = TRUE; 3539 if (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE)
3540 hidden_conv = TRUE;
3541 } else {
3542 if (PIDGIN_CONVERSATION(conv) == NULL)
3543 hidden_conv = TRUE;
3340 } 3544 }
3341 } 3545 }
3342 3546
3343 /* XXX Good luck cleaning up this crap */ 3547 /* XXX Good luck cleaning up this crap */
3344 contact = (PurpleContact*)((PurpleBlistNode*)b)->parent; 3548 contact = (PurpleContact*)((PurpleBlistNode*)b)->parent;
3669 if (menu) { 3873 if (menu) {
3670 gtk_widget_destroy(menu); 3874 gtk_widget_destroy(menu);
3671 menu = NULL; 3875 menu = NULL;
3672 } 3876 }
3673 3877
3674 convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM, PIDGIN_UNSEEN_TEXT, TRUE, 0); 3878 convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_ANY, PIDGIN_UNSEEN_TEXT, TRUE, 0);
3675 if (!convs) 3879 if (!convs)
3676 /* no conversations added, don't show the menu */ 3880 /* no conversations added, don't show the menu */
3677 return; 3881 return;
3678 3882
3679 menu = gtk_menu_new(); 3883 menu = gtk_menu_new();
3725 if (gtkblist->menutrayicon) { 3929 if (gtkblist->menutrayicon) {
3726 gtk_widget_destroy(gtkblist->menutrayicon); 3930 gtk_widget_destroy(gtkblist->menutrayicon);
3727 gtkblist->menutrayicon = NULL; 3931 gtkblist->menutrayicon = NULL;
3728 } 3932 }
3729 3933
3730 convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_IM, PIDGIN_UNSEEN_TEXT, TRUE, 0); 3934 convs = pidgin_conversations_find_unseen_list(PURPLE_CONV_TYPE_ANY, PIDGIN_UNSEEN_TEXT, TRUE, 0);
3731 if (convs) { 3935 if (convs) {
3732 GtkWidget *img = NULL; 3936 GtkWidget *img = NULL;
3733 GString *tooltip_text = NULL; 3937 GString *tooltip_text = NULL;
3734 3938
3735 tooltip_text = g_string_new(""); 3939 tooltip_text = g_string_new("");
3736 l = convs; 3940 l = convs;
3737 while (l != NULL) { 3941 while (l != NULL) {
3738 if (PIDGIN_IS_PIDGIN_CONVERSATION(l->data)) { 3942 int count = GPOINTER_TO_INT(purple_conversation_get_data(l->data, "unseen-count"));
3739 PidginConversation *gtkconv = PIDGIN_CONVERSATION((PurpleConversation *)l->data); 3943 g_string_append_printf(tooltip_text,
3740 3944 ngettext("%d unread message from %s\n", "%d unread messages from %s\n", count),
3741 g_string_append_printf(tooltip_text, 3945 count, purple_conversation_get_name(l->data));
3742 ngettext("%d unread message from %s\n", "%d unread messages from %s\n", gtkconv->unseen_count),
3743 gtkconv->unseen_count,
3744 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)));
3745 }
3746 l = l->next; 3946 l = l->next;
3747 } 3947 }
3748 if(tooltip_text->len > 0) { 3948 if(tooltip_text->len > 0) {
3749 /* get rid of the last newline */ 3949 /* get rid of the last newline */
3750 g_string_truncate(tooltip_text, tooltip_text->len -1); 3950 g_string_truncate(tooltip_text, tooltip_text->len -1);
3766 3966
3767 static void 3967 static void
3768 conversation_deleting_cb(PurpleConversation *conv, PidginBuddyList *gtkblist) 3968 conversation_deleting_cb(PurpleConversation *conv, PidginBuddyList *gtkblist)
3769 { 3969 {
3770 conversation_updated_cb(conv, PURPLE_CONV_UPDATE_UNSEEN, gtkblist); 3970 conversation_updated_cb(conv, PURPLE_CONV_UPDATE_UNSEEN, gtkblist);
3971 }
3972
3973 static void
3974 conversation_deleted_update_ui_cb(PurpleConversation *conv, struct _pidgin_blist_node *ui)
3975 {
3976 if (ui->conv.conv != conv)
3977 return;
3978 ui->conv.conv = NULL;
3979 ui->conv.flags = 0;
3980 ui->conv.last_message = 0;
3981 }
3982
3983 static void
3984 written_msg_update_ui_cb(PurpleAccount *account, const char *who, const char *message,
3985 PurpleConversation *conv, PurpleMessageFlags flag, PurpleBlistNode *node)
3986 {
3987 PidginBlistNode *ui = node->ui_data;
3988 if (ui->conv.conv != conv || PIDGIN_CONVERSATION(conv) ||
3989 !(flag & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)))
3990 return;
3991 ui->conv.flags |= PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE;
3992 ui->conv.last_message = time(NULL); /* XXX: for lack of better data */
3993 pidgin_blist_update(purple_get_blist(), node);
3994 }
3995
3996 static void
3997 displayed_msg_update_ui_cb(PurpleAccount *account, const char *who, const char *message,
3998 PurpleConversation *conv, PurpleMessageFlags flag, PurpleBlistNode *node)
3999 {
4000 PidginBlistNode *ui = node->ui_data;
4001 if (ui->conv.conv != conv)
4002 return;
4003 ui->conv.flags &= ~PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE;
4004 pidgin_blist_update(purple_get_blist(), node);
4005 }
4006
4007 static void
4008 conversation_created_cb(PurpleConversation *conv, PidginBuddyList *gtkblist)
4009 {
4010 switch (conv->type) {
4011 case PURPLE_CONV_TYPE_IM:
4012 {
4013 GSList *buddies = purple_find_buddies(conv->account, conv->name);
4014 while (buddies) {
4015 PurpleBlistNode *buddy = buddies->data;
4016 struct _pidgin_blist_node *ui = buddy->ui_data;
4017 buddies = g_slist_delete_link(buddies, buddies);
4018 if (!ui)
4019 continue;
4020 ui->conv.conv = conv;
4021 ui->conv.flags = 0;
4022 ui->conv.last_message = 0;
4023 purple_signal_connect(purple_conversations_get_handle(), "deleting-conversation",
4024 ui, PURPLE_CALLBACK(conversation_deleted_update_ui_cb), ui);
4025 purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg",
4026 ui, PURPLE_CALLBACK(written_msg_update_ui_cb), buddy);
4027 purple_signal_connect(pidgin_conversations_get_handle(), "displayed-im-msg",
4028 ui, PURPLE_CALLBACK(displayed_msg_update_ui_cb), buddy);
4029 }
4030 }
4031 case PURPLE_CONV_TYPE_CHAT:
4032 {
4033 PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name);
4034 struct _pidgin_blist_node *ui;
4035 if (!chat)
4036 break;
4037 ui = chat->node.ui_data;
4038 if (!ui)
4039 break;
4040 ui->conv.conv = conv;
4041 ui->conv.flags = 0;
4042 ui->conv.last_message = 0;
4043 purple_signal_connect(purple_conversations_get_handle(), "deleting-conversation",
4044 ui, PURPLE_CALLBACK(conversation_deleted_update_ui_cb), ui);
4045 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg",
4046 ui, PURPLE_CALLBACK(written_msg_update_ui_cb), chat);
4047 purple_signal_connect(pidgin_conversations_get_handle(), "displayed-chat-msg",
4048 ui, PURPLE_CALLBACK(displayed_msg_update_ui_cb), chat);
4049 }
4050 default:
4051 break;
4052 }
3771 } 4053 }
3772 4054
3773 /********************************************************************************** 4055 /**********************************************************************************
3774 * Public API Functions * 4056 * Public API Functions *
3775 **********************************************************************************/ 4057 **********************************************************************************/
4332 4614
4333 /* Translators: Please maintain the use of -> and <- to refer to menu heirarchy */ 4615 /* Translators: Please maintain the use of -> and <- to refer to menu heirarchy */
4334 tmp = g_strdup_printf(_("<span weight='bold' size='larger'>Welcome to %s!</span>\n\n" 4616 tmp = g_strdup_printf(_("<span weight='bold' size='larger'>Welcome to %s!</span>\n\n"
4335 4617
4336 "You have no accounts enabled. Enable your IM accounts from the " 4618 "You have no accounts enabled. Enable your IM accounts from the "
4337 "<b>Accounts</b> window at <b>Accounts->Add/Edit</b>. Once you " 4619 "<b>Accounts</b> window at <b>Accounts->Manage</b>. Once you "
4338 "enable accounts, you'll be able to sign on, set your status, " 4620 "enable accounts, you'll be able to sign on, set your status, "
4339 "and talk to your friends."), PIDGIN_NAME); 4621 "and talk to your friends."), PIDGIN_NAME);
4340 pretty = pidgin_make_pretty_arrows(tmp); 4622 pretty = pidgin_make_pretty_arrows(tmp);
4341 g_free(tmp); 4623 g_free(tmp);
4342 label = gtk_label_new(NULL); 4624 label = gtk_label_new(NULL);
4681 gtkblist, PURPLE_CALLBACK(conversation_updated_cb), 4963 gtkblist, PURPLE_CALLBACK(conversation_updated_cb),
4682 gtkblist); 4964 gtkblist);
4683 purple_signal_connect(purple_conversations_get_handle(), "deleting-conversation", 4965 purple_signal_connect(purple_conversations_get_handle(), "deleting-conversation",
4684 gtkblist, PURPLE_CALLBACK(conversation_deleting_cb), 4966 gtkblist, PURPLE_CALLBACK(conversation_deleting_cb),
4685 gtkblist); 4967 gtkblist);
4968 purple_signal_connect(purple_conversations_get_handle(), "conversation-created",
4969 gtkblist, PURPLE_CALLBACK(conversation_created_cb),
4970 gtkblist);
4686 4971
4687 gtk_widget_hide(gtkblist->headline_hbox); 4972 gtk_widget_hide(gtkblist->headline_hbox);
4688 gtk_widget_hide(gtkblist->error_buttons); 4973 gtk_widget_hide(gtkblist->error_buttons);
4689 4974
4690 /* emit our created signal */ 4975 /* emit our created signal */
4787 5072
4788 if(gtknode) { 5073 if(gtknode) {
4789 if(gtknode->recent_signonoff_timer > 0) 5074 if(gtknode->recent_signonoff_timer > 0)
4790 purple_timeout_remove(gtknode->recent_signonoff_timer); 5075 purple_timeout_remove(gtknode->recent_signonoff_timer);
4791 5076
5077 purple_signals_disconnect_by_handle(node->ui_data);
4792 g_free(node->ui_data); 5078 g_free(node->ui_data);
4793 node->ui_data = NULL; 5079 node->ui_data = NULL;
4794 } 5080 }
4795 } 5081 }
4796 5082
4951 gtk_tree_store_set(gtkblist->treemodel, &iter, 5237 gtk_tree_store_set(gtkblist->treemodel, &iter,
4952 STATUS_ICON_VISIBLE_COLUMN, FALSE, 5238 STATUS_ICON_VISIBLE_COLUMN, FALSE,
4953 STATUS_ICON_COLUMN, NULL, 5239 STATUS_ICON_COLUMN, NULL,
4954 NAME_COLUMN, title, 5240 NAME_COLUMN, title,
4955 NODE_COLUMN, gnode, 5241 NODE_COLUMN, gnode,
4956 BGCOLOR_COLUMN, &bgcolor, 5242 /* BGCOLOR_COLUMN, &bgcolor, */
4957 GROUP_EXPANDER_COLUMN, TRUE, 5243 GROUP_EXPANDER_COLUMN, TRUE,
4958 GROUP_EXPANDER_VISIBLE_COLUMN, TRUE, 5244 GROUP_EXPANDER_VISIBLE_COLUMN, TRUE,
4959 CONTACT_EXPANDER_VISIBLE_COLUMN, FALSE, 5245 CONTACT_EXPANDER_VISIBLE_COLUMN, FALSE,
4960 BUDDY_ICON_VISIBLE_COLUMN, FALSE, 5246 BUDDY_ICON_VISIBLE_COLUMN, FALSE,
4961 IDLE_VISIBLE_COLUMN, FALSE, 5247 IDLE_VISIBLE_COLUMN, FALSE,
5211 GdkPixbuf *status; 5497 GdkPixbuf *status;
5212 GdkPixbuf *avatar; 5498 GdkPixbuf *avatar;
5213 GdkPixbuf *emblem; 5499 GdkPixbuf *emblem;
5214 char *mark; 5500 char *mark;
5215 gboolean showicons = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons"); 5501 gboolean showicons = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_buddy_icons");
5216 const char *name = purple_chat_get_name(chat); 5502 PidginBlistNode *ui;
5217 PurpleConversation *conv = 5503 PurpleConversation *conv;
5218 purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, name, chat->account); 5504 gboolean hidden;
5219 gboolean hidden = (conv && !PIDGIN_CONVERSATION(conv)); 5505
5220 5506 if (!insert_node(list, node, &iter))
5221 if(!insert_node(list, node, &iter))
5222 return; 5507 return;
5508
5509 ui = node->ui_data;
5510 conv = ui->conv.conv;
5511 hidden = (conv && (ui->conv.flags & PIDGIN_BLIST_NODE_HAS_PENDING_MESSAGE));
5223 5512
5224 status = pidgin_blist_get_status_icon(node, 5513 status = pidgin_blist_get_status_icon(node,
5225 PIDGIN_STATUS_ICON_SMALL); 5514 PIDGIN_STATUS_ICON_SMALL);
5226 emblem = pidgin_blist_get_emblem(node); 5515 emblem = pidgin_blist_get_emblem(node);
5227 5516
5525 gtk_table_set_col_spacings(GTK_TABLE(table), 5); 5814 gtk_table_set_col_spacings(GTK_TABLE(table), 5);
5526 gtk_container_set_border_width(GTK_CONTAINER(table), 0); 5815 gtk_container_set_border_width(GTK_CONTAINER(table), 0);
5527 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); 5816 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
5528 5817
5529 /* Set up stuff for the account box */ 5818 /* Set up stuff for the account box */
5530 label = gtk_label_new_with_mnemonic(_("_Account:")); 5819 label = gtk_label_new_with_mnemonic(_("A_ccount:"));
5531 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); 5820 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
5532 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1); 5821 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
5533 5822
5534 data->account_box = pidgin_account_option_menu_new(account, FALSE, 5823 data->account_box = pidgin_account_option_menu_new(account, FALSE,
5535 G_CALLBACK(add_buddy_select_account_cb), NULL, data); 5824 G_CALLBACK(add_buddy_select_account_cb), NULL, data);
5641 5930
5642 if (chat != NULL) 5931 if (chat != NULL)
5643 { 5932 {
5644 purple_blist_add_chat(chat, group, NULL); 5933 purple_blist_add_chat(chat, group, NULL);
5645 } 5934 }
5935
5936 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->autojoin)))
5937 purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-autojoin", TRUE);
5938
5939 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->persistent)))
5940 purple_blist_node_set_bool((PurpleBlistNode*)chat, "gtk-persistent", TRUE);
5646 5941
5647 gtk_widget_destroy(data->window); 5942 gtk_widget_destroy(data->window);
5648 g_free(data->default_chat_name); 5943 g_free(data->default_chat_name);
5649 g_list_free(data->entries); 5944 g_list_free(data->entries);
5650 g_free(data); 5945 g_free(data);
5936 6231
5937 data->group_combo = pidgin_text_combo_box_entry_new(group ? group->name : NULL, groups_tree()); 6232 data->group_combo = pidgin_text_combo_box_entry_new(group ? group->name : NULL, groups_tree());
5938 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_BIN(data->group_combo)->child); 6233 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_BIN(data->group_combo)->child);
5939 pidgin_set_accessible_label (data->group_combo, label); 6234 pidgin_set_accessible_label (data->group_combo, label);
5940 gtk_box_pack_end(GTK_BOX(rowbox), data->group_combo, TRUE, TRUE, 0); 6235 gtk_box_pack_end(GTK_BOX(rowbox), data->group_combo, TRUE, TRUE, 0);
6236
6237 data->autojoin = gtk_check_button_new_with_mnemonic(_("Autojoin when account becomes online."));
6238 data->persistent = gtk_check_button_new_with_mnemonic(_("Hide chat when the window is closed."));
6239 gtk_box_pack_start(GTK_BOX(vbox), data->autojoin, FALSE, FALSE, 0);
6240 gtk_box_pack_start(GTK_BOX(vbox), data->persistent, FALSE, FALSE, 0);
5941 6241
5942 g_signal_connect(G_OBJECT(data->window), "response", 6242 g_signal_connect(G_OBJECT(data->window), "response",
5943 G_CALLBACK(add_chat_resp_cb), data); 6243 G_CALLBACK(add_chat_resp_cb), data);
5944 6244
5945 gtk_widget_show_all(data->window); 6245 gtk_widget_show_all(data->window);
6584 6884
6585 /* Clear the old Accounts menu */ 6885 /* Clear the old Accounts menu */
6586 for (l = gtk_container_get_children(GTK_CONTAINER(accountmenu)); l; l = g_list_delete_link(l, l)) { 6886 for (l = gtk_container_get_children(GTK_CONTAINER(accountmenu)); l; l = g_list_delete_link(l, l)) {
6587 menuitem = l->data; 6887 menuitem = l->data;
6588 6888
6589 if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Add\\/Edit"))) 6889 if (menuitem != gtk_item_factory_get_widget(gtkblist->ift, N_("/Accounts/Manage")))
6590 gtk_widget_destroy(menuitem); 6890 gtk_widget_destroy(menuitem);
6591 } 6891 }
6592 6892
6593 for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) { 6893 for (accounts = purple_accounts_get_all(); accounts; accounts = accounts->next) {
6594 char *buf = NULL; 6894 char *buf = NULL;

mercurial