rename file_data_new_simple to file_data_new_group, filedata.c cleanup
authorVladimir Nadvornik <nadvornik@suse.cz>
Tue, 4 Oct 2011 20:09:55 +0000 (22:09 +0200)
committerVladimir Nadvornik <nadvornik@suse.cz>
Tue, 4 Oct 2011 20:09:55 +0000 (22:09 +0200)
14 files changed:
src/bar_sort.c
src/collect-io.c
src/filedata.c
src/filedata.h
src/layout.c
src/main.c
src/metadata.c
src/pan-timeline.c
src/pan-view.c
src/remote.c
src/search.c
src/thumb_standard.c
src/utilops.c
src/view_file_list.c

index 5ca17ca..5e284d6 100644 (file)
@@ -205,18 +205,18 @@ static void bar_sort_undo_folder(SortData *sd, GtkWidget *button)
                        GList *list;
                        gchar *src_dir;
 
-                       list = g_list_append(NULL, file_data_new_simple(sd->undo_dest));
+                       list = g_list_append(NULL, file_data_new_group(sd->undo_dest));
                        src_dir = remove_level_from_path(sd->undo_src);
                        file_util_move_simple(list, src_dir, sd->lw->window);
                        g_free(src_dir);
                        }
                        break;
                case BAR_SORT_COPY:
-                       file_util_delete(file_data_new_simple(sd->undo_dest), NULL, button);
+                       file_util_delete(file_data_new_group(sd->undo_dest), NULL, button);
                        break;
                default:
                        /* undo external command */
-                       file_util_delete(file_data_new_simple(sd->undo_dest), NULL, button);
+                       file_util_delete(file_data_new_group(sd->undo_dest), NULL, button);
                        break;
                }
 
@@ -224,7 +224,7 @@ static void bar_sort_undo_folder(SortData *sd, GtkWidget *button)
 
        if (isfile(sd->undo_src))
                {
-               layout_image_set_fd(sd->lw, file_data_new_simple(sd->undo_src));
+               layout_image_set_fd(sd->lw, file_data_new_group(sd->undo_src));
                }
 
        bar_sort_undo_set(sd, NULL, NULL, NULL);
@@ -241,7 +241,7 @@ static void bar_sort_undo_collection(SortData *sd)
 
                source = work->data;
                work = work->next;
-               collect_manager_remove(file_data_new_simple(source), sd->undo_dest);
+               collect_manager_remove(file_data_new_group(source), sd->undo_dest);
                }
 
        bar_sort_undo_set(sd, NULL, NULL, NULL);
index 3f0b09c..a2f5ba3 100644 (file)
@@ -160,7 +160,7 @@ static gboolean collection_load_private(CollectionData *cd, const gchar *path, C
                        if (!flush)
                                changed |= collect_manager_process_action(entry, &buf);
 
-                       valid = (buf[0] == G_DIR_SEPARATOR && collection_add_check(cd, file_data_new_simple(buf), FALSE, TRUE));
+                       valid = (buf[0] == G_DIR_SEPARATOR && collection_add_check(cd, file_data_new_group(buf), FALSE, TRUE));
                        if (!valid) DEBUG_1("collection invalid file: %s", buf);
 
                        total++;
@@ -190,7 +190,7 @@ static gboolean collection_load_private(CollectionData *cd, const gchar *path, C
                gchar *buf = NULL;
                while (collect_manager_process_action(entry, &buf))
                        {
-                       collection_add_check(cd, file_data_new_simple(buf), FALSE, TRUE);
+                       collection_add_check(cd, file_data_new_group(buf), FALSE, TRUE);
                        changed = TRUE;
                        g_free(buf);
                        buf = NULL;
index 7681587..b7f260d 100644 (file)
@@ -28,7 +28,9 @@ static GHashTable *file_data_pool = NULL;
 static GHashTable *file_data_planned_change_hash = NULL;
 
 static gint sidecar_file_priority(const gchar *extension);
-static FileData *file_data_new_local(const gchar *path, struct stat *st, gboolean disable_sidecars);
+static void file_data_check_sidecars(const GList *basename_list);
+static FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd);
+
 
 
 /*
@@ -133,15 +135,10 @@ const gchar *text_from_time(time_t t)
 
 /*
  *-----------------------------------------------------------------------------
- * file info struct
+ * changed files detection and notification 
  *-----------------------------------------------------------------------------
  */
 
-static FileData *file_data_merge_sidecar_files(FileData *target, FileData *source);
-static void file_data_check_sidecars(const GList *basename_list);
-FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd);
-
-
 void file_data_increment_version(FileData *fd)
 {
        fd->version++;
@@ -153,76 +150,99 @@ void file_data_increment_version(FileData *fd)
                }
 }
 
