From f8f558aa337185b19b338d482eedc648d2504f90 Mon Sep 17 00:00:00 2001 From: Colin Clark Date: Sun, 11 Oct 2020 14:14:43 +0100 Subject: [PATCH] Ref #761: Severe stall/hang at start-up https://github.com/BestImageViewer/geeqie/issues/761 Read star rating in the idle loop. --- src/filedata.c | 4 ++ src/typedefs.h | 4 ++ src/view_file.h | 6 ++ src/view_file/view_file.c | 91 ++++++++++++++++++++++++ src/view_file/view_file_icon.c | 87 ++++++++++++++++++++++- src/view_file/view_file_icon.h | 3 + src/view_file/view_file_list.c | 126 ++++++++++++++++++++++++++++++++- src/view_file/view_file_list.h | 4 ++ 8 files changed, 321 insertions(+), 4 deletions(-) diff --git a/src/filedata.c b/src/filedata.c index 213002c9..7711432f 100644 --- a/src/filedata.c +++ b/src/filedata.c @@ -583,6 +583,10 @@ void read_rating_data(FileData *file) file->rating = atoi(rating_str); g_free(rating_str); } + else + { + file->rating = 0; + } } void set_exif_time_data(GList *files) diff --git a/src/typedefs.h b/src/typedefs.h index 04da8ba2..8269bb3d 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -958,6 +958,10 @@ struct _ViewFile gint active_mark; gint clicked_mark; + /* stars */ + FileData *stars_filedata; + guint stars_id; + /* refresh */ guint refresh_idle_id; /* event source id */ time_t time_refresh_set; /* time when refresh_idle_id was set */ diff --git a/src/view_file.h b/src/view_file.h index d921a3ae..6ec34f7e 100644 --- a/src/view_file.h +++ b/src/view_file.h @@ -77,5 +77,11 @@ void vf_thumb_stop(ViewFile *vf); void vf_read_metadata_in_idle(ViewFile *vf); void vf_file_filter_set(ViewFile *vf, gboolean enable); GRegex *vf_file_filter_get_filter(ViewFile *vf); + +void vf_star_update(ViewFile *vf); +gboolean vf_stars_cb(gpointer data); +void vf_star_stop(ViewFile *vf); +void vf_star_cleanup(ViewFile *vf); + #endif /* VIEW_FILE_H */ /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/view_file/view_file.c b/src/view_file/view_file.c index f44087cf..e07670ad 100644 --- a/src/view_file/view_file.c +++ b/src/view_file/view_file.c @@ -1367,6 +1367,97 @@ void vf_thumb_update(ViewFile *vf) while (vf_thumb_next(vf)); } +void vf_star_cleanup(ViewFile *vf) +{ + if (vf->stars_id != 0) + { + g_source_remove(vf->stars_id); + } + + vf->stars_id = 0; + vf->stars_filedata = NULL; +} + +void vf_star_stop(ViewFile *vf) +{ + vf_star_cleanup(vf); +} + +static void vf_set_star_fd(ViewFile *vf, FileData *fd) +{ + switch (vf->type) + { + case FILEVIEW_LIST: vflist_set_star_fd(vf, fd); break; + case FILEVIEW_ICON: vficon_set_star_fd(vf, fd); break; + default: break; + } +} + +static void vf_star_do(ViewFile *vf, FileData *fd) +{ + if (!fd) return; + + vf_set_star_fd(vf, fd); +} + +static gboolean vf_star_next(ViewFile *vf) +{ + FileData *fd = NULL; + + switch (vf->type) + { + case FILEVIEW_LIST: fd = vflist_star_next_fd(vf); break; + case FILEVIEW_ICON: fd = vficon_star_next_fd(vf); break; + default: break; + } + + if (!fd) + { + /* done */ + vf_star_cleanup(vf); + return FALSE; + } + + return TRUE; +} + +gboolean vf_stars_cb(gpointer data) +{ + ViewFile *vf = data; + FileData *fd = vf->stars_filedata; + + if (fd) + { + read_rating_data(fd); + + vf_star_do(vf, fd); + + if (vf_star_next(vf)) + { + return TRUE; + } + else + { + vf->stars_filedata = NULL; + vf->stars_id = 0; + return FALSE; + } + } + + return FALSE; +} + +void vf_star_update(ViewFile *vf) +{ + vf_star_stop(vf); + + if (!options->show_star_rating) + { + return; + } + + vf_star_next(vf); +} void vf_marks_set(ViewFile *vf, gboolean enable) { diff --git a/src/view_file/view_file_icon.c b/src/view_file/view_file_icon.c index b819a864..611f987c 100644 --- a/src/view_file/view_file_icon.c +++ b/src/view_file/view_file_icon.c @@ -35,6 +35,7 @@ #include "layout_image.h" #include "menu.h" #include "metadata.h" +#include "misc.h" #include "thumb.h" #include "utilops.h" #include "ui_fileops.h" @@ -1662,6 +1663,7 @@ static void vficon_populate(ViewFile *vf, gboolean resize, gboolean keep_positio vf_send_update(vf); vf_thumb_update(vf); + vf_star_update(vf); } static void vficon_populate_at_new_size(ViewFile *vf, gint w, gint h, gboolean force) @@ -1802,6 +1804,86 @@ FileData *vficon_thumb_next_fd(ViewFile *vf) return NULL; } +void vficon_set_star_fd(ViewFile *vf, FileData *fd) +{ + GtkTreeModel *store; + GtkTreeIter iter; + GList *list; + + if (!g_list_find(vf->list, fd)) return; + if (!vficon_find_iter(vf, fd, &iter, NULL)) return; + + store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview)); + + gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &list, -1); + gtk_list_store_set(GTK_LIST_STORE(store), &iter, FILE_COLUMN_POINTER, list, -1); +} + +FileData *vficon_star_next_fd(ViewFile *vf) +{ + GtkTreePath *tpath; + + /* first check the visible files */ + + if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vf->listview), 0, 0, &tpath, NULL, NULL, NULL)) + { + GtkTreeModel *store; + GtkTreeIter iter; + gboolean valid = TRUE; + + store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview)); + gtk_tree_model_get_iter(store, &iter, tpath); + gtk_tree_path_free(tpath); + tpath = NULL; + + while (valid && tree_view_row_get_visibility(GTK_TREE_VIEW(vf->listview), &iter, FALSE) == 0) + { + GList *list; + gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &list, -1); + + for (; list; list = list->next) + { + FileData *fd = list->data; + if (fd && fd->rating == STAR_RATING_NOT_READ) + { + vf->stars_filedata = fd; + + if (vf->stars_id == 0) + { + vf->stars_id = g_idle_add_full(G_PRIORITY_LOW, vf_stars_cb, vf, NULL); + } + + return fd; + } + } + + valid = gtk_tree_model_iter_next(store, &iter); + } + } + + /* Then iterate through the entire list to load all of them. */ + + GList *work; + for (work = vf->list; work; work = work->next) + { + FileData *fd = work->data; + + if (fd && fd->rating == STAR_RATING_NOT_READ) + { + vf->stars_filedata = fd; + + if (vf->stars_id == 0) + { + vf->stars_id = g_idle_add_full(G_PRIORITY_LOW, vf_stars_cb, vf, NULL); + } + + return fd; + } + } + + return NULL; +} + /* *----------------------------------------------------------------------------- * row stuff @@ -2009,9 +2091,9 @@ static void vficon_cell_data_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer g_assert(fd->magick == FD_MAGICK); - if (options->show_star_rating) + if (options->show_star_rating && fd->rating != STAR_RATING_NOT_READ) { - star_rating = metadata_read_rating_stars(fd); + star_rating = convert_rating_to_stars(fd->rating); } else { @@ -2163,6 +2245,7 @@ void vficon_destroy_cb(GtkWidget *widget, gpointer data) tip_unschedule(vf); vf_thumb_cleanup(vf); + vf_star_cleanup(vf); g_list_free(vf->list); g_list_free(VFICON(vf)->selection); diff --git a/src/view_file/view_file_icon.h b/src/view_file/view_file_icon.h index d90bc411..4f2d6c3c 100644 --- a/src/view_file/view_file_icon.h +++ b/src/view_file/view_file_icon.h @@ -75,5 +75,8 @@ void vficon_set_thumb_fd(ViewFile *vf, FileData *fd); FileData *vficon_thumb_next_fd(ViewFile *vf); void vficon_thumb_reset_all(ViewFile *vf); +FileData *vficon_star_next_fd(ViewFile *vf); +void vficon_set_star_fd(ViewFile *vf, FileData *fd); + #endif /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/view_file/view_file_list.c b/src/view_file/view_file_list.c index 76c290cf..2d39d416 100644 --- a/src/view_file/view_file_list.c +++ b/src/view_file/view_file_list.c @@ -32,6 +32,7 @@ #include "layout_image.h" #include "menu.h" #include "metadata.h" +#include "misc.h" #include "thumb.h" #include "utilops.h" #include "ui_fileops.h" @@ -894,6 +895,7 @@ static void vflist_set_expanded(ViewFile *vf, GtkTreeIter *iter, gboolean expand g_free(sidecars); g_free(name); g_free(formatted); + g_free(formatted_with_stars); } static void vflist_setup_iter(ViewFile *vf, GtkTreeStore *store, GtkTreeIter *iter, FileData *fd) @@ -909,9 +911,9 @@ static void vflist_setup_iter(ViewFile *vf, GtkTreeStore *store, GtkTreeIter *it gboolean expanded = FALSE; gchar *star_rating; - if (options->show_star_rating) + if (options->show_star_rating && fd->rating != STAR_RATING_NOT_READ) { - star_rating = metadata_read_rating_stars(fd); + star_rating = convert_rating_to_stars(fd->rating); } else { @@ -1263,6 +1265,123 @@ FileData *vflist_thumb_next_fd(ViewFile *vf) return fd; } +void vflist_set_star_fd(ViewFile *vf, FileData *fd) +{ + GtkTreeStore *store; + GtkTreeIter iter; + gchar *name; + gchar *sidecars; + gchar *size; + gchar *time; + gchar *star_rating; + gchar *formatted_with_stars; + gboolean expanded; + + if (!fd || vflist_find_row(vf, fd, &iter) < 0) return; + + star_rating = metadata_read_rating_stars(fd); + + store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview))); + gtk_tree_store_set(store, &iter, FILE_COLUMN_STAR_RATING, star_rating, -1); + + gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, + FILE_COLUMN_NAME, &name, + FILE_COLUMN_SIDECARS, &sidecars, + FILE_COLUMN_SIZE, &size, + FILE_COLUMN_DATE, &time, + FILE_COLUMN_EXPANDED, &expanded, + -1); + + formatted_with_stars = vflist_get_formatted(vf, name, sidecars, size, time, expanded, TRUE, star_rating); + + gtk_tree_store_set(store, &iter, FILE_COLUMN_FORMATTED_WITH_STARS, formatted_with_stars, + FILE_COLUMN_EXPANDED, expanded, + -1); + + g_free(star_rating); + g_free(formatted_with_stars); +} + +FileData *vflist_star_next_fd(ViewFile *vf) +{ + GtkTreePath *tpath; + FileData *fd = NULL; + FileData *nfd = NULL; + + /* first check the visible files */ + + if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vf->listview), 0, 0, &tpath, NULL, NULL, NULL)) + { + GtkTreeModel *store; + GtkTreeIter iter; + gboolean valid = TRUE; + + store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview)); + gtk_tree_model_get_iter(store, &iter, tpath); + gtk_tree_path_free(tpath); + tpath = NULL; + + while (!fd && valid && tree_view_row_get_visibility(GTK_TREE_VIEW(vf->listview), &iter, FALSE) == 0) + { + GList *work; + + gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &nfd, -1); + + if (nfd && nfd->rating == STAR_RATING_NOT_READ) + { + fd = nfd; + } + + valid = gtk_tree_model_iter_next(store, &iter); + } + + if (fd) + { + vf->stars_filedata = fd; + + if (vf->stars_id == 0) + { + vf->stars_id = g_idle_add_full(G_PRIORITY_LOW, vf_stars_cb, vf, NULL); + } + } + } + + /* then find first undone */ + + if (!fd) + { + GList *work = vf->list; + + while (work && !fd) + { + FileData *fd_p = work->data; + + if (fd_p && fd_p->rating == STAR_RATING_NOT_READ) + { + fd = fd_p; + } + else + { + fd = NULL; + } + + work = work->next; + } + + if (fd) + { + vf->stars_filedata = fd; + + if (vf->stars_id == 0) + { + vf->stars_id = g_idle_add_full(G_PRIORITY_LOW, vf_stars_cb, vf, NULL); + } + } + } + + return fd; +} + /* *----------------------------------------------------------------------------- * row stuff @@ -1755,6 +1874,7 @@ static void vflist_populate_view(ViewFile *vf, gboolean force) store = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview))); vf_thumb_stop(vf); + vf_star_stop(vf); if (!vf->list) { @@ -1779,6 +1899,7 @@ static void vflist_populate_view(ViewFile *vf, gboolean force) vf_send_update(vf); vf_thumb_update(vf); + vf_star_update(vf); } gboolean vflist_refresh(ViewFile *vf) @@ -2018,6 +2139,7 @@ void vflist_destroy_cb(GtkWidget *widget, gpointer data) vflist_select_idle_cancel(vf); vf_refresh_idle_cancel(vf); vf_thumb_stop(vf); + vf_star_stop(vf); filelist_free(vf->list); } diff --git a/src/view_file/view_file_list.h b/src/view_file/view_file_list.h index 2c295d01..a1df3817 100644 --- a/src/view_file/view_file_list.h +++ b/src/view_file/view_file_list.h @@ -75,5 +75,9 @@ void vflist_set_thumb_fd(ViewFile *vf, FileData *fd); FileData *vflist_thumb_next_fd(ViewFile *vf); void vflist_thumb_reset_all(ViewFile *vf); void vflist_pop_menu_show_star_rating_cb(GtkWidget *widget, gpointer data); + +FileData *vflist_star_next_fd(ViewFile *vf); +void vflist_set_star_fd(ViewFile *vf, FileData *fd); + #endif /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ -- 2.20.1