Allow to sort files according to Exif-date
[geeqie.git] / src / filedata.c
index 9cc9424..3ec68b2 100644 (file)
@@ -22,6 +22,8 @@
 #include "trash.h"
 #include "histogram.h"
 
+#include "exif.h"
+
 #include <errno.h>
 
 static GHashTable *file_data_pool = NULL;
@@ -32,6 +34,8 @@ static void file_data_check_sidecars(const GList *basename_list);
 static void file_data_disconnect_sidecar_file(FileData *target, FileData *sfd);
 
 
+static SortType filelist_sort_method = SORT_NONE;
+static gboolean filelist_sort_ascend = TRUE;
 
 /*
  *-----------------------------------------------------------------------------
@@ -406,6 +410,63 @@ static FileData *file_data_new_local(const gchar *path, struct stat *st, gboolea
        return ret;
 }
 
+void init_exif_time_data(GList *files) {
+       FileData *file;
+       DEBUG_1("%s init_exif_time_data: ...", get_exec_time());
+       while (files)
+               {
+               file = files->data;
+
+               if (file)
+                       file->exifdate = 0;
+
+               files = files->next;
+               }
+}
+
+void set_exif_time_data(GList *files) {
+       gchar *tmp;
+       uint year, month, day, hour, min, sec;
+       struct tm time_str;
+       FileData *file;
+       DEBUG_1("%s set_exif_time_data: ...", get_exec_time());
+       while (files)
+               {
+               file = files->data;
+
+               if (file->exifdate > 0)
+                       {
+                       files = files->next;
+                       DEBUG_1("%s set_exif_time_data: Already exists for %s", get_exec_time(), file->path);
+                       continue;
+                       }
+
+               DEBUG_1("%s set_exif_time_data: Getting exiftime for %s", get_exec_time(), file->path);
+
+               file->exif = exif_read_fd(file);
+
+               if (file->exif)
+                       {
+                       tmp = exif_get_data_as_text(file->exif, "Exif.Photo.DateTimeOriginal");
+                       if (tmp)
+                               {
+                               sscanf(tmp, "%4d:%2d:%2d %2d:%2d:%2d", &year, &month, &day, &hour, &min, &sec);
+                               time_str.tm_year = year - 1900;
+                               time_str.tm_mon = month - 1;
+                               time_str.tm_mday = day;
+                               time_str.tm_hour = hour;
+                               time_str.tm_min = min;
+                               time_str.tm_sec = sec;
+                               time_str.tm_isdst = 0;
+
+                               file->exifdate = mktime(&time_str);
+                               }
+                       }
+               files = files->next;
+               }
+
+}
+
 FileData *file_data_new_no_grouping(const gchar *path_utf8)
 {
        struct stat st;
@@ -772,9 +833,6 @@ void file_data_disable_grouping_list(GList *fd_list, gboolean disable)
  *-----------------------------------------------------------------------------
  */
 
-static SortType filelist_sort_method = SORT_NONE;
-static gboolean filelist_sort_ascend = TRUE;
-
 
 gint filelist_sort_compare_filedata(FileData *fa, FileData *fb)
 {
@@ -800,6 +858,11 @@ gint filelist_sort_compare_filedata(FileData *fa, FileData *fb)
                        if (fa->date > fb->date) return 1;
                        /* fall back to name */
                        break;
+               case SORT_EXIFTIME:
+                       if (fa->exifdate < fb->exifdate) return -1;
+                       if (fa->exifdate > fb->exifdate) return 1;
+                       /* fall back to name */
+                       break;
 #ifdef HAVE_STRVERSCMP
                case SORT_NUMBER:
                        ret = strverscmp(fa->name, fb->name);
@@ -851,6 +914,10 @@ GList *filelist_insert_sort_full(GList *list, gpointer data, SortType method, gb
 
 GList *filelist_sort(GList *list, SortType method, gboolean ascend)
 {
+       if (method == SORT_EXIFTIME)
+               {
+               set_exif_time_data(list);
+               }
        return filelist_sort_full(list, method, ascend, (GCompareFunc) filelist_sort_file_cb);
 }
 
@@ -1064,6 +1131,9 @@ static gboolean filelist_read_real(const gchar *dir_path, GList **files, GList *
                }
        if (basename_hash) file_data_basename_hash_free(basename_hash);
 
+       // Call a separate function to initialize the exif datestamps for the found files..
+       if (files) init_exif_time_data(*files);
+
        return TRUE;
 }