# HG changeset patch # User nadvornik # Date 1210020711 0 # Node ID 2b7b966f61cf62c14b004ec1383a47a4d3ec1863 # Parent 46ddfaf13235513e95b68b3e1c3e7cea06548e76 started implementation of API for sidecar files diff -r 46ddfaf13235 -r 2b7b966f61cf src/filedata.c --- a/src/filedata.c Mon May 05 20:51:50 2008 +0000 +++ b/src/filedata.c Mon May 05 20:51:51 2008 +0000 @@ -887,3 +887,365 @@ return list; } + + + +/* + * file_data - operates on the given fd + * file_data_sc - operates on the given fd + sidecars - all fds linked via fd->sidecar_files or fd->parent + */ + + +/* return list of sidecar file extensions in a string */ +gchar *file_data_sc_list_to_string(FileData *fd); // now gchar *sidecar_file_data_list_to_string(FileData *fd) + + +/* disables / enables grouping for particular file, sends UPDATE notification */ +void file_data_disable_grouping(FileData *fd); // now file_data_disconnect_sidecar_file, broken +void file_data_disable_grouping(FileData *fd); + +/* runs stat on a file and sends UPDATE notification if it has been changed */ +void file_data_sc_update(FileData *fd); + + + + +/* + * add FileDataChangeInfo (see typedefs.h) for the given operation + * uses file_data_add_change_info + * + * fails if the fd->change already exists - change operations can't run in parallel + * fd->change_info works as a lock + * + * dest can be NULL - in this case the current name is used for now, it will + * be changed later + */ + +/* + FileDataChangeInfo types: + COPY + MOVE - patch is changed, name may be changed too + RENAME - path remains unchanged, name is changed + extension should remain (FIXME should we allow editing extension? it will make problems wth grouping) + sidecar names are changed too, extensions are not changed + DELETE + UPDATE - file size, date or grouping has been changed +*/ + +gboolean file_data_add_ci(FileData *fd, FileDataChangeType type, const gchar *src, const gchar *dest) +{ + + FileDataChangeInfo *fdci; + + if (fd->change) return FALSE; + + fdci = g_new0(FileDataChangeInfo, 1); + + fdci->type = type; + + if (src) + fdci->source = g_strdup(src); + else + fdci->source = g_strdup(fd->path); + + if (dest) + fdci->dest = g_strdup(dest); + + fd->change = fdci; + + return TRUE; +} + +void file_data_free_ci(FileData *fd) +{ + FileDataChangeInfo *fdci = fd->change; + + if (!fdci) + return; + + g_free(fdci->source); + g_free(fdci->dest); + + g_free(fdci); + + fd->change = NULL; +} + + +static gboolean file_data_sc_add_ci(FileData *fd, FileDataChangeType type) +{ + GList *work; + if (fd->parent) fd = fd->parent; + + if (fd->change) return FALSE; + work = fd->sidecar_files; + while (work) + { + FileData *sfd = work->data; + if (sfd->change) return FALSE; + work = work->next; + } + + file_data_add_ci(fd, type, NULL, NULL); + + work = fd->sidecar_files; + while (work) + { + FileData *sfd = work->data; + file_data_add_ci(sfd, type, NULL, NULL); + work = work->next; + } + + return TRUE; +} + +static gboolean file_data_sc_check_ci(FileData *fd, FileDataChangeType type) +{ + GList *work; + if (fd->parent) fd = fd->parent; + + if (!fd->change) return FALSE; + if (fd->change->type != type) return FALSE; + work = fd->sidecar_files; + while (work) + { + FileData *sfd = work->data; + if (!sfd->change) return FALSE; + if (sfd->change->type != type) return FALSE; + work = work->next; + } + return TRUE; +} + + +gboolean file_data_sc_add_ci_copy(FileData *fd, gchar *dest_path) +{ + if (!file_data_sc_add_ci(fd, FILEDATA_CHANGE_COPY)) return FALSE; + file_data_sc_update_ci_copy(fd, dest_path); + return TRUE; +} + +gboolean file_data_sc_add_ci_move(FileData *fd, gchar *dest_path) +{ + if (!file_data_sc_add_ci(fd, FILEDATA_CHANGE_MOVE)) return FALSE; + file_data_sc_update_ci_move(fd, dest_path); + return TRUE; +} + +gboolean file_data_sc_add_ci_rename(FileData *fd, gchar *dest_path) +{ + if (!file_data_sc_add_ci(fd, FILEDATA_CHANGE_RENAME)) return FALSE; + file_data_sc_update_ci_rename(fd, dest_path); + return TRUE; +} + +gboolean file_data_sc_add_ci_delete(FileData *fd) +{ + return file_data_sc_add_ci(fd, FILEDATA_CHANGE_DELETE); +} + +gboolean file_data_sc_add_ci_update(FileData *fd) +{ + return file_data_sc_add_ci(fd, FILEDATA_CHANGE_UPDATE); +} + +void file_data_sc_free_ci(FileData *fd) +{ + GList *work; + if (fd->parent) fd = fd->parent; + + file_data_free_ci(fd); + + work = fd->sidecar_files; + while (work) + { + FileData *sfd = work->data; + file_data_free_ci(sfd); + work = work->next; + } +} + + +/* + * update existing fd->change, it will be used from dialog callbacks for interactive editing + * fails if fd->change does not exist or the change type does not match + */ + +static void file_data_update_ci_dest(FileData *fd, gchar *dest_path) +{ + g_free(fd->change->dest); + fd->change->dest = g_strdup(dest_path); +} + +static void file_data_update_ci_dest_preserve_ext(FileData *fd, gchar *dest_path) +{ + const char *extension = extension_from_path(fd->change->source); + g_free(fd->change->dest); + fd->change->dest = g_strdup_printf("%*s%s", (int)(extension_from_path(dest_path) - dest_path), dest_path, extension); +} + +static void file_data_sc_update_ci(FileData *fd, gchar *dest_path) +{ + GList *work; + if (fd->parent) fd = fd->parent; + + file_data_update_ci_dest(fd, dest_path); + work = fd->sidecar_files; + while (work) + { + FileData *sfd = work->data; + file_data_update_ci_dest_preserve_ext(sfd, dest_path); + work = work->next; + } +} + +gint file_data_sc_update_ci_copy(FileData *fd, gchar *dest_path) +{ + if (!file_data_sc_check_ci(fd, FILEDATA_CHANGE_COPY)) return FALSE; + file_data_sc_update_ci(fd, dest_path); + return TRUE; +} + +gint file_data_sc_update_ci_move(FileData *fd, gchar *dest_path) +{ + if (!file_data_sc_check_ci(fd, FILEDATA_CHANGE_MOVE)) return FALSE; + file_data_sc_update_ci(fd, dest_path); + return TRUE; +} + +gint file_data_sc_update_ci_rename(FileData *fd, gchar *dest_path) +{ + if (!file_data_sc_check_ci(fd, FILEDATA_CHANGE_RENAME)) return FALSE; + file_data_sc_update_ci(fd, dest_path); + return TRUE; +} + + + +/* + * check dest paths - dest image exists, etc. + * returns FIXME + * it should detect all possible problems with the planned operation + */ + +gint file_data_sc_check_ci_dest(FileData *fd) +{ +} + + + + +/* + * perform the change described by FileFataChangeInfo + * it is used for internal operations, + * this function actually operates with files on the filesystem + * it should implement safe delete + */ + +static gboolean file_data_perform_move(FileData *fd) +{ + g_assert(!strcmp(fd->change->source, fd->path)); + return move_file(fd->change->source, fd->change->dest); +} + +static gboolean file_data_perform_copy(FileData *fd) +{ + g_assert(!strcmp(fd->change->source, fd->path)); + return copy_file(fd->change->source, fd->change->dest); +} + +static gboolean file_data_perform_delete(FileData *fd) +{ + return unlink_file(fd->path); +} + +static gboolean file_data_perform_ci(FileData *fd) +{ + FileDataChangeType type = fd->change->type; + switch (type) + { + case FILEDATA_CHANGE_MOVE: + return file_data_perform_move(fd); + case FILEDATA_CHANGE_COPY: + return file_data_perform_copy(fd); + case FILEDATA_CHANGE_RENAME: + return file_data_perform_move(fd); /* the same as move */ + case FILEDATA_CHANGE_DELETE: + return file_data_perform_delete(fd); + case FILEDATA_CHANGE_UPDATE: + /* notring to do here */ + break; + } + return TRUE; +} + + + +gboolean file_data_sc_perform_ci(FileData *fd) +{ + GList *work; + gboolean ret = TRUE; + FileDataChangeType type = fd->change->type; + if (!file_data_sc_check_ci(fd, type)) return FALSE; + + work = fd->sidecar_files; + while (work) + { + FileData *sfd = work->data; + if (!file_data_perform_ci(sfd)) ret = FALSE; + work = work->next; + } + if (!file_data_perform_ci(fd)) ret = FALSE; + return ret; +} + +/* + * updates FileData structure according to FileDataChangeInfo + */ + +static void file_data_apply_ci(FileData *fd) +{ + FileDataChangeType type = fd->change->type; + /* FIXME delete ?*/ + if (type == FILEDATA_CHANGE_MOVE || type == FILEDATA_CHANGE_COPY || type == FILEDATA_CHANGE_RENAME) + { + g_free(fd->path); + g_hash_table_remove(file_data_pool, fd->original_path); + g_free(fd->original_path); + file_data_set_path(fd, fd->change->dest); + fd->original_path = g_strdup(fd->change->dest); + g_hash_table_insert(file_data_pool, fd->original_path, fd); + } +} + +gint file_data_sc_apply_ci(FileData *fd) // now file_data_do_change +{ + GList *work; + FileDataChangeType type = fd->change->type; + if (!file_data_sc_check_ci(fd, type)) return FALSE; + + work = fd->sidecar_files; + while (work) + { + FileData *sfd = work->data; + file_data_apply_ci(sfd); + work = work->next; + } + file_data_apply_ci(fd); + return TRUE; +} + + +/* + * notify other modules about the change described by FileFataChangeInfo + */ + +/* might use file_maint_ functions for now, later it should be changed to a system of callbacks + FIXME do we need the ignore_list? It looks like a workaround for ineffective + implementation in view_file_list.c */ + +void file_data_sc_send_notification(FileData *fd) +{ +} + + diff -r 46ddfaf13235 -r 2b7b966f61cf src/filedata.h --- a/src/filedata.h Mon May 05 20:51:50 2008 +0000 +++ b/src/filedata.h Mon May 05 20:51:51 2008 +0000 @@ -49,4 +49,18 @@ GList *filelist_sort_path(GList *list); GList *filelist_recursive(const gchar *path); +gchar *file_data_sc_list_to_string(FileData *fd); +gboolean file_data_add_ci(FileData *fd, FileDataChangeType type, const gchar *src, const gchar *dest); +gboolean file_data_sc_add_ci_copy(FileData *fd, gchar *dest_path); +gboolean file_data_sc_add_ci_move(FileData *fd, gchar *dest_path); +gboolean file_data_sc_add_ci_rename(FileData *fd, gchar *dest_path); +gboolean file_data_sc_add_ci_delete(FileData *fd); +gboolean file_data_sc_add_ci_update(FileData *fd); +gint file_data_sc_update_ci_copy(FileData *fd, gchar *dest_path); +gint file_data_sc_update_ci_move(FileData *fd, gchar *dest_path); +gint file_data_sc_update_ci_rename(FileData *fd, gchar *dest_path); +gint file_data_sc_check_ci_dest(FileData *fd); +gboolean file_data_sc_perform_ci(FileData *fd); +gint file_data_sc_apply_ci(FileData *fd); + #endif diff -r 46ddfaf13235 -r 2b7b966f61cf src/typedefs.h --- a/src/typedefs.h Mon May 05 20:51:50 2008 +0000 +++ b/src/typedefs.h Mon May 05 20:51:51 2008 +0000 @@ -91,7 +91,8 @@ FILEDATA_CHANGE_DELETE, FILEDATA_CHANGE_MOVE, FILEDATA_CHANGE_RENAME, - FILEDATA_CHANGE_COPY + FILEDATA_CHANGE_COPY, + FILEDATA_CHANGE_UPDATE } FileDataChangeType; typedef enum {