⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 view_dir_tree.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 3 页
字号:
	list = parts_list(path);	list = parts_list_add_node_points(vdt, list);	work = list;	while (work)		{		PathData *pd = work->data;		if (pd->node == NULL)			{			PathData *parent_pd;			GtkTreeIter parent_iter;			GtkTreeIter iter;			NodeData *nd;			if (work == list)				{				/* should not happen */				printf("vdtree warning, root node not found\n");				parts_list_free(list);				vdtree_busy_pop(vdt);				return NULL;				}			parent_pd = work->prev->data;			if (!vdtree_find_row(vdt, parent_pd->node, &parent_iter, NULL) ||			    !vdtree_populate_path_by_iter(vdt, &parent_iter, force, path) ||			    (nd = vdtree_find_iter_by_name(vdt, &parent_iter, pd->name, &iter)) == NULL)				{				printf("vdtree warning, aborted at %s\n", parent_pd->name);				parts_list_free(list);				vdtree_busy_pop(vdt);				return NULL;				}			pd->node = nd->fd;			if (pd->node)				{				if (expand)					{					vdtree_expand_by_iter(vdt, &parent_iter, TRUE);					vdtree_expand_by_iter(vdt, &iter, TRUE);					}				vdtree_populate_path_by_iter(vdt, &iter, force, path);				}			}		else			{			GtkTreeIter iter;			if (vdtree_find_row(vdt, pd->node, &iter, NULL))				{				if (expand) vdtree_expand_by_iter(vdt, &iter, TRUE);				vdtree_populate_path_by_iter(vdt, &iter, force, path);				}			}		work = work->next;		}	work = g_list_last(list);	if (work)		{		PathData *pd = work->data;		fd = pd->node;		}	parts_list_free(list);	vdtree_busy_pop(vdt);	return fd;}/* *---------------------------------------------------------------------------- * access *---------------------------------------------------------------------------- */static gint selection_is_ok = FALSE;static gboolean vdtree_select_cb(GtkTreeSelection *selection, GtkTreeModel *store, GtkTreePath *tpath,                                 gboolean path_currently_selected, gpointer data){	return selection_is_ok;}static void vdtree_select_row(ViewDirTree *vdt, FileData *fd){	GtkTreeSelection *selection;	GtkTreeIter iter;                                                                                                                               	if (!vdtree_find_row(vdt, fd, &iter, NULL)) return;	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vdt->treeview));	/* hack, such that selection is only allowed to be changed from here */	selection_is_ok = TRUE;	gtk_tree_selection_select_iter(selection, &iter);	selection_is_ok = FALSE;	if (!vdtree_populate_path_by_iter(vdt, &iter, FALSE, vdt->path)) return;	vdtree_expand_by_iter(vdt, &iter, TRUE);        if (fd && vdt->select_func)                {                vdt->select_func(vdt, fd->path, vdt->select_data);                }}gint vdtree_set_path(ViewDirTree *vdt, const gchar *path){	FileData *fd;	GtkTreeIter iter;	if (!path) return FALSE;	if (vdt->path && strcmp(path, vdt->path) == 0) return TRUE;	g_free(vdt->path);	vdt->path = g_strdup(path);	fd = vdtree_populate_path(vdt, vdt->path, TRUE, TRUE);	if (!fd) return FALSE;	if (vdtree_find_row(vdt, fd, &iter, NULL))		{		GtkTreeModel *store;		GtkTreePath *tpath;		tree_view_row_make_visible(GTK_TREE_VIEW(vdt->treeview), &iter, TRUE);		store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->treeview));		tpath = gtk_tree_model_get_path(store, &iter);		gtk_tree_view_set_cursor(GTK_TREE_VIEW(vdt->treeview), tpath, NULL, FALSE);		gtk_tree_path_free(tpath);		vdtree_select_row(vdt, fd);		}	return TRUE;}#if 0const gchar *vdtree_get_path(ViewDirTree *vdt){	return vdt->path;}#endifvoid vdtree_refresh(ViewDirTree *vdt){	vdtree_populate_path(vdt, vdt->path, FALSE, TRUE);}const gchar *vdtree_row_get_path(ViewDirTree *vdt, gint row){	printf("FIXME: no get row path\n");	return NULL;}/* *---------------------------------------------------------------------------- * callbacks *---------------------------------------------------------------------------- */static void vdtree_menu_position_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data){	ViewDirTree *vdt = data;	GtkTreeModel *store;	GtkTreeIter iter;	GtkTreePath *tpath;	gint cw, ch;	if (vdtree_find_row(vdt, vdt->click_fd, &iter, NULL) < 0) return;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->treeview));	tpath = gtk_tree_model_get_path(store, &iter);	tree_view_get_cell_clamped(GTK_TREE_VIEW(vdt->treeview), tpath, 0, TRUE, x, y, &cw, &ch);	gtk_tree_path_free(tpath);	*y += ch;	popup_menu_position_clamp(menu, x, y, 0);}static gint vdtree_press_key_cb(GtkWidget *widget, GdkEventKey *event, gpointer data){	ViewDirTree *vdt = data;	GtkTreePath *tpath;	GtkTreeIter iter;	FileData *fd = NULL;	gtk_tree_view_get_cursor(GTK_TREE_VIEW(vdt->treeview), &tpath, NULL);	if (tpath)		{		GtkTreeModel *store;		NodeData *nd;		store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));		gtk_tree_model_get_iter(store, &iter, tpath);		gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1);		gtk_tree_path_free(tpath);		fd = (nd) ? nd->fd : NULL;		}	switch (event->keyval)		{		case GDK_Menu:			vdt->click_fd = fd;			vdtree_color_set(vdt, vdt->click_fd, TRUE);			vdt->popup = vdtree_pop_menu(vdt, vdt->click_fd);			gtk_menu_popup(GTK_MENU(vdt->popup), NULL, NULL, vdtree_menu_position_cb, vdt, 0, GDK_CURRENT_TIME);			return TRUE;			break;		case GDK_plus:		case GDK_Right:		case GDK_KP_Add:			if (fd)				{				vdtree_populate_path_by_iter(vdt, &iter, FALSE, vdt->path);				vdtree_icon_set_by_iter(vdt, &iter, vdt->pf->open);				}			break;		}	return FALSE;}static gint vdtree_clicked_on_expander(GtkTreeView *treeview, GtkTreePath *tpath,				       GtkTreeViewColumn *column, gint x, gint y, gint *left_of_expander){	gint depth;	gint size;	gint sep;	gint exp_width;	if (column != gtk_tree_view_get_expander_column(treeview)) return FALSE;	gtk_widget_style_get(GTK_WIDGET(treeview), "expander-size", &size, "horizontal-separator", &sep, NULL);	depth = gtk_tree_path_get_depth(tpath);	exp_width = sep + size + sep;	if (x <= depth * exp_width)		{		if (left_of_expander) *left_of_expander = !(x >= (depth - 1) * exp_width);		return TRUE;		}	return FALSE;}static gint vdtree_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){	ViewDirTree *vdt = data;	GtkTreePath *tpath;	GtkTreeViewColumn *column;	GtkTreeIter iter;	NodeData *nd = NULL;	if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y,					  &tpath, &column, NULL, NULL))		{		GtkTreeModel *store;		gint left_of_expander;		store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));		gtk_tree_model_get_iter(store, &iter, tpath);		gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1);		gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE);		if (vdtree_clicked_on_expander(GTK_TREE_VIEW(widget), tpath, column, bevent->x, bevent->y, &left_of_expander))			{			vdt->click_fd = NULL;			/* clicking this region should automatically reveal an expander, if necessary			 * treeview bug: the expander will not expand until a button_motion_event highlights it.			 */			if (bevent->button == 1 &&			    !left_of_expander &&			    !gtk_tree_view_row_expanded(GTK_TREE_VIEW(vdt->treeview), tpath))				{				vdtree_populate_path_by_iter(vdt, &iter, FALSE, vdt->path);				vdtree_icon_set_by_iter(vdt, &iter, vdt->pf->open);				}			gtk_tree_path_free(tpath);			return FALSE;			}		gtk_tree_path_free(tpath);		}	vdt->click_fd = (nd) ? nd->fd : NULL;	vdtree_color_set(vdt, vdt->click_fd, TRUE);	if (bevent->button == 3)		{		vdt->popup = vdtree_pop_menu(vdt, vdt->click_fd);		gtk_menu_popup(GTK_MENU(vdt->popup), NULL, NULL, NULL, NULL,			       bevent->button, bevent->time);		}	return (bevent->button != 1);}static gint vdtree_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){	ViewDirTree *vdt = data;	GtkTreePath *tpath;	GtkTreeIter iter;	NodeData *nd = NULL;	if (!vdt->click_fd) return FALSE;	vdtree_color_set(vdt, vdt->click_fd, FALSE);	if (bevent->button != 1) return TRUE;	if ((bevent->x != 0 || bevent->y != 0) &&	    gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y,					  &tpath, NULL, NULL, NULL))		{		GtkTreeModel *store;		store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));		gtk_tree_model_get_iter(store, &iter, tpath);		gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1);		gtk_tree_path_free(tpath);		}	if (nd && vdt->click_fd == nd->fd)		{		vdtree_select_row(vdt, vdt->click_fd);		}	return FALSE;}static void vdtree_row_expanded(GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *tpath, gpointer data){	ViewDirTree *vdt = data;	vdtree_populate_path_by_iter(vdt, iter, FALSE, NULL);	vdtree_icon_set_by_iter(vdt, iter, vdt->pf->open);}static void vdtree_row_collapsed(GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *tpath, gpointer data){	ViewDirTree *vdt = data;	vdtree_icon_set_by_iter(vdt, iter, vdt->pf->close);}static gint vdtree_sort_cb(GtkTreeModel *store, GtkTreeIter *a, GtkTreeIter *b, gpointer data){	NodeData *nda;	NodeData *ndb;	gtk_tree_model_get(store, a, DIR_COLUMN_POINTER, &nda, -1);	gtk_tree_model_get(store, b, DIR_COLUMN_POINTER, &ndb, -1);	return CASE_SORT(nda->fd->name, ndb->fd->name);}/* *---------------------------------------------------------------------------- * core *---------------------------------------------------------------------------- */static void vdtree_setup_root(ViewDirTree *vdt){	const gchar *path = "/";	FileData *fd;	fd = g_new0(FileData, 1);	fd->path = g_strdup(path);	fd->name = fd->path;	fd->size = 0;	fd->date = filetime(path);	vdtree_add_by_data(vdt, fd, NULL);	vdtree_expand_by_data(vdt, fd, TRUE);	vdtree_populate_path(vdt, path, FALSE, FALSE);}static void vdtree_activate_cb(GtkTreeView *tview, GtkTreePath *tpath, GtkTreeViewColumn *column, gpointer data){	ViewDirTree *vdt = data;	GtkTreeModel *store;	GtkTreeIter iter;	NodeData *nd;	store = gtk_tree_view_get_model(tview);	gtk_tree_model_get_iter(store, &iter, tpath);	gtk_tree_model_get(store, &iter, DIR_COLUMN_POINTER, &nd, -1);	vdtree_select_row(vdt, nd->fd);}static GdkColor *vdtree_color_shifted(GtkWidget *widget){	static GdkColor color;	static GtkWidget *done = NULL;	if (done != widget)		{		GtkStyle *style;		style = gtk_widget_get_style(widget);		memcpy(&color, &style->base[GTK_STATE_NORMAL], sizeof(color));		shift_color(&color, -1, 0);		done = widget;		}	return &color;}static void vdtree_color_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,			    GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data){	ViewDirTree *vdt = data;	gboolean set;	gtk_tree_model_get(tree_model, iter, DIR_COLUMN_COLOR, &set, -1);	g_object_set(G_OBJECT(cell),		     "cell-background-gdk", vdtree_color_shifted(vdt->treeview),		     "cell-background-set", set, NULL);}static gboolean vdtree_destroy_node_cb(GtkTreeModel *store, GtkTreePath *tpath, GtkTreeIter *iter, gpointer data){	NodeData *nd;	gtk_tree_model_get(store, iter, DIR_COLUMN_POINTER, &nd, -1);	vdtree_node_free(nd);	return FALSE;}static void vdtree_destroy_cb(GtkWidget *widget, gpointer data){	ViewDirTree *vdt = data;	GtkTreeModel *store;	if (vdt->popup)		{		g_signal_handlers_disconnect_matched(G_OBJECT(vdt->popup), G_SIGNAL_MATCH_DATA,						     0, 0, 0, NULL, vdt);		gtk_widget_destroy(vdt->popup);		}	vdtree_dnd_drop_expand_cancel(vdt);	vdtree_dnd_drop_scroll_cancel(vdt);	widget_auto_scroll_stop(vdt->treeview);	store = gtk_tree_view_get_model(GTK_TREE_VIEW(vdt->treeview));	gtk_tree_model_foreach(store, vdtree_destroy_node_cb, vdt);	path_list_free(vdt->drop_list);	folder_icons_free(vdt->pf);	g_free(vdt->path);	g_free(vdt);}ViewDirTree *vdtree_new(const gchar *path, gint expand){	ViewDirTree *vdt;	GtkTreeStore *store;	GtkTreeSelection *selection;	GtkTreeViewColumn *column;	GtkCellRenderer *renderer;	vdt = g_new0(ViewDirTree, 1);	vdt->path = NULL;	vdt->click_fd = NULL;	vdt->drop_fd = NULL;	vdt->drop_list = NULL;	vdt->drop_scroll_id = -1;	vdt->drop_expand_id = -1;	vdt->popup = NULL;	vdt->busy_ref = 0;	vdt->widget = gtk_scrolled_window_new(NULL, NULL);	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(vdt->widget), GTK_SHADOW_IN);	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vdt->widget),				       GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);	g_signal_connect(G_OBJECT(vdt->widget), "destroy",			 G_CALLBACK(vdtree_destroy_cb), vdt);	store = gtk_tree_store_new(4, G_TYPE_POINTER, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT);	vdt->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));	g_object_unref(store);	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(vdt->treeview), FALSE);	gtk_tree_view_set_enable_search(GTK_TREE_VIEW(vdt->treeview), FALSE);	gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), vdtree_sort_cb, vdt, NULL);	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store),					     GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);	g_signal_connect(G_OBJECT(vdt->treeview), "row_activated",			 G_CALLBACK(vdtree_activate_cb), vdt);	g_signal_connect(G_OBJECT(vdt->treeview), "row_expanded",			 G_CALLBACK(vdtree_row_expanded), vdt);	g_signal_connect(G_OBJECT(vdt->treeview), "row_collapsed",			 G_CALLBACK(vdtree_row_collapsed), vdt);#if 0	g_signal_connect(G_OBJECT(store), "row_deleted",			 G_CALLBACK(vdtree_row_deleted_cb), vdt);#endif	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vdt->treeview));	gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);	gtk_tree_selection_set_select_function(selection, vdtree_select_cb, vdt, NULL);	column = gtk_tree_view_column_new();	gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);	renderer = gtk_cell_renderer_pixbuf_new();	gtk_tree_view_column_pack_start(column, renderer, FALSE);	gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", DIR_COLUMN_ICON);	gtk_tree_view_column_set_cell_data_func(column, renderer, vdtree_color_cb, vdt, NULL);	renderer = gtk_cell_renderer_text_new();	gtk_tree_view_column_pack_start(column, renderer, TRUE);	gtk_tree_view_column_add_attribute(column, renderer, "text", DIR_COLUMN_NAME);	gtk_tree_view_column_set_cell_data_func(column, renderer, vdtree_color_cb, vdt, NULL);	gtk_tree_view_append_column(GTK_TREE_VIEW(vdt->treeview), column);	g_signal_connect(G_OBJECT(vdt->treeview), "key_press_event",			 G_CALLBACK(vdtree_press_key_cb), vdt);	gtk_container_add(GTK_CONTAINER(vdt->widget), vdt->treeview);	gtk_widget_show(vdt->treeview);	vdt->pf = folder_icons_new();	vdtree_setup_root(vdt);	vdtree_dnd_init(vdt);	g_signal_connect(G_OBJECT(vdt->treeview), "button_press_event",			 G_CALLBACK(vdtree_press_cb), vdt);	g_signal_connect(G_OBJECT(vdt->treeview), "button_release_event",			 G_CALLBACK(vdtree_release_cb), vdt);	vdtree_set_path(vdt, path);	return vdt;}void vdtree_set_select_func(ViewDirTree *vdt,                            void (*func)(ViewDirTree *vdt, const gchar *path, gpointer data), gpointer data){        vdt->select_func = func;        vdt->select_data = data;}#if 0void vdtree_set_click_func(ViewDirTree *vdt,			   void (*func)(ViewDirTree *vdt, GdkEventButton *event, FileData *fd, gpointer), gpointer data){	if (!td) return;	vdt->click_func = func;	vdt->click_data = data;}#endifvoid vdtree_set_layout(ViewDirTree *vdt, LayoutWindow *layout){	vdt->layout = layout;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -