示例#1
0
/**
 * em_utils_folder_is_drafts:
 * @registry: an #ESourceRegistry
 * @folder: a #CamelFolder
 *
 * Decides if @folder is a Drafts folder.
 *
 * Returns %TRUE if this is a Drafts folder or %FALSE otherwise.
 **/
gboolean
em_utils_folder_is_drafts (ESourceRegistry *registry,
                           CamelFolder *folder)
{
	CamelFolder *local_drafts_folder;
	CamelSession *session;
	CamelStore *store;
	GList *list, *iter;
	gchar *folder_uri;
	gboolean is_drafts = FALSE;
	const gchar *extension_name;

	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);

	store = camel_folder_get_parent_store (folder);
	session = camel_service_ref_session (CAMEL_SERVICE (store));

	local_drafts_folder =
		e_mail_session_get_local_folder (
		E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_DRAFTS);

	if (folder == local_drafts_folder) {
		is_drafts = TRUE;
		goto exit;
	}

	folder_uri = e_mail_folder_uri_from_folder (folder);

	store = camel_folder_get_parent_store (folder);

	extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION;
	list = e_source_registry_list_sources (registry, extension_name);

	for (iter = list; iter != NULL; iter = g_list_next (iter)) {
		ESource *source = E_SOURCE (iter->data);
		ESourceExtension *extension;
		const gchar *drafts_folder_uri;

		extension = e_source_get_extension (source, extension_name);

		drafts_folder_uri =
			e_source_mail_composition_get_drafts_folder (
			E_SOURCE_MAIL_COMPOSITION (extension));

		if (drafts_folder_uri != NULL)
			is_drafts = e_mail_folder_uri_equal (
				session, folder_uri, drafts_folder_uri);

		if (is_drafts)
			break;
	}

	g_list_free_full (list, (GDestroyNotify) g_object_unref);
	g_free (folder_uri);

