[PATCH] : separate window with search results



	Hi all,
here is a patch against CVS to implement the "all search results in a
separate window" feature. Ie in the find window you have a new check
button to tell balsa to throw all matching messages in a different window
(with no preview pane for now, but this can be changed) where you can
browse them, delete them ... In fact you have the same popup menu as in
the main window.
This is a really ALPHA PATCH, it is not that clean, but it's just a way to
see if people would be insterested in that sort of feature.
I have no more time now to spend on it, but later I could perhaps
clean/improve it if people like this feature in a near future (read one
month at least). In the meantime I'll note all comments/bug
reports/requests...
Bye
Manu


diff -u ../balsa-cvs/balsa/src/balsa-index.c balsa-cvs/balsa/src/balsa-index.c
--- ../balsa-cvs/balsa/src/balsa-index.c	Sat Mar  2 12:36:19 2002
+++ balsa-cvs/balsa/src/balsa-index.c	Sat Mar 16 19:44:22 2002
@@ -123,7 +123,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);
@@ -134,7 +134,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);
@@ -313,6 +314,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), 
@@ -620,7 +626,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;
@@ -631,15 +637,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
@@ -649,7 +657,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));
     }
 
@@ -690,16 +698,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];
@@ -712,17 +738,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 */
@@ -771,6 +800,7 @@
 
     balsa_index_set_col_images(bindex, node, message);
     balsa_index_set_parent_style(bindex, node);
+    return TRUE;
 }
 
 /*
@@ -778,24 +808,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;
@@ -813,19 +843,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;
@@ -837,8 +867,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);
@@ -849,6 +879,7 @@
     if (GTK_CLIST (bindex->ctree)->rows <= 0) {
         balsa_index_idle_add(bindex, NULL);
     }
+    return TRUE;
 }
 
 
@@ -1568,16 +1599,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
@@ -1603,8 +1642,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
@@ -1687,10 +1729,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);
 }
@@ -2026,6 +2068,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();
     
Only in balsa-cvs/balsa/src/: balsa-index.c.orig
Only in balsa-cvs/balsa/src/: balsa-index.c~
diff -u ../balsa-cvs/balsa/src/balsa-index.h balsa-cvs/balsa/src/balsa-index.h
--- ../balsa-cvs/balsa/src/balsa-index.h	Fri Feb  8 09:03:34 2002
+++ balsa-cvs/balsa/src/balsa-index.h	Sat Mar 16 19:32:13 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
+	   imbedded in the main-window */
+	GtkWidget *preview;
 
         BalsaMailboxNode* mailbox_node;
         LibBalsaMessage* first_new_message;
@@ -56,6 +61,19 @@
 
 	gchar *date_string;
 	gboolean line_length;
+
+#ifdef BALSA_SHOW_ALL
+
+	/* 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;
+#endif /* BALSA_SHOW_ALL */
     };
 
     struct _BalsaIndexClass {
@@ -77,7 +95,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 +105,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 */
diff -u ../balsa-cvs/balsa/src/main-window.c balsa-cvs/balsa/src/main-window.c
--- ../balsa-cvs/balsa/src/main-window.c	Wed Feb 27 14:04:19 2002
+++ balsa-cvs/balsa/src/main-window.c	Sat Mar 16 19:45:23 2002
@@ -1289,9 +1289,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) {
@@ -2549,7 +2551,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();
@@ -2565,7 +2569,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;
@@ -2577,8 +2582,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,
@@ -2600,7 +2603,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);
@@ -2612,12 +2615,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));
@@ -2638,6 +2646,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)));
@@ -2683,13 +2692,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]