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