comparison src/buddy.c @ 4916:d9b6b5ae34e4

[gaim-migrate @ 5250] Buddy list editing. Does this work? I don't know; I don't test things. It compiles though. It probably does work though, because I'm perfect. So, see, I did really terribly in school last semester (really terribly-- like, why didn't they kick me out terribly) and so I'm working really hard to do well this semester (and I am so far :)). Anyway, that's why you may have noticed I'm a bit slow with the development of late. In fact, I would test and fix this stuff up, but I really need to work on an English paper, so I figured it'd be best just to commit it as is and let Rob, Nathan, Chip and the boys work out the kinks. Besides, I've had most of this code written for weeks already. Thank you all for your patience. Oh, so there's now an Edit menu on your buddy list (which makes the minimum buddy list width wider :-D) and here you'll find things with which to edit your list and privacy, prefs and accounts. It should all be real intuitive. Feel free to IM me if you want to talk about my paper. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Mon, 31 Mar 2003 07:19:46 +0000
parents a6e9cd5e853e
children 553d96cb9b26
comparison
equal deleted inserted replaced
4915:0230df73f56a 4916:d9b6b5ae34e4
163 show_log(NULL); 163 show_log(NULL);
164 } 164 }
165 165
166 static void gtk_blist_show_onlinehelp_cb() 166 static void gtk_blist_show_onlinehelp_cb()
167 { 167 {
168 open_url(NULL, "http://gaim.sourceforge.net/documentation.php"); 168 open_url(NULL, WEBSITE "documentation.php");
169 } 169 }
170 170
171 static void gtk_blist_button_im_cb(GtkWidget *w, GtkTreeView *tv) 171 static void gtk_blist_button_im_cb(GtkWidget *w, GtkTreeView *tv)
172 { 172 {
173 GtkTreeIter iter; 173 GtkTreeIter iter;
237 else 237 else
238 gtk_tree_view_expand_row(tv,path,FALSE); 238 gtk_tree_view_expand_row(tv,path,FALSE);
239 } 239 }
240 } 240 }
241 241
242 static void gaim_gtk_blist_add_buddy_cb()
243 {
244 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview));
245 GtkTreeIter iter;
246 GaimBlistNode *node;
247
248 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){
249 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1);
250 if (GAIM_BLIST_NODE_IS_BUDDY(node))
251 show_add_buddy(NULL, NULL, ((struct group*)node->parent)->name, NULL);
252 else if (GAIM_BLIST_NODE_IS_GROUP(node))
253 show_add_buddy(NULL, NULL, ((struct group*)node)->name, NULL);
254 }
255 else {
256 show_add_buddy(NULL, NULL, NULL, NULL);
257 }
258 }
259
260 gaim_gtk_blist_remove_cb (GtkWidget *w, GaimBlistNode *node)
261 {
262 if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
263 struct buddy *b = (struct buddy*)node;
264 show_confirm_del(b->account->gc, b->name);
265 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
266 struct group *g = (struct group*)node;
267 show_confirm_del_group(g);
268 }
269 }
270
242 static void gaim_proto_menu_cb(GtkMenuItem *item, struct buddy *b) 271 static void gaim_proto_menu_cb(GtkMenuItem *item, struct buddy *b)
243 { 272 {
244 struct proto_buddy_menu *pbm = g_object_get_data(G_OBJECT(item), "gaimcallback"); 273 struct proto_buddy_menu *pbm = g_object_get_data(G_OBJECT(item), "gaimcallback");
245 if (pbm->callback) 274 if (pbm->callback)
246 pbm->callback(pbm->gc, b->name); 275 pbm->callback(pbm->gc, b->name);
265 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL)) 294 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tv), event->x, event->y, &path, NULL, NULL, NULL))
266 return FALSE; 295 return FALSE;
267 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path); 296 gtk_tree_model_get_iter(GTK_TREE_MODEL(gtkblist->treemodel), &iter, path);
268 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val); 297 gtk_tree_model_get_value (GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &val);
269 node = g_value_get_pointer(&val); 298 node = g_value_get_pointer(&val);
270
271 if (!GAIM_BLIST_NODE_IS_BUDDY(node)) {
272 gtk_tree_path_free(path);
273 return FALSE;
274 }
275
276 menu = gtk_menu_new(); 299 menu = gtk_menu_new();
277 300
278 /* Protocol specific options */ 301 if (GAIM_BLIST_NODE_IS_GROUP(node)) {
279 prpl = find_prpl(((struct buddy*)node)->account->protocol); 302 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Add a Buddy"));
280 303 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_gtk_blist_add_buddy_cb), node);
281 if(prpl && prpl->get_info) { 304 image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
282 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Get Info")); 305 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
283 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_info_cb), node);
284 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); 306 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
285 } 307
286 308 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Delete Group"));
287 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_IM")); 309 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_gtk_blist_remove_cb), node);
288 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_im_cb), node); 310 image = gtk_image_new_from_stock(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
289 image = gtk_image_new_from_stock(GAIM_STOCK_IM, GTK_ICON_SIZE_MENU); 311 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
290 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image); 312 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
291 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); 313
292 314 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Rename"));
293 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Alias")); 315 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(show_rename_group), node);
294 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_alias_cb), node); 316 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
295 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); 317 } else if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
296 318
297 menuitem = gtk_image_menu_item_new_with_mnemonic(_("Add Buddy _Pounce")); 319 /* Protocol specific options */
298 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_bp_cb), node); 320 prpl = find_prpl(((struct buddy*)node)->account->protocol);
299 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); 321
300 322 if(prpl && prpl->get_info) {
301 menuitem = gtk_image_menu_item_new_with_mnemonic(_("View _Log")); 323 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Get Info"));
302 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_showlog_cb), node); 324 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_info_cb), node);
303 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
304
305 if (prpl) {
306 list = prpl->buddy_menu(((struct buddy*)node)->account->gc, ((struct buddy*)node)->name);
307 while (list) {
308 struct proto_buddy_menu *pbm = list->data;
309 menuitem = gtk_menu_item_new_with_mnemonic(pbm->label);
310 g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pbm);
311 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_proto_menu_cb), node);
312 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); 325 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
313 list = list->next; 326 }
314 } 327
315 } 328 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_IM"));
316 329 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_im_cb), node);
330 image = gtk_image_new_from_stock(GAIM_STOCK_IM, GTK_ICON_SIZE_MENU);
331 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
332 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
333
334 menuitem = gtk_image_menu_item_new_with_mnemonic(_("Add Buddy _Pounce"));
335 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_bp_cb), node);
336 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
337
338 menuitem = gtk_image_menu_item_new_with_mnemonic(_("View _Log"));
339 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_showlog_cb), node);
340 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
341
342 if (prpl) {
343 list = prpl->buddy_menu(((struct buddy*)node)->account->gc, ((struct buddy*)node)->name);
344 while (list) {
345 struct proto_buddy_menu *pbm = list->data;
346 menuitem = gtk_menu_item_new_with_mnemonic(pbm->label);
347 g_object_set_data(G_OBJECT(menuitem), "gaimcallback", pbm);
348 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_proto_menu_cb), node);
349 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
350 list = list->next;
351 }
352 }
353
354 gaim_separator(menu);
355
356 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Alias"));
357 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gtk_blist_menu_alias_cb), node);
358 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
359
360 menuitem = gtk_image_menu_item_new_with_mnemonic(_("_Remove"));
361 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(gaim_gtk_blist_remove_cb), node);
362 image = gtk_image_new_from_stock(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
363 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
364 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
365 }
366
317 gtk_widget_show_all(menu); 367 gtk_widget_show_all(menu);
318 368
319 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, event->time); 369 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, event->time);
320 370
321 #if (1) /* This code only exists because GTK doesn't work. If we return FALSE here, as would be normal 371 #if (1) /* This code only exists because GTK doesn't work. If we return FALSE here, as would be normal
334 { 384 {
335 ((struct buddy*)b)->present = 1; 385 ((struct buddy*)b)->present = 1;
336 gaim_gtk_blist_update(NULL, b); 386 gaim_gtk_blist_update(NULL, b);
337 return FALSE; 387 return FALSE;
338 } 388 }
339 389 static void edit_mode_cb() {
340 static void gaim_gtk_blist_add_buddy_cb() 390 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
341 { 391 gdk_window_set_cursor(gtkblist->window->window, cursor);
342 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); 392 while (gtk_events_pending())
343 GtkTreeIter iter; 393 gtk_main_iteration();
344 GaimBlistNode *node; 394 gtkblist->editmode = !gtkblist->editmode;
345 395 gdk_cursor_unref(cursor);
346 if(gtk_tree_selection_get_selected(sel, NULL, &iter)){ 396 cursor = gdk_cursor_new(GDK_LEFT_PTR);
347 gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter, NODE_COLUMN, &node, -1); 397 gdk_window_set_cursor(gtkblist->window->window, cursor);
348 if (GAIM_BLIST_NODE_IS_BUDDY(node)) 398 gdk_cursor_unref(cursor);
349 show_add_buddy(NULL, NULL, ((struct group*)node->parent)->name, NULL); 399 gaim_gtk_blist_refresh(gaim_get_blist());
350 else if (GAIM_BLIST_NODE_IS_GROUP(node)) 400 }
351 show_add_buddy(NULL, NULL, ((struct group*)node)->name, NULL); 401
352 }
353 else {
354 show_add_buddy(NULL, NULL, NULL, NULL);
355 }
356 }
357 402
358 static void gaim_gtk_blist_update_toolbar_icons (GtkWidget *widget, gpointer data) { 403 static void gaim_gtk_blist_update_toolbar_icons (GtkWidget *widget, gpointer data) {
359 if (GTK_IS_IMAGE(widget)) { 404 if (GTK_IS_IMAGE(widget)) {
360 if (blist_options & OPT_BLIST_SHOW_BUTTON_XPM) 405 if (blist_options & OPT_BLIST_SHOW_BUTTON_XPM)
361 gtk_widget_show(widget); 406 gtk_widget_show(widget);
590 ***************************************************/ 635 ***************************************************/
591 static GtkItemFactoryEntry blist_menu[] = 636 static GtkItemFactoryEntry blist_menu[] =
592 { 637 {
593 /* Buddies menu */ 638 /* Buddies menu */
594 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>" }, 639 { N_("/_Buddies"), NULL, NULL, 0, "<Branch>" },
595 { N_("/Buddies/_Add A Buddy..."), "<CTL>B", gaim_gtk_blist_add_buddy_cb, 0, 640 { N_("/Buddies/New _Instant Message..."), "<CTL>I", show_im_dialog, 0,
596 "<StockItem>", GTK_STOCK_ADD },
597 { N_("/Buddies/New _Instant Message..."), "<CTL>I", show_im_dialog, 0,
598 "<StockItem>", GAIM_STOCK_IM }, 641 "<StockItem>", GAIM_STOCK_IM },
599 { N_("/Buddies/Join a _Chat..."), "<CTL>C", join_chat, 0, 642 { N_("/Buddies/Join a _Chat..."), "<CTL>C", join_chat, 0,
600 "<StockItem>", GAIM_STOCK_CHAT }, 643 "<StockItem>", GAIM_STOCK_CHAT },
601 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>" }, 644 { "/Buddies/sep1", NULL, NULL, 0, "<Separator>" },
602 { N_("/Buddies/Get _User Info..."), "<CTL>J", show_info_dialog, 0, 645 { N_("/Buddies/Get _User Info..."), "<CTL>J", show_info_dialog, 0,
604 { "/Buddies/sep2", NULL, NULL, 0, "<Separator>" }, 647 { "/Buddies/sep2", NULL, NULL, 0, "<Separator>" },
605 { N_("/Buddies/_Signoff"), "<CTL>D", signoff_all, 0, NULL }, 648 { N_("/Buddies/_Signoff"), "<CTL>D", signoff_all, 0, NULL },
606 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0, 649 { N_("/Buddies/_Quit"), "<CTL>Q", do_quit, 0,
607 "<StockItem>", GTK_STOCK_QUIT }, 650 "<StockItem>", GTK_STOCK_QUIT },
608 651
652 /* Edit menu */
653 { N_("/_Edit"), NULL, NULL, 0, "<Branch>" },
654 { N_("/Edit/_Show Offline Buddies"), NULL, edit_mode_cb, 0, "<CheckItem>"},
655 { N_("/Edit/_Add a Buddy..."), NULL, gaim_gtk_blist_add_buddy_cb, 0, "<StockItem>", GTK_STOCK_ADD },
656 { N_("/Edit/Add a _Group..."), NULL, show_add_group, 0, NULL},
657 { "/Edit/sep", NULL, NULL, 0, "<Separator>" },
658 { N_("/Edit/A_ccounts"), "<CTL>A", account_editor, 0, NULL },
659 { N_("/Edit/Preferences"), "<CTL>P", show_prefs, 0,
660 "<StockItem>", GTK_STOCK_PREFERENCES },
661 { N_("/Edit/Pr_ivacy"), NULL, show_privacy_options, 0, NULL },
662
663
609 /* Tools */ 664 /* Tools */
610 { N_("/_Tools"), NULL, NULL, 0, "<Branch>" }, 665 { N_("/_Tools"), NULL, NULL, 0, "<Branch>" },
611 { N_("/Tools/_Away"), NULL, NULL, 0, "<Branch>" }, 666 { N_("/Tools/_Away"), NULL, NULL, 0, "<Branch>" },
612 { N_("/Tools/Buddy _Pounce"), NULL, NULL, 0, "<Branch>" }, 667 { N_("/Tools/Buddy _Pounce"), NULL, NULL, 0, "<Branch>" },
613 { "/Tools/sep1", NULL, NULL, 0, "<Separator>" }, 668 { N_("/Tools/sep1"), NULL, NULL, 0, "<Separator>" },
614 { N_("/Tools/A_ccounts"), "<CTL>A", account_editor, 0, NULL },
615 { N_("/Tools/Preferences"), "<CTL>P", show_prefs, 0,
616 "<StockItem>", GTK_STOCK_PREFERENCES },
617 { N_("/Tools/_File Transfers"), NULL, gaim_show_xfer_dialog, 0, 669 { N_("/Tools/_File Transfers"), NULL, gaim_show_xfer_dialog, 0,
618 "<StockItem>", GTK_STOCK_REVERT_TO_SAVED }, 670 "<StockItem>", GTK_STOCK_REVERT_TO_SAVED },
619 { "/Tools/sep2", NULL, NULL, 0, "<Separator>" }, 671 { "/Tools/sep2", NULL, NULL, 0, "<Separator>" },
620 { N_("/Tools/P_rotocol Actions"), NULL, NULL, 0, "<Branch>" }, 672 { N_("/Tools/P_rotocol Actions"), NULL, NULL, 0, "<Branch>" },
621 { N_("/Tools/Pr_ivacy"), NULL, show_privacy_options, 0, NULL },
622 { N_("/Tools/View System _Log"), NULL, gtk_blist_show_systemlog_cb, 0, NULL }, 673 { N_("/Tools/View System _Log"), NULL, gtk_blist_show_systemlog_cb, 0, NULL },
623 674
624 /* Help */ 675 /* Help */
625 { N_("/_Help"), NULL, NULL, 0, "<Branch>" }, 676 { N_("/_Help"), NULL, NULL, 0, "<Branch>" },
626 { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0, 677 { N_("/Help/Online _Help"), "F1", gtk_blist_show_onlinehelp_cb, 0,
678 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>" 729 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>"
679 "%s %s" /* Alias */ 730 "%s %s" /* Alias */
680 "%s %s" /* Nickname */ 731 "%s %s" /* Nickname */
681 "%s %s" /* Idle */ 732 "%s %s" /* Idle */
682 "%s %s" /* Warning */ 733 "%s %s" /* Warning */
734 "%s" /* Offline */
683 "%s%s", /* Status */ 735 "%s%s", /* Status */
684 b->name, 736 b->name,
685 aliastext ? _("\n<b>Alias:</b>") : "", aliastext ? aliastext : "", 737 aliastext ? _("\n<b>Alias:</b>") : "", aliastext ? aliastext : "",
686 nicktext ? _("\n<b>Nickname:</b>") : "", nicktext ? nicktext : "", 738 nicktext ? _("\n<b>Nickname:</b>") : "", nicktext ? nicktext : "",
687 b->idle ? _("\n<b>Idle:</b>") : "", b->idle ? idletime : "", 739 b->idle ? _("\n<b>Idle:</b>") : "", b->idle ? idletime : "",
688 b->evil ? _("\n<b>Warned:</b>") : "", b->evil ? warning : "", 740 b->evil ? _("\n<b>Warned:</b>") : "", b->evil ? warning : "",
741 !b->present ? _("\n<b>Status:</b> Offline") : "",
689 statustext ? "\n" : "", statustext ? statustext : ""); 742 statustext ? "\n" : "", statustext ? statustext : "");
690 if(warning) 743 if(warning)
691 g_free(warning); 744 g_free(warning);
692 if(idletime) 745 if(idletime)
693 g_free(idletime); 746 g_free(idletime);
713 char *se = NULL, *sw = NULL ,*nw = NULL ,*ne = NULL; 766 char *se = NULL, *sw = NULL ,*nw = NULL ,*ne = NULL;
714 767
715 int scalesize = 30; 768 int scalesize = 30;
716 769
717 struct prpl* prpl = find_prpl(b->account->protocol); 770 struct prpl* prpl = find_prpl(b->account->protocol);
771
772 if (!prpl)
773 return NULL;
774
718 if (prpl->list_icon) 775 if (prpl->list_icon)
719 protoname = prpl->list_icon(b->account, b); 776 protoname = prpl->list_icon(b->account, b);
720 if (prpl->list_emblems) 777 if (prpl->list_emblems)
721 prpl->list_emblems(b, &se, &sw, &nw, &ne); 778 prpl->list_emblems(b, &se, &sw, &nw, &ne);
722 779
723 if (size == GAIM_STATUS_ICON_SMALL) { 780 if (size == GAIM_STATUS_ICON_SMALL) {
724 scalesize = 15; 781 scalesize = 15;
725 sw = nw = ne = NULL; /* So that only the se icon will composite */ 782 sw = nw = ne = NULL; /* So that only the se icon will composite */
726 } 783 }
727 784
840 } 897 }
841 } 898 }
842 899
843 900
844 /* Idle grey buddies affects the whole row. This converts the status icon to greyscale. */ 901 /* Idle grey buddies affects the whole row. This converts the status icon to greyscale. */
845 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) 902 if ((b->idle && blist_options & OPT_BLIST_GREY_IDLERS) || gtkblist->editmode)
846 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0, FALSE); 903 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0, FALSE);
847 return scale; 904 return scale;
848 } 905 }
849 906
850 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b) 907 static GdkPixbuf *gaim_gtk_blist_get_buddy_icon(struct buddy *b)
862 buf = gdk_pixbuf_new_from_file(file, NULL); 919 buf = gdk_pixbuf_new_from_file(file, NULL);
863 g_free(file); 920 g_free(file);
864 921
865 922
866 if (buf) { 923 if (buf) {
867 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS) { 924 if ((b->idle && blist_options & OPT_BLIST_GREY_IDLERS) || gtkblist->editmode) {
868 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0, FALSE); 925 gdk_pixbuf_saturate_and_pixelate(buf, buf, 0, FALSE);
869 } 926 }
870 ret = gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR); 927 ret = gdk_pixbuf_scale_simple(buf,30,30, GDK_INTERP_BILINEAR);
871 g_object_unref(G_OBJECT(buf)); 928 g_object_unref(G_OBJECT(buf));
872 return ret; 929 return ret;
885 int ihrs, imin; 942 int ihrs, imin;
886 char *idletime = NULL, *warning = NULL, *statustext = NULL; 943 char *idletime = NULL, *warning = NULL, *statustext = NULL;
887 time_t t; 944 time_t t;
888 945
889 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) { 946 if (!(blist_options & OPT_BLIST_SHOW_ICONS)) {
890 if (b->idle > 0 && blist_options & OPT_BLIST_GREY_IDLERS && !selected) { 947 if ((b->idle > 0 && blist_options & OPT_BLIST_GREY_IDLERS && !selected) || gtkblist->editmode) {
891 text = g_strdup_printf("<span color='dim grey'>%s</span>", 948 text = g_strdup_printf("<span color='dim grey'>%s</span>",
892 esc); 949 esc);
893 g_free(esc); 950 g_free(esc);
894 return text; 951 return text;
895 } else { 952 } else {
899 956
900 time(&t); 957 time(&t);
901 ihrs = (t - b->idle) / 3600; 958 ihrs = (t - b->idle) / 3600;
902 imin = ((t - b->idle) / 60) % 60; 959 imin = ((t - b->idle) / 60) % 60;
903 960
904 if (prpl->status_text) { 961 if (prpl && prpl->status_text) {
905 char *tmp = prpl->status_text(b); 962 char *tmp = prpl->status_text(b);
906 const char *end; 963 const char *end;
907 964
908 if(tmp && !g_utf8_validate(tmp, -1, &end)) { 965 if(tmp && !g_utf8_validate(tmp, -1, &end)) {
909 char *new = g_strndup(tmp, 966 char *new = g_strndup(tmp,
950 1007
951 if (b->evil > 0) 1008 if (b->evil > 0)
952 warning = g_strdup_printf(_("Warned (%d%%) "), b->evil); 1009 warning = g_strdup_printf(_("Warned (%d%%) "), b->evil);
953 1010
954 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS && !selected) { 1011 if (b->idle && blist_options & OPT_BLIST_GREY_IDLERS && !selected) {
955 text = g_strdup_printf("<span color='dim grey'>%s</span>\n<span color='dim grey' size='smaller'>%s%s%s</span>", 1012 text = g_strdup_printf("<span color='dim grey'>%s</span>\n"
1013 "<span color='dim grey' size='smaller'>%s%s%s%s</span>",
956 esc, 1014 esc,
957 statustext != NULL ? statustext : "", 1015 statustext != NULL ? statustext : "",
958 idletime != NULL ? idletime : "", 1016 idletime != NULL ? idletime : "",
959 warning != NULL ? warning : ""); 1017 warning != NULL ? warning : "",
960 } else if (statustext == NULL && idletime == NULL && warning == NULL) { 1018 !b->present ? _("Offline ") : "");
961 text = g_strdup_printf("%s", esc); 1019 } else if (statustext == NULL && idletime == NULL && warning == NULL && b->present) {
1020 text = g_strdup(esc);
962 } else { 1021 } else {
963 text = g_strdup_printf("%s\n<span %s size='smaller'>%s%s%s</span>", esc, 1022 text = g_strdup_printf("%s\n"
964 selected ? "" : "color='dim grey'", 1023 "<span %s size='smaller'>%s%s%s%s</span>", esc,
965 statustext != NULL ? statustext : "", 1024 selected ? "" : "color='dim grey'",
966 idletime != NULL ? idletime : "", 1025 statustext != NULL ? statustext : "",
967 warning != NULL ? warning : ""); 1026 idletime != NULL ? idletime : "",
1027 warning != NULL ? warning : "",
1028 !b->present ? _("Offline ") : "");
968 } 1029 }
969 if (idletime) 1030 if (idletime)
970 g_free(idletime); 1031 g_free(idletime);
971 if (warning) 1032 if (warning)
972 g_free(warning); 1033 g_free(warning);
1095 1156
1096 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, 1157 gtkblist->treemodel = gtk_tree_store_new(BLIST_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING,
1097 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER); 1158 G_TYPE_STRING, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER);
1098 1159
1099 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel)); 1160 gtkblist->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(gtkblist->treemodel));
1161 gtk_widget_set_size_request(gtkblist->treeview, -1, 200);
1100 1162
1101 /* Set up selection stuff */ 1163 /* Set up selection stuff */
1102 1164
1103 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)); 1165 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview));
1104 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(gaim_gtk_blist_selection_changed), NULL); 1166 g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(gaim_gtk_blist_selection_changed), NULL);
1193 { 1255 {
1194 GaimBlistNode *group = list->root; 1256 GaimBlistNode *group = list->root;
1195 GaimBlistNode *buddy; 1257 GaimBlistNode *buddy;
1196 1258
1197 while (group) { 1259 while (group) {
1260 buddy = group->child;
1198 gaim_gtk_blist_update(list, group); 1261 gaim_gtk_blist_update(list, group);
1199 buddy = group->child;
1200 while (buddy) { 1262 while (buddy) {
1201 gaim_gtk_blist_update(list, buddy); 1263 gaim_gtk_blist_update(list, buddy);
1202 buddy = buddy->next; 1264 buddy = buddy->next;
1203 } 1265 }
1204 group = group->next; 1266 group = group->next;
1325 1387
1326 1388
1327 if (!get_iter_from_node(node, &iter)) { /* This is a newly added node */ 1389 if (!get_iter_from_node(node, &iter)) { /* This is a newly added node */
1328 new_entry = TRUE; 1390 new_entry = TRUE;
1329 if (GAIM_BLIST_NODE_IS_BUDDY(node)) { 1391 if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
1330 if (((struct buddy*)node)->present) { 1392 if (((struct buddy*)node)->present || (gtkblist->editmode && ((struct buddy*)node)->account->gc)) {
1331 GtkTreeIter groupiter; 1393 GtkTreeIter groupiter;
1332 GaimBlistNode *oldersibling; 1394 GaimBlistNode *oldersibling;
1333 GtkTreeIter oldersiblingiter; 1395 GtkTreeIter oldersiblingiter;
1334 1396
1335 if(node->parent && !get_iter_from_node(node->parent, &groupiter)) { 1397 if(node->parent && !get_iter_from_node(node->parent, &groupiter)) {
1375 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE); 1437 gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE);
1376 gtk_tree_path_free(path); 1438 gtk_tree_path_free(path);
1377 } 1439 }
1378 } 1440 }
1379 } 1441 }
1380 } 1442 else if (GAIM_BLIST_NODE_IS_GROUP(node) && gtkblist->editmode) {
1381 1443 GaimBlistNode *oldersibling;
1382 if (GAIM_BLIST_NODE_IS_BUDDY(node) && ((struct buddy*)node)->present) { 1444 GtkTreeIter oldersiblingiter;
1445 GdkPixbuf *groupicon = gtk_widget_render_icon(gtkblist->treeview,
1446 GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL);
1447 char *esc = g_markup_escape_text(((struct group*)node)->name, -1);
1448 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", esc);
1449 g_free(esc);
1450 oldersibling = node->prev;
1451 while (oldersibling && !get_iter_from_node(oldersibling, &oldersiblingiter)) {
1452 oldersibling = oldersibling->prev;
1453 }
1454
1455 gtk_tree_store_insert_after(gtkblist->treemodel, &iter, NULL, oldersibling ? &oldersiblingiter : NULL);
1456 gtk_tree_store_set(gtkblist->treemodel, &iter,
1457 STATUS_ICON_COLUMN, groupicon,
1458 NAME_COLUMN, mark,
1459 NODE_COLUMN, node,
1460 -1);
1461 g_free(mark);
1462 g_object_unref(groupicon);
1463 }
1464
1465 } else if (GAIM_BLIST_NODE_IS_GROUP(node)) {
1466 if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(gtkblist->treemodel), &iter) == FALSE && gtkblist->editmode == FALSE)
1467 gtk_tree_store_remove(gtkblist->treemodel, &iter);
1468 else {
1469 char *esc = g_markup_escape_text(((struct group*)node)->name, -1);
1470 char *mark = g_strdup_printf("<span weight='bold'>%s</span>", esc);
1471 g_free(esc);
1472 gtk_tree_store_set(gtkblist->treemodel, &iter,
1473 NAME_COLUMN, mark,
1474 -1);
1475 g_free(mark);
1476 }
1477 }
1478
1479 if (GAIM_BLIST_NODE_IS_BUDDY(node) && (((struct buddy*)node)->present || (gtkblist->editmode && ((struct buddy*)node)->account->gc))) {
1383 GdkPixbuf *status, *avatar; 1480 GdkPixbuf *status, *avatar;
1384 char *mark; 1481 char *mark;
1385 char *warning = NULL, *idle = NULL; 1482 char *warning = NULL, *idle = NULL;
1386 1483
1387 gboolean selected = (gtkblist->selected_node == node); 1484 gboolean selected = (gtkblist->selected_node == node);
1454 GaimBlistNode *afsad = node->child; 1551 GaimBlistNode *afsad = node->child;
1455 while (afsad) { 1552 while (afsad) {
1456 gaim_gtk_blist_update(list, afsad); 1553 gaim_gtk_blist_update(list, afsad);
1457 afsad = afsad->next; 1554 afsad = afsad->next;
1458 } 1555 }
1459 } 1556
1460 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview)); 1557 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(gtkblist->treeview));
1558 }
1461 } 1559 }
1462 1560
1463 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list) 1561 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list)
1464 { 1562 {
1465 if (!gtkblist) 1563 if (!gtkblist)