void e_mail_shell_view_restore_state (EMailShellView *mail_shell_view) { EMailShellContent *mail_shell_content; EShellSearchbar *searchbar; EMailReader *reader; EMailView *mail_view; CamelFolder *folder; CamelVeeFolder *vee_folder; const gchar *old_state_group; gchar *folder_uri; gchar *new_state_group; /* XXX Move this to EMailShellContent. */ g_return_if_fail (E_IS_MAIL_SHELL_VIEW (mail_shell_view)); mail_shell_content = mail_shell_view->priv->mail_shell_content; mail_view = e_mail_shell_content_get_mail_view (mail_shell_content); searchbar = e_mail_shell_content_get_searchbar (mail_shell_content); reader = E_MAIL_READER (mail_view); folder = e_mail_reader_ref_folder (reader); if (folder == NULL) { if (e_shell_searchbar_get_state_group (searchbar)) { e_shell_searchbar_set_state_group (searchbar, NULL); e_shell_searchbar_load_state (searchbar); } return; } /* Do not restore state if we're running a "Current Account" * or "All Accounts" search, since we don't want the search * criteria to be destroyed in those cases. */ vee_folder = mail_shell_view->priv->search_account_all; if (vee_folder != NULL && folder == CAMEL_FOLDER (vee_folder)) goto exit; vee_folder = mail_shell_view->priv->search_account_current; if (vee_folder != NULL && folder == CAMEL_FOLDER (vee_folder)) goto exit; folder_uri = e_mail_folder_uri_from_folder (folder); new_state_group = g_strdup_printf ("Folder %s", folder_uri); old_state_group = e_shell_searchbar_get_state_group (searchbar); g_free (folder_uri); /* Avoid loading search state unnecessarily. */ if (g_strcmp0 (new_state_group, old_state_group) != 0) { e_shell_searchbar_set_state_group (searchbar, new_state_group); e_shell_searchbar_load_state (searchbar); } g_free (new_state_group); exit: g_clear_object (&folder); }
gboolean camel_nntp_folder_selected (CamelNNTPFolder *nntp_folder, gchar *line, GCancellable *cancellable, GError **error) { CamelFolder *folder; CamelStore *parent_store; gboolean res; folder = CAMEL_FOLDER (nntp_folder); parent_store = camel_folder_get_parent_store (folder); res = camel_nntp_summary_check ( CAMEL_NNTP_SUMMARY (folder->summary), CAMEL_NNTP_STORE (parent_store), line, nntp_folder->changes, cancellable, error); if (camel_folder_change_info_changed (nntp_folder->changes)) { CamelFolderChangeInfo *changes; changes = nntp_folder->changes; nntp_folder->changes = camel_folder_change_info_new (); camel_folder_changed (CAMEL_FOLDER (nntp_folder), changes); camel_folder_change_info_free (changes); } return res; }
static CamelLocalSummary * maildir_folder_create_summary (CamelLocalFolder *lf, const gchar *folder, CamelIndex *index) { return (CamelLocalSummary *) camel_maildir_summary_new ( CAMEL_FOLDER (lf), folder, index); }
static void vfolder_foreach_cb (gpointer key, gpointer data, gpointer user_data) { CamelFolder *folder = CAMEL_FOLDER (data); if (folder) g_object_unref (folder); g_free (key); }
static CamelFolder * vee_store_get_folder_sync (CamelStore *store, const gchar *folder_name, CamelStoreGetFolderFlags flags, GCancellable *cancellable, GError **error) { CamelVeeFolder *vf; CamelFolder *folder; gchar *name, *p; gsize name_len; vf = (CamelVeeFolder *) camel_vee_folder_new (store, folder_name, flags); if (vf && ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0)) { const gchar *full_name; full_name = camel_folder_get_full_name (CAMEL_FOLDER (vf)); /* Check that parents exist, if not, create dummy ones */ name_len = strlen (full_name) + 1; name = alloca (name_len); g_strlcpy (name, full_name, name_len); p = name; while ( (p = strchr (p, '/'))) { *p = 0; folder = camel_object_bag_reserve (store->folders, name); if (folder == NULL) { /* create a dummy vFolder for this, makes get_folder_info simpler */ folder = camel_vee_folder_new (store, name, flags); camel_object_bag_add (store->folders, name, folder); change_folder (store, name, CHANGE_ADD | CHANGE_NOSELECT, 0); /* FIXME: this sort of leaks folder, nobody owns a ref to it but us */ } else { g_object_unref (folder); } *p++='/'; } change_folder (store, full_name, CHANGE_ADD, camel_folder_get_message_count ((CamelFolder *) vf)); } return (CamelFolder *) vf; }
static gint exchange_entry_play_delete (CamelOfflineJournal *journal, CamelExchangeJournalEntry *entry, GCancellable *cancellable, GError **error) { CamelFolder *folder; CamelStore *parent_store; const gchar *full_name; gboolean success; folder = CAMEL_FOLDER (journal->folder); full_name = camel_folder_get_full_name (folder); parent_store = camel_folder_get_parent_store (folder); success = camel_exchange_utils_set_message_flags ( CAMEL_SERVICE (parent_store), full_name, entry->uid, entry->set, entry->flags, error); return success ? 0 : -1; }
static gboolean vee_info_set_flags (CamelMessageInfo *mi, guint32 flags, guint32 set) { gint res = FALSE; CamelVeeFolder *vf = CAMEL_VEE_FOLDER (camel_folder_summary_get_folder (mi->summary)); if (camel_debug("vfolderexp")) printf ( "Expression for vfolder '%s' is '%s'\n", camel_folder_get_full_name (CAMEL_FOLDER (vf)), g_strescape (vf->expression, "")); /* first update original message info... */ if (mi->uid) { CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8); HANDLE_NULL_INFO (FALSE); /* ignore changes done in the folder itself, * unless it's a vTrash or vJunk folder */ if (!CAMEL_IS_VTRASH_FOLDER (vf)) camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder (rmi->summary)); camel_folder_freeze (camel_folder_summary_get_folder (rmi->summary)); res = camel_message_info_set_flags (rmi, flags, set); ((CamelVeeMessageInfo *) mi)->old_flags = camel_message_info_flags (rmi); camel_folder_thaw (camel_folder_summary_get_folder (rmi->summary)); camel_message_info_free (rmi); } if (res) CAMEL_FOLDER_SUMMARY_CLASS (camel_vee_summary_parent_class)->info_set_flags (mi, flags, set); return res; }
void camel_ews_utils_sync_deleted_items (CamelEwsFolder *ews_folder, GSList *items_deleted, CamelFolderChangeInfo *change_info) { CamelStore *store; CamelFolder *folder; const gchar *full_name; CamelEwsStore *ews_store; GSList *l; GList *items_deleted_list = NULL; folder = CAMEL_FOLDER (ews_folder); full_name = camel_folder_get_full_name (folder); store = camel_folder_get_parent_store (folder); ews_store = CAMEL_EWS_STORE (store); for (l = items_deleted; l != NULL; l = g_slist_next (l)) { const gchar *id = l->data; items_deleted_list = g_list_prepend ( items_deleted_list, (gpointer) id); camel_folder_summary_remove_uid (camel_folder_get_folder_summary (folder), id); camel_folder_change_info_remove_uid (change_info, id); } items_deleted_list = g_list_reverse (items_deleted_list); camel_db_delete_uids ( camel_store_get_db (CAMEL_STORE (ews_store)), full_name, items_deleted_list, NULL); g_list_free (items_deleted_list); g_slist_foreach (items_deleted, (GFunc) g_free, NULL); g_slist_free (items_deleted); }
static void nntp_folder_dispose (GObject *object) { CamelFolder *folder; CamelStore *store; folder = CAMEL_FOLDER (object); camel_folder_summary_save_to_db (folder->summary, NULL); store = camel_folder_get_parent_store (folder); if (store != NULL) { CamelNNTPStoreSummary *nntp_store_summary; nntp_store_summary = camel_nntp_store_ref_summary ( CAMEL_NNTP_STORE (store)); camel_store_summary_disconnect_folder_summary ( CAMEL_STORE_SUMMARY (nntp_store_summary), folder->summary); g_clear_object (&nntp_store_summary); } /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (camel_nntp_folder_parent_class)->dispose (object); }
static CamelFolderInfo * vee_store_get_folder_info_sync (CamelStore *store, const gchar *top, CamelStoreGetFolderInfoFlags flags, GCancellable *cancellable, GError **error) { CamelFolderInfo *info, *res = NULL, *tail; GPtrArray *folders; GHashTable *infos_hash; gint i; d (printf ("Get folder info '%s'\n", top ? top:"<null>")); infos_hash = g_hash_table_new (g_str_hash, g_str_equal); folders = camel_object_bag_list (store->folders); qsort (folders->pdata, folders->len, sizeof (folders->pdata[0]), vee_folder_cmp); for (i = 0; i < folders->len; i++) { CamelVeeFolder *folder = folders->pdata[i]; const gchar *full_name; const gchar *display_name; gint add = FALSE; gchar *pname, *tmp; CamelFolderInfo *pinfo; full_name = camel_folder_get_full_name (CAMEL_FOLDER (folder)); display_name = camel_folder_get_display_name (CAMEL_FOLDER (folder)); /* check we have to include this one */ if (top) { gint namelen = strlen (full_name); gint toplen = strlen (top); add = ((namelen == toplen && strcmp (full_name, top) == 0) || ((namelen > toplen) && strncmp (full_name, top, toplen) == 0 && full_name[toplen] == '/' && ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) || strchr (full_name + toplen + 1, '/') == NULL))); } else { add = (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) || strchr (full_name, '/') == NULL; } if (add) { gint32 unread; unread = camel_folder_get_unread_message_count ( CAMEL_FOLDER (folder)); info = camel_folder_info_new (); info->full_name = g_strdup (full_name); info->display_name = g_strdup (display_name); info->unread = unread; info->flags = CAMEL_FOLDER_NOCHILDREN | CAMEL_FOLDER_VIRTUAL; g_hash_table_insert (infos_hash, info->full_name, info); if (res == NULL) res = info; } else { info = NULL; } /* check for parent, if present, update flags and if adding, update parent linkage */ pname = g_strdup (full_name); d (printf ("looking up parent of '%s'\n", pname)); tmp = strrchr (pname, '/'); if (tmp) { *tmp = 0; pinfo = g_hash_table_lookup (infos_hash, pname); } else pinfo = NULL; if (pinfo) { pinfo->flags = (pinfo->flags & ~(CAMEL_FOLDER_CHILDREN | CAMEL_FOLDER_NOCHILDREN)) | CAMEL_FOLDER_CHILDREN; d (printf ("updating parent flags for children '%s' %08x\n", pinfo->full_name, pinfo->flags)); tail = pinfo->child; if (tail == NULL) pinfo->child = info; } else if (info != res) { tail = res; } else { tail = NULL; } if (info && tail) { while (tail->next) tail = tail->next; tail->next = info; info->parent = pinfo; } g_free (pname); g_object_unref (folder); } g_ptr_array_free (folders, TRUE); g_hash_table_destroy (infos_hash); /* and add UNMATCHED, if scanning from top/etc and it's enabled */ if (camel_vee_store_get_unmatched_enabled (CAMEL_VEE_STORE (store)) && (top == NULL || top[0] == 0 || strncmp (top, CAMEL_UNMATCHED_NAME, strlen (CAMEL_UNMATCHED_NAME)) == 0)) { info = vee_store_create_unmatched_fi (); if (res == NULL) res = info; else { tail = res; while (tail->next) tail = tail->next; tail->next = info; } } return res; }
static CamelStream * nntp_folder_download_message (CamelNNTPFolder *nntp_folder, const gchar *id, const gchar *msgid, GCancellable *cancellable, GError **error) { CamelFolder *folder; CamelStore *parent_store; CamelDataCache *nntp_cache; CamelNNTPStore *nntp_store; CamelNNTPStream *nntp_stream = NULL; CamelStream *stream = NULL; gint ret; gchar *line; folder = CAMEL_FOLDER (nntp_folder); parent_store = camel_folder_get_parent_store (folder); nntp_store = CAMEL_NNTP_STORE (parent_store); nntp_cache = camel_nntp_store_ref_cache (nntp_store); ret = camel_nntp_command ( nntp_store, cancellable, error, nntp_folder, &line, "article %s", id); if (ret == 220) { GIOStream *base_stream; nntp_stream = camel_nntp_store_ref_stream (nntp_store); base_stream = camel_data_cache_add ( nntp_cache, "cache", msgid, NULL); if (base_stream != NULL) { gboolean success; stream = camel_stream_new (base_stream); g_object_unref (base_stream); success = (camel_stream_write_to_stream ( CAMEL_STREAM (nntp_stream), stream, cancellable, error) != -1); if (!success) goto fail; success = g_seekable_seek ( G_SEEKABLE (stream), 0, G_SEEK_SET, cancellable, error); if (!success) goto fail; } else { stream = g_object_ref (nntp_stream); } } else if (ret == 423 || ret == 430) { g_set_error ( error, CAMEL_FOLDER_ERROR, CAMEL_FOLDER_ERROR_INVALID_UID, _("Cannot get message %s: %s"), msgid, line); } else if (ret != -1) { g_set_error ( error, CAMEL_ERROR, CAMEL_ERROR_GENERIC, _("Cannot get message %s: %s"), msgid, line); } goto exit; fail: camel_data_cache_remove (nntp_cache, "cache", msgid, NULL); g_prefix_error (error, _("Cannot get message %s: "), msgid); g_clear_object (&stream); exit: g_clear_object (&nntp_cache); g_clear_object (&nntp_stream); return stream; }
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); }
void camel_ews_utils_sync_created_items (CamelEwsFolder *ews_folder, EEwsConnection *cnc, GSList *items_created, CamelFolderChangeInfo *change_info, GCancellable *cancellable) { CamelFolder *folder; CamelFolderSummary *folder_summary; GSList *l; if (!items_created) return; folder = CAMEL_FOLDER (ews_folder); folder_summary = camel_folder_get_folder_summary (folder); for (l = items_created; l != NULL; l = g_slist_next (l)) { EEwsItem *item = (EEwsItem *) l->data; CamelMessageInfo *mi; const EwsId *id; const EwsMailbox *from; gchar *tmp; EEwsItemType item_type; const gchar *msg_headers; gboolean has_attachments, found_property, message_requests_read_receipt = FALSE; guint32 server_flags; if (!item) continue; if (e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) { g_object_unref (item); continue; } id = e_ews_item_get_id (item); if (!id) { g_warning ("%s: Missing ItemId for item type %d (subject:%s)", G_STRFUNC, e_ews_item_get_item_type (item), e_ews_item_get_subject (item) ? e_ews_item_get_subject (item) : "???"); g_object_unref (item); continue; } mi = camel_folder_summary_get (folder_summary, id->id); if (mi) { g_clear_object (&mi); g_object_unref (item); continue; } /* PidTagTransportMessageHeaders */ found_property = FALSE; msg_headers = e_ews_item_get_extended_property_as_string (item, NULL, 0x007D, &found_property); if (!found_property) msg_headers = NULL; if (msg_headers && *msg_headers) { CamelMimePart *part = camel_mime_part_new (); CamelStream *stream; CamelMimeParser *parser; stream = camel_stream_mem_new_with_buffer (msg_headers, strlen (msg_headers)); parser = camel_mime_parser_new (); camel_mime_parser_init_with_stream (parser, stream, NULL); camel_mime_parser_scan_from (parser, FALSE); g_object_unref (stream); if (camel_mime_part_construct_from_parser_sync (part, parser, NULL, NULL)) { mi = camel_folder_summary_info_new_from_headers (folder_summary, camel_medium_get_headers (CAMEL_MEDIUM (part))); if (camel_medium_get_header (CAMEL_MEDIUM (part), "Disposition-Notification-To")) message_requests_read_receipt = TRUE; } g_object_unref (parser); g_object_unref (part); } if (!mi) mi = camel_message_info_new (folder_summary); camel_message_info_set_abort_notifications (mi, TRUE); item_type = e_ews_item_get_item_type (item); if (item_type == E_EWS_ITEM_TYPE_EVENT || item_type == E_EWS_ITEM_TYPE_MEETING_MESSAGE || item_type == E_EWS_ITEM_TYPE_MEETING_REQUEST || item_type == E_EWS_ITEM_TYPE_MEETING_RESPONSE || item_type == E_EWS_ITEM_TYPE_MEETING_RESPONSE) camel_message_info_set_user_flag (mi, "$has_cal", TRUE); camel_message_info_set_uid (mi, id->id); camel_message_info_set_size (mi, e_ews_item_get_size (item)); camel_message_info_set_subject (mi, e_ews_item_get_subject (item)); camel_ews_message_info_set_item_type (CAMEL_EWS_MESSAGE_INFO (mi), item_type); camel_ews_message_info_set_change_key (CAMEL_EWS_MESSAGE_INFO (mi), id->change_key); camel_message_info_set_date_sent (mi, e_ews_item_get_date_sent (item)); camel_message_info_set_date_received (mi, e_ews_item_get_date_received (item)); from = e_ews_item_get_from (item); if (!from) from = e_ews_item_get_sender (item); tmp = form_email_string_from_mb (cnc, from, cancellable); camel_message_info_set_from (mi, tmp); g_free (tmp); tmp = form_recipient_list (cnc, e_ews_item_get_to_recipients (item), cancellable); camel_message_info_set_to (mi, tmp); g_free (tmp); tmp = form_recipient_list (cnc, e_ews_item_get_cc_recipients (item), cancellable); camel_message_info_set_cc (mi, tmp); g_free (tmp); e_ews_item_has_attachments (item, &has_attachments); if (has_attachments) camel_message_info_set_flags (mi, CAMEL_MESSAGE_ATTACHMENTS, CAMEL_MESSAGE_ATTACHMENTS); ews_set_threading_data (mi, item); server_flags = ews_utils_get_server_flags (item); ews_utils_merge_server_user_flags (item, mi); camel_message_info_set_flags (mi, server_flags, server_flags); camel_ews_message_info_set_server_flags (CAMEL_EWS_MESSAGE_INFO (mi), server_flags); camel_ews_utils_update_follow_up_flags (item, mi); camel_ews_utils_update_read_receipt_flags (item, mi, server_flags, message_requests_read_receipt); camel_message_info_set_abort_notifications (mi, FALSE); camel_folder_summary_add (folder_summary, mi, FALSE); /* camel_folder_summary_add() sets folder_flagged flag * on the message info, but this is a fresh item downloaded * from the server, thus unset it, to avoid resync up to the server * on folder leave/store */ camel_message_info_set_folder_flagged (mi, FALSE); camel_folder_change_info_add_uid (change_info, id->id); camel_folder_change_info_recent_uid (change_info, id->id); g_object_unref (mi); g_object_unref (item); } g_slist_free (items_created); }
void camel_ews_utils_sync_updated_items (CamelEwsFolder *ews_folder, GSList *items_updated, CamelFolderChangeInfo *change_info) { CamelFolder *folder; CamelFolderSummary *folder_summary; GSList *l; folder = CAMEL_FOLDER (ews_folder); folder_summary = camel_folder_get_folder_summary (folder); for (l = items_updated; l != NULL; l = g_slist_next (l)) { EEwsItem *item = (EEwsItem *) l->data; const EwsId *id; CamelMessageInfo *mi; if (e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) { g_object_unref (item); continue; } id = e_ews_item_get_id (item); if (!id) { g_warning ("%s: Missing ItemId for item type %d (subject:%s)", G_STRFUNC, e_ews_item_get_item_type (item), e_ews_item_get_subject (item) ? e_ews_item_get_subject (item) : "???"); g_object_unref (item); continue; } mi = camel_folder_summary_get (folder_summary, id->id); if (mi) { guint32 server_flags; gboolean changed, was_changed; camel_message_info_freeze_notifications (mi); was_changed = camel_message_info_get_folder_flagged (mi); server_flags = ews_utils_get_server_flags (item); ews_utils_merge_server_user_flags (item, mi); changed = camel_ews_update_message_info_flags (folder_summary, mi, server_flags, NULL); changed = camel_ews_utils_update_follow_up_flags (item, mi) || changed; changed = camel_ews_utils_update_read_receipt_flags (item, mi, server_flags, FALSE) || changed; if (changed) camel_folder_change_info_change_uid (change_info, id->id); camel_ews_message_info_set_change_key (CAMEL_EWS_MESSAGE_INFO (mi), id->change_key); if (!was_changed) { /* do not save to the server what was just read, when did not change locally before */ camel_message_info_set_folder_flagged (mi, FALSE); } camel_message_info_thaw_notifications (mi); g_clear_object (&mi); g_object_unref (item); continue; } g_object_unref (item); } g_slist_free (items_updated); }