[PATCH] : search results in separate window



	Hi all,
I post this patch (still not really clean but functional) that adds an 
option in the search dialog. You can now ask Balsa to throw all results of 
the search in a separate window. This window act as a normal index : you 
can view source from it, delete messages... and the "normal index" (the 
one in the main window) will get updated also.
Try it, and improve it. I won't be able to improve it right now, but you 
can give me feedback so that when I have time to code I'll make the 
desired improvments/bug fixes.
Patch is against current CVS.
Bye
Manu
--- balsa/src/balsa-index.h	Fri Apr 26 18:17:47 2002
+++ balsa-test/src/balsa-index.h	Sat Apr 27 08:22:03 2002
@@ -46,7 +46,12 @@
         GtkScrolledWindow sw;    
         
         GtkCTree* ctree;
-        GtkWidget* window;       
+        GtkWidget* window;
+
+	/* This new member is NULL if the index has no preview pane
+	   indeed I want to be able to have an index not necessarily
+	   embedded in the main-window */
+	GtkWidget *preview;
 
         BalsaMailboxNode* mailbox_node;
         LibBalsaMessage* first_new_message;
@@ -56,6 +61,16 @@
 
 	gchar *date_string;
 	gboolean line_length;
+
+	/* FIXME : for now these members are used to have the
+	   possibility to have the result of a research
+	   among the messages in a separate index.
+	   This has to be extended to implement so-called
+	   "virtual folders"
+	*/
+	GSList * conditions;
+	gint op;
+	gboolean clone;
     };
 
     struct _BalsaIndexClass {
@@ -77,7 +92,8 @@
 /* sets the mail stream; if it's a new stream, then it's 
  * contents is loaded into the index */
     gboolean balsa_index_load_mailbox_node(BalsaIndex * bindex,
-                                           BalsaMailboxNode * mbnode);
+                                           BalsaMailboxNode * mbnode,
+					   gboolean clone);
     void balsa_index_refresh(BalsaIndex * bindex);
     void balsa_index_update_tree(BalsaIndex *bindex, gboolean expand);
     void balsa_index_set_threading_type(BalsaIndex * bindex, int thtype);
@@ -86,7 +102,10 @@
     void balsa_index_set_first_new_message(BalsaIndex * bindex);
 
 /* adds a new message */
-    void balsa_index_add(BalsaIndex * bindex, LibBalsaMessage * message);
+    /* This now returns TRUE if the message has been added
+       to take care of the case of a "filtered" index
+       eg for search window result of for "virtual folders" */
+    gboolean balsa_index_add(BalsaIndex * bindex, LibBalsaMessage * message);
     void balsa_index_redraw_current(BalsaIndex *);
 
 /* move or copy a list of messages */
--- balsa/src/balsa-index.c	Fri Apr 26 18:17:47 2002
+++ balsa-test/src/balsa-index.c	Sat Apr 27 08:16:34 2002
@@ -48,7 +48,7 @@
 #include "sendmsg-window.h"
 #include "store-address.h"
 
-#include "filter.h"
+#include "filter-funcs.h"
 
 /* constants */
 #define BUFFER_SIZE 1024
@@ -118,7 +118,7 @@
 
 
 /* mailbox callbacks */
-static void balsa_index_del (BalsaIndex * bindex, LibBalsaMessage * message);
+static gboolean balsa_index_del (BalsaIndex * bindex, LibBalsaMessage * message);
 static void mailbox_message_changed_status_cb(LibBalsaMailbox * mb,
 					      LibBalsaMessage * message,
 					      BalsaIndex * bindex);
@@ -129,7 +129,8 @@
 				      LibBalsaMessage * message);
 static void mailbox_messages_delete_cb(BalsaIndex * bindex, 
 				       GList  * message);
-
+static gboolean reject_message(BalsaIndex * bindex,
+			       LibBalsaMessage * message);
 /* clist callbacks */
 static void button_event_press_cb(GtkWidget * clist, GdkEventButton * event,
 				  gpointer data);
@@ -308,6 +309,11 @@
     titles[5] = _("Date");
     titles[6] = _("Size");
 
