# HG changeset patch # User nadvornik # Date 1229805836 0 # Node ID 3ff2aa99108b900dd9d1e31d1a421d0545dba671 # Parent fa91098e49499716a29d01547a170914a21ccc83 use the workflow in utilops.c for metadata approving and writting TODO: configuration diff -r fa91098e4949 -r 3ff2aa99108b src/filedata.c --- 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) diff -r fa91098e4949 -r 3ff2aa99108b src/filedata.h --- 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); diff -r fa91098e4949 -r 3ff2aa99108b src/metadata.c --- 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) diff -r fa91098e4949 -r 3ff2aa99108b src/metadata.h --- 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); diff -r fa91098e4949 -r 3ff2aa99108b src/typedefs.h --- 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 { diff -r fa91098e4949 -r 3ff2aa99108b src/utilops.c --- 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); diff -r fa91098e4949 -r 3ff2aa99108b src/utilops.h --- 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);