Search in sources :

Example 6 with MessageViewInfo

use of com.fsck.k9.mailstore.MessageViewInfo in project k-9 by k9mail.

the class MessageViewInfo method createWithErrorState.

public static MessageViewInfo createWithErrorState(Message message, boolean isMessageIncomplete) {
    try {
        Body emptyBody = new TextBody("");
        Part emptyPart = new MimeBodyPart(emptyBody, "text/plain");
        String subject = message.getSubject();
        return new MessageViewInfo(message, isMessageIncomplete, emptyPart, subject, false, null, null, null, null, null, null);
    } catch (MessagingException e) {
        throw new AssertionError(e);
    }
}
Also used : TextBody(com.fsck.k9.mail.internet.TextBody) MessagingException(com.fsck.k9.mail.MessagingException) Part(com.fsck.k9.mail.Part) MimeBodyPart(com.fsck.k9.mail.internet.MimeBodyPart) MimeBodyPart(com.fsck.k9.mail.internet.MimeBodyPart) TextBody(com.fsck.k9.mail.internet.TextBody) Body(com.fsck.k9.mail.Body)

Example 7 with MessageViewInfo

use of com.fsck.k9.mailstore.MessageViewInfo in project k-9 by k9mail.

the class QuotedMessagePresenter method processDraftMessage.

public void processDraftMessage(MessageViewInfo messageViewInfo, Map<IdentityField, String> k9identity) {
    quoteStyle = k9identity.get(IdentityField.QUOTE_STYLE) != null ? QuoteStyle.valueOf(k9identity.get(IdentityField.QUOTE_STYLE)) : account.getQuoteStyle();
    int cursorPosition = 0;
    if (k9identity.containsKey(IdentityField.CURSOR_POSITION)) {
        try {
            cursorPosition = Integer.parseInt(k9identity.get(IdentityField.CURSOR_POSITION));
        } catch (Exception e) {
            Timber.e(e, "Could not parse cursor position for MessageCompose; continuing.");
        }
    }
    String showQuotedTextMode;
    if (k9identity.containsKey(IdentityField.QUOTED_TEXT_MODE)) {
        showQuotedTextMode = k9identity.get(IdentityField.QUOTED_TEXT_MODE);
    } else {
        showQuotedTextMode = "NONE";
    }
    int bodyLength = k9identity.get(IdentityField.LENGTH) != null ? Integer.valueOf(k9identity.get(IdentityField.LENGTH)) : UNKNOWN_LENGTH;
    int bodyOffset = k9identity.get(IdentityField.OFFSET) != null ? Integer.valueOf(k9identity.get(IdentityField.OFFSET)) : UNKNOWN_LENGTH;
    Integer bodyFooterOffset = k9identity.get(IdentityField.FOOTER_OFFSET) != null ? Integer.valueOf(k9identity.get(IdentityField.FOOTER_OFFSET)) : null;
    Integer bodyPlainLength = k9identity.get(IdentityField.PLAIN_LENGTH) != null ? Integer.valueOf(k9identity.get(IdentityField.PLAIN_LENGTH)) : null;
    Integer bodyPlainOffset = k9identity.get(IdentityField.PLAIN_OFFSET) != null ? Integer.valueOf(k9identity.get(IdentityField.PLAIN_OFFSET)) : null;
    QuotedTextMode quotedMode;
    try {
        quotedMode = QuotedTextMode.valueOf(showQuotedTextMode);
    } catch (Exception e) {
        quotedMode = QuotedTextMode.NONE;
    }
    // Always respect the user's current composition format preference, even if the
    // draft was saved in a different format.
    // TODO - The current implementation doesn't allow a user in HTML mode to edit a draft that wasn't saved with K9mail.
    String messageFormatString = k9identity.get(IdentityField.MESSAGE_FORMAT);
    MessageFormat messageFormat = null;
    if (messageFormatString != null) {
        try {
            messageFormat = MessageFormat.valueOf(messageFormatString);
        } catch (Exception e) {
        /* do nothing */
        }
    }
    if (messageFormat == null) {
        // This message probably wasn't created by us. The exception is legacy
        // drafts created before the advent of HTML composition. In those cases,
        // we'll display the whole message (including the quoted part) in the
        // composition window. If that's the case, try and convert it to text to
        // match the behavior in text mode.
        view.setMessageContentCharacters(BodyTextExtractor.getBodyTextFromMessage(messageViewInfo.rootPart, SimpleMessageFormat.TEXT));
        forcePlainText = true;
        showOrHideQuotedText(quotedMode);
        return;
    }
    if (messageFormat == MessageFormat.HTML) {
        // defaults to null
        String bodyText;
        Part part = MimeUtility.findFirstPartByMimeType(messageViewInfo.rootPart, "text/html");
        if (part != null) {
            // Shouldn't happen if we were the one who saved it.
            quotedTextFormat = SimpleMessageFormat.HTML;
            String text = MessageExtractor.getTextFromPart(part);
            if (text == null) {
                Timber.d("Empty message; skipping.");
                bodyText = "";
            } else {
                Timber.d("Loading message with offset %d, length %d. Text length is %d.", bodyOffset, bodyLength, text.length());
                if (bodyOffset + bodyLength > text.length()) {
                    // The draft was edited outside of K-9 Mail?
                    Timber.d("The identity field from the draft contains an invalid LENGTH/OFFSET");
                    bodyOffset = 0;
                    bodyLength = 0;
                }
                // Grab our reply text.
                bodyText = text.substring(bodyOffset, bodyOffset + bodyLength);
            }
            view.setMessageContentCharacters(HtmlConverter.htmlToText(bodyText));
            // Regenerate the quoted html without our user content in it.
            StringBuilder quotedHTML = new StringBuilder();
            // stuff before the reply
            quotedHTML.append(text.substring(0, bodyOffset));
            quotedHTML.append(text.substring(bodyOffset + bodyLength));
            if (quotedHTML.length() > 0) {
                quotedHtmlContent = new InsertableHtmlContent();
                quotedHtmlContent.setQuotedContent(quotedHTML);
                // We don't know if bodyOffset refers to the header or to the footer
                quotedHtmlContent.setHeaderInsertionPoint(bodyOffset);
                if (bodyFooterOffset != null) {
                    quotedHtmlContent.setFooterInsertionPoint(bodyFooterOffset);
                } else {
                    quotedHtmlContent.setFooterInsertionPoint(bodyOffset);
                }
                // TODO replace with MessageViewInfo data
                view.setQuotedHtml(quotedHtmlContent.getQuotedContent(), AttachmentResolver.createFromPart(messageViewInfo.rootPart));
            }
        }
        if (bodyPlainOffset != null && bodyPlainLength != null) {
            processSourceMessageText(messageViewInfo.rootPart, bodyPlainOffset, bodyPlainLength, false);
        }
    } else if (messageFormat == MessageFormat.TEXT) {
        quotedTextFormat = SimpleMessageFormat.TEXT;
        processSourceMessageText(messageViewInfo.rootPart, bodyOffset, bodyLength, true);
    } else {
        Timber.e("Unhandled message format.");
    }
    // Set the cursor position if we have it.
    try {
        view.setMessageContentCursorPosition(cursorPosition);
    } catch (Exception e) {
        Timber.e(e, "Could not set cursor position in MessageCompose; ignoring.");
    }
    showOrHideQuotedText(quotedMode);
}
Also used : SimpleMessageFormat(com.fsck.k9.message.SimpleMessageFormat) MessageFormat(com.fsck.k9.Account.MessageFormat) Part(com.fsck.k9.mail.Part) QuotedTextMode(com.fsck.k9.message.QuotedTextMode) InsertableHtmlContent(com.fsck.k9.message.quote.InsertableHtmlContent) MessagingException(com.fsck.k9.mail.MessagingException)

Example 8 with MessageViewInfo

use of com.fsck.k9.mailstore.MessageViewInfo in project k-9 by k9mail.

the class MessageContainerView method displayMessageViewContainer.

public void displayMessageViewContainer(MessageViewInfo messageViewInfo, final OnRenderingFinishedListener onRenderingFinishedListener, boolean loadPictures, boolean hideUnsignedTextDivider, AttachmentViewCallback attachmentCallback) {
    this.attachmentCallback = attachmentCallback;
    resetView();
    renderAttachments(messageViewInfo);
    String textToDisplay = messageViewInfo.text;
    if (textToDisplay != null && !isShowingPictures()) {
        if (Utility.hasExternalImages(textToDisplay)) {
            if (loadPictures) {
                setLoadPictures(true);
            } else {
                hasHiddenExternalImages = true;
            }
        }
    }
    if (textToDisplay == null) {
        String noTextMessage = getContext().getString(R.string.webview_empty_message);
        textToDisplay = displayHtml.wrapStatusMessage(noTextMessage);
    }
    OnPageFinishedListener onPageFinishedListener = new OnPageFinishedListener() {

        @Override
        public void onPageFinished() {
            onRenderingFinishedListener.onLoadFinished();
        }
    };
    displayHtmlContentWithInlineAttachments(textToDisplay, messageViewInfo.attachmentResolver, onPageFinishedListener);
    if (!TextUtils.isEmpty(messageViewInfo.extraText)) {
        unsignedTextContainer.setVisibility(View.VISIBLE);
        unsignedTextDivider.setVisibility(hideUnsignedTextDivider ? View.GONE : View.VISIBLE);
        unsignedText.setText(messageViewInfo.extraText);
    }
}
Also used : OnPageFinishedListener(com.fsck.k9.view.MessageWebView.OnPageFinishedListener)

Example 9 with MessageViewInfo

use of com.fsck.k9.mailstore.MessageViewInfo in project k-9 by k9mail.

the class MessageCryptoPresenter method maybeHandleShowMessage.

public boolean maybeHandleShowMessage(MessageTopView messageView, Account account, MessageViewInfo messageViewInfo) {
    this.cryptoResultAnnotation = messageViewInfo.cryptoResultAnnotation;
    MessageCryptoDisplayStatus displayStatus = MessageCryptoDisplayStatus.fromResultAnnotation(messageViewInfo.cryptoResultAnnotation);
    if (displayStatus == MessageCryptoDisplayStatus.DISABLED) {
        return false;
    }
    messageView.getMessageHeaderView().setCryptoStatus(displayStatus);
    switch(displayStatus) {
        case CANCELLED:
            {
                Drawable providerIcon = getOpenPgpApiProviderIcon(messageView.getContext(), account.getOpenPgpProvider());
                messageView.showMessageCryptoCancelledView(messageViewInfo, providerIcon);
                break;
            }
        case INCOMPLETE_ENCRYPTED:
            {
                Drawable providerIcon = getOpenPgpApiProviderIcon(messageView.getContext(), account.getOpenPgpProvider());
                messageView.showMessageEncryptedButIncomplete(messageViewInfo, providerIcon);
                break;
            }
        case ENCRYPTED_ERROR:
        case UNSUPPORTED_ENCRYPTED:
            {
                Drawable providerIcon = getOpenPgpApiProviderIcon(messageView.getContext(), account.getOpenPgpProvider());
                messageView.showMessageCryptoErrorView(messageViewInfo, providerIcon);
                break;
            }
        case ENCRYPTED_NO_PROVIDER:
            {
                messageView.showCryptoProviderNotConfigured(messageViewInfo);
                break;
            }
        case INCOMPLETE_SIGNED:
        case UNSUPPORTED_SIGNED:
        default:
            {
                messageView.showMessage(account, messageViewInfo);
                break;
            }
        case LOADING:
            {
                throw new IllegalStateException("Displaying message while in loading state!");
            }
    }
    return true;
}
Also used : Drawable(android.graphics.drawable.Drawable) MessageCryptoDisplayStatus(com.fsck.k9.view.MessageCryptoDisplayStatus)

Example 10 with MessageViewInfo

use of com.fsck.k9.mailstore.MessageViewInfo in project k-9 by k9mail.

the class QuotedMessagePresenter method populateUIWithQuotedMessage.

/**
 * Build and populate the UI with the quoted message.
 *
 * @param showQuotedText
 *         {@code true} if the quoted text should be shown, {@code false} otherwise.
 */
public void populateUIWithQuotedMessage(MessageViewInfo messageViewInfo, boolean showQuotedText, Action action) throws MessagingException {
    MessageFormat origMessageFormat = account.getMessageFormat();
    if (forcePlainText || origMessageFormat == MessageFormat.TEXT) {
        // Use plain text for the quoted message
        quotedTextFormat = SimpleMessageFormat.TEXT;
    } else if (origMessageFormat == MessageFormat.AUTO) {
        // Figure out which message format to use for the quoted text by looking if the source
        // message contains a text/html part. If it does, we use that.
        quotedTextFormat = (MimeUtility.findFirstPartByMimeType(messageViewInfo.rootPart, "text/html") == null) ? SimpleMessageFormat.TEXT : SimpleMessageFormat.HTML;
    } else {
        quotedTextFormat = SimpleMessageFormat.HTML;
    }
    // Handle the original message in the reply
    // If we already have sourceMessageBody, use that.  It's pre-populated if we've got crypto going on.
    String content = BodyTextExtractor.getBodyTextFromMessage(messageViewInfo.rootPart, quotedTextFormat);
    if (quotedTextFormat == SimpleMessageFormat.HTML) {
        // closing tags such as </div>, </span>, </table>, </pre> will be cut off.
        if (account.isStripSignature() && (action == Action.REPLY || action == Action.REPLY_ALL)) {
            content = HtmlSignatureRemover.stripSignature(content);
        }
        // Add the HTML reply header to the top of the content.
        quotedHtmlContent = HtmlQuoteCreator.quoteOriginalHtmlMessage(messageViewInfo.message, content, quoteStyle);
        // Load the message with the reply header. TODO replace with MessageViewInfo data
        view.setQuotedHtml(quotedHtmlContent.getQuotedContent(), AttachmentResolver.createFromPart(messageViewInfo.rootPart));
        // TODO: Also strip the signature from the text/plain part
        view.setQuotedText(textQuoteCreator.quoteOriginalTextMessage(messageViewInfo.message, BodyTextExtractor.getBodyTextFromMessage(messageViewInfo.rootPart, SimpleMessageFormat.TEXT), quoteStyle, account.getQuotePrefix()));
    } else if (quotedTextFormat == SimpleMessageFormat.TEXT) {
        if (account.isStripSignature() && (action == Action.REPLY || action == Action.REPLY_ALL)) {
            content = TextSignatureRemover.stripSignature(content);
        }
        view.setQuotedText(textQuoteCreator.quoteOriginalTextMessage(messageViewInfo.message, content, quoteStyle, account.getQuotePrefix()));
    }
    if (showQuotedText) {
        showOrHideQuotedText(QuotedTextMode.SHOW);
    } else {
        showOrHideQuotedText(QuotedTextMode.HIDE);
    }
}
Also used : SimpleMessageFormat(com.fsck.k9.message.SimpleMessageFormat) MessageFormat(com.fsck.k9.Account.MessageFormat)

Aggregations

Message (com.fsck.k9.mail.Message)14 MimeMessage (com.fsck.k9.mail.internet.MimeMessage)14 K9RobolectricTest (com.fsck.k9.K9RobolectricTest)10 Test (org.junit.Test)10 MimeBodyPart (com.fsck.k9.mail.internet.MimeBodyPart)8 LocalMessage (com.fsck.k9.mailstore.LocalMessage)5 BodyPart (com.fsck.k9.mail.BodyPart)4 Part (com.fsck.k9.mail.Part)4 MessageFormat (com.fsck.k9.Account.MessageFormat)2 MessageReference (com.fsck.k9.controller.MessageReference)2 MessagingException (com.fsck.k9.mail.MessagingException)2 SimpleMessageFormat (com.fsck.k9.message.SimpleMessageFormat)2 ArrayList (java.util.ArrayList)2 Drawable (android.graphics.drawable.Drawable)1 Uri (android.net.Uri)1 WorkerThread (android.support.annotation.WorkerThread)1 UiThread (androidx.annotation.UiThread)1 WorkerThread (androidx.annotation.WorkerThread)1 Account (com.fsck.k9.Account)1 ShowPictures (com.fsck.k9.Account.ShowPictures)1