Mercurial > geeqie.yaz
diff src/filedata.c @ 1224:ebfd305d902e
improved sidecar writting
private metadata can be saved in xmp format
author | nadvornik |
---|---|
date | Fri, 26 Dec 2008 14:12:36 +0000 |
parents | 31dc2f240afb |
children | 2df7be0cd20b |
line wrap: on
line diff
--- a/src/filedata.c Thu Dec 25 12:39:34 2008 +0000 +++ b/src/filedata.c Fri Dec 26 14:12:36 2008 +0000 @@ -661,7 +661,45 @@ fd->change = NULL; } +static gboolean file_data_can_write_directly(FileData *fd) +{ + return (filter_file_class(fd->extension, FORMAT_CLASS_IMAGE)); +/* FIXME: detect what exiv2 really supports */ +} +static gboolean file_data_can_write_sidecar(FileData *fd) +{ + return (filter_file_class(fd->extension, FORMAT_CLASS_RAWIMAGE)); +/* FIXME: detect what exiv2 really supports */ +} + +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 (strcasecmp(sfd->extension, ".xmp") == 0) + { + sidecar_path = g_strdup(sfd->path); + break; + } + } + + if (!existing_only && !sidecar_path) + { + gchar *base = remove_extension_from_path(fd->path); + sidecar_path = g_strconcat(base, ".xmp", NULL); + g_free(base); + } + + return sidecar_path; +} /* @@ -1687,8 +1725,7 @@ return ret; } - if (!isname(fd->path) && - !filter_file_class(fd->extension, FORMAT_CLASS_META)) /* xmp sidecar can be eventually created from scratch */ + if (!isname(fd->path)) { /* this probably should not happen */ ret |= CHANGE_NO_SRC; @@ -1721,24 +1758,98 @@ } /* WRITE_METADATA is special because it can be configured to silently write to ~/.geeqie/... - that means that there are no hard errors and warnings can be disabled + - the destination is determined during the check */ - else if (fd->change->type == FILEDATA_CHANGE_WRITE_METADATA && - options->metadata.save_in_image_file && options->metadata.warn_on_write_problems) + else if (fd->change->type == FILEDATA_CHANGE_WRITE_METADATA) { - if (isname(fd->path) && !access_file(fd->path, W_OK)) + /* determine destination file */ + gboolean have_dest = FALSE; + gchar *dest_dir = NULL; + + if (options->metadata.save_in_image_file) { - ret |= CHANGE_WARN_NO_WRITE_PERM; - DEBUG_1("Change checked: file is readonly: %s", fd->path); + if (file_data_can_write_directly(fd)) + { + /* we can write the file directly */ + if (access_file(fd->path, W_OK)) + { + have_dest = TRUE; + } + else + { + if (options->metadata.warn_on_write_problems) + { + ret |= CHANGE_WARN_NO_WRITE_PERM; + DEBUG_1("Change checked: file is not writable: %s", fd->path); + } + } + } + else if (file_data_can_write_sidecar(fd)) + { + /* we can write sidecar */ + gchar *sidecar = file_data_get_sidecar_path(fd, FALSE); + if (access_file(sidecar, W_OK) || (!isname(sidecar) && access_file(dir, W_OK))) + { + file_data_update_ci_dest(fd, sidecar); + have_dest = TRUE; + } + else + { + if (options->metadata.warn_on_write_problems) + { + ret |= CHANGE_WARN_NO_WRITE_PERM; + DEBUG_1("Change checked: file is not writable: %s", sidecar); + } + } + g_free(sidecar); + } } - else if (!access_file(dir, W_OK)) + if (!have_dest) { - ret |= CHANGE_WARN_NO_WRITE_PERM; - DEBUG_1("Change checked: dir is readonly: %s", fd->path); + /* write private metadata file under ~/.geeqie */ + + /* If an existing metadata file exists, we will try writing to + * it's location regardless of the user's preference. + */ + gchar *metadata_path = cache_find_location(CACHE_TYPE_XMP_METADATA, fd->path); + if (!metadata_path) metadata_path = cache_find_location(CACHE_TYPE_METADATA, fd->path); + + if (metadata_path && !access_file(metadata_path, W_OK)) + { + g_free(metadata_path); + metadata_path = NULL; + } + + if (!metadata_path) + { + mode_t mode = 0755; + + dest_dir = cache_get_location(CACHE_TYPE_METADATA, fd->path, FALSE, &mode); + if (recursive_mkdir_if_not_exists(dest_dir, mode)) + { + gchar *filename = g_strconcat(fd->name, options->metadata.save_legacy_format ? GQ_CACHE_EXT_METADATA : GQ_CACHE_EXT_XMP_METADATA, NULL); + + metadata_path = g_build_filename(dest_dir, filename, NULL); + g_free(filename); + } + } + if (access_file(metadata_path, W_OK) || (!isname(metadata_path) && access_file(dest_dir, W_OK))) + { + file_data_update_ci_dest(fd, metadata_path); + have_dest = TRUE; + } + else + { + ret |= CHANGE_NO_WRITE_PERM_DEST; + DEBUG_1("Change checked: file is not writable: %s", metadata_path); + } + g_free(metadata_path); } + g_free(dest_dir); } - if (fd->change->dest) + if (fd->change->dest && fd->change->type != FILEDATA_CHANGE_WRITE_METADATA) { gboolean same; gchar *dest_dir;