Mercurial > pidgin.yaz
diff pidgin/gtkprefs.c @ 25271:6ebabe0841a0
propagate from branch 'im.pidgin.pidgin' (head 06e4830f3567955e026f3d594afcc65a07d57b26)
to branch 'im.pidgin.pidgin.next.minor' (head 22a0659074cef317fb0f96d98d9628d193dd224d)
author | Gary Kramlich <grim@reaperworld.com> |
---|---|
date | Thu, 30 Oct 2008 03:03:55 +0000 |
parents | 1c45897c79fc 9525fb966efb |
children | ff6eba605ca3 |
line wrap: on
line diff
--- a/pidgin/gtkprefs.c Thu Oct 30 03:03:45 2008 +0000 +++ b/pidgin/gtkprefs.c Thu Oct 30 03:03:55 2008 +0000 @@ -35,6 +35,8 @@ #include "request.h" #include "savedstatuses.h" #include "sound.h" +#include "sound-theme.h" +#include "theme-manager.h" #include "util.h" #include "network.h" @@ -47,6 +49,7 @@ #include "gtkprefs.h" #include "gtksavedstatuses.h" #include "gtksound.h" +#include "gtkstatus-icon-theme.h" #include "gtkthemes.h" #include "gtkutils.h" #include "pidginstock.h" @@ -56,6 +59,8 @@ #define PROXYUSER 2 #define PROXYPASS 3 +#define PREFS_OPTIMAL_ICON_SIZE 32 + static int sound_row_sel = 0; static GtkWidget *prefsnotebook; @@ -69,6 +74,12 @@ static int notebook_page = 0; static GtkTreeRowReference *previous_smiley_row = NULL; +static gboolean prefs_themes_unsorted = TRUE; +static GtkListStore *prefs_sound_themes; +static GtkListStore *prefs_blist_themes; +static GtkListStore *prefs_status_icon_themes; + + /* * PROTOTYPES */ @@ -546,6 +557,213 @@ gtk_drag_finish(dc, FALSE, FALSE, t); } +/* Rebuild the markup for the sound theme selection for "(Custom)" themes */ +static void +pref_sound_generate_markup() +{ + gboolean print_custom, customized; + const gchar *name, *author, *description, *current_theme; + gchar *markup; + PurpleSoundTheme *theme; + GtkTreeIter iter; + + customized = pidgin_sound_is_customized(); + current_theme = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"); + + if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs_sound_themes), &iter)) { + do { + gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &iter, 2, &name, -1); + + print_custom = customized && g_str_equal(current_theme, name); + + if (g_str_equal(name, "")) + markup = g_strdup_printf("<b>(Default)</b>%s%s - None\n<span foreground='dim grey'>The default Pidgin sound theme</span>", + print_custom ? " " : "", print_custom ? "(Custom)" : ""); + else { + theme = PURPLE_SOUND_THEME(purple_theme_manager_find_theme(name, "sound")); + author = purple_theme_get_author(PURPLE_THEME(theme)); + description = purple_theme_get_description(PURPLE_THEME(theme)); + + markup = g_strdup_printf("<b>%s</b>%s%s%s%s\n<span foreground='dim grey'>%s</span>", + name, print_custom ? " " : "", print_custom ? "(Custom)" : "", + author != NULL ? " - " : "", author != NULL ? author : "", description != NULL ? description : ""); + } + + gtk_list_store_set(prefs_sound_themes, &iter, 1, markup, -1); + + g_free(markup); + + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs_sound_themes), &iter)); + } +} + +/* adds the themes to the theme list from the manager so they can be sisplayed in prefs */ +static void +prefs_themes_sort(PurpleTheme *theme) +{ + GdkPixbuf *pixbuf = NULL; + GtkTreeIter iter; + gchar *image_full = NULL, *markup; + const gchar *name, *author, *description; + + if (PURPLE_IS_SOUND_THEME(theme)){ + + image_full = purple_theme_get_image_full(theme); + if (image_full != NULL){ + pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL); + g_free(image_full); + } else pixbuf = NULL; + + gtk_list_store_append(prefs_sound_themes, &iter); + gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, purple_theme_get_name(theme), -1); + + if (pixbuf != NULL) + gdk_pixbuf_unref(pixbuf); + + } else if (PIDGIN_IS_BLIST_THEME(theme) || PIDGIN_IS_STATUS_ICON_THEME(theme)){ + GtkListStore *store; + + if (PIDGIN_IS_BLIST_THEME(theme)) + store = prefs_blist_themes; + else store = prefs_status_icon_themes; + + image_full = purple_theme_get_image_full(theme); + if (image_full != NULL){ + pixbuf = gdk_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL); + g_free(image_full); + } else pixbuf = NULL; + + name = purple_theme_get_name(theme); + author = purple_theme_get_author(theme); + description = purple_theme_get_description(theme); + + markup = g_strdup_printf("<b>%s</b>%s%s\n<span foreground='dim grey'>%s</span>", name, author != NULL ? " - " : "", + author != NULL ? author : "", description != NULL ? description : ""); + + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, pixbuf, 1, markup, 2, name, -1); + + g_free(markup); + if (pixbuf != NULL) + gdk_pixbuf_unref(pixbuf); + } + +} + +/* init all the theme variables so that the themes can be sorted later and used by pref pages */ +static void +prefs_themes_init() +{ + GdkPixbuf *pixbuf = NULL; + gchar *filename; + GtkTreeIter iter; + + filename = g_build_filename(DATADIR, "icons", "hicolor", "32x32", "apps", "pidgin.png", NULL); + pixbuf = gdk_pixbuf_new_from_file_at_scale(filename, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE, NULL); + g_free(filename); + + /* sound themes */ + prefs_sound_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); + + gtk_list_store_append(prefs_sound_themes, &iter); + gtk_list_store_set(prefs_sound_themes, &iter, 0, pixbuf, 2, "", -1); + + /* blist themes */ + prefs_blist_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); + + gtk_list_store_append(prefs_blist_themes, &iter); + gtk_list_store_set(prefs_blist_themes, &iter, 0, pixbuf, 1, "<b>(Default)</b> - None\n<span color='dim grey'>" + "The default Pidgin buddy list theme</span>", 2, "", -1); + + /* status icon themes */ + prefs_status_icon_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); + + gtk_list_store_append(prefs_status_icon_themes, &iter); + gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1, "<b>(Default)</b> - None\n<span color='dim grey'>" + "The default Pidgin status icon theme</span>", 2, "", -1); + + gdk_pixbuf_unref(pixbuf); +} + +/* builds a theme combo box from a list store with colums: icon preview, markup, theme name */ +static GtkWidget * +prefs_build_theme_combo_box(GtkListStore *store, const gchar *current_theme) +{ + GtkWidget *combo_box; + GtkCellRenderer *cell_rend; + GtkTreeIter iter; + gchar *theme = NULL; + gboolean unset = TRUE; + + g_return_val_if_fail(store != NULL && current_theme != NULL, NULL); + + combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)); + + cell_rend = gtk_cell_renderer_pixbuf_new(); + gtk_cell_renderer_set_fixed_size(cell_rend, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, FALSE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "pixbuf", 0, NULL); + + cell_rend = gtk_cell_renderer_text_new(); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell_rend, FALSE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_rend, "markup", 1, NULL); +/*#if GTK_CHECK_VERSION(2,6,0) + g_object_set(cell_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); +#endif*/ + + if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) { + do { + gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 2, &theme, -1); + + if (g_str_equal(current_theme, theme)) { + gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo_box), &iter); + unset = FALSE; + } + + g_free(theme); + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)); + } + + if (unset) + gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0); + + return combo_box; +} + +/* sets the current sound theme */ +static void +prefs_set_sound_theme_cb(GtkComboBox *combo_box, gpointer user_data) +{ + gint i; + gchar *pref; + gchar *new_theme; + gboolean sucess; + GtkTreeIter new_iter; + + + sucess = gtk_combo_box_get_active_iter(combo_box, &new_iter); + g_return_if_fail(sucess); + + gtk_tree_model_get(GTK_TREE_MODEL(prefs_sound_themes), &new_iter, 2, &new_theme, -1); + + purple_prefs_set_string(PIDGIN_PREFS_ROOT "/sound/theme", new_theme); + + /* New theme removes all customization */ + for(i=0; i < PURPLE_NUM_SOUNDS; i++){ + pref = g_strdup_printf(PIDGIN_PREFS_ROOT "/sound/file/%s", + pidgin_sound_get_event_option(i)); + purple_prefs_set_path(pref, ""); + g_free(pref); + } + + /* gets rid of the "(Custom)" from the last selection */ + pref_sound_generate_markup(); + + gtk_entry_set_text(GTK_ENTRY(sound_entry), _("(default)")); + + g_free(new_theme); +} + /* Does same as normal sort, except "none" is sorted first */ static gint pidgin_sort_smileys (GtkTreeModel *model, GtkTreeIter *a, @@ -922,6 +1140,40 @@ gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE, 0); } +/* sets the current buddy list theme */ +static void +prefs_set_blist_theme_cb(GtkComboBox *combo_box, gpointer user_data) +{ + PidginBlistTheme *theme; + GtkTreeIter iter; + gchar *name = NULL; + + g_return_if_fail(gtk_combo_box_get_active_iter(combo_box, &iter)); + gtk_tree_model_get(GTK_TREE_MODEL(prefs_blist_themes), &iter, 2, &name, -1); + + theme = PIDGIN_BLIST_THEME(purple_theme_manager_find_theme(name, "blist")); + g_free(name); + + pidgin_blist_set_theme(theme); +} + +/* sets the current icon theme */ +static void +prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data) +{ + PidginStatusIconTheme *theme; + GtkTreeIter iter; + gchar *name = NULL; + + g_return_if_fail(gtk_combo_box_get_active_iter(combo_box, &iter)); + gtk_tree_model_get(GTK_TREE_MODEL(prefs_status_icon_themes), &iter, 2, &name, -1); + + theme = PIDGIN_STATUS_ICON_THEME(purple_theme_manager_find_theme(name, "status-icon")); + g_free(name); + + pidgin_stock_load_status_icon_theme(theme); +} + static GtkWidget * interface_page(void) { @@ -929,6 +1181,7 @@ GtkWidget *vbox; GtkWidget *vbox2; GtkWidget *label; + GtkWidget *combo_box; GtkSizeGroup *sg; GList *names = NULL; @@ -937,6 +1190,19 @@ sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + /* Buddy List Themes */ + vbox = pidgin_make_frame(ret, _("Buddy List Theme")); + + combo_box = prefs_build_theme_combo_box(prefs_blist_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme")); + gtk_box_pack_start(GTK_BOX (vbox), combo_box, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(combo_box), "changed", (GCallback)prefs_set_blist_theme_cb, NULL); + + /* Status Icon Themes */ + combo_box = prefs_build_theme_combo_box(prefs_status_icon_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme")); + gtk_box_pack_start(GTK_BOX (vbox), combo_box, FALSE, FALSE, 0); + g_signal_connect(G_OBJECT(combo_box), "changed", (GCallback)prefs_set_status_icon_theme_cb, NULL); + + /* System Tray */ vbox = pidgin_make_frame(ret, _("System Tray Icon")); label = pidgin_prefs_dropdown(vbox, _("_Show system tray icon:"), PURPLE_PREF_STRING, PIDGIN_PREFS_ROOT "/docklet/show", @@ -1736,6 +2002,8 @@ g_free(pref); gtk_entry_set_text(GTK_ENTRY(sound_entry), _("(default)")); + + pref_sound_generate_markup(); } static void @@ -1758,6 +2026,8 @@ */ if (sound == sound_row_sel) gtk_entry_set_text(GTK_ENTRY(sound_entry), filename); + + pref_sound_generate_markup(); } static void select_sound(GtkWidget *button, gpointer being_NULL_is_fun) @@ -1826,6 +2096,8 @@ if (sound_entry) gtk_entry_set_text(GTK_ENTRY(sound_entry), (file && *file != '\0') ? file : _("(default)")); g_value_unset (&val); + + pref_sound_generate_markup(); } @@ -1851,7 +2123,7 @@ sound_page(void) { GtkWidget *ret; - GtkWidget *vbox, *sw, *button; + GtkWidget *vbox, *sw, *button, *combo_box; GtkSizeGroup *sg; GtkTreeIter iter; GtkWidget *event_view; @@ -1945,7 +2217,6 @@ purple_prefs_connect_callback(prefs, PIDGIN_PREFS_ROOT "/sound/method", sound_changed2_cb, vbox); #endif - vbox = pidgin_make_frame(ret, _("Sound Events")); /* The following is an ugly hack to make the frame expand so the @@ -1957,6 +2228,14 @@ gtk_box_set_child_packing(GTK_BOX(vbox->parent->parent->parent), vbox->parent->parent, TRUE, TRUE, 0, GTK_PACK_START); + /* SOUND THEMES */ + combo_box = prefs_build_theme_combo_box(prefs_sound_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme")); + pref_sound_generate_markup(); + gtk_box_pack_start(GTK_BOX (vbox), combo_box, FALSE, FALSE, 0); + + g_signal_connect(G_OBJECT(combo_box), "changed", (GCallback)prefs_set_sound_theme_cb, NULL); + + /* SOUND SELECTION */ sw = gtk_scrolled_window_new(NULL,NULL); gtk_widget_set_size_request(sw, -1, 100); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); @@ -2189,7 +2468,12 @@ gtk_window_present(GTK_WINDOW(prefs)); return; } - + + /* add everthing in the thmeme manager before the window is loaded */ + if (prefs_themes_unsorted) { + purple_theme_manager_for_each_theme(prefs_themes_sort); + prefs_themes_unsorted = FALSE; + } /* copy the preferences to tmp values... * I liked "take affect immediately" Oh well :-( */ /* (that should have been "effect," right?) */ @@ -2284,6 +2568,9 @@ purple_prefs_add_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder", ""); purple_prefs_add_path(PIDGIN_PREFS_ROOT "/filelocations/last_icon_folder", ""); + /* Themes */ + prefs_themes_init(); + /* Smiley Themes */ purple_prefs_add_none(PIDGIN_PREFS_ROOT "/smileys"); purple_prefs_add_string(PIDGIN_PREFS_ROOT "/smileys/theme", "Default");