-static gint file_data_sort_by_ext(gconstpointer a, gconstpointer b)
+static gboolean file_data_check_changed_single_file(FileData *fd, struct stat *st)
 {
-       const FileData *fda = a;
-       const FileData *fdb = b;
-       
-       if (fda->sidecar_priority < fdb->sidecar_priority) return -1;
-       if (fda->sidecar_priority > fdb->sidecar_priority) return 1;
-       
-       return strcmp(fdb->extension, fda->extension);
-}
-
-static GHashTable *file_data_basename_hash_new(void)
-{
-       return g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+       if (fd->size != st->st_size ||
+           fd->date != st->st_mtime)
+               {
+               fd->size = st->st_size;
+               fd->date = st->st_mtime;
+               fd->mode = st->st_mode;
+               if (fd->thumb_pixbuf) g_object_unref(fd->thumb_pixbuf);
+               fd->thumb_pixbuf = NULL;
+               file_data_increment_version(fd);
+               file_data_send_notification(fd, NOTIFY_REREAD);
+               return TRUE;
+               }
+       return FALSE;
 }
 
-static GList * file_data_basename_hash_insert(GHashTable *basename_hash, FileData *fd)
+static gboolean file_data_check_changed_files_recursive(FileData *fd, struct stat *st)
 {
-       GList *list;
-       gchar *basename = g_strndup(fd->path, fd->extension - fd->path);
-
-       list = g_hash_table_lookup(basename_hash, basename);
+       gboolean ret = FALSE;
+       GList *work;
        
-       if (!g_list_find(list, fd))
-               {
-               list = g_list_insert_sorted(list, file_data_ref(fd), file_data_sort_by_ext);
-               g_hash_table_insert(basename_hash, basename, list);
-               }
-       else 
+       ret = file_data_check_changed_single_file(fd, st);
+
+       work = fd->sidecar_files;
+       while (work)
                {
-               g_free(basename);
+               FileData *sfd = work->data;
+               struct stat st;
+               work = work->next;
+
+               if (!stat_utf8(sfd->path, &st))
+                       {
+                       fd->size = 0;
+                       fd->date = 0;
+                       file_data_disconnect_sidecar_file(fd, sfd);
+                       ret = TRUE;
+                       continue;
+                       }
+
+               ret |= file_data_check_changed_files_recursive(sfd, &st);
                }
-       return list;
+       return ret;
 }
 
-#if 0
-static void file_data_basename_hash_remove(GHashTable *basename_hash, FileData *fd)
+
+gboolean file_data_check_changed_files(FileData *fd)
 {
-       GList *list;
-       gchar *basename = g_strndup(fd->path, fd->extension - fd->path);
-       
-       list = g_hash_table_lookup(basename_hash, basename);
-       
-       if (!g_list_find(list, fd)) return;
-       
-       list = g_list_remove(list, fd);
-       file_data_unref(fd);
+       gboolean ret = FALSE;
+       struct stat st;
        
-       if (list)
+       if (fd->parent) fd = fd->parent;
+
+       if (!stat_utf8(fd->path, &st))
                {
-               g_hash_table_insert(basename_hash, basename, list);
+               GList *sidecars;
+               GList *work;
+               FileData *sfd = NULL;
+
+               /* parent is missing, we have to rebuild whole group */
+               ret = TRUE;
+               fd->size = 0;
+               fd->date = 0;
+               
+               /* file_data_disconnect_sidecar_file might delete the file,
+                  we have to keep the reference to prevent this */
+               sidecars = filelist_copy(fd->sidecar_files);
+               work = sidecars;
+               while (work)
+                       {
+                       sfd = work->data;
+                       work = work->next;
+               
+                       file_data_disconnect_sidecar_file(fd, sfd);
+                       }
+               file_data_check_sidecars(sidecars); /* this will group the sidecars back together */
+               /* now we can release the sidecars */
+               filelist_free(sidecars);
+               file_data_send_notification(fd, NOTIFY_REREAD);
                }
-       else 
+       else
                {
-               g_hash_table_remove(basename_hash, basename);
-               g_free(basename);
+               ret |= file_data_check_changed_files_recursive(fd, &st);
                }
-}
-#endif
 
