source: trunk/gtk/icons.c @ 8033

Last change on this file since 8033 was 8033, checked in by charles, 13 years ago

(trunk gtk) icons.c: silence a couple of compiler warnings on older systems

File size: 7.2 KB
Line 
1/*
2 * icons.[ch] written by Paolo Bacchilega, who writes:
3 * "There is no problem for me, you can license my code under whatever licence you wish :)"
4 */
5
6#include <string.h> /* strcmp */
7#include <glib.h>
8#include <gtk/gtk.h>
9#include "icons.h"
10
11#ifdef HAVE_GIO
12 #include <gio/gio.h>
13#endif
14
15#define VOID_PIXBUF_KEY "void-pixbuf"
16
17#ifdef HAVE_GIO
18static const char *
19get_static_string( const char *s )
20{
21    static GHashTable *static_strings = NULL;
22    const char *result;
23
24    if ( s == NULL )
25        return NULL;
26
27    if ( static_strings == NULL )
28        static_strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
29
30    if ( ! g_hash_table_lookup_extended( static_strings, s, (gpointer) &result, NULL )) {
31        result = g_strdup( s );
32        g_hash_table_insert( static_strings,
33                             (gpointer) result,
34                             GINT_TO_POINTER( 1 ));
35    }
36
37    return result;
38}
39#endif
40
41
42typedef struct {
43    GtkIconTheme * icon_theme;
44    int            icon_size;
45    GHashTable   * cache;
46} IconCache;
47
48
49static IconCache *icon_cache[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
50
51
52static GdkPixbuf*
53create_void_pixbuf (int width,
54                    int height)
55{
56    GdkPixbuf *p;
57
58    p = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
59                        TRUE,
60                        8,
61                        width,
62                        height);
63    gdk_pixbuf_fill( p, 0xFFFFFF00 );
64
65    return p;
66}
67
68
69static int
70get_size_in_pixels( GtkWidget   * widget,
71                    GtkIconSize   icon_size )
72{
73    int width, height;
74
75    gtk_icon_size_lookup_for_settings( gtk_widget_get_settings( widget ),
76                                       icon_size,
77                                       &width, 
78                                       &height );
79    return MAX( width, height );
80}
81
82
83static IconCache * 
84icon_cache_new (GtkWidget * for_widget,
85                int         icon_size)
86{
87    IconCache * icon_cache;
88       
89    g_return_val_if_fail( for_widget != NULL, NULL );
90       
91    icon_cache = g_new0( IconCache, 1 );
92    icon_cache->icon_theme = gtk_icon_theme_get_for_screen( gtk_widget_get_screen( for_widget )); 
93    icon_cache->icon_size = get_size_in_pixels( for_widget, icon_size );
94    icon_cache->cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
95       
96    g_hash_table_insert( icon_cache->cache, (void*)VOID_PIXBUF_KEY, create_void_pixbuf( icon_cache->icon_size, icon_cache->icon_size ));
97       
98    return icon_cache;
99}
100
101#ifdef HAVE_GIO
102static const char *
103_icon_cache_get_icon_key( GIcon * icon )
104{
105    const char * key = NULL;
106       
107    if ( G_IS_THEMED_ICON( icon )) {
108        char ** icon_names;
109        char  * name;
110       
111        g_object_get( icon, "names", &icon_names, NULL );
112        name = g_strjoinv( ",", icon_names );
113               
114        key = get_static_string( name );
115               
116        g_free( name );
117        g_strfreev( icon_names );       
118    }
119    else if ( G_IS_FILE_ICON( icon )) {
120        GFile * file;
121        char  * filename;
122
123        file = g_file_icon_get_file( G_FILE_ICON( icon ));
124        filename = g_file_get_path( file );
125               
126        key = get_static_string( filename );
127               
128        g_free( filename );
129        g_object_unref( file );
130    }
131       
132    return key;
133}
134
135
136static GdkPixbuf *
137get_themed_icon_pixbuf( GThemedIcon  *icon,
138                        int           size,
139                        GtkIconTheme *icon_theme )
140{
141    char        ** icon_names;
142    GtkIconInfo  * icon_info;
143    GdkPixbuf    * pixbuf;
144    GError       * error = NULL;
145
146    g_object_get( icon, "names", &icon_names, NULL );
147
148    icon_info = gtk_icon_theme_choose_icon( icon_theme, (const char **)icon_names, size, 0 );
149    if ( icon_info == NULL )
150        icon_info = gtk_icon_theme_lookup_icon( icon_theme, "text-x-generic", size, GTK_ICON_LOOKUP_USE_BUILTIN );
151
152    pixbuf = gtk_icon_info_load_icon( icon_info, &error );
153    if ( pixbuf == NULL ) {
154        g_warning( "could not load icon pixbuf: %s\n", error->message );
155        g_clear_error( &error );
156    }
157
158    gtk_icon_info_free( icon_info );
159    g_strfreev( icon_names );
160
161    return pixbuf;
162}
163
164
165static GdkPixbuf *
166get_file_icon_pixbuf( GFileIcon *icon,
167                      int        size )
168{
169    GFile     * file;
170    char      * filename;
171    GdkPixbuf * pixbuf;
172       
173    file = g_file_icon_get_file( icon );
174    filename = g_file_get_path( file );
175    pixbuf = gdk_pixbuf_new_from_file_at_size( filename, size, -1, NULL );
176    g_free( filename );
177    g_object_unref( file );
178       
179    return pixbuf;
180}
181
182
183static GdkPixbuf *
184_get_icon_pixbuf( GIcon        *icon,
185                  int           size,
186                  GtkIconTheme *theme )
187{
188    if ( icon == NULL )
189        return NULL;
190    if ( G_IS_THEMED_ICON (icon) )
191        return get_themed_icon_pixbuf( G_THEMED_ICON( icon ), size, theme );
192    if ( G_IS_FILE_ICON (icon) )
193        return get_file_icon_pixbuf( G_FILE_ICON( icon ), size );
194    return NULL;
195}
196
197                 
198static GdkPixbuf *
199icon_cache_get_mime_type_icon( IconCache  * icon_cache,
200                               const char * mime_type )
201{
202    GIcon      * icon;
203    const char * key = NULL;
204    GdkPixbuf  * pixbuf;
205
206    icon = g_content_type_get_icon( mime_type );
207    key = _icon_cache_get_icon_key( icon );
208       
209    if (key == NULL)
210        key = VOID_PIXBUF_KEY;
211
212    pixbuf = g_hash_table_lookup( icon_cache->cache, key );
213    if (pixbuf != NULL) {
214        g_object_ref( pixbuf );
215        return pixbuf;
216    }
217       
218    pixbuf = _get_icon_pixbuf( icon, icon_cache->icon_size, icon_cache->icon_theme );
219    g_hash_table_insert( icon_cache->cache, (gpointer) key, g_object_ref( pixbuf ));
220       
221    return pixbuf;
222}
223
224#else /* HAVE_GIO */
225
226static GdkPixbuf *
227icon_cache_get_mime_type_icon( IconCache  * icon_cache,
228                               const char * mime_type )
229{
230    GdkPixbuf  * pixbuf;
231    const char * stock_name;
232
233    if( !strcmp( mime_type, DIRECTORY_MIME_TYPE ) )
234        stock_name = GTK_STOCK_DIRECTORY;
235    else
236        stock_name = GTK_STOCK_FILE;
237
238    pixbuf = g_hash_table_lookup( icon_cache->cache, stock_name );
239
240    if( pixbuf != NULL )
241    {
242        g_object_ref( pixbuf );
243        return pixbuf;
244    }
245
246    pixbuf = gtk_icon_theme_load_icon( icon_cache->icon_theme,
247                                       stock_name,
248                                       icon_cache->icon_size,
249                                       0, NULL );
250    g_hash_table_insert( icon_cache->cache, (gpointer) stock_name, g_object_ref( pixbuf ));
251    return pixbuf;
252}
253
254#endif
255
256
257GdkPixbuf * 
258get_mime_type_icon( const char   * mime_type,
259                    GtkIconSize    icon_size,
260                    GtkWidget    * for_widget )
261{
262    int n;
263   
264    switch ( icon_size ) {
265        case GTK_ICON_SIZE_INVALID:       n = 0; break;
266        case GTK_ICON_SIZE_MENU:          n = 1; break;
267        case GTK_ICON_SIZE_SMALL_TOOLBAR: n = 2; break;
268        case GTK_ICON_SIZE_LARGE_TOOLBAR: n = 3; break;
269        case GTK_ICON_SIZE_BUTTON:        n = 4; break;
270        case GTK_ICON_SIZE_DND:           n = 5; break;
271        case GTK_ICON_SIZE_DIALOG:        n = 6; break; 
272    }   
273
274    if( icon_cache[n] == NULL )
275        icon_cache[n] = icon_cache_new( for_widget, icon_size );
276
277    return icon_cache_get_mime_type_icon( icon_cache[n], mime_type );
278}                   
279
280
281const char * 
282get_mime_type_from_filename( const char * file G_GNUC_UNUSED )
283{
284#ifdef HAVE_GIO
285    return get_static_string( g_content_type_guess( file, NULL, 0, NULL ));
286#else
287    return "uncertain";
288#endif
289}
Note: See TracBrowser for help on using the repository browser.