changeset 1205:3ff2aa99108b

use the workflow in utilops.c for metadata approving and writting TODO: configuration
author nadvornik
date Sat, 20 Dec 2008 20:43:56 +0000
parents fa91098e4949
children d79305a42a9b
files src/filedata.c src/filedata.h src/metadata.c src/metadata.h src/typedefs.h src/utilops.c src/utilops.h
diffstat 7 files changed, 218 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/src/filedata.c	Tue Dec 16 12:59:23 2008 +0000
+++ b/src/filedata.c	Sat Dec 20 20:43:56 2008 +0000
@@ -18,13 +18,13 @@
 #include "cache.h"
 #include "thumb_standard.h"
 #include "ui_fileops.h"
+#include "metadata.h"
 
 
 static GHashTable *file_data_pool = NULL;
 static GHashTable *file_data_planned_change_hash = NULL;
 
 static gint sidecar_file_priority(const gchar *path);
-static void file_data_apply_ci(FileData *fd);
 
 
 /*
@@ -1320,6 +1320,11 @@
 	return TRUE;
 }
 
+gboolean file_data_add_ci_write_metadata(FileData *fd)
+{
+	return file_data_add_ci(fd, FILEDATA_CHANGE_WRITE_METADATA, NULL, NULL);
+}
+
 void file_data_sc_free_ci(FileData *fd)
 {
 	GList *work;
@@ -1409,6 +1414,37 @@
 	return file_data_sc_add_ci_list_call_func(fd_list, dest, file_data_sc_add_ci_unspecified);
 }
 
+gboolean file_data_add_ci_write_metadata_list(GList *fd_list)
+{
+	GList *work;
+	gboolean ret = TRUE;
+
+	work = fd_list;
+	while (work)
+		{
+		FileData *fd = work->data;
+	
+		if (!file_data_add_ci_write_metadata(fd)) ret = FALSE;
+		work = work->next;
+		}
+
+	return ret;
+}
+
+void file_data_free_ci_list(GList *fd_list)
+{
+	GList *work;
+	
+	work = fd_list;
+	while (work)
+		{
+		FileData *fd = work->data;
+		
+		file_data_free_ci(fd);
+		work = work->next;
+		}
+}
+
 void file_data_sc_free_ci_list(GList *fd_list)
 {
 	GList *work;
@@ -1796,7 +1832,7 @@
 	return g_string_free(result, FALSE);
 }
 
-gint file_data_sc_verify_ci_list(GList *list, gchar **desc)
+gint file_data_verify_ci_list(GList *list, gchar **desc, gboolean with_sidecars)
 {
 	GList *work;
 	gint all_errors = 0;
@@ -1819,7 +1855,7 @@
 		fd = work->data;
 		work = work->next;
 			
-		error = file_data_sc_verify_ci(fd);
+		error = with_sidecars ? file_data_sc_verify_ci(fd) : file_data_verify_ci(fd);
 		all_errors |= error;
 		common_errors &= error;
 		
@@ -1896,7 +1932,7 @@
 		return unlink_file(fd->path);
 }
 
-static gboolean file_data_perform_ci(FileData *fd)
+gboolean file_data_perform_ci(FileData *fd)
 {
 	FileDataChangeType type = fd->change->type;
 	switch (type)
@@ -1909,6 +1945,8 @@
 			return file_data_perform_move(fd); /* the same as move */
 		case FILEDATA_CHANGE_DELETE:
 			return file_data_perform_delete(fd);
+		case FILEDATA_CHANGE_WRITE_METADATA:
+			return metadata_write_perform(fd);
 		case FILEDATA_CHANGE_UNSPECIFIED:
 			/* nothing to do here */
 			break;
@@ -1944,10 +1982,10 @@
  * updates FileData structure according to FileDataChangeInfo
  */
 
-static void file_data_apply_ci(FileData *fd)
+gint file_data_apply_ci(FileData *fd)
 {
 	FileDataChangeType type = fd->change->type;
-	
+
 	/* FIXME delete ?*/
 	if (type == FILEDATA_CHANGE_MOVE || type == FILEDATA_CHANGE_RENAME)
 		{
@@ -1970,6 +2008,8 @@
 		}
 	file_data_increment_version(fd);
 	file_data_send_notification(fd, NOTIFY_TYPE_CHANGE);
+	
+	return TRUE;
 }
 
 gint file_data_sc_apply_ci(FileData *fd)
--- a/src/filedata.h	Tue Dec 16 12:59:23 2008 +0000
+++ b/src/filedata.h	Sat Dec 20 20:43:56 2008 +0000
@@ -85,6 +85,7 @@
 gboolean file_data_sc_add_ci_move_list(GList *fd_list, const gchar *dest);
 gboolean file_data_sc_add_ci_rename_list(GList *fd_list, const gchar *dest);
 gboolean file_data_sc_add_ci_unspecified_list(GList *fd_list, const gchar *dest);
+gboolean file_data_add_ci_write_metadata_list(GList *fd_list);
 
 gboolean file_data_sc_update_ci_copy_list(GList *fd_list, const gchar *dest);
 gboolean file_data_sc_update_ci_move_list(GList *fd_list, const gchar *dest);
@@ -95,9 +96,19 @@
 gint file_data_sc_update_ci_move(FileData *fd, const gchar *dest_path);
 gint file_data_sc_update_ci_rename(FileData *fd, const gchar *dest_path);
 gint file_data_sc_update_ci_unspecified(FileData *fd, const gchar *dest_path);
-gint file_data_sc_verify_ci(FileData *fd);
+
 gchar *file_data_get_error_string(gint error);
-gint file_data_sc_verify_ci_list(GList *list, gchar **desc);
+
+gint file_data_verify_ci(FileData *fd);
+gint file_data_verify_ci_list(GList *list, gchar **desc, gboolean with_sidecars);
+
+gboolean file_data_perform_ci(FileData *fd);
+gint file_data_apply_ci(FileData *fd);
+void file_data_free_ci(FileData *fd);
+void file_data_free_ci_list(GList *fd_list);
+
+
+gint file_data_sc_verify_ci(FileData *fd);
 
 gboolean file_data_sc_perform_ci(FileData *fd);
 gint file_data_sc_apply_ci(FileData *fd);
--- a/src/metadata.c	Tue Dec 16 12:59:23 2008 +0000
+++ b/src/metadata.c	Sat Dec 20 20:43:56 2008 +0000
@@ -58,7 +58,34 @@
 }
 
 
-static void metadata_write_queue_commit(FileData *fd)
+gboolean metadata_write_queue_remove(FileData *fd)
+{
+	g_hash_table_destroy(fd->modified_xmp);
+	fd->modified_xmp = NULL;
+
+	metadata_write_queue = g_list_remove(metadata_write_queue, fd);
+	file_data_unref(fd);
+	return TRUE;
+}
+
+
+static gboolean metadata_write_queue_idle_cb(gpointer data)
+{
+	/* TODO:  the queue should not be passed to file_util_write_metadata directly:
+		  metatata under .geeqie/ can be written immediately, 
+	          for others we can decide if we write to the image file or to sidecar */
+	
+
+//	if (metadata_write_queue) return TRUE;
+
+	/* confirm writting */
+	file_util_write_metadata(NULL, metadata_write_queue, NULL);
+
+	metadata_write_idle_id = -1;
+	return FALSE;
+}
+
+gboolean metadata_write_perform(FileData *fd)
 {
 	if (options->save_metadata_in_image_file &&
 	    exif_write_fd(fd))
@@ -66,25 +93,9 @@
 		metadata_legacy_delete(fd);
 		}
 	else metadata_legacy_write(fd);
-	
-	g_hash_table_destroy(fd->modified_xmp);
-	fd->modified_xmp = NULL;
-
-	metadata_write_queue = g_list_remove(metadata_write_queue, fd);
-	file_data_unref(fd);
+	return TRUE;
 }
 
