diff options
author | Harish Krishnaswamy <kharish@novell.com> | 2006-06-30 17:46:32 +0800 |
---|---|---|
committer | Harish Krishnaswamy <kharish@src.gnome.org> | 2006-06-30 17:46:32 +0800 |
commit | a1d6678af2c9f8a075d9d7832c2a6da981afe216 (patch) | |
tree | 9004c48377a85caf85ce21a5f91df6f18bd3ca7c /mail | |
parent | efd7b846b86bafc3efc361a316b9fd204a75ac89 (diff) | |
download | gsoc2013-evolution-a1d6678af2c9f8a075d9d7832c2a6da981afe216.tar gsoc2013-evolution-a1d6678af2c9f8a075d9d7832c2a6da981afe216.tar.gz gsoc2013-evolution-a1d6678af2c9f8a075d9d7832c2a6da981afe216.tar.bz2 gsoc2013-evolution-a1d6678af2c9f8a075d9d7832c2a6da981afe216.tar.lz gsoc2013-evolution-a1d6678af2c9f8a075d9d7832c2a6da981afe216.tar.xz gsoc2013-evolution-a1d6678af2c9f8a075d9d7832c2a6da981afe216.tar.zst gsoc2013-evolution-a1d6678af2c9f8a075d9d7832c2a6da981afe216.zip |
Enhanced search functionality. patch submitted by Johnny Jacob Reviewed
2006-06-30 Harish Krishnaswamy <kharish@novell.com>
Enhanced search functionality. patch submitted by Johnny Jacob
Reviewed and committed by Harish.
svn path=/trunk/; revision=32207
Diffstat (limited to 'mail')
-rw-r--r-- | mail/ChangeLog | 22 | ||||
-rw-r--r-- | mail/em-folder-browser.c | 617 | ||||
-rw-r--r-- | mail/em-folder-browser.h | 4 | ||||
-rw-r--r-- | mail/em-folder-view.c | 5 | ||||
-rw-r--r-- | mail/em-format-html-display.c | 256 | ||||
-rw-r--r-- | mail/em-format-html-display.h | 4 | ||||
-rw-r--r-- | mail/mail-component.c | 40 | ||||
-rw-r--r-- | mail/mail-vfolder.c | 101 | ||||
-rw-r--r-- | mail/message-list.c | 36 | ||||
-rw-r--r-- | mail/message-list.etspec | 2 |
10 files changed, 935 insertions, 152 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index ebf18e842e..4f74e3823a 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,25 @@ +2006-06-30 Johnny Jacob <jjohnny@novell.com> + * mail/em-folder-browser.h: Added search_activated signal + * mail/em-folder-view.c: (emfv_init): + * mail/em-format-html-display.c: (efhd_search_response), + (efhd_search_response_back), (efhd_search_destroy), + (efhd_search_case_toggled), (efhd_key_pressed), + (clear_button_clicked_cb), (icon_entry_changed_cb), + (em_format_html_get_search_dialog), (set_focus_cb), + (em_format_html_display_search), + (em_format_html_display_search_with), + (em_format_html_display_search_close): + * mail/em-format-html-display.h: + * mail/mail-component.c: (disable_folder_tree), + (enable_folder_tree), (impl_createView): + * mail/mail-vfolder.c: (mail_vfolder_add_uri), + (mail_vfolder_get_sources_local), + (mail_vfolder_get_sources_remote), (store_folder_renamed): + * mail/message-list.c: (ml_tree_value_at), + (message_list_setup_etree): + * mail/message-list.etspec: + Added code for search ui. + 2006-06-27 Matthew Barnes <mbarnes@redhat.com> * evolution-mail.schemas.in.in: diff --git a/mail/em-folder-browser.c b/mail/em-folder-browser.c index 0493035075..f15df9984c 100644 --- a/mail/em-folder-browser.c +++ b/mail/em-folder-browser.c @@ -60,6 +60,8 @@ #include <camel/camel-stream.h> #include <camel/camel-url.h> +#include <camel/camel-vee-folder.h> +#include <camel/camel-vee-store.h> #include <bonobo/bonobo-main.h> #include <bonobo/bonobo-object.h> @@ -74,6 +76,7 @@ #include "em-vfolder-rule.h" #include <misc/e-filter-bar.h> #include <camel/camel-search-private.h> +#include <camel/camel-store.h> #include "e-util/e-dialog-utils.h" #include "e-util/e-error.h" @@ -94,6 +97,9 @@ #include "evolution-shell-component-utils.h" /* Pixmap stuff, sigh */ +extern CamelSession *session; +CamelStore *vfolder_store; /* the 1 static vfolder store */ + #define d(x) struct _EMFolderBrowserPrivate { @@ -122,6 +128,7 @@ struct _EMFolderBrowserPrivate { static void emfb_activate(EMFolderView *emfv, BonoboUIComponent *uic, int state); static void emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const char *uri); +static void emfb_set_search_folder(EMFolderView *emfv, CamelFolder *folder, const char *uri); /* FilterBar stuff ... */ static void emfb_search_config_search(EFilterBar *efb, FilterRule *rule, int id, const char *query, void *data); @@ -135,17 +142,70 @@ static void emfb_list_message_selected (MessageList *ml, const char *uid, EMFold static const EMFolderViewEnable emfb_enable_map[]; enum { + ACCOUNT_SEARCH_ACTIVATED, + ACCOUNT_SEARCH_CLEARED, + LAST_SIGNAL +}; + +static guint folder_browser_signals [LAST_SIGNAL] = {0, }; + +enum { ESB_SAVE, }; static ESearchBarItem emfb_search_items[] = { E_FILTERBAR_ADVANCED, - { NULL, 0, NULL }, + { NULL, 0, 0 }, E_FILTERBAR_SAVE, E_FILTERBAR_EDIT, - { NULL, 0, NULL }, - { N_("C_reate Search Folder From Search..."), ESB_SAVE, NULL }, - { NULL, -1, NULL } + { NULL, 0, 0 }, + { N_("C_reate Search Folder From Search..."), ESB_SAVE, 0}, + { NULL, -1, 0 } +}; + +/* IDs and option items for the ESearchBar */ +enum { + VIEW_ALL_MESSAGES, + VIEW_UNREAD_MESSAGES, + VIEW_READ_MESSAGES, + VIEW_RECENT_MESSAGES, + VIEW_LAST_FIVE_DAYS, + VIEW_WITH_ATTACHMENTS, + VIEW_NOT_JUNK, + VIEW_NO_LABEL, + VIEW_LABEL, + VIEW_ANY_FIELD_CONTAINS, + VIEW_CUSTOMIZE +}; + +/* Options for View */ +static ESearchBarItem emfb_view_items[] = { + { N_("All Messages"), VIEW_ALL_MESSAGES, 0 }, + { N_("Unread Messages"), VIEW_UNREAD_MESSAGES, 0 }, + { NULL, 0, 0 }, + { N_("No Label"),VIEW_NO_LABEL, 0 }, + { NULL, -1, 0 } +}; + +/* TODO: Following options should be customizable */ +static ESearchBarItem temp_view_items[] = { + { NULL, 0, 0 }, + { N_("Read Messages"), VIEW_READ_MESSAGES, 0 }, + { N_("Recent Messages"), VIEW_RECENT_MESSAGES, 0 }, + { N_("Last 5 Days Messages"), VIEW_LAST_FIVE_DAYS, 0 }, + { N_("Messages with Attachments"), VIEW_WITH_ATTACHMENTS, 0 }, + { N_("Messages Not Junk"), VIEW_NOT_JUNK, 0 }, +/* { NULL, 0, NULL }, */ +/* { N_("Customize"), NOT_IMPLEMENTED, NULL }, */ + { NULL, -1, 0 } +}; + +static ESearchBarItem emfb_search_scope_items[] = { + E_FILTERBAR_ALL_ACCOUNTS, + E_FILTERBAR_CURRENT_ACCOUNT, + E_FILTERBAR_CURRENT_FOLDER, + E_FILTERBAR_CURRENT_MESSAGE, + { NULL, -1, 0 } }; static EMFolderViewClass *emfb_parent; @@ -189,12 +249,136 @@ free_one_ui_file (gpointer data, g_free (data); } +static char * +string_without_underscores (const char *s) +{ + char *new_string; + const char *sp; + char *dp; + + new_string = g_malloc (strlen (s) + 1); + + dp = new_string; + for (sp = s; *sp != '\0'; sp ++) { + if (*sp != '_') { + *dp = *sp; + dp ++; + } else if (sp[1] == '_') { + /* Translate "__" in "_". */ + *dp = '_'; + dp ++; + sp ++; + } + } + *dp = 0; + + return new_string; +} + +static GtkWidget * +generate_viewoption_menu () +{ + GtkWidget *menu, *menu_item; + gint i = 0; + GSList *l; + + menu = gtk_menu_new (); + + for (i = 0; emfb_view_items[i].id != -1; ++i) { + if (emfb_view_items[i].text) { + char *str; + str = string_without_underscores (emfb_view_items[i].text); + menu_item = gtk_menu_item_new_with_label (str); + g_free (str); + } else { + menu_item = gtk_menu_item_new (); + gtk_widget_set_sensitive (menu_item, FALSE); + } + + g_object_set_data (G_OBJECT (menu_item), "EsbItemId", + GINT_TO_POINTER (emfb_view_items[i].id)); + + gtk_widget_show (menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); + } + + /* Add the labels */ + for (l = mail_config_get_labels(); l; l = l->next) { + MailConfigLabel *label = l->data; + if (label->name && *(label->name)) { + char *str; + str = string_without_underscores (label->name); + menu_item = gtk_menu_item_new_with_label (str); + g_free (str); + + g_object_set_data (G_OBJECT (menu_item), "EsbItemId", + GINT_TO_POINTER (VIEW_LABEL)); + + g_object_set_data (G_OBJECT (menu_item), "LabelTag", + g_strdup(label->tag)); + } + + gtk_widget_show (menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); + } + + for (i = 0; temp_view_items[i].id != -1; ++i) { + if (temp_view_items[i].text) { + char *str; + str = string_without_underscores (temp_view_items[i].text); + menu_item = gtk_menu_item_new_with_label (str); + g_free (str); + } else { + menu_item = gtk_menu_item_new (); + gtk_widget_set_sensitive (menu_item, FALSE); + } + + g_object_set_data (G_OBJECT (menu_item), "EsbItemId", + GINT_TO_POINTER (temp_view_items[i].id)); + + gtk_widget_show (menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); + } + + return menu; +} + + +static GArray * +viewoption_menu_generator () +{ + GArray *menu = g_array_new (FALSE, FALSE, sizeof (ESearchBarItem)); + gint i = 0; + ESearchBarItem dup_item; + GSList *l; + + for (i = 0; emfb_view_items[i].id != -1; i++) + g_array_append_vals (menu, &emfb_view_items[i], 1); + + for (l = mail_config_get_labels(); l; l = l->next) { + ESearchBarItem item; + MailConfigLabel *label = l->data; + + item.text = label->name; + item.id = VIEW_LABEL; + + g_array_append_vals (menu, &item, 1); + } + + dup_item.id = -1; + dup_item.text = NULL; + g_array_append_vals (menu, &dup_item, 1); + + return menu; +} + static void emfb_init(GObject *o) { EMFolderBrowser *emfb = (EMFolderBrowser *)o; RuleContext *search_context = mail_component_peek_search_context (mail_component_peek ()); struct _EMFolderBrowserPrivate *p; + GtkWidget *menu; p = emfb->priv = g_malloc0(sizeof(struct _EMFolderBrowserPrivate)); @@ -222,9 +406,13 @@ emfb_init(GObject *o) if (search_context) { const char *systemrules = g_object_get_data (G_OBJECT (search_context), "system"); const char *userrules = g_object_get_data (G_OBJECT (search_context), "user"); - + emfb->search = e_filter_bar_new(search_context, systemrules, userrules, emfb_search_config_search, emfb); e_search_bar_set_menu ((ESearchBar *)emfb->search, emfb_search_items); + e_search_bar_set_scopeoption ((ESearchBar *)emfb->search, emfb_search_scope_items); + + menu = generate_viewoption_menu(); + e_search_bar_set_viewoption_menu ((ESearchBar *)emfb->search, menu); gtk_widget_show((GtkWidget *)emfb->search); p->search_menu_activated_id = g_signal_connect(emfb->search, "menu_activated", G_CALLBACK(emfb_search_menu_activated), emfb); @@ -261,6 +449,7 @@ emfb_init(GObject *o) g_signal_connect (((EMFolderView *) emfb)->list->tree, "key_press", G_CALLBACK(emfb_list_key_press), emfb); g_signal_connect (((EMFolderView *) emfb)->list, "message_selected", G_CALLBACK (emfb_list_message_selected), emfb); + } static void @@ -305,6 +494,27 @@ emfb_class_init(GObjectClass *klass) { klass->finalize = emfb_finalise; + folder_browser_signals[ACCOUNT_SEARCH_ACTIVATED] = + g_signal_new ("account_search_activated", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EMFolderBrowserClass, account_search_activated), + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + folder_browser_signals[ACCOUNT_SEARCH_CLEARED] = + g_signal_new ("account_search_cleared", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EMFolderBrowserClass, account_search_cleared), + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + ((GtkObjectClass *)klass)->destroy = emfb_destroy; ((EMFolderViewClass *)klass)->set_folder = emfb_set_folder; ((EMFolderViewClass *)klass)->activate = emfb_activate; @@ -465,7 +675,7 @@ emfb_search_config_search(EFilterBar *efb, FilterRule *rule, int id, const char struct _camel_search_words *words; int i; GSList *strings = NULL; - + /* we scan the parts of a rule, and set all the types we know about to the query string */ partl = rule->parts; while (partl) { @@ -502,40 +712,360 @@ emfb_search_config_search(EFilterBar *efb, FilterRule *rule, int id, const char strings); while (strings) { GSList *n = strings->next; - g_free(strings->data); g_slist_free_1(strings); strings = n; } } +static char * +get_view_query (ESearchBar *esb) +{ + char *view_sexp = NULL; + gint id; + GtkWidget *menu_item; + char *tag; + + /* Get the current selected view */ + id = e_search_bar_get_viewitem_id (esb); + menu_item = e_search_bar_get_selected_viewitem (esb); + + switch (id) { + case VIEW_ALL_MESSAGES: + view_sexp = " "; + break; + + case VIEW_UNREAD_MESSAGES: + view_sexp = "(match-all (not (system-flag \"Seen\")))"; + break; + case VIEW_READ_MESSAGES: + view_sexp = "(match-all (system-flag \"Seen\"))"; + break; + case VIEW_RECENT_MESSAGES: + view_sexp = "(match-all (> (get-received-date) (- (get-current-date) 86400)))"; + break; + case VIEW_LAST_FIVE_DAYS: + view_sexp = " (match-all (> (get-received-date) (- (get-current-date) 432000)))"; + break; + case VIEW_WITH_ATTACHMENTS: + view_sexp = "(match-all (system-flag \"Attachments\"))"; + break; + case VIEW_NOT_JUNK: + view_sexp = "(match-all (not (system-flag \"junk\")))"; + break; + case VIEW_NO_LABEL: + /* FIXME : cannot hard code this query */ + view_sexp = "(and (match-all (not (= (user-tag \"label\") \"important\")))" + "(match-all (not (= (user-tag \"label\") \"work\"))) (match-all (not (= (user-tag \"label\") \"personal\")))" + "(match-all (not (= (user-tag \"label\") \"todo\"))) (match-all (not (= (user-tag \"label\") \"later\"))) ))"; + break; + case VIEW_LABEL: + tag = (char *)g_object_get_data (G_OBJECT (menu_item), "LabelTag"); + view_sexp = g_strdup_printf ("(match-all (= (user-tag \"label\") \"%s\"))",tag); + break; + case VIEW_ANY_FIELD_CONTAINS: + break; + + case VIEW_CUSTOMIZE: + view_sexp = " "; + break; + } + return view_sexp; +} + + +struct _setup_msg { + struct _mail_msg msg; + + CamelFolder *folder; + char *query; + GList *sources_uri; + GList *sources_folder; +}; + +static char * +vfolder_setup_desc(struct _mail_msg *mm, int done) +{ + struct _setup_msg *m = (struct _setup_msg *)mm; + + return g_strdup(_("Searching")); +} + +static void +vfolder_setup_do(struct _mail_msg *mm) +{ + struct _setup_msg *m = (struct _setup_msg *)mm; + GList *l, *list = NULL; + CamelFolder *folder; + + d(printf("Setting up Search Folder: %s\n", m->folder->full_name)); + + camel_vee_folder_set_expression((CamelVeeFolder *)m->folder, m->query); + + l = m->sources_uri; + while (l) { + d(printf(" Adding uri: %s\n", (char *)l->data)); + folder = mail_tool_uri_to_folder (l->data, 0, &mm->ex); + if (folder) { + list = g_list_append(list, folder); + } else { + g_warning("Could not open vfolder source: %s", (char *)l->data); + camel_exception_clear(&mm->ex); + } + l = l->next; + } + + l = m->sources_folder; + while (l) { + d(printf(" Adding folder: %s\n", ((CamelFolder *)l->data)->full_name)); + camel_object_ref(l->data); + list = g_list_append(list, l->data); + l = l->next; + } + + camel_vee_folder_set_folders((CamelVeeFolder *)m->folder, list); + + l = list; + while (l) { + camel_object_unref(l->data); + l = l->next; + } + g_list_free(list); +} + +static void +vfolder_setup_done(struct _mail_msg *mm) +{ + struct _setup_msg *m = (struct _setup_msg *)mm; + + m = m; +} + +static void +vfolder_setup_free (struct _mail_msg *mm) +{ + struct _setup_msg *m = (struct _setup_msg *)mm; + GList *l; + + camel_object_unref(m->folder); + g_free(m->query); + + l = m->sources_uri; + while (l) { + g_free(l->data); + l = l->next; + } + g_list_free(m->sources_uri); + + l = m->sources_folder; + while (l) { + camel_object_unref(l->data); + l = l->next; + } + g_list_free(m->sources_folder); +} + +static struct _mail_msg_op vfolder_setup_op = { + vfolder_setup_desc, + vfolder_setup_do, + vfolder_setup_done, + vfolder_setup_free, +}; + +/* sources_uri should be camel uri's */ +static int +vfolder_setup(CamelFolder *folder, const char *query, GList *sources_uri, GList *sources_folder) +{ + struct _setup_msg *m; + int id; + + m = mail_msg_new(&vfolder_setup_op, NULL, sizeof (*m)); + m->folder = folder; + camel_object_ref(folder); + m->query = g_strdup(query); + m->sources_uri = sources_uri; + m->sources_folder = sources_folder; + + id = m->msg.seq; + e_thread_put(mail_thread_queued_slow, (EMsg *)m); + + return id; +} + static void emfb_search_search_activated(ESearchBar *esb, EMFolderBrowser *emfb) { EMFolderView *emfv = (EMFolderView *) emfb; - char *search_word, *search_state; - + EFilterBar *efb = (EFilterBar *)esb; + char *search_state, *view_sexp, *folder_uri; + char *word = NULL, *storeuri = NULL, *search_word = NULL;; + gint id, i; + CamelFolder *folder; + CamelStore *store; + GPtrArray *folders; + GList *folder_list_account = NULL ; + GList *l, *folder_list = NULL ; + CamelException *ex; + + ex = camel_exception_new (); + if (emfv->list == NULL || emfv->folder == NULL) return; + id = e_search_bar_get_search_scope (esb); + + switch (id) { + case E_FILTERBAR_CURRENT_MESSAGE_ID: + word = e_search_bar_get_text (esb); + if ( word && *word ) { + gtk_widget_set_sensitive (esb->option_button, FALSE); + em_format_html_display_search_with (emfb->view.preview, word); + } else { + em_format_html_display_search_close (emfb->view.preview); + } + return; + break; + + case E_FILTERBAR_CURRENT_FOLDER_ID: + g_object_get (esb, "query", &search_word, NULL); + break; + + case E_FILTERBAR_CURRENT_ACCOUNT_ID: + word = e_search_bar_get_text (esb); + if (!(word && *word)) { + g_signal_emit (emfb, folder_browser_signals [ACCOUNT_SEARCH_CLEARED], 0); + gtk_widget_set_sensitive (esb->scopeoption, TRUE); + break; + } + + gtk_widget_set_sensitive (esb->scopeoption, FALSE); + + /* Disable the folder tree */ + g_signal_emit (emfb, folder_browser_signals [ACCOUNT_SEARCH_ACTIVATED], 0); + + store = emfv->folder->parent_store; + if (store->folders) { + folders = camel_object_bag_list(store->folders); + for (i=0;i<folders->len;i++) { + folder = folders->pdata[i]; + folder_list_account = g_list_append(folder_list_account, folder); + } + } + + /* Create a camel vee folder */ + storeuri = g_strdup_printf("vfolder:%s/mail/vfolder", mail_component_peek_base_directory (mail_component_peek ())); + vfolder_store = camel_session_get_store (session, storeuri, NULL); + efb->account_search_vf = camel_vee_folder_new (vfolder_store,"Account Search",CAMEL_STORE_VEE_FOLDER_AUTO); + + /* Set the search expression */ + g_object_get (esb, "query", &search_word, NULL); + + vfolder_setup (efb->account_search_vf, search_word, NULL, folder_list_account); + + folder_uri = mail_tools_folder_to_url ((CamelFolder *)efb->account_search_vf); + emfb_set_search_folder (emfv, (CamelFolder *)efb->account_search_vf, folder_uri); + +/* g_list_free (folder_list_account); */ +/* g_free (folder_uri); */ +/* g_free (storeuri); */ + break; + + case E_FILTERBAR_ALL_ACCOUNTS_ID: + word = e_search_bar_get_text (esb); + if (!(word && *word)) { + g_signal_emit (emfb, folder_browser_signals [ACCOUNT_SEARCH_CLEARED], 0); + gtk_widget_set_sensitive (esb->scopeoption, TRUE); + break; + } + + gtk_widget_set_sensitive (esb->scopeoption, FALSE); + g_signal_emit (emfb, folder_browser_signals [ACCOUNT_SEARCH_ACTIVATED], 0); + + /* Create a camel vee folder */ + storeuri = g_strdup_printf("vfolder:%s/mail/vfolder", mail_component_peek_base_directory (mail_component_peek ())); + vfolder_store = camel_session_get_store (session, storeuri, NULL); + efb->all_account_search_vf = camel_vee_folder_new (vfolder_store,"All Account Search",CAMEL_STORE_VEE_FOLDER_AUTO); + + /* Set sexp */ + g_object_get (esb, "query", &search_word, NULL); + + /* FIXME: there got to be a better way :) */ + + /* Add the local folders */ + l = mail_vfolder_get_sources_local (); + while (l) { + folder = mail_tool_uri_to_folder ((const char *)l->data, 0,ex); + if (folder) + folder_list = g_list_append(folder_list, folder); + else { + g_warning("Could not open vfolder source: %s", (char *)l->data); + camel_exception_clear(ex); + } + l = l->next; + } + + /* Add the remote source folder */ + l = mail_vfolder_get_sources_remote (); + while (l) { + folder = mail_tool_uri_to_folder ((const char *)l->data, 0,ex); + if (folder) + folder_list = g_list_append(folder_list, folder); + else { + g_warning("Could not open vfolder source: %s", (char *)l->data); + camel_exception_clear(ex); + } + l = l->next; + } + + vfolder_setup (efb->all_account_search_vf, search_word, NULL, folder_list); + + folder_uri = mail_tools_folder_to_url ((CamelFolder *)efb->all_account_search_vf); + emfb_set_search_folder (emfv, (CamelFolder *)efb->all_account_search_vf, folder_uri); + + g_list_free (l); + break; + } + + /* Merge the view and search expresion*/ + view_sexp = get_view_query (esb); g_object_get (esb, "query", &search_word, NULL); + + if (search_word && *search_word) + search_word = g_strconcat ("(and ", view_sexp, search_word, " )", NULL); + else + search_word = g_strdup (view_sexp); + message_list_set_search(emfb->view.list, search_word); - g_free (search_word); - + + /* Fixme */ g_object_get (esb, "state", &search_state, NULL); camel_object_meta_set (emfv->folder, "evolution:search_state", search_state); camel_object_state_write (emfv->folder); - g_free (search_state); + + camel_exception_free (ex); } static void emfb_search_query_changed(ESearchBar *esb, EMFolderBrowser *emfb) { - int id; + int search_scope; + int item_id; + + search_scope = e_search_bar_get_search_scope (esb); + item_id = e_search_bar_get_item_id (esb); + + /* Close the current message search bar */ + if ( search_scope != E_FILTERBAR_CURRENT_MESSAGE_ID ) { + em_format_html_display_search_close (emfb->view.preview); + gtk_widget_set_sensitive (esb->option_button, TRUE); + } else + gtk_widget_set_sensitive (esb->option_button, FALSE); - id = e_search_bar_get_item_id(esb); - if (id == E_FILTERBAR_ADVANCED_ID) - emfb_search_search_activated(esb, emfb); + switch (item_id) { + case E_FILTERBAR_ADVANCED_ID: + emfb_search_search_activated(esb, emfb); + break; + } } /* ********************************************************************** */ @@ -581,12 +1111,12 @@ emfb_edit_cut(BonoboUIComponent *uid, void *data, const char *path) /* TODO: pity we can't sucblass this method, ugh, virtualise it? */ - if (GTK_WIDGET_HAS_FOCUS(((ESearchBar *)emfb->search)->entry)) - gtk_editable_cut_clipboard((GtkEditable *)((ESearchBar *)emfb->search)->entry); - else if (GTK_WIDGET_HAS_FOCUS(emfb->view.preview->formathtml.html)) - em_format_html_display_cut(emfb->view.preview); - else - message_list_copy(emfb->view.list, TRUE); +/* if (GTK_HAS_FOCUS(((ESearchBar *)emfb->search)->entry)) */ +/* gtk_editable_cut_clipboard((GtkEditable *)((ESearchBar *)emfb->search)->entry); */ +/* else if (GTK_WIDGET_HAS_FOCUS(emfb->view.preview->formathtml.html)) */ +/* em_format_html_display_cut(emfb->view.preview); */ +/* else */ +/* message_list_copy(emfb->view.list, TRUE); */ } static void @@ -1143,6 +1673,42 @@ emfb_list_built (MessageList *ml, EMFolderBrowser *emfb) } static void +emfb_set_search_folder(EMFolderView *emfv, CamelFolder *folder, const char *uri) +{ + EMFolderBrowser *emfb = (EMFolderBrowser *) emfv; + + message_list_freeze(emfv->list); + + if (emfb->priv->list_scrolled_id) { + g_signal_handler_disconnect (emfv->list, emfb->priv->list_scrolled_id); + emfb->priv->list_scrolled_id = 0; + } + + if (emfb->priv->idle_scroll_id) { + g_source_remove (emfb->priv->idle_scroll_id); + emfb->priv->idle_scroll_id = 0; + } + + if (emfb->view.folder) { + camel_object_remove_event(emfb->view.folder, emfb->priv->folder_changed_id); + emfb->priv->folder_changed_id = 0; + } + + emfb_parent->set_folder(emfv, folder, uri); + + /* etspec for search results */ + char *state = "<ETableState>" + "<column source=\"0\"/> <column source=\"3\"/> <column source=\"1\"/>" + "<column source=\"14\"/> <column source=\"5\"/>" + "<column source=\"7\"/> <column source=\"13\"/> " + "<grouping> </grouping> </ETableState>"; + e_tree_set_state (((MessageList *)emfv->list)->tree, state); + + message_list_thaw(emfv->list); +} + + +static void emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const char *uri) { EMFolderBrowser *emfb = (EMFolderBrowser *) emfv; @@ -1207,9 +1773,10 @@ emfb_set_folder(EMFolderView *emfv, CamelFolder *folder, const char *uri) bonobo_ui_component_set_prop(emfv->uic, "/commands/HideDeleted", "sensitive", state?"1":"0", NULL); } - sstate = camel_object_meta_get(folder, "evolution:search_state"); - g_object_set(emfb->search, "state", sstate, NULL); - g_free(sstate); + /* Fixme */ +/* sstate = camel_object_meta_get(folder, "evolution:search_state"); */ +/* g_object_set(emfb->search, "state", sstate, NULL); */ +/* g_free(sstate); */ /* set the query manually, so we dont pop up advanced or saved search stuff */ g_object_get(emfb->search, "query", &sstate, NULL); diff --git a/mail/em-folder-browser.h b/mail/em-folder-browser.h index f31f78fd93..d09bf91cd3 100644 --- a/mail/em-folder-browser.h +++ b/mail/em-folder-browser.h @@ -44,6 +44,10 @@ struct _EMFolderBrowser { struct _EMFolderBrowserClass { EMFolderViewClass parent_class; + + /* Signals*/ + void (*account_search_activated) (EMFolderBrowser *emfb); + void (*account_search_cleared) (EMFolderBrowser *emfb); }; GType em_folder_browser_get_type(void); diff --git a/mail/em-folder-view.c b/mail/em-folder-view.c index 4c0c225393..c4479a1054 100644 --- a/mail/em-folder-view.c +++ b/mail/em-folder-view.c @@ -91,6 +91,7 @@ #include "em-folder-view.h" #include "em-folder-browser.h" #include "em-mailer-prefs.h" +#include "em-folder-browser.h" #include "em-message-browser.h" #include "message-list.h" #include "em-utils.h" @@ -185,6 +186,7 @@ emfv_init(GObject *o) EMFolderView *emfv = (EMFolderView *)o; struct _EMFolderViewPrivate *p; extern CamelSession *session; + GtkWidget *search_bar; gtk_box_set_homogeneous (GTK_BOX (emfv), FALSE); @@ -227,6 +229,9 @@ emfv_init(GObject *o) gtk_selection_add_target(p->invisible, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 0); gtk_selection_add_target(p->invisible, GDK_SELECTION_CLIPBOARD, GDK_SELECTION_TYPE_STRING, 1); + search_bar = em_format_html_get_search_dialog (emfv->preview); + gtk_box_pack_end(GTK_WIDGET (emfv), search_bar, FALSE, FALSE, 5); + emfv->async = mail_async_event_new(); emfv_setting_setup(emfv); diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c index 5f9160787a..0708439ee8 100644 --- a/mail/em-format-html-display.c +++ b/mail/em-format-html-display.c @@ -105,6 +105,7 @@ #include "em-popup.h" #include "e-attachment.h" #include "e-attachment-bar.h" +#include "e-icon-entry.h" #ifdef G_OS_WIN32 /* Undefine the similar macro from <pthread.h>,it doesn't check if @@ -123,8 +124,9 @@ struct _EMFormatHTMLDisplayPrivate { /* For the interactive search dialogue */ /* TODO: Should this be more subtle, like the mozilla one? */ - GtkDialog *search_dialog; + GtkHBox *search_dialog; GtkWidget *search_entry; + GtkWidget *search_entry_box; GtkWidget *search_matches_label; GtkWidget *search_case_check; char *search_text; @@ -527,37 +529,67 @@ efhd_update_search(EMFormatHTMLDisplay *efhd) } static void -efhd_search_response(GtkWidget *w, int button, EMFormatHTMLDisplay *efhd) +efhd_search_response(GtkWidget *w, EMFormatHTMLDisplay *efhd) { struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - if (button == GTK_RESPONSE_ACCEPT) { - char *txt = g_strdup(gtk_entry_get_text((GtkEntry *)p->search_entry)); + char *txt = g_strdup(gtk_entry_get_text((GtkEntry *)p->search_entry)); - g_strstrip(txt); - if (p->search_text && strcmp(p->search_text, txt) == 0 && !p->search_wrap) { - if (!gtk_html_engine_search_next(((EMFormatHTML *)efhd)->html)) - p->search_wrap = TRUE; - g_free(txt); - } else { - g_free(p->search_text); - p->search_text = txt; - if (!p->search_wrap) - efhd_update_search(efhd); - p->search_wrap = FALSE; - gtk_html_engine_search(((EMFormatHTML *)efhd)->html, txt, - gtk_toggle_button_get_active((GtkToggleButton *)p->search_case_check), - TRUE, FALSE); - } + g_strstrip(txt); + if (p->search_text && strcmp(p->search_text, txt) == 0 && !p->search_wrap) { + gtk_html_engine_search_set_forward (((EMFormatHTML *)efhd)->html, TRUE); + if (!gtk_html_engine_search_next(((EMFormatHTML *)efhd)->html)) + p->search_wrap = TRUE; + g_free(txt); + } else { + g_free(p->search_text); + p->search_text = txt; + if (!p->search_wrap) + efhd_update_search(efhd); + p->search_wrap = FALSE; + gtk_html_engine_search(((EMFormatHTML *)efhd)->html, txt, + gtk_toggle_button_get_active((GtkToggleButton *)p->search_case_check), + TRUE, FALSE); + } +} + + +static void +efhd_search_response_back (GtkWidget *w, EMFormatHTMLDisplay *efhd) +{ + struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; + + char *txt = g_strdup(gtk_entry_get_text((GtkEntry *)p->search_entry)); + + g_strstrip(txt); + if (p->search_text && strcmp(p->search_text, txt) == 0 && !p->search_wrap) { + gtk_html_engine_search_set_forward (((EMFormatHTML *)efhd)->html, FALSE); + if (!gtk_html_engine_search_next(((EMFormatHTML *)efhd)->html)) + p->search_wrap = TRUE; + g_free(txt); } else { g_free(p->search_text); - p->search_text = NULL; - gtk_widget_destroy((GtkWidget *)p->search_dialog); - p->search_dialog = NULL; - em_format_html_display_set_search(efhd, EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY, NULL); + p->search_text = txt; + if (!p->search_wrap) + efhd_update_search(efhd); + p->search_wrap = FALSE; + gtk_html_engine_search(((EMFormatHTML *)efhd)->html, txt, + gtk_toggle_button_get_active((GtkToggleButton *)p->search_case_check), + FALSE, FALSE); } } + +static void +efhd_search_destroy(GtkWidget *w, EMFormatHTMLDisplay *efhd) +{ + struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; + g_free(p->search_text); + p->search_text = NULL; + gtk_widget_hide((GtkWidget *)p->search_dialog); + em_format_html_display_set_search(efhd, EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY, NULL); +} + static void efhd_search_case_toggled(GtkWidget *w, EMFormatHTMLDisplay *efhd) { @@ -565,13 +597,116 @@ efhd_search_case_toggled(GtkWidget *w, EMFormatHTMLDisplay *efhd) g_free(p->search_text); p->search_text = NULL; - efhd_search_response(w, GTK_RESPONSE_ACCEPT, efhd); + efhd_search_response(w, efhd); } +static gboolean +efhd_key_pressed (GtkWidget *w, GdkEventKey *event, EMFormatHTMLDisplay *efhd) +{ + if (event->keyval == GDK_Escape){ + efhd_search_destroy (w, efhd); + return TRUE; + } + return FALSE; +} + +static void +clear_button_clicked_cb (GtkWidget *widget, gpointer dummy, EMFormatHTMLDisplay *efhd) +{ + struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; + + gtk_entry_set_text (p->search_entry, ""); + + gtk_signal_emit_by_name (p->search_entry, "activate", efhd); +} + +/* Controlls the visibility of icon_entry's visibility */ static void -efhd_search_entry_activate(GtkWidget *w, EMFormatHTMLDisplay *efhd) +icon_entry_changed_cb (GtkWidget *widget, GtkWidget *clear_button) { - efhd_search_response(w, GTK_RESPONSE_ACCEPT, efhd); + const char *text = gtk_entry_get_text (widget); + + if (text && *text) + gtk_widget_show (clear_button); + else + gtk_widget_hide (clear_button); +} + +GtkWidget * +em_format_html_get_search_dialog (EMFormatHTMLDisplay *efhd) +{ + struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; + GtkWidget *hbox3, *hbox2, *button3, *button2, *button1, *label1, *alignment, *image1, *label2; + GtkWidget *icon_entry, *clear_button; + + p->search_entry_box = gtk_hbox_new (FALSE, 0); + + label1 = gtk_label_new (_("Find:")); + gtk_widget_show (label1); + gtk_box_pack_start ((GtkBox *)(p->search_entry_box), label1, FALSE, FALSE, 5); + + /* Icon entry */ + icon_entry = e_icon_entry_new (); + p->search_entry = e_icon_entry_get_entry (E_ICON_ENTRY (icon_entry)); + gtk_widget_show (p->search_entry); + clear_button = e_icon_entry_create_button ("gtk-clear"); + e_icon_entry_pack_widget (E_ICON_ENTRY (icon_entry), clear_button, FALSE); + gtk_widget_show_all (icon_entry); + gtk_widget_hide (clear_button); + + g_signal_connect (G_OBJECT (clear_button), "button-press-event", clear_button_clicked_cb, efhd); + g_signal_connect (G_OBJECT (p->search_entry), "changed", icon_entry_changed_cb, clear_button); + + gtk_box_pack_start ((GtkBox *)(p->search_entry_box), icon_entry, FALSE, FALSE, 0); +// gtk_box_pack_start ((GtkBox *)(p->search_entry_box), icon_entry, TRUE, TRUE, 0); + + hbox2 = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start ((GtkBox *)(hbox2), p->search_entry_box, FALSE, FALSE, 5); +// gtk_box_pack_start ((GtkBox *)(hbox2), p->search_entry_box, TRUE, TRUE, 5); + + button3 = gtk_button_new_from_stock ("gtk-go-back"); + gtk_widget_show (button3); + gtk_box_pack_start ((GtkBox *)(hbox2), button3, FALSE, FALSE, 5); + + button2 = gtk_button_new_from_stock ("gtk-go-forward"); + gtk_widget_show (button2); + gtk_box_pack_start ((GtkBox *)(hbox2), button2, FALSE, FALSE, 5); + + p->search_case_check = gtk_check_button_new_with_mnemonic (_("Match case")); + gtk_widget_show (p->search_case_check); + gtk_box_pack_start ((GtkBox *)(hbox2), p->search_case_check, FALSE, FALSE, 0); + + p->search_matches_label = gtk_label_new (_("")); + gtk_widget_show (p->search_matches_label); + gtk_box_pack_start ((GtkBox *)(hbox2), p->search_matches_label, TRUE, TRUE, 0); + p->search_dialog = (GtkWidget *)hbox2; + + p->search_wrap = FALSE; + + g_signal_connect (p->search_entry, "activate", G_CALLBACK(efhd_search_response), efhd); + g_signal_connect (p->search_entry, "key-press-event", G_CALLBACK(efhd_key_pressed), efhd); + g_signal_connect (p->search_case_check, "toggled", G_CALLBACK(efhd_search_case_toggled), efhd); + g_signal_connect (button2, "clicked", G_CALLBACK(efhd_search_response), efhd); + g_signal_connect (button3, "clicked", G_CALLBACK(efhd_search_response_back), efhd); + + efhd_update_matches(efhd); + + return (GtkWidget *)p->search_dialog; + +} + +static void +set_focus_cb (GtkWidget *window, GtkWidget *widget, EMFormatHTMLDisplay *efhd) +{ + struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; + GtkWidget *sbar = p->search_dialog; + + while (widget != NULL && widget != sbar) { + widget = widget->parent; + } + + if (widget != sbar) + efhd_search_destroy(widget, efhd); } /** @@ -584,45 +719,52 @@ void em_format_html_display_search(EMFormatHTMLDisplay *efhd) { struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - GladeXML *xml; - char *gladefile; - if (p->search_dialog) { - gdk_window_raise(((GtkWidget *)p->search_dialog)->window); - return; - } + if (p->search_dialog){ + GtkWidget *toplevel; + gtk_widget_show ( (GtkWidget *)(p->search_dialog)); + gtk_widget_grab_focus ( (GtkWidget *)(p->search_entry)); + gtk_widget_show ( (GtkWidget *) p->search_entry_box); - gladefile = g_build_filename (EVOLUTION_GLADEDIR, - "mail-dialogs.glade", - NULL); - xml = glade_xml_new (gladefile, "search_message_dialog", NULL); - g_free (gladefile); + toplevel = gtk_widget_get_toplevel ((GtkWidget *)(p->search_dialog)); - if (xml == NULL) { - g_warning("Cannot open search dialog glade file"); - /* ?? */ - return; + g_signal_connect (toplevel, "set-focus", + G_CALLBACK (set_focus_cb), efhd); } - /* TODO: The original put the subject in the frame, but it had some - ugly arbitrary string-cutting code to make sure it fit. */ +} +/** + * em_format_html_display_search_with: + * @efhd: + * + * Run an interactive search dialogue. + **/ +void +em_format_html_display_search_with (EMFormatHTMLDisplay *efhd, char *word) +{ + struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; + char *str; - p->search_dialog = (GtkDialog *)glade_xml_get_widget(xml, "search_message_dialog"); - p->search_entry = glade_xml_get_widget(xml, "search_entry"); - p->search_matches_label = glade_xml_get_widget(xml, "search_matches_label"); - p->search_case_check = glade_xml_get_widget(xml, "search_case_check"); - p->search_wrap = FALSE; + if (p->search_dialog){ + GtkWidget *toplevel; + gtk_widget_show ( (GtkWidget *)(p->search_dialog)); + + /* Set the query */ + gtk_entry_set_text ( (GtkWidget *) p->search_entry, word); + gtk_widget_hide ( (GtkWidget *) p->search_entry_box); - gtk_dialog_set_default_response((GtkDialog *)p->search_dialog, GTK_RESPONSE_ACCEPT); - e_dialog_set_transient_for ((GtkWindow *) p->search_dialog, (GtkWidget *) ((EMFormatHTML *) efhd)->html); - gtk_window_set_destroy_with_parent ((GtkWindow *) p->search_dialog, TRUE); - efhd_update_matches(efhd); + /* Trigger the search */ + gtk_signal_emit_by_name (p->search_entry, "activate", efhd); + } +} + +void +em_format_html_display_search_close (EMFormatHTMLDisplay *efhd) +{ + struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - g_signal_connect(p->search_entry, "activate", G_CALLBACK(efhd_search_entry_activate), efhd); - g_signal_connect(p->search_case_check, "toggled", G_CALLBACK(efhd_search_case_toggled), efhd); - g_signal_connect(p->search_dialog, "response", G_CALLBACK(efhd_search_response), efhd); - gtk_widget_show((GtkWidget *)p->search_dialog); - gtk_widget_hide((GtkWidget *)p->search_matches_label); + if (p->search_dialog) + efhd_search_destroy(p->search_dialog, efhd); } void diff --git a/mail/em-format-html-display.h b/mail/em-format-html-display.h index c1aa050c70..be84decc11 100644 --- a/mail/em-format-html-display.h +++ b/mail/em-format-html-display.h @@ -51,6 +51,10 @@ void em_format_html_display_set_caret_mode(EMFormatHTMLDisplay *efhd, gboolean s void em_format_html_display_set_search(EMFormatHTMLDisplay *efhd, int type, GSList *strings); void em_format_html_display_search(EMFormatHTMLDisplay *efhd); +void em_format_html_display_search_with (EMFormatHTMLDisplay *efhd, char *word); +void em_format_html_display_search_close (EMFormatHTMLDisplay *efhd); + +GtkWidget *em_format_html_get_search_dialog (EMFormatHTMLDisplay *efhd); void em_format_html_display_cut (EMFormatHTMLDisplay *efhd); void em_format_html_display_copy (EMFormatHTMLDisplay *efhd); diff --git a/mail/mail-component.c b/mail/mail-component.c index 43e469b78b..1318db581f 100644 --- a/mail/mail-component.c +++ b/mail/mail-component.c @@ -618,6 +618,43 @@ view_changed_cb(EMFolderView *emfv, EComponentView *component_view) g_object_set_data((GObject *)emfv, "view-changed-timeout", GINT_TO_POINTER(g_timeout_add(250, view_changed_timeout, component_view))); } +static void +disable_folder_tree (gpointer *emfb, gpointer dummy, GtkWidget *widget) +{ + gtk_widget_set_sensitive (widget, FALSE); +} + +static void +enable_folder_tree (GtkWidget *emfb, gpointer dum, GtkWidget *emft) +{ + char *uri; + CamelURL *selected_curl, *current_curl; + CamelFolder *folder; + CamelException ex; + EMFolderView *emfv = (EMFolderView *)emfb; + + /* Currently displayed folder */ + MessageList *ml = emfv->list; + folder = ml->folder; + uri = mail_tools_folder_to_url (folder); + current_curl = camel_url_new (uri, NULL); + + /* Selected folder in emft*/ + uri = em_folder_tree_get_selected_uri ((EMFolderTree *) emft); + folder = mail_tool_uri_to_folder (uri, 0, &ex); + selected_curl = camel_url_new (uri, NULL); + + if (!camel_url_equal (selected_curl, current_curl)) + g_signal_emit_by_name (emft, "folder-selected", emft, uri, folder->full_name, uri, folder->folder_flags); + + gtk_widget_set_sensitive (emft, TRUE); + + camel_url_free (current_curl); + camel_url_free (selected_curl); + g_free (uri); + +} + /* Evolution::Component CORBA methods. */ static GNOME_Evolution_ComponentView @@ -676,9 +713,12 @@ impl_createView (PortableServer_Servant servant, e_user_creatable_items_handler_new("mail", create_local_item_cb, tree_widget), (GDestroyNotify)g_object_unref); + g_signal_connect (component_view->view_control, "activate", G_CALLBACK (view_control_activate_cb), view_widget); g_signal_connect (tree_widget, "folder-selected", G_CALLBACK (folder_selected_cb), view_widget); + g_signal_connect((EMFolderBrowser *)view_widget, "account_search_cleared", G_CALLBACK (enable_folder_tree), tree_widget); + g_signal_connect(((EMFolderBrowser *)view_widget), "account_search_activated", G_CALLBACK (disable_folder_tree), tree_widget); g_signal_connect(view_widget, "changed", G_CALLBACK(view_changed_cb), component_view); g_signal_connect(view_widget, "loaded", G_CALLBACK(view_changed_cb), component_view); diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c index 66b29de918..727ed89866 100644 --- a/mail/mail-vfolder.c +++ b/mail/mail-vfolder.c @@ -49,7 +49,7 @@ #include "mail-tools.h" #include "mail-vfolder.h" -#define d(x) /*(printf("%s(%d):%s: ", __FILE__, __LINE__, __PRETTY_FUNCTION__), (x))*/ +#define d(x) /* (printf("%s(%d):%s: ", __FILE__, __LINE__, __PRETTY_FUNCTION__), (x))*/ static EMVFolderContext *context; /* context remains open all time */ CamelStore *vfolder_store; /* the 1 static vfolder store */ @@ -453,8 +453,8 @@ mail_vfolder_add_uri(CamelStore *store, const char *curi, int remove) LOCK(); - d(printf("%s uri to check: %s\n", remove?"Removing":"Adding", uri)); - +/* d(printf("%s uri to check: %s\n", remove?"Removing":"Adding", uri)); */ + /* maintain the source folders lists for changed rules later on */ if (CAMEL_IS_VEE_STORE(store)) { is_ignore = TRUE; @@ -489,7 +489,6 @@ mail_vfolder_add_uri(CamelStore *store, const char *curi, int remove) d(printf("invalid rule (%p): rule->name is set to NULL\n", rule)); continue; } - /* dont auto-add any sent/drafts folders etc, they must be explictly listed as a source */ if (rule->source && !is_ignore @@ -501,7 +500,6 @@ mail_vfolder_add_uri(CamelStore *store, const char *curi, int remove) source = NULL; while (!found && (source = em_vfolder_rule_next_source((EMVFolderRule *)rule, source))) { char *csource; - csource = em_uri_to_camel(source); found = camel_store_folder_uri_equal(store, curi, csource); d(printf(found?" '%s' == '%s'?\n":" '%s' != '%s'\n", curi, csource)); @@ -664,6 +662,18 @@ mail_vfolder_rename_uri(CamelStore *store, const char *cfrom, const char *cto) g_free(to); } +GList * +mail_vfolder_get_sources_local () +{ + return source_folders_local; +} + +GList * +mail_vfolder_get_sources_remote () +{ + return source_folders_remote; +} + /* ********************************************************************** */ static void context_rule_added(RuleContext *ctx, FilterRule *rule); @@ -834,80 +844,43 @@ store_folder_deleted(CamelObject *o, void *event_data, void *data) UNLOCK(); } -static int -store_folder_renamed_rec(char *prefix, int ignore, CamelFolderInfo *new) -{ - int changed = 0; - FilterRule *rule; - char *key; - GString *old = g_string_new(prefix); - CamelFolder *folder; - - while (new) { - if (new->child) - changed |= store_folder_renamed_rec(prefix, ignore, new->child); - - g_string_truncate(old, strlen(prefix)); - g_string_append(old, new->full_name+ignore); - - d(printf("Changing folder name in hash table to '%s'\n", new->full_name)); - if (g_hash_table_lookup_extended(vfolder_hash, old->str, (void **)&key, (void **)&folder)) { - g_hash_table_remove(vfolder_hash, key); - g_hash_table_insert(vfolder_hash, g_strdup(new->full_name), folder); - - rule = rule_context_find_rule((RuleContext *)context, key, NULL); - g_free(key); - g_assert(rule); - g_signal_handlers_disconnect_matched(rule, G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA, 0, - 0, NULL, rule_changed, folder); - filter_rule_set_name(rule, new->full_name); - g_signal_connect(rule, "changed", G_CALLBACK(rule_changed), folder); - changed = 1; - } else { - g_warning("couldn't find a vfolder rule in our table? %s", new->full_name); - } - new = new->next; - } - - g_string_free(old, TRUE); - return changed; -} - static void store_folder_renamed(CamelObject *o, void *event_data, void *data) { CamelRenameInfo *info = event_data; - char *end, *prefix; - int ignore; - + FilterRule *rule; + char *user; + char *key; + CamelFolder *folder; + /* This should be more-or-less thread-safe */ d(printf("Folder renamed to '%s' from '%s'\n", info->new->full_name, info->old_base)); /* Folder is already renamed? */ LOCK(); - end = strrchr(info->new->full_name, '/'); - if (end == NULL) { - ignore = 0; - end = strrchr(info->old_base, '/'); - if (end) { - prefix = g_alloca(end-info->old_base+2); - memcpy(prefix, info->old_base, end-info->old_base+1); - prefix[end-info->old_base+1] = 0; - } else - prefix = ""; - } else { - ignore = end-info->new->full_name+1; - prefix = ""; - } - if (store_folder_renamed_rec(prefix, ignore, info->new)) { - char *user; + d(printf("Changing folder name in hash table to '%s'\n", info->new->full_name)); + if (g_hash_table_lookup_extended(vfolder_hash, info->old_base, (void **)&key, (void **)&folder)) { + g_hash_table_remove(vfolder_hash, key); + g_free(key); + g_hash_table_insert(vfolder_hash, g_strdup(info->new->full_name), folder); + + rule = rule_context_find_rule((RuleContext *)context, info->old_base, NULL); + g_assert(rule); + g_signal_handlers_disconnect_matched(rule, G_SIGNAL_MATCH_FUNC|G_SIGNAL_MATCH_DATA, 0, + 0, NULL, rule_changed, folder); + filter_rule_set_name(rule, info->new->full_name); + g_signal_connect(rule, "changed", G_CALLBACK(rule_changed), folder); user = g_strdup_printf("%s/mail/vfolders.xml", mail_component_peek_base_directory (mail_component_peek ())); rule_context_save((RuleContext *)context, user); g_free(user); + + UNLOCK(); + } else { + UNLOCK(); + g_warning("couldn't find a vfolder rule in our table? %s", info->new->full_name); } - UNLOCK(); } void diff --git a/mail/message-list.c b/mail/message-list.c index cea727d562..865610abfd 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -93,7 +93,7 @@ #define localtime_r(tp,tmp) (localtime(tp)?(*(tmp)=*localtime(tp),(tmp)):0) #endif -#define d(x) +#define d(x) #define t(x) struct _MLSelection { @@ -1209,9 +1209,13 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, int col, void *model_data) { MessageList *message_list = model_data; CamelMessageInfo *msg_info; + CamelException ex; + const char *str; guint32 flags; + camel_exception_init (&ex); + if (e_tree_model_node_is_root (etm, path)) return NULL; @@ -1342,8 +1346,11 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, int col, void *model_data) return (void *) colour; } case COL_LOCATION: { + /* Fixme : freeing memory stuff (mem leaks) */ CamelFolder *folder; - char *name; + CamelURL *curl; + EAccount *account; + char *location, *euri, *url; if (CAMEL_IS_VEE_FOLDER(message_list->folder)) { folder = camel_vee_folder_get_location((CamelVeeFolder *)message_list->folder, (CamelVeeMessageInfo *)msg_info, NULL); @@ -1351,8 +1358,27 @@ ml_tree_value_at (ETreeModel *etm, ETreePath path, int col, void *model_data) folder = message_list->folder; } - camel_object_get(folder, NULL, CAMEL_OBJECT_DESCRIPTION, &name, 0); - return name; + url = mail_tools_folder_to_url (folder); + euri = em_uri_from_camel(url); + + account = mail_config_get_account_by_source_url (url); + + if (account) { + curl = camel_url_new (url, &ex); + location = g_strconcat (account->name, ":", curl->path, NULL); + } else { + /* Local account */ + euri = em_uri_from_camel(url); + curl = camel_url_new (euri, &ex); + if (curl->host && !strcmp(curl->host, "local") && curl->user && !strcmp(curl->user, "local")) + location = g_strconcat ("On This Computer", ":",curl->path, NULL); + } + + camel_exception_clear (&ex); + g_free (url); + g_free (euri); + + return location; } case COL_MIXED_RECIPIENTS: case COL_RECIPIENTS:{ @@ -1673,7 +1699,7 @@ message_list_setup_etree (MessageList *message_list, gboolean outgoing) path = mail_config_folder_to_cachename (message_list->folder, "et-expanded-"); g_object_set_data (((GnomeCanvasItem *) item)->canvas, "freeze-cursor", 1); - + if (path && g_stat (path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) { /* build based on saved file */ e_tree_load_expanded_state (message_list->tree, path); diff --git a/mail/message-list.etspec b/mail/message-list.etspec index 9911ad4fba..3887e2723a 100644 --- a/mail/message-list.etspec +++ b/mail/message-list.etspec @@ -25,7 +25,7 @@ <ETableColumn model_col="12" _title="Due By" expansion="0.2" minimum_width="32" resizable="true" cell="render_date" compare="integer"/> - <ETableColumn model_col="13" _title="Original Location" expansion="0.2" minimum_width="32" resizable="true" cell="render_text" compare="string"/> + <ETableColumn model_col="13" _title="Location" expansion="0.2" minimum_width="32" resizable="true" cell="render_text" compare="string"/> <ETableColumn model_col="14" _title="Sender" expansion="1.0" minimum_width="32" resizable="true" cell="render_text" compare="address_compare" search="string" priority="10"/> <ETableColumn model_col="15" _title="Recipients" expansion="1.0" minimum_width="32" resizable="true" cell="render_text" compare="address_compare" search="string" priority="10"/> |