exit:
	g_object_unref (session);

	return is_drafts;
}
示例#2
0
static void
exchange_get_folder (char *uri, CamelFolder *folder, void *data)
{
	CamelStore *store;
	CamelException ex;
	CamelFolderInfo *info;
	gchar *name = NULL;
	gchar *stored_name = NULL;
	gchar *target_uri = (gchar *)data;
	ExchangeAccount *account = NULL;

	account = exchange_operations_get_exchange_account ();

	if (!account)
		return;

	/* Get the subscribed folder name. */
	name = target_uri + strlen ("exchange://") + strlen (account->account_filename);
	stored_name = strrchr (name + 1, '/');

	if (stored_name)
		name[stored_name - name] = '\0';

	camel_exception_init (&ex);
	store = camel_folder_get_parent_store (folder);

	/* Construct the CamelFolderInfo */
	info = ex_create_folder_info (store, name, target_uri, -1, 0);
	camel_object_trigger_event (CAMEL_OBJECT (store),
				    "folder_unsubscribed", info);
	g_free (target_uri);
}
static CamelSExpResult *
message_location (struct _CamelSExp *f,
		  gint argc,
		  struct _CamelSExpResult **argv,
		  FilterMessageSearch *fms)
{
	CamelSExpResult *r;
	gboolean same = FALSE;

	if (argc != 1 || argv[0]->type != CAMEL_SEXP_RES_STRING)
		camel_sexp_fatal_error (f, _("Invalid arguments to (message-location)"));

	if (fms->folder && argv[0]->value.string) {
		CamelStore *store;
		const gchar *name;
		gchar *uri;

		store = camel_folder_get_parent_store (fms->folder);
		name = camel_folder_get_full_name (fms->folder);
		uri = mail_folder_uri_build (store, name);

		same = g_str_equal (uri, argv[0]->value.string);

		g_free (uri);
	}

	r = camel_sexp_result_new (f, CAMEL_SEXP_RES_BOOL);
	r->value.boolean = same;

	return r;
}
示例#4
0
static gchar *
set_organizer (ECalComponent *comp,
	       CamelMimeMessage *message,
	       CamelFolder *folder,
	       const gchar *message_uid)
{
	EShell *shell;
	ESource *source = NULL;
	ESourceRegistry *registry;
	ESourceMailIdentity *extension;
	const gchar *extension_name;
	const gchar *address, *name;
	ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL};
	gchar *mailto = NULL;
	gchar *identity_name = NULL, *identity_address = NULL;

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);

	source = em_utils_guess_mail_identity_with_recipients (registry, message, folder,
		message_uid, &identity_name, &identity_address);

	if (!source && folder) {
		CamelStore *store;

		store = camel_folder_get_parent_store (folder);
		source = em_utils_ref_mail_identity_for_store (registry, store);
	}

	if (source == NULL)
		source = e_source_registry_ref_default_mail_identity (registry);

	g_return_val_if_fail (source != NULL, NULL);

	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
	extension = e_source_get_extension (source, extension_name);

	name = identity_name;
	if (!name || !*name)
		name = e_source_mail_identity_get_name (extension);

	address = identity_address;
	if (!address || !*address) {
		name = e_source_mail_identity_get_name (extension);
		address = e_source_mail_identity_get_address (extension);
	}

	if (address && *address) {
		mailto = g_strconcat ("mailto:", address, NULL);
		organizer.value = mailto;
		organizer.cn = name;
		e_cal_component_set_organizer (comp, &organizer);
	}

	g_object_unref (source);
	g_free (identity_name);
	g_free (identity_address);

	return mailto;
}
static gboolean
nntp_folder_refresh_info_sync (CamelFolder *folder,
                               GCancellable *cancellable,
                               GError **error)
{
	CamelStore *parent_store;
	CamelNNTPStore *nntp_store;
	CamelFolderChangeInfo *changes = NULL;
	CamelNNTPFolder *nntp_folder;
	gchar *line;
	gboolean success;

	parent_store = camel_folder_get_parent_store (folder);

	nntp_folder = CAMEL_NNTP_FOLDER (folder);
	nntp_store = CAMEL_NNTP_STORE (parent_store);

	/* When invoked with no fmt, camel_nntp_command() just selects the folder
	 * and should return zero. */
	success = !camel_nntp_command (
		nntp_store, cancellable, error, nntp_folder, &line, NULL);

	if (camel_folder_change_info_changed (nntp_folder->changes)) {
		changes = nntp_folder->changes;
		nntp_folder->changes = camel_folder_change_info_new ();
	}

	if (changes) {
		camel_folder_changed (folder, changes);
		camel_folder_change_info_free (changes);
	}

	return success;
}
static gchar *
nntp_get_filename (CamelFolder *folder,
                   const gchar *uid,
                   GError **error)
{
	CamelStore *parent_store;
	CamelDataCache *nntp_cache;
	CamelNNTPStore *nntp_store;
	gchar *article, *msgid;
	gsize article_len;
	gchar *filename;

	parent_store = camel_folder_get_parent_store (folder);
	nntp_store = CAMEL_NNTP_STORE (parent_store);

	article_len = strlen (uid) + 1;
	article = alloca (article_len);
	g_strlcpy (article, uid, article_len);
	msgid = strchr (article, ',');
	if (msgid == NULL) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Internal error: UID in invalid format: %s"), uid);
		return NULL;
	}
	*msgid++ = 0;

	nntp_cache = camel_nntp_store_ref_cache (nntp_store);
	filename = camel_data_cache_get_filename (nntp_cache, "cache", msgid);
	g_clear_object (&nntp_cache);

	return filename;
}
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;
}
GtkWidget *
org_gnome_exchange_show_folder_size_factory (EPlugin *epl, EConfigHookItemFactoryData *data)
{
    EMConfigTargetFolder *target=  (EMConfigTargetFolder *)data->config->target;
    CamelFolder *cml_folder = target->folder;
    CamelService *service;
    CamelProvider *provider;
    ExchangeAccount *account;
    GtkWidget *lbl_size, *lbl_size_val;
    GtkListStore *model;
    GtkVBox *vbx;
    GtkHBox *hbx_size;
    char *folder_name, *folder_size;
    int mode;

    service = CAMEL_SERVICE (camel_folder_get_parent_store (cml_folder));
    if (!service)
        return NULL;

    provider = camel_service_get_provider (service);
    if (!provider)
        return NULL;

    if (g_ascii_strcasecmp (provider->protocol, "exchange"))
        return NULL;

    account = exchange_operations_get_exchange_account ();
    exchange_account_is_offline (account, &mode);
    if (mode == OFFLINE_MODE)
        return NULL;

    folder_name = (char*) camel_folder_get_name (cml_folder);
    if (!folder_name)
        folder_name = g_strdup ("name");

    model = exchange_account_folder_size_get_model (account);
    if (model)
        folder_size = g_strdup_printf (_("%s KB"), exchange_folder_size_get_val (model, folder_name));
    else
        folder_size = g_strdup (_("0 KB"));

    hbx_size = (GtkHBox*) gtk_hbox_new (FALSE, 0);
    vbx = (GtkVBox *)gtk_notebook_get_nth_page (GTK_NOTEBOOK (data->parent), 0);

    lbl_size = gtk_label_new_with_mnemonic (_("Size:"));
    lbl_size_val = gtk_label_new_with_mnemonic (_(folder_size));
    gtk_widget_show (lbl_size);
    gtk_widget_show (lbl_size_val);
    gtk_misc_set_alignment (GTK_MISC (lbl_size), 0.0, 0.5);
    gtk_misc_set_alignment (GTK_MISC (lbl_size_val), 0.0, 0.5);
    gtk_box_pack_start (GTK_BOX (hbx_size), lbl_size, FALSE, TRUE, 12);
    gtk_box_pack_start (GTK_BOX (hbx_size), lbl_size_val, FALSE, TRUE, 10);
    gtk_widget_show_all (GTK_WIDGET (hbx_size));

    gtk_box_pack_start (GTK_BOX (vbx), GTK_WIDGET (hbx_size), FALSE, FALSE, 0);
    g_free (folder_size);

    return GTK_WIDGET (hbx_size);
}
示例#9
0
static ESource *
guess_mail_account_from_folder (ESourceRegistry *registry,
                                CamelFolder *folder,
                                const gchar *message_uid)
{
	ESource *source;
	CamelStore *store;
	const gchar *uid;

	/* Lookup an ESource by CamelStore UID. */
	store = camel_folder_get_parent_store (folder);
	if (message_uid && folder && CAMEL_IS_VEE_STORE (store)) {
		CamelMessageInfo *mi = camel_folder_get_message_info (folder, message_uid);
		if (mi) {
			CamelFolder *location;

			location = camel_vee_folder_get_location (CAMEL_VEE_FOLDER (folder), (CamelVeeMessageInfo *) mi, NULL);
			if (location)
				store = camel_folder_get_parent_store (location);
			camel_folder_free_message_info (folder, mi);
		}
	}

	uid = camel_service_get_uid (CAMEL_SERVICE (store));
	source = e_source_registry_ref_source (registry, uid);

	/* If we found an ESource, make sure it's a mail account. */
	if (source != NULL) {
		const gchar *extension_name;

		extension_name = E_SOURCE_EXTENSION_MAIL_ACCOUNT;
		if (!e_source_has_extension (source, extension_name)) {
			g_object_unref (source);
			source = NULL;
		}
	}

	return source;
}
示例#10
0
static gchar *
set_organizer (ECalComponent *comp,
               CamelFolder *folder)
{
	EShell *shell;
	ESource *source = NULL;
	ESourceRegistry *registry;
	ESourceMailIdentity *extension;
	const gchar *extension_name;
	const gchar *address, *name;
	ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL};
	gchar *mailto = NULL;

	shell = e_shell_get_default ();
	registry = e_shell_get_registry (shell);

	if (folder != NULL) {
		CamelStore *store;

		store = camel_folder_get_parent_store (folder);
		source = em_utils_ref_mail_identity_for_store (registry, store);
	}

	if (source == NULL)
		source = e_source_registry_ref_default_mail_identity (registry);

	g_return_val_if_fail (source != NULL, NULL);

	extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
	extension = e_source_get_extension (source, extension_name);

	name = e_source_mail_identity_get_name (extension);
	address = e_source_mail_identity_get_address (extension);

	if (name != NULL && address != NULL) {
		mailto = g_strconcat ("mailto:", address, NULL);
		organizer.value = mailto;
		organizer.cn = name;
		e_cal_component_set_organizer (comp, &organizer);
	}

	g_object_unref (source);

	return mailto;
}
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;
}
示例#12
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);
}
示例#13
0
/**
 * em_utils_folder_is_outbox:
 * @registry: an #ESourceRegistry
 * @folder: a #CamelFolder
 *
 * Decides if @folder is an Outbox folder.
 *
 * Returns %TRUE if this is an Outbox folder or %FALSE otherwise.
 **/