+    /* FIXME : I added this to be sure it's initialized */
+    bindex->window=NULL;
+    bindex->preview=NULL;
+    bindex->conditions=NULL;
+    bindex->op=FILTER_NOOP;
     bindex->mailbox_node = NULL;
     adj = gtk_adjustment_new (0.0, 0.0, 10.0, 1.0, 1.0, 1.0);
     gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (bindex), 
@@ -610,7 +616,7 @@
 */
 
 gboolean
-balsa_index_load_mailbox_node (BalsaIndex * bindex, BalsaMailboxNode* mbnode)
+balsa_index_load_mailbox_node (BalsaIndex * bindex, BalsaMailboxNode* mbnode,gboolean clone)
 {
     LibBalsaMailbox* mailbox;
     gchar *msg;
@@ -621,15 +627,17 @@
     g_return_val_if_fail (mbnode->mailbox != NULL, TRUE);
 
     mailbox = mbnode->mailbox;
-    msg = g_strdup_printf(_("Opening mailbox %s. Please wait..."),
-			  mbnode->mailbox->name);
-    gnome_appbar_push(balsa_app.appbar, msg);
-    g_free(msg);
-    successp = libbalsa_mailbox_open(mailbox);
-    gnome_appbar_pop(balsa_app.appbar);
-
-    if (!successp)
-	return TRUE;
+    if (!clone) {
+	msg = g_strdup_printf(_("Opening mailbox %s. Please wait..."),
+			      mbnode->mailbox->name);
+	gnome_appbar_push(balsa_app.appbar, msg);
+	g_free(msg);
+	successp = libbalsa_mailbox_open(mailbox);
+	gnome_appbar_pop(balsa_app.appbar);
+	
+	if (!successp)
+	    return TRUE;
+    }
 
     /*
      * release the old mailbox
@@ -639,7 +647,7 @@
 
 	/* This will disconnect all of our signals */
 	gtk_signal_disconnect_by_data(GTK_OBJECT(mailbox), bindex);
-	libbalsa_mailbox_close(mailbox);
+	if (bindex->clone) libbalsa_mailbox_close(mailbox);
 	gtk_clist_clear(GTK_CLIST(bindex->ctree));
     }
 
@@ -680,16 +688,34 @@
        default setting
     */
     mbnode->threading_type = balsa_app.threading_type;
-    balsa_index_set_threading_type(bindex, mbnode->threading_type);
+    /* FIXME : for now no threading, just flat index because
+       threading just makes the assumption that the window
+       containing the index is a BalsaWindow */
+    balsa_index_set_threading_type(bindex, clone ? BALSA_INDEX_THREADING_FLAT:mbnode->threading_type);
     balsa_index_set_first_new_message(bindex);
 
     gtk_idle_add((GtkFunction) moveto_handler, bindex);
+    bindex->clone=clone;
 
     return FALSE;
 }
 
 
-void
+/* This function says if the message can be added to the
+   index : it tests for rejecting deleted messages if
+   the pref says we don't want to display them; it
+   tests if the message is within the search criterium
+   if it is a "search index" */
+static gboolean reject_message(BalsaIndex * bindex,
+			       LibBalsaMessage * message)
+{
+    return 
+	(balsa_app.hide_deleted && message->flags & LIBBALSA_MESSAGE_FLAG_DELETED) ||
+	(bindex->conditions && !match_conditions(bindex->op,bindex->conditions,message));
+}
+
+
+gboolean
 balsa_index_add(BalsaIndex * bindex, LibBalsaMessage * message)
 {
     gchar buff1[32];
@@ -702,17 +728,20 @@
     gboolean append_dots;
     
 
-    g_return_if_fail(bindex != NULL);
-    g_return_if_fail(message != NULL);
+    g_return_val_if_fail(bindex != NULL,FALSE);
+    g_return_val_if_fail(message != NULL,FALSE);
 
-    if (balsa_app.hide_deleted 
-        && message->flags & LIBBALSA_MESSAGE_FLAG_DELETED)
-        return;
+    if (reject_message(bindex,message))
+	/* This is added to have the possibility to "filter"
+	   the added messages : used to have a separate
+	   window with the result of a research among the messages
+	*/
+        return FALSE;
 
     mailbox = bindex->mailbox_node->mailbox;
     
     if (mailbox == NULL)
-	return;
+	return FALSE;
 
     sprintf(buff1, "%ld", LIBBALSA_MESSAGE_GET_NO(message)+1);
     text[0] = buff1;		/* set message number */
@@ -761,6 +790,7 @@
 
     balsa_index_set_col_images(bindex, node, message);
     balsa_index_set_parent_style(bindex, node);
+    return TRUE;
 }
 
 /*
@@ -768,24 +798,24 @@
   for discussion of the GtkCtree bug. The bug is triggered when one
   attempts to delete a collapsed message thread.
 */