-static void file_data_basename_hash_remove_list(gpointer key, gpointer value, gpointer data)
-{
-       filelist_free((GList *)value);
+       return ret;
 }
 
-static void file_data_basename_hash_free(GHashTable *basename_hash)
-{
-       g_hash_table_foreach(basename_hash, file_data_basename_hash_remove_list, NULL); 
-       g_hash_table_destroy(basename_hash);
-}
+/*
+ *-----------------------------------------------------------------------------
+ * file name, extension, sorting, ... 
+ *-----------------------------------------------------------------------------
+ */
 
 static void file_data_set_collate_keys(FileData *fd)
 {
@@ -304,93 +324,11 @@ static void file_data_set_path(FileData *fd, const gchar *path)
        file_data_set_collate_keys(fd);
 }
 
-static gboolean file_data_check_changed(FileData *fd, struct stat *st)
-{
-       if (fd->size != st->st_size ||
-           fd->date != st->st_mtime)
-               {
-               fd->size = st->st_size;
-               fd->date = st->st_mtime;
-               fd->mode = st->st_mode;
-               if (fd->thumb_pixbuf) g_object_unref(fd->thumb_pixbuf);
-               fd->thumb_pixbuf = NULL;
-               file_data_increment_version(fd);
-               file_data_send_notification(fd, NOTIFY_REREAD);
-               return TRUE;
-               }
-       return FALSE;
-}
-
-static gboolean file_data_check_changed_files_recursive(FileData *fd, struct stat *st)
-{
-       gboolean ret = FALSE;
-       GList *work;
-       
-       ret = file_data_check_changed(fd, st);
-
-       work = fd->sidecar_files;
-       while (work)
-               {
-               FileData *sfd = work->data;
-               struct stat st;
-               work = work->next;
-
-               if (!stat_utf8(sfd->path, &st))
-                       {
-                       fd->size = 0;
-                       fd->date = 0;
-                       file_data_disconnect_sidecar_file(fd, sfd);
-                       ret = TRUE;
-                       continue;
-                       }
-
-               ret |= file_data_check_changed_files_recursive(sfd, &st);
-               }
-       return ret;
-}
-
-
-gboolean file_data_check_changed_files(FileData *fd)
-{
-       gboolean ret = FALSE;
-       struct stat st;
-       
-       if (fd->parent) fd = fd->parent;
-
-       if (!stat_utf8(fd->path, &st))
-               {
-               GList *sidecars;
-               GList *work;
-               FileData *sfd = NULL;
-
-               /* parent is missing, we have to rebuild whole group */
-               ret = TRUE;
-               fd->size = 0;
-               fd->date = 0;
-               
-               /* file_data_disconnect_sidecar_file might delete the file,
-                  we have to keep the reference to prevent this */
-               sidecars = filelist_copy(fd->sidecar_files);
-               work = sidecars;
-               while (work)
-                       {
-                       sfd = work->data;
-                       work = work->next;
-               
-                       file_data_disconnect_sidecar_file(fd, sfd);
-                       }
-               file_data_check_sidecars(sidecars); /* this will group the sidecars back together */
-               /* now we can release the sidecars */
-               filelist_free(sidecars);
-               file_data_send_notification(fd, NOTIFY_REREAD);
-               }
-       else
-               {
-               ret |= file_data_check_changed_files_recursive(fd, &st);
-               }
-
-       return ret;
-}
+/*
+ *-----------------------------------------------------------------------------
+ * create or reuse Filedata
+ *-----------------------------------------------------------------------------
+ */
 
 static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean disable_sidecars)
 {
@@ -427,7 +365,7 @@ static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean
                if (disable_sidecars) file_data_disable_grouping(fd, TRUE);
                
                
-               changed = file_data_check_changed(fd, st);
+               changed = file_data_check_changed_single_file(fd, st);
 
                DEBUG_2("file_data_pool hit: '%s' %s", fd->path, changed ? "(changed)" : "");
                
@@ -449,41 +387,6 @@ static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean
        return fd;
 }
 
