Mercurial > pidgin
comparison gtk/gtkaccount.c @ 14191:009db0b357b5
This is a hand-crafted commit to migrate across subversion revisions
16854:16861, due to some vagaries of the way the original renames were
done. Witness that monotone can do in one revision what svn had to
spread across several.
author | Ethan Blanton <elb@pidgin.im> |
---|---|
date | Sat, 16 Dec 2006 04:59:55 +0000 |
parents | |
children | ec2cd563da47 |
comparison
equal
deleted
inserted
replaced
14190:366be2ce35a7 | 14191:009db0b357b5 |
---|---|
1 /** | |
2 * @file gtkaccount.c GTK+ Account Editor UI | |
3 * @ingroup gtkui | |
4 * | |
5 * gaim | |
6 * | |
7 * Gaim is the legal property of its developers, whose names are too numerous | |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
10 * | |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 */ | |
25 | |
26 #include "internal.h" | |
27 #include "gtkgaim.h" | |
28 | |
29 #include "account.h" | |
30 #include "accountopt.h" | |
31 #include "core.h" | |
32 #include "debug.h" | |
33 #include "notify.h" | |
34 #include "plugin.h" | |
35 #include "prefs.h" | |
36 #include "prpl.h" | |
37 #include "request.h" | |
38 #include "savedstatuses.h" | |
39 #include "signals.h" | |
40 #include "util.h" | |
41 | |
42 #include "gtkaccount.h" | |
43 #include "gtkblist.h" | |
44 #include "gtkdialogs.h" | |
45 #include "gtkutils.h" | |
46 #include "gtkstatusbox.h" | |
47 #include "gtkstock.h" | |
48 | |
49 enum | |
50 { | |
51 COLUMN_ICON, | |
52 COLUMN_SCREENNAME, | |
53 COLUMN_ENABLED, | |
54 COLUMN_PROTOCOL, | |
55 COLUMN_DATA, | |
56 COLUMN_PULSE_DATA, | |
57 NUM_COLUMNS | |
58 }; | |
59 | |
60 typedef struct | |
61 { | |
62 GaimAccount *account; | |
63 char *username; | |
64 char *alias; | |
65 | |
66 } GaimGtkAccountAddUserData; | |
67 | |
68 typedef struct | |
69 { | |
70 GtkWidget *window; | |
71 GtkWidget *treeview; | |
72 | |
73 GtkWidget *modify_button; | |
74 GtkWidget *delete_button; | |
75 | |
76 GtkListStore *model; | |
77 GtkTreeIter drag_iter; | |
78 | |
79 GtkTreeViewColumn *screenname_col; | |
80 | |
81 } AccountsWindow; | |
82 | |
83 typedef struct | |
84 { | |
85 GaimGtkAccountDialogType type; | |
86 | |
87 GaimAccount *account; | |
88 char *protocol_id; | |
89 GaimPlugin *plugin; | |
90 GaimPluginProtocolInfo *prpl_info; | |
91 | |
92 GaimProxyType new_proxy_type; | |
93 | |
94 GList *user_split_entries; | |
95 GList *protocol_opt_entries; | |
96 | |
97 GtkSizeGroup *sg; | |
98 GtkWidget *window; | |
99 | |
100 GtkWidget *top_vbox; | |
101 GtkWidget *bottom_vbox; | |
102 GtkWidget *ok_button; | |
103 GtkWidget *register_button; | |
104 | |
105 /* Login Options */ | |
106 GtkWidget *login_frame; | |
107 GtkWidget *protocol_menu; | |
108 GtkWidget *password_box; | |
109 GtkWidget *screenname_entry; | |
110 GtkWidget *password_entry; | |
111 GtkWidget *alias_entry; | |
112 GtkWidget *remember_pass_check; | |
113 | |
114 /* User Options */ | |
115 GtkWidget *user_frame; | |
116 GtkWidget *new_mail_check; | |
117 GtkWidget *icon_hbox; | |
118 GtkWidget *icon_check; | |
119 GtkWidget *icon_entry; | |
120 char *icon_path; | |
121 GtkWidget *icon_filesel; | |
122 GtkWidget *icon_preview; | |
123 GtkWidget *icon_text; | |
124 | |
125 /* Protocol Options */ | |
126 GtkWidget *protocol_frame; | |
127 | |
128 /* Proxy Options */ | |
129 GtkWidget *proxy_frame; | |
130 GtkWidget *proxy_vbox; | |
131 GtkWidget *proxy_dropdown; | |
132 GtkWidget *proxy_host_entry; | |
133 GtkWidget *proxy_port_entry; | |
134 GtkWidget *proxy_user_entry; | |
135 GtkWidget *proxy_pass_entry; | |
136 | |
137 } AccountPrefsDialog; | |
138 | |
139 typedef struct | |
140 { | |
141 GdkPixbuf *online_pixbuf; | |
142 gboolean pulse_to_grey; | |
143 float pulse_value; | |
144 int timeout; | |
145 GaimAccount *account; | |
146 GtkTreeModel *model; | |
147 | |
148 } GaimGtkPulseData; | |
149 | |
150 | |
151 static AccountsWindow *accounts_window = NULL; | |
152 static GHashTable *account_pref_wins; | |
153 | |
154 static void add_account_to_liststore(GaimAccount *account, gpointer user_data); | |
155 static void set_account(GtkListStore *store, GtkTreeIter *iter, | |
156 GaimAccount *account); | |
157 | |
158 /************************************************************************** | |
159 * Add/Modify Account dialog | |
160 **************************************************************************/ | |
161 static void add_login_options(AccountPrefsDialog *dialog, GtkWidget *parent); | |
162 static void add_user_options(AccountPrefsDialog *dialog, GtkWidget *parent); | |
163 static void add_protocol_options(AccountPrefsDialog *dialog, | |
164 GtkWidget *parent); | |
165 static void add_proxy_options(AccountPrefsDialog *dialog, GtkWidget *parent); | |
166 | |
167 static GtkWidget * | |
168 add_pref_box(AccountPrefsDialog *dialog, GtkWidget *parent, | |
169 const char *text, GtkWidget *widget) | |
170 { | |
171 GtkWidget *hbox; | |
172 GtkWidget *label; | |
173 | |
174 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
175 gtk_box_pack_start(GTK_BOX(parent), hbox, FALSE, FALSE, 0); | |
176 gtk_widget_show(hbox); | |
177 | |
178 label = gtk_label_new_with_mnemonic(text); | |
179 gtk_size_group_add_widget(dialog->sg, label); | |
180 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
181 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
182 gtk_widget_show(label); | |
183 | |
184 gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, GAIM_HIG_BORDER); | |
185 gtk_widget_show(widget); | |
186 gaim_set_accessible_label (widget, label); | |
187 | |
188 return hbox; | |
189 } | |
190 | |
191 static void | |
192 set_dialog_icon(AccountPrefsDialog *dialog) | |
193 { | |
194 char *filename = gaim_buddy_icons_get_full_path(dialog->icon_path); | |
195 GdkPixbuf *pixbuf = NULL; | |
196 if (filename) | |
197 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); | |
198 | |
199 if (pixbuf && dialog->prpl_info && | |
200 (dialog->prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_DISPLAY)) | |
201 { | |
202 int width, height; | |
203 GdkPixbuf *scale; | |
204 | |
205 gaim_gtk_buddy_icon_get_scale_size(pixbuf, | |
206 &dialog->prpl_info->icon_spec, &width, &height); | |
207 scale = gdk_pixbuf_scale_simple(pixbuf, width, height, GDK_INTERP_BILINEAR); | |
208 | |
209 g_object_unref(G_OBJECT(pixbuf)); | |
210 pixbuf = scale; | |
211 } | |
212 | |
213 gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->icon_entry), pixbuf); | |
214 if (pixbuf != NULL) | |
215 g_object_unref(G_OBJECT(pixbuf)); | |
216 g_free(filename); | |
217 } | |
218 | |
219 static void | |
220 set_account_protocol_cb(GtkWidget *item, const char *id, | |
221 AccountPrefsDialog *dialog) | |
222 { | |
223 GaimPlugin *new_plugin; | |
224 | |
225 new_plugin = gaim_find_prpl(id); | |
226 | |
227 if (new_plugin == dialog->plugin) | |
228 return; | |
229 | |
230 dialog->plugin = new_plugin; | |
231 | |
232 if (dialog->plugin != NULL) | |
233 { | |
234 dialog->prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(dialog->plugin); | |
235 | |
236 g_free(dialog->protocol_id); | |
237 dialog->protocol_id = g_strdup(dialog->plugin->info->id); | |
238 } | |
239 | |
240 if (dialog->account != NULL) | |
241 gaim_account_clear_settings(dialog->account); | |
242 | |
243 add_login_options(dialog, dialog->top_vbox); | |
244 add_user_options(dialog, dialog->top_vbox); | |
245 add_protocol_options(dialog, dialog->bottom_vbox); | |
246 | |
247 if (!dialog->prpl_info || !dialog->prpl_info->register_user) { | |
248 gtk_widget_hide(dialog->register_button); | |
249 } else { | |
250 if (dialog->prpl_info != NULL && | |
251 (dialog->prpl_info->options & OPT_PROTO_REGISTER_NOSCREENNAME)) { | |
252 gtk_widget_set_sensitive(dialog->register_button, TRUE); | |
253 } else { | |
254 gtk_widget_set_sensitive(dialog->register_button, FALSE); | |
255 } | |
256 gtk_widget_show(dialog->register_button); | |
257 } | |
258 } | |
259 | |
260 static void | |
261 screenname_changed_cb(GtkEntry *entry, AccountPrefsDialog *dialog) | |
262 { | |
263 if (dialog->ok_button) | |
264 gtk_widget_set_sensitive(dialog->ok_button, | |
265 *gtk_entry_get_text(entry) != '\0'); | |
266 if (dialog->register_button) { | |
267 if (dialog->prpl_info != NULL && (dialog->prpl_info->options & OPT_PROTO_REGISTER_NOSCREENNAME)) | |
268 gtk_widget_set_sensitive(dialog->register_button, TRUE); | |
269 else | |
270 gtk_widget_set_sensitive(dialog->register_button, | |
271 *gtk_entry_get_text(entry) != '\0'); | |
272 } | |
273 } | |
274 | |
275 static void | |
276 icon_filesel_choose_cb(const char *filename, gpointer data) | |
277 { | |
278 AccountPrefsDialog *dialog; | |
279 | |
280 dialog = data; | |
281 | |
282 if (filename) { | |
283 g_free(dialog->icon_path); | |
284 dialog->icon_path = gaim_gtk_convert_buddy_icon(dialog->plugin, filename); | |
285 set_dialog_icon(dialog); | |
286 gtk_widget_show(dialog->icon_entry); | |
287 } | |
288 | |
289 dialog->icon_filesel = NULL; | |
290 } | |
291 | |
292 static void | |
293 icon_select_cb(GtkWidget *button, AccountPrefsDialog *dialog) | |
294 { | |
295 dialog->icon_filesel = gaim_gtk_buddy_icon_chooser_new(GTK_WINDOW(dialog->window), icon_filesel_choose_cb, dialog); | |
296 gtk_widget_show_all(dialog->icon_filesel); | |
297 } | |
298 | |
299 static void | |
300 icon_reset_cb(GtkWidget *button, AccountPrefsDialog *dialog) | |
301 { | |
302 g_free(dialog->icon_path); | |
303 dialog->icon_path = NULL; | |
304 | |
305 gtk_widget_hide(dialog->icon_entry); | |
306 } | |
307 | |
308 | |
309 static void | |
310 account_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y, | |
311 GtkSelectionData *sd, guint info, guint t, AccountPrefsDialog *dialog) | |
312 { | |
313 gchar *name = (gchar *)sd->data; | |
314 | |
315 if ((sd->length >= 0) && (sd->format == 8)) { | |
316 /* Well, it looks like the drag event was cool. | |
317 * Let's do something with it */ | |
318 if (!g_ascii_strncasecmp(name, "file://", 7)) { | |
319 GError *converr = NULL; | |
320 gchar *tmp, *rtmp; | |
321 /* It looks like we're dealing with a local file. Let's | |
322 * just untar it in the right place */ | |
323 if(!(tmp = g_filename_from_uri(name, NULL, &converr))) { | |
324 gaim_debug(GAIM_DEBUG_ERROR, "buddyicon", "%s\n", | |
325 (converr ? converr->message : | |
326 "g_filename_from_uri error")); | |
327 return; | |
328 } | |
329 if ((rtmp = strchr(tmp, '\r')) || (rtmp = strchr(tmp, '\n'))) | |
330 *rtmp = '\0'; | |
331 g_free(dialog->icon_path); | |
332 | |
333 dialog->icon_path = gaim_gtk_convert_buddy_icon(dialog->plugin, tmp); | |
334 set_dialog_icon(dialog); | |
335 gtk_widget_show(dialog->icon_entry); | |
336 g_free(tmp); | |
337 } | |
338 gtk_drag_finish(dc, TRUE, FALSE, t); | |
339 } | |
340 gtk_drag_finish(dc, FALSE, FALSE, t); | |
341 } | |
342 | |
343 static void | |
344 update_editable(GaimConnection *gc, AccountPrefsDialog *dialog) | |
345 { | |
346 gboolean set; | |
347 GList *l; | |
348 | |
349 if (dialog->account == NULL) | |
350 return; | |
351 | |
352 if (gc != NULL && dialog->account != gaim_connection_get_account(gc)) | |
353 return; | |
354 | |
355 set = !(gaim_account_is_connected(dialog->account) || gaim_account_is_connecting(dialog->account)); | |
356 gtk_widget_set_sensitive(dialog->protocol_menu, set); | |
357 gtk_widget_set_sensitive(dialog->screenname_entry, set); | |
358 | |
359 for (l = dialog->user_split_entries ; l != NULL ; l = l->next) | |
360 gtk_widget_set_sensitive((GtkWidget *)l->data, set); | |
361 } | |
362 | |
363 static void | |
364 add_login_options(AccountPrefsDialog *dialog, GtkWidget *parent) | |
365 { | |
366 GtkWidget *frame; | |
367 GtkWidget *vbox; | |
368 GtkWidget *entry; | |
369 GList *user_splits; | |
370 GList *l, *l2; | |
371 char *username = NULL; | |
372 | |
373 if (dialog->login_frame != NULL) | |
374 gtk_widget_destroy(dialog->login_frame); | |
375 | |
376 /* Build the login options frame. */ | |
377 frame = gaim_gtk_make_frame(parent, _("Login Options")); | |
378 | |
379 /* cringe */ | |
380 dialog->login_frame = gtk_widget_get_parent(gtk_widget_get_parent(frame)); | |
381 | |
382 gtk_box_reorder_child(GTK_BOX(parent), dialog->login_frame, 0); | |
383 gtk_widget_show(dialog->login_frame); | |
384 | |
385 /* Main vbox */ | |
386 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
387 gtk_container_add(GTK_CONTAINER(frame), vbox); | |
388 gtk_widget_show(vbox); | |
389 | |
390 /* Protocol */ | |
391 dialog->protocol_menu = gaim_gtk_protocol_option_menu_new( | |
392 dialog->protocol_id, G_CALLBACK(set_account_protocol_cb), dialog); | |
393 | |
394 add_pref_box(dialog, vbox, _("Protocol:"), dialog->protocol_menu); | |
395 | |
396 /* Screen name */ | |
397 dialog->screenname_entry = gtk_entry_new(); | |
398 | |
399 add_pref_box(dialog, vbox, _("Screen name:"), dialog->screenname_entry); | |
400 | |
401 g_signal_connect(G_OBJECT(dialog->screenname_entry), "changed", | |
402 G_CALLBACK(screenname_changed_cb), dialog); | |
403 | |
404 /* Do the user split thang */ | |
405 if (dialog->plugin == NULL) /* Yeah right. */ | |
406 user_splits = NULL; | |
407 else | |
408 user_splits = dialog->prpl_info->user_splits; | |
409 | |
410 if (dialog->account != NULL) | |
411 username = g_strdup(gaim_account_get_username(dialog->account)); | |
412 | |
413 if (dialog->user_split_entries != NULL) { | |
414 g_list_free(dialog->user_split_entries); | |
415 dialog->user_split_entries = NULL; | |
416 } | |
417 | |
418 for (l = user_splits; l != NULL; l = l->next) { | |
419 GaimAccountUserSplit *split = l->data; | |
420 char *buf; | |
421 | |
422 buf = g_strdup_printf("%s:", gaim_account_user_split_get_text(split)); | |
423 | |
424 entry = gtk_entry_new(); | |
425 | |
426 add_pref_box(dialog, vbox, buf, entry); | |
427 | |
428 g_free(buf); | |
429 | |
430 dialog->user_split_entries = | |
431 g_list_append(dialog->user_split_entries, entry); | |
432 } | |
433 | |
434 for (l = g_list_last(dialog->user_split_entries), | |
435 l2 = g_list_last(user_splits); | |
436 l != NULL && l2 != NULL; | |
437 l = l->prev, l2 = l2->prev) { | |
438 | |
439 GtkWidget *entry = l->data; | |
440 GaimAccountUserSplit *split = l2->data; | |
441 const char *value = NULL; | |
442 char *c; | |
443 | |
444 if (dialog->account != NULL) { | |
445 c = strrchr(username, | |
446 gaim_account_user_split_get_separator(split)); | |
447 | |
448 if (c != NULL) { | |
449 *c = '\0'; | |
450 c++; | |
451 | |
452 value = c; | |
453 } | |
454 } | |
455 | |
456 if (value == NULL) | |
457 value = gaim_account_user_split_get_default_value(split); | |
458 | |
459 if (value != NULL) | |
460 gtk_entry_set_text(GTK_ENTRY(entry), value); | |
461 } | |
462 | |
463 if (username != NULL) | |
464 gtk_entry_set_text(GTK_ENTRY(dialog->screenname_entry), username); | |
465 | |
466 g_free(username); | |
467 | |
468 | |
469 /* Password */ | |
470 dialog->password_entry = gtk_entry_new(); | |
471 gtk_entry_set_visibility(GTK_ENTRY(dialog->password_entry), FALSE); | |
472 gtk_entry_set_invisible_char(GTK_ENTRY(dialog->password_entry), GAIM_INVISIBLE_CHAR); | |
473 dialog->password_box = add_pref_box(dialog, vbox, _("Password:"), | |
474 dialog->password_entry); | |
475 | |
476 /* Alias */ | |
477 dialog->alias_entry = gtk_entry_new(); | |
478 add_pref_box(dialog, vbox, _("Local alias:"), dialog->alias_entry); | |
479 | |
480 /* Remember Password */ | |
481 dialog->remember_pass_check = | |
482 gtk_check_button_new_with_label(_("Remember password")); | |
483 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->remember_pass_check), | |
484 FALSE); | |
485 gtk_box_pack_start(GTK_BOX(vbox), dialog->remember_pass_check, | |
486 FALSE, FALSE, 0); | |
487 gtk_widget_show(dialog->remember_pass_check); | |
488 | |
489 /* Set the fields. */ | |
490 if (dialog->account != NULL) { | |
491 if (gaim_account_get_password(dialog->account)) | |
492 gtk_entry_set_text(GTK_ENTRY(dialog->password_entry), | |
493 gaim_account_get_password(dialog->account)); | |
494 | |
495 if (gaim_account_get_alias(dialog->account)) | |
496 gtk_entry_set_text(GTK_ENTRY(dialog->alias_entry), | |
497 gaim_account_get_alias(dialog->account)); | |
498 | |
499 gtk_toggle_button_set_active( | |
500 GTK_TOGGLE_BUTTON(dialog->remember_pass_check), | |
501 gaim_account_get_remember_password(dialog->account)); | |
502 } | |
503 | |
504 if (dialog->prpl_info != NULL && | |
505 (dialog->prpl_info->options & OPT_PROTO_NO_PASSWORD)) { | |
506 | |
507 gtk_widget_hide(dialog->password_box); | |
508 gtk_widget_hide(dialog->remember_pass_check); | |
509 } | |
510 | |
511 /* Do not let the user change the protocol/screenname while connected. */ | |
512 update_editable(NULL, dialog); | |
513 gaim_signal_connect(gaim_connections_get_handle(), "signing-on", dialog, | |
514 G_CALLBACK(update_editable), dialog); | |
515 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", dialog, | |
516 G_CALLBACK(update_editable), dialog); | |
517 } | |
518 | |
519 static void | |
520 icon_check_cb(GtkWidget *checkbox, AccountPrefsDialog *dialog) | |
521 { | |
522 gtk_widget_set_sensitive(dialog->icon_hbox, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check))); | |
523 } | |
524 | |
525 static void | |
526 add_user_options(AccountPrefsDialog *dialog, GtkWidget *parent) | |
527 { | |
528 GtkWidget *frame; | |
529 GtkWidget *vbox; | |
530 GtkWidget *vbox2; | |
531 GtkWidget *hbox; | |
532 GtkWidget *hbox2; | |
533 GtkWidget *button; | |
534 GtkWidget *label; | |
535 | |
536 if (dialog->user_frame != NULL) | |
537 gtk_widget_destroy(dialog->user_frame); | |
538 | |
539 /* Build the user options frame. */ | |
540 frame = gaim_gtk_make_frame(parent, _("User Options")); | |
541 dialog->user_frame = gtk_widget_get_parent(gtk_widget_get_parent(frame)); | |
542 | |
543 gtk_box_reorder_child(GTK_BOX(parent), dialog->user_frame, 1); | |
544 gtk_widget_show(dialog->user_frame); | |
545 | |
546 /* Main vbox */ | |
547 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
548 gtk_container_add(GTK_CONTAINER(frame), vbox); | |
549 gtk_widget_show(vbox); | |
550 | |
551 /* New mail notifications */ | |
552 dialog->new_mail_check = | |
553 gtk_check_button_new_with_label(_("New mail notifications")); | |
554 gtk_box_pack_start(GTK_BOX(vbox), dialog->new_mail_check, FALSE, FALSE, 0); | |
555 gtk_widget_show(dialog->new_mail_check); | |
556 | |
557 /* Buddy icon */ | |
558 dialog->icon_check = gtk_check_button_new_with_label(_("Use this buddy icon for this account:")); | |
559 g_signal_connect(G_OBJECT(dialog->icon_check), "toggled", G_CALLBACK(icon_check_cb), dialog); | |
560 gtk_widget_show(dialog->icon_check); | |
561 gtk_box_pack_start(GTK_BOX(vbox), dialog->icon_check, FALSE, FALSE, 0); | |
562 | |
563 dialog->icon_hbox = hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
564 gtk_widget_set_sensitive(hbox, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check))); | |
565 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
566 gtk_widget_show(hbox); | |
567 | |
568 label = gtk_label_new(" "); | |
569 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
570 gtk_widget_show(label); | |
571 | |
572 dialog->icon_entry = gtk_image_new(); | |
573 gtk_box_pack_start(GTK_BOX(hbox), dialog->icon_entry, | |
574 FALSE, FALSE, 0); | |
575 gtk_widget_show(dialog->icon_entry); | |
576 gaim_set_accessible_label (dialog->icon_entry, label); | |
577 dialog->icon_path = NULL; | |
578 | |
579 vbox2 = gtk_vbox_new(FALSE, 0); | |
580 gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0); | |
581 gtk_widget_show(vbox2); | |
582 | |
583 hbox2 = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
584 gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, GAIM_HIG_BORDER); | |
585 gtk_widget_show(hbox2); | |
586 | |
587 button = gtk_button_new_from_stock(GTK_STOCK_OPEN); | |
588 gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0); | |
589 g_signal_connect(G_OBJECT(button), "clicked", | |
590 G_CALLBACK(icon_select_cb), dialog); | |
591 gtk_widget_show(button); | |
592 | |
593 button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); | |
594 g_signal_connect(G_OBJECT(button), "clicked", | |
595 G_CALLBACK(icon_reset_cb), dialog); | |
596 gtk_box_pack_start(GTK_BOX(hbox2), button, FALSE, FALSE, 0); | |
597 gtk_widget_show(button); | |
598 | |
599 if (dialog->prpl_info != NULL) { | |
600 if (!(dialog->prpl_info->options & OPT_PROTO_MAIL_CHECK)) | |
601 gtk_widget_hide(dialog->new_mail_check); | |
602 | |
603 if (!(dialog->prpl_info->icon_spec.format != NULL)) | |
604 gtk_widget_hide(dialog->icon_hbox); | |
605 } | |
606 | |
607 if (dialog->account != NULL) { | |
608 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->new_mail_check), | |
609 gaim_account_get_check_mail(dialog->account)); | |
610 | |
611 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->icon_check), | |
612 !gaim_account_get_ui_bool(dialog->account, GAIM_GTK_UI, "use-global-buddyicon", | |
613 TRUE)); | |
614 | |
615 dialog->icon_path = g_strdup(gaim_account_get_ui_string(dialog->account, GAIM_GTK_UI, "non-global-buddyicon", NULL)); | |
616 set_dialog_icon(dialog); | |
617 } | |
618 | |
619 if (!dialog->prpl_info || | |
620 (!(dialog->prpl_info->options & OPT_PROTO_MAIL_CHECK) && | |
621 (dialog->prpl_info->icon_spec.format == NULL))) { | |
622 | |
623 /* Nothing to see :( aww. */ | |
624 gtk_widget_hide(dialog->user_frame); | |
625 } | |
626 } | |
627 | |
628 static void | |
629 add_protocol_options(AccountPrefsDialog *dialog, GtkWidget *parent) | |
630 { | |
631 GaimAccountOption *option; | |
632 GaimAccount *account; | |
633 GtkWidget *frame, *vbox, *check, *entry, *combo; | |
634 const GList *list, *node; | |
635 gint i, idx, int_value; | |
636 GtkListStore *model; | |
637 GtkTreeIter iter; | |
638 GtkCellRenderer *renderer; | |
639 GaimKeyValuePair *kvp; | |
640 GList *l; | |
641 char buf[1024]; | |
642 char *title; | |
643 const char *str_value; | |
644 gboolean bool_value; | |
645 | |
646 if (dialog->protocol_frame != NULL) { | |
647 gtk_widget_destroy(dialog->protocol_frame); | |
648 dialog->protocol_frame = NULL; | |
649 } | |
650 | |
651 if (dialog->protocol_opt_entries != NULL) { | |
652 g_list_free(dialog->protocol_opt_entries); | |
653 dialog->protocol_opt_entries = NULL; | |
654 } | |
655 | |
656 if (dialog->prpl_info == NULL || | |
657 dialog->prpl_info->protocol_options == NULL) { | |
658 | |
659 return; | |
660 } | |
661 | |
662 account = dialog->account; | |
663 | |
664 /* Build the protocol options frame. */ | |
665 g_snprintf(buf, sizeof(buf), _("%s Options"), dialog->plugin->info->name); | |
666 | |
667 frame = gaim_gtk_make_frame(parent, buf); | |
668 dialog->protocol_frame = | |
669 gtk_widget_get_parent(gtk_widget_get_parent(frame)); | |
670 | |
671 gtk_box_reorder_child(GTK_BOX(parent), dialog->protocol_frame, 0); | |
672 gtk_widget_show(dialog->protocol_frame); | |
673 | |
674 /* Main vbox */ | |
675 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
676 gtk_container_add(GTK_CONTAINER(frame), vbox); | |
677 gtk_widget_show(vbox); | |
678 | |
679 for (l = dialog->prpl_info->protocol_options; l != NULL; l = l->next) | |
680 { | |
681 option = (GaimAccountOption *)l->data; | |
682 | |
683 switch (gaim_account_option_get_type(option)) | |
684 { | |
685 case GAIM_PREF_BOOLEAN: | |
686 if (account == NULL || | |
687 strcmp(gaim_account_get_protocol_id(account), | |
688 dialog->protocol_id)) | |
689 { | |
690 bool_value = gaim_account_option_get_default_bool(option); | |
691 } | |
692 else | |
693 { | |
694 bool_value = gaim_account_get_bool(account, | |
695 gaim_account_option_get_setting(option), | |
696 gaim_account_option_get_default_bool(option)); | |
697 } | |
698 | |
699 check = gtk_check_button_new_with_label( | |
700 gaim_account_option_get_text(option)); | |
701 | |
702 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), | |
703 bool_value); | |
704 | |
705 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0); | |
706 gtk_widget_show(check); | |
707 | |
708 dialog->protocol_opt_entries = | |
709 g_list_append(dialog->protocol_opt_entries, check); | |
710 | |
711 break; | |
712 | |
713 case GAIM_PREF_INT: | |
714 if (account == NULL || | |
715 strcmp(gaim_account_get_protocol_id(account), | |
716 dialog->protocol_id)) | |
717 { | |
718 int_value = gaim_account_option_get_default_int(option); | |
719 } | |
720 else | |
721 { | |
722 int_value = gaim_account_get_int(account, | |
723 gaim_account_option_get_setting(option), | |
724 gaim_account_option_get_default_int(option)); | |
725 } | |
726 | |
727 g_snprintf(buf, sizeof(buf), "%d", int_value); | |
728 | |
729 entry = gtk_entry_new(); | |
730 gtk_entry_set_text(GTK_ENTRY(entry), buf); | |
731 | |
732 title = g_strdup_printf("%s:", | |
733 gaim_account_option_get_text(option)); | |
734 | |
735 add_pref_box(dialog, vbox, title, entry); | |
736 | |
737 g_free(title); | |
738 | |
739 dialog->protocol_opt_entries = | |
740 g_list_append(dialog->protocol_opt_entries, entry); | |
741 | |
742 break; | |
743 | |
744 case GAIM_PREF_STRING: | |
745 if (account == NULL || | |
746 strcmp(gaim_account_get_protocol_id(account), | |
747 dialog->protocol_id)) | |
748 { | |
749 str_value = gaim_account_option_get_default_string(option); | |
750 } | |
751 else | |
752 { | |
753 str_value = gaim_account_get_string(account, | |
754 gaim_account_option_get_setting(option), | |
755 gaim_account_option_get_default_string(option)); | |
756 } | |
757 | |
758 entry = gtk_entry_new(); | |
759 if (gaim_account_option_get_masked(option)) | |
760 { | |
761 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); | |
762 gtk_entry_set_invisible_char(GTK_ENTRY(entry), GAIM_INVISIBLE_CHAR); | |
763 } | |
764 | |
765 if (str_value != NULL) | |
766 gtk_entry_set_text(GTK_ENTRY(entry), str_value); | |
767 | |
768 title = g_strdup_printf("%s:", | |
769 gaim_account_option_get_text(option)); | |
770 | |
771 add_pref_box(dialog, vbox, title, entry); | |
772 | |
773 g_free(title); | |
774 | |
775 dialog->protocol_opt_entries = | |
776 g_list_append(dialog->protocol_opt_entries, entry); | |
777 | |
778 break; | |
779 | |
780 case GAIM_PREF_STRING_LIST: | |
781 i = 0; | |
782 idx = 0; | |
783 | |
784 if (account == NULL || | |
785 strcmp(gaim_account_get_protocol_id(account), | |
786 dialog->protocol_id)) | |
787 { | |
788 str_value = gaim_account_option_get_default_list_value(option); | |
789 } | |
790 else | |
791 { | |
792 str_value = gaim_account_get_string(account, | |
793 gaim_account_option_get_setting(option), | |
794 gaim_account_option_get_default_list_value(option)); | |
795 } | |
796 | |
797 list = gaim_account_option_get_list(option); | |
798 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER); | |
799 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model)); | |
800 | |
801 /* Loop through list of GaimKeyValuePair items */ | |
802 for (node = list; node != NULL; node = node->next) { | |
803 if (node->data != NULL) { | |
804 kvp = (GaimKeyValuePair *) node->data; | |
805 if ((kvp->value != NULL) && (str_value != NULL) && | |
806 !g_utf8_collate(kvp->value, str_value)) | |
807 idx = i; | |
808 | |
809 gtk_list_store_append(model, &iter); | |
810 gtk_list_store_set(model, &iter, | |
811 0, kvp->key, | |
812 1, kvp->value, | |
813 -1); | |
814 } | |
815 | |
816 i++; | |
817 } | |
818 | |
819 /* Set default */ | |
820 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), idx); | |
821 | |
822 /* Define renderer */ | |
823 renderer = gtk_cell_renderer_text_new(); | |
824 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, | |
825 TRUE); | |
826 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), | |
827 renderer, "text", 0, NULL); | |
828 | |
829 title = g_strdup_printf("%s:", | |
830 gaim_account_option_get_text(option)); | |
831 | |
832 add_pref_box(dialog, vbox, title, combo); | |
833 | |
834 g_free(title); | |
835 | |
836 dialog->protocol_opt_entries = | |
837 g_list_append(dialog->protocol_opt_entries, combo); | |
838 | |
839 break; | |
840 | |
841 | |
842 default: | |
843 break; | |
844 } | |
845 } | |
846 } | |
847 | |
848 static GtkWidget * | |
849 make_proxy_dropdown(void) | |
850 { | |
851 GtkWidget *dropdown; | |
852 GtkListStore *model; | |
853 GtkTreeIter iter; | |
854 GtkCellRenderer *renderer; | |
855 | |
856 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); | |
857 dropdown = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model)); | |
858 | |
859 gtk_list_store_append(model, &iter); | |
860 gtk_list_store_set(model, &iter, | |
861 0, _("Use Global Proxy Settings"), | |
862 1, GAIM_PROXY_USE_GLOBAL, | |
863 -1); | |
864 | |
865 gtk_list_store_append(model, &iter); | |
866 gtk_list_store_set(model, &iter, | |
867 0, _("No Proxy"), | |
868 1, GAIM_PROXY_NONE, | |
869 -1); | |
870 | |
871 gtk_list_store_append(model, &iter); | |
872 gtk_list_store_set(model, &iter, | |
873 0, _("HTTP"), | |
874 1, GAIM_PROXY_HTTP, | |
875 -1); | |
876 | |
877 gtk_list_store_append(model, &iter); | |
878 gtk_list_store_set(model, &iter, | |
879 0, _("SOCKS 4"), | |
880 1, GAIM_PROXY_SOCKS4, | |
881 -1); | |
882 | |
883 gtk_list_store_append(model, &iter); | |
884 gtk_list_store_set(model, &iter, | |
885 0, _("SOCKS 5"), | |
886 1, GAIM_PROXY_SOCKS5, | |
887 -1); | |
888 | |
889 gtk_list_store_append(model, &iter); | |
890 gtk_list_store_set(model, &iter, | |
891 0, _("Use Environmental Settings"), | |
892 1, GAIM_PROXY_USE_ENVVAR, | |
893 -1); | |
894 | |
895 renderer = gtk_cell_renderer_text_new(); | |
896 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dropdown), renderer, TRUE); | |
897 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dropdown), renderer, | |
898 "text", 0, NULL); | |
899 | |
900 return dropdown; | |
901 } | |
902 | |
903 static void | |
904 proxy_type_changed_cb(GtkWidget *menu, AccountPrefsDialog *dialog) | |
905 { | |
906 dialog->new_proxy_type = | |
907 gtk_combo_box_get_active(GTK_COMBO_BOX(menu)) - 1; | |
908 | |
909 if (dialog->new_proxy_type == GAIM_PROXY_USE_GLOBAL || | |
910 dialog->new_proxy_type == GAIM_PROXY_NONE || | |
911 dialog->new_proxy_type == GAIM_PROXY_USE_ENVVAR) { | |
912 | |
913 gtk_widget_hide_all(dialog->proxy_vbox); | |
914 } | |
915 else | |
916 gtk_widget_show_all(dialog->proxy_vbox); | |
917 } | |
918 | |
919 static void | |
920 port_popup_cb(GtkWidget *w, GtkMenu *menu, gpointer data) | |
921 { | |
922 GtkWidget *item1; | |
923 GtkWidget *item2; | |
924 | |
925 /* This is an easter egg. | |
926 It means one of two things, both intended as humourus: | |
927 A) your network is really slow and you have nothing better to do than | |
928 look at butterflies. | |
929 B)You are looking really closely at something that shouldn't matter. */ | |
930 item1 = gtk_menu_item_new_with_label(_("If you look real closely")); | |
931 | |
932 /* This is an easter egg. See the comment on the previous line in the source. */ | |
933 item2 = gtk_menu_item_new_with_label(_("you can see the butterflies mating")); | |
934 | |
935 gtk_widget_show(item1); | |
936 gtk_widget_show(item2); | |
937 | |
938 /* Prepend these in reverse order so they appear correctly. */ | |
939 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item2); | |
940 gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), item1); | |
941 } | |
942 | |
943 static void | |
944 add_proxy_options(AccountPrefsDialog *dialog, GtkWidget *parent) | |
945 { | |
946 GaimProxyInfo *proxy_info; | |
947 GtkWidget *frame; | |
948 GtkWidget *vbox; | |
949 GtkWidget *vbox2; | |
950 | |
951 if (dialog->proxy_frame != NULL) | |
952 gtk_widget_destroy(dialog->proxy_frame); | |
953 | |
954 frame = gaim_gtk_make_frame(parent, _("Proxy Options")); | |
955 dialog->proxy_frame = gtk_widget_get_parent(gtk_widget_get_parent(frame)); | |
956 | |
957 gtk_box_reorder_child(GTK_BOX(parent), dialog->proxy_frame, 1); | |
958 gtk_widget_show(dialog->proxy_frame); | |
959 | |
960 /* Main vbox */ | |
961 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
962 gtk_container_add(GTK_CONTAINER(frame), vbox); | |
963 gtk_widget_show(vbox); | |
964 | |
965 /* Proxy Type drop-down. */ | |
966 dialog->proxy_dropdown = make_proxy_dropdown(); | |
967 | |
968 add_pref_box(dialog, vbox, _("Proxy _type:"), dialog->proxy_dropdown); | |
969 | |
970 /* Setup the second vbox, which may be hidden at times. */ | |
971 dialog->proxy_vbox = vbox2 = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
972 gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, FALSE, GAIM_HIG_BORDER); | |
973 gtk_widget_show(vbox2); | |
974 | |
975 /* Host */ | |
976 dialog->proxy_host_entry = gtk_entry_new(); | |
977 add_pref_box(dialog, vbox2, _("_Host:"), dialog->proxy_host_entry); | |
978 | |
979 /* Port */ | |
980 dialog->proxy_port_entry = gtk_entry_new(); | |
981 add_pref_box(dialog, vbox2, _("_Port:"), dialog->proxy_port_entry); | |
982 | |
983 g_signal_connect(G_OBJECT(dialog->proxy_port_entry), "populate-popup", | |
984 G_CALLBACK(port_popup_cb), NULL); | |
985 | |
986 /* User */ | |
987 dialog->proxy_user_entry = gtk_entry_new(); | |
988 | |
989 add_pref_box(dialog, vbox2, _("_Username:"), dialog->proxy_user_entry); | |
990 | |
991 /* Password */ | |
992 dialog->proxy_pass_entry = gtk_entry_new(); | |
993 gtk_entry_set_visibility(GTK_ENTRY(dialog->proxy_pass_entry), FALSE); | |
994 gtk_entry_set_invisible_char(GTK_ENTRY(dialog->proxy_pass_entry), GAIM_INVISIBLE_CHAR); | |
995 add_pref_box(dialog, vbox2, _("Pa_ssword:"), dialog->proxy_pass_entry); | |
996 | |
997 if (dialog->account != NULL && | |
998 (proxy_info = gaim_account_get_proxy_info(dialog->account)) != NULL) { | |
999 | |
1000 GaimProxyType type = gaim_proxy_info_get_type(proxy_info); | |
1001 | |
1002 /* Hah! */ | |
1003 /* I dunno what you're laughing about, fuzz ball. */ | |
1004 dialog->new_proxy_type = type; | |
1005 gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->proxy_dropdown), | |
1006 type + 1); | |
1007 | |
1008 if (type == GAIM_PROXY_USE_GLOBAL || type == GAIM_PROXY_NONE || | |
1009 type == GAIM_PROXY_USE_ENVVAR) { | |
1010 gtk_widget_hide_all(vbox2); | |
1011 } | |
1012 else { | |
1013 const char *value; | |
1014 int int_val; | |
1015 | |
1016 if ((value = gaim_proxy_info_get_host(proxy_info)) != NULL) | |
1017 gtk_entry_set_text(GTK_ENTRY(dialog->proxy_host_entry), value); | |
1018 | |
1019 if ((int_val = gaim_proxy_info_get_port(proxy_info)) != 0) { | |
1020 char buf[32]; | |
1021 | |
1022 g_snprintf(buf, sizeof(buf), "%d", int_val); | |
1023 | |
1024 gtk_entry_set_text(GTK_ENTRY(dialog->proxy_port_entry), buf); | |
1025 } | |
1026 | |
1027 if ((value = gaim_proxy_info_get_username(proxy_info)) != NULL) | |
1028 gtk_entry_set_text(GTK_ENTRY(dialog->proxy_user_entry), value); | |
1029 | |
1030 if ((value = gaim_proxy_info_get_password(proxy_info)) != NULL) | |
1031 gtk_entry_set_text(GTK_ENTRY(dialog->proxy_pass_entry), value); | |
1032 } | |
1033 } | |
1034 else { | |
1035 dialog->new_proxy_type = GAIM_PROXY_USE_GLOBAL; | |
1036 gtk_combo_box_set_active(GTK_COMBO_BOX(dialog->proxy_dropdown), | |
1037 dialog->new_proxy_type + 1); | |
1038 gtk_widget_hide_all(vbox2); | |
1039 } | |
1040 | |
1041 /* Connect signals. */ | |
1042 g_signal_connect(G_OBJECT(dialog->proxy_dropdown), "changed", | |
1043 G_CALLBACK(proxy_type_changed_cb), dialog); | |
1044 } | |
1045 | |
1046 static void | |
1047 account_win_destroy_cb(GtkWidget *w, GdkEvent *event, | |
1048 AccountPrefsDialog *dialog) | |
1049 { | |
1050 g_hash_table_remove(account_pref_wins, dialog->account); | |
1051 | |
1052 gtk_widget_destroy(dialog->window); | |
1053 | |
1054 g_list_free(dialog->user_split_entries); | |
1055 g_list_free(dialog->protocol_opt_entries); | |
1056 g_free(dialog->protocol_id); | |
1057 | |
1058 if (dialog->icon_path != NULL) | |
1059 { | |
1060 const char *icon = gaim_account_get_ui_string(dialog->account, GAIM_GTK_UI, "non-global-buddyicon", NULL); | |
1061 if (dialog->icon_path != NULL && (icon == NULL || strcmp(dialog->icon_path, icon))) | |
1062 { | |
1063 /* The user set an icon, which would've been cached by convert_buddy_icon, | |
1064 * but didn't save the changes. Delete the cache file. */ | |
1065 char *filename = g_build_filename(gaim_buddy_icons_get_cache_dir(), dialog->icon_path, NULL); | |
1066 printf("Deleting\n"); | |
1067 g_unlink(filename); | |
1068 g_free(filename); | |
1069 } | |
1070 | |
1071 g_free(dialog->icon_path); | |
1072 } | |
1073 | |
1074 if (dialog->icon_filesel) | |
1075 gtk_widget_destroy(dialog->icon_filesel); | |
1076 | |
1077 gaim_signals_disconnect_by_handle(dialog); | |
1078 | |
1079 g_free(dialog); | |
1080 } | |
1081 | |
1082 static void | |
1083 cancel_account_prefs_cb(GtkWidget *w, AccountPrefsDialog *dialog) | |
1084 { | |
1085 account_win_destroy_cb(NULL, NULL, dialog); | |
1086 } | |
1087 | |
1088 static GaimAccount* | |
1089 ok_account_prefs_cb(GtkWidget *w, AccountPrefsDialog *dialog) | |
1090 { | |
1091 GaimProxyInfo *proxy_info = NULL; | |
1092 GList *l, *l2; | |
1093 const char *value; | |
1094 char *username; | |
1095 char *tmp; | |
1096 gboolean new = FALSE, icon_change = FALSE; | |
1097 GaimAccount *account; | |
1098 | |
1099 if (dialog->account == NULL) | |
1100 { | |
1101 const char *screenname; | |
1102 | |
1103 screenname = gtk_entry_get_text(GTK_ENTRY(dialog->screenname_entry)); | |
1104 account = gaim_account_new(screenname, dialog->protocol_id); | |
1105 new = TRUE; | |
1106 } | |
1107 else | |
1108 { | |
1109 account = dialog->account; | |
1110 | |
1111 /* Protocol */ | |
1112 gaim_account_set_protocol_id(account, dialog->protocol_id); | |
1113 } | |
1114 | |
1115 /* Alias */ | |
1116 value = gtk_entry_get_text(GTK_ENTRY(dialog->alias_entry)); | |
1117 | |
1118 if (*value != '\0') | |
1119 gaim_account_set_alias(account, value); | |
1120 else | |
1121 gaim_account_set_alias(account, NULL); | |
1122 | |
1123 /* Buddy Icon */ | |
1124 if (new || gaim_account_get_ui_bool(account, GAIM_GTK_UI, "use-global-buddyicon", TRUE) == | |
1125 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check))) { | |
1126 icon_change = TRUE; | |
1127 } | |
1128 gaim_account_set_ui_bool(account, GAIM_GTK_UI, "use-global-buddyicon", !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check))); | |
1129 gaim_account_set_ui_string(account, GAIM_GTK_UI, "non-global-buddyicon", dialog->icon_path); | |
1130 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->icon_check))) { | |
1131 gaim_account_set_buddy_icon(account, dialog->icon_path); | |
1132 } else if (gaim_prefs_get_string("/gaim/gtk/accounts/buddyicon") && icon_change) { | |
1133 char *icon = gaim_gtk_convert_buddy_icon(dialog->plugin, gaim_prefs_get_string("/gaim/gtk/accounts/buddyicon")); | |
1134 gaim_account_set_buddy_icon(account, icon); | |
1135 g_free(icon); | |
1136 } | |
1137 | |
1138 | |
1139 /* Remember Password */ | |
1140 gaim_account_set_remember_password(account, | |
1141 gtk_toggle_button_get_active( | |
1142 GTK_TOGGLE_BUTTON(dialog->remember_pass_check))); | |
1143 | |
1144 /* Check Mail */ | |
1145 if (dialog->prpl_info && dialog->prpl_info->options & OPT_PROTO_MAIL_CHECK) | |
1146 gaim_account_set_check_mail(account, | |
1147 gtk_toggle_button_get_active( | |
1148 GTK_TOGGLE_BUTTON(dialog->new_mail_check))); | |
1149 | |
1150 /* Password */ | |
1151 value = gtk_entry_get_text(GTK_ENTRY(dialog->password_entry)); | |
1152 | |
1153 /* | |
1154 * We set the password if this is a new account because new accounts | |
1155 * will be set to online, and if the user has entered a password into | |
1156 * the account editor (but has not checked the 'save' box), then we | |
1157 * don't want to prompt them. | |
1158 */ | |
1159 if ((gaim_account_get_remember_password(account) || new) && (*value != '\0')) | |
1160 gaim_account_set_password(account, value); | |
1161 else | |
1162 gaim_account_set_password(account, NULL); | |
1163 | |
1164 /* Build the username string. */ | |
1165 username = | |
1166 g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog->screenname_entry))); | |
1167 | |
1168 if (dialog->prpl_info != NULL) | |
1169 { | |
1170 for (l = dialog->prpl_info->user_splits, | |
1171 l2 = dialog->user_split_entries; | |
1172 l != NULL && l2 != NULL; | |
1173 l = l->next, l2 = l2->next) | |
1174 { | |
1175 GaimAccountUserSplit *split = l->data; | |
1176 GtkEntry *entry = l2->data; | |
1177 char sep[2] = " "; | |
1178 | |
1179 value = gtk_entry_get_text(entry); | |
1180 | |
1181 *sep = gaim_account_user_split_get_separator(split); | |
1182 | |
1183 tmp = g_strconcat(username, sep, | |
1184 (*value ? value : | |
1185 gaim_account_user_split_get_default_value(split)), | |
1186 NULL); | |
1187 | |
1188 g_free(username); | |
1189 username = tmp; | |
1190 } | |
1191 } | |
1192 | |
1193 gaim_account_set_username(account, username); | |
1194 g_free(username); | |
1195 | |
1196 /* Add the protocol settings */ | |
1197 if (dialog->prpl_info) { | |
1198 for (l = dialog->prpl_info->protocol_options, | |
1199 l2 = dialog->protocol_opt_entries; | |
1200 l != NULL && l2 != NULL; | |
1201 l = l->next, l2 = l2->next) { | |
1202 | |
1203 GaimPrefType type; | |
1204 GaimAccountOption *option = l->data; | |
1205 GtkWidget *widget = l2->data; | |
1206 GtkTreeIter iter; | |
1207 const char *setting; | |
1208 char *value2; | |
1209 int int_value; | |
1210 gboolean bool_value; | |
1211 | |
1212 type = gaim_account_option_get_type(option); | |
1213 | |
1214 setting = gaim_account_option_get_setting(option); | |
1215 | |
1216 switch (type) { | |
1217 case GAIM_PREF_STRING: | |
1218 value = gtk_entry_get_text(GTK_ENTRY(widget)); | |
1219 gaim_account_set_string(account, setting, value); | |
1220 break; | |
1221 | |
1222 case GAIM_PREF_INT: | |
1223 int_value = atoi(gtk_entry_get_text(GTK_ENTRY(widget))); | |
1224 gaim_account_set_int(account, setting, int_value); | |
1225 break; | |
1226 | |
1227 case GAIM_PREF_BOOLEAN: | |
1228 bool_value = | |
1229 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | |
1230 gaim_account_set_bool(account, setting, bool_value); | |
1231 break; | |
1232 | |
1233 case GAIM_PREF_STRING_LIST: | |
1234 gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter); | |
1235 gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(widget)), &iter, 1, &value2, -1); | |
1236 gaim_account_set_string(account, setting, value2); | |
1237 g_free(value2); | |
1238 break; | |
1239 | |
1240 default: | |
1241 break; | |
1242 } | |
1243 } | |
1244 } | |
1245 | |
1246 /* Set the proxy stuff. */ | |
1247 if (dialog->new_proxy_type == GAIM_PROXY_USE_GLOBAL) { | |
1248 gaim_account_set_proxy_info(account, NULL); | |
1249 } | |
1250 else { | |
1251 proxy_info = gaim_account_get_proxy_info(account); | |
1252 | |
1253 /* Create the proxy info if it doesn't exist. */ | |
1254 if (proxy_info == NULL) { | |
1255 proxy_info = gaim_proxy_info_new(); | |
1256 gaim_account_set_proxy_info(account, proxy_info); | |
1257 } | |
1258 | |
1259 /* Set the proxy info type. */ | |
1260 gaim_proxy_info_set_type(proxy_info, dialog->new_proxy_type); | |
1261 | |
1262 /* Host */ | |
1263 value = gtk_entry_get_text(GTK_ENTRY(dialog->proxy_host_entry)); | |
1264 | |
1265 if (*value != '\0') | |
1266 gaim_proxy_info_set_host(proxy_info, value); | |
1267 else | |
1268 gaim_proxy_info_set_host(proxy_info, NULL); | |
1269 | |
1270 /* Port */ | |
1271 value = gtk_entry_get_text(GTK_ENTRY(dialog->proxy_port_entry)); | |
1272 | |
1273 if (*value != '\0') | |
1274 gaim_proxy_info_set_port(proxy_info, atoi(value)); | |
1275 else | |
1276 gaim_proxy_info_set_port(proxy_info, 0); | |
1277 | |
1278 /* Username */ | |
1279 value = gtk_entry_get_text(GTK_ENTRY(dialog->proxy_user_entry)); | |
1280 | |
1281 if (*value != '\0') | |
1282 gaim_proxy_info_set_username(proxy_info, value); | |
1283 else | |
1284 gaim_proxy_info_set_username(proxy_info, NULL); | |
1285 | |
1286 /* Password */ | |
1287 value = gtk_entry_get_text(GTK_ENTRY(dialog->proxy_pass_entry)); | |
1288 | |
1289 if (*value != '\0') | |
1290 gaim_proxy_info_set_password(proxy_info, value); | |
1291 else | |
1292 gaim_proxy_info_set_password(proxy_info, NULL); | |
1293 } | |
1294 | |
1295 /* We no longer need the data from the dialog window */ | |
1296 account_win_destroy_cb(NULL, NULL, dialog); | |
1297 | |
1298 /* If this is a new account, add it to our list */ | |
1299 if (new) | |
1300 gaim_accounts_add(account); | |
1301 else | |
1302 gaim_signal_emit(gaim_gtk_account_get_handle(), "account-modified", account); | |
1303 | |
1304 /* If this is a new account, then sign on! */ | |
1305 if (new) { | |
1306 const GaimSavedStatus *saved_status; | |
1307 | |
1308 saved_status = gaim_savedstatus_get_current(); | |
1309 if (saved_status != NULL) { | |
1310 gaim_savedstatus_activate_for_account(saved_status, account); | |
1311 gaim_account_set_enabled(account, GAIM_GTK_UI, TRUE); | |
1312 } | |
1313 } | |
1314 | |
1315 return account; | |
1316 } | |
1317 | |
1318 static void | |
1319 register_account_prefs_cb(GtkWidget *w, AccountPrefsDialog *dialog) | |
1320 { | |
1321 GaimAccount *account = ok_account_prefs_cb(NULL, dialog); | |
1322 | |
1323 gaim_account_register(account); | |
1324 } | |
1325 | |
1326 | |
1327 static const GtkTargetEntry dnd_targets[] = { | |
1328 {"text/plain", 0, 0}, | |
1329 {"text/uri-list", 0, 1}, | |
1330 {"STRING", 0, 2} | |
1331 }; | |
1332 | |
1333 void | |
1334 gaim_gtk_account_dialog_show(GaimGtkAccountDialogType type, | |
1335 GaimAccount *account) | |
1336 { | |
1337 AccountPrefsDialog *dialog; | |
1338 GtkWidget *win; | |
1339 GtkWidget *main_vbox; | |
1340 GtkWidget *vbox; | |
1341 GtkWidget *bbox; | |
1342 GtkWidget *dbox; | |
1343 GtkWidget *notebook; | |
1344 GtkWidget *button; | |
1345 | |
1346 if (accounts_window != NULL && account != NULL && | |
1347 (dialog = g_hash_table_lookup(account_pref_wins, account)) != NULL) | |
1348 { | |
1349 gtk_window_present(GTK_WINDOW(dialog->window)); | |
1350 return; | |
1351 } | |
1352 | |
1353 dialog = g_new0(AccountPrefsDialog, 1); | |
1354 | |
1355 if (accounts_window != NULL && account != NULL) | |
1356 { | |
1357 g_hash_table_insert(account_pref_wins, account, dialog); | |
1358 } | |
1359 | |
1360 dialog->account = account; | |
1361 dialog->type = type; | |
1362 dialog->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
1363 | |
1364 if (dialog->account == NULL) { | |
1365 /* Select the first prpl in the list*/ | |
1366 GList *prpl_list = gaim_plugins_get_protocols(); | |
1367 if (prpl_list != NULL) | |
1368 dialog->protocol_id = g_strdup(((GaimPlugin *) prpl_list->data)->info->id); | |
1369 } | |
1370 else | |
1371 { | |
1372 dialog->protocol_id = | |
1373 g_strdup(gaim_account_get_protocol_id(dialog->account)); | |
1374 } | |
1375 | |
1376 if ((dialog->plugin = gaim_find_prpl(dialog->protocol_id)) != NULL) | |
1377 dialog->prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(dialog->plugin); | |
1378 | |
1379 | |
1380 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
1381 gtk_window_set_role(GTK_WINDOW(win), "account"); | |
1382 | |
1383 if (type == GAIM_GTK_ADD_ACCOUNT_DIALOG) | |
1384 gtk_window_set_title(GTK_WINDOW(win), _("Add Account")); | |
1385 else | |
1386 gtk_window_set_title(GTK_WINDOW(win), _("Modify Account")); | |
1387 | |
1388 gtk_window_set_resizable(GTK_WINDOW(win), FALSE); | |
1389 | |
1390 gtk_container_set_border_width(GTK_CONTAINER(win), GAIM_HIG_BORDER); | |
1391 | |
1392 g_signal_connect(G_OBJECT(win), "delete_event", | |
1393 G_CALLBACK(account_win_destroy_cb), dialog); | |
1394 | |
1395 /* Setup the vbox */ | |
1396 main_vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
1397 gtk_container_add(GTK_CONTAINER(win), main_vbox); | |
1398 gtk_widget_show(main_vbox); | |
1399 | |
1400 notebook = gtk_notebook_new(); | |
1401 gtk_box_pack_start(GTK_BOX(main_vbox), notebook, FALSE, FALSE, 0); | |
1402 gtk_widget_show(GTK_WIDGET(notebook)); | |
1403 | |
1404 /* Setup the inner vbox */ | |
1405 dialog->top_vbox = vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
1406 gtk_container_set_border_width(GTK_CONTAINER(vbox), GAIM_HIG_BORDER); | |
1407 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, | |
1408 gtk_label_new_with_mnemonic(_("_Basic"))); | |
1409 gtk_widget_show(vbox); | |
1410 | |
1411 /* Setup the top frames. */ | |
1412 add_login_options(dialog, vbox); | |
1413 add_user_options(dialog, vbox); | |
1414 | |
1415 /* Setup the page with 'Advanced'. */ | |
1416 dialog->bottom_vbox = dbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
1417 gtk_container_set_border_width(GTK_CONTAINER(dbox), GAIM_HIG_BORDER); | |
1418 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dbox, | |
1419 gtk_label_new_with_mnemonic(_("_Advanced"))); | |
1420 gtk_widget_show(dbox); | |
1421 | |
1422 /** Setup the bottom frames. */ | |
1423 add_protocol_options(dialog, dbox); | |
1424 add_proxy_options(dialog, dbox); | |
1425 | |
1426 /* Setup the button box */ | |
1427 bbox = gtk_hbutton_box_new(); | |
1428 gtk_box_set_spacing(GTK_BOX(bbox), GAIM_HIG_BOX_SPACE); | |
1429 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
1430 gtk_box_pack_end(GTK_BOX(main_vbox), bbox, FALSE, TRUE, 0); | |
1431 gtk_widget_show(bbox); | |
1432 | |
1433 /* Register button */ | |
1434 button = gtk_button_new_with_label(_("Register")); | |
1435 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1436 gtk_widget_show(button); | |
1437 | |
1438 g_signal_connect(G_OBJECT(button), "clicked", | |
1439 G_CALLBACK(register_account_prefs_cb), dialog); | |
1440 | |
1441 dialog->register_button = button; | |
1442 | |
1443 if (dialog->account == NULL) | |
1444 gtk_widget_set_sensitive(button, FALSE); | |
1445 | |
1446 if (!dialog->prpl_info || !dialog->prpl_info->register_user) | |
1447 gtk_widget_hide(button); | |
1448 | |
1449 /* Cancel button */ | |
1450 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); | |
1451 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1452 gtk_widget_show(button); | |
1453 | |
1454 g_signal_connect(G_OBJECT(button), "clicked", | |
1455 G_CALLBACK(cancel_account_prefs_cb), dialog); | |
1456 | |
1457 /* Save button */ | |
1458 button = gtk_button_new_from_stock(GTK_STOCK_SAVE); | |
1459 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1460 | |
1461 if (dialog->account == NULL) | |
1462 gtk_widget_set_sensitive(button, FALSE); | |
1463 | |
1464 gtk_widget_show(button); | |
1465 | |
1466 dialog->ok_button = button; | |
1467 | |
1468 /* Set up DND */ | |
1469 gtk_drag_dest_set(dialog->window, | |
1470 GTK_DEST_DEFAULT_MOTION | | |
1471 GTK_DEST_DEFAULT_DROP, | |
1472 dnd_targets, | |
1473 sizeof(dnd_targets) / sizeof(GtkTargetEntry), | |
1474 GDK_ACTION_COPY); | |
1475 | |
1476 g_signal_connect(G_OBJECT(dialog->window), "drag_data_received", | |
1477 G_CALLBACK(account_dnd_recv), dialog); | |
1478 | |
1479 g_signal_connect(G_OBJECT(button), "clicked", | |
1480 G_CALLBACK(ok_account_prefs_cb), dialog); | |
1481 | |
1482 /* Show the window. */ | |
1483 gtk_widget_show(win); | |
1484 } | |
1485 | |
1486 /************************************************************************** | |
1487 * Accounts Dialog | |
1488 **************************************************************************/ | |
1489 static void | |
1490 signed_on_off_cb(GaimConnection *gc, gpointer user_data) | |
1491 { | |
1492 GaimAccount *account; | |
1493 GaimGtkPulseData *pulse_data; | |
1494 GtkTreeModel *model; | |
1495 GtkTreeIter iter; | |
1496 GdkPixbuf *pixbuf; | |
1497 size_t index; | |
1498 | |
1499 /* Don't need to do anything if the accounts window is not visible */ | |
1500 if (accounts_window == NULL) | |
1501 return; | |
1502 | |
1503 account = gaim_connection_get_account(gc); | |
1504 model = GTK_TREE_MODEL(accounts_window->model); | |
1505 index = g_list_index(gaim_accounts_get_all(), account); | |
1506 | |
1507 if (gtk_tree_model_iter_nth_child(model, &iter, NULL, index)) | |
1508 { | |
1509 gtk_tree_model_get(GTK_TREE_MODEL(accounts_window->model), &iter, | |
1510 COLUMN_PULSE_DATA, &pulse_data, -1); | |
1511 | |
1512 if (pulse_data != NULL) | |
1513 { | |
1514 if (pulse_data->timeout > 0) | |
1515 g_source_remove(pulse_data->timeout); | |
1516 | |
1517 g_object_unref(G_OBJECT(pulse_data->online_pixbuf)); | |
1518 | |
1519 g_free(pulse_data); | |
1520 } | |
1521 | |
1522 pixbuf = gaim_gtk_create_prpl_icon(account, 0.5); | |
1523 if ((pixbuf != NULL) && gaim_account_is_disconnected(account)) | |
1524 gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE); | |
1525 | |
1526 gtk_list_store_set(accounts_window->model, &iter, | |
1527 COLUMN_ICON, pixbuf, | |
1528 COLUMN_PULSE_DATA, NULL, | |
1529 -1); | |
1530 | |
1531 | |
1532 if (pixbuf != NULL) | |
1533 g_object_unref(G_OBJECT(pixbuf)); | |
1534 } | |
1535 } | |
1536 | |
1537 /* | |
1538 * Get the GtkTreeIter of the specified account in the | |
1539 * GtkListStore | |
1540 */ | |
1541 static gboolean | |
1542 accounts_window_find_account_in_treemodel(GtkTreeIter *iter, GaimAccount *account) | |
1543 { | |
1544 GtkTreeModel *model; | |
1545 GaimAccount *cur; | |
1546 | |
1547 g_return_val_if_fail(account != NULL, FALSE); | |
1548 g_return_val_if_fail(accounts_window != NULL, FALSE); | |
1549 | |
1550 model = GTK_TREE_MODEL(accounts_window->model); | |
1551 | |
1552 if (!gtk_tree_model_get_iter_first(model, iter)) | |
1553 return FALSE; | |
1554 | |
1555 gtk_tree_model_get(model, iter, COLUMN_DATA, &cur, -1); | |
1556 if (cur == account) | |
1557 return TRUE; | |
1558 | |
1559 while (gtk_tree_model_iter_next(model, iter)) | |
1560 { | |
1561 gtk_tree_model_get(model, iter, COLUMN_DATA, &cur, -1); | |
1562 if (cur == account) | |
1563 return TRUE; | |
1564 } | |
1565 | |
1566 return FALSE; | |
1567 } | |
1568 | |
1569 static void | |
1570 account_removed_cb(GaimAccount *account, gpointer user_data) | |
1571 { | |
1572 AccountPrefsDialog *dialog; | |
1573 GtkTreeIter iter; | |
1574 | |
1575 /* If the account was being modified, close the edit window */ | |
1576 if ((dialog = g_hash_table_lookup(account_pref_wins, account)) != NULL) | |
1577 account_win_destroy_cb(NULL, NULL, dialog); | |
1578 | |
1579 if (accounts_window == NULL) | |
1580 return; | |
1581 | |
1582 /* Remove the account from the GtkListStore */ | |
1583 if (accounts_window_find_account_in_treemodel(&iter, account)) | |
1584 gtk_list_store_remove(accounts_window->model, &iter); | |
1585 } | |
1586 | |
1587 static void | |
1588 account_abled_cb(GaimAccount *account, gpointer user_data) | |
1589 { | |
1590 GtkTreeIter iter; | |
1591 | |
1592 if (accounts_window == NULL) | |
1593 return; | |
1594 | |
1595 /* update the account in the GtkListStore */ | |
1596 if (accounts_window_find_account_in_treemodel(&iter, account)) | |
1597 gtk_list_store_set(accounts_window->model, &iter, | |
1598 COLUMN_ENABLED, GPOINTER_TO_INT(user_data), | |
1599 -1); | |
1600 } | |
1601 | |
1602 static void | |
1603 drag_data_get_cb(GtkWidget *widget, GdkDragContext *ctx, | |
1604 GtkSelectionData *data, guint info, guint time, | |
1605 AccountsWindow *dialog) | |
1606 { | |
1607 if (data->target == gdk_atom_intern("GAIM_ACCOUNT", FALSE)) { | |
1608 GtkTreeRowReference *ref; | |
1609 GtkTreePath *source_row; | |
1610 GtkTreeIter iter; | |
1611 GaimAccount *account = NULL; | |
1612 GValue val; | |
1613 | |
1614 ref = g_object_get_data(G_OBJECT(ctx), "gtk-tree-view-source-row"); | |
1615 source_row = gtk_tree_row_reference_get_path(ref); | |
1616 | |
1617 if (source_row == NULL) | |
1618 return; | |
1619 | |
1620 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, | |
1621 source_row); | |
1622 val.g_type = 0; | |
1623 gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter, | |
1624 COLUMN_DATA, &val); | |
1625 | |
1626 dialog->drag_iter = iter; | |
1627 | |
1628 account = g_value_get_pointer(&val); | |
1629 | |
1630 gtk_selection_data_set(data, gdk_atom_intern("GAIM_ACCOUNT", FALSE), | |
1631 8, (void *)&account, sizeof(account)); | |
1632 | |
1633 gtk_tree_path_free(source_row); | |
1634 } | |
1635 } | |
1636 | |
1637 static void | |
1638 move_account_after(GtkListStore *store, GtkTreeIter *iter, | |
1639 GtkTreeIter *position) | |
1640 { | |
1641 GtkTreeIter new_iter; | |
1642 GaimAccount *account; | |
1643 | |
1644 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, | |
1645 COLUMN_DATA, &account, | |
1646 -1); | |
1647 | |
1648 gtk_list_store_insert_after(store, &new_iter, position); | |
1649 | |
1650 set_account(store, &new_iter, account); | |
1651 | |
1652 gtk_list_store_remove(store, iter); | |
1653 } | |
1654 | |
1655 static void | |
1656 move_account_before(GtkListStore *store, GtkTreeIter *iter, | |
1657 GtkTreeIter *position) | |
1658 { | |
1659 GtkTreeIter new_iter; | |
1660 GaimAccount *account; | |
1661 | |
1662 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, | |
1663 COLUMN_DATA, &account, | |
1664 -1); | |
1665 | |
1666 gtk_list_store_insert_before(store, &new_iter, position); | |
1667 | |
1668 set_account(store, &new_iter, account); | |
1669 | |
1670 gtk_list_store_remove(store, iter); | |
1671 } | |
1672 | |
1673 static void | |
1674 drag_data_received_cb(GtkWidget *widget, GdkDragContext *ctx, | |
1675 guint x, guint y, GtkSelectionData *sd, | |
1676 guint info, guint t, AccountsWindow *dialog) | |
1677 { | |
1678 if (sd->target == gdk_atom_intern("GAIM_ACCOUNT", FALSE) && sd->data) { | |
1679 gint dest_index; | |
1680 GaimAccount *a = NULL; | |
1681 GtkTreePath *path = NULL; | |
1682 GtkTreeViewDropPosition position; | |
1683 | |
1684 memcpy(&a, sd->data, sizeof(a)); | |
1685 | |
1686 if (gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(widget), x, y, | |
1687 &path, &position)) { | |
1688 | |
1689 GtkTreeIter iter; | |
1690 GaimAccount *account; | |
1691 GValue val; | |
1692 | |
1693 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path); | |
1694 val.g_type = 0; | |
1695 gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter, | |
1696 COLUMN_DATA, &val); | |
1697 | |
1698 account = g_value_get_pointer(&val); | |
1699 | |
1700 switch (position) { | |
1701 case GTK_TREE_VIEW_DROP_AFTER: | |
1702 case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: | |
1703 move_account_after(dialog->model, &dialog->drag_iter, | |
1704 &iter); | |
1705 dest_index = g_list_index(gaim_accounts_get_all(), | |
1706 account) + 1; | |
1707 break; | |
1708 | |
1709 case GTK_TREE_VIEW_DROP_BEFORE: | |
1710 case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: | |
1711 dest_index = g_list_index(gaim_accounts_get_all(), | |
1712 account); | |
1713 | |
1714 move_account_before(dialog->model, &dialog->drag_iter, | |
1715 &iter); | |
1716 break; | |
1717 | |
1718 default: | |
1719 return; | |
1720 } | |
1721 | |
1722 gaim_accounts_reorder(a, dest_index); | |
1723 } | |
1724 } | |
1725 } | |
1726 | |
1727 static gint | |
1728 accedit_win_destroy_cb(GtkWidget *w, GdkEvent *event, AccountsWindow *dialog) | |
1729 { | |
1730 gaim_gtk_accounts_window_hide(); | |
1731 | |
1732 return 0; | |
1733 } | |
1734 | |
1735 static gboolean | |
1736 configure_cb(GtkWidget *w, GdkEventConfigure *event, AccountsWindow *dialog) | |
1737 { | |
1738 if (GTK_WIDGET_VISIBLE(w)) { | |
1739 int old_width = gaim_prefs_get_int("/gaim/gtk/accounts/dialog/width"); | |
1740 int col_width; | |
1741 int difference; | |
1742 | |
1743 gaim_prefs_set_int("/gaim/gtk/accounts/dialog/width", event->width); | |
1744 gaim_prefs_set_int("/gaim/gtk/accounts/dialog/height", event->height); | |
1745 | |
1746 col_width = gtk_tree_view_column_get_width(dialog->screenname_col); | |
1747 | |
1748 if (col_width == 0) | |
1749 return FALSE; | |
1750 | |
1751 difference = (MAX(old_width, event->width) - | |
1752 MIN(old_width, event->width)); | |
1753 | |
1754 if (difference == 0) | |
1755 return FALSE; | |
1756 | |
1757 if (old_width < event->width) | |
1758 gtk_tree_view_column_set_min_width(dialog->screenname_col, | |
1759 col_width + difference); | |
1760 else | |
1761 gtk_tree_view_column_set_max_width(dialog->screenname_col, | |
1762 col_width - difference); | |
1763 } | |
1764 | |
1765 return FALSE; | |
1766 } | |
1767 | |
1768 static void | |
1769 add_account_cb(GtkWidget *w, AccountsWindow *dialog) | |
1770 { | |
1771 gaim_gtk_account_dialog_show(GAIM_GTK_ADD_ACCOUNT_DIALOG, NULL); | |
1772 } | |
1773 | |
1774 static void | |
1775 modify_account_sel(GtkTreeModel *model, GtkTreePath *path, | |
1776 GtkTreeIter *iter, gpointer data) | |
1777 { | |
1778 GaimAccount *account; | |
1779 | |
1780 gtk_tree_model_get(model, iter, COLUMN_DATA, &account, -1); | |
1781 | |
1782 if (account != NULL) | |
1783 gaim_gtk_account_dialog_show(GAIM_GTK_MODIFY_ACCOUNT_DIALOG, account); | |
1784 } | |
1785 | |
1786 static void | |
1787 modify_account_cb(GtkWidget *w, AccountsWindow *dialog) | |
1788 { | |
1789 GtkTreeSelection *selection; | |
1790 | |
1791 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
1792 | |
1793 gtk_tree_selection_selected_foreach(selection, modify_account_sel, dialog); | |
1794 } | |
1795 | |
1796 static void | |
1797 delete_account_cb(GaimAccount *account) | |
1798 { | |
1799 gaim_accounts_delete(account); | |
1800 } | |
1801 | |
1802 static void | |
1803 ask_delete_account_sel(GtkTreeModel *model, GtkTreePath *path, | |
1804 GtkTreeIter *iter, gpointer data) | |
1805 { | |
1806 GaimAccount *account; | |
1807 | |
1808 gtk_tree_model_get(model, iter, COLUMN_DATA, &account, -1); | |
1809 | |
1810 if (account != NULL) { | |
1811 char *buf; | |
1812 | |
1813 buf = g_strdup_printf(_("Are you sure you want to delete %s?"), | |
1814 gaim_account_get_username(account)); | |
1815 | |
1816 gaim_request_close_with_handle(account); | |
1817 gaim_request_action(account, NULL, buf, NULL, 0, account, 2, | |
1818 _("Delete"), delete_account_cb, | |
1819 _("Cancel"), NULL); | |
1820 g_free(buf); | |
1821 } | |
1822 } | |
1823 | |
1824 static void | |
1825 ask_delete_account_cb(GtkWidget *w, AccountsWindow *dialog) | |
1826 { | |
1827 GtkTreeSelection *selection; | |
1828 | |
1829 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
1830 | |
1831 gtk_tree_selection_selected_foreach(selection, ask_delete_account_sel, | |
1832 dialog); | |
1833 } | |
1834 | |
1835 static void | |
1836 close_accounts_cb(GtkWidget *w, AccountsWindow *dialog) | |
1837 { | |
1838 gtk_widget_destroy(dialog->window); | |
1839 | |
1840 gaim_gtk_accounts_window_hide(); | |
1841 } | |
1842 | |
1843 | |
1844 static void | |
1845 enabled_cb(GtkCellRendererToggle *renderer, gchar *path_str, | |
1846 gpointer data) | |
1847 { | |
1848 AccountsWindow *dialog = (AccountsWindow *)data; | |
1849 GaimAccount *account; | |
1850 GtkTreeModel *model = GTK_TREE_MODEL(dialog->model); | |
1851 GtkTreeIter iter; | |
1852 gboolean enabled; | |
1853 const GaimSavedStatus *saved_status; | |
1854 | |
1855 gtk_tree_model_get_iter_from_string(model, &iter, path_str); | |
1856 gtk_tree_model_get(model, &iter, | |
1857 COLUMN_DATA, &account, | |
1858 COLUMN_ENABLED, &enabled, | |
1859 -1); | |
1860 | |
1861 /* | |
1862 * If we just enabled the account, then set the statuses | |
1863 * to the current status. | |
1864 */ | |
1865 if (!enabled) | |
1866 { | |
1867 saved_status = gaim_savedstatus_get_current(); | |
1868 gaim_savedstatus_activate_for_account(saved_status, account); | |
1869 } | |
1870 | |
1871 gaim_account_set_enabled(account, GAIM_GTK_UI, !enabled); | |
1872 } | |
1873 | |
1874 static void | |
1875 add_columns(GtkWidget *treeview, AccountsWindow *dialog) | |
1876 { | |
1877 GtkCellRenderer *renderer; | |
1878 GtkTreeViewColumn *column; | |
1879 | |
1880 /* Screen Name column */ | |
1881 column = gtk_tree_view_column_new(); | |
1882 gtk_tree_view_column_set_title(column, _("Screen Name")); | |
1883 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeview), column, -1); | |
1884 gtk_tree_view_column_set_resizable(column, TRUE); | |
1885 | |
1886 /* Icon */ | |
1887 renderer = gtk_cell_renderer_pixbuf_new(); | |
1888 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
1889 gtk_tree_view_column_add_attribute(column, renderer, | |
1890 "pixbuf", COLUMN_ICON); | |
1891 | |
1892 /* Screen Name */ | |
1893 renderer = gtk_cell_renderer_text_new(); | |
1894 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1895 gtk_tree_view_column_add_attribute(column, renderer, | |
1896 "text", COLUMN_SCREENNAME); | |
1897 dialog->screenname_col = column; | |
1898 | |
1899 /* Enabled */ | |
1900 renderer = gtk_cell_renderer_toggle_new(); | |
1901 | |
1902 g_signal_connect(G_OBJECT(renderer), "toggled", | |
1903 G_CALLBACK(enabled_cb), dialog); | |
1904 | |
1905 column = gtk_tree_view_column_new_with_attributes(_("Enabled"), | |
1906 renderer, "active", COLUMN_ENABLED, NULL); | |
1907 | |
1908 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeview), column, -1); | |
1909 gtk_tree_view_column_set_resizable(column, TRUE); | |
1910 | |
1911 /* Protocol name */ | |
1912 column = gtk_tree_view_column_new(); | |
1913 gtk_tree_view_column_set_title(column, _("Protocol")); | |
1914 gtk_tree_view_insert_column(GTK_TREE_VIEW(treeview), column, -1); | |
1915 gtk_tree_view_column_set_resizable(column, TRUE); | |
1916 | |
1917 renderer = gtk_cell_renderer_text_new(); | |
1918 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
1919 gtk_tree_view_column_add_attribute(column, renderer, | |
1920 "text", COLUMN_PROTOCOL); | |
1921 } | |
1922 | |
1923 static void | |
1924 set_account(GtkListStore *store, GtkTreeIter *iter, GaimAccount *account) | |
1925 { | |
1926 GdkPixbuf *pixbuf; | |
1927 | |
1928 pixbuf = gaim_gtk_create_prpl_icon(account, 0.5); | |
1929 if ((pixbuf != NULL) && gaim_account_is_disconnected(account)) | |
1930 gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE); | |
1931 | |
1932 gtk_list_store_set(store, iter, | |
1933 COLUMN_ICON, pixbuf, | |
1934 COLUMN_SCREENNAME, gaim_account_get_username(account), | |
1935 COLUMN_ENABLED, gaim_account_get_enabled(account, GAIM_GTK_UI), | |
1936 COLUMN_PROTOCOL, gaim_account_get_protocol_name(account), | |
1937 COLUMN_DATA, account, | |
1938 -1); | |
1939 | |
1940 if (pixbuf != NULL) | |
1941 g_object_unref(G_OBJECT(pixbuf)); | |
1942 } | |
1943 | |
1944 static void | |
1945 add_account_to_liststore(GaimAccount *account, gpointer user_data) | |
1946 { | |
1947 GtkTreeIter iter; | |
1948 | |
1949 if (accounts_window == NULL) | |
1950 return; | |
1951 | |
1952 gtk_list_store_append(accounts_window->model, &iter); | |
1953 | |
1954 set_account(accounts_window->model, &iter, account); | |
1955 } | |
1956 | |
1957 static void | |
1958 populate_accounts_list(AccountsWindow *dialog) | |
1959 { | |
1960 GList *l; | |
1961 | |
1962 gtk_list_store_clear(dialog->model); | |
1963 | |
1964 for (l = gaim_accounts_get_all(); l != NULL; l = l->next) | |
1965 add_account_to_liststore((GaimAccount *)l->data, NULL); | |
1966 } | |
1967 | |
1968 #if !GTK_CHECK_VERSION(2,2,0) | |
1969 static void | |
1970 get_selected_helper(GtkTreeModel *model, GtkTreePath *path, | |
1971 GtkTreeIter *iter, gpointer user_data) | |
1972 { | |
1973 *((gboolean *)user_data) = TRUE; | |
1974 } | |
1975 #endif | |
1976 | |
1977 static void | |
1978 account_selected_cb(GtkTreeSelection *sel, AccountsWindow *dialog) | |
1979 { | |
1980 gboolean selected = FALSE; | |
1981 | |
1982 #if GTK_CHECK_VERSION(2,2,0) | |
1983 selected = (gtk_tree_selection_count_selected_rows(sel) > 0); | |
1984 #else | |
1985 gtk_tree_selection_selected_foreach(sel, get_selected_helper, &selected); | |
1986 #endif | |
1987 | |
1988 gtk_widget_set_sensitive(dialog->modify_button, selected); | |
1989 gtk_widget_set_sensitive(dialog->delete_button, selected); | |
1990 } | |
1991 | |
1992 static gboolean | |
1993 account_treeview_double_click_cb(GtkTreeView *treeview, GdkEventButton *event, gpointer user_data) | |
1994 { | |
1995 AccountsWindow *dialog; | |
1996 GtkTreePath *path; | |
1997 GtkTreeViewColumn *column; | |
1998 GtkTreeIter iter; | |
1999 GaimAccount *account; | |
2000 const gchar *title; | |
2001 | |
2002 dialog = (AccountsWindow *)user_data; | |
2003 | |
2004 /* Figure out which node was clicked */ | |
2005 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(dialog->treeview), event->x, event->y, &path, &column, NULL, NULL)) | |
2006 return FALSE; | |
2007 title = gtk_tree_view_column_get_title(column); | |
2008 /* The -1 is required because the first two columns of the list | |
2009 * store are displayed as only one column in the tree view. */ | |
2010 column = gtk_tree_view_get_column(treeview, COLUMN_ENABLED-1); | |
2011 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path); | |
2012 gtk_tree_path_free(path); | |
2013 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, COLUMN_DATA, &account, -1); | |
2014 | |
2015 if ((account != NULL) && (event->button == 1) && | |
2016 (event->type == GDK_2BUTTON_PRESS) && | |
2017 (strcmp(gtk_tree_view_column_get_title(column), title))) | |
2018 { | |
2019 gaim_gtk_account_dialog_show(GAIM_GTK_MODIFY_ACCOUNT_DIALOG, account); | |
2020 return TRUE; | |
2021 } | |
2022 | |
2023 return FALSE; | |
2024 } | |
2025 | |
2026 static GtkWidget * | |
2027 create_accounts_list(AccountsWindow *dialog) | |
2028 { | |
2029 GtkWidget *sw; | |
2030 GtkWidget *treeview; | |
2031 GtkTreeSelection *sel; | |
2032 GtkTargetEntry gte[] = {{"GAIM_ACCOUNT", GTK_TARGET_SAME_APP, 0}}; | |
2033 | |
2034 /* Create the scrolled window. */ | |
2035 sw = gtk_scrolled_window_new(0, 0); | |
2036 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
2037 GTK_POLICY_AUTOMATIC, | |
2038 GTK_POLICY_AUTOMATIC); | |
2039 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
2040 GTK_SHADOW_IN); | |
2041 gtk_widget_show(sw); | |
2042 | |
2043 /* Create the list model. */ | |
2044 dialog->model = gtk_list_store_new(NUM_COLUMNS, | |
2045 GDK_TYPE_PIXBUF, G_TYPE_STRING, | |
2046 G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER, | |
2047 G_TYPE_POINTER); | |
2048 | |
2049 /* And now the actual treeview */ | |
2050 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); | |
2051 dialog->treeview = treeview; | |
2052 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); | |
2053 | |
2054 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); | |
2055 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); | |
2056 g_signal_connect(G_OBJECT(sel), "changed", | |
2057 G_CALLBACK(account_selected_cb), dialog); | |
2058 | |
2059 /* Handle double-clicking */ | |
2060 g_signal_connect(G_OBJECT(treeview), "button_press_event", | |
2061 G_CALLBACK(account_treeview_double_click_cb), dialog); | |
2062 | |
2063 gtk_container_add(GTK_CONTAINER(sw), treeview); | |
2064 gtk_widget_show(treeview); | |
2065 | |
2066 add_columns(treeview, dialog); | |
2067 | |
2068 populate_accounts_list(dialog); | |
2069 | |
2070 /* Setup DND. I wanna be an orc! */ | |
2071 gtk_tree_view_enable_model_drag_source( | |
2072 GTK_TREE_VIEW(treeview), GDK_BUTTON1_MASK, gte, | |
2073 1, GDK_ACTION_COPY); | |
2074 gtk_tree_view_enable_model_drag_dest( | |
2075 GTK_TREE_VIEW(treeview), gte, 1, | |
2076 GDK_ACTION_COPY | GDK_ACTION_MOVE); | |
2077 | |
2078 g_signal_connect(G_OBJECT(treeview), "drag-data-received", | |
2079 G_CALLBACK(drag_data_received_cb), dialog); | |
2080 g_signal_connect(G_OBJECT(treeview), "drag-data-get", | |
2081 G_CALLBACK(drag_data_get_cb), dialog); | |
2082 | |
2083 return sw; | |
2084 } | |
2085 | |
2086 static void | |
2087 account_modified_cb(GaimAccount *account, AccountsWindow *window) | |
2088 { | |
2089 GtkTreeIter iter; | |
2090 | |
2091 if (!accounts_window_find_account_in_treemodel(&iter, account)) | |
2092 return; | |
2093 | |
2094 set_account(window->model, &iter, account); | |
2095 } | |
2096 | |
2097 void | |
2098 gaim_gtk_accounts_window_show(void) | |
2099 { | |
2100 AccountsWindow *dialog; | |
2101 GtkWidget *win; | |
2102 GtkWidget *vbox; | |
2103 GtkWidget *bbox; | |
2104 GtkWidget *sw; | |
2105 GtkWidget *button; | |
2106 int width, height; | |
2107 | |
2108 if (accounts_window != NULL) { | |
2109 gtk_window_present(GTK_WINDOW(accounts_window->window)); | |
2110 return; | |
2111 } | |
2112 | |
2113 accounts_window = dialog = g_new0(AccountsWindow, 1); | |
2114 | |
2115 width = gaim_prefs_get_int("/gaim/gtk/accounts/dialog/width"); | |
2116 height = gaim_prefs_get_int("/gaim/gtk/accounts/dialog/height"); | |
2117 | |
2118 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
2119 gtk_window_set_default_size(GTK_WINDOW(win), width, height); | |
2120 gtk_window_set_role(GTK_WINDOW(win), "accounts"); | |
2121 gtk_window_set_title(GTK_WINDOW(win), _("Accounts")); | |
2122 gtk_container_set_border_width(GTK_CONTAINER(win), GAIM_HIG_BORDER); | |
2123 | |
2124 g_signal_connect(G_OBJECT(win), "delete_event", | |
2125 G_CALLBACK(accedit_win_destroy_cb), accounts_window); | |
2126 g_signal_connect(G_OBJECT(win), "configure_event", | |
2127 G_CALLBACK(configure_cb), accounts_window); | |
2128 | |
2129 /* Setup the vbox */ | |
2130 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
2131 gtk_container_add(GTK_CONTAINER(win), vbox); | |
2132 gtk_widget_show(vbox); | |
2133 | |
2134 /* Setup the scrolled window that will contain the list of accounts. */ | |
2135 sw = create_accounts_list(dialog); | |
2136 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); | |
2137 gtk_widget_show(sw); | |
2138 | |
2139 /* Button box. */ | |
2140 bbox = gtk_hbutton_box_new(); | |
2141 gtk_box_set_spacing(GTK_BOX(bbox), GAIM_HIG_BOX_SPACE); | |
2142 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
2143 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); | |
2144 gtk_widget_show(bbox); | |
2145 | |
2146 /* Add button */ | |
2147 button = gtk_button_new_from_stock(GTK_STOCK_ADD); | |
2148 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
2149 gtk_widget_show(button); | |
2150 | |
2151 g_signal_connect(G_OBJECT(button), "clicked", | |
2152 G_CALLBACK(add_account_cb), dialog); | |
2153 | |
2154 /* Modify button */ | |
2155 button = gtk_button_new_from_stock(GAIM_STOCK_MODIFY); | |
2156 dialog->modify_button = button; | |
2157 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
2158 gtk_widget_set_sensitive(button, FALSE); | |
2159 gtk_widget_show(button); | |
2160 | |
2161 g_signal_connect(G_OBJECT(button), "clicked", | |
2162 G_CALLBACK(modify_account_cb), dialog); | |
2163 | |
2164 /* Delete button */ | |
2165 button = gtk_button_new_from_stock(GTK_STOCK_DELETE); | |
2166 dialog->delete_button = button; | |
2167 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
2168 gtk_widget_set_sensitive(button, FALSE); | |
2169 gtk_widget_show(button); | |
2170 | |
2171 g_signal_connect(G_OBJECT(button), "clicked", | |
2172 G_CALLBACK(ask_delete_account_cb), dialog); | |
2173 | |
2174 /* Close button */ | |
2175 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); | |
2176 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
2177 gtk_widget_show(button); | |
2178 | |
2179 g_signal_connect(G_OBJECT(button), "clicked", | |
2180 G_CALLBACK(close_accounts_cb), dialog); | |
2181 | |
2182 gaim_signal_connect(gaim_gtk_account_get_handle(), "account-modified", | |
2183 accounts_window, | |
2184 GAIM_CALLBACK(account_modified_cb), accounts_window); | |
2185 | |
2186 gtk_widget_show(win); | |
2187 } | |
2188 | |
2189 void | |
2190 gaim_gtk_accounts_window_hide(void) | |
2191 { | |
2192 if (accounts_window == NULL) | |
2193 return; | |
2194 | |
2195 gaim_signals_disconnect_by_handle(accounts_window); | |
2196 | |
2197 g_free(accounts_window); | |
2198 accounts_window = NULL; | |
2199 | |
2200 /* See if we're the main window here. */ | |
2201 if (GAIM_GTK_BLIST(gaim_get_blist())->window == NULL && | |
2202 gaim_connections_get_all() == NULL) { | |
2203 | |
2204 gaim_core_quit(); | |
2205 } | |
2206 } | |
2207 | |
2208 static void | |
2209 free_add_user_data(GaimGtkAccountAddUserData *data) | |
2210 { | |
2211 g_free(data->username); | |
2212 g_free(data->alias); | |
2213 g_free(data); | |
2214 } | |
2215 | |
2216 static void | |
2217 add_user_cb(GaimGtkAccountAddUserData *data) | |
2218 { | |
2219 GaimConnection *gc = gaim_account_get_connection(data->account); | |
2220 | |
2221 if (g_list_find(gaim_connections_get_all(), gc)) | |
2222 { | |
2223 gaim_blist_request_add_buddy(data->account, data->username, | |
2224 NULL, data->alias); | |
2225 } | |
2226 | |
2227 free_add_user_data(data); | |
2228 } | |
2229 | |
2230 static char * | |
2231 make_info(GaimAccount *account, GaimConnection *gc, const char *remote_user, | |
2232 const char *id, const char *alias, const char *msg) | |
2233 { | |
2234 if (msg != NULL && *msg == '\0') | |
2235 msg = NULL; | |
2236 | |
2237 return g_strdup_printf(_("%s%s%s%s has made %s his or her buddy%s%s"), | |
2238 remote_user, | |
2239 (alias != NULL ? " (" : ""), | |
2240 (alias != NULL ? alias : ""), | |
2241 (alias != NULL ? ")" : ""), | |
2242 (id != NULL | |
2243 ? id | |
2244 : (gaim_connection_get_display_name(gc) != NULL | |
2245 ? gaim_connection_get_display_name(gc) | |
2246 : gaim_account_get_username(account))), | |
2247 (msg != NULL ? ": " : "."), | |
2248 (msg != NULL ? msg : "")); | |
2249 } | |
2250 | |
2251 static void | |
2252 gaim_gtk_accounts_notify_added(GaimAccount *account, const char *remote_user, | |
2253 const char *id, const char *alias, | |
2254 const char *msg) | |
2255 { | |
2256 char *buffer; | |
2257 GaimConnection *gc; | |
2258 | |
2259 gc = gaim_account_get_connection(account); | |
2260 | |
2261 buffer = make_info(account, gc, remote_user, id, alias, msg); | |
2262 | |
2263 gaim_notify_info(NULL, NULL, buffer, NULL); | |
2264 | |
2265 g_free(buffer); | |
2266 } | |
2267 | |
2268 static void | |
2269 gaim_gtk_accounts_request_add(GaimAccount *account, const char *remote_user, | |
2270 const char *id, const char *alias, | |
2271 const char *msg) | |
2272 { | |
2273 char *buffer; | |
2274 GaimConnection *gc; | |
2275 GaimGtkAccountAddUserData *data; | |
2276 | |
2277 gc = gaim_account_get_connection(account); | |
2278 | |
2279 data = g_new0(GaimGtkAccountAddUserData, 1); | |
2280 data->account = account; | |
2281 data->username = g_strdup(remote_user); | |
2282 data->alias = g_strdup(alias); | |
2283 | |
2284 buffer = make_info(account, gc, remote_user, id, alias, msg); | |
2285 | |
2286 gaim_request_action(NULL, NULL, _("Add buddy to your list?"), | |
2287 buffer, GAIM_DEFAULT_ACTION_NONE, data, 2, | |
2288 _("Add"), G_CALLBACK(add_user_cb), | |
2289 _("Cancel"), G_CALLBACK(free_add_user_data)); | |
2290 | |
2291 g_free(buffer); | |
2292 } | |
2293 | |
2294 static GaimAccountUiOps ui_ops = | |
2295 { | |
2296 gaim_gtk_accounts_notify_added, | |
2297 NULL, | |
2298 gaim_gtk_accounts_request_add | |
2299 }; | |
2300 | |
2301 GaimAccountUiOps * | |
2302 gaim_gtk_accounts_get_ui_ops(void) | |
2303 { | |
2304 return &ui_ops; | |
2305 } | |
2306 | |
2307 void * | |
2308 gaim_gtk_account_get_handle(void) { | |
2309 static int handle; | |
2310 | |
2311 return &handle; | |
2312 } | |
2313 | |
2314 void | |
2315 gaim_gtk_account_init(void) | |
2316 { | |
2317 gaim_prefs_add_none("/gaim/gtk/accounts"); | |
2318 gaim_prefs_add_none("/gaim/gtk/accounts/dialog"); | |
2319 gaim_prefs_add_int("/gaim/gtk/accounts/dialog/width", 520); | |
2320 gaim_prefs_add_int("/gaim/gtk/accounts/dialog/height", 321); | |
2321 gaim_prefs_add_string("/gaim/gtk/accounts/buddyicon", NULL); | |
2322 | |
2323 gaim_signal_register(gaim_gtk_account_get_handle(), "account-modified", | |
2324 gaim_marshal_VOID__POINTER, NULL, 1, | |
2325 gaim_value_new(GAIM_TYPE_SUBTYPE, | |
2326 GAIM_SUBTYPE_ACCOUNT)); | |
2327 | |
2328 /* Setup some gaim signal handlers. */ | |
2329 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", | |
2330 gaim_gtk_account_get_handle(), | |
2331 GAIM_CALLBACK(signed_on_off_cb), NULL); | |
2332 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", | |
2333 gaim_gtk_account_get_handle(), | |
2334 GAIM_CALLBACK(signed_on_off_cb), NULL); | |
2335 gaim_signal_connect(gaim_accounts_get_handle(), "account-added", | |
2336 gaim_gtk_account_get_handle(), | |
2337 GAIM_CALLBACK(add_account_to_liststore), NULL); | |
2338 gaim_signal_connect(gaim_accounts_get_handle(), "account-removed", | |
2339 gaim_gtk_account_get_handle(), | |
2340 GAIM_CALLBACK(account_removed_cb), NULL); | |
2341 gaim_signal_connect(gaim_accounts_get_handle(), "account-disabled", | |
2342 gaim_gtk_account_get_handle(), | |
2343 GAIM_CALLBACK(account_abled_cb), GINT_TO_POINTER(FALSE)); | |
2344 gaim_signal_connect(gaim_accounts_get_handle(), "account-enabled", | |
2345 gaim_gtk_account_get_handle(), | |
2346 GAIM_CALLBACK(account_abled_cb), GINT_TO_POINTER(TRUE)); | |
2347 | |
2348 account_pref_wins = | |
2349 g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); | |
2350 } | |
2351 | |
2352 void | |
2353 gaim_gtk_account_uninit(void) | |
2354 { | |
2355 /* | |
2356 * TODO: Need to free all the dialogs in here. Could probably create | |
2357 * a callback function to use for the free-some-data-function | |
2358 * parameter of g_hash_table_new_full, above. | |
2359 */ | |
2360 g_hash_table_destroy(account_pref_wins); | |
2361 | |
2362 gaim_signals_disconnect_by_handle(gaim_gtk_account_get_handle()); | |
2363 gaim_signals_unregister_by_instance(gaim_gtk_account_get_handle()); | |
2364 } | |
2365 |