[gaim-migrate @ 5891]
[pidgin-git.git] / src / dialogs.c
blob9cfc8e18bf81354c5625397d05008e9d801f3c7f
1 /*
2 * gaim
4 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <string.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <ctype.h>
33 #ifdef _WIN32
34 #include <winsock.h>
35 #else
36 #include <sys/socket.h>
37 #include <time.h>
38 #include <netdb.h>
39 #include <netinet/in.h>
40 #include <unistd.h>
41 #include <arpa/inet.h>
42 #endif
44 #include <errno.h>
45 #include <math.h>
47 #include <gtk/gtk.h>
48 #include "gaim.h"
49 #include "gtkimhtml.h"
50 #include "prpl.h"
51 #include "gtkblist.h"
52 #include "notify.h"
54 #ifdef _WIN32
55 #include "win32dep.h"
56 #endif
58 #define PATHSIZE 1024
60 GdkColor bgcolor;
61 GdkColor fgcolor;
63 static GtkWidget *imdialog = NULL; /*I only want ONE of these :) */
64 static GList *dialogwindows = NULL;
65 static GtkWidget *importdialog;
66 static struct gaim_connection *importgc;
67 static GtkWidget *icondlg;
68 static GtkWidget *alias_dialog = NULL;
69 static GtkWidget *rename_dialog = NULL;
70 static GtkWidget *rename_bud_dialog = NULL;
73 struct confirm_del {
74 GtkWidget *window;
75 GtkWidget *label;
76 GtkWidget *ok;
77 GtkWidget *cancel;
78 char name[1024];
79 struct gaim_connection *gc;
82 struct create_away {
83 GtkWidget *window;
84 GtkWidget *entry;
85 GtkWidget *text;
86 struct away_message *mess;
89 struct warning {
90 GtkWidget *window;
91 GtkWidget *anon;
92 char *who;
93 struct gaim_connection *gc;
96 struct addbuddy {
97 GtkWidget *window;
98 GtkWidget *combo;
99 GtkWidget *entry;
100 GtkWidget *entry_for_alias;
101 GtkWidget *account;
102 struct gaim_connection *gc;
105 struct addperm {
106 GtkWidget *window;
107 GtkWidget *entry;
108 struct gaim_connection *gc;
109 gboolean permit;
112 struct findbyemail {
113 GtkWidget *window;
114 GtkWidget *emailentry;
115 struct gaim_connection *gc;
118 struct findbyinfo {
119 struct gaim_connection *gc;
120 GtkWidget *window;
121 GtkWidget *firstentry;
122 GtkWidget *middleentry;
123 GtkWidget *lastentry;
124 GtkWidget *maidenentry;
125 GtkWidget *cityentry;
126 GtkWidget *stateentry;
127 GtkWidget *countryentry;
130 struct info_dlg {
131 struct gaim_connection *gc;
132 char *who;
133 GtkWidget *window;
134 GtkWidget *text;
137 struct getuserinfo {
138 GtkWidget *window;
139 GtkWidget *entry;
140 GtkWidget *account;
141 struct gaim_connection *gc;
144 struct alias_dialog_info
146 GtkWidget *window;
147 GtkWidget *name_entry;
148 GtkWidget *alias_entry;
149 struct buddy *buddy;
152 static GSList *info_dlgs = NULL;
154 static struct info_dlg *find_info_dlg(struct gaim_connection *gc, const char *who)
156 GSList *i = info_dlgs;
157 while (i) {
158 struct info_dlg *d = i->data;
159 i = i->next;
160 if (d->gc != gc)
161 continue;
162 if (d->who == NULL)
163 continue;
164 if (!who)
165 continue;
166 if (!gaim_utf8_strcasecmp(normalize(who), d->who))
167 return d;
169 return NULL;
172 struct set_info_dlg {
173 GtkWidget *window;
174 GtkWidget *menu;
175 struct gaim_account *account;
176 GtkWidget *text;
177 GtkWidget *save;
178 GtkWidget *cancel;
181 struct set_icon_dlg {
182 GtkWidget *window;
183 struct gaim_account *account;
184 GtkWidget *ok;
185 GtkWidget *cancel;
186 GtkWidget *entry;
189 struct set_dir_dlg {
190 struct gaim_connection *gc;
191 GtkWidget *window;
192 GtkWidget *first;
193 GtkWidget *middle;
194 GtkWidget *last;
195 GtkWidget *maiden;
196 GtkWidget *city;
197 GtkWidget *state;
198 GtkWidget *country;
199 GtkWidget *web;
200 GtkWidget *cancel;
201 GtkWidget *save;
204 struct linkdlg {
205 GtkWidget *ok;
206 GtkWidget *cancel;
207 GtkWidget *window;
208 GtkWidget *url;
209 GtkWidget *text;
210 GtkWidget *toggle;
211 GtkWidget *entry;
212 struct gaim_conversation *c;
215 struct passwddlg {
216 GtkWidget *window;
217 GtkWidget *ok;
218 GtkWidget *cancel;
219 GtkWidget *original;
220 GtkWidget *new1;
221 GtkWidget *new2;
222 struct gaim_connection *gc;
225 struct view_log {
226 long offset;
227 int options;
228 char *name;
229 GtkWidget *bbox;
230 GtkWidget *window;
231 GtkWidget *layout;
234 /* Wrapper to get all the text from a GtkTextView */
235 gchar* gtk_text_view_get_text(GtkTextView *text, gboolean include_hidden_chars)
237 GtkTextBuffer *buffer;
238 GtkTextIter start, end;
240 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
241 gtk_text_buffer_get_start_iter(buffer, &start);
242 gtk_text_buffer_get_end_iter(buffer, &end);
244 return gtk_text_buffer_get_text(buffer, &start, &end, include_hidden_chars);
247 /*------------------------------------------------------------------------*/
248 /* Destroys */
249 /*------------------------------------------------------------------------*/
251 static gint delete_event_dialog(GtkWidget *w, GdkEventAny *e, struct gaim_conversation *c)
253 struct gaim_gtk_conversation *gtkconv;
254 gchar *object_data;
256 object_data = g_object_get_data(G_OBJECT(w), "dialog_type");
258 gtkconv = GAIM_GTK_CONVERSATION(c);
260 if (GTK_IS_COLOR_SELECTION_DIALOG(w)) {
261 if (w == gtkconv->dialogs.fg_color) {
262 gtk_toggle_button_set_active(
263 GTK_TOGGLE_BUTTON(gtkconv->toolbar.fgcolor), FALSE);
264 gtkconv->dialogs.fg_color = NULL;
265 } else {
266 gtk_toggle_button_set_active(
267 GTK_TOGGLE_BUTTON(gtkconv->toolbar.bgcolor), FALSE);
268 gtkconv->dialogs.bg_color = NULL;
270 } else if (GTK_IS_FONT_SELECTION_DIALOG(w)) {
271 gtk_toggle_button_set_active(
272 GTK_TOGGLE_BUTTON(gtkconv->toolbar.font), FALSE);
273 gtkconv->dialogs.font = NULL;
274 } else if (!g_ascii_strcasecmp(object_data, "smiley dialog")) {
275 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkconv->toolbar.smiley),
276 FALSE);
277 gtkconv->dialogs.smiley = NULL;
278 } else if (!g_ascii_strcasecmp(object_data, "log dialog")) {
279 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->toolbar.log),
280 FALSE);
281 gtkconv->dialogs.log = NULL;
284 dialogwindows = g_list_remove(dialogwindows, w);
285 gtk_widget_destroy(w);
287 return FALSE;
290 static void destroy_dialog(GtkWidget *w, GtkWidget *w2)
292 GtkWidget *dest;
294 if (!GTK_IS_WIDGET(w2))
295 dest = w;
296 else
297 dest = w2;
299 if (dest == imdialog)
300 imdialog = NULL;
301 else if (dest == importdialog) {
302 importdialog = NULL;
303 importgc = NULL;
305 else if (dest == icondlg)
306 icondlg = NULL;
307 else if (dest == rename_dialog)
308 rename_dialog = NULL;
309 else if (dest == rename_bud_dialog)
310 rename_bud_dialog = NULL;
312 dialogwindows = g_list_remove(dialogwindows, dest);
313 gtk_widget_destroy(dest);
317 void destroy_all_dialogs()
319 while (dialogwindows)
320 destroy_dialog(NULL, dialogwindows->data);
322 if (awaymessage)
323 do_im_back(NULL, NULL);
325 if (imdialog) {
326 destroy_dialog(NULL, imdialog);
327 imdialog = NULL;
330 if (importdialog) {
331 destroy_dialog(NULL, importdialog);
332 importdialog = NULL;
335 if (icondlg) {
336 destroy_dialog(NULL, icondlg);
337 icondlg = NULL;
341 static void do_warn(GtkWidget *widget, gint resp, struct warning *w)
343 if (resp == GTK_RESPONSE_OK)
344 serv_warn(w->gc, w->who, (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w->anon))) ? 1 : 0);
346 destroy_dialog(NULL, w->window);
347 g_free(w);
350 void show_warn_dialog(struct gaim_connection *gc, char *who)
352 char *labeltext;
353 GtkWidget *hbox, *vbox;
354 GtkWidget *label;
355 GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
356 struct gaim_conversation *c = gaim_find_conversation(who);
358 struct warning *w = g_new0(struct warning, 1);
359 w->who = who;
360 w->gc = gc;
362 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
364 w->window = gtk_dialog_new_with_buttons(_("Warn User"), GTK_WINDOW(c->window), 0, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("_Warn"), GTK_RESPONSE_OK, NULL);
365 gtk_dialog_set_default_response (GTK_DIALOG(w->window), GTK_RESPONSE_OK);
366 g_signal_connect(G_OBJECT(w->window), "response", G_CALLBACK(do_warn), w);
368 gtk_container_set_border_width (GTK_CONTAINER(w->window), 6);
369 gtk_window_set_resizable(GTK_WINDOW(w->window), FALSE);
370 gtk_dialog_set_has_separator(GTK_DIALOG(w->window), FALSE);
371 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(w->window)->vbox), 12);
372 gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(w->window)->vbox), 6);
374 hbox = gtk_hbox_new(FALSE, 12);
375 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(w->window)->vbox), hbox);
376 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
378 vbox = gtk_vbox_new(FALSE, 0);
379 gtk_container_add(GTK_CONTAINER(hbox), vbox);
380 labeltext = g_strdup_printf(_("<span weight=\"bold\" size=\"larger\">Warn %s?</span>\n\n"
381 "This will increase %s's warning level and he or she will be subject to harsher rate limiting.\n"), who, who);
382 label = gtk_label_new(NULL);
383 gtk_label_set_markup(GTK_LABEL(label), labeltext);
384 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
385 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
386 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
387 g_free(labeltext);
389 w->anon = gtk_check_button_new_with_mnemonic(_("Warn _anonymously?"));
390 gtk_box_pack_start(GTK_BOX(vbox), w->anon, FALSE, FALSE, 0);
392 hbox = gtk_hbox_new(FALSE, 6);
393 gtk_container_add(GTK_CONTAINER(vbox), hbox);
394 img = gtk_image_new_from_stock(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_MENU);
395 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
396 labeltext = _("<b>Anonymous warnings are less severe.</b>");
397 /* labeltext = _("Anonymous warnings are less severe."); */
398 label = gtk_label_new(NULL);
399 gtk_label_set_markup(GTK_LABEL(label), labeltext);
400 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
401 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
403 dialogwindows = g_list_prepend(dialogwindows, w->window);
404 gtk_widget_show_all(w->window);
407 void do_remove_chat(struct chat *chat)
409 gaim_blist_remove_chat(chat);
410 gaim_blist_save();
413 void do_remove_buddy(struct buddy *b)
415 struct group *g;
416 struct gaim_conversation *c;
417 gchar *name;
419 if (!b)
420 return;
422 g = gaim_find_buddys_group(b);
423 name = g_strdup(b->name); /* b->name is null after remove_buddy */
425 gaim_debug(GAIM_DEBUG_INFO, "blist",
426 "Removing '%s' from buddy list.\n", b->name);
427 serv_remove_buddy(b->account->gc, name, g->name);
428 gaim_blist_remove_buddy(b);
429 gaim_blist_save();
431 c = gaim_find_conversation(name);
433 if (c != NULL)
434 gaim_conversation_update(c, GAIM_CONV_UPDATE_REMOVE);
436 g_free(name);
439 void do_remove_group(struct group *g)
441 GaimBlistNode *b = ((GaimBlistNode*)g)->child;
442 while (b) {
443 if(GAIM_BLIST_NODE_IS_BUDDY(b)) {
444 struct buddy *bd = (struct buddy *)b;
445 struct gaim_conversation *c = gaim_find_conversation(bd->name);
446 if(bd->account->gc) {
447 serv_remove_buddy(bd->account->gc, bd->name, g->name);
448 gaim_blist_remove_buddy(bd);
450 if (c != NULL)
451 gaim_conversation_update(c, GAIM_CONV_UPDATE_REMOVE);
454 b = b->next;
456 gaim_blist_remove_group(g);
457 gaim_blist_save();
460 void show_confirm_del(struct gaim_connection *gc, gchar *name)
462 struct buddy *bd = gaim_find_buddy(gc->account, name);
463 char *text;
464 if (!bd)
465 return;
467 text = g_strdup_printf(_("You are about to remove %s from your buddy list. Do you want to continue?"), name);
468 do_ask_dialog(_("Remove Buddy"), text, bd, _("Remove Buddy"), do_remove_buddy, _("Cancel"), NULL, NULL, FALSE);
469 g_free(text);
472 void show_confirm_del_chat(struct chat *chat)
474 char *text = g_strdup_printf(_("You are about to remove the chat %s from your buddy list. Do you want to continue?"), chat->alias);
475 do_ask_dialog(_("Remove Chat"), text, chat, _("Remove Chat"), do_remove_chat, _("Cancel"), NULL, NULL, FALSE);
476 g_free(text);
479 void show_confirm_del_group(struct group *g)
481 char *text = g_strdup_printf(_("You are about to remove the group %s and all its members from your buddy list. Do you want to continue?"),
482 g->name);
483 do_ask_dialog(_("Remove Group"), text, g, _("Remove Group"), do_remove_group, _("Cancel"), NULL, NULL, FALSE);
484 g_free(text);
487 /*------------------------------------------------------------------------*/
488 /* The dialog for getting an error */
489 /*------------------------------------------------------------------------*/
490 static void do_im(GtkWidget *widget, int resp, struct getuserinfo *info)
492 const char *who;
493 struct gaim_conversation *conv;
494 struct gaim_account *account;
496 if (resp == GTK_RESPONSE_OK) {
497 who = gtk_entry_get_text(GTK_ENTRY(info->entry));
499 if (!who || !*who) {
500 /* this shouldn't ever happen */
501 return;
504 account = (info->gc ? info->gc->account : NULL);
506 conv = gaim_find_conversation(who);
508 if (conv == NULL)
509 conv = gaim_conversation_new(GAIM_CONV_IM, account, who);
510 else {
511 gaim_window_raise(gaim_conversation_get_window(conv));
513 if (account)
514 gaim_conversation_set_account(conv, account);
518 destroy_dialog(NULL, imdialog);
519 imdialog = NULL;
520 g_free(info);
523 static void do_info(GtkWidget *widget, int resp, struct getuserinfo *info)
525 char *who;
527 if (resp == GTK_RESPONSE_OK) {
528 who = g_strdup(normalize(gtk_entry_get_text(GTK_ENTRY(info->entry))));
530 if (!g_ascii_strcasecmp(who, "")) {
531 g_free(who);
532 return;
535 /* what do we want to do about this case? */
536 if (info->gc)
537 serv_get_info(info->gc, who);
538 g_free(who);
540 gtk_widget_destroy(GTK_WIDGET(widget));
541 g_free(info);
544 void show_ee_dialog(int ee)
546 GtkWidget *window;
547 GtkWidget *hbox;
548 GtkWidget *label;
549 struct gaim_gtk_buddy_list *gtkblist;
550 GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_COOL, GTK_ICON_SIZE_DIALOG);
552 gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
554 label = gtk_label_new(NULL);
555 if (ee == 0)
556 gtk_label_set_markup(GTK_LABEL(label),
557 "<span weight=\"bold\" size=\"large\" foreground=\"purple\">Amazing! Simply Amazing!</span>");
558 else if (ee == 1)
559 gtk_label_set_markup(GTK_LABEL(label),
560 "<span weight=\"bold\" size=\"large\" foreground=\"#1f6bad\">Pimpin\' Penguin Style! *Waddle Waddle*</span>");
561 else if (ee == 2)
562 gtk_label_set_markup(GTK_LABEL(label),
563 "<span weight=\"bold\" size=\"large\" foreground=\"blue\">You should be me. I'm so cute!</span>");
564 else if (ee == 3)
565 gtk_label_set_markup(GTK_LABEL(label),
566 "<span weight=\"bold\" size=\"large\" foreground=\"orange\">Now that's what I like!</span>");
567 else if (ee == 4)
568 gtk_label_set_markup(GTK_LABEL(label),
569 "<span weight=\"bold\" size=\"large\" foreground=\"brown\">Ahh, and excellent choice!</span>");
570 else if (ee == 5)
571 gtk_label_set_markup(GTK_LABEL(label),
572 "<span weight=\"bold\" size=\"large\" foreground=\"#009900\">Everytime you click my name, an angel gets its wings.</span>");
573 else if (ee == 6)
574 gtk_label_set_markup(GTK_LABEL(label),
575 "<span weight=\"bold\" size=\"large\" foreground=\"red\">This sunflower seed taste like pizza.</span>");
576 else if (ee == 7)
577 gtk_label_set_markup(GTK_LABEL(label),
578 "<span weight=\"bold\" size=\"large\" foreground=\"#6364B1\">Hey! I was in that tumbleweed!</span>");
579 else
580 gtk_label_set_markup(GTK_LABEL(label),
581 "<span weight=\"bold\" size=\"large\" foreground=\"gray\">I'm not anything.</span>");
583 window = gtk_dialog_new_with_buttons("", GTK_WINDOW(gtkblist->window), 0, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
584 gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_OK);
585 g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(gtk_widget_destroy), NULL);
587 gtk_container_set_border_width (GTK_CONTAINER(window), 6);
588 gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
589 gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);
590 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(window)->vbox), 12);
591 gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(window)->vbox), 6);
593 hbox = gtk_hbox_new(FALSE, 12);
594 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), hbox);
595 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
597 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
598 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
599 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
601 gtk_widget_show_all(window);
604 void show_info_select_account(GObject *w, struct gaim_connection *gc)
606 struct getuserinfo *info = g_object_get_data(w, "getuserinfo");
607 info->gc = gc;
610 static void dialog_set_ok_sensitive(GtkWidget *entry, GtkWidget *dlg) {
611 const char *txt = gtk_entry_get_text(GTK_ENTRY(entry));
612 gtk_dialog_set_response_sensitive(GTK_DIALOG(dlg), GTK_RESPONSE_OK,
613 (*txt != '\0'));
616 void show_im_dialog()
618 GtkWidget *hbox, *vbox;
619 GtkWidget *label;
620 GtkWidget *table, *menu, *opt;
621 GSList *g = connections;
622 struct gaim_connection *c;
623 struct gaim_gtk_buddy_list *gtkblist;
624 char buf[256];
625 GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
626 struct getuserinfo *info = NULL;
628 gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
630 if (!imdialog) {
631 info = g_new0(struct getuserinfo, 1);
632 info->gc = connections->data;
633 imdialog = gtk_dialog_new_with_buttons(_("New Message"), gtkblist ? GTK_WINDOW(gtkblist->window) : NULL, 0,
634 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
635 gtk_dialog_set_default_response (GTK_DIALOG(imdialog), GTK_RESPONSE_OK);
636 gtk_container_set_border_width (GTK_CONTAINER(imdialog), 6);
637 gtk_window_set_resizable(GTK_WINDOW(imdialog), FALSE);
638 gtk_dialog_set_has_separator(GTK_DIALOG(imdialog), FALSE);
639 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(imdialog)->vbox), 12);
640 gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(imdialog)->vbox), 6);
641 gtk_dialog_set_response_sensitive(GTK_DIALOG(imdialog), GTK_RESPONSE_OK, FALSE);
643 hbox = gtk_hbox_new(FALSE, 12);
644 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(imdialog)->vbox), hbox);
645 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
646 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
648 vbox = gtk_vbox_new(FALSE, 0);
649 gtk_container_add(GTK_CONTAINER(hbox), vbox);
651 label = gtk_label_new(_("Please enter the screenname of the person you would like to IM.\n"));
652 gtk_widget_set_size_request(GTK_WIDGET(label), 350, -1);
653 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
654 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
655 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
657 hbox = gtk_hbox_new(FALSE, 6);
658 gtk_container_add(GTK_CONTAINER(vbox), hbox);
660 table = gtk_table_new(2, 2, FALSE);
661 gtk_table_set_row_spacings(GTK_TABLE(table), 6);
662 gtk_table_set_col_spacings(GTK_TABLE(table), 6);
663 gtk_container_set_border_width(GTK_CONTAINER(table), 12);
664 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
666 label = gtk_label_new(NULL);
667 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Screenname:"));
668 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
669 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
671 info->entry = gtk_entry_new();
672 gtk_table_attach_defaults(GTK_TABLE(table), info->entry, 1, 2, 0, 1);
673 gtk_entry_set_activates_default (GTK_ENTRY(info->entry), TRUE);
674 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(info->entry));
675 g_signal_connect(G_OBJECT(info->entry), "changed",
676 G_CALLBACK(dialog_set_ok_sensitive), imdialog);
678 if (connections->next) {
680 label = gtk_label_new(NULL);
681 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
682 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Account:"));
683 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
685 info->account = gtk_option_menu_new();
686 gtk_table_attach_defaults(GTK_TABLE(table), info->account, 1, 2, 1, 2);
687 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(info->account));
689 menu = gtk_menu_new();
691 while (g) {
692 c = (struct gaim_connection *)g->data;
694 if (!GAIM_PLUGIN_PROTOCOL_INFO(c->prpl)->send_im) {
695 g = g->next;
696 continue;
698 g_snprintf(buf, sizeof(buf), "%s (%s)",
699 c->username, c->prpl->info->name);
700 opt = gtk_menu_item_new_with_label(buf);
701 g_object_set_data(G_OBJECT(opt), "getuserinfo", info);
703 g_signal_connect(G_OBJECT(opt), "activate",
704 G_CALLBACK(show_info_select_account), c);
706 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
707 g = g->next;
710 gtk_option_menu_set_menu(GTK_OPTION_MENU(info->account), menu);
713 g_signal_connect(G_OBJECT(imdialog), "response", G_CALLBACK(do_im), info);
716 gtk_widget_show_all(imdialog);
717 if (info)
718 gtk_widget_grab_focus(GTK_WIDGET(info->entry));
721 void show_info_dialog()
723 GtkWidget *window, *hbox, *vbox;
724 GtkWidget *label;
725 GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
726 GtkWidget *table, *menu, *opt;
727 GSList *g = connections;
728 struct gaim_connection *c;
729 struct getuserinfo *info = g_new0(struct getuserinfo, 1);
730 struct gaim_gtk_buddy_list *gtkblist;
731 char buf[256];
733 gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
735 info->gc = connections->data;
737 window = gtk_dialog_new_with_buttons(_("Get User Info"), gtkblist->window ? GTK_WINDOW(gtkblist->window) : NULL, 0,
738 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
739 gtk_dialog_set_default_response (GTK_DIALOG(window), GTK_RESPONSE_OK);
740 gtk_container_set_border_width (GTK_CONTAINER(window), 6);
741 gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
742 gtk_dialog_set_has_separator(GTK_DIALOG(window), FALSE);
743 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(window)->vbox), 12);
744 gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(window)->vbox), 6);
746 hbox = gtk_hbox_new(FALSE, 12);
747 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), hbox);
748 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
749 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
750 gtk_dialog_set_response_sensitive(GTK_DIALOG(window), GTK_RESPONSE_OK,
751 FALSE);
753 vbox = gtk_vbox_new(FALSE, 0);
754 gtk_container_add(GTK_CONTAINER(hbox), vbox);
756 label = gtk_label_new(_("Please enter the screenname of the person whose info you would like to view.\n"));
757 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
758 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
759 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
761 table = gtk_table_new(2, 2, FALSE);
762 gtk_table_set_row_spacings(GTK_TABLE(table), 6);
763 gtk_table_set_col_spacings(GTK_TABLE(table), 6);
764 gtk_container_set_border_width(GTK_CONTAINER(table), 12);
765 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
767 label = gtk_label_new(NULL);
768 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Screenname:"));
769 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
770 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
772 info->entry = gtk_entry_new();
773 gtk_table_attach_defaults(GTK_TABLE(table), info->entry, 1, 2, 0, 1);
774 gtk_entry_set_activates_default (GTK_ENTRY(info->entry), TRUE);
775 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(info->entry));
777 g_signal_connect(G_OBJECT(info->entry), "changed",
778 G_CALLBACK(dialog_set_ok_sensitive), window);
780 if (connections->next) {
782 label = gtk_label_new(NULL);
783 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
784 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Account:"));
785 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
787 info->account = gtk_option_menu_new();
788 gtk_table_attach_defaults(GTK_TABLE(table), info->account, 1, 2, 1, 2);
789 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(info->account));
791 menu = gtk_menu_new();
793 while (g) {
794 c = (struct gaim_connection *)g->data;
796 if (!GAIM_PLUGIN_PROTOCOL_INFO(c->prpl)->get_info) {
797 g = g->next;
798 continue;
800 g_snprintf(buf, sizeof(buf), "%s (%s)",
801 c->username, c->prpl->info->name);
802 opt = gtk_menu_item_new_with_label(buf);
803 g_object_set_data(G_OBJECT(opt), "getuserinfo", info);
805 g_signal_connect(G_OBJECT(opt), "activate",
806 G_CALLBACK(show_info_select_account), c);
808 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
809 g = g->next;
812 gtk_option_menu_set_menu(GTK_OPTION_MENU(info->account), menu);
815 g_signal_connect(G_OBJECT(window), "response", G_CALLBACK(do_info), info);
818 gtk_widget_show_all(window);
819 if (info->entry)
820 gtk_widget_grab_focus(GTK_WIDGET(info->entry));
824 /*------------------------------------------------------------------------*/
825 /* The dialog for adding buddies */
826 /*------------------------------------------------------------------------*/
828 extern void add_callback(GtkWidget *, struct gaim_conversation *);
830 void do_add_buddy(GtkWidget *w, int resp, struct addbuddy *a)
832 const char *grp, *who, *whoalias;
833 struct gaim_conversation *c;
834 struct buddy *b;
835 struct group *g;
836 void *icon_data;
837 void *icon_data2;
838 int icon_len;
840 if (resp == GTK_RESPONSE_OK) {
842 who = gtk_entry_get_text(GTK_ENTRY(a->entry));
843 grp = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(a->combo)->entry));
844 whoalias = gtk_entry_get_text(GTK_ENTRY(a->entry_for_alias));
846 c = gaim_find_conversation(who);
847 if (!(g = gaim_find_group(grp))) {
848 g = gaim_group_new(grp);
849 gaim_blist_add_group(g, NULL);
851 b = gaim_buddy_new(a->gc->account, who, whoalias);
852 gaim_blist_add_buddy(b, g, NULL);
853 serv_add_buddy(a->gc, who);
855 if (c != NULL)
856 gaim_conversation_update(c, GAIM_CONV_UPDATE_ADD);
858 icon_data = get_icon_data(a->gc, normalize(who), &icon_len);
860 if(icon_data) {
861 icon_data2 = g_memdup(icon_data, icon_len);
862 set_icon_data(a->gc, who, icon_data2, icon_len);
863 g_free(icon_data2);
866 gaim_blist_save();
869 destroy_dialog(NULL, a->window);
872 void do_add_group(GtkWidget *w, int resp, struct addbuddy *a)
874 const char *grp;
875 struct group *g;
877 if (resp == GTK_RESPONSE_OK) {
878 grp = gtk_entry_get_text(GTK_ENTRY(a->entry));
880 if (!a->gc)
881 a->gc = connections->data;
883 g = gaim_group_new(grp);
884 gaim_blist_add_group (g, NULL);
885 gaim_blist_save();
888 destroy_dialog(NULL, a->window);
892 static GList *groups_tree()
894 GList *tmp = NULL;
895 char *tmp2;
896 struct group *g;
898 GaimBlistNode *gnode = gaim_get_blist()->root;
900 if (!gnode) {
901 tmp2 = g_strdup(_("Buddies"));
902 tmp = g_list_append(tmp, tmp2);
903 } else {
904 while (gnode) {
905 if(GAIM_BLIST_NODE_IS_GROUP(gnode)) {
906 g = (struct group *)gnode;
907 tmp2 = g->name;
908 tmp = g_list_append(tmp, tmp2);
910 gnode = gnode->next;
913 return tmp;
916 static void free_dialog(GtkWidget *w, struct addbuddy *a)
918 g_free(a);
922 void show_add_group(struct gaim_connection *gc)
925 GtkWidget *hbox, *vbox;
926 GtkWidget *label;
927 struct gaim_gtk_buddy_list *gtkblist;
928 GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
929 struct addbuddy *a = g_new0(struct addbuddy, 1);
931 gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
933 a->gc = gc;
935 a->window = gtk_dialog_new_with_buttons(_("Add Group"), GTK_WINDOW(gtkblist->window), 0,
936 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_ADD, GTK_RESPONSE_OK, NULL);
937 gtk_dialog_set_default_response (GTK_DIALOG(a->window), GTK_RESPONSE_OK);
938 gtk_container_set_border_width (GTK_CONTAINER(a->window), 6);
939 gtk_window_set_resizable(GTK_WINDOW(a->window), FALSE);
940 gtk_dialog_set_has_separator(GTK_DIALOG(a->window), FALSE);
941 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(a->window)->vbox), 12);
942 gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(a->window)->vbox), 6);
944 hbox = gtk_hbox_new(FALSE, 12);
945 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(a->window)->vbox), hbox);
946 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
947 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
949 vbox = gtk_vbox_new(FALSE, 0);
950 gtk_container_add(GTK_CONTAINER(hbox), vbox);
952 label = gtk_label_new(_("Please enter the name of the group to be added.\n"));
953 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
954 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
955 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
957 hbox = gtk_hbox_new(FALSE, 6);
958 gtk_container_add(GTK_CONTAINER(vbox), hbox);
960 label = gtk_label_new(NULL);
961 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Group:"));
962 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
964 a->entry = gtk_entry_new();
965 gtk_entry_set_activates_default (GTK_ENTRY(a->entry), TRUE);
966 gtk_box_pack_start(GTK_BOX(hbox), a->entry, FALSE, FALSE, 0);
967 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(a->entry));
969 g_signal_connect(G_OBJECT(a->window), "response", G_CALLBACK(do_add_group), a);
971 gtk_widget_show_all(a->window);
972 gtk_widget_grab_focus(GTK_WIDGET(a->entry));
975 static void addbuddy_select_account(GObject *w, struct gaim_connection *gc)
977 struct addbuddy *b = g_object_get_data(w, "addbuddy");
979 /* Save our account */
980 b->gc = gc;
983 static void create_online_user_names(struct addbuddy *b)
985 char buf[2048]; /* Never hurts to be safe ;-) */
986 GSList *g = connections;
987 struct gaim_connection *c;
988 GtkWidget *menu, *opt;
989 int count = 0;
990 int place = 0;
992 menu = gtk_menu_new();
994 while (g) {
995 c = (struct gaim_connection *)g->data;
996 g_snprintf(buf, sizeof(buf), "%s (%s)",
997 c->username, c->prpl->info->name);
998 opt = gtk_menu_item_new_with_label(buf);
999 g_object_set_data(G_OBJECT(opt), "addbuddy", b);
1000 g_signal_connect(G_OBJECT(opt), "activate",
1001 G_CALLBACK(addbuddy_select_account),
1003 gtk_widget_show(opt);
1004 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
1006 /* Now check to see if it's our current menu */
1007 if (c == b->gc) {
1008 place = count;
1009 gtk_menu_item_activate(GTK_MENU_ITEM(opt));
1010 gtk_option_menu_set_history(GTK_OPTION_MENU(b->account), count);
1012 /* Do the cha cha cha */
1015 count++;
1017 g = g->next;
1020 gtk_option_menu_remove_menu(GTK_OPTION_MENU(b->account));
1021 gtk_option_menu_set_menu(GTK_OPTION_MENU(b->account), menu);
1022 gtk_option_menu_set_history(GTK_OPTION_MENU(b->account), place);
1024 gtk_widget_show(b->account);
1025 gtk_widget_show(b->account->parent);
1029 void show_add_buddy(struct gaim_connection *gc, char *buddy, char *group, char *alias)
1031 GtkWidget *table;
1032 GtkWidget *label;
1033 GtkWidget *hbox;
1034 GtkWidget *vbox;
1035 struct gaim_gtk_buddy_list *gtkblist;
1036 GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
1037 struct addbuddy *a = g_new0(struct addbuddy, 1);
1038 a->gc = gc ? gc : connections->data;
1040 gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
1042 GAIM_DIALOG(a->window);
1043 a->window = gtk_dialog_new_with_buttons(_("Add Buddy"), gtkblist->window ? GTK_WINDOW(gtkblist->window) : NULL, 0,
1044 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_ADD, GTK_RESPONSE_OK, NULL);
1046 gtk_dialog_set_default_response(GTK_DIALOG(a->window), GTK_RESPONSE_OK);
1047 gtk_container_set_border_width(GTK_CONTAINER(a->window), 6);
1048 gtk_window_set_resizable(GTK_WINDOW(a->window), FALSE);
1049 gtk_dialog_set_has_separator(GTK_DIALOG(a->window), FALSE);
1050 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(a->window)->vbox), 12);
1051 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(a->window)->vbox), 6);
1052 gtk_window_set_role(GTK_WINDOW(a->window), "add_buddy");
1054 hbox = gtk_hbox_new(FALSE, 12);
1055 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(a->window)->vbox), hbox);
1056 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
1057 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
1059 vbox = gtk_vbox_new(FALSE, 0);
1060 gtk_container_add(GTK_CONTAINER(hbox), vbox);
1062 label = gtk_label_new(_("Please enter the screen name of the person you would like to add to your buddy list. You may optionally enter an alias, or nickname, for the buddy. The alias will be displayed in place of the screen name whenever possible.\n"));
1063 gtk_widget_set_size_request(GTK_WIDGET(label), 400, -1);
1064 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1065 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
1066 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
1068 hbox = gtk_hbox_new(FALSE, 6);
1069 gtk_container_add(GTK_CONTAINER(vbox), hbox);
1071 g_signal_connect(G_OBJECT(a->window), "destroy", G_CALLBACK(destroy_dialog), a->window);
1072 g_signal_connect(G_OBJECT(a->window), "destroy", G_CALLBACK(free_dialog), a);
1073 dialogwindows = g_list_prepend(dialogwindows, a->window);
1075 table = gtk_table_new(4, 2, FALSE);
1076 gtk_table_set_row_spacings(GTK_TABLE(table), 5);
1077 gtk_table_set_col_spacings(GTK_TABLE(table), 5);
1078 gtk_container_set_border_width(GTK_CONTAINER(table), 0);
1079 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
1081 label = gtk_label_new(_("Screen Name"));
1082 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1083 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
1085 a->entry = gtk_entry_new();
1086 gtk_table_attach_defaults(GTK_TABLE(table), a->entry, 1, 2, 0, 1);
1087 gtk_widget_grab_focus(a->entry);
1089 if (buddy != NULL)
1090 gtk_entry_set_text(GTK_ENTRY(a->entry), buddy);
1092 gtk_entry_set_activates_default (GTK_ENTRY(a->entry), TRUE);
1094 label = gtk_label_new(_("Alias"));
1095 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1096 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
1098 a->entry_for_alias = gtk_entry_new();
1099 gtk_table_attach_defaults(GTK_TABLE(table), a->entry_for_alias, 1, 2, 1, 2);
1100 if (alias != NULL)
1101 gtk_entry_set_text(GTK_ENTRY(a->entry_for_alias), alias);
1102 gtk_entry_set_activates_default (GTK_ENTRY(a->entry_for_alias), TRUE);
1104 label = gtk_label_new(_("Group"));
1105 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1106 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 2, 3);
1108 a->combo = gtk_combo_new();
1109 gtk_combo_set_popdown_strings(GTK_COMBO(a->combo), groups_tree());
1110 gtk_table_attach_defaults(GTK_TABLE(table), a->combo, 1, 2, 2, 3);
1112 /* Set up stuff for the account box */
1113 label = gtk_label_new(_("Add To"));
1114 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1115 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4);
1117 a->account = gtk_option_menu_new();
1118 gtk_table_attach_defaults(GTK_TABLE(table), a->account, 1, 2, 3, 4);
1120 create_online_user_names(a);
1122 /* End of account box */
1124 g_signal_connect(G_OBJECT(a->window), "response", G_CALLBACK(do_add_buddy), a);
1126 gtk_widget_show_all(a->window);
1128 if (group != NULL)
1129 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(a->combo)->entry), group);
1132 struct addchat {
1133 struct gaim_account *account;
1134 GtkWidget *window;
1135 GtkWidget *account_menu;
1136 GtkWidget *alias_entry;
1137 GtkWidget *group_combo;
1138 GtkWidget *entries_box;
1139 GtkSizeGroup *sg;
1140 GList *entries;
1143 static void do_add_chat(GtkWidget *w, struct addchat *ac) {
1144 GHashTable *components = g_hash_table_new_full(g_str_hash, g_str_equal,
1145 g_free, g_free);
1146 GList *tmp;
1148 struct chat *chat;
1149 struct group *group;
1150 const char *group_name;
1152 for(tmp = ac->entries; tmp; tmp = tmp->next) {
1153 if(g_object_get_data(tmp->data, "is_spin")) {
1154 g_hash_table_replace(components,
1155 g_strdup(g_object_get_data(tmp->data, "identifier")),
1156 g_strdup_printf("%d",
1157 gtk_spin_button_get_value_as_int(tmp->data)));
1158 } else {
1159 g_hash_table_replace(components,
1160 g_strdup(g_object_get_data(tmp->data, "identifier")),
1161 g_strdup(gtk_entry_get_text(tmp->data)));
1165 chat = gaim_chat_new(ac->account, gtk_entry_get_text(GTK_ENTRY(ac->alias_entry)), components);
1167 group_name = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(ac->group_combo)->entry));
1168 if (!(group = gaim_find_group(group_name))) {
1169 group = gaim_group_new(group_name);
1170 gaim_blist_add_group(group, NULL);
1173 if(chat) {
1174 gaim_blist_add_chat(chat, group, NULL);
1175 gaim_blist_save();
1178 gtk_widget_destroy(ac->window);
1179 g_list_free(ac->entries);
1181 g_free(ac);
1184 static void do_add_chat_resp(GtkWidget *w, int resp, struct addchat *ac) {
1185 if(resp == GTK_RESPONSE_OK) {
1186 do_add_chat(NULL, ac);
1187 } else {
1188 gtk_widget_destroy(ac->window);
1189 g_list_free(ac->entries);
1190 g_free(ac);
1195 static void rebuild_addchat_entries(struct addchat *ac) {
1196 GList *list, *tmp;
1197 struct proto_chat_entry *pce;
1198 gboolean focus = TRUE;
1200 while(GTK_BOX(ac->entries_box)->children)
1201 gtk_container_remove(GTK_CONTAINER(ac->entries_box),
1202 ((GtkBoxChild *)GTK_BOX(ac->entries_box)->children->data)->widget);
1204 if(ac->entries)
1205 g_list_free(ac->entries);
1207 ac->entries = NULL;
1209 list = GAIM_PLUGIN_PROTOCOL_INFO(ac->account->gc->prpl)->chat_info(ac->account->gc);
1211 for(tmp = list; tmp; tmp = tmp->next) {
1212 GtkWidget *label;
1213 GtkWidget *rowbox;
1214 pce = tmp->data;
1216 rowbox = gtk_hbox_new(FALSE, 5);
1217 gtk_box_pack_start(GTK_BOX(ac->entries_box), rowbox, FALSE, FALSE, 0);
1219 label = gtk_label_new(pce->label);
1220 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1221 gtk_size_group_add_widget(ac->sg, label);
1222 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
1224 if(pce->is_int) {
1225 GtkObject *adjust;
1226 GtkWidget *spin;
1227 adjust = gtk_adjustment_new(pce->min, pce->min, pce->max,
1228 1, 10, 10);
1229 spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjust), 1, 0);
1230 g_object_set_data(G_OBJECT(spin), "is_spin", GINT_TO_POINTER(TRUE));
1231 g_object_set_data(G_OBJECT(spin), "identifier", pce->identifier);
1232 ac->entries = g_list_append(ac->entries, spin);
1233 gtk_widget_set_size_request(spin, 50, -1);
1234 gtk_box_pack_end(GTK_BOX(rowbox), spin, FALSE, FALSE, 0);
1235 } else {
1236 GtkWidget *entry = gtk_entry_new();
1237 g_object_set_data(G_OBJECT(entry), "identifier", pce->identifier);
1238 ac->entries = g_list_append(ac->entries, entry);
1240 if(pce->def)
1241 gtk_entry_set_text(GTK_ENTRY(entry), pce->def);
1243 if(focus) {
1244 gtk_widget_grab_focus(entry);
1245 focus = FALSE;
1248 gtk_box_pack_end(GTK_BOX(rowbox), entry, TRUE, TRUE, 0);
1250 g_signal_connect(G_OBJECT(entry), "activate",
1251 G_CALLBACK(do_add_chat), ac);
1253 g_free(pce);
1256 gtk_widget_show_all(ac->entries_box);
1259 static void addchat_select_account(GObject *w, struct gaim_connection *gc)
1261 struct addchat *ac = g_object_get_data(w, "addchat");
1263 if(ac->account->protocol == gc->account->protocol) {
1264 ac->account = gc->account;
1265 } else {
1266 ac->account = gc->account;
1267 rebuild_addchat_entries(ac);
1271 static void create_online_account_menu_for_add_chat(struct addchat *ac)
1273 char buf[2048]; /* Never hurts to be safe ;-) */
1274 GSList *g = connections;
1275 struct gaim_connection *c;
1276 GtkWidget *menu, *opt;
1277 int count = 0;
1278 int place = 0;
1280 menu = gtk_menu_new();
1282 while (g) {
1283 c = (struct gaim_connection *)g->data;
1284 if (GAIM_PLUGIN_PROTOCOL_INFO(c->prpl)->join_chat) {
1285 g_snprintf(buf, sizeof(buf), "%s (%s)",
1286 c->username, c->prpl->info->name);
1287 opt = gtk_menu_item_new_with_label(buf);
1288 g_object_set_data(G_OBJECT(opt), "addchat", ac);
1289 g_signal_connect(G_OBJECT(opt), "activate",
1290 G_CALLBACK(addchat_select_account),
1292 gtk_widget_show(opt);
1293 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
1295 /* Now check to see if it's our current menu */
1296 if (c->account == ac->account) {
1297 place = count;
1298 gtk_menu_item_activate(GTK_MENU_ITEM(opt));
1299 gtk_option_menu_set_history(GTK_OPTION_MENU(ac->account_menu), count);
1301 /* Do the cha cha cha */
1304 count++;
1307 g = g->next;
1310 gtk_option_menu_remove_menu(GTK_OPTION_MENU(ac->account_menu));
1311 gtk_option_menu_set_menu(GTK_OPTION_MENU(ac->account_menu), menu);
1312 gtk_option_menu_set_history(GTK_OPTION_MENU(ac->account_menu), place);
1315 void show_add_chat(struct gaim_account *account, struct group *group) {
1316 struct addchat *ac = g_new0(struct addchat, 1);
1317 struct gaim_gtk_buddy_list *gtkblist;
1318 GSList *c;
1319 struct gaim_connection *gc;
1321 GtkWidget *label;
1322 GtkWidget *rowbox;
1323 GtkWidget *hbox;
1324 GtkWidget *vbox;
1325 GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION,
1326 GTK_ICON_SIZE_DIALOG);
1328 gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
1330 if (account) {
1331 ac->account = account;
1332 } else {
1333 /* Select an account with chat capabilities */
1334 for (c = connections; c != NULL; c = c->next) {
1335 gc = c->data;
1337 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->join_chat) {
1338 ac->account = gc->account;
1339 break;
1344 if (!ac->account) {
1345 gaim_notify_error(NULL, NULL,
1346 _("You are not currently signed on with any "
1347 "protocols that have the ability to chat."), NULL);
1348 return;
1351 ac->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1353 ac->window = gtk_dialog_new_with_buttons(_("Add Chat"),
1354 GTK_WINDOW(gtkblist->window), 0,
1355 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1356 GTK_STOCK_ADD, GTK_RESPONSE_OK,
1357 NULL);
1359 gtk_dialog_set_default_response(GTK_DIALOG(ac->window), GTK_RESPONSE_OK);
1360 gtk_container_set_border_width(GTK_CONTAINER(ac->window), 6);
1361 gtk_window_set_resizable(GTK_WINDOW(ac->window), FALSE);
1362 gtk_dialog_set_has_separator(GTK_DIALOG(ac->window), FALSE);
1363 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(ac->window)->vbox), 12);
1364 gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(ac->window)->vbox),
1366 gtk_window_set_role(GTK_WINDOW(ac->window), "add_chat");
1368 hbox = gtk_hbox_new(FALSE, 12);
1369 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(ac->window)->vbox), hbox);
1370 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
1371 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
1373 vbox = gtk_vbox_new(FALSE, 5);
1374 gtk_container_add(GTK_CONTAINER(hbox), vbox);
1376 label = gtk_label_new(_("Please enter an alias, and the appropriate information about the chat you would like to add to your buddy list.\n"));
1377 gtk_widget_set_size_request(label, 400, -1);
1378 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1379 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
1380 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
1382 rowbox = gtk_hbox_new(FALSE, 5);
1383 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0);
1385 label = gtk_label_new(_("Account:"));
1386 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1387 gtk_size_group_add_widget(ac->sg, label);
1388 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
1390 ac->account_menu = gtk_option_menu_new();
1391 gtk_box_pack_end(GTK_BOX(rowbox), ac->account_menu, TRUE, TRUE, 0);
1393 create_online_account_menu_for_add_chat(ac);
1395 ac->entries_box = gtk_vbox_new(FALSE, 5);
1396 gtk_container_set_border_width(GTK_CONTAINER(ac->entries_box), 0);
1397 gtk_box_pack_start(GTK_BOX(vbox), ac->entries_box, TRUE, TRUE, 0);
1399 rebuild_addchat_entries(ac);
1401 rowbox = gtk_hbox_new(FALSE, 5);
1402 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0);
1404 label = gtk_label_new(_("Alias:"));
1405 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1406 gtk_size_group_add_widget(ac->sg, label);
1407 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
1409 ac->alias_entry = gtk_entry_new();
1410 gtk_box_pack_end(GTK_BOX(rowbox), ac->alias_entry, TRUE, TRUE, 0);
1412 rowbox = gtk_hbox_new(FALSE, 5);
1413 gtk_box_pack_start(GTK_BOX(vbox), rowbox, FALSE, FALSE, 0);
1415 label = gtk_label_new(_("Group:"));
1416 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1417 gtk_size_group_add_widget(ac->sg, label);
1418 gtk_box_pack_start(GTK_BOX(rowbox), label, FALSE, FALSE, 0);
1420 ac->group_combo = gtk_combo_new();
1421 gtk_combo_set_popdown_strings(GTK_COMBO(ac->group_combo), groups_tree());
1422 gtk_box_pack_end(GTK_BOX(rowbox), ac->group_combo, TRUE, TRUE, 0);
1424 if (group)
1425 gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(ac->group_combo)->entry), group->name);
1427 g_signal_connect(G_OBJECT(ac->window), "response", G_CALLBACK(do_add_chat_resp), ac);
1429 gtk_widget_show_all(ac->window);
1434 /*------------------------------------------------------------------------*
1435 * Privacy Settings *
1436 *------------------------------------------------------------------------*/
1437 static GtkWidget *deny_type = NULL;
1438 static GtkWidget *deny_conn_hbox = NULL;
1439 static GtkWidget *deny_opt_menu = NULL;
1440 static struct gaim_connection *current_deny_gc = NULL;
1441 static gboolean current_is_deny = FALSE;
1442 static GtkWidget *allow_list = NULL;
1443 static GtkWidget *block_list = NULL;
1445 static GtkListStore *block_store = NULL;
1446 static GtkListStore *allow_store = NULL;
1448 static void set_deny_mode(GtkWidget *w, int data)
1450 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
1451 return;
1453 gaim_debug(GAIM_DEBUG_INFO, "privacy", "Setting deny mode %d\n", data);
1454 current_deny_gc->account->permdeny = data;
1455 serv_set_permit_deny(current_deny_gc);
1456 gaim_blist_save();
1459 static GtkWidget *deny_opt(char *label, int which, GtkWidget *set)
1461 GtkWidget *opt;
1463 if (!set)
1464 opt = gtk_radio_button_new_with_label(NULL, label);
1465 else
1466 opt =
1467 gtk_radio_button_new_with_label(gtk_radio_button_get_group(
1468 GTK_RADIO_BUTTON(set)),
1469 label);
1471 g_signal_connect(G_OBJECT(opt), "toggled", G_CALLBACK(set_deny_mode), (void *)which);
1472 gtk_widget_show(opt);
1473 if (current_deny_gc->account->permdeny == which)
1474 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt), TRUE);
1476 return opt;
1479 static void des_deny_opt(GtkWidget *d, gpointer e)
1481 gtk_widget_destroy(d);
1482 current_deny_gc = NULL;
1483 deny_conn_hbox = NULL;
1484 deny_type = NULL;
1485 deny_opt_menu = NULL;
1486 current_is_deny = FALSE;
1487 allow_list = NULL;
1488 allow_store = NULL;
1490 block_list = NULL;
1491 block_store = NULL;
1494 static void set_deny_type()
1496 GSList *bg = gtk_radio_button_get_group(GTK_RADIO_BUTTON(deny_type));
1498 switch (current_deny_gc->account->permdeny) {
1499 case 5:
1500 bg = bg->next->next;
1501 break;
1502 case 4:
1503 break;
1504 case 3:
1505 bg = bg->next->next->next;
1506 break;
1507 case 2:
1508 bg = bg->next;
1509 break;
1510 case 1:
1511 bg = bg->next->next->next->next;
1512 break;
1515 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bg->data), TRUE);
1518 void build_allow_list()
1520 GSList *p;
1521 GtkListStore *ls;
1522 GtkTreeIter iter;
1524 if (!current_is_deny)
1525 return;
1527 p = current_deny_gc->account->permit;
1529 gtk_list_store_clear(GTK_LIST_STORE(allow_store));
1531 while (p) {
1532 ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(allow_list)));
1534 gtk_list_store_append(ls, &iter);
1535 gtk_list_store_set(ls, &iter, 0, p->data, -1);
1537 p = p->next;
1542 void build_block_list()
1544 GSList *d;
1545 GtkListStore *ls;
1546 GtkTreeIter iter;
1548 if (!current_is_deny)
1549 return;
1551 d = current_deny_gc->account->deny;
1553 gtk_list_store_clear(GTK_LIST_STORE(block_store));
1555 while (d) {
1556 ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(block_list)));
1558 gtk_list_store_append(ls, &iter);
1559 gtk_list_store_set(ls, &iter, 0, d->data, -1);
1561 d = d->next;
1565 static void deny_gc_opt(GtkWidget *opt, struct gaim_connection *gc)
1567 current_deny_gc = gc;
1568 set_deny_type();
1569 build_allow_list();
1570 build_block_list();
1573 static void build_deny_menu()
1575 GtkWidget *menu;
1576 GtkWidget *opt;
1577 GSList *c = connections;
1578 struct gaim_connection *gc;
1579 int count = 0;
1580 gboolean found = FALSE;
1581 char buf[2048];
1583 if (g_slist_length(connections) == 1) {
1584 gtk_widget_hide(deny_conn_hbox);
1585 return;
1586 } else
1587 gtk_widget_show(deny_conn_hbox);
1589 menu = gtk_menu_new();
1591 while (c) {
1592 gc = (struct gaim_connection *)c->data;
1593 c = c->next;
1595 if (!GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->set_permit_deny)
1596 continue;
1598 g_snprintf(buf, sizeof buf, "%s (%s)",
1599 gc->username, gc->prpl->info->name);
1600 opt = gtk_menu_item_new_with_label(buf);
1601 g_signal_connect(G_OBJECT(opt), "activate", G_CALLBACK(deny_gc_opt), gc);
1602 gtk_widget_show(opt);
1603 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
1604 if (gc == current_deny_gc)
1605 found = TRUE;
1606 else if (!found)
1607 count++;
1610 if (!found) {
1611 current_deny_gc = connections->data;
1612 count = 0;
1615 gtk_option_menu_remove_menu(GTK_OPTION_MENU(deny_opt_menu));
1616 gtk_option_menu_set_menu(GTK_OPTION_MENU(deny_opt_menu), menu);
1617 gtk_option_menu_set_history(GTK_OPTION_MENU(deny_opt_menu), count);
1619 gtk_widget_show(menu);
1620 gtk_widget_show(deny_opt_menu);
1623 static void pref_deny_add(GtkWidget *button, gboolean permit)
1625 show_add_perm(current_deny_gc, NULL, permit);
1629 gchar *find_permdeny_by_name(GSList *l, char *who) {
1630 gchar *name;
1632 while (l) {
1633 name = (gchar *)l->data;
1634 if (!strcmp(name, who)) {
1635 return name;
1638 l = l->next;
1641 return NULL;
1644 static void pref_deny_rem(GtkWidget *button, gboolean permit)
1646 gchar *who;
1647 GtkTreeIter iter;
1648 GtkTreeModel *mod;
1649 GtkTreeSelection *sel;
1651 if (permit) {
1652 mod = gtk_tree_view_get_model(GTK_TREE_VIEW(allow_list));
1653 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(allow_list));
1654 } else {
1655 mod = gtk_tree_view_get_model(GTK_TREE_VIEW(block_list));
1656 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(block_list));
1659 if (gtk_tree_selection_get_selected(sel, NULL, &iter))
1660 gtk_tree_model_get(GTK_TREE_MODEL(mod), &iter, 0, &who, -1);
1661 else {
1662 return;
1665 if (permit && !allow_list)
1666 return;
1668 if (!permit && !block_list)
1669 return;
1671 if (permit) {
1672 char *name = find_permdeny_by_name(current_deny_gc->account->permit, who);
1674 if (name) {
1675 gaim_privacy_permit_remove(current_deny_gc->account, name);
1676 serv_rem_permit(current_deny_gc, who);
1677 build_allow_list();
1679 } else {
1680 char *name = find_permdeny_by_name(current_deny_gc->account->deny, who);
1682 if (name) {
1683 gaim_privacy_deny_remove(current_deny_gc->account, name);
1684 serv_rem_deny(current_deny_gc, who);
1685 build_block_list();
1689 gaim_blist_save();
1692 GtkWidget *privacy_win;
1693 void update_privacy_connections() { /* This is a slightly better name */
1694 gboolean needdeny = FALSE;
1695 GSList *c = connections;
1696 struct gaim_connection *gc = NULL;
1698 if (!privacy_win)
1699 return;
1701 while (c) {
1702 gc = c->data;
1703 if (GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl)->set_permit_deny)
1704 break;
1705 gc = NULL;
1706 c = c->next;
1708 needdeny = (gc != NULL);
1711 if (needdeny) {
1712 gtk_widget_set_sensitive(privacy_win, TRUE);
1713 build_deny_menu();
1714 build_allow_list();
1715 build_block_list();
1716 } else {
1717 gtk_widget_set_sensitive(privacy_win, FALSE);
1720 static void destroy_privacy() {
1721 current_deny_gc = NULL;
1722 privacy_win = NULL;
1725 void show_privacy_options() {
1726 GtkWidget *pwin;
1727 GtkWidget *box;
1728 GtkWidget *hbox;
1729 GtkWidget *label;
1730 GtkWidget *sw;
1731 GtkWidget *bbox;
1732 GtkWidget *button;
1733 GtkWidget *sep;
1734 GtkWidget *close_button;
1735 GtkSizeGroup *sg1 = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
1736 GtkSizeGroup *sg2 = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
1737 GtkCellRenderer *rend;
1738 GtkTreeViewColumn *col;
1739 GtkWidget *table;
1741 current_deny_gc = connections->data; /* this is safe because this screen will only be
1742 available when there are connections */
1743 current_is_deny = TRUE;
1745 privacy_win = pwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1746 gtk_window_set_resizable(GTK_WINDOW(pwin), FALSE);
1747 gtk_window_set_role(GTK_WINDOW(pwin), "privacy");
1748 gtk_window_set_title(GTK_WINDOW(pwin), _("Privacy"));
1749 g_signal_connect(G_OBJECT(pwin), "destroy", G_CALLBACK(destroy_privacy), NULL);
1750 gtk_widget_realize(pwin);
1752 gtk_widget_set_size_request(pwin, -1, 400);
1754 box = gtk_vbox_new(FALSE, 5);
1755 gtk_container_set_border_width(GTK_CONTAINER(box), 5);
1756 gtk_container_add(GTK_CONTAINER(pwin), box);
1757 gtk_widget_show(box);
1759 label = gtk_label_new(_("Changes to privacy settings take effect immediately."));
1760 gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 5);
1761 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1762 gtk_widget_show(label);
1764 deny_conn_hbox = gtk_hbox_new(FALSE, 5);
1765 gtk_box_pack_start(GTK_BOX(box), deny_conn_hbox, FALSE, FALSE, 0);
1766 gtk_widget_show(deny_conn_hbox);
1768 label = gtk_label_new(_("Set privacy for:"));
1769 gtk_box_pack_start(GTK_BOX(deny_conn_hbox), label, FALSE, FALSE, 5);
1770 gtk_widget_show(label);
1772 deny_opt_menu = gtk_option_menu_new();
1773 gtk_box_pack_start(GTK_BOX(deny_conn_hbox), deny_opt_menu, FALSE, FALSE, 5);
1774 g_signal_connect(G_OBJECT(deny_opt_menu), "destroy", G_CALLBACK(des_deny_opt), NULL);
1775 gtk_widget_show(deny_opt_menu);
1777 build_deny_menu();
1779 table = gtk_table_new(5, 2, FALSE);
1780 gtk_box_pack_start(GTK_BOX(box), table, TRUE, TRUE, 0);
1781 gtk_table_set_row_spacings(GTK_TABLE(table), 7);
1782 gtk_table_set_col_spacings(GTK_TABLE(table), 5);
1783 gtk_widget_show(table);
1785 deny_type = deny_opt(_("Allow all users to contact me"), 1, NULL);
1786 gtk_size_group_add_widget(sg1, deny_type);
1787 gtk_table_attach(GTK_TABLE(table), deny_type, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
1789 deny_type = deny_opt(_("Allow only users on my buddy list"), 5, deny_type);
1790 gtk_size_group_add_widget(sg1, deny_type);
1791 gtk_table_attach(GTK_TABLE(table), deny_type, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
1793 deny_type = deny_opt(_("Allow only the users below"), 3, deny_type);
1794 gtk_size_group_add_widget(sg1, deny_type);
1795 gtk_table_attach(GTK_TABLE(table), deny_type, 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
1797 sw = gtk_scrolled_window_new(NULL, NULL);
1798 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1799 gtk_table_attach(GTK_TABLE(table), sw, 0, 1, 3, 4, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
1800 gtk_widget_show(sw);
1802 allow_store = gtk_list_store_new(1, G_TYPE_STRING);
1803 allow_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(allow_store));
1805 rend = gtk_cell_renderer_text_new();
1806 col = gtk_tree_view_column_new_with_attributes(NULL, rend, "text", 0, NULL);
1807 gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(col), TRUE);
1808 gtk_tree_view_append_column(GTK_TREE_VIEW(allow_list), col);
1809 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(allow_list), FALSE);
1810 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), allow_list);
1811 gtk_widget_show(allow_list);
1813 build_allow_list();
1815 bbox = gtk_hbox_new(TRUE, 0);
1816 gtk_widget_show(bbox);
1817 gtk_table_attach(GTK_TABLE(table), bbox, 0, 1, 4, 5, GTK_FILL, 0, 0, 0);
1819 button = gtk_button_new_from_stock(GTK_STOCK_ADD);
1820 gtk_size_group_add_widget(sg2, button);
1821 gtk_widget_show(button);
1822 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(pref_deny_add), (void *)TRUE);
1823 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
1825 button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
1826 gtk_size_group_add_widget(sg2, button);
1827 gtk_widget_show(button);
1828 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(pref_deny_rem), (void *)TRUE);
1829 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
1831 deny_type = deny_opt(_("Deny all users"), 2, deny_type);
1832 gtk_size_group_add_widget(sg1, deny_type);
1833 gtk_table_attach(GTK_TABLE(table), deny_type, 1, 2, 1, 2, GTK_FILL, 0, 0, 0);
1835 deny_type = deny_opt(_("Block the users below"), 4, deny_type);
1836 gtk_size_group_add_widget(sg1, deny_type);
1837 gtk_table_attach(GTK_TABLE(table), deny_type, 1, 2, 2, 3, GTK_FILL, 0, 0, 0);
1839 sw = gtk_scrolled_window_new(NULL, NULL);
1840 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1841 gtk_table_attach(GTK_TABLE(table), sw, 1, 2, 3, 4, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
1842 gtk_widget_show(sw);
1844 block_store = gtk_list_store_new(1, G_TYPE_STRING);
1845 block_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(block_store));
1847 rend = gtk_cell_renderer_text_new();
1848 col = gtk_tree_view_column_new_with_attributes(NULL, rend, "text", 0, NULL);
1849 gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(col), TRUE);
1850 gtk_tree_view_append_column(GTK_TREE_VIEW(block_list), col);
1851 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(block_list), FALSE);
1852 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), block_list);
1853 gtk_widget_show(block_list);
1855 build_block_list();
1857 bbox = gtk_hbox_new(TRUE, 0);
1858 gtk_table_attach(GTK_TABLE(table), bbox, 1, 2, 4, 5, GTK_FILL, 0, 0, 0);
1859 gtk_widget_show(bbox);
1861 button = gtk_button_new_from_stock(GTK_STOCK_ADD);
1862 gtk_size_group_add_widget(sg2, button);
1863 gtk_widget_show(button);
1864 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(pref_deny_add), FALSE);
1865 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
1867 button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
1868 gtk_size_group_add_widget(sg2, button);
1869 gtk_widget_show(button);
1870 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(pref_deny_rem), FALSE);
1871 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
1873 sep = gtk_hseparator_new();
1874 gtk_box_pack_start(GTK_BOX(box), sep, FALSE, FALSE, 5);
1875 gtk_widget_show(sep);
1877 hbox = gtk_hbox_new(FALSE, 0);
1878 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
1879 gtk_widget_show(hbox);
1881 close_button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
1882 gtk_box_pack_end(GTK_BOX(hbox), close_button, FALSE, FALSE, 0);
1883 g_signal_connect_swapped(G_OBJECT(close_button), "clicked", G_CALLBACK(gtk_widget_destroy), pwin);
1884 gtk_widget_show(close_button);
1886 gtk_widget_show(pwin);
1891 /*------------------------------------------------------------------------*/
1892 /* The dialog for SET INFO / SET DIR INFO */
1893 /*------------------------------------------------------------------------*/
1895 void do_save_info(GtkWidget *widget, struct set_info_dlg *b)
1897 gchar *junk;
1898 struct gaim_connection *gc;
1900 junk = gtk_text_view_get_text(GTK_TEXT_VIEW(b->text), FALSE);
1902 if (b->account) {
1903 strncpy_withhtml(b->account->user_info, junk, sizeof b->account->user_info);
1904 gc = b->account->gc;
1906 save_prefs();
1908 if (gc)
1909 serv_set_info(gc, b->account->user_info);
1911 g_free(junk);
1912 destroy_dialog(NULL, b->window);
1913 g_free(b);
1916 void do_set_dir(GtkWidget *widget, struct set_dir_dlg *b)
1918 const char *first = gtk_entry_get_text(GTK_ENTRY(b->first));
1919 int web = GTK_TOGGLE_BUTTON(b->web)->active;
1920 const char *middle = gtk_entry_get_text(GTK_ENTRY(b->middle));
1921 const char *last = gtk_entry_get_text(GTK_ENTRY(b->last));
1922 const char *maiden = gtk_entry_get_text(GTK_ENTRY(b->maiden));
1923 const char *city = gtk_entry_get_text(GTK_ENTRY(b->city));
1924 const char *state = gtk_entry_get_text(GTK_ENTRY(b->state));
1925 const char *country = gtk_entry_get_text(GTK_ENTRY(b->country));
1927 serv_set_dir(b->gc, first, middle, last, maiden, city, state, country, web);
1929 destroy_dialog(NULL, b->window);
1930 g_free(b);
1933 void show_set_dir(struct gaim_connection *gc)
1935 GtkWidget *label;
1936 GtkWidget *bot;
1937 GtkWidget *vbox;
1938 GtkWidget *hbox;
1939 GtkWidget *frame;
1940 GtkWidget *fbox;
1941 char buf[256];
1943 struct set_dir_dlg *b = g_new0(struct set_dir_dlg, 1);
1944 b->gc = gc;
1946 GAIM_DIALOG(b->window);
1947 dialogwindows = g_list_prepend(dialogwindows, b->window);
1948 gtk_window_set_role(GTK_WINDOW(b->window), "set_dir");
1949 gtk_window_set_resizable(GTK_WINDOW(b->window), TRUE);
1950 gtk_window_set_title(GTK_WINDOW(b->window), _("Set Directory Info"));
1951 g_signal_connect(G_OBJECT(b->window), "destroy", G_CALLBACK(destroy_dialog), b->window);
1952 gtk_widget_realize(b->window);
1954 fbox = gtk_vbox_new(FALSE, 5);
1955 gtk_container_add(GTK_CONTAINER(b->window), fbox);
1956 gtk_widget_show(fbox);
1958 frame = gtk_frame_new(_("Directory Info"));
1959 gtk_container_set_border_width(GTK_CONTAINER(fbox), 5);
1960 gtk_box_pack_start(GTK_BOX(fbox), frame, FALSE, FALSE, 0);
1961 gtk_widget_show(frame);
1963 vbox = gtk_vbox_new(FALSE, 5);
1964 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1965 gtk_container_add(GTK_CONTAINER(frame), vbox);
1966 gtk_widget_show(vbox);
1968 g_snprintf(buf, sizeof(buf), _("Setting Dir Info for %s:"), gc->username);
1969 label = gtk_label_new(buf);
1970 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);
1971 gtk_widget_show(label);
1973 b->first = gtk_entry_new();
1974 b->middle = gtk_entry_new();
1975 b->last = gtk_entry_new();
1976 b->maiden = gtk_entry_new();
1977 b->city = gtk_entry_new();
1978 b->state = gtk_entry_new();
1979 b->country = gtk_entry_new();
1980 b->web = gtk_check_button_new_with_label(_("Allow Web Searches To Find Your Info"));
1982 /* Line 1 */
1983 label = gtk_label_new(_("First Name"));
1984 gtk_widget_show(label);
1986 hbox = gtk_hbox_new(FALSE, 5);
1987 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1988 gtk_box_pack_end(GTK_BOX(hbox), b->first, FALSE, FALSE, 0);
1990 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1991 gtk_widget_show(hbox);
1993 /* Line 2 */
1994 label = gtk_label_new(_("Middle Name"));
1995 gtk_widget_show(label);
1997 hbox = gtk_hbox_new(FALSE, 5);
1998 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1999 gtk_box_pack_end(GTK_BOX(hbox), b->middle, FALSE, FALSE, 0);
2001 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2002 gtk_widget_show(hbox);
2005 /* Line 3 */
2006 label = gtk_label_new(_("Last Name"));
2007 gtk_widget_show(label);
2009 hbox = gtk_hbox_new(FALSE, 5);
2010 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2011 gtk_box_pack_end(GTK_BOX(hbox), b->last, FALSE, FALSE, 0);
2013 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2014 gtk_widget_show(hbox);
2016 /* Line 4 */
2017 label = gtk_label_new(_("Maiden Name"));
2018 gtk_widget_show(label);
2020 hbox = gtk_hbox_new(FALSE, 5);
2021 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2022 gtk_box_pack_end(GTK_BOX(hbox), b->maiden, FALSE, FALSE, 0);
2024 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2025 gtk_widget_show(hbox);
2027 /* Line 5 */
2028 label = gtk_label_new(_("City"));
2029 gtk_widget_show(label);
2031 hbox = gtk_hbox_new(FALSE, 5);
2032 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2033 gtk_box_pack_end(GTK_BOX(hbox), b->city, FALSE, FALSE, 0);
2035 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2036 gtk_widget_show(hbox);
2038 /* Line 6 */
2039 label = gtk_label_new(_("State"));
2040 gtk_widget_show(label);
2042 hbox = gtk_hbox_new(FALSE, 5);
2043 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2044 gtk_box_pack_end(GTK_BOX(hbox), b->state, FALSE, FALSE, 0);
2046 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2047 gtk_widget_show(hbox);
2049 /* Line 7 */
2050 label = gtk_label_new(_("Country"));
2051 gtk_widget_show(label);
2053 hbox = gtk_hbox_new(FALSE, 5);
2054 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2055 gtk_box_pack_end(GTK_BOX(hbox), b->country, FALSE, FALSE, 0);
2057 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2058 gtk_widget_show(hbox);
2060 /* Line 8 */
2062 hbox = gtk_hbox_new(FALSE, 5);
2063 gtk_box_pack_start(GTK_BOX(hbox), b->web, TRUE, TRUE, 0);
2064 gtk_widget_show(hbox);
2065 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2067 gtk_widget_show(b->first);
2068 gtk_widget_show(b->middle);
2069 gtk_widget_show(b->last);
2070 gtk_widget_show(b->maiden);
2071 gtk_widget_show(b->city);
2072 gtk_widget_show(b->state);
2073 gtk_widget_show(b->country);
2074 gtk_widget_show(b->web);
2076 /* And add the buttons */
2078 bot = gtk_hbox_new(FALSE, 5);
2079 gtk_box_pack_start(GTK_BOX(fbox), bot, FALSE, FALSE, 0);
2081 b->save = gaim_pixbuf_button_from_stock(_("Save"), GTK_STOCK_SAVE, GAIM_BUTTON_HORIZONTAL);
2082 gtk_box_pack_end(GTK_BOX(bot), b->save, FALSE, FALSE, 0);
2083 g_signal_connect(G_OBJECT(b->save), "clicked", G_CALLBACK(do_set_dir), b);
2085 b->cancel = gaim_pixbuf_button_from_stock(_("Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
2086 gtk_box_pack_end(GTK_BOX(bot), b->cancel, FALSE, FALSE, 0);
2087 g_signal_connect(G_OBJECT(b->cancel), "clicked", G_CALLBACK(destroy_dialog), b->window);
2089 gtk_window_set_focus(GTK_WINDOW(b->window), b->first);
2091 gtk_widget_show_all(b->window);
2094 void do_change_password(GtkWidget *widget, struct passwddlg *b)
2096 const gchar *orig, *new1, *new2;
2098 orig = gtk_entry_get_text(GTK_ENTRY(b->original));
2099 new1 = gtk_entry_get_text(GTK_ENTRY(b->new1));
2100 new2 = gtk_entry_get_text(GTK_ENTRY(b->new2));
2102 if (g_utf8_collate(new1, new2)) {
2103 gaim_notify_error(NULL, NULL,
2104 _("New passwords do not match."), NULL);
2105 return;
2108 if ((strlen(orig) < 1) || (strlen(new1) < 1) || (strlen(new2) < 1)) {
2109 gaim_notify_error(NULL, NULL,
2110 _("Fill out all fields completely."), NULL);
2111 return;
2114 serv_change_passwd(b->gc, orig, new1);
2115 g_snprintf(b->gc->account->password, sizeof(b->gc->account->password), "%s", new1);
2116 save_prefs();
2118 destroy_dialog(NULL, b->window);
2119 g_free(b);
2122 void show_change_passwd(struct gaim_connection *gc)
2124 GtkWidget *hbox;
2125 GtkWidget *label;
2126 GtkWidget *vbox;
2127 GtkWidget *fbox;
2128 GtkWidget *frame;
2129 char buf[256];
2131 struct passwddlg *b = g_new0(struct passwddlg, 1);
2132 b->gc = gc;
2134 GAIM_DIALOG(b->window);
2135 gtk_window_set_resizable(GTK_WINDOW(b->window), TRUE);
2136 gtk_window_set_role(GTK_WINDOW(b->window), "change_passwd");
2137 gtk_window_set_title(GTK_WINDOW(b->window), _("Change Password"));
2138 g_signal_connect(G_OBJECT(b->window), "destroy", G_CALLBACK(destroy_dialog), b->window);
2139 gtk_widget_realize(b->window);
2140 dialogwindows = g_list_prepend(dialogwindows, b->window);
2142 fbox = gtk_vbox_new(FALSE, 5);
2143 gtk_container_set_border_width(GTK_CONTAINER(fbox), 5);
2144 gtk_container_add(GTK_CONTAINER(b->window), fbox);
2146 frame = gtk_frame_new(_("Change Password"));
2147 gtk_box_pack_start(GTK_BOX(fbox), frame, FALSE, FALSE, 0);
2149 vbox = gtk_vbox_new(FALSE, 5);
2150 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2151 gtk_container_add(GTK_CONTAINER(frame), vbox);
2153 g_snprintf(buf, sizeof(buf), _("Changing password for %s:"), gc->username);
2154 label = gtk_label_new(buf);
2155 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);
2157 /* First Line */
2158 hbox = gtk_hbox_new(FALSE, 5);
2159 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2161 label = gtk_label_new(_("Original Password"));
2162 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2164 b->original = gtk_entry_new();
2165 gtk_entry_set_visibility(GTK_ENTRY(b->original), FALSE);
2166 gtk_box_pack_end(GTK_BOX(hbox), b->original, FALSE, FALSE, 0);
2168 /* Next Line */
2169 hbox = gtk_hbox_new(FALSE, 5);
2170 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2172 label = gtk_label_new(_("New Password"));
2173 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2175 b->new1 = gtk_entry_new();
2176 gtk_entry_set_visibility(GTK_ENTRY(b->new1), FALSE);
2177 gtk_box_pack_end(GTK_BOX(hbox), b->new1, FALSE, FALSE, 0);
2179 /* Next Line */
2180 hbox = gtk_hbox_new(FALSE, 5);
2181 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2183 label = gtk_label_new(_("New Password (again)"));
2184 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2186 b->new2 = gtk_entry_new();
2187 gtk_entry_set_visibility(GTK_ENTRY(b->new2), FALSE);
2188 gtk_box_pack_end(GTK_BOX(hbox), b->new2, FALSE, FALSE, 0);
2190 /* Now do our row of buttons */
2191 hbox = gtk_hbox_new(FALSE, 5);
2192 gtk_box_pack_start(GTK_BOX(fbox), hbox, FALSE, FALSE, 0);
2194 b->ok = gaim_pixbuf_button_from_stock(_("OK"), GTK_STOCK_OK, GAIM_BUTTON_HORIZONTAL);
2195 gtk_box_pack_end(GTK_BOX(hbox), b->ok, FALSE, FALSE, 0);
2196 g_signal_connect(G_OBJECT(b->ok), "clicked", G_CALLBACK(do_change_password), b);
2198 b->cancel = gaim_pixbuf_button_from_stock(_("Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
2199 gtk_box_pack_end(GTK_BOX(hbox), b->cancel, FALSE, FALSE, 0);
2200 g_signal_connect(G_OBJECT(b->cancel), "clicked", G_CALLBACK(destroy_dialog), b->window);
2202 gtk_widget_show_all(b->window);
2205 void show_set_info(struct gaim_connection *gc)
2207 GtkWidget *buttons;
2208 GtkWidget *label;
2209 GtkWidget *vbox;
2210 GtkTextBuffer *buffer;
2211 GtkWidget *frame;
2212 gchar *buf;
2213 struct gaim_account *account;
2215 struct set_info_dlg *b = g_new0(struct set_info_dlg, 1);
2216 account = gc->account;
2217 b->account = account;
2219 GAIM_DIALOG(b->window);
2220 gtk_window_set_role(GTK_WINDOW(b->window), "set_info");
2221 dialogwindows = g_list_prepend(dialogwindows, b->window);
2222 gtk_window_set_title(GTK_WINDOW(b->window), _("Set User Info"));
2223 g_signal_connect(G_OBJECT(b->window), "destroy", G_CALLBACK(destroy_dialog), b->window);
2224 gtk_widget_realize(b->window);
2226 vbox = gtk_vbox_new(FALSE, 5);
2227 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2228 gtk_container_add(GTK_CONTAINER(b->window), vbox);
2230 buf = g_malloc(256);
2231 g_snprintf(buf, 256, _("Changing info for %s:"), account->username);
2232 label = gtk_label_new(buf);
2233 g_free(buf);
2234 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);
2236 frame = gtk_frame_new(NULL);
2237 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
2238 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
2240 b->text = gtk_text_view_new();
2241 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(b->text), GTK_WRAP_WORD_CHAR);
2242 gtk_widget_set_size_request(b->text, 300, 200);
2243 buf = g_malloc(strlen(account->user_info) + 1);
2244 strncpy_nohtml(buf, account->user_info, strlen(account->user_info) + 1);
2245 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(b->text));
2246 gtk_text_buffer_set_text(buffer, buf, -1);
2247 g_free(buf);
2248 gtk_container_add(GTK_CONTAINER(frame), b->text);
2249 gtk_window_set_focus(GTK_WINDOW(b->window), b->text);
2251 buttons = gtk_hbox_new(FALSE, 5);
2252 gtk_box_pack_start(GTK_BOX(vbox), buttons, FALSE, FALSE, 0);
2254 b->save = gaim_pixbuf_button_from_stock(_("Save"), GTK_STOCK_SAVE, GAIM_BUTTON_HORIZONTAL);
2255 gtk_box_pack_end(GTK_BOX(buttons), b->save, FALSE, FALSE, 0);
2256 g_signal_connect(G_OBJECT(b->save), "clicked", G_CALLBACK(do_save_info), b);
2258 b->cancel = gaim_pixbuf_button_from_stock(_("Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
2259 gtk_box_pack_end(GTK_BOX(buttons), b->cancel, FALSE, FALSE, 0);
2260 g_signal_connect(G_OBJECT(b->cancel), "clicked", G_CALLBACK(destroy_dialog), b->window);
2262 gtk_widget_show_all(b->window);
2265 /*------------------------------------------------------------------------*/
2266 /* The dialog for the info requests */
2267 /*------------------------------------------------------------------------*/
2269 static void info_dlg_free(GtkWidget *b, struct info_dlg *d)
2271 if (g_slist_find(info_dlgs, d))
2272 info_dlgs = g_slist_remove(info_dlgs, d);
2273 g_free(d->who);
2274 g_free(d);
2277 /* if away is 0, show regardless and try to get away message
2278 * 1, don't show if regular info isn't shown
2279 * 2, show regardless but don't try to get away message
2281 * i wish this were my client. if i were i wouldn't have to deal with this shit.
2283 void g_show_info_text(struct gaim_connection *gc, const char *who, int away, const char *info, ...)
2285 GtkWidget *ok;
2286 GtkWidget *label;
2287 GtkWidget *text;
2288 GtkWidget *bbox;
2289 GtkWidget *sw;
2290 gint options = 0;
2291 char *more_info;
2292 va_list ap;
2294 struct info_dlg *b = find_info_dlg(gc, who);
2295 if (!b && (away == 1))
2296 return;
2297 if (!b) {
2298 b = g_new0(struct info_dlg, 1);
2299 b->gc = gc;
2300 b->who = who ? g_strdup(normalize(who)) : NULL;
2301 info_dlgs = g_slist_append(info_dlgs, b);
2303 GAIM_DIALOG(b->window);
2304 gtk_window_set_title(GTK_WINDOW(b->window), "Gaim");
2305 gtk_container_set_border_width(GTK_CONTAINER(b->window), 5);
2306 gtk_widget_realize(GTK_WIDGET(b->window));
2307 g_signal_connect(G_OBJECT(b->window), "destroy", G_CALLBACK(info_dlg_free), b);
2309 bbox = gtk_vbox_new(FALSE, 5);
2310 gtk_container_add(GTK_CONTAINER(b->window), bbox);
2312 label = gtk_label_new(_("Below are the results of your search: "));
2313 gtk_box_pack_start(GTK_BOX(bbox), label, FALSE, FALSE, 0);
2315 sw = gtk_scrolled_window_new(NULL, NULL);
2316 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
2317 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
2318 gtk_box_pack_start(GTK_BOX(bbox), sw, TRUE, TRUE, 0);
2320 text = gtk_imhtml_new(NULL, NULL);
2321 b->text = text;
2322 gtk_container_add(GTK_CONTAINER(sw), text);
2323 gtk_widget_set_size_request(sw, 300, 250);
2324 gaim_setup_imhtml(text);
2326 ok = gaim_pixbuf_button_from_stock(_("OK"), GTK_STOCK_OK, GAIM_BUTTON_HORIZONTAL);
2327 g_signal_connect_swapped(G_OBJECT(ok), "clicked", G_CALLBACK(gtk_widget_destroy),
2328 G_OBJECT(b->window));
2329 gtk_box_pack_start(GTK_BOX(bbox), ok, FALSE, FALSE, 0);
2331 gtk_widget_show_all(b->window);
2334 if (convo_options & OPT_CONVO_IGNORE_COLOUR)
2335 options ^= GTK_IMHTML_NO_COLOURS;
2336 if (convo_options & OPT_CONVO_IGNORE_FONTS)
2337 options ^= GTK_IMHTML_NO_FONTS;
2338 if (convo_options & OPT_CONVO_IGNORE_SIZES)
2339 options ^= GTK_IMHTML_NO_SIZES;
2340 options ^= GTK_IMHTML_NO_COMMENTS;
2341 options ^= GTK_IMHTML_NO_TITLE;
2342 options ^= GTK_IMHTML_NO_NEWLINE;
2343 options ^= GTK_IMHTML_NO_SCROLL;
2345 gtk_imhtml_append_text(GTK_IMHTML(b->text), info, -1, options);
2347 va_start(ap, info);
2348 while ((more_info = va_arg(ap, char *)) != NULL) {
2349 gchar *linkifyinated = linkify_text(more_info);
2350 gtk_imhtml_append_text(GTK_IMHTML(b->text), linkifyinated, -1, options);
2351 g_free(linkifyinated);
2353 va_end(ap);
2355 if (away)
2356 info_dlgs = g_slist_remove(info_dlgs, b);
2357 else
2358 serv_get_away(gc, who);
2361 /*------------------------------------------------------------------------*/
2362 /* The dialog for adding to permit/deny */
2363 /*------------------------------------------------------------------------*/
2366 static void do_add_perm(GtkWidget *w, struct addperm *p)
2369 const char *who;
2371 who = gtk_entry_get_text(GTK_ENTRY(p->entry));
2373 if (!p->permit) {
2374 if (gaim_privacy_deny_add(p->gc->account, who)) {
2375 serv_add_deny(p->gc, who);
2376 build_block_list();
2377 gaim_blist_save();
2379 } else {
2380 if (gaim_privacy_permit_add(p->gc->account, who)) {
2381 serv_add_permit(p->gc, who);
2382 build_allow_list();
2383 gaim_blist_save();
2387 destroy_dialog(NULL, p->window);
2392 void show_add_perm(struct gaim_connection *gc, char *who, gboolean permit)
2394 GtkWidget *cancel;
2395 GtkWidget *add;
2396 GtkWidget *label;
2397 GtkWidget *bbox;
2398 GtkWidget *vbox;
2399 GtkWidget *topbox;
2401 struct addperm *p = g_new0(struct addperm, 1);
2402 p->gc = gc;
2403 p->permit = permit;
2405 GAIM_DIALOG(p->window);
2406 gtk_container_set_border_width(GTK_CONTAINER(p->window), 5);
2407 gtk_window_set_resizable(GTK_WINDOW(p->window), FALSE);
2408 gtk_widget_realize(p->window);
2410 dialogwindows = g_list_prepend(dialogwindows, p->window);
2412 bbox = gtk_hbox_new(FALSE, 5);
2413 topbox = gtk_hbox_new(FALSE, 5);
2414 vbox = gtk_vbox_new(FALSE, 5);
2415 p->entry = gtk_entry_new();
2417 /* Build Add Button */
2419 if (permit)
2420 add = gaim_pixbuf_button_from_stock(_("Permit"), GTK_STOCK_ADD, GAIM_BUTTON_HORIZONTAL);
2421 else
2422 add = gaim_pixbuf_button_from_stock(_("Deny"), GTK_STOCK_ADD, GAIM_BUTTON_HORIZONTAL);
2423 cancel = gaim_pixbuf_button_from_stock(_("Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
2425 /* End of Cancel Button */
2426 if (who != NULL)
2427 gtk_entry_set_text(GTK_ENTRY(p->entry), who);
2429 /* Put the buttons in the box */
2431 gtk_box_pack_end(GTK_BOX(bbox), add, FALSE, FALSE, 5);
2432 gtk_box_pack_end(GTK_BOX(bbox), cancel, FALSE, FALSE, 5);
2434 label = gtk_label_new(_("Add"));
2435 gtk_box_pack_start(GTK_BOX(topbox), label, FALSE, FALSE, 5);
2436 gtk_box_pack_start(GTK_BOX(topbox), p->entry, FALSE, FALSE, 5);
2437 /* And the boxes in the box */
2438 gtk_box_pack_start(GTK_BOX(vbox), topbox, TRUE, TRUE, 5);
2439 gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 5);
2440 topbox=gtk_hbox_new(FALSE, 5);
2441 gtk_box_pack_start(GTK_BOX(topbox), vbox, FALSE, FALSE, 5);
2444 /* Handle closes right */
2445 g_signal_connect(G_OBJECT(p->window), "destroy", G_CALLBACK(destroy_dialog), p->window);
2446 g_signal_connect(G_OBJECT(cancel), "clicked", G_CALLBACK(destroy_dialog), p->window);
2447 g_signal_connect(G_OBJECT(add), "clicked", G_CALLBACK(do_add_perm), p);
2448 g_signal_connect(G_OBJECT(p->entry), "activate", G_CALLBACK(do_add_perm), p);
2450 /* Finish up */
2451 if (permit)
2452 gtk_window_set_title(GTK_WINDOW(p->window), _("Add Permit"));
2453 else
2454 gtk_window_set_title(GTK_WINDOW(p->window), _("Add Deny"));
2455 gtk_window_set_focus(GTK_WINDOW(p->window), p->entry);
2456 gtk_container_add(GTK_CONTAINER(p->window), topbox);
2457 gtk_widget_realize(p->window);
2459 gtk_widget_show_all(p->window);
2463 /*------------------------------------------------------------------------*/
2464 /* Functions Called To Add A Log */
2465 /*------------------------------------------------------------------------*/
2467 void cancel_log(GtkWidget *widget, struct gaim_conversation *c)
2469 struct gaim_gtk_conversation *gtkconv;
2471 gtkconv = GAIM_GTK_CONVERSATION(c);
2473 if (gtkconv->toolbar.log) {
2474 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtkconv->toolbar.log),
2475 FALSE);
2478 dialogwindows = g_list_remove(dialogwindows, gtkconv->dialogs.log);
2479 gtk_widget_destroy(gtkconv->dialogs.log);
2480 gtkconv->dialogs.log = NULL;
2483 void do_log(GtkWidget *w, struct gaim_conversation *c)
2485 struct gaim_gtk_conversation *gtkconv;
2486 struct log_conversation *l;
2487 const char *file;
2488 char path[PATHSIZE];
2490 gtkconv = GAIM_GTK_CONVERSATION(c);
2492 if (!find_log_info(c->name)) {
2493 file = gtk_file_selection_get_filename(
2494 GTK_FILE_SELECTION(gtkconv->dialogs.log));
2496 strncpy(path, file, PATHSIZE - 1);
2498 if (file_is_dir(path, gtkconv->dialogs.log))
2499 return;
2501 l = (struct log_conversation *)g_new0(struct log_conversation, 1);
2502 strcpy(l->name, gaim_conversation_get_name(c));
2503 strcpy(l->filename, file);
2504 log_conversations = g_list_append(log_conversations, l);
2506 if (c != NULL)
2507 gaim_conversation_set_logging(c, TRUE);
2510 save_prefs();
2511 cancel_log(NULL, c);
2514 void show_log_dialog(struct gaim_conversation *c)
2516 struct gaim_gtk_conversation *gtkconv;
2517 char *buf = g_malloc(BUF_LEN);
2519 gtkconv = GAIM_GTK_CONVERSATION(c);
2521 if (!gtkconv->dialogs.log) {
2522 gtkconv->dialogs.log = gtk_file_selection_new(_("Log Conversation"));
2524 gtk_file_selection_hide_fileop_buttons(
2525 GTK_FILE_SELECTION(gtkconv->dialogs.log));
2527 g_snprintf(buf, BUF_LEN - 1, "%s" G_DIR_SEPARATOR_S "%s.log",
2528 gaim_home_dir(), normalize(c->name));
2529 g_object_set_data(G_OBJECT(gtkconv->dialogs.log), "dialog_type",
2530 "log dialog");
2531 gtk_file_selection_set_filename(GTK_FILE_SELECTION(gtkconv->dialogs.log),
2532 buf);
2533 g_signal_connect(G_OBJECT(gtkconv->dialogs.log), "delete_event",
2534 G_CALLBACK(delete_event_dialog), c);
2535 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(gtkconv->dialogs.log)->ok_button), "clicked",
2536 G_CALLBACK(do_log), c);
2537 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(gtkconv->dialogs.log)->cancel_button), "clicked",
2538 G_CALLBACK(cancel_log), c);
2541 g_free(buf);
2543 gtk_widget_show(gtkconv->dialogs.log);
2544 gdk_window_raise(gtkconv->dialogs.log->window);
2547 /*------------------------------------------------------*/
2548 /* Find Buddy By Email */
2549 /*------------------------------------------------------*/
2551 void do_find_info(GtkWidget *w, struct findbyinfo *b)
2553 const char *first;
2554 const char *middle;
2555 const char *last;
2556 const char *maiden;
2557 const char *city;
2558 const char *state;
2559 const char *country;
2561 first = gtk_entry_get_text(GTK_ENTRY(b->firstentry));
2562 middle = gtk_entry_get_text(GTK_ENTRY(b->middleentry));
2563 last = gtk_entry_get_text(GTK_ENTRY(b->lastentry));
2564 maiden = gtk_entry_get_text(GTK_ENTRY(b->maidenentry));
2565 city = gtk_entry_get_text(GTK_ENTRY(b->cityentry));
2566 state = gtk_entry_get_text(GTK_ENTRY(b->stateentry));
2567 country = gtk_entry_get_text(GTK_ENTRY(b->countryentry));
2569 serv_dir_search(b->gc, first, middle, last, maiden, city, state, country, "");
2570 destroy_dialog(NULL, b->window);
2573 void do_find_email(GtkWidget *w, struct findbyemail *b)
2575 const char *email;
2577 email = gtk_entry_get_text(GTK_ENTRY(b->emailentry));
2579 serv_dir_search(b->gc, "", "", "", "", "", "", "", email);
2581 destroy_dialog(NULL, b->window);
2584 void show_find_info(struct gaim_connection *gc)
2586 GtkWidget *cancel;
2587 GtkWidget *ok;
2588 GtkWidget *label;
2589 GtkWidget *bbox;
2590 GtkWidget *vbox;
2591 GtkWidget *hbox;
2592 GtkWidget *fbox;
2593 GtkWidget *frame;
2595 struct findbyinfo *b = g_new0(struct findbyinfo, 1);
2596 b->gc = gc;
2597 GAIM_DIALOG(b->window);
2598 gtk_window_set_resizable(GTK_WINDOW(b->window), TRUE);
2599 gtk_window_set_role(GTK_WINDOW(b->window), "find_info");
2601 dialogwindows = g_list_prepend(dialogwindows, b->window);
2603 frame = gtk_frame_new(_("Search for Buddy"));
2604 fbox = gtk_vbox_new(FALSE, 5);
2606 /* Build OK Button */
2608 ok = gaim_pixbuf_button_from_stock(_("OK"), GTK_STOCK_OK, GAIM_BUTTON_HORIZONTAL);
2609 cancel = gaim_pixbuf_button_from_stock(_("Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
2611 bbox = gtk_hbox_new(FALSE, 5);
2612 vbox = gtk_vbox_new(FALSE, 5);
2613 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2615 b->firstentry = gtk_entry_new();
2616 b->middleentry = gtk_entry_new();
2617 b->lastentry = gtk_entry_new();
2618 b->maidenentry = gtk_entry_new();
2619 b->cityentry = gtk_entry_new();
2620 b->stateentry = gtk_entry_new();
2621 b->countryentry = gtk_entry_new();
2623 gtk_box_pack_end(GTK_BOX(bbox), ok, FALSE, FALSE, 0);
2624 gtk_box_pack_end(GTK_BOX(bbox), cancel, FALSE, FALSE, 0);
2626 /* Line 1 */
2627 label = gtk_label_new(_("First Name"));
2629 hbox = gtk_hbox_new(FALSE, 5);
2630 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2631 gtk_box_pack_end(GTK_BOX(hbox), b->firstentry, FALSE, FALSE, 0);
2633 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2635 /* Line 2 */
2637 label = gtk_label_new(_("Middle Name"));
2639 hbox = gtk_hbox_new(FALSE, 5);
2640 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2641 gtk_box_pack_end(GTK_BOX(hbox), b->middleentry, FALSE, FALSE, 0);
2643 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2645 /* Line 3 */
2647 label = gtk_label_new(_("Last Name"));
2649 hbox = gtk_hbox_new(FALSE, 5);
2650 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2651 gtk_box_pack_end(GTK_BOX(hbox), b->lastentry, FALSE, FALSE, 0);
2653 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2655 /* Line 4 */
2657 label = gtk_label_new(_("Maiden Name"));
2659 hbox = gtk_hbox_new(FALSE, 5);
2660 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2661 gtk_box_pack_end(GTK_BOX(hbox), b->maidenentry, FALSE, FALSE, 0);
2663 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2665 /* Line 5 */
2667 label = gtk_label_new(_("City"));
2669 hbox = gtk_hbox_new(FALSE, 5);
2670 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2671 gtk_box_pack_end(GTK_BOX(hbox), b->cityentry, FALSE, FALSE, 0);
2673 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2675 /* Line 6 */
2676 label = gtk_label_new(_("State"));
2678 hbox = gtk_hbox_new(FALSE, 5);
2679 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2680 gtk_box_pack_end(GTK_BOX(hbox), b->stateentry, FALSE, FALSE, 0);
2682 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2684 /* Line 7 */
2685 label = gtk_label_new(_("Country"));
2687 hbox = gtk_hbox_new(FALSE, 5);
2688 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2689 gtk_box_pack_end(GTK_BOX(hbox), b->countryentry, FALSE, FALSE, 0);
2691 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2693 /* Merge The Boxes */
2695 gtk_container_add(GTK_CONTAINER(frame), vbox);
2696 gtk_box_pack_start(GTK_BOX(fbox), frame, FALSE, FALSE, 0);
2697 gtk_box_pack_start(GTK_BOX(fbox), bbox, FALSE, FALSE, 0);
2699 g_signal_connect(G_OBJECT(b->window), "destroy", G_CALLBACK(destroy_dialog), b->window);
2700 g_signal_connect(G_OBJECT(cancel), "clicked", G_CALLBACK(destroy_dialog), b->window);
2701 g_signal_connect(G_OBJECT(ok), "clicked", G_CALLBACK(do_find_info), b);
2703 gtk_window_set_title(GTK_WINDOW(b->window), _("Find Buddy By Info"));
2704 gtk_window_set_focus(GTK_WINDOW(b->window), b->firstentry);
2705 gtk_container_add(GTK_CONTAINER(b->window), fbox);
2706 gtk_container_set_border_width(GTK_CONTAINER(b->window), 5);
2707 gtk_widget_realize(b->window);
2709 gtk_widget_show_all(b->window);
2712 void show_find_email(struct gaim_connection *gc)
2714 GtkWidget *label;
2715 GtkWidget *bbox;
2716 GtkWidget *vbox;
2717 GtkWidget *frame;
2718 GtkWidget *topbox;
2719 GtkWidget *button;
2721 struct findbyemail *b = g_new0(struct findbyemail, 1);
2722 if (g_slist_find(connections, gc))
2723 b->gc = gc;
2724 GAIM_DIALOG(b->window);
2725 gtk_window_set_resizable(GTK_WINDOW(b->window), TRUE);
2726 gtk_window_set_role(GTK_WINDOW(b->window), "find_email");
2727 gtk_widget_realize(b->window);
2728 dialogwindows = g_list_prepend(dialogwindows, b->window);
2729 g_signal_connect(G_OBJECT(b->window), "destroy", G_CALLBACK(destroy_dialog), b->window);
2730 gtk_window_set_title(GTK_WINDOW(b->window), _("Find Buddy By Email"));
2732 vbox = gtk_vbox_new(FALSE, 5);
2733 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
2734 gtk_container_add(GTK_CONTAINER(b->window), vbox);
2736 frame = gtk_frame_new(_("Search for Buddy"));
2737 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
2739 topbox = gtk_hbox_new(FALSE, 5);
2740 gtk_container_add(GTK_CONTAINER(frame), topbox);
2741 gtk_container_set_border_width(GTK_CONTAINER(topbox), 5);
2743 label = gtk_label_new(_("Email"));
2744 gtk_box_pack_start(GTK_BOX(topbox), label, FALSE, FALSE, 0);
2746 b->emailentry = gtk_entry_new();
2747 gtk_box_pack_start(GTK_BOX(topbox), b->emailentry, TRUE, TRUE, 0);
2748 g_signal_connect(G_OBJECT(b->emailentry), "activate", G_CALLBACK(do_find_email), b);
2749 gtk_window_set_focus(GTK_WINDOW(b->window), b->emailentry);
2751 bbox = gtk_hbox_new(FALSE, 5);
2752 gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
2754 button = gaim_pixbuf_button_from_stock(_("OK"), GTK_STOCK_OK, GAIM_BUTTON_HORIZONTAL);
2755 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(do_find_email), b);
2756 gtk_box_pack_end(GTK_BOX(bbox), button, FALSE, FALSE, 0);
2758 button = gaim_pixbuf_button_from_stock(_("Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
2759 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(destroy_dialog), b->window);
2760 gtk_box_pack_end(GTK_BOX(bbox), button, FALSE, FALSE, 0);
2762 gtk_widget_show_all(b->window);
2765 /*------------------------------------------------------*/
2766 /* Link Dialog */
2767 /*------------------------------------------------------*/
2769 void cancel_link(GtkWidget *widget, struct gaim_conversation *c)
2771 struct gaim_gtk_conversation *gtkconv;
2773 gtkconv = GAIM_GTK_CONVERSATION(c);
2775 if (gtkconv->toolbar.link) {
2776 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkconv->toolbar.link),
2777 FALSE);
2780 destroy_dialog(NULL, gtkconv->dialogs.link);
2781 gtkconv->dialogs.link = NULL;
2784 void do_insert_link(GtkWidget *w, int resp, struct linkdlg *b)
2786 struct gaim_gtk_conversation *gtkconv;
2787 char *open_tag;
2788 const char *urltext, *showtext;
2790 gtkconv = GAIM_GTK_CONVERSATION(b->c);
2792 if (resp == GTK_RESPONSE_OK) {
2794 open_tag = g_malloc(2048);
2796 urltext = gtk_entry_get_text(GTK_ENTRY(b->url));
2797 showtext = gtk_entry_get_text(GTK_ENTRY(b->text));
2799 if (!strlen(showtext))
2800 showtext = urltext;
2802 g_snprintf(open_tag, 2048, "<A HREF=\"%s\">%s", urltext, showtext);
2803 gaim_gtk_surround(gtkconv, open_tag, "</A>");
2805 g_free(open_tag);
2808 if (gtkconv->toolbar.link) {
2809 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkconv->toolbar.link),
2810 FALSE);
2813 gtkconv->dialogs.link = NULL;
2814 destroy_dialog(NULL, b->window);
2817 void show_insert_link(GtkWidget *linky, struct gaim_conversation *c)
2819 struct gaim_gtk_conversation *gtkconv;
2820 struct gaim_gtk_window *gtkwin;
2821 GtkWidget *table;
2822 GtkWidget *label;
2823 GtkWidget *hbox;
2824 GtkWidget *vbox;
2826 gtkconv = GAIM_GTK_CONVERSATION(c);
2827 gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(c));
2829 if (gtkconv->dialogs.link == NULL) {
2830 struct linkdlg *a = g_new0(struct linkdlg, 1);
2831 GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
2833 a->c = c;
2834 a->window = gtk_dialog_new_with_buttons(_("Insert Link"),
2835 GTK_WINDOW(gtkwin->window), 0, GTK_STOCK_CANCEL,
2836 GTK_RESPONSE_CANCEL, _("Insert"), GTK_RESPONSE_OK, NULL);
2838 gtk_dialog_set_default_response(GTK_DIALOG(a->window), GTK_RESPONSE_OK);
2839 gtk_container_set_border_width(GTK_CONTAINER(a->window), 6);
2840 gtk_window_set_resizable(GTK_WINDOW(a->window), FALSE);
2841 gtk_dialog_set_has_separator(GTK_DIALOG(a->window), FALSE);
2842 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(a->window)->vbox), 12);
2843 gtk_container_set_border_width(
2844 GTK_CONTAINER(GTK_DIALOG(a->window)->vbox), 6);
2845 gtk_window_set_role(GTK_WINDOW(a->window), "insert_link");
2847 hbox = gtk_hbox_new(FALSE, 12);
2848 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(a->window)->vbox), hbox);
2849 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
2850 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
2852 vbox = gtk_vbox_new(FALSE, 0);
2853 gtk_container_add(GTK_CONTAINER(hbox), vbox);
2855 label = gtk_label_new(_("Please enter the URL and description of "
2856 "the link that you want to insert. The "
2857 "description is optional.\n"));
2859 gtk_widget_set_size_request(GTK_WIDGET(label), 335, -1);
2860 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
2861 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
2862 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
2864 hbox = gtk_hbox_new(FALSE, 6);
2865 gtk_container_add(GTK_CONTAINER(vbox), hbox);
2867 g_signal_connect(G_OBJECT(a->window), "destroy",
2868 G_CALLBACK(destroy_dialog), a->window);
2869 g_signal_connect(G_OBJECT(a->window), "destroy",
2870 G_CALLBACK(free_dialog), a);
2871 dialogwindows = g_list_prepend(dialogwindows, a->window);
2873 table = gtk_table_new(4, 2, FALSE);
2874 gtk_table_set_row_spacings(GTK_TABLE(table), 5);
2875 gtk_table_set_col_spacings(GTK_TABLE(table), 5);
2876 gtk_container_set_border_width(GTK_CONTAINER(table), 0);
2877 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
2879 label = gtk_label_new(_("URL"));
2880 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
2881 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
2883 a->url = gtk_entry_new();
2884 gtk_table_attach_defaults(GTK_TABLE(table), a->url, 1, 2, 0, 1);
2885 gtk_widget_grab_focus(a->url);
2887 gtk_entry_set_activates_default (GTK_ENTRY(a->url), TRUE);
2889 label = gtk_label_new(_("Description"));
2890 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
2891 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
2893 a->text = gtk_entry_new();
2894 gtk_table_attach_defaults(GTK_TABLE(table), a->text, 1, 2, 1, 2);
2895 gtk_entry_set_activates_default (GTK_ENTRY(a->text), TRUE);
2897 g_signal_connect(G_OBJECT(a->window), "response",
2898 G_CALLBACK(do_insert_link), a);
2900 a->toggle = linky;
2901 gtkconv->dialogs.link = a->window;
2904 gtk_widget_show_all(gtkconv->dialogs.link);
2905 gdk_window_raise(gtkconv->dialogs.link->window);
2908 /*------------------------------------------------------*/
2909 /* Color Selection Dialog */
2910 /*------------------------------------------------------*/
2912 GtkWidget *fgcseld = NULL;
2913 GtkWidget *bgcseld = NULL;
2915 void cancel_fgcolor(GtkWidget *widget, struct gaim_conversation *c)
2917 struct gaim_gtk_conversation *gtkconv;
2919 gtkconv = GAIM_GTK_CONVERSATION(c);
2921 if (gtkconv->toolbar.fgcolor && widget) {
2922 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkconv->toolbar.fgcolor),
2923 FALSE);
2926 dialogwindows = g_list_remove(dialogwindows, gtkconv->dialogs.fg_color);
2927 gtk_widget_destroy(gtkconv->dialogs.fg_color);
2928 gtkconv->dialogs.fg_color = NULL;
2931 void cancel_bgcolor(GtkWidget *widget, struct gaim_conversation *c)
2933 struct gaim_gtk_conversation *gtkconv;
2935 gtkconv = GAIM_GTK_CONVERSATION(c);
2937 if (gtkconv->toolbar.bgcolor && widget) {
2938 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkconv->toolbar.bgcolor),
2939 FALSE);
2942 dialogwindows = g_list_remove(dialogwindows, gtkconv->dialogs.bg_color);
2943 gtk_widget_destroy(gtkconv->dialogs.bg_color);
2944 gtkconv->dialogs.bg_color = NULL;
2947 void do_fgcolor(GtkWidget *widget, GtkColorSelection *colorsel)
2949 GdkColor text_color;
2950 struct gaim_conversation *c;
2951 struct gaim_gtk_conversation *gtkconv;
2952 char *open_tag;
2954 open_tag = g_malloc(30);
2956 gtk_color_selection_get_current_color(colorsel, &text_color);
2958 c = g_object_get_data(G_OBJECT(colorsel), "gaim_conversation");
2959 /* GTK_IS_EDITABLE(c->entry); huh? */
2961 gtkconv = GAIM_GTK_CONVERSATION(c);
2963 gtkconv->fg_color = text_color;
2964 g_snprintf(open_tag, 23, "<FONT COLOR=\"#%02X%02X%02X\">",
2965 text_color.red / 256,
2966 text_color.green / 256,
2967 text_color.blue / 256);
2968 gaim_gtk_surround(gtkconv, open_tag, "</FONT>");
2970 gaim_debug(GAIM_DEBUG_MISC, "fgcolor dialog", "#%02X%02X%02X\n",
2971 text_color.red / 256,
2972 text_color.green / 256,
2973 text_color.blue / 256);
2974 g_free(open_tag);
2975 cancel_fgcolor(NULL, c);
2978 void do_bgcolor(GtkWidget *widget, GtkColorSelection *colorsel)
2980 GdkColor text_color;
2981 struct gaim_conversation *c;
2982 struct gaim_gtk_conversation *gtkconv;
2983 char *open_tag;
2985 open_tag = g_malloc(30);
2987 gtk_color_selection_get_current_color(colorsel, &text_color);
2989 c = g_object_get_data(G_OBJECT(colorsel), "gaim_conversation");
2990 /* GTK_IS_EDITABLE(c->entry); huh? */
2992 gtkconv = GAIM_GTK_CONVERSATION(c);
2994 gtkconv->bg_color = text_color;
2995 g_snprintf(open_tag, 25, "<BODY BGCOLOR=\"#%02X%02X%02X\">",
2996 text_color.red / 256,
2997 text_color.green / 256,
2998 text_color.blue / 256);
2999 gaim_gtk_surround(gtkconv, open_tag, "</BODY>");
3000 gaim_debug(GAIM_DEBUG_MISC, "bgcolor dialog", "#%02X%02X%02X\n",
3001 text_color.red / 256,
3002 text_color.green / 256,
3003 text_color.blue / 256);
3005 g_free(open_tag);
3006 cancel_bgcolor(NULL, c);
3009 void show_fgcolor_dialog(struct gaim_conversation *c, GtkWidget *color)
3011 struct gaim_gtk_conversation *gtkconv;
3012 GtkWidget *colorsel;
3014 gtkconv = GAIM_GTK_CONVERSATION(c);
3016 if (color == NULL) { /* we came from the prefs */
3017 if (fgcseld)
3018 return;
3020 fgcseld = gtk_color_selection_dialog_new(_("Select Text Color"));
3021 gtk_color_selection_set_current_color(GTK_COLOR_SELECTION
3022 (GTK_COLOR_SELECTION_DIALOG(fgcseld)->colorsel), &fgcolor);
3023 g_signal_connect(G_OBJECT(fgcseld), "delete_event",
3024 G_CALLBACK(destroy_colorsel), (void *)1);
3025 g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(fgcseld)->cancel_button),
3026 "clicked", G_CALLBACK(destroy_colorsel), (void *)1);
3027 g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(fgcseld)->ok_button), "clicked",
3028 G_CALLBACK(apply_color_dlg), (void *)1);
3029 gtk_widget_realize(fgcseld);
3030 gtk_widget_show(fgcseld);
3031 gdk_window_raise(fgcseld->window);
3032 return;
3035 if (!gtkconv->dialogs.fg_color) {
3037 gtkconv->dialogs.fg_color = gtk_color_selection_dialog_new(_("Select Text Color"));
3038 colorsel = GTK_COLOR_SELECTION_DIALOG(gtkconv->dialogs.fg_color)->colorsel;
3039 gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &fgcolor);
3040 g_object_set_data(G_OBJECT(colorsel), "gaim_conversation", c);
3042 g_signal_connect(G_OBJECT(gtkconv->dialogs.fg_color), "delete_event",
3043 G_CALLBACK(delete_event_dialog), c);
3044 g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(gtkconv->dialogs.fg_color)->ok_button),
3045 "clicked", G_CALLBACK(do_fgcolor), colorsel);
3046 g_signal_connect(G_OBJECT
3047 (GTK_COLOR_SELECTION_DIALOG(gtkconv->dialogs.fg_color)->cancel_button),
3048 "clicked", G_CALLBACK(cancel_fgcolor), c);
3050 gtk_widget_realize(gtkconv->dialogs.fg_color);
3053 gtk_widget_show(gtkconv->dialogs.fg_color);
3054 gdk_window_raise(gtkconv->dialogs.fg_color->window);
3057 void show_bgcolor_dialog(struct gaim_conversation *c, GtkWidget *color)
3059 struct gaim_gtk_conversation *gtkconv;
3060 GtkWidget *colorsel;
3062 gtkconv = GAIM_GTK_CONVERSATION(c);
3064 if (color == NULL) { /* we came from the prefs */
3065 if (bgcseld)
3066 return;
3068 bgcseld = gtk_color_selection_dialog_new(_("Select Background Color"));
3069 gtk_color_selection_set_current_color(GTK_COLOR_SELECTION
3070 (GTK_COLOR_SELECTION_DIALOG(bgcseld)->colorsel), &bgcolor);
3071 g_signal_connect(G_OBJECT(bgcseld), "delete_event",
3072 G_CALLBACK(destroy_colorsel), NULL);
3073 g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(bgcseld)->cancel_button),
3074 "clicked", G_CALLBACK(destroy_colorsel), NULL);
3075 g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(bgcseld)->ok_button), "clicked",
3076 G_CALLBACK(apply_color_dlg), (void *)2);
3077 gtk_widget_realize(bgcseld);
3078 gtk_widget_show(bgcseld);
3079 gdk_window_raise(bgcseld->window);
3080 return;
3083 if (!gtkconv->dialogs.bg_color) {
3085 gtkconv->dialogs.bg_color = gtk_color_selection_dialog_new(_("Select Background Color"));
3086 colorsel = GTK_COLOR_SELECTION_DIALOG(gtkconv->dialogs.bg_color)->colorsel;
3087 gtk_color_selection_set_current_color(GTK_COLOR_SELECTION(colorsel), &bgcolor);
3088 g_object_set_data(G_OBJECT(colorsel), "gaim_conversation", c);
3090 g_signal_connect(G_OBJECT(gtkconv->dialogs.bg_color), "delete_event",
3091 G_CALLBACK(delete_event_dialog), c);
3092 g_signal_connect(G_OBJECT(GTK_COLOR_SELECTION_DIALOG(gtkconv->dialogs.bg_color)->ok_button),
3093 "clicked", G_CALLBACK(do_bgcolor), colorsel);
3094 g_signal_connect(G_OBJECT
3095 (GTK_COLOR_SELECTION_DIALOG(gtkconv->dialogs.bg_color)->cancel_button),
3096 "clicked", G_CALLBACK(cancel_bgcolor), c);
3098 gtk_widget_realize(gtkconv->dialogs.bg_color);
3101 gtk_widget_show(gtkconv->dialogs.bg_color);
3102 gdk_window_raise(gtkconv->dialogs.bg_color->window);
3105 /*------------------------------------------------------------------------*/
3106 /* Font Selection Dialog */
3107 /*------------------------------------------------------------------------*/
3109 void cancel_font(GtkWidget *widget, struct gaim_conversation *c)
3111 struct gaim_gtk_conversation *gtkconv;
3113 gtkconv = GAIM_GTK_CONVERSATION(c);
3115 if (gtkconv->toolbar.font && widget) {
3116 gtk_toggle_button_set_active(
3117 GTK_TOGGLE_BUTTON(gtkconv->toolbar.font), FALSE);
3120 dialogwindows = g_list_remove(dialogwindows, gtkconv->dialogs.font);
3121 gtk_widget_destroy(gtkconv->dialogs.font);
3122 gtkconv->dialogs.font = NULL;
3125 void apply_font(GtkWidget *widget, GtkFontSelection *fontsel)
3127 /* this could be expanded to include font size, weight, etc.
3128 but for now only works with font face */
3129 int i = 0;
3130 char *fontname;
3131 struct gaim_conversation *c = g_object_get_data(G_OBJECT(fontsel),
3132 "gaim_conversation");
3134 if (c) {
3135 fontname = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(fontsel));
3136 while(fontname[i] && !isdigit(fontname[i])) {
3137 i++;
3139 fontname[i] = 0;
3140 gaim_gtk_set_font_face(GAIM_GTK_CONVERSATION(c), fontname);
3141 } else {
3142 fontname = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(fontsel));
3143 while(fontface[i] && !isdigit(fontname[i]) && i < sizeof(fontface)) {
3144 fontface[i] = fontname[i];
3145 i++;
3147 fontface[i] = 0;
3150 cancel_font(NULL, c);
3153 void destroy_fontsel(GtkWidget *w, gpointer d)
3155 gtk_widget_destroy(fontseld);
3156 fontseld = NULL;
3159 void show_font_dialog(struct gaim_conversation *c, GtkWidget *font)
3161 struct gaim_gtk_conversation *gtkconv;
3162 char fonttif[128];
3164 gtkconv = GAIM_GTK_CONVERSATION(c);
3166 if (!font) { /* we came from the prefs dialog */
3167 if (fontseld)
3168 return;
3169 fontseld = gtk_font_selection_dialog_new(_("Select Font"));
3170 if (fontface[0]) {
3171 g_snprintf(fonttif, sizeof(fonttif), "%s 12", fontface);
3172 gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(fontseld),
3173 fonttif);
3174 } else {
3175 gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(fontseld),
3176 DEFAULT_FONT_FACE " 12");
3179 g_signal_connect(G_OBJECT(fontseld), "delete_event",
3180 G_CALLBACK(destroy_fontsel), NULL);
3181 g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(fontseld)->cancel_button),
3182 "clicked", G_CALLBACK(destroy_fontsel), NULL);
3183 g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(fontseld)->ok_button), "clicked",
3184 G_CALLBACK(apply_font_dlg), fontseld);
3185 gtk_widget_realize(fontseld);
3186 gtk_widget_show(fontseld);
3187 gdk_window_raise(fontseld->window);
3188 return;
3191 if (!gtkconv->dialogs.font) {
3192 gtkconv->dialogs.font = gtk_font_selection_dialog_new(_("Select Font"));
3194 g_object_set_data(G_OBJECT(gtkconv->dialogs.font), "gaim_conversation", c);
3196 if (gtkconv->fontface[0]) {
3197 g_snprintf(fonttif, sizeof(fonttif), "%s 12", gtkconv->fontface);
3198 gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(gtkconv->dialogs.font),
3199 fonttif);
3200 } else {
3201 gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(gtkconv->dialogs.font),
3202 DEFAULT_FONT_FACE);
3205 g_signal_connect(G_OBJECT(gtkconv->dialogs.font), "delete_event",
3206 G_CALLBACK(delete_event_dialog), c);
3207 g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(gtkconv->dialogs.font)->ok_button),
3208 "clicked", G_CALLBACK(apply_font), gtkconv->dialogs.font);
3209 g_signal_connect(G_OBJECT(GTK_FONT_SELECTION_DIALOG(gtkconv->dialogs.font)->cancel_button),
3210 "clicked", G_CALLBACK(cancel_font), c);
3212 gtk_widget_realize(gtkconv->dialogs.font);
3216 gtk_widget_show(gtkconv->dialogs.font);
3217 gdk_window_raise(gtkconv->dialogs.font->window);
3220 /*------------------------------------------------------------------------*/
3221 /* The dialog for new away messages */
3222 /*------------------------------------------------------------------------*/
3224 static struct away_message *save_away_message(struct create_away *ca)
3226 struct away_message *am;
3227 gchar *away_message;
3229 if (!ca->mess)
3230 am = g_new0(struct away_message, 1);
3231 else {
3232 am = ca->mess;
3236 g_snprintf(am->name, sizeof(am->name), "%s", gtk_entry_get_text(GTK_ENTRY(ca->entry)));
3237 away_message = gtk_text_view_get_text(GTK_TEXT_VIEW(ca->text), FALSE);
3239 g_snprintf(am->message, sizeof(am->message), "%s", away_message);
3240 g_free(away_message);
3242 if (!ca->mess) {
3243 away_messages = g_slist_insert_sorted(away_messages, am, sort_awaymsg_list);
3246 save_prefs();
3247 do_away_menu();
3249 return am;
3252 int check_away_mess(struct create_away *ca, int type)
3254 char *msg;
3255 if ((strlen(gtk_entry_get_text(GTK_ENTRY(ca->entry))) == 0) && (type == 1)) {
3256 /* We shouldn't allow a blank title */
3257 gaim_notify_error(NULL, NULL,
3258 _("You cannot save an away message with a "
3259 "blank title"),
3260 _("Please give the message a title, or choose "
3261 "\"Use\" to use without saving."));
3262 return 0;
3265 msg = gtk_text_view_get_text(GTK_TEXT_VIEW(ca->text), FALSE);
3267 if (!msg && (type <= 1)) {
3268 /* We shouldn't allow a blank message */
3269 gaim_notify_error(NULL, NULL,
3270 _("You cannot create an empty away message"), NULL);
3271 return 0;
3274 g_free(msg);
3276 return 1;
3279 void save_away_mess(GtkWidget *widget, struct create_away *ca)
3281 if (!check_away_mess(ca, 1))
3282 return;
3284 save_away_message(ca);
3285 destroy_dialog(NULL, ca->window);
3286 g_free(ca);
3289 void use_away_mess(GtkWidget *widget, struct create_away *ca)
3291 static struct away_message am;
3292 gchar *away_message;
3294 if (!check_away_mess(ca, 0))
3295 return;
3297 g_snprintf(am.name, sizeof(am.name), "%s", gtk_entry_get_text(GTK_ENTRY(ca->entry)));
3298 away_message = gtk_text_view_get_text(GTK_TEXT_VIEW(ca->text), FALSE);
3300 g_snprintf(am.message, sizeof(am.message), "%s", away_message);
3301 g_free(away_message);
3303 do_away_message(NULL, &am);
3305 destroy_dialog(NULL, ca->window);
3306 g_free(ca);
3309 void su_away_mess(GtkWidget *widget, struct create_away *ca)
3311 if (!check_away_mess(ca, 1))
3312 return;
3313 do_away_message(NULL, save_away_message(ca));
3314 destroy_dialog(NULL, ca->window);
3315 g_free(ca);
3318 void create_away_mess(GtkWidget *widget, void *dummy)
3320 GtkWidget *hbox;
3321 GtkWidget *titlebox;
3322 GtkWidget *tbox;
3323 GtkWidget *label;
3324 GtkWidget *frame;
3325 GtkWidget *fbox;
3326 GtkWidget *button;
3328 struct create_away *ca = g_new0(struct create_away, 1);
3330 /* Set up window */
3331 GAIM_DIALOG(ca->window);
3332 gtk_widget_set_size_request(ca->window, -1, 250);
3333 gtk_container_set_border_width(GTK_CONTAINER(ca->window), 5);
3334 gtk_window_set_role(GTK_WINDOW(ca->window), "away_mess");
3335 gtk_window_set_title(GTK_WINDOW(ca->window), _("New away message"));
3336 g_signal_connect(G_OBJECT(ca->window), "delete_event",
3337 G_CALLBACK(destroy_dialog), ca->window);
3338 gtk_widget_realize(ca->window);
3340 tbox = gtk_vbox_new(FALSE, 5);
3341 gtk_container_add(GTK_CONTAINER(ca->window), tbox);
3343 frame = gtk_frame_new(_("New away message"));
3344 gtk_box_pack_start(GTK_BOX(tbox), frame, TRUE, TRUE, 0);
3346 fbox = gtk_vbox_new(FALSE, 5);
3347 gtk_container_set_border_width(GTK_CONTAINER(fbox), 5);
3348 gtk_container_add(GTK_CONTAINER(frame), fbox);
3350 titlebox = gtk_hbox_new(FALSE, 5);
3351 gtk_box_pack_start(GTK_BOX(fbox), titlebox, FALSE, FALSE, 0);
3353 label = gtk_label_new(_("Away title: "));
3354 gtk_box_pack_start(GTK_BOX(titlebox), label, FALSE, FALSE, 0);
3356 ca->entry = gtk_entry_new();
3357 gtk_box_pack_start(GTK_BOX(titlebox), ca->entry, TRUE, TRUE, 0);
3358 gtk_widget_grab_focus(ca->entry);
3360 frame = gtk_frame_new(NULL);
3361 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
3362 gtk_box_pack_start(GTK_BOX(fbox), frame, TRUE, TRUE, 0);
3364 ca->text = gtk_text_view_new();
3365 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(ca->text), GTK_WRAP_WORD_CHAR);
3367 gtk_container_add(GTK_CONTAINER(frame), ca->text);
3369 if (dummy) {
3370 struct away_message *amt;
3371 GtkTreeIter iter;
3372 int pos = 0;
3373 GtkListStore *ls = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dummy)));
3374 GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(dummy));
3375 GValue val = { 0, };
3376 GtkTextIter start;
3377 GtkTextBuffer *buffer;
3379 if (! gtk_tree_selection_get_selected (sel, (GtkTreeModel**)&ls, &iter))
3380 return;
3381 gtk_tree_model_get_value (GTK_TREE_MODEL(ls), &iter, 1, &val);
3382 amt = g_value_get_pointer (&val);
3383 gtk_entry_set_text(GTK_ENTRY(ca->entry), amt->name);
3384 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(ca->text));
3385 gtk_text_buffer_get_iter_at_offset(buffer, &start, pos);
3386 gtk_text_buffer_insert(buffer, &start, amt->message, strlen(amt->message));
3388 ca->mess = amt;
3391 hbox = gtk_hbox_new(FALSE, 5);
3392 gtk_box_pack_start(GTK_BOX(tbox), hbox, FALSE, FALSE, 0);
3394 button = gaim_pixbuf_button_from_stock(_("Save"), GTK_STOCK_SAVE, GAIM_BUTTON_HORIZONTAL);
3395 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(save_away_mess), ca);
3396 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3398 button = gaim_pixbuf_button_from_stock(_("Save & Use"), GTK_STOCK_OK, GAIM_BUTTON_HORIZONTAL);
3399 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(su_away_mess), ca);
3400 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3402 button = gaim_pixbuf_button_from_stock(_("Use"), GTK_STOCK_EXECUTE, GAIM_BUTTON_HORIZONTAL);
3403 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(use_away_mess), ca);
3404 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3406 button = gaim_pixbuf_button_from_stock(_("Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
3407 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(destroy_dialog), ca->window);
3408 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
3410 gtk_widget_show_all(ca->window);
3413 /* smiley dialog */
3415 void close_smiley_dialog(GtkWidget *widget, struct gaim_conversation *c)
3417 struct gaim_gtk_conversation *gtkconv;
3419 gtkconv = GAIM_GTK_CONVERSATION(c);
3421 if (gtkconv->toolbar.smiley) {
3422 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gtkconv->toolbar.smiley),
3423 FALSE);
3425 if(gtkconv->dialogs.smiley) {
3426 dialogwindows = g_list_remove(dialogwindows, gtkconv->dialogs.smiley);
3427 gtk_widget_destroy(gtkconv->dialogs.smiley);
3428 gtkconv->dialogs.smiley = NULL;
3432 void insert_smiley_text(GtkWidget *widget, struct gaim_conversation *c)
3434 struct gaim_gtk_conversation *gtkconv;
3435 char *smiley_text = g_object_get_data(G_OBJECT(widget), "smiley_text");
3436 GtkTextMark *select_mark, *insert_mark;
3437 GtkTextIter select_iter, insert_iter;
3439 gtkconv = GAIM_GTK_CONVERSATION(c);
3441 select_mark = gtk_text_buffer_get_selection_bound(gtkconv->entry_buffer);
3442 insert_mark = gtk_text_buffer_get_insert(gtkconv->entry_buffer);
3444 if(insert_mark != select_mark) { /* there is text selected */
3445 gtk_text_buffer_get_iter_at_mark(gtkconv->entry_buffer, &select_iter, select_mark);
3446 gtk_text_buffer_get_iter_at_mark(gtkconv->entry_buffer, &insert_iter, insert_mark);
3447 gtk_text_buffer_delete(gtkconv->entry_buffer, &select_iter, &insert_iter);
3450 gtk_text_buffer_insert_at_cursor(gtkconv->entry_buffer, smiley_text, -1);
3451 close_smiley_dialog(NULL, c);
3454 static void add_smiley(struct gaim_conversation *c, GtkWidget *table, int row, int col, char *filename, char *face)
3456 GtkWidget *image;
3457 GtkWidget *button;
3458 struct gaim_gtk_conversation *gtkconv = GAIM_GTK_CONVERSATION(c);
3460 image = gtk_image_new_from_file(filename);
3461 button = gtk_button_new();
3462 gtk_container_add(GTK_CONTAINER(button), image);
3463 g_object_set_data(G_OBJECT(button), "smiley_text", face);
3464 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(insert_smiley_text), c);
3466 gtk_tooltips_set_tip(gtkconv->tooltips, button, face, NULL);
3468 gtk_table_attach_defaults(GTK_TABLE(table), button, col, col+1, row, row+1);
3470 /* these look really weird with borders */
3471 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
3473 gtk_widget_show(button);
3476 static gboolean smiley_is_unique(GSList *list, GtkIMHtmlSmiley *smiley) {
3477 while(list) {
3478 GtkIMHtmlSmiley *cur = list->data;
3479 if(!strcmp(cur->file, smiley->file))
3480 return FALSE;
3481 list = list->next;
3483 return TRUE;
3486 void show_smiley_dialog(struct gaim_conversation *c, GtkWidget *widget)
3488 struct gaim_gtk_conversation *gtkconv;
3489 GtkWidget *dialog;
3490 GtkWidget *smiley_table = NULL;
3491 GSList *smileys, *unique_smileys = NULL;
3492 int width;
3493 int row = 0, col = 0;
3495 gtkconv = GAIM_GTK_CONVERSATION(c);
3497 if (gtkconv->dialogs.smiley)
3498 return;
3500 if(c->account)
3501 smileys = get_proto_smileys(c->account->protocol);
3502 else
3503 smileys = get_proto_smileys(GAIM_PROTO_DEFAULT);
3505 while(smileys) {
3506 GtkIMHtmlSmiley *smiley = smileys->data;
3507 if(!smiley->hidden) {
3508 if(smiley_is_unique(unique_smileys, smiley))
3509 unique_smileys = g_slist_append(unique_smileys, smiley);
3511 smileys = smileys->next;
3515 width = floor(sqrt(g_slist_length(unique_smileys)));
3517 GAIM_DIALOG(dialog);
3518 gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
3519 gtk_window_set_role(GTK_WINDOW(dialog), "smiley_dialog");
3520 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
3522 smiley_table = gtk_table_new(width, width, TRUE);
3524 /* pack buttons */
3526 while(unique_smileys) {
3527 GtkIMHtmlSmiley *smiley = unique_smileys->data;
3528 if(!smiley->hidden) {
3529 add_smiley(c, smiley_table, row, col, smiley->file, smiley->smile);
3530 if(++col >= width) {
3531 col = 0;
3532 row++;
3535 unique_smileys = unique_smileys->next;
3538 gtk_container_add(GTK_CONTAINER(dialog), smiley_table);
3540 gtk_widget_show(smiley_table);
3542 gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
3544 /* connect signals */
3545 g_object_set_data(G_OBJECT(dialog), "dialog_type", "smiley dialog");
3546 g_signal_connect(G_OBJECT(dialog), "delete_event",
3547 G_CALLBACK(delete_event_dialog), c);
3549 /* show everything */
3550 gtk_window_set_title(GTK_WINDOW(dialog), _("Smile!"));
3551 gtk_widget_show_all(dialog);
3553 gtkconv->dialogs.smiley = dialog;
3555 return;
3558 static void do_alias_chat(GtkWidget *w, int resp, struct chat *chat)
3560 if(resp == GTK_RESPONSE_OK) {
3561 GtkWidget *entry = g_object_get_data(G_OBJECT(w), "alias_entry");
3562 const char *text = gtk_entry_get_text(GTK_ENTRY(entry));
3563 gaim_blist_alias_chat(chat, text);
3564 gaim_blist_save();
3566 gtk_widget_destroy(w);
3569 static void
3570 do_alias_buddy(GtkWidget *w, int resp, struct alias_dialog_info *info)
3572 if (resp == GTK_RESPONSE_OK) {
3573 const char *alias;
3575 alias = gtk_entry_get_text(GTK_ENTRY(info->alias_entry));
3577 gaim_blist_alias_buddy(info->buddy, (alias && *alias) ? alias : NULL);
3578 serv_alias_buddy(info->buddy);
3579 gaim_blist_save();
3582 destroy_dialog(NULL, alias_dialog);
3583 alias_dialog = NULL;
3585 g_free(info);
3588 void alias_dialog_chat(struct chat *chat) {
3589 GtkWidget *dialog;
3590 GtkWidget *hbox;
3591 GtkWidget *img;
3592 GtkWidget *vbox;
3593 GtkWidget *label;
3594 GtkWidget *alias_entry;
3596 dialog = gtk_dialog_new_with_buttons(_("Alias Buddy"), NULL,
3597 GTK_DIALOG_NO_SEPARATOR,
3598 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
3599 GTK_STOCK_OK, GTK_RESPONSE_OK,
3600 NULL);
3601 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
3602 GTK_RESPONSE_OK);
3604 gtk_container_set_border_width(GTK_CONTAINER(dialog), 6);
3605 gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
3606 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), 12);
3607 gtk_container_set_border_width(
3608 GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 6);
3610 /* The main hbox container. */
3611 hbox = gtk_hbox_new(FALSE, 12);
3612 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
3614 /* The dialog image. */
3615 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION,
3616 GTK_ICON_SIZE_DIALOG);
3617 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
3618 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
3620 /* The main vbox container. */
3621 vbox = gtk_vbox_new(FALSE, 0);
3622 gtk_container_add(GTK_CONTAINER(hbox), vbox);
3624 /* Setup the label containing the description. */
3625 label = gtk_label_new(_("Please enter an aliased name for this chat.\n"));
3626 gtk_widget_set_size_request(GTK_WIDGET(label), 350, -1);
3628 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
3629 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
3630 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
3632 hbox = gtk_hbox_new(FALSE, 6);
3633 gtk_container_add(GTK_CONTAINER(vbox), hbox);
3635 /* The "Alias:" label. */
3636 label = gtk_label_new(NULL);
3637 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Alias:"));
3638 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
3639 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
3641 /* The alias entry field. */
3642 alias_entry = gtk_entry_new();
3643 gtk_box_pack_start(GTK_BOX(hbox), alias_entry, FALSE, FALSE, 0);
3644 gtk_entry_set_activates_default(GTK_ENTRY(alias_entry), TRUE);
3645 gtk_label_set_mnemonic_widget(GTK_LABEL(label), alias_entry);
3647 gtk_entry_set_text(GTK_ENTRY(alias_entry), chat->alias);
3649 g_object_set_data(G_OBJECT(dialog), "alias_entry", alias_entry);
3651 g_signal_connect(G_OBJECT(dialog), "response",
3652 G_CALLBACK(do_alias_chat), chat);
3654 gtk_widget_show_all(dialog);
3657 void
3658 alias_dialog_bud(struct buddy *b)
3660 struct alias_dialog_info *info = NULL;
3661 struct gaim_gtk_buddy_list *gtkblist;
3662 GtkWidget *hbox;
3663 GtkWidget *vbox;
3664 GtkWidget *label;
3665 GtkWidget *table;
3666 GtkWidget *img;
3668 gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
3670 if (!alias_dialog) {
3671 info = g_new0(struct alias_dialog_info, 1);
3672 info->buddy = b;
3674 alias_dialog = gtk_dialog_new_with_buttons(_("Alias Buddy"),
3675 (gtkblist ? GTK_WINDOW(gtkblist->window) : NULL),
3676 GTK_DIALOG_NO_SEPARATOR,
3677 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
3678 GTK_STOCK_OK, GTK_RESPONSE_OK,
3679 NULL);
3681 gtk_dialog_set_default_response(GTK_DIALOG(alias_dialog),
3682 GTK_RESPONSE_OK);
3683 gtk_container_set_border_width(GTK_CONTAINER(alias_dialog), 6);
3684 gtk_window_set_resizable(GTK_WINDOW(alias_dialog), FALSE);
3685 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(alias_dialog)->vbox), 12);
3686 gtk_container_set_border_width(
3687 GTK_CONTAINER(GTK_DIALOG(alias_dialog)->vbox), 6);
3689 /* The main hbox container. */
3690 hbox = gtk_hbox_new(FALSE, 12);
3691 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(alias_dialog)->vbox), hbox);
3693 /* The dialog image. */
3694 img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION,
3695 GTK_ICON_SIZE_DIALOG);
3696 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
3697 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
3699 /* The main vbox container. */
3700 vbox = gtk_vbox_new(FALSE, 0);
3701 gtk_container_add(GTK_CONTAINER(hbox), vbox);
3703 /* Setup the label containing the description. */
3704 label = gtk_label_new(_("Please enter an aliased name for the "
3705 "person below, or rename this contact "
3706 "in your buddy list.\n"));
3707 gtk_widget_set_size_request(GTK_WIDGET(label), 350, -1);
3709 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
3710 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
3711 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
3713 hbox = gtk_hbox_new(FALSE, 6);
3714 gtk_container_add(GTK_CONTAINER(vbox), hbox);
3716 /* The table containing the entry widgets and labels. */
3717 table = gtk_table_new(2, 2, FALSE);
3718 gtk_table_set_row_spacings(GTK_TABLE(table), 6);
3719 gtk_table_set_col_spacings(GTK_TABLE(table), 6);
3720 gtk_container_set_border_width(GTK_CONTAINER(table), 12);
3721 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0);
3723 /* The "Screenname:" label. */
3724 label = gtk_label_new(NULL);
3725 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Screenname:"));
3726 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
3727 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
3729 /* The Screen name entry field. */
3730 info->name_entry = gtk_entry_new();
3731 gtk_table_attach_defaults(GTK_TABLE(table), info->name_entry,
3732 1, 2, 0, 1);
3733 gtk_entry_set_activates_default(GTK_ENTRY(info->name_entry), TRUE);
3734 gtk_label_set_mnemonic_widget(GTK_LABEL(label), info->name_entry);
3735 gtk_entry_set_text(GTK_ENTRY(info->name_entry), info->buddy->name);
3737 /* The "Alias:" label. */
3738 label = gtk_label_new(NULL);
3739 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Alias:"));
3740 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
3741 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
3743 /* The alias entry field. */
3744 info->alias_entry = gtk_entry_new();
3745 gtk_table_attach_defaults(GTK_TABLE(table), info->alias_entry,
3746 1, 2, 1, 2);
3747 gtk_entry_set_activates_default(GTK_ENTRY(info->alias_entry), TRUE);
3748 gtk_label_set_mnemonic_widget(GTK_LABEL(label), info->alias_entry);
3750 if (info->buddy->alias != NULL)
3751 gtk_entry_set_text(GTK_ENTRY(info->alias_entry),
3752 info->buddy->alias);
3754 g_signal_connect(G_OBJECT(alias_dialog), "response",
3755 G_CALLBACK(do_alias_buddy), info);
3758 gtk_widget_show_all(alias_dialog);
3760 if (info)
3761 gtk_widget_grab_focus(info->name_entry);
3765 static gboolean dont_destroy(gpointer a, gpointer b, gpointer c)
3767 return TRUE;
3770 static void do_save_log(GtkWidget *w, GtkWidget *filesel)
3772 const char *file;
3773 char path[PATHSIZE];
3774 char buf[BUF_LONG];
3775 char error[BUF_LEN];
3776 FILE *fp_old, *fp_new;
3777 char filename[PATHSIZE];
3778 char *name;
3779 char *tmp;
3781 name = g_object_get_data(G_OBJECT(filesel), "name");
3782 tmp = gaim_user_dir();
3783 g_snprintf(filename, PATHSIZE, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s%s", tmp,
3784 name ? normalize(name) : "system", name ? ".log" : "");
3786 file = (const char*)gtk_file_selection_get_filename(GTK_FILE_SELECTION(filesel));
3787 strncpy(path, file, PATHSIZE - 1);
3788 if (file_is_dir(path, filesel))
3789 return;
3791 if ((fp_new = fopen(path, "w")) == NULL) {
3792 g_snprintf(error, BUF_LONG,
3793 _("Couldn't write to %s."), path);
3794 gaim_notify_error(NULL, NULL, error, strerror(errno));
3795 return;
3798 if ((fp_old = fopen(filename, "r")) == NULL) {
3799 g_snprintf(error, BUF_LONG,
3800 _("Couldn't write to %s."), filename);
3801 gaim_notify_error(NULL, NULL, error, strerror(errno));
3802 fclose(fp_new);
3803 return;
3806 while (fgets(buf, BUF_LONG, fp_old))
3807 fputs(buf, fp_new);
3808 fclose(fp_old);
3809 fclose(fp_new);
3811 gtk_widget_destroy(filesel);
3813 return;
3816 static void show_save_log(GtkWidget *w, gchar *name)
3818 GtkWidget *filesel;
3819 gchar buf[BUF_LEN];
3821 g_snprintf(buf, BUF_LEN - 1, "%s" G_DIR_SEPARATOR_S "%s%s", gaim_home_dir(),
3822 name ? normalize(name) : "system", name ? ".log" : "");
3824 filesel = gtk_file_selection_new(_("Save Log File"));
3825 g_signal_connect(G_OBJECT(filesel), "delete_event",
3826 G_CALLBACK(destroy_dialog), filesel);
3828 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(filesel));
3829 gtk_file_selection_set_filename(GTK_FILE_SELECTION(filesel), buf);
3830 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button),
3831 "clicked", G_CALLBACK(do_save_log), filesel);
3832 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(filesel)->cancel_button),
3833 "clicked", G_CALLBACK(destroy_dialog), filesel);
3834 g_object_set_data(G_OBJECT(filesel), "name", name);
3836 gtk_widget_realize(filesel);
3837 gtk_widget_show(filesel);
3839 return;
3842 static void do_clear_log_file(GtkWidget *w, gchar *name)
3844 gchar buf[256];
3845 gchar filename[256];
3846 GtkWidget *window;
3847 char *tmp;
3849 tmp = gaim_user_dir();
3850 g_snprintf(filename, 256, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s%s", tmp,
3851 name ? normalize(name) : "system", name ? ".log" : "");
3853 if ((remove(filename)) == -1) {
3854 g_snprintf(buf, 256, _("Couldn't remove file %s." ), filename);
3855 gaim_notify_error(NULL, NULL, buf, strerror(errno));
3858 window = g_object_get_data(G_OBJECT(w), "log_window");
3859 destroy_dialog(NULL, window);
3862 static void show_clear_log(GtkWidget *w, gchar *name)
3864 GtkWidget *window;
3865 GtkWidget *box;
3866 GtkWidget *hbox;
3867 GtkWidget *button;
3868 GtkWidget *label;
3869 GtkWidget *hsep;
3871 GAIM_DIALOG(window);
3872 gtk_window_set_role(GTK_WINDOW(window), "dialog");
3873 gtk_window_set_title(GTK_WINDOW(window), _("Clear Log"));
3874 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
3875 gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
3876 g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(destroy_dialog), window);
3877 gtk_widget_realize(window);
3879 box = gtk_vbox_new(FALSE, 5);
3880 gtk_container_add(GTK_CONTAINER(window), box);
3882 label = gtk_label_new(_("Really clear log?"));
3883 gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 15);
3885 hsep = gtk_hseparator_new();
3886 gtk_box_pack_start(GTK_BOX(box), hsep, FALSE, FALSE, 0);
3888 hbox = gtk_hbox_new(FALSE, 0);
3889 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
3891 button = gaim_pixbuf_button_from_stock(_("OK"), GTK_STOCK_OK, GAIM_BUTTON_HORIZONTAL);
3892 g_object_set_data(G_OBJECT(button), "log_window", g_object_get_data(G_OBJECT(w),
3893 "log_window"));
3894 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(do_clear_log_file), name);
3895 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(destroy_dialog), window);
3896 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 5);
3898 button = gaim_pixbuf_button_from_stock(_("Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
3899 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(destroy_dialog), window);
3900 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 5);
3902 gtk_widget_show_all(window);
3904 return;
3907 static void log_show_convo(struct view_log *view)
3909 gchar buf[BUF_LONG];
3910 FILE *fp;
3911 char filename[256];
3912 int i=0;
3913 GString *string;
3914 guint block;
3916 string = g_string_new("");
3918 if (view->name) {
3919 char *tmp = gaim_user_dir();
3920 g_snprintf(filename, 256, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s.log", tmp, normalize(view->name));
3921 } else {
3922 char *tmp = gaim_user_dir();
3923 g_snprintf(filename, 256, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "system", tmp);
3925 if ((fp = fopen(filename, "r")) == NULL) {
3926 if (view->name) {
3927 g_snprintf(buf, BUF_LONG, _("Couldn't open log file %s."), filename);
3928 gaim_notify_error(NULL, NULL, buf, strerror(errno));
3930 /* If the system log doesn't exist.. no message just show empty system log window.
3931 That way user knows that the log is empty :)
3933 return;
3936 gtk_widget_set_sensitive(view->bbox, FALSE);
3937 g_signal_handlers_disconnect_by_func(G_OBJECT(view->window),
3938 G_CALLBACK(destroy_dialog), view->window);
3939 block = g_signal_connect(G_OBJECT(view->window), "delete_event",
3940 G_CALLBACK(dont_destroy), view->window);
3942 fseek(fp, view->offset, SEEK_SET);
3943 gtk_imhtml_clear(GTK_IMHTML(view->layout));
3945 while (gtk_events_pending())
3946 gtk_main_iteration();
3949 while (fgets(buf, BUF_LONG, fp) && !strstr(buf, "---- New C")) {
3950 i++;
3951 if (strlen(buf) >= 5 && (!strncmp(buf + strlen(buf) - 5, "<BR>\n", 5)))
3952 /* take off the \n */
3953 buf[strlen(buf) - 1] = '\0';
3955 /* don't lose the thirtieth line of conversation. thanks FeRD */
3956 g_string_append(string, buf);
3958 if (i == 30) {
3959 gtk_imhtml_append_text(GTK_IMHTML(view->layout), string->str, -1, view->options);
3960 g_string_free(string, TRUE);
3961 string = g_string_new("");
3962 /* you can't have these anymore. if someone clicks on another item while one is
3963 * drawing, it will try to move to that item, and that causes problems here.
3964 while (gtk_events_pending())
3965 gtk_main_iteration();
3967 i = 0;
3971 gtk_imhtml_append_text(GTK_IMHTML(view->layout), string->str, -1, view->options);
3972 gtk_imhtml_append_text(GTK_IMHTML(view->layout), "<BR>", -1, view->options);
3974 gtk_widget_set_sensitive(view->bbox, TRUE);
3975 g_signal_handler_disconnect(G_OBJECT(view->window), block);
3976 g_signal_connect(G_OBJECT(view->window), "delete_event",
3977 G_CALLBACK(destroy_dialog), view->window);
3978 g_string_free(string, TRUE);
3979 fclose(fp);
3982 static void log_select_convo(GtkTreeSelection *sel, GtkTreeModel *model)
3984 GValue val = { 0, };
3985 GtkTreeIter iter;
3987 if(!gtk_tree_selection_get_selected(sel, &model, &iter))
3988 return;
3989 gtk_tree_model_get_value(model, &iter, 1, &val);
3990 log_show_convo(g_value_get_pointer(&val));
3993 static void des_view_item(GtkObject *obj, struct view_log *view)
3995 if (view->name)
3996 g_free(view->name);
3997 g_free(view);
4000 static void des_log_win(GObject *win, gpointer data)
4002 char *x = g_object_get_data(win, "log_window");
4003 if (x)
4004 g_free(x);
4005 x = g_object_get_data(win, "name");
4006 if (x)
4007 g_free(x);
4010 void conv_show_log(GtkWidget *w, gpointer data)
4012 char *name = g_strdup(data);
4013 show_log(name);
4014 g_free(name);
4017 void chat_show_log(GtkWidget *w, gpointer data)
4019 char *name = g_strdup_printf("%s.chat", (char*)data);
4020 show_log(name);
4021 g_free(name);
4024 void show_log(char *nm)
4026 gchar filename[256];
4027 gchar buf[BUF_LONG];
4028 FILE *fp;
4029 GtkWidget *window;
4030 GtkWidget *box;
4031 GtkWidget *hbox;
4032 GtkWidget *bbox;
4033 GtkWidget *sw;
4034 GtkWidget *layout;
4035 GtkWidget *close_button;
4036 GtkWidget *clear_button;
4037 GtkWidget *save_button;
4038 GtkListStore *list_store;
4039 GtkWidget *tree_view;
4040 GtkTreeSelection *sel = NULL;
4041 GtkTreePath *path;
4042 GtkWidget *item = NULL;
4043 GtkWidget *last = NULL;
4044 GtkWidget *frame;
4045 struct view_log *view;
4046 char *name = nm ? g_strdup(nm) : NULL;
4048 int options;
4049 guint block;
4050 char convo_start[32];
4051 long offset = 0;
4053 options = GTK_IMHTML_NO_COMMENTS | GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_SCROLL;
4054 if (convo_options & OPT_CONVO_IGNORE_COLOUR)
4055 options ^= GTK_IMHTML_NO_COLOURS;
4056 if (convo_options & OPT_CONVO_IGNORE_FONTS)
4057 options ^= GTK_IMHTML_NO_FONTS;
4058 if (convo_options & OPT_CONVO_IGNORE_SIZES)
4059 options ^= GTK_IMHTML_NO_SIZES;
4061 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
4062 g_object_set_data(G_OBJECT(window), "name", name);
4063 g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(des_log_win), NULL);
4064 gtk_window_set_role(GTK_WINDOW(window), "log");
4065 if (name)
4066 g_snprintf(buf, BUF_LONG, _("Conversations with %s"), name);
4067 else
4068 g_snprintf(buf, BUF_LONG, _("System Log"));
4069 gtk_window_set_title(GTK_WINDOW(window), buf);
4070 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
4071 gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
4072 block = g_signal_connect(G_OBJECT(window), "delete_event",
4073 G_CALLBACK(dont_destroy), window);
4074 gtk_widget_realize(window);
4076 layout = gtk_imhtml_new(NULL, NULL);
4077 bbox = gtk_hbox_new(FALSE, 0);
4079 box = gtk_vbox_new(FALSE, 5);
4080 gtk_container_add(GTK_CONTAINER(window), box);
4082 hbox = gtk_hbox_new(FALSE, 5);
4083 gtk_box_pack_start(GTK_BOX(box), hbox, TRUE, TRUE, 0);
4085 if (name) {
4086 char *tmp = gaim_user_dir();
4087 g_snprintf(filename, 256, "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s.log", tmp, normalize(name));
4088 if ((fp = fopen(filename, "r")) == NULL) {
4089 g_snprintf(buf, BUF_LONG, _("Couldn't open log file %s"), filename);
4090 gaim_notify_error(NULL, NULL, buf, strerror(errno));
4091 return;
4094 list_store = gtk_list_store_new(2,
4095 G_TYPE_STRING,
4096 G_TYPE_POINTER);
4098 tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
4100 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), FALSE);
4102 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree_view),
4103 -1, "", gtk_cell_renderer_text_new(), "text", 0, NULL);
4105 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
4106 g_signal_connect(G_OBJECT(sel), "changed",
4107 G_CALLBACK(log_select_convo),
4108 NULL);
4110 frame = gtk_frame_new(_("Date"));
4111 gtk_widget_show(frame);
4113 sw = gtk_scrolled_window_new(NULL, NULL);
4114 gtk_container_set_border_width(GTK_CONTAINER(sw), 5);
4115 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), tree_view);
4116 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
4117 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
4118 gtk_widget_set_size_request(sw, 220, 220);
4119 gtk_container_add(GTK_CONTAINER(frame), sw);
4120 gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0);
4122 while (fgets(buf, BUF_LONG, fp)) {
4123 if (strstr(buf, "---- New C")) {
4124 int length;
4125 char *temp = strchr(buf, '@');
4126 GtkTreeIter iter;
4128 if (temp == NULL || strlen(temp) < 2)
4129 continue;
4131 temp++;
4132 length = strcspn(temp, "-");
4133 if (length > 31) length = 31;
4135 offset = ftell(fp);
4136 g_snprintf(convo_start, length, "%s", temp);
4137 gtk_list_store_append(list_store, &iter);
4138 view = g_new0(struct view_log, 1);
4139 view->options = options;
4140 view->offset = offset;
4141 view->name = g_strdup(name);
4142 view->bbox = bbox;
4143 view->window = window;
4144 view->layout = layout;
4145 gtk_list_store_set(list_store, &iter,
4146 0, convo_start,
4147 1, view,
4148 -1);
4149 g_signal_connect(G_OBJECT(window), "destroy",
4150 G_CALLBACK(des_view_item), view);
4151 last = item;
4154 fclose(fp);
4156 path = gtk_tree_path_new_first();
4157 gtk_tree_selection_select_path(sel, path);
4158 gtk_tree_path_free(path);
4160 g_object_unref(G_OBJECT(list_store));
4164 g_signal_handler_disconnect(G_OBJECT(window), block);
4165 g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(destroy_dialog), window);
4167 frame = gtk_frame_new(_("Log"));
4168 gtk_widget_show(frame);
4170 sw = gtk_scrolled_window_new(NULL, NULL);
4171 gtk_container_set_border_width(GTK_CONTAINER(sw), 5);
4172 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
4173 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
4174 gtk_widget_set_size_request(sw, 390, 220);
4175 gtk_container_add(GTK_CONTAINER(frame), sw);
4176 gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0);
4178 g_signal_connect(G_OBJECT(layout), "url_clicked", G_CALLBACK(open_url), NULL);
4179 gtk_container_add(GTK_CONTAINER(sw), layout);
4180 gaim_setup_imhtml(layout);
4182 gtk_box_pack_start(GTK_BOX(box), bbox, FALSE, FALSE, 0);
4183 gtk_widget_set_sensitive(bbox, FALSE);
4185 close_button = gaim_pixbuf_button_from_stock(_("Close"), GTK_STOCK_CLOSE, GAIM_BUTTON_HORIZONTAL);
4186 gtk_box_pack_end(GTK_BOX(bbox), close_button, FALSE, FALSE, 5);
4187 g_signal_connect(G_OBJECT(close_button), "clicked", G_CALLBACK(destroy_dialog), window);
4189 clear_button = gaim_pixbuf_button_from_stock(_("Clear"), GTK_STOCK_CLEAR, GAIM_BUTTON_HORIZONTAL);
4190 g_object_set_data(G_OBJECT(clear_button), "log_window", window);
4191 gtk_box_pack_end(GTK_BOX(bbox), clear_button, FALSE, FALSE, 5);
4192 g_signal_connect(G_OBJECT(clear_button), "clicked", G_CALLBACK(show_clear_log), name);
4194 save_button = gaim_pixbuf_button_from_stock(_("Save"), GTK_STOCK_SAVE, GAIM_BUTTON_HORIZONTAL);
4195 gtk_box_pack_end(GTK_BOX(bbox), save_button, FALSE, FALSE, 5);
4196 g_signal_connect(G_OBJECT(save_button), "clicked", G_CALLBACK(show_save_log), name);
4198 gtk_widget_show_all(window);
4200 if (!name) {
4201 view = g_new0(struct view_log, 1);
4202 view->options = options;
4203 view->name = NULL;
4204 view->bbox = bbox;
4205 view->window = window;
4206 view->layout = layout;
4207 log_show_convo(view);
4208 g_signal_connect(G_OBJECT(layout), "destroy", G_CALLBACK(des_view_item), view);
4211 gtk_widget_set_sensitive(bbox, TRUE);
4213 return;
4216 /*------------------------------------------------------------------------*/
4217 /* The dialog for renaming groups */
4218 /*------------------------------------------------------------------------*/
4220 static void do_rename_group(GtkObject *obj, int resp, GtkWidget *entry)
4222 const char *new_name;
4223 struct group *g;
4225 if (resp == GTK_RESPONSE_OK) {
4226 new_name = gtk_entry_get_text(GTK_ENTRY(entry));
4227 g = g_object_get_data(G_OBJECT(entry), "group");
4229 gaim_blist_rename_group(g, new_name);
4230 gaim_blist_save();
4232 destroy_dialog(rename_dialog, rename_dialog);
4235 void show_rename_group(GtkWidget *unused, struct group *g)
4238 GtkWidget *hbox, *vbox;
4239 GtkWidget *label;
4240 struct gaim_gtk_buddy_list *gtkblist;
4241 GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG);
4242 GtkWidget *name_entry = NULL;
4244 gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
4246 if (!rename_dialog) {
4247 rename_dialog = gtk_dialog_new_with_buttons(_("Rename Group"), GTK_WINDOW(gtkblist->window), 0,
4248 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
4249 gtk_dialog_set_default_response (GTK_DIALOG(rename_dialog), GTK_RESPONSE_OK);
4250 gtk_container_set_border_width (GTK_CONTAINER(rename_dialog), 6);
4251 gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE);
4252 gtk_dialog_set_has_separator(GTK_DIALOG(rename_dialog), FALSE);
4253 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(rename_dialog)->vbox), 12);
4254 gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(rename_dialog)->vbox), 6);
4256 hbox = gtk_hbox_new(FALSE, 12);
4257 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(rename_dialog)->vbox), hbox);
4258 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
4259 gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
4261 vbox = gtk_vbox_new(FALSE, 0);
4262 gtk_container_add(GTK_CONTAINER(hbox), vbox);
4264 label = gtk_label_new(_("Please enter a new name for the selected group.\n"));
4265 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
4266 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
4267 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
4269 hbox = gtk_hbox_new(FALSE, 6);
4270 gtk_container_add(GTK_CONTAINER(vbox), hbox);
4272 label = gtk_label_new(NULL);
4273 gtk_label_set_markup_with_mnemonic(GTK_LABEL(label), _("_Group:"));
4274 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
4276 name_entry = gtk_entry_new();
4277 gtk_entry_set_activates_default (GTK_ENTRY(name_entry), TRUE);
4278 g_object_set_data(G_OBJECT(name_entry), "group", g);
4279 gtk_entry_set_text(GTK_ENTRY(name_entry), g->name);
4280 gtk_box_pack_start(GTK_BOX(hbox), name_entry, FALSE, FALSE, 0);
4281 gtk_entry_set_activates_default (GTK_ENTRY(name_entry), TRUE);
4282 gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(name_entry));
4284 g_signal_connect(G_OBJECT(rename_dialog), "response", G_CALLBACK(do_rename_group), name_entry);
4288 gtk_widget_show_all(rename_dialog);
4289 if(name_entry)
4290 gtk_widget_grab_focus(GTK_WIDGET(name_entry));
4294 /*------------------------------------------------------------------------*/
4295 /* The dialog for renaming buddies */
4296 /*------------------------------------------------------------------------*/
4298 static void do_rename_buddy(GObject *obj, GtkWidget *entry)
4300 const char *new_name;
4301 struct buddy *b;
4303 new_name = gtk_entry_get_text(GTK_ENTRY(entry));
4304 b = g_object_get_data(obj, "buddy");
4306 if (!g_slist_find(connections, b->account->gc)) {
4307 destroy_dialog(rename_bud_dialog, rename_bud_dialog);
4308 return;
4311 if (new_name && (strlen(new_name) != 0) && strcmp(new_name, b->name)) {
4312 struct group *g = gaim_find_buddys_group(b);
4313 char *prevname = b->name;
4314 if (g)
4315 serv_remove_buddy(b->account->gc, b->name, g->name);
4316 b->name = g_strdup(new_name);
4317 serv_add_buddy(b->account->gc, b->name);
4318 gaim_blist_rename_buddy(b, prevname);
4319 gaim_blist_save();
4320 g_free(prevname);
4323 destroy_dialog(rename_bud_dialog, rename_bud_dialog);
4326 void show_rename_buddy(GtkWidget *unused, struct buddy *b)
4328 GtkWidget *mainbox;
4329 GtkWidget *frame;
4330 GtkWidget *fbox;
4331 GtkWidget *bbox;
4332 GtkWidget *button;
4333 GtkWidget *name_entry;
4334 GtkWidget *label;
4336 if (!rename_bud_dialog) {
4337 GAIM_DIALOG(rename_bud_dialog);
4338 gtk_window_set_role(GTK_WINDOW(rename_bud_dialog), "rename_bud_dialog");
4339 gtk_window_set_resizable(GTK_WINDOW(rename_bud_dialog), TRUE);
4340 gtk_window_set_title(GTK_WINDOW(rename_bud_dialog), _("Rename Buddy"));
4341 g_signal_connect(G_OBJECT(rename_bud_dialog), "destroy",
4342 G_CALLBACK(destroy_dialog), rename_bud_dialog);
4343 gtk_widget_realize(rename_bud_dialog);
4345 mainbox = gtk_vbox_new(FALSE, 5);
4346 gtk_container_set_border_width(GTK_CONTAINER(mainbox), 5);
4347 gtk_container_add(GTK_CONTAINER(rename_bud_dialog), mainbox);
4349 frame = gtk_frame_new(_("Rename Buddy"));
4350 gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, TRUE, 0);
4352 fbox = gtk_hbox_new(FALSE, 5);
4353 gtk_container_set_border_width(GTK_CONTAINER(fbox), 5);
4354 gtk_container_add(GTK_CONTAINER(frame), fbox);
4356 label = gtk_label_new(_("New name:"));
4357 gtk_box_pack_start(GTK_BOX(fbox), label, FALSE, FALSE, 0);
4359 name_entry = gtk_entry_new();
4360 gtk_box_pack_start(GTK_BOX(fbox), name_entry, TRUE, TRUE, 0);
4361 g_object_set_data(G_OBJECT(name_entry), "buddy", b);
4362 gtk_entry_set_text(GTK_ENTRY(name_entry), b->name);
4363 g_signal_connect(G_OBJECT(name_entry), "activate",
4364 G_CALLBACK(do_rename_buddy), name_entry);
4365 gtk_widget_grab_focus(name_entry);
4367 bbox = gtk_hbox_new(FALSE, 5);
4368 gtk_box_pack_start(GTK_BOX(mainbox), bbox, FALSE, FALSE, 0);
4370 button = gaim_pixbuf_button_from_stock(_("OK"), GTK_STOCK_OK, GAIM_BUTTON_HORIZONTAL);
4371 g_object_set_data(G_OBJECT(button), "buddy", b);
4372 gtk_box_pack_end(GTK_BOX(bbox), button, FALSE, FALSE, 0);
4373 g_signal_connect(G_OBJECT(button), "clicked",
4374 G_CALLBACK(do_rename_buddy), name_entry);
4376 button = gaim_pixbuf_button_from_stock(_("Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
4377 gtk_box_pack_end(GTK_BOX(bbox), button, FALSE, FALSE, 0);
4378 g_signal_connect(G_OBJECT(button), "clicked",
4379 G_CALLBACK(destroy_dialog), rename_bud_dialog);
4382 gtk_widget_show_all(rename_bud_dialog);
4386 GtkWidget *gaim_pixbuf_toolbar_button_from_stock(char *icon)
4388 GtkWidget *button, *image, *bbox;
4390 button = gtk_toggle_button_new();
4391 gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
4393 bbox = gtk_vbox_new(FALSE, 0);
4395 gtk_container_add (GTK_CONTAINER(button), bbox);
4397 image = gtk_image_new_from_stock(icon, GTK_ICON_SIZE_MENU);
4398 gtk_box_pack_start(GTK_BOX(bbox), image, FALSE, FALSE, 0);
4400 gtk_widget_show_all(bbox);
4401 return button;
4404 GtkWidget *
4405 gaim_pixbuf_button_from_stock(const char *text, const char *icon,
4406 GaimButtonStyle style)
4408 GtkWidget *button, *image, *label, *bbox, *ibox, *lbox;
4409 button = gtk_button_new();
4411 if (style == GAIM_BUTTON_HORIZONTAL) {
4412 bbox = gtk_hbox_new(FALSE, 5);
4413 ibox = gtk_hbox_new(FALSE, 0);
4414 lbox = gtk_hbox_new(FALSE, 0);
4415 } else {
4416 bbox = gtk_vbox_new(FALSE, 5);
4417 ibox = gtk_vbox_new(FALSE, 0);
4418 lbox = gtk_vbox_new(FALSE, 0);
4421 gtk_container_add (GTK_CONTAINER(button), bbox);
4423 gtk_box_pack_start_defaults(GTK_BOX(bbox), ibox);
4424 gtk_box_pack_start_defaults(GTK_BOX(bbox), lbox);
4426 if (icon) {
4427 image = gtk_image_new_from_stock(icon, GTK_ICON_SIZE_BUTTON);
4428 gtk_box_pack_end(GTK_BOX(ibox), image, FALSE, FALSE, 0);
4431 if (text) {
4432 label = gtk_label_new(NULL);
4433 gtk_label_set_text_with_mnemonic(GTK_LABEL(label), text);
4434 gtk_label_set_mnemonic_widget(GTK_LABEL(label), button);
4435 gtk_box_pack_start(GTK_BOX(lbox), label, FALSE, FALSE, 0);
4438 gtk_widget_show_all(bbox);
4439 return button;
4442 GtkWidget *gaim_pixbuf_button(char *text, char *iconfile, GaimButtonStyle style)
4444 GtkWidget *button, *image, *label, *bbox, *ibox, *lbox;
4445 button = gtk_button_new();
4447 if (style == GAIM_BUTTON_HORIZONTAL) {
4448 bbox = gtk_hbox_new(FALSE, 5);
4449 ibox = gtk_hbox_new(FALSE, 0);
4450 lbox = gtk_hbox_new(FALSE, 0);
4451 } else {
4452 bbox = gtk_vbox_new(FALSE, 5);
4453 ibox = gtk_vbox_new(FALSE, 0);
4454 lbox = gtk_vbox_new(FALSE, 0);
4457 gtk_container_add (GTK_CONTAINER(button), bbox);
4459 gtk_box_pack_start_defaults(GTK_BOX(bbox), ibox);
4460 gtk_box_pack_start_defaults(GTK_BOX(bbox), lbox);
4462 if (iconfile) {
4463 char *filename;
4464 filename = g_build_filename (DATADIR, "pixmaps", "gaim", "buttons", iconfile, NULL);
4465 gaim_debug(GAIM_DEBUG_MISC, "gaim_pixbuf_button",
4466 "Loading: %s\n", filename);
4467 image = gtk_image_new_from_file(filename);
4468 gtk_box_pack_end(GTK_BOX(ibox), image, FALSE, FALSE, 0);
4469 g_free(filename);
4472 if (text) {
4473 label = gtk_label_new(NULL);
4474 gtk_label_set_text_with_mnemonic(GTK_LABEL(label), text);
4475 gtk_label_set_mnemonic_widget(GTK_LABEL(label), button);
4476 gtk_box_pack_start(GTK_BOX(lbox), label, FALSE, FALSE, 0);
4479 gtk_widget_show_all(bbox);
4480 return button;
4483 int file_is_dir(const char *path, GtkWidget *w)
4485 struct stat st;
4486 char *name;
4488 if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
4489 /* append a / if needed */
4490 if (path[strlen(path) - 1] != '/') {
4491 name = g_strconcat(path, "/", NULL);
4492 } else {
4493 name = g_strdup(path);
4495 gtk_file_selection_set_filename(GTK_FILE_SELECTION(w), name);
4496 g_free(name);
4497 return 1;
4500 return 0;
4503 /*------------------------------------------------------------------------*/
4504 /* The dialog for setting V-Card info */
4505 /*------------------------------------------------------------------------*/
4507 * There are actually two "chunks" of code following: generic "multi-entry dialog"
4508 * support and V-Card dialog specific support.
4510 * At first blush, this may seem like an unnecessary duplication of effort given
4511 * that a "set dir info" dialog already exists. However, this is not so because:
4513 * 1. V-Cards can have a lot more data in them than what the current
4514 * "set dir" dialog supports.
4516 * 2. V-Card data, at least with respect to Jabber, is currently in a
4517 * state of flux. As the data and format changes, all that need be
4518 * changed with the V-Card support I've written is the "template"
4519 * data.
4521 * 3. The "multi entry dialog" support itself was originally written
4522 * to support Jabber server user registration (TBD). A "dynamically
4523 * configurable" multi-entry dialog is needed for that, as different
4524 * servers may require different registration information. It just
4525 * turned out to be well-suited to adding V-Card setting support, as
4526 * well :-).
4528 * TBD: Add check-box support to the generic multi-entry dialog support so that
4529 * it can be used to "replace" the "set dir info" support?
4531 * Multiple-language support. Currently Not In There. I think this should
4532 * be easy. Note that when it's added: if anybody saved their data in
4533 * English, it'll be lost when MLS is added and they'll have to re-enter it.
4535 * More "TBDs" noted in the code.
4539 /*------------------------------------*/
4540 /* generic multi-entry dialog support */
4541 /*------------------------------------*/
4544 * Print all multi-entry items
4546 * Note: Simply a debug helper
4548 void multi_entry_item_print_all(const GSList *list) {
4550 int cnt = 0;
4552 /* While there's something to print... */
4553 while(list != NULL) {
4554 fprintf(stderr, "label %2d: \"%s\"", ++cnt, ((MultiEntryData *) (list->data))->label);
4555 if(((MultiEntryData *) (list->data))->text != NULL) {
4556 fprintf(stderr, ", text: \"%s\"", ((MultiEntryData *) (list->data))->text);
4558 fputs("\n", stderr);
4559 list = list->next;
4564 * Print all multi-text items
4566 * Note: Simply a debug helper
4568 void multi_text_item_print_all(const GSList *list) {
4570 int cnt = 0;
4572 /* While there's something to print... */
4573 while(list != NULL) {
4574 fprintf(stderr, "label %2d: \"%s\"", ++cnt, ((MultiTextData *) (list->data))->label);
4575 if(((MultiTextData *) (list->data))->text != NULL) {
4576 fprintf(stderr, ", text: \"%s\"", ((MultiTextData *) (list->data))->text);
4578 fputs("\n", stderr);
4579 list = list->next;
4585 * Free all multi-entry item allocs and NULL the list pointer
4587 void multi_entry_items_free_all(GSList **list)
4590 GSList *next = *list;
4591 MultiEntryData *data;
4593 /* While there's something to free() ... */
4594 while(next != NULL) {
4595 data = (MultiEntryData *) next->data;
4596 g_free(data->label);
4597 g_free(data->text);
4598 g_free(data);
4599 next = next->next;
4601 g_slist_free(*list);
4602 *list = NULL;
4606 * Free all multi-text item allocs and NULL the list pointer
4608 void multi_text_items_free_all(GSList **list)
4611 GSList *next = *list;
4612 MultiTextData *data;
4614 /* While there's something to free() ... */
4615 while(next != NULL) {
4616 data = (MultiTextData *) next->data;
4617 g_free(data->label);
4618 g_free(data->text);
4619 g_free(data);
4620 next = next->next;
4622 g_slist_free(*list);
4623 *list = NULL;
4627 * See if a MultiEntryData item contains a given label
4629 * See: glib docs for g_slist_compare_custom() for details
4631 static gint multi_entry_data_label_compare(gconstpointer data, gconstpointer label)
4633 return(strcmp(((MultiEntryData *) (data))->label, (char *) label));
4637 * Add a new multi-entry item to list
4639 * If adding to existing list: will search the list for existence of
4640 * "label" and change/create "text" entry if necessary.
4643 MultiEntryData *multi_entry_list_update(GSList **list, const char *label, const char *text, int add_it)
4645 GSList *found;
4646 MultiEntryData *data;
4648 if((found = g_slist_find_custom(*list, (void *)label, multi_entry_data_label_compare)) == NULL) {
4649 if(add_it) {
4650 data = (MultiEntryData *) g_slist_last(*list =
4651 g_slist_append(*list, g_malloc(sizeof(MultiEntryData))))->data;
4652 data->label = strcpy(g_malloc(strlen(label) +1), label);
4653 data->text = NULL;
4655 * default to setting "visible" and editable to TRUE - they can be
4656 * overridden later, of course.
4658 data->visible = TRUE;
4659 data->editable = TRUE;
4660 } else {
4661 data = NULL;
4663 } else {
4664 data = found->data;
4667 if(data != NULL && text != NULL && text[0] != '\0') {
4668 if(data->text == NULL) {
4669 data->text = g_malloc(strlen(text) + 1);
4670 } else {
4671 data->text = g_realloc(data->text, strlen(text) + 1);
4673 strcpy(data->text, text);
4676 return(data);
4680 * See if a MultiTextData item contains a given label
4682 * See: glib docs for g_slist_compare_custom() for details
4684 static gint multi_text_data_label_compare(gconstpointer data, gconstpointer label)
4686 return(strcmp(((MultiTextData *) (data))->label, (char *) label));
4690 * Add a new multi-text item to list
4692 * If adding to existing list: will search the list for existence of
4693 * "label" and change/create "text" text if necessary.
4696 MultiTextData *multi_text_list_update(GSList **list, const char *label, const char *text, int add_it)
4698 GSList *found;
4699 MultiTextData *data;
4701 if((found = g_slist_find_custom(*list, (void *)label, multi_text_data_label_compare)) == NULL) {
4702 if(add_it) {
4703 data = (MultiTextData *) g_slist_last(*list =
4704 g_slist_append(*list, g_malloc(sizeof(MultiTextData))))->data;
4705 data->label = strcpy(g_malloc(strlen(label) +1), label);
4706 data->text = NULL;
4707 } else {
4708 data = NULL;
4710 } else {
4711 data = found->data;
4714 if(data != NULL && text != NULL && text[0] != '\0') {
4715 if(data->text == NULL) {
4716 data->text = g_malloc(strlen(text) + 1);
4717 } else {
4718 data->text = g_realloc(data->text, strlen(text) + 1);
4720 strcpy(data->text, text);
4723 return(data);
4727 * Free-up the multi-entry item list and the MultiEntryDlg
4728 * struct alloc.
4730 void multi_entry_free(struct multi_entry_dlg *b)
4732 multi_entry_items_free_all(&(b->multi_entry_items));
4733 multi_text_items_free_all(&(b->multi_text_items));
4734 g_free(b->instructions->text);
4735 g_free(b->instructions);
4736 g_free(b->entries_title);
4737 g_free(b);
4741 * Multi-Entry dialog "destroyed" catcher
4743 * Free-up the multi-entry item list, destroy the dialog widget
4744 * and free the MultiEntryDlg struct alloc.
4747 void multi_entry_dialog_destroy(GtkWidget *widget, gpointer data)
4749 MultiEntryDlg *b = data;
4751 multi_entry_free(b);
4755 * Show/Re-show instructions
4757 void re_show_multi_entry_instr(MultiInstrData *instructions)
4759 if(instructions->label != NULL) {
4760 if(instructions->text == NULL) {
4761 gtk_widget_hide(instructions->label);
4762 } else {
4763 gtk_label_set_text(GTK_LABEL (instructions->label), _(instructions->text));
4764 gtk_widget_show(instructions->label);
4770 * Show/Re-show entry boxes
4772 void re_show_multi_entry_entries(GtkWidget **entries_table,
4773 GtkWidget *entries_frame,
4774 GSList *multi_entry_items)
4776 GtkWidget *label;
4777 GSList *multi_entry;
4778 MultiEntryData *med;
4779 int rows, row_num, col_num, col_offset;
4780 int cols = 1;
4782 /* Figure-out number of rows needed for table */
4783 if((rows = g_slist_length(multi_entry_items)) > 9) {
4784 rows /= 2;
4785 ++cols;
4788 if(*entries_table != NULL) {
4789 gtk_widget_destroy(GTK_WIDGET (*entries_table));
4791 *entries_table = gtk_table_new(rows, 3 * cols, FALSE);
4792 gtk_container_add(GTK_CONTAINER (entries_frame), *entries_table);
4794 for(col_num = 0, multi_entry = multi_entry_items; col_num < cols && multi_entry != NULL;
4795 ++col_num) {
4796 col_offset = col_num * 3;
4797 for(row_num = 0; row_num < rows && multi_entry != NULL;
4798 ++row_num, multi_entry = multi_entry->next) {
4800 med = (MultiEntryData *) multi_entry->data;
4802 label = gtk_label_new(_(med->label));
4803 gtk_misc_set_alignment(GTK_MISC(label), (gfloat) 1.0, (gfloat) 0.5);
4804 gtk_table_attach_defaults(GTK_TABLE (*entries_table), label,
4805 col_offset, 1 + col_offset, row_num, row_num +1);
4806 gtk_widget_show(label);
4808 label = gtk_label_new(": ");
4809 gtk_misc_set_alignment(GTK_MISC(label), (gfloat) 0.0, (gfloat) 0.5);
4810 gtk_table_attach_defaults(GTK_TABLE (*entries_table), label,
4811 1 + col_offset, 2 + col_offset, row_num, row_num +1);
4812 gtk_widget_show(label);
4814 med->widget = gtk_entry_new();
4815 gtk_entry_set_max_length(GTK_ENTRY(med->widget), 50);
4816 if(med->text != NULL) {
4817 gtk_entry_set_text(GTK_ENTRY (med->widget), med->text);
4819 gtk_entry_set_visibility(GTK_ENTRY (med->widget), med->visible);
4820 gtk_editable_set_editable(GTK_EDITABLE(med->widget), med->editable);
4821 gtk_table_attach(GTK_TABLE (*entries_table), med->widget,
4822 2 + col_offset, 3 + col_offset, row_num, row_num +1,
4823 GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 5, 0);
4824 gtk_widget_show(med->widget);
4828 gtk_widget_show(*entries_table);
4832 * Show/Re-show textboxes
4834 void re_show_multi_entry_textboxes(GtkWidget **texts_ibox,
4835 GtkWidget *texts_obox,
4836 GSList *multi_text_items)
4838 GSList *multi_text;
4839 MultiTextData *mtd;
4840 GtkWidget *frame;
4841 GtkWidget *sw;
4843 if(*texts_ibox != NULL) {
4844 gtk_widget_destroy(GTK_WIDGET (*texts_ibox));
4846 *texts_ibox = gtk_vbox_new(FALSE, 5);
4847 gtk_container_add(GTK_CONTAINER (texts_obox), *texts_ibox);
4849 for(multi_text = multi_text_items; multi_text != NULL; multi_text = multi_text->next) {
4850 mtd = (MultiTextData *) multi_text->data;
4851 frame = gtk_frame_new(_(mtd->label));
4852 sw = gtk_scrolled_window_new(NULL, NULL);
4853 gtk_container_set_border_width(GTK_CONTAINER(sw), 5);
4854 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
4855 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
4856 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
4857 GTK_SHADOW_IN);
4858 gtk_widget_set_size_request(sw, 300, 100);
4859 gtk_container_add(GTK_CONTAINER (frame), sw);
4860 gtk_container_add(GTK_CONTAINER (*texts_ibox), frame);
4861 mtd->textbox = gtk_text_view_new();
4862 gtk_text_view_set_editable(GTK_TEXT_VIEW(mtd->textbox), TRUE);
4863 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(mtd->textbox), GTK_WRAP_WORD_CHAR);
4864 gtk_text_buffer_set_text(
4865 gtk_text_view_get_buffer(GTK_TEXT_VIEW(mtd->textbox)),
4866 mtd->text?mtd->text:"", -1);
4867 gtk_container_add(GTK_CONTAINER (sw), mtd->textbox);
4868 gtk_widget_show(mtd->textbox);
4869 gtk_widget_show(sw);
4870 gtk_widget_show(frame);
4873 gtk_widget_show(*texts_ibox);
4877 * Create and initialize a new Multi-Entry Dialog struct
4879 MultiEntryDlg *multi_entry_dialog_new()
4881 MultiEntryDlg *b = g_new0(MultiEntryDlg, 1);
4882 b->instructions = g_new0(MultiInstrData, 1);
4883 b->multi_entry_items = NULL;
4884 b->multi_text_items = NULL;
4885 return(b);
4889 * Instantiate a new multi-entry dialog
4891 * data == pointer to MultiEntryDlg with the following
4892 * initialized:
4894 * role
4895 * title
4896 * user
4897 * multi_entry_items - pointers to MultiEntryData list
4898 * and MultiTextData list
4899 * instructions (optional)
4900 * ok function pointer
4901 * cancel function pointer (actually used to set
4902 * window destroy signal--cancel asserts destroy)
4904 * sets the following in the MultiEntryDialog struct:
4906 * window
4908 void show_multi_entry_dialog(gpointer data)
4910 GtkWidget *vbox, *hbox;
4911 GtkWidget *button;
4912 MultiEntryDlg *b = data;
4914 GAIM_DIALOG(b->window);
4915 gtk_container_set_border_width(GTK_CONTAINER(b->window), 5);
4916 gtk_window_set_role(GTK_WINDOW(b->window), b->role);
4917 gtk_window_set_title(GTK_WINDOW (b->window), b->title);
4919 /* Clean up if user dismisses window via window manager! */
4920 g_signal_connect(G_OBJECT(b->window), "destroy", G_CALLBACK(b->cancel), (gpointer) b);
4921 gtk_widget_realize(b->window);
4923 vbox = gtk_vbox_new(FALSE, 5);
4924 gtk_container_add(GTK_CONTAINER (b->window), vbox);
4926 b->instructions->label = gtk_label_new(NULL);
4927 gtk_label_set_line_wrap(GTK_LABEL (b->instructions->label), TRUE);
4928 gtk_box_pack_start(GTK_BOX (vbox), b->instructions->label, TRUE, TRUE, 5);
4929 re_show_multi_entry_instr(b->instructions);
4931 b->entries_frame = gtk_frame_new(b->entries_title);
4932 gtk_box_pack_start(GTK_BOX (vbox), b->entries_frame, TRUE, TRUE, 5);
4933 b->entries_table = NULL;
4934 re_show_multi_entry_entries(&(b->entries_table), b->entries_frame, b->multi_entry_items);
4936 b->texts_obox = gtk_vbox_new(FALSE, 0);
4937 gtk_box_pack_start(GTK_BOX (vbox), b->texts_obox, TRUE, TRUE, 5);
4938 b->texts_ibox = NULL;
4939 re_show_multi_entry_textboxes(&(b->texts_ibox), b->texts_obox, b->multi_text_items);
4941 hbox = gtk_hbox_new(FALSE, 0);
4942 gtk_box_pack_start(GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
4944 button = gaim_pixbuf_button_from_stock(_("Save"), GTK_STOCK_SAVE, GAIM_BUTTON_HORIZONTAL);
4945 g_signal_connect(G_OBJECT (button), "clicked",
4946 G_CALLBACK (b->ok), (gpointer) b);
4947 gtk_box_pack_end(GTK_BOX (hbox), button, FALSE, FALSE, 5);
4949 button = gaim_pixbuf_button_from_stock(_("Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL);
4951 /* Let "destroy handling" (set above) handle cleanup */
4952 g_signal_connect_swapped(G_OBJECT (button), "clicked",
4953 G_CALLBACK (gtk_widget_destroy), G_OBJECT (b->window));
4954 gtk_box_pack_end(GTK_BOX (hbox), button, FALSE, FALSE, 5);
4956 gtk_widget_show_all(b->window);
4960 /*------------------------------------*/
4961 /* V-Card dialog specific support */
4962 /*------------------------------------*/
4965 * V-Card "set info" dialog "Save" clicked
4967 * Copy data from GTK+ dialogs into GSLists, call protocol-specific
4968 * formatter and save the user info data.
4970 void set_vcard_dialog_ok_clicked(GtkWidget *widget, gpointer data)
4972 MultiEntryDlg *b = (MultiEntryDlg *) data;
4973 struct gaim_connection *gc;
4974 gchar *tmp;
4975 GSList *list;
4977 for(list = b->multi_entry_items; list != NULL; list = list->next) {
4978 if(((MultiEntryData *) list->data)->text != NULL) {
4979 g_free(((MultiEntryData *) list->data)->text);
4981 ((MultiEntryData *) list->data)->text =
4982 g_strdup(gtk_entry_get_text(GTK_ENTRY(((MultiEntryData *) list->data)->widget)));
4985 for(list = b->multi_text_items; list != NULL; list = list->next) {
4986 if(((MultiTextData *) list->data)->text != NULL) {
4987 g_free(((MultiTextData *) list->data)->text);
4989 ((MultiTextData *) list->data)->text =
4990 gtk_text_view_get_text(GTK_TEXT_VIEW(((MultiTextData *) list->data)->textbox), FALSE);
4994 tmp = b->custom(b);
4997 * Set the user info and (possibly) send to the server
4999 if (b->account) {
5000 strncpy(b->account->user_info, tmp, sizeof b->account->user_info);
5001 gc = b->account->gc;
5003 save_prefs();
5005 if (gc)
5006 serv_set_info(gc, b->account->user_info);
5009 g_free(tmp);
5011 /* Let multi-edit dialog window "destroy" event catching handle remaining cleanup */
5012 gtk_widget_destroy(GTK_WIDGET (b->window));
5016 * Instantiate a v-card dialog
5018 void show_set_vcard(MultiEntryDlg *b)
5020 b->ok = set_vcard_dialog_ok_clicked;
5021 b->cancel = multi_entry_dialog_destroy;
5023 show_multi_entry_dialog(b);
5027 /*------------------------------------------------------------------------*/
5028 /* End dialog for setting v-card info */
5029 /*------------------------------------------------------------------------*/