Mercurial > hg > forks > geeqie
changeset 2454:93d1c77a312b
Fix #147: Alternative format for sidecar extension
https://github.com/BestImageViewer/geeqie/issues/147
Add option to store sidecar extension with a format e.g. filename.jpg.xmp rather than filename.xmp
author | Tomasz Golinski <tomaszg@math.uwb.edu.pl> |
---|---|
date | Wed, 15 Mar 2017 11:06:10 +0000 |
parents | 7cdaa31d3b45 |
children | ecdf0274a079 |
files | doc/docbook/GuideOptionsMetadata.xml src/filedata.c src/metadata.c src/options.c src/options.h src/preferences.c src/print.c src/rcfile.c src/typedefs.h src/ui_fileops.c src/ui_fileops.h src/utilops.c |
diffstat | 12 files changed, 92 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/docbook/GuideOptionsMetadata.xml Sun Feb 26 19:58:21 2017 +0000 +++ b/doc/docbook/GuideOptionsMetadata.xml Wed Mar 15 11:06:10 2017 +0000 @@ -70,6 +70,13 @@ If checked, open a confirmation dialogue before writing to the file </para> </listitem> + <listitem> + <para> + <guilabel>Create sidecar files named image.ext.xmp (as opposed to image.xmp)</guilabel> + <para /> + If checked, new sidecar files will use image.ext.xmp naming scheme + </para> + </listitem> </itemizedlist> </section> <section id="WriteToGeeqiePrivateFiles">
--- a/src/filedata.c Sun Feb 26 19:58:21 2017 +0000 +++ b/src/filedata.c Wed Mar 15 11:06:10 2017 +0000 @@ -605,6 +605,7 @@ g_free(fd->original_path); g_free(fd->collate_key_name); g_free(fd->collate_key_name_nocase); + g_free(fd->extended_extension); if (fd->thumb_pixbuf) g_object_unref(fd->thumb_pixbuf); histmap_free(fd->histmap); @@ -932,6 +933,8 @@ target->sidecar_files = g_list_remove(target->sidecar_files, sfd); sfd->parent = NULL; + g_free(sfd->extended_extension); + sfd->extended_extension = NULL; file_data_unref(target); file_data_unref(sfd); @@ -1119,6 +1122,37 @@ list = g_hash_table_lookup(basename_hash, basename); + if (!list) + { + DEBUG_1("TG: basename_hash not found for %s",fd->path); + const gchar *parent_extension = registered_extension_from_path(basename); + + if (parent_extension) + { + DEBUG_1("TG: parent extension %s",parent_extension); + gchar *parent_basename = g_strndup(basename, parent_extension - basename); + DEBUG_1("TG: parent basename %s",parent_basename); + FileData *parent_fd = g_hash_table_lookup(file_data_pool, basename); + if (parent_fd) + { + DEBUG_1("TG: parent fd found"); + list = g_hash_table_lookup(basename_hash, parent_basename); + if (!g_list_find(list, parent_fd)) + { + DEBUG_1("TG: parent fd doesn't fit"); + g_free(parent_basename); + list = NULL; + } + else + { + g_free(basename); + basename = parent_basename; + fd->extended_extension = g_strconcat(parent_extension, fd->extension, NULL); + } + } + } + } + if (!g_list_find(list, fd)) { list = g_list_insert_sorted(list, file_data_ref(fd), file_data_sort_by_ext); @@ -1131,6 +1165,11 @@ return list; } +static void file_data_basename_hash_insert_cb(gpointer fd, gpointer basename_hash) +{ + file_data_basename_hash_insert((GHashTable *)basename_hash, (FileData *)fd); +} + static void file_data_basename_hash_remove_list(gpointer key, gpointer value, gpointer data) { filelist_free((GList *)value); @@ -1195,6 +1234,7 @@ gchar *pathl; GList *dlist = NULL; GList *flist = NULL; + GList *xmp_files = NULL; gint (*stat_func)(const gchar *path, struct stat *buf); GHashTable *basename_hash = NULL; @@ -1252,7 +1292,10 @@ flist = g_list_prepend(flist, fd); if (fd->sidecar_priority && !fd->disable_grouping) { - file_data_basename_hash_insert(basename_hash, fd); + if (strcmp(fd->extension, ".xmp") != 0) + file_data_basename_hash_insert(basename_hash, fd); + else + xmp_files = g_list_append(xmp_files, fd); } } } @@ -1271,6 +1314,12 @@ g_free(pathl); + if (xmp_files) + { + g_list_foreach(xmp_files,file_data_basename_hash_insert_cb,basename_hash); + g_list_free(xmp_files); + } + if (dirs) *dirs = dlist; if (files) @@ -1531,22 +1580,29 @@ if (!file_data_can_write_sidecar(fd)) return NULL; work = fd->parent ? fd->parent->sidecar_files : fd->sidecar_files; + gchar *extended_extension = g_strconcat(fd->parent ? fd->parent->extension : fd->extension, ".xmp", NULL); while (work) { FileData *sfd = work->data; work = work->next; - if (g_ascii_strcasecmp(sfd->extension, ".xmp") == 0) + if (g_ascii_strcasecmp(sfd->extension, ".xmp") == 0 || g_ascii_strcasecmp(sfd->extension, extended_extension) == 0) { sidecar_path = g_strdup(sfd->path); break; } } + g_free(extended_extension); 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); + if (options->metadata.sidecar_extended_name) + sidecar_path = g_strconcat(fd->path, ".xmp", NULL); + else + { + gchar *base = g_strndup(fd->path, fd->extension - fd->path); + sidecar_path = g_strconcat(base, ".xmp", NULL); + g_free(base); + } } return sidecar_path; @@ -2095,11 +2151,11 @@ static void file_data_update_ci_dest_preserve_ext(FileData *fd, const gchar *dest_path) { - const gchar *extension = extension_from_path(fd->change->source); + const gchar *extension = registered_extension_from_path(fd->change->source); gchar *base = remove_extension_from_path(dest_path); gchar *old_path = fd->change->dest; - fd->change->dest = g_strconcat(base, extension, NULL); + fd->change->dest = g_strconcat(base, fd->extended_extension ? fd->extended_extension : extension, NULL); file_data_update_planned_change_hash(fd, old_path, fd->change->dest); g_free(old_path); @@ -2372,7 +2428,7 @@ if (!same) { - const gchar *dest_ext = extension_from_path(fd->change->dest); + const gchar *dest_ext = registered_extension_from_path(fd->change->dest); if (!dest_ext) dest_ext = ""; if (!options->file_filter.disable_file_extension_checks) {
--- a/src/metadata.c Sun Feb 26 19:58:21 2017 +0000 +++ b/src/metadata.c Wed Mar 15 11:06:10 2017 +0000 @@ -302,7 +302,7 @@ g_assert(fd->change); if (fd->change->dest && - strcmp(extension_from_path(fd->change->dest), GQ_CACHE_EXT_METADATA) == 0) + strcmp(registered_extension_from_path(fd->change->dest), GQ_CACHE_EXT_METADATA) == 0) { success = metadata_legacy_write(fd); if (success) metadata_legacy_delete(fd, fd->change->dest);
--- a/src/options.c Sun Feb 26 19:58:21 2017 +0000 +++ b/src/options.c Wed Mar 15 11:06:10 2017 +0000 @@ -131,6 +131,7 @@ options->metadata.confirm_on_dir_change = TRUE; options->metadata.keywords_case_sensitive = FALSE; options->metadata.write_orientation = TRUE; + options->metadata.sidecar_extended_name = FALSE; options->show_icon_names = TRUE;
--- a/src/options.h Sun Feb 26 19:58:21 2017 +0000 +++ b/src/options.h Wed Mar 15 11:06:10 2017 +0000 @@ -210,6 +210,7 @@ gboolean confirm_on_dir_change; gboolean keywords_case_sensitive; gboolean write_orientation; + gboolean sidecar_extended_name; } metadata; /* Stereo */
--- a/src/preferences.c Sun Feb 26 19:58:21 2017 +0000 +++ b/src/preferences.c Wed Mar 15 11:06:10 2017 +0000 @@ -334,6 +334,7 @@ options->metadata.save_legacy_format = c_options->metadata.save_legacy_format; options->metadata.sync_grouped_files = c_options->metadata.sync_grouped_files; options->metadata.confirm_write = c_options->metadata.confirm_write; + options->metadata.sidecar_extended_name = c_options->metadata.sidecar_extended_name; options->metadata.confirm_timeout = c_options->metadata.confirm_timeout; options->metadata.confirm_after_timeout = c_options->metadata.confirm_after_timeout; options->metadata.confirm_on_image_change = c_options->metadata.confirm_on_image_change; @@ -1908,6 +1909,9 @@ pref_checkbox_new_int(hbox, _("Ask before writing to image files"), options->metadata.confirm_write, &c_options->metadata.confirm_write); + pref_checkbox_new_int(hbox, _("Create sidecar files named image.ext.xmp (as opposed to image.xmp)"), + options->metadata.sidecar_extended_name, &c_options->metadata.sidecar_extended_name); + group = pref_group_new(vbox, FALSE, _("Step 2 and 3: write to Geeqie private files"), GTK_ORIENTATION_VERTICAL); #ifndef HAVE_EXIV2 gtk_widget_set_sensitive(group, FALSE);
--- a/src/print.c Sun Feb 26 19:58:21 2017 +0000 +++ b/src/print.c Wed Mar 15 11:06:10 2017 +0000 @@ -23,6 +23,7 @@ #include "print.h" #include "filedata.h" +#include "filefilter.h" #include "image.h" #include "image-load.h" #include "pixbuf_util.h" @@ -1449,7 +1450,7 @@ const gchar *ext; gchar *base; - ext = extension_from_path(pw->output_path); + ext = registered_extension_from_path(pw->output_path); if (ext) {
--- a/src/rcfile.c Sun Feb 26 19:58:21 2017 +0000 +++ b/src/rcfile.c Wed Mar 15 11:06:10 2017 +0000 @@ -442,6 +442,7 @@ WRITE_NL(); WRITE_BOOL(*options, metadata.save_legacy_format); WRITE_NL(); WRITE_BOOL(*options, metadata.sync_grouped_files); WRITE_NL(); WRITE_BOOL(*options, metadata.confirm_write); + WRITE_NL(); WRITE_BOOL(*options, metadata.sidecar_extended_name); WRITE_NL(); WRITE_INT(*options, metadata.confirm_timeout); WRITE_NL(); WRITE_BOOL(*options, metadata.confirm_after_timeout); WRITE_NL(); WRITE_BOOL(*options, metadata.confirm_on_image_change); @@ -720,6 +721,7 @@ if (READ_BOOL(*options, metadata.save_legacy_format)) continue; if (READ_BOOL(*options, metadata.sync_grouped_files)) continue; if (READ_BOOL(*options, metadata.confirm_write)) continue; + if (READ_BOOL(*options, metadata.sidecar_extended_name)) continue; if (READ_BOOL(*options, metadata.confirm_after_timeout)) continue; if (READ_INT(*options, metadata.confirm_timeout)) continue; if (READ_BOOL(*options, metadata.confirm_on_image_change)) continue;
--- a/src/typedefs.h Sun Feb 26 19:58:21 2017 +0000 +++ b/src/typedefs.h Wed Mar 15 11:06:10 2017 +0000 @@ -536,6 +536,7 @@ gchar *path; const gchar *name; const gchar *extension; + gchar *extended_extension; gchar *collate_key_name; gchar *collate_key_name_nocase; gint64 size;
--- a/src/ui_fileops.c Sun Feb 26 19:58:21 2017 +0000 +++ b/src/ui_fileops.c Wed Mar 15 11:06:10 2017 +0000 @@ -41,6 +41,7 @@ #include "ui_utildlg.h" /* for locale warning dialog */ #include "md5-util.h" +#include "filefilter.h" /* *----------------------------------------------------------------------------- * generic file information and manipulation routines (public) @@ -697,7 +698,7 @@ name = filename_from_path(path); if (!name) return NULL; - ext = extension_from_path(name); + ext = registered_extension_from_path(name); if (!ext) { @@ -729,24 +730,14 @@ gchar *remove_level_from_path(const gchar *path) { - gint p = 0, n = -1; + const gchar *base; if (!path) return NULL; - while (path[p]) - { - if (path[p] == G_DIR_SEPARATOR) n = p; - p++; - } - if (n <= 0) n++; + base = strrchr(path, G_DIR_SEPARATOR); + if (base) return g_strndup(path, strlen(path)-strlen(base)); - return g_strndup(path, (gsize) n); -} - -const gchar *extension_from_path(const gchar *path) -{ - if (!path) return NULL; - return strrchr(path, '.'); + return NULL; } gboolean file_extension_match(const gchar *path, const gchar *ext) @@ -766,18 +757,8 @@ gchar *remove_extension_from_path(const gchar *path) { - gint p = 0, n = -1; - if (!path) return NULL; - - while (path[p]) - { - if (path[p] == '.') n = p; - p++; - } - if (n < 0) n = p; - - return g_strndup(path, (gsize) n); + return g_strndup(path, strlen(path)-strlen(registered_extension_from_path(path))); } void parse_out_relatives(gchar *path)
--- a/src/ui_fileops.h Sun Feb 26 19:58:21 2017 +0000 +++ b/src/ui_fileops.h Wed Mar 15 11:06:10 2017 +0000 @@ -91,7 +91,6 @@ const gchar *filename_from_path(const gchar *path); gchar *remove_level_from_path(const gchar *path); -const gchar *extension_from_path(const gchar *path); gchar *remove_extension_from_path(const gchar *path); gboolean file_extension_match(const gchar *path, const gchar *ext);
--- a/src/utilops.c Sun Feb 26 19:58:21 2017 +0000 +++ b/src/utilops.c Wed Mar 15 11:06:10 2017 +0000 @@ -225,7 +225,7 @@ { const gchar *ext; - ext = extension_from_path(name); + ext = registered_extension_from_path(name); if (ext) n -= strlen(ext); } @@ -1205,7 +1205,7 @@ parsed = tmp; } - ext = extension_from_path(name); + ext = registered_extension_from_path(name); middle = strchr(parsed, '*'); if (middle)