-
-static void file_data_check_sidecars(const GList *basename_list)
-{
-       GList *work;
-       FileData *parent_fd;
-       if (!basename_list) return;
-       /* process the group list - the first one is the parent file, others are sidecars */
-       parent_fd = basename_list->data;
-       work = basename_list->next;
-       while (work)
-               {
-               FileData *sfd = work->data;
-               work = work->next;
-
-               file_data_merge_sidecar_files(parent_fd, sfd);
-               }
-               
-       /* there may be some sidecars that are already deleted - disconnect them */
-       work = parent_fd->sidecar_files;
-       while (work)
-               {
-               FileData *sfd = work->data;
-               work = work->next;
-               
-               if (!g_list_find((GList *)basename_list, sfd)) 
-                       {
-                       printf("removing unknown %s: %s \n", parent_fd->path, sfd->path);
-                       file_data_disconnect_sidecar_file(parent_fd, sfd);
-                       file_data_send_notification(sfd, NOTIFY_REREAD);
-                       file_data_send_notification(parent_fd, NOTIFY_REREAD);
-                       }
-               }
-}
-
-
 static FileData *file_data_new_local(const gchar *path, struct stat *st, gboolean disable_sidecars)
 {
        gchar *path_utf8 = path_to_utf8(path);
@@ -493,36 +396,41 @@ static FileData *file_data_new_local(const gchar *path, struct stat *st, gboolea
        return ret;
 }
 
-static FileData *file_data_add_sidecar_file(FileData *target, FileData *sfd)
+FileData *file_data_new_no_grouping(const gchar *path_utf8)
 {
-       sfd->parent = target;
-       if (!g_list_find(target->sidecar_files, sfd))
-               target->sidecar_files = g_list_insert_sorted(target->sidecar_files, sfd, file_data_sort_by_ext);
-       file_data_increment_version(sfd); /* increments both sfd and target */
-       return target;
-}
+       struct stat st;
 
+       if (!stat_utf8(path_utf8, &st))
+               {
+               st.st_size = 0;
+               st.st_mtime = 0;
+               }
 
-static FileData *file_data_merge_sidecar_files(FileData *target, FileData *source)
+       return file_data_new(path_utf8, &st, TRUE);
+}
+
+FileData *file_data_new_dir(const gchar *path_utf8)
 {
-       GList *work;
-       
-       file_data_add_sidecar_file(target, source);
+       struct stat st;
 
-       work = source->sidecar_files;
-       while (work)
+       if (!stat_utf8(path_utf8, &st))
                {
-               FileData *sfd = work->data;
-               file_data_add_sidecar_file(target, sfd);
-               work = work->next;
+               st.st_size = 0;
+               st.st_mtime = 0;
                }
-
-       g_list_free(source->sidecar_files);
-       source->sidecar_files = NULL;
-
-       return target;
+       else
+               /* dir or non-existing yet */
+               g_assert(S_ISDIR(st.st_mode));
+               
+       return file_data_new(path_utf8, &st, TRUE);
 }
 
+/*
+ *-----------------------------------------------------------------------------
+ * reference counting
+ *-----------------------------------------------------------------------------
+ */
+
 #ifdef DEBUG_FILEDATA
 FileData *file_data_ref_debug(const gchar *file, gint line, FileData *fd)
 #else
@@ -611,15 +519,118 @@ void file_data_unref(FileData *fd)
                        file_data_free(sfd);
                        work = work->next;
                        }
