<guilabel>File date</guilabel>\r
</term>\r
<listitem>\r
- The search will match if the file modification time on disk is equal to, before, after, or between the entered date, depending on the method selected from the drop down menu. The\r
+ The search will match if the file date is equal to, before, after, or between the entered date, depending on the method selected from the drop down menu. The\r
<emphasis>between</emphasis>\r
test is inclusive, for example a file with date of 10/04/2003 will match if the date parameters are between 10/04/2003 and 12/31/2003.\r
<para />\r
</code>\r
button displays a pop up calendar to enter the date.\r
<para />\r
- The\r
- <emphasis role="strong">Exif date</emphasis>\r
- checkbox permits searches to be made on the exif date of images. If an image does not have an exif date, it will default to 01 January 1970.\r
+ One of four date types may be selected. They are described in the\r
+ <link linkend="GuideReferenceFileDates">Reference section</link>\r
+ .\r
+ <note>If an image does not have an exif date, it will default to 01 January 1970.</note>\r
</listitem>\r
</varlistentry>\r
<varlistentry>\r
</varlistentry>\r
<varlistentry>\r
<term>\r
- <guilabel>File Creation Date</guilabel>\r
+ <guilabel>File Date</guilabel>\r
</term>\r
<listitem>\r
- <para>Images are sorted by file creation date.</para>\r
- </listitem>\r
- </varlistentry>\r
- <varlistentry>\r
- <term>\r
- <guilabel>Exif Date</guilabel>\r
- </term>\r
- <listitem>\r
- <para>Images are sorted by file Exif date.</para>\r
+ <para>\r
+ Images are sorted by one of four types of file date. They are described in the\r
+ <link linkend="GuideReferenceFileDates">Reference section</link>\r
+ .\r
+ </para>\r
</listitem>\r
</varlistentry>\r
<varlistentry>\r
if (cia->fd->cdate > cib->fd->cdate) return 1;
return 0;
break;
+ case SORT_EXIFTIME:
+ if (cia->fd->exifdate < cib->fd->exifdate) return -1;
+ if (cia->fd->exifdate > cib->fd->exifdate) return 1;
+ break;
+ case SORT_EXIFTIMEDIGITIZED:
+ if (cia->fd->exifdate_digitized < cib->fd->exifdate_digitized) return -1;
+ if (cia->fd->exifdate_digitized > cib->fd->exifdate_digitized) return 1;
+ break;
+ case SORT_RATING:
+ if (cia->fd->rating < cib->fd->rating) return -1;
+ if (cia->fd->rating > cib->fd->rating) return 1;
+ break;
case SORT_PATH:
return utf8_compare(cia->fd->path, cib->fd->path, options->file_sort.case_sensitive);
break;
return text;
}
+static gchar *exif_build_formatted_DateTimeDigitized(ExifData *exif)
+{
+ gchar *text = exif_get_data_as_text(exif, "Exif.Photo.DateTimeDigitized");
+ gchar *subsec = NULL;
+ gchar buf[128];
+ gchar *tmp;
+ gint buflen;
+ struct tm tm;
+ GError *error = NULL;
+
+ if (text)
+ {
+ subsec = exif_get_data_as_text(exif, "Exif.Photo.SubSecTimeDigitized");
+ }
+ else
+ {
+ text = exif_get_data_as_text(exif, "Exif.Image.DateTime");
+ if (text) subsec = exif_get_data_as_text(exif, "Exif.Photo.SubSecTime");
+ }
+
+ /* Convert the stuff into a tm struct */
+ memset(&tm, 0, sizeof(tm)); /* Uh, strptime could let garbage in tm! */
+ if (text && strptime(text, "%Y:%m:%d %H:%M:%S", &tm))
+ {
+ buflen = strftime(buf, sizeof(buf), "%x %X", &tm);
+ if (buflen > 0)
+ {
+ tmp = g_locale_to_utf8(buf, buflen, NULL, NULL, &error);
+ if (error)
+ {
+ log_printf("Error converting locale strftime to UTF-8: %s\n", error->message);
+ g_error_free(error);
+ }
+ else
+ {
+ g_free(text);
+ text = g_strdup(tmp);
+ }
+ }
+ }
+
+ if (subsec)
+ {
+ tmp = text;
+ text = g_strconcat(tmp, ".", subsec, NULL);
+ g_free(tmp);
+ g_free(subsec);
+ }
+ return text;
+}
+
static gchar *exif_build_formatted_ShutterSpeed(ExifData *exif)
{
ExifRational *r;
ExifFormattedText ExifFormattedList[] = {
EXIF_FORMATTED_TAG(Camera, N_("Camera")),
EXIF_FORMATTED_TAG(DateTime, N_("Date")),
+ EXIF_FORMATTED_TAG(DateTimeDigitized, N_("DateDigitized")),
EXIF_FORMATTED_TAG(ShutterSpeed, N_("Shutter speed")),
EXIF_FORMATTED_TAG(Aperture, N_("Aperture")),
EXIF_FORMATTED_TAG(ExposureBias, N_("Exposure bias")),
}
}
+void read_exif_time_digitized_data(FileData *file)
+{
+ if (file->exifdate > 0)
+ {
+ DEBUG_1("%s set_exif_time_digitized_data: Already exists for %s", get_exec_time(), file->path);
+ return;
+ }
+
+ file->exif = exif_read_fd(file);
+
+ if (file->exif)
+ {
+ gchar *tmp = exif_get_data_as_text(file->exif, "Exif.Photo.DateTimeDigitized");
+ DEBUG_2("%s set_exif_time_digitized_data: reading %p %s", get_exec_time(), file, file->path);
+
+ if (tmp)
+ {
+ struct tm time_str;
+ uint year, month, day, hour, min, sec;
+
+ 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_digitized = mktime(&time_str);
+ g_free(tmp);
+ }
+ }
+}
+
void set_exif_time_data(GList *files)
{
DEBUG_1("%s set_exif_time_data: ...", get_exec_time());
}
}
+void set_exif_time_digitized_data(GList *files)
+{
+ DEBUG_1("%s set_exif_time_digitized_data: ...", get_exec_time());
+
+ while (files)
+ {
+ FileData *file = files->data;
+
+ read_exif_time_digitized_data(file);
+ files = files->next;
+ }
+}
+
void set_rating_data(GList *files)
{
gchar *rating_str;
if (fa->exifdate > fb->exifdate) return 1;
/* fall back to name */
break;
+ case SORT_EXIFTIMEDIGITIZED:
+ if (fa->exifdate_digitized < fb->exifdate_digitized) return -1;
+ if (fa->exifdate_digitized > fb->exifdate_digitized) return 1;
+ /* fall back to name */
+ break;
case SORT_RATING:
if (fa->rating < fb->rating) return -1;
if (fa->rating > fb->rating) return 1;
{
set_exif_time_data(list);
}
+ if (method == SORT_EXIFTIMEDIGITIZED)
+ {
+ set_exif_time_digitized_data(list);
+ }
if (method == SORT_RATING)
{
set_rating_data(list);
gboolean file_data_unregister_real_time_monitor(FileData *fd);
void read_exif_time_data(FileData *file);
+void read_exif_time_digitized_data(FileData *file);
#endif
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
lua_pushnil(L);
return 1;
}
- } // if (strcmp(key, "Exif.Photo.Da...
+ }
+ else if (strcmp(key, "Exif.Photo.DateTimeDigitized") == 0)
+ {
+ memset(&tm, 0, sizeof(tm));
+ if (value && strptime(value, "%Y:%m:%d %H:%M:%S", &tm))
+ {
+ datetime = mktime(&tm);
+ lua_pushnumber(L, datetime);
+ return 1;
+ }
+ else
+ {
+ lua_pushnil(L);
+ return 1;
+ }
+ }
lua_pushstring(L, value);
return 1;
}
return _("Sort by file creation date");
break;
case SORT_EXIFTIME:
- return _("Sort by Exif-date");
+ return _("Sort by Exif date original");
+ break;
+ case SORT_EXIFTIMEDIGITIZED:
+ return _("Sort by Exif date digitized");
break;
case SORT_NONE:
return _("Unsorted");
submenu_add_sort_item(submenu, func, SORT_TIME, show_current, type);
submenu_add_sort_item(submenu, func, SORT_CTIME, show_current, type);
submenu_add_sort_item(submenu, func, SORT_EXIFTIME, show_current, type);
+ submenu_add_sort_item(submenu, func, SORT_EXIFTIMEDIGITIZED, show_current, type);
submenu_add_sort_item(submenu, func, SORT_SIZE, show_current, type);
submenu_add_sort_item(submenu, func, SORT_RATING, show_current, type);
submenu_add_sort_item(submenu, func, SORT_CLASS, show_current, type);
GtkWidget *menu_date;
GtkWidget *date_sel;
GtkWidget *date_sel_end;
+ GtkWidget *date_type;
GtkWidget *check_dimensions;
GtkWidget *menu_dimensions;
gint search_rating;
gint search_rating_end;
gboolean search_comment_match_case;
- gboolean search_date_exif;
MatchType search_type;
tested = TRUE;
match = FALSE;
- if (sd->search_date_exif)
+ if (g_strcmp0(gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(sd->date_type)), _("Changed")) == 0)
+ {
+ file_date = fd->cdate;
+ }
+ else if (g_strcmp0(gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(sd->date_type)), _("Original")) == 0)
{
read_exif_time_data(fd);
file_date = fd->exifdate;
}
+ else if (g_strcmp0(gtk_combo_box_text_get_active_text(
+ GTK_COMBO_BOX_TEXT(sd->date_type)), _("Digitized")) == 0)
+ {
+ read_exif_time_digitized_data(fd);
+ file_date = fd->exifdate_digitized;
+ }
else
{
file_date = fd->date;
_("File date is"), &sd->match_date_enable,
text_search_menu_date, sizeof(text_search_menu_date) / sizeof(MatchList),
G_CALLBACK(menu_choice_date_cb), sd);
+
sd->date_sel = date_selection_new();
date_selection_time_set(sd->date_sel, time(NULL));
gtk_box_pack_start(GTK_BOX(hbox), sd->date_sel, FALSE, FALSE, 0);
date_selection_time_set(sd->date_sel_end, time(NULL));
gtk_box_pack_start(GTK_BOX(hbox2), sd->date_sel_end, FALSE, FALSE, 0);
gtk_widget_show(sd->date_sel_end);
- pref_checkbox_new_int(hbox, _("Exif date"),
- sd->search_date_exif, &sd->search_date_exif);
+
+ sd->date_type = gtk_combo_box_text_new();
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(sd->date_type), _("Modified"));
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(sd->date_type), _("Status Changed"));
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(sd->date_type), _("Original"));
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(sd->date_type), _("Digitized"));
+ gtk_box_pack_start(GTK_BOX(hbox), sd->date_type, FALSE, FALSE, 0);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(sd->date_type), 0);
+ gtk_widget_set_tooltip_text(sd->date_type, "Modified (mtime)\nStatus Changed (ctime)\nOriginal (Exif.Photo.DateTimeOriginal)\nDigitized (Exif.Photo.DateTimeDigitized)");
+ gtk_widget_show(sd->date_type);
/* Search for image dimensions */
hbox = menu_choice(sd->box_search, &sd->check_dimensions, &sd->menu_dimensions,
SORT_PATH,
SORT_NUMBER,
SORT_EXIFTIME,
+ SORT_EXIFTIMEDIGITIZED,
SORT_RATING,
SORT_CLASS
} SortType;
ExifData *exif;
time_t exifdate;
+ time_t exifdate_digitized;
GHashTable *modified_xmp; // hash table which contains unwritten xmp metadata in format: key->list of string values
GList *cached_metadata;
gint rating;
<span class="guilabel">File date</span>
</dt>
<dd>
- The search will match if the file modification time on disk is equal to, before, after, or between the entered date, depending on the method selected from the drop down menu. The
+ The search will match if the file date is equal to, before, after, or between the entered date, depending on the method selected from the drop down menu. The
<span class="emphasis">between</span>
test is inclusive, for example a file with date of 10/04/2003 will match if the date parameters are between 10/04/2003 and 12/31/2003.
<p class="para block"></p>
</span>
button displays a pop up calendar to enter the date.
<p class="para block"></p>
- The
- <span class="emphasis emphasis-bold">Exif date</span>
- checkbox permits searches to be made on the exif date of images. If an image does not have an exif date, it will default to 01 January 1970.
+ One of four date types may be selected. They are described in the
+ <a class="link" href=".html#GuideReferenceFileDates" title="">Reference section</a>
+ .
+ <div class="admonition block note block-indent"><div class="note-inner">If an image does not have an exif date, it will default to 01 January 1970.</div></div>
</dd>
<dt class="term">
<span class="guilabel">Image dimensions</span>
<p class="para block block-first">Images are sorted by file modification date.</p>
</dd>
<dt class="term">
- <span class="guilabel">File Creation Date</span>
+ <span class="guilabel">File Date</span>
</dt>
<dd>
- <p class="para block block-first">Images are sorted by file creation date.</p>
- </dd>
-<dt class="term">
- <span class="guilabel">Exif Date</span>
- </dt>
-<dd>
- <p class="para block block-first">Images are sorted by file Exif date.</p>
+ <p class="para block block-first">
+ Images are sorted by one of four types of file date. They are described in the
+ <a class="link" href=".html#GuideReferenceFileDates" title="">Reference section</a>
+ .
+ </p>
</dd>
<dt class="term">
<span class="guilabel">Size</span>