[gaim-migrate @ 3125]
[pidgin-git.git] / src / multi.c
blob1bfe5eca533a93292c342f8b1a1dd4b54fe74248
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 #include <string.h>
23 #include <ctype.h>
24 #include <gtk/gtk.h>
25 #include "prpl.h"
26 #include "multi.h"
27 #include "gaim.h"
28 #ifdef USE_APPLET
29 #include "applet.h"
30 #endif
32 #include "pixmaps/gnome_add.xpm"
33 #include "pixmaps/gnome_preferences.xpm"
34 #include "pixmaps/join.xpm"
35 #include "pixmaps/gnome_remove.xpm"
36 #include "pixmaps/cancel.xpm"
37 #include "pixmaps/ok.xpm"
38 #include "pixmaps/tb_redo.xpm"
39 #include "pixmaps/tb_undo.xpm"
40 #include "pixmaps/tb_refresh.xpm"
41 #include "pixmaps/no_icon.xpm"
43 #define LOGIN_STEPS 5
45 GSList *connections;
47 static GtkWidget *acctedit = NULL;
48 static GtkWidget *list = NULL; /* the clist of names in the accteditor */
50 static GSList *mod_users = NULL;
52 static struct mod_user *find_mod_user(struct aim_user *a)
54 GSList *m = mod_users;
55 while (m) {
56 struct mod_user *u = m->data;
57 if (u->user == a)
58 return u;
59 m = m->next;
61 return NULL;
64 static void generate_protocol_options(struct mod_user *, GtkWidget *);
66 struct mod_usr_opt {
67 struct mod_user *user;
68 int opt;
71 struct gaim_connection *new_gaim_conn(struct aim_user *user)
73 struct gaim_connection *gc = g_new0(struct gaim_connection, 1);
74 gc->edittype = EDIT_GC;
75 gc->protocol = user->protocol;
76 gc->prpl = find_prpl(user->protocol);
77 g_snprintf(gc->username, sizeof(gc->username), "%s", user->username);
78 g_snprintf(gc->password, sizeof(gc->password), "%s", user->password);
79 gc->keepalive = 0;
80 gc->inpa = 0;
81 gc->buddy_chats = NULL;
82 gc->groups = NULL;
83 gc->permit = NULL;
84 gc->deny = NULL;
86 connections = g_slist_append(connections, gc);
88 user->gc = gc;
89 gc->user = user;
91 return gc;
94 struct meter_window {
95 GtkWidget *window;
96 GtkTable *table;
97 gint rows;
98 gint active_count;
99 } *meter_win = NULL;
101 void destroy_gaim_conn(struct gaim_connection *gc)
103 GSList *g = gc->groups;
104 GSList *h;
105 struct group *m;
106 struct buddy *n;
107 connections = g_slist_remove(connections, gc);
108 while (g) {
109 m = (struct group *)g->data;
110 g = g_slist_remove(g, m);
111 h = m->members;
112 while (h) {
113 n = (struct buddy *)h->data;
114 if (gc->prpl->buddy_free)
115 gc->prpl->buddy_free(n);
116 h = g_slist_remove(h, n);
117 g_free(n);
119 g_free(m);
121 g = gc->permit;
122 while (g) {
123 g_free(g->data);
124 g = g_slist_remove(g, g->data);
126 g = gc->deny;
127 while (g) {
128 g_free(g->data);
129 g = g_slist_remove(g, g->data);
131 g_free(gc);
132 #ifndef USE_APPLET
133 if (!connections && mainwindow)
134 gtk_widget_show(mainwindow);
135 #endif
138 static void delete_acctedit(GtkWidget *w, gpointer d)
140 if (acctedit) {
141 save_prefs();
142 gtk_widget_destroy(acctedit);
144 acctedit = NULL;
145 list = NULL;
146 if (!d && !blist && !mainwindow && !connections)
147 gtk_main_quit();
150 static gint acctedit_close(GtkWidget *w, gpointer d)
152 gtk_widget_destroy(acctedit);
153 if (!d && !blist && !mainwindow && !connections)
154 gtk_main_quit();
155 return FALSE;
158 static char *proto_name(int proto)
160 struct prpl *p = find_prpl(proto);
161 if (p && p->name)
162 return p->name();
163 else
164 return "Unknown";
168 static void reorder_list(GtkCList *cl, int from, int to, void *p)
170 struct aim_user *au;
171 if (from == to)
172 return; /* This shouldn't happen, but just in case */
173 au = (struct aim_user*)g_slist_nth_data(aim_users, from);
174 aim_users = g_slist_remove (aim_users, au);
175 aim_users = g_slist_insert(aim_users, au, to);
176 save_prefs();
179 void regenerate_user_list()
181 char *titles[4];
182 GSList *u = aim_users;
183 struct aim_user *a;
184 int i;
186 if (!acctedit)
187 return;
189 gtk_clist_clear(GTK_CLIST(list));
191 while (u) {
192 a = (struct aim_user *)u->data;
193 titles[0] = a->username;
194 titles[1] = a->gc ? "Yes" : "No";
195 titles[2] = (a->options & OPT_USR_AUTO) ? "True" : "False";
196 titles[3] = proto_name(a->protocol);
197 i = gtk_clist_append(GTK_CLIST(list), titles);
198 gtk_clist_set_row_data(GTK_CLIST(list), i, a);
199 u = u->next;
203 static GtkWidget *generate_list()
205 GtkWidget *win;
206 char *titles[4] = { "Screenname", "Currently Online", "Auto-login", "Protocol" };
208 win = gtk_scrolled_window_new(0, 0);
209 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(win), GTK_POLICY_AUTOMATIC,
210 GTK_POLICY_ALWAYS);
212 list = gtk_clist_new_with_titles(4, titles);
213 gtk_clist_set_column_width(GTK_CLIST(list), 0, 90);
214 gtk_clist_set_selection_mode(GTK_CLIST(list), GTK_SELECTION_EXTENDED);
215 gtk_clist_column_titles_passive(GTK_CLIST(list));
217 gtk_container_add(GTK_CONTAINER(win), list);
218 gtk_widget_show(list);
220 regenerate_user_list();
221 gtk_clist_set_reorderable (GTK_CLIST(list), TRUE);
222 gtk_clist_set_use_drag_icons (GTK_CLIST(list), TRUE);
223 gtk_signal_connect(GTK_OBJECT(list), "row-move", GTK_SIGNAL_FUNC(reorder_list), NULL);
225 gtk_widget_show(win);
226 return win;
229 static void delmod(GtkWidget *w, struct mod_user *u)
231 mod_users = g_slist_remove(mod_users, u);
232 g_free(u);
235 static void mod_opt(GtkWidget *b, struct mod_usr_opt *m)
237 m->user->options = m->user->options ^ m->opt;
240 static void free_muo(GtkWidget *b, struct mod_usr_opt *m)
242 g_free(m);
245 static GtkWidget *acct_button(const char *text, struct mod_user *u, int option, GtkWidget *box)
247 GtkWidget *button;
248 struct mod_usr_opt *muo = g_new0(struct mod_usr_opt, 1);
249 button = gtk_check_button_new_with_label(text);
250 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), (u->options & option));
251 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
252 muo->user = u;
253 muo->opt = option;
254 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(mod_opt), muo);
255 gtk_signal_connect(GTK_OBJECT(button), "destroy", GTK_SIGNAL_FUNC(free_muo), muo);
256 gtk_widget_show(button);
257 return button;
260 static void ok_mod(GtkWidget *w, struct mod_user *u)
262 GList *tmp;
263 const char *txt;
264 int i;
265 struct aim_user *a;
266 struct prpl *p;
268 if (!u->user) {
269 txt = gtk_entry_get_text(GTK_ENTRY(u->name));
270 u->user = new_user(txt, u->protocol, u->options);
272 a = u->user;
274 a->options = u->options;
275 a->protocol = u->protocol;
276 txt = gtk_entry_get_text(GTK_ENTRY(u->name));
277 g_snprintf(a->username, sizeof(a->username), "%s", txt);
278 txt = gtk_entry_get_text(GTK_ENTRY(u->pass));
279 if (a->options & OPT_USR_REM_PASS)
280 g_snprintf(a->password, sizeof(a->password), "%s", txt);
281 else
282 a->password[0] = '\0';
284 i = gtk_clist_find_row_from_data(GTK_CLIST(list), a);
285 gtk_clist_set_text(GTK_CLIST(list), i, 0, a->username);
286 gtk_clist_set_text(GTK_CLIST(list), i, 2,
287 (a->options & OPT_USR_AUTO) ? "True" : "False");
288 gtk_clist_set_text(GTK_CLIST(list), i, 3, proto_name(a->protocol));
290 tmp = u->opt_entries;
291 while (tmp) {
292 GtkEntry *entry = tmp->data;
293 int pos = (int)gtk_object_get_user_data(GTK_OBJECT(entry));
294 g_snprintf(a->proto_opt[pos], sizeof(a->proto_opt[pos]), "%s",
295 gtk_entry_get_text(entry));
296 tmp = tmp->next;
298 if (u->opt_entries)
299 g_list_free(u->opt_entries);
300 u->opt_entries = NULL;
302 g_snprintf(a->iconfile, sizeof(a->iconfile), "%s", u->iconfile);
303 if (u->icondlg)
304 gtk_widget_destroy(u->icondlg);
305 u->icondlg = NULL;
308 * See if user registration is supported/required
310 if((p = find_prpl(u->protocol)) == NULL) {
311 /* TBD: error dialog here! (This should never happen, you know...) */
312 fprintf(stderr, "dbg: couldn't find protocol for protocol number %d!\n", u->protocol);
313 fflush(stderr);
314 } else {
315 if(p->register_user != NULL &&
316 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(u->register_user)) == TRUE) {
318 p->register_user(a);
322 save_prefs();
324 gtk_widget_destroy(u->mod);
327 static void cancel_mod(GtkWidget *w, struct mod_user *u)
329 if (u->opt_entries)
330 g_list_free(u->opt_entries);
331 u->opt_entries = NULL;
332 if (u->icondlg)
333 gtk_widget_destroy(u->icondlg);
334 u->icondlg = NULL;
335 gtk_widget_destroy(u->mod);
338 static void set_prot(GtkWidget *opt, int proto)
340 struct mod_user *u = gtk_object_get_user_data(GTK_OBJECT(opt));
341 struct prpl *p, *q;
342 q = find_prpl(proto);
343 if (u->protocol != proto) {
344 int i;
345 for (i = 0; i < 7; i++)
346 u->proto_opt[i][0] = '\0';
347 p = find_prpl(u->protocol);
349 if (!(p->options & OPT_PROTO_NO_PASSWORD) && (q->options & OPT_PROTO_NO_PASSWORD)) {
350 gtk_widget_hide(u->pwdbox);
351 gtk_widget_hide(u->rempass);
352 } else if ((p->options & OPT_PROTO_NO_PASSWORD) && !(q->options & OPT_PROTO_NO_PASSWORD)) {
353 gtk_widget_show(u->pwdbox);
354 gtk_widget_show(u->rempass);
356 if (!(p->options & OPT_PROTO_MAIL_CHECK) && (q->options & OPT_PROTO_MAIL_CHECK)) {
357 gtk_widget_show(u->checkmail);
358 } else if ((p->options & OPT_PROTO_MAIL_CHECK) && !(q->options & OPT_PROTO_MAIL_CHECK)) {
359 gtk_widget_hide(u->checkmail);
362 if (!(p->options & OPT_PROTO_BUDDY_ICON) && (q->options & OPT_PROTO_BUDDY_ICON)) {
363 gtk_widget_show(u->iconsel);
364 } else if ((p->options & OPT_PROTO_BUDDY_ICON) && !(q->options & OPT_PROTO_BUDDY_ICON)) {
365 gtk_widget_hide(u->iconsel);
368 if ((q->options & OPT_PROTO_BUDDY_ICON) || (q->options & OPT_PROTO_MAIL_CHECK))
369 gtk_widget_show(u->user_frame);
370 else
371 gtk_widget_hide(u->user_frame);
373 u->protocol = proto;
374 generate_protocol_options(u, u->main);
378 static GtkWidget *make_protocol_menu(GtkWidget *box, struct mod_user *u)
380 GtkWidget *optmenu;
381 GtkWidget *menu;
382 GtkWidget *opt;
383 GSList *p = protocols;
384 struct prpl *e;
385 int count = 0;
386 gboolean found = FALSE;
388 optmenu = gtk_option_menu_new();
389 gtk_box_pack_start(GTK_BOX(box), optmenu, FALSE, FALSE, 5);
390 gtk_widget_show(optmenu);
392 menu = gtk_menu_new();
394 while (p) {
395 e = (struct prpl *)p->data;
396 if (e->protocol == u->protocol)
397 found = TRUE;
398 if (!found)
399 count++;
400 if (e->name)
401 opt = gtk_menu_item_new_with_label(e->name());
402 else
403 opt = gtk_menu_item_new_with_label("Unknown");
404 gtk_object_set_user_data(GTK_OBJECT(opt), u);
405 gtk_signal_connect(GTK_OBJECT(opt), "activate",
406 GTK_SIGNAL_FUNC(set_prot), (void *)e->protocol);
407 gtk_menu_append(GTK_MENU(menu), opt);
408 gtk_widget_show(opt);
409 p = p->next;
412 gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu);
413 gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), count);
415 return optmenu;
418 static void des_icon_sel(GtkWidget *w, struct mod_user *u)
420 w = u->icondlg;
421 if (u->icondlg)
422 u->icondlg = NULL;
423 if (w)
424 gtk_widget_destroy(w);
427 static void set_icon(GtkWidget *w, struct mod_user *u)
429 GtkWidget *sel = u->icondlg;
430 char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(sel));
432 if (file_is_dir(file, sel))
433 return;
435 gtk_entry_set_text(GTK_ENTRY(u->iconentry), file);
436 g_snprintf(u->iconfile, sizeof(u->iconfile), "%s", file);
437 u->icondlg = NULL;
439 gtk_widget_destroy(sel);
442 static void sel_icon_dlg(GtkWidget *w, struct mod_user *u)
444 GtkWidget *dlg;
445 char buf[256];
447 if (u->icondlg) {
448 gtk_widget_show(u->icondlg);
449 return;
452 dlg = gtk_file_selection_new(_("Gaim - Load Buddy Icon"));
453 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(dlg));
454 if (u->iconfile) {
455 char *tmp = g_dirname(u->iconfile);
456 gtk_file_selection_set_filename(GTK_FILE_SELECTION(dlg), tmp);
457 g_free(tmp);
458 } else {
459 g_snprintf(buf, sizeof(buf), "%s/", g_get_home_dir());
460 gtk_file_selection_set_filename(GTK_FILE_SELECTION(dlg), buf);
463 gtk_signal_connect(GTK_OBJECT(dlg), "destroy", GTK_SIGNAL_FUNC(des_icon_sel), u);
464 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(dlg)->cancel_button), "clicked",
465 GTK_SIGNAL_FUNC(des_icon_sel), u);
466 gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(dlg)->ok_button), "clicked",
467 GTK_SIGNAL_FUNC(set_icon), u);
469 u->icondlg = dlg;
471 gtk_widget_show(dlg);
474 static void reset_icon(GtkWidget *w, struct mod_user *u)
476 u->iconfile[0] = 0;
477 gtk_entry_set_text(GTK_ENTRY(u->iconentry), "");
480 static GtkWidget *build_icon_selection(struct mod_user *u, GtkWidget *box)
482 GtkWidget *hbox;
483 GtkWidget *label;
484 GtkWidget *name;
485 GtkWidget *browse;
486 GtkWidget *reset;
488 if (u->user)
489 g_snprintf(u->iconfile, sizeof(u->iconfile), "%s", u->user->iconfile);
491 hbox = gtk_hbox_new(FALSE, 0);
492 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 5);
493 gtk_widget_show(hbox);
495 label = gtk_label_new(_("Buddy Icon File:"));
496 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
497 gtk_widget_show(label);
499 name = gtk_entry_new();
500 gtk_entry_set_text(GTK_ENTRY(name), u->iconfile);
501 gtk_entry_set_editable(GTK_ENTRY(name), FALSE);
502 gtk_box_pack_start(GTK_BOX(hbox), name, TRUE, TRUE, 5);
503 gtk_widget_show(name);
504 u->iconentry = name;
506 browse = gtk_button_new_with_label(_("Browse"));
507 gtk_signal_connect(GTK_OBJECT(browse), "clicked", GTK_SIGNAL_FUNC(sel_icon_dlg), u);
508 gtk_box_pack_start(GTK_BOX(hbox), browse, FALSE, FALSE, 0);
509 gtk_widget_show(browse);
511 reset = gtk_button_new_with_label(_("Reset"));
512 gtk_signal_connect(GTK_OBJECT(reset), "clicked", GTK_SIGNAL_FUNC(reset_icon), u);
513 gtk_box_pack_start(GTK_BOX(hbox), reset, FALSE, FALSE, 0);
514 gtk_widget_show(reset);
516 return hbox;
519 static void generate_login_options(struct mod_user *u, GtkWidget *box)
521 GtkWidget *frame;
522 GtkWidget *vbox;
523 GtkWidget *hbox;
524 GtkWidget *label;
526 struct prpl *p;
528 frame = gtk_frame_new("Login Options");
529 gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 0);
531 vbox = gtk_vbox_new(FALSE, 5);
532 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
533 gtk_container_add(GTK_CONTAINER(frame), vbox);
535 hbox = gtk_hbox_new(FALSE, 5);
536 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
538 label = gtk_label_new(_("Screenname:"));
539 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
541 u->name = gtk_entry_new();
542 gtk_box_pack_start(GTK_BOX(hbox), u->name, TRUE, TRUE, 0);
544 u->pwdbox = gtk_hbox_new(FALSE, 5);
545 gtk_box_pack_start(GTK_BOX(vbox), u->pwdbox, FALSE, FALSE, 0);
547 label = gtk_label_new(_("Password:"));
548 gtk_box_pack_start(GTK_BOX(u->pwdbox), label, FALSE, FALSE, 0);
550 u->pass = gtk_entry_new();
551 gtk_box_pack_start(GTK_BOX(u->pwdbox), u->pass, TRUE, TRUE, 0);
552 gtk_entry_set_visibility(GTK_ENTRY(u->pass), FALSE);
554 hbox = gtk_hbox_new(FALSE, 5);
555 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
556 gtk_widget_show(hbox);
558 label = gtk_label_new(_("Protocol:"));
559 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
561 make_protocol_menu(hbox, u);
563 u->rempass = acct_button(_("Remember Password"), u, OPT_USR_REM_PASS, vbox);
564 acct_button(_("Auto-Login"), u, OPT_USR_AUTO, vbox);
566 gtk_widget_show_all(frame);
568 if (u->user) {
569 gtk_entry_set_text(GTK_ENTRY(u->name), u->user->username);
570 gtk_entry_set_text(GTK_ENTRY(u->pass), u->user->password);
573 p = find_prpl(u->protocol);
574 if (p && (p->options & OPT_PROTO_NO_PASSWORD)) {
575 gtk_widget_hide(u->pwdbox);
576 gtk_widget_hide(u->rempass);
580 static void generate_user_options(struct mod_user *u, GtkWidget *box)
582 /* This function will add the appropriate (depending on the current
583 * protocol) widgets to frame and return TRUE if there anything
584 * was added (meaning the frame should be shown)
585 * Eric will most likely change this (as he does all other submitted code)
586 * so that it will accept the vbox as an argument and create, add, and show
587 * the frame itself (like generate_protocol_options). I'd do it myself, but I'm
588 * tired and I don't care. */
589 /* Sean was right. I did do that. I told him I would. */
591 GtkWidget *vbox;
593 struct prpl *p = find_prpl(u->protocol);
595 u->user_frame = gtk_frame_new("User Options");
596 gtk_box_pack_start(GTK_BOX(box), u->user_frame, FALSE, FALSE, 0);
597 gtk_widget_show(u->user_frame);
599 vbox = gtk_vbox_new(FALSE, 5);
600 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
601 gtk_container_add(GTK_CONTAINER(u->user_frame), vbox);
602 gtk_widget_show(vbox);
604 u->checkmail = acct_button(_("New Mail Notifications"), u, OPT_USR_MAIL_CHECK, vbox);
605 u->iconsel = build_icon_selection(u, vbox);
607 if (!p) {
608 gtk_widget_hide(u->user_frame);
609 return;
612 if (!(p->options & OPT_PROTO_MAIL_CHECK))
613 gtk_widget_hide(u->checkmail);
614 if (!(p->options & OPT_PROTO_BUDDY_ICON))
615 gtk_widget_hide(u->iconsel);
617 if ((p->options & OPT_PROTO_BUDDY_ICON) || (p->options & OPT_PROTO_MAIL_CHECK))
618 return;
619 gtk_widget_hide(u->user_frame);
622 static void generate_protocol_options(struct mod_user *u, GtkWidget *box)
624 struct prpl *p = find_prpl(u->protocol);
626 GList *op, *tmp;
628 GtkWidget *vbox;
629 GtkWidget *hbox;
630 GtkWidget *label;
631 GtkWidget *entry;
633 char buf[256];
635 if (u->proto_frame)
636 gtk_widget_destroy(u->proto_frame);
637 u->proto_frame = NULL;
639 if (u->opt_entries) {
640 g_list_free(u->opt_entries);
641 u->opt_entries = NULL;
644 if (!p)
645 return;
647 if (!p->user_opts)
648 return;
650 tmp = op = p->user_opts();
652 if (!op)
653 return;
655 g_snprintf(buf, sizeof(buf), "%s Options", p->name());
656 u->proto_frame = gtk_frame_new(buf);
657 gtk_box_pack_start(GTK_BOX(box), u->proto_frame, FALSE, FALSE, 0);
658 gtk_widget_show(u->proto_frame);
660 vbox = gtk_vbox_new(FALSE, 5);
661 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
662 gtk_container_add(GTK_CONTAINER(u->proto_frame), vbox);
663 gtk_widget_show(vbox);
665 while (op) {
666 struct proto_user_opt *puo = op->data;
668 hbox = gtk_hbox_new(FALSE, 5);
669 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
670 gtk_widget_show(hbox);
672 label = gtk_label_new(puo->label);
673 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
674 gtk_widget_show(label);
676 entry = gtk_entry_new();
677 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
678 gtk_object_set_user_data(GTK_OBJECT(entry), (void *)puo->pos);
679 if (u->proto_opt[puo->pos][0]) {
680 debug_printf("setting text %s\n", u->proto_opt[puo->pos]);
681 gtk_entry_set_text(GTK_ENTRY(entry), u->proto_opt[puo->pos]);
682 } else {
683 gtk_entry_set_text(GTK_ENTRY(entry), puo->def);
685 gtk_widget_show(entry);
687 u->opt_entries = g_list_append(u->opt_entries, entry);
689 g_free(puo);
690 op = op->next;
693 if(p->register_user != NULL) {
694 u->register_user = gtk_check_button_new_with_label(_("Register with server"));
695 gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(u->register_user), FALSE);
696 gtk_box_pack_start(GTK_BOX(vbox), u->register_user, FALSE, FALSE, 0);
697 gtk_widget_show(u->register_user);
700 g_list_free(tmp);
703 static void show_acct_mod(struct aim_user *a)
705 /* This is the fucking modify account dialog. I've fucking seperated it into
706 * three fucking frames:
707 * a fucking Login Options frame, a fucking User Options frame and a fucking
708 * Protcol Options frame. This fucking removes the two fucking tabs, which were
709 * quite fucking uneccessary. Fuck. */
710 /* -- SeanEgan */
711 GtkWidget *hbox;
712 GtkWidget *button;
714 struct mod_user *u = find_mod_user(a);
716 if (!u) {
717 u = g_new0(struct mod_user, 1);
718 u->user = a;
719 mod_users = g_slist_append(mod_users, u);
721 if (a) {
722 int i;
723 u->options = a->options;
724 if (find_prpl(a->protocol))
725 u->protocol = a->protocol;
726 else if (protocols)
727 u->protocol = ((struct prpl *)protocols->data)->protocol;
728 else
729 u->protocol = -1;
730 g_snprintf(u->iconfile, sizeof(u->iconfile), "%s", a->iconfile);
731 for (i = 0; i < 7; i++)
732 g_snprintf(u->proto_opt[i], sizeof(u->proto_opt[i]), "%s",
733 a->proto_opt[i]);
734 } else {
735 u->options = OPT_USR_REM_PASS;
736 if (find_prpl(DEFAULT_PROTO))
737 u->protocol = DEFAULT_PROTO;
738 else if (protocols)
739 u->protocol = ((struct prpl *)protocols->data)->protocol;
740 else
741 u->protocol = -1;
743 } else {
744 gtk_widget_show(u->mod);
745 return;
748 u->mod = gtk_window_new(GTK_WINDOW_TOPLEVEL);
749 gtk_window_set_wmclass(GTK_WINDOW(u->mod), "account", "Gaim");
750 gtk_widget_realize(u->mod);
751 aol_icon(u->mod->window);
752 gtk_window_set_title(GTK_WINDOW(u->mod), _("Gaim - Modify Account"));
753 gtk_window_set_policy(GTK_WINDOW(u->mod), FALSE, TRUE, TRUE); /* nothing odd here :) */
754 gtk_signal_connect(GTK_OBJECT(u->mod), "destroy", GTK_SIGNAL_FUNC(delmod), u);
756 u->main = gtk_vbox_new(FALSE, 5);
757 gtk_container_border_width(GTK_CONTAINER(u->main), 5);
758 gtk_container_add(GTK_CONTAINER(u->mod), u->main);
759 gtk_widget_show(u->main);
761 generate_login_options(u, u->main);
762 generate_user_options(u, u->main);
763 generate_protocol_options(u, u->main);
765 hbox = gtk_hbox_new(FALSE, 5);
766 gtk_box_pack_end(GTK_BOX(u->main), hbox, FALSE, FALSE, 0);
767 gtk_widget_show(hbox);
769 button = picture_button(u->mod, _("Cancel"), cancel_xpm);
770 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
771 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(cancel_mod), u);
772 gtk_widget_show(button);
774 button = picture_button(u->mod, _("OK"), ok_xpm);
775 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
776 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(ok_mod), u);
777 gtk_widget_show(button);
779 gtk_widget_show(u->mod);
782 static void add_acct(GtkWidget *w, gpointer d)
784 show_acct_mod(NULL);
787 static void mod_acct(GtkWidget *w, gpointer d)
789 GList *l = GTK_CLIST(list)->selection;
790 int row = -1;
791 struct aim_user *u;
792 while (l) {
793 row = (int)l->data;
794 if (row != -1) {
795 u = g_slist_nth_data(aim_users, row);
796 if (u)
797 show_acct_mod(u);
799 l = l->next;
803 struct pass_prompt {
804 struct aim_user *u;
805 GtkWidget *win;
806 GtkWidget *entry;
808 static GSList *passes = NULL;
810 static struct pass_prompt *find_pass_prompt(struct aim_user *u)
812 GSList *p = passes;
813 while (p) {
814 struct pass_prompt *r = p->data;
815 if (r->u == u)
816 return r;
817 p = p->next;
819 return NULL;
822 static void pass_des(GtkWidget *w, struct pass_prompt *p)
824 passes = g_slist_remove(passes, p);
825 g_free(p);
828 static void pass_cancel(GtkWidget *w, struct pass_prompt *p)
830 gtk_widget_destroy(p->win);
833 static void pass_signon(GtkWidget *w, struct pass_prompt *p)
835 const char *txt = gtk_entry_get_text(GTK_ENTRY(p->entry));
836 g_snprintf(p->u->password, sizeof(p->u->password), "%s", txt);
837 #ifdef USE_APPLET
838 set_user_state(signing_on);
839 #endif
840 serv_login(p->u);
841 gtk_widget_destroy(p->win);
844 static void do_pass_dlg(struct aim_user *u)
846 /* we can safely assume that u is not NULL */
847 GtkWidget *frame;
848 GtkWidget *vbox;
849 GtkWidget *hbox;
850 char buf[96];
851 GtkWidget *label;
852 GtkWidget *button;
853 struct pass_prompt *p = find_pass_prompt(u);
855 if (p) {
856 gtk_widget_show(p->win);
857 return;
860 p = g_new0(struct pass_prompt, 1);
861 p->u = u;
862 passes = g_slist_append(passes, p);
864 GAIM_DIALOG(p->win);
865 gtk_window_set_wmclass(GTK_WINDOW(p->win), "password", "Gaim");
866 gtk_container_border_width(GTK_CONTAINER(p->win), 5);
867 gtk_signal_connect(GTK_OBJECT(p->win), "destroy", GTK_SIGNAL_FUNC(pass_des), p);
868 gtk_widget_realize(p->win);
869 aol_icon(p->win->window);
871 frame = gtk_frame_new(_("Enter Password"));
872 gtk_container_add(GTK_CONTAINER(p->win), frame);
873 gtk_widget_show(frame);
875 vbox = gtk_vbox_new(FALSE, 5);
876 gtk_container_add(GTK_CONTAINER(frame), vbox);
877 gtk_widget_show(vbox);
879 hbox = gtk_hbox_new(FALSE, 5);
880 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
881 gtk_widget_show(hbox);
883 g_snprintf(buf, sizeof(buf), "Password for %s:", u->username);
884 label = gtk_label_new(buf);
885 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
886 gtk_widget_show(label);
888 p->entry = gtk_entry_new();
889 gtk_entry_set_visibility(GTK_ENTRY(p->entry), FALSE);
890 gtk_box_pack_start(GTK_BOX(hbox), p->entry, FALSE, FALSE, 5);
891 gtk_signal_connect(GTK_OBJECT(p->entry), "activate", GTK_SIGNAL_FUNC(pass_signon), p);
892 gtk_widget_grab_focus(p->entry);
893 gtk_widget_show(p->entry);
895 hbox = gtk_hbox_new(FALSE, 5);
896 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
897 gtk_widget_show(hbox);
899 button = picture_button(p->win, _("Cancel"), cancel_xpm);
900 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(pass_cancel), p);
901 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 5);
903 button = picture_button(p->win, _("Signon"), ok_xpm);
904 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(pass_signon), p);
905 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 5);
907 gtk_widget_show(p->win);
910 static void acct_signin(GtkWidget *w, gpointer d)
912 GList *l = GTK_CLIST(list)->selection;
913 int row = -1;
914 struct aim_user *u = NULL;
915 struct prpl *p = NULL;
916 while (l) {
917 row = (int)l->data;
918 u = g_slist_nth_data(aim_users, row);
919 p = find_prpl(u->protocol);
920 if (!u->gc && p && p->login) {
921 struct prpl *p = find_prpl(u->protocol);
922 if (p && !(p->options & OPT_PROTO_NO_PASSWORD) && !u->password[0]) {
923 do_pass_dlg(u);
924 } else {
925 serv_login(u);
926 #ifdef USE_APPLET
927 set_user_state(signing_on);
928 #endif /* USE_APPLET */
929 gtk_clist_set_text(GTK_CLIST(list), row, 1, "Attempting");
931 } else if (u->gc) {
932 u->gc->wants_to_die = TRUE;
933 signoff(u->gc);
934 } else {
935 do_error_dialog(_("You cannot log this account in; you do not have "
936 "the protocol it uses loaded, or the protocol does "
937 "not have a login function."), _("Login Error"));
939 l = l->next;
943 static void do_del_acct(gpointer w, struct aim_user *u)
945 if (u->gc) {
946 u->gc->wants_to_die = TRUE;
947 signoff(u->gc);
949 gtk_clist_remove(GTK_CLIST(list), g_slist_index(aim_users, u));
950 aim_users = g_slist_remove(aim_users, u);
951 save_prefs();
954 static void del_acct(GtkWidget *w, gpointer d)
956 GList *l = GTK_CLIST(list)->selection;
957 char buf[8192];
958 int row = -1;
959 struct aim_user *u;
960 while (l) {
961 row = (int)l->data;
962 u = g_slist_nth_data(aim_users, row);
963 if (!u)
964 return;
966 g_snprintf(buf, sizeof(buf), _("Are you sure you want to delete %s?"), u->username);
967 do_ask_dialog(buf, u, do_del_acct, NULL);
968 l = l->next;
972 static void sel_auto(gpointer w, gpointer d)
974 GSList *l = aim_users;
975 struct aim_user *u;
976 int i = 0; /* faster than doing g_list_index each time */
977 while (l) {
978 u = l->data;
979 l = l->next;
980 if (u->options & OPT_USR_AUTO)
981 gtk_clist_select_row(GTK_CLIST(list), i, -1);
982 else
983 gtk_clist_unselect_row(GTK_CLIST(list), i, -1);
984 i++;
988 void account_editor(GtkWidget *w, GtkWidget *W)
990 /* please kill me */
991 GtkWidget *vbox;
992 GtkWidget *hbox;
993 GtkWidget *vbox2;
994 GtkWidget *sw;
995 GtkWidget *button; /* used for many things */
997 if (acctedit) {
998 gtk_widget_show(acctedit);
999 return;
1002 acctedit = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1003 gtk_window_set_title(GTK_WINDOW(acctedit), _("Gaim - Account Editor"));
1004 gtk_window_set_wmclass(GTK_WINDOW(acctedit), "accounteditor", "Gaim");
1005 gtk_widget_realize(acctedit);
1006 aol_icon(acctedit->window);
1007 gtk_widget_set_usize(acctedit, -1, 200);
1008 gtk_signal_connect(GTK_OBJECT(acctedit), "destroy", GTK_SIGNAL_FUNC(delete_acctedit), W);
1010 vbox = gtk_vbox_new(FALSE, 5);
1011 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1012 gtk_container_add(GTK_CONTAINER(acctedit), vbox);
1014 hbox = gtk_hbox_new(FALSE, 5);
1015 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0);
1017 sw = generate_list();
1019 vbox2 = gtk_vbox_new(TRUE, 5);
1020 gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 0);
1022 button = picture_button2(acctedit, _("Select All"), tb_refresh_xpm, 2);
1023 gtk_box_pack_start(GTK_BOX(vbox2), button, TRUE, TRUE, 0);
1024 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
1025 GTK_SIGNAL_FUNC(gtk_clist_select_all), GTK_OBJECT(list));
1027 button = picture_button2(acctedit, _("Select Autos"), tb_redo_xpm, 2);
1028 gtk_box_pack_start(GTK_BOX(vbox2), button, TRUE, TRUE, 0);
1029 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sel_auto), NULL);
1031 button = picture_button2(acctedit, _("Select None"), tb_undo_xpm, 2);
1032 gtk_box_pack_start(GTK_BOX(vbox2), button, TRUE, TRUE, 0);
1033 gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
1034 GTK_SIGNAL_FUNC(gtk_clist_unselect_all), GTK_OBJECT(list));
1036 gtk_box_pack_start(GTK_BOX(hbox), sw, TRUE, TRUE, 0);
1038 hbox = gtk_hbox_new(TRUE, 5);
1039 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1041 button = picture_button(acctedit, _("Add"), gnome_add_xpm);
1042 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
1043 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(add_acct), NULL);
1045 button = picture_button(acctedit, _("Modify"), gnome_preferences_xpm);
1046 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
1047 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(mod_acct), NULL);
1049 button = picture_button(acctedit, _("Sign On/Off"), join_xpm);
1050 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
1051 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(acct_signin), NULL);
1053 button = picture_button(acctedit, _("Delete"), gnome_remove_xpm);
1054 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
1055 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(del_acct), NULL);
1057 button = picture_button(acctedit, _("Close"), cancel_xpm);
1058 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
1059 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(acctedit_close), W);
1061 gtk_widget_show_all(acctedit);
1064 struct signon_meter {
1065 struct gaim_connection *gc;
1066 GtkWidget *button;
1067 GtkWidget *progress;
1068 GtkWidget *status;
1070 static GSList *meters = NULL;
1072 GtkWidget* create_meter_pixmap (GtkWidget *widget, struct gaim_connection *gc)
1074 GdkPixmap *gdkpixmap;
1075 GdkBitmap *mask;
1076 GtkWidget *pixmap;
1078 create_prpl_icon (widget, gc, &gdkpixmap, &mask);
1080 pixmap = gtk_pixmap_new (gdkpixmap, mask);
1081 gdk_pixmap_unref (gdkpixmap);
1082 gdk_bitmap_unref (mask);
1083 return pixmap;
1086 static struct signon_meter *find_signon_meter(struct gaim_connection *gc)
1088 GSList *m = meters;
1089 while (m) {
1090 if (((struct signon_meter *)m->data)->gc == gc)
1091 return m->data;
1092 m = m->next;
1094 return NULL;
1097 void kill_meter(struct signon_meter *meter) {
1098 gtk_widget_set_sensitive (meter->button, FALSE);
1099 gtk_progress_bar_update(GTK_PROGRESS_BAR(meter->progress), 1);
1100 gtk_statusbar_pop(GTK_STATUSBAR(meter->status), 1);
1101 gtk_statusbar_push(GTK_STATUSBAR(meter->status), 1, "Done.");
1102 meter_win->active_count--;
1103 if (meter_win->active_count == 0) {
1104 gtk_widget_destroy(meter_win->window);
1105 g_free (meter_win);
1106 meter_win = NULL;
1110 void account_online(struct gaim_connection *gc)
1112 int i;
1113 struct signon_meter *meter = find_signon_meter(gc);
1115 /* first we hide the login progress meter */
1116 if (meter) {
1117 kill_meter(meter);
1118 meters = g_slist_remove(meters, meter);
1119 g_free(meter);
1122 /* then we do the buddy list stuff */
1123 if (mainwindow)
1124 gtk_widget_hide(mainwindow);
1126 #ifdef USE_APPLET
1127 if (blist_options & OPT_BLIST_APP_BUDDY_SHOW) {
1128 show_buddy_list();
1129 refresh_buddy_window();
1130 createOnlinePopup();
1131 applet_buddy_show = TRUE;
1132 } else if (!blist) {
1133 show_buddy_list();
1134 build_edit_tree();
1135 gtk_widget_hide(blist);
1136 applet_buddy_show = FALSE;
1137 } else {
1138 build_edit_tree();
1140 set_user_state(online);
1141 #else
1142 show_buddy_list();
1143 refresh_buddy_window();
1144 #endif
1146 update_connection_dependent_prefs();
1147 do_away_menu();
1148 do_proto_menu();
1149 redo_convo_menus();
1150 gaim_setup(gc);
1152 plugin_event(event_signon, gc, 0, 0, 0);
1153 system_log(log_signon, gc, NULL, OPT_LOG_BUDDY_SIGNON | OPT_LOG_MY_SIGNON);
1155 /* away option given? */
1156 if (opt_away) {
1157 away_on_login(opt_away_arg);
1158 /* don't do it again */
1159 opt_away = 0;
1160 } else if (awaymessage) {
1161 serv_set_away(gc, GAIM_AWAY_CUSTOM, awaymessage->message);
1163 if (opt_away_arg != NULL) {
1164 g_free(opt_away_arg);
1165 opt_away_arg = NULL;
1168 /* everything for the account editor */
1169 if (!acctedit)
1170 return;
1171 i = gtk_clist_find_row_from_data(GTK_CLIST(list), gc->user);
1172 gtk_clist_set_text(GTK_CLIST(list), i, 1, "Yes");
1173 gtk_clist_set_text(GTK_CLIST(list), i, 3, gc->prpl->name());
1175 return;
1178 void account_offline(struct gaim_connection *gc)
1180 int i;
1181 struct signon_meter *meter = find_signon_meter(gc);
1182 if (meter) {
1183 kill_meter(meter);
1184 meters = g_slist_remove(meters, meter);
1185 g_free(meter);
1187 gc->user->gc = NULL; /* wasn't that awkward? */
1188 if (!acctedit)
1189 return;
1190 i = gtk_clist_find_row_from_data(GTK_CLIST(list), gc->user);
1191 gtk_clist_set_text(GTK_CLIST(list), i, 1, "No");
1194 void auto_login()
1196 GSList *u = aim_users;
1197 struct aim_user *a = NULL;
1199 while (u) {
1200 a = (struct aim_user *)u->data;
1201 if ((a->options & OPT_USR_AUTO) && (a->options & OPT_USR_REM_PASS)) {
1202 #ifdef USE_APPLET
1203 set_user_state(signing_on);
1204 #endif /* USE_APPLET */
1205 serv_login(a);
1207 u = u->next;
1211 static void cancel_signon(GtkWidget *button, struct signon_meter *meter)
1213 meter->gc->wants_to_die = TRUE;
1214 signoff(meter->gc);
1217 static gint meter_destroy(GtkWidget *window, GdkEvent *evt, struct signon_meter *meter)
1219 return TRUE;
1222 static struct signon_meter *register_meter(struct gaim_connection *gc, GtkWidget *widget, GtkTable *table, gint *rows)
1224 GtkWidget *graphic;
1225 GtkWidget *label;
1226 GtkWidget *nest_vbox;
1227 GString *name_to_print;
1228 struct signon_meter *meter;
1230 name_to_print = g_string_new(gc->username);
1232 meter = g_new0(struct signon_meter, 1);
1234 (*rows)++;
1235 gtk_table_resize (table, *rows, 4);
1237 graphic = create_meter_pixmap( widget , gc);
1239 nest_vbox = gtk_vbox_new (FALSE, 0);
1241 name_to_print = g_string_prepend(name_to_print, "Signon: ");
1242 label = gtk_label_new (name_to_print->str);
1243 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1245 meter->status = gtk_statusbar_new();
1246 gtk_widget_set_usize(meter->status, 250, 0);
1248 meter->progress = gtk_progress_bar_new ();
1250 meter->button = gtk_button_new_with_label ("Cancel");
1251 gtk_signal_connect (GTK_OBJECT (meter->button), "clicked", GTK_SIGNAL_FUNC (cancel_signon), meter);
1253 gtk_table_attach (GTK_TABLE (table), graphic, 0, 1, *rows, *rows+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1254 gtk_table_attach (GTK_TABLE (table), nest_vbox, 1, 2, *rows, *rows+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1255 gtk_box_pack_start (GTK_BOX (nest_vbox), GTK_WIDGET (label), FALSE, FALSE, 0);
1256 gtk_box_pack_start (GTK_BOX (nest_vbox), GTK_WIDGET (meter->status), FALSE, FALSE, 0);
1257 gtk_table_attach (GTK_TABLE (table), meter->progress, 2, 3, *rows, *rows+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1258 gtk_table_attach (GTK_TABLE (table), meter->button, 3, 4, *rows, *rows+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1260 gtk_widget_show_all (GTK_WIDGET (meter_win->window));
1262 meter_win->active_count++;
1264 return meter;
1267 static void loop_cancel () {
1268 GSList *m = meters;
1269 struct signon_meter *meter = NULL;
1271 while (m) {
1272 meter = (struct signon_meter *) (m->data);
1273 meter->gc->wants_to_die = TRUE;
1274 signoff((struct gaim_connection *) meter->gc);
1275 m = meters;
1279 void set_login_progress(struct gaim_connection *gc, float howfar, char *message)
1281 struct signon_meter *meter = find_signon_meter(gc);
1283 if (mainwindow)
1284 gtk_widget_hide(mainwindow);
1286 if (!meter_win) {
1287 GtkWidget *cancel_button;
1288 GtkWidget *vbox;
1290 meter_win = g_new0(struct meter_window, 1);
1291 meter_win->rows=0;
1293 meter_win->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1294 GAIM_DIALOG(meter_win->window);
1295 gtk_window_set_policy(GTK_WINDOW(meter_win->window), 0, 0, 1);
1296 gtk_window_set_wmclass(GTK_WINDOW(meter_win->window), "signon", "Gaim");
1297 gtk_container_set_border_width(GTK_CONTAINER(meter_win->window), 5);
1298 gtk_window_set_title (GTK_WINDOW (meter_win->window), "Gaim Account Signon");
1299 gtk_widget_realize(meter_win->window);
1300 aol_icon(meter_win->window->window);
1302 vbox = gtk_vbox_new (FALSE, 0);
1303 gtk_container_add (GTK_CONTAINER (meter_win->window), GTK_WIDGET (vbox));
1305 meter_win->table = (GtkTable *) gtk_table_new (1 , 4, FALSE);
1306 gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (meter_win->table), FALSE, FALSE, 0);
1307 gtk_container_set_border_width (GTK_CONTAINER (meter_win->table), 5);
1308 gtk_table_set_row_spacings (GTK_TABLE (meter_win->table), 5);
1309 gtk_table_set_col_spacings (GTK_TABLE (meter_win->table), 10);
1311 cancel_button = gtk_button_new_with_label ("Cancel All");
1312 gtk_signal_connect_object (GTK_OBJECT (cancel_button), "clicked", GTK_SIGNAL_FUNC (loop_cancel), NULL);
1313 gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (cancel_button), FALSE, FALSE, 0);
1315 gtk_signal_connect (GTK_OBJECT (meter_win->window), "delete_event", GTK_SIGNAL_FUNC (meter_destroy), NULL);
1318 if (!meter) {
1319 char buf[256];
1321 meter = register_meter(gc, GTK_WIDGET (meter_win->window), GTK_TABLE (meter_win->table), (gint *) &meter_win->rows);
1322 meter->gc = gc;
1323 meters = g_slist_append(meters, meter);
1325 g_snprintf(buf, sizeof(buf), "%s Signing On (using %s)", gc->username, gc->prpl->name());
1328 gtk_progress_bar_update(GTK_PROGRESS_BAR(meter->progress), howfar / LOGIN_STEPS);
1329 gtk_statusbar_pop(GTK_STATUSBAR(meter->status), 1);
1330 gtk_statusbar_push(GTK_STATUSBAR(meter->status), 1, message);
1333 struct kick_dlg {
1334 struct aim_user *user;
1335 GtkWidget *dlg;
1337 static GSList *kicks = NULL;
1339 static struct kick_dlg *find_kick_dlg(struct aim_user *u)
1341 GSList *k = kicks;
1342 while (k) {
1343 struct kick_dlg *d = k->data;
1344 if (d->user == u)
1345 return d;
1346 k = k->next;
1348 return NULL;
1351 static void set_kick_null(GtkObject *obj, struct kick_dlg *k)
1353 kicks = g_slist_remove(kicks, k);
1354 g_free(k);
1358 * Common code for hide_login_progress(), and hide_login_progress_info()
1360 static void hide_login_progress_common(struct gaim_connection *gc,
1361 char *details,
1362 char *title,
1363 char *prologue)
1365 char buf[2048];
1366 struct kick_dlg *k = find_kick_dlg(gc->user);
1367 struct signon_meter *meter = find_signon_meter(gc);
1368 sprintf(buf, _("%s\n%s: %s"), full_date(), prologue, details);
1369 if (k)
1370 gtk_widget_destroy(k->dlg);
1371 k = g_new0(struct kick_dlg, 1);
1372 k->user = gc->user;
1373 k->dlg = do_error_dialog(buf, title);
1374 kicks = g_slist_append(kicks, k);
1375 gtk_signal_connect(GTK_OBJECT(k->dlg), "destroy", GTK_SIGNAL_FUNC(set_kick_null), k);
1376 if (meter) {
1377 kill_meter(meter);
1378 meters = g_slist_remove(meters, meter);
1379 g_free(meter);
1383 void hide_login_progress(struct gaim_connection *gc, char *why)
1385 char buf[2048];
1387 sprintf(buf, _("%s was unable to sign on"), gc->username);
1388 hide_login_progress_common(gc, why, _("Signon Error"), buf);
1392 * Like hide_login_progress(), but for informational, not error/warning,
1393 * messages.
1396 void hide_login_progress_notice(struct gaim_connection *gc, char *why)
1398 hide_login_progress_common(gc, why, _("Notice"), gc->username);
1402 * Like hide_login_progress(), but for non-signon error messages.
1405 void hide_login_progress_error(struct gaim_connection *gc, char *why)
1407 char buf[2048];
1408 g_snprintf(buf, sizeof(buf), _("%s has been signed off"), gc->username);
1409 hide_login_progress_common(gc, why, _("Connection Error"), buf);
1412 void signoff_all()
1414 GSList *c = connections;
1415 struct gaim_connection *g = NULL;
1417 while (c) {
1418 g = (struct gaim_connection *)c->data;
1419 g->wants_to_die = TRUE;
1420 signoff(g);
1421 c = connections;
1425 void signoff(struct gaim_connection *gc)
1427 /* core stuff */
1428 debug_printf("date: %s\n", full_date());
1429 plugin_event(event_signoff, gc, 0, 0, 0);
1430 system_log(log_signoff, gc, NULL, OPT_LOG_BUDDY_SIGNON | OPT_LOG_MY_SIGNON);
1432 /* UI stuff */
1433 convo_menu_remove(gc);
1434 remove_icon_data(gc);
1435 serv_close(gc);
1436 redo_buddy_list();
1437 build_edit_tree();
1438 do_away_menu();
1439 do_proto_menu();
1440 redo_convo_menus();
1441 #ifdef USE_APPLET
1442 if (connections)
1443 set_user_state(online);
1444 #endif
1445 update_connection_dependent_prefs();
1447 if (connections)
1448 return;
1450 destroy_all_dialogs();
1451 destroy_buddy();
1452 #ifdef USE_APPLET
1453 set_user_state(offline);
1454 applet_buddy_show = FALSE;
1456 if (applet) {
1457 /* These don't have any purpose if the applet is gone :-P */
1458 applet_widget_unregister_callback(APPLET_WIDGET(applet), "signoff");
1459 remove_applet_away();
1461 #else
1462 show_login();
1463 #endif /* USE_APPLET */
1464 if (misc_options & OPT_MISC_BUDDY_TICKER)
1465 BuddyTickerSignoff();
1468 struct aim_user *new_user(const char *name, int proto, int opts)
1470 char *titles[4];
1471 int i;
1473 struct aim_user *u = g_new0(struct aim_user, 1);
1474 g_snprintf(u->username, sizeof(u->username), "%s", name);
1475 g_snprintf(u->user_info, sizeof(u->user_info), "%s", DEFAULT_INFO);
1476 u->protocol = proto;
1477 u->options = opts;
1478 aim_users = g_slist_append(aim_users, u);
1480 if (list) {
1481 titles[0] = u->username;
1482 titles[1] = u->gc ? "Yes" : "No";
1483 titles[2] = (u->options & OPT_USR_AUTO) ? "True" : "False";
1484 titles[3] = proto_name(u->protocol);
1485 i = gtk_clist_append(GTK_CLIST(list), titles);
1486 gtk_clist_set_row_data(GTK_CLIST(list), i, u);
1489 return u;