Mercurial > pidgin.yaz
diff pidgin/plugins/themeedit-icon.c @ 26664:5d71de58452c
Make it possible to load non-status icons using a PidginStockIconTheme.
For now, just chat-room emblems can be set, but adding other icons should
be trivial.
WISHLIST (Crazy/Driveby Patch Writers step forward please!):
* Move the theme-editor plugin to a subdirectory under plugins/.
* Make the 'Save' buttons work, possibly ask for some details when saving
(e.g. Author's name etc.)
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Mon, 20 Apr 2009 03:20:15 +0000 |
parents | 7519de6ea00f |
children | df0915055560 |
line wrap: on
line diff
--- a/pidgin/plugins/themeedit-icon.c Sun Apr 19 19:45:53 2009 +0000 +++ b/pidgin/plugins/themeedit-icon.c Mon Apr 20 03:20:15 2009 +0000 @@ -43,7 +43,7 @@ PIDGIN_ICON_SIZE_TANGO_HUGE, /* We don't have huge status icons, it seems! */ }; -static const struct { +static const struct options { const char *stockid; const char *text; } statuses[] = { @@ -52,50 +52,69 @@ {PIDGIN_STOCK_STATUS_BUSY, N_("Busy")}, {PIDGIN_STOCK_STATUS_OFFLINE, N_("Offline")}, {NULL, NULL} +}, chatemblems[] = { + {PIDGIN_STOCK_STATUS_IGNORED, N_("Ignored")}, + {PIDGIN_STOCK_STATUS_FOUNDER, N_("Founder")}, + {PIDGIN_STOCK_STATUS_OPERATOR, N_("Operator")}, + {PIDGIN_STOCK_STATUS_HALFOP, N_("Half Operator")}, + {PIDGIN_STOCK_STATUS_VOICE, N_("Voice")}, + {NULL, NULL} +}; + +static const struct { + const char *heading; + const struct options *options; +} sections[] = { + {N_("Status Icons"), statuses}, + {N_("Chatroom Embems"), chatemblems}, + {NULL, NULL} }; static PidginStatusIconTheme * create_icon_theme(GtkWidget *window) { - int i, j; + int s, i, j; char *dirname = "/tmp"; /* FIXME */ PidginStatusIconTheme *theme = g_object_new(PIDGIN_TYPE_STATUS_ICON_THEME, "type", "status-icon", "author", getlogin(), "directory", dirname, NULL); - for (i = 0; statuses[i].stockid; i++) { - GtkWidget *image = g_object_get_data(G_OBJECT(window), statuses[i].stockid); - GdkPixbuf *pixbuf = g_object_get_data(G_OBJECT(image), "pixbuf"); - if (!pixbuf) - continue; - pidgin_icon_theme_set_icon(PIDGIN_ICON_THEME(theme), statuses[i].stockid, - statuses[i].stockid); - for (j = 0; stocksizes[j]; j++) { - int width, height; - GtkIconSize iconsize; - char size[8]; - char *name; - GdkPixbuf *scale; - GError *error = NULL; + for (s = 0; sections[s].heading; s++) { + GtkWidget *vbox = g_object_get_data(G_OBJECT(window), sections[s].heading); + for (i = 0; sections[s].options[i].stockid; i++) { + GtkWidget *image = g_object_get_data(G_OBJECT(vbox), sections[s].options[i].stockid); + GdkPixbuf *pixbuf = g_object_get_data(G_OBJECT(image), "pixbuf"); + if (!pixbuf) + continue; + pidgin_icon_theme_set_icon(PIDGIN_ICON_THEME(theme), sections[s].options[i].stockid, + sections[s].options[i].stockid); + for (j = 0; stocksizes[j]; j++) { + int width, height; + GtkIconSize iconsize; + char size[8]; + char *name; + GdkPixbuf *scale; + GError *error = NULL; - iconsize = gtk_icon_size_from_name(stocksizes[j]); - gtk_icon_size_lookup(iconsize, &width, &height); - g_snprintf(size, sizeof(size), "%d", width); + iconsize = gtk_icon_size_from_name(stocksizes[j]); + gtk_icon_size_lookup(iconsize, &width, &height); + g_snprintf(size, sizeof(size), "%d", width); - if (i == 0) { - name = g_build_filename(dirname, size, NULL); - purple_build_dir(name, S_IRUSR | S_IWUSR | S_IXUSR); + if (i == 0) { + name = g_build_filename(dirname, size, NULL); + purple_build_dir(name, S_IRUSR | S_IWUSR | S_IXUSR); + g_free(name); + } + + name = g_build_filename(dirname, size, sections[s].options[i].stockid, NULL); + scale = gdk_pixbuf_scale_simple(pixbuf, width, height, GDK_INTERP_BILINEAR); + gdk_pixbuf_save(scale, name, "png", &error, "compression", "9", NULL); g_free(name); + g_object_unref(G_OBJECT(scale)); + if (error) + g_error_free(error); } - - name = g_build_filename(dirname, size, statuses[i].stockid, NULL); - scale = gdk_pixbuf_scale_simple(pixbuf, width, height, GDK_INTERP_BILINEAR); - gdk_pixbuf_save(scale, name, "png", &error, "compression", "9", NULL); - g_free(name); - g_object_unref(G_OBJECT(scale)); - if (error) - g_error_free(error); } } return theme; @@ -104,8 +123,21 @@ static void use_icon_theme(GtkWidget *w, GtkWidget *window) { + /* I don't quite understand the icon-theme stuff. For example, I don't + * know why PidginIconTheme needs to be abstract, or how PidginStatusIconTheme + * would be different from other PidginIconTheme's (e.g. PidginStockIconTheme) + * etc., but anyway, this works for now. + * + * Here's an interesting note: A PidginStatusIconTheme can be used for both + * stock and status icons. Like I said, I don't quite know how they could be + * different. So I am going to just keep it as it is, for now anyway, until I + * have the time to dig through this, or someone explains this stuff to me + * clearly. + * -- Sad + */ PidginStatusIconTheme *theme = create_icon_theme(window); pidgin_stock_load_status_icon_theme(PIDGIN_STATUS_ICON_THEME(theme)); + pidgin_stock_load_stock_icon_theme((PidginStockIconTheme *)theme); pidgin_blist_refresh(purple_get_blist()); g_object_unref(theme); } @@ -123,8 +155,12 @@ GError *error = NULL; GdkPixbuf *scale; int i; - GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, &error); + GdkPixbuf *pixbuf; + if (!filename) + return; + + pixbuf = gdk_pixbuf_new_from_file(filename, &error); if (error || !pixbuf) { purple_debug_error("theme-editor-icon", "Unable to load icon file '%s' (%s)\n", filename, error ? error->message : "Reason unknown"); @@ -171,41 +207,47 @@ GtkWidget *dialog; GtkWidget *box, *vbox; GtkSizeGroup *sizegroup; - int i, j; + int s, i, j; dialog = pidgin_create_dialog(_("Pidgin Icon Theme Editor"), 0, "theme-editor-icon", FALSE); box = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(dialog), FALSE, PIDGIN_HIG_BOX_SPACE); - vbox = pidgin_make_frame(box, _("Status Icons")); sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - for (i = 0; statuses[i].stockid; i++) { - const char *id = statuses[i].stockid; - const char *text = _(statuses[i].text); + for (s = 0; sections[s].heading; s++) { + const char *heading = sections[s].heading; + + vbox = pidgin_make_frame(box, heading); + g_object_set_data(G_OBJECT(dialog), heading, vbox); - GtkWidget *hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); - GtkWidget *label = gtk_label_new(text); - GtkWidget *image = gtk_image_new_from_stock(id, - gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); - GtkWidget *ebox = gtk_event_box_new(); - gtk_container_add(GTK_CONTAINER(ebox), image); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + for (i = 0; sections[s].options[i].stockid; i++) { + const char *id = sections[s].options[i].stockid; + const char *text = _(sections[s].options[i].text); + + GtkWidget *hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_CAT_SPACE); + GtkWidget *label = gtk_label_new(text); + GtkWidget *image = gtk_image_new_from_stock(id, + gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL)); + GtkWidget *ebox = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(ebox), image); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - g_signal_connect(G_OBJECT(ebox), "button-press-event", G_CALLBACK(change_stock_image), image); - g_object_set_data(G_OBJECT(image), "property-name", (gpointer)id); + g_signal_connect(G_OBJECT(ebox), "button-press-event", G_CALLBACK(change_stock_image), image); + g_object_set_data(G_OBJECT(image), "property-name", (gpointer)id); - gtk_size_group_add_widget(sizegroup, label); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(hbox), ebox, FALSE, FALSE, 0); + gtk_size_group_add_widget(sizegroup, label); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), ebox, FALSE, FALSE, 0); - for (j = 0; stocksizes[j]; j++) { - GtkWidget *sh = gtk_image_new_from_stock(id, gtk_icon_size_from_name(stocksizes[j])); - gtk_box_pack_start(GTK_BOX(hbox), sh, FALSE, FALSE, 0); - g_object_set_data(G_OBJECT(image), stocksizes[j], sh); + for (j = 0; stocksizes[j]; j++) { + GtkWidget *sh = gtk_image_new_from_stock(id, gtk_icon_size_from_name(stocksizes[j])); + gtk_box_pack_start(GTK_BOX(hbox), sh, FALSE, FALSE, 0); + g_object_set_data(G_OBJECT(image), stocksizes[j], sh); + } + + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + + g_object_set_data(G_OBJECT(vbox), id, image); } - - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); - - g_object_set_data(G_OBJECT(dialog), id, image); } gtk_dialog_set_has_separator(GTK_DIALOG(dialog), TRUE);