| 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) |
| 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 |