summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@ximian.com>2004-01-27 23:20:01 +0000
committerFederico Mena Quintero <federico@src.gnome.org>2004-01-27 23:20:01 +0000
commit7af769f92c49fab087991ab63c15874f9a4c211b (patch)
treed0ad263891e5909566fe2ec57feff09d8ed7c122 /gtk
parent320166f2a73bec5cf860249b796ba72e2730bd07 (diff)
downloadgdk-pixbuf-7af769f92c49fab087991ab63c15874f9a4c211b.tar.gz
Fix #132314.
2004-01-27 Federico Mena Quintero <federico@ximian.com> Fix #132314. * gtk/gtkfilesystem.h: Removed the #ifdef-ed out, old icon API. * gtk/gtkfilesystem.c: Likewise. * gtk/gtkfilesystemunix.c (filename_get_info): Removed the old icon-type code. (gtk_file_system_unix_render_icon): Moved the icon-rendering code from GtkFileInfo to here. (gtk_file_system_unix_volume_render_icon): Implement.
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtkfilesystem.c166
-rw-r--r--gtk/gtkfilesystem.h28
-rw-r--r--gtk/gtkfilesystemunix.c264
3 files changed, 219 insertions, 239 deletions
diff --git a/gtk/gtkfilesystem.c b/gtk/gtkfilesystem.c
index 0a7d47675..31d73d3dd 100644
--- a/gtk/gtkfilesystem.c
+++ b/gtk/gtkfilesystem.c
@@ -31,9 +31,6 @@ struct _GtkFileInfo
gchar *display_name;
gchar *display_key;
gchar *mime_type;
-#if 0
- GtkFileIconType icon_type : 4;
-#endif
guint is_folder : 1;
guint is_hidden : 1;
};
@@ -247,169 +244,6 @@ gtk_file_info_set_size (GtkFileInfo *info,
info->size = size;
}
-#if 0
-void
-gtk_file_info_set_icon_type (GtkFileInfo *info,
- GtkFileIconType icon_type)
-{
- g_return_if_fail (info != NULL);
-
- info->icon_type = icon_type;
-}
-
-GtkFileIconType
-gtk_file_info_get_icon_type (const GtkFileInfo *info)
-{
- g_return_val_if_fail (info != NULL, GTK_FILE_ICON_REGULAR);
-
- return info->icon_type;
-}
-
-typedef struct _IconCacheElement IconCacheElement;
-
-struct _IconCacheElement
-{
- gint size;
- GdkPixbuf *pixbuf;
-};
-
-static void
-icon_cache_element_free (IconCacheElement *element)
-{
- if (element->pixbuf)
- g_object_unref (element->pixbuf);
- g_free (element);
-}
-
-static void
-icon_theme_changed (GtkIconTheme *icon_theme)
-{
- GHashTable *cache;
-
- /* Difference from the initial creation is that we don't
- * reconnect the signal
- */
- cache = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify)g_free,
- (GDestroyNotify)icon_cache_element_free);
- g_object_set_data_full (G_OBJECT (icon_theme), "gtk-file-icon-cache",
- cache, (GDestroyNotify)g_hash_table_destroy);
-}
-
-static GdkPixbuf *
-get_cached_icon (GtkWidget *widget,
- const gchar *name,
- gint pixel_size)
-{
- GtkIconTheme *icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
- GHashTable *cache = g_object_get_data (G_OBJECT (icon_theme), "gtk-file-icon-cache");
- IconCacheElement *element;
-
- if (!cache)
- {
- cache = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify)g_free,
- (GDestroyNotify)icon_cache_element_free);
-
- g_object_set_data_full (G_OBJECT (icon_theme), "gtk-file-icon-cache",
- cache, (GDestroyNotify)g_hash_table_destroy);
- g_signal_connect (icon_theme, "changed",
- G_CALLBACK (icon_theme_changed), NULL);
- }
-
- element = g_hash_table_lookup (cache, name);
- if (!element)
- {
- element = g_new0 (IconCacheElement, 1);
- g_hash_table_insert (cache, g_strdup (name), element);
- }
-
- if (element->size != pixel_size)
- {
- if (element->pixbuf)
- g_object_unref (element->pixbuf);
- element->size = pixel_size;
- element->pixbuf = gtk_icon_theme_load_icon (icon_theme, name,
- pixel_size, 0, NULL);
- }
-
- return element->pixbuf ? g_object_ref (element->pixbuf) : NULL;
-}
-
-
-GdkPixbuf *
-gtk_file_info_render_icon (const GtkFileInfo *info,
- GtkWidget *widget,
- gint pixel_size)
-{
- const gchar *separator;
- GdkPixbuf *pixbuf;
- GString *icon_name;
-
- g_return_val_if_fail (info != NULL, NULL);
- g_return_val_if_fail (widget != NULL, NULL);
- g_return_val_if_fail (pixel_size > 0, NULL);
-
- if (info->icon_type != GTK_FILE_ICON_REGULAR)
- {
- const char *name = NULL; /* Quiet gcc */
-
- switch (info->icon_type)
- {
- case GTK_FILE_ICON_BLOCK_DEVICE:
- name ="gnome-fs-blockdev";
- break;
- case GTK_FILE_ICON_BROKEN_SYMBOLIC_LINK:
- name = "gnome-fs-symlink";
- break;
- case GTK_FILE_ICON_CHARACTER_DEVICE:
- name = "gnome-fs-chardev";
- break;
- case GTK_FILE_ICON_DIRECTORY:
- name = "gnome-fs-directory";
- break;
- case GTK_FILE_ICON_EXECUTABLE:
- name ="gnome-fs-executable";
- break;
- case GTK_FILE_ICON_FIFO:
- name = "gnome-fs-fifo";
- break;
- case GTK_FILE_ICON_SOCKET:
- name = "gnome-fs-socket";
- break;
- case GTK_FILE_ICON_REGULAR:
- g_assert_not_reached ();
- }
-
- return get_cached_icon (widget, name, pixel_size);
- }
-
- if (!info->mime_type)
- return NULL;
-
- separator = strchr (info->mime_type, '/');
- if (!separator)
- return NULL;
-
- icon_name = g_string_new ("gnome-mime-");
- g_string_append_len (icon_name, info->mime_type, separator - info->mime_type);
- g_string_append_c (icon_name, '-');
- g_string_append (icon_name, separator + 1);
- pixbuf = get_cached_icon (widget, icon_name->str, pixel_size);
- g_string_free (icon_name, TRUE);
- if (pixbuf)
- return pixbuf;
-
- icon_name = g_string_new ("gnome-mime-");
- g_string_append_len (icon_name, info->mime_type, separator - info->mime_type);
- pixbuf = get_cached_icon (widget, icon_name->str, pixel_size);
- g_string_free (icon_name, TRUE);
- if (pixbuf)
- return pixbuf;
-
- return get_cached_icon (widget, "gnome-fs-regular", pixel_size);
-}
-#endif
/*****************************************
* GtkFileSystem *
diff --git a/gtk/gtkfilesystem.h b/gtk/gtkfilesystem.h
index 9f9d2650c..99e726886 100644
--- a/gtk/gtkfilesystem.h
+++ b/gtk/gtkfilesystem.h
@@ -55,27 +55,9 @@ typedef enum {
GTK_FILE_INFO_MIME_TYPE = 1 << 3,
GTK_FILE_INFO_MODIFICATION_TIME = 1 << 4,
GTK_FILE_INFO_SIZE = 1 << 5,
-#if 0
- GTK_FILE_INFO_ICON = 1 << 6,
-#endif
- GTK_FILE_INFO_ALL = (1 << 7) - 1
+ GTK_FILE_INFO_ALL = (1 << 6) - 1
} GtkFileInfoType;
-#if 0
-/* Icon type, supplemented by MIME type
- */
-typedef enum {
- GTK_FILE_ICON_REGULAR, /* Use mime type for icon */
- GTK_FILE_ICON_BLOCK_DEVICE,
- GTK_FILE_ICON_BROKEN_SYMBOLIC_LINK,
- GTK_FILE_ICON_CHARACTER_DEVICE,
- GTK_FILE_ICON_DIRECTORY,
- GTK_FILE_ICON_EXECUTABLE,
- GTK_FILE_ICON_FIFO,
- GTK_FILE_ICON_SOCKET
-} GtkFileIconType;
-#endif
-
/* GError enumeration for GtkFileSystem
*/
@@ -122,14 +104,6 @@ void gtk_file_info_set_modification_time (GtkFileInfo *in
gint64 gtk_file_info_get_size (const GtkFileInfo *info);
void gtk_file_info_set_size (GtkFileInfo *info,
gint64 size);
-#if 0
-void gtk_file_info_set_icon_type (GtkFileInfo *info,
- GtkFileIconType icon_type);
-GtkFileIconType gtk_file_info_get_icon_type (const GtkFileInfo *info);
-GdkPixbuf * gtk_file_info_render_icon (const GtkFileInfo *info,
- GtkWidget *widget,
- gint pixel_size);
-#endif
/* The base GtkFileSystem interface
*/
diff --git a/gtk/gtkfilesystemunix.c b/gtk/gtkfilesystemunix.c
index 610c63e0e..fd5e93d94 100644
--- a/gtk/gtkfilesystemunix.c
+++ b/gtk/gtkfilesystemunix.c
@@ -20,6 +20,7 @@
#include "gtkfilesystem.h"
#include "gtkfilesystemunix.h"
+#include "gtkicontheme.h"
#include "gtkintl.h"
#define XDG_PREFIX _gtk_xdg
@@ -47,10 +48,20 @@ struct _GtkFileSystemUnix
GObject parent_instance;
};
-/* Simple stub for our returned volumes */
-typedef struct {
- int dummy;
-} Volume;
+/* Icon type, supplemented by MIME type
+ */
+typedef enum {
+ ICON_NONE,
+ ICON_REGULAR, /* Use mime type for icon */
+ ICON_BLOCK_DEVICE,
+ ICON_BROKEN_SYMBOLIC_LINK,
+ ICON_CHARACTER_DEVICE,
+ ICON_DIRECTORY,
+ ICON_EXECUTABLE,
+ ICON_FIFO,
+ ICON_SOCKET
+} IconType;
+
#define GTK_TYPE_FILE_FOLDER_UNIX (gtk_file_folder_unix_get_type ())
#define GTK_FILE_FOLDER_UNIX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_FOLDER_UNIX, GtkFileFolderUnix))
@@ -386,6 +397,128 @@ gtk_file_system_unix_volume_get_display_name (GtkFileSystem *file_system,
return g_strdup (_("Filesystem")); /* Same as Nautilus */
}
+static IconType
+get_icon_type (const char *filename,
+ GError **error)
+{
+ struct stat statbuf;
+ IconType icon_type;
+
+ /* If stat fails, try to fall back to lstat to catch broken links
+ */
+ if (stat (filename, &statbuf) != 0 &&
+ lstat (filename, &statbuf) != 0)
+ {
+ gchar *filename_utf8 = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
+ g_set_error (error,
+ GTK_FILE_SYSTEM_ERROR,
+ GTK_FILE_SYSTEM_ERROR_NONEXISTENT,
+ _("error getting information for '%s': %s"),
+ filename_utf8 ? filename_utf8 : "???",
+ g_strerror (errno));
+ g_free (filename_utf8);
+
+ return ICON_NONE;
+ }
+
+ if (S_ISBLK (statbuf.st_mode))
+ icon_type = ICON_BLOCK_DEVICE;
+ else if (S_ISLNK (statbuf.st_mode))
+ icon_type = ICON_BROKEN_SYMBOLIC_LINK; /* See above */
+ else if (S_ISCHR (statbuf.st_mode))
+ icon_type = ICON_CHARACTER_DEVICE;
+ else if (S_ISDIR (statbuf.st_mode))
+ icon_type = ICON_DIRECTORY;
+ else if (S_ISFIFO (statbuf.st_mode))
+ icon_type = ICON_FIFO;
+ else if (S_ISSOCK (statbuf.st_mode))
+ icon_type = ICON_SOCKET;
+ else
+ {
+ icon_type = ICON_REGULAR;
+
+#if 0
+ if ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR &&
+ (statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) &&
+ (strcmp (mime_type, XDG_MIME_TYPE_UNKNOWN) == 0 ||
+ strcmp (mime_type, "application/x-executable") == 0 ||
+ strcmp (mime_type, "application/x-shellscript") == 0))
+ gtk_file_info_set_icon_type (info, GTK_FILE_ICON_EXECUTABLE);
+#endif
+ }
+
+ return icon_type;
+}
+
+typedef struct
+{
+ gint size;
+ GdkPixbuf *pixbuf;
+} IconCacheElement;
+
+static void
+icon_cache_element_free (IconCacheElement *element)
+{
+ if (element->pixbuf)
+ g_object_unref (element->pixbuf);
+ g_free (element);
+}
+
+static void
+icon_theme_changed (GtkIconTheme *icon_theme)
+{
+ GHashTable *cache;
+
+ /* Difference from the initial creation is that we don't
+ * reconnect the signal
+ */
+ cache = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)icon_cache_element_free);
+ g_object_set_data_full (G_OBJECT (icon_theme), "gtk-file-icon-cache",
+ cache, (GDestroyNotify)g_hash_table_destroy);
+}
+
+static GdkPixbuf *
+get_cached_icon (GtkWidget *widget,
+ const gchar *name,
+ gint pixel_size)
+{
+ GtkIconTheme *icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
+ GHashTable *cache = g_object_get_data (G_OBJECT (icon_theme), "gtk-file-icon-cache");
+ IconCacheElement *element;
+
+ if (!cache)
+ {
+ cache = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)icon_cache_element_free);
+
+ g_object_set_data_full (G_OBJECT (icon_theme), "gtk-file-icon-cache",
+ cache, (GDestroyNotify)g_hash_table_destroy);
+ g_signal_connect (icon_theme, "changed",
+ G_CALLBACK (icon_theme_changed), NULL);
+ }
+
+ element = g_hash_table_lookup (cache, name);
+ if (!element)
+ {
+ element = g_new0 (IconCacheElement, 1);
+ g_hash_table_insert (cache, g_strdup (name), element);
+ }
+
+ if (element->size != pixel_size)
+ {
+ if (element->pixbuf)
+ g_object_unref (element->pixbuf);
+ element->size = pixel_size;
+ element->pixbuf = gtk_icon_theme_load_icon (icon_theme, name,
+ pixel_size, 0, NULL);
+ }
+
+ return element->pixbuf ? g_object_ref (element->pixbuf) : NULL;
+}
+
static GdkPixbuf *
gtk_file_system_unix_volume_render_icon (GtkFileSystem *file_system,
GtkFileSystemVolume *volume,
@@ -393,7 +526,8 @@ gtk_file_system_unix_volume_render_icon (GtkFileSystem *file_system,
gint pixel_size,
GError **error)
{
- return NULL; /* FIXME: We need a hard disk icon or something */
+ /* FIXME: set the GError if we can't load the icon */
+ return get_cached_icon (widget, "gnome-fs-blockdev", pixel_size);
}
static gboolean
@@ -641,12 +775,85 @@ gtk_file_system_unix_render_icon (GtkFileSystem *file_system,
gint pixel_size,
GError **error)
{
- /* FIXME: Implement this */
- g_set_error (error,
- GTK_FILE_SYSTEM_ERROR,
- GTK_FILE_SYSTEM_ERROR_FAILED,
- _("This file system does not support icons"));
- return NULL;
+ const char *filename;
+ IconType icon_type;
+ const char *mime_type;
+
+ filename = gtk_file_path_get_string (path);
+ icon_type = get_icon_type (filename, error);
+
+ /* FIXME: this function should not return NULL without setting the GError; we
+ * should perhaps provide a "never fails" generic stock icon for when all else
+ * fails.
+ */
+
+ if (icon_type == ICON_NONE)
+ return NULL;
+
+ if (icon_type != ICON_REGULAR)
+ {
+ const char *name;
+
+ switch (icon_type)
+ {
+ case ICON_BLOCK_DEVICE:
+ name = "gnome-fs-blockdev";
+ break;
+ case ICON_BROKEN_SYMBOLIC_LINK:
+ name = "gnome-fs-symlink";
+ break;
+ case ICON_CHARACTER_DEVICE:
+ name = "gnome-fs-chardev";
+ break;
+ case ICON_DIRECTORY:
+ name = "gnome-fs-directory";
+ break;
+ case ICON_EXECUTABLE:
+ name ="gnome-fs-executable";
+ break;
+ case ICON_FIFO:
+ name = "gnome-fs-fifo";
+ break;
+ case ICON_SOCKET:
+ name = "gnome-fs-socket";
+ break;
+ default:
+ g_assert_not_reached ();
+ return NULL;
+ }
+
+ return get_cached_icon (widget, name, pixel_size);
+ }
+
+ mime_type = xdg_mime_get_mime_type_for_file (filename);
+ if (mime_type)
+ {
+ const char *separator;
+ GString *icon_name;
+ GdkPixbuf *pixbuf;
+
+ separator = strchr (mime_type, '/');
+ if (!separator)
+ return NULL;
+
+ icon_name = g_string_new ("gnome-mime-");
+ g_string_append_len (icon_name, mime_type, separator - mime_type);
+ g_string_append_c (icon_name, '-');
+ g_string_append (icon_name, separator + 1);
+ pixbuf = get_cached_icon (widget, icon_name->str, pixel_size);
+ g_string_free (icon_name, TRUE);
+ if (pixbuf)
+ return pixbuf;
+
+ icon_name = g_string_new ("gnome-mime-");
+ g_string_append_len (icon_name, mime_type, separator - mime_type);
+ pixbuf = get_cached_icon (widget, icon_name->str, pixel_size);
+ g_string_free (icon_name, TRUE);
+ if (pixbuf)
+ return pixbuf;
+ }
+
+ return get_cached_icon (widget, "gnome-fs-regular", pixel_size);
}
static gboolean
@@ -830,9 +1037,6 @@ filename_get_info (const gchar *filename,
GError **error)
{
GtkFileInfo *info;
-#if 0
- GtkFileIconType icon_type = GTK_FILE_ICON_REGULAR;
-#endif
struct stat statbuf;
/* If stat fails, try to fall back to lstat to catch broken links
@@ -890,42 +1094,10 @@ filename_get_info (const gchar *filename,
gtk_file_info_set_is_folder (info, S_ISDIR (statbuf.st_mode));
}
-#if 0
- if (types & GTK_FILE_INFO_ICON)
- {
- if (S_ISBLK (statbuf.st_mode))
- icon_type = GTK_FILE_ICON_BLOCK_DEVICE;
- else if (S_ISLNK (statbuf.st_mode))
- icon_type = GTK_FILE_ICON_BROKEN_SYMBOLIC_LINK;
- else if (S_ISCHR (statbuf.st_mode))
- icon_type = GTK_FILE_ICON_CHARACTER_DEVICE;
- else if (S_ISDIR (statbuf.st_mode))
- icon_type = GTK_FILE_ICON_DIRECTORY;
- else if (S_ISFIFO (statbuf.st_mode))
- icon_type = GTK_FILE_ICON_FIFO;
- else if (S_ISSOCK (statbuf.st_mode))
- icon_type = GTK_FILE_ICON_SOCKET;
-
- gtk_file_info_set_icon_type (info, icon_type);
- }
-
- if ((types & GTK_FILE_INFO_MIME_TYPE) ||
- ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR))
-#else
if (types & GTK_FILE_INFO_MIME_TYPE)
-#endif
{
const char *mime_type = xdg_mime_get_mime_type_for_file (filename);
gtk_file_info_set_mime_type (info, mime_type);
-
-#if 0
- if ((types & GTK_FILE_INFO_ICON) && icon_type == GTK_FILE_ICON_REGULAR &&
- (statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) &&
- (strcmp (mime_type, XDG_MIME_TYPE_UNKNOWN) == 0 ||
- strcmp (mime_type, "application/x-executable") == 0 ||
- strcmp (mime_type, "application/x-shellscript") == 0))
- gtk_file_info_set_icon_type (info, GTK_FILE_ICON_EXECUTABLE);
-#endif
}
if (types & GTK_FILE_INFO_MODIFICATION_TIME)