pidgin/gtkprefs.c

branch
soc.2008.masterpassword
changeset 34023
6bc30809f7fe
parent 34021
25c14927f826
parent 32596
927575c2af4e
child 34034
f508fa47f2ac
equal deleted inserted replaced
34022:c49f6e9ea27d 34023:6bc30809f7fe
44 #include "network.h" 44 #include "network.h"
45 #include "keyring.h" 45 #include "keyring.h"
46 46
47 #include "gtkblist.h" 47 #include "gtkblist.h"
48 #include "gtkconv.h" 48 #include "gtkconv.h"
49 #include "gtkconv-theme.h"
49 #include "gtkdebug.h" 50 #include "gtkdebug.h"
50 #include "gtkdialogs.h" 51 #include "gtkdialogs.h"
51 #include "gtkimhtml.h" 52 #include "gtkimhtml.h"
52 #include "gtkimhtmltoolbar.h" 53 #include "gtkimhtmltoolbar.h"
53 #include "gtkprefs.h" 54 #include "gtkprefs.h"
69 gchar *type; 70 gchar *type;
70 gchar *extension; 71 gchar *extension;
71 gchar *original_name; 72 gchar *original_name;
72 }; 73 };
73 74
75 /* Main dialog */
76 static GtkWidget *prefs = NULL;
77
78 /* Notebook */
79 static GtkWidget *prefsnotebook = NULL;
80 static int notebook_page = 0;
81
82 /* Conversations page */
83 static GtkWidget *sample_imhtml = NULL;
84
85 /* Themes page */
86 static GtkWidget *prefs_sound_themes_combo_box;
87 static GtkWidget *prefs_blist_themes_combo_box;
88 static GtkWidget *prefs_conv_themes_combo_box;
89 static GtkWidget *prefs_conv_variants_combo_box;
90 static GtkWidget *prefs_status_themes_combo_box;
91 static GtkWidget *prefs_smiley_themes_combo_box;
92
93 /* Sound theme specific */
94 static GtkWidget *sound_entry = NULL;
74 static int sound_row_sel = 0; 95 static int sound_row_sel = 0;
75 static GtkWidget *prefsnotebook; 96 static gboolean prefs_sound_themes_loading;
76 97
77 static GtkWidget *sound_entry = NULL; 98 /* These exist outside the lifetime of the prefs dialog */
78 static GtkListStore *smiley_theme_store = NULL;
79 static GtkTreeSelection *smiley_theme_sel = NULL;
80 static GtkWidget *prefs_proxy_frame = NULL;
81
82 static GtkWidget *prefs = NULL;
83 static GtkWidget *debugbutton = NULL;
84 static int notebook_page = 0;
85 static GtkTreeRowReference *previous_smiley_row = NULL;
86
87 static GtkListStore *prefs_sound_themes; 99 static GtkListStore *prefs_sound_themes;
88 static GtkListStore *prefs_blist_themes; 100 static GtkListStore *prefs_blist_themes;
101 static GtkListStore *prefs_conv_themes;
102 static GtkListStore *prefs_conv_variants;
89 static GtkListStore *prefs_status_icon_themes; 103 static GtkListStore *prefs_status_icon_themes;
90 104 static GtkListStore *prefs_smiley_themes;
91 static GtkWidget *prefs_sound_themes_combo_box;
92 static GtkWidget *prefs_blist_themes_combo_box;
93 static GtkWidget *prefs_status_themes_combo_box;
94 105
95 /* 106 /*
96 * PROTOTYPES 107 * PROTOTYPES
97 */ 108 */
98 static void delete_prefs(GtkWidget *, void *); 109 static void delete_prefs(GtkWidget *, void *);
216 const char *str_value = NULL; 227 const char *str_value = NULL;
217 int o = 0; 228 int o = 0;
218 229
219 g_return_val_if_fail(menuitems != NULL, NULL); 230 g_return_val_if_fail(menuitems != NULL, NULL);
220 231
221 #if 0 /* GTK_CHECK_VERSION(2,4,0) */
222 if(type == PURPLE_PREF_INT)
223 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
224 else if(type == PURPLE_PREF_STRING)
225 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
226 dropdown = gtk_combo_box_new_with_model(model);
227 #else
228 dropdown = gtk_option_menu_new(); 232 dropdown = gtk_option_menu_new();
229 menu = gtk_menu_new(); 233 menu = gtk_menu_new();
230 #endif
231 234
232 if (type == PURPLE_PREF_INT) 235 if (type == PURPLE_PREF_INT)
233 stored_int = purple_prefs_get_int(key); 236 stored_int = purple_prefs_get_int(key);
234 else if (type == PURPLE_PREF_STRING) 237 else if (type == PURPLE_PREF_STRING)
235 stored_str = purple_prefs_get_string(key); 238 stored_str = purple_prefs_get_string(key);
333 purple_request_close_with_handle(prefs); 336 purple_request_close_with_handle(prefs);
334 337
335 /* Unregister callbacks. */ 338 /* Unregister callbacks. */
336 purple_prefs_disconnect_by_handle(prefs); 339 purple_prefs_disconnect_by_handle(prefs);
337 340
341 /* NULL-ify globals */
342 sound_entry = NULL;
343 sound_row_sel = 0;
344 prefs_sound_themes_loading = FALSE;
345
346 prefs_sound_themes_combo_box = NULL;
347 prefs_blist_themes_combo_box = NULL;
348 prefs_conv_themes_combo_box = NULL;
349 prefs_conv_variants_combo_box = NULL;
350 prefs_status_themes_combo_box = NULL;
351 prefs_smiley_themes_combo_box = NULL;
352
353 sample_imhtml = NULL;
354
355 notebook_page = 0;
356 prefsnotebook = NULL;
338 prefs = NULL; 357 prefs = NULL;
339 sound_entry = NULL; 358 }
340 debugbutton = NULL; 359
341 notebook_page = 0; 360 static gchar *
342 smiley_theme_store = NULL; 361 get_theme_markup(const char *name, gboolean custom, const char *author,
343 if (previous_smiley_row) 362 const char *description)
344 gtk_tree_row_reference_free(previous_smiley_row); 363 {
345 previous_smiley_row = NULL; 364
346 365 return g_strdup_printf("<b>%s</b>%s%s%s%s\n<span foreground='dim grey'>%s</span>",
347 } 366 name, custom ? " " : "", custom ? _("(Custom)") : "",
348 367 author != NULL ? " - " : "", author != NULL ? author : "",
349 static void 368 description != NULL ? description : "");
350 smiley_sel(GtkTreeSelection *sel, GtkTreeModel *model) 369 }
351 { 370
352 GtkTreeIter iter; 371 static void
353 const char *themename; 372 smileys_refresh_theme_list(void)
354 char *description;
355 GValue val;
356 GtkTreePath *path, *oldpath;
357 struct smiley_theme *new_theme, *old_theme;
358 GtkWidget *remove_button = g_object_get_data(G_OBJECT(sel), "remove_button");
359
360 if (!gtk_tree_selection_get_selected(sel, &model, &iter)) {
361 gtk_widget_set_sensitive(remove_button, FALSE);
362 return;
363 }
364
365 old_theme = current_smiley_theme;
366 val.g_type = 0;
367 gtk_tree_model_get_value(model, &iter, 3, &val);
368 path = gtk_tree_model_get_path(model, &iter);
369 themename = g_value_get_string(&val);
370 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/smileys/theme", themename);
371
372 gtk_widget_set_sensitive(remove_button, (strcmp(themename, "none") &&
373 strcmp(themename, _("Default"))));
374 g_value_unset (&val);
375
376 /* current_smiley_theme is set in callback for the above pref change */
377 new_theme = current_smiley_theme;
378 description = g_strdup_printf("<span size='larger' weight='bold'>%s</span> - %s\n"
379 "<span size='smaller' foreground='white'>%s</span>",
380 _(new_theme->name), _(new_theme->author), _(new_theme->desc));
381 gtk_list_store_set(smiley_theme_store, &iter, 1, description, -1);
382 g_free(description);
383
384 if (new_theme != old_theme && previous_smiley_row) {
385 oldpath = gtk_tree_row_reference_get_path(previous_smiley_row);
386 if (gtk_tree_model_get_iter(model, &iter, oldpath)) {
387 description = g_strdup_printf("<span size='larger' weight='bold'>%s</span> - %s\n"
388 "<span size='smaller' foreground='dim grey'>%s</span>",
389 _(old_theme->name), _(old_theme->author), _(old_theme->desc));
390 gtk_list_store_set(smiley_theme_store, &iter, 1,
391 description, -1);
392 g_free(description);
393 }
394 gtk_tree_path_free(oldpath);
395 }
396 if (previous_smiley_row)
397 gtk_tree_row_reference_free(previous_smiley_row);
398 previous_smiley_row = gtk_tree_row_reference_new(model, path);
399 gtk_tree_path_free(path);
400 }
401
402 static GtkTreeRowReference *
403 theme_refresh_theme_list(void)
404 { 373 {
405 GdkPixbuf *pixbuf; 374 GdkPixbuf *pixbuf;
406 GSList *themes; 375 GSList *themes;
407 GtkTreeIter iter; 376 GtkTreeIter iter;
408 GtkTreeRowReference *row_ref = NULL;
409
410 if (previous_smiley_row)
411 gtk_tree_row_reference_free(previous_smiley_row);
412 previous_smiley_row = NULL;
413 377
414 pidgin_themes_smiley_theme_probe(); 378 pidgin_themes_smiley_theme_probe();
415 379
416 if (!(themes = smiley_themes)) 380 if (!(themes = smiley_themes))
417 return NULL; 381 return;
418
419 gtk_list_store_clear(smiley_theme_store);
420 382
421 while (themes) { 383 while (themes) {
422 struct smiley_theme *theme = themes->data; 384 struct smiley_theme *theme = themes->data;
423 char *description = g_strdup_printf("<span size='larger' weight='bold'>%s</span> - %s\n" 385 char *description = get_theme_markup(_(theme->name), FALSE,
424 "<span size='smaller' foreground='dim grey'>%s</span>", 386 _(theme->author), _(theme->desc));
425 _(theme->name), _(theme->author), _(theme->desc)); 387 gtk_list_store_append(prefs_smiley_themes, &iter);
426 gtk_list_store_append (smiley_theme_store, &iter);
427 388
428 /* 389 /*
429 * LEAK - Gentoo memprof thinks pixbuf is leaking here... but it 390 * LEAK - Gentoo memprof thinks pixbuf is leaking here... but it
430 * looks like it should be ok to me. Anyone know what's up? --Mark 391 * looks like it should be ok to me. Anyone know what's up? --Mark
431 */ 392 */
432 pixbuf = (theme->icon ? gdk_pixbuf_new_from_file(theme->icon, NULL) : NULL); 393 pixbuf = (theme->icon ? pidgin_pixbuf_new_from_file(theme->icon) : NULL);
433 394
434 gtk_list_store_set(smiley_theme_store, &iter, 395 gtk_list_store_set(prefs_smiley_themes, &iter,
435 0, pixbuf, 396 0, pixbuf,
436 1, description, 397 1, description,
437 2, theme->path, 398 2, theme->name,
438 3, theme->name,
439 -1); 399 -1);
440 400
441 if (pixbuf != NULL) 401 if (pixbuf != NULL)
442 g_object_unref(G_OBJECT(pixbuf)); 402 g_object_unref(G_OBJECT(pixbuf));
443 403
444 g_free(description); 404 g_free(description);
445 themes = themes->next; 405 themes = themes->next;
446 406 }
447 /* If this is the currently selected theme,
448 * we will need to select it. Grab the row reference. */
449 if (theme == current_smiley_theme) {
450 GtkTreePath *path = gtk_tree_model_get_path(
451 GTK_TREE_MODEL(smiley_theme_store), &iter);
452 row_ref = gtk_tree_row_reference_new(
453 GTK_TREE_MODEL(smiley_theme_store), path);
454 gtk_tree_path_free(path);
455 }
456 }
457
458 return row_ref;
459 } 407 }
460 408
461 /* Rebuild the markup for the sound theme selection for "(Custom)" themes */ 409 /* Rebuild the markup for the sound theme selection for "(Custom)" themes */
462 static void 410 static void
463 pref_sound_generate_markup(void) 411 pref_sound_generate_markup(void)
464 { 412 {
465 gboolean print_custom, customized; 413 gboolean print_custom, customized;
466 const gchar *name, *author, *description, *current_theme; 414 const gchar *author, *description, *current_theme;
467 gchar *markup; 415 gchar *name, *markup;
468 PurpleSoundTheme *theme; 416 PurpleSoundTheme *theme;
469 GtkTreeIter iter; 417 GtkTreeIter iter;
470 418
471 customized = pidgin_sound_is_customized(); 419 customized = pidgin_sound_is_customized();
472 current_theme = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"); 420 current_theme = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme");
473 421
474 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs_sound_themes), &iter)) { 422 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs_sound_themes), &iter)) {
475 do { 423 do {
476 gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &iter, 2, &name, -1); 424 gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &iter, 2, &name, -1);
477 425
478 print_custom = customized && g_str_equal(current_theme, name); 426 print_custom = customized && name && g_str_equal(current_theme, name);
479 427
480 if (!name || *name == '\0') 428 if (!name || *name == '\0') {
481 markup = g_strdup_printf("<b>(Default)</b>%s%s - None\n<span foreground='dim grey'>The default Pidgin sound theme</span>", 429 g_free(name);
482 print_custom ? " " : "", print_custom ? "(Custom)" : ""); 430 name = g_strdup(_("Default"));
483 else { 431 author = _("Penguin Pimps");
432 description = _("The default Pidgin sound theme");
433 } else {
484 theme = PURPLE_SOUND_THEME(purple_theme_manager_find_theme(name, "sound")); 434 theme = PURPLE_SOUND_THEME(purple_theme_manager_find_theme(name, "sound"));
485 author = purple_theme_get_author(PURPLE_THEME(theme)); 435 author = purple_theme_get_author(PURPLE_THEME(theme));
486 description = purple_theme_get_description(PURPLE_THEME(theme)); 436 description = purple_theme_get_description(PURPLE_THEME(theme));
487
488 markup = g_strdup_printf("<b>%s</b>%s%s%s%s\n<span foreground='dim grey'>%s</span>",
489 name, print_custom ? " " : "", print_custom ? "(Custom)" : "",
490 author != NULL ? " - " : "", author != NULL ? author : "", description != NULL ? description : "");
491 } 437 }
492 438
439 markup = get_theme_markup(name, print_custom, author, description);
440
493 gtk_list_store_set(prefs_sound_themes, &iter, 1, markup, -1); 441 gtk_list_store_set(prefs_sound_themes, &iter, 1, markup, -1);
494 442
443 g_free(name);
495 g_free(markup); 444 g_free(markup);
496 445
497 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs_sound_themes), &iter)); 446 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs_sound_themes), &iter));
498 } 447 }
499 } 448 }
509 458
510 if (PURPLE_IS_SOUND_THEME(theme)){ 459 if (PURPLE_IS_SOUND_THEME(theme)){
511 460
512 image_full = purple_theme_get_image_full(theme); 461 image_full = purple_theme_get_image_full(theme);
513 if (image_full != NULL){ 462 if (image_full != NULL){
514 pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL); 463 pixbuf = pidgin_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE);
515 g_free(image_full); 464 g_free(image_full);
516 } else pixbuf = NULL; 465 } else
466 pixbuf = NULL;
517 467
518 gtk_list_store_append(prefs_sound_themes, &iter); 468 gtk_list_store_append(prefs_sound_themes, &iter);
519 gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, purple_theme_get_name(theme), -1); 469 gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, purple_theme_get_name(theme), -1);
520 470
521 if (pixbuf != NULL) 471 if (pixbuf != NULL)
524 } else if (PIDGIN_IS_BLIST_THEME(theme) || PIDGIN_IS_STATUS_ICON_THEME(theme)){ 474 } else if (PIDGIN_IS_BLIST_THEME(theme) || PIDGIN_IS_STATUS_ICON_THEME(theme)){
525 GtkListStore *store; 475 GtkListStore *store;
526 476
527 if (PIDGIN_IS_BLIST_THEME(theme)) 477 if (PIDGIN_IS_BLIST_THEME(theme))
528 store = prefs_blist_themes; 478 store = prefs_blist_themes;
529 else store = prefs_status_icon_themes; 479 else
480 store = prefs_status_icon_themes;
530 481
531 image_full = purple_theme_get_image_full(theme); 482 image_full = purple_theme_get_image_full(theme);
532 if (image_full != NULL){ 483 if (image_full != NULL){
533 pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL); 484 pixbuf = pidgin_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE);
534 g_free(image_full); 485 g_free(image_full);
535 } else pixbuf = NULL; 486 } else
487 pixbuf = NULL;
536 488
537 name = purple_theme_get_name(theme); 489 name = purple_theme_get_name(theme);
538 author = purple_theme_get_author(theme); 490 author = purple_theme_get_author(theme);
539 description = purple_theme_get_description(theme); 491 description = purple_theme_get_description(theme);
540 492
541 markup = g_strdup_printf("<b>%s</b>%s%s\n<span foreground='dim grey'>%s</span>", name, author != NULL ? " - " : "", 493 markup = get_theme_markup(name, FALSE, author, description);
542 author != NULL ? author : "", description != NULL ? description : "");
543 494
544 gtk_list_store_append(store, &iter); 495 gtk_list_store_append(store, &iter);
545 gtk_list_store_set(store, &iter, 0, pixbuf, 1, markup, 2, name, -1); 496 gtk_list_store_set(store, &iter, 0, pixbuf, 1, markup, 2, name, -1);
546 497
547 g_free(markup); 498 g_free(markup);
548 if (pixbuf != NULL) 499 if (pixbuf != NULL)
549 g_object_unref(G_OBJECT(pixbuf)); 500 g_object_unref(G_OBJECT(pixbuf));
501
502 } else if (PIDGIN_IS_CONV_THEME(theme)) {
503 /* No image available? */
504
505 name = purple_theme_get_name(theme);
506 /* No author available */
507 /* No description available */
508
509 markup = get_theme_markup(name, FALSE, NULL, NULL);
510
511 gtk_list_store_append(prefs_conv_themes, &iter);
512 gtk_list_store_set(prefs_conv_themes, &iter, 1, markup, 2, name, -1);
550 } 513 }
551 } 514 }
552 515
553 static void 516 static void
554 prefs_set_active_theme_combo(GtkWidget *combo_box, GtkListStore *store, const gchar *current_theme) 517 prefs_set_active_theme_combo(GtkWidget *combo_box, GtkListStore *store, const gchar *current_theme)
576 539
577 static void 540 static void
578 prefs_themes_refresh(void) 541 prefs_themes_refresh(void)
579 { 542 {
580 GdkPixbuf *pixbuf = NULL; 543 GdkPixbuf *pixbuf = NULL;
581 gchar *filename; 544 gchar *tmp;
582 GtkTreeIter iter; 545 GtkTreeIter iter;
583 546
547 prefs_sound_themes_loading = TRUE;
584 /* refresh the list of themes in the manager */ 548 /* refresh the list of themes in the manager */
585 purple_theme_manager_refresh(); 549 purple_theme_manager_refresh();
586 550
587 filename = g_build_filename(DATADIR, "icons", "hicolor", "32x32", "apps", "pidgin.png", NULL); 551 tmp = g_build_filename(DATADIR, "icons", "hicolor", "32x32", "apps", "pidgin.png", NULL);
588 pixbuf = gdk_pixbuf_new_from_file_at_scale(filename, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL); 552 pixbuf = pidgin_pixbuf_new_from_file_at_scale(tmp, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE);
589 g_free(filename); 553 g_free(tmp);
590 554
591 /* sound themes */ 555 /* sound themes */
592 gtk_list_store_clear(prefs_sound_themes); 556 gtk_list_store_clear(prefs_sound_themes);
593 gtk_list_store_append(prefs_sound_themes, &iter); 557 gtk_list_store_append(prefs_sound_themes, &iter);
594 gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, "", -1); 558 gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, "", -1);
595 559
596 /* blist themes */ 560 /* blist themes */
597 gtk_list_store_clear(prefs_blist_themes); 561 gtk_list_store_clear(prefs_blist_themes);
598 gtk_list_store_append(prefs_blist_themes, &iter); 562 gtk_list_store_append(prefs_blist_themes, &iter);
599 gtk_list_store_set(prefs_blist_themes, &iter, 0, pixbuf, 1, 563 tmp = get_theme_markup(_("Default"), FALSE, _("Penguin Pimps"),
600 "<b>(Default)</b> - None\n<span color='dim grey'>" 564 _("The default Pidgin buddy list theme"));
601 "The default Pidgin buddy list theme</span>", 2, "", -1); 565 gtk_list_store_set(prefs_blist_themes, &iter, 0, pixbuf, 1, tmp, 2, "", -1);
566 g_free(tmp);
567
568 /* conversation themes */
569 gtk_list_store_clear(prefs_conv_themes);
570 gtk_list_store_append(prefs_conv_themes, &iter);
571 tmp = get_theme_markup(_("Default"), FALSE, _("Penguin Pimps"),
572 _("The default Pidgin conversation theme"));
573 gtk_list_store_set(prefs_conv_themes, &iter, 0, pixbuf, 1, tmp, 2, "", -1);
574 g_free(tmp);
575
576 /* conversation theme variants */
577 gtk_list_store_clear(prefs_conv_variants);
602 578
603 /* status icon themes */ 579 /* status icon themes */
604 gtk_list_store_clear(prefs_status_icon_themes); 580 gtk_list_store_clear(prefs_status_icon_themes);
605 gtk_list_store_append(prefs_status_icon_themes, &iter); 581 gtk_list_store_append(prefs_status_icon_themes, &iter);
606 gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1, 582 tmp = get_theme_markup(_("Default"), FALSE, _("Penguin Pimps"),
607 "<b>(Default)</b> - None\n<span color='dim grey'>" 583 _("The default Pidgin status icon theme"));
608 "The default Pidgin status icon theme</span>", 2, "", -1); 584 gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1, tmp, 2, "", -1);
609 g_object_unref(G_OBJECT(pixbuf)); 585 g_free(tmp);
586 if (pixbuf)
587 g_object_unref(G_OBJECT(pixbuf));
588
589 /* smiley themes */
590 gtk_list_store_clear(prefs_smiley_themes);
610 591
611 purple_theme_manager_for_each_theme(prefs_themes_sort); 592 purple_theme_manager_for_each_theme(prefs_themes_sort);
612 pref_sound_generate_markup(); 593 pref_sound_generate_markup();
594 smileys_refresh_theme_list();
613 595
614 /* set active */ 596 /* set active */
615 prefs_set_active_theme_combo(prefs_sound_themes_combo_box, prefs_sound_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme")); 597 prefs_set_active_theme_combo(prefs_sound_themes_combo_box, prefs_sound_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"));
616 prefs_set_active_theme_combo(prefs_blist_themes_combo_box, prefs_blist_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme")); 598 prefs_set_active_theme_combo(prefs_blist_themes_combo_box, prefs_blist_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme"));
599 prefs_set_active_theme_combo(prefs_conv_themes_combo_box, prefs_conv_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"));
617 prefs_set_active_theme_combo(prefs_status_themes_combo_box, prefs_status_icon_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme")); 600 prefs_set_active_theme_combo(prefs_status_themes_combo_box, prefs_status_icon_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme"));
601 prefs_set_active_theme_combo(prefs_smiley_themes_combo_box, prefs_smiley_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/smileys/theme"));
602 prefs_sound_themes_loading = FALSE;
618 } 603 }
619 604
620 /* init all the theme variables so that the themes can be sorted later and used by pref pages */ 605 /* init all the theme variables so that the themes can be sorted later and used by pref pages */
621 static void 606 static void
622 prefs_themes_init(void) 607 prefs_themes_init(void)
623 { 608 {
624 prefs_sound_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); 609 prefs_sound_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
625 610
626 prefs_blist_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); 611 prefs_blist_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
627 612
613 prefs_conv_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
614
615 prefs_conv_variants = gtk_list_store_new(1, G_TYPE_STRING);
616
628 prefs_status_icon_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); 617 prefs_status_icon_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
618
619 prefs_smiley_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
629 } 620 }
630 621
631 static PurpleTheme * 622 static PurpleTheme *
632 prefs_theme_find_theme(const gchar *path, const gchar *type) 623 prefs_theme_find_theme(const gchar *path, const gchar *type)
633 { 624 {
671 fclose(src); 662 fclose(src);
672 663
673 return TRUE; 664 return TRUE;
674 } 665 }
675 666
667 static void
668 free_theme_info(struct theme_info *info)
669 {
670 if (info != NULL) {
671 g_free(info->type);
672 g_free(info->extension);
673 g_free(info->original_name);
674 g_free(info);
675 }
676 }
677
676 /* installs a theme, info is freed by function */ 678 /* installs a theme, info is freed by function */
677 static void 679 static void
678 theme_install_theme(char *path, struct theme_info *info) 680 theme_install_theme(char *path, struct theme_info *info)
679 { 681 {
680 #ifndef _WIN32 682 #ifndef _WIN32
681 gchar *command; 683 gchar *command;
682 #endif 684 #endif
683 gchar *destdir, *tail, *type, *original_name; 685 gchar *destdir;
684 GtkTreeRowReference *theme_rowref; 686 const char *tail;
685 gboolean is_smiley_theme, is_archive; 687 gboolean is_smiley_theme, is_archive;
686 PurpleTheme *theme = NULL; 688 PurpleTheme *theme = NULL;
687 689
688 if (info == NULL) 690 if (info == NULL)
689 return; 691 return;
690 692
691 original_name = info->original_name;
692 type = info->type;
693
694 /* check the extension */ 693 /* check the extension */
695 tail = info->extension ? info->extension : g_strdup(strrchr(path, '.')); 694 tail = info->extension ? info->extension : strrchr(path, '.');
696 695
697 if (!tail) { 696 if (!tail) {
698 g_free(type); 697 free_theme_info(info);
699 g_free(original_name);
700 g_free(info);
701 return; 698 return;
702 } else 699 }
703 g_free(info);
704 700
705 is_archive = !g_ascii_strcasecmp(tail, ".gz") || !g_ascii_strcasecmp(tail, ".tgz"); 701 is_archive = !g_ascii_strcasecmp(tail, ".gz") || !g_ascii_strcasecmp(tail, ".tgz");
706
707 g_free(tail);
708 702
709 /* Just to be safe */ 703 /* Just to be safe */
710 g_strchomp(path); 704 g_strchomp(path);
711 705
712 if ((is_smiley_theme = g_str_equal(type, "smiley"))) 706 if ((is_smiley_theme = g_str_equal(info->type, "smiley")))
713 destdir = g_build_filename(purple_user_dir(), "smileys", NULL); 707 destdir = g_build_filename(purple_user_dir(), "smileys", NULL);
714 else destdir = g_build_filename(purple_user_dir(), "themes", "temp", NULL); 708 else
709 destdir = g_build_filename(purple_user_dir(), "themes", "temp", NULL);
715 710
716 /* We'll check this just to make sure. This also lets us do something different on 711 /* We'll check this just to make sure. This also lets us do something different on
717 * other platforms, if need be */ 712 * other platforms, if need be */
718 if (is_archive) { 713 if (is_archive) {
719 #ifndef _WIN32 714 #ifndef _WIN32
730 /* Fire! */ 725 /* Fire! */
731 if (system(command)) { 726 if (system(command)) {
732 purple_notify_error(NULL, NULL, _("Theme failed to unpack."), NULL); 727 purple_notify_error(NULL, NULL, _("Theme failed to unpack."), NULL);
733 g_free(command); 728 g_free(command);
734 g_free(destdir); 729 g_free(destdir);
735 g_free(type); 730 free_theme_info(info);
736 g_free(original_name);
737 return; 731 return;
738 } 732 }
739 #else 733 #else
740 if(!winpidgin_gz_untar(path, destdir)) { 734 if (!winpidgin_gz_untar(path, destdir)) {
735 purple_notify_error(NULL, NULL, _("Theme failed to unpack."), NULL);
741 g_free(destdir); 736 g_free(destdir);
742 g_free(type); 737 free_theme_info(info);
743 g_free(original_name);
744 return; 738 return;
745 } 739 }
746 #endif 740 #endif
747 } 741 }
748 742
749 if (is_smiley_theme) { 743 if (is_smiley_theme) {
750 /* just extract the folder to the smiley directory */ 744 /* just extract the folder to the smiley directory */
751 theme_rowref = theme_refresh_theme_list(); 745 prefs_themes_refresh();
752
753 if (theme_rowref != NULL) {
754 GtkTreePath *tp = gtk_tree_row_reference_get_path(theme_rowref);
755
756 if (tp)
757 gtk_tree_selection_select_path(smiley_theme_sel, tp);
758
759 gtk_tree_row_reference_free(theme_rowref);
760 }
761 746
762 } else if (is_archive) { 747 } else if (is_archive) {
763 theme = prefs_theme_find_theme(destdir, type); 748 theme = prefs_theme_find_theme(destdir, info->type);
764 749
765 if (PURPLE_IS_THEME(theme)) { 750 if (PURPLE_IS_THEME(theme)) {
766 /* create the location for the theme */ 751 /* create the location for the theme */
767 gchar *theme_dest = g_build_filename(purple_user_dir(), "themes", 752 gchar *theme_dest = g_build_filename(purple_user_dir(), "themes",
768 purple_theme_get_name(theme), 753 purple_theme_get_name(theme),
769 "purple", type, NULL); 754 "purple", info->type, NULL);
770 755
771 if (!g_file_test(theme_dest, G_FILE_TEST_IS_DIR)) 756 if (!g_file_test(theme_dest, G_FILE_TEST_IS_DIR))
772 purple_build_dir(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR); 757 purple_build_dir(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR);
773 758
774 g_free(theme_dest); 759 g_free(theme_dest);
775 theme_dest = g_build_filename(purple_user_dir(), "themes", 760 theme_dest = g_build_filename(purple_user_dir(), "themes",
776 purple_theme_get_name(theme), 761 purple_theme_get_name(theme),
777 "purple", type, NULL); 762 "purple", info->type, NULL);
778 763
779 /* move the entire directory to new location */ 764 /* move the entire directory to new location */
780 g_rename(purple_theme_get_dir(theme), theme_dest); 765 g_rename(purple_theme_get_dir(theme), theme_dest);
781 766
782 g_free(theme_dest); 767 g_free(theme_dest);
794 } else { /* just a single file so copy it to a new temp directory and attempt to load it*/ 779 } else { /* just a single file so copy it to a new temp directory and attempt to load it*/
795 gchar *temp_path, *temp_file; 780 gchar *temp_path, *temp_file;
796 781
797 temp_path = g_build_filename(purple_user_dir(), "themes", "temp", "sub_folder", NULL); 782 temp_path = g_build_filename(purple_user_dir(), "themes", "temp", "sub_folder", NULL);
798 783
799 if (original_name != NULL) { 784 if (info->original_name != NULL) {
800 /* name was changed from the original (probably a dnd) change it back before loading */ 785 /* name was changed from the original (probably a dnd) change it back before loading */
801 temp_file = g_build_filename(temp_path, original_name, NULL); 786 temp_file = g_build_filename(temp_path, info->original_name, NULL);
802 787
803 } else { 788 } else {
804 gchar *source_name = g_path_get_basename(path); 789 gchar *source_name = g_path_get_basename(path);
805 temp_file = g_build_filename(temp_path, source_name, NULL); 790 temp_file = g_build_filename(temp_path, source_name, NULL);
806 g_free(source_name); 791 g_free(source_name);
809 if (!g_file_test(temp_path, G_FILE_TEST_IS_DIR)) 794 if (!g_file_test(temp_path, G_FILE_TEST_IS_DIR))
810 purple_build_dir(temp_path, S_IRUSR | S_IWUSR | S_IXUSR); 795 purple_build_dir(temp_path, S_IRUSR | S_IWUSR | S_IXUSR);
811 796
812 if (purple_theme_file_copy(path, temp_file)) { 797 if (purple_theme_file_copy(path, temp_file)) {
813 /* find the theme, could be in subfolder */ 798 /* find the theme, could be in subfolder */
814 theme = prefs_theme_find_theme(temp_path, type); 799 theme = prefs_theme_find_theme(temp_path, info->type);
815 800
816 if (PURPLE_IS_THEME(theme)) { 801 if (PURPLE_IS_THEME(theme)) {
817 gchar *theme_dest = g_build_filename(purple_user_dir(), "themes", 802 gchar *theme_dest = g_build_filename(purple_user_dir(), "themes",
818 purple_theme_get_name(theme), 803 purple_theme_get_name(theme),
819 "purple", type, NULL); 804 "purple", info->type, NULL);
820 805
821 if(!g_file_test(theme_dest, G_FILE_TEST_IS_DIR)) 806 if(!g_file_test(theme_dest, G_FILE_TEST_IS_DIR))
822 purple_build_dir(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR); 807 purple_build_dir(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR);
823 808
824 g_rename(purple_theme_get_dir(theme), theme_dest); 809 g_rename(purple_theme_get_dir(theme), theme_dest);
837 822
838 g_free(temp_file); 823 g_free(temp_file);
839 g_free(temp_path); 824 g_free(temp_path);
840 } 825 }
841 826
842 g_free(type);
843 g_free(original_name);
844 g_free(destdir); 827 g_free(destdir);
828 free_theme_info(info);
845 } 829 }
846 830
847 static void 831 static void
848 theme_got_url(PurpleUtilFetchUrlData *url_data, gpointer user_data, 832 theme_got_url(PurpleUtilFetchUrlData *url_data, gpointer user_data,
849 const gchar *themedata, size_t len, const gchar *error_message) 833 const gchar *themedata, size_t len, const gchar *error_message)
850 { 834 {
851 FILE *f; 835 FILE *f;
852 gchar *path; 836 gchar *path;
853 size_t wc; 837 size_t wc;
854 838
855 if ((error_message != NULL) || (len == 0)) 839 if ((error_message != NULL) || (len == 0)) {
840 free_theme_info(user_data);
856 return; 841 return;
842 }
857 843
858 f = purple_mkstemp(&path, TRUE); 844 f = purple_mkstemp(&path, TRUE);
859 wc = fwrite(themedata, len, 1, f); 845 wc = fwrite(themedata, len, 1, f);
860 if (wc != 1) { 846 if (wc != 1) {
861 purple_debug_warning("theme_got_url", "Unable to write theme data.\n"); 847 purple_debug_warning("theme_got_url", "Unable to write theme data.\n");
862 fclose(f); 848 fclose(f);
863 g_unlink(path); 849 g_unlink(path);
864 g_free(path); 850 g_free(path);
851 free_theme_info(user_data);
865 return; 852 return;
866 } 853 }
867 fclose(f); 854 fclose(f);
868 855
869 theme_install_theme(path, user_data); 856 theme_install_theme(path, user_data);
895 * just untar it in the right place */ 882 * just untar it in the right place */
896 if(!(tmp = g_filename_from_uri(name, NULL, &converr))) { 883 if(!(tmp = g_filename_from_uri(name, NULL, &converr))) {
897 purple_debug(PURPLE_DEBUG_ERROR, "theme dnd", "%s\n", 884 purple_debug(PURPLE_DEBUG_ERROR, "theme dnd", "%s\n",
898 (converr ? converr->message : 885 (converr ? converr->message :
899 "g_filename_from_uri error")); 886 "g_filename_from_uri error"));
887 free_theme_info(info);
900 return; 888 return;
901 } 889 }
902 theme_install_theme(tmp, info); 890 theme_install_theme(tmp, info);
903 g_free(tmp); 891 g_free(tmp);
904 } else if (!g_ascii_strncasecmp(name, "http://", 7)) { 892 } else if (!g_ascii_strncasecmp(name, "http://", 7)) {
905 /* Oo, a web drag and drop. This is where things 893 /* Oo, a web drag and drop. This is where things
906 * will start to get interesting */ 894 * will start to get interesting */
907 purple_util_fetch_url(name, TRUE, NULL, FALSE, theme_got_url, info); 895 purple_util_fetch_url(name, TRUE, NULL, FALSE, -1, theme_got_url, info);
908 } else if (!g_ascii_strncasecmp(name, "https://", 8)) { 896 } else if (!g_ascii_strncasecmp(name, "https://", 8)) {
909 /* purple_util_fetch_url() doesn't support HTTPS, but we want users 897 /* purple_util_fetch_url() doesn't support HTTPS, but we want users
910 * to be able to drag and drop links from the SF trackers, so 898 * to be able to drag and drop links from the SF trackers, so
911 * we'll try it as an HTTP URL. */ 899 * we'll try it as an HTTP URL. */
912 char *tmp = g_strdup(name + 1); 900 char *tmp = g_strdup(name + 1);
913 tmp[0] = 'h'; 901 tmp[0] = 'h';
914 tmp[1] = 't'; 902 tmp[1] = 't';
915 tmp[2] = 't'; 903 tmp[2] = 't';
916 tmp[3] = 'p'; 904 tmp[3] = 'p';
917 905
918 purple_util_fetch_url(tmp, TRUE, NULL, FALSE, theme_got_url, info); 906 purple_util_fetch_url(tmp, TRUE, NULL, FALSE, -1, theme_got_url, info);
919 g_free(tmp); 907 g_free(tmp);
920 } 908 } else
909 free_theme_info(info);
921 910
922 gtk_drag_finish(dc, TRUE, FALSE, t); 911 gtk_drag_finish(dc, TRUE, FALSE, t);
923 } 912 }
924 913
925 gtk_drag_finish(dc, FALSE, FALSE, t); 914 gtk_drag_finish(dc, FALSE, FALSE, t);
926 } 915 }
927 916
928 /* builds a theme combo box from a list store with colums: icon preview, markup, theme name */ 917 /* builds a theme combo box from a list store with colums: icon preview, markup, theme name */
929 static GtkWidget * 918 static GtkWidget *
930 prefs_build_theme_combo_box(GtkListStore *store, const gchar *current_theme, gchar *type) 919 prefs_build_theme_combo_box(GtkListStore *store, const char *current_theme, const char *type)
931 { 920 {
932 GtkCellRenderer *cell_rend; 921 GtkCellRenderer *cell_rend;
933 GtkWidget *combo_box; 922 GtkWidget *combo_box;
934 GtkTargetEntry te[3] = {{"text/plain", 0, 0},{"text/uri-list", 0, 1},{"STRING", 0, 2}}; 923 GtkTargetEntry te[3] = {
924 {"text/plain", 0, 0},
925 {"text/uri-list", 0, 1},
926 {"STRING", 0, 2}
927 };
935 928
936 g_return_val_if_fail(store != NULL && current_theme != NULL, NULL); 929 g_return_val_if_fail(store != NULL && current_theme != NULL, NULL);
937 930
938 combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); 931 combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
939 932
941 gtk_cell_renderer_set_fixed_size(cell_rend, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE); 934 gtk_cell_renderer_set_fixed_size(cell_rend, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE);
942 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, FALSE); 935 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, FALSE);
943 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "pixbuf", 0, NULL); 936 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "pixbuf", 0, NULL);
944 937
945 cell_rend = gtk_cell_renderer_text_new(); 938 cell_rend = gtk_cell_renderer_text_new();
946 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, FALSE); 939 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, TRUE);
947 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "markup", 1, NULL); 940 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "markup", 1, NULL);
948 /*#if GTK_CHECK_VERSION(2,6,0) 941 g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
949 g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
950 #endif*/
951 942
952 gtk_drag_dest_set(combo_box, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te, 943 gtk_drag_dest_set(combo_box, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te,
953 sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE); 944 sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE);
954 945
955 g_signal_connect(G_OBJECT(combo_box), "drag_data_received", G_CALLBACK(theme_dnd_recv), type); 946 g_signal_connect(G_OBJECT(combo_box), "drag_data_received", G_CALLBACK(theme_dnd_recv), (gpointer) type);
956 947
957 return combo_box; 948 return combo_box;
958 } 949 }
959 950
960 /* sets the current sound theme */ 951 /* sets the current sound theme */
964 gint i; 955 gint i;
965 gchar *pref; 956 gchar *pref;
966 gchar *new_theme; 957 gchar *new_theme;
967 GtkTreeIter new_iter; 958 GtkTreeIter new_iter;
968 959
969 if(gtk_combo_box_get_active_iter(combo_box, &new_iter)) { 960 if(gtk_combo_box_get_active_iter(combo_box, &new_iter) && !prefs_sound_themes_loading) {
970 961
971 gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &new_iter, 2, &new_theme, -1); 962 gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &new_iter, 2, &new_theme, -1);
972 963
973 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/sound/theme", new_theme); 964 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/sound/theme", new_theme);
974 965
975 /* New theme removes all customization */ 966 /* New theme removes all customization */
976 for(i=0; i < PURPLE_NUM_SOUNDS; i++){ 967 for(i = 0; i < PURPLE_NUM_SOUNDS; i++){
977 pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s", 968 pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s",
978 pidgin_sound_get_event_option(i)); 969 pidgin_sound_get_event_option(i));
979 purple_prefs_set_path(pref, ""); 970 purple_prefs_set_path(pref, "");
980 g_free(pref); 971 g_free(pref);
981 } 972 }
987 978
988 g_free(new_theme); 979 g_free(new_theme);
989 } 980 }
990 } 981 }
991 982
983 /* sets the current smiley theme */
984 static void
985 prefs_set_smiley_theme_cb(GtkComboBox *combo_box, gpointer user_data)
986 {
987 gchar *new_theme;
988 GtkTreeIter new_iter;
989
990 if (gtk_combo_box_get_active_iter(combo_box, &new_iter)) {
991
992 gtk_tree_model_get(GTK_TREE_MODEL(prefs_smiley_themes), &new_iter, 2, &new_theme, -1);
993
994 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/smileys/theme", new_theme);
995 pidgin_themes_smiley_themeize(sample_imhtml);
996
997 g_free(new_theme);
998 }
999 }
1000
992 1001
993 /* Does same as normal sort, except "none" is sorted first */ 1002 /* Does same as normal sort, except "none" is sorted first */
994 static gint pidgin_sort_smileys (GtkTreeModel *model, 1003 static gint pidgin_sort_smileys (GtkTreeModel *model,
995 GtkTreeIter *a, 1004 GtkTreeIter *a,
996 GtkTreeIter *b, 1005 GtkTreeIter *b,
997 gpointer userdata) 1006 gpointer userdata)
998 { 1007 {
999 gint ret = 0; 1008 gint ret = 0;
1000 gchar *name1 = NULL, *name2 = NULL; 1009 gchar *name1 = NULL, *name2 = NULL;
1001 1010
1002 gtk_tree_model_get(model, a, 3, &name1, -1); 1011 gtk_tree_model_get(model, a, 2, &name1, -1);
1003 gtk_tree_model_get(model, b, 3, &name2, -1); 1012 gtk_tree_model_get(model, b, 2, &name2, -1);
1004 1013
1005 if (name1 == NULL || name2 == NULL) { 1014 if (name1 == NULL || name2 == NULL) {
1006 if (!(name1 == NULL && name2 == NULL)) 1015 if (!(name1 == NULL && name2 == NULL))
1007 ret = (name1 == NULL) ? -1: 1; 1016 ret = (name1 == NULL) ? -1: 1;
1008 } else if (!g_ascii_strcasecmp(name1, "none")) { 1017 } else if (!g_ascii_strcasecmp(name1, "none")) {
1014 } else if (!g_ascii_strcasecmp(name2, "none")) { 1023 } else if (!g_ascii_strcasecmp(name2, "none")) {
1015 /* Sort name2 first */ 1024 /* Sort name2 first */
1016 ret = 1; 1025 ret = 1;
1017 } else { 1026 } else {
1018 /* Neither string is "none", default to normal sort */ 1027 /* Neither string is "none", default to normal sort */
1019 ret = purple_utf8_strcasecmp(name1,name2); 1028 ret = purple_utf8_strcasecmp(name1, name2);
1020 } 1029 }
1021 1030
1022 g_free(name1); 1031 g_free(name1);
1023 g_free(name2); 1032 g_free(name2);
1024 1033
1025 return ret; 1034 return ret;
1026 } 1035 }
1027 1036
1028 static void 1037 /* sets the current buddy list theme */
1029 request_theme_file_name_cb(gpointer data, char *theme_file_name) 1038 static void
1030 { 1039 prefs_set_blist_theme_cb(GtkComboBox *combo_box, gpointer user_data)
1031 struct theme_info *info = g_new0(struct theme_info, 1); 1040 {
1032 info->type = g_strdup("smiley"); 1041 PidginBlistTheme *theme = NULL;
1033 info->extension = NULL; 1042 GtkTreeIter iter;
1034 info->original_name = NULL; 1043 gchar *name = NULL;
1035 1044
1036 theme_install_theme(theme_file_name, info); 1045 if(gtk_combo_box_get_active_iter(combo_box, &iter)) {
1037 } 1046
1038 1047 gtk_tree_model_get(GTK_TREE_MODEL(prefs_blist_themes), &iter, 2, &name, -1);
1039 static void 1048
1040 add_theme_button_clicked_cb(GtkWidget *widget, gpointer user_data) 1049 if(!name || !g_str_equal(name, ""))
1041 { 1050 theme = PIDGIN_BLIST_THEME(purple_theme_manager_find_theme(name, "blist"));
1042 purple_request_file(NULL, _("Install Theme"), NULL, FALSE, (GCallback)request_theme_file_name_cb, NULL, NULL, NULL, NULL, NULL); 1051
1043 } 1052 g_free(name);
1044 1053
1045 static void 1054 pidgin_blist_set_theme(theme);
1046 remove_theme_button_clicked_cb(GtkWidget *button, GtkTreeView *tv) 1055 }
1047 { 1056 }
1048 char *theme_name = NULL, *theme_file = NULL; 1057
1049 GtkTreeModel *tm; 1058 /* sets the current conversation theme */
1050 GtkTreeIter itr; 1059 static void
1051 GtkTreeRowReference *trr = NULL; 1060 prefs_set_conv_theme_cb(GtkComboBox *combo_box, gpointer user_data)
1052 1061 {
1053 if ((tm = gtk_tree_view_get_model(tv)) == NULL) 1062 PidginConvTheme *theme = NULL;
1054 return; 1063 GtkTreeIter iter;
1055 if (!gtk_tree_selection_get_selected(smiley_theme_sel, NULL, &itr)) 1064 gchar *name = NULL;
1056 return; 1065
1057 gtk_tree_model_get(tm, &itr, 2, &theme_file, 3, &theme_name, -1); 1066 if (gtk_combo_box_get_active_iter(combo_box, &iter)) {
1058 1067 const GList *variants;
1059 if (theme_file && theme_name && strcmp(theme_name, "none")) 1068 const char *current_variant;
1060 pidgin_themes_remove_smiley_theme(theme_file); 1069 gboolean unset = TRUE;
1061 1070
1062 if ((trr = theme_refresh_theme_list()) != NULL) { 1071 gtk_tree_model_get(GTK_TREE_MODEL(prefs_conv_themes), &iter, 2, &name, -1);
1063 GtkTreePath *tp = gtk_tree_row_reference_get_path(trr); 1072 if (!name || !*name) {
1064 1073 g_free(name);
1065 if (tp) { 1074 return;
1066 gtk_tree_selection_select_path(smiley_theme_sel, tp);
1067 gtk_tree_path_free(tp);
1068 } 1075 }
1069 gtk_tree_row_reference_free(trr); 1076
1070 } 1077 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/theme", name);
1071 1078
1072 g_free(theme_file); 1079 /* Update list of variants */
1073 g_free(theme_name); 1080 gtk_list_store_clear(prefs_conv_variants);
1081
1082 theme = PIDGIN_CONV_THEME(purple_theme_manager_find_theme(name, "conversation"));
1083 current_variant = pidgin_conversation_theme_get_variant(theme);
1084
1085 variants = pidgin_conversation_theme_get_variants(theme);
1086 for (; variants && current_variant; variants = g_list_next(variants)) {
1087 gtk_list_store_append(prefs_conv_variants, &iter);
1088 gtk_list_store_set(prefs_conv_variants, &iter, 0, variants->data, -1);
1089
1090 if (g_str_equal(variants->data, current_variant)) {
1091 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(prefs_conv_variants_combo_box), &iter);
1092 unset = FALSE;
1093 }
1094 }
1095
1096 if (unset)
1097 gtk_combo_box_set_active(GTK_COMBO_BOX(prefs_conv_variants_combo_box), 0);
1098
1099 g_free(name);
1100 }
1101 }
1102
1103 /* sets the current conversation theme variant */
1104 static void
1105 prefs_set_conv_variant_cb(GtkComboBox *combo_box, gpointer user_data)
1106 {
1107 PidginConvTheme *theme = NULL;
1108 GtkTreeIter iter;
1109 gchar *name = NULL;
1110
1111 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(prefs_conv_themes_combo_box), &iter)) {
1112 gtk_tree_model_get(GTK_TREE_MODEL(prefs_conv_themes), &iter, 2, &name, -1);
1113 theme = PIDGIN_CONV_THEME(purple_theme_manager_find_theme(name, "conversation"));
1114 g_free(name);
1115
1116 if (gtk_combo_box_get_active_iter(combo_box, &iter)) {
1117 gtk_tree_model_get(GTK_TREE_MODEL(prefs_conv_variants), &iter, 0, &name, -1);
1118 pidgin_conversation_theme_set_variant(theme, name);
1119 g_free(name);
1120 }
1121 }
1122 }
1123
1124 /* sets the current icon theme */
1125 static void
1126 prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data)
1127 {
1128 PidginStatusIconTheme *theme = NULL;
1129 GtkTreeIter iter;
1130 gchar *name = NULL;
1131
1132 if(gtk_combo_box_get_active_iter(combo_box, &iter)) {
1133
1134 gtk_tree_model_get(GTK_TREE_MODEL(prefs_status_icon_themes), &iter, 2, &name, -1);
1135
1136 if(!name || !g_str_equal(name, ""))
1137 theme = PIDGIN_STATUS_ICON_THEME(purple_theme_manager_find_theme(name, "status-icon"));
1138
1139 g_free(name);
1140
1141 pidgin_stock_load_status_icon_theme(theme);
1142 pidgin_blist_refresh(purple_get_blist());
1143 }
1144 }
1145
1146 static GtkWidget *
1147 add_theme_prefs_combo(GtkWidget *vbox,
1148 GtkSizeGroup *combo_sg, GtkSizeGroup *label_sg,
1149 GtkListStore *theme_store,
1150 GCallback combo_box_cb, gpointer combo_box_cb_user_data,
1151 const char *label_str, const char *prefs_path,
1152 const char *theme_type)
1153 {
1154 GtkWidget *label;
1155 GtkWidget *combo_box = NULL;
1156 GtkWidget *themesel_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
1157
1158 label = gtk_label_new(label_str);
1159 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1160 gtk_size_group_add_widget(label_sg, label);
1161 gtk_box_pack_start(GTK_BOX(themesel_hbox), label, FALSE, FALSE, 0);
1162
1163 combo_box = prefs_build_theme_combo_box(theme_store,
1164 purple_prefs_get_string(prefs_path),
1165 theme_type);
1166 g_signal_connect(G_OBJECT(combo_box), "changed",
1167 (GCallback)combo_box_cb, combo_box_cb_user_data);
1168 gtk_size_group_add_widget(combo_sg, combo_box);
1169 gtk_box_pack_start(GTK_BOX(themesel_hbox), combo_box, TRUE, TRUE, 0);
1170
1171 gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
1172
1173 return combo_box;
1174 }
1175
1176 static GtkWidget *
1177 add_child_theme_prefs_combo(GtkWidget *vbox, GtkSizeGroup *combo_sg,
1178 GtkSizeGroup *label_sg, GtkListStore *theme_store,
1179 GCallback combo_box_cb, gpointer combo_box_cb_user_data,
1180 const char *label_str)
1181 {
1182 GtkWidget *label;
1183 GtkWidget *combo_box;
1184 GtkWidget *themesel_hbox;
1185 GtkCellRenderer *cell_rend;
1186
1187 themesel_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
1188 gtk_box_pack_start(GTK_BOX(vbox), themesel_hbox, FALSE, FALSE, 0);
1189
1190 label = gtk_label_new(label_str);
1191 gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
1192 gtk_size_group_add_widget(label_sg, label);
1193 gtk_box_pack_start(GTK_BOX(themesel_hbox), label, FALSE, FALSE, 0);
1194
1195 combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(theme_store));
1196
1197 cell_rend = gtk_cell_renderer_text_new();
1198 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell_rend, TRUE);
1199 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "text", 0, NULL);
1200 g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
1201
1202 g_signal_connect(G_OBJECT(combo_box), "changed",
1203 (GCallback)combo_box_cb, combo_box_cb_user_data);
1204 gtk_size_group_add_widget(combo_sg, combo_box);
1205 gtk_box_pack_start(GTK_BOX(themesel_hbox), combo_box, TRUE, TRUE, 0);
1206
1207 return combo_box;
1074 } 1208 }
1075 1209
1076 static GtkWidget * 1210 static GtkWidget *
1077 theme_page(void) 1211 theme_page(void)
1078 { 1212 {
1079 GtkWidget *add_button, *remove_button;
1080 GtkWidget *hbox_buttons;
1081 GtkWidget *alignment;
1082 GtkWidget *ret;
1083 GtkWidget *sw;
1084 GtkWidget *view;
1085 GtkCellRenderer *rend;
1086 GtkTreeViewColumn *col;
1087 GtkTreeSelection *sel;
1088 GtkTreeRowReference *rowref;
1089 GtkWidget *label; 1213 GtkWidget *label;
1090 GtkTargetEntry te[3] = {{"text/plain", 0, 0},{"text/uri-list", 0, 1},{"STRING", 0, 2}}; 1214 GtkWidget *ret, *vbox;
1215 GtkSizeGroup *label_sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1216 GtkSizeGroup *combo_sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1091 1217
1092 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); 1218 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
1093 gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER); 1219 gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER);
1094 1220
1095 label = gtk_label_new(_("Select a smiley theme that you would like to use from the list below. New themes can be installed by dragging and dropping them onto the theme list.")); 1221 vbox = pidgin_make_frame(ret, _("Theme Selections"));
1096 1222
1097 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); 1223 /* Instructions */
1224 label = gtk_label_new(_("Select a theme that you would like to use from "
1225 "the lists below.\nNew themes can be installed by "
1226 "dragging and dropping them onto the theme list."));
1227
1098 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); 1228 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1099 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); 1229 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
1100 1230
1101 gtk_box_pack_start(GTK_BOX(ret), label, FALSE, TRUE, 0); 1231 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, FALSE, 0);
1102 gtk_widget_show(label); 1232 gtk_widget_show(label);
1103 1233
1104 sw = gtk_scrolled_window_new(NULL,NULL); 1234 /* Buddy List Themes */
1105 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); 1235 prefs_blist_themes_combo_box = add_theme_prefs_combo(
1106 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); 1236 vbox, combo_sg, label_sg, prefs_blist_themes,
1107 1237 (GCallback)prefs_set_blist_theme_cb, NULL,
1108 gtk_box_pack_start(GTK_BOX(ret), sw, TRUE, TRUE, 0); 1238 _("Buddy List Theme:"), PIDGIN_PREFS_ROOT "/blist/theme", "blist");
1109 smiley_theme_store = gtk_list_store_new (4, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); 1239
1110 1240 /* Conversation Themes */
1111 rowref = theme_refresh_theme_list(); 1241 prefs_conv_themes_combo_box = add_theme_prefs_combo(
1112 1242 vbox, combo_sg, label_sg, prefs_conv_themes,
1113 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(smiley_theme_store)); 1243 (GCallback)prefs_set_conv_theme_cb, NULL,
1114 1244 _("Conversation Theme:"), PIDGIN_PREFS_ROOT "/conversations/theme", "conversation");
1115 gtk_drag_dest_set(view, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te, 1245
1116 sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE); 1246 /* Conversation Theme Variants */
1117 1247 prefs_conv_variants_combo_box = add_child_theme_prefs_combo(
1118 g_signal_connect(G_OBJECT(view), "drag_data_received", G_CALLBACK(theme_dnd_recv), "smiley"); 1248 vbox, combo_sg, label_sg, prefs_conv_variants,
1119 1249 (GCallback)prefs_set_conv_variant_cb, NULL, _("\tVariant:"));
1120 rend = gtk_cell_renderer_pixbuf_new(); 1250
1121 smiley_theme_sel = sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); 1251 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(prefs_conv_variants),
1252 0, GTK_SORT_ASCENDING);
1253
1254 /* Status Icon Themes */
1255 prefs_status_themes_combo_box = add_theme_prefs_combo(
1256 vbox, combo_sg, label_sg, prefs_status_icon_themes,
1257 (GCallback)prefs_set_status_icon_theme_cb, NULL,
1258 _("Status Icon Theme:"), PIDGIN_PREFS_ROOT "/status/icon-theme", "icon");
1259
1260 /* Sound Themes */
1261 prefs_sound_themes_combo_box = add_theme_prefs_combo(
1262 vbox, combo_sg, label_sg, prefs_sound_themes,
1263 (GCallback)prefs_set_sound_theme_cb, NULL,
1264 _("Sound Theme:"), PIDGIN_PREFS_ROOT "/sound/theme", "sound");
1265
1266 /* Smiley Themes */
1267 prefs_smiley_themes_combo_box = add_theme_prefs_combo(
1268 vbox, combo_sg, label_sg, prefs_smiley_themes,
1269 (GCallback)prefs_set_smiley_theme_cb, NULL,
1270 _("Smiley Theme:"), PIDGIN_PREFS_ROOT "/smileys/theme", "smiley");
1122 1271
1123 /* Custom sort so "none" theme is at top of list */ 1272 /* Custom sort so "none" theme is at top of list */
1124 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(smiley_theme_store), 1273 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(prefs_smiley_themes),
1125 3, pidgin_sort_smileys, NULL, NULL); 1274 2, pidgin_sort_smileys, NULL, NULL);
1126 1275 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(prefs_smiley_themes),
1127 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(smiley_theme_store), 1276 2, GTK_SORT_ASCENDING);
1128 3, GTK_SORT_ASCENDING);
1129
1130 col = gtk_tree_view_column_new_with_attributes (_("Icon"),
1131 rend,
1132 "pixbuf", 0,
1133 NULL);
1134 gtk_tree_view_append_column (GTK_TREE_VIEW(view), col);
1135
1136 rend = gtk_cell_renderer_text_new();
1137 col = gtk_tree_view_column_new_with_attributes (_("Description"),
1138 rend,
1139 "markup", 1,
1140 NULL);
1141 gtk_tree_view_append_column (GTK_TREE_VIEW(view), col);
1142 g_object_unref(G_OBJECT(smiley_theme_store));
1143 gtk_container_add(GTK_CONTAINER(sw), view);
1144
1145 g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(smiley_sel), NULL);
1146
1147 alignment = gtk_alignment_new(1.0, 0.5, 0.0, 1.0);
1148 gtk_widget_show(alignment);
1149 gtk_box_pack_start(GTK_BOX(ret), alignment, FALSE, TRUE, 0);
1150
1151 hbox_buttons = gtk_hbox_new(TRUE, PIDGIN_HIG_CAT_SPACE);
1152 gtk_widget_show(hbox_buttons);
1153 gtk_container_add(GTK_CONTAINER(alignment), hbox_buttons);
1154
1155 add_button = gtk_button_new_from_stock(GTK_STOCK_ADD);
1156 gtk_widget_show(add_button);
1157 gtk_box_pack_start(GTK_BOX(hbox_buttons), add_button, FALSE, TRUE, 0);
1158 g_signal_connect(G_OBJECT(add_button), "clicked", (GCallback)add_theme_button_clicked_cb, view);
1159
1160 remove_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
1161 gtk_widget_show(remove_button);
1162 gtk_box_pack_start(GTK_BOX(hbox_buttons), remove_button, FALSE, TRUE, 0);
1163 g_signal_connect(G_OBJECT(remove_button), "clicked", (GCallback)remove_theme_button_clicked_cb, view);
1164 g_object_set_data(G_OBJECT(sel), "remove_button", remove_button);
1165
1166 if (rowref) {
1167 GtkTreePath *path = gtk_tree_row_reference_get_path(rowref);
1168 gtk_tree_row_reference_free(rowref);
1169 gtk_tree_selection_select_path(sel, path);
1170 gtk_tree_path_free(path);
1171 }
1172 1277
1173 gtk_widget_show_all(ret); 1278 gtk_widget_show_all(ret);
1174
1175 pidgin_set_accessible_label (view, label);
1176 1279
1177 return ret; 1280 return ret;
1178 } 1281 }
1179 1282
1180 static void 1283 static void
1369 G_CALLBACK(conversation_close_accel_changed_cb), checkbox, (GConnectFlags)0); 1472 G_CALLBACK(conversation_close_accel_changed_cb), checkbox, (GConnectFlags)0);
1370 1473
1371 gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE, 0); 1474 gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE, 0);
1372 } 1475 }
1373 1476
1374 /* sets the current buddy list theme */
1375 static void
1376 prefs_set_blist_theme_cb(GtkComboBox *combo_box, gpointer user_data)
1377 {
1378 PidginBlistTheme *theme = NULL;
1379 GtkTreeIter iter;
1380 gchar *name = NULL;
1381
1382 if(gtk_combo_box_get_active_iter(combo_box, &iter)) {
1383
1384 gtk_tree_model_get(GTK_TREE_MODEL(prefs_blist_themes), &iter, 2, &name, -1);
1385
1386 if(!name || !g_str_equal(name, ""))
1387 theme = PIDGIN_BLIST_THEME(purple_theme_manager_find_theme(name, "blist"));
1388
1389 g_free(name);
1390
1391 pidgin_blist_set_theme(theme);
1392 }
1393 }
1394
1395 /* sets the current icon theme */
1396 static void
1397 prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data)
1398 {
1399 PidginStatusIconTheme *theme = NULL;
1400 GtkTreeIter iter;
1401 gchar *name = NULL;
1402
1403 if(gtk_combo_box_get_active_iter(combo_box, &iter)) {
1404
1405 gtk_tree_model_get(GTK_TREE_MODEL(prefs_status_icon_themes), &iter, 2, &name, -1);
1406
1407 if(!name || !g_str_equal(name, ""))
1408 theme = PIDGIN_STATUS_ICON_THEME(purple_theme_manager_find_theme(name, "status-icon"));
1409
1410 g_free(name);
1411
1412 pidgin_stock_load_status_icon_theme(theme);
1413 }
1414 }
1415
1416 static GtkWidget * 1477 static GtkWidget *
1417 interface_page(void) 1478 interface_page(void)
1418 { 1479 {
1419 GtkWidget *ret; 1480 GtkWidget *ret;
1420 GtkWidget *vbox; 1481 GtkWidget *vbox;
1425 1486
1426 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); 1487 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
1427 gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER); 1488 gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER);
1428 1489
1429 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); 1490 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1430
1431 /* Buddy List Themes */
1432 vbox = pidgin_make_frame(ret, _("Buddy List Theme"));
1433
1434 prefs_blist_themes_combo_box = prefs_build_theme_combo_box(prefs_blist_themes,
1435 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme"),
1436 "blist");
1437
1438 gtk_box_pack_start(GTK_BOX (vbox), prefs_blist_themes_combo_box, FALSE, FALSE, 0);
1439 g_signal_connect(G_OBJECT(prefs_blist_themes_combo_box), "changed", (GCallback)prefs_set_blist_theme_cb, NULL);
1440
1441 /* Status Icon Themes */
1442 prefs_status_themes_combo_box = prefs_build_theme_combo_box(prefs_status_icon_themes,
1443 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme"),
1444 "icon");
1445
1446 gtk_box_pack_start(GTK_BOX (vbox), prefs_status_themes_combo_box, FALSE, FALSE, 0);
1447 g_signal_connect(G_OBJECT(prefs_status_themes_combo_box), "changed", (GCallback)prefs_set_status_icon_theme_cb, NULL);
1448 1491
1449 /* System Tray */ 1492 /* System Tray */
1450 vbox = pidgin_make_frame(ret, _("System Tray Icon")); 1493 vbox = pidgin_make_frame(ret, _("System Tray Icon"));
1451 label = pidgin_prefs_dropdown(vbox, _("_Show system tray icon:"), PURPLE_PREF_STRING, 1494 label = pidgin_prefs_dropdown(vbox, _("_Show system tray icon:"), PURPLE_PREF_STRING,
1452 PIDGIN_PREFS_ROOT "/docklet/show", 1495 PIDGIN_PREFS_ROOT "/docklet/show",
1495 PIDGIN_PREFS_ROOT "/conversations/tab_side", 1538 PIDGIN_PREFS_ROOT "/conversations/tab_side",
1496 _("Top"), GTK_POS_TOP, 1539 _("Top"), GTK_POS_TOP,
1497 _("Bottom"), GTK_POS_BOTTOM, 1540 _("Bottom"), GTK_POS_BOTTOM,
1498 _("Left"), GTK_POS_LEFT, 1541 _("Left"), GTK_POS_LEFT,
1499 _("Right"), GTK_POS_RIGHT, 1542 _("Right"), GTK_POS_RIGHT,
1500 #if GTK_CHECK_VERSION(2,6,0)
1501 _("Left Vertical"), GTK_POS_LEFT|8, 1543 _("Left Vertical"), GTK_POS_LEFT|8,
1502 _("Right Vertical"), GTK_POS_RIGHT|8, 1544 _("Right Vertical"), GTK_POS_RIGHT|8,
1503 #endif
1504 NULL); 1545 NULL);
1505 gtk_size_group_add_widget(sg, label); 1546 gtk_size_group_add_widget(sg, label);
1506 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); 1547 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1507 1548
1508 names = pidgin_conv_placement_get_options(); 1549 names = pidgin_conv_placement_get_options();
1519 gtk_widget_show_all(ret); 1560 gtk_widget_show_all(ret);
1520 g_object_unref(sg); 1561 g_object_unref(sg);
1521 return ret; 1562 return ret;
1522 } 1563 }
1523 1564
1524 #if GTK_CHECK_VERSION(2,4,0) 1565 #ifdef _WIN32
1566 static void
1567 apply_custom_font(void)
1568 {
1569 PangoFontDescription *desc = NULL;
1570 if (!purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font")) {
1571 const char *font = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/custom_font");
1572 desc = pango_font_description_from_string(font);
1573 }
1574
1575 gtk_widget_modify_font(sample_imhtml, desc);
1576 if (desc)
1577 pango_font_description_free(desc);
1578
1579 }
1525 static void 1580 static void
1526 pidgin_custom_font_set(GtkFontButton *font_button, gpointer nul) 1581 pidgin_custom_font_set(GtkFontButton *font_button, gpointer nul)
1527 { 1582 {
1583
1528 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/custom_font", 1584 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/conversations/custom_font",
1529 gtk_font_button_get_font_name(font_button)); 1585 gtk_font_button_get_font_name(font_button));
1586
1587 apply_custom_font();
1530 } 1588 }
1531 #endif 1589 #endif
1532 1590
1533 static GtkWidget * 1591 static GtkWidget *
1534 conv_page(void) 1592 conv_page(void)
1536 GtkWidget *ret; 1594 GtkWidget *ret;
1537 GtkWidget *vbox; 1595 GtkWidget *vbox;
1538 GtkWidget *toolbar; 1596 GtkWidget *toolbar;
1539 GtkWidget *iconpref1; 1597 GtkWidget *iconpref1;
1540 GtkWidget *iconpref2; 1598 GtkWidget *iconpref2;
1541 GtkWidget *fontpref;
1542 GtkWidget *imhtml; 1599 GtkWidget *imhtml;
1543 GtkWidget *frame; 1600 GtkWidget *frame;
1544
1545 #if GTK_CHECK_VERSION(2,4,0)
1546 GtkWidget *hbox; 1601 GtkWidget *hbox;
1547 GtkWidget *font_button; 1602 GtkWidget *checkbox;
1548 const char *font_name; 1603 GtkWidget *spin_button;
1549 #endif
1550 1604
1551 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); 1605 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
1552 gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER); 1606 gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER);
1553 1607
1554 vbox = pidgin_make_frame(ret, _("Conversations")); 1608 vbox = pidgin_make_frame(ret, _("Conversations"));
1577 pidgin_prefs_checkbox(_("Use smooth-scrolling"), PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", vbox); 1631 pidgin_prefs_checkbox(_("Use smooth-scrolling"), PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", vbox);
1578 1632
1579 #ifdef _WIN32 1633 #ifdef _WIN32
1580 pidgin_prefs_checkbox(_("F_lash window when IMs are received"), PIDGIN_PREFS_ROOT "/win32/blink_im", vbox); 1634 pidgin_prefs_checkbox(_("F_lash window when IMs are received"), PIDGIN_PREFS_ROOT "/win32/blink_im", vbox);
1581 #endif 1635 #endif
1636 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
1637
1638 checkbox = pidgin_prefs_checkbox(_("Resize incoming custom smileys"),
1639 PIDGIN_PREFS_ROOT "/conversations/resize_custom_smileys", hbox);
1640
1641 spin_button = pidgin_prefs_labeled_spin_button(hbox,
1642 _("Maximum size:"),
1643 PIDGIN_PREFS_ROOT "/conversations/custom_smileys_size",
1644 16, 512, NULL);
1645
1646 if (!purple_prefs_get_bool(
1647 PIDGIN_PREFS_ROOT "/conversations/resize_custom_smileys"))
1648 gtk_widget_set_sensitive(GTK_WIDGET(spin_button), FALSE);
1649
1650 g_signal_connect(G_OBJECT(checkbox), "clicked",
1651 G_CALLBACK(pidgin_toggle_sensitive), spin_button);
1652
1653 pidgin_add_widget_to_vbox(GTK_BOX(vbox), NULL, NULL, hbox, TRUE, NULL);
1582 1654
1583 pidgin_prefs_labeled_spin_button(vbox, 1655 pidgin_prefs_labeled_spin_button(vbox,
1584 _("Minimum input area height in lines:"), 1656 _("Minimum input area height in lines:"),
1585 PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines", 1657 PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines",
1586 1, 8, NULL); 1658 1, 8, NULL);
1587 1659
1588 #if GTK_CHECK_VERSION(2,4,0) 1660 #ifdef _WIN32
1661 {
1662 GtkWidget *fontpref, *font_button, *hbox;
1663 const char *font_name;
1589 vbox = pidgin_make_frame(ret, _("Font")); 1664 vbox = pidgin_make_frame(ret, _("Font"));
1590 if (purple_running_gnome()) 1665
1591 fontpref = pidgin_prefs_checkbox(_("Use document font from _theme"), PIDGIN_PREFS_ROOT "/conversations/use_theme_font", vbox); 1666 fontpref = pidgin_prefs_checkbox(_("Use font from _theme"),
1592 else 1667 PIDGIN_PREFS_ROOT "/conversations/use_theme_font", vbox);
1593 fontpref = pidgin_prefs_checkbox(_("Use font from _theme"), PIDGIN_PREFS_ROOT "/conversations/use_theme_font", vbox);
1594 1668
1595 font_name = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/custom_font"); 1669 font_name = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/custom_font");
1596 if ((font_name == NULL) || (*font_name == '\0')) { 1670 if ((font_name == NULL) || (*font_name == '\0')) {
1597 font_button = gtk_font_button_new(); 1671 font_button = gtk_font_button_new();
1598 } else { 1672 } else {
1602 gtk_font_button_set_show_style(GTK_FONT_BUTTON(font_button), TRUE); 1676 gtk_font_button_set_show_style(GTK_FONT_BUTTON(font_button), TRUE);
1603 hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Conversation _font:"), NULL, font_button, FALSE, NULL); 1677 hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Conversation _font:"), NULL, font_button, FALSE, NULL);
1604 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font")) 1678 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font"))
1605 gtk_widget_set_sensitive(hbox, FALSE); 1679 gtk_widget_set_sensitive(hbox, FALSE);
1606 g_signal_connect(G_OBJECT(fontpref), "clicked", G_CALLBACK(pidgin_toggle_sensitive), hbox); 1680 g_signal_connect(G_OBJECT(fontpref), "clicked", G_CALLBACK(pidgin_toggle_sensitive), hbox);
1681 g_signal_connect(G_OBJECT(fontpref), "clicked", G_CALLBACK(apply_custom_font), hbox);
1607 g_signal_connect(G_OBJECT(font_button), "font-set", G_CALLBACK(pidgin_custom_font_set), NULL); 1682 g_signal_connect(G_OBJECT(font_button), "font-set", G_CALLBACK(pidgin_custom_font_set), NULL);
1683
1684 }
1608 #endif 1685 #endif
1609 1686
1610 vbox = pidgin_make_frame(ret, _("Default Formatting")); 1687 vbox = pidgin_make_frame(ret, _("Default Formatting"));
1611 gtk_box_set_child_packing(GTK_BOX(vbox->parent), vbox, TRUE, TRUE, 0, GTK_PACK_START);
1612 1688
1613 frame = pidgin_create_imhtml(TRUE, &imhtml, &toolbar, NULL); 1689 frame = pidgin_create_imhtml(TRUE, &imhtml, &toolbar, NULL);
1614 gtk_widget_show(frame); 1690 gtk_widget_show(frame);
1615 gtk_widget_set_name(imhtml, "pidgin_prefs_font_imhtml"); 1691 gtk_widget_set_name(imhtml, "pidgin_prefs_font_imhtml");
1616 gtk_widget_set_size_request(frame, 300, -1); 1692 gtk_widget_set_size_request(frame, 450, -1);
1617 gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(imhtml), TRUE); 1693 gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(imhtml), TRUE);
1618 gtk_imhtml_set_format_functions(GTK_IMHTML(imhtml), 1694 gtk_imhtml_set_format_functions(GTK_IMHTML(imhtml),
1619 GTK_IMHTML_BOLD | 1695 GTK_IMHTML_BOLD |
1620 GTK_IMHTML_ITALIC | 1696 GTK_IMHTML_ITALIC |
1621 GTK_IMHTML_UNDERLINE | 1697 GTK_IMHTML_UNDERLINE |
1634 1710
1635 g_signal_connect_after(G_OBJECT(imhtml), "format_function_toggle", 1711 g_signal_connect_after(G_OBJECT(imhtml), "format_function_toggle",
1636 G_CALLBACK(formatting_toggle_cb), toolbar); 1712 G_CALLBACK(formatting_toggle_cb), toolbar);
1637 g_signal_connect_after(G_OBJECT(imhtml), "format_function_clear", 1713 g_signal_connect_after(G_OBJECT(imhtml), "format_function_clear",
1638 G_CALLBACK(formatting_clear_cb), NULL); 1714 G_CALLBACK(formatting_clear_cb), NULL);
1639 1715 sample_imhtml = imhtml;
1640 1716
1641 gtk_widget_show(ret); 1717 gtk_widget_show(ret);
1642 1718
1643 return ret; 1719 return ret;
1644 } 1720 }
1719 else if (entrynum == PROXYPASS) 1795 else if (entrynum == PROXYPASS)
1720 purple_prefs_set_string("/purple/proxy/password", gtk_entry_get_text(entry)); 1796 purple_prefs_set_string("/purple/proxy/password", gtk_entry_get_text(entry));
1721 } 1797 }
1722 1798
1723 static void 1799 static void
1724 proxy_button_clicked_cb(GtkWidget *button, gpointer null) 1800 proxy_button_clicked_cb(GtkWidget *button, gchar *program)
1725 { 1801 {
1726 GError *err = NULL; 1802 GError *err = NULL;
1727 1803
1728 if (g_spawn_command_line_async ("gnome-network-preferences", &err)) 1804 if (g_spawn_command_line_async(program, &err))
1729 return; 1805 return;
1730 1806
1731 purple_notify_error(NULL, NULL, _("Cannot start proxy configuration program."), err->message); 1807 purple_notify_error(NULL, NULL, _("Cannot start proxy configuration program."), err->message);
1732 g_error_free(err); 1808 g_error_free(err);
1733 } 1809 }
1734 1810
1811 #ifndef _WIN32
1735 static void 1812 static void
1736 browser_button_clicked_cb(GtkWidget *button, gpointer null) 1813 browser_button_clicked_cb(GtkWidget *button, gpointer null)
1737 { 1814 {
1738 GError *err = NULL; 1815 GError *err = NULL;
1739 1816
1741 return; 1818 return;
1742 1819
1743 purple_notify_error(NULL, NULL, _("Cannot start browser configuration program."), err->message); 1820 purple_notify_error(NULL, NULL, _("Cannot start browser configuration program."), err->message);
1744 g_error_free(err); 1821 g_error_free(err);
1745 } 1822 }
1746 1823 #endif
1747 static GtkWidget * 1824
1748 network_page(void) 1825 static void
1749 { 1826 auto_ip_button_clicked_cb(GtkWidget *button, gpointer null)
1750 GtkWidget *ret; 1827 {
1751 GtkWidget *vbox, *hbox, *entry;
1752 GtkWidget *table, *label, *auto_ip_checkbox, *ports_checkbox, *spin_button;
1753 GtkWidget *proxy_warning = NULL, *browser_warning = NULL;
1754 GtkWidget *proxy_button = NULL, *browser_button = NULL;
1755 GtkSizeGroup *sg;
1756 PurpleProxyInfo *proxy_info = NULL;
1757 const char *ip; 1828 const char *ip;
1758 PurpleStunNatDiscovery *stun; 1829 PurpleStunNatDiscovery *stun;
1759 char *auto_ip_text; 1830 char *auto_ip_text;
1831
1832 /* purple_network_get_my_ip will return the IP that was set by the user with
1833 purple_network_set_public_ip, so make a lookup for the auto-detected IP
1834 ourselves. */
1835
1836 if (purple_prefs_get_bool("/purple/network/auto_ip")) {
1837 /* Check if STUN discovery was already done */
1838 stun = purple_stun_discover(NULL);
1839 if ((stun != NULL) && (stun->status == PURPLE_STUN_STATUS_DISCOVERED)) {
1840 ip = stun->publicip;
1841 } else {
1842 /* Attempt to get the IP from a NAT device using UPnP */
1843 ip = purple_upnp_get_public_ip();
1844 if (ip == NULL) {
1845 /* Attempt to get the IP from a NAT device using NAT-PMP */
1846 ip = purple_pmp_get_public_ip();
1847 if (ip == NULL) {
1848 /* Just fetch the IP of the local system */
1849 ip = purple_network_get_local_system_ip(-1);
1850 }
1851 }
1852 }
1853 }
1854 else
1855 ip = _("Disabled");
1856
1857 auto_ip_text = g_strdup_printf(_("Use _automatically detected IP address: %s"), ip);
1858 gtk_button_set_label(GTK_BUTTON(button), auto_ip_text);
1859 g_free(auto_ip_text);
1860 }
1861
1862 static GtkWidget *
1863 network_page(void)
1864 {
1865 GtkWidget *ret;
1866 GtkWidget *vbox, *hbox, *entry;
1867 GtkWidget *label, *auto_ip_checkbox, *ports_checkbox, *spin_button;
1868 GtkSizeGroup *sg;
1760 1869
1761 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); 1870 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
1762 gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER); 1871 gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER);
1763 1872
1764 vbox = pidgin_make_frame (ret, _("IP Address")); 1873 vbox = pidgin_make_frame (ret, _("IP Address"));
1769 "/purple/network/stun_server")); 1878 "/purple/network/stun_server"));
1770 g_signal_connect(G_OBJECT(entry), "focus-out-event", 1879 g_signal_connect(G_OBJECT(entry), "focus-out-event",
1771 G_CALLBACK(network_stun_server_changed_cb), NULL); 1880 G_CALLBACK(network_stun_server_changed_cb), NULL);
1772 gtk_widget_show(entry); 1881 gtk_widget_show(entry);
1773 1882
1774 pidgin_add_widget_to_vbox(GTK_BOX(vbox), "ST_UN server:", 1883 pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("ST_UN server:"),
1775 sg, entry, TRUE, NULL); 1884 sg, entry, TRUE, NULL);
1776 1885
1777 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); 1886 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
1778 gtk_container_add(GTK_CONTAINER(vbox), hbox); 1887 gtk_container_add(GTK_CONTAINER(vbox), hbox);
1779 1888
1785 gtk_label_set_markup(GTK_LABEL(label), 1894 gtk_label_set_markup(GTK_LABEL(label),
1786 _("<span style=\"italic\">Example: stunserver.org</span>")); 1895 _("<span style=\"italic\">Example: stunserver.org</span>"));
1787 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); 1896 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1788 gtk_container_add(GTK_CONTAINER(hbox), label); 1897 gtk_container_add(GTK_CONTAINER(hbox), label);
1789 1898
1790 /* purple_network_get_my_ip will return the IP that was set by the user with 1899 auto_ip_checkbox = pidgin_prefs_checkbox("Use _automatically detected IP address",
1791 purple_network_set_public_ip, so make a lookup for the auto-detected IP 1900 "/purple/network/auto_ip", vbox);
1792 ourselves. */ 1901 g_signal_connect(G_OBJECT(auto_ip_checkbox), "clicked",
1793 1902 G_CALLBACK(auto_ip_button_clicked_cb), NULL);
1794 /* Check if STUN discovery was already done */ 1903 auto_ip_button_clicked_cb(auto_ip_checkbox, NULL); /* Update label */
1795 stun = purple_stun_discover(NULL);
1796 if ((stun != NULL) && (stun->status == PURPLE_STUN_STATUS_DISCOVERED)) {
1797 ip = stun->publicip;
1798 } else {
1799 /* Attempt to get the IP from a NAT device using UPnP */
1800 ip = purple_upnp_get_public_ip();
1801 if (ip == NULL) {
1802 /* Attempt to get the IP from a NAT device using NAT-PMP */
1803 ip = purple_pmp_get_public_ip();
1804 if (ip == NULL) {
1805 /* Just fetch the IP of the local system */
1806 ip = purple_network_get_local_system_ip(-1);
1807 }
1808 }
1809 }
1810
1811 auto_ip_text = g_strdup_printf(_("Use _automatically detected IP address: %s"), ip);
1812 auto_ip_checkbox = pidgin_prefs_checkbox(auto_ip_text, "/purple/network/auto_ip", vbox);
1813 g_free(auto_ip_text);
1814
1815 table = gtk_table_new(2, 2, FALSE);
1816 gtk_container_set_border_width(GTK_CONTAINER(table), 0);
1817 gtk_table_set_col_spacings(GTK_TABLE(table), 5);
1818 gtk_table_set_row_spacings(GTK_TABLE(table), 10);
1819 gtk_container_add(GTK_CONTAINER(vbox), table);
1820
1821 label = gtk_label_new_with_mnemonic(_("Public _IP:"));
1822 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
1823 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
1824 gtk_size_group_add_widget(sg, label);
1825 1904
1826 entry = gtk_entry_new(); 1905 entry = gtk_entry_new();
1827 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry); 1906 gtk_entry_set_text(GTK_ENTRY(entry), purple_network_get_public_ip());
1828 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
1829 g_signal_connect(G_OBJECT(entry), "changed", 1907 g_signal_connect(G_OBJECT(entry), "changed",
1830 G_CALLBACK(network_ip_changed), NULL); 1908 G_CALLBACK(network_ip_changed), NULL);
1831 1909
1832 gtk_entry_set_text(GTK_ENTRY(entry), purple_network_get_public_ip()); 1910 hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Public _IP:"),
1833 1911 sg, entry, TRUE, NULL);
1834 pidgin_set_accessible_label(entry, label);
1835 1912
1836 if (purple_prefs_get_bool("/purple/network/auto_ip")) { 1913 if (purple_prefs_get_bool("/purple/network/auto_ip")) {
1837 gtk_widget_set_sensitive(GTK_WIDGET(table), FALSE); 1914 gtk_widget_set_sensitive(GTK_WIDGET(hbox), FALSE);
1838 } 1915 }
1839 1916
1840 g_signal_connect(G_OBJECT(auto_ip_checkbox), "clicked", 1917 g_signal_connect(G_OBJECT(auto_ip_checkbox), "clicked",
1841 G_CALLBACK(pidgin_toggle_sensitive), table); 1918 G_CALLBACK(pidgin_toggle_sensitive), hbox);
1842 1919
1843 g_object_unref(sg); 1920 g_object_unref(sg);
1844 1921
1845 vbox = pidgin_make_frame (ret, _("Ports")); 1922 vbox = pidgin_make_frame (ret, _("Ports"));
1846 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); 1923 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1847 1924
1848 pidgin_prefs_checkbox(_("_Enable automatic router port forwarding"), 1925 pidgin_prefs_checkbox(_("_Enable automatic router port forwarding"),
1849 "/purple/network/map_ports", vbox); 1926 "/purple/network/map_ports", vbox);
1850 1927
1851 ports_checkbox = pidgin_prefs_checkbox(_("_Manually specify range of ports to listen on"), 1928 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
1852 "/purple/network/ports_range_use", vbox); 1929
1853 1930 ports_checkbox = pidgin_prefs_checkbox(_("_Manually specify range of ports to listen on:"),
1854 spin_button = pidgin_prefs_labeled_spin_button(vbox, _("_Start port:"), 1931 "/purple/network/ports_range_use", hbox);
1932
1933 spin_button = pidgin_prefs_labeled_spin_button(hbox, _("_Start:"),
1855 "/purple/network/ports_range_start", 0, 65535, sg); 1934 "/purple/network/ports_range_start", 0, 65535, sg);
1856 if (!purple_prefs_get_bool("/purple/network/ports_range_use")) 1935 if (!purple_prefs_get_bool("/purple/network/ports_range_use"))
1857 gtk_widget_set_sensitive(GTK_WIDGET(spin_button), FALSE); 1936 gtk_widget_set_sensitive(GTK_WIDGET(spin_button), FALSE);
1858 g_signal_connect(G_OBJECT(ports_checkbox), "clicked", 1937 g_signal_connect(G_OBJECT(ports_checkbox), "clicked",
1859 G_CALLBACK(pidgin_toggle_sensitive), spin_button); 1938 G_CALLBACK(pidgin_toggle_sensitive), spin_button);
1860 1939
1861 spin_button = pidgin_prefs_labeled_spin_button(vbox, _("_End port:"), 1940 spin_button = pidgin_prefs_labeled_spin_button(hbox, _("_End:"),
1862 "/purple/network/ports_range_end", 0, 65535, sg); 1941 "/purple/network/ports_range_end", 0, 65535, sg);
1863 if (!purple_prefs_get_bool("/purple/network/ports_range_use")) 1942 if (!purple_prefs_get_bool("/purple/network/ports_range_use"))
1864 gtk_widget_set_sensitive(GTK_WIDGET(spin_button), FALSE); 1943 gtk_widget_set_sensitive(GTK_WIDGET(spin_button), FALSE);
1865 g_signal_connect(G_OBJECT(ports_checkbox), "clicked", 1944 g_signal_connect(G_OBJECT(ports_checkbox), "clicked",
1866 G_CALLBACK(pidgin_toggle_sensitive), spin_button); 1945 G_CALLBACK(pidgin_toggle_sensitive), spin_button);
1946
1947 pidgin_add_widget_to_vbox(GTK_BOX(vbox), NULL, NULL, hbox, TRUE, NULL);
1867 1948
1868 g_object_unref(sg); 1949 g_object_unref(sg);
1869 1950
1870 /* TURN server */ 1951 /* TURN server */
1871 vbox = pidgin_make_frame(ret, _("Relay Server (TURN)")); 1952 vbox = pidgin_make_frame(ret, _("Relay Server (TURN)"));
1876 "/purple/network/turn_server")); 1957 "/purple/network/turn_server"));
1877 g_signal_connect(G_OBJECT(entry), "focus-out-event", 1958 g_signal_connect(G_OBJECT(entry), "focus-out-event",
1878 G_CALLBACK(network_turn_server_changed_cb), NULL); 1959 G_CALLBACK(network_turn_server_changed_cb), NULL);
1879 gtk_widget_show(entry); 1960 gtk_widget_show(entry);
1880 1961
1881 hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), "_TURN server:", 1962 hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_TURN server:"),
1882 sg, entry, TRUE, NULL); 1963 sg, entry, TRUE, NULL);
1883 1964
1884 pidgin_prefs_labeled_spin_button(hbox, _("_Port:"), 1965 pidgin_prefs_labeled_spin_button(hbox, _("_UDP Port:"),
1885 "/purple/network/turn_port", 0, 65535, NULL); 1966 "/purple/network/turn_port", 0, 65535, NULL);
1886 hbox = pidgin_prefs_labeled_entry(vbox, "_Username:", 1967
1968 pidgin_prefs_labeled_spin_button(hbox, _("T_CP Port:"),
1969 "/purple/network/turn_port_tcp", 0, 65535, NULL);
1970
1971 hbox = pidgin_prefs_labeled_entry(vbox, _("Use_rname:"),
1887 "/purple/network/turn_username", sg); 1972 "/purple/network/turn_username", sg);
1888 pidgin_prefs_labeled_password(hbox, "_Password:", 1973 pidgin_prefs_labeled_password(hbox, _("Pass_word:"),
1889 "/purple/network/turn_password", NULL); 1974 "/purple/network/turn_password", NULL);
1890
1891 if (purple_running_gnome()) {
1892 vbox = pidgin_make_frame(ret, _("Proxy Server &amp; Browser"));
1893 prefs_proxy_frame = gtk_vbox_new(FALSE, 0);
1894
1895 proxy_warning = hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
1896 gtk_container_add(GTK_CONTAINER(vbox), hbox);
1897
1898 label = gtk_label_new(NULL);
1899 gtk_label_set_markup(GTK_LABEL(label),
1900 _("<b>Proxy configuration program was not found.</b>"));
1901 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1902
1903 browser_warning = hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
1904 gtk_container_add(GTK_CONTAINER(vbox), hbox);
1905
1906 label = gtk_label_new(NULL);
1907 gtk_label_set_markup(GTK_LABEL(label),
1908 _("<b>Browser configuration program was not found.</b>"));
1909 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1910
1911 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
1912 gtk_container_add(GTK_CONTAINER(vbox), hbox);
1913 label = gtk_label_new(_("Proxy & Browser preferences are configured\n"
1914 "in GNOME Preferences"));
1915 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
1916 gtk_widget_show(label);
1917
1918 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
1919 gtk_container_add(GTK_CONTAINER(vbox), hbox);
1920 proxy_button = gtk_button_new_with_mnemonic(_("Configure _Proxy"));
1921 g_signal_connect(G_OBJECT(proxy_button), "clicked",
1922 G_CALLBACK(proxy_button_clicked_cb), NULL);
1923 gtk_box_pack_start(GTK_BOX(hbox), proxy_button, FALSE, FALSE, 0);
1924 gtk_widget_show(proxy_button);
1925 browser_button = gtk_button_new_with_mnemonic(_("Configure _Browser"));
1926 g_signal_connect(G_OBJECT(browser_button), "clicked",
1927 G_CALLBACK(browser_button_clicked_cb), NULL);
1928 gtk_box_pack_start(GTK_BOX(hbox), browser_button, FALSE, FALSE, 0);
1929 gtk_widget_show(browser_button);
1930 } else {
1931 vbox = pidgin_make_frame(ret, _("Proxy Server"));
1932 prefs_proxy_frame = gtk_vbox_new(FALSE, 0);
1933
1934 pidgin_prefs_dropdown(vbox, _("Proxy _type:"), PURPLE_PREF_STRING,
1935 "/purple/proxy/type",
1936 _("No proxy"), "none",
1937 "SOCKS 4", "socks4",
1938 "SOCKS 5", "socks5",
1939 "HTTP", "http",
1940 _("Use Environmental Settings"), "envvar",
1941 NULL);
1942 gtk_box_pack_start(GTK_BOX(vbox), prefs_proxy_frame, 0, 0, 0);
1943 proxy_info = purple_global_proxy_get_info();
1944
1945 purple_prefs_connect_callback(prefs, "/purple/proxy/type",
1946 proxy_changed_cb, prefs_proxy_frame);
1947
1948 /* This is a global option that affects SOCKS4 usage even with account-specific proxy settings */
1949 pidgin_prefs_checkbox(_("Use remote DNS with SOCKS4 proxies"),
1950 "/purple/proxy/socks4_remotedns", prefs_proxy_frame);
1951
1952 table = gtk_table_new(4, 2, FALSE);
1953 gtk_container_set_border_width(GTK_CONTAINER(table), 0);
1954 gtk_table_set_col_spacings(GTK_TABLE(table), 5);
1955 gtk_table_set_row_spacings(GTK_TABLE(table), 10);
1956 gtk_container_add(GTK_CONTAINER(prefs_proxy_frame), table);
1957
1958
1959 label = gtk_label_new_with_mnemonic(_("_Host:"));
1960 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1961 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
1962
1963 entry = gtk_entry_new();
1964 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
1965 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
1966 g_signal_connect(G_OBJECT(entry), "changed",
1967 G_CALLBACK(proxy_print_option), (void *)PROXYHOST);
1968
1969 if (proxy_info != NULL && purple_proxy_info_get_host(proxy_info))
1970 gtk_entry_set_text(GTK_ENTRY(entry),
1971 purple_proxy_info_get_host(proxy_info));
1972
1973 hbox = gtk_hbox_new(TRUE, 5);
1974 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1975 pidgin_set_accessible_label (entry, label);
1976
1977 label = gtk_label_new_with_mnemonic(_("_Port:"));
1978 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1979 gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0);
1980
1981 entry = gtk_entry_new();
1982 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
1983 gtk_table_attach(GTK_TABLE(table), entry, 3, 4, 0, 1, GTK_FILL, 0, 0, 0);
1984 g_signal_connect(G_OBJECT(entry), "changed",
1985 G_CALLBACK(proxy_print_option), (void *)PROXYPORT);
1986
1987 if (proxy_info != NULL && purple_proxy_info_get_port(proxy_info) != 0) {
1988 char buf[128];
1989 g_snprintf(buf, sizeof(buf), "%d",
1990 purple_proxy_info_get_port(proxy_info));
1991
1992 gtk_entry_set_text(GTK_ENTRY(entry), buf);
1993 }
1994 pidgin_set_accessible_label (entry, label);
1995
1996 label = gtk_label_new_with_mnemonic(_("_User:"));
1997 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
1998 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
1999
2000 entry = gtk_entry_new();
2001 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
2002 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 1, 2, GTK_FILL, 0, 0, 0);
2003 g_signal_connect(G_OBJECT(entry), "changed",
2004 G_CALLBACK(proxy_print_option), (void *)PROXYUSER);
2005
2006 if (proxy_info != NULL && purple_proxy_info_get_username(proxy_info) != NULL)
2007 gtk_entry_set_text(GTK_ENTRY(entry),
2008 purple_proxy_info_get_username(proxy_info));
2009
2010 hbox = gtk_hbox_new(TRUE, 5);
2011 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2012 pidgin_set_accessible_label (entry, label);
2013
2014 label = gtk_label_new_with_mnemonic(_("Pa_ssword:"));
2015 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
2016 gtk_table_attach(GTK_TABLE(table), label, 2, 3, 1, 2, GTK_FILL, 0, 0, 0);
2017
2018 entry = gtk_entry_new();
2019 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
2020 gtk_table_attach(GTK_TABLE(table), entry, 3, 4, 1, 2, GTK_FILL , 0, 0, 0);
2021 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
2022 #if !GTK_CHECK_VERSION(2,16,0)
2023 if (gtk_entry_get_invisible_char(GTK_ENTRY(entry)) == '*')
2024 gtk_entry_set_invisible_char(GTK_ENTRY(entry), PIDGIN_INVISIBLE_CHAR);
2025 #endif /* Less than GTK+ 2.16 */
2026 g_signal_connect(G_OBJECT(entry), "changed",
2027 G_CALLBACK(proxy_print_option), (void *)PROXYPASS);
2028
2029 if (proxy_info != NULL && purple_proxy_info_get_password(proxy_info) != NULL)
2030 gtk_entry_set_text(GTK_ENTRY(entry),
2031 purple_proxy_info_get_password(proxy_info));
2032 pidgin_set_accessible_label (entry, label);
2033 }
2034 1975
2035 gtk_widget_show_all(ret); 1976 gtk_widget_show_all(ret);
2036 g_object_unref(sg); 1977 g_object_unref(sg);
2037 /* Only hide table if not running gnome otherwise we hide the IP address table! */
2038 if (!purple_running_gnome() && (proxy_info == NULL ||
2039 purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_NONE ||
2040 purple_proxy_info_get_type(proxy_info) == PURPLE_PROXY_USE_ENVVAR)) {
2041 gtk_widget_hide(table);
2042 } else if (purple_running_gnome()) {
2043 gchar *path;
2044 path = g_find_program_in_path("gnome-network-preferences");
2045 if (path != NULL) {
2046 gtk_widget_set_sensitive(proxy_button, TRUE);
2047 gtk_widget_hide(proxy_warning);
2048 g_free(path);
2049 } else {
2050 gtk_widget_set_sensitive(proxy_button, FALSE);
2051 gtk_widget_show(proxy_warning);
2052 }
2053 path = g_find_program_in_path("gnome-default-applications-properties");
2054 if (path != NULL) {
2055 gtk_widget_set_sensitive(browser_button, TRUE);
2056 gtk_widget_hide(browser_warning);
2057 g_free(path);
2058 } else {
2059 gtk_widget_set_sensitive(browser_button, FALSE);
2060 gtk_widget_show(browser_warning);
2061 }
2062 }
2063 1978
2064 return ret; 1979 return ret;
2065 } 1980 }
2066 1981
2067 #ifndef _WIN32 1982 #ifndef _WIN32
2068 static gboolean 1983 static gboolean
2069 manual_browser_set(GtkWidget *entry, GdkEventFocus *event, gpointer data) 1984 manual_browser_set(GtkWidget *entry, GdkEventFocus *event, gpointer data)
2070 { 1985 {
2071 const char *program = gtk_entry_get_text(GTK_ENTRY(entry)); 1986 const char *program = gtk_entry_get_text(GTK_ENTRY(entry));
2072 1987
2073 purple_prefs_set_path(PIDGIN_PREFS_ROOT "/browsers/command", program); 1988 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/browsers/manual_command", program);
2074 1989
2075 /* carry on normally */ 1990 /* carry on normally */
2076 return FALSE; 1991 return FALSE;
2077 } 1992 }
2078 1993
2089 {N_("Seamonkey"), "seamonkey"}, 2004 {N_("Seamonkey"), "seamonkey"},
2090 {N_("Opera"), "opera"}, 2005 {N_("Opera"), "opera"},
2091 {N_("Netscape"), "netscape"}, 2006 {N_("Netscape"), "netscape"},
2092 {N_("Mozilla"), "mozilla"}, 2007 {N_("Mozilla"), "mozilla"},
2093 {N_("Konqueror"), "kfmclient"}, 2008 {N_("Konqueror"), "kfmclient"},
2009 {N_("Google Chrome"), "google-chrome"},
2010 /* Do not move the line below. Code below expects gnome-open to be in
2011 * this list immediately after xdg-open! */
2094 {N_("Desktop Default"), "xdg-open"}, 2012 {N_("Desktop Default"), "xdg-open"},
2095 {N_("GNOME Default"), "gnome-open"}, 2013 {N_("GNOME Default"), "gnome-open"},
2096 {N_("Galeon"), "galeon"}, 2014 {N_("Galeon"), "galeon"},
2097 {N_("Firefox"), "firefox"}, 2015 {N_("Firefox"), "firefox"},
2098 {N_("Firebird"), "mozilla-firebird"}, 2016 {N_("Firebird"), "mozilla-firebird"},
2099 {N_("Epiphany"), "epiphany"} 2017 {N_("Epiphany"), "epiphany"},
2018 /* Translators: please do not translate "chromium-browser" here! */
2019 {N_("Chromium (chromium-browser)"), "chromium-browser"},
2020 /* Translators: please do not translate "chrome" here! */
2021 {N_("Chromium (chrome)"), "chrome"}
2100 }; 2022 };
2101 static const int num_possible_browsers = G_N_ELEMENTS(possible_browsers); 2023 static const int num_possible_browsers = G_N_ELEMENTS(possible_browsers);
2102 2024
2103 GList *browsers = NULL; 2025 GList *browsers = NULL;
2104 int i = 0; 2026 int i = 0;
2152 } 2074 }
2153 2075
2154 static GtkWidget * 2076 static GtkWidget *
2155 browser_page(void) 2077 browser_page(void)
2156 { 2078 {
2157 GtkWidget *ret; 2079 GtkWidget *ret, *vbox, *hbox, *label, *entry, *browser_button;
2158 GtkWidget *vbox;
2159 GtkWidget *hbox;
2160 GtkWidget *label;
2161 GtkWidget *entry;
2162 GtkSizeGroup *sg; 2080 GtkSizeGroup *sg;
2163 GList *browsers = NULL; 2081 GList *browsers = NULL;
2164 2082
2165 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); 2083 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
2166 gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER); 2084 gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER);
2167 2085
2168 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2169 vbox = pidgin_make_frame (ret, _("Browser Selection")); 2086 vbox = pidgin_make_frame (ret, _("Browser Selection"));
2170 2087
2171 browsers = get_available_browsers(); 2088 if(purple_running_gnome()) {
2172 if (browsers != NULL) { 2089 gchar *path = g_find_program_in_path("gnome-default-applications-properties");
2173 label = pidgin_prefs_dropdown_from_list(vbox,_("_Browser:"), PURPLE_PREF_STRING, 2090
2174 PIDGIN_PREFS_ROOT "/browsers/browser", 2091 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
2175 browsers); 2092 label = gtk_label_new(_("Browser preferences are configured in GNOME preferences"));
2176 g_list_free(browsers); 2093 gtk_container_add(GTK_CONTAINER(vbox), hbox);
2177 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); 2094 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2178 gtk_size_group_add_widget(sg, label); 2095
2179 2096 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
2180 hbox = gtk_hbox_new(FALSE, 0); 2097 gtk_container_add(GTK_CONTAINER(vbox), hbox);
2181 label = pidgin_prefs_dropdown(hbox, _("_Open link in:"), PURPLE_PREF_INT, 2098
2182 PIDGIN_PREFS_ROOT "/browsers/place", 2099 if(path == NULL) {
2183 _("Browser default"), PIDGIN_BROWSER_DEFAULT, 2100 label = gtk_label_new(NULL);
2184 _("Existing window"), PIDGIN_BROWSER_CURRENT, 2101 gtk_label_set_markup(GTK_LABEL(label),
2185 _("New window"), PIDGIN_BROWSER_NEW_WINDOW, 2102 _("<b>Browser configuration program was not found.</b>"));
2186 _("New tab"), PIDGIN_BROWSER_NEW_TAB, 2103 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2187 NULL); 2104 } else {
2188 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); 2105 browser_button = gtk_button_new_with_mnemonic(_("Configure _Browser"));
2189 gtk_size_group_add_widget(sg, label); 2106 g_signal_connect(G_OBJECT(browser_button), "clicked",
2190 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); 2107 G_CALLBACK(browser_button_clicked_cb), NULL);
2191 2108 gtk_box_pack_start(GTK_BOX(hbox), browser_button, FALSE, FALSE, 0);
2192 if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom")) 2109 }
2110
2111 g_free(path);
2112 gtk_widget_show_all(ret);
2113 } else {
2114 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2115
2116 browsers = get_available_browsers();
2117 if (browsers != NULL) {
2118 label = pidgin_prefs_dropdown_from_list(vbox,_("_Browser:"), PURPLE_PREF_STRING,
2119 PIDGIN_PREFS_ROOT "/browsers/browser",
2120 browsers);
2121 g_list_free(browsers);
2122 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
2123 gtk_size_group_add_widget(sg, label);
2124
2125 hbox = gtk_hbox_new(FALSE, 0);
2126 label = pidgin_prefs_dropdown(hbox, _("_Open link in:"), PURPLE_PREF_INT,
2127 PIDGIN_PREFS_ROOT "/browsers/place",
2128 _("Browser default"), PIDGIN_BROWSER_DEFAULT,
2129 _("Existing window"), PIDGIN_BROWSER_CURRENT,
2130 _("New window"), PIDGIN_BROWSER_NEW_WINDOW,
2131 _("New tab"), PIDGIN_BROWSER_NEW_TAB,
2132 NULL);
2133 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
2134 gtk_size_group_add_widget(sg, label);
2135 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2136
2137 if (!strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom"))
2138 gtk_widget_set_sensitive(hbox, FALSE);
2139 purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/browsers/browser",
2140 browser_changed1_cb, hbox);
2141 }
2142
2143 entry = gtk_entry_new();
2144 gtk_entry_set_text(GTK_ENTRY(entry),
2145 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/manual_command"));
2146 g_signal_connect(G_OBJECT(entry), "focus-out-event",
2147 G_CALLBACK(manual_browser_set), NULL);
2148 hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Manual:\n(%s for URL)"), sg, entry, TRUE, NULL);
2149 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom"))
2193 gtk_widget_set_sensitive(hbox, FALSE); 2150 gtk_widget_set_sensitive(hbox, FALSE);
2194 purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/browsers/browser", 2151 purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/browsers/browser",
2195 browser_changed1_cb, hbox); 2152 browser_changed2_cb, hbox);
2196 } 2153
2197 2154 gtk_widget_show_all(ret);
2198 entry = gtk_entry_new(); 2155 g_object_unref(sg);
2199 gtk_entry_set_text(GTK_ENTRY(entry), 2156 }
2200 purple_prefs_get_path(PIDGIN_PREFS_ROOT "/browsers/command")); 2157
2201 g_signal_connect(G_OBJECT(entry), "focus-out-event",
2202 G_CALLBACK(manual_browser_set), NULL);
2203 hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Manual:\n(%s for URL)"), sg, entry, TRUE, NULL);
2204 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"), "custom"))
2205 gtk_widget_set_sensitive(hbox, FALSE);
2206 purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/browsers/browser",
2207 browser_changed2_cb, hbox);
2208
2209 gtk_widget_show_all(ret);
2210 g_object_unref(sg);
2211 return ret; 2158 return ret;
2212 } 2159 }
2213 #endif /*_WIN32*/ 2160 #endif /*_WIN32*/
2161
2162 static GtkWidget *
2163 proxy_page(void)
2164 {
2165 GtkWidget *ret = NULL, *vbox = NULL, *hbox = NULL;
2166 GtkWidget *table = NULL, *entry = NULL, *label = NULL, *proxy_button = NULL;
2167 GtkWidget *prefs_proxy_frame = NULL;
2168 PurpleProxyInfo *proxy_info;
2169
2170 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
2171 gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER);
2172 vbox = pidgin_make_frame(ret, _("Proxy Server"));
2173 prefs_proxy_frame = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
2174
2175 if(purple_running_gnome()) {
2176 gchar *path = NULL;
2177
2178 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
2179 label = gtk_label_new(_("Proxy preferences are configured in GNOME preferences"));
2180 gtk_container_add(GTK_CONTAINER(vbox), hbox);
2181 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2182
2183 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
2184 gtk_container_add(GTK_CONTAINER(vbox), hbox);
2185
2186 path = g_find_program_in_path("gnome-network-properties");
2187 if (path == NULL)
2188 path = g_find_program_in_path("gnome-network-preferences");
2189
2190 if (path == NULL) {
2191 label = gtk_label_new(NULL);
2192 gtk_label_set_markup(GTK_LABEL(label),
2193 _("<b>Proxy configuration program was not found.</b>"));
2194 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
2195 } else {
2196 proxy_button = gtk_button_new_with_mnemonic(_("Configure _Proxy"));
2197 g_signal_connect(G_OBJECT(proxy_button), "clicked",
2198 G_CALLBACK(proxy_button_clicked_cb),
2199 path);
2200 gtk_box_pack_start(GTK_BOX(hbox), proxy_button, FALSE, FALSE, 0);
2201 }
2202
2203 /* NOTE: path leaks, but only when the prefs window is destroyed,
2204 which is never */
2205 gtk_widget_show_all(ret);
2206 } else {
2207 GtkWidget *prefs_proxy_subframe = gtk_vbox_new(FALSE, 0);
2208
2209 /* This is a global option that affects SOCKS4 usage even with
2210 * account-specific proxy settings */
2211 pidgin_prefs_checkbox(_("Use remote _DNS with SOCKS4 proxies"),
2212 "/purple/proxy/socks4_remotedns", prefs_proxy_frame);
2213 gtk_box_pack_start(GTK_BOX(vbox), prefs_proxy_frame, 0, 0, 0);
2214
2215 pidgin_prefs_dropdown(prefs_proxy_frame, _("Proxy t_ype:"), PURPLE_PREF_STRING,
2216 "/purple/proxy/type",
2217 _("No proxy"), "none",
2218 _("SOCKS 4"), "socks4",
2219 _("SOCKS 5"), "socks5",
2220 _("Tor/Privacy (SOCKS5)"), "tor",
2221 _("HTTP"), "http",
2222 _("Use Environmental Settings"), "envvar",
2223 NULL);
2224 gtk_box_pack_start(GTK_BOX(prefs_proxy_frame), prefs_proxy_subframe, 0, 0, 0);
2225 proxy_info = purple_global_proxy_get_info();
2226
2227 gtk_widget_show_all(ret);
2228
2229 purple_prefs_connect_callback(prefs, "/purple/proxy/type",
2230 proxy_changed_cb, prefs_proxy_subframe);
2231
2232 table = gtk_table_new(4, 2, FALSE);
2233 gtk_container_set_border_width(GTK_CONTAINER(table), 0);
2234 gtk_table_set_col_spacings(GTK_TABLE(table), 5);
2235 gtk_table_set_row_spacings(GTK_TABLE(table), 10);
2236 gtk_container_add(GTK_CONTAINER(prefs_proxy_subframe), table);
2237
2238 label = gtk_label_new_with_mnemonic(_("_Host:"));
2239 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
2240 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
2241
2242 entry = gtk_entry_new();
2243 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
2244 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);
2245 g_signal_connect(G_OBJECT(entry), "changed",
2246 G_CALLBACK(proxy_print_option), (void *)PROXYHOST);
2247
2248 if (proxy_info != NULL && purple_proxy_info_get_host(proxy_info))
2249 gtk_entry_set_text(GTK_ENTRY(entry),
2250 purple_proxy_info_get_host(proxy_info));
2251
2252 hbox = gtk_hbox_new(TRUE, 5);
2253 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2254 pidgin_set_accessible_label (entry, label);
2255
2256 label = gtk_label_new_with_mnemonic(_("P_ort:"));
2257 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
2258 gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0);
2259
2260 entry = gtk_spin_button_new_with_range(0, 65535, 1);
2261 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
2262 gtk_table_attach(GTK_TABLE(table), entry, 3, 4, 0, 1, GTK_FILL, 0, 0, 0);
2263 g_signal_connect(G_OBJECT(entry), "changed",
2264 G_CALLBACK(proxy_print_option), (void *)PROXYPORT);
2265
2266 if (proxy_info != NULL && purple_proxy_info_get_port(proxy_info) != 0) {
2267 gtk_spin_button_set_value(GTK_SPIN_BUTTON(entry),
2268 purple_proxy_info_get_port(proxy_info));
2269 }
2270 pidgin_set_accessible_label (entry, label);
2271
2272 label = gtk_label_new_with_mnemonic(_("User_name:"));
2273 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
2274 gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
2275
2276 entry = gtk_entry_new();
2277 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
2278 gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 1, 2, GTK_FILL, 0, 0, 0);
2279 g_signal_connect(G_OBJECT(entry), "changed",
2280 G_CALLBACK(proxy_print_option), (void *)PROXYUSER);
2281
2282 if (proxy_info != NULL && purple_proxy_info_get_username(proxy_info) != NULL)
2283 gtk_entry_set_text(GTK_ENTRY(entry),
2284 purple_proxy_info_get_username(proxy_info));
2285
2286 hbox = gtk_hbox_new(TRUE, 5);
2287 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2288 pidgin_set_accessible_label (entry, label);
2289
2290 label = gtk_label_new_with_mnemonic(_("Pa_ssword:"));
2291 gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
2292 gtk_table_attach(GTK_TABLE(table), label, 2, 3, 1, 2, GTK_FILL, 0, 0, 0);
2293
2294 entry = gtk_entry_new();
2295 gtk_label_set_mnemonic_widget(GTK_LABEL(label), entry);
2296 gtk_table_attach(GTK_TABLE(table), entry, 3, 4, 1, 2, GTK_FILL , 0, 0, 0);
2297 gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
2298 #if !GTK_CHECK_VERSION(2,16,0)
2299 if (gtk_entry_get_invisible_char(GTK_ENTRY(entry)) == '*')
2300 gtk_entry_set_invisible_char(GTK_ENTRY(entry), PIDGIN_INVISIBLE_CHAR);
2301 #endif /* Less than GTK+ 2.16 */
2302 g_signal_connect(G_OBJECT(entry), "changed",
2303 G_CALLBACK(proxy_print_option), (void *)PROXYPASS);
2304
2305 if (proxy_info != NULL && purple_proxy_info_get_password(proxy_info) != NULL)
2306 gtk_entry_set_text(GTK_ENTRY(entry),
2307 purple_proxy_info_get_password(proxy_info));
2308 pidgin_set_accessible_label (entry, label);
2309
2310 proxy_changed_cb("/purple/proxy/type", PURPLE_PREF_STRING,
2311 purple_prefs_get_string("/purple/proxy/type"),
2312 prefs_proxy_subframe);
2313
2314 }
2315
2316 return ret;
2317 }
2214 2318
2215 static GtkWidget * 2319 static GtkWidget *
2216 logging_page(void) 2320 logging_page(void)
2217 { 2321 {
2218 GtkWidget *ret; 2322 GtkWidget *ret;
2355 GtkWidget *hbox = data; 2459 GtkWidget *hbox = data;
2356 const char *method = value; 2460 const char *method = value;
2357 2461
2358 gtk_widget_set_sensitive(hbox, 2462 gtk_widget_set_sensitive(hbox,
2359 !strcmp(method, "automatic") || 2463 !strcmp(method, "automatic") ||
2464 !strcmp(method, "alsa") ||
2360 !strcmp(method, "esd")); 2465 !strcmp(method, "esd"));
2361 } 2466 }
2362 #endif /* USE_GSTREAMER */ 2467 #endif /* USE_GSTREAMER */
2363 2468
2364 2469
2547 2652
2548 static GtkWidget * 2653 static GtkWidget *
2549 sound_page(void) 2654 sound_page(void)
2550 { 2655 {
2551 GtkWidget *ret; 2656 GtkWidget *ret;
2552 GtkWidget *vbox, *sw, *button; 2657 GtkWidget *vbox, *vbox2, *sw, *button;
2553 GtkSizeGroup *sg; 2658 GtkSizeGroup *sg;
2554 GtkTreeIter iter; 2659 GtkTreeIter iter;
2555 GtkWidget *event_view; 2660 GtkWidget *event_view;
2556 GtkListStore *event_store; 2661 GtkListStore *event_store;
2557 GtkCellRenderer *rend; 2662 GtkCellRenderer *rend;
2571 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); 2676 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
2572 gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER); 2677 gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER);
2573 2678
2574 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); 2679 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2575 2680
2681 vbox2 = pidgin_make_frame(ret, _("Sound Options"));
2682
2683 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
2684 gtk_box_pack_start(GTK_BOX(vbox2), vbox, FALSE, FALSE, 0);
2685
2576 #ifndef _WIN32 2686 #ifndef _WIN32
2577 vbox = pidgin_make_frame (ret, _("Sound Method")); 2687 dd = pidgin_prefs_dropdown(vbox2, _("_Method:"), PURPLE_PREF_STRING,
2578 dd = pidgin_prefs_dropdown(vbox, _("_Method:"), PURPLE_PREF_STRING,
2579 PIDGIN_PREFS_ROOT "/sound/method", 2688 PIDGIN_PREFS_ROOT "/sound/method",
2580 _("Console beep"), "beep", 2689 _("Console beep"), "beep",
2581 #ifdef USE_GSTREAMER 2690 #ifdef USE_GSTREAMER
2582 _("Automatic"), "automatic", 2691 _("Automatic"), "automatic",
2583 "ESD", "esd", 2692 "ESD", "esd",
2603 gtk_widget_set_sensitive(hbox, 2712 gtk_widget_set_sensitive(hbox,
2604 !strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"), 2713 !strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/method"),
2605 "custom")); 2714 "custom"));
2606 #endif /* _WIN32 */ 2715 #endif /* _WIN32 */
2607 2716
2608 vbox = pidgin_make_frame (ret, _("Sound Options"));
2609
2610 button = pidgin_prefs_checkbox(_("M_ute sounds"), PIDGIN_PREFS_ROOT "/sound/mute", vbox); 2717 button = pidgin_prefs_checkbox(_("M_ute sounds"), PIDGIN_PREFS_ROOT "/sound/mute", vbox);
2611 purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/mute", mute_changed_cb, button); 2718 purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/mute", mute_changed_cb, button);
2612 2719
2613 pidgin_prefs_checkbox(_("Sounds when conversation has _focus"), 2720 pidgin_prefs_checkbox(_("Sounds when conversation has _focus"),
2614 PIDGIN_PREFS_ROOT "/sound/conv_focus", vbox); 2721 PIDGIN_PREFS_ROOT "/sound/conv_focus", vbox);
2652 gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent), vbox->parent, TRUE, 2759 gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent), vbox->parent, TRUE,
2653 TRUE, 0, GTK_PACK_START); 2760 TRUE, 0, GTK_PACK_START);
2654 gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent->parent), 2761 gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent->parent),
2655 vbox->parent->parent, TRUE, TRUE, 0, GTK_PACK_START); 2762 vbox->parent->parent, TRUE, TRUE, 0, GTK_PACK_START);
2656 2763
2657 /* SOUND THEMES */
2658 prefs_sound_themes_combo_box = prefs_build_theme_combo_box(prefs_sound_themes,
2659 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"),
2660 "sound");
2661
2662
2663 gtk_box_pack_start(GTK_BOX (vbox), prefs_sound_themes_combo_box, FALSE, FALSE, 0);
2664
2665 g_signal_connect(G_OBJECT(prefs_sound_themes_combo_box), "changed", (GCallback)prefs_set_sound_theme_cb, NULL);
2666
2667 /* SOUND SELECTION */ 2764 /* SOUND SELECTION */
2668 sw = gtk_scrolled_window_new(NULL,NULL);
2669 gtk_widget_set_size_request(sw, -1, 100);
2670 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
2671 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN);
2672
2673 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
2674 event_store = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT); 2765 event_store = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT);
2675 2766
2676 for (j=0; j < PURPLE_NUM_SOUNDS; j++) { 2767 for (j=0; j < PURPLE_NUM_SOUNDS; j++) {
2677 char *pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/enabled/%s", 2768 char *pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/enabled/%s",
2678 pidgin_sound_get_event_option(j)); 2769 pidgin_sound_get_event_option(j));
2717 rend, 2808 rend,
2718 "text", 1, 2809 "text", 1,
2719 NULL); 2810 NULL);
2720 gtk_tree_view_append_column (GTK_TREE_VIEW(event_view), col); 2811 gtk_tree_view_append_column (GTK_TREE_VIEW(event_view), col);
2721 g_object_unref(G_OBJECT(event_store)); 2812 g_object_unref(G_OBJECT(event_store));
2722 gtk_container_add(GTK_CONTAINER(sw), event_view); 2813 gtk_box_pack_start(GTK_BOX(vbox),
2814 pidgin_make_scrollable(event_view, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, 100),
2815 TRUE, TRUE, 0);
2723 2816
2724 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); 2817 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
2725 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); 2818 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2726 sound_entry = gtk_entry_new(); 2819 sound_entry = gtk_entry_new();
2727 pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s", 2820 pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s",
2766 static GtkWidget * 2859 static GtkWidget *
2767 away_page(void) 2860 away_page(void)
2768 { 2861 {
2769 GtkWidget *ret; 2862 GtkWidget *ret;
2770 GtkWidget *vbox; 2863 GtkWidget *vbox;
2864 GtkWidget *hbox;
2771 GtkWidget *dd; 2865 GtkWidget *dd;
2772 GtkWidget *label; 2866 GtkWidget *label;
2773 GtkWidget *button; 2867 GtkWidget *button;
2774 GtkWidget *select; 2868 GtkWidget *select;
2775 GtkWidget *menu; 2869 GtkWidget *menu;
2792 #endif 2886 #endif
2793 NULL); 2887 NULL);
2794 gtk_size_group_add_widget(sg, dd); 2888 gtk_size_group_add_widget(sg, dd);
2795 gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5); 2889 gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5);
2796 2890
2891 select = pidgin_prefs_labeled_spin_button(vbox,
2892 _("_Minutes before becoming idle:"), "/purple/away/mins_before_away",
2893 1, 24 * 60, sg);
2894
2895 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
2896 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2897
2898 button = pidgin_prefs_checkbox(_("Change to this status when _idle:"),
2899 "/purple/away/away_when_idle", hbox);
2900 gtk_size_group_add_widget(sg, button);
2901
2902 /* TODO: Show something useful if we don't have any saved statuses. */
2903 menu = pidgin_status_menu(purple_savedstatus_get_idleaway(), G_CALLBACK(set_idle_away));
2904 gtk_size_group_add_widget(sg, menu);
2905 gtk_box_pack_start(GTK_BOX(hbox), menu, FALSE, FALSE, 0);
2906
2907 g_signal_connect(G_OBJECT(button), "clicked",
2908 G_CALLBACK(pidgin_toggle_sensitive), menu);
2909
2910 if(!purple_prefs_get_bool("/purple/away/away_when_idle"))
2911 gtk_widget_set_sensitive(GTK_WIDGET(menu), FALSE);
2912
2797 /* Away stuff */ 2913 /* Away stuff */
2798 vbox = pidgin_make_frame(ret, _("Away")); 2914 vbox = pidgin_make_frame(ret, _("Away"));
2799 2915
2800 dd = pidgin_prefs_dropdown(vbox, _("_Auto-reply:"), 2916 dd = pidgin_prefs_dropdown(vbox, _("_Auto-reply:"),
2801 PURPLE_PREF_STRING, "/purple/away/auto_reply", 2917 PURPLE_PREF_STRING, "/purple/away/auto_reply",
2804 _("When both away and idle"), "awayidle", 2920 _("When both away and idle"), "awayidle",
2805 NULL); 2921 NULL);
2806 gtk_size_group_add_widget(sg, dd); 2922 gtk_size_group_add_widget(sg, dd);
2807 gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5); 2923 gtk_misc_set_alignment(GTK_MISC(dd), 0, 0.5);
2808 2924
2809 /* Auto-away stuff */
2810 vbox = pidgin_make_frame(ret, _("Auto-away"));
2811
2812 select = pidgin_prefs_labeled_spin_button(vbox,
2813 _("_Minutes before becoming idle:"), "/purple/away/mins_before_away",
2814 1, 24 * 60, sg);
2815
2816 button = pidgin_prefs_checkbox(_("Change status when _idle"),
2817 "/purple/away/away_when_idle", vbox);
2818
2819 /* TODO: Show something useful if we don't have any saved statuses. */
2820 menu = pidgin_status_menu(purple_savedstatus_get_idleaway(), G_CALLBACK(set_idle_away));
2821 pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Change _status to:"), sg, menu, TRUE, &label);
2822 g_signal_connect(G_OBJECT(button), "clicked",
2823 G_CALLBACK(pidgin_toggle_sensitive), menu);
2824 g_signal_connect(G_OBJECT(button), "clicked",
2825 G_CALLBACK(pidgin_toggle_sensitive), label);
2826
2827 if (!purple_prefs_get_bool("/purple/away/away_when_idle")) {
2828 gtk_widget_set_sensitive(GTK_WIDGET(menu), FALSE);
2829 gtk_widget_set_sensitive(GTK_WIDGET(label), FALSE);
2830 }
2831
2832 /* Signon status stuff */ 2925 /* Signon status stuff */
2833 vbox = pidgin_make_frame(ret, _("Status at Startup")); 2926 vbox = pidgin_make_frame(ret, _("Status at Startup"));
2834 2927
2835 button = pidgin_prefs_checkbox(_("Use status from last _exit at startup"), 2928 button = pidgin_prefs_checkbox(_("Use status from last _exit at startup"),
2836 "/purple/savedstatus/startup_current_status", vbox); 2929 "/purple/savedstatus/startup_current_status", vbox);
2930 gtk_size_group_add_widget(sg, button);
2837 2931
2838 /* TODO: Show something useful if we don't have any saved statuses. */ 2932 /* TODO: Show something useful if we don't have any saved statuses. */
2839 menu = pidgin_status_menu(purple_savedstatus_get_startup(), G_CALLBACK(set_startupstatus)); 2933 menu = pidgin_status_menu(purple_savedstatus_get_startup(), G_CALLBACK(set_startupstatus));
2934 gtk_size_group_add_widget(sg, menu);
2840 g_signal_connect(G_OBJECT(button), "clicked", 2935 g_signal_connect(G_OBJECT(button), "clicked",
2841 G_CALLBACK(pidgin_toggle_sensitive), menu); 2936 G_CALLBACK(pidgin_toggle_sensitive), menu);
2842 pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Status to a_pply at startup:"), sg, menu, TRUE, &label); 2937 pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("Status to a_pply at startup:"), sg, menu, TRUE, &label);
2843 g_signal_connect(G_OBJECT(button), "clicked", 2938 g_signal_connect(G_OBJECT(button), "clicked",
2844 G_CALLBACK(pidgin_toggle_sensitive), label); 2939 G_CALLBACK(pidgin_toggle_sensitive), label);
2845 2940
2846 if (purple_prefs_get_bool("/purple/savedstatus/startup_current_status")) { 2941 if(purple_prefs_get_bool("/purple/savedstatus/startup_current_status")) {
2847 gtk_widget_set_sensitive(GTK_WIDGET(menu), FALSE); 2942 gtk_widget_set_sensitive(GTK_WIDGET(menu), FALSE);
2848 gtk_widget_set_sensitive(GTK_WIDGET(label), FALSE); 2943 gtk_widget_set_sensitive(GTK_WIDGET(label), FALSE);
2849 } 2944 }
2850 2945
2851 gtk_widget_show_all(ret); 2946 gtk_widget_show_all(ret);
2855 } 2950 }
2856 2951
2857 static int 2952 static int
2858 prefs_notebook_add_page(const char *text, GtkWidget *page, int ind) 2953 prefs_notebook_add_page(const char *text, GtkWidget *page, int ind)
2859 { 2954 {
2860 #if GTK_CHECK_VERSION(2,4,0)
2861 return gtk_notebook_append_page(GTK_NOTEBOOK(prefsnotebook), page, gtk_label_new(text)); 2955 return gtk_notebook_append_page(GTK_NOTEBOOK(prefsnotebook), page, gtk_label_new(text));
2862 #else
2863 gtk_notebook_append_page(GTK_NOTEBOOK(prefsnotebook), page, gtk_label_new(text));
2864 return gtk_notebook_page_num(GTK_NOTEBOOK(prefsnotebook), page);
2865 #endif
2866 } 2956 }
2867 2957
2868 static void 2958 static void
2869 prefs_notebook_init(void) 2959 prefs_notebook_init(void)
2870 { 2960 {
2871 prefs_notebook_add_page(_("Interface"), interface_page(), notebook_page++); 2961 prefs_notebook_add_page(_("Interface"), interface_page(), notebook_page++);
2872 prefs_notebook_add_page(_("Conversations"), conv_page(), notebook_page++); 2962
2873 prefs_notebook_add_page(_("Smiley Themes"), theme_page(), notebook_page++);
2874 prefs_notebook_add_page(_("Sounds"), sound_page(), notebook_page++);
2875 prefs_notebook_add_page(_("Network"), network_page(), notebook_page++);
2876 #ifndef _WIN32 2963 #ifndef _WIN32
2877 /* We use the registered default browser in windows */ 2964 /* We use the registered default browser in windows */
2878 /* if the user is running gnome 2.x or Mac OS X, hide the browsers tab */ 2965 /* if the user is running Mac OS X, hide the browsers tab */
2879 if ((purple_running_gnome() == FALSE) && (purple_running_osx() == FALSE)) { 2966 if(purple_running_osx() == FALSE)
2880 prefs_notebook_add_page(_("Browser"), browser_page(), notebook_page++); 2967 prefs_notebook_add_page(_("Browser"), browser_page(), notebook_page++);
2881 }
2882 #endif 2968 #endif
2969
2970 prefs_notebook_add_page(_("Conversations"), conv_page(), notebook_page++);
2883 prefs_notebook_add_page(_("Logging"), logging_page(), notebook_page++); 2971 prefs_notebook_add_page(_("Logging"), logging_page(), notebook_page++);
2972 prefs_notebook_add_page(_("Network"), network_page(), notebook_page++);
2973 prefs_notebook_add_page(_("Proxy"), proxy_page(), notebook_page++);
2884 prefs_notebook_add_page(_("Password Storage"), keyring_page(), notebook_page++); 2974 prefs_notebook_add_page(_("Password Storage"), keyring_page(), notebook_page++);
2975
2976 prefs_notebook_add_page(_("Sounds"), sound_page(), notebook_page++);
2885 prefs_notebook_add_page(_("Status / Idle"), away_page(), notebook_page++); 2977 prefs_notebook_add_page(_("Status / Idle"), away_page(), notebook_page++);
2978 prefs_notebook_add_page(_("Themes"), theme_page(), notebook_page++);
2886 } 2979 }
2887 2980
2888 void 2981 void
2889 pidgin_prefs_show(void) 2982 pidgin_prefs_show(void)
2890 { 2983 {
2910 3003
2911 vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(prefs), FALSE, PIDGIN_HIG_BORDER); 3004 vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(prefs), FALSE, PIDGIN_HIG_BORDER);
2912 3005
2913 /* The notebook */ 3006 /* The notebook */
2914 prefsnotebook = notebook = gtk_notebook_new (); 3007 prefsnotebook = notebook = gtk_notebook_new ();
2915 gtk_box_pack_start (GTK_BOX (vbox), notebook, FALSE, FALSE, 0); 3008 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_LEFT);
3009 gtk_box_pack_start(GTK_BOX (vbox), notebook, FALSE, FALSE, 0);
2916 gtk_widget_show(prefsnotebook); 3010 gtk_widget_show(prefsnotebook);
2917 3011
2918 button = pidgin_dialog_add_button(GTK_DIALOG(prefs), GTK_STOCK_CLOSE, NULL, NULL); 3012 button = pidgin_dialog_add_button(GTK_DIALOG(prefs), GTK_STOCK_CLOSE, NULL, NULL);
2919 g_signal_connect_swapped(G_OBJECT(button), "clicked", 3013 g_signal_connect_swapped(G_OBJECT(button), "clicked",
2920 G_CALLBACK(gtk_widget_destroy), prefs); 3014 G_CALLBACK(gtk_widget_destroy), prefs);
2978 3072
2979 #ifndef _WIN32 3073 #ifndef _WIN32
2980 /* Browsers */ 3074 /* Browsers */
2981 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/browsers"); 3075 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/browsers");
2982 purple_prefs_add_int(PIDGIN_PREFS_ROOT "/browsers/place", PIDGIN_BROWSER_DEFAULT); 3076 purple_prefs_add_int(PIDGIN_PREFS_ROOT "/browsers/place", PIDGIN_BROWSER_DEFAULT);
2983 purple_prefs_add_path(PIDGIN_PREFS_ROOT "/browsers/command", ""); 3077 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/browsers/manual_command", "");
2984 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/browsers/browser", "mozilla"); 3078 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/browsers/browser", "xdg-open");
2985 #endif 3079 #endif
2986 3080
2987 /* Plugins */ 3081 /* Plugins */
2988 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/plugins"); 3082 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/plugins");
2989 purple_prefs_add_path_list(PIDGIN_PREFS_ROOT "/plugins/loaded", NULL); 3083 purple_prefs_add_path_list(PIDGIN_PREFS_ROOT "/plugins/loaded", NULL);
2995 purple_prefs_add_path(PIDGIN_PREFS_ROOT "/filelocations/last_icon_folder", ""); 3089 purple_prefs_add_path(PIDGIN_PREFS_ROOT "/filelocations/last_icon_folder", "");
2996 3090
2997 /* Themes */ 3091 /* Themes */
2998 prefs_themes_init(); 3092 prefs_themes_init();
2999 3093
3094 /* Conversation Themes */
3095 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations");
3096 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/conversations/theme", "Default");
3097
3000 /* Smiley Themes */ 3098 /* Smiley Themes */
3001 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/smileys"); 3099 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/smileys");
3002 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/smileys/theme", "Default"); 3100 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/smileys/theme", "Default");
3003 3101
3004 /* Smiley Callbacks */ 3102 /* Smiley Callbacks */
3005 purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/smileys/theme", 3103 purple_prefs_connect_callback(&prefs, PIDGIN_PREFS_ROOT "/smileys/theme",
3006 smiley_theme_pref_cb, NULL); 3104 smiley_theme_pref_cb, NULL);
3007 3105
3008 pidgin_prefs_update_old(); 3106 pidgin_prefs_update_old();
3009 } 3107 }
3010 3108
3011 void 3109 void
3012 pidgin_prefs_update_old(void) 3110 pidgin_prefs_update_old(void)
3013 { 3111 {
3014 const char *str; 3112 const char *str = NULL;
3015
3016 purple_prefs_rename("/gaim/gtk", PIDGIN_PREFS_ROOT);
3017 3113
3018 /* Rename some old prefs */ 3114 /* Rename some old prefs */
3019 purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_ims", "/purple/logging/log_ims"); 3115 purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_ims", "/purple/logging/log_ims");
3020 purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_chats", "/purple/logging/log_chats"); 3116 purple_prefs_rename(PIDGIN_PREFS_ROOT "/logging/log_chats", "/purple/logging/log_chats");
3021 purple_prefs_rename("/purple/conversations/placement", 3117 purple_prefs_rename("/purple/conversations/placement",
3025 purple_prefs_rename(PIDGIN_PREFS_ROOT "/conversations/im/raise_on_events", "/plugins/gtk/X11/notify/method_raise"); 3121 purple_prefs_rename(PIDGIN_PREFS_ROOT "/conversations/im/raise_on_events", "/plugins/gtk/X11/notify/method_raise");
3026 3122
3027 purple_prefs_rename_boolean_toggle(PIDGIN_PREFS_ROOT "/conversations/ignore_colors", 3123 purple_prefs_rename_boolean_toggle(PIDGIN_PREFS_ROOT "/conversations/ignore_colors",
3028 PIDGIN_PREFS_ROOT "/conversations/show_incoming_formatting"); 3124 PIDGIN_PREFS_ROOT "/conversations/show_incoming_formatting");
3029 3125
3030 /* this string pref moved into the core, try to be friendly */ 3126 /*
3031 purple_prefs_rename(PIDGIN_PREFS_ROOT "/idle/reporting_method", "/purple/away/idle_reporting"); 3127 * this path pref changed to a string, so migrate. I know this will break
3032 if ((str = purple_prefs_get_string("/purple/away/idle_reporting")) && 3128 * things for and confuse users that use multiple versions with the same
3033 strcmp(str, "gaim") == 0) 3129 * config directory, but I'm not inclined to want to deal with that at the
3034 purple_prefs_set_string("/purple/away/idle_reporting", "purple"); 3130 * moment. -- rekkanoryo
3131 */
3132 if((str = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/browsers/command")) != NULL) {
3133 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/browsers/manual_command", str);
3134 purple_prefs_remove(PIDGIN_PREFS_ROOT "/browsers/command");
3135 }
3035 3136
3036 /* Remove some no-longer-used prefs */ 3137 /* Remove some no-longer-used prefs */
3037 purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/auto_expand_contacts"); 3138 purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/auto_expand_contacts");
3038 purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/button_style"); 3139 purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/button_style");
3039 purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/grey_idle_buddies"); 3140 purple_prefs_remove(PIDGIN_PREFS_ROOT "/blist/grey_idle_buddies");

mercurial