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)