-
-               g_list_free(parent->sidecar_files);
-               parent->sidecar_files = NULL;
-
-               file_data_free(parent);
+
+               g_list_free(parent->sidecar_files);
+               parent->sidecar_files = NULL;
+
+               file_data_free(parent);
+               }
+}
+
+
+
+/*
+ *-----------------------------------------------------------------------------
+ * sidecar file info struct
+ *-----------------------------------------------------------------------------
+ */
+
+static gint file_data_sort_by_ext(gconstpointer a, gconstpointer b)
+{
+       const FileData *fda = a;
+       const FileData *fdb = b;
+       
+       if (fda->sidecar_priority < fdb->sidecar_priority) return -1;
+       if (fda->sidecar_priority > fdb->sidecar_priority) return 1;
+       
+       return strcmp(fdb->extension, fda->extension);
+}
+
+
+static gint sidecar_file_priority(const gchar *extension)
+{
+       gint i = 1;
+       GList *work;
+
+       if (extension == NULL)
+               return 0;
+
+       work = sidecar_ext_get_list();
+
+       while (work) {
+               gchar *ext = work->data;
+               
+               work = work->next;
+               if (g_ascii_strcasecmp(extension, ext) == 0) return i;
+               i++;
+       }
+       return 0;
+}
+
+static FileData *file_data_add_sidecar_file(FileData *target, FileData *sfd)
+{
+       sfd->parent = target;
+       if (!g_list_find(target->sidecar_files, sfd))
+               target->sidecar_files = g_list_insert_sorted(target->sidecar_files, sfd, file_data_sort_by_ext);
+       file_data_increment_version(sfd); /* increments both sfd and target */
+       return target;
+}
+
+
+static FileData *file_data_merge_sidecar_files(FileData *target, FileData *source)
+{
+       GList *work;
+       
+       file_data_add_sidecar_file(target, source);
+
+       work = source->sidecar_files;
+       while (work)
+               {
+               FileData *sfd = work->data;
+               file_data_add_sidecar_file(target, sfd);
+               work = work->next;
+               }
+
+       g_list_free(source->sidecar_files);
+       source->sidecar_files = NULL;
+
+       return target;
+}
+
+static void file_data_check_sidecars(const GList *basename_list)
+{
+       GList *work;
+       FileData *parent_fd;
+       if (!basename_list) return;
+       /* process the group list - the first one is the parent file, others are sidecars */
+       parent_fd = basename_list->data;
+       work = basename_list->next;
+       while (work)
+               {
+               FileData *sfd = work->data;
+               work = work->next;
+
+               file_data_merge_sidecar_files(parent_fd, sfd);
+               }
+               
+       /* there may be some sidecars that are already deleted - disconnect them */
+       work = parent_fd->sidecar_files;
+       while (work)
+               {
+               FileData *sfd = work->data;
+               work = work->next;
+               
+               if (!g_list_find((GList *)basename_list, sfd)) 
+                       {
+                       printf("removing unknown %s: %s \n", parent_fd->path, sfd->path);
+                       file_data_disconnect_sidecar_file(parent_fd, sfd);
+                       file_data_send_notification(sfd, NOTIFY_REREAD);
+                       file_data_send_notification(parent_fd, NOTIFY_REREAD);
+                       }
                }
 }
 
-FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd)
+static FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd)
 {
        sfd->parent = target;
        g_assert(g_list_find(target->sidecar_files, sfd));
@@ -696,104 +707,10 @@ void file_data_disable_grouping_list(GList *fd_list, gboolean disable)
 }
 
 
-/* compare name without extension */
-gint file_data_compare_name_without_ext(FileData *fd1, FileData *fd2)
-{
-       size_t len1 = fd1->extension - fd1->name;
-       size_t len2 = fd2->extension - fd2->name;
-
-       if (len1 < len2) return -1;
-       if (len1 > len2) return 1;
-
-       return strncmp(fd1->name, fd2->name, len1); /* FIXME: utf8 */
-}
-
-void file_data_change_info_free(FileDataChangeInfo *fdci, FileData *fd)
-{
-       if (!fdci && fd) fdci = fd->change;
-
-       if (!fdci) return;
-
-       g_free(fdci->source);
-       g_free(fdci->dest);
-
-       g_free(fdci);
-
-       if (fd) fd->change = NULL;
-}
-
-static gboolean file_data_can_write_directly(FileData *fd)
-{
-       return filter_name_is_writable(fd->extension);
-}
-
-static gboolean file_data_can_write_sidecar(FileData *fd)
-{
-       return filter_name_allow_sidecar(fd->extension) && !filter_name_is_writable(fd->extension);
-}
-
-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 (g_ascii_strcasecmp(sfd->extension, ".xmp") == 0)
-                       {
-                       sidecar_path = g_strdup(sfd->path);
-                       break;
-                       }
-               }
-       
-       if (!existing_only && !sidecar_path)
-               {
-               gchar *base = g_strndup(fd->path, fd->extension - fd->path);
-               sidecar_path = g_strconcat(base, ".xmp", NULL);
-               g_free(base);
-               }
-
-       return sidecar_path;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- * sidecar file info struct
- *-----------------------------------------------------------------------------
- */
-
-
-
-static gint sidecar_file_priority(const gchar *extension)
-{
-       gint i = 1;
-       GList *work;
-
-       if (extension == NULL)
-               return 0;
-
-       work = sidecar_ext_get_list();
-
-       while (work) {
-               gchar *ext = work->data;
-               
-               work = work->next;
-               if (g_ascii_strcasecmp(extension, ext) == 0) return i;
-               i++;
-       }
-       return 0;
-}
-
 
 /*
  *-----------------------------------------------------------------------------
- * load file list
+ * filelist sorting
  *-----------------------------------------------------------------------------
  */
 
@@ -884,6 +801,78 @@ GList *filelist_insert_sort(GList *list, FileData *fd, SortType method, gboolean
        return filelist_insert_sort_full(list, fd, method, ascend, (GCompareFunc) filelist_sort_file_cb);
 }
 
