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

📄 collect-table.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 4 页
字号:
void collection_table_file_update(CollectTable *ct, CollectInfo *info){	GtkTreeIter iter;	gint row, col;	gdouble value;	if (!info)		{		collection_table_update_extras(ct, FALSE, 0.0);		return;		}	if (!collection_table_find_position(ct, info, &row, &col)) return;	if (ct->columns != 0 && ct->rows != 0)		{		value = (gdouble)(row * ct->columns + col) / (ct->columns * ct->rows);		}	else		{		value = 0.0;		}	collection_table_update_extras(ct, TRUE, value);	if (collection_table_find_iter(ct, info, &iter, NULL))		{		GtkTreeModel *store;		GList *list;		store = gtk_tree_view_get_model(GTK_TREE_VIEW(ct->listview));		gtk_tree_model_get(store, &iter, CTABLE_COLUMN_POINTER, &list, -1);		gtk_list_store_set(GTK_LIST_STORE(store), &iter, CTABLE_COLUMN_POINTER, list, -1);		}}void collection_table_file_add(CollectTable *ct, CollectInfo *info){	collection_table_sync_idle(ct);}void collection_table_file_insert(CollectTable *ct, CollectInfo *ci){	collection_table_sync_idle(ct);}void collection_table_file_remove(CollectTable *ct, CollectInfo *ci){	if (ci && INFO_SELECTED(ci))		{		ct->selection = g_list_remove(ct->selection, ci);		}	collection_table_sync_idle(ct);}void collection_table_refresh(CollectTable *ct){	collection_table_populate(ct, FALSE);}/* *------------------------------------------------------------------- * dnd *------------------------------------------------------------------- */static void collection_table_add_dir_recursive(CollectTable *ct, gchar *path, gint recursive){	GList *d = NULL;	GList *f = NULL;	if (path_list(path, &f, recursive ? &d : NULL))		{		GList *work;		f = path_list_filter(f, FALSE);		d = path_list_filter(d, TRUE);		f = path_list_sort(f);		d = path_list_sort(d);		collection_table_insert_path_list(ct, f, ct->marker_info);		work = g_list_last(d);		while (work)			{			collection_table_add_dir_recursive(ct, (gchar *)work->data, TRUE);			work = work->prev;			}		path_list_free(f);		path_list_free(d);		}}static void confirm_dir_list_do(CollectTable *ct, GList *list, gint recursive){	GList *work = list;	while (work)		{		gchar *path = work->data;		work = work->next;		if (isdir(path)) collection_table_add_dir_recursive(ct, path, recursive);		}	collection_table_insert_path_list(ct, list, ct->marker_info);}static void confirm_dir_list_add(GtkWidget *widget, gpointer data){	CollectTable *ct = data;	confirm_dir_list_do(ct, ct->drop_list, FALSE);}static void confirm_dir_list_recurse(GtkWidget *widget, gpointer data){	CollectTable *ct = data;	confirm_dir_list_do(ct, ct->drop_list, TRUE);}static void confirm_dir_list_skip(GtkWidget *widget, gpointer data){	CollectTable *ct = data;	collection_table_insert_path_list(ct, ct->drop_list, ct->marker_info);}static GtkWidget *collection_table_drop_menu(CollectTable *ct){	GtkWidget *menu;	menu = popup_menu_short_lived();	g_signal_connect(G_OBJECT(menu), "destroy",			 G_CALLBACK(collection_table_popup_destroy_cb), ct);	menu_item_add_stock(menu, _("Dropped list includes folders."), GTK_STOCK_DND_MULTIPLE, NULL, NULL);	menu_item_add_divider(menu);	menu_item_add_stock(menu, _("_Add contents"), GTK_STOCK_OK,			    G_CALLBACK(confirm_dir_list_add), ct);	menu_item_add_stock(menu, _("Add contents _recursive"), GTK_STOCK_ADD,			    G_CALLBACK(confirm_dir_list_recurse), ct);	menu_item_add_stock(menu, _("_Skip folders"), GTK_STOCK_REMOVE,			    G_CALLBACK(confirm_dir_list_skip), ct);	menu_item_add_divider(menu);	menu_item_add_stock(menu, _("Cancel"), GTK_STOCK_CANCEL, NULL, ct);	return menu;}/* *------------------------------------------------------------------- * dnd *------------------------------------------------------------------- */static GtkTargetEntry collection_drag_types[] = {	{ "application/x-gqview-collection-member", 0, TARGET_APP_COLLECTION_MEMBER },	{ "text/uri-list", 0, TARGET_URI_LIST },	{ "text/plain", 0, TARGET_TEXT_PLAIN }};static gint n_collection_drag_types = 3;static GtkTargetEntry collection_drop_types[] = {	{ "application/x-gqview-collection-member", 0, TARGET_APP_COLLECTION_MEMBER },	{ "text/uri-list", 0, TARGET_URI_LIST }};static gint n_collection_drop_types = 2;static void collection_table_dnd_get(GtkWidget *widget, GdkDragContext *context,				     GtkSelectionData *selection_data, guint info,				     guint time, gpointer data){	CollectTable *ct = data;	gint selected;	GList *list = NULL;	gchar *uri_text = NULL;	gint total;	if (!ct->click_info) return;	selected = INFO_SELECTED(ct->click_info);		switch (info)		{		case TARGET_APP_COLLECTION_MEMBER:			if (selected)				{				uri_text = collection_info_list_to_dnd_data(ct->cd, ct->selection, &total);				}			else				{				list = g_list_append(NULL, ct->click_info);				uri_text = collection_info_list_to_dnd_data(ct->cd, list, &total);				g_list_free(list);				}			break;		case TARGET_URI_LIST:		case TARGET_TEXT_PLAIN:		default:			if (selected)				{				list = collection_table_selection_get_list(ct);				}			else				{				const gchar *path = ct->click_info->path;				list = g_list_append(NULL, g_strdup(path));				}			if (!list) return;			uri_text = uri_text_from_list(list, &total, (info == TARGET_TEXT_PLAIN));			path_list_free(list);			break;		}	gtk_selection_data_set(selection_data, selection_data->target,			       8, uri_text, total);	g_free(uri_text);}static void collection_table_dnd_receive(GtkWidget *widget, GdkDragContext *context,					  gint x, gint y,					  GtkSelectionData *selection_data, guint info,					  guint time, gpointer data){	CollectTable *ct = data;	GList *list = NULL;	GList *info_list = NULL;	CollectionData *source;	CollectInfo *drop_info;	GList *work;	if (debug) printf(selection_data->data);	collection_table_scroll(ct, FALSE);	collection_table_insert_marker(ct, NULL, FALSE);	drop_info = collection_table_insert_point(ct, x, y);	switch (info)		{		case TARGET_APP_COLLECTION_MEMBER:			source = collection_from_dnd_data((gchar *)selection_data->data, &list, &info_list);			if (source)				{				if (source == ct->cd)					{					gint row = -1;					gint col = -1;					/* it is a move within a collection */					path_list_free(list);					list = NULL;					if (!drop_info)						{						collection_table_move_by_info_list(ct, info_list, -1, -1);						}					else if (collection_table_find_position(ct, drop_info, &row, &col))						{						collection_table_move_by_info_list(ct, info_list, row, col);						}					}				else					{					/* it is a move/copy across collections */					if (context->action == GDK_ACTION_MOVE)						{						collection_remove_by_info_list(source, info_list);						}					}				g_list_free(info_list);				}			break;		case TARGET_URI_LIST:			list = uri_list_from_text(selection_data->data, TRUE);			work = list;			while (work)				{				if (isdir((gchar *)work->data))					{					GtkWidget *menu;					ct->drop_list = list;					ct->drop_info = drop_info;					menu = collection_table_drop_menu(ct);					gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, time);					return;					}				work = work->next;				}			break;		default:			list = NULL;			break;		}	if (list)		{		collection_table_insert_path_list(ct, list, drop_info);		path_list_free(list);		}}static void collection_table_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data){	CollectTable *ct = data;	if (ct->click_info && ct->click_info->pixbuf)		{		gint items;		if (INFO_SELECTED(ct->click_info))			items = g_list_length(ct->selection);		else			items = 1;		dnd_set_drag_icon(widget, context, ct->click_info->pixbuf, items);		}}static void collection_table_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data){	CollectTable *ct = data;	/* apparently a leave event is not generated on a drop */	tip_unschedule(ct);	collection_table_scroll(ct, FALSE);}static gint collection_table_dnd_motion(GtkWidget *widget, GdkDragContext *context,					gint x, gint y, guint time, gpointer data){	CollectTable *ct = data;	collection_table_motion_update(ct, x, y, TRUE);	collection_table_scroll(ct, TRUE);	return FALSE;}static void collection_table_dnd_leave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer data){	CollectTable *ct = data;	collection_table_scroll(ct, FALSE);} static void collection_table_dnd_init(CollectTable *ct){	gtk_drag_source_set(ct->listview, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,			    collection_drag_types, n_collection_drag_types,			    GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);	g_signal_connect(G_OBJECT(ct->listview), "drag_data_get",			 G_CALLBACK(collection_table_dnd_get), ct);	g_signal_connect(G_OBJECT(ct->listview), "drag_begin",			 G_CALLBACK(collection_table_dnd_begin), ct);	g_signal_connect(G_OBJECT(ct->listview), "drag_end",			 G_CALLBACK(collection_table_dnd_end), ct);	gtk_drag_dest_set(ct->listview,			  GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,			  collection_drop_types, n_collection_drop_types,			  GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);	g_signal_connect(G_OBJECT(ct->listview), "drag_motion",			 G_CALLBACK(collection_table_dnd_motion), ct);	g_signal_connect(G_OBJECT(ct->listview), "drag_leave",			 G_CALLBACK(collection_table_dnd_leave), ct);	g_signal_connect(G_OBJECT(ct->listview), "drag_data_received",			 G_CALLBACK(collection_table_dnd_receive), ct);}/* *----------------------------------------------------------------------------- * draw, etc. *----------------------------------------------------------------------------- */typedef struct _ColumnData ColumnData;struct _ColumnData{	CollectTable *ct;	gint number;};static void collection_table_cell_data_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,					  GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data){	ColumnData *cd = data;	CollectTable *ct;	GtkStyle *style;	GList *list;	CollectInfo *info;	GdkColor color_fg;	GdkColor color_bg;	ct = cd->ct;	gtk_tree_model_get(tree_model, iter, CTABLE_COLUMN_POINTER, &list, -1);	info = g_list_nth_data(list, cd->number);	style = gtk_widget_get_style(ct->listview);	if (info && (info->flag_mask & SELECTION_SELECTED) )		{		memcpy(&color_fg, &style->text[GTK_STATE_SELECTED], sizeof(color_fg));		memcpy(&color_bg, &style->base[GTK_STATE_SELECTED], sizeof(color_bg));		}	else		{		memcpy(&color_fg, &style->text[GTK_STATE_NORMAL], sizeof(color_fg));		memcpy(&color_bg, &style->base[GTK_STATE_NORMAL], sizeof(color_bg));		}	if (info && (info->flag_mask & SELECTION_PRELIGHT))		{#if 0		shift_color(&color_fg, -1, 0);#endif		shift_color(&color_bg, -1, 0);		}	if (GQV_IS_CELL_RENDERER_ICON(cell))		{		if (info)			{			g_object_set(cell,	"pixbuf", info->pixbuf,						"text", filename_from_path(info->path),						"cell-background-gdk", &color_bg,						"cell-background-set", TRUE,						"foreground-gdk", &color_fg,						"foreground-set", TRUE,						"has-focus", (ct->focus_info == info), NULL);			}		else			{			g_object_set(cell,	"pixbuf", NULL,						"text", NULL,						"cell-background-set", FALSE,						"foreground-set", FALSE,						"has-focus", FALSE,  NULL);			}		}}static void collection_table_append_column(CollectTable *ct, gint n){	ColumnData *cd;	GtkTreeViewColumn *column;	GtkCellRenderer *renderer;	column = gtk_tree_view_column_new();	gtk_tree_view_column_set_min_width(column, 0);	gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);	gtk_tree_view_column_set_alignment(column, 0.5);	renderer = gqv_cell_renderer_icon_new();	gtk_tree_view_column_pack_start(column, renderer, FALSE);	g_object_set(G_OBJECT(renderer), "xpad", THUMB_BORDER_PADDING * 2,					 "ypad", THUMB_BORDER_PADDING,					 "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);	g_object_set_data(G_OBJECT(column), "column_number", GINT_TO_POINTER(n));	cd = g_new0(ColumnData, 1);	cd->ct = ct;	cd->number = n;	gtk_tree_view_column_set_cell_data_func(column, renderer, collection_table_cell_data_cb, cd, g_free);	gtk_tree_view_append_column(GTK_TREE_VIEW(ct->listview), column);}/* *------------------------------------------------------------------- * init, destruction *------------------------------------------------------------------- */static void collection_table_destroy(GtkWidget *widget, gpointer data){	CollectTable *ct = data;	if (ct->popup)		{		g_signal_handlers_disconnect_matched(GTK_OBJECT(ct->popup), G_SIGNAL_MATCH_DATA,						     0, 0, 0, NULL, ct);		gtk_widget_destroy(ct->popup);		}	if (ct->sync_idle_id != -1) g_source_remove(ct->sync_idle_id);	tip_unschedule(ct);	collection_table_scroll(ct, FALSE);	g_free(ct);}static void collection_table_sized(GtkWidget *widget, GtkAllocation *allocation, gpointer data){	CollectTable *ct = data;	collection_table_populate_at_new_size(ct, allocation->width, allocation->height, FALSE);}CollectTable *collection_table_new(CollectionData *cd){	CollectTable *ct;	GtkListStore *store;	GtkTreeSelection *selection;	gint i;	ct = g_new0(CollectTable, 1);	ct->cd = cd;	ct->columns = 0;	ct->rows = 0;	ct->selection = NULL;	ct->prev_selection = NULL;	ct->tip_window = NULL;	ct->tip_delay_id = -1;	ct->marker_window = NULL;	ct->marker_info = NULL;	ct->status_label = NULL;	ct->extra_label = NULL;	ct->focus_row = 0;	ct->focus_column = 0;	ct->focus_info = NULL;	ct->show_text = show_icon_names;	ct->sync_idle_id = -1;	ct->drop_idle_id = -1;	ct->popup = NULL;	ct->drop_info = NULL;	ct->drop_list = NULL;	ct->scrolled = gtk_scrolled_window_new(NULL, NULL);	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(ct->scrolled), GTK_SHADOW_IN);	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ct->scrolled),					GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);	store = gtk_list_store_new(1, G_TYPE_POINTER);	ct->listview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));	g_object_unref(store);	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(ct->listview));	gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_NONE);	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(ct->listview), FALSE);	gtk_tree_view_set_enable_search(GTK_TREE_VIEW(ct->listview), FALSE);	for (i = 0; i < COLLECT_TABLE_MAX_COLUMNS; i++)		{		collection_table_append_column(ct, i);		}	/* zero width column to hide tree view focus, we draw it ourselves */	collection_table_append_column(ct, i);	/* end column to fill white space */	collection_table_append_column(ct, i);	g_signal_connect(G_OBJECT(ct->listview), "destroy",			 G_CALLBACK(collection_table_destroy), ct);	g_signal_connect(G_OBJECT(ct->listview), "size_allocate",			 G_CALLBACK(collection_table_sized), ct);	g_signal_connect(G_OBJECT(ct->listview), "key_press_event",			 G_CALLBACK(collection_table_press_key_cb), ct);	gtk_container_add(GTK_CONTAINER(ct->scrolled), ct->listview);	gtk_widget_show(ct->listview);	collection_table_dnd_init(ct);	gtk_widget_set_events(ct->listview, GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK |			      GDK_BUTTON_PRESS_MASK | GDK_LEAVE_NOTIFY_MASK);	g_signal_connect(G_OBJECT(ct->listview),"button_press_event",			 G_CALLBACK(collection_table_press_cb), ct);	g_signal_connect(G_OBJECT(ct->listview),"button_release_event",			 G_CALLBACK(collection_table_release_cb), ct);	g_signal_connect(G_OBJECT(ct->listview),"motion_notify_event",			 G_CALLBACK(collection_table_motion_cb), ct);	g_signal_connect(G_OBJECT(ct->listview), "leave_notify_event",			 G_CALLBACK(collection_table_leave_cb), ct);	return ct;}void collection_table_set_labels(CollectTable *ct, GtkWidget *status, GtkWidget *extra){	ct->status_label = status;	ct->extra_label = extra;	collection_table_update_status(ct);	collection_table_update_extras(ct, FALSE, 0.0);}CollectInfo *collection_table_get_focus_info(CollectTable *ct){	return collection_table_find_data(ct, ct->focus_row, ct->focus_column, NULL);}

⌨️ 快捷键说明

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