From a15a071f35f2743451aa98b2b069b7eca975c7ea Mon Sep 17 00:00:00 2001 From: William Jon McCann Date: Tue, 28 Aug 2012 18:56:53 -0400 Subject: [PATCH] Add symbolic icon support to gfileinfo https://bugzilla.gnome.org/show_bug.cgi?id=682101 --- docs/reference/gio/gio-sections.txt | 3 + gio/gfileinfo-priv.h | 1 + gio/gfileinfo.c | 58 +++++++++++++++++ gio/gfileinfo.h | 14 +++++ gio/gio.symbols | 2 + gio/glocalfileinfo.c | 97 ++++++++++++++++++++++------- 6 files changed, 154 insertions(+), 21 deletions(-) diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt index bb0e29561..dfc79d3df 100644 --- a/docs/reference/gio/gio-sections.txt +++ b/docs/reference/gio/gio-sections.txt @@ -241,6 +241,7 @@ G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME G_FILE_ATTRIBUTE_STANDARD_COPY_NAME G_FILE_ATTRIBUTE_STANDARD_ICON +G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE G_FILE_ATTRIBUTE_STANDARD_SIZE @@ -347,6 +348,7 @@ g_file_info_get_name g_file_info_get_display_name g_file_info_get_edit_name g_file_info_get_icon +g_file_info_get_symbolic_icon g_file_info_get_content_type g_file_info_get_size g_file_info_get_modification_time @@ -362,6 +364,7 @@ g_file_info_set_name g_file_info_set_display_name g_file_info_set_edit_name g_file_info_set_icon +g_file_info_set_symbolic_icon g_file_info_set_content_type g_file_info_set_size g_file_info_set_modification_time diff --git a/gio/gfileinfo-priv.h b/gio/gfileinfo-priv.h index 97fcf8930..0298db5a1 100644 --- a/gio/gfileinfo-priv.h +++ b/gio/gfileinfo-priv.h @@ -44,6 +44,7 @@ #define G_FILE_ATTRIBUTE_ID_STANDARD_SYMLINK_TARGET (1048576 + 16) #define G_FILE_ATTRIBUTE_ID_STANDARD_TARGET_URI (1048576 + 17) #define G_FILE_ATTRIBUTE_ID_STANDARD_SORT_ORDER (1048576 + 18) +#define G_FILE_ATTRIBUTE_ID_STANDARD_SYMBOLIC_ICON (1048576 + 19) #define G_FILE_ATTRIBUTE_ID_ETAG_VALUE (2097152 + 1) #define G_FILE_ATTRIBUTE_ID_ID_FILE (3145728 + 1) #define G_FILE_ATTRIBUTE_ID_ID_FILESYSTEM (3145728 + 2) diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c index 3e957b9fb..0fd76da09 100644 --- a/gio/gfileinfo.c +++ b/gio/gfileinfo.c @@ -204,6 +204,7 @@ ensure_attribute_hash (void) REGISTER_ATTRIBUTE (STANDARD_SYMLINK_TARGET); REGISTER_ATTRIBUTE (STANDARD_TARGET_URI); REGISTER_ATTRIBUTE (STANDARD_SORT_ORDER); + REGISTER_ATTRIBUTE (STANDARD_SYMBOLIC_ICON); REGISTER_ATTRIBUTE (ETAG_VALUE); REGISTER_ATTRIBUTE (ID_FILE); REGISTER_ATTRIBUTE (ID_FILESYSTEM); @@ -1627,6 +1628,35 @@ g_file_info_get_icon (GFileInfo *info) return NULL; } +/** + * g_file_info_get_symbolic_icon: + * @info: a #GFileInfo. + * + * Gets the symbolic icon for a file. + * + * Returns: (transfer none): #GIcon for the given @info. + * + * Since: 2.34 + **/ +GIcon * +g_file_info_get_symbolic_icon (GFileInfo *info) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + GObject *obj; + + g_return_val_if_fail (G_IS_FILE_INFO (info), NULL); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON); + + value = g_file_info_find_value (info, attr); + obj = _g_file_attribute_value_get_object (value); + if (G_IS_ICON (obj)) + return G_ICON (obj); + return NULL; +} + /** * g_file_info_get_content_type: * @info: a #GFileInfo. @@ -1954,6 +1984,34 @@ g_file_info_set_icon (GFileInfo *info, _g_file_attribute_value_set_object (value, G_OBJECT (icon)); } +/** + * g_file_info_set_symbolic_icon: + * @info: a #GFileInfo. + * @icon: a #GIcon. + * + * Sets the symbolic icon for a given #GFileInfo. + * See %G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON. + * + * Since: 2.34 + **/ +void +g_file_info_set_symbolic_icon (GFileInfo *info, + GIcon *icon) +{ + static guint32 attr = 0; + GFileAttributeValue *value; + + g_return_if_fail (G_IS_FILE_INFO (info)); + g_return_if_fail (G_IS_ICON (icon)); + + if (attr == 0) + attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON); + + value = g_file_info_create_value (info, attr); + if (value) + _g_file_attribute_value_set_object (value, G_OBJECT (icon)); +} + /** * g_file_info_set_content_type: * @info: a #GFileInfo. diff --git a/gio/gfileinfo.h b/gio/gfileinfo.h index 7514093bd..9399e5343 100644 --- a/gio/gfileinfo.h +++ b/gio/gfileinfo.h @@ -162,6 +162,17 @@ typedef struct _GFileInfoClass GFileInfoClass; **/ #define G_FILE_ATTRIBUTE_STANDARD_ICON "standard::icon" /* object (GIcon) */ +/** + * G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON: + * + * A key in the "standard" namespace for getting the symbolic icon for the file. + * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_OBJECT. + * The value for this key should contain a #GIcon. + * + * Since: 2.34 + **/ +#define G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON "standard::symbolic-icon" /* object (GIcon) */ + /** * G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE: * @@ -908,6 +919,7 @@ const char * g_file_info_get_name (GFileInfo *info); const char * g_file_info_get_display_name (GFileInfo *info); const char * g_file_info_get_edit_name (GFileInfo *info); GIcon * g_file_info_get_icon (GFileInfo *info); +GIcon * g_file_info_get_symbolic_icon (GFileInfo *info); const char * g_file_info_get_content_type (GFileInfo *info); goffset g_file_info_get_size (GFileInfo *info); void g_file_info_get_modification_time (GFileInfo *info, @@ -935,6 +947,8 @@ void g_file_info_set_edit_name (GFileInfo *info, const char *edit_name); void g_file_info_set_icon (GFileInfo *info, GIcon *icon); +void g_file_info_set_symbolic_icon (GFileInfo *info, + GIcon *icon); void g_file_info_set_content_type (GFileInfo *info, const char *content_type); void g_file_info_set_size (GFileInfo *info, diff --git a/gio/gio.symbols b/gio/gio.symbols index f06e5e085..e366d9ca9 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -422,6 +422,7 @@ g_file_info_get_name g_file_info_get_display_name g_file_info_get_edit_name g_file_info_get_icon +g_file_info_get_symbolic_icon g_file_info_get_content_type g_file_info_get_size g_file_info_get_modification_time @@ -437,6 +438,7 @@ g_file_info_set_name g_file_info_set_display_name g_file_info_set_edit_name g_file_info_set_icon +g_file_info_set_symbolic_icon g_file_info_set_content_type g_file_info_set_size g_file_info_set_modification_time diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index af4fc43aa..0d4c1b77d 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -1448,6 +1448,63 @@ _g_local_file_info_get_nostat (GFileInfo *info, } } +static const char * +get_icon_name (const char *path, + gboolean use_symbolic, + gboolean *with_fallbacks_out) +{ + const char *name = NULL; + gboolean with_fallbacks = TRUE; + + if (strcmp (path, g_get_home_dir ()) == 0) + { + name = use_symbolic ? "user-home-symbolic" : "user-home"; + with_fallbacks = FALSE; + } + else if (strcmp (path, g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)) == 0) + { + name = use_symbolic ? "user-desktop-symbolic" : "user-desktop"; + with_fallbacks = FALSE; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS)) == 0) + { + name = use_symbolic ? "folder-documents-symbolic" : "folder-documents"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD)) == 0) + { + name = use_symbolic ? "folder-download-symbolic" : "folder-download"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_MUSIC)) == 0) + { + name = use_symbolic ? "folder-music-symbolic" : "folder-music"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_PICTURES)) == 0) + { + name = use_symbolic ? "folder-pictures-symbolic" : "folder-pictures"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_PUBLIC_SHARE)) == 0) + { + name = use_symbolic ? "folder-publicshare-symbolic" : "folder-publicshare"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES)) == 0) + { + name = use_symbolic ? "folder-templates-symbolic" : "folder-templates"; + } + else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS)) == 0) + { + name = use_symbolic ? "folder-videos-symbolic" : "folder-videos"; + } + else + { + name = NULL; + } + + if (with_fallbacks_out != NULL) + *with_fallbacks_out = with_fallbacks; + + return name; +} + GFileInfo * _g_local_file_info_get (const char *basename, const char *path, @@ -1601,37 +1658,35 @@ _g_local_file_info_get (const char *basename, if (_g_file_attribute_matcher_matches_id (attribute_matcher, G_FILE_ATTRIBUTE_ID_STANDARD_CONTENT_TYPE) || _g_file_attribute_matcher_matches_id (attribute_matcher, - G_FILE_ATTRIBUTE_ID_STANDARD_ICON)) + G_FILE_ATTRIBUTE_ID_STANDARD_ICON) || + _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_SYMBOLIC_ICON)) { char *content_type = get_content_type (basename, path, stat_ok ? &statbuf : NULL, is_symlink, symlink_broken, flags, FALSE); if (content_type) { + gboolean use_symbolics = FALSE; + g_file_info_set_content_type (info, content_type); - if (_g_file_attribute_matcher_matches_id (attribute_matcher, - G_FILE_ATTRIBUTE_ID_STANDARD_ICON)) + use_symbolics = _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_SYMBOLIC_ICON); + if (use_symbolics || + _g_file_attribute_matcher_matches_id (attribute_matcher, + G_FILE_ATTRIBUTE_ID_STANDARD_ICON)) { GIcon *icon; + gboolean with_fallbacks = TRUE; + const char *icon_name = get_icon_name (path, use_symbolics, &with_fallbacks); - if (strcmp (path, g_get_home_dir ()) == 0) - icon = g_themed_icon_new ("user-home"); - else if (strcmp (path, g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP)) == 0) - icon = g_themed_icon_new ("user-desktop"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-documents"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-download"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_MUSIC)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-music"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_PICTURES)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-pictures"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_PUBLIC_SHARE)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-publicshare"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_TEMPLATES)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-templates"); - else if (g_strcmp0 (path, g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS)) == 0) - icon = g_themed_icon_new_with_default_fallbacks ("folder-videos"); + if (icon_name != NULL) + { + if (with_fallbacks) + icon = g_themed_icon_new_with_default_fallbacks (icon_name); + else + icon = g_themed_icon_new (icon_name); + } else { icon = g_content_type_get_icon (content_type);