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 + -
显示快捷键?