Check if theme has changed when building cache

SVN revision: 56596
This commit is contained in:
Sebastian Dransfeld 2011-01-31 11:44:35 +00:00
parent 4ec17d71fc
commit 8309f40d0f
6 changed files with 145 additions and 55 deletions

View File

@ -46,3 +46,6 @@
* Create internal struct for theme cache
2011-01-XX Sebastian Dransfeld
* Check if theme has changed when building cache

View File

@ -302,6 +302,35 @@ cache_scan(Efreet_Icon_Theme *theme, Eina_Hash *themes, Eina_Hash *icons, Eina_H
return EINA_TRUE;
}
static Eina_Bool
check_changed(Efreet_Cache_Icon_Theme *theme)
{
Eina_List *l;
const char *name;
if (!theme) return EINA_FALSE;
if (theme->changed) return EINA_TRUE;
if (theme->theme.inherits)
{
EINA_LIST_FOREACH(theme->theme.inherits, l, name)
{
Efreet_Cache_Icon_Theme *inherit;
inherit = eina_hash_find(icon_themes, name);
if (!inherit) fprintf(stderr, "Theme `%s` not found for `%s`.\n",
name, theme->theme.name.internal);
if (check_changed(inherit)) return EINA_TRUE;
}
}
else if (strcmp(theme->theme.name.internal, "hicolor"))
{
theme = eina_hash_find(icon_themes, "hicolor");
if (check_changed(theme)) return EINA_TRUE;
}
return EINA_FALSE;
}
static Efreet_Icon_Theme_Directory *
icon_theme_directory_new(Efreet_Ini *ini, const char *name)
{
@ -314,6 +343,7 @@ icon_theme_directory_new(Efreet_Ini *ini, const char *name)
dir = NEW(Efreet_Icon_Theme_Directory, 1);
if (!dir) return NULL;
dir->name = eina_stringshare_add(name);
eina_array_push(strs, dir->name);
efreet_ini_section_set(ini, name);
@ -369,33 +399,64 @@ icon_theme_directory_new(Efreet_Ini *ini, const char *name)
return dir;
}
static void
static Eina_Bool
icon_theme_index_read(Efreet_Cache_Icon_Theme *theme, const char *path)
{
/* TODO: return error value */
Efreet_Ini *ini;
Efreet_Icon_Theme_Directory *dir;
const char *tmp;
struct stat st;
char rp[PATH_MAX];
if (!theme || !path) return;
if (!theme || !path) return EINA_FALSE;
if (!realpath(path, rp)) return EINA_FALSE;
if (stat(rp, &st) < 0) return EINA_FALSE;
if (theme->path && !strcmp(theme->path, rp) && theme->last_cache_check >= (long long) st.st_mtime)
{
/* no change */
theme->valid = 1;
return EINA_TRUE;
}
if (!theme->path || strcmp(theme->path, rp))
{
theme->path = eina_stringshare_add(rp);
eina_array_push(strs, theme->path);
}
if ((long long) st.st_mtime > theme->last_cache_check)
theme->last_cache_check = (long long) st.st_mtime;
theme->changed = 1;
ini = efreet_ini_new(path);
if (!ini) return;
if (!ini) return EINA_FALSE;
if (!ini->data)
{
efreet_ini_free(ini);
return;
return EINA_FALSE;
}
efreet_ini_section_set(ini, "Icon Theme");
tmp = efreet_ini_localestring_get(ini, "Name");
if (tmp) theme->theme.name.name = eina_stringshare_add(tmp);
if (tmp)
{
theme->theme.name.name = eina_stringshare_add(tmp);
eina_array_push(strs, theme->theme.name.name);
}
tmp = efreet_ini_localestring_get(ini, "Comment");
if (tmp) theme->theme.comment = eina_stringshare_add(tmp);
if (tmp)
{
theme->theme.comment = eina_stringshare_add(tmp);
eina_array_push(strs, theme->theme.comment);
}
tmp = efreet_ini_string_get(ini, "Example");
if (tmp) theme->theme.example_icon = eina_stringshare_add(tmp);
if (tmp)
{
theme->theme.example_icon = eina_stringshare_add(tmp);
eina_array_push(strs, theme->theme.example_icon);
}
theme->hidden = efreet_ini_boolean_get(ini, "Hidden");
@ -406,6 +467,7 @@ icon_theme_index_read(Efreet_Cache_Icon_Theme *theme, const char *path)
if (tmp)
{
char *t, *s, *p;
const char *i;
size_t len;
len = strlen(tmp) + 1;
@ -418,11 +480,15 @@ icon_theme_index_read(Efreet_Cache_Icon_Theme *theme, const char *path)
{
*p = '\0';
theme->theme.inherits = eina_list_append(theme->theme.inherits, eina_stringshare_add(s));
i = eina_stringshare_add(s);
theme->theme.inherits = eina_list_append(theme->theme.inherits, i);
eina_array_push(strs, i);
s = ++p;
p = strchr(s, ',');
}
theme->theme.inherits = eina_list_append(theme->theme.inherits, eina_stringshare_add(s));
i = eina_stringshare_add(s);
theme->theme.inherits = eina_list_append(theme->theme.inherits, i);
eina_array_push(strs, i);
}
/* make sure this one is done last as setting the directory will change
@ -455,6 +521,8 @@ icon_theme_index_read(Efreet_Cache_Icon_Theme *theme, const char *path)
error:
efreet_ini_free(ini);
return EINA_TRUE;
}
static Eina_Bool
@ -472,6 +540,9 @@ cache_theme_scan(const char *dir)
const char *name;
const char *path;
char buf[PATH_MAX];
struct stat st;
if (stat(entry->path, &st) < 0) continue;
if ((entry->type != EINA_FILE_DIR) &&
(entry->type != EINA_FILE_LNK))
@ -484,17 +555,26 @@ cache_theme_scan(const char *dir)
{
theme = NEW(Efreet_Cache_Icon_Theme, 1);
theme->theme.name.internal = eina_stringshare_add(name);
eina_array_push(strs, theme->theme.name.internal);
eina_hash_direct_add(icon_themes,
(void *)theme->theme.name.internal, theme);
theme->changed = 1;
}
if ((long long) st.st_mtime > theme->last_cache_check)
{
theme->last_cache_check = (long long) st.st_mtime;
theme->changed = 1;
}
path = eina_stringshare_add(entry->path);
if (!eina_list_data_find(theme->theme.paths, path))
/* TODO: We need to handle change in order of included paths */
if (!eina_list_search_unsorted(theme->theme.paths, EINA_COMPARE_CB(strcmp), entry->path))
{
path = eina_stringshare_add(entry->path);
theme->theme.paths = eina_list_append(theme->theme.paths, path);
else
eina_stringshare_del(path);
eina_array_push(strs, path);
theme->changed = 1;
}
theme->last_cache_check = ecore_time_unix_get();
/* we're already valid so no reason to check for an index.theme file */
if (theme->valid) continue;
@ -502,7 +582,10 @@ cache_theme_scan(const char *dir)
memcpy(buf, entry->path, entry->path_length);
memcpy(buf + entry->path_length, "/index.theme", sizeof("/index.theme"));
if (ecore_file_exists(buf))
icon_theme_index_read(theme, buf);
{
if (!icon_theme_index_read(theme, buf))
theme->valid = 0;
}
}
eina_iterator_free(it);
return EINA_TRUE;
@ -536,17 +619,12 @@ static void
icon_theme_free(Efreet_Cache_Icon_Theme *theme)
{
void *data;
Efreet_Icon_Theme_Directory *dir;
EINA_LIST_FREE(theme->theme.paths, data)
eina_stringshare_del(data);
EINA_LIST_FREE(theme->theme.inherits, data)
eina_stringshare_del(data);
EINA_LIST_FREE(theme->theme.directories, dir)
{
eina_stringshare_del(dir->name);
free(dir);
}
eina_list_free(theme->theme.paths);
eina_list_free(theme->theme.inherits);
EINA_LIST_FREE(theme->theme.directories, data)
free(data);
if (theme->dirs) efreet_hash_free(theme->dirs, free);
free(theme);
}
@ -577,7 +655,8 @@ main(int argc, char **argv)
Eina_Bool changed = EINA_FALSE;
int lockfd = -1;
int tmpfd = -1;
int i;
char **keys;
int num, i;
for (i = 1; i < argc; i++)
{
@ -668,6 +747,18 @@ main(int argc, char **argv)
theme_version->major = EFREET_ICON_CACHE_MAJOR;
theme_version->minor = EFREET_ICON_CACHE_MINOR;
keys = eet_list(theme_ef, "*", &num);
if (keys)
{
for (i = 0; i < num; i++)
{
if (!strncmp(keys[i], "efreet", 6)) continue;
theme = eet_data_read(theme_ef, theme_edd, keys[i]);
if (theme) eina_hash_direct_add(icon_themes, theme->theme.name.internal, theme);
}
free(keys);
}
/* scan themes */
cache_theme_scan(efreet_icon_deprecated_user_dir_get());
cache_theme_scan(efreet_icon_user_dir_get());
@ -690,7 +781,7 @@ main(int argc, char **argv)
cache_theme_scan("/usr/share/pixmaps");
/* scan icons */
edd = efreet_icons_edd(EINA_TRUE);
edd = efreet_icons_edd();
it = eina_hash_iterator_data_new(icon_themes);
EINA_ITERATOR_FOREACH(it, theme)
{
@ -718,10 +809,16 @@ main(int argc, char **argv)
if (!cache->icons)
cache->icons = eina_hash_string_superfast_new(NULL);
if (!cache->dirs)
cache->dirs = eina_hash_string_superfast_new(NULL);
changed = theme->changed = check_changed(theme);
if (theme->changed && theme->dirs)
{
efreet_hash_free(theme->dirs, free);
theme->dirs = NULL;
}
if (!theme->dirs)
theme->dirs = eina_hash_string_superfast_new(NULL);
if (cache_scan(&(theme->theme), themes, cache->icons, cache->dirs, &changed))
if (cache_scan(&(theme->theme), themes, cache->icons, theme->dirs, &changed))
{
fprintf(stderr, "generated: '%s' %i (%i)\n",
theme->theme.name.internal,
@ -734,7 +831,6 @@ main(int argc, char **argv)
eina_hash_free(themes);
efreet_hash_free(cache->icons, EINA_FREE_CB(efreet_cache_icon_free));
efreet_hash_free(cache->dirs, free);
free(cache);
/* TODO: Only write if changed */
@ -742,7 +838,7 @@ main(int argc, char **argv)
}
eina_iterator_free(it);
edd = efreet_icons_fallback_edd(EINA_TRUE);
edd = efreet_icons_fallback_edd();
/* read fallback icons from the eet file */
cache = eet_data_read(icon_ef, edd, EFREET_CACHE_ICON_FALLBACK);
@ -759,11 +855,14 @@ main(int argc, char **argv)
if (!cache->icons)
cache->icons = eina_hash_string_superfast_new(NULL);
if (!cache->dirs)
cache->dirs = eina_hash_string_superfast_new(NULL);
theme = eet_data_read(theme_ef, theme_edd, EFREET_CACHE_ICON_FALLBACK);
if (!theme)
theme = NEW(Efreet_Cache_Icon_Theme, 1);
if (!theme->dirs)
theme->dirs = eina_hash_string_superfast_new(NULL);
/* Save fallback in the right part */
if (cache_fallback_scan(cache->icons, cache->dirs, &changed))
if (cache_fallback_scan(cache->icons, theme->dirs, &changed))
{
fprintf(stderr, "generated: fallback %i (%i)\n", changed, eina_hash_population(cache->icons));
if (changed)
@ -771,7 +870,6 @@ main(int argc, char **argv)
}
efreet_hash_free(cache->icons, EINA_FREE_CB(efreet_cache_icon_fallback_free));
efreet_hash_free(cache->dirs, free);
free(cache);
eina_hash_free(icon_themes);

View File

@ -384,7 +384,6 @@ _efreet_cache_free(Efreet_Cache_Icons *c)
if (!c) return NULL;
if (c->icons) efreet_hash_free(c->icons, EINA_FREE_CB(efreet_cache_icon_free));
if (c->dirs) efreet_hash_free(c->dirs, free);
free(c);
return NULL;
@ -396,7 +395,6 @@ _efreet_cache_fallback_free(Efreet_Cache_Icons *c)
if (!c) return NULL;
if (c->icons) efreet_hash_free(c->icons, EINA_FREE_CB(efreet_cache_icon_fallback_free));
if (c->dirs) efreet_hash_free(c->dirs, free);
free(c);
return NULL;
@ -423,7 +421,7 @@ efreet_icon_directory_edd(void)
* Needs EAPI because of helper binaries
*/
EAPI Eet_Data_Descriptor *
efreet_icons_edd(Eina_Bool include_dirs)
efreet_icons_edd(void)
{
Eet_Data_Descriptor_Class eddc;
@ -464,10 +462,6 @@ efreet_icons_edd(Eina_Bool include_dirs)
EET_DATA_DESCRIPTOR_ADD_HASH(icons_edd, Efreet_Cache_Icons,
"icons", icons, icon_edd);
if (include_dirs)
EET_DATA_DESCRIPTOR_ADD_HASH(icons_edd, Efreet_Cache_Icons,
"dirs", dirs, efreet_icon_directory_edd());
return icons_edd;
}
@ -539,7 +533,7 @@ efreet_icon_theme_edd(Eina_Bool cache)
* Needs EAPI because of helper binaries
*/
EAPI Eet_Data_Descriptor *
efreet_icons_fallback_edd(Eina_Bool include_dirs)
efreet_icons_fallback_edd(void)
{
Eet_Data_Descriptor_Class eddc;
@ -559,10 +553,6 @@ efreet_icons_fallback_edd(Eina_Bool include_dirs)
EET_DATA_DESCRIPTOR_ADD_HASH(fallback_edd, Efreet_Cache_Icons,
"icons", icons, icon_fallback_edd);
if (include_dirs)
EET_DATA_DESCRIPTOR_ADD_HASH(fallback_edd, Efreet_Cache_Icons,
"dirs", dirs, efreet_icon_directory_edd());
return fallback_edd;
}
@ -651,7 +641,7 @@ efreet_cache_icon_find(Efreet_Icon_Theme *theme, const char *icon)
if (!theme_name)
{
INFO("loading theme %s", theme->name.internal);
theme_cache = eet_data_read(icon_cache, efreet_icons_edd(EINA_FALSE), theme->name.internal);
theme_cache = eet_data_read(icon_cache, efreet_icons_edd(), theme->name.internal);
if (theme_cache && !theme_cache->icons)
theme_cache->icons = eina_hash_string_superfast_new(NULL);
if (theme_cache)
@ -671,7 +661,7 @@ efreet_cache_icon_fallback_find(const char *icon)
if (!fallback_cache)
{
INFO("loading fallback cache");
fallback_cache = eet_data_read(icon_cache, efreet_icons_fallback_edd(EINA_FALSE), EFREET_CACHE_ICON_FALLBACK);
fallback_cache = eet_data_read(icon_cache, efreet_icons_fallback_edd(), EFREET_CACHE_ICON_FALLBACK);
if (fallback_cache && !fallback_cache->icons)
fallback_cache->icons = eina_hash_string_superfast_new(NULL);
}

View File

@ -13,8 +13,8 @@ EAPI Eet_Data_Descriptor *efreet_hash_array_string_edd(void);
EAPI Eet_Data_Descriptor *efreet_hash_string_edd(void);
EAPI Eet_Data_Descriptor *efreet_array_string_edd(void);
EAPI Eet_Data_Descriptor *efreet_icon_theme_edd(Eina_Bool cache);
EAPI Eet_Data_Descriptor *efreet_icons_edd(Eina_Bool include_dirs);
EAPI Eet_Data_Descriptor *efreet_icons_fallback_edd(Eina_Bool include_dirs);
EAPI Eet_Data_Descriptor *efreet_icons_edd(void);
EAPI Eet_Data_Descriptor *efreet_icons_fallback_edd(void);
typedef struct Efreet_Cache_Icon_Theme Efreet_Cache_Icon_Theme;

View File

@ -133,7 +133,6 @@ typedef struct _Efreet_Cache_Fallback_Icon Efreet_Cache_Fallback_Icon;
struct _Efreet_Cache_Icons
{
Eina_Hash *icons;
Eina_Hash *dirs;
};
struct _Efreet_Cache_Directory

View File

@ -82,7 +82,7 @@ main(int argc, char **argv)
theme_ef = eet_open(efreet_icon_theme_cache_file(), EET_FILE_MODE_READ);
if (!theme_ef) return -1;
edd = efreet_icons_edd(EINA_FALSE);
edd = efreet_icons_edd();
if (!edd) return -1;
if (argc > 1)