Hi all,

It's been quite a while, for I'm buried under work and it prevents me
from thinking about gtkg too much :/

However I recently found some free time and now I'm able to submit this
miserable patch.

Basically it prevents adding the same filter rule several times when
using the 'Auto-download' and 'Drop' commands in the search pane. That
was happening a lot to me, especially with autoselect turned on.

Partial support was added a while ago to the gtk-1.2 frontend, but
remained absent from gtk2, which I'm using now (sob).

The patch includes cosmetic changes and the following :
- Ported existing code to avoid duplicate filename and SHA1 rules from
gtk-1.2 to gtk2 (we now have a tree_selection_collect_data() similar to
clist_collect_data()).
- Added support to avoid duplicate IP rules when using 'Drop by host'
commands.
- Added support to avoid duplicate new searches when using the targetted
search feature.

Many related helper functions are now shared by the gtk-1.2 and gtk2
frontends, so I basically stuffed them all in gui.c for now, since we
lack a common search_gui module which gets compiled in both frontends.

That's all for now. As an aside, someone proposed to write a
frontend-to-daemon protocol spec a while ago, how is this going ? I,
among others, suggested XML for daemon-to-frontend communication at the
time, and since I'm buried under XML anyway, working on the protocol or
discussing it is my best option :)

In addition, is there an official icon for gtkg ? Something we can use
as a gnome panel/menu icon (I don't know about KDE, I assume the same
features are present).

Cheers,


ko [junkpile at free dot fr on this platform]

-- Your fault - Core dumped.


