comparison src/multi.c @ 5563:9eb5b13fd412

[gaim-migrate @ 5965] Just a taste of what's coming. Standard "This won't compile" thing. Plugin authors, you're going to hate me, but that's okay, because I have friends too! It's really late. My brain resembles that of fish swimming in jello pudding with neon lights flying around chanting musicals. I'm not on drugs. I'm just that tired. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Fri, 30 May 2003 09:38:29 +0000
parents b7319c094153
children e2f2d8857f9f
comparison
equal deleted inserted replaced
5562:3c8d34574601 5563:9eb5b13fd412
35 #include "win32dep.h" 35 #include "win32dep.h"
36 #endif 36 #endif
37 37
38 #define LOGIN_STEPS 5 38 #define LOGIN_STEPS 5
39 39
40 GSList *connections;
41 int connecting_count = 0;
42
43 static GtkWidget *acctedit = NULL;
44 static GtkWidget *treeview = NULL; /* the treeview of names in the accteditor */
45 static GtkListStore *model = NULL;
46
47 static GSList *mod_accounts = NULL;
48
49 enum 40 enum
50 { 41 {
51 COLUMN_SCREENNAME, 42 COLUMN_SCREENNAME,
52 COLUMN_ONLINE, 43 COLUMN_ONLINE,
53 COLUMN_AUTOLOGIN, 44 COLUMN_AUTOLOGIN,
54 COLUMN_PROTOCOL, 45 COLUMN_PROTOCOL,
55 COLUMN_DATA, 46 COLUMN_DATA,
56 NUM_COLUMNS 47 NUM_COLUMNS
57 }; 48 };
58 49
59 struct mod_account {
60 struct gaim_account *account;
61
62 /* these are temporary */
63 char username[64];
64 char show[400];
65 char password[32];
66 int options;
67 int protocol;
68 char proto_opt[7][256];
69
70 /* stuff for modify window */
71 GtkWidget *mod;
72 GtkWidget *main;
73 GtkWidget *disc_box;
74 GtkWidget *name;
75 GtkWidget *alias;
76 GtkWidget *pwdbox;
77 GtkWidget *pass;
78 GtkWidget *rempass;
79 GtkWidget *login_frame;
80 GtkWidget *user_frame;
81 GtkWidget *proto_frame;
82 GtkSizeGroup *sg;
83 GList *user_split_entries;
84 GList *opt_entries;
85
86 /* stuff for icon selection */
87 char iconfile[256];
88 GtkWidget *iconsel;
89 GtkWidget *iconentry;
90 GtkWidget *icondlg;
91
92 /* stuff for mail check prompt */
93 GtkWidget *checkmail;
94
95 /* stuff for register with server */
96 GtkWidget *register_user;
97
98 /* stuff for proxy options */
99 GtkWidget *proxy_frame;
100 GtkWidget *proxy_host_box;
101 GtkWidget *proxytype_menu;
102 GtkWidget *proxyhost_entry;
103 GtkWidget *proxyport_entry;
104 GtkWidget *proxyuser_entry;
105 GtkWidget *proxypass_entry;
106 };
107
108
109 struct mod_account_opt {
110 struct mod_account *ma;
111 int opt;
112 };
113
114 static void acct_signin(GtkCellRendererToggle *cell, gchar *path_str,
115 gpointer d);
116 static void acct_autologin(GtkCellRendererToggle *cell, gchar *path_str,
117 gpointer d);
118
119 static struct mod_account *mod_account_find(struct gaim_account *a)
120 {
121 GSList *m = mod_accounts;
122 while (m) {
123 struct mod_account *ma = m->data;
124 if (ma->account == a)
125 return ma;
126 m = m->next;
127 }
128 return NULL;
129 }
130
131
132 struct gaim_connection *new_gaim_conn(struct gaim_account *account)
133 {
134 struct gaim_connection *gc = g_new0(struct gaim_connection, 1);
135 gc->edittype = EDIT_GC;
136 gc->protocol = account->protocol;
137 gc->prpl = gaim_find_prpl(account->protocol);
138 g_snprintf(gc->username, sizeof(gc->username), "%s", account->username);
139 g_snprintf(gc->password, sizeof(gc->password), "%s", account->password);
140 gc->keepalive = 0;
141 gc->inpa = 0;
142 gc->buddy_chats = NULL;
143 gc->away = NULL;
144 gc->away_state = NULL;
145
146 connections = g_slist_append(connections, gc);
147
148 account->gc = gc;
149 gc->account = account;
150
151 return gc;
152 }
153
154 struct meter_window { 50 struct meter_window {
155 GtkWidget *window; 51 GtkWidget *window;
156 GtkTable *table; 52 GtkTable *table;
157 gint rows; 53 gint rows;
158 gint active_count; 54 gint active_count;
159 } *meter_win = NULL; 55 } *meter_win = NULL;
160 56
161 void destroy_gaim_conn(struct gaim_connection *gc)
162 {
163 GaimBlistNode *gnode,*bnode;
164 struct group *m;
165 struct buddy *n;
166 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) {
167 if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
168 continue;
169 m = (struct group *)gnode;
170 for(bnode = gnode->child; bnode; bnode = bnode->next) {
171 if(GAIM_BLIST_NODE_IS_BUDDY(bnode)) {
172 n = (struct buddy *)bnode;
173 if(n->account == gc->account) {
174 n->present = GAIM_BUDDY_OFFLINE;
175 }
176 }
177 }
178 }
179 g_free(gc->away);
180 g_free(gc->away_state);
181 g_free(gc);
182
183 if (!connections && mainwindow)
184 gtk_widget_show(mainwindow);
185 }
186
187 static void quit_acctedit(gpointer d)
188 {
189 if (acctedit) {
190 save_prefs();
191 gtk_widget_destroy(acctedit);
192 acctedit = NULL;
193 }
194
195 treeview = NULL;
196
197 if (!d && !GAIM_GTK_BLIST(gaim_get_blist())->window &&
198 !mainwindow && !connections) {
199
200 do_quit();
201 }
202 }
203
204 static void on_delete_acctedit(GtkWidget *w, GdkEvent *ev, gpointer d)
205 {
206 quit_acctedit(d);
207 }
208
209 static void on_close_acctedit(GtkButton *button, gpointer d)
210 {
211 quit_acctedit(d);
212 }
213
214 static char *proto_name(int proto)
215 {
216 GaimPlugin *p = gaim_find_prpl(proto);
217 if (p && p->info->name)
218 return p->info->name;
219 else
220 return "Unknown";
221 }
222
223 void regenerate_user_list()
224 {
225 GSList *accounts = gaim_accounts;
226 struct gaim_account *a;
227 GtkTreeIter iter;
228
229 if (!acctedit)
230 return;
231
232 gtk_list_store_clear(model);
233
234 while (accounts) {
235 a = (struct gaim_account *)accounts->data;
236
237 gtk_list_store_append(model, &iter);
238 gtk_list_store_set(model, &iter,
239 COLUMN_SCREENNAME, a->username,
240 COLUMN_ONLINE, (a->gc ? TRUE : FALSE),
241 COLUMN_AUTOLOGIN, (a->options & OPT_ACCT_AUTO),
242 COLUMN_PROTOCOL, proto_name(a->protocol),
243 COLUMN_DATA, a,
244 -1);
245 accounts = accounts->next;
246 }
247 }
248
249 static gboolean get_iter_from_data(GtkTreeView *treeview,
250 struct gaim_account *a, GtkTreeIter *iter)
251 {
252 return gtk_tree_model_iter_nth_child(gtk_tree_view_get_model(treeview),
253 iter, NULL,
254 g_slist_index(gaim_accounts, a));
255 }
256
257 static void add_columns(GtkWidget *treeview)
258 {
259 GtkCellRenderer *renderer;
260 /* GtkTreeViewColumn *column; */
261
262 /* Screennames */
263 renderer = gtk_cell_renderer_text_new();
264 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview),
265 -1, _("Screenname"),
266 renderer,
267 "text", COLUMN_SCREENNAME,
268 NULL);
269
270 /* Online? */
271 renderer = gtk_cell_renderer_toggle_new();
272 g_signal_connect(G_OBJECT(renderer), "toggled",
273 G_CALLBACK(acct_signin), model);
274 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview),
275 -1, _("Online"),
276 renderer,
277 "active", COLUMN_ONLINE,
278 NULL);
279
280 /* Auto-login? */
281 renderer = gtk_cell_renderer_toggle_new();
282 g_signal_connect(G_OBJECT(renderer), "toggled",
283 G_CALLBACK(acct_autologin), model);
284 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview),
285 -1, _("Auto-login"),
286 renderer,
287 "active", COLUMN_AUTOLOGIN,
288 NULL);
289
290 /* Protocol */
291 renderer = gtk_cell_renderer_text_new();
292 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview),
293 -1, _("Protocol"),
294 renderer,
295 "text", COLUMN_PROTOCOL,
296 NULL);
297
298 /* Data */
299 /*
300 column = gtk_tree_view_column_new();
301 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeview), column, -1);
302 gtk_tree_view_column_set_visible(column, FALSE);
303 */
304 }
305
306 static void
307 __rows_reordered_cb(GtkTreeModel *model, GtkTreePath *arg1,
308 GtkTreeIter *arg2, int *new_order, gpointer user_data)
309 {
310 GSList *accounts = gaim_accounts;
311 GSList *new_accounts = NULL;
312 struct gaim_account **account_array;
313 int count, i;
314
315 gaim_debug(GAIM_DEBUG_INFO, "accounts", "Reordering accounts\n");
316
317 count = g_slist_length(accounts);
318
319 /* Grr. */
320 account_array = g_new(struct gaim_account *, count);
321
322 /* I hate this. */
323 for (i = 0; i < count; i++, accounts = accounts->next)
324 account_array[new_order[i]] = accounts->data;
325
326 /* I hate this too. */
327 for (i = 0; i < count; i++)
328 new_accounts = g_slist_append(new_accounts, account_array[i]);
329
330 gaim_accounts = new_accounts;
331
332 g_slist_free(accounts);
333 g_free(account_array);
334
335 save_prefs();
336 }
337
338 static GtkWidget *generate_list()
339 {
340 GtkWidget *win;
341
342 win = gtk_scrolled_window_new(0, 0);
343 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(win),
344 GTK_POLICY_AUTOMATIC,
345 GTK_POLICY_ALWAYS);
346 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(win),
347 GTK_SHADOW_IN);
348
349 /* Create the list model. */
350 model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_STRING, G_TYPE_BOOLEAN,
351 G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER);
352
353 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
354 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
355 gtk_tree_selection_set_mode(
356 gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)),
357 GTK_SELECTION_MULTIPLE);
358
359 add_columns(treeview);
360
361 gtk_container_add(GTK_CONTAINER(win), treeview);
362 gtk_widget_show(treeview);
363
364 regenerate_user_list();
365 gtk_tree_view_set_reorderable (GTK_TREE_VIEW(treeview), TRUE);
366 g_signal_connect(G_OBJECT(model), "rows-reordered",
367 G_CALLBACK(__rows_reordered_cb), NULL);
368
369 gtk_widget_show(win);
370 return win;
371 }
372
373 static void delmod(GtkWidget *w, struct mod_account *ma)
374 {
375 mod_accounts = g_slist_remove(mod_accounts, ma);
376 g_free(ma);
377 }
378
379 static void mod_opt(GtkWidget *b, struct mod_account_opt *mao)
380 {
381 mao->ma->options = mao->ma->options ^ mao->opt;
382 }
383
384 static void free_mao(GtkWidget *b, struct mod_account_opt *mao)
385 {
386 g_free(mao);
387 }
388
389 static GtkWidget *acct_button(const char *text, struct mod_account *ma, int option, GtkWidget *box)
390 {
391 GtkWidget *button;
392 struct mod_account_opt *mao = g_new0(struct mod_account_opt, 1);
393 button = gtk_check_button_new_with_label(text);
394 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), (ma->options & option));
395 gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
396 mao->ma = ma;
397 mao->opt = option;
398 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(mod_opt), mao);
399 g_signal_connect(G_OBJECT(button), "destroy", G_CALLBACK(free_mao), mao);
400 gtk_widget_show(button);
401 return button;
402 }
403
404 static void process_login_opts(struct mod_account *ma) {
405 GaimPlugin *p = gaim_find_prpl(ma->protocol);
406 const char *entry_text;
407 char *username = g_strdup(gtk_entry_get_text(GTK_ENTRY(ma->name)));
408 char *tmp;
409 GList *entries = ma->user_split_entries;
410 GList *user_splits = NULL;
411
412 if(p)
413 user_splits = GAIM_PLUGIN_PROTOCOL_INFO(p)->user_splits;
414
415 while(user_splits) {
416 GtkWidget *entry = entries->data;
417 struct proto_user_split *pus = user_splits->data;
418 char tmp_sep[2] = " ";
419 entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
420
421 tmp_sep[0] = pus->sep;
422 tmp = g_strconcat(username, tmp_sep, *entry_text ? entry_text : pus->def, NULL);
423 g_free(username);
424 username = tmp;
425
426 entries = entries->next;
427 user_splits = user_splits->next;
428 }
429
430 g_snprintf(ma->username, sizeof(ma->username), "%s", username);
431 g_free(username);
432
433 entry_text = gtk_entry_get_text(GTK_ENTRY(ma->pass));
434 g_snprintf(ma->password, sizeof(ma->password), "%s", entry_text);
435
436 entry_text = gtk_entry_get_text(GTK_ENTRY(ma->alias));
437 g_snprintf(ma->show, sizeof(ma->show), "%s", entry_text);
438 }
439
440 static void ok_mod(GtkWidget *w, struct mod_account *ma)
441 {
442 GList *tmp;
443 const char *txt;
444 struct gaim_account *a;
445 GaimPlugin *p = gaim_find_prpl(ma->protocol);
446 GaimPluginProtocolInfo *prpl_info = NULL;
447 GtkTreeIter iter;
448 int proxytype;
449
450 if (!ma->account) {
451 txt = gtk_entry_get_text(GTK_ENTRY(ma->name));
452 ma->account = gaim_account_new(txt, ma->protocol, ma->options);
453 }
454 a = ma->account;
455
456 a->options = ma->options;
457 a->protocol = ma->protocol;
458
459 process_login_opts(ma);
460 g_snprintf(a->username, sizeof(a->username), "%s", ma->username);
461 g_snprintf(a->alias, sizeof(a->alias), "%s", ma->show);
462
463 if (a->options & OPT_ACCT_REM_PASS)
464 g_snprintf(a->password, sizeof(a->password), "%s", ma->password);
465 else
466 a->password[0] = '\0';
467
468 if (get_iter_from_data(GTK_TREE_VIEW(treeview), a, &iter)) {
469 gtk_list_store_set(model, &iter,
470 COLUMN_SCREENNAME, a->username,
471 COLUMN_AUTOLOGIN, (a->options & OPT_ACCT_AUTO),
472 COLUMN_PROTOCOL, proto_name(a->protocol),
473 -1);
474 }
475
476 #if 0
477 i = gtk_clist_find_row_from_data(GTK_CLIST(list), a);
478 gtk_clist_set_text(GTK_CLIST(list), i, 0, a->username);
479 gtk_clist_set_text(GTK_CLIST(list), i, 2,
480 (a->options & OPT_ACCT_AUTO) ? "True" : "False");
481 gtk_clist_set_text(GTK_CLIST(list), i, 3, proto_name(a->protocol));
482 #endif
483
484 tmp = ma->opt_entries;
485 while (tmp) {
486 GtkEntry *entry = tmp->data;
487 int pos = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(entry), "position"));
488 g_snprintf(a->proto_opt[pos], sizeof(a->proto_opt[pos]), "%s",
489 gtk_entry_get_text(entry));
490 tmp = tmp->next;
491 }
492 if (ma->opt_entries)
493 g_list_free(ma->opt_entries);
494 ma->opt_entries = NULL;
495
496 g_snprintf(a->iconfile, sizeof(a->iconfile), "%s", ma->iconfile);
497 if (ma->icondlg)
498 gtk_widget_destroy(ma->icondlg);
499 ma->icondlg = NULL;
500
501 if(ma->account->gpi)
502 g_free(ma->account->gpi);
503 ma->account->gpi = NULL;
504
505 proxytype = GPOINTER_TO_INT(g_object_get_data(
506 G_OBJECT(gtk_menu_get_active(GTK_MENU(ma->proxytype_menu))),
507 "proxytype"));
508
509 if(proxytype != PROXY_USE_GLOBAL) {
510 struct gaim_proxy_info *gpi = g_new0(struct gaim_proxy_info, 1);
511 gpi->proxytype = proxytype;
512 g_snprintf(gpi->proxyhost, sizeof(gpi->proxyhost), "%s", gtk_entry_get_text(GTK_ENTRY(ma->proxyhost_entry)));
513 gpi->proxyport = atoi(gtk_entry_get_text(GTK_ENTRY(ma->proxyport_entry)));
514 g_snprintf(gpi->proxyuser, sizeof(gpi->proxyuser), "%s", gtk_entry_get_text(GTK_ENTRY(ma->proxyuser_entry)));
515 g_snprintf(gpi->proxypass, sizeof(gpi->proxypass), "%s", gtk_entry_get_text(GTK_ENTRY(ma->proxypass_entry)));
516
517 ma->account->gpi = gpi;
518 }
519
520 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(p);
521
522 /*
523 * See if user registration is supported/required
524 */
525 if (!p) {
526 /* TBD: error dialog here! (This should never happen, you know...) */
527 fprintf(stderr, "dbg: couldn't find protocol for protocol number %d!\n", ma->protocol);
528 fflush(stderr);
529 } else {
530 if (prpl_info->register_user != NULL &&
531 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ma->register_user)) == TRUE) {
532 prpl_info->register_user(a);
533 }
534 }
535
536 save_prefs();
537
538 gtk_widget_destroy(ma->mod);
539 }
540
541 static void cancel_mod(GtkWidget *w, struct mod_account *ma)
542 {
543 if (ma->opt_entries)
544 g_list_free(ma->opt_entries);
545 ma->opt_entries = NULL;
546 if (ma->icondlg)
547 gtk_widget_destroy(ma->icondlg);
548 ma->icondlg = NULL;
549 gtk_widget_destroy(ma->mod);
550 }
551
552 static void generate_login_options(struct mod_account *ma, GtkWidget *box);
553 static void generate_user_options(struct mod_account *ma, GtkWidget *box);
554 static void generate_protocol_options(struct mod_account *ma, GtkWidget *box);
555
556 static void set_prot(GtkWidget *opt, int proto)
557 {
558 struct mod_account *ma = g_object_get_data(G_OBJECT(opt), "mod_account");
559 GaimPlugin *p;
560 if (ma->protocol != proto) {
561 int i;
562
563 for (i = 0; i < 7; i++)
564 ma->proto_opt[i][0] = '\0';
565 p = gaim_find_prpl(ma->protocol);
566
567 process_login_opts(ma);
568
569 ma->protocol = proto;
570
571 if(!ma->account)
572 g_snprintf(ma->username, sizeof(ma->username), "%s",
573 gtk_entry_get_text(GTK_ENTRY(ma->name)));
574
575 generate_login_options(ma, ma->main);
576 generate_user_options(ma, ma->main);
577 generate_protocol_options(ma, ma->disc_box);
578 }
579 }
580
581 static GtkWidget *make_protocol_menu(GtkWidget *box, struct mod_account *ma)
582 {
583 GaimPluginProtocolInfo *prpl_info = NULL;
584 GtkWidget *optmenu;
585 GtkWidget *menu;
586 GtkWidget *opt;
587 GSList *p;
588 GaimPlugin *e;
589 int count = 0;
590 gboolean found = FALSE;
591
592 optmenu = gtk_option_menu_new();
593 gtk_box_pack_start(GTK_BOX(box), optmenu, FALSE, FALSE, 5);
594 gtk_widget_show(optmenu);
595
596 menu = gtk_menu_new();
597
598 for (p = protocols; p != NULL; p = p->next) {
599 e = (GaimPlugin *)p->data;
600 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(e);
601
602 if (prpl_info->protocol == ma->protocol)
603 found = TRUE;
604 if (!found)
605 count++;
606 if (e->info->name)
607 opt = gtk_menu_item_new_with_label(e->info->name);
608 else
609 opt = gtk_menu_item_new_with_label("Unknown");
610 g_object_set_data(G_OBJECT(opt), "mod_account", ma);
611 g_signal_connect(G_OBJECT(opt), "activate",
612 G_CALLBACK(set_prot), (void *)prpl_info->protocol);
613 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
614 gtk_widget_show(opt);
615 }
616
617 gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu);
618 gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), count);
619
620 return optmenu;
621 }
622
623 static void des_icon_sel(GtkWidget *w, struct mod_account *ma)
624 {
625 w = ma->icondlg;
626 if (ma->icondlg)
627 ma->icondlg = NULL;
628 if (w)
629 gtk_widget_destroy(w);
630 }
631
632 static void set_icon(GtkWidget *w, struct mod_account *ma)
633 {
634 GtkWidget *sel = ma->icondlg;
635 const char *file = gtk_file_selection_get_filename(GTK_FILE_SELECTION(sel));
636
637 if (file_is_dir(file, sel))
638 return;
639
640 gtk_entry_set_text(GTK_ENTRY(ma->iconentry), file);
641 g_snprintf(ma->iconfile, sizeof(ma->iconfile), "%s", file);
642 ma->icondlg = NULL;
643
644 gtk_widget_destroy(sel);
645 }
646
647 static void sel_icon_dlg(GtkWidget *w, struct mod_account *ma)
648 {
649 GtkWidget *dlg;
650 char buf[256];
651
652 if (ma->icondlg) {
653 gtk_widget_show(ma->icondlg);
654 return;
655 }
656
657 dlg = gtk_file_selection_new(_("Load Buddy Icon"));
658 gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(dlg));
659 if (ma->iconfile) {
660 char *tmp = g_path_get_dirname(ma->iconfile);
661 g_snprintf(buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S, tmp);
662 g_free(tmp);
663 } else {
664 g_snprintf(buf, sizeof(buf), "%s" G_DIR_SEPARATOR_S, gaim_home_dir());
665 }
666 gtk_file_selection_set_filename(GTK_FILE_SELECTION(dlg), buf);
667
668 g_signal_connect(G_OBJECT(dlg), "destroy",
669 G_CALLBACK(des_icon_sel), ma);
670 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(dlg)->cancel_button), "clicked",
671 G_CALLBACK(des_icon_sel), ma);
672 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(dlg)->ok_button), "clicked",
673 G_CALLBACK(set_icon), ma);
674
675 ma->icondlg = dlg;
676
677 gtk_widget_show(dlg);
678 }
679
680 static void reset_icon(GtkWidget *w, struct mod_account *ma)
681 {
682 ma->iconfile[0] = 0;
683 gtk_entry_set_text(GTK_ENTRY(ma->iconentry), "");
684 }
685
686 static GtkWidget *build_icon_selection(struct mod_account *ma, GtkWidget *box)
687 {
688 GtkWidget *hbox;
689 GtkWidget *label;
690 GtkWidget *name;
691 GtkWidget *browse;
692 GtkWidget *reset;
693
694 if (ma->account)
695 g_snprintf(ma->iconfile, sizeof(ma->iconfile), "%s", ma->account->iconfile);
696
697 hbox = gtk_hbox_new(FALSE, 0);
698 gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 5);
699 gtk_widget_show(hbox);
700
701 label = gtk_label_new(_("Buddy Icon File:"));
702 gtk_size_group_add_widget(ma->sg, label);
703 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
704 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
705 gtk_widget_show(label);
706
707 name = gtk_entry_new();
708 gtk_entry_set_text(GTK_ENTRY(name), ma->iconfile);
709 gtk_editable_set_editable(GTK_EDITABLE(name), FALSE);
710 gtk_box_pack_start(GTK_BOX(hbox), name, TRUE, TRUE, 5);
711 gtk_widget_show(name);
712 ma->iconentry = name;
713
714 browse = gtk_button_new_with_label(_("Browse"));
715 g_signal_connect(G_OBJECT(browse), "clicked",
716 G_CALLBACK(sel_icon_dlg), ma);
717 gtk_box_pack_start(GTK_BOX(hbox), browse, FALSE, FALSE, 0);
718 gtk_widget_show(browse);
719
720 reset = gtk_button_new_with_label(_("Reset"));
721 g_signal_connect(G_OBJECT(reset), "clicked",
722 G_CALLBACK(reset_icon), ma);
723 gtk_box_pack_start(GTK_BOX(hbox), reset, FALSE, FALSE, 0);
724 gtk_widget_show(reset);
725
726 return hbox;
727 }
728
729 static void generate_login_options(struct mod_account *ma, GtkWidget *box)
730 {
731 GtkWidget *frame;
732 GtkWidget *vbox;
733 GtkWidget *hbox;
734 GtkWidget *label;
735 GList *user_splits = NULL;
736 GList *split_entries;
737
738 GaimPlugin *p;
739
740 char *username = NULL;
741 char *start;
742
743 if(ma->login_frame)
744 gtk_widget_destroy(ma->login_frame);
745 ma->login_frame = NULL;
746
747 frame = gaim_gtk_make_frame(box, _("Login Options"));
748 ma->login_frame = gtk_widget_get_parent(gtk_widget_get_parent(frame));
749 gtk_box_reorder_child(GTK_BOX(box), ma->login_frame, 0);
750
751 vbox = gtk_vbox_new(FALSE, 5);
752 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
753 gtk_container_add(GTK_CONTAINER(frame), vbox);
754
755 hbox = gtk_hbox_new(FALSE, 5);
756 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
757 gtk_widget_show(hbox);
758
759 label = gtk_label_new(_("Protocol:"));
760 gtk_size_group_add_widget(ma->sg, label);
761 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
762 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
763
764 make_protocol_menu(hbox, ma);
765
766 hbox = gtk_hbox_new(FALSE, 5);
767 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
768
769 p = gaim_find_prpl(ma->protocol);
770
771 if(p)
772 user_splits = GAIM_PLUGIN_PROTOCOL_INFO(p)->user_splits;
773
774 label = gtk_label_new(_("Screenname:"));
775 gtk_size_group_add_widget(ma->sg, label);
776 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
777 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
778
779 ma->name = gtk_entry_new();
780 gtk_box_pack_start(GTK_BOX(hbox), ma->name, TRUE, TRUE, 0);
781
782 if(ma->user_split_entries) {
783 g_list_free(ma->user_split_entries);
784 ma->user_split_entries = NULL;
785 }
786
787 while(user_splits) {
788 struct proto_user_split *pus = user_splits->data;
789 GtkWidget *entry;
790
791 hbox = gtk_hbox_new(FALSE, 5);
792 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
793
794 label = gtk_label_new(pus->label);
795 gtk_size_group_add_widget(ma->sg, label);
796 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
797 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
798 user_splits = user_splits->next;
799
800 entry = gtk_entry_new();
801 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
802
803 ma->user_split_entries = g_list_append(ma->user_split_entries, entry);
804 }
805
806 ma->pwdbox = gtk_hbox_new(FALSE, 5);
807 gtk_box_pack_start(GTK_BOX(vbox), ma->pwdbox, FALSE, FALSE, 0);
808
809 label = gtk_label_new(_("Password:"));
810 gtk_size_group_add_widget(ma->sg, label);
811 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
812 gtk_box_pack_start(GTK_BOX(ma->pwdbox), label, FALSE, FALSE, 0);
813
814 ma->pass = gtk_entry_new();
815 gtk_box_pack_start(GTK_BOX(ma->pwdbox), ma->pass, TRUE, TRUE, 0);
816 gtk_entry_set_visibility(GTK_ENTRY(ma->pass), FALSE);
817
818 hbox = gtk_hbox_new(FALSE, 5);
819 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
820
821 label = gtk_label_new(_("Alias:"));
822 gtk_size_group_add_widget(ma->sg, label);
823 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
824 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
825
826 ma->alias = gtk_entry_new();
827 gtk_box_pack_start(GTK_BOX(hbox), ma->alias, TRUE, TRUE, 0);
828
829 ma->rempass = acct_button(_("Remember Password"), ma, OPT_ACCT_REM_PASS, vbox);
830 acct_button(_("Auto-Login"), ma, OPT_ACCT_AUTO, vbox);
831
832 gtk_widget_show_all(ma->login_frame);
833
834 if (p)
835 user_splits = g_list_last(GAIM_PLUGIN_PROTOCOL_INFO(p)->user_splits);
836
837 username = g_strdup(ma->username);
838 split_entries = g_list_last(ma->user_split_entries);
839
840 while(user_splits) {
841 struct proto_user_split *pus = user_splits->data;
842 GtkWidget *entry = split_entries->data;
843 start = strrchr(username, pus->sep);
844 if(start) {
845 *start = '\0';
846 start++;
847 gtk_entry_set_text(GTK_ENTRY(entry), start);
848 } else {
849 gtk_entry_set_text(GTK_ENTRY(entry), pus->def);
850 }
851 user_splits = user_splits->prev;
852 split_entries = split_entries->prev;
853 }
854
855 gtk_entry_set_text(GTK_ENTRY(ma->name), username);
856 gtk_entry_set_text(GTK_ENTRY(ma->alias), ma->show);
857 gtk_entry_set_text(GTK_ENTRY(ma->pass), ma->password);
858 g_free(username);
859
860 if (p && (GAIM_PLUGIN_PROTOCOL_INFO(p)->options & OPT_PROTO_NO_PASSWORD)) {
861 gtk_widget_hide(ma->pwdbox);
862 gtk_widget_hide(ma->rempass);
863 }
864 }
865
866 static void generate_user_options(struct mod_account *ma, GtkWidget *box)
867 {
868 /* This function will add the appropriate (depending on the current
869 * protocol) widgets to frame and return TRUE if there anything
870 * was added (meaning the frame should be shown)
871 * Eric will most likely change this (as he does all other submitted code)
872 * so that it will accept the vbox as an argument and create, add, and show
873 * the frame itself (like generate_protocol_options). I'd do it myself, but I'm
874 * tired and I don't care. */
875 /* Sean was right. I did do that. I told him I would. */
876
877 GtkWidget *vbox;
878 GtkWidget *frame;
879 GaimPluginProtocolInfo *prpl_info = NULL;
880
881 GaimPlugin *p = gaim_find_prpl(ma->protocol);
882
883 if(ma->user_frame)
884 gtk_widget_destroy(ma->user_frame);
885 ma->user_frame = NULL;
886
887 frame = gaim_gtk_make_frame(box, _("User Options"));
888 ma->user_frame = gtk_widget_get_parent(gtk_widget_get_parent(frame));
889 gtk_box_reorder_child(GTK_BOX(box), ma->user_frame, 1);
890 gtk_widget_show_all(ma->user_frame);
891
892 vbox = gtk_vbox_new(FALSE, 5);
893 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
894 gtk_container_add(GTK_CONTAINER(frame), vbox);
895 gtk_widget_show(vbox);
896
897 ma->checkmail = acct_button(_("New Mail Notifications"), ma, OPT_ACCT_MAIL_CHECK, vbox);
898 ma->iconsel = build_icon_selection(ma, vbox);
899
900 if (!p) {
901 gtk_widget_hide(ma->user_frame);
902 return;
903 }
904
905 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(p);
906
907 if (!(prpl_info->options & OPT_PROTO_MAIL_CHECK))
908 gtk_widget_hide(ma->checkmail);
909 if (!(prpl_info->options & OPT_PROTO_BUDDY_ICON))
910 gtk_widget_hide(ma->iconsel);
911
912 if ((prpl_info->options & OPT_PROTO_BUDDY_ICON) ||
913 (prpl_info->options & OPT_PROTO_MAIL_CHECK)) {
914
915 return;
916 }
917
918 gtk_widget_hide(ma->user_frame);
919 }
920
921 static void generate_protocol_options(struct mod_account *ma, GtkWidget *box)
922 {
923 GaimPlugin *p = gaim_find_prpl(ma->protocol);
924 GaimPluginProtocolInfo *prpl_info = NULL;
925
926 GList *op, *tmp;
927
928 GtkWidget *vbox;
929 GtkWidget *hbox;
930 GtkWidget *label;
931 GtkWidget *entry;
932 GtkWidget *frame;
933
934 char buf[256];
935
936 if (ma->proto_frame)
937 gtk_widget_destroy(ma->proto_frame);
938 ma->proto_frame = NULL;
939
940 if (ma->opt_entries) {
941 g_list_free(ma->opt_entries);
942 ma->opt_entries = NULL;
943 }
944
945 if (!p)
946 return;
947
948 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(p);
949
950 if (!prpl_info->user_opts)
951 return;
952
953 tmp = op = prpl_info->user_opts;
954
955 if (!op)
956 return;
957
958 g_snprintf(buf, sizeof(buf), _("%s Options"), p->info->name);
959 frame = gaim_gtk_make_frame(box, buf);
960
961 /* BLEH */
962 ma->proto_frame = gtk_widget_get_parent(gtk_widget_get_parent(frame));
963 gtk_box_reorder_child(GTK_BOX(box), ma->proto_frame, 0);
964 gtk_widget_show_all(ma->proto_frame);
965
966 vbox = gtk_vbox_new(FALSE, 5);
967 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
968 gtk_container_add(GTK_CONTAINER(frame), vbox);
969 gtk_widget_show(vbox);
970
971 while (op) {
972 struct proto_user_opt *puo = op->data;
973
974 hbox = gtk_hbox_new(FALSE, 5);
975 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
976 gtk_widget_show(hbox);
977
978 label = gtk_label_new(puo->label);
979 gtk_size_group_add_widget(ma->sg, label);
980 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
981 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
982 gtk_widget_show(label);
983
984 entry = gtk_entry_new();
985 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
986 g_object_set_data(G_OBJECT(entry), "position", GINT_TO_POINTER(puo->pos));
987 if (ma->proto_opt[puo->pos][0]) {
988 gaim_debug(GAIM_DEBUG_MISC, "protocol options",
989 "Setting text %s\n", ma->proto_opt[puo->pos]);
990 gtk_entry_set_text(GTK_ENTRY(entry), ma->proto_opt[puo->pos]);
991 } else {
992 gtk_entry_set_text(GTK_ENTRY(entry), puo->def);
993 }
994 gtk_widget_show(entry);
995
996 ma->opt_entries = g_list_append(ma->opt_entries, entry);
997
998 op = op->next;
999 }
1000
1001 if(prpl_info->register_user != NULL) {
1002 ma->register_user = gtk_check_button_new_with_label(_("Register with server"));
1003 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ma->register_user), FALSE);
1004 gtk_box_pack_start(GTK_BOX(vbox), ma->register_user, FALSE, FALSE, 0);
1005 gtk_widget_show(ma->register_user);
1006 }
1007
1008 }
1009
1010 static void proxy_dropdown_set(GObject *w, struct mod_account *ma) {
1011 int opt = GPOINTER_TO_INT(g_object_get_data(w, "proxytype"));
1012 if(opt == PROXY_NONE || opt == PROXY_USE_GLOBAL)
1013 gtk_widget_hide_all(ma->proxy_host_box);
1014 else {
1015 gtk_widget_show_all(ma->proxy_host_box);
1016 }
1017 }
1018
1019 static void generate_proxy_options(struct mod_account *ma, GtkWidget *box) {
1020 GtkWidget *frame;
1021 GtkWidget *hbox;
1022 GtkWidget *vbox;
1023 GtkWidget *label;
1024 GtkWidget *menu;
1025 GtkWidget *dropdown;
1026 GtkWidget *opt;
1027 GtkWidget *entry;
1028 GtkWidget *vbox2;
1029
1030 struct gaim_proxy_info *gpi = NULL;
1031
1032 if(ma->account)
1033 gpi = ma->account->gpi;
1034
1035 frame = gaim_gtk_make_frame(box, _("Proxy Options"));
1036 ma->proxy_frame = gtk_widget_get_parent(gtk_widget_get_parent(frame));
1037 gtk_widget_show_all(ma->proxy_frame);
1038
1039 vbox = gtk_vbox_new(FALSE, 5);
1040 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
1041 gtk_container_add(GTK_CONTAINER(frame), vbox);
1042 gtk_widget_show(vbox);
1043
1044 /* make the dropdown w/o the benefit of the easy helper funcs in prefs.c */
1045 hbox = gtk_hbox_new(FALSE, 5);
1046 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1047 gtk_widget_show(hbox);
1048
1049 label = gtk_label_new_with_mnemonic(_("Proxy _Type"));
1050 gtk_size_group_add_widget(ma->sg, label);
1051 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1052 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1053 gtk_widget_show(label);
1054
1055 dropdown = gtk_option_menu_new();
1056 menu = gtk_menu_new();
1057
1058 opt = gtk_menu_item_new_with_label(_("Use Global Proxy Settings"));
1059 g_object_set_data(G_OBJECT(opt), "proxytype", GINT_TO_POINTER(PROXY_USE_GLOBAL));
1060 g_signal_connect(G_OBJECT(opt), "activate",
1061 G_CALLBACK(proxy_dropdown_set), ma);
1062 gtk_widget_show(opt);
1063 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
1064 if(!gpi)
1065 gtk_menu_set_active(GTK_MENU(menu), 0);
1066
1067 opt = gtk_menu_item_new_with_label(_("No Proxy"));
1068 g_object_set_data(G_OBJECT(opt), "proxytype", GINT_TO_POINTER(PROXY_NONE));
1069 g_signal_connect(G_OBJECT(opt), "activate",
1070 G_CALLBACK(proxy_dropdown_set), ma);
1071 gtk_widget_show(opt);
1072 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
1073 if(gpi && gpi->proxytype == PROXY_NONE)
1074 gtk_menu_set_active(GTK_MENU(menu), 1);
1075
1076 opt = gtk_menu_item_new_with_label("SOCKS 4");
1077 g_object_set_data(G_OBJECT(opt), "proxytype", GINT_TO_POINTER(PROXY_SOCKS4));
1078 g_signal_connect(G_OBJECT(opt), "activate",
1079 G_CALLBACK(proxy_dropdown_set), ma);
1080 gtk_widget_show(opt);
1081 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
1082 if(gpi && gpi->proxytype == PROXY_SOCKS4)
1083 gtk_menu_set_active(GTK_MENU(menu), 2);
1084
1085 opt = gtk_menu_item_new_with_label("SOCKS 5");
1086 g_object_set_data(G_OBJECT(opt), "proxytype", GINT_TO_POINTER(PROXY_SOCKS5));
1087 g_signal_connect(G_OBJECT(opt), "activate",
1088 G_CALLBACK(proxy_dropdown_set), ma);
1089 gtk_widget_show(opt);
1090 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
1091 if(gpi && gpi->proxytype == PROXY_SOCKS5)
1092 gtk_menu_set_active(GTK_MENU(menu), 3);
1093
1094 opt = gtk_menu_item_new_with_label("HTTP");
1095 g_object_set_data(G_OBJECT(opt), "proxytype", GINT_TO_POINTER(PROXY_HTTP));
1096 g_signal_connect(G_OBJECT(opt), "activate",
1097 G_CALLBACK(proxy_dropdown_set), ma);
1098 gtk_widget_show(opt);
1099 gtk_menu_shell_append(GTK_MENU_SHELL(menu), opt);
1100 if(gpi && gpi->proxytype == PROXY_HTTP)
1101 gtk_menu_set_active(GTK_MENU(menu), 4);
1102
1103 gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu);
1104 gtk_box_pack_start(GTK_BOX(hbox), dropdown, FALSE, FALSE, 0);
1105 gtk_widget_show(dropdown);
1106
1107 ma->proxytype_menu = menu;
1108
1109
1110 vbox2 = gtk_vbox_new(FALSE, 5);
1111 gtk_container_add(GTK_CONTAINER(vbox), vbox2);
1112 gtk_widget_show(vbox2);
1113 ma->proxy_host_box = vbox2;
1114
1115 hbox = gtk_hbox_new(FALSE, 5);
1116 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
1117 gtk_widget_show(hbox);
1118
1119 label = gtk_label_new_with_mnemonic(_("_Host:"));
1120 gtk_size_group_add_widget(ma->sg, label);
1121 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1122 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1123 gtk_widget_show(label);
1124 entry = gtk_entry_new();
1125 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
1126 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
1127 gtk_entry_set_text(GTK_ENTRY(entry), gpi ? gpi->proxyhost : "");
1128 gtk_widget_show(entry);
1129 ma->proxyhost_entry = entry;
1130
1131 hbox = gtk_hbox_new(FALSE, 5);
1132 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
1133 gtk_widget_show(hbox);
1134
1135 label = gtk_label_new_with_mnemonic(_("Port:"));
1136 gtk_size_group_add_widget(ma->sg, label);
1137 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1138 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1139 gtk_widget_show(label);
1140 entry = gtk_entry_new();
1141 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
1142 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
1143 if(gpi && gpi->proxyport) {
1144 char buf[128];
1145 g_snprintf(buf, sizeof(buf), "%d", gpi->proxyport);
1146 gtk_entry_set_text(GTK_ENTRY(entry), buf);
1147 }
1148 gtk_widget_show(entry);
1149 ma->proxyport_entry = entry;
1150
1151 hbox = gtk_hbox_new(FALSE, 5);
1152 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
1153 gtk_widget_show(hbox);
1154
1155 label = gtk_label_new_with_mnemonic(_("_User:"));
1156 gtk_size_group_add_widget(ma->sg, label);
1157 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1158 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1159 gtk_widget_show(label);
1160 entry = gtk_entry_new();
1161 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
1162 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
1163 gtk_entry_set_text(GTK_ENTRY(entry), gpi ? gpi->proxyuser : "");
1164 gtk_widget_show(entry);
1165 ma->proxyuser_entry = entry;
1166
1167 hbox = gtk_hbox_new(FALSE, 5);
1168 gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
1169 gtk_widget_show(hbox);
1170
1171 label = gtk_label_new_with_mnemonic(_("Pa_ssword:"));
1172 gtk_size_group_add_widget(ma->sg, label);
1173 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1174 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1175 gtk_widget_show(label);
1176 entry = gtk_entry_new();
1177 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
1178 gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0);
1179 gtk_entry_set_text(GTK_ENTRY(entry), gpi ? gpi->proxypass : "");
1180 gtk_entry_set_visibility(GTK_ENTRY(entry),FALSE); /*show *'s for passwd*/
1181 gtk_widget_show(entry);
1182 ma->proxypass_entry = entry;
1183
1184 if(gpi == NULL || gpi->proxytype == PROXY_NONE)
1185 gtk_widget_hide_all(vbox2);
1186 }
1187
1188 static void show_acct_mod(struct gaim_account *a)
1189 {
1190 /* This is the fucking modify account dialog. I've fucking seperated it into
1191 * three fucking frames:
1192 * a fucking Login Options frame, a fucking User Options frame and a fucking
1193 * Protcol Options frame. This fucking removes the two fucking tabs, which
1194 * were quite fucking uneccessary. Fuck. */
1195 /* -- SeanEgan */
1196 /* YEAH!! -- ChipX86 */
1197 GtkWidget *hbox, *vbox, *disc, *dbox;
1198 GtkWidget *button;
1199 GtkWidget *sep;
1200 GtkSizeGroup *button_sg;
1201
1202 struct mod_account *ma = mod_account_find(a);
1203
1204 if (!ma) {
1205 ma = g_new0(struct mod_account, 1);
1206 ma->account = a;
1207 mod_accounts = g_slist_append(mod_accounts, ma);
1208
1209 if (a) {
1210 int i;
1211 ma->options = a->options;
1212 if (gaim_find_prpl(a->protocol))
1213 ma->protocol = a->protocol;
1214 else if (protocols)
1215 ma->protocol = GAIM_PLUGIN_PROTOCOL_INFO(
1216 ((GaimPlugin *)protocols->data))->protocol;
1217 else
1218 ma->protocol = -1;
1219 g_snprintf(ma->iconfile, sizeof(ma->iconfile), "%s", a->iconfile);
1220 g_snprintf(ma->username, sizeof(ma->username), "%s", a->username);
1221 g_snprintf(ma->show, sizeof(ma->show), "%s", a->alias);
1222 g_snprintf(ma->password, sizeof(ma->password), "%s", a->password);
1223
1224 for (i = 0; i < 7; i++)
1225 g_snprintf(ma->proto_opt[i], sizeof(ma->proto_opt[i]), "%s",
1226 a->proto_opt[i]);
1227 } else {
1228 ma->options = OPT_ACCT_REM_PASS;
1229 if (gaim_find_prpl(GAIM_PROTO_DEFAULT))
1230 ma->protocol = GAIM_PROTO_DEFAULT;
1231 else if (protocols)
1232 ma->protocol = GAIM_PLUGIN_PROTOCOL_INFO(
1233 ((GaimPlugin *)protocols->data))->protocol;
1234 else
1235 ma->protocol = -1;
1236 }
1237 } else {
1238 gtk_widget_show(ma->mod);
1239 return;
1240 }
1241
1242 ma->mod = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1243 gtk_window_set_role(GTK_WINDOW(ma->mod), "account");
1244 gtk_widget_realize(ma->mod);
1245 gtk_window_set_title(GTK_WINDOW(ma->mod), _("Modify Account"));
1246 gtk_window_set_resizable(GTK_WINDOW(ma->mod), FALSE); /* nothing odd here :) */
1247 g_signal_connect(G_OBJECT(ma->mod), "destroy",
1248 G_CALLBACK(delmod), ma);
1249
1250 vbox = gtk_vbox_new(FALSE, 6);
1251 gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
1252 gtk_container_add(GTK_CONTAINER(ma->mod), vbox);
1253 gtk_widget_show(vbox);
1254
1255 ma->main = gtk_vbox_new(FALSE, 12);
1256 gtk_container_set_border_width(GTK_CONTAINER(ma->main), 6);
1257 gtk_box_pack_start(GTK_BOX(vbox), ma->main, FALSE, FALSE, 0);
1258 gtk_widget_show(ma->main);
1259
1260 ma->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1261
1262 generate_login_options(ma, ma->main);
1263 generate_user_options(ma, ma->main);
1264 disc = gaim_disclosure_new(_("Show more options"), _("Show fewer options"));
1265 gtk_box_pack_start(GTK_BOX(ma->main), disc, FALSE, FALSE, 0);
1266 gtk_widget_show(disc);
1267 ma->disc_box = dbox = gtk_vbox_new(FALSE, 12);
1268 gtk_container_set_border_width(GTK_CONTAINER(dbox), 6);
1269 gtk_box_pack_start(GTK_BOX(ma->main), dbox, FALSE, FALSE, 0);
1270 gaim_disclosure_set_container(GAIM_DISCLOSURE(disc), dbox);
1271 generate_protocol_options(ma, dbox);
1272 generate_proxy_options(ma, dbox);
1273
1274 hbox = gtk_hbox_new(FALSE, 6);
1275 gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
1276 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1277
1278 button_sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
1279
1280 button = gtk_button_new_from_stock(GTK_STOCK_OK);
1281 gtk_size_group_add_widget(button_sg, button);
1282 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1283 g_signal_connect(G_OBJECT(button), "clicked",
1284 G_CALLBACK(ok_mod), ma);
1285
1286 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
1287 gtk_size_group_add_widget(button_sg, button);
1288 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1289 g_signal_connect(G_OBJECT(button), "clicked",
1290 G_CALLBACK(cancel_mod), ma);
1291
1292 sep = gtk_hseparator_new();
1293 gtk_box_pack_end (GTK_BOX (vbox), sep, FALSE, FALSE, 0);
1294 gtk_widget_show(sep);
1295
1296 gtk_widget_show_all(hbox);
1297 gtk_widget_show(ma->mod);
1298 }
1299
1300 static void add_acct(GtkWidget *w, gpointer d)
1301 {
1302 show_acct_mod(NULL);
1303 }
1304
1305 static void mod_acct_func(GtkTreeModel *model, GtkTreePath *path,
1306 GtkTreeIter *iter, gpointer data)
1307 {
1308 struct gaim_account *a;
1309
1310 gtk_tree_model_get(model, iter, COLUMN_DATA, &a, -1);
1311
1312 if (a != NULL)
1313 show_acct_mod(a);
1314 }
1315
1316 static void mod_acct(GtkWidget *w, gpointer d)
1317 {
1318 GtkTreeSelection *selection;
1319
1320 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
1321
1322 gtk_tree_selection_selected_foreach(selection, mod_acct_func, NULL);
1323 }
1324
1325 struct pass_prompt {
1326 struct gaim_account *account;
1327 GtkWidget *win;
1328 GtkWidget *entry;
1329 };
1330 static GSList *passes = NULL;
1331
1332 static struct pass_prompt *find_pass_prompt(struct gaim_account *account)
1333 {
1334 GSList *p = passes;
1335 while (p) {
1336 struct pass_prompt *r = p->data;
1337 if (r->account == account)
1338 return r;
1339 p = p->next;
1340 }
1341 return NULL;
1342 }
1343
1344 static void pass_callback(GtkDialog *d, gint resp, struct pass_prompt *p)
1345 {
1346 if (resp == GTK_RESPONSE_YES) {
1347 const char *txt = gtk_entry_get_text(GTK_ENTRY(p->entry));
1348 g_snprintf(p->account->password, sizeof(p->account->password), "%s", txt);
1349 serv_login(p->account);
1350 }
1351 passes = g_slist_remove(passes, p);
1352 gtk_widget_destroy(p->win);
1353 g_free(p);
1354 }
1355
1356 static void do_pass_dlg(struct gaim_account *account)
1357 {
1358 /* we can safely assume that u is not NULL */
1359 struct pass_prompt *p = find_pass_prompt(account);
1360 GtkWidget *label;
1361 GtkWidget *hbox, *vbox;
1362 char *labeltext=NULL;
1363 GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_AUTH, GTK_ICON_SIZE_DIALOG);
1364
1365 if (p) {
1366 gtk_widget_show(p->win);
1367 return;
1368 }
1369
1370 p = g_new0(struct pass_prompt, 1);
1371 p->account = account;
1372 passes = g_slist_append(passes, p);
1373
1374 p->win = gtk_dialog_new_with_buttons("", NULL, 0, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1375 _("_Login"), GTK_RESPONSE_YES, NULL);
1376
1377 gtk_dialog_set_default_response (GTK_DIALOG(p->win), GTK_RESPONSE_YES);
1378 g_signal_connect(G_OBJECT(p->win), "response", G_CALLBACK(pass_callback), p);
1379
1380 gtk_container_set_border_width (GTK_CONTAINER(p->win), 6);
1381 gtk_window_set_resizable(GTK_WINDOW(p->win), FALSE);
1382 gtk_dialog_set_has_separator(GTK_DIALOG(p->win), FALSE);
1383 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(p->win)->vbox), 12);
1384 gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(p->win)->vbox), 6);
1385
1386 hbox = gtk_hbox_new(FALSE, 12);
1387 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(p->win)->vbox), hbox);
1388 gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
1389
1390 vbox = gtk_vbox_new(FALSE, 0);
1391 gtk_container_add(GTK_CONTAINER(hbox), vbox);
1392
1393 labeltext = g_strdup_printf(_("Please enter your password for %s.\n\n"),
1394 account->username);
1395 label = gtk_label_new(labeltext);
1396 g_free(labeltext);
1397
1398 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1399 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
1400 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
1401
1402 hbox = gtk_hbox_new(FALSE, 5);
1403 gtk_container_add(GTK_CONTAINER(vbox), hbox);
1404 label = gtk_label_new_with_mnemonic(_("_Password"));
1405 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
1406 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
1407
1408 p->entry = gtk_entry_new();
1409 gtk_entry_set_visibility(GTK_ENTRY(p->entry), FALSE);
1410 gtk_box_pack_start(GTK_BOX(hbox), p->entry, FALSE, FALSE, 5);
1411 gtk_label_set_mnemonic_widget(GTK_LABEL(label), p->entry);
1412 gtk_widget_grab_focus(p->entry);
1413
1414 gtk_widget_show_all(p->win);
1415 }
1416
1417 static void acct_signin(GtkCellRendererToggle *cell, gchar *path_str,
1418 gpointer d)
1419 {
1420 GtkTreeModel *model = (GtkTreeModel *)d;
1421 GtkTreeIter iter;
1422
1423 struct gaim_account *account = NULL;
1424 GaimPlugin *p = NULL;
1425 GaimPluginProtocolInfo *prpl_info = NULL;
1426
1427 gtk_tree_model_get_iter_from_string(model, &iter, path_str);
1428 gtk_tree_model_get(model, &iter, COLUMN_DATA, &account, -1);
1429
1430 p = gaim_find_prpl(account->protocol);
1431
1432 if (p != NULL)
1433 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(p);
1434
1435 if (!account->gc && p && prpl_info->login) {
1436 GaimPlugin *p = gaim_find_prpl(account->protocol);
1437
1438 if (p != NULL)
1439 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(p);
1440
1441 if (p && !(prpl_info->options & OPT_PROTO_NO_PASSWORD) &&
1442 !(prpl_info->options & OPT_PROTO_PASSWORD_OPTIONAL) &&
1443 !account->password[0]) {
1444
1445 do_pass_dlg(account);
1446 }
1447 else {
1448 serv_login(account);
1449 }
1450 } else if (account->gc) {
1451 account->gc->wants_to_die = TRUE;
1452 signoff(account->gc);
1453 } else {
1454 if (account->protocol == GAIM_PROTO_TOC)
1455 gaim_notify_error(NULL, NULL,
1456 _("TOC not found."),
1457 _("You have attempted to login an IM account "
1458 "using the TOC protocol. Because this "
1459 "protocol is inferior to OSCAR, it is now "
1460 "compiled as a plugin by default. To login, "
1461 "edit this account to use OSCAR or load the "
1462 "TOC plugin."));
1463 else
1464 gaim_notify_error(NULL, NULL,
1465 _("Protocol not found."),
1466 _("You cannot log this account in; you do "
1467 "not have the protocol it uses loaded, or "
1468 "the protocol does not have a login "
1469 "function."));
1470 }
1471 }
1472
1473 static void acct_autologin(GtkCellRendererToggle *cell, gchar *path_str,
1474 gpointer d)
1475 {
1476 GtkTreeModel *model = (GtkTreeModel *)d;
1477 GtkTreeIter iter;
1478
1479 struct gaim_account *account = NULL;
1480
1481 gtk_tree_model_get_iter_from_string(model, &iter, path_str);
1482 gtk_tree_model_get(model, &iter, COLUMN_DATA, &account, -1);
1483
1484 account->options ^= OPT_ACCT_AUTO;
1485
1486 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
1487 COLUMN_AUTOLOGIN, (account->options & OPT_ACCT_AUTO), -1);
1488
1489 save_prefs();
1490 }
1491
1492 static void do_del_acct(struct gaim_account *account)
1493 {
1494 GtkTreeIter iter;
1495 GaimBlistNode *gnode,*bnode;
1496
1497 if (account->gc) {
1498 account->gc->wants_to_die = TRUE;
1499 signoff(account->gc);
1500 }
1501
1502 if (get_iter_from_data(GTK_TREE_VIEW(treeview), account, &iter)) {
1503 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
1504 }
1505
1506
1507 /* remove the buddies for the account we just destroyed */
1508 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) {
1509 struct group *g = (struct group *)gnode;
1510 if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
1511 continue;
1512 for(bnode = gnode->child; bnode; bnode = bnode->next) {
1513 if(GAIM_BLIST_NODE_IS_BUDDY(bnode)) {
1514 struct buddy *b = (struct buddy *)bnode;
1515 if(b->account == account)
1516 gaim_blist_remove_buddy(b);
1517 } else if(GAIM_BLIST_NODE_IS_CHAT(bnode)) {
1518 struct chat *chat = (struct chat *)bnode;
1519 if(chat->account == account)
1520 gaim_blist_remove_chat(chat);
1521 }
1522 }
1523 if(!gnode->child) {
1524 gaim_blist_remove_group(g);
1525 }
1526 }
1527
1528 gaim_accounts = g_slist_remove(gaim_accounts, account);
1529
1530 gaim_blist_save();
1531
1532 save_prefs();
1533 }
1534
1535 static void del_acct_func(GtkTreeModel *model, GtkTreePath *path,
1536 GtkTreeIter *iter, gpointer data)
1537 {
1538 struct gaim_account *account;
1539
1540 gtk_tree_model_get(model, iter, COLUMN_DATA, &account, -1);
1541
1542 if (account != NULL) {
1543 char buf[8192];
1544
1545 g_snprintf(buf, sizeof(buf),
1546 _("Are you sure you want to delete %s?"), account->username);
1547
1548 gaim_request_action(NULL, NULL, buf, NULL, 1, account, 2,
1549 _("Delete"), G_CALLBACK(do_del_acct),
1550 _("Cancel"), NULL);
1551 }
1552 }
1553
1554 static void del_acct(GtkWidget *w, gpointer d)
1555 {
1556 GtkTreeSelection *selection;
1557
1558 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
1559
1560 gtk_tree_selection_selected_foreach(selection, del_acct_func, NULL);
1561 }
1562
1563 void account_editor(GtkWidget *w, GtkWidget *W)
1564 {
1565 /* please kill me */
1566 GtkWidget *vbox;
1567 GtkWidget *hbox;
1568 GtkWidget *sw;
1569 GtkWidget *button; /* used for many things */
1570 GtkWidget *sep;
1571 GtkSizeGroup *sg;
1572
1573 if (acctedit) {
1574 gtk_window_present(GTK_WINDOW(acctedit));
1575 return;
1576 }
1577
1578 acctedit = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1579 gtk_window_set_title(GTK_WINDOW(acctedit), _("Account Editor"));
1580 gtk_window_set_role(GTK_WINDOW(acctedit), "accounteditor");
1581 gtk_widget_realize(acctedit);
1582 gtk_widget_set_size_request(acctedit, -1, 250);
1583 gtk_window_set_default_size(GTK_WINDOW(acctedit), 550, 250);
1584 g_signal_connect(G_OBJECT(acctedit), "delete_event",
1585 G_CALLBACK(on_delete_acctedit), W);
1586
1587 vbox = gtk_vbox_new(FALSE, 6);
1588 gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
1589 gtk_container_add(GTK_CONTAINER(acctedit), vbox);
1590
1591 sw = generate_list();
1592 hbox = gtk_hbox_new(FALSE, 6);
1593 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 6);
1594
1595 gtk_box_pack_start(GTK_BOX(hbox), sw, TRUE, TRUE, 0);
1596
1597 sep = gtk_hseparator_new();
1598 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
1599
1600 hbox = gtk_hbox_new(FALSE, 6);
1601 gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
1602 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1603
1604 sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
1605
1606 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
1607 gtk_size_group_add_widget(sg, button);
1608 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1609 g_signal_connect(G_OBJECT(button), "clicked",
1610 G_CALLBACK(on_close_acctedit), W);
1611
1612 button = gtk_button_new_from_stock(GTK_STOCK_DELETE);
1613 gtk_size_group_add_widget(sg, button);
1614 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1615 g_signal_connect(G_OBJECT(button), "clicked",
1616 G_CALLBACK(del_acct), NULL);
1617
1618 button = gaim_pixbuf_button_from_stock(_("_Modify"), GTK_STOCK_PREFERENCES,
1619 GAIM_BUTTON_HORIZONTAL);
1620 gtk_size_group_add_widget(sg, button);
1621 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1622 g_signal_connect(G_OBJECT(button), "clicked",
1623 G_CALLBACK(mod_acct), NULL);
1624
1625 button = gtk_button_new_from_stock(GTK_STOCK_ADD);
1626 gtk_size_group_add_widget(sg, button);
1627 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
1628 g_signal_connect(G_OBJECT(button), "clicked",
1629 G_CALLBACK(add_acct), NULL);
1630
1631 gtk_widget_show_all(acctedit);
1632 }
1633
1634 struct signon_meter { 57 struct signon_meter {
1635 struct gaim_connection *gc; 58 GaimConnection *gc;
1636 GtkWidget *button; 59 GtkWidget *button;
1637 GtkWidget *progress; 60 GtkWidget *progress;
1638 GtkWidget *status; 61 GtkWidget *status;
1639 }; 62 };
1640 static GSList *meters = NULL; 63 static GSList *meters = NULL;
1641 64
1642 GtkWidget* create_meter_pixmap (struct gaim_connection *gc) 65 GtkWidget* create_meter_pixmap (GaimConnection *gc)
1643 { 66 {
1644 GdkPixbuf *pb = create_prpl_icon(gc->account); 67 GdkPixbuf *pb = create_prpl_icon(gc->account);
1645 GdkPixbuf *scale = gdk_pixbuf_scale_simple(pb, 30,30,GDK_INTERP_BILINEAR); 68 GdkPixbuf *scale = gdk_pixbuf_scale_simple(pb, 30,30,GDK_INTERP_BILINEAR);
1646 GtkWidget *image = 69 GtkWidget *image =
1647 gtk_image_new_from_pixbuf(scale); 70 gtk_image_new_from_pixbuf(scale);
1648 g_object_unref(G_OBJECT(pb)); 71 g_object_unref(G_OBJECT(pb));
1649 g_object_unref(G_OBJECT(scale)); 72 g_object_unref(G_OBJECT(scale));
1650 return image; 73 return image;
1651 } 74 }
1652 75
1653 static struct signon_meter *find_signon_meter(struct gaim_connection *gc) 76 static struct signon_meter *find_signon_meter(GaimConnection *gc)
1654 { 77 {
1655 GSList *m = meters; 78 GSList *m = meters;
1656 while (m) { 79 while (m) {
1657 if (((struct signon_meter *)m->data)->gc == gc) 80 if (((struct signon_meter *)m->data)->gc == gc)
1658 return m->data; 81 return m->data;
1704 do_away_message(NULL, message); 127 do_away_message(NULL, message);
1705 } 128 }
1706 return; 129 return;
1707 } 130 }
1708 131
1709 void account_online(struct gaim_connection *gc)
1710 {
1711 struct signon_meter *meter = find_signon_meter(gc);
1712 GList *wins;
1713 GtkTreeIter iter;
1714 GaimBlistNode *gnode,*bnode;
1715 GList *add_buds=NULL;
1716 GList *l;
1717
1718 /* Set the time the account came online */
1719 time(&gc->login_time);
1720
1721 /* first we hide the login progress meter */
1722 if (meter) {
1723 kill_meter(meter);
1724 meters = g_slist_remove(meters, meter);
1725 g_free(meter);
1726 }
1727
1728 /* then we do the buddy list stuff */
1729 if (mainwindow)
1730 gtk_widget_hide(mainwindow);
1731
1732 gaim_blist_show();
1733
1734 update_privacy_connections();
1735 do_away_menu(NULL);
1736 do_proto_menu();
1737
1738 gaim_blist_add_account(gc->account);
1739
1740 /*
1741 * XXX This is a hack! Remove this and replace it with a better event
1742 * notification system.
1743 */
1744 for (wins = gaim_get_windows(); wins != NULL; wins = wins->next) {
1745 struct gaim_window *win = (struct gaim_window *)wins->data;
1746 gaim_conversation_update(gaim_window_get_conversation_at(win, 0),
1747 GAIM_CONV_ACCOUNT_ONLINE);
1748 }
1749
1750 gaim_setup(gc);
1751
1752 gc->account->connecting = FALSE;
1753 connecting_count--;
1754 gaim_debug(GAIM_DEBUG_MISC, "accounts",
1755 "Connecting count: %d\n", connecting_count);
1756
1757 gaim_event_broadcast(event_signon, gc);
1758 system_log(log_signon, gc, NULL, OPT_LOG_BUDDY_SIGNON | OPT_LOG_MY_SIGNON);
1759
1760 /* away option given? */
1761 if (opt_away) {
1762 away_on_login(opt_away_arg);
1763 /* don't do it again */
1764 opt_away = 0;
1765 } else if (awaymessage) {
1766 serv_set_away(gc, GAIM_AWAY_CUSTOM, awaymessage->message);
1767 }
1768 if (opt_away_arg != NULL) {
1769 g_free(opt_away_arg);
1770 opt_away_arg = NULL;
1771 }
1772
1773 /* let the prpl know what buddies we pulled out of the local list */
1774 for(gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) {
1775 if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
1776 continue;
1777 for(bnode = gnode->child; bnode; bnode = bnode->next) {
1778 if(GAIM_BLIST_NODE_IS_BUDDY(bnode)) {
1779 struct buddy *b = (struct buddy *)bnode;
1780 if(b->account == gc->account) {
1781 add_buds = g_list_append(add_buds, b->name);
1782 }
1783 }
1784 }
1785 }
1786
1787 if(add_buds) {
1788 serv_add_buddies(gc, add_buds);
1789 g_list_free(add_buds);
1790 }
1791
1792 serv_set_permit_deny(gc);
1793
1794 /* everything for the account editor */
1795 if (!acctedit)
1796 return;
1797
1798 if (get_iter_from_data(GTK_TREE_VIEW(treeview), gc->account, &iter)) {
1799 gtk_list_store_set(model, &iter,
1800 COLUMN_ONLINE, TRUE,
1801 COLUMN_PROTOCOL, gc->prpl->info->name,
1802 -1);
1803 }
1804
1805 /* Update the conversation windows that use this account. */
1806 for (l = gaim_get_conversations(); l != NULL; l = l->next) {
1807 struct gaim_conversation *conv = (struct gaim_conversation *)l->data;
1808
1809 if (gaim_conversation_get_account(conv) == gc->account) {
1810 gaim_conversation_update(conv, GAIM_CONV_UPDATE_ACCOUNT);
1811 }
1812 }
1813 }
1814
1815 void account_offline(struct gaim_connection *gc)
1816 {
1817 struct signon_meter *meter = find_signon_meter(gc);
1818 GtkTreeIter iter;
1819 GList *l;
1820
1821 if (meter) {
1822 kill_meter(meter);
1823 meters = g_slist_remove(meters, meter);
1824 g_free(meter);
1825 }
1826
1827 gaim_debug(GAIM_DEBUG_MISC, "accounts",
1828 "Disconnecting. user = %p, gc = %p (%p)\n",
1829 gc->account, gc->account->gc, gc);
1830
1831 gc->account->gc = NULL; /* wasn't that awkward? */
1832
1833 if (!acctedit)
1834 return;
1835
1836 if (get_iter_from_data(GTK_TREE_VIEW(treeview), gc->account, &iter)) {
1837 gtk_list_store_set(model, &iter, COLUMN_ONLINE, FALSE, -1);
1838 }
1839
1840 /* Update the conversation windows that use this account. */
1841 for (l = gaim_get_conversations(); l != NULL; l = l->next) {
1842 struct gaim_conversation *conv = (struct gaim_conversation *)l->data;
1843
1844 if (gaim_conversation_get_account(conv) == gc->account) {
1845 gaim_conversation_update(conv, GAIM_CONV_UPDATE_ACCOUNT);
1846 }
1847 }
1848 }
1849
1850 void auto_login()
1851 {
1852 GSList *accts = gaim_accounts;
1853 struct gaim_account *a = NULL;
1854
1855 while (accts) {
1856 a = (struct gaim_account *)accts->data;
1857 if ((a->options & OPT_ACCT_AUTO) && (a->options & OPT_ACCT_REM_PASS)) {
1858 serv_login(a);
1859 }
1860 accts = accts->next;
1861 }
1862 }
1863
1864 /*
1865 * d:)->-<
1866 *
1867 * d:O-\-<
1868 *
1869 * d:D-/-<
1870 *
1871 * d8D->-< DANCE!
1872 */
1873
1874 static void cancel_signon(GtkWidget *button, struct signon_meter *meter) 132 static void cancel_signon(GtkWidget *button, struct signon_meter *meter)
1875 { 133 {
1876 meter->gc->wants_to_die = TRUE; 134 meter->gc->wants_to_die = TRUE;
1877 signoff(meter->gc); 135 gaim_connection_destroy(meter->gc);
1878 } 136 }
1879 137
1880 static gint meter_destroy(GtkWidget *window, GdkEvent *evt, struct signon_meter *meter) 138 static gint meter_destroy(GtkWidget *window, GdkEvent *evt, struct signon_meter *meter)
1881 { 139 {
1882 return TRUE; 140 return TRUE;
1883 } 141 }
1884 142
1885 static struct signon_meter *register_meter(struct gaim_connection *gc, GtkWidget *widget, GtkTable *table, gint *rows) 143 static struct signon_meter *
1886 { 144 register_meter(GaimConnection *gc, GtkWidget *widget,
145 GtkTable *table, gint *rows)
146 {
147 GaimAccount *account;
1887 GtkWidget *graphic; 148 GtkWidget *graphic;
1888 GtkWidget *label; 149 GtkWidget *label;
1889 GtkWidget *nest_vbox; 150 GtkWidget *nest_vbox;
1890 GString *name_to_print; 151 GString *name_to_print;
1891 struct signon_meter *meter; 152 struct signon_meter *meter;
1892 153
1893 name_to_print = g_string_new(gc->username); 154 account = gaim_connection_get_account(gc);
155
156 name_to_print = g_string_new(gaim_account_get_username(account));
1894 157
1895 meter = g_new0(struct signon_meter, 1); 158 meter = g_new0(struct signon_meter, 1);
1896 159
1897 (*rows)++; 160 (*rows)++;
1898 gtk_table_resize (table, *rows, 4); 161 gtk_table_resize (table, *rows, 4);
1934 struct signon_meter *meter = NULL; 197 struct signon_meter *meter = NULL;
1935 198
1936 while (m) { 199 while (m) {
1937 meter = (struct signon_meter *) (m->data); 200 meter = (struct signon_meter *) (m->data);
1938 meter->gc->wants_to_die = TRUE; 201 meter->gc->wants_to_die = TRUE;
1939 signoff((struct gaim_connection *) meter->gc); 202 gaim_connection_destroy((GaimConnection *) meter->gc);
1940 m = meters; 203 m = meters;
1941 } 204 }
1942 } 205 }
1943 206
1944 void set_login_progress(struct gaim_connection *gc, float howfar, char *message) 207 void set_login_progress(GaimConnection *gc, float howfar, char *message)
1945 { 208 {
1946 struct signon_meter *meter = find_signon_meter(gc); 209 struct signon_meter *meter = find_signon_meter(gc);
1947 210
1948 if (mainwindow) 211 if (mainwindow)
1949 gtk_widget_hide(mainwindow); 212 gtk_widget_hide(mainwindow);
1991 gtk_statusbar_pop(GTK_STATUSBAR(meter->status), 1); 254 gtk_statusbar_pop(GTK_STATUSBAR(meter->status), 1);
1992 gtk_statusbar_push(GTK_STATUSBAR(meter->status), 1, message); 255 gtk_statusbar_push(GTK_STATUSBAR(meter->status), 1, message);
1993 } 256 }
1994 257
1995 struct kick_dlg { 258 struct kick_dlg {
1996 struct gaim_account *account; 259 GaimAccount *account;
1997 GtkWidget *dlg; 260 GtkWidget *dlg;
1998 }; 261 };
1999 static GSList *kicks = NULL; 262 static GSList *kicks = NULL;
2000 263
2001 static struct kick_dlg *find_kick_dlg(struct gaim_account *account) 264 static struct kick_dlg *find_kick_dlg(GaimAccount *account)
2002 { 265 {
2003 GSList *k = kicks; 266 GSList *k = kicks;
2004 while (k) { 267 while (k) {
2005 struct kick_dlg *d = k->data; 268 struct kick_dlg *d = k->data;
2006 if (d->account == account) 269 if (d->account == account)
2017 } 280 }
2018 281
2019 /* 282 /*
2020 * Common code for hide_login_progress(), and hide_login_progress_info() 283 * Common code for hide_login_progress(), and hide_login_progress_info()
2021 */ 284 */
2022 static void hide_login_progress_common(struct gaim_connection *gc, 285 static void hide_login_progress_common(GaimConnection *gc,
2023 char *details, 286 char *details,
2024 char *title, 287 char *title,
2025 char *prologue) 288 char *prologue)
2026 { 289 {
2027 gchar *buf; 290 gchar *buf;
2041 g_free(meter); 304 g_free(meter);
2042 } 305 }
2043 g_free(buf); 306 g_free(buf);
2044 } 307 }
2045 308
2046 void hide_login_progress(struct gaim_connection *gc, char *why) 309 void hide_login_progress(GaimConnection *gc, char *why)
2047 { 310 {
311 GaimAccount *account = gaim_connection_get_account(gc);
2048 gchar *buf; 312 gchar *buf;
2049 313
2050 gaim_event_broadcast(event_error, gc, why); 314 gaim_event_broadcast(event_error, gc, why);
2051 buf = g_strdup_printf(_("%s was unable to sign on"), gc->username); 315 buf = g_strdup_printf(_("%s was unable to sign on"),
316 gaim_account_get_username(account));
2052 hide_login_progress_common(gc, why, _("Signon Error"), buf); 317 hide_login_progress_common(gc, why, _("Signon Error"), buf);
2053 g_free(buf); 318 g_free(buf);
2054 } 319 }
2055 320
2056 /* 321 /*
2057 * Like hide_login_progress(), but for informational, not error/warning, 322 * Like hide_login_progress(), but for informational, not error/warning,
2058 * messages. 323 * messages.
2059 * 324 *
2060 */ 325 */
2061 void hide_login_progress_notice(struct gaim_connection *gc, char *why) 326 void hide_login_progress_notice(GaimConnection *gc, char *why)
2062 { 327 {
2063 hide_login_progress_common(gc, why, _("Notice"), gc->username); 328 GaimAccount *account = gaim_connection_get_account(gc);
329
330 hide_login_progress_common(gc, why, _("Notice"),
331 (char *)gaim_account_get_username(account));
2064 } 332 }
2065 333
2066 /* 334 /*
2067 * Like hide_login_progress(), but for non-signon error messages. 335 * Like hide_login_progress(), but for non-signon error messages.
2068 * 336 *
2069 */ 337 */
2070 void hide_login_progress_error(struct gaim_connection *gc, char *why) 338 void hide_login_progress_error(GaimConnection *gc, char *why)
2071 { 339 {
2072 char buf[2048]; 340 char buf[2048];
341 GaimAccount *account = gaim_connection_get_account(gc);
2073 342
2074 gaim_event_broadcast(event_error, gc, why); 343 gaim_event_broadcast(event_error, gc, why);
2075 g_snprintf(buf, sizeof(buf), _("%s has been signed off"), gc->username); 344 g_snprintf(buf, sizeof(buf), _("%s has been signed off"),
345 gaim_account_get_username(account));
2076 hide_login_progress_common(gc, why, _("Connection Error"), buf); 346 hide_login_progress_common(gc, why, _("Connection Error"), buf);
2077 } 347 }
2078 348
2079 void signoff_all()
2080 {
2081 GSList *c = connections;
2082 struct gaim_connection *g = NULL;
2083
2084 while (c) {
2085 g = (struct gaim_connection *)c->data;
2086 g->wants_to_die = TRUE;
2087 signoff(g);
2088 c = connections;
2089 }
2090 }
2091
2092 void signoff(struct gaim_connection *gc)
2093 {
2094 GList *wins;
2095
2096 /* we only remove the account if we ever added it */
2097 if(!gc->account->connecting)
2098 gaim_blist_remove_account(gc->account);
2099
2100 /* core stuff */
2101 /* remove this here so plugins get a sensible count of connections */
2102 connections = g_slist_remove(connections, gc);
2103 gaim_debug(GAIM_DEBUG_MISC, "accounts", "date: %s\n", full_date());
2104 gaim_event_broadcast(event_signoff, gc);
2105 system_log(log_signoff, gc, NULL, OPT_LOG_BUDDY_SIGNON | OPT_LOG_MY_SIGNON);
2106 /* set this in case the plugin died before really connecting.
2107 do it after calling the plugins so they can determine if
2108 this user was ever on-line or not */
2109 if (gc->account->connecting) {
2110 gc->account->connecting = FALSE;
2111 connecting_count--;
2112 }
2113 gaim_debug(GAIM_DEBUG_MISC, "accounts", "connecting_count: %d\n",
2114 connecting_count);
2115 serv_close(gc);
2116
2117 /* more UI stuff */
2118 do_away_menu();
2119 do_proto_menu();
2120
2121 /*
2122 * XXX This is a hack! Remove this and replace it with a better event
2123 * notification system.
2124 */
2125 for (wins = gaim_get_windows(); wins != NULL; wins = wins->next) {
2126 struct gaim_window *win = (struct gaim_window *)wins->data;
2127 gaim_conversation_update(gaim_window_get_conversation_at(win, 0),
2128 GAIM_CONV_ACCOUNT_OFFLINE);
2129 }
2130
2131 gaim_request_close_with_handle(gc);
2132 gaim_notify_close_with_handle(gc);
2133
2134 update_privacy_connections();
2135
2136 /* in, out, shake it all about */
2137 if (connections)
2138 return;
2139
2140 destroy_all_dialogs();
2141 gaim_blist_destroy();
2142
2143 show_login();
2144 }
2145
2146 struct gaim_account *gaim_account_new(const char *name, int proto, int opts)
2147 {
2148 struct gaim_account *account = g_new0(struct gaim_account, 1);
2149 g_snprintf(account->username, sizeof(account->username), "%s", name);
2150 g_snprintf(account->user_info, sizeof(account->user_info), "%s", DEFAULT_INFO);
2151 account->protocol = proto;
2152 account->options = opts;
2153 account->permit = NULL;
2154 account->deny = NULL;
2155 gaim_accounts = g_slist_append(gaim_accounts, account);
2156
2157 if (treeview) {
2158 GtkTreeIter iter;
2159
2160 gtk_list_store_append(model, &iter);
2161 gtk_list_store_set(model, &iter,
2162 COLUMN_SCREENNAME, account->username,
2163 COLUMN_ONLINE, (account->gc ? TRUE : FALSE),
2164 COLUMN_AUTOLOGIN, (account->options & OPT_ACCT_AUTO),
2165 COLUMN_PROTOCOL, proto_name(account->protocol),
2166 COLUMN_DATA, account,
2167 -1);
2168 }
2169
2170 return account;
2171 }
2172
2173 GSList *gaim_get_connections()
2174 {
2175 return connections;
2176 }