+/*
+ *-----------------------------------------------------------------------------
+ * basename hash - grouping of sidecars in filelist
+ *-----------------------------------------------------------------------------
+ */
+
+
+static GHashTable *file_data_basename_hash_new(void)
+{
+       return g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+}
+
+static GList * file_data_basename_hash_insert(GHashTable *basename_hash, FileData *fd)
+{
+       GList *list;
+       gchar *basename = g_strndup(fd->path, fd->extension - fd->path);
+
+       list = g_hash_table_lookup(basename_hash, basename);
+       
+       if (!g_list_find(list, fd))
+               {
+               list = g_list_insert_sorted(list, file_data_ref(fd), file_data_sort_by_ext);
+               g_hash_table_insert(basename_hash, basename, list);
+               }
+       else 
+               {
+               g_free(basename);
+               }
+       return list;
+}
+
+#if 0
+static void file_data_basename_hash_remove(GHashTable *basename_hash, FileData *fd)
+{
+       GList *list;
+       gchar *basename = g_strndup(fd->path, fd->extension - fd->path);
+       
+       list = g_hash_table_lookup(basename_hash, basename);
+       
+       if (!g_list_find(list, fd)) return;
+       
+       list = g_list_remove(list, fd);
+       file_data_unref(fd);
+       
+       if (list)
+               {
+               g_hash_table_insert(basename_hash, basename, list);
+               }
+       else 
+               {
+               g_hash_table_remove(basename_hash, basename);
+               g_free(basename);
+               }
+}
+#endif
+
+static void file_data_basename_hash_remove_list(gpointer key, gpointer value, gpointer data)
+{
+       filelist_free((GList *)value);
+}
+
+static void file_data_basename_hash_free(GHashTable *basename_hash)
+{
+       g_hash_table_foreach(basename_hash, file_data_basename_hash_remove_list, NULL); 
+       g_hash_table_destroy(basename_hash);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ * handling sidecars in filelist
+ *-----------------------------------------------------------------------------
+ */
 
 static GList *filelist_filter_out_sidecars(GList *flist)
 {
@@ -919,6 +908,12 @@ static gboolean is_hidden_file(const gchar *name)
        return TRUE;
 }
 
+/*
+ *-----------------------------------------------------------------------------
+ * the main filelist function
+ *-----------------------------------------------------------------------------
+ */
+
 static gboolean filelist_read_real(const gchar *dir_path, GList **files, GList **dirs, gboolean follow_symlinks)
 {
        DIR *dp;
@@ -1024,7 +1019,7 @@ gboolean filelist_read_lstat(FileData *dir_fd, GList **files, GList **dirs)
        return filelist_read_real(dir_fd->path, files, dirs, FALSE);
 }
 
-FileData *file_data_new_simple(const gchar *path_utf8)
+FileData *file_data_new_group(const gchar *path_utf8)
 {
        gchar *dir;
        struct stat st;
@@ -1053,32 +1048,6 @@ FileData *file_data_new_simple(const gchar *path_utf8)
        return fd;
 }
 
-FileData *file_data_new_no_grouping(const gchar *path_utf8)
-{
-       struct stat st;
-
-       if (!stat_utf8(path_utf8, &st))
-               {
-               st.st_size = 0;
-               st.st_mtime = 0;
-               }
-
-       return file_data_new(path_utf8, &st, TRUE);
-}
-
-FileData *file_data_new_dir(const gchar *path_utf8)
-{
-       struct stat st;
-
-       if (!stat_utf8(path_utf8, &st))
-               {
-               st.st_size = 0;
-               st.st_mtime = 0;
-               }
-
-       g_assert(S_ISDIR(st.st_mode));
-       return file_data_new(path_utf8, &st, TRUE);
-}
 
 void filelist_free(GList *list)
 {
@@ -1127,7 +1096,7 @@ GList *filelist_from_path_list(GList *list)
                path = work->data;
                work = work->next;
 
-               new_list = g_list_prepend(new_list, file_data_new_simple(path));
+               new_list = g_list_prepend(new_list, file_data_new_group(path));
                }
 
        return g_list_reverse(new_list);
@@ -1242,6 +1211,65 @@ GList *filelist_recursive(FileData *dir_fd)
        return list;
 }
 