-static void
+static gboolean
 balsa_index_del(BalsaIndex * bindex, LibBalsaMessage * message)
 {
     gint row;
     gpointer row_data;
     GtkCTreeNode *node;
 
-    g_return_if_fail(bindex != NULL);
-    g_return_if_fail(message != NULL);
+    g_return_val_if_fail(bindex != NULL,FALSE);
+    g_return_val_if_fail(message != NULL,FALSE);
 
     if (bindex->mailbox_node->mailbox == NULL)
-	return;
+	return FALSE;
 
     node = gtk_ctree_find_by_row_data (GTK_CTREE (bindex->ctree), NULL, 
                                        (gpointer) message);
 
     if (node == NULL)
-	return;
+	return FALSE;
 
     if(bindex->first_new_message == message){
 	bindex->first_new_message=NULL;
@@ -803,19 +833,19 @@
 	    
 	    if(sibling!=NULL)sibling=GTK_CTREE_ROW(sibling)->sibling;
 	    else{sibling=GTK_CTREE_ROW(node)->sibling;}
-
-
+	    
+	    
 	    /* BEGIN GtkCTree bug workaround. */
-           if(sibling==NULL){
-             gboolean expanded;
-             gtk_ctree_get_node_info(GTK_CTREE(bindex->ctree), node,
-                                     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                                     &expanded);
-             if(!expanded)
-               gtk_ctree_expand(GTK_CTREE(bindex->ctree), node);
-           }
-	   /* end GtkCTRee bug workaround. */
-
+	    if(sibling==NULL){
+		gboolean expanded;
+		gtk_ctree_get_node_info(GTK_CTREE(bindex->ctree), node,
+					NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+					&expanded);
+		if(!expanded)
+		    gtk_ctree_expand(GTK_CTREE(bindex->ctree), node);
+	    }
+	    /* end GtkCTRee bug workaround. */
+	    
 	    while(1){
 		if(children==NULL)break;
 		next=GTK_CTREE_ROW(children)->sibling;
@@ -827,8 +857,8 @@
 					     NULL, (gpointer) message);
 	}
     }
-
-
+    
+    
     row_data = gtk_ctree_node_get_row_data (bindex->ctree, node);
     row = gtk_clist_find_row_from_data (GTK_CLIST (bindex->ctree), row_data);
     gtk_clist_unselect_row (GTK_CLIST (bindex->ctree), row, -1);
@@ -839,6 +869,7 @@
     if (GTK_CLIST (bindex->ctree)->rows <= 0) {
         balsa_index_idle_add(bindex, NULL);
     }
+    return TRUE;
 }
 
 
@@ -1531,16 +1562,24 @@
 static void
 mailbox_message_new_cb(BalsaIndex * bindex, LibBalsaMessage * message)
 {
-    gtk_clist_freeze(GTK_CLIST (bindex->ctree));
-    balsa_index_add(bindex, message);
-    if(bindex->mailbox_node->mailbox->new_messages==0){
-      balsa_index_threading(bindex);
-      gtk_clist_sort (GTK_CLIST (bindex->ctree));
-      DO_CLIST_WORKAROUND(GTK_CLIST (bindex->ctree));
+    /* Do something only when the message has been actually added to the index*/
+    if (balsa_index_add(bindex, message)) {
+	gtk_clist_freeze(GTK_CLIST (bindex->ctree));
+	/* FIXME : I don't understand that test */
+	if(bindex->mailbox_node->mailbox->new_messages==0){
+	    balsa_index_threading(bindex);
+	    gtk_clist_sort (GTK_CLIST (bindex->ctree));
+	    DO_CLIST_WORKAROUND(GTK_CLIST (bindex->ctree));
+	}
+	gtk_clist_thaw (GTK_CLIST (bindex->ctree));
     }
-    gtk_clist_thaw (GTK_CLIST (bindex->ctree));
+    /* FIXME : Reorganize this because in case of a massive
+       incoming of mails (upon checking in general) we update
+       the mailbox state a zillion times whereas we could do it
+       only once.
+       Moreover : why is the index updating the mailbox state ? */
     balsa_mblist_update_mailbox(balsa_app.mblist, 
-                                bindex->mailbox_node->mailbox);
+				bindex->mailbox_node->mailbox);
 }
 
 static void
