pidgin/gtkprefs.c

changeset 27445
b8bbf88abd0f
parent 27196
e5e4a0f2eaa9
child 27449
ebd2e0ae2e3a
child 27602
9147f6a00811
equal deleted inserted replaced
27444:21add455833a 27445:b8bbf88abd0f
59 #define PROXYUSER 2 59 #define PROXYUSER 2
60 #define PROXYPASS 3 60 #define PROXYPASS 3
61 61
62 #define PREFS_OPTIMAL_ICON_SIZE 32 62 #define PREFS_OPTIMAL_ICON_SIZE 32
63 63
64 struct theme_info {
65 gchar *type;
66 gchar *extension;
67 gchar *original_name;
68 };
69
64 static int sound_row_sel = 0; 70 static int sound_row_sel = 0;
65 static GtkWidget *prefsnotebook; 71 static GtkWidget *prefsnotebook;
66 72
67 static GtkWidget *sound_entry = NULL; 73 static GtkWidget *sound_entry = NULL;
68 static GtkListStore *smiley_theme_store = NULL; 74 static GtkListStore *smiley_theme_store = NULL;
72 static GtkWidget *prefs = NULL; 78 static GtkWidget *prefs = NULL;
73 static GtkWidget *debugbutton = NULL; 79 static GtkWidget *debugbutton = NULL;
74 static int notebook_page = 0; 80 static int notebook_page = 0;
75 static GtkTreeRowReference *previous_smiley_row = NULL; 81 static GtkTreeRowReference *previous_smiley_row = NULL;
76 82
77 static gboolean prefs_themes_unsorted = TRUE;
78 static GtkListStore *prefs_sound_themes; 83 static GtkListStore *prefs_sound_themes;
79 static GtkListStore *prefs_blist_themes; 84 static GtkListStore *prefs_blist_themes;
80 static GtkListStore *prefs_status_icon_themes; 85 static GtkListStore *prefs_status_icon_themes;
81 86
87 static GtkWidget *prefs_sound_themes_combo_box;
88 static GtkWidget *prefs_blist_themes_combo_box;
89 static GtkWidget *prefs_status_themes_combo_box;
82 90
83 /* 91 /*
84 * PROTOTYPES 92 * PROTOTYPES
85 */ 93 */
86 static void delete_prefs(GtkWidget *, void *); 94 static void delete_prefs(GtkWidget *, void *);
440 } 448 }
441 449
442 return row_ref; 450 return row_ref;
443 } 451 }
444 452
445 static void theme_install_theme(char *path, char *extn) { 453 /* Rebuild the markup for the sound theme selection for "(Custom)" themes */
454 static void
455 pref_sound_generate_markup()
456 {
457 gboolean print_custom, customized;
458 const gchar *name, *author, *description, *current_theme;
459 gchar *markup;
460 PurpleSoundTheme *theme;
461 GtkTreeIter iter;
462
463 customized = pidgin_sound_is_customized();
464 current_theme = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme");
465
466 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs_sound_themes), &iter)) {
467 do {
468 gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &iter, 2, &name, -1);
469
470 print_custom = customized && g_str_equal(current_theme, name);
471
472 if (!name || *name == '\0')
473 markup = g_strdup_printf("<b>(Default)</b>%s%s - None\n<span foreground='dim grey'>The default Pidgin sound theme</span>",
474 print_custom ? " " : "", print_custom ? "(Custom)" : "");
475 else {
476 theme = PURPLE_SOUND_THEME(purple_theme_manager_find_theme(name, "sound"));
477 author = purple_theme_get_author(PURPLE_THEME(theme));
478 description = purple_theme_get_description(PURPLE_THEME(theme));
479
480 markup = g_strdup_printf("<b>%s</b>%s%s%s%s\n<span foreground='dim grey'>%s</span>",
481 name, print_custom ? " " : "", print_custom ? "(Custom)" : "",
482 author != NULL ? " - " : "", author != NULL ? author : "", description != NULL ? description : "");
483 }
484
485 gtk_list_store_set(prefs_sound_themes, &iter, 1, markup, -1);
486
487 g_free(markup);
488
489 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs_sound_themes), &iter));
490 }
491 }
492
493 /* adds the themes to the theme list from the manager so they can be displayed in prefs */
494 static void
495 prefs_themes_sort(PurpleTheme *theme)
496 {
497 GdkPixbuf *pixbuf = NULL;
498 GtkTreeIter iter;
499 gchar *image_full = NULL, *markup;
500 const gchar *name, *author, *description;
501
502 if (PURPLE_IS_SOUND_THEME(theme)){
503
504 image_full = purple_theme_get_image_full(theme);
505 if (image_full != NULL){
506 pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL);
507 g_free(image_full);
508 } else pixbuf = NULL;
509
510 gtk_list_store_append(prefs_sound_themes, &iter);
511 gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, purple_theme_get_name(theme), -1);
512
513 if (pixbuf != NULL)
514 g_object_unref(G_OBJECT(pixbuf));
515
516 } else if (PIDGIN_IS_BLIST_THEME(theme) || PIDGIN_IS_STATUS_ICON_THEME(theme)){
517 GtkListStore *store;
518
519 if (PIDGIN_IS_BLIST_THEME(theme))
520 store = prefs_blist_themes;
521 else store = prefs_status_icon_themes;
522
523 image_full = purple_theme_get_image_full(theme);
524 if (image_full != NULL){
525 pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL);
526 g_free(image_full);
527 } else pixbuf = NULL;
528
529 name = purple_theme_get_name(theme);
530 author = purple_theme_get_author(theme);
531 description = purple_theme_get_description(theme);
532
533 markup = g_strdup_printf("<b>%s</b>%s%s\n<span foreground='dim grey'>%s</span>", name, author != NULL ? " - " : "",
534 author != NULL ? author : "", description != NULL ? description : "");
535
536 gtk_list_store_append(store, &iter);
537 gtk_list_store_set(store, &iter, 0, pixbuf, 1, markup, 2, name, -1);
538
539 g_free(markup);
540 if (pixbuf != NULL)
541 g_object_unref(G_OBJECT(pixbuf));
542 }
543 }
544
545 static void
546 prefs_set_active_theme_combo(GtkWidget *combo_box, GtkListStore *store, const gchar *current_theme)
547 {
548 GtkTreeIter iter;
549 gchar *theme = NULL;
550 gboolean unset = TRUE;
551
552 if (current_theme && *current_theme && gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) {
553 do {
554 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 2, &theme, -1);
555
556 if (g_str_equal(current_theme, theme)) {
557 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo_box), &iter);
558 unset = FALSE;
559 }
560
561 g_free(theme);
562 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
563 }
564
565 if (unset)
566 gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
567 }
568
569 static void
570 prefs_themes_refresh()
571 {
572 GdkPixbuf *pixbuf = NULL;
573 gchar *filename;
574 GtkTreeIter iter;
575
576 /* refresh the list of themes in the manager */
577 purple_theme_manager_refresh();
578
579 filename = g_build_filename(DATADIR, "icons", "hicolor", "32x32", "apps", "pidgin.png", NULL);
580 pixbuf = gdk_pixbuf_new_from_file_at_scale(filename, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL);
581 g_free(filename);
582
583 /* sound themes */
584 gtk_list_store_clear(prefs_sound_themes);
585 gtk_list_store_append(prefs_sound_themes, &iter);
586 gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, "", -1);
587
588 /* blist themes */
589 gtk_list_store_clear(prefs_blist_themes);
590 gtk_list_store_append(prefs_blist_themes, &iter);
591 gtk_list_store_set(prefs_blist_themes, &iter, 0, pixbuf, 1,
592 "<b>(Default)</b> - None\n<span color='dim grey'>"
593 "The default Pidgin buddy list theme</span>", 2, "", -1);
594
595 /* status icon themes */
596 gtk_list_store_clear(prefs_status_icon_themes);
597 gtk_list_store_append(prefs_status_icon_themes, &iter);
598 gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1,
599 "<b>(Default)</b> - None\n<span color='dim grey'>"
600 "The default Pidgin status icon theme</span>", 2, "", -1);
601 g_object_unref(G_OBJECT(pixbuf));
602
603 purple_theme_manager_for_each_theme(prefs_themes_sort);
604 pref_sound_generate_markup();
605
606 /* set active */
607 prefs_set_active_theme_combo(prefs_sound_themes_combo_box, prefs_sound_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"));
608 prefs_set_active_theme_combo(prefs_blist_themes_combo_box, prefs_blist_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme"));
609 prefs_set_active_theme_combo(prefs_status_themes_combo_box, prefs_status_icon_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme"));
610 }
611
612 /* init all the theme variables so that the themes can be sorted later and used by pref pages */
613 static void
614 prefs_themes_init()
615 {
616 prefs_sound_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
617
618 prefs_blist_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
619
620 prefs_status_icon_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
621 }
622
623 static PurpleTheme *
624 prefs_theme_find_theme(const gchar *path, const gchar *type)
625 {
626 PurpleTheme *theme = purple_theme_manager_load_theme(path, type);
627 GDir *dir = g_dir_open(path, 0, NULL);
628 const gchar *next;
629
630 while (!PURPLE_IS_THEME(theme) && (next = g_dir_read_name(dir))) {
631 gchar *next_path = g_build_filename(path, next, NULL);
632
633 if (g_file_test(next_path, G_FILE_TEST_IS_DIR))
634 theme = prefs_theme_find_theme(next_path, type);
635
636 g_free(next_path);
637 }
638
639 g_dir_close(dir);
640
641 return theme;
642 }
643
644 /* installs a theme, info is freed by function */
645 static void
646 theme_install_theme(char *path, struct theme_info *info) {
446 #ifndef _WIN32 647 #ifndef _WIN32
447 gchar *command; 648 gchar *command;
448 #endif 649 #endif
449 gchar *destdir; 650 gchar *destdir, *tail, *type, *original_name;
450 gchar *tail; 651 GtkTreeRowReference *theme_rowref;
451 GtkTreeRowReference *theme_rowref; 652 gboolean is_smiley_theme, is_archive;
653 PurpleTheme *theme = NULL;
654
655 if (info == NULL)
656 return;
657
658 original_name = info->original_name;
659 type = info->type;
660
661 /* check the extension */
662 tail = info->extension ? info->extension : g_strdup(strrchr(path, '.'));
663
664 if (!tail) {
665 g_free(type);
666 g_free(original_name);
667 g_free(info);
668 return;
669 } else g_free(info);
670
671 is_archive = !g_ascii_strcasecmp(tail, ".gz") || !g_ascii_strcasecmp(tail, ".tgz");
672
673 g_free(tail);
452 674
453 /* Just to be safe */ 675 /* Just to be safe */
454 g_strchomp(path); 676 g_strchomp(path);
455 677
456 /* I dont know what you are, get out of here */ 678 if ((is_smiley_theme = g_str_equal(type, "smiley")))
457 if (extn != NULL) 679 destdir = g_build_filename(purple_user_dir(), "smileys", NULL);
458 tail = extn; 680 else destdir = g_build_filename(purple_user_dir(), "themes", "temp", NULL);
459 else if ((tail = strrchr(path, '.')) == NULL)
460 return;
461
462 destdir = g_strconcat(purple_user_dir(), G_DIR_SEPARATOR_S "smileys", NULL);
463 681
464 /* We'll check this just to make sure. This also lets us do something different on 682 /* We'll check this just to make sure. This also lets us do something different on
465 * other platforms, if need be */ 683 * other platforms, if need be */
466 if (!g_ascii_strcasecmp(tail, ".gz") || !g_ascii_strcasecmp(tail, ".tgz")) { 684 if (is_archive) {
467 #ifndef _WIN32 685 #ifndef _WIN32
468 gchar *path_escaped = g_shell_quote(path); 686 gchar *path_escaped = g_shell_quote(path);
469 gchar *destdir_escaped = g_shell_quote(destdir); 687 gchar *destdir_escaped = g_shell_quote(destdir);
688
689 if (!g_file_test(destdir, G_FILE_TEST_IS_DIR))
690 g_mkdir_with_parents(destdir, 0700);
691
470 command = g_strdup_printf("tar > /dev/null xzf %s -C %s", path_escaped, destdir_escaped); 692 command = g_strdup_printf("tar > /dev/null xzf %s -C %s", path_escaped, destdir_escaped);
471 g_free(path_escaped); 693 g_free(path_escaped);
472 g_free(destdir_escaped); 694 g_free(destdir_escaped);
695
696 /* Fire! */
697 if (system(command)) {
698 purple_notify_error(NULL, NULL, _("Theme failed to unpack."), NULL);
699 g_free(command);
700 g_free(destdir);
701 g_free(type);
702 g_free(original_name);
703 return;
704 }
473 #else 705 #else
474 if(!winpidgin_gz_untar(path, destdir)) { 706 if(!winpidgin_gz_untar(path, destdir)) {
475 g_free(destdir); 707 g_free(destdir);
708 g_free(type);
709 g_free(original_name);
476 return; 710 return;
477 } 711 }
478 #endif 712 #endif
479 } 713 }
480 else { 714
481 g_free(destdir); 715 if (is_smiley_theme) {
482 return; 716 /* just extract the folder to the smiley directory */
483 } 717 theme_rowref = theme_refresh_theme_list();
484 718
485 #ifndef _WIN32 719 if (theme_rowref != NULL) {
486 /* Fire! */ 720 GtkTreePath *tp = gtk_tree_row_reference_get_path(theme_rowref);
487 if (system(command)) 721
488 { 722 if (tp)
489 purple_notify_error(NULL, NULL, _("Smiley theme failed to unpack."), NULL); 723 gtk_tree_selection_select_path(smiley_theme_sel, tp);
490 } 724
491 725 gtk_tree_row_reference_free(theme_rowref);
492 g_free(command); 726 }
493 #endif 727
728 } else if (is_archive) {
729 theme = prefs_theme_find_theme(destdir, type);
730
731 if (PURPLE_IS_THEME(theme)) {
732 /* create the location for the theme */
733 gchar *theme_dest = g_build_filename(purple_user_dir(), "themes",
734 purple_theme_get_name(theme),
735 "purple", type, NULL);
736
737 if (!g_file_test(theme_dest, G_FILE_TEST_IS_DIR))
738 g_mkdir_with_parents(theme_dest, 0700);
739
740 g_free(theme_dest);
741 theme_dest = g_build_filename(purple_user_dir(), "themes",
742 purple_theme_get_name(theme),
743 "purple", type, NULL);
744
745 /* move the entire directory to new location */
746 g_rename(purple_theme_get_dir(theme), theme_dest);
747
748 g_free(theme_dest);
749 g_remove(destdir);
750 g_object_unref(theme);
751
752 prefs_themes_refresh();
753
754 } else {
755 /* something was wrong with the theme archive */
756 g_unlink(destdir);
757 purple_notify_error(NULL, NULL, _("Theme failed to load."), NULL);
758 }
759
760 } else { /* just a single file so copy it to a new temp directory and attempt to load it*/
761 GFile *source, *destination;
762 gchar *temp_path, *temp_file;
763
764 source = g_file_new_for_path(path);
765
766 temp_path = g_build_filename(purple_user_dir(), "themes", "temp", "sub_folder", NULL);
767
768 if (original_name != NULL) {
769 /* name was changed from the original (probably a dnd) change it back before loading */
770 temp_file = g_build_filename(temp_path, original_name, NULL);
771
772 } else {
773 /* find the file name and name the new file the same thing */
774 GFileInfo* file_info = g_file_query_info (source,
775 G_FILE_ATTRIBUTE_STANDARD_NAME,
776 G_FILE_QUERY_INFO_NONE,
777 NULL,
778 NULL);
779
780 const gchar *source_name = g_file_info_get_content_type(file_info);
781
782 temp_file = g_build_filename(temp_path, source_name, NULL);
783
784 g_object_unref(file_info);
785 }
786
787 destination = g_file_new_for_path(temp_file);
788
789 if (!g_file_test(temp_path, G_FILE_TEST_IS_DIR))
790 g_mkdir_with_parents(temp_path, 0700);
791
792 g_file_copy(source, destination, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
793
794 g_object_unref(source);
795 g_object_unref(destination);
796
797 /* find the theme, could be in subfolder */
798 theme = prefs_theme_find_theme(temp_path, type);
799
800 if (PURPLE_IS_THEME(theme)) {
801 gchar *theme_dest = g_build_filename(purple_user_dir(), "themes",
802 purple_theme_get_name(theme),
803 "purple", type, NULL);
804
805 if(!g_file_test(theme_dest, G_FILE_TEST_IS_DIR))
806 g_mkdir_with_parents(theme_dest, 0700);
807
808 g_rename(purple_theme_get_dir(theme), theme_dest);
809
810 g_free(theme_dest);
811 g_object_unref(theme);
812
813 prefs_themes_refresh();
814
815 } else {
816 g_remove(temp_path);
817 purple_notify_error(NULL, NULL, _("Theme failed to load."), NULL);
818 }
819
820 g_free(temp_file);
821 g_free(temp_path);
822 }
823
824 g_free(type);
825 g_free(original_name);
494 g_free(destdir); 826 g_free(destdir);
495
496 theme_rowref = theme_refresh_theme_list();
497 if (theme_rowref != NULL) {
498 GtkTreePath *tp = gtk_tree_row_reference_get_path(theme_rowref);
499
500 if (tp)
501 gtk_tree_selection_select_path(smiley_theme_sel, tp);
502 gtk_tree_row_reference_free(theme_rowref);
503 }
504 } 827 }
505 828
506 static void 829 static void
507 theme_got_url(PurpleUtilFetchUrlData *url_data, gpointer user_data, 830 theme_got_url(PurpleUtilFetchUrlData *url_data, gpointer user_data,
508 const gchar *themedata, size_t len, const gchar *error_message) 831 const gchar *themedata, size_t len, const gchar *error_message)
531 g_free(path); 854 g_free(path);
532 } 855 }
533 856
534 static void 857 static void
535 theme_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, 858 theme_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
536 GtkSelectionData *sd, guint info, guint t, gpointer data) 859 GtkSelectionData *sd, guint info, guint t, gpointer user_data)
537 { 860 {
538 gchar *name = (gchar *)sd->data; 861 gchar *name = g_strchomp((gchar *)sd->data);
539 862
540 if ((sd->length >= 0) && (sd->format == 8)) { 863 if ((sd->length >= 0) && (sd->format == 8)) {
541 /* Well, it looks like the drag event was cool. 864 /* Well, it looks like the drag event was cool.
542 * Let's do something with it */ 865 * Let's do something with it */
866 gchar *temp;
867 struct theme_info *info = g_new0(struct theme_info, 1);
868 info->type = g_strdup((gchar *)user_data);
869 info->extension = g_strdup(g_strrstr(name,"."));
870 temp = g_strrstr(name, "/");
871 info->original_name = temp ? g_strdup(++temp) : NULL;
543 872
544 if (!g_ascii_strncasecmp(name, "file://", 7)) { 873 if (!g_ascii_strncasecmp(name, "file://", 7)) {
545 GError *converr = NULL; 874 GError *converr = NULL;
546 gchar *tmp; 875 gchar *tmp;
547 /* It looks like we're dealing with a local file. Let's 876 /* It looks like we're dealing with a local file. Let's
550 purple_debug(PURPLE_DEBUG_ERROR, "theme dnd", "%s\n", 879 purple_debug(PURPLE_DEBUG_ERROR, "theme dnd", "%s\n",
551 (converr ? converr->message : 880 (converr ? converr->message :
552 "g_filename_from_uri error")); 881 "g_filename_from_uri error"));
553 return; 882 return;
554 } 883 }
555 theme_install_theme(tmp, NULL); 884 theme_install_theme(tmp, info);
556 g_free(tmp); 885 g_free(tmp);
557 } else if (!g_ascii_strncasecmp(name, "http://", 7)) { 886 } else if (!g_ascii_strncasecmp(name, "http://", 7)) {
558 /* Oo, a web drag and drop. This is where things 887 /* Oo, a web drag and drop. This is where things
559 * will start to get interesting */ 888 * will start to get interesting */
560 purple_util_fetch_url(name, TRUE, NULL, FALSE, theme_got_url, ".tgz"); 889 purple_util_fetch_url(name, TRUE, NULL, FALSE, theme_got_url, info);
561 } else if (!g_ascii_strncasecmp(name, "https://", 8)) { 890 } else if (!g_ascii_strncasecmp(name, "https://", 8)) {
562 /* purple_util_fetch_url() doesn't support HTTPS, but we want users 891 /* purple_util_fetch_url() doesn't support HTTPS, but we want users
563 * to be able to drag and drop links from the SF trackers, so 892 * to be able to drag and drop links from the SF trackers, so
564 * we'll try it as an HTTP URL. */ 893 * we'll try it as an HTTP URL. */
565 char *tmp = g_strdup(name + 1); 894 char *tmp = g_strdup(name + 1);
566 tmp[0] = 'h'; 895 tmp[0] = 'h';
567 tmp[1] = 't'; 896 tmp[1] = 't';
568 tmp[2] = 't'; 897 tmp[2] = 't';
569 tmp[3] = 'p'; 898 tmp[3] = 'p';
570 purple_util_fetch_url(tmp, TRUE, NULL, FALSE, theme_got_url, ".tgz"); 899
900 purple_util_fetch_url(tmp, TRUE, NULL, FALSE, theme_got_url, info);
571 g_free(tmp); 901 g_free(tmp);
572 } 902 }
573 903
574 gtk_drag_finish(dc, TRUE, FALSE, t); 904 gtk_drag_finish(dc, TRUE, FALSE, t);
575 } 905 }
576 906
577 gtk_drag_finish(dc, FALSE, FALSE, t); 907 gtk_drag_finish(dc, FALSE, FALSE, t);
578 }
579
580 /* Rebuild the markup for the sound theme selection for "(Custom)" themes */
581 static void
582 pref_sound_generate_markup()
583 {
584 gboolean print_custom, customized;
585 const gchar *name, *author, *description, *current_theme;
586 gchar *markup;
587 PurpleSoundTheme *theme;
588 GtkTreeIter iter;
589
590 customized = pidgin_sound_is_customized();
591 current_theme = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme");
592
593 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs_sound_themes), &iter)) {
594 do {
595 gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &iter, 2, &name, -1);
596
597 print_custom = customized && g_str_equal(current_theme, name);
598
599 if (g_str_equal(name, ""))
600 markup = g_strdup_printf("<b>(Default)</b>%s%s - None\n<span foreground='dim grey'>The default Pidgin sound theme</span>",
601 print_custom ? " " : "", print_custom ? "(Custom)" : "");
602 else {
603 theme = PURPLE_SOUND_THEME(purple_theme_manager_find_theme(name, "sound"));
604 author = purple_theme_get_author(PURPLE_THEME(theme));
605 description = purple_theme_get_description(PURPLE_THEME(theme));
606
607 markup = g_strdup_printf("<b>%s</b>%s%s%s%s\n<span foreground='dim grey'>%s</span>",
608 name, print_custom ? " " : "", print_custom ? "(Custom)" : "",
609 author != NULL ? " - " : "", author != NULL ? author : "", description != NULL ? description : "");
610 }
611
612 gtk_list_store_set(prefs_sound_themes, &iter, 1, markup, -1);
613
614 g_free(markup);
615
616 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs_sound_themes), &iter));
617 }
618 }
619
620 /* adds the themes to the theme list from the manager so they can be sisplayed in prefs */
621 static void
622 prefs_themes_sort(PurpleTheme *theme)
623 {
624 GdkPixbuf *pixbuf = NULL;
625 GtkTreeIter iter;
626 gchar *image_full = NULL, *markup;
627 const gchar *name, *author, *description;
628
629 if (PURPLE_IS_SOUND_THEME(theme)){
630
631 image_full = purple_theme_get_image_full(theme);
632 if (image_full != NULL){
633 pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL);
634 g_free(image_full);
635 } else pixbuf = NULL;
636
637 gtk_list_store_append(prefs_sound_themes, &iter);
638 gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, purple_theme_get_name(theme), -1);
639
640 if (pixbuf != NULL)
641 g_object_unref(G_OBJECT(pixbuf));
642
643 } else if (PIDGIN_IS_BLIST_THEME(theme) || PIDGIN_IS_STATUS_ICON_THEME(theme)){
644 GtkListStore *store;
645
646 if (PIDGIN_IS_BLIST_THEME(theme))
647 store = prefs_blist_themes;
648 else store = prefs_status_icon_themes;
649
650 image_full = purple_theme_get_image_full(theme);
651 if (image_full != NULL){
652 pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL);
653 g_free(image_full);
654 } else pixbuf = NULL;
655
656 name = purple_theme_get_name(theme);
657 author = purple_theme_get_author(theme);
658 description = purple_theme_get_description(theme);
659
660 markup = g_strdup_printf("<b>%s</b>%s%s\n<span foreground='dim grey'>%s</span>", name, author != NULL ? " - " : "",
661 author != NULL ? author : "", description != NULL ? description : "");
662
663 gtk_list_store_append(store, &iter);
664 gtk_list_store_set(store, &iter, 0, pixbuf, 1, markup, 2, name, -1);
665
666 g_free(markup);
667 if (pixbuf != NULL)
668 g_object_unref(G_OBJECT(pixbuf));
669 }
670
671 }
672
673 /* init all the theme variables so that the themes can be sorted later and used by pref pages */
674 static void
675 prefs_themes_init()
676 {
677 GdkPixbuf *pixbuf = NULL;
678 gchar *filename;
679 GtkTreeIter iter;
680
681 filename = g_build_filename(DATADIR, "icons", "hicolor", "32x32", "apps", "pidgin.png", NULL);
682 pixbuf = gdk_pixbuf_new_from_file_at_scale(filename, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL);
683 g_free(filename);
684
685 /* sound themes */
686 prefs_sound_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
687
688 gtk_list_store_append(prefs_sound_themes, &iter);
689 gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, "", -1);
690
691 /* blist themes */
692 prefs_blist_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
693
694 gtk_list_store_append(prefs_blist_themes, &iter);
695 gtk_list_store_set(prefs_blist_themes, &iter, 0, pixbuf, 1, "<b>(Default)</b> - None\n<span color='dim grey'>"
696 "The default Pidgin buddy list theme</span>", 2, "", -1);
697
698 /* status icon themes */
699 prefs_status_icon_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
700
701 gtk_list_store_append(prefs_status_icon_themes, &iter);
702 gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1, "<b>(Default)</b> - None\n<span color='dim grey'>"
703 "The default Pidgin status icon theme</span>", 2, "", -1);
704
705 g_object_unref(G_OBJECT(pixbuf));
706 } 908 }
707 909
708 /* builds a theme combo box from a list store with colums: icon preview, markup, theme name */ 910 /* builds a theme combo box from a list store with colums: icon preview, markup, theme name */
709 static GtkWidget * 911 static GtkWidget *
710 prefs_build_theme_combo_box(GtkListStore *store, const gchar *current_theme) 912 prefs_build_theme_combo_box(GtkListStore *store, const gchar *current_theme, gchar *type)
711 { 913 {
914 GtkCellRenderer *cell_rend;
712 GtkWidget *combo_box; 915 GtkWidget *combo_box;
713 GtkCellRenderer *cell_rend; 916 GtkTargetEntry te[3] = {{"text/plain", 0, 0},{"text/uri-list", 0, 1},{"STRING", 0, 2}};
714 GtkTreeIter iter;
715 gchar *theme = NULL;
716 gboolean unset = TRUE;
717 917
718 g_return_val_if_fail(store != NULL && current_theme != NULL, NULL); 918 g_return_val_if_fail(store != NULL && current_theme != NULL, NULL);
719 919
720 combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); 920 combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
721 921
729 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "markup", 1, NULL); 929 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "markup", 1, NULL);
730 /*#if GTK_CHECK_VERSION(2,6,0) 930 /*#if GTK_CHECK_VERSION(2,6,0)
731 g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); 931 g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
732 #endif*/ 932 #endif*/
733 933
734 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) { 934 gtk_drag_dest_set(combo_box, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te,
735 do { 935 sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE);
736 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 2, &theme, -1); 936
737 937 g_signal_connect(G_OBJECT(combo_box), "drag_data_received", G_CALLBACK(theme_dnd_recv), type);
738 if (g_str_equal(current_theme, theme)) {
739 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo_box), &iter);
740 unset = FALSE;
741 }
742
743 g_free(theme);
744 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
745 }
746
747 if (unset)
748 gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
749 938
750 return combo_box; 939 return combo_box;
751 } 940 }
752 941
753 /* sets the current sound theme */ 942 /* sets the current sound theme */
755 prefs_set_sound_theme_cb(GtkComboBox *combo_box, gpointer user_data) 944 prefs_set_sound_theme_cb(GtkComboBox *combo_box, gpointer user_data)
756 { 945 {
757 gint i; 946 gint i;
758 gchar *pref; 947 gchar *pref;
759 gchar *new_theme; 948 gchar *new_theme;
760 gboolean success;
761 GtkTreeIter new_iter; 949 GtkTreeIter new_iter;
762 950
763 success = gtk_combo_box_get_active_iter(combo_box, &new_iter); 951 if(gtk_combo_box_get_active_iter(combo_box, &new_iter)) {
764 g_return_if_fail(success); 952
765 953 gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &new_iter, 2, &new_theme, -1);
766 gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &new_iter, 2, &new_theme, -1); 954
767 955 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/sound/theme", new_theme);
768 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/sound/theme", new_theme); 956
769 957 /* New theme removes all customization */
770 /* New theme removes all customization */ 958 for(i=0; i < PURPLE_NUM_SOUNDS; i++){
771 for(i=0; i < PURPLE_NUM_SOUNDS; i++){ 959 pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s",
772 pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s", 960 pidgin_sound_get_event_option(i));
773 pidgin_sound_get_event_option(i)); 961 purple_prefs_set_path(pref, "");
774 purple_prefs_set_path(pref, ""); 962 g_free(pref);
775 g_free(pref); 963 }
776 } 964
777 965 /* gets rid of the "(Custom)" from the last selection */
778 /* gets rid of the "(Custom)" from the last selection */ 966 pref_sound_generate_markup();
779 pref_sound_generate_markup(); 967
780 968 gtk_entry_set_text(GTK_ENTRY(sound_entry), _("(default)"));
781 gtk_entry_set_text(GTK_ENTRY(sound_entry), _("(default)")); 969
782 970 g_free(new_theme);
783 g_free(new_theme); 971 }
784 } 972 }
973
785 974
786 /* Does same as normal sort, except "none" is sorted first */ 975 /* Does same as normal sort, except "none" is sorted first */
787 static gint pidgin_sort_smileys (GtkTreeModel *model, 976 static gint pidgin_sort_smileys (GtkTreeModel *model,
788 GtkTreeIter *a, 977 GtkTreeIter *a,
789 GtkTreeIter *b, 978 GtkTreeIter *b,
819 } 1008 }
820 1009
821 static void 1010 static void
822 request_theme_file_name_cb(gpointer data, char *theme_file_name) 1011 request_theme_file_name_cb(gpointer data, char *theme_file_name)
823 { 1012 {
824 theme_install_theme(theme_file_name, NULL) ; 1013 struct theme_info *info = g_new0(struct theme_info, 1);
825 } 1014 info->type = g_strdup("smiley");
826 1015 info->extension = NULL;
827 static void 1016 info->original_name = NULL;
828 add_theme_button_clicked_cb(GtkWidget *widget, gpointer null) 1017
1018 theme_install_theme(theme_file_name, info) ;
1019
1020 g_free(info);
1021 }
1022
1023 static void
1024 add_theme_button_clicked_cb(GtkWidget *widget, gpointer user_data)
829 { 1025 {
830 purple_request_file(NULL, _("Install Theme"), NULL, FALSE, (GCallback)request_theme_file_name_cb, NULL, NULL, NULL, NULL, NULL) ; 1026 purple_request_file(NULL, _("Install Theme"), NULL, FALSE, (GCallback)request_theme_file_name_cb, NULL, NULL, NULL, NULL, NULL) ;
831 } 1027 }
832 1028
833 static void 1029 static void
901 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(smiley_theme_store)); 1097 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(smiley_theme_store));
902 1098
903 gtk_drag_dest_set(view, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te, 1099 gtk_drag_dest_set(view, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te,
904 sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE); 1100 sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE);
905 1101
906 g_signal_connect(G_OBJECT(view), "drag_data_received", G_CALLBACK(theme_dnd_recv), smiley_theme_store); 1102 g_signal_connect(G_OBJECT(view), "drag_data_received", G_CALLBACK(theme_dnd_recv), "smiley");
907 1103
908 rend = gtk_cell_renderer_pixbuf_new(); 1104 rend = gtk_cell_renderer_pixbuf_new();
909 smiley_theme_sel = sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); 1105 smiley_theme_sel = sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
910 1106
911 /* Custom sort so "none" theme is at top of list */ 1107 /* Custom sort so "none" theme is at top of list */
1161 1357
1162 /* sets the current buddy list theme */ 1358 /* sets the current buddy list theme */
1163 static void 1359 static void
1164 prefs_set_blist_theme_cb(GtkComboBox *combo_box, gpointer user_data) 1360 prefs_set_blist_theme_cb(GtkComboBox *combo_box, gpointer user_data)
1165 { 1361 {
1166 PidginBlistTheme *theme = NULL; 1362 PidginBlistTheme *theme = NULL;
1167 GtkTreeIter iter; 1363 GtkTreeIter iter;
1168 gchar *name = NULL; 1364 gchar *name = NULL;
1169 1365
1170 g_return_if_fail(gtk_combo_box_get_active_iter(combo_box, &iter)); 1366 if(gtk_combo_box_get_active_iter(combo_box, &iter)) {
1171 gtk_tree_model_get(GTK_TREE_MODEL(prefs_blist_themes), &iter, 2, &name, -1); 1367
1172 1368 gtk_tree_model_get(GTK_TREE_MODEL(prefs_blist_themes), &iter, 2, &name, -1);
1173 if (name && *name) 1369
1174 theme = PIDGIN_BLIST_THEME(purple_theme_manager_find_theme(name, "blist")); 1370 if(!name || !g_str_equal(name, ""))
1175 g_free(name); 1371 theme = PIDGIN_BLIST_THEME(purple_theme_manager_find_theme(name, "blist"));
1176 1372
1177 pidgin_blist_set_theme(theme); 1373 g_free(name);
1374
1375 pidgin_blist_set_theme(theme);
1376 }
1178 } 1377 }
1179 1378
1180 /* sets the current icon theme */ 1379 /* sets the current icon theme */
1181 static void 1380 static void
1182 prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data) 1381 prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data)
1183 { 1382 {
1184 PidginStatusIconTheme *theme; 1383 PidginStatusIconTheme *theme = NULL;
1185 GtkTreeIter iter; 1384 GtkTreeIter iter;
1186 gchar *name = NULL; 1385 gchar *name = NULL;
1187 1386
1188 g_return_if_fail(gtk_combo_box_get_active_iter(combo_box, &iter)); 1387 if(gtk_combo_box_get_active_iter(combo_box, &iter)) {
1189 gtk_tree_model_get(GTK_TREE_MODEL(prefs_status_icon_themes), &iter, 2, &name, -1); 1388
1190 1389 gtk_tree_model_get(GTK_TREE_MODEL(prefs_status_icon_themes), &iter, 2, &name, -1);
1191 theme = PIDGIN_STATUS_ICON_THEME(purple_theme_manager_find_theme(name, "status-icon")); 1390
1192 g_free(name); 1391 if(!name || !g_str_equal(name, ""))
1193 1392 theme = PIDGIN_STATUS_ICON_THEME(purple_theme_manager_find_theme(name, "status-icon"));
1194 pidgin_stock_load_status_icon_theme(theme); 1393
1394 g_free(name);
1395
1396 pidgin_stock_load_status_icon_theme(theme);
1397 }
1195 } 1398 }
1196 1399
1197 static GtkWidget * 1400 static GtkWidget *
1198 interface_page(void) 1401 interface_page(void)
1199 { 1402 {
1200 GtkWidget *ret; 1403 GtkWidget *ret;
1201 GtkWidget *vbox; 1404 GtkWidget *vbox;
1202 GtkWidget *vbox2; 1405 GtkWidget *vbox2;
1203 GtkWidget *label; 1406 GtkWidget *label;
1204 GtkWidget *combo_box;
1205 GtkSizeGroup *sg; 1407 GtkSizeGroup *sg;
1206 GList *names = NULL; 1408 GList *names = NULL;
1207 1409
1208 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); 1410 ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
1209 gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER); 1411 gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER);
1211 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); 1413 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1212 1414
1213 /* Buddy List Themes */ 1415 /* Buddy List Themes */
1214 vbox = pidgin_make_frame(ret, _("Buddy List Theme")); 1416 vbox = pidgin_make_frame(ret, _("Buddy List Theme"));
1215 1417
1216 combo_box = prefs_build_theme_combo_box(prefs_blist_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme")); 1418 prefs_blist_themes_combo_box = prefs_build_theme_combo_box(prefs_blist_themes,
1217 gtk_box_pack_start(GTK_BOX (vbox), combo_box, FALSE, FALSE, 0); 1419 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme"),
1218 g_signal_connect(G_OBJECT(combo_box), "changed", (GCallback)prefs_set_blist_theme_cb, NULL); 1420 "blist");
1421
1422 gtk_box_pack_start(GTK_BOX (vbox), prefs_blist_themes_combo_box, FALSE, FALSE, 0);
1423 g_signal_connect(G_OBJECT(prefs_blist_themes_combo_box), "changed", (GCallback)prefs_set_blist_theme_cb, NULL);
1219 1424
1220 /* Status Icon Themes */ 1425 /* Status Icon Themes */
1221 combo_box = prefs_build_theme_combo_box(prefs_status_icon_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme")); 1426 prefs_status_themes_combo_box = prefs_build_theme_combo_box(prefs_status_icon_themes,
1222 gtk_box_pack_start(GTK_BOX (vbox), combo_box, FALSE, FALSE, 0); 1427 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme"),
1223 g_signal_connect(G_OBJECT(combo_box), "changed", (GCallback)prefs_set_status_icon_theme_cb, NULL); 1428 "icon");
1429
1430 gtk_box_pack_start(GTK_BOX (vbox), prefs_status_themes_combo_box, FALSE, FALSE, 0);
1431 g_signal_connect(G_OBJECT(prefs_status_themes_combo_box), "changed", (GCallback)prefs_set_status_icon_theme_cb, NULL);
1224 1432
1225 /* System Tray */ 1433 /* System Tray */
1226 vbox = pidgin_make_frame(ret, _("System Tray Icon")); 1434 vbox = pidgin_make_frame(ret, _("System Tray Icon"));
1227 label = pidgin_prefs_dropdown(vbox, _("_Show system tray icon:"), PURPLE_PREF_STRING, 1435 label = pidgin_prefs_dropdown(vbox, _("_Show system tray icon:"), PURPLE_PREF_STRING,
1228 PIDGIN_PREFS_ROOT "/docklet/show", 1436 PIDGIN_PREFS_ROOT "/docklet/show",
2200 2408
2201 static GtkWidget * 2409 static GtkWidget *
2202 sound_page(void) 2410 sound_page(void)
2203 { 2411 {
2204 GtkWidget *ret; 2412 GtkWidget *ret;
2205 GtkWidget *vbox, *sw, *button, *combo_box; 2413 GtkWidget *vbox, *sw, *button;
2206 GtkSizeGroup *sg; 2414 GtkSizeGroup *sg;
2207 GtkTreeIter iter; 2415 GtkTreeIter iter;
2208 GtkWidget *event_view; 2416 GtkWidget *event_view;
2209 GtkListStore *event_store; 2417 GtkListStore *event_store;
2210 GtkCellRenderer *rend; 2418 GtkCellRenderer *rend;
2306 TRUE, 0, GTK_PACK_START); 2514 TRUE, 0, GTK_PACK_START);
2307 gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent->parent), 2515 gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent->parent),
2308 vbox->parent->parent, TRUE, TRUE, 0, GTK_PACK_START); 2516 vbox->parent->parent, TRUE, TRUE, 0, GTK_PACK_START);
2309 2517
2310 /* SOUND THEMES */ 2518 /* SOUND THEMES */
2311 combo_box = prefs_build_theme_combo_box(prefs_sound_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme")); 2519 prefs_sound_themes_combo_box = prefs_build_theme_combo_box(prefs_sound_themes,
2312 pref_sound_generate_markup(); 2520 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"),
2313 gtk_box_pack_start(GTK_BOX (vbox), combo_box, FALSE, FALSE, 0); 2521 "sound");
2314 2522
2315 g_signal_connect(G_OBJECT(combo_box), "changed", (GCallback)prefs_set_sound_theme_cb, NULL); 2523
2524 gtk_box_pack_start(GTK_BOX (vbox), prefs_sound_themes_combo_box, FALSE, FALSE, 0);
2525
2526 g_signal_connect(G_OBJECT(prefs_sound_themes_combo_box), "changed", (GCallback)prefs_set_sound_theme_cb, NULL);
2316 2527
2317 /* SOUND SELECTION */ 2528 /* SOUND SELECTION */
2318 sw = gtk_scrolled_window_new(NULL,NULL); 2529 sw = gtk_scrolled_window_new(NULL,NULL);
2319 gtk_widget_set_size_request(sw, -1, 100); 2530 gtk_widget_set_size_request(sw, -1, 100);
2320 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); 2531 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
2543 if (prefs) { 2754 if (prefs) {
2544 gtk_window_present(GTK_WINDOW(prefs)); 2755 gtk_window_present(GTK_WINDOW(prefs));
2545 return; 2756 return;
2546 } 2757 }
2547 2758
2548 /* Refresh the list of themes before showing the preferences window */
2549 purple_theme_manager_refresh();
2550
2551 /* add everything in the theme manager before the window is loaded */
2552 if (prefs_themes_unsorted) {
2553 purple_theme_manager_for_each_theme(prefs_themes_sort);
2554 prefs_themes_unsorted = FALSE;
2555 }
2556 /* copy the preferences to tmp values... 2759 /* copy the preferences to tmp values...
2557 * I liked "take affect immediately" Oh well :-( */ 2760 * I liked "take affect immediately" Oh well :-( */
2558 /* (that should have been "effect," right?) */ 2761 /* (that should have been "effect," right?) */
2559 2762
2560 /* Back to instant-apply! I win! BU-HAHAHA! */ 2763 /* Back to instant-apply! I win! BU-HAHAHA! */
2574 button = pidgin_dialog_add_button(GTK_DIALOG(prefs), GTK_STOCK_CLOSE, NULL, NULL); 2777 button = pidgin_dialog_add_button(GTK_DIALOG(prefs), GTK_STOCK_CLOSE, NULL, NULL);
2575 g_signal_connect_swapped(G_OBJECT(button), "clicked", 2778 g_signal_connect_swapped(G_OBJECT(button), "clicked",
2576 G_CALLBACK(gtk_widget_destroy), prefs); 2779 G_CALLBACK(gtk_widget_destroy), prefs);
2577 2780
2578 prefs_notebook_init(); 2781 prefs_notebook_init();
2782
2783 /* Refresh the list of themes before showing the preferences window */
2784 prefs_themes_refresh();
2579 2785
2580 /* Show everything. */ 2786 /* Show everything. */
2581 gtk_widget_show(prefs); 2787 gtk_widget_show(prefs);
2582 } 2788 }
2583 2789

mercurial