Index: src/gtk-missing.c
===================================================================
RCS file: /cvsroot/gtk-gnutella/gtk-gnutella-current/src/gtk-missing.c,v
retrieving revision 1.19
diff -u -r1.19 gtk-missing.c
--- src/gtk-missing.c	31 Dec 2002 15:21:11 -0000	1.19
+++ src/gtk-missing.c	30 Jan 2003 15:59:55 -0000
@@ -248,7 +248,7 @@
 /*
  * clist_collect_data:
  *
- * Fetch data from the selection of a clist. Returns a GList containing
+ * Fetch data from the selection of a clist. Returns a GSList containing
  * the user_data pointers from the selected rows. If allow_null is TRUE,
  * the returned list may contain NULL pointers. If cfn != NULL, it will
  * be used to determine wether two entries are equal and drop all duplicate
@@ -277,10 +277,12 @@
         if ((data != NULL) || allow_null) {
             if (cfn != NULL) {
                 if (g_slist_find_custom(result_list, data, cfn) != NULL) {
-                    const gchar *name = gtk_widget_get_name(GTK_WIDGET(clist));
-                    if (gui_debug >= 3)
+                    if (gui_debug >= 3) {
+                    	const gchar *name =
+                    		gtk_widget_get_name(GTK_WIDGET(clist));
                         printf("%s has duplicate data: %p\n",
                             (name != NULL) ? name : "<UNKNOWN>", data);
+                    }
                     to_unselect =
 						g_slist_prepend(to_unselect, GINT_TO_POINTER(row));
                     continue;
@@ -288,11 +290,10 @@
             }
             result_list = g_slist_prepend(result_list, data);
             to_unselect = g_slist_prepend(to_unselect, GINT_TO_POINTER(row));
-        } else {
-            const gchar *name = gtk_widget_get_name(GTK_WIDGET(clist));
-            if (gui_debug >= 3)
-                printf("%s contains NULL data in row %d\n",
-                    (name != NULL) ? name : "<UNKNOWN>", row);
+        } else if (gui_debug >= 3) {
+           	const gchar *name = gtk_widget_get_name(GTK_WIDGET(clist));
+            printf("%s contains NULL data in row %d\n",
+                   (name != NULL) ? name : "<UNKNOWN>", row);
         }
     }
 
@@ -306,6 +307,82 @@
 
     return result_list;
 }
+
+/*
+ * tree_selection_collect_data:
+ *
+ * Fetch data from the selection of a treeview. Returns a GSList containing
+ * the user_data pointers from the selected rows. If allow_null is TRUE,
+ * the returned list may contain NULL pointers. If cfn != NULL, it will
+ * be used to determine wether two entries are equal and drop all duplicate
+ * items from the result list. Using cfn will significantly increase runtime.
+ */
+#ifdef USE_GTK2
+GSList *tree_selection_collect_data(GtkTreeSelection *tsel,
+	gboolean allow_null, GCompareFunc cfn)
+{
+	GSList *results = NULL;
+	GSList *to_unselect = NULL;
+	GtkTreeModel *model = NULL;
+	GList *rows;
+	GList *row;
+	GSList *sl;
+
+	g_assert(tsel != NULL);
+	rows = gtk_tree_selection_get_selected_rows(tsel, &model);
+
+	/*
+	 * Browse selected rows and gather data.
+	 */
+	for (row = rows; row != NULL; row = g_list_next(row)) {
+		gpointer data;
+		GtkTreeIter iter;
+		GtkTreePath *path;
+
+		path = (GtkTreePath *) row->data;
+		gtk_tree_model_get_iter(model, &iter, path);
+		gtk_tree_model_get(model, &iter, c_sr_record, &data, -1);
+
+		if ((data != NULL) || allow_null) {
+            if (cfn != NULL) {
+                if (g_slist_find_custom(results, data, cfn) != NULL) {
+                    if (gui_debug >= 3) {
+           				const gchar *name = gtk_widget_get_name(GTK_WIDGET(
+           					gtk_tree_selection_get_tree_view (tsel)));
+                        printf("%s has duplicate data: %p\n",
+                            (name != NULL) ? name : "<UNKNOWN>", data);
+                    }
+                    to_unselect =
+						g_slist_prepend(to_unselect, path);
+                    continue;
+                }
+            }
+            results = g_slist_prepend(results, data);
+            to_unselect = g_slist_prepend(to_unselect, path);
+		} else if (gui_debug >= 3) {
+           	const gchar *name = gtk_widget_get_name(GTK_WIDGET(
+           		gtk_tree_selection_get_tree_view (tsel)));
+            printf("%s contains NULL data in row %p\n",
+                   (name != NULL) ? name : "<UNKNOWN>", row);
+		}
+	}
+
+	/*
+	 * Now unselect the rows from which we got data.
+	 */
+    for (sl = to_unselect; sl != NULL; sl = g_slist_next(sl))
+        gtk_tree_selection_unselect_path(tsel, (GtkTreePath *) sl->data);
+
+	/*
+	 * Cleanup before exit.
+	 */
+	g_slist_free(to_unselect);
+	g_list_foreach(rows, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free(rows);
+
+	return results;
+}
+#endif	/* USE_GTK2 */
 
 gdouble _gtk_spin_button_get_value(GtkSpinButton *spinbutton)
 {
Index: src/gtk-missing.h
===================================================================
RCS file: /cvsroot/gtk-gnutella/gtk-gnutella-current/src/gtk-missing.h,v
retrieving revision 1.15
diff -u -r1.15 gtk-missing.h
--- src/gtk-missing.h	1 Jan 2003 00:14:35 -0000	1.15
+++ src/gtk-missing.h	30 Jan 2003 15:59:55 -0000
@@ -52,6 +52,10 @@
 void gtk_mass_widget_set_sensitive(GtkWidget *tl, gchar *list[], gboolean b);
 GSList *clist_collect_data(GtkCList *clist, gboolean allow_null, 
     GCompareFunc cfn);
+#ifdef USE_GTK2
+GSList *tree_selection_collect_data(GtkTreeSelection *tsel,
+	gboolean allow_null, GCompareFunc cfn);
+#endif
 gdouble _gtk_spin_button_get_value(GtkSpinButton *);
 guint32 gtk_editable_get_value_as_uint(GtkEditable *editable);
 void gtk_combo_init_choices(
Index: src/gui.c
===================================================================
RCS file: /cvsroot/gtk-gnutella/gtk-gnutella-current/src/gui.c,v
retrieving revision 1.132
diff -u -r1.132 gui.c
--- src/gui.c	31 Dec 2002 15:21:11 -0000	1.132
+++ src/gui.c	30 Jan 2003 15:59:55 -0000
@@ -34,6 +34,7 @@
 #include "uploads_gui.h"
 #include "statusbar_gui.h"
 #include "settings_gui.h"
+#include "search_gui.h"
 #include "search_stats_gui.h"
 
 RCSID("$Id: gui.c,v 1.132 2002/12/31 15:21:11 rmanfredi Exp $");
@@ -214,3 +215,189 @@
         gtk_widget_hide(frame_bws_ginout);
     }
 }
+
+/*
+ * Adds a drop SHA1 rule to specified filter.
+ */
+void search_gui_add_drop_sha1_filter(record_t *rec, filter_t *filter)
+{
+    rule_t *rule;
+
+    g_assert(rec != NULL);
+    g_assert(filter != NULL);
+
+    rule = filter_new_sha1_rule(rec->sha1, rec->name,
+        filter_get_drop_target(), RULE_FLAG_ACTIVE);
+
+    filter_append_rule(filter, rule);
+}
+
+/*
+ * Adds a drop filename rule to specified filter.
+ */
+void search_gui_add_drop_name_filter(record_t *rec, filter_t *filter)
+{
+    rule_t *rule;
+
+    g_assert(rec != NULL);
+    g_assert(filter != NULL);
+
+    rule = filter_new_text_rule(rec->name, RULE_TEXT_EXACT, TRUE,
+        filter_get_drop_target(), RULE_FLAG_ACTIVE);
+
+    filter_append_rule(filter, rule);
+}
+
+/*
+ * Adds a drop host rule to specified filter.
+ */
+void search_gui_add_drop_host_filter(record_t *rec, filter_t *filter)
+{
+    rule_t *rule;
+
+    g_assert(rec != NULL);
+    g_assert(filter != NULL);
+
+    rule = filter_new_ip_rule(rec->results_set->ip, 0xFFFFFFFF,
+        filter_get_drop_target(), RULE_FLAG_ACTIVE);
+
+    filter_append_rule(filter, rule);
+}
+
+/*
+ * Adds a download SHA1 rule to specified filter.
+ */
+void search_gui_add_download_sha1_filter(record_t *rec, filter_t *filter)
+{
+    g_assert(rec != NULL);
+    g_assert(filter != NULL);
+
+    if (rec->sha1) {
+        rule_t *rule;
+
+        rule = filter_new_sha1_rule(rec->sha1, rec->name,
+            filter_get_download_target(), RULE_FLAG_ACTIVE);
+
+        filter_append_rule(filter, rule);
+    }
+}
+
+/*
+ * Adds a download filename rule to specified filter.
+ */
+void search_gui_add_download_name_filter(record_t *rec, filter_t *filter)
+{
+    rule_t *rule;
+
+    g_assert(rec != NULL);
+    g_assert(filter != NULL);
+
+    rule = filter_new_text_rule(rec->name, RULE_TEXT_EXACT, TRUE,
+        filter_get_download_target(), RULE_FLAG_ACTIVE);
+
+    filter_append_rule(filter, rule);
+}
+
+/*
+ * search_gui_add_targetted_search:
+ *
+ * Creates a new search based on the filename found and adds a filter
+ * to it based on the sha1 hash if it has one or the exact filename if
+ * it hasn't.
+ * (patch by Andrew Meredith <[EMAIL PROTECTED]>)
+ */
+void search_gui_add_targetted_search(record_t *rec, filter_t *noneed)
+{
+    search_t *new_search;
+    rule_t *rule;
+
+    g_assert(rec != NULL);
+    g_assert(rec->name != NULL);
+
+    /* create new search item with search string set to filename */
+    search_gui_new_search(rec->name, 0, &new_search);
+    g_assert(new_search != NULL);
+
+    if (rec->sha1) {
+        rule = filter_new_sha1_rule(rec->sha1, rec->name,
+            filter_get_download_target(), RULE_FLAG_ACTIVE);
+    } else {
+        rule = filter_new_text_rule(rec->name, RULE_TEXT_EXACT, TRUE,
+            filter_get_download_target(), RULE_FLAG_ACTIVE);
+    }
+    g_assert(rule != NULL);
+
+    filter_append_rule(new_search->filter, rule);
+}
+
+/*
+ * Tells if two hit records have the same filename.
+ */
+gint record_name_eq(gconstpointer rec1, gconstpointer rec2)
+{
+    gint result;
+
+    result = g_str_equal(((const record_t *) rec1)->name,
+    	((const record_t *) rec2)->name) ? 0 : 1;
+
+    printf("[%s] == [%s] -> %d\n", ((const record_t *) rec1)->name,
+    	((const record_t *) rec2)->name, result);
+
+    return result;
+}
+
+/*
+ * Tells if two hit records have the same SHA1.
+ */
+gint record_sha1_eq(gconstpointer rec1, gconstpointer rec2)
+{
+    const guchar *s1 = ((const record_t *) rec1)->sha1;
+    const guchar *s2 = ((const record_t *) rec2)->sha1;
+
+    if (s1 == s2)
+        return 0;
+
+    if (s1 == NULL || s2 == NULL)
+       	return 1;
+
+    return memcmp(s1, s2, SHA1_RAW_SIZE);
+}
+
+/*
+ * Tells if two hit records come from the same host.
+ */
+gint record_host_eq(gconstpointer rec1, gconstpointer rec2)
+{
+    return ((const record_t *) rec1)->results_set->ip
+    	== ((const record_t *) rec2)->results_set->ip
+    	? 0 : 1;
+}
+
+/*
+ * Tells if two hit records have the same SHA1 or the same name.
+ *
+ * The targetted search feature by Andrew Meredith ([EMAIL PROTECTED])
+ * now uses this function to filter input and avoid duplicates.
+ * Andrew, if this somehow breaks the intent, let me know at
+ * [EMAIL PROTECTED]
+ *
+ * This provides the following behavior :
+ *
+ * - If several hits with the same SHA1 are selected, only one SHA1 rule
+ *   will be added even if the filenames differ (same as before).
+ *
+ * - If several hits with the same filename and no SHA1 are selected,
+ *   only one filename rule will be added.
+ *
+ * - If two selected hits have the same filename, but one has an SHA1
+ *   and the other doesn't, both rules (filename and SHA1) will be added.
+ *
+ */ 
+gint record_sha1_or_name_eq(gconstpointer rec1, gconstpointer rec2)
+{
+	if (((const record_t *) rec1)->sha1 || ((const record_t *) rec2)->sha1)
+		return record_sha1_eq(rec1, rec2);
+	else
+		return record_name_eq(rec1, rec2);
+}
+
Index: src/search_cb.c
===================================================================
RCS file: /cvsroot/gtk-gnutella/gtk-gnutella-current/src/search_cb.c,v
retrieving revision 1.16
diff -u -r1.16 search_cb.c
--- src/search_cb.c	31 Dec 2002 15:21:32 -0000	1.16
+++ src/search_cb.c	30 Jan 2003 15:59:56 -0000
@@ -55,102 +55,6 @@
     return search_gui_compare_records(clist->sort_column, s1, s2);
 }
 
-static gint rec_name_eq(gconstpointer ptr1, gconstpointer ptr2)
-{
-    gint result;
-
-    result = g_str_equal(
-        ((record_t *)ptr1)->name, 
-        ((record_t *)ptr2)->name) ? 0 : 1;
-
-    printf("[%s] == [%s] -> %d\n",
-        ((record_t *)ptr1)->name, ((record_t *)ptr2)->name, result);
-
-    return result;
-}
-
-static gint rec_sha1_eq(gconstpointer ptr1, gconstpointer ptr2)
-{
-
-    guchar *s1 = ((record_t *)ptr1)->sha1; 
-    guchar *s2 = ((record_t *)ptr2)->sha1; 
-
-    if (s1 == s2)
-        return 0;
-
-    if (s1 == NULL || s2 == NULL)
-        return 1;
-
-    return memcmp(s1, s2, SHA1_RAW_SIZE);
-}
-
-static void add_drop_sha1_filter(record_t *rec, filter_t *filter)
-{
-    rule_t *rule;
-
-    g_assert(rec != NULL);
-    g_assert(filter != NULL);
-
-    rule = filter_new_sha1_rule(rec->sha1, rec->name,
-        filter_get_drop_target(), RULE_FLAG_ACTIVE);
-
-    filter_append_rule(filter, rule);
-}
-
-static void add_drop_name_filter(record_t *rec, filter_t *filter)
-{
-    rule_t *rule;
-
-    g_assert(rec != NULL);
-    g_assert(filter != NULL);
-
-    rule = filter_new_text_rule(rec->name, RULE_TEXT_EXACT, TRUE, 
-        filter_get_drop_target(), RULE_FLAG_ACTIVE);
-
-    filter_append_rule(filter, rule);
-}
-
-static void add_drop_host_filter(record_t *rec, filter_t *filter)
-{
-    rule_t *rule;
-
-    g_assert(rec != NULL);
-    g_assert(filter != NULL);
-
-    rule = filter_new_ip_rule(rec->results_set->ip, 0xFFFFFFFF,
-        filter_get_drop_target(), RULE_FLAG_ACTIVE);
-
-    filter_append_rule(filter, rule);
-}
-
-static void add_download_sha1_filter(record_t *rec, filter_t *filter)
-{
-    g_assert(rec != NULL);
-    g_assert(filter != NULL);
-
-    if (rec->sha1) {
-        rule_t *rule;
-
-        rule = filter_new_sha1_rule(rec->sha1, rec->name,
-            filter_get_download_target(), RULE_FLAG_ACTIVE);
-
-        filter_append_rule(filter, rule);
-    }
-}
-
-static void add_download_name_filter(record_t *rec, filter_t *filter)
-{
-    rule_t *rule;
-
-    g_assert(rec != NULL);
-    g_assert(filter != NULL);
-
-    rule = filter_new_text_rule(rec->name, RULE_TEXT_EXACT, TRUE, 
-        filter_get_download_target(), RULE_FLAG_ACTIVE);
-
-    filter_append_rule(filter, rule);
-}
-
 static void refresh_popup(void)
 {
 	gboolean sensitive;
@@ -213,38 +117,6 @@
     }
 }
 
-/*
- * add_targetted_search:
- *
- * Creates a new search based on the filename found and adds a filter 
- * to it based on the sha1 hash if it has one or the exact filename if 
- * it hasn't. 
- * (patch by Andrew Meredith <[EMAIL PROTECTED]>)   
- */
-static void add_targetted_search(record_t *rec, filter_t *noneed)
-{
-    search_t *new_search;
-    rule_t *rule;
-
-    g_assert(rec != NULL);
-    g_assert(rec->name != NULL);
-
-    /* create new search item with search string set to filename */
-    search_gui_new_search(rec->name, 0, &new_search);
-    g_assert(new_search != NULL);
-
-    if (rec->sha1) {
-        rule = filter_new_sha1_rule(rec->sha1, rec->name,
-            filter_get_download_target(), RULE_FLAG_ACTIVE);
-    } else {
-        rule = filter_new_text_rule(rec->name, RULE_TEXT_EXACT, TRUE, 
-            filter_get_download_target(), RULE_FLAG_ACTIVE);
-    }
-    g_assert(rule != NULL);
-
-    filter_append_rule(new_search->filter, rule);
-}
-
 
 /***
  *** Glade callbacks
@@ -775,10 +647,10 @@
     gtk_clist_freeze(GTK_CLIST(current_search->clist));
 
     sl = clist_collect_data(GTK_CLIST(current_search->clist), 
-        FALSE, rec_name_eq);
+        FALSE, record_name_eq);
 
-    g_slist_foreach(sl, 
-        (GFunc) add_drop_name_filter, current_search->filter);
+    g_slist_foreach(sl, (GFunc) search_gui_add_drop_name_filter,
+    	current_search->filter);
 
     g_slist_free(sl);
 
@@ -798,10 +670,10 @@
     gtk_clist_freeze(GTK_CLIST(current_search->clist));
 
     sl = clist_collect_data(GTK_CLIST(current_search->clist), 
-        FALSE, rec_sha1_eq);
+        FALSE, record_sha1_eq);
 
-    g_slist_foreach(sl, 
-        (GFunc) add_drop_sha1_filter, current_search->filter);
+    g_slist_foreach(sl, (GFunc) search_gui_add_drop_sha1_filter,
+    	current_search->filter);
 
     g_slist_free(sl);
 
@@ -821,10 +693,10 @@
     gtk_clist_freeze(GTK_CLIST(current_search->clist));
 
     sl = clist_collect_data(GTK_CLIST(current_search->clist), 
-        FALSE, rec_sha1_eq);
+        FALSE, record_host_eq);
 
-    g_slist_foreach(sl, 
-        (GFunc) add_drop_host_filter, current_search->filter);
+    g_slist_foreach(sl, (GFunc) search_gui_add_drop_host_filter,
+    	current_search->filter);
 
     g_slist_free(sl);
 
@@ -844,10 +716,10 @@
     gtk_clist_freeze(GTK_CLIST(current_search->clist));
 
     sl = clist_collect_data(GTK_CLIST(current_search->clist), 
-        FALSE, rec_name_eq);
+        FALSE, record_name_eq);
 
-    g_slist_foreach(sl, 
-        (GFunc) add_drop_name_filter, filter_get_global_pre());
+    g_slist_foreach(sl, (GFunc) search_gui_add_drop_name_filter,
+    	filter_get_global_pre());
 
     g_slist_free(sl);
 
@@ -867,10 +739,10 @@
     gtk_clist_freeze(GTK_CLIST(current_search->clist));
 
     sl = clist_collect_data(GTK_CLIST(current_search->clist), 
-        FALSE, rec_sha1_eq);
+        FALSE, record_sha1_eq);
 
-    g_slist_foreach(sl, 
-        (GFunc) add_drop_sha1_filter, filter_get_global_pre());
+    g_slist_foreach(sl, (GFunc) search_gui_add_drop_sha1_filter,
+    	filter_get_global_pre());
 
     g_slist_free(sl);
 
@@ -890,10 +762,10 @@
     gtk_clist_freeze(GTK_CLIST(current_search->clist));
 
     sl = clist_collect_data(GTK_CLIST(current_search->clist), 
-        FALSE, rec_sha1_eq);
+        FALSE, record_host_eq);
 
-    g_slist_foreach(sl, 
-        (GFunc) add_drop_host_filter, filter_get_global_pre());
+    g_slist_foreach(sl, (GFunc) search_gui_add_drop_host_filter,
+    	filter_get_global_pre());
 
     g_slist_free(sl);
 
@@ -913,10 +785,10 @@
     gtk_clist_freeze(GTK_CLIST(current_search->clist));
 
     sl = clist_collect_data(GTK_CLIST(current_search->clist), 
-        FALSE, rec_name_eq);
+        FALSE, record_name_eq);
 
-    g_slist_foreach(sl, 
-        (GFunc) add_download_name_filter, current_search->filter);
+    g_slist_foreach(sl, (GFunc) search_gui_add_download_name_filter,
+    	current_search->filter);
 
     g_slist_free(sl);
 
@@ -936,10 +808,10 @@
     gtk_clist_freeze(GTK_CLIST(current_search->clist));
 
     sl = clist_collect_data(GTK_CLIST(current_search->clist), 
-        FALSE, rec_sha1_eq);
+        FALSE, record_sha1_eq);
 
-    g_slist_foreach(sl, 
-        (GFunc) add_download_sha1_filter, current_search->filter);
+    g_slist_foreach(sl, (GFunc) search_gui_add_download_sha1_filter,
+    	current_search->filter);
 
     g_slist_free(sl);
 
@@ -960,10 +832,10 @@
     gtk_clist_freeze(GTK_CLIST(current_search->clist));
 
     sl = clist_collect_data(GTK_CLIST(current_search->clist), 
-        FALSE, rec_sha1_eq);
+        FALSE, record_sha1_or_name_eq);
 
-    g_slist_foreach(sl, 
-        (GFunc) add_targetted_search, current_search->filter);
+    g_slist_foreach(sl, (GFunc) search_gui_add_targetted_search,
+    	current_search->filter);
 
     g_slist_free(sl);
 
Index: src/search_cb2.c
===================================================================
RCS file: /cvsroot/gtk-gnutella/gtk-gnutella-current/src/search_cb2.c,v
retrieving revision 1.11
diff -u -r1.11 search_cb2.c
--- src/search_cb2.c	11 Jan 2003 19:04:50 -0000	1.11
+++ src/search_cb2.c	30 Jan 2003 15:59:56 -0000
@@ -34,7 +34,7 @@
 
 RCSID("$Id: search_cb2.c,v 1.11 2003/01/11 19:04:50 cbiere Exp $");
 
-/* Privat variables */
+/* Private variables */
 
 static gboolean search_callbacks_shutting_down = FALSE;
 static gchar tmpstr[4096];
