aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/folderview.c29
-rw-r--r--src/mainwindow.c9
-rw-r--r--src/prefs_filter_edit.c7
-rw-r--r--src/prefs_filter_edit.h19
-rw-r--r--src/prefs_folder_item.c3
-rw-r--r--src/summary_search.c1156
-rw-r--r--src/summary_search.h4
-rw-r--r--src/summaryview.c2
8 files changed, 873 insertions, 356 deletions
diff --git a/src/folderview.c b/src/folderview.c
index 43ff7732..42965160 100644
--- a/src/folderview.c
+++ b/src/folderview.c
@@ -105,6 +105,7 @@ static GdkPixbuf *folderopen_pixbuf;
static GdkPixbuf *foldernoselect_pixbuf;
static GdkPixbuf *draft_pixbuf;
static GdkPixbuf *trash_pixbuf;
+static GdkPixbuf *virtual_pixbuf;
static void folderview_set_columns (FolderView *folderview);
@@ -516,6 +517,7 @@ void folderview_init(FolderView *folderview)
&foldernoselect_pixbuf);
stock_pixbuf_gdk(treeview, STOCK_PIXMAP_DRAFT, &draft_pixbuf);
stock_pixbuf_gdk(treeview, STOCK_PIXMAP_TRASH, &trash_pixbuf);
+ stock_pixbuf_gdk(treeview, STOCK_PIXMAP_GROUP, &virtual_pixbuf);
}
void folderview_reflect_prefs(FolderView *folderview)
@@ -1170,6 +1172,19 @@ static void folderview_update_row(FolderView *folderview, GtkTreeIter *iter)
!strcmp2(item->name, DRAFT_DIR) ? _("Drafts") :
item->name);
break;
+#if 0
+ case F_JUNK:
+ pixbuf = folder_pixbuf;
+ open_pixbuf = folderopen_pixbuf;
+ name = g_strdup(FOLDER_IS_LOCAL(item->folder) &&
+ !strcmp2(item->name, JUNK_DIR) ? _("Junk") :
+ item->name);
+ break;
+#endif
+ case F_VIRTUAL:
+ pixbuf = open_pixbuf = virtual_pixbuf;
+ name = g_strdup(item->name);
+ break;
default:
if (item->no_select) {
pixbuf = open_pixbuf = foldernoselect_pixbuf;
@@ -1540,14 +1555,13 @@ static gboolean folderview_menu_popup(FolderView *folderview,
if (folderview->mainwin->lock_count == 0) {
new_folder = TRUE;
folder_property = TRUE;
+ search_folder = TRUE;
if (item->parent == NULL) {
update_tree = remove_tree = TRUE;
} else {
if (gtkut_tree_row_reference_equal
- (folderview->selected, folderview->opened)) {
+ (folderview->selected, folderview->opened))
update_summary = TRUE;
- search_folder = TRUE;
- }
}
if (FOLDER_IS_LOCAL(folder) || FOLDER_TYPE(folder) == F_IMAP) {
if (item->parent == NULL)
@@ -1562,6 +1576,9 @@ static gboolean folderview_menu_popup(FolderView *folderview,
if (item->parent != NULL)
delete_folder = TRUE;
}
+ if (item->stype == F_VIRTUAL) {
+ rename_folder = delete_folder = TRUE;
+ }
if (FOLDER_TYPE(folder) == F_IMAP ||
FOLDER_TYPE(folder) == F_NEWS) {
if (item->parent != NULL && item->no_select == FALSE)
@@ -2608,7 +2625,11 @@ static void folderview_rm_news_server_cb(FolderView *folderview, guint action,
static void folderview_search_cb(FolderView *folderview, guint action,
GtkWidget *widget)
{
- summary_search(folderview->summaryview);
+ FolderItem *item;
+
+ item = folderview_get_selected_item(folderview);
+ if (item)
+ summary_search(folderview->summaryview, item);
}
static void folderview_property_cb(FolderView *folderview, guint action,
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 19afdda3..d7f90d19 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -2758,9 +2758,12 @@ static void app_exit_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
static void search_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
{
- if (action == 1)
- summary_search(mainwin->summaryview);
- else
+ if (action == 1) {
+ FolderItem *item;
+
+ item = folderview_get_selected_item(mainwin->folderview);
+ summary_search(mainwin->summaryview, item);
+ } else
message_search(mainwin->messageview);
}
diff --git a/src/prefs_filter_edit.c b/src/prefs_filter_edit.c
index 52821448..af804aed 100644
--- a/src/prefs_filter_edit.c
+++ b/src/prefs_filter_edit.c
@@ -335,6 +335,7 @@ FilterCondEdit *prefs_filter_edit_cond_edit_create(void)
cond_edit->cond_hbox_list = NULL;
cond_edit->hdr_list = NULL;
cond_edit->rule_hdr_list = NULL;
+ cond_edit->add_hbox = NULL;
return cond_edit;
}
@@ -1243,6 +1244,8 @@ static void prefs_filter_edit_add_rule_cond(FilterCondEdit *cond_edit,
hbox = prefs_filter_edit_cond_hbox_create(cond_edit);
prefs_filter_edit_set_cond_hbox_widgets(hbox, PF_COND_HEADER);
prefs_filter_edit_insert_cond_hbox(cond_edit, hbox, -1);
+ if (cond_edit->add_hbox)
+ cond_edit->add_hbox(hbox);
return;
}
@@ -1252,6 +1255,8 @@ static void prefs_filter_edit_add_rule_cond(FilterCondEdit *cond_edit,
hbox = prefs_filter_edit_cond_hbox_create(cond_edit);
prefs_filter_edit_cond_hbox_set(hbox, cond);
prefs_filter_edit_insert_cond_hbox(cond_edit, hbox, -1);
+ if (cond_edit->add_hbox)
+ cond_edit->add_hbox(hbox);
}
}
@@ -1964,6 +1969,8 @@ static void prefs_filter_cond_add_cb(GtkWidget *widget, gpointer data)
new_hbox = prefs_filter_edit_cond_hbox_create(cond_edit);
prefs_filter_edit_set_cond_hbox_widgets(new_hbox, PF_COND_HEADER);
prefs_filter_edit_insert_cond_hbox(cond_edit, new_hbox, index + 1);
+ if (cond_edit->add_hbox)
+ cond_edit->add_hbox(new_hbox);
}
static void prefs_filter_action_del_cb(GtkWidget *widget, gpointer data)
diff --git a/src/prefs_filter_edit.h b/src/prefs_filter_edit.h
index fd720fa2..dbc967f3 100644
--- a/src/prefs_filter_edit.h
+++ b/src/prefs_filter_edit.h
@@ -24,6 +24,10 @@
#include "filter.h"
+typedef struct _FilterCondEdit FilterCondEdit;
+typedef struct _CondHBox CondHBox;
+typedef struct _ActionHBox ActionHBox;
+
typedef enum
{
PF_COND_HEADER,
@@ -81,15 +85,18 @@ typedef enum
PF_ACTION_NONE
} ActionMenuType;
-typedef struct _FilterCondEdit {
+struct _FilterCondEdit {
GtkWidget *cond_vbox;
GSList *cond_hbox_list;
GSList *hdr_list;
GSList *rule_hdr_list;
-} FilterCondEdit;
-typedef struct _CondHBox {
+ /* callback */
+ void (*add_hbox) (CondHBox *hbox);
+};
+
+struct _CondHBox {
GtkWidget *hbox;
GtkWidget *cond_type_optmenu;
@@ -107,9 +114,9 @@ typedef struct _CondHBox {
gchar *cur_header_name;
FilterCondEdit *cond_edit;
-} CondHBox;
+};
-typedef struct _ActionHBox {
+struct _ActionHBox {
GtkWidget *hbox;
GtkWidget *action_type_optmenu;
@@ -125,7 +132,7 @@ typedef struct _ActionHBox {
GtkWidget *del_btn;
GtkWidget *add_btn;
-} ActionHBox;
+};
FilterRule *prefs_filter_edit_open (FilterRule *rule,
diff --git a/src/prefs_folder_item.c b/src/prefs_folder_item.c
index fefe44bc..9d777eba 100644
--- a/src/prefs_folder_item.c
+++ b/src/prefs_folder_item.c
@@ -561,6 +561,9 @@ static void prefs_folder_item_apply_cb(GtkWidget *widget,
prev_item = folder->trash;
folder->trash = item;
break;
+ default:
+ type = item->stype;
+ break;
}
item->stype = type;
diff --git a/src/summary_search.c b/src/summary_search.c
index c388944a..d6a76017 100644
--- a/src/summary_search.c
+++ b/src/summary_search.c
@@ -40,69 +40,139 @@
#include <gtk/gtkmenuitem.h>
#include <gtk/gtkstock.h>
#include <gtk/gtktreemodel.h>
+#include <gtk/gtkliststore.h>
+#include <gtk/gtktreeview.h>
#include <gtk/gtktreeselection.h>
+#include <gtk/gtkcellrenderertext.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include "main.h"
#include "summary_search.h"
+#include "prefs_filter_edit.h"
#include "summaryview.h"
#include "messageview.h"
#include "mainwindow.h"
+#include "folderview.h"
#include "menu.h"
#include "utils.h"
#include "gtkutils.h"
#include "manage_window.h"
#include "alertpanel.h"
+#include "foldersel.h"
+#include "procmsg.h"
+#include "procheader.h"
+#include "folder.h"
+#include "filter.h"
+#include "prefs_filter.h"
+#include "prefs_filter_edit.h"
+
+enum
+{
+ COL_FOLDER,
+ COL_SUBJECT,
+ COL_FROM,
+ COL_DATE,
+ COL_MSGINFO,
+ N_COLS
+};
static struct SummarySearchWindow {
GtkWidget *window;
GtkWidget *bool_optmenu;
- GtkWidget *from_entry;
- GtkWidget *to_entry;
- GtkWidget *subject_entry;
- GtkWidget *body_entry;
+ FilterCondEdit *cond_edit;
+
+ GtkWidget *folder_entry;
+ GtkWidget *folder_btn;
+ GtkWidget *subfolder_checkbtn;
GtkWidget *case_checkbtn;
+ GtkWidget *treeview;
+ GtkListStore *store;
+
+ GtkWidget *status_label;
+
GtkWidget *clear_btn;
+ GtkWidget *search_btn;
+ GtkWidget *save_btn;
GtkWidget *close_btn;
- GtkWidget *all_btn;
- GtkWidget *prev_btn;
- GtkWidget *next_btn;
SummaryView *summaryview;
+
+ FilterRule *rule;
+ gboolean requires_full_headers;
+
+ gboolean on_search;
+ gboolean cancelled;
} search_window;
+typedef struct {
+ GtkWidget *window;
+
+ GtkWidget *folder_entry;
+ GtkWidget *name_entry;
+
+ gboolean cancelled;
+ gboolean finished;
+} SummarySearchSaveDialog;
+
static void summary_search_create (void);
-static void summary_search_execute (gboolean backward,
- gboolean search_all);
+static FilterRule *summary_search_dialog_to_rule
+ (const gchar *name,
+ FolderItem **item);
+
+static void summary_search_query (void);
+static void summary_search_folder (FolderItem *item);
+
+static gboolean summary_search_recursive_func (GNode *node,
+ gpointer data);
+
+static void summary_search_append_msg (MsgInfo *msginfo);
+static void summary_search_clear_list (void);
+
+static void summary_search_hbox_added (CondHBox *hbox);
+
+static void row_activated (GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column,
+ gpointer data);
+
+static gboolean row_selected (GtkTreeSelection *selection,
+ GtkTreeModel *model,
+ GtkTreePath *path,
+ gboolean cur_selected,
+ gpointer data);
static void summary_search_clear (GtkButton *button,
gpointer data);
-static void summary_search_prev_clicked (GtkButton *button,
+static void summary_select_folder (GtkButton *button,
+ gpointer data);
+static void summary_search_clicked (GtkButton *button,
gpointer data);
-static void summary_search_next_clicked (GtkButton *button,
+static void summary_search_save (GtkButton *button,
gpointer data);
-static void summary_search_all_clicked (GtkButton *button,
+static void summary_search_close (GtkButton *button,
gpointer data);
-static void from_activated (void);
-static void to_activated (void);
-static void subject_activated (void);
-static void body_activated (void);
+static void summary_search_entry_activated (GtkWidget *widget,
+ gpointer data);
+static gint summary_search_deleted (GtkWidget *widget,
+ GdkEventAny *event,
+ gpointer data);
static gboolean key_pressed (GtkWidget *widget,
GdkEventKey *event,
gpointer data);
-void summary_search(SummaryView *summaryview)
+void summary_search(SummaryView *summaryview, FolderItem *item)
{
+ gchar *id;
+
if (!search_window.window)
summary_search_create();
else
@@ -110,8 +180,14 @@ void summary_search(SummaryView *summaryview)
search_window.summaryview = summaryview;
- gtk_widget_grab_focus(search_window.next_btn);
- gtk_widget_grab_focus(search_window.subject_entry);
+ if (item) {
+ id = folder_item_get_identifier(item);
+ gtk_entry_set_text(GTK_ENTRY(search_window.folder_entry), id);
+ g_free(id);
+ } else
+ gtk_entry_set_text(GTK_ENTRY(search_window.folder_entry), "");
+
+ gtk_widget_grab_focus(search_window.search_btn);
gtk_widget_show(search_window.window);
}
@@ -124,42 +200,51 @@ static void summary_search_create(void)
GtkWidget *bool_menu;
GtkWidget *menuitem;
GtkWidget *clear_btn;
+ GtkWidget *search_btn;
- GtkWidget *table1;
- GtkWidget *from_label;
- GtkWidget *from_entry;
- GtkWidget *to_label;
- GtkWidget *to_entry;
- GtkWidget *subject_label;
- GtkWidget *subject_entry;
- GtkWidget *body_label;
- GtkWidget *body_entry;
+ GtkWidget *scrolledwin;
+ FilterCondEdit *cond_edit;
+ CondHBox *cond_hbox;
+
+ GtkWidget *folder_hbox;
+ GtkWidget *folder_label;
+ GtkWidget *folder_entry;
+ GtkWidget *folder_btn;
GtkWidget *checkbtn_hbox;
+ GtkWidget *subfolder_checkbtn;
GtkWidget *case_checkbtn;
+ GtkWidget *treeview;
+ GtkListStore *store;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *selection;
+
GtkWidget *confirm_area;
+
+ GtkWidget *status_label;
+
+ GtkWidget *hbbox;
+ GtkWidget *save_btn;
GtkWidget *close_btn;
- GtkWidget *all_btn;
- GtkWidget *prev_btn;
- GtkWidget *next_btn;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW (window), _("Search messages"));
- gtk_widget_set_size_request(window, 450, -1);
+ gtk_widget_set_size_request(window, 600, -1);
gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, TRUE);
gtk_container_set_border_width(GTK_CONTAINER (window), 8);
g_signal_connect(G_OBJECT(window), "delete_event",
- G_CALLBACK(gtk_widget_hide_on_delete), NULL);
+ G_CALLBACK(summary_search_deleted), NULL);
g_signal_connect(G_OBJECT(window), "key_press_event",
G_CALLBACK(key_pressed), NULL);
MANAGE_WINDOW_SIGNALS_CONNECT(window);
- vbox1 = gtk_vbox_new (FALSE, 0);
+ vbox1 = gtk_vbox_new (FALSE, 6);
gtk_widget_show (vbox1);
gtk_container_add (GTK_CONTAINER (window), vbox1);
- bool_hbox = gtk_hbox_new(FALSE, 4);
+ bool_hbox = gtk_hbox_new(FALSE, 12);
gtk_widget_show(bool_hbox);
gtk_box_pack_start(GTK_BOX(vbox1), bool_hbox, FALSE, FALSE, 0);
@@ -168,389 +253,778 @@ static void summary_search_create(void)
gtk_box_pack_start(GTK_BOX(bool_hbox), bool_optmenu, FALSE, FALSE, 0);
bool_menu = gtk_menu_new();
- MENUITEM_ADD(bool_menu, menuitem, _("Match any of the following"), 0);
- MENUITEM_ADD(bool_menu, menuitem, _("Match all of the following"), 1);
+ MENUITEM_ADD(bool_menu, menuitem, _("Match any of the following"),
+ FLT_OR);
+ MENUITEM_ADD(bool_menu, menuitem, _("Match all of the following"),
+ FLT_AND);
gtk_option_menu_set_menu(GTK_OPTION_MENU(bool_optmenu), bool_menu);
+ hbbox = gtk_hbutton_box_new();
+ gtk_widget_show(hbbox);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(hbbox), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing(GTK_BOX(hbbox), 6);
+ gtk_box_pack_end(GTK_BOX(bool_hbox), hbbox, FALSE, FALSE, 0);
+
clear_btn = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
gtk_widget_show(clear_btn);
- gtk_box_pack_end(GTK_BOX(bool_hbox), clear_btn, FALSE, FALSE, 0);
-
- table1 = gtk_table_new (4, 3, FALSE);
- gtk_widget_show (table1);
- gtk_box_pack_start (GTK_BOX (vbox1), table1, TRUE, TRUE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (table1), 4);
- gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
- gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
-
- from_entry = gtk_entry_new ();
- gtk_widget_show (from_entry);
- gtk_table_attach (GTK_TABLE (table1), from_entry, 1, 3, 0, 1,
- GTK_EXPAND|GTK_FILL, 0, 0, 0);
- g_signal_connect(G_OBJECT(from_entry), "activate",
- G_CALLBACK(from_activated), NULL);
-
- to_entry = gtk_entry_new ();
- gtk_widget_show (to_entry);
- gtk_table_attach (GTK_TABLE (table1), to_entry, 1, 3, 1, 2,
- GTK_EXPAND|GTK_FILL, 0, 0, 0);
- g_signal_connect(G_OBJECT(to_entry), "activate",
- G_CALLBACK(to_activated), NULL);
-
- subject_entry = gtk_entry_new ();
- gtk_widget_show (subject_entry);
- gtk_table_attach (GTK_TABLE (table1), subject_entry, 1, 3, 2, 3,
- GTK_EXPAND|GTK_FILL, 0, 0, 0);
- g_signal_connect(G_OBJECT(subject_entry), "activate",
- G_CALLBACK(subject_activated), NULL);
-
- body_entry = gtk_entry_new ();
- gtk_widget_show (body_entry);
- gtk_table_attach (GTK_TABLE (table1), body_entry, 1, 3, 3, 4,
- GTK_EXPAND|GTK_FILL, 0, 0, 0);
- g_signal_connect(G_OBJECT(body_entry), "activate",
- G_CALLBACK(body_activated), NULL);
-
- from_label = gtk_label_new (_("From:"));
- gtk_widget_show (from_label);
- gtk_table_attach (GTK_TABLE (table1), from_label, 0, 1, 0, 1,
- GTK_FILL, 0, 0, 0);
- gtk_label_set_justify (GTK_LABEL (from_label), GTK_JUSTIFY_RIGHT);
- gtk_misc_set_alignment (GTK_MISC (from_label), 1, 0.5);
-
- to_label = gtk_label_new (_("To:"));
- gtk_widget_show (to_label);
- gtk_table_attach (GTK_TABLE (table1), to_label, 0, 1, 1, 2,
- GTK_FILL, 0, 0, 0);
- gtk_label_set_justify (GTK_LABEL (to_label), GTK_JUSTIFY_RIGHT);
- gtk_misc_set_alignment (GTK_MISC (to_label), 1, 0.5);
-
- subject_label = gtk_label_new (_("Subject:"));
- gtk_widget_show (subject_label);
- gtk_table_attach (GTK_TABLE (table1), subject_label, 0, 1, 2, 3,
- GTK_FILL, 0, 0, 0);
- gtk_label_set_justify (GTK_LABEL (subject_label), GTK_JUSTIFY_RIGHT);
- gtk_misc_set_alignment (GTK_MISC (subject_label), 1, 0.5);
-
- body_label = gtk_label_new (_("Body:"));
- gtk_widget_show (body_label);
- gtk_table_attach (GTK_TABLE (table1), body_label, 0, 1, 3, 4,
- GTK_FILL, 0, 0, 0);
- gtk_label_set_justify (GTK_LABEL (body_label), GTK_JUSTIFY_RIGHT);
- gtk_misc_set_alignment (GTK_MISC (body_label), 1, 0.5);
-
- checkbtn_hbox = gtk_hbox_new (FALSE, 8);
+ gtk_box_pack_start(GTK_BOX(hbbox), clear_btn, FALSE, FALSE, 0);
+
+ search_btn = gtk_button_new_from_stock(GTK_STOCK_FIND);
+ GTK_WIDGET_SET_FLAGS(search_btn, GTK_CAN_DEFAULT);
+ gtk_widget_show(search_btn);
+ gtk_box_pack_start(GTK_BOX(hbbox), search_btn, FALSE, FALSE, 0);
+ gtk_widget_grab_default(search_btn);
+
+ scrolledwin = gtk_scrolled_window_new(NULL, NULL);
+ gtk_widget_show(scrolledwin);
+ gtk_box_pack_start(GTK_BOX(vbox1), scrolledwin, FALSE, FALSE, 0);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_widget_set_size_request(scrolledwin, -1, 120);
+
+ cond_edit = prefs_filter_edit_cond_edit_create();
+ cond_edit->add_hbox = summary_search_hbox_added;
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolledwin),
+ cond_edit->cond_vbox);
+ prefs_filter_set_header_list(NULL);
+ prefs_filter_edit_set_header_list(cond_edit, NULL);
+ cond_hbox = prefs_filter_edit_cond_hbox_create(cond_edit);
+ prefs_filter_edit_set_cond_hbox_widgets(cond_hbox, PF_COND_HEADER);
+ prefs_filter_edit_insert_cond_hbox(cond_edit, cond_hbox, -1);
+ if (cond_edit->add_hbox)
+ cond_edit->add_hbox(cond_hbox);
+
+ folder_hbox = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (folder_hbox);
+ gtk_box_pack_start (GTK_BOX (vbox1), folder_hbox, FALSE, FALSE, 0);
+
+ folder_label = gtk_label_new (_("Folder:"));
+ gtk_widget_show (folder_label);
+ gtk_box_pack_start (GTK_BOX (folder_hbox), folder_label,
+ FALSE, FALSE, 0);
+
+ folder_entry = gtk_entry_new ();
+ gtk_widget_show (folder_entry);
+ gtk_box_pack_start (GTK_BOX (folder_hbox), folder_entry, TRUE, TRUE, 0);
+
+ folder_btn = gtk_button_new_with_label("...");
+ gtk_widget_show (folder_btn);
+ gtk_box_pack_start (GTK_BOX (folder_hbox), folder_btn, FALSE, FALSE, 0);
+
+ checkbtn_hbox = gtk_hbox_new (FALSE, 12);
gtk_widget_show (checkbtn_hbox);
- gtk_box_pack_start (GTK_BOX (vbox1), checkbtn_hbox, TRUE, TRUE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (checkbtn_hbox), 8);
+ gtk_box_pack_start (GTK_BOX (vbox1), checkbtn_hbox, FALSE, FALSE, 0);
+
+ subfolder_checkbtn =
+ gtk_check_button_new_with_label (_("Search subfolders"));
+ gtk_widget_show (subfolder_checkbtn);
+ gtk_box_pack_start (GTK_BOX (checkbtn_hbox), subfolder_checkbtn,
+ FALSE, FALSE, 0);
case_checkbtn = gtk_check_button_new_with_label (_("Case sensitive"));
gtk_widget_show (case_checkbtn);
gtk_box_pack_start (GTK_BOX (checkbtn_hbox), case_checkbtn,
FALSE, FALSE, 0);
- confirm_area = gtk_hbutton_box_new();
- gtk_widget_show (confirm_area);
- gtk_button_box_set_layout(GTK_BUTTON_BOX(confirm_area),
- GTK_BUTTONBOX_END);
- gtk_box_set_spacing(GTK_BOX(confirm_area), 6);
+ scrolledwin = gtk_scrolled_window_new(NULL, NULL);
+ gtk_box_pack_start(GTK_BOX(vbox1), scrolledwin, TRUE, TRUE, 0);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin),
+ GTK_SHADOW_IN);
+ gtk_widget_set_size_request(scrolledwin, -1, 150);
+
+ store = gtk_list_store_new(N_COLS,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_POINTER);
+ treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+ g_object_unref(store);
+ gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
+ g_signal_connect(G_OBJECT(treeview), "row-activated",
+ G_CALLBACK(row_activated), NULL);
+
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
+ gtk_tree_selection_set_select_function(selection, row_selected,
+ NULL, NULL);
+
+ gtk_container_add(GTK_CONTAINER(scrolledwin), treeview);
+
+#define APPEND_COLUMN(label, col, width) \
+{ \
+ renderer = gtk_cell_renderer_text_new(); \
+ column = gtk_tree_view_column_new_with_attributes \
+ (label, renderer, "text", col, NULL); \
+ gtk_tree_view_column_set_resizable(column, TRUE); \
+ if (width) { \
+ gtk_tree_view_column_set_sizing \
+ (column, GTK_TREE_VIEW_COLUMN_FIXED); \
+ gtk_tree_view_column_set_fixed_width(column, width); \
+ } \
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); \
+}
- close_btn = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
- GTK_WIDGET_SET_FLAGS(close_btn, GTK_CAN_DEFAULT);
- gtk_box_pack_start(GTK_BOX(confirm_area), close_btn, TRUE, TRUE, 0);
- gtk_widget_show(close_btn);
+ APPEND_COLUMN(_("Folder"), COL_FOLDER, 0);
+ APPEND_COLUMN(_("Subject"), COL_SUBJECT, 200);
+ APPEND_COLUMN(_("From"), COL_FROM, 180);
+ APPEND_COLUMN(_("Date"), COL_DATE, 0);
+
+ gtk_widget_show_all(scrolledwin);
- all_btn = gtk_button_new_from_stock(_("Find all"));
- GTK_WIDGET_SET_FLAGS(all_btn, GTK_CAN_DEFAULT);
- gtk_box_pack_start(GTK_BOX(confirm_area), all_btn, TRUE, TRUE, 0);
- gtk_widget_show(all_btn);
+ confirm_area = gtk_hbox_new(FALSE, 12);
+ gtk_widget_show(confirm_area);
+ gtk_box_pack_start(GTK_BOX(vbox1), confirm_area, FALSE, FALSE, 0);
- prev_btn = gtk_button_new_from_stock(GTK_STOCK_GO_BACK);
- GTK_WIDGET_SET_FLAGS(prev_btn, GTK_CAN_DEFAULT);
- gtk_box_pack_start(GTK_BOX(confirm_area), prev_btn, TRUE, TRUE, 0);
- gtk_widget_show(prev_btn);
+ status_label = gtk_label_new("");
+ gtk_widget_show(status_label);
+ gtk_box_pack_start(GTK_BOX(confirm_area), status_label,
+ FALSE, FALSE, 0);
- next_btn = gtk_button_new_from_stock(GTK_STOCK_GO_FORWARD);
- GTK_WIDGET_SET_FLAGS(next_btn, GTK_CAN_DEFAULT);
- gtk_box_pack_start(GTK_BOX(confirm_area), next_btn, TRUE, TRUE, 0);
- gtk_widget_show(next_btn);
+ hbbox = gtk_hbutton_box_new();
+ gtk_widget_show(hbbox);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(hbbox), GTK_BUTTONBOX_END);
+ gtk_box_set_spacing(GTK_BOX(hbbox), 6);
+ gtk_box_pack_end(GTK_BOX(confirm_area), hbbox, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (vbox1), confirm_area, FALSE, FALSE, 0);
- gtk_widget_grab_default(next_btn);
+ save_btn = gtk_button_new_with_mnemonic(_("_Save as search folder"));
+ gtk_box_pack_start(GTK_BOX(hbbox), save_btn, FALSE, FALSE, 0);
+ gtk_widget_show(save_btn);
+
+ close_btn = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
+ GTK_WIDGET_SET_FLAGS(close_btn, GTK_CAN_DEFAULT);
+ gtk_box_pack_start(GTK_BOX(hbbox), close_btn, FALSE, FALSE, 0);
+ gtk_widget_show(close_btn);
g_signal_connect(G_OBJECT(clear_btn), "clicked",
G_CALLBACK(summary_search_clear), NULL);
- g_signal_connect(G_OBJECT(all_btn), "clicked",
- G_CALLBACK(summary_search_all_clicked), NULL);
- g_signal_connect(G_OBJECT(prev_btn), "clicked",
- G_CALLBACK(summary_search_prev_clicked), NULL);
- g_signal_connect(G_OBJECT(next_btn), "clicked",
- G_CALLBACK(summary_search_next_clicked), NULL);
- g_signal_connect_closure
- (G_OBJECT(close_btn), "clicked",
- g_cclosure_new_swap(G_CALLBACK(gtk_widget_hide),
- window, NULL),
- FALSE);
+ g_signal_connect(G_OBJECT(folder_btn), "clicked",
+ G_CALLBACK(summary_select_folder), NULL);
+ g_signal_connect(G_OBJECT(search_btn), "clicked",
+ G_CALLBACK(summary_search_clicked), NULL);
+ g_signal_connect(G_OBJECT(save_btn), "clicked",
+ G_CALLBACK(summary_search_save), NULL);
+ g_signal_connect(G_OBJECT(close_btn), "clicked",
+ G_CALLBACK(summary_search_close), NULL);
search_window.window = window;
search_window.bool_optmenu = bool_optmenu;
- search_window.from_entry = from_entry;
- search_window.to_entry = to_entry;
- search_window.subject_entry = subject_entry;
- search_window.body_entry = body_entry;
+
+ search_window.cond_edit = cond_edit;
+
+ search_window.folder_entry = folder_entry;
+ search_window.folder_btn = folder_btn;
+ search_window.subfolder_checkbtn = subfolder_checkbtn;
search_window.case_checkbtn = case_checkbtn;
+
+ search_window.treeview = treeview;
+ search_window.store = store;
+
+ search_window.status_label = status_label;
+
search_window.clear_btn = clear_btn;
+ search_window.search_btn = search_btn;
+ search_window.save_btn = save_btn;
search_window.close_btn = close_btn;
- search_window.all_btn = all_btn;
- search_window.prev_btn = prev_btn;
- search_window.next_btn = next_btn;
}
-static void summary_search_execute(gboolean backward, gboolean search_all)
+static FilterRule *summary_search_dialog_to_rule(const gchar *name,
+ FolderItem **item)
{
- SummaryView *summaryview = search_window.summaryview;
- GtkTreeModel *model;
- GtkTreeIter iter;
- MsgInfo *msginfo;
- gboolean bool_and;
+ const gchar *id;
+ FolderItem *item_;
+ FilterBoolOp bool_op = FLT_OR;
+ gboolean recursive;
gboolean case_sens;
- gboolean all_searched = FALSE;
- gboolean matched;
- gboolean body_matched;
- const gchar *from_str, *to_str, *subject_str, *body_str;
- StrFindFunc str_find_func;
- gboolean valid;
-
- if (summary_is_locked(summaryview)) return;
- summary_lock(summaryview);
-
- model = GTK_TREE_MODEL(summaryview->store);
-
- bool_and = menu_get_option_menu_active_index
+ GSList *cond_list = NULL;
+ FilterCond *cond;
+ FilterRule *rule;
+ GSList *cur;
+
+ id = gtk_entry_get_text(GTK_ENTRY(search_window.folder_entry));
+ item_ = folder_find_item_from_identifier(id);
+ if (!item_)
+ return NULL;
+ if (item)
+ *item = item_;
+
+ bool_op = menu_get_option_menu_active_index
(GTK_OPTION_MENU(search_window.bool_optmenu));
+ recursive = gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(search_window.subfolder_checkbtn));
case_sens = gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON(search_window.case_checkbtn));
- if (case_sens)
- str_find_func = str_find;
- else
- str_find_func = str_case_find;
-
- from_str = gtk_entry_get_text(GTK_ENTRY(search_window.from_entry));
- to_str = gtk_entry_get_text(GTK_ENTRY(search_window.to_entry));
- subject_str = gtk_entry_get_text(GTK_ENTRY(search_window.subject_entry));
- body_str = gtk_entry_get_text(GTK_ENTRY(search_window.body_entry));
-
- if (search_all) {
- summary_unselect_all(summaryview);
- valid = gtk_tree_model_get_iter_first(model, &iter);
- backward = FALSE;
- } else if (!summaryview->selected) {
- if (backward)
- valid = gtkut_tree_model_get_iter_last(model, &iter);
- else
- valid = gtk_tree_model_get_iter_first(model, &iter);
- if (!valid) {
- summary_unlock(summaryview);
- return;
- }
- } else {
- valid = gtkut_tree_row_reference_get_iter
- (model, summaryview->selected, &iter);
- if (!valid) {
- summary_unlock(summaryview);
- return;
+ for (cur = search_window.cond_edit->cond_hbox_list; cur != NULL;
+ cur = cur->next) {
+ CondHBox *hbox = (CondHBox *)cur->data;
+ gchar *error_msg;
+
+ cond = prefs_filter_edit_cond_hbox_to_cond(hbox, case_sens,
+ &error_msg);
+ if (cond) {
+ cond_list = g_slist_append(cond_list, cond);
+ } else {
+ if (!error_msg)
+ error_msg = _("Invalid condition exists.");
+ alertpanel_error("%s", error_msg);
+ filter_cond_list_free(cond_list);
+ return NULL;
}
+ }
- if (backward)
- valid = gtkut_tree_model_prev(model, &iter);
- else
- valid = gtkut_tree_model_next(model, &iter);
+ if (!cond_list)
+ return NULL;
+
+ rule = filter_rule_new(name, bool_op, cond_list, NULL);
+ rule->target_folder = g_strdup(id);
+ rule->recursive = recursive;
+
+ return rule;
+}
+
+static void summary_search_query(void)
+{
+ FolderItem *item;
+
+ if (search_window.on_search)
+ return;
+
+ search_window.on_search = TRUE;
+
+ search_window.rule = summary_search_dialog_to_rule("Query rule", &item);
+ if (!search_window.rule) {
+ search_window.on_search = FALSE;
+ return;
}
+ search_window.requires_full_headers =
+ filter_rule_requires_full_headers(search_window.rule);
- if (*body_str)
- main_window_cursor_wait(summaryview->mainwin);
+ search_window.cancelled = FALSE;
- for (;;) {
- if (!valid) {
- gchar *str;
- AlertValue val;
+ gtk_button_set_label(GTK_BUTTON(search_window.search_btn),
+ GTK_STOCK_STOP);
+ summary_search_clear_list();
- if (search_all) {
- break;
- }
+ if (search_window.rule->recursive)
+ g_node_traverse(item->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
+ summary_search_recursive_func, NULL);
+ else
+ summary_search_folder(item);
- if (all_searched) {
- alertpanel_message
- (_("Search failed"),
- _("Search string not found."),
- ALERT_WARNING);
- break;
- }
+ filter_rule_free(search_window.rule);
+ search_window.rule = NULL;
+ search_window.requires_full_headers = FALSE;
- if (backward)
- str = _("Beginning of list reached; continue from end?");
- else
- str = _("End of list reached; continue from beginning?");
-
- val = alertpanel(_("Search finished"), str,
- GTK_STOCK_YES, GTK_STOCK_NO, NULL);
- if (G_ALERTDEFAULT == val) {
- if (backward)
- valid = gtkut_tree_model_get_iter_last
- (model, &iter);
- else
- valid = gtk_tree_model_get_iter_first
- (model, &iter);
- all_searched = TRUE;
- manage_window_focus_in(search_window.window,
- NULL, NULL);
- } else
- break;
- }
+ gtk_button_set_label(GTK_BUTTON(search_window.search_btn),
+ GTK_STOCK_FIND);
+ gtk_label_set_text(GTK_LABEL(search_window.status_label), _("Done."));
- gtk_tree_model_get(model, &iter, S_COL_MSG_INFO, &msginfo, -1);
- body_matched = FALSE;
+ if (search_window.cancelled)
+ debug_print("* query search cancelled.\n");
+ debug_print("query search finished.\n");
- if (bool_and) {
- matched = TRUE;
- if (*from_str) {
- if (!msginfo->from ||
- !str_find_func(msginfo->from, from_str))
- matched = FALSE;
- }
- if (matched && *to_str) {
- if (!msginfo->to ||
- !str_find_func(msginfo->to, to_str))
- matched = FALSE;
- }
- if (matched && *subject_str) {
- if (!msginfo->subject ||
- !str_find_func(msginfo->subject, subject_str))
- matched = FALSE;
- }
- if (matched && *body_str) {
- if (procmime_find_string(msginfo, body_str,
- str_find_func))
- body_matched = TRUE;
- else
- matched = FALSE;
- }
- if (matched && !*from_str && !*to_str &&
- !*subject_str && !*body_str)
- matched = FALSE;
- } else {
- matched = FALSE;
- if (*from_str && msginfo->from) {
- if (str_find_func(msginfo->from, from_str))
- matched = TRUE;
- }
- if (!matched && *to_str && msginfo->to) {
- if (str_find_func(msginfo->to, to_str))
- matched = TRUE;
- }
- if (!matched && *subject_str && msginfo->subject) {
- if (str_find_func(msginfo->subject, subject_str))
- matched = TRUE;
- }
- if (!matched && *body_str) {
- if (procmime_find_string(msginfo, body_str,
- str_find_func)) {
- matched = TRUE;
- body_matched = TRUE;
- }
- }
- }
+ search_window.on_search = FALSE;
+ search_window.cancelled = FALSE;
+}
- if (matched) {
- if (search_all) {
- gtk_tree_selection_select_iter
- (summaryview->selection, &iter);
- } else {
- if (messageview_is_visible
- (summaryview->messageview)) {
- summary_unlock(summaryview);
- summary_select_row
- (summaryview, &iter,
- TRUE, TRUE);
- summary_lock(summaryview);
- if (body_matched) {
- messageview_search_string
- (summaryview->messageview,
- body_str, case_sens);
- }
- } else {
- summary_select_row
- (summaryview, &iter,
- FALSE, TRUE);
- }
- break;
- }
+static void summary_search_folder(FolderItem *item)
+{
+ gchar *folder_name, *str;
+ GSList *mlist;
+ FilterInfo fltinfo;
+ GSList *cur;
+ gint count = 1, total;
+ GTimeVal tv_prev, tv_cur;
+
+ if (!item->path)
+ return;
+
+ folder_name = g_path_get_basename(item->path);
+ str = g_strdup_printf(_("Searching %s ..."), folder_name);
+ gtk_label_set_text(GTK_LABEL(search_window.status_label), str);
+ g_free(str);
+ g_get_current_time(&tv_prev);
+ ui_update();
+
+ if (search_window.cancelled) {
+ g_free(folder_name);
+ return;
+ }
+
+ mlist = folder_item_get_msg_list(item, TRUE);
+ total = g_slist_length(mlist);
+
+ memset(&fltinfo, 0, sizeof(FilterInfo));
+
+ debug_print("requires_full_headers: %d\n",
+ search_window.requires_full_headers);
+ debug_print("start query search: %s\n", item->path ? item->path : "");
+
+ for (cur = mlist; cur != NULL; cur = cur->next) {
+ MsgInfo *msginfo = (MsgInfo *)cur->data;
+ GSList *hlist;
+
+ g_get_current_time(&tv_cur);
+ if (tv_cur.tv_sec > tv_prev.tv_sec ||
+ tv_cur.tv_usec - tv_prev.tv_usec >
+ PROGRESS_UPDATE_INTERVAL * 1000) {
+ str = g_strdup_printf(_("Searching %s (%d / %d)..."),
+ folder_name, count, total);
+ gtk_label_set_text
+ (GTK_LABEL(search_window.status_label), str);
+ g_free(str);
+ ui_update();
+ tv_prev = tv_cur;
+ }
+ ++count;
+
+ if (search_window.cancelled)
+ break;
+
+ fltinfo.flags = msginfo->flags;
+ if (search_window.requires_full_headers) {
+ gchar *file;
+
+ file = procmsg_get_message_file(msginfo);
+ hlist = procheader_get_header_list_from_file(file);
+ g_free(file);
+ } else
+ hlist = procheader_get_header_list_from_msginfo
+ (msginfo);
+ if (!hlist)
+ continue;
+
+ if (filter_match_rule(search_window.rule, msginfo, hlist,
+ &fltinfo)) {
+ summary_search_append_msg(msginfo);
+ cur->data = NULL;
}
- if (backward)
- valid = gtkut_tree_model_prev(model, &iter);
- else
- valid = gtkut_tree_model_next(model, &iter);
+ procheader_header_list_destroy(hlist);
}
- if (*body_str)
- main_window_cursor_normal(summaryview->mainwin);
+ procmsg_msg_list_free(mlist);
+ g_free(folder_name);
+}
- summary_unlock(summaryview);
+static gboolean summary_search_recursive_func(GNode *node, gpointer data)
+{
+ FolderItem *item;
+
+ g_return_val_if_fail(node->data != NULL, FALSE);
+
+ item = FOLDER_ITEM(node->data);
+
+ if (!item->path)
+ return FALSE;
+
+ summary_search_folder(item);
+
+ if (search_window.cancelled)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void summary_search_append_msg(MsgInfo *msginfo)
+{
+ GtkListStore *store = search_window.store;
+ GtkTreeIter iter;
+ gchar *folder;
+ gchar date_buf[80];
+ const gchar *subject, *from, *date;
+ gchar *id;
+
+ id = folder_item_get_identifier(msginfo->folder);
+ folder = g_path_get_basename(id);
+ g_free(id);
+ subject = msginfo->subject ? msginfo->subject : _("(No Subject)");
+ from = msginfo->from ? msginfo->from : _("(No From)");
+ if (msginfo->date_t) {
+ procheader_date_get_localtime(date_buf, sizeof(date_buf),
+ msginfo->date_t);
+ date = date_buf;
+ } else if (msginfo->date)
+ date = msginfo->date;
+ else
+ date = _("(No Date)");
+
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ COL_FOLDER, folder,
+ COL_SUBJECT, subject,
+ COL_FROM, from,
+ COL_DATE, date,
+ COL_MSGINFO, msginfo,
+ -1);
+
+ g_free(folder);
+}
+
+static void summary_search_clear_list(void)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model = GTK_TREE_MODEL(search_window.store);
+ MsgInfo *msginfo;
+
+ if (!gtk_tree_model_get_iter_first(model, &iter))
+ return;
+
+ do {
+ gtk_tree_model_get(model, &iter, COL_MSGINFO, &msginfo, -1);
+ procmsg_msginfo_free(msginfo);
+ } while (gtk_tree_model_iter_next(model, &iter));
+
+ gtk_list_store_clear(search_window.store);
+}
+
+static void summary_search_hbox_added(CondHBox *hbox)
+{
+ g_signal_connect(hbox->key_entry, "activate",
+ G_CALLBACK(summary_search_entry_activated), NULL);
+}
+
+static void row_activated(GtkTreeView *treeview, GtkTreePath *path,
+ GtkTreeViewColumn *column, gpointer data)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model = GTK_TREE_MODEL(search_window.store);
+ MsgInfo *msginfo;
+ MessageView *msgview;
+
+ if (!gtk_tree_model_get_iter(model, &iter, path))
+ return;
+
+ gtk_tree_model_get(model, &iter, COL_MSGINFO, &msginfo, -1);
+ msgview = messageview_create_with_new_window();
+ messageview_show(msgview, msginfo, FALSE);
+}
+
+static gboolean row_selected(GtkTreeSelection *selection,
+ GtkTreeModel *model, GtkTreePath *path,
+ gboolean cur_selected, gpointer data)
+{
+ return TRUE;
}
static void summary_search_clear(GtkButton *button, gpointer data)
{
- gtk_editable_delete_text(GTK_EDITABLE(search_window.from_entry),
- 0, -1);
- gtk_editable_delete_text(GTK_EDITABLE(search_window.to_entry),
- 0, -1);
- gtk_editable_delete_text(GTK_EDITABLE(search_window.subject_entry),
- 0, -1);
- gtk_editable_delete_text(GTK_EDITABLE(search_window.body_entry),
- 0, -1);
+ CondHBox *cond_hbox;
+
+ prefs_filter_edit_clear_cond_edit(search_window.cond_edit);
+ prefs_filter_set_header_list(NULL);
+ prefs_filter_edit_set_header_list(search_window.cond_edit, NULL);
+ cond_hbox = prefs_filter_edit_cond_hbox_create(search_window.cond_edit);
+ prefs_filter_edit_set_cond_hbox_widgets(cond_hbox, PF_COND_HEADER);
+ prefs_filter_edit_insert_cond_hbox
+ (search_window.cond_edit, cond_hbox, -1);
+ if (search_window.cond_edit->add_hbox)
+ search_window.cond_edit->add_hbox(cond_hbox);
+
+ gtk_label_set_text(GTK_LABEL(search_window.status_label), "");
+
+ summary_search_clear_list();
}
-static void summary_search_prev_clicked(GtkButton *button, gpointer data)
+static void summary_select_folder(GtkButton *button, gpointer data)
{
- summary_search_execute(TRUE, FALSE);
+ FolderItem *item;
+ gchar *id;
+
+ item = foldersel_folder_sel(NULL, FOLDER_SEL_ALL, NULL);
+ if (!item)
+ return;
+
+ id = folder_item_get_identifier(item);
+ if (id) {
+ gtk_entry_set_text(GTK_ENTRY(search_window.folder_entry), id);
+ g_free(id);
+ }
}
-static void summary_search_next_clicked(GtkButton *button, gpointer data)
+static void summary_search_clicked(GtkButton *button, gpointer data)
{
- summary_search_execute(FALSE, FALSE);
+ if (search_window.on_search)
+ search_window.cancelled = TRUE;
+ else
+ summary_search_query();
}
-static void summary_search_all_clicked(GtkButton *button, gpointer data)
+static gint summary_search_save_dialog_deleted(GtkWidget *widget,
+ GdkEventAny *event,
+ gpointer data)
{
- summary_search_execute(FALSE, TRUE);
+ SummarySearchSaveDialog *dialog = (SummarySearchSaveDialog *)data;
+
+ dialog->cancelled = TRUE;
+ dialog->finished = TRUE;
+ return TRUE;
}
-static void from_activated(void)
+static gint summary_search_save_dialog_key_pressed(GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data)
{
- gtk_widget_grab_focus(search_window.to_entry);
+ SummarySearchSaveDialog *dialog = (SummarySearchSaveDialog *)data;
+
+ if (event && event->keyval == GDK_Escape) {
+ dialog->cancelled = TRUE;
+ dialog->finished = TRUE;
+ }
+ return FALSE;
}
-static void to_activated(void)
+static void summary_search_save_dialog_select_folder(GtkButton *button,
+ gpointer data)
{
- gtk_widget_grab_focus(search_window.subject_entry);
+ SummarySearchSaveDialog *dialog = (SummarySearchSaveDialog *)data;
+ FolderItem *item;
+ gchar *id;
+
+ item = foldersel_folder_sel(NULL, FOLDER_SEL_ALL, NULL);
+ if (!item)
+ return;
+
+ id = folder_item_get_identifier(item);
+ if (id) {
+ gtk_entry_set_text(GTK_ENTRY(dialog->folder_entry), id);
+ g_free(id);
+ }
}
-static void subject_activated(void)
+static void summary_search_save_ok(GtkButton *button, gpointer data)
{
- gtk_button_clicked(GTK_BUTTON(search_window.next_btn));
+ SummarySearchSaveDialog *dialog = (SummarySearchSaveDialog *)data;
+
+ dialog->finished = TRUE;
}
-static void body_activated(void)
+static void summary_search_save_cancel(GtkButton *button, gpointer data)
{
- gtk_button_clicked(GTK_BUTTON(search_window.next_btn));
+ SummarySearchSaveDialog *dialog = (SummarySearchSaveDialog *)data;
+
+ dialog->cancelled = TRUE;
+ dialog->finished = TRUE;
+}
+
+static SummarySearchSaveDialog *summary_search_save_dialog_create(void)
+{
+ SummarySearchSaveDialog *dialog;
+ GtkWidget *window;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *label;
+ GtkWidget *folder_entry;
+ GtkWidget *folder_btn;
+ GtkWidget *name_entry;
+
+ GtkWidget *confirm_area;
+ GtkWidget *hbbox;
+ GtkWidget *cancel_btn;
+ GtkWidget *ok_btn;
+
+ dialog = g_new0(SummarySearchSaveDialog, 1);
+
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(window), _("Save as search folder"));
+ gtk_widget_set_size_request(window, 400, -1);
+ gtk_container_set_border_width(GTK_CONTAINER(window), 8);
+ gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+ gtk_window_set_modal(GTK_WINDOW(window), TRUE);
+ gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);
+ g_signal_connect(G_OBJECT(window), "delete_event",
+ G_CALLBACK(summary_search_save_dialog_deleted),
+ dialog);
+ g_signal_connect(G_OBJECT(window), "key_press_event",
+ G_CALLBACK(summary_search_save_dialog_key_pressed),
+ dialog);
+ MANAGE_WINDOW_SIGNALS_CONNECT(window);
+ manage_window_set_transient(GTK_WINDOW(window));
+
+ vbox = gtk_vbox_new(FALSE, 8);
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+
+ hbox = gtk_hbox_new(FALSE, 8);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
+ label = gtk_label_new(_("Location:"));
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ folder_entry = gtk_entry_new();
+ gtk_box_pack_start(GTK_BOX(hbox), folder_entry, TRUE, TRUE, 0);
+
+ folder_btn = gtk_button_new_with_label("...");
+ gtk_box_pack_start(GTK_BOX(hbox), folder_btn, FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(folder_btn), "clicked",
+ G_CALLBACK(summary_search_save_dialog_select_folder),
+ dialog);
+
+ hbox = gtk_hbox_new(FALSE, 8);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+
+ label = gtk_label_new(_("Folder name:"));
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ name_entry = gtk_entry_new();
+ gtk_box_pack_start(GTK_BOX(hbox), name_entry, TRUE, TRUE, 0);
+
+ confirm_area = gtk_hbox_new(FALSE, 12);
+ gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
+
+ gtkut_stock_button_set_create(&hbbox,
+ &ok_btn, GTK_STOCK_OK,
+ &cancel_btn, GTK_STOCK_CANCEL,
+ NULL, NULL);
+ gtk_box_pack_end(GTK_BOX(confirm_area), hbbox, FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(ok_btn), "clicked",
+ G_CALLBACK(summary_search_save_ok), dialog);
+ g_signal_connect(G_OBJECT(cancel_btn), "clicked",
+ G_CALLBACK(summary_search_save_cancel), dialog);
+
+ gtk_widget_show_all(window);
+
+ dialog->window = window;
+ dialog->folder_entry = folder_entry;
+ dialog->name_entry = name_entry;
+ dialog->cancelled = FALSE;
+ dialog->finished = FALSE;
+
+ return dialog;
+}
+
+static void summary_search_save_dialog_destroy(SummarySearchSaveDialog *dialog)
+{
+ gtk_widget_destroy(dialog->window);
+ g_free(dialog);
+}
+
+static FolderItem *summary_search_create_vfolder(FolderItem *parent,
+ const gchar *name)
+{
+ gchar *path;
+ gchar *fs_name;
+ gchar *fullpath;
+ FolderItem *item;
+
+ g_return_val_if_fail(parent != NULL, NULL);
+ g_return_val_if_fail(name != NULL, NULL);
+
+ path = folder_item_get_path(parent);
+ fs_name = g_filename_from_utf8(name, -1, NULL, NULL, NULL);
+ fullpath = g_strconcat(path, G_DIR_SEPARATOR_S,
+ fs_name ? fs_name : name, NULL);
+ g_free(fs_name);
+ g_free(path);
+
+ if (make_dir_hier(fullpath) < 0) {
+ g_free(fullpath);
+ return NULL;
+ }
+
+ if (parent->path)
+ path = g_strconcat(parent->path, G_DIR_SEPARATOR_S, name, NULL);
+ else
+ path = g_strdup(name);
+
+ item = folder_item_new(name, path);
+ item->stype = F_VIRTUAL;
+ folder_item_append(parent, item);
+
+ g_free(path);
+
+ return item;
+}
+
+static void summary_search_vfolder_update_rule(FolderItem *item)
+{
+ GSList list;
+ FilterRule *rule;
+ gchar *file;
+ gchar *path;
+
+ rule = summary_search_dialog_to_rule(item->name, NULL);
+ list.data = rule;
+ list.next = NULL;
+
+ path = folder_item_get_path(item);
+ file = g_strconcat(path, G_DIR_SEPARATOR_S, FILTER_LIST, NULL);
+ filter_write_file(&list, file);
+ g_free(file);
+ g_free(path);
+
+ filter_rule_free(rule);
+}
+
+static void summary_search_save(GtkButton *button, gpointer data)
+{
+ SummarySearchSaveDialog *dialog;
+
+ dialog = summary_search_save_dialog_create();
+
+ while (!dialog->finished)
+ gtk_main_iteration();
+
+ if (!dialog->cancelled) {
+ const gchar *id, *name;
+ FolderItem *parent, *item;
+
+ id = gtk_entry_get_text(GTK_ENTRY(dialog->folder_entry));
+ parent = folder_find_item_from_identifier(id);
+ name = gtk_entry_get_text(GTK_ENTRY(dialog->name_entry));
+ if (parent && name && *name) {
+ if (folder_find_child_item_by_name(parent, name)) {
+ alertpanel_error
+ (_("The folder `%s' already exists."),
+ name);
+ } else {
+ item = summary_search_create_vfolder
+ (parent, name);
+ if (item) {
+ summary_search_vfolder_update_rule
+ (item);
+ folderview_append_item(folderview_get(),
+ NULL, item,
+ TRUE);
+ folder_write_list();
+ }
+ }
+ }
+ }
+
+ summary_search_save_dialog_destroy(dialog);
+}
+
+static void summary_search_close(GtkButton *button, gpointer data)
+{
+ if (search_window.on_search)
+ search_window.cancelled = TRUE;
+ gtk_widget_hide(search_window.window);
+}
+
+static void summary_search_entry_activated(GtkWidget *widget, gpointer data)
+{
+ gtk_button_clicked(GTK_BUTTON(search_window.search_btn));
+}
+
+static gint summary_search_deleted(GtkWidget *widget, GdkEventAny *event,
+ gpointer data)
+{
+ gtk_button_clicked(GTK_BUTTON(search_window.close_btn));
+ return TRUE;
}
static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event,
gpointer data)
{
- if (event && event->keyval == GDK_Escape)
- gtk_widget_hide(search_window.window);
+ if (event && event->keyval == GDK_Escape) {
+ if (search_window.on_search)
+ gtk_button_clicked
+ (GTK_BUTTON(search_window.search_btn));
+ else
+ gtk_button_clicked(GTK_BUTTON(search_window.close_btn));
+ return TRUE;
+ }
return FALSE;
}
diff --git a/src/summary_search.h b/src/summary_search.h
index 8e3fcc0c..2b0d3cc6 100644
--- a/src/summary_search.h
+++ b/src/summary_search.h
@@ -23,7 +23,9 @@
#include <glib.h>
#include "summaryview.h"
+#include "folder.h"
-void summary_search (SummaryView *summaryview);
+void summary_search (SummaryView *summaryview,
+ FolderItem *item);
#endif /* __SUMMARY_SEARCH_H__ */
diff --git a/src/summaryview.c b/src/summaryview.c
index 498d965e..214c735d 100644
--- a/src/summaryview.c
+++ b/src/summaryview.c
@@ -649,7 +649,7 @@ gboolean summary_show(SummaryView *summaryview, FolderItem *item,
buf = NULL;
if (!item || !item->path || !item->parent || item->no_select ||
- (FOLDER_TYPE(item->folder) == F_MH &&
+ (FOLDER_TYPE(item->folder) == F_MH && item->stype != F_VIRTUAL &&
((buf = folder_item_get_path(item)) == NULL ||
change_dir(buf) < 0))) {
g_free(buf);