From 04bb6f2326f58139c22d3bb8de7e639c8efb40ba Mon Sep 17 00:00:00 2001 From: Vladimir Nadvornik Date: Tue, 4 Oct 2011 22:09:55 +0200 Subject: [PATCH] rename file_data_new_simple to file_data_new_group, filedata.c cleanup --- src/bar_sort.c | 10 +- src/collect-io.c | 4 +- src/filedata.c | 692 ++++++++++++++++++++++--------------------- src/filedata.h | 2 +- src/layout.c | 2 +- src/main.c | 2 +- src/metadata.c | 2 +- src/pan-timeline.c | 2 +- src/pan-view.c | 2 +- src/remote.c | 8 +- src/search.c | 2 +- src/thumb_standard.c | 2 +- src/utilops.c | 4 +- src/view_file_list.c | 2 +- 14 files changed, 382 insertions(+), 354 deletions(-) diff --git a/src/bar_sort.c b/src/bar_sort.c index 5ca17ca1..5e284d60 100644 --- a/src/bar_sort.c +++ b/src/bar_sort.c @@ -205,18 +205,18 @@ static void bar_sort_undo_folder(SortData *sd, GtkWidget *button) GList *list; gchar *src_dir; - list = g_list_append(NULL, file_data_new_simple(sd->undo_dest)); + list = g_list_append(NULL, file_data_new_group(sd->undo_dest)); src_dir = remove_level_from_path(sd->undo_src); file_util_move_simple(list, src_dir, sd->lw->window); g_free(src_dir); } break; case BAR_SORT_COPY: - file_util_delete(file_data_new_simple(sd->undo_dest), NULL, button); + file_util_delete(file_data_new_group(sd->undo_dest), NULL, button); break; default: /* undo external command */ - file_util_delete(file_data_new_simple(sd->undo_dest), NULL, button); + file_util_delete(file_data_new_group(sd->undo_dest), NULL, button); break; } @@ -224,7 +224,7 @@ static void bar_sort_undo_folder(SortData *sd, GtkWidget *button) if (isfile(sd->undo_src)) { - layout_image_set_fd(sd->lw, file_data_new_simple(sd->undo_src)); + layout_image_set_fd(sd->lw, file_data_new_group(sd->undo_src)); } bar_sort_undo_set(sd, NULL, NULL, NULL); @@ -241,7 +241,7 @@ static void bar_sort_undo_collection(SortData *sd) source = work->data; work = work->next; - collect_manager_remove(file_data_new_simple(source), sd->undo_dest); + collect_manager_remove(file_data_new_group(source), sd->undo_dest); } bar_sort_undo_set(sd, NULL, NULL, NULL); diff --git a/src/collect-io.c b/src/collect-io.c index 3f0b09c8..a2f5ba3c 100644 --- a/src/collect-io.c +++ b/src/collect-io.c @@ -160,7 +160,7 @@ static gboolean collection_load_private(CollectionData *cd, const gchar *path, C if (!flush) changed |= collect_manager_process_action(entry, &buf); - valid = (buf[0] == G_DIR_SEPARATOR && collection_add_check(cd, file_data_new_simple(buf), FALSE, TRUE)); + valid = (buf[0] == G_DIR_SEPARATOR && collection_add_check(cd, file_data_new_group(buf), FALSE, TRUE)); if (!valid) DEBUG_1("collection invalid file: %s", buf); total++; @@ -190,7 +190,7 @@ static gboolean collection_load_private(CollectionData *cd, const gchar *path, C gchar *buf = NULL; while (collect_manager_process_action(entry, &buf)) { - collection_add_check(cd, file_data_new_simple(buf), FALSE, TRUE); + collection_add_check(cd, file_data_new_group(buf), FALSE, TRUE); changed = TRUE; g_free(buf); buf = NULL; diff --git a/src/filedata.c b/src/filedata.c index 76815877..b7f260de 100644 --- a/src/filedata.c +++ b/src/filedata.c @@ -28,7 +28,9 @@ static GHashTable *file_data_pool = NULL; static GHashTable *file_data_planned_change_hash = NULL; static gint sidecar_file_priority(const gchar *extension); -static FileData *file_data_new_local(const gchar *path, struct stat *st, gboolean disable_sidecars); +static void file_data_check_sidecars(const GList *basename_list); +static FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd); + /* @@ -133,15 +135,10 @@ const gchar *text_from_time(time_t t) /* *----------------------------------------------------------------------------- - * file info struct + * changed files detection and notification *----------------------------------------------------------------------------- */ -static FileData *file_data_merge_sidecar_files(FileData *target, FileData *source); -static void file_data_check_sidecars(const GList *basename_list); -FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd); - - void file_data_increment_version(FileData *fd) { fd->version++; @@ -153,76 +150,99 @@ void file_data_increment_version(FileData *fd) } } -static gint file_data_sort_by_ext(gconstpointer a, gconstpointer b) +static gboolean file_data_check_changed_single_file(FileData *fd, struct stat *st) { - const FileData *fda = a; - const FileData *fdb = b; - - if (fda->sidecar_priority < fdb->sidecar_priority) return -1; - if (fda->sidecar_priority > fdb->sidecar_priority) return 1; - - return strcmp(fdb->extension, fda->extension); -} - -static GHashTable *file_data_basename_hash_new(void) -{ - return g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + if (fd->size != st->st_size || + fd->date != st->st_mtime) + { + fd->size = st->st_size; + fd->date = st->st_mtime; + fd->mode = st->st_mode; + if (fd->thumb_pixbuf) g_object_unref(fd->thumb_pixbuf); + fd->thumb_pixbuf = NULL; + file_data_increment_version(fd); + file_data_send_notification(fd, NOTIFY_REREAD); + return TRUE; + } + return FALSE; } -static GList * file_data_basename_hash_insert(GHashTable *basename_hash, FileData *fd) +static gboolean file_data_check_changed_files_recursive(FileData *fd, struct stat *st) { - GList *list; - gchar *basename = g_strndup(fd->path, fd->extension - fd->path); - - list = g_hash_table_lookup(basename_hash, basename); + gboolean ret = FALSE; + GList *work; - if (!g_list_find(list, fd)) - { - list = g_list_insert_sorted(list, file_data_ref(fd), file_data_sort_by_ext); - g_hash_table_insert(basename_hash, basename, list); - } - else + ret = file_data_check_changed_single_file(fd, st); + + work = fd->sidecar_files; + while (work) { - g_free(basename); + FileData *sfd = work->data; + struct stat st; + work = work->next; + + if (!stat_utf8(sfd->path, &st)) + { + fd->size = 0; + fd->date = 0; + file_data_disconnect_sidecar_file(fd, sfd); + ret = TRUE; + continue; + } + + ret |= file_data_check_changed_files_recursive(sfd, &st); } - return list; + return ret; } -#if 0 -static void file_data_basename_hash_remove(GHashTable *basename_hash, FileData *fd) + +gboolean file_data_check_changed_files(FileData *fd) { - GList *list; - gchar *basename = g_strndup(fd->path, fd->extension - fd->path); - - list = g_hash_table_lookup(basename_hash, basename); - - if (!g_list_find(list, fd)) return; - - list = g_list_remove(list, fd); - file_data_unref(fd); + gboolean ret = FALSE; + struct stat st; - if (list) + if (fd->parent) fd = fd->parent; + + if (!stat_utf8(fd->path, &st)) { - g_hash_table_insert(basename_hash, basename, list); + GList *sidecars; + GList *work; + FileData *sfd = NULL; + + /* parent is missing, we have to rebuild whole group */ + ret = TRUE; + fd->size = 0; + fd->date = 0; + + /* file_data_disconnect_sidecar_file might delete the file, + we have to keep the reference to prevent this */ + sidecars = filelist_copy(fd->sidecar_files); + work = sidecars; + while (work) + { + sfd = work->data; + work = work->next; + + file_data_disconnect_sidecar_file(fd, sfd); + } + file_data_check_sidecars(sidecars); /* this will group the sidecars back together */ + /* now we can release the sidecars */ + filelist_free(sidecars); + file_data_send_notification(fd, NOTIFY_REREAD); } - else + else { - g_hash_table_remove(basename_hash, basename); - g_free(basename); + ret |= file_data_check_changed_files_recursive(fd, &st); } -} -#endif -static void file_data_basename_hash_remove_list(gpointer key, gpointer value, gpointer data) -{ - filelist_free((GList *)value); + return ret; } -static void file_data_basename_hash_free(GHashTable *basename_hash) -{ - g_hash_table_foreach(basename_hash, file_data_basename_hash_remove_list, NULL); - g_hash_table_destroy(basename_hash); -} +/* + *----------------------------------------------------------------------------- + * file name, extension, sorting, ... + *----------------------------------------------------------------------------- + */ static void file_data_set_collate_keys(FileData *fd) { @@ -304,93 +324,11 @@ static void file_data_set_path(FileData *fd, const gchar *path) file_data_set_collate_keys(fd); } -static gboolean file_data_check_changed(FileData *fd, struct stat *st) -{ - if (fd->size != st->st_size || - fd->date != st->st_mtime) - { - fd->size = st->st_size; - fd->date = st->st_mtime; - fd->mode = st->st_mode; - if (fd->thumb_pixbuf) g_object_unref(fd->thumb_pixbuf); - fd->thumb_pixbuf = NULL; - file_data_increment_version(fd); - file_data_send_notification(fd, NOTIFY_REREAD); - return TRUE; - } - return FALSE; -} - -static gboolean file_data_check_changed_files_recursive(FileData *fd, struct stat *st) -{ - gboolean ret = FALSE; - GList *work; - - ret = file_data_check_changed(fd, st); - - work = fd->sidecar_files; - while (work) - { - FileData *sfd = work->data; - struct stat st; - work = work->next; - - if (!stat_utf8(sfd->path, &st)) - { - fd->size = 0; - fd->date = 0; - file_data_disconnect_sidecar_file(fd, sfd); - ret = TRUE; - continue; - } - - ret |= file_data_check_changed_files_recursive(sfd, &st); - } - return ret; -} - - -gboolean file_data_check_changed_files(FileData *fd) -{ - gboolean ret = FALSE; - struct stat st; - - if (fd->parent) fd = fd->parent; - - if (!stat_utf8(fd->path, &st)) - { - GList *sidecars; - GList *work; - FileData *sfd = NULL; - - /* parent is missing, we have to rebuild whole group */ - ret = TRUE; - fd->size = 0; - fd->date = 0; - - /* file_data_disconnect_sidecar_file might delete the file, - we have to keep the reference to prevent this */ - sidecars = filelist_copy(fd->sidecar_files); - work = sidecars; - while (work) - { - sfd = work->data; - work = work->next; - - file_data_disconnect_sidecar_file(fd, sfd); - } - file_data_check_sidecars(sidecars); /* this will group the sidecars back together */ - /* now we can release the sidecars */ - filelist_free(sidecars); - file_data_send_notification(fd, NOTIFY_REREAD); - } - else - { - ret |= file_data_check_changed_files_recursive(fd, &st); - } - - return ret; -} +/* + *----------------------------------------------------------------------------- + * create or reuse Filedata + *----------------------------------------------------------------------------- + */ static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean disable_sidecars) { @@ -427,7 +365,7 @@ static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean if (disable_sidecars) file_data_disable_grouping(fd, TRUE); - changed = file_data_check_changed(fd, st); + changed = file_data_check_changed_single_file(fd, st); DEBUG_2("file_data_pool hit: '%s' %s", fd->path, changed ? "(changed)" : ""); @@ -449,41 +387,6 @@ static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean return fd; } - -static void file_data_check_sidecars(const GList *basename_list) -{ - GList *work; - FileData *parent_fd; - if (!basename_list) return; - /* process the group list - the first one is the parent file, others are sidecars */ - parent_fd = basename_list->data; - work = basename_list->next; - while (work) - { - FileData *sfd = work->data; - work = work->next; - - file_data_merge_sidecar_files(parent_fd, sfd); - } - - /* there may be some sidecars that are already deleted - disconnect them */ - work = parent_fd->sidecar_files; - while (work) - { - FileData *sfd = work->data; - work = work->next; - - if (!g_list_find((GList *)basename_list, sfd)) - { - printf("removing unknown %s: %s \n", parent_fd->path, sfd->path); - file_data_disconnect_sidecar_file(parent_fd, sfd); - file_data_send_notification(sfd, NOTIFY_REREAD); - file_data_send_notification(parent_fd, NOTIFY_REREAD); - } - } -} - - static FileData *file_data_new_local(const gchar *path, struct stat *st, gboolean disable_sidecars) { gchar *path_utf8 = path_to_utf8(path); @@ -493,36 +396,41 @@ static FileData *file_data_new_local(const gchar *path, struct stat *st, gboolea return ret; } -static FileData *file_data_add_sidecar_file(FileData *target, FileData *sfd) +FileData *file_data_new_no_grouping(const gchar *path_utf8) { - sfd->parent = target; - if (!g_list_find(target->sidecar_files, sfd)) - target->sidecar_files = g_list_insert_sorted(target->sidecar_files, sfd, file_data_sort_by_ext); - file_data_increment_version(sfd); /* increments both sfd and target */ - return target; -} + struct stat st; + if (!stat_utf8(path_utf8, &st)) + { + st.st_size = 0; + st.st_mtime = 0; + } -static FileData *file_data_merge_sidecar_files(FileData *target, FileData *source) + return file_data_new(path_utf8, &st, TRUE); +} + +FileData *file_data_new_dir(const gchar *path_utf8) { - GList *work; - - file_data_add_sidecar_file(target, source); + struct stat st; - work = source->sidecar_files; - while (work) + if (!stat_utf8(path_utf8, &st)) { - FileData *sfd = work->data; - file_data_add_sidecar_file(target, sfd); - work = work->next; + st.st_size = 0; + st.st_mtime = 0; } - - g_list_free(source->sidecar_files); - source->sidecar_files = NULL; - - return target; + else + /* dir or non-existing yet */ + g_assert(S_ISDIR(st.st_mode)); + + return file_data_new(path_utf8, &st, TRUE); } +/* + *----------------------------------------------------------------------------- + * reference counting + *----------------------------------------------------------------------------- + */ + #ifdef DEBUG_FILEDATA FileData *file_data_ref_debug(const gchar *file, gint line, FileData *fd) #else @@ -611,15 +519,118 @@ void file_data_unref(FileData *fd) file_data_free(sfd); work = work->next; } - - g_list_free(parent->sidecar_files); - parent->sidecar_files = NULL; - - file_data_free(parent); + + g_list_free(parent->sidecar_files); + parent->sidecar_files = NULL; + + file_data_free(parent); + } +} + + + +/* + *----------------------------------------------------------------------------- + * sidecar file info struct + *----------------------------------------------------------------------------- + */ + +static gint file_data_sort_by_ext(gconstpointer a, gconstpointer b) +{ + const FileData *fda = a; + const FileData *fdb = b; + + if (fda->sidecar_priority < fdb->sidecar_priority) return -1; + if (fda->sidecar_priority > fdb->sidecar_priority) return 1; + + return strcmp(fdb->extension, fda->extension); +} + + +static gint sidecar_file_priority(const gchar *extension) +{ + gint i = 1; + GList *work; + + if (extension == NULL) + return 0; + + work = sidecar_ext_get_list(); + + while (work) { + gchar *ext = work->data; + + work = work->next; + if (g_ascii_strcasecmp(extension, ext) == 0) return i; + i++; + } + return 0; +} + +static FileData *file_data_add_sidecar_file(FileData *target, FileData *sfd) +{ + sfd->parent = target; + if (!g_list_find(target->sidecar_files, sfd)) + target->sidecar_files = g_list_insert_sorted(target->sidecar_files, sfd, file_data_sort_by_ext); + file_data_increment_version(sfd); /* increments both sfd and target */ + return target; +} + + +static FileData *file_data_merge_sidecar_files(FileData *target, FileData *source) +{ + GList *work; + + file_data_add_sidecar_file(target, source); + + work = source->sidecar_files; + while (work) + { + FileData *sfd = work->data; + file_data_add_sidecar_file(target, sfd); + work = work->next; + } + + g_list_free(source->sidecar_files); + source->sidecar_files = NULL; + + return target; +} + +static void file_data_check_sidecars(const GList *basename_list) +{ + GList *work; + FileData *parent_fd; + if (!basename_list) return; + /* process the group list - the first one is the parent file, others are sidecars */ + parent_fd = basename_list->data; + work = basename_list->next; + while (work) + { + FileData *sfd = work->data; + work = work->next; + + file_data_merge_sidecar_files(parent_fd, sfd); + } + + /* there may be some sidecars that are already deleted - disconnect them */ + work = parent_fd->sidecar_files; + while (work) + { + FileData *sfd = work->data; + work = work->next; + + if (!g_list_find((GList *)basename_list, sfd)) + { + printf("removing unknown %s: %s \n", parent_fd->path, sfd->path); + file_data_disconnect_sidecar_file(parent_fd, sfd); + file_data_send_notification(sfd, NOTIFY_REREAD); + file_data_send_notification(parent_fd, NOTIFY_REREAD); + } } } -FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd) +static FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd) { sfd->parent = target; g_assert(g_list_find(target->sidecar_files, sfd)); @@ -696,104 +707,10 @@ void file_data_disable_grouping_list(GList *fd_list, gboolean disable) } -/* compare name without extension */ -gint file_data_compare_name_without_ext(FileData *fd1, FileData *fd2) -{ - size_t len1 = fd1->extension - fd1->name; - size_t len2 = fd2->extension - fd2->name; - - if (len1 < len2) return -1; - if (len1 > len2) return 1; - - return strncmp(fd1->name, fd2->name, len1); /* FIXME: utf8 */ -} - -void file_data_change_info_free(FileDataChangeInfo *fdci, FileData *fd) -{ - if (!fdci && fd) fdci = fd->change; - - if (!fdci) return; - - g_free(fdci->source); - g_free(fdci->dest); - - g_free(fdci); - - if (fd) fd->change = NULL; -} - -static gboolean file_data_can_write_directly(FileData *fd) -{ - return filter_name_is_writable(fd->extension); -} - -static gboolean file_data_can_write_sidecar(FileData *fd) -{ - return filter_name_allow_sidecar(fd->extension) && !filter_name_is_writable(fd->extension); -} - -gchar *file_data_get_sidecar_path(FileData *fd, gboolean existing_only) -{ - gchar *sidecar_path = NULL; - GList *work; - - if (!file_data_can_write_sidecar(fd)) return NULL; - - work = fd->parent ? fd->parent->sidecar_files : fd->sidecar_files; - while (work) - { - FileData *sfd = work->data; - work = work->next; - if (g_ascii_strcasecmp(sfd->extension, ".xmp") == 0) - { - sidecar_path = g_strdup(sfd->path); - break; - } - } - - if (!existing_only && !sidecar_path) - { - gchar *base = g_strndup(fd->path, fd->extension - fd->path); - sidecar_path = g_strconcat(base, ".xmp", NULL); - g_free(base); - } - - return sidecar_path; -} - - -/* - *----------------------------------------------------------------------------- - * sidecar file info struct - *----------------------------------------------------------------------------- - */ - - - -static gint sidecar_file_priority(const gchar *extension) -{ - gint i = 1; - GList *work; - - if (extension == NULL) - return 0; - - work = sidecar_ext_get_list(); - - while (work) { - gchar *ext = work->data; - - work = work->next; - if (g_ascii_strcasecmp(extension, ext) == 0) return i; - i++; - } - return 0; -} - /* *----------------------------------------------------------------------------- - * load file list + * filelist sorting *----------------------------------------------------------------------------- */ @@ -884,6 +801,78 @@ GList *filelist_insert_sort(GList *list, FileData *fd, SortType method, gboolean return filelist_insert_sort_full(list, fd, method, ascend, (GCompareFunc) filelist_sort_file_cb); } +/* + *----------------------------------------------------------------------------- + * basename hash - grouping of sidecars in filelist + *----------------------------------------------------------------------------- + */ + + +static GHashTable *file_data_basename_hash_new(void) +{ + return g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); +} + +static GList * file_data_basename_hash_insert(GHashTable *basename_hash, FileData *fd) +{ + GList *list; + gchar *basename = g_strndup(fd->path, fd->extension - fd->path); + + list = g_hash_table_lookup(basename_hash, basename); + + if (!g_list_find(list, fd)) + { + list = g_list_insert_sorted(list, file_data_ref(fd), file_data_sort_by_ext); + g_hash_table_insert(basename_hash, basename, list); + } + else + { + g_free(basename); + } + return list; +} + +#if 0 +static void file_data_basename_hash_remove(GHashTable *basename_hash, FileData *fd) +{ + GList *list; + gchar *basename = g_strndup(fd->path, fd->extension - fd->path); + + list = g_hash_table_lookup(basename_hash, basename); + + if (!g_list_find(list, fd)) return; + + list = g_list_remove(list, fd); + file_data_unref(fd); + + if (list) + { + g_hash_table_insert(basename_hash, basename, list); + } + else + { + g_hash_table_remove(basename_hash, basename); + g_free(basename); + } +} +#endif + +static void file_data_basename_hash_remove_list(gpointer key, gpointer value, gpointer data) +{ + filelist_free((GList *)value); +} + +static void file_data_basename_hash_free(GHashTable *basename_hash) +{ + g_hash_table_foreach(basename_hash, file_data_basename_hash_remove_list, NULL); + g_hash_table_destroy(basename_hash); +} + +/* + *----------------------------------------------------------------------------- + * handling sidecars in filelist + *----------------------------------------------------------------------------- + */ static GList *filelist_filter_out_sidecars(GList *flist) { @@ -919,6 +908,12 @@ static gboolean is_hidden_file(const gchar *name) return TRUE; } +/* + *----------------------------------------------------------------------------- + * the main filelist function + *----------------------------------------------------------------------------- + */ + static gboolean filelist_read_real(const gchar *dir_path, GList **files, GList **dirs, gboolean follow_symlinks) { DIR *dp; @@ -1024,7 +1019,7 @@ gboolean filelist_read_lstat(FileData *dir_fd, GList **files, GList **dirs) return filelist_read_real(dir_fd->path, files, dirs, FALSE); } -FileData *file_data_new_simple(const gchar *path_utf8) +FileData *file_data_new_group(const gchar *path_utf8) { gchar *dir; struct stat st; @@ -1053,32 +1048,6 @@ FileData *file_data_new_simple(const gchar *path_utf8) return fd; } -FileData *file_data_new_no_grouping(const gchar *path_utf8) -{ - struct stat st; - - if (!stat_utf8(path_utf8, &st)) - { - st.st_size = 0; - st.st_mtime = 0; - } - - return file_data_new(path_utf8, &st, TRUE); -} - -FileData *file_data_new_dir(const gchar *path_utf8) -{ - struct stat st; - - if (!stat_utf8(path_utf8, &st)) - { - st.st_size = 0; - st.st_mtime = 0; - } - - g_assert(S_ISDIR(st.st_mode)); - return file_data_new(path_utf8, &st, TRUE); -} void filelist_free(GList *list) { @@ -1127,7 +1096,7 @@ GList *filelist_from_path_list(GList *list) path = work->data; work = work->next; - new_list = g_list_prepend(new_list, file_data_new_simple(path)); + new_list = g_list_prepend(new_list, file_data_new_group(path)); } return g_list_reverse(new_list); @@ -1242,6 +1211,65 @@ GList *filelist_recursive(FileData *dir_fd) return list; } +/* + *----------------------------------------------------------------------------- + * file modification support + *----------------------------------------------------------------------------- + */ + + +void file_data_change_info_free(FileDataChangeInfo *fdci, FileData *fd) +{ + if (!fdci && fd) fdci = fd->change; + + if (!fdci) return; + + g_free(fdci->source); + g_free(fdci->dest); + + g_free(fdci); + + if (fd) fd->change = NULL; +} + +static gboolean file_data_can_write_directly(FileData *fd) +{ + return filter_name_is_writable(fd->extension); +} + +static gboolean file_data_can_write_sidecar(FileData *fd) +{ + return filter_name_allow_sidecar(fd->extension) && !filter_name_is_writable(fd->extension); +} + +gchar *file_data_get_sidecar_path(FileData *fd, gboolean existing_only) +{ + gchar *sidecar_path = NULL; + GList *work; + + if (!file_data_can_write_sidecar(fd)) return NULL; + + work = fd->parent ? fd->parent->sidecar_files : fd->sidecar_files; + while (work) + { + FileData *sfd = work->data; + work = work->next; + if (g_ascii_strcasecmp(sfd->extension, ".xmp") == 0) + { + sidecar_path = g_strdup(sfd->path); + break; + } + } + + if (!existing_only && !sidecar_path) + { + gchar *base = g_strndup(fd->path, fd->extension - fd->path); + sidecar_path = g_strconcat(base, ".xmp", NULL); + g_free(base); + } + + return sidecar_path; +} /* * marks and orientation diff --git a/src/filedata.h b/src/filedata.h index 26129a73..8e5e8678 100644 --- a/src/filedata.h +++ b/src/filedata.h @@ -23,7 +23,7 @@ gchar *text_from_size_abrev(gint64 size); const gchar *text_from_time(time_t t); /* scan for sidecar files - expensive */ -FileData *file_data_new_simple(const gchar *path_utf8); +FileData *file_data_new_group(const gchar *path_utf8); /* should be used on helper files which can't have sidecars */ FileData *file_data_new_no_grouping(const gchar *path_utf8); diff --git a/src/layout.c b/src/layout.c index 45cc1e1e..64d514ff 100644 --- a/src/layout.c +++ b/src/layout.c @@ -851,7 +851,7 @@ gboolean layout_set_path(LayoutWindow *lw, const gchar *path) if (!path) return FALSE; - fd = file_data_new_simple(path); + fd = file_data_new_group(path); ret = layout_set_fd(lw, fd); file_data_unref(fd); return ret; diff --git a/src/main.c b/src/main.c index cde2f4a4..a60cb91a 100644 --- a/src/main.c +++ b/src/main.c @@ -125,7 +125,7 @@ static void parse_command_line_add_file(const gchar *file_path, gchar **path, gc { if (!*path) *path = remove_level_from_path(path_parsed); if (!*file) *file = g_strdup(path_parsed); - *list = g_list_prepend(*list, file_data_new_simple(path_parsed)); + *list = g_list_prepend(*list, file_data_new_group(path_parsed)); } } diff --git a/src/metadata.c b/src/metadata.c index 33a2a522..f2659274 100644 --- a/src/metadata.c +++ b/src/metadata.c @@ -318,7 +318,7 @@ gboolean metadata_write_perform(FileData *fd) store the metadata in the cache) FIXME: this does not catch new sidecars created by independent external programs */ - file_data_unref(file_data_new_simple(fd->change->dest)); + file_data_unref(file_data_new_group(fd->change->dest)); if (success) metadata_legacy_delete(fd, fd->change->dest); return success; diff --git a/src/pan-timeline.c b/src/pan-timeline.c index ea942aab..6435d374 100644 --- a/src/pan-timeline.c +++ b/src/pan-timeline.c @@ -91,7 +91,7 @@ void pan_timeline_compute(PanWindow *pw, FileData *dir_fd, gint *width, gint *he g_free(buf); y += pi->height; - pi_month = pan_item_box_new(pw, file_data_new_simple(fd->path), + pi_month = pan_item_box_new(pw, file_data_ref(fd), x, y, 0, 0, PAN_BOX_OUTLINE_THICKNESS, PAN_BOX_COLOR, PAN_BOX_ALPHA, diff --git a/src/pan-view.c b/src/pan-view.c index f3d16c88..9d6679ad 100644 --- a/src/pan-view.c +++ b/src/pan-view.c @@ -1604,7 +1604,7 @@ static void pan_info_update(PanWindow *pw, PanItem *pi) PAN_POPUP_BORDER_COLOR, PAN_POPUP_ALPHA); pan_item_set_key(pbox, "info"); - p = pan_item_image_new(pw, file_data_new_simple(pi->fd->path), + p = pan_item_image_new(pw, file_data_new_group(pi->fd->path), pbox->x + PREF_PAD_BORDER, pbox->y + PREF_PAD_BORDER, iw, ih); pan_item_set_key(p, "info"); pan_item_size_by_item(pbox, p, PREF_PAD_BORDER); diff --git a/src/remote.c b/src/remote.c index 50a6d353..f94ef07c 100644 --- a/src/remote.c +++ b/src/remote.c @@ -532,7 +532,7 @@ static void gr_config_load(const gchar *text, GIOChannel *channel, gpointer data static void gr_get_sidecars(const gchar *text, GIOChannel *channel, gpointer data) { gchar *filename = expand_tilde(text); - FileData *fd = file_data_new_simple(filename); + FileData *fd = file_data_new_group(filename); GList *work; if (fd->parent) fd = fd->parent; @@ -555,7 +555,7 @@ static void gr_get_sidecars(const gchar *text, GIOChannel *channel, gpointer dat static void gr_get_destination(const gchar *text, GIOChannel *channel, gpointer data) { gchar *filename = expand_tilde(text); - FileData *fd = file_data_new_simple(filename); + FileData *fd = file_data_new_group(filename); if (fd->change && fd->change->dest) { @@ -569,7 +569,7 @@ static void gr_file_view(const gchar *text, GIOChannel *channel, gpointer data) { gchar *filename = expand_tilde(text); - view_window_new(file_data_new_simple(filename)); + view_window_new(file_data_new_group(filename)); g_free(filename); } @@ -607,7 +607,7 @@ static void gr_list_add(const gchar *text, GIOChannel *channel, gpointer data) new = (!collection_get_first(remote_data->command_collection)); } - if (collection_add(remote_data->command_collection, file_data_new_simple(text), FALSE) && new) + if (collection_add(remote_data->command_collection, file_data_new_group(text), FALSE) && new) { layout_image_set_collection(NULL, remote_data->command_collection, collection_get_first(remote_data->command_collection)); diff --git a/src/search.c b/src/search.c index c7fbaf4f..c855e615 100644 --- a/src/search.c +++ b/src/search.c @@ -2124,7 +2124,7 @@ static void search_start(SearchData *sd) sd->search_similarity_cd = cache_sim_data_new(); } - sd->img_loader = image_loader_new(file_data_new_simple(sd->search_similarity_path)); + sd->img_loader = image_loader_new(file_data_new_group(sd->search_similarity_path)); g_signal_connect(G_OBJECT(sd->img_loader), "error", (GCallback)search_similarity_load_done_cb, sd); g_signal_connect(G_OBJECT(sd->img_loader), "done", (GCallback)search_similarity_load_done_cb, sd); if (image_loader_start(sd->img_loader)) diff --git a/src/thumb_standard.c b/src/thumb_standard.c index f816809c..c23329f9 100644 --- a/src/thumb_standard.c +++ b/src/thumb_standard.c @@ -983,7 +983,7 @@ static void thumb_std_maint_move_validate_cb(const gchar *path, gboolean valid, tm->tl->cache_hit = FALSE; tm->tl->cache_local = FALSE; file_data_unref(tm->tl->fd); - tm->tl->fd = file_data_new_simple(tm->dest); + tm->tl->fd = file_data_new_group(tm->dest); tm->tl->source_mtime = strtol(mtime_str, NULL, 10); pathl = path_from_utf8(tm->tl->fd->path); diff --git a/src/utilops.c b/src/utilops.c index e32a18df..d8a0ccdf 100644 --- a/src/utilops.c +++ b/src/utilops.c @@ -1074,7 +1074,7 @@ static void file_util_dest_folder_update_path(UtilityData *ud) break; case UTILITY_TYPE_CREATE_FOLDER: file_data_unref(ud->dir_fd); - ud->dir_fd = file_data_new_simple(ud->dest_path); + ud->dir_fd = file_data_new_dir(ud->dest_path); break; case UTILITY_TYPE_DELETE: case UTILITY_TYPE_DELETE_LINK: @@ -2676,7 +2676,7 @@ static void file_util_create_dir_full(FileData *fd, const gchar *dest_path, GtkW g_free(buf); } - ud->dir_fd = file_data_new_simple(ud->dest_path); + ud->dir_fd = file_data_new_dir(ud->dest_path); ud->done_func = done_func; ud->done_data = done_data; diff --git a/src/view_file_list.c b/src/view_file_list.c index ca16324c..c2905874 100644 --- a/src/view_file_list.c +++ b/src/view_file_list.c @@ -516,7 +516,7 @@ static gboolean vflist_row_rename_cb(TreeEditData *td, const gchar *old, const g else { gchar *old_path = g_build_filename(vf->dir_fd->path, old, NULL); - FileData *fd = file_data_new_simple(old_path); /* get the fd from cache */ + FileData *fd = file_data_new_group(old_path); /* get the fd from cache */ file_util_rename_simple(fd, new_path, vf->listview); file_data_unref(fd); g_free(old_path); -- 2.20.1