changeset 2489:ab6a0d1bd821

Fix #477: similarity duplicate search https://github.com/BestImageViewer/geeqie/issues/477 Additional find dupes option: sort groups with the lowest number of matches to the top of the results list
author Colin Clark <colin.clark@cclark.uk>
date Sun, 28 May 2017 19:30:41 +0100
parents fa98e57c9e2e
children a1b125f07ead
files doc/docbook/GuideImageSearchFindingDuplicates.xml src/dupe.c src/options.c src/options.h src/rcfile.c
diffstat 5 files changed, 58 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/doc/docbook/GuideImageSearchFindingDuplicates.xml	Sat May 27 15:58:00 2017 +0100
+++ b/doc/docbook/GuideImageSearchFindingDuplicates.xml	Sun May 28 19:30:41 2017 +0100
@@ -185,6 +185,14 @@
     <title>Ignore Rotation</title>
     <para>When checked, the rotational orientation of images will be ignored.</para>
   </section>
+  <section id="Sort">
+    <title>Sort</title>
+    <para>
+      The normal sort order is for groups (in the case of Similarity checks) with the highest number of near-100% matches to be at the top of the list.
+      <para />
+      If this box is checked, groups with the lowest number of matches are placed at the top of the list.
+    </para>
+  </section>
   <section id="Comparetwofilesets">
     <title>Compare two file sets</title>
     <para>Sometimes it is useful to compare one group of files to another, different group of files. Enable this check box to compare two groups of files. When enabled, a second list will appear and files can be added to this list using the same methods for the main list.</para>
@@ -202,4 +210,4 @@
     </para>
     <para />
   </section>
-</section>
+</section>
--- a/src/dupe.c	Sat May 27 15:58:00 2017 +0100
+++ b/src/dupe.c	Sun May 28 19:30:41 2017 +0100
@@ -1066,6 +1066,20 @@
 		}
 }
 
+static gint dupe_match_totals_sort_cb(gconstpointer a, gconstpointer b)
+{
+	DupeItem *da = (DupeItem *)a;
+	DupeItem *db = (DupeItem *)b;
+
+	if (g_list_length(da->group) > g_list_length(db->group)) return -1;
+	if (g_list_length(da->group) < g_list_length(db->group)) return 1;
+
+	if (da->group_rank < db->group_rank) return -1;
+	if (da->group_rank > db->group_rank) return 1;
+
+	return 0;
+}
+
 static gint dupe_match_rank_sort_cb(gconstpointer a, gconstpointer b)
 {
 	DupeItem *da = (DupeItem *)a;
@@ -1099,6 +1113,15 @@
 	return g_list_sort(list, dupe_match_rank_sort_cb);
 }
 
+/* returns allocated GList of dupes sorted by totals */
+static GList *dupe_match_totals_sort(GList *source_list)
+{
+	source_list = g_list_sort(source_list, dupe_match_totals_sort_cb);
+
+	source_list = g_list_first(source_list);
+	return g_list_reverse(source_list);
+}
+
 static void dupe_match_rank(DupeWindow *dw)
 {
 	GList *list;
@@ -1116,6 +1139,11 @@
 	if (required_debug_level(2)) dupe_match_print_list(list);
 
 	list = dupe_match_rank_sort(list);
+	if (options->sort_totals)
+		{
+		list = dupe_match_totals_sort(list);
+		}
+	if (required_debug_level(2)) dupe_match_print_list(list);
 
 	g_list_free(dw->dupes);
 	dw->dupes = list;
@@ -2648,6 +2676,15 @@
 	dupe_window_recompare(dw);
 }
 
+static void dupe_sort_totals_toggle_cb(GtkWidget *widget, gpointer data)
+{
+	DupeWindow *dw = data;
+
+	options->sort_totals = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+	dupe_window_recompare(dw);
+
+}
+
 /*
  *-------------------------------------------------------------------
  * match type menu
@@ -3331,6 +3368,14 @@
 	gtk_container_add(GTK_CONTAINER(frame), dw->status_label);
 	gtk_widget_show(dw->status_label);
 
+	button = gtk_check_button_new_with_label(_("Sort"));
+	gtk_widget_set_tooltip_text(GTK_WIDGET(button), "Sort by group totals");
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), options->sort_totals);
+	g_signal_connect(G_OBJECT(button), "toggled",
+			 G_CALLBACK(dupe_sort_totals_toggle_cb), dw);
+	gtk_box_pack_start(GTK_BOX(status_box), button, FALSE, FALSE, PREF_PAD_SPACE);
+	gtk_widget_show(button);
+
 	label = gtk_label_new(_("Custom Threshold"));
 	gtk_box_pack_start(GTK_BOX(status_box), label, FALSE, FALSE, PREF_PAD_SPACE);
 	gtk_widget_show(label);
--- a/src/options.c	Sat May 27 15:58:00 2017 +0100
+++ b/src/options.c	Sun May 28 19:30:41 2017 +0100
@@ -48,6 +48,7 @@
 	options->dnd_icon_size = 48;
 	options->duplicates_similarity_threshold = 99;
 	options->rot_invariant_sim = TRUE;
+	options->sort_totals = FALSE;
 
 	options->file_filter.disable = FALSE;
 	options->file_filter.show_dot_directory = FALSE;
--- a/src/options.h	Sat May 27 15:58:00 2017 +0100
+++ b/src/options.h	Sun May 28 19:30:41 2017 +0100
@@ -45,6 +45,7 @@
 	gboolean duplicates_thumbnails;
 	guint duplicates_select_type;
 	gboolean rot_invariant_sim;
+	gboolean sort_totals;
 
 	gint open_recent_list_maxsize;
 	gint dnd_icon_size;
--- a/src/rcfile.c	Sat May 27 15:58:00 2017 +0100
+++ b/src/rcfile.c	Sun May 28 19:30:41 2017 +0100
@@ -322,6 +322,7 @@
 	WRITE_NL(); WRITE_UINT(*options, duplicates_select_type);
 	WRITE_NL(); WRITE_BOOL(*options, duplicates_thumbnails);
 	WRITE_NL(); WRITE_BOOL(*options, rot_invariant_sim);
+	WRITE_NL(); WRITE_BOOL(*options, sort_totals);
 	WRITE_SEPARATOR();
 
 	WRITE_NL(); WRITE_BOOL(*options, mousewheel_scrolls);
@@ -606,6 +607,7 @@
 		if (READ_UINT_CLAMP(*options, duplicates_select_type, 0, DUPE_SELECT_GROUP2)) continue;
 		if (READ_BOOL(*options, duplicates_thumbnails)) continue;
 		if (READ_BOOL(*options, rot_invariant_sim)) continue;
+		if (READ_BOOL(*options, sort_totals)) continue;
 
 		if (READ_BOOL(*options, progressive_key_scrolling)) continue;
 		if (READ_UINT_CLAMP(*options, keyboard_scroll_step, 1, 32)) continue;