aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog41
-rw-r--r--mail/folder-browser.c279
-rw-r--r--mail/folder-browser.h4
-rw-r--r--mail/mail-mt.c70
-rw-r--r--mail/mail-send-recv.c135
-rw-r--r--mail/mail-vfolder.c14
-rw-r--r--mail/mail-vfolder.h1
-rw-r--r--mail/main.c18
8 files changed, 272 insertions, 290 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 5ad22dc3cc..8aadc9dc3c 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,44 @@
+2001-03-01 Not Zed <NotZed@Ximian.com>
+
+ * folder-browser.c (folder_browser_search_menu_activated): Fixes
+ for changes to search bar.
+ (search_save): Removed.
+ (search_full): Removed.
+ (search_full_clicked): Removed.
+ (folder_browser_search_option_items[]): Removed.
+ (folder_browser_search_query_changed): Changed for search bar
+ changes.
+ (folder_browser_clear_search): Removed.
+
+ * mail-vfolder.c (vfolder_clone_rule): New function to clone a
+ filter/search rule into a matching vfolder rule.
+
+ * mail-send-recv.c (mail_receive_uri): Setup a timeout for status
+ updates.
+ (build_dialogue): Setup timeout id for status updates.
+ (operation_status_timeout): New function to set the status via a
+ timeout.
+ (receive_done): Remove the timeout handler if we need to.
+ (operation_status):
+ (receive_status): Just update the info, and let the timeout
+ handler update the gui.
+ (do_free_status):
+ (do_show_status): Removed gui thread status message processing.
+
+2001-02-28 Not Zed <NotZed@Ximian.com>
+
+ * folder-browser.c (folder_browser_config_search): New function to
+ configure the FilterRule for the search mechanism.
+
+2001-02-27 Not Zed <NotZed@Ximian.com>
+
+ * folder-browser.c (folder_browser_gui_init): Setup the search bar
+ as a filterbar.
+ (got_folder): Set the whole search bar sensitive or not based on
+ the search capability of the folder.
+
+ * folder-browser.h: Changed to use efilterbar instead of esearchbar.
+
2001-02-27 Jeffrey Stedfast <fejj@ximian.com>
* mail-callbacks.c (configure_mail): Return TRUE if the user
diff --git a/mail/folder-browser.c b/mail/folder-browser.c
index 45cee5446e..324599a726 100644
--- a/mail/folder-browser.c
+++ b/mail/folder-browser.c
@@ -173,10 +173,7 @@ got_folder(char *uri, CamelFolder *folder, void *data)
update_unread_count, fb);
}
- gtk_widget_set_sensitive (GTK_WIDGET (fb->search->entry),
- camel_folder_has_search_capability (folder));
- gtk_widget_set_sensitive (GTK_WIDGET (fb->search->option),
- camel_folder_has_search_capability (folder));
+ gtk_widget_set_sensitive(GTK_WIDGET(fb->search), camel_folder_has_search_capability(folder));
message_list_set_threaded(fb->message_list, mail_config_get_thread_list());
message_list_set_folder(fb->message_list, folder);
done:
@@ -212,237 +209,81 @@ folder_browser_set_message_preview (FolderBrowser *folder_browser, gboolean show
}
enum {
- ESB_SHOW_ALL,
- ESB_ADVANCED,
ESB_SAVE,
};
static ESearchBarItem folder_browser_search_menu_items[] = {
- { N_("Show All"), ESB_SHOW_ALL },
- { NULL, 0 },
- { N_("Advanced..."), ESB_ADVANCED },
- { NULL, 0 },
+ E_FILTERBAR_RESET,
+ E_FILTERBAR_SAVE,
{ N_("Store search as vFolder"), ESB_SAVE },
{ NULL, -1 }
};
-enum {
- ESB_BODY_SUBJECT_CONTAINS,
- ESB_BODY_CONTAINS,
- ESB_SUBJECT_CONTAINS,
- ESB_BODY_DOES_NOT_CONTAIN,
- ESB_SUBJECT_DOES_NOT_CONTAIN,
- ESB_SENDER_CONTAINS,
-};
+static void
+folder_browser_search_menu_activated (ESearchBar *esb, int id, FolderBrowser *fb)
+{
+ EFilterBar *efb = (EFilterBar *)esb;
-static ESearchBarItem folder_browser_search_option_items[] = {
- { N_("Body or subject contains"), ESB_BODY_SUBJECT_CONTAINS },
- { N_("Body contains"), ESB_BODY_CONTAINS },
- { N_("Subject contains"), ESB_SUBJECT_CONTAINS },
- { N_("Body does not contain"), ESB_BODY_DOES_NOT_CONTAIN },
- { N_("Subject does not contain"), ESB_SUBJECT_DOES_NOT_CONTAIN },
- { N_("Sender contains"), ESB_SENDER_CONTAINS },
- { NULL, -1 }
-};
+ printf("menyu activated\n");
-/* NOTE: If this is changed, then change the search_save() function to match! */
-/* %s is replaced by the whole search string in quotes ...
- possibly could split the search string into words as well ? */
-static char *search_string[] = {
- "(or (body-contains %s) (match-all (header-contains \"Subject\" %s)))",
- "(body-contains %s)",
- "(match-all (header-contains \"Subject\" %s))",
- "(match-all (not (body-contains %s)))",
- "(match-all (not (header-contains \"Subject\" %s)))",
- "(match-all (header-contains \"from\" %s))",
-};
+ switch (id) {
+ case ESB_SAVE:
+ printf("Save vfolder\n");
+ if (efb->current_query) {
+ FilterRule *rule = vfolder_clone_rule(efb->current_query);
-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);
- message_list_set_search (fb->message_list, query);
- g_free (query);
-
- /* save the search as well */
- if (fb->search_full)
- gtk_object_unref (GTK_OBJECT (fb->search_full));
-
- fb->search_full = msd->rule;
-
- gtk_object_ref (GTK_OBJECT (fb->search_full));
- if (button == 0)
- gnome_dialog_close (GNOME_DIALOG (msd));
- break;
- case 2: /* 'cancel' */
- gnome_dialog_close (GNOME_DIALOG (msd));
- case -1: /* dialogue closed */
- message_list_set_search (fb->message_list, 0);
- /* reset the search buttons state */
- gtk_menu_set_active (GTK_MENU (GTK_OPTION_MENU (fb->search->option)->menu), 0);
- gtk_widget_set_sensitive (fb->search->entry, TRUE);
+ filter_rule_set_source(rule, FILTER_SOURCE_INCOMING);
+ vfolder_rule_add_source((VfolderRule *)rule, fb->uri);
+ vfolder_gui_add_rule((VfolderRule *)rule);
+ }
break;
}
}
-/* bring up the 'full search' dialogue and let the user use that to search with */
-static void
-search_full (GtkWidget *w, FolderBrowser *fb)
+static void folder_browser_config_search(EFilterBar *efb, FilterRule *rule, int id, const char *query, void *data)
{
- MailSearchDialogue *msd;
-
- gtk_widget_set_sensitive (fb->search->entry, FALSE);
-
- msd = mail_search_dialogue_new_with_rule (fb->search_full);
- gtk_signal_connect (GTK_OBJECT (msd), "clicked", search_full_clicked, fb);
- gtk_widget_show (GTK_WIDGET (msd));
-}
+ GList *partl;
-static void
-search_save (GtkWidget *w, FolderBrowser *fb)
-{
- char *text;
- FilterElement *element;
- VfolderRule *rule;
- FilterPart *part;
- int index;
-
- text = e_utf8_gtk_entry_get_text (GTK_ENTRY (fb->search->entry));
-
- index = fb->search->option_choice;
-
- 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) {
- default:
- /* header or body contains */
- index = ESB_BODY_SUBJECT_CONTAINS;
- case ESB_BODY_CONTAINS:
- case ESB_SUBJECT_CONTAINS:
- if (index == ESB_BODY_SUBJECT_CONTAINS || index == ESB_BODY_CONTAINS) {
- part = vfolder_create_part ("body");
- filter_rule_add_part ((FilterRule *)rule, part);
- element = filter_part_find_element (part, "body-type");
- filter_option_set_current ((FilterOption *)element, "contains");
- element = filter_part_find_element (part, "word");
- filter_input_set_value ((FilterInput *)element, text);
+ /* we scan the parts of a rule, and set all the types we know about to the query string */
+ partl = rule->parts;
+ while (partl) {
+ FilterPart *part = partl->data;
+
+ if (!strcmp(part->name, "subject")) {
+ FilterInput *input = (FilterInput *)filter_part_find_element(part, "subject");
+ if (input)
+ filter_input_set_value(input, query);
+ } else if (!strcmp(part->name, "body")) {
+ FilterInput *input = (FilterInput *)filter_part_find_element(part, "word");
+ if (input)
+ filter_input_set_value(input, query);
+ } else if(!strcmp(part->name, "sender")) {
+ FilterInput *input = (FilterInput *)filter_part_find_element(part, "sender");
+ if (input)
+ filter_input_set_value(input, query);
}
- if (index == ESB_BODY_SUBJECT_CONTAINS || index == ESB_SUBJECT_CONTAINS) {
- part = vfolder_create_part ("subject");
- filter_rule_add_part ((FilterRule *)rule, part);
- element = filter_part_find_element (part, "subject-type");
- filter_option_set_current ((FilterOption *)element, "contains");
- element = filter_part_find_element (part, "subject");
- filter_input_set_value ((FilterInput *)element, text);
- }
- break;
- case ESB_BODY_DOES_NOT_CONTAIN:
- part = vfolder_create_part ("body");
- filter_rule_add_part ((FilterRule *)rule, part);
- element = filter_part_find_element (part, "body-type");
- filter_option_set_current ((FilterOption *)element, "not contains");
- element = filter_part_find_element (part, "word");
- filter_input_set_value ((FilterInput *)element, text);
- break;
- case ESB_SUBJECT_DOES_NOT_CONTAIN:
- part = vfolder_create_part ("subject");
- filter_rule_add_part ((FilterRule *)rule, part);
- element = filter_part_find_element (part, "subject-type");
- filter_option_set_current ((FilterOption *)element, "not contains");
- element = filter_part_find_element (part, "subject");
- filter_input_set_value ((FilterInput *)element, text);
- break;
- case ESB_SENDER_CONTAINS:
- part = vfolder_create_part ("from");
- filter_rule_add_part ((FilterRule *)rule, part);
- element = filter_part_find_element (part, "from-type");
- filter_option_set_current ((FilterOption *)element, "contains");
- element = filter_part_find_element (part, "from");
- filter_input_set_value ((FilterInput *)element, text);
- break;
- }
-
- vfolder_gui_add_rule (rule);
-
- g_free (text);
-}
-
-static void
-folder_browser_search_menu_activated (ESearchBar *esb, int id, FolderBrowser *fb)
-{
- switch (id) {
- case ESB_SHOW_ALL:
- gtk_entry_set_text (GTK_ENTRY (esb->entry), "");
- gtk_widget_set_sensitive (esb->entry, TRUE);
- message_list_set_search (fb->message_list, NULL);
- break;
- case ESB_ADVANCED:
- search_full (NULL, fb);
- break;
- case ESB_SAVE:
- search_save (NULL, fb);
- break;
+ partl = partl->next;
}
+ printf("configuring search for search string '%s', rule is '%s'\n", query, rule->name);
}
static void
folder_browser_search_query_changed (ESearchBar *esb, FolderBrowser *fb)
{
- GString *search_query;
- char *search_word, *str;
- int search_type;
-
- gtk_widget_set_sensitive (esb->entry, TRUE);
-
+ char *search_word;
+
+ printf("query changed\n");
+
gtk_object_get (GTK_OBJECT (esb),
- "text", &search_word,
- "option_choice", &search_type,
+ "query", &search_word,
NULL);
-
- if (search_word && strlen (search_word)) {
- str = search_string[search_type];
-
- search_query = g_string_new ("");
- while (*str) {
- if (str[0] == '%' && str[1]=='s') {
- str += 2;
- e_sexp_encode_string (search_query, search_word);
- } else {
- g_string_append_c (search_query, *str);
- str++;
- }
- }
-
- message_list_set_search (fb->message_list, search_query->str);
- g_string_free (search_query, TRUE);
- } else {
- message_list_set_search (fb->message_list, NULL);
- }
-
- g_free (search_word);
-}
-void
-folder_browser_clear_search (FolderBrowser *fb)
-{
- gtk_entry_set_text (GTK_ENTRY (fb->search->entry), "");
- gtk_option_menu_set_history (GTK_OPTION_MENU (fb->search->option), 0);
-
- message_list_set_search (fb->message_list, NULL);
+ message_list_set_search (fb->message_list, search_word);
+
+ printf("query is %s\n", search_word);
+ g_free(search_word);
+ return;
}
void
@@ -888,9 +729,27 @@ folder_browser_gui_init (FolderBrowser *fb)
GTK_FILL | GTK_EXPAND,
0, 0);
- /* quick-search entry */
- fb->search = E_SEARCH_BAR (e_search_bar_new (folder_browser_search_menu_items,
- folder_browser_search_option_items));
+ /* quick-search bar */
+ {
+ RuleContext *rc = (RuleContext *)rule_context_new ();
+ char *userrules = g_strdup_printf("%s/searches.xml", evolution_dir);
+ /* we reuse the vfolder types here, they should match */
+ char *systemrules = g_strdup_printf("%s/evolution/vfoldertypes.xml", EVOLUTION_DATADIR);
+
+ rule_context_add_part_set((RuleContext *)rc, "partset", filter_part_get_type(),
+ rule_context_add_part, rule_context_next_part);
+
+ rule_context_add_rule_set((RuleContext *)rc, "ruleset", filter_rule_get_type(),
+ rule_context_add_rule, rule_context_next_rule);
+
+ fb->search = e_filter_bar_new(rc, systemrules, userrules, folder_browser_config_search, fb);
+ e_search_bar_set_menu((ESearchBar *)fb->search, folder_browser_search_menu_items);
+ /*e_search_bar_set_option((ESearchBar *)fb->search, folder_browser_search_option_items);*/
+ g_free(userrules);
+ g_free(systemrules);
+ gtk_object_unref((GtkObject *)rc);
+ }
+
gtk_widget_show (GTK_WIDGET (fb->search));
gtk_signal_connect (GTK_OBJECT (fb->search), "query_changed",
diff --git a/mail/folder-browser.h b/mail/folder-browser.h
index 04ddaae110..0cf7feb1ee 100644
--- a/mail/folder-browser.h
+++ b/mail/folder-browser.h
@@ -9,7 +9,7 @@
#include "camel/camel-stream.h"
#include <bonobo/bonobo-property-bag.h>
#include <bonobo/bonobo-ui-component.h>
-#include <widgets/misc/e-search-bar.h>
+#include <widgets/misc/e-filter-bar.h>
#include "filter/filter-rule.h"
#include "filter/filter-context.h" /*eek*/
#include "message-list.h"
@@ -54,7 +54,7 @@ struct _FolderBrowser {
MailDisplay *mail_display;
GtkWidget *vpaned;
- ESearchBar *search;
+ EFilterBar *search;
FilterRule *search_full; /* if we have a full search active */
gboolean preview_shown;
diff --git a/mail/mail-mt.c b/mail/mail-mt.c
index 991d1cf33e..ee84b6649d 100644
--- a/mail/mail-mt.c
+++ b/mail/mail-mt.c
@@ -20,6 +20,7 @@
#include <libgnomeui/gnome-dialog.h>
#include <gtk/gtkprogress.h>
+/*#define MALLOC_CHECK*/
#define d(x)
static void set_view_data(const char *current_message, int busy);
@@ -69,6 +70,8 @@ void *mail_msg_new(mail_msg_op_t *ops, EMsgPort *reply_port, size_t size)
g_hash_table_insert(mail_msg_active, (void *)msg->seq, msg);
+ d(printf("New message %p\n", msg));
+
MAIL_MT_UNLOCK(mail_msg_lock);
return msg;
@@ -83,10 +86,41 @@ static void destroy_widgets(CamelObject *o, void *event_data, void *data)
gtk_widget_destroy((GtkWidget *)event_data);
}
+#ifdef MALLOC_CHECK
+#include <mcheck.h>
+
+static void
+checkmem(void *p)
+{
+ if (p) {
+ int status = mprobe(p);
+
+ switch (status) {
+ case MCHECK_HEAD:
+ printf("Memory underrun at %p\n", p);
+ abort();
+ case MCHECK_TAIL:
+ printf("Memory overrun at %p\n", p);
+ abort();
+ case MCHECK_FREE:
+ printf("Double free %p\n", p);
+ abort();
+ }
+ }
+}
+#endif
+
void mail_msg_free(void *msg)
{
struct _mail_msg *m = msg;
+#ifdef MALLOC_CHECK
+ checkmem(m);
+ checkmem(m->cancel);
+ checkmem(m->priv);
+#endif
+ d(printf("Free message %p\n", msg));
+
if (m->ops->destroy_msg)
m->ops->destroy_msg(m);
@@ -126,6 +160,12 @@ void mail_msg_check_error(void *msg)
char *text;
GnomeDialog *gd;
+#ifdef MALLOC_CHECK
+ checkmem(m);
+ checkmem(m->cancel);
+ checkmem(m->priv);
+#endif
+
if (!camel_exception_is_set(&m->ex)
|| m->ex.id == CAMEL_EXCEPTION_USER_CANCEL)
return;
@@ -201,6 +241,13 @@ mail_msgport_replied(GIOChannel *source, GIOCondition cond, void *d)
mail_msg_t *m;
while (( m = (mail_msg_t *)e_msgport_get(port))) {
+
+#ifdef MALLOC_CHECK
+ checkmem(m);
+ checkmem(m->cancel);
+ checkmem(m->priv);
+#endif
+
if (m->ops->reply_msg)
m->ops->reply_msg(m);
mail_msg_check_error(m);
@@ -219,6 +266,11 @@ mail_msgport_received(GIOChannel *source, GIOCondition cond, void *d)
mail_msg_t *m;
while (( m = (mail_msg_t *)e_msgport_get(port))) {
+#ifdef MALLOC_CHECK
+ checkmem(m);
+ checkmem(m->cancel);
+ checkmem(m->priv);
+#endif
if (m->ops->describe_msg) {
char *text = m->ops->describe_msg(m, FALSE);
mail_status_start(text);
@@ -245,6 +297,12 @@ mail_msg_destroy(EThread *e, EMsg *msg, void *data)
{
mail_msg_t *m = (mail_msg_t *)msg;
+#ifdef MALLOC_CHECK
+ checkmem(m);
+ checkmem(m->cancel);
+ checkmem(m->priv);
+#endif
+
if (m->ops->describe_msg)
mail_status_end();
mail_msg_free(m);
@@ -255,6 +313,12 @@ mail_msg_received(EThread *e, EMsg *msg, void *data)
{
mail_msg_t *m = (mail_msg_t *)msg;
+#ifdef MALLOC_CHECK
+ checkmem(m);
+ checkmem(m->cancel);
+ checkmem(m->priv);
+#endif
+
if (m->ops->describe_msg) {
char *text = m->ops->describe_msg(m, FALSE);
d(printf("message received at thread\n"));
@@ -809,7 +873,7 @@ mail_operation_status(struct _CamelOperation *op, const char *what, int pc, void
{
struct _op_status_msg *m;
- printf("got operation statys: %s %d%%\n", what, pc);
+ d(printf("got operation statys: %s %d%%\n", what, pc));
m = mail_msg_new(&op_status_op, NULL, sizeof(*m));
m->op = op;
@@ -882,10 +946,10 @@ set_view_data(const char *current_message, int busy)
if (shell_view_interface != CORBA_OBJECT_NIL) {
if ((current_message == NULL || current_message[0] == 0) && ! busy) {
- printf("clearing msg\n");
+ d(printf("clearing msg\n"));
GNOME_Evolution_ShellView_unsetMessage (shell_view_interface, &ev);
} else {
- printf("setting msg %s\n", current_message ? current_message : "(null)");
+ d(printf("setting msg %s\n", current_message ? current_message : "(null)"));
GNOME_Evolution_ShellView_setMessage (shell_view_interface,
current_message?current_message:"",
busy,
diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c
index c037568d24..b9f51b65ac 100644
--- a/mail/mail-send-recv.c
+++ b/mail/mail-send-recv.c
@@ -48,6 +48,10 @@
#include <libgnomeui/gnome-dialog.h>
#include <libgnomeui/gnome-window-icon.h>
+#define d(x)
+
+/* ms between status updates to the gui */
+#define STATUS_TIMEOUT (250)
/* send/receive email */
@@ -98,7 +102,12 @@ struct _send_info {
send_state_t state;
GtkProgressBar *bar;
GtkButton *stop;
- time_t update;
+
+ int timeout_id;
+ char *what;
+ int pc;
+
+ /*time_t update;*/
struct _send_data *data;
};
@@ -141,8 +150,11 @@ free_folder_info(void *key, struct _folder_info *info, void *data)
static void free_send_info(void *key, struct _send_info *info, void *data)
{
+ d(printf("Freeing send info %p\n", info));
g_free(info->uri);
camel_operation_unref(info->cancel);
+ if (info->timeout_id != 0)
+ gtk_timeout_remove(info->timeout_id);
g_free(info);
}
@@ -184,7 +196,7 @@ dialogue_clicked(GnomeDialog *gd, int button, struct _send_data *data)
{
switch(button) {
case 0:
- printf("cancelled whole thing\n");
+ d(printf("cancelled whole thing\n"));
if (!data->cancelled) {
data->cancelled = TRUE;
g_hash_table_foreach(data->active, (GHFunc)cancel_send_info, NULL);
@@ -192,13 +204,14 @@ dialogue_clicked(GnomeDialog *gd, int button, struct _send_data *data)
gnome_dialog_set_sensitive(gd, 0, FALSE);
break;
case -1: /* dialogue vanished, so make out its just hidden */
- printf("hiding dialogue\n");
+ d(printf("hiding dialogue\n"));
g_hash_table_foreach(data->active, (GHFunc)hide_send_info, NULL);
break;
}
}
static void operation_status(CamelOperation *op, const char *what, int pc, void *data);
+static int operation_status_timeout(void *data);
static struct _send_data *build_dialogue(GSList *sources, CamelFolder *outbox, const char *destination)
{
@@ -243,12 +256,13 @@ static struct _send_data *build_dialogue(GSList *sources, CamelFolder *outbox, c
info->type = SEND_UPDATE;
else
info->type = SEND_RECEIVE;
- printf("adding source %s\n", source->url);
+ d(printf("adding source %s\n", source->url));
info->uri = g_strdup(source->url);
info->keep = source->keep_on_server;
info->cancel = camel_operation_new(operation_status, info);
info->state = SEND_ACTIVE;
+ info->timeout_id = gtk_timeout_add(STATUS_TIMEOUT, operation_status_timeout, info);
g_hash_table_insert(data->active, info->uri, info);
list = g_list_prepend(list, info);
@@ -256,7 +270,8 @@ static struct _send_data *build_dialogue(GSList *sources, CamelFolder *outbox, c
/* incase we get the same source pop up again */
sources = sources->next;
continue;
- }
+ } else if (info->timeout_id == 0)
+ info->timeout_id = gtk_timeout_add(STATUS_TIMEOUT, operation_status_timeout, info);
label = (GtkLabel *)gtk_label_new(source->url);
bar = (GtkProgressBar *)gtk_progress_bar_new();
@@ -296,16 +311,18 @@ static struct _send_data *build_dialogue(GSList *sources, CamelFolder *outbox, c
if (info == NULL) {
info = g_malloc0(sizeof(*info));
info->type = SEND_SEND;
- printf("adding dest %s\n", destination);
+ d(printf("adding dest %s\n", destination));
info->uri = g_strdup(destination);
info->keep = FALSE;
info->cancel = camel_operation_new(operation_status, info);
info->state = SEND_ACTIVE;
+ info->timeout_id = gtk_timeout_add(STATUS_TIMEOUT, operation_status_timeout, info);
g_hash_table_insert(data->active, info->uri, info);
list = g_list_prepend(list, info);
- }
+ } else if (info->timeout_id == 0)
+ info->timeout_id = gtk_timeout_add(STATUS_TIMEOUT, operation_status_timeout, info);
label = (GtkLabel *)gtk_label_new(destination);
bar = (GtkProgressBar *)gtk_progress_bar_new();
@@ -341,12 +358,12 @@ update_folders(char *uri, struct _folder_info *info, void *data)
{
time_t now = *((time_t *)data);
- printf("checking update for folder: %s\n", info->uri);
+ d(printf("checking update for folder: %s\n", info->uri));
/* let it flow through to the folders every 10 seconds */
/* we back off slowly as we progress */
if (now > info->update+10+info->count*5) {
- printf("upating a folder: %s\n", info->uri);
+ d(printf("upating a folder: %s\n", info->uri));
/*camel_folder_thaw(info->folder);
camel_folder_freeze(info->folder);*/
info->update = now;
@@ -354,69 +371,38 @@ update_folders(char *uri, struct _folder_info *info, void *data)
}
}
-/* for forwarding stuff to the gui thread */
-struct _status_msg {
- struct _mail_msg msg;
- char *desc;
- int pc;
- struct _send_info *info;
-};
-
-static void
-do_show_status(struct _mail_msg *mm)
+static void set_send_status(struct _send_info *info, const char *desc, int pc)
{
- struct _status_msg *m = (struct _status_msg *)mm;
- char *out, *p, *o, c;
+ const char *p;
+ char *out, *o, c;
- out = alloca(strlen(m->desc)*2+1);
+ out = alloca(strlen(desc)*2+1);
o = out;
- p = m->desc;
+ p = desc;
while ((c = *p++)) {
if (c=='%')
*o++ = '%';
*o++ = c;
}
*o = 0;
- if (m->info->bar) {
- gtk_progress_set_percentage((GtkProgress *)m->info->bar, (gfloat)(m->pc/100.0));
- gtk_progress_set_format_string((GtkProgress *)m->info->bar, out);
- }
-}
-
-static void
-do_free_status(struct _mail_msg *mm)
-{
- struct _status_msg *m = (struct _status_msg *)mm;
-
- g_free(m->desc);
+
+ /* FIXME: LOCK */
+ g_free(info->what);
+ info->what = g_strdup(out);
+ info->pc = pc;
}
-struct _mail_msg_op status_op = {
- NULL,
- do_show_status,
- NULL,
- do_free_status,
-};
-
static void
receive_status (CamelFilterDriver *driver, enum camel_filter_status_t status, int pc, const char *desc, void *data)
{
struct _send_info *info = data;
time_t now;
- struct _status_msg *m;
-
- /* only update every second */
- now = time(0);
- if (now <= info->update)
- return;
-
- info->update = now;
/* let it flow through to the folder, every now and then too? */
g_hash_table_foreach(info->data->folders, (GHFunc)update_folders, &now);
if (info->data->inbox && now > info->data->inbox_update+20) {
- printf("updating inbox too\n");
+ d(printf("updating inbox too\n"));
/* this doesn't seem to work right :( */
/*camel_folder_thaw(info->data->inbox);
camel_folder_freeze(info->data->inbox);*/
@@ -430,23 +416,31 @@ receive_status (CamelFilterDriver *driver, enum camel_filter_status_t status, in
switch (status) {
case CAMEL_FILTER_STATUS_START:
case CAMEL_FILTER_STATUS_END:
- m = mail_msg_new(&status_op, NULL, sizeof(*m));
- m->desc = g_strdup(desc);
- m->pc = pc;
- m->info = info;
- e_msgport_put(mail_gui_port, (EMsg *)m);
+ set_send_status(info, desc, pc);
break;
default:
break;
}
}
+static int operation_status_timeout(void *data)
+{
+ struct _send_info *info = data;
+
+ if (info->bar) {
+ gtk_progress_set_percentage((GtkProgress *)info->bar, (gfloat)(info->pc/100.0));
+ gtk_progress_set_format_string((GtkProgress *)info->bar, info->what);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/* for camel operation status */
static void operation_status(CamelOperation *op, const char *what, int pc, void *data)
{
- struct _status_msg *m;
struct _send_info *info = data;
- time_t now;
/*printf("Operation '%s', percent %d\n");*/
switch (pc) {
@@ -458,16 +452,7 @@ static void operation_status(CamelOperation *op, const char *what, int pc, void
break;
}
- now = time(0);
- if (now <= info->update)
- return;
- info->update = now;
-
- m = mail_msg_new(&status_op, NULL, sizeof(*m));
- m->desc = g_strdup(what);
- m->pc = pc;
- m->info = info;
- e_msgport_put(mail_gui_port, (EMsg *)m);
+ set_send_status(info, what, pc);
}
/* when receive/send is complete */
@@ -493,10 +478,13 @@ receive_done (char *uri, void *data)
gtk_widget_set_sensitive((GtkWidget *)info->stop, FALSE);
/* remove/free this active download */
+ d(printf("%s: freeing info %p\n", __FUNCTION__, info));
g_hash_table_remove(info->data->active, info->uri);
info->data->infos = g_list_remove(info->data->infos, info);
g_free(info->uri);
camel_operation_unref(info->cancel);
+ if (info->timeout_id)
+ gtk_timeout_remove(info->timeout_id);
if (g_hash_table_size(info->data->active) == 0) {
if (info->data->gd)
@@ -669,7 +657,7 @@ static void auto_setup_set(void *key, struct _auto_data *info, GHashTable *set)
static void auto_clean_set(void *key, struct _auto_data *info, GHashTable *set)
{
- printf("removing auto-check for %s\n", info->uri);
+ d(printf("removing auto-check for %s %p\n", info->uri, info));
g_hash_table_remove(set, info->uri);
gtk_timeout_remove(info->timeout_id);
g_free(info->uri);
@@ -699,7 +687,7 @@ mail_autoreceive_setup(void)
if (source->url && source->auto_check && source->enabled) {
struct _auto_data *info;
- printf("setting up auto-receive mail for : %s\n", source->url);
+ d(printf("setting up auto-receive mail for : %s\n", source->url));
g_hash_table_remove(set_hash, source->url);
info = g_hash_table_lookup(auto_active, source->url);
@@ -742,11 +730,11 @@ void mail_receive_uri(const char *uri, int keep)
data = setup_send_data();
info = g_hash_table_lookup(data->active, uri);
if (info != NULL) {
- printf("download of %s still in progress\n", uri);
+ d(printf("download of %s still in progress\n", uri));
return;
}
- printf("starting non-interactive download of '%s'\n", uri);
+ d(printf("starting non-interactive download of '%s'\n", uri));
info = g_malloc0(sizeof(*info));
/* imap is handled differently */
@@ -762,6 +750,9 @@ void mail_receive_uri(const char *uri, int keep)
info->stop = NULL;
info->data = data;
info->state = SEND_ACTIVE;
+ info->timeout_id = 0;
+
+ d(printf("Adding new info %p\n", info));
g_hash_table_insert(data->active, info->uri, info);
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index cb5be64207..706f259b85 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -309,6 +309,20 @@ vfolder_create_part(const char *name)
return rule_context_create_part((RuleContext *)context, name);
}
+/* clones a filter/search rule into a matching vfolder rule (assuming the same system definitions) */
+FilterRule *
+vfolder_clone_rule(FilterRule *in)
+{
+ FilterRule *rule = vfolder_rule_new();
+ xmlNodePtr xml;
+
+ xml = filter_rule_xml_encode(in);
+ filter_rule_xml_decode(rule, xml, (RuleContext *)context);
+ xmlFreeNodeList(xml);
+
+ return rule;
+}
+
/* adds a rule with a gui */
void
vfolder_gui_add_rule(VfolderRule *rule)
diff --git a/mail/mail-vfolder.h b/mail/mail-vfolder.h
index c76e532b0c..b8b409b1e7 100644
--- a/mail/mail-vfolder.h
+++ b/mail/mail-vfolder.h
@@ -18,6 +18,7 @@ void vfolder_create_storage(EvolutionShellComponent *shell_component);
CamelFolder *vfolder_uri_to_folder(const char *uri, CamelException *ex);
void vfolder_edit(void);
FilterPart *vfolder_create_part(const char *name);
+FilterRule *vfolder_clone_rule(FilterRule *in);
void vfolder_gui_add_rule(VfolderRule *rule);
void vfolder_gui_add_from_message(CamelMimeMessage *msg, int flags, const char *source);
void vfolder_gui_add_from_mlist(CamelMimeMessage *msg, const char *mlist, const char *source);
diff --git a/mail/main.c b/mail/main.c
index 8da4c9420b..5900ee5625 100644
--- a/mail/main.c
+++ b/mail/main.c
@@ -32,10 +32,22 @@
#include "mail-mt.h"
#include "mail-vtrash.h"
-#if 0
+/*#define DO_MCHECK*/
+
+#ifdef DO_MCHECK
static int blowup(int status)
{
- printf("memory blew up, status %d\n", status);
+ switch(status) {
+ case 1:
+ printf("Double free failure\n");
+ break;
+ case 2:
+ printf("Memory clobbered before block\n");
+ break;
+ case 3:
+ printf("Memory clobbered after block\n");
+ break;
+ }
abort();
return status;
}
@@ -63,7 +75,7 @@ main (int argc, char *argv [])
CORBA_ORB orb;
struct sigaction sa, osa;
-#if 0
+#ifdef DO_MCHECK
/* used to make elfence work */
#if 0
free (malloc (10));