@@ -43,94 +43,6 @@
  *** Private functions
  ***/
 
-static void add_drop_sha1_filter(
-	GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
-	filter_t *filter = data;
-	record_t *rec;
-    rule_t *rule;
-
-	gtk_tree_model_get(model, iter, c_sr_record, &rec, -1);	
-    g_assert(rec != NULL);
-    g_assert(filter != NULL);
-
-    rule = filter_new_sha1_rule(rec->sha1, rec->name,
-        filter_get_drop_target(), RULE_FLAG_ACTIVE);
-
-    filter_append_rule(filter, rule);
-}
-
-static void add_drop_name_filter (
-	GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
-	filter_t *filter = data;
-	record_t *rec;
-    rule_t *rule;
-
-	gtk_tree_model_get(model, iter, c_sr_record, &rec, -1);	
-    g_assert(rec != NULL);
-    g_assert(filter != NULL);
-
-    rule = filter_new_text_rule(rec->name, RULE_TEXT_EXACT, TRUE, 
-        filter_get_drop_target(), RULE_FLAG_ACTIVE);
-
-    filter_append_rule(filter, rule);
-}
-
-static void add_drop_host_filter(
-	GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
-	filter_t *filter = data;
-	record_t *rec;
-    rule_t *rule;
-
-	gtk_tree_model_get(model, iter, c_sr_record, &rec, -1);	
-    g_assert(rec != NULL);
-    g_assert(filter != NULL);
-
-    rule = filter_new_ip_rule(rec->results_set->ip, 0xFFFFFFFF,
-        filter_get_drop_target(), RULE_FLAG_ACTIVE);
-
-    filter_append_rule(filter, rule);
-}
-
-static void add_download_sha1_filter(
-	GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
-	filter_t *filter = data;
-	record_t *rec;
-
-	gtk_tree_model_get(model, iter, c_sr_record, &rec, -1);	
-    g_assert(rec != NULL);
-    g_assert(filter != NULL);
-
-    if (rec->sha1) {
-        rule_t *rule;
-
-        rule = filter_new_sha1_rule(rec->sha1, rec->name,
-            filter_get_download_target(), RULE_FLAG_ACTIVE);
-
-        filter_append_rule(filter, rule);
-    }
-}
-
-static void add_download_name_filter(
-	GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
-	filter_t *filter = data;
-	record_t *rec;
-    rule_t *rule;
-
-	gtk_tree_model_get(model, iter, c_sr_record, &rec, -1);	
-    g_assert(rec != NULL);
-    g_assert(filter != NULL);
-
-    rule = filter_new_text_rule(rec->name, RULE_TEXT_EXACT, TRUE, 
-        filter_get_download_target(), RULE_FLAG_ACTIVE);
-
-    filter_append_rule(filter, rule);
-}
-
 static void refresh_popup(void)
 {
 	gboolean sensitive;
@@ -197,42 +109,6 @@
 
 }
 