-static gboolean metadata_write_queue_idle_cb(gpointer data)
-{
-	metadata_write_queue_commit(metadata_write_queue->data); /* the first entry */
-	
-	if (metadata_write_queue) return TRUE;
-
-	metadata_write_idle_id = -1;
-	return FALSE;
-}
-
-
 gint metadata_write_list(FileData *fd, const gchar *key, GList *values)
 {
 	if (!fd->modified_xmp)
--- a/src/metadata.h	Tue Dec 16 12:59:23 2008 +0000
+++ b/src/metadata.h	Sat Dec 20 20:43:56 2008 +0000
@@ -13,6 +13,9 @@
 
 #ifndef METADATA_H
 #define METADATA_H
+gboolean metadata_write_queue_remove(FileData *fd);
+gboolean metadata_write_perform(FileData *fd);
+
 
 gint metadata_write(FileData *fd, GList *keywords, const gchar *comment);
 
--- a/src/typedefs.h	Tue Dec 16 12:59:23 2008 +0000
+++ b/src/typedefs.h	Sat Dec 20 20:43:56 2008 +0000
@@ -98,7 +98,8 @@
 	FILEDATA_CHANGE_MOVE,
 	FILEDATA_CHANGE_RENAME,
 	FILEDATA_CHANGE_COPY,
-	FILEDATA_CHANGE_UNSPECIFIED
+	FILEDATA_CHANGE_UNSPECIFIED,
+	FILEDATA_CHANGE_WRITE_METADATA
 } FileDataChangeType;
 
 typedef enum {
--- a/src/utilops.c	Tue Dec 16 12:59:23 2008 +0000
+++ b/src/utilops.c	Sat Dec 20 20:43:56 2008 +0000
@@ -31,6 +31,7 @@
 #include "ui_misc.h"
 #include "ui_tabcomp.h"
 #include "editors.h"
+#include "metadata.h"
 
 static GdkPixbuf *file_util_get_error_icon(FileData *fd, GtkWidget *widget);
 
@@ -241,7 +242,8 @@
 	UTILITY_TYPE_DELETE,
 	UTILITY_TYPE_DELETE_LINK,
 	UTILITY_TYPE_DELETE_FOLDER,
-	UTILITY_TYPE_CREATE_FOLDER
+	UTILITY_TYPE_CREATE_FOLDER,
+	UTILITY_TYPE_WRITE_METADATA
 } UtilityType;
 
 typedef enum {
@@ -282,6 +284,8 @@
 	FileDialog *fdlg;
 	
 	gint update_idle_id;
+
+	gboolean with_sidecars; /* operate on grouped or single files; TRUE = use file_data_sc_, FALSE = use file_data_ functions */
 	
 	/* alternative dialog parts */
 	GtkWidget *notebook;
@@ -537,11 +541,24 @@
 
 		if (!(flags & EDITOR_ERROR_MASK)) /* files were successfully deleted, call the maint functions */
 			{
-			file_data_sc_apply_ci(fd);
+			if (ud->with_sidecars) 
+				file_data_sc_apply_ci(fd);
+			else
+				file_data_apply_ci(fd);
 			}
 		
 		ud->flist = g_list_remove(ud->flist, fd);
-		file_data_sc_free_ci(fd);
+		
+		/* FIXME: put it here for now */
+		if (ud->type == UTILITY_TYPE_WRITE_METADATA)
+			{
+			metadata_write_queue_remove(fd);
+			}
+
+		if (ud->with_sidecars) 
+			file_data_sc_free_ci(fd);
+		else
+			file_data_free_ci(fd);
 		file_data_unref(fd);
 		}
 		
@@ -573,7 +590,8 @@
 		gboolean last = !ud->flist->next;
 		gint status = EDITOR_ERROR_STATUS;
 	
-		if (file_data_sc_perform_ci(single_entry->data))
+		if (ud->with_sidecars ? file_data_sc_perform_ci(single_entry->data) 
+		                      : file_data_perform_ci(single_entry->data))
 			status = 0; /* OK */
 		
 		ret = file_util_perform_ci_cb(GINT_TO_POINTER(!last), status, single_entry, ud);
