view_file_list.c
来自「Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。」· C语言 代码 · 共 1,819 行 · 第 1/3 页
C
1,819 行
gtk_tree_path_free(tpath); } if (bevent->button == 2) { if (fd && vfl->click_fd == fd) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); if (vflist_row_is_selected(vfl, fd)) { gtk_tree_selection_unselect_iter(selection, &iter); } else { gtk_tree_selection_select_iter(selection, &iter); } } return TRUE; } if (fd && vfl->click_fd == fd && !(bevent->state & GDK_SHIFT_MASK ) && !(bevent->state & GDK_CONTROL_MASK ) && vflist_row_is_selected(vfl, fd)) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_iter(selection, &iter); vflist_move_cursor(vfl, &iter); return TRUE; } return FALSE;}static void vflist_select_image(ViewFileList *vfl, gint row){ const gchar *path; const gchar *read_ahead_path = NULL; path = vflist_index_get_path(vfl, row); if (!path) return; if (path && enable_read_ahead) { FileData *fd; if (row > vflist_index_by_path(vfl, layout_image_get_path(vfl->layout)) && row + 1 < vflist_count(vfl, NULL)) { fd = vflist_index_get_data(vfl, row + 1); } else if (row > 0) { fd = vflist_index_get_data(vfl, row - 1); } else { fd = NULL; } if (fd) read_ahead_path = fd->path; } layout_image_set_with_ahead(vfl->layout, path, read_ahead_path);}static gint vflist_select_idle_cb(gpointer data){ ViewFileList *vfl = data; if (!vfl->layout) { vfl->select_idle_id = -1; return FALSE; } vflist_send_update(vfl); if (vfl->select_fd) { vflist_select_image(vfl, g_list_index(vfl->list, vfl->select_fd)); vfl->select_fd = NULL; } vfl->select_idle_id = -1; return FALSE;}static void vflist_select_idle_cancel(ViewFileList *vfl){ if (vfl->select_idle_id != -1) g_source_remove(vfl->select_idle_id); vfl->select_idle_id = -1;}static gboolean vflist_select_cb(GtkTreeSelection *selection, GtkTreeModel *store, GtkTreePath *tpath, gboolean path_currently_selected, gpointer data){ ViewFileList *vfl = data; GtkTreeIter iter; if (!path_currently_selected && gtk_tree_model_get_iter(store, &iter, tpath)) { gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &vfl->select_fd, -1); } else { vfl->select_fd = NULL; } if (vfl->layout && vfl->select_idle_id == -1) { vfl->select_idle_id = g_idle_add(vflist_select_idle_cb, vfl); } return TRUE;}/* *----------------------------------------------------------------------------- * misc *----------------------------------------------------------------------------- */void vflist_sort_set(ViewFileList *vfl, SortType type, gint ascend){ GtkListStore *store; GList *work; if (vfl->sort_method == type && vfl->sort_ascend == ascend) return; vfl->sort_method = type; vfl->sort_ascend = ascend; if (!vfl->list) return; vfl->list = filelist_sort(vfl->list, vfl->sort_method, vfl->sort_ascend); store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); /* reorder the treeview, maintaining current selection */ work = g_list_last(vfl->list); while (work) { FileData *fd; GtkTreeIter iter; fd = work->data; if (vflist_find_row(vfl, fd, &iter) >= 0) { gtk_list_store_move_after(store, &iter, NULL); } work = work->prev; }}/* *----------------------------------------------------------------------------- * thumb updates *----------------------------------------------------------------------------- */static gint vflist_thumb_next(ViewFileList *vfl);static void vflist_thumb_status(ViewFileList *vfl, gdouble val, const gchar *text){ if (vfl->func_thumb_status) { vfl->func_thumb_status(vfl, val, text, vfl->data_thumb_status); }}static void vflist_thumb_cleanup(ViewFileList *vfl){ vflist_thumb_status(vfl, 0.0, NULL); vfl->thumbs_count = 0; vfl->thumbs_running = FALSE; thumb_loader_free(vfl->thumbs_loader); vfl->thumbs_loader = NULL; vfl->thumbs_filedata = NULL;}static void vflist_thumb_stop(ViewFileList *vfl){ if (vfl->thumbs_running) vflist_thumb_cleanup(vfl);}static void vflist_thumb_do(ViewFileList *vfl, ThumbLoader *tl, FileData *fd){ GtkListStore *store; GtkTreeIter iter; if (!fd || vflist_find_row(vfl, fd, &iter) < 0) return; if (fd->pixbuf) g_object_unref(fd->pixbuf); fd->pixbuf = thumb_loader_get_pixbuf(tl, TRUE); store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview))); gtk_list_store_set(store, &iter, FILE_COLUMN_THUMB, fd->pixbuf, -1); vflist_thumb_status(vfl, (gdouble)(vfl->thumbs_count) / g_list_length(vfl->list), _("Loading thumbs..."));}static void vflist_thumb_error_cb(ThumbLoader *tl, gpointer data){ ViewFileList *vfl = data; if (vfl->thumbs_filedata && vfl->thumbs_loader == tl) { vflist_thumb_do(vfl, tl, vfl->thumbs_filedata); } while (vflist_thumb_next(vfl));}static void vflist_thumb_done_cb(ThumbLoader *tl, gpointer data){ ViewFileList *vfl = data; if (vfl->thumbs_filedata && vfl->thumbs_loader == tl) { vflist_thumb_do(vfl, tl, vfl->thumbs_filedata); } while (vflist_thumb_next(vfl));}static gint vflist_thumb_next(ViewFileList *vfl){ GtkTreePath *tpath; FileData *fd = NULL; /* first check the visible files */ if (GTK_WIDGET_REALIZED(vfl->listview) && gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vfl->listview), 0, 0, &tpath, NULL, NULL, NULL)) { GtkTreeModel *store; GtkTreeIter iter; gint valid = TRUE; store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); gtk_tree_model_get_iter(store, &iter, tpath); gtk_tree_path_free(tpath); while (!fd && valid && tree_view_row_get_visibility(GTK_TREE_VIEW(vfl->listview), &iter, FALSE) == 0) { gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); if (fd->pixbuf) fd = NULL; valid = gtk_tree_model_iter_next(store, &iter); } } /* then find first undone */ if (!fd) { GList *work = vfl->list; while (work && !fd) { FileData *fd_p = work->data; work = work->next; if (!fd_p->pixbuf) fd = fd_p; } } if (!fd) { /* done */ vflist_thumb_cleanup(vfl); return FALSE; } vfl->thumbs_count++; vfl->thumbs_filedata = fd; thumb_loader_free(vfl->thumbs_loader); vfl->thumbs_loader = thumb_loader_new(thumb_max_width, thumb_max_height); thumb_loader_set_callbacks(vfl->thumbs_loader, vflist_thumb_done_cb, vflist_thumb_error_cb, NULL, vfl); if (!thumb_loader_start(vfl->thumbs_loader, fd->path)) { /* set icon to unknown, continue */ if (debug) printf("thumb loader start failed %s\n", vfl->thumbs_loader->path); vflist_thumb_do(vfl, vfl->thumbs_loader, fd); return TRUE; } return FALSE;}static void vflist_thumb_update(ViewFileList *vfl){ vflist_thumb_stop(vfl); if (!vfl->thumbs_enabled) return; vflist_thumb_status(vfl, 0.0, _("Loading thumbs...")); vfl->thumbs_running = TRUE; while (vflist_thumb_next(vfl));}/* *----------------------------------------------------------------------------- * row stuff *----------------------------------------------------------------------------- */FileData *vflist_index_get_data(ViewFileList *vfl, gint row){ return g_list_nth_data(vfl->list, row);}gchar *vflist_index_get_path(ViewFileList *vfl, gint row){ FileData *fd; fd = g_list_nth_data(vfl->list, row); return (fd ? fd->path : NULL);}static gint vflist_row_by_path(ViewFileList *vfl, const gchar *path, FileData **fd){ gint p = 0; GList *work; if (!path) return -1; work = vfl->list; while (work) { FileData *fd_n = work->data; if (strcmp(path, fd_n->path) == 0) { if (fd) *fd = fd_n; return p; } work = work->next; p++; } if (fd) *fd = NULL; return -1;}gint vflist_index_by_path(ViewFileList *vfl, const gchar *path){ return vflist_row_by_path(vfl, path, NULL);}gint vflist_count(ViewFileList *vfl, gint64 *bytes){ if (bytes) { gint64 b = 0; GList *work; work = vfl->list; while (work) { FileData *fd = work->data; work = work->next; b += fd->size; } *bytes = b; } return g_list_length(vfl->list);}GList *vflist_get_list(ViewFileList *vfl){ GList *list = NULL; GList *work; work = vfl->list; while (work) { FileData *fd = work->data; work = work->next; list = g_list_prepend(list, g_strdup(fd->path)); } return g_list_reverse(list);}/* *----------------------------------------------------------------------------- * selections *----------------------------------------------------------------------------- */static gint vflist_row_is_selected(ViewFileList *vfl, FileData *fd){ GtkTreeModel *store; GtkTreeSelection *selection; GList *slist; GList *work; gint found = FALSE; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); slist = gtk_tree_selection_get_selected_rows(selection, &store); work = slist; while (!found && work) { GtkTreePath *tpath = work->data; FileData *fd_n; GtkTreeIter iter; gtk_tree_model_get_iter(store, &iter, tpath); gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd_n, -1); if (fd_n == fd) found = TRUE; work = work->next; } g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); g_list_free(slist); return found;}gint vflist_index_is_selected(ViewFileList *vfl, gint row){ FileData *fd; fd = vflist_index_get_data(vfl, row); return vflist_row_is_selected(vfl, fd);}gint vflist_selection_count(ViewFileList *vfl, gint64 *bytes){ GtkTreeModel *store; GtkTreeSelection *selection; GList *slist; gint count; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); slist = gtk_tree_selection_get_selected_rows(selection, &store); if (bytes) { gint64 b = 0; GList *work; work = slist; while (work) { GtkTreePath *tpath = work->data; GtkTreeIter iter; FileData *fd; gtk_tree_model_get_iter(store, &iter, tpath); gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); b += fd->size; work = work->next; } *bytes = b; } count = g_list_length(slist); g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); g_list_free(slist); return count;}GList *vflist_selection_get_list(ViewFileList *vfl){ GtkTreeModel *store; GtkTreeSelection *selection; GList *slist; GList *list = NULL; GList *work; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); slist = gtk_tree_selection_get_selected_rows(selection, &store); work = slist; while (work) { GtkTreePath *tpath = work->data; FileData *fd; GtkTreeIter iter; gtk_tree_model_get_iter(store, &iter, tpath); gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); list = g_list_prepend(list, g_strdup(fd->path)); work = work->next; } g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); g_list_free(slist); return g_list_reverse(list);}GList *vflist_selection_get_list_by_index(ViewFileList *vfl){ GtkTreeModel *store; GtkTreeSelection *selection; GList *slist; GList *list = NULL; GList *work; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); slist = gtk_tree_selection_get_selected_rows(selection, &store); work = slist; while (work) { GtkTreePath *tpath = work->data; FileData *fd; GtkTreeIter iter; gtk_tree_model_get_iter(store, &iter, tpath); gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1); list = g_list_prepend(list, GINT_TO_POINTER(g_list_index(vfl->list, fd))); work = work->next; } g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); g_list_free(slist); return g_list_reverse(list);}void vflist_select_all(ViewFileList *vfl){ GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); gtk_tree_selection_select_all(selection); vfl->select_fd = NULL;}void vflist_select_none(ViewFileList *vfl){ GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); gtk_tree_selection_unselect_all(selection);}void vflist_select_by_path(ViewFileList *vfl, const gchar *path){ FileData *fd; GtkTreeIter iter; if (vflist_row_by_path(vfl, path, &fd) < 0) return; if (vflist_find_row(vfl, fd, &iter) < 0) return; tree_view_row_make_visible(GTK_TREE_VIEW(vfl->listview), &iter, TRUE); if (!vflist_row_is_selected(vfl, fd)) { GtkTreeSelection *selection; GtkTreeModel *store; GtkTreePath *tpath; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfl->listview)); gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_iter(selection, &iter); vflist_move_cursor(vfl, &iter); store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfl->listview)); tpath = gtk_tree_model_get_path(store, &iter); gtk_tree_view_set_cursor(GTK_TREE_VIEW(vfl->listview), tpath, NULL, FALSE); gtk_tree_path_free(tpath); }}/* *----------------------------------------------------------------------------- * core (population) *----------------------------------------------------------------------------- */static void vflist_listview_set_height(GtkWidget *listview, gint thumb){ GtkTreeViewColumn *column; GtkCellRenderer *cell; GList *list; column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), FILE_COLUMN_THUMB - 1); if (!column) return;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?