# HG changeset patch # User Justin Rodriguez # Date 1218159766 0 # Node ID 2d419a0fc0e4b9888968a152e2ec5e0e1252cbd0 # Parent d93578eb7244de2370ae6781947939e375f9207d partially working status icon theme stuff diff -r d93578eb7244 -r 2d419a0fc0e4 libpurple/xmlnode.c --- a/libpurple/xmlnode.c Wed Aug 06 02:54:39 2008 +0000 +++ b/libpurple/xmlnode.c Fri Aug 08 01:42:46 2008 +0000 @@ -728,6 +728,78 @@ return ret; } +xmlnode * +xmlnode_from_file(const char *dir, const char *filename, const char *description, const char *process) +{ + gchar *filename_full; + GError *error = NULL; + gchar *contents = NULL; + gsize length; + xmlnode *node = NULL; + + g_return_val_if_fail(dir != NULL, NULL); + + purple_debug_info(process, "Reading file %s from directory %s\n", + filename, dir); + + filename_full = g_build_filename(dir, filename, NULL); + + if (!g_file_test(filename_full, G_FILE_TEST_EXISTS)) + { + purple_debug_info(process, "File %s does not exist (this is not " + "necessarily an error)\n", filename_full); + g_free(filename_full); + return NULL; + } + + if (!g_file_get_contents(filename_full, &contents, &length, &error)) + { + purple_debug_error(process, "Error reading file %s: %s\n", + filename_full, error->message); + g_error_free(error); + } + + if ((contents != NULL) && (length > 0)) + { + node = xmlnode_from_str(contents, length); + + /* If we were unable to parse the file then save its contents to a backup file */ + if (node == NULL) + { + gchar *filename_temp, *filename_temp_full; + + filename_temp = g_strdup_printf("%s~", filename); + filename_temp_full = g_build_filename(dir, filename_temp, NULL); + + purple_debug_error("util", "Error parsing file %s. Renaming old " + "file to %s\n", filename_full, filename_temp); + purple_util_write_data_to_file_absolute(filename_temp_full, contents, length); + + g_free(filename_temp_full); + g_free(filename_temp); + } + + g_free(contents); + } + + /* If we could not parse the file then show the user an error message */ + if (node == NULL) + { + gchar *title, *msg; + title = g_strdup_printf(_("Error Reading %s"), filename); + msg = g_strdup_printf(_("An error was encountered reading your " + "%s. The file has not been loaded, and the old file " + "has been renamed to %s~."), description, filename_full); + purple_notify_error(NULL, NULL, title, msg); + g_free(title); + g_free(msg); + } + + g_free(filename_full); + + return node; +} + static void xmlnode_copy_foreach_ns(gpointer key, gpointer value, gpointer user_data) { diff -r d93578eb7244 -r 2d419a0fc0e4 pidgin/Makefile.am --- a/pidgin/Makefile.am Wed Aug 06 02:54:39 2008 +0000 +++ b/pidgin/Makefile.am Fri Aug 08 01:42:46 2008 +0000 @@ -96,6 +96,8 @@ gtkeventloop.c \ gtkexpander.c \ gtkft.c \ + gtkicon-theme.c \ + gtkicon-loader.c \ gtkidle.c \ gtkimhtml.c \ gtkimhtmltoolbar.c \ @@ -150,6 +152,8 @@ gtkeventloop.h \ gtkexpander.h \ gtkft.h \ + gtkicon-theme.h \ + gtkicon-loader.h \ gtkidle.h \ gtkgaim-compat.h \ gtkimhtml.h \ diff -r d93578eb7244 -r 2d419a0fc0e4 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Wed Aug 06 02:54:39 2008 +0000 +++ b/pidgin/gtkblist.c Fri Aug 08 01:42:46 2008 +0000 @@ -50,6 +50,7 @@ #include "gtkdebug.h" #include "gtkdialogs.h" #include "gtkft.h" +#include "gtkicon-theme.h" #include "gtklog.h" #include "gtkmenutray.h" #include "gtkpounce.h" @@ -5385,6 +5386,8 @@ priv->current_theme = PIDGIN_BLIST_THEME(purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme"), "blist")); + pidgin_stock_load_status_icon_theme(PIDGIN_ICON_THEME(purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/icon/status/theme"), "status_icon"))); + gtkblist->empty_avatar = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 32, 32); gdk_pixbuf_fill(gtkblist->empty_avatar, 0x00000000); diff -r d93578eb7244 -r 2d419a0fc0e4 pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Wed Aug 06 02:54:39 2008 +0000 +++ b/pidgin/gtkprefs.c Fri Aug 08 01:42:46 2008 +0000 @@ -44,6 +44,7 @@ #include "gtkconv.h" #include "gtkdebug.h" #include "gtkdialogs.h" +#include "gtkicon-theme.h" #include "gtkimhtml.h" #include "gtkimhtmltoolbar.h" #include "gtkprefs.h" @@ -76,6 +77,7 @@ static gboolean prefs_themes_unsorted = TRUE; static GtkListStore *prefs_sound_themes; static GtkListStore *prefs_blist_themes; +static GtkListStore *prefs_status_icon_themes; /* @@ -618,7 +620,12 @@ if (pixbuf != NULL) gdk_pixbuf_unref(pixbuf); - } else if (PIDGIN_IS_BLIST_THEME(theme)){ + } else if (PIDGIN_IS_BLIST_THEME(theme) || PIDGIN_IS_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){ @@ -633,13 +640,14 @@ markup = g_strdup_printf("%s%s%s\n%s", name, author != NULL ? " - " : "", author != NULL ? author : "", description != NULL ? description : ""); - gtk_list_store_append (prefs_blist_themes, &iter); - gtk_list_store_set (prefs_blist_themes, &iter, 0, pixbuf, 1, markup, 2, name, -1); + 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 */ @@ -667,9 +675,52 @@ gtk_list_store_set(prefs_blist_themes, &iter, 0, pixbuf, 1, "(Default) - None\n" "The default Pidgin buddy list theme", 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, "(Default) - None\n" + "The default Pidgin status icon theme", 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; + + 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_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); + + g_free(theme); + } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)); + } + + return combo_box; +} + /* sets the current sound theme */ static void prefs_set_sound_theme_cb(GtkComboBox *combo_box, gpointer user_data) @@ -1097,6 +1148,22 @@ pidgin_blist_set_theme(theme); } +/* sets the current icon theme */ +static void +prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data) +{ + PidginIconTheme *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_ICON_THEME(purple_theme_manager_find_theme(name, "icon")); + g_free(name); + + pidgin_stock_load_status_icon_theme(theme); +} static GtkWidget * interface_page(void) @@ -1106,12 +1173,8 @@ GtkWidget *vbox2; GtkWidget *label; GtkWidget *combo_box; - GtkCellRenderer *cell_rend; GtkSizeGroup *sg; - GtkTreeIter iter; GList *names = NULL; - gchar *theme; - const gchar *current_theme; ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); gtk_container_set_border_width(GTK_CONTAINER(ret), PIDGIN_HIG_BORDER); @@ -1120,33 +1183,16 @@ /* Buddy List Themes */ vbox = pidgin_make_frame(ret, _("Buddy List Theme")); - combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL (prefs_blist_themes)); - gtk_box_pack_start(GTK_BOX (vbox), combo_box, TRUE, TRUE, 0); - - 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); - - current_theme = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/blist/theme"); - - if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(prefs_blist_themes), &iter)) { - do { - gtk_tree_model_get(GTK_TREE_MODEL(prefs_blist_themes), &iter, 2, &theme, -1); - - if (g_str_equal(current_theme, theme)) - gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo_box), &iter); - - g_free(theme); - } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(prefs_blist_themes), &iter)); - } - + + 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 "/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, @@ -2059,12 +2105,9 @@ GtkTreeSelection *sel; GtkTreePath *path; GtkWidget *hbox; - PurpleSoundTheme *theme; - gboolean equal, customized, print_custom; int j; - const char *file, *current_theme, *name, *author, *description; - char *pref, *markup; - GtkCellRenderer *cell_rend; + const char *file; + char *pref; #ifndef _WIN32 GtkWidget *dd; GtkWidget *entry; @@ -2154,52 +2197,10 @@ vbox->parent->parent, TRUE, TRUE, 0, GTK_PACK_START); /* SOUND THEMES */ - combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL (prefs_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); - 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); - - /* Generate markup and set combo box to the active theme */ - current_theme = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/sound/theme"); - customized = pidgin_sound_is_customized(); - - 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); - - equal = g_str_equal(current_theme, name); - - if (equal) - gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo_box), &iter); - - print_custom = customized && equal; - - if (g_str_equal(name, "")) - markup = g_strdup_printf("(Default)%s%s - None\nThe default Pidgin sound theme", - 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("%s%s%s%s%s\n%s", - 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)); - } - g_signal_connect(G_OBJECT(combo_box), "changed", (GCallback)prefs_set_sound_theme_cb, NULL); /* SOUND SELECTION */ diff -r d93578eb7244 -r 2d419a0fc0e4 pidgin/pidginstock.c --- a/pidgin/pidginstock.c Wed Aug 06 02:54:39 2008 +0000 +++ b/pidgin/pidginstock.c Fri Aug 08 01:42:46 2008 +0000 @@ -26,17 +26,32 @@ */ #include "internal.h" #include "pidgin.h" +#include "prefs.h" + +#include "gtkicon-loader.h" +#include "theme-manager.h" #include "pidginstock.h" +/************************************************************************** + * Globals + **************************************************************************/ + +static gboolean stock_initted = FALSE; +static GtkIconSize microscopic, extra_small, small, medium, large, huge; + +/************************************************************************** + * Structures + **************************************************************************/ + static struct StockIcon { const char *name; const char *dir; const char *filename; -} const stock_icons[] = -{ +} const stock_icons[] = { + { PIDGIN_STOCK_ACTION, NULL, GTK_STOCK_EXECUTE }, #if GTK_CHECK_VERSION(2,6,0) { PIDGIN_STOCK_ALIAS, NULL, GTK_STOCK_EDIT }, @@ -95,7 +110,7 @@ { PIDGIN_STOCK_PAUSE, N_("_Pause"), 0, 0, NULL }, }; -static struct SizedStockIcon { +typedef struct { const char *name; const char *dir; const char *filename; @@ -107,18 +122,9 @@ gboolean huge; gboolean rtl; const char *translucent_name; -} const sized_stock_icons [] = { - { PIDGIN_STOCK_STATUS_AVAILABLE, "status", "available.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_AVAILABLE_I }, - { PIDGIN_STOCK_STATUS_AWAY, "status", "away.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_AWAY_I }, - { PIDGIN_STOCK_STATUS_BUSY, "status", "busy.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_BUSY_I }, - { PIDGIN_STOCK_STATUS_CHAT, "status", "chat.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_STATUS_INVISIBLE,"status", "invisible.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_STATUS_XA, "status", "extended-away.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, PIDGIN_STOCK_STATUS_XA_I }, - { PIDGIN_STOCK_STATUS_LOGIN, "status", "log-in.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, - { PIDGIN_STOCK_STATUS_LOGOUT, "status", "log-out.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, - { PIDGIN_STOCK_STATUS_OFFLINE, "status", "offline.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_OFFLINE_I }, - { PIDGIN_STOCK_STATUS_PERSON, "status", "person.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_STATUS_MESSAGE, "toolbar", "message-new.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, +} SizedStockIcon; + +const SizedStockIcon sized_stock_icons [] = { { PIDGIN_STOCK_STATUS_IGNORED, "emblems", "blocked.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_STATUS_FOUNDER, "emblems", "founder.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, @@ -150,37 +156,56 @@ { PIDGIN_STOCK_ANIMATION_TYPING4, "animations", "typing4.png",FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, { PIDGIN_STOCK_ANIMATION_TYPING5, "animations", "typing5.png",FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_ACCOUNTS, "toolbar", "accounts.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_BGCOLOR, "toolbar", "change-bgcolor.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_BLOCK, "emblems", "blocked.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_FGCOLOR, "toolbar", "change-fgcolor.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_SMILEY, "toolbar", "emote-select.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_FONT_FACE, "toolbar", "font-face.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER, "toolbar", "font-size-down.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_TEXT_LARGER, "toolbar", "font-size-up.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_INSERT, "toolbar", "insert.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, "toolbar", "insert-image.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_INSERT_LINK, "toolbar", "insert-link.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, "toolbar", "message-new.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_PENDING, "toolbar", "message-new.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_PLUGINS, "toolbar", "plugins.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_TYPING, "toolbar", "typing.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_UNBLOCK, "toolbar", "unblock.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR, "toolbar", "select-avatar.png", FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_SEND_FILE, "toolbar", "send-file.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TOOLBAR_TRANSFER, "toolbar", "transfer.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_ACCOUNTS, "toolbar", "accounts.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_BGCOLOR, "toolbar", "change-bgcolor.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_BLOCK, "emblems", "blocked.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_FGCOLOR, "toolbar", "change-fgcolor.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_SMILEY, "toolbar", "emote-select.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_FONT_FACE, "toolbar", "font-face.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_TEXT_SMALLER, "toolbar", "font-size-down.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_TEXT_LARGER, "toolbar", "font-size-up.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_INSERT, "toolbar", "insert.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_INSERT_IMAGE, "toolbar", "insert-image.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_INSERT_LINK, "toolbar", "insert-link.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_MESSAGE_NEW, "toolbar", "message-new.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_PENDING, "toolbar", "message-new.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_PLUGINS, "toolbar", "plugins.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_TYPING, "toolbar", "typing.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_UNBLOCK, "toolbar", "unblock.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR, "toolbar", "select-avatar.png", FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_SEND_FILE, "toolbar", "send-file.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TOOLBAR_TRANSFER, "toolbar", "transfer.png", FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL } +}; + +const SizedStockIcon sized_status_icons [] = { - { PIDGIN_STOCK_TRAY_AVAILABLE, "tray", "tray-online.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_INVISIBLE, "tray", "tray-invisible.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_AWAY, "tray", "tray-away.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_BUSY, "tray", "tray-busy.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_XA, "tray", "tray-extended-away.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_OFFLINE, "tray", "tray-offline.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_CONNECT, "tray", "tray-connecting.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_PENDING, "tray", "tray-new-im.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, - { PIDGIN_STOCK_TRAY_EMAIL, "tray", "tray-message.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL } + { PIDGIN_STOCK_STATUS_AVAILABLE, "status", "available.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_AVAILABLE_I }, + { PIDGIN_STOCK_STATUS_AWAY, "status", "away.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_AWAY_I }, + { PIDGIN_STOCK_STATUS_BUSY, "status", "busy.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_BUSY_I }, + { PIDGIN_STOCK_STATUS_CHAT, "status", "chat.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_STATUS_INVISIBLE, "status", "invisible.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_STATUS_XA, "status", "extended-away.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, PIDGIN_STOCK_STATUS_XA_I }, + { PIDGIN_STOCK_STATUS_LOGIN, "status", "log-in.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, + { PIDGIN_STOCK_STATUS_LOGOUT, "status", "log-out.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, NULL }, + { PIDGIN_STOCK_STATUS_OFFLINE, "status", "offline.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, PIDGIN_STOCK_STATUS_OFFLINE_I }, + { PIDGIN_STOCK_STATUS_PERSON, "status", "person.png", TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_STATUS_MESSAGE, "toolbar", "message-new.png", TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL }, + + { PIDGIN_STOCK_TRAY_AVAILABLE, "tray", "tray-online.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_INVISIBLE, "tray", "tray-invisible.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_AWAY, "tray", "tray-away.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_BUSY, "tray", "tray-busy.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_XA, "tray", "tray-extended-away.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_OFFLINE, "tray", "tray-offline.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_CONNECT, "tray", "tray-connecting.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_PENDING, "tray", "tray-new-im.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL }, + { PIDGIN_STOCK_TRAY_EMAIL, "tray", "tray-message.png", FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, NULL } }; +/***************************************************************************** + * Private functions + *****************************************************************************/ + static gchar * find_file(const char *dir, const char *base) { @@ -335,25 +360,106 @@ g_object_unref(pixbuf); gtk_icon_source_free(source); } +} +static void +build_sized_icon_sets(GtkIconSet *normal, GtkIconSet *translucent, SizedStockIcon icon, + GtkIconSize size, PidginIconTheme *theme, const gchar *pix) +{ + const gchar *file, *dir; + gchar *file_full; + gboolean use_theme; + if ((use_theme = theme != NULL)) { + file = pidgin_icon_theme_get_file(theme, icon.name); + dir = purple_theme_get_dir(PURPLE_THEME(theme)); + + file_full = g_build_filename(dir, pix, file, NULL); + use_theme = g_file_test(file_full, G_FILE_TEST_IS_REGULAR); + g_free(file_full); + } + + if (!use_theme) { + file = icon.filename; + dir = icon.dir; + } + + add_sized_icon(normal, size, dir, icon.rtl, pix, file); + if (translucent != NULL) + add_translucent_sized_icon(translucent, size, dir, icon.rtl, pix, file); } +/***************************************************************************** + * Public API functions + *****************************************************************************/ + +void +pidgin_stock_load_status_icon_theme(PidginIconTheme *theme) +{ + GtkIconFactory *icon_factory; + gint i; + GtkIconSet *normal; + GtkIconSet *translucent = NULL; + GtkWidget *win; + + g_return_if_fail(stock_initted); + + icon_factory = gtk_icon_factory_new(); + + gtk_icon_factory_add_default(icon_factory); + + win = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_realize(win); + + for (i = 0; i < G_N_ELEMENTS(sized_status_icons); i++) + { + normal = gtk_icon_set_new(); + if (sized_status_icons[i].translucent_name) + translucent = gtk_icon_set_new(); + + if (sized_status_icons[i].microscopic) + build_sized_icon_sets(normal, translucent, sized_status_icons[i], microscopic, theme, "11"); + if (sized_status_icons[i].extra_small) + build_sized_icon_sets(normal, translucent, sized_status_icons[i], extra_small, theme, "16"); + if (sized_status_icons[i].small) + build_sized_icon_sets(normal, translucent, sized_status_icons[i], small, theme, "22"); + if (sized_status_icons[i].medium) + build_sized_icon_sets(normal, translucent, sized_status_icons[i], medium, theme, "32"); + if (sized_status_icons[i].large) + build_sized_icon_sets(normal, translucent, sized_status_icons[i], large, theme, "48"); + if (sized_status_icons[i].huge) + build_sized_icon_sets(normal, translucent, sized_status_icons[i], huge, theme, "64"); + + gtk_icon_factory_add(icon_factory, sized_status_icons[i].name, normal); + gtk_icon_set_unref(normal); + + if (sized_status_icons[i].translucent_name) { + gtk_icon_factory_add(icon_factory, sized_status_icons[i].translucent_name, translucent); + gtk_icon_set_unref(translucent); + } + } + + gtk_widget_destroy(win); + g_object_unref(G_OBJECT(icon_factory)); +} void pidgin_stock_init(void) { - static gboolean stock_initted = FALSE; GtkIconFactory *icon_factory; size_t i; GtkWidget *win; - GtkIconSize microscopic, extra_small, small, medium, large, huge; if (stock_initted) return; stock_initted = TRUE; + /* Setup the theme */ + purple_theme_manager_register_type(g_object_new(PIDGIN_TYPE_ICON_THEME_LOADER, "type", "icon", NULL)); + purple_prefs_add_none(PIDGIN_PREFS_ROOT "/icon/status"); + purple_prefs_add_string(PIDGIN_PREFS_ROOT "/icon/status/theme", ""); + /* Setup the icon factory. */ icon_factory = gtk_icon_factory_new(); @@ -402,7 +508,6 @@ } /* register custom icon sizes */ - microscopic = gtk_icon_size_register(PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC, 11, 11); extra_small = gtk_icon_size_register(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL, 16, 16); small = gtk_icon_size_register(PIDGIN_ICON_SIZE_TANGO_SMALL, 22, 22); @@ -416,48 +521,28 @@ iconset = gtk_icon_set_new(); -#define ADD_SIZED_ICON(name, size) do { \ - if (sized_stock_icons[i].name) \ - add_sized_icon(iconset, name, \ - sized_stock_icons[i].dir, sized_stock_icons[i].rtl, \ - size, sized_stock_icons[i].filename); \ - } while (0) - ADD_SIZED_ICON(microscopic, "11"); - ADD_SIZED_ICON(extra_small, "16"); - ADD_SIZED_ICON(small, "22"); - ADD_SIZED_ICON(medium, "32"); - ADD_SIZED_ICON(large, "48"); - ADD_SIZED_ICON(huge, "64"); -#undef ADD_SIZED_ICON + if (sized_stock_icons[i].microscopic) + build_sized_icon_sets(iconset, NULL, sized_stock_icons[i], microscopic, NULL, "11"); + if (sized_stock_icons[i].extra_small) + build_sized_icon_sets(iconset, NULL, sized_stock_icons[i], extra_small, NULL, "16"); + if (sized_stock_icons[i].small) + build_sized_icon_sets(iconset, NULL, sized_stock_icons[i], small, NULL, "22"); + if (sized_stock_icons[i].medium) + build_sized_icon_sets(iconset, NULL, sized_stock_icons[i], medium, NULL, "32"); + if (sized_stock_icons[i].large) + build_sized_icon_sets(iconset, NULL, sized_stock_icons[i], large, NULL, "48"); + if (sized_stock_icons[i].huge) + build_sized_icon_sets(iconset, NULL, sized_stock_icons[i], huge, NULL, "64"); gtk_icon_factory_add(icon_factory, sized_stock_icons[i].name, iconset); gtk_icon_set_unref(iconset); - - if (sized_stock_icons[i].translucent_name) { - iconset = gtk_icon_set_new(); - -#define ADD_TRANS_ICON(name, size) do { \ - if (sized_stock_icons[i].name) \ - add_translucent_sized_icon(iconset, name, \ - sized_stock_icons[i].dir, sized_stock_icons[i].rtl, \ - size, sized_stock_icons[i].filename); \ - } while (0) - ADD_TRANS_ICON(microscopic, "11"); - ADD_TRANS_ICON(extra_small, "16"); - ADD_TRANS_ICON(small, "22"); - ADD_TRANS_ICON(medium, "32"); - ADD_TRANS_ICON(large, "48"); - ADD_TRANS_ICON(huge, "64"); -#undef ADD_TRANS_ICON - - gtk_icon_factory_add(icon_factory, sized_stock_icons[i].translucent_name, iconset); - gtk_icon_set_unref(iconset); - } } gtk_widget_destroy(win); g_object_unref(G_OBJECT(icon_factory)); + pidgin_stock_load_status_icon_theme(NULL); + /* Register the stock items. */ gtk_stock_add_static(stock_items, G_N_ELEMENTS(stock_items)); } diff -r d93578eb7244 -r 2d419a0fc0e4 pidgin/pidginstock.h --- a/pidgin/pidginstock.h Wed Aug 06 02:54:39 2008 +0000 +++ b/pidgin/pidginstock.h Fri Aug 08 01:42:46 2008 +0000 @@ -24,6 +24,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include +#include "gtkicon-theme.h" #ifndef _PIDGIN_STOCK_H_ #define _PIDGIN_STOCK_H_ @@ -154,6 +155,14 @@ #define PIDGIN_ICON_SIZE_TANGO_MEDIUM "pidgin-icon-size-tango-medium" #define PIDGIN_ICON_SIZE_TANGO_LARGE "pidgin-icon-size-tango-large" #define PIDGIN_ICON_SIZE_TANGO_HUGE "pidgin-icon-size-tango-huge" + +/** + * Loades all of the icons from the status icon theme into Pidgin stock + * + * @param theme the theme to load, or null to load all the default icons + */ +void pidgin_stock_load_status_icon_theme(PidginIconTheme *theme); + /** * Sets up the purple stock repository. */