diff options
author | Not Zed <NotZed@Ximian.com> | 2001-03-01 08:58:16 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2001-03-01 08:58:16 +0800 |
commit | f01589262ca132b980bb067e5aa6fbaee8fd3579 (patch) | |
tree | b0cfe93753569c33cad150331342025fd98bcd76 /mail | |
parent | efa31cf176b236410e88a11b33bbfec5160e2c81 (diff) | |
download | gsoc2013-evolution-f01589262ca132b980bb067e5aa6fbaee8fd3579.tar gsoc2013-evolution-f01589262ca132b980bb067e5aa6fbaee8fd3579.tar.gz gsoc2013-evolution-f01589262ca132b980bb067e5aa6fbaee8fd3579.tar.bz2 gsoc2013-evolution-f01589262ca132b980bb067e5aa6fbaee8fd3579.tar.lz gsoc2013-evolution-f01589262ca132b980bb067e5aa6fbaee8fd3579.tar.xz gsoc2013-evolution-f01589262ca132b980bb067e5aa6fbaee8fd3579.tar.zst gsoc2013-evolution-f01589262ca132b980bb067e5aa6fbaee8fd3579.zip |
Fixes for changes to search bar. (search_save): Removed. (search_full):
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.
svn path=/trunk/; revision=8438
Diffstat (limited to 'mail')
-rw-r--r-- | mail/ChangeLog | 41 | ||||
-rw-r--r-- | mail/folder-browser.c | 279 | ||||
-rw-r--r-- | mail/folder-browser.h | 4 | ||||
-rw-r--r-- | mail/mail-mt.c | 70 | ||||
-rw-r--r-- | mail/mail-send-recv.c | 135 | ||||
-rw-r--r-- | mail/mail-vfolder.c | 14 | ||||
-rw-r--r-- | mail/mail-vfolder.h | 1 | ||||
-rw-r--r-- | mail/main.c | 18 |
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)); |