forked from enlightenment/efl
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.
SVN revision: 30875
This commit is contained in:
parent
be190f1117
commit
0a4d1e3605
|
@ -34,6 +34,9 @@ const char *efreet_mime_magic_type_get(const char *file);
|
|||
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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -11,10 +11,26 @@ static Ecore_Hash *efreet_icon_themes = NULL;
|
|||
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);
|
||||
|
@ -237,6 +253,63 @@ efreet_icon_theme_find(const char *theme_name)
|
|||
return theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
@ -254,50 +327,26 @@ efreet_icon_find(const char *theme_name, const char *icon, const char *size)
|
|||
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);
|
||||
|
@ -308,6 +357,80 @@ efreet_icon_find(const char *theme_name, const char *icon, const char *size)
|
|||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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),"%s@%s", 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
|
||||
|
@ -325,6 +448,53 @@ efreet_icon_path_find(const char *theme, const char *icon, const char *size)
|
|||
return (ico ? ico->path : NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param theme: The theme to search in
|
||||
* @param cache_key: The cache key to use (icon\@sizexsize 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 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
|
||||
|
@ -341,7 +511,7 @@ efreet_icon_find_helper(Efreet_Icon_Theme *theme, const char *cache_key,
|
|||
const char *size)
|
||||
{
|
||||
Efreet_Icon *value;
|
||||
static int recurse = 0;
|
||||
static int recurse = 0;
|
||||
|
||||
efreet_icon_theme_cache_check(theme);
|
||||
|
||||
|
@ -360,36 +530,108 @@ efreet_icon_find_helper(Efreet_Icon_Theme *theme, const char *cache_key,
|
|||
|
||||
/* we didin't find the image check the inherited themes */
|
||||
if (!value)
|
||||
value = efreet_icon_find_fallback(theme, cache_key, icon, size);
|
||||
|
||||
recurse--;
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @param theme: The theme to search in
|
||||
* @param cache_keys: The cache keys to use (icon\@sizexsize 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;
|
||||
|
||||
if (theme->inherits)
|
||||
{
|
||||
char *parent;
|
||||
|
||||
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"))
|
||||
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 (icon\@sizexsize 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 @@ efreet_icon_cache_set(Efreet_Icon_Theme *theme, const char *key, void *value)
|
|||
/* 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
|
||||
{
|
||||
|
|
|
@ -167,7 +167,9 @@ Ecore_List *efreet_icon_theme_list_get(void);
|
|||
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);
|
||||
|
||||
|
|
|
@ -109,6 +109,9 @@ efreet_mime_init(void)
|
|||
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 @@ efreet_mime_shutdown(void)
|
|||
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
|
||||
*/
|
||||
|
@ -172,6 +176,76 @@ efreet_mime_type_get(const char *file)
|
|||
return efreet_mime_fallback_check(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
@ -535,12 +609,15 @@ efreet_mime_fallback_check(const char *file)
|
|||
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";
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue