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 (camel_folder_get_folder_summary (source), 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 (info);

			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_message_info_get_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));
					g_clear_object (&info);
					g_free (s_filename);
					g_free (d_filename);
					g_free (new_filename);
					break;
				}
			} else {
				CamelMessageInfo *clone;

				clone = camel_message_info_clone (info, camel_folder_get_folder_summary (dest));

				camel_maildir_message_info_set_filename (CAMEL_MAILDIR_MESSAGE_INFO (clone), new_filename);
				/* unset deleted flag when transferring from trash folder */
				if ((camel_folder_get_flags (source) & CAMEL_FOLDER_IS_TRASH) != 0)
					camel_message_info_set_flags (info, CAMEL_MESSAGE_DELETED, 0);
				/* unset junk flag when transferring from junk folder */
				if ((camel_folder_get_flags (source) & CAMEL_FOLDER_IS_JUNK) != 0)
					camel_message_info_set_flags (info, CAMEL_MESSAGE_JUNK, 0);
				camel_folder_summary_add (camel_folder_get_folder_summary (dest), clone, FALSE);

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

				camel_folder_set_message_flags (
					source, uid, CAMEL_MESSAGE_DELETED |
					CAMEL_MESSAGE_SEEN, ~0);
				camel_local_folder_lock_changes (lf);
				camel_folder_change_info_remove_uid (lf->changes, camel_message_info_get_uid (info));
				camel_local_folder_unlock_changes (lf);
				camel_folder_summary_remove (camel_folder_get_folder_summary (source), info);
				g_clear_object (&clone);
			}

			g_clear_object (&info);
			g_free (s_filename);
			g_free (d_filename);
			g_free (new_filename);
		}

		camel_local_folder_claim_changes (lf);
		camel_local_folder_claim_changes (df);

		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;
}
Ejemplo n.º 2
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);
}