-/*
- * add_targetted_search:
- *
- * Creates a new search based on the filename found and adds a filter 
- * to it based on the sha1 hash if it has one or the exact filename if 
- * it hasn't. 
- * (patch by Andrew Meredith <[EMAIL PROTECTED]>)   
- */
-static void add_targetted_search(
-	GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
-{
-    search_t *new_search;
-	record_t *rec;
-    rule_t *rule;
-
-	gtk_tree_model_get(model, iter, c_sr_record, &rec, -1);	
-    g_assert(rec != NULL);
-    g_assert(rec->name != NULL);
-
-    /* create new search item with search string set to filename */
-    search_gui_new_search(rec->name, 0, &new_search);
-    g_assert(new_search != NULL);
-
-    if (rec->sha1) {
-        rule = filter_new_sha1_rule(rec->sha1, rec->name,
-            filter_get_download_target(), RULE_FLAG_ACTIVE);
-    } else {
-        rule = filter_new_text_rule(rec->name, RULE_TEXT_EXACT, TRUE,
-            filter_get_download_target(), RULE_FLAG_ACTIVE);
-    }
-    g_assert(rule != NULL);
-
-    filter_append_rule(new_search->filter, rule);
-}
-
-
 /***
  *** Glade callbacks
  ***/
@@ -725,16 +601,17 @@
 {
     search_t *current_search;
 	GtkTreeSelection *selection;
+	GSList *sl = NULL ;
 
     current_search = search_gui_get_current_search();
     g_assert(current_search != NULL);
 	selection = gtk_tree_view_get_selection(
 					GTK_TREE_VIEW(current_search->tree_view));
 
-	gtk_tree_selection_selected_foreach(
-		selection, 
-		add_drop_name_filter, 
+	sl = tree_selection_collect_data(selection, FALSE, record_name_eq);
+	g_slist_foreach(sl, (GFunc) search_gui_add_drop_name_filter,
 		current_search->filter);
+	g_slist_free(sl);
 }
 
 void on_popup_search_drop_sha1_activate(
@@ -742,16 +619,17 @@
 {
     search_t *current_search;
 	GtkTreeSelection *selection;
+	GSList *sl = NULL ;
 
     current_search = search_gui_get_current_search();
     g_assert(current_search != NULL);
 	selection = gtk_tree_view_get_selection(
 					GTK_TREE_VIEW(current_search->tree_view));
 
-	gtk_tree_selection_selected_foreach(
-		selection, 
-		add_drop_sha1_filter, 
+	sl = tree_selection_collect_data(selection, FALSE, record_sha1_eq);
+	g_slist_foreach(sl, (GFunc) search_gui_add_drop_sha1_filter,
 		current_search->filter);
+	g_slist_free(sl);
 }
 
 void on_popup_search_drop_host_activate(
@@ -759,16 +637,17 @@
 {
     search_t *current_search;
 	GtkTreeSelection *selection;
+	GSList *sl = NULL ;
 
     current_search = search_gui_get_current_search();
     g_assert(current_search != NULL);
 	selection = gtk_tree_view_get_selection(
 					GTK_TREE_VIEW(current_search->tree_view));
 
-	gtk_tree_selection_selected_foreach(
-		selection, 
-		add_drop_host_filter, 
+	sl = tree_selection_collect_data(selection, FALSE, record_host_eq);
+	g_slist_foreach(sl, (GFunc) search_gui_add_drop_host_filter,
 		current_search->filter);
+	g_slist_free(sl);
 }
 
 void on_popup_search_drop_name_global_activate
@@ -776,16 +655,17 @@
 {
     search_t *current_search;
 	GtkTreeSelection *selection;
+	GSList *sl = NULL ;
 
     current_search = search_gui_get_current_search();
     g_assert(current_search != NULL);
 	selection = gtk_tree_view_get_selection(
 					GTK_TREE_VIEW(current_search->tree_view));
 
-	gtk_tree_selection_selected_foreach(
-		selection, 
-		add_drop_name_filter, 
+	sl = tree_selection_collect_data(selection, FALSE, record_name_eq);
+	g_slist_foreach(sl, (GFunc) search_gui_add_drop_name_filter,
 		filter_get_global_pre());
+	g_slist_free(sl);
 }
 
 void on_popup_search_drop_sha1_global_activate
@@ -793,16 +673,17 @@
 {
     search_t *current_search;
 	GtkTreeSelection *selection;
+	GSList *sl = NULL ;
 
     current_search = search_gui_get_current_search();
     g_assert(current_search != NULL);
 	selection = gtk_tree_view_get_selection(
 					GTK_TREE_VIEW(current_search->tree_view));
 
-	gtk_tree_selection_selected_foreach(
-		selection, 
-		add_drop_sha1_filter, 
+	sl = tree_selection_collect_data(selection, FALSE, record_sha1_eq);
+	g_slist_foreach(sl, (GFunc) search_gui_add_drop_sha1_filter,
 		filter_get_global_pre());
+	g_slist_free(sl);
 }
 
 void on_popup_search_drop_host_global_activate
@@ -810,16 +691,17 @@
 {
     search_t *current_search;
 	GtkTreeSelection *selection;
+	GSList *sl = NULL ;
 
     current_search = search_gui_get_current_search();
     g_assert(current_search != NULL);
 	selection = gtk_tree_view_get_selection(
 				GTK_TREE_VIEW(current_search->tree_view));
 
-	gtk_tree_selection_selected_foreach(
-		selection, 
-		add_drop_host_filter, 
+	sl = tree_selection_collect_data(selection, FALSE, record_host_eq);
+	g_slist_foreach(sl, (GFunc) search_gui_add_drop_host_filter,
 		filter_get_global_pre());
+	g_slist_free(sl);
 }
 
 void on_popup_search_autodownload_name_activate
@@ -827,16 +709,17 @@
 {
     search_t *current_search;
 	GtkTreeSelection *selection;
+	GSList *sl = NULL ;
 
     current_search = search_gui_get_current_search();
     g_assert(current_search != NULL);
 	selection = gtk_tree_view_get_selection(
 				GTK_TREE_VIEW(current_search->tree_view));
 
-	gtk_tree_selection_selected_foreach(
-		selection, 
-		add_download_name_filter, 
+	sl = tree_selection_collect_data(selection, FALSE, record_name_eq);
+	g_slist_foreach(sl, (GFunc) search_gui_add_download_name_filter,
 		current_search->filter);
+	g_slist_free(sl);
 }
 
 void on_popup_search_autodownload_sha1_activate(
@@ -844,16 +727,17 @@
 {
     search_t *current_search;
 	GtkTreeSelection *selection;
+	GSList *sl = NULL ;
 
     current_search = search_gui_get_current_search();
     g_assert(current_search != NULL);
 	selection = gtk_tree_view_get_selection(
 					GTK_TREE_VIEW(current_search->tree_view));
 
-	gtk_tree_selection_selected_foreach(
-		selection, 
-		add_download_sha1_filter, 
+	sl = tree_selection_collect_data(selection, FALSE, record_sha1_eq);
+	g_slist_foreach(sl, (GFunc) search_gui_add_download_sha1_filter,
 		current_search->filter);
+	g_slist_free(sl);
 }
 
 void on_popup_search_new_from_selected_activate(
@@ -861,16 +745,18 @@
 {
     search_t *current_search;
 	GtkTreeSelection *selection;
+	GSList *sl = NULL ;
 
     current_search = search_gui_get_current_search();
     g_assert(current_search != NULL);
 	selection = gtk_tree_view_get_selection(
 					GTK_TREE_VIEW(current_search->tree_view));
 
-	gtk_tree_selection_selected_foreach(
-		selection, 
-		add_targetted_search, 
+	sl = tree_selection_collect_data(selection, FALSE,
+		record_sha1_or_name_eq);
+	g_slist_foreach(sl, (GFunc) search_gui_add_targetted_search,
 		current_search->filter);
+	g_slist_free(sl);
 }
 
 void on_popup_search_edit_filter_activate(GtkMenuItem * menuitem,
Index: src/search_gui.h
===================================================================
RCS file: /cvsroot/gtk-gnutella/gtk-gnutella-current/src/search_gui.h,v
retrieving revision 1.14
diff -u -r1.14 search_gui.h
--- src/search_gui.h	10 Jan 2003 22:34:28 -0000	1.14
+++ src/search_gui.h	30 Jan 2003 15:59:57 -0000
@@ -78,6 +78,14 @@
     flag_t  flags;              /* same flags as in gnet_record_t */
 } record_t;
 
+/*
+ * Hit record comparison functions.
+ */
+gint record_name_eq(gconstpointer rec1, gconstpointer rec2);
+gint record_sha1_eq(gconstpointer rec1, gconstpointer rec2);
+gint record_host_eq(gconstpointer rec1, gconstpointer rec2);
+gint record_sha1_or_name_eq(gconstpointer rec1, gconstpointer rec2);
+
 /* 
  * Structure for search results 
  */
@@ -171,6 +179,17 @@
 #endif
 void gui_search_force_update_tab_label(struct search *);
 void gui_search_update_items(struct search *);
+
+
+/*
+ * Helper functions for adding filters.
+ */
+void search_gui_add_drop_sha1_filter(record_t *rec, filter_t *filter);
+void search_gui_add_drop_name_filter(record_t *rec, filter_t *filter);
+void search_gui_add_drop_host_filter(record_t *rec, filter_t *filter);
+void search_gui_add_download_sha1_filter(record_t *rec, filter_t *filter);
+void search_gui_add_download_name_filter(record_t *rec, filter_t *filter);
+void search_gui_add_targetted_search(record_t *rec, filter_t *noneed);
 
 
 /*
Index: src/shell.c
===================================================================
RCS file: /cvsroot/gtk-gnutella/gtk-gnutella-current/src/shell.c,v
retrieving revision 1.3
diff -u -r1.3 shell.c
--- src/shell.c	31 Dec 2002 15:21:38 -0000	1.3
+++ src/shell.c	30 Jan 2003 15:59:57 -0000
@@ -641,8 +641,8 @@
 
 	sh = shell_new(s);
     
-    s->gdk_tag = gdk_input_add(s->file_desc,
-        (GdkInputCondition) GDK_INPUT_READ | GDK_INPUT_EXCEPTION,
+    s->gdk_tag = inputevt_add(s->file_desc,
+        INPUT_EVENT_READ | INPUT_EVENT_EXCEPTION,
 		shell_handle_data, (gpointer) sh);
 
     sl_shells = g_slist_prepend(sl_shells, sh);

Reply via email to