Skip to content

Commit

Permalink
Merge branch 'datetime-encap' of https://github.com/phweyland/darktable
Browse files Browse the repository at this point in the history
  • Loading branch information
TurboGit committed Feb 11, 2022
2 parents b1339f6 + 40a7bb0 commit d9e582d
Show file tree
Hide file tree
Showing 31 changed files with 648 additions and 382 deletions.
9 changes: 8 additions & 1 deletion data/darktableconfig.xml.in
Expand Up @@ -928,7 +928,7 @@
<type>string</type>
<default/>
<shortdescription>override today's date</shortdescription>
<longdescription>enter a valid date/time (YYYY-MM-DD[Thh:mm:ss] format) if you want to override the current date/time used when expanding variables:\n$(YEAR), $(MONTH), $(DAY), $(HOUR), $(MINUTE), $(SECONDS).\nlet the field empty otherwise</longdescription>
<longdescription>type a date in the form: YYYY:MM:DD[ hh:mm:ss[.sss]] if you want to override the current date/time used when expanding variables:\n$(YEAR), $(MONTH), $(DAY), $(HOUR), $(MINUTE), $(SECONDS), $(MSEC).\nlet the field empty otherwise</longdescription>
</dtconfig>
<dtconfig ui="yes">
<name>ui_last/import_keep_open</name>
Expand Down Expand Up @@ -2084,6 +2084,13 @@
<shortdescription>show scrollbars for central view</shortdescription>
<longdescription>defines whether scrollbars should be displayed</longdescription>
</dtconfig>
<dtconfig prefs="lighttable" section="general">
<name>lighttable/ui/milliseconds</name>
<type>bool</type>
<default>false</default>
<shortdescription>show image time with milliseconds</shortdescription>
<longdescription>defines whether time should be displayed with milliseconds</longdescription>
</dtconfig>
<dtconfig>
<name>darkroom/ui/rawoverexposed/mode</name>
<type>int</type>
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Expand Up @@ -28,6 +28,7 @@ FILE(GLOB SOURCE_FILES
"common/cpuid.c"
"common/darktable.c"
"common/database.c"
"common/datetime.c"
"common/dbus.c"
"common/dtpthread.c"
"common/eaw.c"
Expand Down
16 changes: 8 additions & 8 deletions src/common/camera_control.c
Expand Up @@ -119,9 +119,9 @@ static gpointer _camera_get_job(const dt_camctl_t *c, const dt_camera_t *camera)
static void _camera_process_job(const dt_camctl_t *c, const dt_camera_t *camera, gpointer job);

/** Dispatch functions for listener interfaces */
static const char *_dispatch_request_image_path(const dt_camctl_t *c, time_t *exif_time, const dt_camera_t *camera);
static const char *_dispatch_request_image_path(const dt_camctl_t *c, char *exif_time, const dt_camera_t *camera);
static const char *_dispatch_request_image_filename(const dt_camctl_t *c, const char *filename,
time_t *exif_time, const dt_camera_t *camera);
const char *exif_time, const dt_camera_t *camera);
static void _dispatch_camera_image_downloaded(const dt_camctl_t *c, const dt_camera_t *camera, const char *filename);
static void _dispatch_camera_connected(const dt_camctl_t *c, const dt_camera_t *camera);
static void _dispatch_camera_disconnected(const dt_camctl_t *c, const dt_camera_t *camera);
Expand Down Expand Up @@ -1111,7 +1111,7 @@ void dt_camctl_import(const dt_camctl_t *c, const dt_camera_t *cam, GList *image
int res = GP_OK;
char *data = NULL;
gsize size = 0;
time_t exif_time;
char exif_time[DT_DATETIME_LENGTH];

gp_file_new(&camfile);
if((res = gp_camera_file_get(cam->gpcam, folder, filename, GP_FILE_TYPE_NORMAL, camfile, NULL)) < GP_OK)
Expand Down Expand Up @@ -1143,10 +1143,10 @@ void dt_camctl_import(const dt_camctl_t *c, const dt_camera_t *cam, GList *image
}
else
{
const gboolean have_exif_time = dt_exif_get_datetime_taken((uint8_t *)data, size, &exif_time);
dt_exif_get_datetime_taken((uint8_t *)data, size, exif_time);

const char *output_path = _dispatch_request_image_path(c, have_exif_time ? &exif_time : NULL, cam);
const char *fname = _dispatch_request_image_filename(c, filename, have_exif_time ? &exif_time : NULL, cam);
const char *output_path = _dispatch_request_image_path(c, exif_time, cam);
const char *fname = _dispatch_request_image_filename(c, filename, exif_time[0] ? exif_time : NULL, cam);
if(!fname)
{
gp_file_free(camfile);
Expand Down Expand Up @@ -1910,7 +1910,7 @@ static void _camera_configuration_update(const dt_camctl_t *c, const dt_camera_t
}

static const char *_dispatch_request_image_filename(const dt_camctl_t *c, const char *filename,
time_t *exif_time, const dt_camera_t *camera)
const char *exif_time, const dt_camera_t *camera)
{
dt_camctl_t *camctl = (dt_camctl_t *)c;

Expand All @@ -1929,7 +1929,7 @@ static const char *_dispatch_request_image_filename(const dt_camctl_t *c, const
return path;
}

static const char *_dispatch_request_image_path(const dt_camctl_t *c, time_t *exif_time, const dt_camera_t *camera)
static const char *_dispatch_request_image_path(const dt_camctl_t *c, char *exif_time, const dt_camera_t *camera)
{
dt_camctl_t *camctl = (dt_camctl_t *)c;
const char *path = NULL;
Expand Down
4 changes: 2 additions & 2 deletions src/common/camera_control.h
Expand Up @@ -202,11 +202,11 @@ typedef struct dt_camctl_listener_t

/** Invoked before images are fetched from camera and when tethered capture fetching an image. \note That
* only one listener should implement this at time... */
const char *(*request_image_path)(const dt_camera_t *camera, time_t *exif_time, void *data);
const char *(*request_image_path)(const dt_camera_t *camera, char *exif_time, void *data);

/** Invoked before images are fetched from camera and when tethered capture fetching an image. \note That
* only one listener should implement this at time... */
const char *(*request_image_filename)(const dt_camera_t *camera, const char *filename, time_t *exif_time,
const char *(*request_image_filename)(const dt_camera_t *camera, const char *filename, const char *exif_time,
void *data);

/** Invoked when a image is downloaded while in tethered mode or by import */
Expand Down
83 changes: 21 additions & 62 deletions src/common/collection.c
Expand Up @@ -23,6 +23,7 @@
#include "common/metadata.h"
#include "common/utility.h"
#include "common/map_locations.h"
#include "common/datetime.h"
#include "control/conf.h"
#include "control/control.h"

Expand Down Expand Up @@ -179,6 +180,8 @@ void dt_collection_memory_update()
g_free(ins_query);
}

#define DATETIME "(CASE WHEN LENGTH(datetime_taken) = 19 THEN datetime_taken || '.000' ELSE datetime_taken END) AS datetime_taken"

static void _dt_collection_set_selq_pre_sort(const dt_collection_t *collection, char **selq_pre)
{
const uint32_t tagid = collection->tagid;
Expand All @@ -187,12 +190,12 @@ static void _dt_collection_set_selq_pre_sort(const dt_collection_t *collection,

*selq_pre = dt_util_dstrcat(*selq_pre,
"SELECT DISTINCT mi.id FROM (SELECT"
" id, group_id, film_id, filename, datetime_taken, "
" id, group_id, film_id, filename, %s, "
" flags, version, %s position, aspect_ratio,"
" maker, model, lens, aperture, exposure, focal_length,"
" iso, import_timestamp, change_timestamp,"
" export_timestamp, print_timestamp"
" FROM main.images AS mi %s%s WHERE ",
" FROM main.images AS mi %s%s WHERE ", DATETIME,
tagid ? "CASE WHEN ti.position IS NULL THEN 0 ELSE ti.position END AS" : "",
tagid ? " LEFT JOIN main.tagged_images AS ti"
" ON ti.imgid = mi.id AND ti.tagid = " : "",
Expand Down Expand Up @@ -409,12 +412,12 @@ int dt_collection_update(const dt_collection_t *collection)
snprintf(tag, sizeof(tag), "%d", tagid);
selq_pre = dt_util_dstrcat(selq_pre,
"SELECT DISTINCT mi.id FROM (SELECT"
" id, group_id, film_id, filename, datetime_taken, "
" id, group_id, film_id, filename, %s, "
" flags, version, %s position, aspect_ratio,"
" maker, model, lens, aperture, exposure, focal_length,"
" iso, import_timestamp, change_timestamp,"
" export_timestamp, print_timestamp"
" FROM main.images AS mi %s%s ) AS mi ",
" FROM main.images AS mi %s%s ) AS mi ", DATETIME,
tagid ? "CASE WHEN ti.position IS NULL THEN 0 ELSE ti.position END AS" : "",
tagid ? " LEFT JOIN main.tagged_images AS ti"
" ON ti.imgid = mi.id AND ti.tagid = " : "",
Expand All @@ -427,12 +430,12 @@ int dt_collection_update(const dt_collection_t *collection)
snprintf(tag, sizeof(tag), "%d", tagid);
selq_pre = dt_util_dstrcat(selq_pre,
"SELECT DISTINCT mi.id FROM (SELECT"
" id, group_id, film_id, filename, datetime_taken, "
" id, group_id, film_id, filename, %s, "
" flags, version, %s position, aspect_ratio,"
" maker, model, lens, aperture, exposure, focal_length,"
" iso, import_timestamp, change_timestamp,"
" export_timestamp, print_timestamp"
" FROM main.images AS mi %s%s ) AS mi WHERE ",
" FROM main.images AS mi %s%s ) AS mi WHERE ", DATETIME,
tagid ? "CASE WHEN ti.position IS NULL THEN 0 ELSE ti.position END AS" : "",
tagid ? " LEFT JOIN main.tagged_images AS ti"
" ON ti.imgid = mi.id AND ti.tagid = " : "",
Expand Down Expand Up @@ -480,6 +483,7 @@ int dt_collection_update(const dt_collection_t *collection)

return result;
}
#undef DATETIME

void dt_collection_reset(const dt_collection_t *collection)
{
Expand Down Expand Up @@ -1185,67 +1189,22 @@ void dt_collection_split_operator_number(const gchar *input, char **number1, cha

static char *_dt_collection_compute_datetime(const char *operator, const char *input)
{
const int len = strlen(input);
if(len < 4) return NULL;

struct tm tm1 = { 0 };
if(strlen(input) < 4) return NULL;

// we initialise all the values of tm, depending of the operator
// we allow unreal values like "2014:02:31" as it's just text comparison at the end
char bound[DT_DATETIME_LENGTH];
gboolean res;
if(strcmp(operator, ">") == 0 || strcmp(operator, "<=") == 0)
{
// we set all values to their maximum
tm1.tm_mon = 11;
tm1.tm_mday = 31;
tm1.tm_hour = 23;
tm1.tm_min = 59;
tm1.tm_sec = 59;
}
if(strcmp(operator, "<") == 0 || strcmp(operator, ">=") == 0)
{
// we set all values to their minimum
tm1.tm_mon = 0;
tm1.tm_mday = 1;
tm1.tm_hour = 0;
tm1.tm_min = 0;
tm1.tm_sec = 0;
}

// we read the input date, depending of his length
if(len < 7)
{
if(!strptime(input, "%Y", &tm1)) return NULL;
}
else if(len < 10)
{
if(!strptime(input, "%Y:%m", &tm1)) return NULL;
}
else if(len < 13)
{
if(!strptime(input, "%Y:%m:%d", &tm1)) return NULL;
}
else if(len < 16)
{
if(!strptime(input, "%Y:%m:%d %H", &tm1)) return NULL;
}
else if(len < 19)
{
if(!strptime(input, "%Y:%m:%d %H:%M", &tm1)) return NULL;
}
res = dt_datetime_entry_to_exif_upper_bound(bound, sizeof(bound), input);
else
{
if(!strptime(input, "%Y:%m:%d %H:%M:%S", &tm1)) return NULL;
}

// we return the created date
char *ret = (char *)g_malloc0_n(20, sizeof(char));
strftime(ret, 20, "%Y:%m:%d %H:%M:%S", &tm1);
return ret;
res = dt_datetime_entry_to_exif(bound, sizeof(bound), input);
if(res)
return g_strdup(bound);
else return NULL;
}
/* splits an input string into a date-time part and an optional operator part.
operator can be any of "=", "<", ">", "<=", ">=" and "<>".
range notation [x;y] can also be used
datetime values should follow the pattern YYYY:mm:dd HH:MM:SS
datetime values should follow the pattern YYYY:MM:DD hh:mm:ss.sss
but only year part is mandatory
datetime and operator are returned as pointers to null terminated strings in g_mallocated
Expand All @@ -1260,7 +1219,7 @@ void dt_collection_split_operator_datetime(const gchar *input, char **number1, c

// we test the range expression first
// 2 elements : date-time1 and date-time2
regex = g_regex_new("^\\s*\\[\\s*(\\d{4}[:\\d\\s]*)\\s*;\\s*(\\d{4}[:\\d\\s]*)\\s*\\]\\s*$", 0, 0, NULL);
regex = g_regex_new("^\\s*\\[\\s*(\\d{4}[:.\\d\\s]*)\\s*;\\s*(\\d{4}[:.\\d\\s]*)\\s*\\]\\s*$", 0, 0, NULL);
g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
int match_count = g_match_info_get_match_count(match_info);

Expand All @@ -1285,7 +1244,7 @@ void dt_collection_split_operator_datetime(const gchar *input, char **number1, c

// and we test the classic comparison operators
// 2 elements : operator and date-time
regex = g_regex_new("^\\s*(=|<|>|<=|>=|<>)?\\s*(\\d{4}[:\\d\\s]*)?\\s*%?\\s*$", 0, 0, NULL);
regex = g_regex_new("^\\s*(=|<|>|<=|>=|<>)?\\s*(\\d{4}[:.\\d\\s]*)?\\s*%?\\s*$", 0, 0, NULL);
g_regex_match_full(regex, input, -1, 0, 0, &match_info, NULL);
match_count = g_match_info_get_match_count(match_info);

Expand Down
15 changes: 3 additions & 12 deletions src/common/darktable.c
Expand Up @@ -982,6 +982,9 @@ int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load
// init darktable tags table
dt_set_darktable_tags();

// init utc timezone
darktable.utc_tz = g_time_zone_new_utc();

// Initialize the signal system
darktable.signals = dt_control_signal_init();

Expand Down Expand Up @@ -1356,18 +1359,6 @@ void dt_print(dt_debug_thread_t thread, const char *msg, ...)
}
}

void dt_gettime_t(char *datetime, size_t datetime_len, time_t t)
{
struct tm tt;
(void)localtime_r(&t, &tt);
strftime(datetime, datetime_len, "%Y:%m:%d %H:%M:%S", &tt);
}

void dt_gettime(char *datetime, size_t datetime_len)
{
dt_gettime_t(datetime, datetime_len, time(NULL));
}

void *dt_alloc_align(size_t alignment, size_t size)
{
const size_t aligned_size = dt_round_size(size, alignment);
Expand Down
4 changes: 1 addition & 3 deletions src/common/darktable.h
Expand Up @@ -47,7 +47,6 @@
#include "common/dtpthread.h"
#include "common/dttypes.h"
#include "common/utility.h"
#include <time.h>
#ifdef _WIN32
#include "win/getrusage.h"
#else
Expand Down Expand Up @@ -333,6 +332,7 @@ typedef struct darktable_t
GList *themes;
int32_t unmuted_signal_dbg_acts;
gboolean unmuted_signal_dbg[DT_SIGNAL_COUNT];
GTimeZone *utc_tz;
} darktable_t;

typedef struct
Expand All @@ -346,8 +346,6 @@ extern darktable_t darktable;
int dt_init(int argc, char *argv[], const gboolean init_gui, const gboolean load_data, lua_State *L);
void dt_cleanup();
void dt_print(dt_debug_thread_t thread, const char *msg, ...) __attribute__((format(printf, 2, 3)));
void dt_gettime_t(char *datetime, size_t datetime_len, time_t t);
void dt_gettime(char *datetime, size_t datetime_len);
int dt_worker_threads();
void *dt_alloc_align(size_t alignment, size_t size);
static inline void* dt_calloc_align(size_t alignment, size_t size)
Expand Down

0 comments on commit d9e582d

Please sign in to comment.