gboolean
em_utils_folder_is_outbox (ESourceRegistry *registry,
                           CamelFolder *folder)
{
	CamelStore *store;
	CamelSession *session;
	CamelFolder *local_outbox_folder;
	gboolean is_outbox;

	g_return_val_if_fail (CAMEL_IS_FOLDER (folder), FALSE);

	store = camel_folder_get_parent_store (folder);
	session = camel_service_ref_session (CAMEL_SERVICE (store));

	local_outbox_folder =
		e_mail_session_get_local_folder (
		E_MAIL_SESSION (session), E_MAIL_LOCAL_FOLDER_OUTBOX);

	is_outbox = (folder == local_outbox_folder);

	g_object_unref (session);

	return is_outbox;
}
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 gint
exchange_entry_play_transfer (CamelOfflineJournal *journal,
                              CamelExchangeJournalEntry *entry,
                              GCancellable *cancellable,
                              GError **error)
{
	CamelExchangeFolder *exchange_folder = (CamelExchangeFolder *) journal->folder;
	CamelFolder *folder = journal->folder;
	CamelMessageInfo *info, *real;
	GPtrArray *xuids, *uids;
	CamelFolder *src;
	CamelExchangeStore *store;
	CamelStream *stream;
	CamelMimeMessage *message;
	CamelStore *parent_store;

	if (!exchange_folder->cache || !(stream = camel_data_cache_get (exchange_folder->cache, "cache", entry->uid, NULL)))
		goto done;

	message = camel_mime_message_new ();
	if (!camel_data_wrapper_construct_from_stream_sync (
		(CamelDataWrapper *) message, stream, cancellable, NULL)) {
		g_object_unref (message);
		g_object_unref (stream);
		goto done;
	}

	g_object_unref (stream);

	if (!(info = camel_folder_summary_get (folder->summary, entry->uid))) {
		/* Note: this should never happen, but rather than crash lets make a new info */
		info = camel_message_info_new (NULL);
	}

	if (!entry->folder_name) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("No folder name found"));
		goto exception;
	}

	parent_store = camel_folder_get_parent_store (folder);
	store = CAMEL_EXCHANGE_STORE (parent_store);

	g_mutex_lock (store->folders_lock);
	src = (CamelFolder *) g_hash_table_lookup (store->folders, entry->folder_name);
	g_mutex_unlock (store->folders_lock);

	if (src) {
		gboolean success;
		uids = g_ptr_array_sized_new (1);
		g_ptr_array_add (uids, entry->original_uid);

		success = camel_folder_transfer_messages_to_sync (
			src, uids, folder, entry->delete_original,
			&xuids, cancellable, error);
		if (!success)
			goto exception;

		real = camel_folder_summary_info_new_from_message (
			folder->summary, message, NULL);
		g_object_unref (message);
		real->uid = camel_pstring_strdup (
			(gchar *) xuids->pdata[0]);
		/* Transfer flags */
		exchange_message_info_dup_to (
			(CamelMessageInfoBase *) real,
			(CamelMessageInfoBase *) info);
		camel_folder_summary_add (folder->summary, real);
		/* FIXME: should a folder_changed event be triggered? */

		g_ptr_array_free (xuids, TRUE);
		g_ptr_array_free (uids, TRUE);
		/* g_object_unref (src); FIXME: should we? */

	} else {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Folder doesn't exist"));
		goto exception;
	}

	camel_message_info_free (info);
