diff options
author | Cosimo Cecchi <cosimoc@gnome.org> | 2012-10-28 15:01:30 -0400 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@gnome.org> | 2012-10-31 11:53:50 -0400 |
commit | 86ecf54139874e5e2eee8bfd55b93e28f969bf72 (patch) | |
tree | 9bef23be41ba1c936d6b3fd1141bb548c605a619 /gtk/gtkicontheme.c | |
parent | 2e287576b4c197350908251b99e08cdc4b6840e7 (diff) | |
download | gtk+-86ecf54139874e5e2eee8bfd55b93e28f969bf72.tar.gz |
icon-theme: support loading symbolic GFileIcons from generic URIs
Right now we support loading and recoloring symbolic GFileIcons, but
only if the underlying GFile has a local path. This breaks when the
GFileIcon is loaded from a GResource, which is a reasonable option for an
application that wants to ship a custom symbolic icon.
This patch changes GtkIconInfo to store a GFile together with the file
path, and changes the symbolic icon lookup code to use the GFile URI,
which transparently makes the code work also for GResources.
https://bugzilla.gnome.org/show_bug.cgi?id=687059
Diffstat (limited to 'gtk/gtkicontheme.c')
-rw-r--r-- | gtk/gtkicontheme.c | 96 |
1 files changed, 60 insertions, 36 deletions
diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c index 58b643fcdb..764320b982 100644 --- a/gtk/gtkicontheme.c +++ b/gtk/gtkicontheme.c @@ -202,6 +202,7 @@ struct _GtkIconInfo /* Information about the source */ gchar *filename; + GFile *icon_file; GLoadableIcon *loadable; GSList *emblem_infos; @@ -1409,6 +1410,8 @@ choose_icon (GtkIconTheme *icon_theme, else if (unthemed_icon->no_svg_filename) icon_info->filename = g_strdup (unthemed_icon->no_svg_filename); + icon_info->icon_file = g_file_new_for_path (icon_info->filename); + icon_info->dir_type = ICON_THEME_DIR_UNTHEMED; icon_info->dir_size = size; } @@ -2291,11 +2294,13 @@ theme_lookup_icon (IconTheme *theme, { file = g_strconcat (icon_name, string_from_suffix (suffix), NULL); icon_info->filename = g_build_filename (min_dir->dir, file, NULL); + icon_info->icon_file = g_file_new_for_path (icon_info->filename); g_free (file); } else { icon_info->filename = NULL; + icon_info->icon_file = NULL; } if (min_dir->icon_data != NULL) @@ -2732,6 +2737,8 @@ gtk_icon_info_free (GtkIconInfo *icon_info) return; g_free (icon_info->filename); + g_clear_object (&icon_info->icon_file); + if (icon_info->loadable) g_object_unref (icon_info->loadable); g_slist_free_full (icon_info->emblem_infos, (GDestroyNotify) gtk_icon_info_free); @@ -2937,14 +2944,8 @@ icon_info_ensure_scale_and_pixbuf (GtkIconInfo *icon_info, /* SVG icons are a special case - we just immediately scale them * to the desired size */ - if (icon_info->filename && !icon_info->loadable) - { - GFile *file; - - file = g_file_new_for_path (icon_info->filename); - icon_info->loadable = G_LOADABLE_ICON (g_file_icon_new (file)); - g_object_unref (file); - } + if (icon_info->icon_file && !icon_info->loadable) + icon_info->loadable = G_LOADABLE_ICON (g_file_icon_new (icon_info->icon_file)); is_svg = FALSE; if (G_IS_FILE_ICON (icon_info->loadable)) @@ -3173,7 +3174,7 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info, GdkPixbuf *pixbuf; gchar *data; gchar *success, *warning, *err; - gchar *width, *height; + gchar *width, *height, *uri; /* css_fg can't possibly have failed, otherwise * that would mean we have a broken style */ @@ -3199,8 +3200,14 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info, if (!icon_info->symbolic_pixbuf_size) { + stream = G_INPUT_STREAM (g_file_read (icon_info->icon_file, NULL, error)); + + if (!stream) + return NULL; + /* Fetch size from the original icon */ - pixbuf = gdk_pixbuf_new_from_file (icon_info->filename, error); + pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, error); + g_object_unref (stream); if (!pixbuf) return NULL; @@ -3213,6 +3220,7 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info, width = g_strdup_printf ("%d", icon_info->symbolic_pixbuf_size->width); height = g_strdup_printf ("%d", icon_info->symbolic_pixbuf_size->height); + uri = g_file_get_uri (icon_info->icon_file); data = g_strconcat ("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" "<svg version=\"1.1\"\n" @@ -3234,7 +3242,7 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info, " fill: ", css_success ? css_success : success," !important;\n" " }\n" " </style>\n" - " <xi:include href=\"", icon_info->filename, "\"/>\n" + " <xi:include href=\"", uri, "\"/>\n" "</svg>", NULL); g_free (warning); @@ -3242,6 +3250,7 @@ _gtk_icon_info_load_symbolic_internal (GtkIconInfo *icon_info, g_free (success); g_free (width); g_free (height); + g_free (uri); stream = g_memory_input_stream_new_from_data (data, -1, g_free); pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream, @@ -3306,19 +3315,23 @@ gtk_icon_info_load_symbolic (GtkIconInfo *icon_info, gchar *css_success; gchar *css_warning; gchar *css_error; + gchar *icon_uri; + gboolean is_symbolic; g_return_val_if_fail (fg != NULL, NULL); - if (!icon_info->filename || - !g_str_has_suffix (icon_info->filename, "-symbolic.svg")) - { - if (was_symbolic) - *was_symbolic = FALSE; - return gtk_icon_info_load_icon (icon_info, error); - } + icon_uri = NULL; + if (icon_info->icon_file) + icon_uri = g_file_get_uri (icon_info->icon_file); + + is_symbolic = (icon_uri != NULL) && (g_str_has_suffix (icon_uri, "-symbolic.svg")); + g_free (icon_uri); if (was_symbolic) - *was_symbolic = TRUE; + *was_symbolic = is_symbolic; + + if (!is_symbolic) + return gtk_icon_info_load_icon (icon_info, error); css_fg = gdk_rgba_to_css (fg); @@ -3382,17 +3395,21 @@ gtk_icon_info_load_symbolic_for_context (GtkIconInfo *icon_info, gchar *css_fg = NULL, *css_success; gchar *css_warning, *css_error; GtkStateFlags state; + gchar *icon_uri; + gboolean is_symbolic; - if (!icon_info->filename || - !g_str_has_suffix (icon_info->filename, "-symbolic.svg")) - { - if (was_symbolic) - *was_symbolic = FALSE; - return gtk_icon_info_load_icon (icon_info, error); - } + icon_uri = NULL; + if (icon_info->icon_file) + icon_uri = g_file_get_uri (icon_info->icon_file); + + is_symbolic = (icon_uri != NULL) && (g_str_has_suffix (icon_uri, "-symbolic.svg")); + g_free (icon_uri); if (was_symbolic) - *was_symbolic = TRUE; + *was_symbolic = is_symbolic; + + if (!is_symbolic) + return gtk_icon_info_load_icon (icon_info, error); state = gtk_style_context_get_state (context); gtk_style_context_get (context, state, "color", &color, NULL); @@ -3465,17 +3482,21 @@ gtk_icon_info_load_symbolic_for_style (GtkIconInfo *icon_info, GdkColor *fg; gchar *css_fg, *css_success; gchar *css_warning, *css_error; + gchar *icon_uri; + gboolean is_symbolic; - if (!icon_info->filename || - !g_str_has_suffix (icon_info->filename, "-symbolic.svg")) - { - if (was_symbolic) - *was_symbolic = FALSE; - return gtk_icon_info_load_icon (icon_info, error); - } + icon_uri = NULL; + if (icon_info->icon_file) + icon_uri = g_file_get_uri (icon_info->icon_file); + + is_symbolic = (icon_uri != NULL) && (g_str_has_suffix (icon_uri, "-symbolic.svg")); + g_free (icon_uri); if (was_symbolic) - *was_symbolic = TRUE; + *was_symbolic = is_symbolic; + + if (!is_symbolic) + return gtk_icon_info_load_icon (icon_info, error); fg = &style->fg[state]; css_fg = gdk_color_to_css (fg); @@ -3889,7 +3910,10 @@ gtk_icon_theme_lookup_by_gicon (GtkIconTheme *icon_theme, { GFile *file = g_file_icon_get_file (G_FILE_ICON (icon)); if (file != NULL) - info->filename = g_file_get_path (file); + { + info->icon_file = g_object_ref (file); + info->filename = g_file_get_path (file); + } } info->dir_type = ICON_THEME_DIR_UNTHEMED; |