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

📄 dupe.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dw->listview)));	gtk_list_store_clear(store);	work = g_list_last(dw->dupes);	while (work)		{		DupeItem *parent = work->data;		GList *temp;		dupe_listview_add(dw, parent, NULL);		temp = g_list_last(parent->group);		while (temp)			{			DupeMatch *dm = temp->data;			DupeItem *child;			child = dm->di;			dupe_listview_add(dw, parent, child);			temp = temp->prev;			}		work = work->prev;		}	gtk_tree_view_columns_autosize(GTK_TREE_VIEW(dw->listview));}static void dupe_listview_remove(DupeWindow *dw, DupeItem *di){	GtkListStore *store;	GtkTreeIter iter;	gint row;	if (!di) return;	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dw->listview)));	row = dupe_listview_find_item(store, di, &iter);	if (row < 0) return;	tree_view_move_cursor_away(GTK_TREE_VIEW(dw->listview), &iter, TRUE);	gtk_list_store_remove(store, &iter);	if (g_list_find(dw->dupes, di) != NULL)		{		if (!dw->color_frozen) dupe_listview_realign_colors(dw);		}}static GList *dupe_listview_get_path_list(DupeWindow *dw, GtkWidget *listview){	GtkTreeModel *store;	GtkTreeIter iter;	gint valid;	GList *list = NULL;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(listview));	valid = gtk_tree_model_get_iter_first(store, &iter);	while (valid)		{		DupeItem *di;		gtk_tree_model_get(store, &iter, DUPE_COLUMN_POINTER, &di, -1);		list = g_list_prepend(list, g_strdup(di->path));		valid = gtk_tree_model_iter_next(store, &iter);		}	return g_list_reverse(list);}static GList *dupe_listview_get_selection(DupeWindow *dw, GtkWidget *listview){	GtkTreeModel *store;	GtkTreeSelection *selection;	GList *slist;	GList *list = NULL;	GList *work;	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(listview));	slist = gtk_tree_selection_get_selected_rows(selection, &store);	work = slist;	while (work)		{		GtkTreePath *tpath = work->data;		DupeItem *di = NULL;		GtkTreeIter iter;		gtk_tree_model_get_iter(store, &iter, tpath);		gtk_tree_model_get(store, &iter, DUPE_COLUMN_POINTER, &di, -1);		if (di)			{			list = g_list_prepend(list, g_strdup(di->path));			}		work = work->next;		}	g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL);	g_list_free(slist);	return g_list_reverse(list);}static gint dupe_listview_item_is_selected(DupeWindow *dw, DupeItem *di, GtkWidget *listview){	GtkTreeModel *store;	GtkTreeSelection *selection;	GList *slist;	GList *work;	gint found = FALSE;	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(listview));	slist = gtk_tree_selection_get_selected_rows(selection, &store);	work = slist;	while (!found && work)		{		GtkTreePath *tpath = work->data;		DupeItem *di_n;		GtkTreeIter iter;		gtk_tree_model_get_iter(store, &iter, tpath);		gtk_tree_model_get(store, &iter, DUPE_COLUMN_POINTER, &di_n, -1);		if (di_n == di) found = TRUE;		work = work->next;		}	g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL);	g_list_free(slist);	return found;}static void dupe_listview_select_dupes(DupeWindow *dw, gint parents){	GtkTreeModel *store;	GtkTreeSelection *selection;	GtkTreeIter iter;	gint valid;	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dw->listview));	gtk_tree_selection_unselect_all(selection);	store = gtk_tree_view_get_model(GTK_TREE_VIEW(dw->listview));	valid = gtk_tree_model_get_iter_first(store, &iter);	while (valid)		{		DupeItem *di;		gtk_tree_model_get(store, &iter, DUPE_COLUMN_POINTER, &di, -1);		if ( (dupe_match_find_parent(dw, di) == di) == (parents) )			{			gtk_tree_selection_select_iter(selection, &iter);			}		valid = gtk_tree_model_iter_next(store, &iter);		}}/* * ------------------------------------------------------------------ * Match group manipulation * ------------------------------------------------------------------ */static DupeMatch *dupe_match_find_match(DupeItem *child, DupeItem *parent){	GList *work;	work = parent->group;	while (work)		{		DupeMatch *dm = work->data;		if (dm->di == child) return dm;		work = work->next;		}	return NULL;}static void dupe_match_link_child(DupeItem *child, DupeItem *parent, gdouble rank){	DupeMatch *dm;	dm = g_new0(DupeMatch, 1);	dm->di = child;	dm->rank = rank;	parent->group = g_list_append(parent->group, dm);}static void dupe_match_link(DupeItem *a, DupeItem *b, gdouble rank){	dupe_match_link_child(a, b, rank);	dupe_match_link_child(b, a, rank);}static void dupe_match_unlink_child(DupeItem *child, DupeItem *parent){	DupeMatch *dm;	dm = dupe_match_find_match(child, parent);	if (dm)		{		parent->group = g_list_remove(parent->group, dm);		g_free(dm);		}}static void dupe_match_unlink(DupeItem *a, DupeItem *b){	dupe_match_unlink_child(a, b);	dupe_match_unlink_child(b, a);}static void dupe_match_link_clear(DupeItem *parent, gint unlink_children){	GList *work;                                                                                                                               	work = parent->group;	while (work)		{		DupeMatch *dm = work->data;		work = work->next;		if (unlink_children) dupe_match_unlink_child(parent, dm->di);		g_free(dm);		}	g_list_free(parent->group);	parent->group = NULL;	parent->group_rank = 0.0;}static gint dupe_match_link_exists(DupeItem *child, DupeItem *parent){	return (dupe_match_find_match(child, parent) != NULL);}static gdouble dupe_match_link_rank(DupeItem *child, DupeItem *parent){	DupeMatch *dm;	dm = dupe_match_find_match(child, parent);	if (dm) return dm->rank;	return 0.0;}static DupeItem *dupe_match_highest_rank(DupeItem *child){	DupeMatch *dr;	GList *work;	dr = NULL;	work = child->group;	while (work)		{		DupeMatch *dm = work->data;		if (!dr || dm->rank > dr->rank) dr = dm;		work = work->next;		}	return (dr) ? dr->di : NULL;}static void dupe_match_rank_update(DupeItem *parent){	GList *work;	gdouble rank = 0.0;	gint c = 0;	work = parent->group;	while (work)		{		DupeMatch *dm = work->data;		work = work->next;		rank += dm->rank;		c++;		}	if (c > 0)		{		parent->group_rank = rank / c;		}	else		{		parent->group_rank = 0.0;		}}static DupeItem *dupe_match_find_parent(DupeWindow *dw, DupeItem *child){	GList *work;	if (g_list_find(dw->dupes, child)) return child;	work = child->group;	while (work)		{		DupeMatch *dm = work->data;		if (g_list_find(dw->dupes, dm->di)) return dm->di;		work = work->next;		}	return NULL;}static void dupe_match_reset_list(GList *work){	while (work)		{		DupeItem *di = work->data;		work = work->next;		dupe_match_link_clear(di, FALSE);		}}static void dupe_match_reparent(DupeWindow *dw, DupeItem *old, DupeItem *new){	GList *work;	if (!old || !new || !dupe_match_link_exists(old, new)) return;	dupe_match_link_clear(new, TRUE);	work = old->group;	while (work)		{		DupeMatch *dm = work->data;		dupe_match_unlink_child(old, dm->di);		dupe_match_link_child(new, dm->di, dm->rank);		work = work->next;		}	new->group = old->group;	old->group = NULL;	work = g_list_find(dw->dupes, old);	if (work) work->data = new;}static void dupe_match_print_group(DupeItem *di){	GList *work;	printf("+ %f %s\n", di->group_rank, di->name);	work = di->group;	while (work)		{		DupeMatch *dm = work->data;		work = work->next;		printf("  %f %s\n", dm->rank, dm->di->name);		}	printf("\n");}static void dupe_match_print_list(GList *list){	GList *work;	work = list;	while (work)		{		DupeItem *di = work->data;		dupe_match_print_group(di);		work = work->next;		}}/* level 3, unlinking and orphan handling */static GList *dupe_match_unlink_by_rank(DupeItem *child, DupeItem *parent, GList *list, DupeWindow *dw){	DupeItem *best;	best = dupe_match_highest_rank(parent);	if (best == child || dupe_match_highest_rank(child) == parent)		{		GList *work;		gdouble rank;		if (debug > 1) printf("link found %s to %s [%d]\n", child->name, parent->name, g_list_length(parent->group));		work = parent->group;		while (work)			{			DupeMatch *dm = work->data;			DupeItem *orphan;			work = work->next;			orphan = dm->di;			if (orphan != child && g_list_length(orphan->group) < 2)				{				dupe_match_link_clear(orphan, TRUE);				if (!dw->second_set || orphan->second)					{					dupe_match(orphan, child, dw->match_mask, &rank, FALSE);					dupe_match_link(orphan, child, rank);					}				list = g_list_remove(list, orphan);				}			}				rank = dupe_match_link_rank(child, parent);		dupe_match_link_clear(parent, TRUE);		dupe_match_link(child, parent, rank);		list = g_list_remove(list, parent);		}	else		{		if (debug > 1) printf("unlinking %s and %s\n", child->name, parent->name);				dupe_match_unlink(child, parent);		}	return list;}/* level 2 */static GList *dupe_match_group_filter(GList *list, DupeItem *di, DupeWindow *dw){	GList *work;	work = g_list_last(di->group);	while (work)		{		DupeMatch *dm = work->data;		work = work->prev;		list = dupe_match_unlink_by_rank(di, dm->di, list, dw);		}	return list;}/* level 1 (top) */static GList *dupe_match_group_trim(GList *list, DupeWindow *dw){	GList *work;	work = list;	while (work)		{		DupeItem *di = work->data;		if (!di->second) list = dupe_match_group_filter(list, di, dw);		work = work->next;		if (di->second) list = g_list_remove(list, di);		}	return list;}static gint dupe_match_sort_groups_cb(gconstpointer a, gconstpointer b){	DupeMatch *da = (DupeMatch *)a;	DupeMatch *db = (DupeMatch *)b;	if (da->rank > db->rank) return -1;	if (da->rank < db->rank) return 1;	return 0;}static void dupe_match_sort_groups(GList *list){	GList *work;	work = list;	while (work)		{		DupeItem *di = work->data;		di->group = g_list_sort(di->group, dupe_match_sort_groups_cb);		work = work->next;		}}static gint dupe_match_rank_sort_cb(gconstpointer a, gconstpointer b){	DupeItem *da = (DupeItem *)a;	DupeItem *db = (DupeItem *)b;	if (da->group_rank > db->group_rank) return -1;	if (da->group_rank < db->group_rank) return 1;	return 0;}/* returns allocated GList of dupes sorted by rank */static GList *dupe_match_rank_sort(GList *source_list){	GList *list = NULL;	GList *work;	work = source_list;	while (work)		{		DupeItem *di = work->data;		if (di->group)			{			dupe_match_rank_update(di);			list = g_list_prepend(list, di);			}					work = work->next;		}	return g_list_sort(list, dupe_match_rank_sort_cb);}static void dupe_match_rank(DupeWindow *dw){	GList *list;	list = dupe_match_rank_sort(dw->list);	if (debug > 1) dupe_match_print_list(list);		if (debug) printf("Similar items: %d\n", g_list_length(list));	list = dupe_match_group_trim(list, dw);	if (debug) printf("Unique groups: %d\n", g_list_length(list));	dupe_match_sort_groups(list);	if (debug) dupe_match_print_list(list);	list = dupe_match_rank_sort(list);	g_list_free(dw->dupes);	dw->dupes = list;}/* * ------------------------------------------------------------------ * Match group tests * ------------------------------------------------------------------ */static gint dupe_match(DupeItem *a, DupeItem *b, DupeMatchType mask, gdouble *rank, gint fast){	*rank = 0.0;	if (a == b) return FALSE;	if (mask & DUPE_MATCH_PATH)		{		if (strcmp(a->path, b->path) != 0) return FALSE;		}	if (mask & DUPE_MATCH_NAME)		{		if (strcmp(a->name, b->name) != 0) return FALSE;		}	if (mask & DUPE_MATCH_SIZE)		{		if (a->size != b->size) return FALSE;		}	if (mask & DUPE_MATCH_DATE)		{		if (a->date != b->date) return FALSE;

⌨️ 快捷键说明

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