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

📄 dupe.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
	GtkTreeModel *store;	GtkTreePath *tpath;	GtkTreeIter iter;	DupeItem *di = NULL;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));	if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y,					  &tpath, NULL, NULL, NULL))		{		gtk_tree_model_get_iter(store, &iter, tpath);		gtk_tree_model_get(store, &iter, DUPE_COLUMN_POINTER, &di, -1);		gtk_tree_path_free(tpath);		}	dw->click_item = di;	if (bevent->button == 3)		{		/* right click menu */		GtkWidget *menu;		if (bevent->state & GDK_CONTROL_MASK && bevent->state & GDK_SHIFT_MASK)			{			dupe_display_stats(dw, di);			return TRUE;			}		if (widget == dw->listview)			{			menu = dupe_menu_popup_main(dw, di);			}		else			{			menu = dupe_menu_popup_second(dw, di);			}		gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time);		}	if (!di) return FALSE;	if (bevent->button == 1 && bevent->type == GDK_2BUTTON_PRESS)		{		dupe_menu_view(dw, di, widget, FALSE);		}	if (bevent->button == 2) return TRUE;	if (bevent->button == 3)		{		if (!dupe_listview_item_is_selected(dw, di, widget))			{			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);			tpath = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);			gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE);			gtk_tree_path_free(tpath);			}		return TRUE;		}	if (bevent->button == 1 && bevent->type == GDK_BUTTON_PRESS &&	    !(bevent->state & GDK_SHIFT_MASK ) &&	    !(bevent->state & GDK_CONTROL_MASK ) &&	    dupe_listview_item_is_selected(dw, di, widget))		{		/* this selection handled on release_cb */		gtk_widget_grab_focus(widget);		return TRUE;		}	return FALSE;}static gint dupe_listview_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){	DupeWindow *dw = data;	GtkTreeModel *store;	GtkTreePath *tpath;	GtkTreeIter iter;	DupeItem *di = NULL;	if (bevent->button != 1 && bevent->button != 2) return TRUE;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));	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))		{		gtk_tree_model_get_iter(store, &iter, tpath);		gtk_tree_model_get(store, &iter, DUPE_COLUMN_POINTER, &di, -1);		gtk_tree_path_free(tpath);		}	if (bevent->button == 2)		{		if (di && dw->click_item == di)			{			GtkTreeSelection *selection;			selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));			if (dupe_listview_item_is_selected(dw, di, widget))				{				gtk_tree_selection_unselect_iter(selection, &iter);				}			else				{				gtk_tree_selection_select_iter(selection, &iter);				}			}		return TRUE;		}	if (di && dw->click_item == di &&	    !(bevent->state & GDK_SHIFT_MASK ) &&	    !(bevent->state & GDK_CONTROL_MASK ) &&	    dupe_listview_item_is_selected(dw, di, widget))		{		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);		tpath = gtk_tree_model_get_path(store, &iter);		gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE);		gtk_tree_path_free(tpath);		return TRUE;		}	return FALSE;}/* *------------------------------------------------------------------- * second set stuff *------------------------------------------------------------------- */static void dupe_second_update_status(DupeWindow *dw){	gchar *buf;	buf = g_strdup_printf(_("%d files (set 2)"), g_list_length(dw->second_list));	gtk_label_set_text(GTK_LABEL(dw->second_status_label), buf);	g_free(buf);}static void dupe_second_add(DupeWindow *dw, DupeItem *di){	GtkListStore *store;	GtkTreeIter iter;	if (!di) return;	di->second = TRUE;	dw->second_list = g_list_prepend(dw->second_list, di);	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dw->second_listview)));	gtk_list_store_append(store, &iter);	gtk_list_store_set(store, &iter, DUPE_COLUMN_POINTER, di, 1, di->path, -1);	dupe_second_update_status(dw);}static void dupe_second_remove(DupeWindow *dw, DupeItem *di){	GtkListStore *store;	GtkTreeIter iter;	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dw->second_listview)));	if (dupe_listview_find_item(store, di, &iter) >= 0)		{		tree_view_move_cursor_away(GTK_TREE_VIEW(dw->second_listview), &iter, TRUE);		gtk_list_store_remove(store, &iter);		}	dw->second_list = g_list_remove(dw->second_list, di);	dupe_second_update_status(dw);}static void dupe_second_clear(DupeWindow *dw){	GtkListStore *store;	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dw->second_listview)));	gtk_list_store_clear(store);	gtk_tree_view_columns_autosize(GTK_TREE_VIEW(dw->second_listview));	g_list_free(dw->dupes);	dw->dupes = NULL;	dupe_list_free(dw->second_list);	dw->second_list = NULL;	dupe_match_reset_list(dw->list);	dupe_second_update_status(dw);}static void dupe_second_menu_view_cb(GtkWidget *widget, gpointer data){	DupeWindow *dw = data;	if (dw->click_item) dupe_menu_view(dw, dw->click_item, dw->second_listview, FALSE);}static void dupe_second_menu_viewnew_cb(GtkWidget *widget, gpointer data){	DupeWindow *dw = data;	if (dw->click_item) dupe_menu_view(dw, dw->click_item, dw->second_listview, TRUE);}static void dupe_second_menu_select_all_cb(GtkWidget *widget, gpointer data){	GtkTreeSelection *selection;	DupeWindow *dw = data;	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dw->second_listview));	gtk_tree_selection_select_all(selection);}static void dupe_second_menu_select_none_cb(GtkWidget *widget, gpointer data){	GtkTreeSelection *selection;	DupeWindow *dw = data;	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dw->second_listview));	gtk_tree_selection_unselect_all(selection);}static void dupe_second_menu_remove_cb(GtkWidget *widget, gpointer data){	DupeWindow *dw = data;	dupe_window_remove_selection(dw, dw->second_listview);}static void dupe_second_menu_clear_cb(GtkWidget *widget, gpointer data){	DupeWindow *dw = data;	dupe_second_clear(dw);	dupe_window_recompare(dw);}static GtkWidget *dupe_menu_popup_second(DupeWindow *dw, DupeItem *di){	GtkWidget *menu;	gint notempty;	gint on_row;	on_row = (di != NULL);	notempty = (dw->second_list != NULL);	menu = popup_menu_short_lived();	menu_item_add_sensitive(menu, _("_View"), on_row,				G_CALLBACK(dupe_second_menu_view_cb), dw);	menu_item_add_stock_sensitive(menu, _("View in _new window"), GTK_STOCK_NEW, on_row,				G_CALLBACK(dupe_second_menu_viewnew_cb), dw);	menu_item_add_divider(menu);	menu_item_add_sensitive(menu, _("Select all"), notempty,				G_CALLBACK(dupe_second_menu_select_all_cb), dw);	menu_item_add_sensitive(menu, _("Select none"), notempty,				G_CALLBACK(dupe_second_menu_select_none_cb), dw);	menu_item_add_divider(menu);	menu_item_add_stock_sensitive(menu, _("Rem_ove"), GTK_STOCK_REMOVE, on_row,				      G_CALLBACK(dupe_second_menu_remove_cb), dw);	menu_item_add_stock_sensitive(menu, _("C_lear"), GTK_STOCK_CLEAR, notempty,				   G_CALLBACK(dupe_second_menu_clear_cb), dw);	menu_item_add_divider(menu);	menu_item_add_stock(menu, _("Close _window"), GTK_STOCK_CLOSE,			    G_CALLBACK(dupe_menu_close_cb), dw);	return menu;}static void dupe_second_set_toggle_cb(GtkWidget *widget, gpointer data){	DupeWindow *dw = data;	dw->second_set = GTK_TOGGLE_BUTTON(widget)->active;	if (dw->second_set)		{		dupe_second_update_status(dw);		gtk_table_set_col_spacings(GTK_TABLE(dw->table), PREF_PAD_GAP);		gtk_widget_show(dw->second_vbox);		}	else		{		gtk_table_set_col_spacings(GTK_TABLE(dw->table), 0);		gtk_widget_hide(dw->second_vbox);		dupe_second_clear(dw);		}	dupe_window_recompare(dw);}/* *------------------------------------------------------------------- * match type menu *------------------------------------------------------------------- */enum {	DUPE_MENU_COLUMN_NAME = 0,	DUPE_MENU_COLUMN_MASK};static void dupe_menu_type_cb(GtkWidget *combo, gpointer data){	DupeWindow *dw = data;	GtkTreeModel *store;	GtkTreeIter iter;	store = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));	if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter)) return;	gtk_tree_model_get(store, &iter, DUPE_MENU_COLUMN_MASK, &dw->match_mask, -1);	dupe_window_recompare(dw);}static void dupe_menu_add_item(GtkListStore *store, const gchar *text, DupeMatchType type, DupeWindow *dw){	GtkTreeIter iter;	gtk_list_store_append(store, &iter);	gtk_list_store_set(store, &iter, DUPE_MENU_COLUMN_NAME, text,					 DUPE_MENU_COLUMN_MASK, type, -1);	if (dw->match_mask == type) gtk_combo_box_set_active_iter(GTK_COMBO_BOX(dw->combo), &iter);}static void dupe_menu_setup(DupeWindow *dw){	GtkListStore *store;	GtkCellRenderer *renderer;	store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);	dw->combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));	g_object_unref(store);	renderer = gtk_cell_renderer_text_new();	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dw->combo), renderer, TRUE);	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dw->combo), renderer,				       "text", DUPE_MENU_COLUMN_NAME, NULL);	dupe_menu_add_item(store, _("Name"), DUPE_MATCH_NAME, dw);	dupe_menu_add_item(store, _("Size"), DUPE_MATCH_SIZE, dw);	dupe_menu_add_item(store, _("Date"), DUPE_MATCH_DATE, dw);	dupe_menu_add_item(store, _("Dimensions"), DUPE_MATCH_DIM, dw);	dupe_menu_add_item(store, _("Checksum"), DUPE_MATCH_SUM, dw);	dupe_menu_add_item(store, _("Path"), DUPE_MATCH_PATH, dw);	dupe_menu_add_item(store, _("Similarity (high)"), DUPE_MATCH_SIM_HIGH, dw);	dupe_menu_add_item(store, _("Similarity"), DUPE_MATCH_SIM_MED, dw);	dupe_menu_add_item(store, _("Similarity (low)"), DUPE_MATCH_SIM_LOW, dw);	dupe_menu_add_item(store, _("Similarity (custom)"), DUPE_MATCH_SIM_CUSTOM, dw);	g_signal_connect(G_OBJECT(dw->combo), "changed",			 G_CALLBACK(dupe_menu_type_cb), dw);}/* *------------------------------------------------------------------- * list view columns *------------------------------------------------------------------- *//* this overrides the low default of a GtkCellRenderer from 100 to CELL_HEIGHT_OVERRIDE, something sane for our purposes */#define CELL_HEIGHT_OVERRIDE 512                                                                                                                               void cell_renderer_height_override(GtkCellRenderer *renderer){	GParamSpec *spec;	spec = g_object_class_find_property(G_OBJECT_GET_CLASS(G_OBJECT(renderer)), "height");	if (spec && G_IS_PARAM_SPEC_INT(spec))		{		GParamSpecInt *spec_int;		spec_int = G_PARAM_SPEC_INT(spec);		if (spec_int->maximum < CELL_HEIGHT_OVERRIDE) spec_int->maximum = CELL_HEIGHT_OVERRIDE;		}}static GdkColor *dupe_listview_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 dupe_listview_color_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,				   GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data){	DupeWindow *dw = data;	gboolean set;	gtk_tree_model_get(tree_model, iter, DUPE_COLUMN_COLOR, &set, -1);	g_object_set(G_OBJECT(cell),		     "cell-background-gdk", dupe_listview_color_shifted(dw->listview),		     "cell-background-set", set, NULL);}static void dupe_listview_add_column(DupeWindow *dw, GtkWidget *listview, gint n, const gchar *title, gint image, gint right_justify){	GtkTreeViewColumn *column;	GtkCellRenderer *renderer;	column = gtk_tree_view_column_new();	gtk_tree_view_column_set_title(column, title);	gtk_tree_view_column_set_min_width(column, 4);	if (n != DUPE_COLUMN_RANK &&	    n != DUPE_COLUMN_THUMB)		{		gtk_tree_view_column_set_resizable(column, TRUE);		}	if (!image)		{		gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);		renderer = gtk_cell_renderer_text_new();		if (right_justify)			{			g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);			}		gtk_tree_view_column_pack_start(column, renderer, TRUE);		gtk_tree_view_column_add_attribute(column, renderer, "text", n);		}	else		{		gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);		renderer = gtk_cell_renderer_pixbuf_new();		cell_renderer_height_override(renderer);		gtk_tree_view_column_pack_start(column, renderer, TRUE);		gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", n);		}	if (listview == dw->listview)		{		/* sets background before rendering */		gtk_tree_view_column_set_cell_data_func(column, renderer, dupe_listview_color_cb, dw, NULL);		}	gtk_tree_view_append_column(GTK_TREE_VIEW(listview), column);}static void dupe_listview_set_height(GtkWidget *listview, gint thumb){	GtkTreeViewColumn *column;	GtkCellRenderer *cell;	GList *list;	column = gtk_tree_view_get_column(GTK_TREE_VIEW(listview), DUPE_COLUMN_THUMB - 1);	if (!column) return;	gtk_tree_view_column_set_fixed_width(column, (thumb) ? thumb_max_width : 4);		list = gtk_tree_view_column_get_cell_renderers(column);	if (!list) return;	cell = list->data;	g_list_free(list);	g_object_set(G_OBJECT(cell), "height", (thumb) ? thumb_max_height : -1, NULL);	gtk_tree_view_columns_autosize(GTK_TREE_VIEW(listview));}/* *------------------------------------------------------------------- * misc cb *------------------------------------------------------------------- */static void dupe_window_show_thumb_cb(GtkWidget *widget, gpointer data){	DupeWindow *dw = data;	dw->show_thumbs = GTK_TOGGLE_BUTTON(widget)->active;	if (dw->show_thumbs)		{		if (!dw->working) dupe_thumb_step(dw);		}	else		{		GtkTreeModel *store;		GtkTreeIter iter;		gint valid;		thumb_loader_free(dw->thumb_loader);		dw->thumb_loader = NULL;		store = gtk_tree_view_get_model(GTK_TREE_VIEW(dw->listview));		valid = gtk_tree_model_get_iter_first(store, &iter);		while (valid)			{			gtk_list_store_set(GTK_LIST_STORE(store), &iter, DUPE_COLUMN_THUMB, NULL, -1);			valid = gtk_tree_model_iter_next(store, &iter);			}		dupe_window_update_progress(dw, NULL, 0.0, FALSE);		}	dupe_listview_set_height(dw->listview, dw->show_thumbs);}static void dupe_popup_menu_pos_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data){	GtkWidget *view = data;	GtkTreePath *tpath;	gint cx, cy, cw, ch;	gint column;	gtk_tree_view_get_cursor(GTK_TREE_VIEW(view), &tpath, NULL);	if (!tpath) return;	if (gtk_tree_view_get_column(GTK_TREE_VIEW(view), DUPE_COLUMN_NAME - 1) != NULL)		{		column = DUPE_COLUMN_NAME - 1;		}	else		{		/* dw->second_listview */		column = 0;		}	tree_view_get_cell_clamped(GTK_TREE_VIEW(view), tpath, column, TRUE, &cx, &cy, &cw, &ch);	gtk_tree_path_free(tpath);	cy += ch;	popup_menu_position_clamp(menu, &cx, &cy, 0);	*x = cx;	*y = cy;}static gint dupe_window_keypress_cb(GtkWidget *widget

⌨️ 快捷键说明

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