+/*
+ *-----------------------------------------------------------------------------
+ * file modification support
+ *-----------------------------------------------------------------------------
+ */
+
+
+void file_data_change_info_free(FileDataChangeInfo *fdci, FileData *fd)
+{
+       if (!fdci && fd) fdci = fd->change;
+
+       if (!fdci) return;
+
+       g_free(fdci->source);
+       g_free(fdci->dest);
+
+       g_free(fdci);
+
+       if (fd) fd->change = NULL;
+}
+
+static gboolean file_data_can_write_directly(FileData *fd)
+{
+       return filter_name_is_writable(fd->extension);
+}
+
+static gboolean file_data_can_write_sidecar(FileData *fd)
+{
+       return filter_name_allow_sidecar(fd->extension) && !filter_name_is_writable(fd->extension);
+}
+
+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 (g_ascii_strcasecmp(sfd->extension, ".xmp") == 0)
+                       {
+                       sidecar_path = g_strdup(sfd->path);
+                       break;
+                       }
+               }
+       
+       if (!existing_only && !sidecar_path)
+               {
+               gchar *base = g_strndup(fd->path, fd->extension - fd->path);
+               sidecar_path = g_strconcat(base, ".xmp", NULL);
+               g_free(base);
+               }
+
+       return sidecar_path;
+}
 
 /*
  * marks and orientation
index 26129a7..8e5e867 100644 (file)
@@ -23,7 +23,7 @@ gchar *text_from_size_abrev(gint64 size);
 const gchar *text_from_time(time_t t);
 
 /* scan for sidecar files - expensive */
-FileData *file_data_new_simple(const gchar *path_utf8);
+FileData *file_data_new_group(const gchar *path_utf8);
 
 /* should be used on helper files which can't have sidecars */
 FileData *file_data_new_no_grouping(const gchar *path_utf8);
index 45cc1e1..64d514f 100644 (file)
@@ -851,7 +851,7 @@ gboolean layout_set_path(LayoutWindow *lw, const gchar *path)
 
        if (!path) return FALSE;
        
-       fd = file_data_new_simple(path);
+       fd = file_data_new_group(path);
        ret = layout_set_fd(lw, fd);
        file_data_unref(fd);
        return ret;
index cde2f4a..a60cb91 100644 (file)
@@ -125,7 +125,7 @@ static void parse_command_line_add_file(const gchar *file_path, gchar **path, gc
                {
                if (!*path) *path = remove_level_from_path(path_parsed);
                if (!*file) *file = g_strdup(path_parsed);
-               *list = g_list_prepend(*list, file_data_new_simple(path_parsed));
+               *list = g_list_prepend(*list, file_data_new_group(path_parsed));
                }
 }
 
index 33a2a52..f265927 100644 (file)
@@ -318,7 +318,7 @@ gboolean metadata_write_perform(FileData *fd)
                    store the metadata in the cache)
                    FIXME: this does not catch new sidecars created by independent external programs
                */
-               file_data_unref(file_data_new_simple(fd->change->dest)); 
+               file_data_unref(file_data_new_group(fd->change->dest)); 
                
        if (success) metadata_legacy_delete(fd, fd->change->dest);
        return success;