@@ -1566,8 +1605,11 @@
 static void
 mailbox_message_delete_cb(BalsaIndex * bindex, LibBalsaMessage * message)
 {
-    balsa_index_del(bindex, message);
-    balsa_index_check_visibility(GTK_CLIST(bindex->ctree), NULL, 0.5);
+    if (balsa_index_del(bindex, message))
+	balsa_index_check_visibility(GTK_CLIST(bindex->ctree), NULL, 0.5);
+
+    /* FIXME : here also if we delete a lot of message we check visibility a
+       zillion times, is this useful here?*/
 }
 
 static void
@@ -1650,10 +1692,10 @@
     /*page->window references our owner */
     if (bindex->mailbox_node && (mailbox = bindex->mailbox_node->mailbox) ) {
         gtk_signal_disconnect_by_data (GTK_OBJECT (mailbox), bindex);
-	libbalsa_mailbox_close(mailbox);
+	if (!bindex->clone) libbalsa_mailbox_close(mailbox);
 	bindex->mailbox_node = NULL;
     }
-
+    libbalsa_conditions_free(bindex->conditions);
     if (GTK_OBJECT_CLASS(parent_class)->destroy)
         (*GTK_OBJECT_CLASS(parent_class)->destroy) (obj);
 }
@@ -1989,6 +2031,9 @@
     LibBalsaMessage *message;
     BalsaIndex* index;
     /* gpointer data; */
+
+    /* If there is no preview pane, just return */
+    if (!BALSA_INDEX (widget)->preview) return FALSE;
 
     gdk_threads_enter();
     
--- balsa/src/main-window.c	Fri Apr 26 18:17:48 2002
+++ balsa-test/src/main-window.c	Fri Apr 26 21:42:19 2002
@@ -1272,9 +1272,11 @@
     gdk_threads_enter();
     index = BALSA_INDEX(balsa_index_new());
     index->window = GTK_WIDGET(balsa_app.main_window);
+    /* Now you have to set the preview pane */
+    index->preview= balsa_app.main_window->preview;
 
     balsa_window_increase_activity(balsa_app.main_window);
-    failurep = balsa_index_load_mailbox_node(BALSA_INDEX (index), mbnode);
+    failurep = balsa_index_load_mailbox_node(BALSA_INDEX (index), mbnode, FALSE);
     balsa_window_decrease_activity(balsa_app.main_window);
 
     if(failurep) {
@@ -2534,7 +2536,9 @@
        CONDITION_NONE if nothing has been set up */
     static LibBalsaCondition * cnd=NULL;
     GSList * conditions;
-    static gboolean reverse=FALSE;
+    static gboolean reverse=FALSE,in_sep_window=FALSE;
+
+    if (!bindex->mailbox_node->mailbox) return;
 
     if (!cnd) {
 	cnd=libbalsa_condition_new();
@@ -2550,7 +2554,8 @@
                                           GNOME_STOCK_BUTTON_OK,
                                           GNOME_STOCK_BUTTON_CANCEL,
                                           NULL));
-	GtkWidget *reverse_button, *search_entry, *w, *page, *table;
+	GtkWidget *reverse_button, *search_entry, *w, *page, *table,
+	    * in_sep_window_button;
 	GtkToggleButton *matching_body, *matching_from;
         GtkToggleButton *matching_to, *matching_cc, *matching_subject;
 	gint ok;
@@ -2562,8 +2567,6 @@
 	   gtk_signal_connect(GTK_OBJECT(dia),"clicked",
 	   find_dialog_button_cb,&f);
 	*/
-	reverse_button = gtk_check_button_new_with_label(_("Reverse search"));
-
 	page=gtk_table_new(2, 1, FALSE);
 	w = gtk_label_new(_("Search for:"));
 	gtk_table_attach(GTK_TABLE(page),w,0, 1, 0, 1,
@@ -2585,7 +2588,7 @@
 			 0, 3, 0, 2,
 			 GTK_FILL | GTK_SHRINK | GTK_EXPAND, GTK_SHRINK, 5, 5);
     
