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