index ea942aa..6435d37 100644 (file)
@@ -91,7 +91,7 @@ void pan_timeline_compute(PanWindow *pw, FileData *dir_fd, gint *width, gint *he
                                g_free(buf);
                                y += pi->height;
 
-                               pi_month = pan_item_box_new(pw, file_data_new_simple(fd->path),
+                               pi_month = pan_item_box_new(pw, file_data_ref(fd),
                                                            x, y, 0, 0,
                                                            PAN_BOX_OUTLINE_THICKNESS,
                                                            PAN_BOX_COLOR, PAN_BOX_ALPHA,
index f3d16c8..9d6679a 100644 (file)
@@ -1604,7 +1604,7 @@ static void pan_info_update(PanWindow *pw, PanItem *pi)
                                                PAN_POPUP_BORDER_COLOR, PAN_POPUP_ALPHA);
                        pan_item_set_key(pbox, "info");
 
-                       p = pan_item_image_new(pw, file_data_new_simple(pi->fd->path),
+                       p = pan_item_image_new(pw, file_data_new_group(pi->fd->path),
                                               pbox->x + PREF_PAD_BORDER, pbox->y + PREF_PAD_BORDER, iw, ih);
                        pan_item_set_key(p, "info");
                        pan_item_size_by_item(pbox, p, PREF_PAD_BORDER);
index 50a6d35..f94ef07 100644 (file)
@@ -532,7 +532,7 @@ static void gr_config_load(const gchar *text, GIOChannel *channel, gpointer data
 static void gr_get_sidecars(const gchar *text, GIOChannel *channel, gpointer data)
 {
        gchar *filename = expand_tilde(text);
-       FileData *fd = file_data_new_simple(filename);
+       FileData *fd = file_data_new_group(filename);
        
        GList *work;
        if (fd->parent) fd = fd->parent;
@@ -555,7 +555,7 @@ static void gr_get_sidecars(const gchar *text, GIOChannel *channel, gpointer dat
 static void gr_get_destination(const gchar *text, GIOChannel *channel, gpointer data)
 {
        gchar *filename = expand_tilde(text);
-       FileData *fd = file_data_new_simple(filename);
+       FileData *fd = file_data_new_group(filename);
        
        if (fd->change && fd->change->dest)
                {
@@ -569,7 +569,7 @@ static void gr_file_view(const gchar *text, GIOChannel *channel, gpointer data)
 {
        gchar *filename = expand_tilde(text);
 
-       view_window_new(file_data_new_simple(filename));
+       view_window_new(file_data_new_group(filename));
        g_free(filename);
 }
 
@@ -607,7 +607,7 @@ static void gr_list_add(const gchar *text, GIOChannel *channel, gpointer data)
                new = (!collection_get_first(remote_data->command_collection));
                }
 
-       if (collection_add(remote_data->command_collection, file_data_new_simple(text), FALSE) && new)
+       if (collection_add(remote_data->command_collection, file_data_new_group(text), FALSE) && new)
                {
                layout_image_set_collection(NULL, remote_data->command_collection,
                                            collection_get_first(remote_data->command_collection));
index c7fbaf4..c855e61 100644 (file)
@@ -2124,7 +2124,7 @@ static void search_start(SearchData *sd)
                                sd->search_similarity_cd = cache_sim_data_new();
                                }
 
-                       sd->img_loader = image_loader_new(file_data_new_simple(sd->search_similarity_path));
+                       sd->img_loader = image_loader_new(file_data_new_group(sd->search_similarity_path));
                        g_signal_connect(G_OBJECT(sd->img_loader), "error", (GCallback)search_similarity_load_done_cb, sd);
                        g_signal_connect(G_OBJECT(sd->img_loader), "done", (GCallback)search_similarity_load_done_cb, sd);
                        if (image_loader_start(sd->img_loader))
index f816809..c23329f 100644 (file)
@@ -983,7 +983,7 @@ static void thumb_std_maint_move_validate_cb(const gchar *path, gboolean valid,
                        tm->tl->cache_hit = FALSE;
                        tm->tl->cache_local = FALSE;
                        file_data_unref(tm->tl->fd);
-                       tm->tl->fd = file_data_new_simple(tm->dest);
+                       tm->tl->fd = file_data_new_group(tm->dest);
                        tm->tl->source_mtime = strtol(mtime_str, NULL, 10);
 
                        pathl = path_from_utf8(tm->tl->fd->path);
index e32a18d..d8a0ccd 100644 (file)
@@ -1074,7 +1074,7 @@ static void file_util_dest_folder_update_path(UtilityData *ud)
                        break;
                case UTILITY_TYPE_CREATE_FOLDER:
                        file_data_unref(ud->dir_fd);
-                       ud->dir_fd = file_data_new_simple(ud->dest_path);
+                       ud->dir_fd = file_data_new_dir(ud->dest_path);
                        break;
                case UTILITY_TYPE_DELETE:
                case UTILITY_TYPE_DELETE_LINK:
@@ -2676,7 +2676,7 @@ static void file_util_create_dir_full(FileData *fd, const gchar *dest_path, GtkW
                g_free(buf);
                }
        
-       ud->dir_fd = file_data_new_simple(ud->dest_path);
+       ud->dir_fd = file_data_new_dir(ud->dest_path);
 
        ud->done_func = done_func;
        ud->done_data = done_data;
index ca16324..c290587 100644 (file)
@@ -516,7 +516,7 @@ static gboolean vflist_row_rename_cb(TreeEditData *td, const gchar *old, const g
        else
                {
                gchar *old_path = g_build_filename(vf->dir_fd->path, old, NULL);
-               FileData *fd = file_data_new_simple(old_path); /* get the fd from cache */
+               FileData *fd = file_data_new_group(old_path); /* get the fd from cache */
                file_util_rename_simple(fd, new_path, vf->listview);
                file_data_unref(fd);
                g_free(old_path);