-	table = gtk_table_new(3, 3, TRUE);
+	table = gtk_table_new(2, 3, TRUE);
 	gtk_container_add(GTK_CONTAINER(w), table);
 		
 	matching_body    = add_check_button(table, _("Body"),    0, 0);
@@ -2597,12 +2600,17 @@
 
 	gtk_box_pack_start(GTK_BOX(dia->vbox), gtk_hseparator_new(), 
                            FALSE, FALSE, 2);
+	reverse_button = gtk_check_button_new_with_label(_("Reverse search"));
 	gtk_box_pack_start(GTK_BOX(dia->vbox), reverse_button,TRUE,TRUE,0);
+	in_sep_window_button = gtk_check_button_new_with_label(_("Show all results in a separate window"));
+	gtk_box_pack_start(GTK_BOX(dia->vbox), in_sep_window_button,TRUE,TRUE,0);
+	
 	gtk_widget_show_all(dia->vbox);
 
 	if (cnd->match.string)
 	    gtk_entry_set_text(GTK_ENTRY(search_entry),cnd->match.string);
 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(reverse_button),reverse);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(in_sep_window_button),in_sep_window);
 	gtk_toggle_button_set_active(matching_body,
 				     CONDITION_CHKMATCH(cnd,
                                                         CONDITION_MATCH_BODY));
@@ -2623,6 +2631,7 @@
 	    ok=gnome_dialog_run(dia);
 	    if (ok==0) {
 		reverse=GTK_TOGGLE_BUTTON(reverse_button)->active;
+		in_sep_window = GTK_TOGGLE_BUTTON(in_sep_window_button)->active;
 		g_free(cnd->match.string);
 		cnd->match.string =
                     g_strdup(gtk_entry_get_text(GTK_ENTRY(search_entry)));
@@ -2668,13 +2677,50 @@
     }
     else conditions=g_slist_append(NULL,cnd);
 
-    balsa_index_find(bindex,
-                     f ? f->conditions_op : FILTER_OP_OR,
-                     conditions, reverse);
-
-    /* FIXME : See if this does not lead to a segfault because of
-       balsa_index_scan_info */
-    if (!f) g_slist_free(conditions);
+    if (!in_sep_window) {
+	balsa_index_find(bindex,
+			 f ? f->conditions_op : FILTER_OP_OR,
+			 conditions, reverse);
+
+	/* FIXME : See if this does not lead to a segfault because of
+	   balsa_index_scan_info */
+	if (!f) g_slist_free(conditions);
+    }
+    else {
+	/* FIXME : this is just to see if people like this feature
+	   we should think about how to do it cleaner if finally
+	   we decide to keep it (perhaps reusing code from
+	   message-window.c ? */
+	GtkWidget * window;
+	gchar * title;
+	BalsaIndex * new_index = BALSA_INDEX(balsa_index_new());
+	gboolean failurep;
+
+	new_index->conditions=g_slist_append(NULL,libbalsa_condition_clone(cnd));
+	new_index->op=FILTER_OP_OR;
+	failurep = balsa_index_load_mailbox_node(new_index, bindex->mailbox_node,TRUE);
+
+	if(failurep) {
+	    libbalsa_information(
+				 LIBBALSA_INFORMATION_ERROR,
+				 _("Unable to Open search window!"));
+	    gtk_object_destroy(GTK_OBJECT(new_index));
+	    return;
+	}
+	title = g_strdup_printf("Search results from mailbox : %s",bindex->mailbox_node->mailbox->name);
+	window = gnome_app_new("balsa",title);
+	g_free(title);
+
+	gtk_window_set_wmclass(GTK_WINDOW(window), "search", "Balsa");
+	gtk_window_set_default_size(GTK_WINDOW(window), 400, 500);
+    
+	new_index->window = window;
+	new_index->preview= NULL;
+	new_index->date_string = g_strdup (balsa_app.date_string);
+	new_index->line_length = balsa_app.line_length;
+	gnome_app_set_contents(GNOME_APP(window),GTK_WIDGET(new_index));
+	gtk_widget_show_all(window);
+    }
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]