info.c

来自「Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。」· C语言 代码 · 共 772 行 · 第 1/2 页

C
772
字号
	td->func_sync = info_tab_general_sync;	td->func_image = info_tab_general_image;	td->data = tab;	return td;}/* *------------------------------------------------------------------- * tabs *------------------------------------------------------------------- */static void info_tabs_sync(InfoData *id, gint image){	GList *work;	work = id->tab_list;	while (work)		{		TabData *td = work->data;		work = work->next;		if (image)			{			if (td->func_image) td->func_image(id, td->data);			}		else			{			if (td->func_sync) td->func_sync(id, td->data);			}		}}static void info_tabs_free(InfoData *id){	GList *work;	work = id->tab_list;	while (work)		{		TabData *td = work->data;		work = work->next;		if (td->func_free) td->func_free(td->data);		g_free(td);		}	g_list_free(id->tab_list);	id->tab_list = NULL;}static void info_tabs_init(InfoData *id){	id->tab_list = g_list_append(id->tab_list, info_tab_general_new(id));	id->tab_list = g_list_append(id->tab_list, info_tab_meta_new(id));	id->tab_list = g_list_append(id->tab_list, info_tab_exif_new(id));}/* *------------------------------------------------------------------- * sync *------------------------------------------------------------------- */static void info_window_sync(InfoData *id, const gchar *path){	if (!path) return;	gtk_entry_set_text(GTK_ENTRY(id->name_entry), filename_from_path(path));	if (id->label_count)		{		gchar *buf;		buf = g_strdup_printf(_("Image %d of %d"),				      g_list_index(id->list, (gpointer)path) + 1,				      g_list_length(id->list));		gtk_label_set_text(GTK_LABEL(id->label_count), buf);		g_free(buf);		}	info_tabs_sync(id, FALSE);	id->updated = FALSE;	image_change_path(id->image, path, 0.0);}/* *------------------------------------------------------------------- * drag n drop (dropping not supported!) *------------------------------------------------------------------- */static void info_window_dnd_data_set(GtkWidget *widget, GdkDragContext *context,				     GtkSelectionData *selection_data, guint info,				     guint time, gpointer data){	InfoData *id = data;	const gchar *path;	path = image_get_path(id->image);	if (path)		{		gchar *text;		gint len;		GList *list;		gint plain_text;		switch (info)			{			case TARGET_URI_LIST:				plain_text = FALSE;				break;			case TARGET_TEXT_PLAIN:			default:				plain_text = TRUE;				break;			}		list = g_list_append(NULL, (gchar *)path);		text = uri_text_from_list(list, &len, plain_text);		g_list_free(list);		gtk_selection_data_set(selection_data, selection_data->target,				       8, text, len);		g_free(text);		}}static void info_window_dnd_init(InfoData *id){	ImageWindow *imd;	imd = id->image;	gtk_drag_source_set(imd->pr, GDK_BUTTON2_MASK,			    dnd_file_drag_types, dnd_file_drag_types_count,			    GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);	g_signal_connect(G_OBJECT(imd->pr), "drag_data_get",			 G_CALLBACK(info_window_dnd_data_set), id);#if 0	gtk_drag_dest_set(imd->pr,			  GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,			  dnd_file_drop_types, dnd_file_drop_types_count,			  GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);	g_signal_connect(G_OBJECT(imd->pr), "drag_data_received",			 G_CALLBACK(info_window_dnd_data_get), id);#endif}/* *------------------------------------------------------------------- * base window *------------------------------------------------------------------- */static gint info_window_last_width = DEF_PROPERTY_WIDTH;static gint info_window_last_height = DEF_PROPERTY_HEIGHT;static void info_window_image_update_cb(ImageWindow *imd, gpointer data){	InfoData *id = data;	/* only do this once after when loading a new image,	 * for tabs that depend on image data (exif)	 * Subsequent updates are ignored, as the image	 * should not really changed if id->updated is TRUE.	 */	if (id->updated) return;	if (imd->unknown) return;	info_tabs_sync(id, TRUE);	id->updated = TRUE;}static void info_window_back_cb(GtkWidget *widget, gpointer data){	InfoData *id = data;	GList *work;	work = g_list_find(id->list, (gpointer)id->path);	if (!work || !work->prev) return;	work = work->prev;	id->path = work->data;	info_window_sync(id, id->path);	gtk_widget_set_sensitive(id->button_back, (work->prev != NULL));	gtk_widget_set_sensitive(id->button_next, TRUE);}static void info_window_next_cb(GtkWidget *widget, gpointer data){	InfoData *id = data;	GList *work;	work = g_list_find(id->list, (gpointer)id->path);	if (!work || !work->next) return;	work = work->next;	id->path = work->data;	info_window_sync(id, id->path);	gtk_widget_set_sensitive(id->button_next, (work->next != NULL));	gtk_widget_set_sensitive(id->button_back, TRUE);}static void info_window_image_button_cb(ImageWindow *imd, gint button, guint32 time,					gdouble x, gdouble y, guint state, gpointer data){	if (button == 1)		{		info_window_next_cb(NULL, data);		}	else if (button == 2 || button == 3)		{		info_window_back_cb(NULL, data);		}}static void info_window_image_scroll_cb(ImageWindow *imd, GdkScrollDirection direction, guint32 time,					gdouble x, gdouble y, guint state, gpointer data){	if (direction == GDK_SCROLL_UP)		{		info_window_back_cb(NULL, data);		}	else if (direction == GDK_SCROLL_DOWN)		{		info_window_next_cb(NULL, data);		}}static void info_window_close(InfoData *id){	gdk_drawable_get_size(id->window->window, &info_window_last_width, &info_window_last_height);	info_window_last_width = MAX(info_window_last_width, DEF_PROPERTY_WIDTH);	info_window_last_height = MAX(info_window_last_height, DEF_PROPERTY_HEIGHT);	gtk_widget_destroy(id->window);}static void info_window_close_cb(GtkWidget *widget, gpointer data){	InfoData *id = data;	info_window_close(id);}static gint info_window_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data){	InfoData *id = data;	info_window_close(id);	return TRUE;}static void info_window_destroy_cb(GtkWidget *widget, gpointer data){	InfoData *id = data;	info_tabs_free(id);	path_list_free(id->list);	g_free(id);}void info_window_new(const gchar *path, GList *list){	InfoData *id;	GtkWidget *main_vbox;	GtkWidget *paned;	GtkWidget *hbox;	GtkWidget *button;	GtkWidget *label;	GdkGeometry geometry;	if (!path && !list) return;	if (!list)		{		list = g_list_append(NULL, g_strdup(path));		}	id = g_new0(InfoData, 1);	id->list = list;	id->path = (gchar *)id->list->data;	id->updated = FALSE;	id->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);	gtk_window_set_type_hint(GTK_WINDOW(id->window), GDK_WINDOW_TYPE_HINT_DIALOG);	window_set_icon(id->window, NULL, NULL);	gtk_window_set_resizable(GTK_WINDOW(id->window), TRUE);	gtk_window_set_title(GTK_WINDOW(id->window), _("Image properties - GQview"));	gtk_window_set_wmclass(GTK_WINDOW(id->window), "properties", "GQview");	geometry.min_width = 32;	geometry.min_height = 32;	geometry.base_width = DEF_PROPERTY_WIDTH;	geometry.base_height = DEF_PROPERTY_HEIGHT;	gtk_window_set_geometry_hints(GTK_WINDOW(id->window), NULL, &geometry,				      GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE);	gtk_window_set_default_size(GTK_WINDOW(id->window), info_window_last_width, info_window_last_height);	gtk_container_set_border_width(GTK_CONTAINER(id->window), PREF_PAD_BORDER);	g_signal_connect(G_OBJECT(id->window), "delete_event",			 G_CALLBACK(info_window_delete_cb), id);	g_signal_connect(G_OBJECT(id->window), "destroy",			 G_CALLBACK(info_window_destroy_cb), id);	paned = gtk_hpaned_new();	gtk_container_add(GTK_CONTAINER(id->window), paned);	gtk_widget_show(paned);	id->image = image_new(FALSE);	image_set_update_func(id->image, info_window_image_update_cb, id);	image_set_button_func(id->image, info_window_image_button_cb, id);	image_set_scroll_func(id->image, info_window_image_scroll_cb, id);	gtk_widget_set_size_request(id->image->widget, IMAGE_SIZE_W, IMAGE_SIZE_H);	gtk_paned_pack1(GTK_PANED(paned), id->image->widget, FALSE, TRUE);	gtk_widget_show(id->image->widget);	main_vbox = gtk_vbox_new(FALSE, 0);	gtk_paned_pack2(GTK_PANED(paned), main_vbox, TRUE, TRUE);	gtk_widget_show(main_vbox);	hbox = pref_box_new(main_vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE);	label = pref_label_new(hbox, _("Filename:"));	pref_label_bold(label, TRUE, FALSE);	id->name_entry = gtk_entry_new();	gtk_editable_set_editable(GTK_EDITABLE(id->name_entry), FALSE);	gtk_box_pack_start(GTK_BOX(hbox), id->name_entry, TRUE, TRUE, 0);	gtk_widget_show(id->name_entry);	id->notebook = gtk_notebook_new();	gtk_notebook_set_tab_pos(GTK_NOTEBOOK(id->notebook), GTK_POS_TOP);	gtk_box_pack_start(GTK_BOX(main_vbox), id->notebook, TRUE, TRUE, 5);	gtk_widget_show(id->notebook);	pref_spacer(main_vbox, PREF_PAD_GAP);	hbox = pref_box_new(main_vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP);	id->button_back = pref_button_new(hbox, GTK_STOCK_GO_BACK, NULL, TRUE,					  G_CALLBACK(info_window_back_cb), id);	gtk_widget_set_sensitive(id->button_back, FALSE);	id->button_next = pref_button_new(hbox, GTK_STOCK_GO_FORWARD, NULL, TRUE,					  G_CALLBACK(info_window_next_cb), id);	gtk_widget_set_sensitive(id->button_next, (id->list->next != NULL));	if (id->list->next)		{		id->label_count = pref_label_new(hbox, "");		}	button = pref_button_new(NULL, GTK_STOCK_CLOSE, NULL, FALSE,				 G_CALLBACK(info_window_close_cb), id);	gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);	gtk_widget_show(button);	/* set up tabs */	info_tabs_init(id);	/* fill it */	info_window_sync(id, id->path);	/* finish */	info_window_dnd_init(id);	gtk_widget_show(id->window);}

⌨️ 快捷键说明

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