Skip to content

Commit 9f3e64a

Browse files
committed
manage XMP sidecar files
1 parent d41dbce commit 9f3e64a

File tree

5 files changed

+801
-183
lines changed

5 files changed

+801
-183
lines changed

src/common/exif.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5860,6 +5860,7 @@ gboolean dt_exif_xmp_write(const dt_imgid_t imgid,
58605860
fprintf(fout, "%s", xml_header);
58615861
fprintf(fout, "%s", xmpPacket.c_str());
58625862
fclose(fout);
5863+
dt_diratime_action(filename, "update");
58635864
}
58645865
else
58655866
{

src/control/control.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,90 @@ void dt_control_set_mouse_over_id(const dt_imgid_t imgid)
819819
dt_pthread_mutex_unlock(&dc->global_mutex);
820820
}
821821

822+
time_t dt_diratime_action(const char *dir_path, const char *action)
823+
{
824+
time_t timestamp = 0;
825+
gchar *_dir = g_strdup(dir_path);
826+
size_t name_len = strlen(dir_path);
827+
const char *ext = dir_path + name_len - 4;
828+
if (((!g_strcmp0(action, "update") && (!g_strcmp0(ext, ".xmp") || !g_strcmp0(ext, ".XMP")))
829+
|| !g_strcmp0(action, "delete"))
830+
&& name_len > 4)
831+
{
832+
size_t len = strlen(dir_path);
833+
const char *c = dir_path + len;
834+
while((c > dir_path) && ((*c) != G_DIR_SEPARATOR)) c--;
835+
size_t vers_len = c - dir_path + 1;
836+
g_strlcpy(_dir, dir_path, vers_len + 1);
837+
}
838+
839+
GError *error = NULL;
840+
GFile *_g_dir = g_file_new_for_path(_dir);
841+
GFileInfo *info = g_file_query_info(_g_dir,
842+
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
843+
G_FILE_ATTRIBUTE_STANDARD_TYPE,
844+
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL);
845+
const char *dirname = g_file_info_get_attribute_string(info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
846+
847+
const char *dir_mark = g_strconcat(_dir, dirname, ".dt", NULL);
848+
time_t dir_mark_time = 0;
849+
850+
GFile *_g_dir_mark = g_file_new_for_path(dir_mark);
851+
if (!g_strcmp0(action, "create"))
852+
{
853+
if(!g_file_test(dir_mark, G_FILE_TEST_EXISTS))
854+
{
855+
GFileEnumerator *dir_files = g_file_enumerate_children(_g_dir,
856+
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
857+
G_FILE_ATTRIBUTE_TIME_MODIFIED ","
858+
G_FILE_ATTRIBUTE_STANDARD_TYPE,
859+
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
860+
if(dir_files)
861+
{
862+
while((info = g_file_enumerator_next_file(dir_files, NULL, &error)))
863+
{
864+
const char *filename = g_file_info_get_display_name(info);
865+
if(!filename) continue;
866+
const GFileType filetype = g_file_info_get_attribute_uint32(info, G_FILE_ATTRIBUTE_STANDARD_TYPE);
867+
if(filetype == G_FILE_TYPE_REGULAR)
868+
{
869+
name_len = strlen(filename);
870+
ext = filename + name_len - 4;
871+
if ((strcmp(ext, ".xmp") == 0 || strcmp(ext, ".XMP") == 0) && name_len > 4)
872+
{
873+
time_t _timestamp = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
874+
if (_timestamp > dir_mark_time)
875+
dir_mark_time = _timestamp;
876+
}
877+
}
878+
}
879+
}
880+
GFileOutputStream *out = g_file_replace(_g_dir_mark, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &error);
881+
g_object_unref(out);
882+
info = g_file_query_info(_g_dir_mark,
883+
G_FILE_ATTRIBUTE_TIME_MODIFIED,
884+
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
885+
g_file_set_attribute_uint64(_g_dir_mark, G_FILE_ATTRIBUTE_TIME_MODIFIED, dir_mark_time, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,FALSE,&error);
886+
g_object_unref(dir_files);
887+
}
888+
}
889+
else if (!g_strcmp0(action, "update") || !g_strcmp0(action, "delete"))
890+
{
891+
GFileOutputStream *out = g_file_replace(_g_dir_mark, NULL, FALSE,
892+
G_FILE_CREATE_REPLACE_DESTINATION, NULL, &error);
893+
g_object_unref(out);
894+
}
895+
info = g_file_query_info(_g_dir_mark,
896+
G_FILE_ATTRIBUTE_TIME_MODIFIED,
897+
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
898+
timestamp = g_file_info_get_attribute_uint64(info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
899+
g_object_unref(info);
900+
g_object_unref(_g_dir_mark);
901+
g_object_unref(_g_dir);
902+
903+
return timestamp;
904+
}
905+
822906
// clang-format off
823907
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
824908
// vim: shiftwidth=2 expandtab tabstop=2 cindent

src/control/control.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,10 @@ gboolean dt_control_running(void);
256256
dt_imgid_t dt_control_get_mouse_over_id(void);
257257
void dt_control_set_mouse_over_id(const dt_imgid_t value);
258258

259+
/** actions on directory access mark file.
260+
'action' must be one of "create", "update", "delete" */
261+
time_t dt_diratime_action(const char *dir_path, const char *action);
262+
259263
G_END_DECLS
260264

261265
// clang-format off

0 commit comments

Comments
 (0)