done:
	camel_exchange_folder_remove_message (exchange_folder, entry->uid);

	return 0;

exception:

	camel_message_info_free (info);

	return -1;
}
static gboolean
maildir_folder_transfer_messages_to_sync (CamelFolder *source,
                                          GPtrArray *uids,
                                          CamelFolder *dest,
                                          gboolean delete_originals,
                                          GPtrArray **transferred_uids,
                                          GCancellable *cancellable,
                                          GError **error)
{
	gboolean fallback = FALSE;

	if (delete_originals && CAMEL_IS_MAILDIR_FOLDER (source) && CAMEL_IS_MAILDIR_FOLDER (dest)
	    && camel_folder_get_parent_store (source) == camel_folder_get_parent_store (dest)) {
		gint i;
		CamelLocalFolder *lf = (CamelLocalFolder *) source;
		CamelLocalFolder *df = (CamelLocalFolder *) dest;

		camel_operation_push_message (
			cancellable, _("Moving messages"));

		camel_folder_freeze (dest);
		camel_folder_freeze (source);

		for (i = 0; i < uids->len; i++) {
			gchar *uid = (gchar *) uids->pdata[i];
			gchar *s_filename, *d_filename, *new_filename;
			CamelMaildirMessageInfo *mdi;
			CamelMessageInfo *info;

			if ((info = camel_folder_summary_get (source->summary, uid)) == NULL) {
				set_cannot_get_message_ex (
					error, CAMEL_FOLDER_ERROR_INVALID_UID,
					uid, lf->folder_path, _("No such message"));
				return FALSE;
			}

			mdi = (CamelMaildirMessageInfo *) info;
			new_filename = camel_maildir_summary_info_to_name (mdi);

			d_filename = g_strdup_printf ("%s/cur/%s", df->folder_path, new_filename);
			s_filename = g_strdup_printf ("%s/cur/%s", lf->folder_path, camel_maildir_info_filename (mdi));

			if (g_rename (s_filename, d_filename) != 0) {
				if (errno == EXDEV) {
					i = uids->len + 1;
					fallback = TRUE;
				} else {
					g_set_error (
						error, G_IO_ERROR,
						g_io_error_from_errno (errno),
						_("Cannot transfer message to destination folder: %s"),
						g_strerror (errno));
					camel_message_info_unref (info);
					g_free (s_filename);
					g_free (d_filename);
					g_free (new_filename);
					break;
				}
			} else {
				CamelMessageInfo *clone;
				CamelMaildirMessageInfo *mclone;

				clone = camel_message_info_clone (info);
				clone->summary = dest->summary;

				mclone = (CamelMaildirMessageInfo *) clone;
				/* preserve also UID, as it matches the file name */
				mclone->info.info.uid = camel_pstring_strdup (camel_message_info_get_uid (info));
				camel_maildir_info_set_filename (clone, g_strdup (new_filename));
				/* unset deleted flag when transferring from trash folder */
				if ((source->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0)
					camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0);
				/* unset junk flag when transferring from junk folder */
				if ((source->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0)
					camel_message_info_set_flags (info, CAMEL_MESSAGE_JUNK, 0);
				camel_folder_summary_add (dest->summary, clone);

				camel_folder_change_info_add_uid (df->changes, camel_message_info_get_uid (clone));

				camel_folder_set_message_flags (
					source, uid, CAMEL_MESSAGE_DELETED |
					CAMEL_MESSAGE_SEEN, ~0);
				camel_folder_change_info_remove_uid (lf->changes, camel_message_info_get_uid (info));
				camel_folder_summary_remove (source->summary, info);
			}

			camel_message_info_unref (info);
			g_free (s_filename);
			g_free (d_filename);
			g_free (new_filename);
		}

		if (lf && camel_folder_change_info_changed (lf->changes)) {
			camel_folder_changed (source, lf->changes);
			camel_folder_change_info_clear (lf->changes);
		}

		if (df && camel_folder_change_info_changed (df->changes)) {
			camel_folder_changed (dest, df->changes);
			camel_folder_change_info_clear (df->changes);
		}

		camel_folder_thaw (source);
		camel_folder_thaw (dest);

		camel_operation_pop_message (cancellable);
	} else
		fallback = TRUE;

	if (fallback) {
		CamelFolderClass *folder_class;

		/* Chain up to parent's transfer_messages_to() method. */
		folder_class = CAMEL_FOLDER_CLASS (camel_maildir_folder_parent_class);
		return folder_class->transfer_messages_to_sync (
			source, uids, dest, delete_originals,
			transferred_uids, cancellable, error);
	}

	return TRUE;
}
示例#17
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);
}
static gboolean
nntp_folder_append_message_sync (CamelFolder *folder,
                                 CamelMimeMessage *message,
                                 CamelMessageInfo *info,
                                 gchar **appended_uid,
                                 GCancellable *cancellable,
                                 GError **error)
{
	CamelStore *parent_store;
	CamelNNTPStore *nntp_store;
	CamelNNTPStream *nntp_stream = NULL;
	CamelStream *filtered_stream;
	CamelMimeFilter *crlffilter;
	gint ret;
	guint u;
	struct _camel_header_raw *header, *savedhdrs, *n, *tail;
	const gchar *full_name;
	gchar *group, *line;
	gboolean success = TRUE;
	GError *local_error = NULL;

	full_name = camel_folder_get_full_name (folder);
	parent_store = camel_folder_get_parent_store (folder);

	nntp_store = CAMEL_NNTP_STORE (parent_store);

	/* send 'POST' command */
	ret = camel_nntp_command (
		nntp_store, cancellable, error, NULL, &line, "post");
	if (ret != 340) {
		if (ret == 440) {
			g_set_error (
				error, CAMEL_FOLDER_ERROR,
				CAMEL_FOLDER_ERROR_INSUFFICIENT_PERMISSION,
				_("Posting failed: %s"), line);
			success = FALSE;
		} else if (ret != -1) {
			g_set_error (
				error, CAMEL_ERROR,
				CAMEL_ERROR_GENERIC,
				_("Posting failed: %s"), line);
			success = FALSE;
		}
		goto exit;
	}

	/* the 'Newsgroups: ' header */
	group = g_strdup_printf ("Newsgroups: %s\r\n", full_name);

	/* remove mail 'To', 'CC', and 'BCC' headers */
	savedhdrs = NULL;
	tail = (struct _camel_header_raw *) &savedhdrs;

	header = (struct _camel_header_raw *) &CAMEL_MIME_PART (message)->headers;
	n = header->next;
	while (n != NULL) {
		if (!g_ascii_strcasecmp (n->name, "To") || !g_ascii_strcasecmp (n->name, "Cc") || !g_ascii_strcasecmp (n->name, "Bcc")) {
			header->next = n->next;
			tail->next = n;
			n->next = NULL;
			tail = n;
		} else {
			header = n;
		}

		n = header->next;
	}

	nntp_stream = camel_nntp_store_ref_stream (nntp_store);

	/* setup stream filtering */
	filtered_stream = camel_stream_filter_new (CAMEL_STREAM (nntp_stream));
	crlffilter = camel_mime_filter_crlf_new (
		CAMEL_MIME_FILTER_CRLF_ENCODE,
		CAMEL_MIME_FILTER_CRLF_MODE_CRLF_DOTS);
	camel_stream_filter_add (
		CAMEL_STREAM_FILTER (filtered_stream), crlffilter);
	g_object_unref (crlffilter);

	/* write the message */
	if (local_error == NULL)
		camel_stream_write (
			CAMEL_STREAM (nntp_stream),
			group, strlen (group),
			cancellable, &local_error);
	if (local_error == NULL)
		camel_data_wrapper_write_to_stream_sync (
			CAMEL_DATA_WRAPPER (message),
			filtered_stream, cancellable, &local_error);
	if (local_error == NULL)
		camel_stream_flush (
			filtered_stream, cancellable, &local_error);
	if (local_error == NULL)
		camel_stream_write (
			CAMEL_STREAM (nntp_stream),
			"\r\n.\r\n", 5,
			cancellable, &local_error);
	if (local_error == NULL)
		camel_nntp_stream_line (
			nntp_stream, (guchar **) &line,
			&u, cancellable, &local_error);
	if (local_error == NULL && atoi (line) != 240)
		local_error = g_error_new_literal (
			CAMEL_ERROR, CAMEL_ERROR_GENERIC, line);

	if (local_error != NULL) {
		g_propagate_prefixed_error (
			error, local_error, _("Posting failed: "));
		success = FALSE;
	}

	g_object_unref (filtered_stream);
	g_free (group);
	header->next = savedhdrs;

exit:
	g_clear_object (&nntp_stream);

	return success;
}
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 CamelMimeMessage *
nntp_folder_get_message_sync (CamelFolder *folder,
                              const gchar *uid,
                              GCancellable *cancellable,
                              GError **error)
{
	CamelStore *parent_store;
	CamelMimeMessage *message = NULL;
	CamelDataCache *nntp_cache;
	CamelNNTPStore *nntp_store;
	CamelFolderChangeInfo *changes;
	CamelNNTPFolder *nntp_folder;
	CamelStream *stream = NULL;
	GIOStream *base_stream;
	gchar *article, *msgid;
	gsize article_len;

	parent_store = camel_folder_get_parent_store (folder);

	nntp_folder = CAMEL_NNTP_FOLDER (folder);
	nntp_store = CAMEL_NNTP_STORE (parent_store);

	article_len = strlen (uid) + 1;
	article = alloca (article_len);
	g_strlcpy (article, uid, article_len);
	msgid = strchr (article, ',');
	if (msgid == NULL) {
		g_set_error (
			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
			_("Internal error: UID in invalid format: %s"), uid);
		return NULL;
	}
	*msgid++ = 0;

	/* Lookup in cache, NEWS is global messageid's so use a global cache path */
	nntp_cache = camel_nntp_store_ref_cache (nntp_store);
	base_stream = camel_data_cache_get (nntp_cache, "cache", msgid, NULL);
	g_clear_object (&nntp_cache);

	if (base_stream != NULL) {
		stream = camel_stream_new (base_stream);
		g_object_unref (base_stream);
	} else {
		CamelServiceConnectionStatus connection_status;

		connection_status = camel_service_get_connection_status (
			CAMEL_SERVICE (parent_store));

		if (connection_status != CAMEL_SERVICE_CONNECTED) {
			g_set_error (
				error, CAMEL_SERVICE_ERROR,
				CAMEL_SERVICE_ERROR_UNAVAILABLE,
				_("This message is not currently available"));
			goto fail;
		}

		stream = nntp_folder_download_message (nntp_folder, article, msgid, cancellable, error);
		if (stream == NULL)
			goto fail;
	}

	message = camel_mime_message_new ();
	if (!camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) message, stream, cancellable, error)) {
		g_prefix_error (error, _("Cannot get message %s: "), uid);
		g_object_unref (message);
		message = NULL;
	}

	g_object_unref (stream);
