[PATCH] : search results in separate window
- From: Emmanuel <e allaud wanadoo fr>
- To: ML de Balsa <balsa-list gnome org>
- Subject: [PATCH] : search results in separate window
- Date: Sat, 27 Apr 2002 08:35:22 +0200
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]