Check if theme has changed when building cache
authorSebastian Dransfeld <sd@tango.flipp.net>
Mon, 31 Jan 2011 11:44:35 +0000 (11:44 +0000)
committerSebastian Dransfeld <sd@tango.flipp.net>
Mon, 31 Jan 2011 11:44:35 +0000 (11:44 +0000)
SVN revision: 56596

legacy/efreet/ChangeLog
legacy/efreet/src/bin/efreet_icon_cache_create.c
legacy/efreet/src/lib/efreet_cache.c
legacy/efreet/src/lib/efreet_cache_private.h
legacy/efreet/src/lib/efreet_private.h
legacy/efreet/src/tests/efreet_icon_cache_dump.c

index 23aa1af..0c4349b 100644 (file)
@@ -46,3 +46,6 @@
 
        * Create internal struct for theme cache
 
+2011-01-XX  Sebastian Dransfeld
+
+       * Check if theme has changed when building cache
index 75075c0..c44e025 100644 (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);
index 5dbe4ea..55de4df 100644 (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);
     }
index 1add8f8..8db044f 100644 (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;
 
index 9743834..e1b212b 100644 (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
index da6291c..8f22468 100644 (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)