Example #1
0
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);
}
Example #4
0
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;
}
Example #8
0
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;
}
Example #12
0
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);
}
Example #13
0
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);
}
Example #14
0
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);
}