static void rule_match_recipients (ERuleContext *context, EFilterRule *rule, CamelInternetAddress *iaddr) { EFilterPart *part; EFilterElement *element; gint i; const gchar *real, *addr; gchar *namestr; /* address types etc should handle multiple values */ for (i = 0; camel_internet_address_get (iaddr, i, &real, &addr); i++) { part = e_rule_context_create_part (context, "to"); e_filter_rule_add_part ((EFilterRule *) rule, part); element = e_filter_part_find_element (part, "recipient-type"); e_filter_option_set_current ((EFilterOption *)element, "contains"); element = e_filter_part_find_element (part, "recipient"); e_filter_input_set_value ((EFilterInput *) element, addr); namestr = g_strdup_printf (_("Mail to %s"), real && real[0] ? real : addr); e_filter_rule_set_name (rule, namestr); g_free (namestr); } }
static void rule_add_sender (ERuleContext *context, EFilterRule *rule, const gchar *text) { EFilterPart *part; EFilterElement *element; /* dont match on empty strings ever */ if (*text == 0) return; part = e_rule_context_create_part (context, "sender"); e_filter_rule_add_part ((EFilterRule *) rule, part); element = e_filter_part_find_element (part, "sender-type"); e_filter_option_set_current ((EFilterOption *)element, "contains"); element = e_filter_part_find_element (part, "sender"); e_filter_input_set_value ((EFilterInput *) element, text); }
static void rule_match_mlist (ERuleContext *context, EFilterRule *rule, const gchar *mlist) { EFilterPart *part; EFilterElement *element; if (mlist[0] == 0) return; part = e_rule_context_create_part(context, "mlist"); e_filter_rule_add_part (rule, part); element = e_filter_part_find_element(part, "mlist-type"); e_filter_option_set_current((EFilterOption *)element, "is"); element = e_filter_part_find_element (part, "mlist"); e_filter_input_set_value ((EFilterInput *) element, mlist); }
static void mail_shell_view_execute_search (EShellView *shell_view) { EMailShellViewPrivate *priv; EMailShellContent *mail_shell_content; EMailShellSidebar *mail_shell_sidebar; EShellWindow *shell_window; EShellBackend *shell_backend; EShellContent *shell_content; EShellSidebar *shell_sidebar; EShellSearchbar *searchbar; EActionComboBox *combo_box; EMailBackend *backend; EMailSession *session; ESourceRegistry *registry; EMFolderTree *folder_tree; GtkWidget *message_list; EFilterRule *rule; EMailReader *reader; EMailView *mail_view; CamelVeeFolder *search_folder; CamelFolder *folder; CamelService *service; CamelStore *store; GtkAction *action; EMailLabelListStore *label_store; GtkTreePath *path; GtkTreeIter tree_iter; GString *string; GList *list, *iter; GSList *search_strings = NULL; const gchar *text; gboolean valid; gchar *query; gchar *temp; gchar *tag; const gchar *use_tag; gint value; priv = E_MAIL_SHELL_VIEW_GET_PRIVATE (shell_view); shell_window = e_shell_view_get_shell_window (shell_view); shell_backend = e_shell_view_get_shell_backend (shell_view); shell_content = e_shell_view_get_shell_content (shell_view); shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); backend = E_MAIL_BACKEND (shell_backend); session = e_mail_backend_get_session (backend); mail_shell_content = E_MAIL_SHELL_CONTENT (shell_content); mail_view = e_mail_shell_content_get_mail_view (mail_shell_content); searchbar = e_mail_shell_content_get_searchbar (mail_shell_content); mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (shell_sidebar); folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar); reader = E_MAIL_READER (mail_view); folder = e_mail_reader_ref_folder (reader); message_list = e_mail_reader_get_message_list (reader); registry = e_mail_session_get_registry (session); label_store = e_mail_ui_session_get_label_store ( E_MAIL_UI_SESSION (session)); action = ACTION (MAIL_SEARCH_SUBJECT_OR_ADDRESSES_CONTAIN); value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); text = e_shell_searchbar_get_search_text (searchbar); if (value == MAIL_SEARCH_ADVANCED || text == NULL || *text == '\0') { if (value != MAIL_SEARCH_ADVANCED) e_shell_view_set_search_rule (shell_view, NULL); query = e_shell_view_get_search_query (shell_view); if (!query) query = g_strdup (""); goto filter; } /* Replace variables in the selected rule with the * current search text and extract a query string. */ g_return_if_fail (value >= 0 && value < MAIL_NUM_SEARCH_RULES); rule = priv->search_rules[value]; /* Set the search rule in EShellView so that "Create * Search Folder from Search" works for quick searches. */ e_shell_view_set_search_rule (shell_view, rule); for (iter = rule->parts; iter != NULL; iter = iter->next) { EFilterPart *part = iter->data; EFilterElement *element = NULL; if (strcmp (part->name, "subject") == 0) element = e_filter_part_find_element (part, "subject"); else if (strcmp (part->name, "body") == 0) element = e_filter_part_find_element (part, "word"); else if (strcmp (part->name, "sender") == 0) element = e_filter_part_find_element (part, "sender"); else if (strcmp (part->name, "to") == 0) element = e_filter_part_find_element (part, "recipient"); if (strcmp (part->name, "body") == 0) { struct _camel_search_words *words; gint ii; words = camel_search_words_split ((guchar *) text); for (ii = 0; ii < words->len; ii++) search_strings = g_slist_prepend ( search_strings, g_strdup ( words->words[ii]->word)); camel_search_words_free (words); } if (element != NULL) { EFilterInput *input = E_FILTER_INPUT (element); e_filter_input_set_value (input, text); } } string = g_string_sized_new (1024); e_filter_rule_build_code (rule, string); query = g_string_free (string, FALSE); filter: /* Apply selected filter. */ combo_box = e_shell_searchbar_get_filter_combo_box (searchbar); value = e_action_combo_box_get_current_value (combo_box); switch (value) { case MAIL_FILTER_ALL_MESSAGES: break; case MAIL_FILTER_UNREAD_MESSAGES: temp = g_strdup_printf ( "(and %s (match-all (not " "(system-flag \"Seen\"))))", query); g_free (query); query = temp; break; case MAIL_FILTER_NO_LABEL: string = g_string_sized_new (1024); g_string_append_printf ( string, "(and %s (and ", query); valid = gtk_tree_model_get_iter_first ( GTK_TREE_MODEL (label_store), &tree_iter); while (valid) { tag = e_mail_label_list_store_get_tag ( label_store, &tree_iter); use_tag = tag; if (g_str_has_prefix (use_tag, "$Label")) use_tag += 6; g_string_append_printf ( string, " (match-all (not (or " "(= (user-tag \"label\") \"%s\") " "(user-flag \"$Label%s\") " "(user-flag \"%s\"))))", use_tag, use_tag, use_tag); g_free (tag); valid = gtk_tree_model_iter_next ( GTK_TREE_MODEL (label_store), &tree_iter); } g_string_append_len (string, "))", 2); g_free (query); query = g_string_free (string, FALSE); break; case MAIL_FILTER_READ_MESSAGES: temp = g_strdup_printf ( "(and %s (match-all " "(system-flag \"Seen\")))", query); g_free (query); query = temp; break; case MAIL_FILTER_LAST_5_DAYS_MESSAGES: if (em_utils_folder_is_sent (registry, folder)) temp = g_strdup_printf ( "(and %s (match-all " "(> (get-sent-date) " "(- (get-current-date) 432000))))", query); else temp = g_strdup_printf ( "(and %s (match-all " "(> (get-received-date) " "(- (get-current-date) 432000))))", query); g_free (query); query = temp; break; case MAIL_FILTER_MESSAGES_WITH_ATTACHMENTS: temp = g_strdup_printf ( "(and %s (match-all " "(system-flag \"Attachments\")))", query); g_free (query); query = temp; break; case MAIL_FILTER_IMPORTANT_MESSAGES: temp = g_strdup_printf ( "(and %s (match-all " "(system-flag \"Flagged\")))", query); g_free (query); query = temp; break; case MAIL_FILTER_MESSAGES_NOT_JUNK: temp = g_strdup_printf ( "(and %s (match-all (not " "(system-flag \"junk\"))))", query); g_free (query); query = temp; break; default: /* The action value also serves as a path for * the label list store. That's why we number * the label actions from zero. */ path = gtk_tree_path_new_from_indices (value, -1); gtk_tree_model_get_iter ( GTK_TREE_MODEL (label_store), &tree_iter, path); gtk_tree_path_free (path); tag = e_mail_label_list_store_get_tag ( label_store, &tree_iter); use_tag = tag; if (g_str_has_prefix (use_tag, "$Label")) use_tag += 6; temp = g_strdup_printf ( "(and %s (match-all (or " "(= (user-tag \"label\") \"%s\") " "(user-flag \"$Label%s\") " "(user-flag \"%s\"))))", query, use_tag, use_tag, use_tag); g_free (tag); g_free (query); query = temp; break; } /* Apply selected scope. */ combo_box = e_shell_searchbar_get_scope_combo_box (searchbar); value = e_action_combo_box_get_current_value (combo_box); switch (value) { case MAIL_SCOPE_CURRENT_FOLDER: goto execute; case MAIL_SCOPE_CURRENT_ACCOUNT: goto current_account; case MAIL_SCOPE_ALL_ACCOUNTS: goto all_accounts; default: g_warn_if_reached (); goto execute; } all_accounts: /* Prepare search folder for all accounts. */ /* If the search text is empty, cancel any * account-wide searches still in progress. */ text = e_shell_searchbar_get_search_text (searchbar); if (text == NULL || *text == '\0') { CamelStore *selected_store = NULL; gchar *selected_folder_name = NULL; if (priv->search_account_all != NULL) { g_object_unref (priv->search_account_all); priv->search_account_all = NULL; } if (priv->search_account_cancel != NULL) { g_cancellable_cancel (priv->search_account_cancel); g_object_unref (priv->search_account_cancel); priv->search_account_cancel = NULL; } /* Reset the message list to the current folder tree * selection. This needs to happen synchronously to * avoid search conflicts, so we can't just grab the * folder URI and let the asynchronous callbacks run * after we've already kicked off the search. */ em_folder_tree_get_selected ( folder_tree, &selected_store, &selected_folder_name); if (selected_store != NULL && selected_folder_name != NULL) { folder = camel_store_get_folder_sync ( selected_store, selected_folder_name, CAMEL_STORE_FOLDER_INFO_FAST, NULL, NULL); e_mail_reader_set_folder (reader, folder); g_object_unref (folder); } g_clear_object (&selected_store); g_free (selected_folder_name); gtk_widget_set_sensitive (GTK_WIDGET (combo_box), TRUE); goto execute; } search_folder = priv->search_account_all; /* Skip the search if we already have the results. */ if (search_folder != NULL) { const gchar *vf_query; vf_query = camel_vee_folder_get_expression (search_folder); if (g_strcmp0 (query, vf_query) == 0) goto all_accounts_setup; } /* Disable the scope combo while search is in progress. */ gtk_widget_set_sensitive (GTK_WIDGET (combo_box), FALSE); /* If we already have a search folder, reuse it. */ if (search_folder != NULL) { if (priv->search_account_cancel != NULL) { g_cancellable_cancel (priv->search_account_cancel); g_object_unref (priv->search_account_cancel); priv->search_account_cancel = NULL; } camel_vee_folder_set_expression (search_folder, query); goto all_accounts_setup; } /* Create a new search folder. */ /* FIXME Complete lack of error checking here. */ service = camel_session_ref_service ( CAMEL_SESSION (session), E_MAIL_SESSION_VFOLDER_UID); camel_service_connect_sync (service, NULL, NULL); search_folder = (CamelVeeFolder *) camel_vee_folder_new ( CAMEL_STORE (service), _("All Account Search"), CAMEL_STORE_FOLDER_PRIVATE); priv->search_account_all = search_folder; g_object_unref (service); camel_vee_folder_set_expression (search_folder, query); all_accounts_setup: list = em_folder_tree_model_list_stores (EM_FOLDER_TREE_MODEL ( gtk_tree_view_get_model (GTK_TREE_VIEW (folder_tree)))); g_list_foreach (list, (GFunc) g_object_ref, NULL); priv->search_account_cancel = camel_operation_new (); /* This takes ownership of the stores list. */ mail_shell_view_setup_search_results_folder ( CAMEL_FOLDER (search_folder), list, priv->search_account_cancel); mail_shell_view_show_search_results_folder ( E_MAIL_SHELL_VIEW (shell_view), CAMEL_FOLDER (search_folder)); goto execute; current_account: /* Prepare search folder for current account only. */ /* If the search text is empty, cancel any * account-wide searches still in progress. */ text = e_shell_searchbar_get_search_text (searchbar); if (text == NULL || *text == '\0') { CamelStore *selected_store = NULL; gchar *selected_folder_name = NULL; if (priv->search_account_current != NULL) { g_object_unref (priv->search_account_current); priv->search_account_current = NULL; } if (priv->search_account_cancel != NULL) { g_cancellable_cancel (priv->search_account_cancel); g_object_unref (priv->search_account_cancel); priv->search_account_cancel = NULL; } /* Reset the message list to the current folder tree * selection. This needs to happen synchronously to * avoid search conflicts, so we can't just grab the * folder URI and let the asynchronous callbacks run * after we've already kicked off the search. */ em_folder_tree_get_selected ( folder_tree, &selected_store, &selected_folder_name); if (selected_store != NULL && selected_folder_name != NULL) { folder = camel_store_get_folder_sync ( selected_store, selected_folder_name, CAMEL_STORE_FOLDER_INFO_FAST, NULL, NULL); e_mail_reader_set_folder (reader, folder); g_object_unref (folder); } g_clear_object (&selected_store); g_free (selected_folder_name); gtk_widget_set_sensitive (GTK_WIDGET (combo_box), TRUE); goto execute; } search_folder = priv->search_account_current; /* Skip the search if we already have the results. */ if (search_folder != NULL) { const gchar *vf_query; vf_query = camel_vee_folder_get_expression (search_folder); if (g_strcmp0 (query, vf_query) == 0) goto current_accout_setup; } /* Disable the scope combo while search is in progress. */ gtk_widget_set_sensitive (GTK_WIDGET (combo_box), FALSE); /* If we already have a search folder, reuse it. */ if (search_folder != NULL) { if (priv->search_account_cancel != NULL) { g_cancellable_cancel (priv->search_account_cancel); g_object_unref (priv->search_account_cancel); priv->search_account_cancel = NULL; } camel_vee_folder_set_expression (search_folder, query); goto current_accout_setup; } /* Create a new search folder. */ /* FIXME Complete lack of error checking here. */ service = camel_session_ref_service ( CAMEL_SESSION (session), E_MAIL_SESSION_VFOLDER_UID); camel_service_connect_sync (service, NULL, NULL); search_folder = (CamelVeeFolder *) camel_vee_folder_new ( CAMEL_STORE (service), _("Account Search"), CAMEL_STORE_FOLDER_PRIVATE); priv->search_account_current = search_folder; g_object_unref (service); camel_vee_folder_set_expression (search_folder, query); current_accout_setup: if (folder != NULL && folder != CAMEL_FOLDER (search_folder)) { store = camel_folder_get_parent_store (folder); if (store != NULL) g_object_ref (store); } else { store = NULL; em_folder_tree_get_selected (folder_tree, &store, NULL); } list = NULL; /* list of CamelStore-s */ if (store != NULL) list = g_list_append (NULL, store); priv->search_account_cancel = camel_operation_new (); /* This takes ownership of the stores list. */ mail_shell_view_setup_search_results_folder ( CAMEL_FOLDER (search_folder), list, priv->search_account_cancel); mail_shell_view_show_search_results_folder ( E_MAIL_SHELL_VIEW (shell_view), CAMEL_FOLDER (search_folder)); execute: /* Finally, execute the search. */ message_list_set_search (MESSAGE_LIST (message_list), query); e_mail_view_set_search_strings (mail_view, search_strings); g_slist_foreach (search_strings, (GFunc) g_free, NULL); g_slist_free (search_strings); g_free (query); g_clear_object (&folder); }