# HG changeset patch # User nadvornik # Date 1195597720 0 # Node ID 8be2cc6873044d18c433325787157cde9cd48af8 # Parent 2310066cc55ac9cdf2797ed61a06fe5a09cfca21 fixed grouping sidecar files and made it configurable via config file (no gui yet) diff -r 2310066cc55a -r 8be2cc687304 src/filelist.c --- a/src/filelist.c Mon Oct 22 19:58:47 2007 +0000 +++ b/src/filelist.c Tue Nov 20 22:28:40 2007 +0000 @@ -27,6 +27,7 @@ static GList *filter_list = NULL; static GList *extension_list = NULL; +static GList *sidecar_ext_list = NULL; gint ishidden(const gchar *name) { @@ -403,6 +404,63 @@ return list; } + +/* + *----------------------------------------------------------------------------- + * sidecar extension list + *----------------------------------------------------------------------------- + */ + +static GList *sidecar_ext_get_list(void) +{ + return sidecar_ext_list; +} + +void sidecar_ext_parse(const gchar *text) +{ + GList *work; + gchar *value; + + work = sidecar_ext_list; + while (work) + { + gchar *ext = work->data; + work = work->next; + g_free(ext); + } + g_list_free(sidecar_ext_list); + sidecar_ext_list = NULL; + + value = quoted_value(text); + + if (value == NULL) return; + + sidecar_ext_list = filter_to_list(value); + + g_free(value); +} + +void sidecar_ext_write(FILE *f) +{ + GList *work; + fprintf(f, "\nsidecar_ext: \""); + + work = sidecar_ext_list; + while (work) + { + gchar *ext = work->data; + work = work->next; + fprintf(f, "%s%s", ext, work ? ";" : ""); + } + fprintf(f, "\"\n"); + +} + +void sidecar_ext_add_defaults() +{ + sidecar_ext_parse("\".jpg;.cr2;.nef;.crw\""); +} + /* *----------------------------------------------------------------------------- * path list recursive @@ -569,6 +627,9 @@ *----------------------------------------------------------------------------- */ +FileData *file_data_merge_sidecar_files(FileData *target, FileData *source); + + static void file_data_set_path(FileData *fd, const gchar *path) { @@ -603,15 +664,17 @@ } fd->extension = extension_from_path(fd->path); + if (fd->extension == NULL) + fd->extension = fd->name + strlen(fd->name); } static GHashTable *file_data_pool = NULL; -FileData *file_data_new(const gchar *path_utf8, struct stat *st) +static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean check_sidecars) { FileData *fd; - printf("file_data_new: '%s'\n", path_utf8); + printf("file_data_new: '%s' %d\n", path_utf8, check_sidecars); if (!file_data_pool) file_data_pool = g_hash_table_new (g_str_hash, g_str_equal); @@ -637,13 +700,59 @@ g_hash_table_insert(file_data_pool, fd->original_path, fd); + if (check_sidecars && sidecar_file_priority(fd->extension)) + { + int i = 0; + int base_len = fd->extension - fd->path; + GString *fname = g_string_new_len(fd->path, base_len); + FileData *parent_fd = NULL; + GList *work = sidecar_ext_get_list(); + while (work) + { + /* check for possible sidecar files; + the sidecar files created here are referenced only via fd->sidecar_files or fd->parent, + they have fd->ref set to 0 and file_data unref must chack and free them all together + (using fd->ref would cause loops and leaks) + */ + + FileData *new_fd; + + gchar *ext = work->data; + work = work->next; + + if (strcmp(ext, fd->extension) == 0) + { + new_fd = fd; /* processing the original file */ + } + else + { + struct stat nst; + g_string_truncate(fname, base_len); + g_string_append(fname, ext); + + if (!stat_utf8(fname->str, &nst)) + continue; + + new_fd = file_data_new(fname->str, &nst, FALSE); + new_fd->ref--; /* do not use ref here */ + } + + if (!parent_fd) + parent_fd = new_fd; /* parent is the one with the highest prio, found first */ + else + file_data_merge_sidecar_files(parent_fd, new_fd); + + } + g_string_free(fname, TRUE); + } + return fd; } -FileData *file_data_new_local(const gchar *path, struct stat *st) +static FileData *file_data_new_local(const gchar *path, struct stat *st, gboolean check_sidecars) { gchar *path_utf8 = path_to_utf8(path); - FileData *ret = file_data_new(path_utf8, st); + FileData *ret = file_data_new(path_utf8, st, check_sidecars); g_free(path_utf8); return ret; } @@ -658,12 +767,12 @@ st.st_mtime = 0; } - return file_data_new(path_utf8, &st); + return file_data_new(path_utf8, &st, TRUE); } FileData *file_data_add_sidecar_file(FileData *target, FileData *sfd) { - target->sidecar_files = g_list_append(target->sidecar_files, file_data_ref(sfd)); + target->sidecar_files = g_list_append(target->sidecar_files, sfd); sfd->parent = target; return target; } @@ -687,33 +796,6 @@ return target; } - -void file_data_free(FileData *fd) -{ - GList *work; - - g_assert(fd->magick == 0x12345678); - g_assert(fd->ref == 0 || fd->ref == 1); - - g_hash_table_remove(file_data_pool, fd->original_path); - - g_free(fd->path); - g_free(fd->original_path); - if (fd->pixbuf) g_object_unref(fd->pixbuf); - - work = fd->sidecar_files; - while (work) - { - FileData *sfd = work->data; - sfd->parent = NULL; - work = work->next; - } - filelist_free(fd->sidecar_files); - - file_data_change_info_free(NULL, fd); - g_free(fd); -} - FileData *file_data_ref(FileData *fd) { if (fd == NULL) return NULL; @@ -723,13 +805,67 @@ fd->ref++; return fd; } + +static void file_data_free(FileData *fd) +{ + g_assert(fd->magick == 0x12345678); + g_assert(fd->ref == 0); + + g_hash_table_remove(file_data_pool, fd->original_path); + + g_free(fd->path); + g_free(fd->original_path); + if (fd->pixbuf) g_object_unref(fd->pixbuf); + + + g_assert(fd->sidecar_files == NULL); /* sidecar files must be freed before calling this */ + + file_data_change_info_free(NULL, fd); + g_free(fd); +} + void file_data_unref(FileData *fd) { if (fd == NULL) return; g_assert(fd->magick == 0x12345678); + printf("file_data_unref: '%s'\n", fd->path); fd->ref--; if (fd->ref == 0) - file_data_free(fd); + { + FileData *parent = fd->parent ? fd->parent : fd; + + GList *work; + + if (parent->ref > 0) + return; + + work = parent->sidecar_files; + while (work) + { + FileData *sfd = work->data; + if (sfd->ref > 0) + return; + work = work->next; + } + + /* none of parent/children is referenced, we can free everything */ + + printf("file_data_unref: '%s', parent '%s'\n", fd->path, parent->path); + + work = parent->sidecar_files; + while (work) + { + FileData *sfd = work->data; + file_data_free(sfd); + work = work->next; + } + + g_list_free(parent->sidecar_files); + parent->sidecar_files = NULL; + + file_data_free(parent); + + } } /* compare name without extension */ @@ -746,6 +882,7 @@ FileData *file_data_do_change(FileData *fd) { +//FIXME sidecars g_assert(fd->change); g_free(fd->path); g_hash_table_remove(file_data_pool, fd->original_path); @@ -806,25 +943,23 @@ */ + gint sidecar_file_priority(const gchar *path) { const char *extension = extension_from_path(path); + int i = 1; + GList *work; + if (extension == NULL) + return 0; - printf("prio %s >%s<\n", path, extension); + work = sidecar_ext_get_list(); - if (strcmp(extension, ".jpg") == 0) return 1; - - if (strcmp(extension, ".cr2") == 0) return 1001; - if (strcmp(extension, ".crw") == 0) return 1002; - if (strcmp(extension, ".nef") == 0) return 1003; - if (strcmp(extension, ".raw") == 0) return 1004; - - - if (strcmp(extension, ".vaw") == 0) return 2001; - if (strcmp(extension, ".mp3") == 0) return 2002; - - if (strcmp(extension, ".xmp") == 0) return 3002; - + while (work) { + gchar *ext = work->data; + work = work->next; + if (strcmp(extension, ext) == 0) return i; + i++; + } return 0; } @@ -966,42 +1101,17 @@ strcmp(name, GQVIEW_CACHE_LOCAL_METADATA) != 0 && strcmp(name, THUMB_FOLDER_LOCAL) != 0) { - dlist = g_list_prepend(dlist, file_data_new_local(filepath, &ent_sbuf)); + dlist = g_list_prepend(dlist, file_data_new_local(filepath, &ent_sbuf, FALSE)); } } else { if ((files) && filter_name_exists(name)) { - FileData *fd = file_data_new_local(filepath, &ent_sbuf); - - GList *same = g_list_find_custom(flist, fd, (GCompareFunc) file_data_compare_name_without_ext); - - int p1 = 0; - int p2 = 0; - FileData *samefd = NULL; + FileData *fd = file_data_new_local(filepath, &ent_sbuf, TRUE); - if (same) - { - samefd = (FileData *) same->data; - p1 = sidecar_file_priority(samefd->name); - p2 = sidecar_file_priority(fd->name); - printf("same %s %s %d %d\n", fd->name, samefd->name, p2, p1); - } - - if (p1 && p2) - { - if (p1 < p2) - { - file_data_merge_sidecar_files(samefd, fd); - } - else - { - file_data_merge_sidecar_files(fd, samefd); - flist = g_list_delete_link(flist, same); - flist = g_list_prepend(flist, fd); - } - } + if (fd->parent) + file_data_unref(fd); else flist = g_list_prepend(flist, fd); } diff -r 2310066cc55a -r 8be2cc687304 src/filelist.h --- a/src/filelist.h Mon Oct 22 19:58:47 2007 +0000 +++ b/src/filelist.h Tue Nov 20 22:28:40 2007 +0000 @@ -37,6 +37,10 @@ void filter_write_list(FILE *f); void filter_parse(const gchar *text); +void sidecar_ext_parse(const gchar *text); +void sidecar_ext_write(FILE *f); +void sidecar_ext_add_defaults(); + gint ishidden(const gchar *name); @@ -49,13 +53,9 @@ gchar *text_from_size_abrev(gint64 size); const gchar *text_from_time(time_t t); -/* this expects a locale encoded path */ -FileData *file_data_new_local(const gchar *path, struct stat *st); -/* this expects a utf-8 path */ -FileData *file_data_new(const gchar *path_utf8, struct stat *st); /* this expects a utf-8 path */ FileData *file_data_new_simple(const gchar *path_utf8); -void file_data_free(FileData *fd); + FileData *file_data_ref(FileData *fd); void file_data_unref(FileData *fd); diff -r 2310066cc55a -r 8be2cc687304 src/main.c --- a/src/main.c Mon Oct 22 19:58:47 2007 +0000 +++ b/src/main.c Tue Nov 20 22:28:40 2007 +0000 @@ -1297,6 +1297,8 @@ keys_load(); filter_add_defaults(); filter_rebuild(); + + sidecar_ext_add_defaults(); buf = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/accels", NULL); bufl = path_from_utf8(buf); diff -r 2310066cc55a -r 8be2cc687304 src/rcfile.c --- a/src/rcfile.c Mon Oct 22 19:58:47 2007 +0000 +++ b/src/rcfile.c Tue Nov 20 22:28:40 2007 +0000 @@ -304,6 +304,8 @@ write_bool_option(f, "show_dotfiles", show_dot_files); write_bool_option(f, "disable_filtering", file_filter_disable); filter_write_list(f); + + sidecar_ext_write(f); fprintf(f,"\n##### Color Profiles #####\n\n"); @@ -581,6 +583,11 @@ filter_parse(value_all); } + if (strcasecmp(option, "sidecar_ext") == 0) + { + sidecar_ext_parse(value_all); + } + /* Color Profiles */ color_profile_enabled = read_bool_option(f, option, diff -r 2310066cc55a -r 8be2cc687304 src/view_dir_tree.c --- a/src/view_dir_tree.c Mon Oct 22 19:58:47 2007 +0000 +++ b/src/view_dir_tree.c Tue Nov 20 22:28:40 2007 +0000 @@ -1080,14 +1080,12 @@ while (target_path[n] != '\0' && target_path[n] != '/') n++; name8 = g_strndup(target_path, n); - namel = path_from_utf8(name8); if (stat_utf8(name8, &sbuf)) { - list = g_list_prepend(list, file_data_new_local(namel, &sbuf)); + list = g_list_prepend(list, file_data_new_simple(name8)); } - g_free(namel); g_free(name8); } }