various refresh and notification fixes
authorVladimir Nadvornik <nadvornik@suse.cz>
Sat, 7 Jun 2008 22:44:17 +0000 (22:44 +0000)
committerVladimir Nadvornik <nadvornik@suse.cz>
Sat, 7 Jun 2008 22:44:17 +0000 (22:44 +0000)
src/filedata.c
src/view_file_list.c

index 439ab76..ba20aaf 100644 (file)
@@ -220,8 +220,9 @@ static void file_data_set_path(FileData *fd, const gchar *path)
        file_data_set_collate_keys(fd);
 }
 
-static void file_data_check_changed_files(FileData *fd, struct stat *st)
+static gboolean file_data_check_changed_files_recursive(FileData *fd, struct stat *st)
 {
+       gboolean ret = FALSE;
        GList *work;
        if (fd->size != st->st_size ||
            fd->date != st->st_mtime)
@@ -232,6 +233,7 @@ static void file_data_check_changed_files(FileData *fd, struct stat *st)
                fd->pixbuf = NULL;
                file_data_increment_version(fd);
                file_data_send_notification(fd, NOTIFY_TYPE_REREAD);
+               ret = TRUE;
                }
 
        work = fd->sidecar_files;
@@ -239,15 +241,50 @@ static void file_data_check_changed_files(FileData *fd, struct stat *st)
                {
                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;
                        }
 
-               file_data_check_changed_files(sfd, &st);
-               work = work->next;
+               ret |= file_data_check_changed_files_recursive(sfd, &st);
                }
+       return ret;
+}
+
+
+static 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))
+               {
+               /* parent is missing, we have to rebuild whole group */
+               ret = TRUE;
+               fd->size = 0;
+               fd->date = 0;
+               GList *work = fd->sidecar_files;
+               FileData *sfd = NULL;
+               while (work)
+                       {
+                       sfd = work->data;
+                       work = work->next;
+               
+                       file_data_disconnect_sidecar_file(fd, sfd);
+                       }
+               if (sfd) file_data_check_sidecars(sfd); /* this will group the sidecars back together */
+               file_data_send_notification(fd, NOTIFY_TYPE_REREAD);
+               }
+       else 
+               ret |= file_data_check_changed_files_recursive(fd, &st);
+       return ret;
 }
 
 static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean check_sidecars)
@@ -262,8 +299,14 @@ static FileData *file_data_new(const gchar *path_utf8, struct stat *st, gboolean
        fd = g_hash_table_lookup(file_data_pool, path_utf8);
        if (fd)
                {
-               file_data_check_changed_files(fd, st);
-               DEBUG_2("file_data_pool hit: '%s'", fd->path);
+               gboolean changed;
+               if (fd->parent)
+                       changed = file_data_check_changed_files(fd);
+               else
+                       changed = file_data_check_changed_files_recursive(fd, st);
+               if (changed && check_sidecars && sidecar_file_priority(fd->extension))
+                       file_data_check_sidecars(fd);
+               DEBUG_2("file_data_pool hit: '%s' %s", fd->path, changed ? "(changed)" : "");
                return file_data_ref(fd);
                }
 
@@ -361,6 +404,7 @@ 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_prepend(target->sidecar_files, sfd);
+       file_data_increment_version(sfd); /* increments both sfd and target */
        return target;
 }
 
@@ -467,6 +511,8 @@ FileData *file_data_disconnect_sidecar_file(FileData *target, FileData *sfd)
 {
        sfd->parent = target;
        g_assert(g_list_find(target->sidecar_files, sfd));
+       
+       file_data_increment_version(sfd); /* increments both sfd and target */
 
        target->sidecar_files = g_list_remove(target->sidecar_files, sfd);
        sfd->parent = NULL;
@@ -1541,12 +1587,8 @@ static gint realtime_monitor_id = -1;
 static void realtime_monitor_check_cb(gpointer key, gpointer value, gpointer data)
 {
        FileData *fd = key;
-       struct stat st;
 
-       if (stat_utf8(fd->path, &st))
-               file_data_check_changed_files(fd, &st);
-       else 
-               file_data_send_notification(fd, NOTIFY_TYPE_REREAD);
+       file_data_check_changed_files(fd);
        
        DEBUG_1("monitor %s", fd->path);
 }
index 691a971..95d3c6f 100644 (file)
@@ -142,6 +142,21 @@ static gint vflist_sidecar_list_count(GList *work)
        return i;
 }
 
+static gboolean vflist_store_clear_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
+{
+       FileData *fd;
+       gtk_tree_model_get(model, iter, FILE_COLUMN_POINTER, &fd, -1);
+       file_data_unref(fd);
+       return FALSE;
+}
+
+static void vflist_store_clear(ViewFile *vf)
+{
+       GtkTreeModel *store;
+       store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
+       gtk_tree_model_foreach(store, vflist_store_clear_cb, NULL);
+       gtk_tree_store_clear(GTK_TREE_STORE(store));
+}
 
 void vflist_color_set(ViewFile *vf, FileData *fd, gint color_set)
 {
@@ -793,7 +808,7 @@ static void vflist_setup_iter_recursive(ViewFile *vf, GtkTreeStore *store, GtkTr
                                        gtk_tree_store_append(store, &new, parent_iter);
                                        }
 
-                               vflist_setup_iter(vf, store, &new, fd);
+                               vflist_setup_iter(vf, store, &new, file_data_ref(fd));
                                vflist_setup_iter_recursive(vf, store, &new, fd->sidecar_files, selected);
                                
                                if (g_list_find(selected, fd))
@@ -808,6 +823,7 @@ static void vflist_setup_iter_recursive(ViewFile *vf, GtkTreeStore *store, GtkTr
                                }
                        else if (match > 0)
                                {
+                               file_data_unref(old_fd);
                                valid = gtk_tree_store_remove(store, &iter);
                                }
                        else
@@ -828,6 +844,10 @@ static void vflist_setup_iter_recursive(ViewFile *vf, GtkTreeStore *store, GtkTr
 
        while (valid)
                {
+               FileData *old_fd;
+               gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, FILE_COLUMN_POINTER, &old_fd, -1);
+               file_data_unref(old_fd);
+
                valid = gtk_tree_store_remove(store, &iter);
                }
 }
@@ -1514,7 +1534,7 @@ static void vflist_populate_view(ViewFile *vf)
 
        if (!vf->list)
                {
-               gtk_tree_store_clear(store);
+               vflist_store_clear(vf);
                vf_send_update(vf);
                return;
                }
@@ -1748,8 +1768,6 @@ static void vflist_listview_add_column_toggle(ViewFile *vf, gint n, const gchar
 
 gint vflist_set_fd(ViewFile *vf, FileData *dir_fd)
 {
-       GtkTreeStore *store;
-
        if (!dir_fd) return FALSE;
        if (vf->dir_fd == dir_fd) return TRUE;
 
@@ -1757,8 +1775,7 @@ gint vflist_set_fd(ViewFile *vf, FileData *dir_fd)
        vf->dir_fd = file_data_ref(dir_fd);
 
        /* force complete reload */
-       store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview)));
-       gtk_tree_store_clear(store);
+       vflist_store_clear(vf);
 
        filelist_free(vf->list);
        vf->list = NULL;