Enlightenment CVS committal Author : mekius Project : e17 Module : libs/efreet
Dir : e17/libs/efreet/src/lib Modified Files: Efreet_Mime.h efreet_icon.c efreet_icon.h efreet_mime.c Log Message: Added efreet_mime_type_icon_get which will retrieve a mimetype icon. This follows the loose specification described in the fdo icon spec. Also added efreet_icon_list_find which will search for a list of icons in a theme before falling back to inherited themes. Also made a slight modification to the fallback detection for efreet_mime. Tabs will no longer trigger the return of application/octet-stream. =================================================================== RCS file: /cvs/e/e17/libs/efreet/src/lib/Efreet_Mime.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -3 -r1.4 -r1.5 --- Efreet_Mime.h 6 Jul 2007 03:01:21 -0000 1.4 +++ Efreet_Mime.h 17 Jul 2007 19:21:20 -0000 1.5 @@ -34,6 +34,9 @@ const char *efreet_mime_globs_type_get(const char *file); const char *efreet_mime_special_type_get(const char *file); const char *efreet_mime_fallback_type_get(const char *file); + +const char *efreet_mime_type_icon_get(const char *mime, const char *theme, + const char *size); /** * @} =================================================================== RCS file: /cvs/e/e17/libs/efreet/src/lib/efreet_icon.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -3 -r1.22 -r1.23 --- efreet_icon.c 22 Jun 2007 10:20:44 -0000 1.22 +++ efreet_icon.c 17 Jul 2007 19:21:20 -0000 1.23 @@ -11,10 +11,26 @@ Ecore_List *efreet_icon_extensions = NULL; static Ecore_List *efreet_extra_icon_dirs = NULL; +static char *efreet_icon_remove_extension(const char *icon); +static Efreet_Icon_Theme *efreet_icon_find_theme_check(const char *theme_name); + + +static Efreet_Icon *efreet_icon_find_fallback(Efreet_Icon_Theme *theme, + const char *cache_key, + const char *icon, + const char *size); +static Efreet_Icon *efreet_icon_list_find_fallback(Efreet_Icon_Theme *theme, + Ecore_List *cache_keys, + Ecore_List *icons, + const char *size); static Efreet_Icon *efreet_icon_find_helper(Efreet_Icon_Theme *theme, const char *cache_key, const char *icon, const char *size); +static Efreet_Icon *efreet_icon_list_find_helper(Efreet_Icon_Theme *theme, + Ecore_List *cache_keys, + Ecore_List *icons, + const char *size); static Efreet_Icon *efreet_icon_lookup_icon(Efreet_Icon_Theme *theme, const char *icon_name, const char *size); @@ -238,6 +254,63 @@ } /** + * @internal + * @param icon: The icon name to strip extension + * @return Extension removed if in list of extensions, else untouched. + * @brief Removes extension from icon name if in list of extensions. + */ +static char * +efreet_icon_remove_extension(const char *icon) +{ + char *tmp = NULL, *ext = NULL; + + tmp = strdup(icon); + ext = strrchr(tmp, '.'); + if (ext) + { + const char *ext2; + ecore_list_goto_first(efreet_icon_extensions); + while ((ext2 = ecore_list_next(efreet_icon_extensions))) + { + if (!strcmp(ext, ext2)) + { +#ifdef STRICT_SPEC + printf("[Efreet]: Requesting an icon with an extension: %s\n", + icon); +#endif + *ext = '\0'; + break; + } + } + } + + return tmp; +} + +/** + * @internal + * @param theme_name: The icon theme to look for + * @return Returns the Efreet_Icon_Theme structure representing this theme + * or a new blank theme if not found + * @brief Retrieves a theme, or creates a blank one if not found. + */ +static Efreet_Icon_Theme * +efreet_icon_find_theme_check(const char *theme_name) +{ + Efreet_Icon_Theme *theme = NULL; + theme = efreet_icon_theme_find(theme_name); + if (!theme) + { + theme = efreet_icon_theme_new(); + theme->fake = 1; + theme->name.internal = ecore_string_instance(theme_name); + ecore_hash_set(efreet_icon_themes, (void *)theme->name.internal, theme); + } + + return theme; +} + +/** * @param theme_name: The icon theme to look for * @param icon: The icon to look for * @param size; The icon size to look for @@ -254,50 +327,26 @@ Efreet_Icon_Theme *theme; const char *key_list[] = { icon, "@", size, NULL }; - theme = efreet_icon_theme_find(theme_name); - if (!theme) - { - theme = efreet_icon_theme_new(); - theme->fake = 1; - theme->name.internal = ecore_string_instance(theme_name); - ecore_hash_set(efreet_icon_themes, (void *)theme->name.internal, theme); - } + theme = efreet_icon_find_theme_check(theme_name); efreet_array_cat(cache_key, sizeof(cache_key), key_list); share_key = ecore_string_instance(cache_key); #ifdef SLOPPY_SPEC { - char *tmp, *ext; - - tmp = strdup(icon); - ext = strrchr(tmp, '.'); - if (ext) - { - const char *ext2; - ecore_list_goto_first(efreet_icon_extensions); - while ((ext2 = ecore_list_next(efreet_icon_extensions))) - { - if (!strcmp(ext, ext2)) - { -#ifdef STRICT_SPEC - printf("[Efreet]: Requesting an icon with an extension: %s\n", icon); -#endif - *ext = '\0'; - break; - } - } - } - + char *tmp; + + tmp = efreet_icon_remove_extension(icon); value = efreet_icon_find_helper(theme, share_key, tmp, size); - free(tmp); + FREE(tmp); } #else value = efreet_icon_find_helper(theme, share_key, icon, size); #endif /* we didn't find the icon in the theme or in the inherited directories - * then just look for a non theme icon */ + * then just look for a non theme icon + */ if (!value) value = efreet_icon_fallback_icon(icon); efreet_icon_cache_set(theme, share_key, value); @@ -309,6 +358,80 @@ } /** + * @param theme_name: The icon theme to look for + * @param icon: List of icons to look for + * @param size; The icon size to look for + * @return Returns the Efreet_Icon structure representing first found icon or + * NULL if none of the icons are found + * @brief Retrieves all of the information about the first found icon in + * the list. + * @note This function will search the given theme for all icons before falling + * back. This is useful when searching for mimetype icons. + */ +Efreet_Icon * +efreet_icon_list_find(const char *theme_name, Ecore_List *icons, + const char *size) +{ + Ecore_List *share_keys; + char cache_key[PATH_MAX]; + const char *icon = NULL; + const char *share_key = NULL; + Efreet_Icon *value = NULL; + Efreet_Icon_Theme *theme; + + theme = efreet_icon_find_theme_check(theme_name); + + share_keys = ecore_list_new(); + ecore_list_set_free_cb(share_keys,free); + ecore_list_goto_first(icons); + + while ((icon = ecore_list_next(icons))) + { + snprintf(cache_key, sizeof(cache_key),"[EMAIL PROTECTED]", icon, size); + ecore_list_append(share_keys, strdup(cache_key)); + } +#ifdef SLOPPY_SPEC + { + Ecore_List *tmps = NULL; + + tmps = ecore_list_new(); + ecore_list_set_free_cb(tmps, free); + ecore_list_goto_first(icons); + while ((icon = ecore_list_next(icons))) + ecore_list_append(tmps, efreet_icon_remove_extension(icon)); + + value = efreet_icon_list_find_helper(theme, share_keys, tmps, size); + ecore_list_destroy(tmps); + } +#else + value = efreet_icon_list_find_helper(theme, share_keys, icons, size); +#endif + + /* we didn't find the icons in the theme or in the inherited directories + * then just look for a non theme icon + */ + if(!value) + { + ecore_list_goto_first(icons); + while ((icon = ecore_list_next(icons))) + { + if ((value = efreet_icon_fallback_icon(icon))) + break; + } + } + + ecore_list_goto_first(share_keys); + while ((share_key = ecore_list_next(share_keys))) + efreet_icon_cache_set(theme, ecore_string_instance(share_key), value); + ecore_list_destroy(share_keys); + + if (value == (void *)NO_MATCH_KEY) + value = NULL; + + return value; +} + +/** * @param theme: The icon theme to look for * @param icon: The icon to look for * @param size: The icon size to look for @@ -333,6 +456,53 @@ * @param size: The size to search for * @return Returns the icon matching the given information or NULL if no * icon found + * @brief Scans inheriting themes for the given icon + */ +static Efreet_Icon * +efreet_icon_find_fallback(Efreet_Icon_Theme *theme, const char *cache_key, + const char *icon, const char *size) +{ + char *parent = NULL; + Efreet_Icon *value = NULL; + + if (theme->inherits) + { + ecore_list_goto_first(theme->inherits); + while ((parent = ecore_list_next(theme->inherits))) + { + Efreet_Icon_Theme *parent_theme; + + parent_theme = efreet_icon_theme_find(parent); + if ((!parent_theme) || (parent_theme == theme)) continue; + + value = efreet_icon_find_helper(parent_theme, cache_key, + icon, size); + if (value) break; + } + } + /* if this isn't the hicolor theme, and we have no other fallbacks + * check hicolor */ + else if (strcmp(theme->name.internal, "hicolor")) + { + Efreet_Icon_Theme *parent_theme; + + parent_theme = efreet_icon_theme_find("hicolor"); + if (parent_theme) + value = efreet_icon_find_helper(parent_theme, cache_key, + icon, size); + } + + return value; +} + +/** + * @internal + * @param theme: The theme to search in + * @param cache_key: The cache key to use ([EMAIL PROTECTED] ecore_string) + * @param icon: The icon to search for + * @param size: The size to search for + * @return Returns the icon matching the given information or NULL if no + * icon found * @brief Scans the theme and any inheriting themes for the given icon */ static Efreet_Icon * @@ -341,7 +511,7 @@ const char *size) { Efreet_Icon *value; - static int recurse = 0; + static int recurse = 0; efreet_icon_theme_cache_check(theme); @@ -360,36 +530,108 @@ /* we didin't find the image check the inherited themes */ if (!value) - { - char *parent; + value = efreet_icon_find_fallback(theme, cache_key, icon, size); - if (theme->inherits) - { - ecore_list_goto_first(theme->inherits); - while ((parent = ecore_list_next(theme->inherits))) - { - Efreet_Icon_Theme *parent_theme; + recurse--; + return value; +} - parent_theme = efreet_icon_theme_find(parent); - if ((!parent_theme) || (parent_theme == theme)) continue; +/** + * @internal + * @param theme: The theme to search in + * @param cache_keys: The cache keys to use ([EMAIL PROTECTED] ecore_string) + * @param icons: The icons to search for + * @param size: The size to search for + * @return Returns the icon matching the given information or NULL if no + * icon found + * @brief Scans inheriting themes for the given icons + */ +static Efreet_Icon * +efreet_icon_list_find_fallback(Efreet_Icon_Theme *theme, Ecore_List *cache_keys, + Ecore_List *icons, const char *size) +{ + char *parent = NULL; + Efreet_Icon *value = NULL; - value = efreet_icon_find_helper(parent_theme, cache_key, - icon, size); - if (value) break; - } - } - /* if this isn't the hicolor theme, and we have no other fallbacks - * check hicolor */ - else if (strcmp(theme->name.internal, "hicolor")) + if (theme->inherits) + { + ecore_list_goto_first(theme->inherits); + while ((parent = ecore_list_next(theme->inherits))) { Efreet_Icon_Theme *parent_theme; - parent_theme = efreet_icon_theme_find("hicolor"); - if (parent_theme) - value = efreet_icon_find_helper(parent_theme, cache_key, - icon, size); + parent_theme = efreet_icon_theme_find(parent); + if ((!parent_theme) || (parent_theme == theme)) continue; + + value = efreet_icon_list_find_helper(parent_theme, cache_keys, + icons, size); + if (value) break; } } + + /* if this isn't the hicolor theme, and we have no other fallbacks + * check hicolor + */ + else if (strcmp(theme->name.internal, "hicolor")) + { + Efreet_Icon_Theme *parent_theme; + + parent_theme = efreet_icon_theme_find("hicolor"); + if (parent_theme) + value = efreet_icon_list_find_helper(parent_theme, cache_keys, + icons, size); + } + + return value; +} + +/** + * @internal + * @param theme: The theme to search in + * @param cache_keys: The cache keys to use ([EMAIL PROTECTED] ecore_string) + * @param icons: The icons to search for + * @param size: The size to search for + * @return Returns the icon matching the given information or NULL if no + * icon found + * @brief Scans the theme and any inheriting themes for the given icons + */ +static Efreet_Icon * +efreet_icon_list_find_helper(Efreet_Icon_Theme *theme, Ecore_List *cache_keys, + Ecore_List *icons, + const char *size) +{ + Efreet_Icon *value = NULL; + const char *icon = NULL; + const char *cache_key = NULL; + static int recurse = 0; + + efreet_icon_theme_cache_check(theme); + + /* see if this is in the cache already */ + ecore_list_goto_first(cache_keys); + while ((cache_key = ecore_list_next(cache_keys))) + { + if ((value = efreet_icon_cache_get(theme, cache_key))) + return value; + } + + /* go no further if this theme is fake */ + if (theme->fake || !theme->valid) return NULL; + + /* limit recursion in finding themes and inherited themes to 256 levels */ + if (recurse > 256) return NULL; + recurse++; + + ecore_list_goto_first(icons); + while ((icon = ecore_list_next(icons))) + { + if ((value = efreet_icon_lookup_icon(theme, icon, size))) + break; + } + + /* we didn't find the image check the inherited themes */ + if (!value) + value = efreet_icon_list_find_fallback(theme, cache_keys, icons, size); recurse--; return value; @@ -800,7 +1042,7 @@ /* XXX this is a bit inefficient as I'll end up adding back to the cache * even if I found the item in the cache. Not a big deal at the moment * tho. */ - if (!value) + if (!value) ecore_hash_set(theme->icon_cache, (void *)key, NO_MATCH_KEY); else { =================================================================== RCS file: /cvs/e/e17/libs/efreet/src/lib/efreet_icon.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- efreet_icon.h 15 Apr 2007 17:19:08 -0000 1.3 +++ efreet_icon.h 17 Jul 2007 19:21:20 -0000 1.4 @@ -167,7 +167,9 @@ Efreet_Icon_Theme *efreet_icon_theme_find(const char *theme_name); Efreet_Icon *efreet_icon_find(const char *theme_name, const char *icon, const char *size); - +Efreet_Icon *efreet_icon_list_find(const char *theme_name, + Ecore_List *icons, + const char *size); const char *efreet_icon_path_find(const char *theme, const char *icon, const char *size); =================================================================== RCS file: /cvs/e/e17/libs/efreet/src/lib/efreet_mime.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -3 -r1.20 -r1.21 --- efreet_mime.c 13 Jul 2007 23:23:13 -0000 1.20 +++ efreet_mime.c 17 Jul 2007 19:21:20 -0000 1.21 @@ -109,6 +109,9 @@ if (!efreet_init()) return 0; + if (!efreet_icon_init()) + return 0; + efreet_mime_endianess = efreet_mime_endian_check(); monitors = ecore_hash_new(ecore_str_hash, ecore_str_compare); @@ -133,13 +136,14 @@ IF_FREE_LIST(magics); IF_FREE_HASH(monitors); + efreet_icon_shutdown(); efreet_shutdown(); ecore_file_shutdown(); ecore_shutdown(); } /** - * @param file: The file to check the mime type + * @param file: The file to find the mime type * @return Returns mime type as a string * @brief Retreive the mime type of a file */ @@ -173,6 +177,76 @@ } /** + * @param file: The file to find the mime type icon + * @return Returns mime type icon path as a string + * @brief Retreive the mime type icon for a file + */ +const char * +efreet_mime_type_icon_get(const char *mime, const char *theme, const char *size) +{ + Efreet_Icon *icon = NULL; + Ecore_List *icons = NULL; + const char *env = NULL; + char *p = NULL, *pp = NULL, *ppp = NULL; + char buf[PATH_MAX]; + + if (!mime || !theme || !size) + return NULL; + + icons = ecore_list_new(); + ecore_list_set_free_cb(icons, free); + + /* Standard icon name */ + p = strdup(mime); + pp = p; + while (*pp) + { + if (*pp == '/') + *pp = '-'; + pp++; + } + ecore_list_append(icons, p); + + /* Environment Based icon names */ + if ((env = efreet_desktop_environment_get())) + { + snprintf(buf, sizeof(buf), "%s-mime-%s", env, p); + ecore_list_append(icons, strdup(buf)); + + snprintf(buf, sizeof(buf), "%s-%s", env, p); + ecore_list_append(icons, strdup(buf)); + } + + /* Mime prefixed icon names */ + snprintf(buf, sizeof(buf), "mime-%s", p); + ecore_list_append(icons, strdup(buf)); + + /* Generic icons */ + pp = strdup(p); + while ((ppp = strrchr(pp, '-'))) + { + *ppp = '\0'; + + snprintf(buf, sizeof(buf), "%s-generic", pp); + ecore_list_append(icons, strdup(buf)); + + snprintf(buf, sizeof(buf), "%s", pp); + ecore_list_append(icons, strdup(buf)); + } + FREE(pp); + + /* Search for icons using list */ + icon = efreet_icon_list_find(theme, icons, size); + + ecore_list_destroy(icons); + + if (icon) + return icon->path; + + return NULL; +} + +/** * @param file: The file to check the mime type * @return Returns mime type as a string * @brief Retreive the mime type of a file using magic @@ -535,12 +609,15 @@ return "application/octet-stream"; /* * Check for ASCII control characters in the first 32 bytes. - * New lines and carriage returns are ignored as they are - * quite common in text files. + * Line Feeds, carriage returns, and tabs are ignored as they are + * quite common in text files in the first 32 chars. */ for (i -= 1; i >= 0; --i) { - if ((buf[i] < 0x20) && (buf[i] != '\n') && (buf[i] != '\r')) + if ((buf[i] < 0x20) && + (buf[i] != '\n') && /* Line Feed */ + (buf[i] != '\r') && /* Carriage Return */ + (buf[i] != '\t')) /* Tab */ return "application/octet-stream"; } ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs