aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog44
-rw-r--r--mail/Makefile.am2
-rw-r--r--mail/folder-browser-factory.c15
-rw-r--r--mail/folder-browser.c114
-rw-r--r--mail/folder-browser.h3
-rw-r--r--mail/mail-autofilter.c4
-rw-r--r--mail/mail-callbacks.c2
-rw-r--r--mail/mail-format.c5
-rw-r--r--mail/mail-ops.c2
-rw-r--r--mail/mail-vfolder.c21
-rw-r--r--mail/message-list.c57
-rw-r--r--mail/message-list.h2
12 files changed, 221 insertions, 50 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 42e30b5e00..c78fdbf918 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,46 @@
+2000-10-06 Not Zed <NotZed@HelixCode.com>
+
+ * mail-search-dialogue.c: New widget, full search dialogue for
+ mail.
+
+ * folder-browser.c (search_set): If we click on custom search, run
+ the full search dialogue.
+ (folder_browser_gui_init): Add a button to perform a full search.
+ (search_full): Bring up the mail search dialogue asynchronously.
+ (search_full_clicked): Handle search options.
+ (folder_browser_destroy): Free the saved rule if there is one
+ there.
+ (search_options[]): Added a custom option option - brings up the
+ full search dialogue.
+ (search_set): Disable the search entry if we are doing a full
+ search.
+
+ * mail-vfolder.c (vfolder_create_storage): Yay, finally
+ depeterised this stuff.
+ (vfolder_uri_to_folder): Removed an irrelevant comment.
+
+ * mail-callbacks.c (filter_edit): And here.
+
+ * mail-ops.c (do_fetch_mail): And here too.
+
+ * mail-autofilter.c (filter_gui_add_from_message): Fixed call to
+ context_load.
+ (filter_gui_add_for_mailing_list): And here too.
+
+ * folder-browser-factory.c (create_ondemand_hooks): Remove that
+ ondemand callback snot.
+
+2000-10-05 Not Zed <NotZed@HelixCode.com>
+
+ * message-list.c (message_list_init_etable): Build the etable once
+ we know what folder we are going to use.
+ (save_header_state): Save the header spec to a cache file.
+ (message_list_destroy): Save the header spec.
+ (message_list_setup_etable): Setup the etable spec for this
+ folder, from a saved version if one exists, or to suit the folder
+ type (sent/received).
+ (message_list_set_folder): Setup the etable here once we have a folder.
+
2000-10-09 Michael Meeks <michael@helixcode.com>
* message-list.c (message_list_toggle_threads): re-write.
@@ -146,6 +189,7 @@
* mail-ops.c (do_scan_subfolders): Don't try to add_folders if
get_folder_info returned NULL.
+>>>>>>> 1.611
2000-10-04 Not Zed <NotZed@HelixCode.com>
* message-list.c (message_list_init_header): Fix the attachment
diff --git a/mail/Makefile.am b/mail/Makefile.am
index eaefe9f32b..fb68f7a7b0 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -65,6 +65,8 @@ evolution_mail_SOURCES = \
mail-mlist-magic.h \
mail-ops.c \
mail-ops.h \
+ mail-search-dialogue.c \
+ mail-search-dialogue.h \
mail-summary.c \
mail-summary.h \
mail-threads.c \
diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c
index 7f590465ea..1bc493b381 100644
--- a/mail/folder-browser-factory.c
+++ b/mail/folder-browser-factory.c
@@ -32,10 +32,8 @@
static GList *control_list = NULL;
static void
-register_ondemand (RuleContext *f, FilterRule *rule, gpointer data)
+register_ondemand (RuleContext *f, FilterRule *rule, FolderBrowser *fb, BonoboUIComponent *uic)
{
- FolderBrowser *fb = FOLDER_BROWSER (data);
- BonoboUIComponent *uic = gtk_object_get_data (GTK_OBJECT (fb), "uih");
BonoboUIHandler *uih;
gchar *text;
struct fb_ondemand_closure *oc;
@@ -67,14 +65,15 @@ static void
create_ondemand_hooks (FolderBrowser *fb, BonoboUIComponent *uic)
{
gchar *system, *user;
-
+ FilterRule *rule = NULL;
+
user = g_strdup_printf ("%s/filters.xml", evolution_dir);
system = EVOLUTION_DATADIR "/evolution/filtertypes.xml";
fb->filter_context = filter_context_new();
- gtk_object_set_data (GTK_OBJECT (fb), "uih", uic);
- rule_context_load ((RuleContext *) fb->filter_context, system, user,
- register_ondemand, fb);
- gtk_object_remove_data (GTK_OBJECT (fb), "uih");
+ rule_context_load ((RuleContext *) fb->filter_context, system, user);
+ while ( (rule = rule_context_next_rule((RuleContext *)fb->filter_context, rule)) != NULL ) {
+ register_ondemand((RuleContext *)fb->filter_context, rule, fb, uic);
+ }
g_free (user);
}
diff --git a/mail/folder-browser.c b/mail/folder-browser.c
index 6530929b42..9518ff8e7b 100644
--- a/mail/folder-browser.c
+++ b/mail/folder-browser.c
@@ -27,6 +27,8 @@
#include "filter/filter-option.h"
#include "filter/filter-input.h"
+#include "mail-search-dialogue.h"
+
#include "mail-local.h"
#include "mail-config.h"
@@ -53,12 +55,14 @@ folder_browser_destroy (GtkObject *object)
folder_browser = FOLDER_BROWSER (object);
CORBA_exception_init (&ev);
-
+
+ if (folder_browser->search_full)
+ gtk_object_unref((GtkObject *)folder_browser->search_full);
+
if (folder_browser->shell != CORBA_OBJECT_NIL)
CORBA_Object_release (folder_browser->shell, &ev);
-
- if (folder_browser->uri)
- g_free (folder_browser->uri);
+
+ g_free (folder_browser->uri);
if (folder_browser->folder) {
mail_do_sync_folder (folder_browser->folder);
@@ -135,6 +139,7 @@ static char * search_options[] = {
"Subject contains",
"Body does not contain",
"Subject does not contain",
+ "Custom search",
NULL
};
@@ -146,8 +151,55 @@ static char * search_string[] = {
"(body-contains %s)",
"(match-all (header-contains \"Subject\" %s)",
"(match-all (not (body-contains %s)))",
- "(match-all (not (header-contains \"Subject\" %s)))"
+ "(match-all (not (header-contains \"Subject\" %s)))",
+ "%s",
};
+#define CUSTOM_SEARCH_ID (5)
+
+static void
+search_full_clicked(MailSearchDialogue *msd, guint button, FolderBrowser *fb)
+{
+ char *query;
+
+ switch (button) {
+ case 0: /* 'ok' */
+ case 1: /* 'search' */
+ query = mail_search_dialogue_get_query(msd);
+ mail_do_regenerate_messagelist(fb->message_list, query);
+ g_free(query);
+ /* save the search as well */
+ if (fb->search_full)
+ gtk_object_unref((GtkObject *)fb->search_full);
+ fb->search_full = msd->rule;
+ gtk_object_ref((GtkObject *)fb->search_full);
+ if (button == 0)
+ gnome_dialog_close((GnomeDialog *)msd);
+ break;
+ case 2: /* 'cancel' */
+ gnome_dialog_close((GnomeDialog *)msd);
+ case -1: /* dialogue closed */
+ mail_do_regenerate_messagelist(fb->message_list, 0);
+ /* reset the search buttons state */
+ gtk_menu_set_active(GTK_MENU(GTK_OPTION_MENU(fb->search_menu)->menu), 0);
+ gtk_widget_set_sensitive(fb->search_entry, TRUE);
+ break;
+ }
+}
+
+/* bring up the 'full search' dialogue and let the user use that to search with */
+static void
+search_full(GtkWidget *w, FolderBrowser *fb)
+{
+ MailSearchDialogue *msd;
+
+ /* make search dialogue thingy match */
+ gtk_menu_set_active(GTK_MENU(GTK_OPTION_MENU(fb->search_menu)->menu), CUSTOM_SEARCH_ID);
+ gtk_widget_set_sensitive(fb->search_entry, FALSE);
+
+ msd = mail_search_dialogue_new_with_rule(fb->search_full);
+ gtk_signal_connect((GtkObject *)msd, "clicked", search_full_clicked, fb);
+ gtk_widget_show((GtkWidget*)msd);
+}
static void
search_set(FolderBrowser *fb)
@@ -158,16 +210,23 @@ search_set(FolderBrowser *fb)
int index;
char *text;
+ widget = gtk_menu_get_active (GTK_MENU(GTK_OPTION_MENU(fb->search_menu)->menu));
+ index = (int)gtk_object_get_data((GtkObject *)widget, "search_option");
+ if (index == CUSTOM_SEARCH_ID) {
+ search_full(NULL, fb);
+ return;
+ }
+ gtk_widget_set_sensitive(fb->search_entry, TRUE);
+
text = e_utf8_gtk_entry_get_text((GtkEntry *)fb->search_entry);
if (text == NULL || text[0] == 0) {
- if (text) g_free (text);
+ if (text)
+ g_free(text);
mail_do_regenerate_messagelist (fb->message_list, NULL);
return;
}
- widget = gtk_menu_get_active (GTK_MENU(GTK_OPTION_MENU(fb->search_menu)->menu));
- index = (int)gtk_object_get_data((GtkObject *)widget, "search_option");
if (index > sizeof(search_string)/sizeof(search_string[0]))
index = 0;
str = search_string[index];
@@ -242,18 +301,39 @@ search_save(GtkWidget *w, FolderBrowser *fb)
text = e_utf8_gtk_entry_get_text((GtkEntry *)fb->search_entry);
- if (text == NULL || text[0] == 0) {
- if (text) g_free (text);
- return;
- }
-
widget = gtk_menu_get_active (GTK_MENU(GTK_OPTION_MENU(fb->search_menu)->menu));
index = (int)gtk_object_get_data((GtkObject *)widget, "search_option");
+
+ /* some special case code for the custom search position */
+ if (index == CUSTOM_SEARCH_ID) {
+ g_free(text);
+ text = g_strdup("Custom");
+ } else {
+ if (text == NULL || text[0] == 0) {
+ g_free (text);
+ return;
+ }
+ }
+
rule = vfolder_rule_new();
((FilterRule *)rule)->grouping = FILTER_GROUP_ANY;
vfolder_rule_add_source(rule, fb->uri);
filter_rule_set_name((FilterRule *)rule, text);
switch(index) {
+ case 5: /* custom search */
+ if (fb->search_full) {
+ GList *partl;
+
+ /* copy the parts from the search rule to the vfolder rule */
+ partl = fb->search_full->parts;
+ while (partl) {
+ FilterPart *old = partl->data;
+ part = filter_part_clone(old);
+ filter_rule_add_part((FilterRule *)rule, part);
+ partl = g_list_next(partl);
+ }
+ break;
+ }
default: /* header or body contains */
index = 0;
case 1: case 2:
@@ -290,6 +370,7 @@ search_save(GtkWidget *w, FolderBrowser *fb)
element = filter_part_find_element(part, "subject");
filter_input_set_value((FilterInput *)element, text);
break;
+
}
vfolder_gui_add_rule(rule);
@@ -380,7 +461,7 @@ static void
folder_browser_gui_init (FolderBrowser *fb)
{
GtkWidget *hbox, *label;
- GtkButton *button;
+ GtkButton *button, *searchbutton;
/*
* The panned container
@@ -402,16 +483,20 @@ folder_browser_gui_init (FolderBrowser *fb)
gtk_widget_show(fb->search_entry);
gtk_signal_connect(GTK_OBJECT (fb->search_entry), "activate", search_activate, fb);
/* gtk_signal_connect(fb->search_entry, "changed", search_activate, fb); */
+ searchbutton = (GtkButton *)gtk_button_new_with_label(_("Full Search"));
+ gtk_widget_show((GtkWidget *)searchbutton);
label = gtk_label_new(_("Search"));
gtk_widget_show(label);
fb->search_menu = create_option_menu(search_options, 0, fb);
button = (GtkButton *)gtk_button_new_with_label(_("Save"));
gtk_widget_show((GtkWidget *)button);
gtk_signal_connect((GtkObject *)button, "clicked", search_save, fb);
+ gtk_signal_connect((GtkObject *)searchbutton, "clicked", search_full, fb);
gtk_box_pack_end((GtkBox *)hbox, (GtkWidget *)button, FALSE, FALSE, 3);
gtk_box_pack_end((GtkBox *)hbox, fb->search_entry, FALSE, FALSE, 3);
gtk_box_pack_end((GtkBox *)hbox, fb->search_menu, FALSE, FALSE, 3);
gtk_box_pack_end((GtkBox *)hbox, label, FALSE, FALSE, 3);
+ gtk_box_pack_end((GtkBox *)hbox, (GtkWidget *)searchbutton, FALSE, FALSE, 3);
gtk_table_attach (
GTK_TABLE (fb), hbox,
0, 1, 0, 1,
@@ -423,7 +508,6 @@ folder_browser_gui_init (FolderBrowser *fb)
e_paned_add1 (E_PANED (fb->vpaned), fb->message_list_w);
gtk_widget_show (fb->message_list_w);
- /* (jwise) <-- for searching purposes :) */
gtk_signal_connect (GTK_OBJECT (fb->message_list_w), "size_allocate",
GTK_SIGNAL_FUNC (fb_resize_cb), NULL);
diff --git a/mail/folder-browser.h b/mail/folder-browser.h
index 14c75c3367..0e82ba2a49 100644
--- a/mail/folder-browser.h
+++ b/mail/folder-browser.h
@@ -43,7 +43,8 @@ struct _FolderBrowser {
GtkWidget *vpaned;
GtkWidget *search_menu;
GtkWidget *search_entry;
-
+ FilterRule *search_full; /* if we have a full search active */
+
gboolean preview_shown;
/* Stuff to allow on-demand filtering */
diff --git a/mail/mail-autofilter.c b/mail/mail-autofilter.c
index e7c9f8997c..81ed429e40 100644
--- a/mail/mail-autofilter.c
+++ b/mail/mail-autofilter.c
@@ -278,7 +278,7 @@ filter_gui_add_from_message(CamelMimeMessage *msg, int flags)
fc = filter_context_new();
userrules = g_strdup_printf("%s/filters.xml", evolution_dir);
systemrules = g_strdup_printf("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR);
- rule_context_load((RuleContext *)fc, systemrules, userrules, NULL, NULL);
+ rule_context_load((RuleContext *)fc, systemrules, userrules);
rule = filter_rule_from_message(fc, msg, flags);
rule_context_add_rule_gui((RuleContext *)fc, rule, _("Add Filter Rule"), userrules);
g_free (userrules);
@@ -309,7 +309,7 @@ filter_gui_add_for_mailing_list (CamelMimeMessage *msg,
fc = filter_context_new();
userrules = g_strdup_printf("%s/filters.xml", evolution_dir);
systemrules = g_strdup_printf("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR);
- rule_context_load((RuleContext *)fc, systemrules, userrules, NULL, NULL);
+ rule_context_load((RuleContext *)fc, systemrules, userrules);
rule = (FilterRule *) filter_filter_new ();
diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c
index 35d59b688f..91afe99a93 100644
--- a/mail/mail-callbacks.c
+++ b/mail/mail-callbacks.c
@@ -696,7 +696,7 @@ filter_edit (BonoboUIHandler *uih, void *user_data, const char *path)
fc = filter_context_new();
user = g_strdup_printf ("%s/filters.xml", evolution_dir);
system = g_strdup_printf ("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR);
- rule_context_load ((RuleContext *)fc, system, user, NULL, NULL);
+ rule_context_load ((RuleContext *)fc, system, user);
g_free (user);
g_free (system);
diff --git a/mail/mail-format.c b/mail/mail-format.c
index 5d7cb1f695..8d690a1c84 100644
--- a/mail/mail-format.c
+++ b/mail/mail-format.c
@@ -599,9 +599,8 @@ write_headers (CamelMimeMessage *message, MailDisplay *md)
md->html, md->stream);
g_free (string);
- recipients = camel_mime_message_get_recipients (
- message, CAMEL_RECIPIENT_TYPE_CC);
- string = camel_address_encode (CAMEL_ADDRESS (recipients));
+ recipients = camel_mime_message_get_recipients(message, CAMEL_RECIPIENT_TYPE_CC);
+ string = camel_address_encode(CAMEL_ADDRESS(recipients));
if (string) {
write_field_to_stream ("Cc:", string, TRUE,
md->html, md->stream);
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 59cf938840..ff4ff8ed1b 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -91,7 +91,7 @@ mail_load_evolution_rule_context ()
userrules = g_strdup_printf ("%s/filters.xml", evolution_dir);
systemrules = g_strdup_printf ("%s/evolution/filtertypes.xml", EVOLUTION_DATADIR);
fc = filter_context_new ();
- rule_context_load ((RuleContext *)fc, systemrules, userrules, NULL, NULL);
+ rule_context_load ((RuleContext *)fc, systemrules, userrules);
g_free (userrules);
g_free (systemrules);
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index 40e3cd7f11..a26c2986fc 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -87,16 +87,11 @@ vfolder_refresh(void)
g_free(info->query);
info->query = g_strdup(expr->str);
- /*uri = g_strdup_printf("vfolder:%s/vfolder/%s?%s", evolution_dir, info->name, info->query);*/
uri = g_strdup_printf("vfolder:%s", info->name);
path = g_strdup_printf("/%s", info->name);
evolution_storage_removed_folder(vfolder_storage, path);
- evolution_storage_new_folder (vfolder_storage,
- path,
- g_basename (path),
- "mail",
- uri,
- info->name);
+ evolution_storage_new_folder(vfolder_storage, path, g_basename(path),
+ "mail", uri, info->name);
g_free(uri);
g_free(path);
}
@@ -106,15 +101,10 @@ vfolder_refresh(void)
info->query = g_strdup(expr->str);
d(printf("Adding new vfolder: %s %s\n", rule->name, expr->str));
- /*uri = g_strdup_printf("vfolder:%s/vfolder/%s?%s", evolution_dir, info->name, info->query);*/
uri = g_strdup_printf("vfolder:%s", info->name);
path = g_strdup_printf("/%s", info->name);
- evolution_storage_new_folder (vfolder_storage,
- path,
- g_basename (path),
- "mail",
- uri,
- info->name);
+ evolution_storage_new_folder(vfolder_storage, path, g_basename(path),
+ "mail", uri, info->name);
g_free(uri);
g_free(path);
}
@@ -167,7 +157,7 @@ vfolder_create_storage(EvolutionShellComponent *shell_component)
context = vfolder_context_new();
printf("loading rules %s %s\n", system, user);
- if (rule_context_load((RuleContext *)context, system, user, NULL, NULL) != 0) {
+ if (rule_context_load((RuleContext *)context, system, user) != 0) {
g_warning("cannot load vfolders: %s\n", ((RuleContext *)context)->error);
}
g_free(user);
@@ -175,7 +165,6 @@ vfolder_create_storage(EvolutionShellComponent *shell_component)
vfolder_refresh();
}
-/* THIS IS ANALOGOUS TO mail_tool_uri_to_folder. IT IS NOT ASYNCHRONOUS */
/* maps the shell's uri to the real vfolder uri and open the folder */
CamelFolder *
vfolder_uri_to_folder(const char *uri, CamelException *ex)
diff --git a/mail/message-list.c b/mail/message-list.c
index 4f02e1d7b8..22f6cb741d 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -87,6 +87,7 @@ static void select_msg (MessageList *message_list, gint row);
static char *filter_date (const void *data);
static void nuke_uids (GtkObject *o);
+static char *folder_to_cachename(CamelFolder *folder, const char *prefix);
static void save_tree_state(MessageList *ml);
static struct {
@@ -933,6 +934,20 @@ message_list_init_header (MessageList *message_list)
}
}
+static void
+save_header_state(MessageList *ml)
+{
+ char *filename;
+
+ if (ml->folder == NULL
+ || ml->etable == NULL)
+ return;
+
+ filename = folder_to_cachename(ml->folder, "et-header-");
+ e_table_scrolled_save_specification(E_TABLE_SCROLLED(ml->etable), filename);
+ g_free(filename);
+}
+
static char *
message_list_get_layout (MessageList *message_list)
{
@@ -940,6 +955,39 @@ message_list_get_layout (MessageList *message_list)
return g_strdup ("<ETableSpecification> <columns-shown> <column> 0 </column> <column> 3 </column> <column> 4 </column> <column> 5 </column> </columns-shown> <grouping> </grouping> </ETableSpecification>");
}
+static void
+message_list_setup_etable(MessageList *message_list)
+{
+ char *spec = "<ETableSpecification> <columns-shown> "
+ "<column> 0 </column> <column> 7 </column>"
+ "<column> 4 </column> <column> 5 </column> "
+ "</columns-shown> <grouping> </grouping> </ETableSpecification>";
+
+ /* build the spec based on the folder, and possibly from a saved file */
+ /* otherwise, leave default */
+ if (message_list->folder) {
+ char *name;
+ char *path;
+ struct stat st;
+
+ path = folder_to_cachename(message_list->folder, "et-header-");
+ if (stat(path, &st) == 0 && st.st_size > 0 && S_ISREG(st.st_mode)) {
+ e_table_scrolled_load_specification(E_TABLE_SCROLLED(message_list->etable), path);
+ } else {
+ /* I wonder if there's a better way to do this ...? */
+ name = camel_service_get_name((CAMEL_SERVICE(message_list->folder->parent_store)), TRUE);
+ printf("folder name is '%s'\n", name);
+ if (strstr(name, "/Drafts") == 0
+ || strstr(name, "/Outbox") == 0
+ || strstr(name, "/Sent") == 0) {
+ e_table_scrolled_set_specification(E_TABLE_SCROLLED(message_list->etable), spec);
+ }
+ g_free(name);
+ }
+ g_free(path);
+ }
+}
+
/*
* GtkObject::init
*/
@@ -997,7 +1045,7 @@ message_list_init (GtkObject *object)
GTK_SIGNAL_FUNC (on_double_click), message_list);
gtk_widget_show (message_list->etable);
-
+
gtk_object_ref (GTK_OBJECT (message_list->table_model));
gtk_object_sink (GTK_OBJECT (message_list->table_model));
@@ -1020,8 +1068,10 @@ message_list_destroy (GtkObject *object)
MessageList *message_list = MESSAGE_LIST (object);
int i;
- if (message_list->folder)
+ if (message_list->folder) {
save_tree_state(message_list);
+ save_header_state(message_list);
+ }
gtk_object_unref (GTK_OBJECT (message_list->table_model));
gtk_object_unref (GTK_OBJECT (message_list->header_model));
@@ -1425,6 +1475,9 @@ message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder)
message_list->folder = camel_folder;
+ /* build the etable suitable for this folder */
+ message_list_setup_etable(message_list);
+
camel_object_hook_event(CAMEL_OBJECT (camel_folder), "folder_changed",
folder_changed, message_list);
camel_object_hook_event(CAMEL_OBJECT (camel_folder), "message_changed",
diff --git a/mail/message-list.h b/mail/message-list.h
index 4d02e7815a..15267f8293 100644
--- a/mail/message-list.h
+++ b/mail/message-list.h
@@ -67,7 +67,7 @@ struct _MessageList {
ETreePath *tree_root; /* for tree view */
GtkWidget *etable;
-
+
CamelFolder *folder;
GHashTable *uid_rowmap;