changeset 2067:b53cdc8cf7b8

Allow to sort files according to Exif-date I also like the idea about sorting files according to Exif-date. This behaviour seemed to be implemented in the pan-view but not in the main browser view. I created a little patch to "correct" this issue. ;) This satisfies my own needs, although the exif-date reading could be probably somehow optimised(?).. now the GUI becomes unresponsive for few seconds if there are a lot of pictures in the directory...
author Juuso Räsänen <juusora@gmail.com>
date Thu, 23 Dec 2010 00:38:40 +0100
parents 01d2c966209e
children 5c9e1870adaf
files src/filedata.c src/menu.c src/typedefs.h
diffstat 3 files changed, 80 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/filedata.c	Fri Apr 02 20:47:34 2010 +0930
+++ b/src/filedata.c	Thu Dec 23 00:38:40 2010 +0100
@@ -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_disconnect_sidecar_file(FileData *target, FileData *sfd);
 
 
+static SortType filelist_sort_method = SORT_NONE;
+static gboolean filelist_sort_ascend = TRUE;
 
 /*
  *-----------------------------------------------------------------------------
@@ -406,6 +410,63 @@
 	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 @@
  *-----------------------------------------------------------------------------
  */
 
-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 @@
 			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_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 @@
 		}
 	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;
 }
 
--- a/src/menu.c	Fri Apr 02 20:47:34 2010 +0930
+++ b/src/menu.c	Thu Dec 23 00:38:40 2010 +0100
@@ -135,6 +135,9 @@
 		case SORT_TIME:
 			return _("Sort by date");
 			break;
+		case SORT_EXIFTIME:
+			return _("Sort by Exif-date");
+			break;
 		case SORT_NONE:
 			return _("Unsorted");
 			break;
@@ -188,6 +191,7 @@
 	submenu_add_sort_item(submenu, func, SORT_NUMBER, show_current, type);
 #endif
 	submenu_add_sort_item(submenu, func, SORT_TIME, show_current, type);
+	submenu_add_sort_item(submenu, func, SORT_EXIFTIME, show_current, type);
 	submenu_add_sort_item(submenu, func, SORT_SIZE, show_current, type);
 	if (include_path) submenu_add_sort_item(submenu, func, SORT_PATH, show_current, type);
 	if (include_none) submenu_add_sort_item(submenu, func, SORT_NONE, show_current, type);
--- a/src/typedefs.h	Fri Apr 02 20:47:34 2010 +0930
+++ b/src/typedefs.h	Thu Dec 23 00:38:40 2010 +0100
@@ -50,7 +50,8 @@
 	SORT_SIZE,
 	SORT_TIME,
 	SORT_PATH,
-	SORT_NUMBER
+	SORT_NUMBER,
+	SORT_EXIFTIME
 } SortType;
 
 typedef enum {
@@ -521,6 +522,7 @@
 	gint exif_orientation;
 	
 	ExifData *exif;
+	time_t exifdate;
 	GHashTable *modified_xmp; // hash table which contains unwritten xmp metadata in format: key->list of string values
 	GList *cached_metadata;
 };