Skip to content

Commit

Permalink
Allow to sort files according to Exif-date
Browse files Browse the repository at this point in the history
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...
  • Loading branch information
Juuso Räsänen authored and zas committed Aug 16, 2012
1 parent b73335c commit 92c6523
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 4 deletions.
76 changes: 73 additions & 3 deletions src/filedata.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "trash.h"
#include "histogram.h"

#include "exif.h"

#include <errno.h>

static GHashTable *file_data_pool = NULL;
Expand All @@ -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;

/*
*-----------------------------------------------------------------------------
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;
}

Expand Down
4 changes: 4 additions & 0 deletions src/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ gchar *sort_type_get_text(SortType method)
case SORT_TIME:
return _("Sort by date");
break;
case SORT_EXIFTIME:
return _("Sort by Exif-date");
break;
case SORT_NONE:
return _("Unsorted");
break;
Expand Down Expand Up @@ -188,6 +191,7 @@ GtkWidget *submenu_add_sort(GtkWidget *menu, GCallback func, gpointer data,
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);
Expand Down
4 changes: 3 additions & 1 deletion src/typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ typedef enum {
SORT_SIZE,
SORT_TIME,
SORT_PATH,
SORT_NUMBER
SORT_NUMBER,
SORT_EXIFTIME
} SortType;

typedef enum {
Expand Down Expand Up @@ -521,6 +522,7 @@ struct _FileData {
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;
};
Expand Down

0 comments on commit 92c6523

Please sign in to comment.