fail:
	if (camel_folder_change_info_changed (nntp_folder->changes)) {
		changes = nntp_folder->changes;
		nntp_folder->changes = camel_folder_change_info_new ();
	} else {
		changes = NULL;
	}

	if (changes) {
		camel_folder_changed (folder, changes);
		camel_folder_change_info_free (changes);
	}

	return message;
}
示例#21
0
void
e_mail_shell_view_update_sidebar (EMailShellView *mail_shell_view)
{
	EMailShellContent *mail_shell_content;
	EShellBackend *shell_backend;
	EShellSidebar *shell_sidebar;
	EShellView *shell_view;
	EShell *shell;
	EMailReader *reader;
	EMailView *mail_view;
	ESourceRegistry *registry;
	CamelStore *parent_store;
	CamelFolder *folder;
	CamelFolderInfoFlags flags = 0;
	CamelFolderSummary *folder_summary;
	MailFolderCache *folder_cache;
	MessageList *message_list;
	guint selected_count;
	GString *buffer, *title_short = NULL;
	gboolean store_is_local, is_inbox;
	const gchar *display_name;
	const gchar *folder_name;
	const gchar *uid;
	gchar *title;
	guint32 num_deleted;
	guint32 num_junked;
	guint32 num_junked_not_deleted;
	guint32 num_unread;
	guint32 num_visible;

	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);

	shell_view = E_SHELL_VIEW (mail_shell_view);
	shell_backend = e_shell_view_get_shell_backend (shell_view);
	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);

	shell = e_shell_backend_get_shell (shell_backend);
	registry = e_shell_get_registry (shell);

	reader = E_MAIL_READER (mail_view);
	folder = e_mail_reader_ref_folder (reader);

	/* If no folder is selected, reset the sidebar banners
	 * to their default values and stop. */
	if (folder == NULL) {
		GtkAction *action;
		gchar *label;

		action = e_shell_view_get_action (shell_view);

		g_object_get (action, "label", &label, NULL);
		e_shell_sidebar_set_secondary_text (shell_sidebar, NULL);
		e_shell_view_set_title (shell_view, label);
		g_free (label);

		return;
	}

	folder_name = camel_folder_get_display_name (folder);
	parent_store = camel_folder_get_parent_store (folder);
	folder_summary = camel_folder_get_folder_summary (folder);

	folder_cache = e_mail_session_get_folder_cache (
		e_mail_backend_get_session (E_MAIL_BACKEND (shell_backend)));
	mail_folder_cache_get_folder_info_flags (folder_cache, parent_store, folder_name, &flags);
	is_inbox = (flags & CAMEL_FOLDER_TYPE_MASK) == CAMEL_FOLDER_TYPE_INBOX;

	num_deleted = camel_folder_summary_get_deleted_count (folder_summary);
	num_junked = camel_folder_summary_get_junk_count (folder_summary);
	num_junked_not_deleted = camel_folder_summary_get_junk_not_deleted_count (folder_summary);
	num_unread = camel_folder_summary_get_unread_count (folder_summary);
	num_visible = camel_folder_summary_get_visible_count (folder_summary);

	buffer = g_string_sized_new (256);
	message_list = MESSAGE_LIST (e_mail_reader_get_message_list (reader));
	selected_count = message_list_selected_count (message_list);

	if (selected_count > 1)
		g_string_append_printf (
			buffer, ngettext ("%d selected, ", "%d selected, ",
			selected_count), selected_count);

	/* "Trash" folder (virtual or real) */
	if (camel_folder_get_flags (folder) & CAMEL_FOLDER_IS_TRASH) {
		if (CAMEL_IS_VTRASH_FOLDER (folder)) {
			/* For a virtual Trash folder, count
			 * the messages marked for deletion. */
			g_string_append_printf (
				buffer, ngettext ("%d deleted",
				"%d deleted", num_deleted), num_deleted);
		} else {
			/* For a regular Trash folder, just
			 * count the visible messages.
			 *
			 * XXX Open question: what to do about messages
			 *     marked for deletion in Trash?  Probably
			 *     this is the wrong question to be asking
			 *     anyway.  Deleting a message in a real
			 *     Trash should permanently expunge the
			 *     message (if the server supports that),
			 *     which would eliminate this corner case. */
			if (!e_mail_reader_get_hide_deleted (reader))
				num_visible += num_deleted;

			g_string_append_printf (
				buffer, ngettext ("%d deleted",
				"%d deleted", num_visible), num_visible);
		}

	/* "Junk" folder (virtual or real) */
	} else if (camel_folder_get_flags (folder) & CAMEL_FOLDER_IS_JUNK) {
		if (e_mail_reader_get_hide_deleted (reader)) {
			/* Junk folder with deleted messages hidden. */
			g_string_append_printf (
				buffer, ngettext ("%d junk",
				"%d junk", num_junked_not_deleted),
				num_junked_not_deleted);
		} else {
			/* Junk folder with deleted messages visible. */
			g_string_append_printf (
				buffer, ngettext ("%d junk", "%d junk",
				num_junked), num_junked);
		}

	/* "Drafts" folder */
	} else if (!is_inbox && em_utils_folder_is_drafts (registry, folder)) {
		g_string_append_printf (
			buffer, ngettext ("%d draft", "%d drafts",
			num_visible), num_visible);

	/* "Outbox" folder */
	} else if (!is_inbox && em_utils_folder_is_outbox (registry, folder)) {
		g_string_append_printf (
			buffer, ngettext ("%d unsent", "%d unsent",
			num_visible), num_visible);

	/* "Sent" folder */
	} else if (!is_inbox && em_utils_folder_is_sent (registry, folder)) {
		g_string_append_printf (
			buffer, ngettext ("%d sent", "%d sent",
			num_visible), num_visible);

	/* Normal folder */
	} else {
		if (!e_mail_reader_get_hide_deleted (reader))
			num_visible +=
				num_deleted - num_junked +
				num_junked_not_deleted;

		if (num_unread > 0 && selected_count <= 1) {
			g_string_append_printf (
				buffer, ngettext ("%d unread, ",
				"%d unread, ", num_unread), num_unread);

			title_short = g_string_sized_new (64);
			g_string_append_printf (
				title_short, ngettext ("%d unread",
				"%d unread", num_unread), num_unread);
		}

		g_string_append_printf (
			buffer, ngettext ("%d total", "%d total",
			num_visible), num_visible);
	}

	uid = camel_service_get_uid (CAMEL_SERVICE (parent_store));
	store_is_local = (g_strcmp0 (uid, E_MAIL_SESSION_LOCAL_UID) == 0);

	/* Choose a suitable folder name for displaying. */
	display_name = folder_name;
	if (store_is_local) {
		if (strcmp (folder_name, "Drafts") == 0)
			display_name = _("Drafts");
		else if (strcmp (folder_name, "Inbox") == 0)
			display_name = _("Inbox");
		else if (strcmp (folder_name, "Outbox") == 0)
			display_name = _("Outbox");
		else if (strcmp (folder_name, "Sent") == 0)
			display_name = _("Sent");
		else if (strcmp (folder_name, "Templates") == 0)
			display_name = _("Templates");
		else if (strcmp (folder_name, "Trash") == 0)
			display_name = _("Trash");
	}
	if (strcmp (folder_name, "INBOX") == 0)
		display_name = _("Inbox");

	if (title_short && title_short->len > 0)
		title = g_strdup_printf ("%s (%s)", display_name, title_short->str);
	else
		title = g_strdup (display_name);
	e_shell_sidebar_set_secondary_text (shell_sidebar, buffer->str);
	e_shell_view_set_title (shell_view, title);
	g_free (title);

	g_string_free (buffer, TRUE);
	if (title_short)
		g_string_free (title_short, TRUE);

	g_clear_object (&folder);
}