mirror of
https://github.com/transmission/transmission
synced 2024-12-26 09:37:56 +00:00
879a2afcbd
The Berne Convention says that the copyright year is moot, so instead of adding another year to each file as in previous years, I've removed the year altogether from the source code comments in libtransmission, gtk, qt, utils, daemon, and cli. Juliusz's copyright notice in tr-dht and Johannes' copyright notice in tr-lpd have been left alone; it didn't seem appropriate to modify them.
294 lines
7.3 KiB
C
294 lines
7.3 KiB
C
/*
|
|
* icons.[ch] written by Paolo Bacchilega, who writes:
|
|
* "There is no problem for me, you can license my code
|
|
* under whatever licence you wish :)"
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#include <string.h> /* strcmp */
|
|
#include <glib.h>
|
|
#include <gtk/gtk.h>
|
|
#include "icons.h"
|
|
|
|
#ifdef HAVE_GIO
|
|
#if GTK_CHECK_VERSION( 2, 12, 0 )
|
|
#define USE_GIO_ICONS
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef USE_GIO_ICONS
|
|
#include <gio/gio.h>
|
|
#endif
|
|
|
|
#define VOID_PIXBUF_KEY "void-pixbuf"
|
|
|
|
#ifdef USE_GIO_ICONS
|
|
static const char *
|
|
get_static_string( const char *s )
|
|
{
|
|
static GStringChunk * static_strings = NULL;
|
|
|
|
if( s == NULL )
|
|
return NULL;
|
|
|
|
if( static_strings == NULL )
|
|
static_strings = g_string_chunk_new( 1024 );
|
|
|
|
return g_string_chunk_insert_const( static_strings, s );
|
|
}
|
|
#endif
|
|
|
|
|
|
typedef struct {
|
|
GtkIconTheme * icon_theme;
|
|
int icon_size;
|
|
GHashTable * cache;
|
|
} IconCache;
|
|
|
|
|
|
static IconCache *icon_cache[7] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
|
|
|
|
|
static GdkPixbuf*
|
|
create_void_pixbuf (int width,
|
|
int height)
|
|
{
|
|
GdkPixbuf *p;
|
|
|
|
p = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
|
|
TRUE,
|
|
8,
|
|
width,
|
|
height);
|
|
gdk_pixbuf_fill( p, 0xFFFFFF00 );
|
|
|
|
return p;
|
|
}
|
|
|
|
|
|
static int
|
|
get_size_in_pixels( GtkWidget * widget,
|
|
GtkIconSize icon_size )
|
|
{
|
|
int width, height;
|
|
|
|
gtk_icon_size_lookup_for_settings( gtk_widget_get_settings( widget ),
|
|
icon_size,
|
|
&width,
|
|
&height );
|
|
return MAX( width, height );
|
|
}
|
|
|
|
|
|
static IconCache *
|
|
icon_cache_new (GtkWidget * for_widget, int icon_size)
|
|
{
|
|
IconCache * icon_cache;
|
|
|
|
g_return_val_if_fail( for_widget != NULL, NULL );
|
|
|
|
icon_cache = g_new0( IconCache, 1 );
|
|
icon_cache->icon_theme = gtk_icon_theme_get_for_screen( gtk_widget_get_screen( for_widget ));
|
|
icon_cache->icon_size = get_size_in_pixels( for_widget, icon_size );
|
|
icon_cache->cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
|
|
|
|
g_hash_table_insert( icon_cache->cache, (void*)VOID_PIXBUF_KEY, create_void_pixbuf( icon_cache->icon_size, icon_cache->icon_size ));
|
|
|
|
return icon_cache;
|
|
}
|
|
|
|
#ifdef USE_GIO_ICONS
|
|
static const char *
|
|
_icon_cache_get_icon_key( GIcon * icon )
|
|
{
|
|
const char * key = NULL;
|
|
|
|
if ( G_IS_THEMED_ICON( icon )) {
|
|
char ** icon_names;
|
|
char * name;
|
|
|
|
g_object_get( icon, "names", &icon_names, NULL );
|
|
name = g_strjoinv( ",", icon_names );
|
|
|
|
key = get_static_string( name );
|
|
|
|
g_free( name );
|
|
g_strfreev( icon_names );
|
|
}
|
|
else if ( G_IS_FILE_ICON( icon )) {
|
|
GFile * file;
|
|
char * filename;
|
|
|
|
file = g_file_icon_get_file( G_FILE_ICON( icon ));
|
|
filename = g_file_get_path( file );
|
|
|
|
key = get_static_string( filename );
|
|
|
|
g_free( filename );
|
|
g_object_unref( file );
|
|
}
|
|
|
|
return key;
|
|
}
|
|
|
|
|
|
static GdkPixbuf *
|
|
get_themed_icon_pixbuf( GThemedIcon * icon,
|
|
int size,
|
|
GtkIconTheme * icon_theme )
|
|
{
|
|
char ** icon_names = NULL;
|
|
GtkIconInfo * icon_info;
|
|
GdkPixbuf * pixbuf;
|
|
GError * error = NULL;
|
|
|
|
g_object_get( icon, "names", &icon_names, NULL );
|
|
|
|
icon_info = gtk_icon_theme_choose_icon( icon_theme, (const char **)icon_names, size, 0 );
|
|
if ( icon_info == NULL )
|
|
icon_info = gtk_icon_theme_lookup_icon( icon_theme, "text-x-generic", size, GTK_ICON_LOOKUP_USE_BUILTIN );
|
|
|
|
pixbuf = gtk_icon_info_load_icon( icon_info, &error );
|
|
if ( pixbuf == NULL ) {
|
|
if( error && error->message )
|
|
g_warning( "could not load icon pixbuf: %s\n", error->message );
|
|
g_clear_error( &error );
|
|
}
|
|
|
|
gtk_icon_info_free( icon_info );
|
|
g_strfreev( icon_names );
|
|
|
|
return pixbuf;
|
|
}
|
|
|
|
|
|
static GdkPixbuf *
|
|
get_file_icon_pixbuf( GFileIcon * icon, int size )
|
|
{
|
|
GFile * file;
|
|
char * filename;
|
|
GdkPixbuf * pixbuf;
|
|
|
|
file = g_file_icon_get_file( icon );
|
|
filename = g_file_get_path( file );
|
|
pixbuf = gdk_pixbuf_new_from_file_at_size( filename, size, -1, NULL );
|
|
g_free( filename );
|
|
g_object_unref( file );
|
|
|
|
return pixbuf;
|
|
}
|
|
|
|
|
|
static GdkPixbuf *
|
|
_get_icon_pixbuf( GIcon * icon, int size, GtkIconTheme * theme )
|
|
{
|
|
if ( icon == NULL )
|
|
return NULL;
|
|
if ( G_IS_THEMED_ICON (icon) )
|
|
return get_themed_icon_pixbuf( G_THEMED_ICON( icon ), size, theme );
|
|
if ( G_IS_FILE_ICON (icon) )
|
|
return get_file_icon_pixbuf( G_FILE_ICON( icon ), size );
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static GdkPixbuf *
|
|
icon_cache_get_mime_type_icon( IconCache * icon_cache, const char * mime_type )
|
|
{
|
|
GIcon * icon;
|
|
const char * key = NULL;
|
|
GdkPixbuf * pixbuf;
|
|
|
|
icon = g_content_type_get_icon( mime_type );
|
|
key = _icon_cache_get_icon_key( icon );
|
|
|
|
if (key == NULL)
|
|
key = VOID_PIXBUF_KEY;
|
|
|
|
pixbuf = g_hash_table_lookup( icon_cache->cache, key );
|
|
if (pixbuf != NULL) {
|
|
g_object_ref( pixbuf );
|
|
g_object_unref( G_OBJECT( icon ) );
|
|
return pixbuf;
|
|
}
|
|
|
|
pixbuf = _get_icon_pixbuf( icon, icon_cache->icon_size, icon_cache->icon_theme );
|
|
if( pixbuf != NULL )
|
|
g_hash_table_insert( icon_cache->cache, (gpointer) key, g_object_ref( pixbuf ) );
|
|
|
|
g_object_unref( G_OBJECT( icon ) );
|
|
|
|
return pixbuf;
|
|
}
|
|
|
|
#else /* USE_GIO_ICONS */
|
|
|
|
static GdkPixbuf *
|
|
icon_cache_get_mime_type_icon( IconCache * icon_cache, const char * mime_type )
|
|
{
|
|
GdkPixbuf * pixbuf;
|
|
const char * stock_name;
|
|
|
|
if( !strcmp( mime_type, UNKNOWN_MIME_TYPE ) )
|
|
stock_name = GTK_STOCK_MISSING_IMAGE;
|
|
else if( !strcmp( mime_type, DIRECTORY_MIME_TYPE ) )
|
|
stock_name = GTK_STOCK_DIRECTORY;
|
|
else
|
|
stock_name = GTK_STOCK_FILE;
|
|
|
|
pixbuf = g_hash_table_lookup( icon_cache->cache, stock_name );
|
|
|
|
if( pixbuf != NULL )
|
|
{
|
|
g_object_ref( pixbuf );
|
|
return pixbuf;
|
|
}
|
|
|
|
pixbuf = gtk_icon_theme_load_icon( icon_cache->icon_theme,
|
|
stock_name,
|
|
icon_cache->icon_size,
|
|
0, NULL );
|
|
g_hash_table_insert( icon_cache->cache, (gpointer) stock_name, g_object_ref( pixbuf ));
|
|
return pixbuf;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
GdkPixbuf *
|
|
gtr_get_mime_type_icon( const char * mime_type,
|
|
GtkIconSize icon_size,
|
|
GtkWidget * for_widget )
|
|
{
|
|
int n;
|
|
|
|
switch ( icon_size ) {
|
|
case GTK_ICON_SIZE_MENU: n = 1; break;
|
|
case GTK_ICON_SIZE_SMALL_TOOLBAR: n = 2; break;
|
|
case GTK_ICON_SIZE_LARGE_TOOLBAR: n = 3; break;
|
|
case GTK_ICON_SIZE_BUTTON: n = 4; break;
|
|
case GTK_ICON_SIZE_DND: n = 5; break;
|
|
case GTK_ICON_SIZE_DIALOG: n = 6; break;
|
|
default /*GTK_ICON_SIZE_INVALID*/: n = 0; break;
|
|
}
|
|
|
|
if( icon_cache[n] == NULL )
|
|
icon_cache[n] = icon_cache_new( for_widget, icon_size );
|
|
|
|
return icon_cache_get_mime_type_icon( icon_cache[n], mime_type );
|
|
}
|
|
|
|
|
|
const char *
|
|
gtr_get_mime_type_from_filename( const char * file G_GNUC_UNUSED )
|
|
{
|
|
#ifdef USE_GIO_ICONS
|
|
char * tmp = g_content_type_guess( file, NULL, 0, NULL );
|
|
const char * ret = get_static_string( tmp );
|
|
g_free( tmp );
|
|
return ret;
|
|
#else
|
|
return "uncertain";
|
|
#endif
|
|
}
|