@@ -597,10 +615,11 @@
 		{
 		case UTILITY_TYPE_DELETE_LINK:
 			{
-			if ((internal && file_data_sc_perform_ci(ud->dir_fd)) ||
+			g_assert(ud->dir_fd->sidecar_files == NULL); // directories should not have sidecars
+			if ((internal && file_data_perform_ci(ud->dir_fd)) ||
 			    (!internal && ext_result))
 				{
-				file_data_sc_apply_ci(ud->dir_fd);
+				file_data_apply_ci(ud->dir_fd);
 				}
 			else
 				{
@@ -610,7 +629,7 @@
 				file_util_warning_dialog(ud->messages.fail, text, GTK_STOCK_DIALOG_ERROR, NULL);
 				g_free(text);
 				}
-			file_data_sc_free_ci(ud->dir_fd);
+			file_data_free_ci(ud->dir_fd);
 			break;
 			}
 		case UTILITY_TYPE_DELETE_FOLDER:
@@ -642,10 +661,11 @@
 
 			if (!fail)
 				{
+				g_assert(ud->dir_fd->sidecar_files == NULL); // directories should not have sidecars
 				if ((internal && file_data_sc_perform_ci(ud->dir_fd)) ||
 				    (!internal && ext_result))
 					{
-					file_data_sc_apply_ci(ud->dir_fd);
+					file_data_apply_ci(ud->dir_fd);
 					}
 				else
 					{
@@ -679,6 +699,8 @@
 			{
 			FileData *fail = NULL;
 			GList *work;
+			g_assert(ud->dir_fd->sidecar_files == NULL); // directories should not have sidecars
+
 			if ((internal && file_data_sc_perform_ci(ud->dir_fd)) ||
 			    (!internal && ext_result))
 				{
@@ -777,6 +799,8 @@
 		case UTILITY_TYPE_EDITOR:
 			g_assert(ud->external_command != -1); /* it should be already set */
 			break;
+		case UTILITY_TYPE_WRITE_METADATA:
+			ud->external_command = -1;
 		}
 
 	if (is_valid_editor_command(ud->external_command))
@@ -879,12 +903,13 @@
 			}
 		else if (ud->dir_fd)
 			{
-			error = file_data_sc_verify_ci(ud->dir_fd);
+			g_assert(ud->dir_fd->sidecar_files == NULL); // directories should not have sidecars
+			error = file_data_verify_ci(ud->dir_fd);
 			if (error) desc = file_data_get_error_string(error);
 			}
 		else
 			{
-			error = file_data_sc_verify_ci_list(ud->flist, &desc);
+			error = file_data_verify_ci_list(ud->flist, &desc, ud->with_sidecars);
 			}
 		}
 
@@ -973,7 +998,6 @@
 		{
 		case UTILITY_TYPE_COPY:
 			file_data_sc_update_ci_copy_list(ud->flist, ud->dest_path);
-			break;
 		case UTILITY_TYPE_MOVE:
 			file_data_sc_update_ci_move_list(ud->flist, ud->dest_path);
 			break;
@@ -990,6 +1014,7 @@
 		case UTILITY_TYPE_DELETE_FOLDER:
 		case UTILITY_TYPE_RENAME:
 		case UTILITY_TYPE_RENAME_FOLDER:
+		case UTILITY_TYPE_WRITE_METADATA:
 			g_warning("unhandled operation");
 		}
 }
@@ -1099,6 +1124,7 @@
 			const gchar *dest = gtk_entry_get_text(GTK_ENTRY(ud->rename_entry));
 			
 			gtk_tree_model_get(store, &iter, UTILITY_COLUMN_FD, &fd, -1);
+			g_assert(ud->with_sidecars); /* sidecars must be renamed too, it would break the pairing otherwise */
 			file_data_sc_update_ci_rename(fd, dest);
 			gtk_list_store_set(GTK_LIST_STORE(store), &iter,
 					   UTILITY_COLUMN_PIXBUF, file_util_get_error_icon(fd, ud->listview),
@@ -1143,6 +1169,7 @@
 			dest = g_strdup_printf("%s%0*d%s", front, padding, n, end);
 			}
 
+		g_assert(ud->with_sidecars); /* sidecars must be renamed too, it would break the pairing otherwise */
 		file_data_sc_update_ci_rename(fd, dest);
 		gtk_list_store_set(GTK_LIST_STORE(store), &iter,
 				   UTILITY_COLUMN_PIXBUF, file_util_get_error_icon(fd, ud->listview),
@@ -1241,9 +1268,22 @@
 	GtkTreeSelection *selection;
 	gchar *dir_msg;
 
+	const gchar *stock_id;
+
+	if (ud->type == UTILITY_TYPE_DELETE ||
+	    ud->type == UTILITY_TYPE_DELETE_LINK ||
+	    ud->type == UTILITY_TYPE_DELETE_FOLDER)
+		{
+		stock_id = GTK_STOCK_DELETE;
+		}
+	else
+		{
+		stock_id = GTK_STOCK_OK;
+		}
+
 	ud->gd = file_util_gen_dlg(ud->messages.title, "dlg_confirm",
 				   ud->parent, FALSE,  file_util_cancel_cb, ud);
-	generic_dialog_add_button(ud->gd, GTK_STOCK_DELETE, NULL, file_util_ok_cb, TRUE);
+	generic_dialog_add_button(ud->gd, stock_id, NULL, file_util_ok_cb, TRUE);
 
 
 	if (ud->dir_fd)
@@ -1272,7 +1312,10 @@
 
 	generic_dialog_add_image(ud->gd, box, NULL, NULL, NULL, NULL, FALSE);
 
-	box_append_safe_delete_status(ud->gd);
+	if (ud->type == UTILITY_TYPE_DELETE ||
+	    ud->type == UTILITY_TYPE_DELETE_LINK ||
+	    ud->type == UTILITY_TYPE_DELETE_FOLDER)
+		box_append_safe_delete_status(ud->gd);
 
 	gtk_widget_show(ud->gd->dialog);
 
@@ -1476,6 +1519,7 @@
 				case UTILITY_TYPE_DELETE_LINK:
 				case UTILITY_TYPE_DELETE_FOLDER:
 				case UTILITY_TYPE_EDITOR:
+				case UTILITY_TYPE_WRITE_METADATA:
 					file_util_dialog_init_simple_list(ud);
 					break;
 				case UTILITY_TYPE_RENAME:
@@ -1504,9 +1548,15 @@
 			break;
 		case UTILITY_PHASE_CANCEL:
 		case UTILITY_PHASE_DONE:
-			file_data_sc_free_ci_list(ud->flist);
+			if (ud->with_sidecars)
+				file_data_sc_free_ci_list(ud->flist);
+			else
+				file_data_free_ci_list(ud->flist);
+			
+			/* directory content is always handled including sidecars */
 			file_data_sc_free_ci_list(ud->content_list);
-			if (ud->dir_fd) file_data_sc_free_ci(ud->dir_fd);
+			
+			if (ud->dir_fd) file_data_free_ci(ud->dir_fd);
 			file_util_data_free(ud);
 			break;
 		}
@@ -1556,6 +1606,8 @@
 	ud = file_util_data_new(UTILITY_TYPE_DELETE);
 	
 	ud->phase = phase;
+	
+	ud->with_sidecars = TRUE;
 
 	ud->dir_fd = NULL;
 	ud->flist = flist;
@@ -1571,6 +1623,44 @@
 	file_util_dialog_run(ud);
 }
 
+static void file_util_write_metadata_full(FileData *source_fd, GList *source_list, GtkWidget *parent, UtilityPhase phase)
+{
+	UtilityData *ud;
+	GList *flist = filelist_copy(source_list);
+	
+	if (source_fd)
+		flist = g_list_append(flist, file_data_ref(source_fd));
+
+	if (!flist) return;
+	
+	if (!file_data_add_ci_write_metadata_list(flist))
+		{
+		file_util_warn_op_in_progress(_("Can't write metadata"));
+		filelist_free(flist);
+		return;
+		}
+
+	ud = file_util_data_new(UTILITY_TYPE_WRITE_METADATA);
+	
+	ud->phase = phase;
+
+	ud->with_sidecars = FALSE; /* operate on individual files, not groups */
+
+	ud->dir_fd = NULL;
+	ud->flist = flist;
+	ud->content_list = NULL;
+	ud->parent = parent;
+	
+	ud->messages.title = _("Write metadata");
+	ud->messages.question = _("Write metadata?");
+	ud->messages.desc_flist = _("This will write the changed metadata into the following files");
+	ud->messages.desc_source_fd = "";
+	ud->messages.fail = _("Metadata writting failed");
+
+	file_util_dialog_run(ud);
+}
+
+
 static void file_util_move_full(FileData *source_fd, GList *source_list, const gchar *dest_path, GtkWidget *parent, UtilityPhase phase)
 {
 	UtilityData *ud;
@@ -1594,6 +1684,8 @@
 
 	ud->phase = phase;
 
+	ud->with_sidecars = TRUE;
+
 	ud->dir_fd = NULL;
 	ud->flist = flist;
 	ud->content_list = NULL;
@@ -1632,6 +1724,8 @@
 
 	ud->phase = phase;
 
+	ud->with_sidecars = TRUE;
+
 	ud->dir_fd = NULL;
 	ud->flist = flist;
 	ud->content_list = NULL;
@@ -1671,6 +1765,8 @@
 
 	ud->phase = phase;
 
+	ud->with_sidecars = TRUE;
+
 	ud->dir_fd = NULL;
 	ud->flist = flist;
 	ud->content_list = NULL;
@@ -1714,6 +1810,8 @@
 	if (ud->type == UTILITY_TYPE_FILTER && dest_path == NULL) phase = UTILITY_PHASE_START;
 	
 	ud->phase = phase;
+
+	ud->with_sidecars = TRUE;
 	
 	ud->external_command = n;
 
@@ -1890,6 +1988,7 @@
 		ud = file_util_data_new(UTILITY_TYPE_DELETE_LINK);
 
 		ud->phase = phase;
+		ud->with_sidecars = TRUE;
 		ud->dir_fd = file_data_ref(fd);
 		ud->content_list = NULL;
 		ud->flist = NULL;
@@ -1962,6 +2061,7 @@
 		ud = file_util_data_new(UTILITY_TYPE_DELETE_FOLDER);
 
 		ud->phase = phase;
+		ud->with_sidecars = TRUE;
 		ud->dir_fd = file_data_ref(fd);
 		ud->content_list = NULL; /* will be filled by file_util_delete_dir_prepare */
 		ud->flist = flist = filelist_sort_path(flist);
@@ -2088,6 +2188,8 @@
 	ud = file_util_data_new(UTILITY_TYPE_RENAME_FOLDER);
 
 	ud->phase = phase;
+	ud->with_sidecars = TRUE; /* does not matter, the directory should not have sidecars 
+	                            and the content must be handled including sidecars */
 
 	ud->dir_fd = file_data_ref(fd);
 	ud->flist = NULL;
@@ -2114,11 +2216,12 @@
 
 static void file_util_create_dir_full(FileData *fd, const gchar *dest_path, GtkWidget *parent, UtilityPhase phase)
 {
-	UtilityData *ud;
+	UtilityData *ud; 
 
 	ud = file_util_data_new(UTILITY_TYPE_CREATE_FOLDER);
 
 	ud->phase = phase;
+	ud->with_sidecars = TRUE;
 
 	ud->dir_fd = NULL;
 	ud->flist = NULL;
@@ -2156,6 +2259,11 @@
 	file_util_delete_full(source_fd, source_list, parent, options->file_ops.confirm_delete ? UTILITY_PHASE_START : UTILITY_PHASE_ENTERING);
 }
 
+void file_util_write_metadata(FileData *source_fd, GList *source_list, GtkWidget *parent)
+{
+	file_util_write_metadata_full(source_fd, source_list, parent, UTILITY_PHASE_START);
+}
+
 void file_util_copy(FileData *source_fd, GList *source_list, const gchar *dest_path, GtkWidget *parent)
 {
 	file_util_copy_full(source_fd, source_list, dest_path, parent, UTILITY_PHASE_START);
--- a/src/utilops.h	Tue Dec 16 12:59:23 2008 +0000
+++ b/src/utilops.h	Sat Dec 20 20:43:56 2008 +0000
@@ -38,6 +38,7 @@
 void file_util_move(FileData *source_fd, GList *source_list, const gchar *dest_path, GtkWidget *parent);
 void file_util_copy(FileData *source_fd, GList *source_list, const gchar *dest_path, GtkWidget *parent);
 void file_util_rename(FileData *source_fd, GList *source_list, GtkWidget *parent);
+void file_util_write_metadata(FileData *source_fd, GList *source_list, GtkWidget *parent);
 
 void file_util_create_dir(FileData *dir_fd, GtkWidget *parent);
 void file_util_rename_dir(FileData *source_fd, const gchar *new_path, GtkWidget *parent);