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

📄 view_file_icon.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * GQview * (C) 2004 John Ellis * * Author: John Ellis * * This software is released under the GNU General Public License (GNU GPL). * Please read the included file COPYING for more information. * This software comes with no warranty of any kind, use at your own risk! */#include "gqview.h"#include "view_file_icon.h"#include "cellrenderericon.h"#include "collect.h"#include "collect-io.h"#include "collect-table.h"#include "dnd.h"#include "editors.h"#include "img-view.h"#include "info.h"#include "filelist.h"#include "layout.h"#include "layout_image.h"#include "menu.h"#include "thumb.h"#include "utilops.h"#include "ui_bookmark.h"#include "ui_fileops.h"#include "ui_menu.h"#include "ui_tree_edit.h"#include <gdk/gdkkeysyms.h> /* for keyboard values *//* between these, the icon width is increased by thumb_max_width / 2 */#define THUMB_MIN_ICON_WIDTH 128#define THUMB_MAX_ICON_WIDTH 150#define VFICON_MAX_COLUMNS 32#define THUMB_BORDER_PADDING 2#define VFICON_TIP_DELAY 500#define ICON_DATA(x) ((IconData *)x)#define FILE_DATA(x) ((FileData *)x)enum {	FILE_COLUMN_POINTER = 0,	FILE_COLUMN_COUNT};typedef enum {	SELECTION_NONE		= 0,	SELECTION_SELECTED	= 1 << 0,	SELECTION_PRELIGHT	= 1 << 1,	SELECTION_FOCUS		= 1 << 2} SelectionType;typedef struct _IconData IconData;struct _IconData{	FileData fd;	SelectionType selected;};static gint iconlist_read(const gchar *path, GList **list){	GList *temp;	GList *work;	if (!filelist_read(path, &temp, NULL)) return FALSE;	work = temp;	while (work)		{		FileData *fd;		IconData *id;		fd = work->data;		id = g_new0(IconData, 1);		memcpy(id, fd, sizeof(FileData));		id->selected = SELECTION_NONE;		work->data = id;		g_free(fd);		work = work->next;		}	*list = temp;	return TRUE;}static void iconlist_free(GList *list){	filelist_free(list);}static void vficon_toggle_filenames(ViewFileIcon *vfi);static void vficon_selection_remove(ViewFileIcon *vfi, FileData *fd, SelectionType mask, GtkTreeIter *iter);static void vficon_move_focus(ViewFileIcon *vfi, gint row, gint col, gint relative);static void vficon_set_focus(ViewFileIcon *vfi, FileData *fd);static void vficon_thumb_update(ViewFileIcon *vfi);static void vficon_populate_at_new_size(ViewFileIcon *vfi, gint w, gint h, gint force);/* *----------------------------------------------------------------------------- * pop-up menu *----------------------------------------------------------------------------- */static GList *vficon_pop_menu_file_list(ViewFileIcon *vfi){	if (!vfi->click_fd) return NULL;	if (ICON_DATA(vfi->click_fd)->selected & SELECTION_SELECTED)		{		return vficon_selection_get_list(vfi);		}	return g_list_append(NULL, g_strdup(vfi->click_fd->path));}static void vficon_pop_menu_edit_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi;	gint n;	GList *list;	vfi = submenu_item_get_data(widget);	n = GPOINTER_TO_INT(data);	if (!vfi) return;	list = vficon_pop_menu_file_list(vfi);	start_editor_from_path_list(n, list);	path_list_free(list);}static void vficon_pop_menu_info_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;	info_window_new(NULL, vficon_pop_menu_file_list(vfi));}static void vficon_pop_menu_view_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;	if (!vfi->click_fd) return;	if (ICON_DATA(vfi->click_fd)->selected & SELECTION_SELECTED)		{		GList *list;				list = vficon_selection_get_list(vfi);		view_window_new_from_list(list);		path_list_free(list);		}	else		{		view_window_new(vfi->click_fd->path);		}}static void vficon_pop_menu_copy_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;	file_util_copy(NULL, vficon_pop_menu_file_list(vfi), NULL, vfi->listview);}static void vficon_pop_menu_move_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;	file_util_move(NULL, vficon_pop_menu_file_list(vfi), NULL, vfi->listview);}static void vficon_pop_menu_rename_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;	file_util_rename(NULL, vficon_pop_menu_file_list(vfi), vfi->listview);}static void vficon_pop_menu_delete_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;	file_util_delete(NULL, vficon_pop_menu_file_list(vfi), vfi->listview);}static void vficon_pop_menu_sort_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi;	SortType type;		vfi = submenu_item_get_data(widget);	if (!vfi) return;	type = (SortType)GPOINTER_TO_INT(data);	if (vfi->layout)		{		layout_sort_set(vfi->layout, type, vfi->sort_ascend);		}	else		{		vficon_sort_set(vfi, type, vfi->sort_ascend);		}}static void vficon_pop_menu_sort_ascend_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;	if (vfi->layout)		{		layout_sort_set(vfi->layout, vfi->sort_method, !vfi->sort_ascend);		}	else		{		vficon_sort_set(vfi, vfi->sort_method, !vfi->sort_ascend);		}}static void vficon_pop_menu_list_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;	if (vfi->layout) layout_views_set(vfi->layout, vfi->layout->tree_view, FALSE);}static void vficon_pop_menu_show_names_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;	vficon_toggle_filenames(vfi);}static void vficon_pop_menu_refresh_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;	vficon_refresh(vfi);}static void vficon_popup_destroy_cb(GtkWidget *widget, gpointer data){	ViewFileIcon *vfi = data;                                                                                                                               	vficon_selection_remove(vfi, vfi->click_fd, SELECTION_PRELIGHT, NULL);	vfi->click_fd = NULL;	vfi->popup = NULL;}static GtkWidget *vficon_pop_menu(ViewFileIcon *vfi, gint active){	GtkWidget *menu;	GtkWidget *item;	GtkWidget *submenu;	menu = popup_menu_short_lived();	g_signal_connect(G_OBJECT(menu), "destroy",			 G_CALLBACK(vficon_popup_destroy_cb), vfi);	submenu_add_edit(menu, &item, G_CALLBACK(vficon_pop_menu_edit_cb), vfi);	gtk_widget_set_sensitive(item, active);	item = menu_item_add_stock(menu, _("_Properties"), GTK_STOCK_PROPERTIES, G_CALLBACK(vficon_pop_menu_info_cb), vfi);	gtk_widget_set_sensitive(item, active);	item = menu_item_add_stock(menu, _("View in _new window"), GTK_STOCK_NEW, G_CALLBACK(vficon_pop_menu_view_cb), vfi);	gtk_widget_set_sensitive(item, active);	menu_item_add_divider(menu);	item = menu_item_add_stock(menu, _("_Copy..."), GTK_STOCK_COPY, G_CALLBACK(vficon_pop_menu_copy_cb), vfi);	gtk_widget_set_sensitive(item, active);	item = menu_item_add(menu, _("_Move..."), G_CALLBACK(vficon_pop_menu_move_cb), vfi);	gtk_widget_set_sensitive(item, active);	item = menu_item_add(menu, _("_Rename..."), G_CALLBACK(vficon_pop_menu_rename_cb), vfi);	gtk_widget_set_sensitive(item, active);	item = menu_item_add_stock(menu, _("_Delete..."), GTK_STOCK_DELETE, G_CALLBACK(vficon_pop_menu_delete_cb), vfi);	gtk_widget_set_sensitive(item, active);	menu_item_add_divider(menu);	submenu = submenu_add_sort(NULL, G_CALLBACK(vficon_pop_menu_sort_cb), vfi,				   FALSE, FALSE, TRUE, vfi->sort_method);	menu_item_add_divider(submenu);	menu_item_add_check(submenu, _("Ascending"), vfi->sort_ascend,			    G_CALLBACK(vficon_pop_menu_sort_ascend_cb), vfi);	item = menu_item_add(menu, _("_Sort"), NULL, NULL);	gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);	menu_item_add_check(menu, _("View as _icons"), TRUE,			    G_CALLBACK(vficon_pop_menu_list_cb), vfi);	menu_item_add_check(menu, _("Show filename _text"), vfi->show_text,			    G_CALLBACK(vficon_pop_menu_show_names_cb), vfi);	menu_item_add_stock(menu, _("Re_fresh"), GTK_STOCK_REFRESH, G_CALLBACK(vficon_pop_menu_refresh_cb), vfi);	return menu;}/* *------------------------------------------------------------------- * signals *------------------------------------------------------------------- */static void vficon_send_update(ViewFileIcon *vfi){	if (vfi->func_status) vfi->func_status(vfi, vfi->data_status);}static void vficon_send_layout_select(ViewFileIcon *vfi, FileData *fd){	const gchar *read_ahead_path = NULL;	if (!vfi->layout || !fd) return;	if (enable_read_ahead)		{		FileData *fd_n;		gint row;		row = g_list_index(vfi->list, fd);		if (row > vficon_index_by_path(vfi, layout_image_get_path(vfi->layout)) &&		    row + 1 < vficon_count(vfi, NULL))			{			fd_n = vficon_index_get_data(vfi, row + 1);			}		else if (row > 0)			{			fd_n = vficon_index_get_data(vfi, row - 1);			}		else			{			fd_n = NULL;			}		if (fd_n) read_ahead_path = fd_n->path;		}	layout_image_set_with_ahead(vfi->layout, fd->path, read_ahead_path);}static void vficon_toggle_filenames(ViewFileIcon *vfi){	vfi->show_text = !vfi->show_text;	show_icon_names = vfi->show_text;	vficon_populate_at_new_size(vfi, vfi->listview->allocation.width, vfi->listview->allocation.height, TRUE);}static gint vficon_get_icon_width(ViewFileIcon *vfi){	gint width;	if (!vfi->show_text) return thumb_max_width;	width = thumb_max_width + thumb_max_width / 2;	if (width < THUMB_MIN_ICON_WIDTH) width = THUMB_MIN_ICON_WIDTH;	if (width > THUMB_MAX_ICON_WIDTH) width = thumb_max_width;	return width;}/* *------------------------------------------------------------------- * misc utils *------------------------------------------------------------------- */static gint vficon_find_position(ViewFileIcon *vfi, FileData *fd, gint *row, gint *col){	gint n;	n = g_list_index(vfi->list, fd);	if (n < 0) return FALSE;	*row = n / vfi->columns;	*col = n - (*row * vfi->columns);	return TRUE;}static gint vficon_find_iter(ViewFileIcon *vfi, FileData *fd, GtkTreeIter *iter, gint *column){	GtkTreeModel *store;	gint row, col;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfi->listview));	if (!vficon_find_position(vfi, fd, &row, &col)) return FALSE;	if (!gtk_tree_model_iter_nth_child(store, iter, NULL, row)) return FALSE;	if (column) *column = col;	return TRUE;}static FileData *vficon_find_data(ViewFileIcon *vfi, gint row, gint col, GtkTreeIter *iter){	GtkTreeModel *store;	GtkTreeIter p;	if (row < 0 || col < 0) return NULL;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfi->listview));	if (gtk_tree_model_iter_nth_child(store, &p, NULL, row))		{		GList *list;		gtk_tree_model_get(store, &p, FILE_COLUMN_POINTER, &list, -1);		if (!list) return NULL;		if (iter) *iter = p;		return g_list_nth_data(list, col);		}	return NULL;}static FileData *vficon_find_data_by_coord(ViewFileIcon *vfi, gint x, gint y, GtkTreeIter *iter){	GtkTreePath *tpath;	GtkTreeViewColumn *column;	if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vfi->listview), x, y,					  &tpath, &column, NULL, NULL))		{		GtkTreeModel *store;		GtkTreeIter row;		GList *list;		gint n;		store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfi->listview));		gtk_tree_model_get_iter(store, &row, tpath);		gtk_tree_path_free(tpath);		gtk_tree_model_get(store, &row, FILE_COLUMN_POINTER, &list, -1);		n = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(column), "column_number"));		if (list)			{			if (iter) *iter = row;			return g_list_nth_data(list, n);			}		}	return NULL;}/* *------------------------------------------------------------------- * tooltip type window *------------------------------------------------------------------- */static void tip_show(ViewFileIcon *vfi){	GtkWidget *label;	gint x, y;	if (vfi->tip_window) return;	gdk_window_get_pointer(gtk_tree_view_get_bin_window(GTK_TREE_VIEW(vfi->listview)), &x, &y, NULL);	vfi->tip_fd = vficon_find_data_by_coord(vfi, x, y, NULL);	if (!vfi->tip_fd) return;	vfi->tip_window = gtk_window_new(GTK_WINDOW_POPUP);	gtk_window_set_resizable(GTK_WINDOW(vfi->tip_window), FALSE);	gtk_container_set_border_width(GTK_CONTAINER(vfi->tip_window), 2);	label = gtk_label_new(vfi->tip_fd->name);	g_object_set_data(G_OBJECT(vfi->tip_window), "tip_label", label);	gtk_container_add(GTK_CONTAINER(vfi->tip_window), label);	gtk_widget_show(label);	gdk_window_get_pointer(NULL, &x, &y, NULL);	if (!GTK_WIDGET_REALIZED(vfi->tip_window)) gtk_widget_realize(vfi->tip_window);	gtk_window_move(GTK_WINDOW(vfi->tip_window), x + 16, y + 16);	gtk_widget_show(vfi->tip_window);}static void tip_hide(ViewFileIcon *vfi){	if (vfi->tip_window) gtk_widget_destroy(vfi->tip_window);	vfi->tip_window = NULL;}static gint tip_schedule_cb(gpointer data){	ViewFileIcon *vfi = data;	GtkWidget *window;	if (vfi->tip_delay_id == -1) return FALSE;	window = gtk_widget_get_toplevel(vfi->listview);	if (GTK_WIDGET_SENSITIVE(window) &&	    GTK_WINDOW(window)->has_focus)		{		tip_show(vfi);		}	vfi->tip_delay_id = -1;	return FALSE;}static void tip_schedule(ViewFileIcon *vfi){	tip_hide(vfi);	if (vfi->tip_delay_id != -1)		{		g_source_remove(vfi->tip_delay_id);		vfi->tip_delay_id = -1;		}	if (!vfi->show_text)		{		vfi->tip_delay_id = g_timeout_add(VFICON_TIP_DELAY, tip_schedule_cb, vfi);		}}static void tip_unschedule(ViewFileIcon *vfi){	tip_hide(vfi);	if (vfi->tip_delay_id != -1) g_source_remove(vfi->tip_delay_id);	vfi->tip_delay_id = -1;}static void tip_update(ViewFileIcon *vfi, FileData *fd){	if (vfi->tip_window)		{		gint x, y;		gdk_window_get_pointer(NULL, &x, &y, NULL);		gtk_window_move(GTK_WINDOW(vfi->tip_window), x + 16, y + 16);		if (fd != vfi->tip_fd)			{			GtkWidget *label;			vfi->tip_fd = fd;			if (!vfi->tip_fd)				{				tip_hide(vfi);				tip_schedule(vfi);				return;				}			label = g_object_get_data(G_OBJECT(vfi->tip_window), "tip_label");			gtk_label_set_text(GTK_LABEL(label), vfi->tip_fd->name);			}		}	else		{		tip_schedule(vfi);		}}/* *------------------------------------------------------------------- * dnd *------------------------------------------------------------------- */static void vficon_dnd_get(GtkWidget *widget, GdkDragContext *context,			   GtkSelectionData *selection_data, guint info,			   guint time, gpointer data){	ViewFileIcon *vfi = data;	GList *list = NULL;	gchar *uri_text = NULL;	gint total;	if (!vfi->click_fd) return;	if (ICON_DATA(vfi->click_fd)->selected & SELECTION_SELECTED)		{		list = vficon_selection_get_list(vfi);		}	else		{		const gchar *path = vfi->click_fd->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);	if (debug) printf(uri_text);	gtk_selection_data_set(selection_data, selection_data->target,			       8, uri_text, total);	g_free(uri_text);}static void vficon_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data){	ViewFileIcon *vfi = data;	tip_unschedule(vfi);	if (vfi->click_fd && vfi->click_fd->pixbuf)		{		gint items;		if (ICON_DATA(vfi->click_fd)->selected & SELECTION_SELECTED)			items = g_list_length(vfi->selection);		else			items = 1;		dnd_set_drag_icon(widget, context, vfi->click_fd->pixbuf, items);		}}static void vficon_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data){

⌨️ 快捷键说明

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