Loading k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java +36 −35 Original line number Diff line number Diff line Loading @@ -113,8 +113,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, public static final String ACTION_EDIT_DRAFT = "com.fsck.k9.intent.action.EDIT_DRAFT"; public static final String EXTRA_ACCOUNT = "account"; public static final String EXTRA_MESSAGE_BODY = "messageBody"; public static final String EXTRA_MESSAGE_REFERENCE = "message_reference"; public static final String EXTRA_MESSAGE_DECRYPTION_RESULT = "message_decryption_result"; private static final String STATE_KEY_SOURCE_MESSAGE_PROCED = "com.fsck.k9.activity.MessageCompose.stateKeySourceMessageProced"; Loading @@ -133,7 +133,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, private static final int MSG_PROGRESS_ON = 1; private static final int MSG_PROGRESS_OFF = 2; private static final int MSG_SKIPPED_ATTACHMENTS = 3; public static final int MSG_SAVED_DRAFT = 4; private static final int MSG_DISCARDED_DRAFT = 5; Loading Loading @@ -278,12 +277,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, case MSG_PROGRESS_OFF: setProgressBarIndeterminateVisibility(false); break; case MSG_SKIPPED_ATTACHMENTS: Toast.makeText( MessageCompose.this, getString(R.string.message_compose_attachments_skipped_toast), Toast.LENGTH_LONG).show(); break; case MSG_SAVED_DRAFT: mDraftId = (Long) msg.obj; Toast.makeText( Loading Loading @@ -373,10 +366,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, EolConvertingEditText upperSignature = (EolConvertingEditText)findViewById(R.id.upper_signature); EolConvertingEditText lowerSignature = (EolConvertingEditText)findViewById(R.id.lower_signature); String sourceMessageBody = intent.getStringExtra(EXTRA_MESSAGE_BODY); QuotedMessageMvpView quotedMessageMvpView = new QuotedMessageMvpView(this); quotedMessagePresenter = new QuotedMessagePresenter(this, quotedMessageMvpView, mAccount, sourceMessageBody); quotedMessagePresenter = new QuotedMessagePresenter(this, quotedMessageMvpView, mAccount); attachmentPresenter = new AttachmentPresenter(getApplicationContext(), attachmentMvpView, getLoaderManager()); mMessageContentView = (EolConvertingEditText)findViewById(R.id.message_content); Loading Loading @@ -474,7 +465,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, messageLoaderHelper = new MessageLoaderHelper(this, getLoaderManager(), getFragmentManager(), messageLoaderCallbacks); mHandler.sendEmptyMessage(MSG_PROGRESS_ON); messageLoaderHelper.asyncStartOrResumeLoadingMessage(mMessageReference); Parcelable cachedDecryptionResult = intent.getParcelableExtra(EXTRA_MESSAGE_DECRYPTION_RESULT); messageLoaderHelper.asyncStartOrResumeLoadingMessage(mMessageReference, cachedDecryptionResult); } if (mAction != Action.EDIT_DRAFT) { Loading Loading @@ -1139,30 +1132,30 @@ public class MessageCompose extends K9Activity implements OnClickListener, throw new IllegalStateException("tried to edit quoted message with no referenced message"); } messageLoaderHelper.asyncStartOrResumeLoadingMessage(mMessageReference); messageLoaderHelper.asyncStartOrResumeLoadingMessage(mMessageReference, null); } /** * Pull out the parts of the now loaded source message and apply them to the new message * depending on the type of message being composed. * * @param message * @param messageViewInfo * The source message used to populate the various text fields. */ private void processSourceMessage(LocalMessage message) { private void processSourceMessage(MessageViewInfo messageViewInfo) { try { switch (mAction) { case REPLY: case REPLY_ALL: { processMessageToReplyTo(message); processMessageToReplyTo(messageViewInfo); break; } case FORWARD: { processMessageToForward(message); processMessageToForward(messageViewInfo); break; } case EDIT_DRAFT: { processDraftMessage(message); processDraftMessage(messageViewInfo); break; } default: { Loading @@ -1184,7 +1177,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, updateMessageFormat(); } private void processMessageToReplyTo(Message message) throws MessagingException { private void processMessageToReplyTo(MessageViewInfo messageViewInfo) throws MessagingException { Message message = messageViewInfo.message; if (message.getSubject() != null) { final String subject = PREFIX.matcher(message.getSubject()).replaceFirst(""); Loading Loading @@ -1221,7 +1216,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, } // Quote the message and setup the UI. quotedMessagePresenter.initFromReplyToMessage(message, mAction); quotedMessagePresenter.initFromReplyToMessage(messageViewInfo, mAction); if (mAction == Action.REPLY || mAction == Action.REPLY_ALL) { Identity useIdentity = IdentityHelper.getRecipientIdentityFromMessage(mAccount, message); Loading @@ -1233,7 +1228,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, } private void processMessageToForward(Message message) throws MessagingException { private void processMessageToForward(MessageViewInfo messageViewInfo) throws MessagingException { Message message = messageViewInfo.message; String subject = message.getSubject(); if (subject != null && !subject.toLowerCase(Locale.US).startsWith("fwd:")) { mSubjectView.setText("Fwd: " + subject); Loading @@ -1255,16 +1252,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, } // Quote the message and setup the UI. quotedMessagePresenter.processMessageToForward(message); if (!mSourceMessageProcessed) { if (message.isSet(Flag.X_DOWNLOADED_PARTIAL) || !attachmentPresenter.loadAttachments(message, 0)) { mHandler.sendEmptyMessage(MSG_SKIPPED_ATTACHMENTS); } } quotedMessagePresenter.processMessageToForward(messageViewInfo); attachmentPresenter.processMessageToForward(messageViewInfo); } private void processDraftMessage(LocalMessage message) throws MessagingException { private void processDraftMessage(MessageViewInfo messageViewInfo) throws MessagingException { Message message = messageViewInfo.message; mDraftId = MessagingController.getInstance(getApplication()).getId(message); mSubjectView.setText(message.getSubject()); Loading Loading @@ -1301,7 +1294,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, newIdentity.setSignature(k9identity.get(IdentityField.SIGNATURE)); mSignatureChanged = true; } else { newIdentity.setSignatureUse(message.getFolder().getSignatureUse()); if (message instanceof LocalMessage) { newIdentity.setSignatureUse(((LocalMessage) message).getFolder().getSignatureUse()); } newIdentity.setSignature(mIdentity.getSignature()); } Loading Loading @@ -1341,7 +1336,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, updateSignature(); updateFrom(); quotedMessagePresenter.processDraftMessage(message, k9identity); quotedMessagePresenter.processDraftMessage(messageViewInfo, k9identity); } static class SendMessageTask extends AsyncTask<Void, Void, Void> { Loading Loading @@ -1524,14 +1519,14 @@ public class MessageCompose extends K9Activity implements OnClickListener, } } public void loadLocalMessageForDisplay(LocalMessage message, Action action) { public void loadLocalMessageForDisplay(MessageViewInfo messageViewInfo, Action action) { // We check to see if we've previously processed the source message since this // could be called when switching from HTML to text replies. If that happens, we // only want to update the UI with quoted text (which picks the appropriate // part). if (mSourceMessageProcessed) { try { quotedMessagePresenter.populateUIWithQuotedMessage(message, true, action); quotedMessagePresenter.populateUIWithQuotedMessage(messageViewInfo, true, action); } catch (MessagingException e) { // Hm, if we couldn't populate the UI after source reprocessing, let's just delete it? quotedMessagePresenter.showOrHideQuotedText(QuotedTextMode.HIDE); Loading @@ -1539,7 +1534,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, } updateMessageFormat(); } else { processSourceMessage(message); processSourceMessage(messageViewInfo); mSourceMessageProcessed = true; } } Loading @@ -1559,7 +1554,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, @Override public void onMessageViewInfoLoadFinished(LocalMessage localMessage, MessageViewInfo messageViewInfo) { mHandler.sendEmptyMessage(MSG_PROGRESS_OFF); loadLocalMessageForDisplay(localMessage, mAction); loadLocalMessageForDisplay(messageViewInfo, mAction); } @Override Loading Loading @@ -1731,6 +1726,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, public void performSaveAfterChecks() { MessageCompose.this.performSaveAfterChecks(); } @Override public void showMissingAttachmentsPartialMessageWarning() { Toast.makeText(MessageCompose.this, getString(R.string.message_compose_attachments_skipped_toast), Toast.LENGTH_LONG).show(); } }; } k9mail/src/main/java/com/fsck/k9/activity/MessageList.java +19 −4 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ import android.content.res.Configuration; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Parcelable; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; Loading Loading @@ -53,7 +54,6 @@ import com.fsck.k9.search.SearchSpecification; import com.fsck.k9.search.SearchSpecification.Attribute; import com.fsck.k9.search.SearchSpecification.SearchCondition; import com.fsck.k9.search.SearchSpecification.SearchField; import com.fsck.k9.ui.messageview.CryptoInfoDialog.OnClickShowCryptoKeyListener; import com.fsck.k9.ui.messageview.MessageViewFragment; import com.fsck.k9.ui.messageview.MessageViewFragment.MessageViewFragmentListener; import com.fsck.k9.view.MessageHeader; Loading Loading @@ -1210,17 +1210,32 @@ public class MessageList extends K9Activity implements MessageListFragmentListen @Override public void onForward(LocalMessage message) { MessageActions.actionForward(this, message, null); onForward(message, null); } @Override public void onForward(LocalMessage message, Parcelable decryptionResultForReply) { MessageActions.actionForward(this, message, decryptionResultForReply); } @Override public void onReply(LocalMessage message) { MessageActions.actionReply(this, message, false, null); onReply(message, null); } @Override public void onReply(LocalMessage message, Parcelable decryptionResultForReply) { MessageActions.actionReply(this, message, false, decryptionResultForReply); } @Override public void onReplyAll(LocalMessage message) { MessageActions.actionReply(this, message, true, null); onReplyAll(message, null); } @Override public void onReplyAll(LocalMessage message, Parcelable decryptionResultForReply) { MessageActions.actionReply(this, message, true, decryptionResultForReply); } @Override Loading k9mail/src/main/java/com/fsck/k9/activity/MessageLoaderHelper.java +14 −2 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ import android.content.Intent; import android.content.IntentSender; import android.content.Loader; import android.os.Bundle; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; Loading @@ -28,6 +29,7 @@ import com.fsck.k9.ui.crypto.MessageCryptoCallback; import com.fsck.k9.ui.crypto.MessageCryptoHelper; import com.fsck.k9.ui.message.LocalMessageExtractorLoader; import com.fsck.k9.ui.message.LocalMessageLoader; import org.openintents.openpgp.OpenPgpDecryptionResult; /** This class is responsible for loading a message start to finish, and Loading Loading @@ -83,6 +85,7 @@ public class MessageLoaderHelper { private LocalMessage localMessage; private MessageCryptoAnnotations messageCryptoAnnotations; private OpenPgpDecryptionResult cachedDecryptionResult; private MessageCryptoHelper messageCryptoHelper; Loading @@ -99,10 +102,18 @@ public class MessageLoaderHelper { // public interface @UiThread public void asyncStartOrResumeLoadingMessage(MessageReference messageReference) { public void asyncStartOrResumeLoadingMessage(MessageReference messageReference, Parcelable cachedDecryptionResult) { this.messageReference = messageReference; this.account = Preferences.getPreferences(context).getAccount(messageReference.getAccountUuid()); if (cachedDecryptionResult != null) { if (cachedDecryptionResult instanceof OpenPgpDecryptionResult) { this.cachedDecryptionResult = (OpenPgpDecryptionResult) cachedDecryptionResult; } else { Log.e(K9.LOG_TAG, "Got decryption result of unknown type - ignoring"); } } startOrResumeLocalMessageLoader(); } Loading Loading @@ -248,7 +259,8 @@ public class MessageLoaderHelper { messageCryptoHelper = new MessageCryptoHelper(context, account.getOpenPgpProvider()); retainCryptoHelperFragment.setData(messageCryptoHelper); } messageCryptoHelper.asyncStartOrResumeProcessingMessage(localMessage, messageCryptoCallback); messageCryptoHelper.asyncStartOrResumeProcessingMessage( localMessage, messageCryptoCallback, cachedDecryptionResult); } private void cancelAndClearCryptoOperation() { Loading k9mail/src/main/java/com/fsck/k9/activity/compose/AttachmentPresenter.java +52 −5 Original line number Diff line number Diff line Loading @@ -21,11 +21,14 @@ import com.fsck.k9.activity.loader.AttachmentContentLoader; import com.fsck.k9.activity.loader.AttachmentInfoLoader; import com.fsck.k9.activity.misc.Attachment; import com.fsck.k9.activity.misc.Attachment.LoadingState; import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.Multipart; import com.fsck.k9.mail.Part; import com.fsck.k9.mail.internet.MimeUtility; import com.fsck.k9.mailstore.AttachmentViewInfo; import com.fsck.k9.mailstore.LocalBodyPart; import com.fsck.k9.mailstore.MessageViewInfo; import com.fsck.k9.provider.AttachmentProvider; Loading Loading @@ -130,31 +133,74 @@ public class AttachmentPresenter { addAttachment(uri, null); } public void addAttachment(AttachmentViewInfo attachmentViewInfo) { if (attachments.containsKey(attachmentViewInfo.uri)) { throw new IllegalStateException("Received the same attachmentViewInfo twice!"); } int loaderId = getNextFreeLoaderId(); Attachment attachment = Attachment.createAttachment( attachmentViewInfo.uri, loaderId, attachmentViewInfo.mimeType); attachment = attachment.deriveWithMetadataLoaded( attachmentViewInfo.mimeType, attachmentViewInfo.displayName, attachmentViewInfo.size); addAttachmentAndStartLoader(attachment); } public void addAttachment(Uri uri, String contentType) { if (attachments.containsKey(uri)) { return; } int loaderId = getNextFreeLoaderId(); Attachment attachment = Attachment.createAttachment(uri, loaderId, contentType); if (attachments.containsKey(uri)) { addAttachmentAndStartLoader(attachment); } public void processMessageToForward(MessageViewInfo messageViewInfo) { if (messageViewInfo.message.isSet(Flag.X_DOWNLOADED_PARTIAL)) { attachmentMvpView.showMissingAttachmentsPartialMessageWarning(); return; } attachments.put(uri, attachment); for (AttachmentViewInfo attachmentViewInfo : messageViewInfo.attachments) { if (attachmentViewInfo.firstClassAttachment) { addAttachment(attachmentViewInfo); } } } private void addAttachmentAndStartLoader(Attachment attachment) { attachments.put(attachment.uri, attachment); attachmentMvpView.addAttachmentView(attachment); if (attachment.state == LoadingState.URI_ONLY) { initAttachmentInfoLoader(attachment); } else if (attachment.state == LoadingState.METADATA) { initAttachmentContentLoader(attachment); } else { throw new IllegalStateException("Attachment can only be added in URI_ONLY or METADATA state!"); } } private void initAttachmentInfoLoader(Attachment attachment) { if (attachment.state != LoadingState.URI_ONLY) { throw new IllegalStateException("initAttachmentInfoLoader can only be called for URI_ONLY state!"); } Bundle bundle = new Bundle(); bundle.putParcelable(LOADER_ARG_ATTACHMENT, attachment.uri); loaderManager.initLoader(attachment.loaderId, bundle, mAttachmentInfoLoaderCallback); } private void initAttachmentContentLoader(Attachment attachment) { if (attachment.state != LoadingState.METADATA) { throw new IllegalStateException("initAttachmentContentLoader can only be called for METADATA state!"); } Bundle bundle = new Bundle(); bundle.putParcelable(LOADER_ARG_ATTACHMENT, attachment.uri); loaderManager.initLoader(attachment.loaderId, bundle, mAttachmentContentLoaderCallback); } Loading Loading @@ -364,5 +410,6 @@ public class AttachmentPresenter { void performSendAfterChecks(); void performSaveAfterChecks(); void showMissingAttachmentsPartialMessageWarning(); } } k9mail/src/main/java/com/fsck/k9/activity/compose/MessageActions.java +7 −18 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ package com.fsck.k9.activity.compose; import android.content.Context; import android.content.Intent; import android.os.Parcelable; import com.fsck.k9.Account; import com.fsck.k9.Preferences; Loading @@ -28,15 +29,11 @@ public class MessageActions { /** * Get intent for composing a new message as a reply to the given message. If replyAll is true * the function is reply all instead of simply reply. * @param messageBody optional, for decrypted messages, null if it should be grabbed from the given message */ public static Intent getActionReplyIntent( Context context, LocalMessage message, boolean replyAll, String messageBody) { Context context, LocalMessage message, boolean replyAll, Parcelable decryptionResult) { Intent i = new Intent(context, MessageCompose.class); i.putExtra(MessageCompose.EXTRA_MESSAGE_BODY, messageBody); i.putExtra(MessageCompose.EXTRA_MESSAGE_DECRYPTION_RESULT, decryptionResult); i.putExtra(MessageCompose.EXTRA_MESSAGE_REFERENCE, message.makeMessageReference()); if (replyAll) { i.setAction(MessageCompose.ACTION_REPLY_ALL); Loading @@ -58,27 +55,19 @@ public class MessageActions { /** * Compose a new message as a reply to the given message. If replyAll is true the function * is reply all instead of simply reply. * @param messageBody optional, for decrypted messages, null if it should be grabbed from the given message */ public static void actionReply( Context context, LocalMessage message, boolean replyAll, String messageBody) { context.startActivity(getActionReplyIntent(context, message, replyAll, messageBody)); Context context, LocalMessage message, boolean replyAll, Parcelable decryptionResult) { context.startActivity(getActionReplyIntent(context, message, replyAll, decryptionResult)); } /** * Compose a new message as a forward of the given message. * @param messageBody optional, for decrypted messages, null if it should be grabbed from the given message */ public static void actionForward( Context context, LocalMessage message, String messageBody) { public static void actionForward(Context context, LocalMessage message, Parcelable decryptionResult) { Intent i = new Intent(context, MessageCompose.class); i.putExtra(MessageCompose.EXTRA_MESSAGE_BODY, messageBody); i.putExtra(MessageCompose.EXTRA_MESSAGE_REFERENCE, message.makeMessageReference()); i.putExtra(MessageCompose.EXTRA_MESSAGE_DECRYPTION_RESULT, decryptionResult); i.setAction(MessageCompose.ACTION_FORWARD); context.startActivity(i); } Loading Loading
k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java +36 −35 Original line number Diff line number Diff line Loading @@ -113,8 +113,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, public static final String ACTION_EDIT_DRAFT = "com.fsck.k9.intent.action.EDIT_DRAFT"; public static final String EXTRA_ACCOUNT = "account"; public static final String EXTRA_MESSAGE_BODY = "messageBody"; public static final String EXTRA_MESSAGE_REFERENCE = "message_reference"; public static final String EXTRA_MESSAGE_DECRYPTION_RESULT = "message_decryption_result"; private static final String STATE_KEY_SOURCE_MESSAGE_PROCED = "com.fsck.k9.activity.MessageCompose.stateKeySourceMessageProced"; Loading @@ -133,7 +133,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, private static final int MSG_PROGRESS_ON = 1; private static final int MSG_PROGRESS_OFF = 2; private static final int MSG_SKIPPED_ATTACHMENTS = 3; public static final int MSG_SAVED_DRAFT = 4; private static final int MSG_DISCARDED_DRAFT = 5; Loading Loading @@ -278,12 +277,6 @@ public class MessageCompose extends K9Activity implements OnClickListener, case MSG_PROGRESS_OFF: setProgressBarIndeterminateVisibility(false); break; case MSG_SKIPPED_ATTACHMENTS: Toast.makeText( MessageCompose.this, getString(R.string.message_compose_attachments_skipped_toast), Toast.LENGTH_LONG).show(); break; case MSG_SAVED_DRAFT: mDraftId = (Long) msg.obj; Toast.makeText( Loading Loading @@ -373,10 +366,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, EolConvertingEditText upperSignature = (EolConvertingEditText)findViewById(R.id.upper_signature); EolConvertingEditText lowerSignature = (EolConvertingEditText)findViewById(R.id.lower_signature); String sourceMessageBody = intent.getStringExtra(EXTRA_MESSAGE_BODY); QuotedMessageMvpView quotedMessageMvpView = new QuotedMessageMvpView(this); quotedMessagePresenter = new QuotedMessagePresenter(this, quotedMessageMvpView, mAccount, sourceMessageBody); quotedMessagePresenter = new QuotedMessagePresenter(this, quotedMessageMvpView, mAccount); attachmentPresenter = new AttachmentPresenter(getApplicationContext(), attachmentMvpView, getLoaderManager()); mMessageContentView = (EolConvertingEditText)findViewById(R.id.message_content); Loading Loading @@ -474,7 +465,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, messageLoaderHelper = new MessageLoaderHelper(this, getLoaderManager(), getFragmentManager(), messageLoaderCallbacks); mHandler.sendEmptyMessage(MSG_PROGRESS_ON); messageLoaderHelper.asyncStartOrResumeLoadingMessage(mMessageReference); Parcelable cachedDecryptionResult = intent.getParcelableExtra(EXTRA_MESSAGE_DECRYPTION_RESULT); messageLoaderHelper.asyncStartOrResumeLoadingMessage(mMessageReference, cachedDecryptionResult); } if (mAction != Action.EDIT_DRAFT) { Loading Loading @@ -1139,30 +1132,30 @@ public class MessageCompose extends K9Activity implements OnClickListener, throw new IllegalStateException("tried to edit quoted message with no referenced message"); } messageLoaderHelper.asyncStartOrResumeLoadingMessage(mMessageReference); messageLoaderHelper.asyncStartOrResumeLoadingMessage(mMessageReference, null); } /** * Pull out the parts of the now loaded source message and apply them to the new message * depending on the type of message being composed. * * @param message * @param messageViewInfo * The source message used to populate the various text fields. */ private void processSourceMessage(LocalMessage message) { private void processSourceMessage(MessageViewInfo messageViewInfo) { try { switch (mAction) { case REPLY: case REPLY_ALL: { processMessageToReplyTo(message); processMessageToReplyTo(messageViewInfo); break; } case FORWARD: { processMessageToForward(message); processMessageToForward(messageViewInfo); break; } case EDIT_DRAFT: { processDraftMessage(message); processDraftMessage(messageViewInfo); break; } default: { Loading @@ -1184,7 +1177,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, updateMessageFormat(); } private void processMessageToReplyTo(Message message) throws MessagingException { private void processMessageToReplyTo(MessageViewInfo messageViewInfo) throws MessagingException { Message message = messageViewInfo.message; if (message.getSubject() != null) { final String subject = PREFIX.matcher(message.getSubject()).replaceFirst(""); Loading Loading @@ -1221,7 +1216,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, } // Quote the message and setup the UI. quotedMessagePresenter.initFromReplyToMessage(message, mAction); quotedMessagePresenter.initFromReplyToMessage(messageViewInfo, mAction); if (mAction == Action.REPLY || mAction == Action.REPLY_ALL) { Identity useIdentity = IdentityHelper.getRecipientIdentityFromMessage(mAccount, message); Loading @@ -1233,7 +1228,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, } private void processMessageToForward(Message message) throws MessagingException { private void processMessageToForward(MessageViewInfo messageViewInfo) throws MessagingException { Message message = messageViewInfo.message; String subject = message.getSubject(); if (subject != null && !subject.toLowerCase(Locale.US).startsWith("fwd:")) { mSubjectView.setText("Fwd: " + subject); Loading @@ -1255,16 +1252,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, } // Quote the message and setup the UI. quotedMessagePresenter.processMessageToForward(message); if (!mSourceMessageProcessed) { if (message.isSet(Flag.X_DOWNLOADED_PARTIAL) || !attachmentPresenter.loadAttachments(message, 0)) { mHandler.sendEmptyMessage(MSG_SKIPPED_ATTACHMENTS); } } quotedMessagePresenter.processMessageToForward(messageViewInfo); attachmentPresenter.processMessageToForward(messageViewInfo); } private void processDraftMessage(LocalMessage message) throws MessagingException { private void processDraftMessage(MessageViewInfo messageViewInfo) throws MessagingException { Message message = messageViewInfo.message; mDraftId = MessagingController.getInstance(getApplication()).getId(message); mSubjectView.setText(message.getSubject()); Loading Loading @@ -1301,7 +1294,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, newIdentity.setSignature(k9identity.get(IdentityField.SIGNATURE)); mSignatureChanged = true; } else { newIdentity.setSignatureUse(message.getFolder().getSignatureUse()); if (message instanceof LocalMessage) { newIdentity.setSignatureUse(((LocalMessage) message).getFolder().getSignatureUse()); } newIdentity.setSignature(mIdentity.getSignature()); } Loading Loading @@ -1341,7 +1336,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, updateSignature(); updateFrom(); quotedMessagePresenter.processDraftMessage(message, k9identity); quotedMessagePresenter.processDraftMessage(messageViewInfo, k9identity); } static class SendMessageTask extends AsyncTask<Void, Void, Void> { Loading Loading @@ -1524,14 +1519,14 @@ public class MessageCompose extends K9Activity implements OnClickListener, } } public void loadLocalMessageForDisplay(LocalMessage message, Action action) { public void loadLocalMessageForDisplay(MessageViewInfo messageViewInfo, Action action) { // We check to see if we've previously processed the source message since this // could be called when switching from HTML to text replies. If that happens, we // only want to update the UI with quoted text (which picks the appropriate // part). if (mSourceMessageProcessed) { try { quotedMessagePresenter.populateUIWithQuotedMessage(message, true, action); quotedMessagePresenter.populateUIWithQuotedMessage(messageViewInfo, true, action); } catch (MessagingException e) { // Hm, if we couldn't populate the UI after source reprocessing, let's just delete it? quotedMessagePresenter.showOrHideQuotedText(QuotedTextMode.HIDE); Loading @@ -1539,7 +1534,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, } updateMessageFormat(); } else { processSourceMessage(message); processSourceMessage(messageViewInfo); mSourceMessageProcessed = true; } } Loading @@ -1559,7 +1554,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, @Override public void onMessageViewInfoLoadFinished(LocalMessage localMessage, MessageViewInfo messageViewInfo) { mHandler.sendEmptyMessage(MSG_PROGRESS_OFF); loadLocalMessageForDisplay(localMessage, mAction); loadLocalMessageForDisplay(messageViewInfo, mAction); } @Override Loading Loading @@ -1731,6 +1726,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, public void performSaveAfterChecks() { MessageCompose.this.performSaveAfterChecks(); } @Override public void showMissingAttachmentsPartialMessageWarning() { Toast.makeText(MessageCompose.this, getString(R.string.message_compose_attachments_skipped_toast), Toast.LENGTH_LONG).show(); } }; }
k9mail/src/main/java/com/fsck/k9/activity/MessageList.java +19 −4 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ import android.content.res.Configuration; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Parcelable; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; Loading Loading @@ -53,7 +54,6 @@ import com.fsck.k9.search.SearchSpecification; import com.fsck.k9.search.SearchSpecification.Attribute; import com.fsck.k9.search.SearchSpecification.SearchCondition; import com.fsck.k9.search.SearchSpecification.SearchField; import com.fsck.k9.ui.messageview.CryptoInfoDialog.OnClickShowCryptoKeyListener; import com.fsck.k9.ui.messageview.MessageViewFragment; import com.fsck.k9.ui.messageview.MessageViewFragment.MessageViewFragmentListener; import com.fsck.k9.view.MessageHeader; Loading Loading @@ -1210,17 +1210,32 @@ public class MessageList extends K9Activity implements MessageListFragmentListen @Override public void onForward(LocalMessage message) { MessageActions.actionForward(this, message, null); onForward(message, null); } @Override public void onForward(LocalMessage message, Parcelable decryptionResultForReply) { MessageActions.actionForward(this, message, decryptionResultForReply); } @Override public void onReply(LocalMessage message) { MessageActions.actionReply(this, message, false, null); onReply(message, null); } @Override public void onReply(LocalMessage message, Parcelable decryptionResultForReply) { MessageActions.actionReply(this, message, false, decryptionResultForReply); } @Override public void onReplyAll(LocalMessage message) { MessageActions.actionReply(this, message, true, null); onReplyAll(message, null); } @Override public void onReplyAll(LocalMessage message, Parcelable decryptionResultForReply) { MessageActions.actionReply(this, message, true, decryptionResultForReply); } @Override Loading
k9mail/src/main/java/com/fsck/k9/activity/MessageLoaderHelper.java +14 −2 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ import android.content.Intent; import android.content.IntentSender; import android.content.Loader; import android.os.Bundle; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; Loading @@ -28,6 +29,7 @@ import com.fsck.k9.ui.crypto.MessageCryptoCallback; import com.fsck.k9.ui.crypto.MessageCryptoHelper; import com.fsck.k9.ui.message.LocalMessageExtractorLoader; import com.fsck.k9.ui.message.LocalMessageLoader; import org.openintents.openpgp.OpenPgpDecryptionResult; /** This class is responsible for loading a message start to finish, and Loading Loading @@ -83,6 +85,7 @@ public class MessageLoaderHelper { private LocalMessage localMessage; private MessageCryptoAnnotations messageCryptoAnnotations; private OpenPgpDecryptionResult cachedDecryptionResult; private MessageCryptoHelper messageCryptoHelper; Loading @@ -99,10 +102,18 @@ public class MessageLoaderHelper { // public interface @UiThread public void asyncStartOrResumeLoadingMessage(MessageReference messageReference) { public void asyncStartOrResumeLoadingMessage(MessageReference messageReference, Parcelable cachedDecryptionResult) { this.messageReference = messageReference; this.account = Preferences.getPreferences(context).getAccount(messageReference.getAccountUuid()); if (cachedDecryptionResult != null) { if (cachedDecryptionResult instanceof OpenPgpDecryptionResult) { this.cachedDecryptionResult = (OpenPgpDecryptionResult) cachedDecryptionResult; } else { Log.e(K9.LOG_TAG, "Got decryption result of unknown type - ignoring"); } } startOrResumeLocalMessageLoader(); } Loading Loading @@ -248,7 +259,8 @@ public class MessageLoaderHelper { messageCryptoHelper = new MessageCryptoHelper(context, account.getOpenPgpProvider()); retainCryptoHelperFragment.setData(messageCryptoHelper); } messageCryptoHelper.asyncStartOrResumeProcessingMessage(localMessage, messageCryptoCallback); messageCryptoHelper.asyncStartOrResumeProcessingMessage( localMessage, messageCryptoCallback, cachedDecryptionResult); } private void cancelAndClearCryptoOperation() { Loading
k9mail/src/main/java/com/fsck/k9/activity/compose/AttachmentPresenter.java +52 −5 Original line number Diff line number Diff line Loading @@ -21,11 +21,14 @@ import com.fsck.k9.activity.loader.AttachmentContentLoader; import com.fsck.k9.activity.loader.AttachmentInfoLoader; import com.fsck.k9.activity.misc.Attachment; import com.fsck.k9.activity.misc.Attachment.LoadingState; import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.Multipart; import com.fsck.k9.mail.Part; import com.fsck.k9.mail.internet.MimeUtility; import com.fsck.k9.mailstore.AttachmentViewInfo; import com.fsck.k9.mailstore.LocalBodyPart; import com.fsck.k9.mailstore.MessageViewInfo; import com.fsck.k9.provider.AttachmentProvider; Loading Loading @@ -130,31 +133,74 @@ public class AttachmentPresenter { addAttachment(uri, null); } public void addAttachment(AttachmentViewInfo attachmentViewInfo) { if (attachments.containsKey(attachmentViewInfo.uri)) { throw new IllegalStateException("Received the same attachmentViewInfo twice!"); } int loaderId = getNextFreeLoaderId(); Attachment attachment = Attachment.createAttachment( attachmentViewInfo.uri, loaderId, attachmentViewInfo.mimeType); attachment = attachment.deriveWithMetadataLoaded( attachmentViewInfo.mimeType, attachmentViewInfo.displayName, attachmentViewInfo.size); addAttachmentAndStartLoader(attachment); } public void addAttachment(Uri uri, String contentType) { if (attachments.containsKey(uri)) { return; } int loaderId = getNextFreeLoaderId(); Attachment attachment = Attachment.createAttachment(uri, loaderId, contentType); if (attachments.containsKey(uri)) { addAttachmentAndStartLoader(attachment); } public void processMessageToForward(MessageViewInfo messageViewInfo) { if (messageViewInfo.message.isSet(Flag.X_DOWNLOADED_PARTIAL)) { attachmentMvpView.showMissingAttachmentsPartialMessageWarning(); return; } attachments.put(uri, attachment); for (AttachmentViewInfo attachmentViewInfo : messageViewInfo.attachments) { if (attachmentViewInfo.firstClassAttachment) { addAttachment(attachmentViewInfo); } } } private void addAttachmentAndStartLoader(Attachment attachment) { attachments.put(attachment.uri, attachment); attachmentMvpView.addAttachmentView(attachment); if (attachment.state == LoadingState.URI_ONLY) { initAttachmentInfoLoader(attachment); } else if (attachment.state == LoadingState.METADATA) { initAttachmentContentLoader(attachment); } else { throw new IllegalStateException("Attachment can only be added in URI_ONLY or METADATA state!"); } } private void initAttachmentInfoLoader(Attachment attachment) { if (attachment.state != LoadingState.URI_ONLY) { throw new IllegalStateException("initAttachmentInfoLoader can only be called for URI_ONLY state!"); } Bundle bundle = new Bundle(); bundle.putParcelable(LOADER_ARG_ATTACHMENT, attachment.uri); loaderManager.initLoader(attachment.loaderId, bundle, mAttachmentInfoLoaderCallback); } private void initAttachmentContentLoader(Attachment attachment) { if (attachment.state != LoadingState.METADATA) { throw new IllegalStateException("initAttachmentContentLoader can only be called for METADATA state!"); } Bundle bundle = new Bundle(); bundle.putParcelable(LOADER_ARG_ATTACHMENT, attachment.uri); loaderManager.initLoader(attachment.loaderId, bundle, mAttachmentContentLoaderCallback); } Loading Loading @@ -364,5 +410,6 @@ public class AttachmentPresenter { void performSendAfterChecks(); void performSaveAfterChecks(); void showMissingAttachmentsPartialMessageWarning(); } }
k9mail/src/main/java/com/fsck/k9/activity/compose/MessageActions.java +7 −18 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ package com.fsck.k9.activity.compose; import android.content.Context; import android.content.Intent; import android.os.Parcelable; import com.fsck.k9.Account; import com.fsck.k9.Preferences; Loading @@ -28,15 +29,11 @@ public class MessageActions { /** * Get intent for composing a new message as a reply to the given message. If replyAll is true * the function is reply all instead of simply reply. * @param messageBody optional, for decrypted messages, null if it should be grabbed from the given message */ public static Intent getActionReplyIntent( Context context, LocalMessage message, boolean replyAll, String messageBody) { Context context, LocalMessage message, boolean replyAll, Parcelable decryptionResult) { Intent i = new Intent(context, MessageCompose.class); i.putExtra(MessageCompose.EXTRA_MESSAGE_BODY, messageBody); i.putExtra(MessageCompose.EXTRA_MESSAGE_DECRYPTION_RESULT, decryptionResult); i.putExtra(MessageCompose.EXTRA_MESSAGE_REFERENCE, message.makeMessageReference()); if (replyAll) { i.setAction(MessageCompose.ACTION_REPLY_ALL); Loading @@ -58,27 +55,19 @@ public class MessageActions { /** * Compose a new message as a reply to the given message. If replyAll is true the function * is reply all instead of simply reply. * @param messageBody optional, for decrypted messages, null if it should be grabbed from the given message */ public static void actionReply( Context context, LocalMessage message, boolean replyAll, String messageBody) { context.startActivity(getActionReplyIntent(context, message, replyAll, messageBody)); Context context, LocalMessage message, boolean replyAll, Parcelable decryptionResult) { context.startActivity(getActionReplyIntent(context, message, replyAll, decryptionResult)); } /** * Compose a new message as a forward of the given message. * @param messageBody optional, for decrypted messages, null if it should be grabbed from the given message */ public static void actionForward( Context context, LocalMessage message, String messageBody) { public static void actionForward(Context context, LocalMessage message, Parcelable decryptionResult) { Intent i = new Intent(context, MessageCompose.class); i.putExtra(MessageCompose.EXTRA_MESSAGE_BODY, messageBody); i.putExtra(MessageCompose.EXTRA_MESSAGE_REFERENCE, message.makeMessageReference()); i.putExtra(MessageCompose.EXTRA_MESSAGE_DECRYPTION_RESULT, decryptionResult); i.setAction(MessageCompose.ACTION_FORWARD); context.startActivity(i); } Loading