use of com.fsck.k9.message.quote.InsertableHtmlContent in project k-9 by k9mail.
the class PgpMessageBuilderTest method createDefaultPgpMessageBuilder.
private static PgpMessageBuilder createDefaultPgpMessageBuilder(OpenPgpApi openPgpApi) {
PgpMessageBuilder builder = new PgpMessageBuilder(RuntimeEnvironment.application, MessageIdGenerator.getInstance(), BoundaryGenerator.getInstance());
builder.setOpenPgpApi(openPgpApi);
Identity identity = new Identity();
identity.setName("tester");
identity.setEmail("test@example.org");
identity.setDescription("test identity");
identity.setSignatureUse(false);
builder.setSubject("subject").setSentDate(new Date()).setHideTimeZone(false).setTo(new ArrayList<Address>()).setCc(new ArrayList<Address>()).setBcc(new ArrayList<Address>()).setInReplyTo("inreplyto").setReferences("references").setRequestReadReceipt(false).setIdentity(identity).setMessageFormat(SimpleMessageFormat.TEXT).setText(TEST_MESSAGE_TEXT).setAttachments(new ArrayList<Attachment>()).setSignature("signature").setQuoteStyle(QuoteStyle.PREFIX).setQuotedTextMode(QuotedTextMode.NONE).setQuotedText("quoted text").setQuotedHtmlContent(new InsertableHtmlContent()).setReplyAfterQuote(false).setSignatureBeforeQuotedText(false).setIdentityChanged(false).setSignatureChanged(false).setCursorPosition(0).setMessageReference(null).setDraft(false);
return builder;
}
use of com.fsck.k9.message.quote.InsertableHtmlContent 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);
}
use of com.fsck.k9.message.quote.InsertableHtmlContent in project k-9 by k9mail.
the class TextBodyBuilderTest method testBuildTextHtml.
@Theory
public void testBuildTextHtml(boolean includeQuotedText, QuoteStyle quoteStyle, boolean isReplyAfterQuote, boolean isSignatureUse, boolean isSignatureBeforeQuotedText, boolean isDraft) {
String expectedText;
int expectedMessageLength;
int expectedMessagePosition = 0;
String expectedHtmlContent;
String expectedPrefix = "";
if (includeQuotedText && quoteStyle == QuoteStyle.PREFIX && isReplyAfterQuote && !isDraft) {
expectedPrefix = "<br clear=\"all\">";
}
String expectedPostfix = "";
if (!isDraft && includeQuotedText) {
expectedPostfix = "<br><br>";
}
// 3.signature
if (quoteStyle == QuoteStyle.PREFIX && isReplyAfterQuote) {
expectedText = expectedPrefix + "<html>message content";
if (!isDraft && isSignatureUse) {
expectedText += "\r\n" + "signature";
}
expectedText += "</html>";
expectedMessageLength = expectedText.length();
String quotedContent = "quoted text";
if (isDraft || includeQuotedText) {
expectedHtmlContent = makeExpectedHtmlContent(expectedText, quotedContent, 0, false, expectedText, expectedText + quotedContent);
expectedText += quotedContent;
} else {
expectedHtmlContent = makeExpectedHtmlContent(expectedText, quotedContent, 0, true, "", quotedContent);
// expectedText += quotedContent;
}
} else // 3.quoted text
if (isSignatureBeforeQuotedText) {
expectedText = expectedPrefix + "<html>message content";
if (!isDraft && isSignatureUse) {
expectedText += "\r\n" + "signature";
}
expectedText += "</html>";
expectedText += expectedPostfix;
expectedMessageLength = expectedText.length();
String quotedContent = "quoted text";
if (isDraft || includeQuotedText) {
expectedHtmlContent = makeExpectedHtmlContent(expectedText, quotedContent, 0, true, expectedText, expectedText + quotedContent);
expectedText += quotedContent;
} else {
expectedHtmlContent = makeExpectedHtmlContent(expectedText, quotedContent, 0, true, "", quotedContent);
// expectedText += quotedContent;
}
} else // 1.message content
// 2.quoted text
// 3.signature
{
String expectedSignature = "";
expectedText = expectedPrefix + "<html>message content";
if (!isDraft && isSignatureUse) {
if (!includeQuotedText) {
expectedText += "\r\n" + "signature";
} else {
expectedSignature = "<html>\r\nsignature</html>";
}
}
expectedText += "</html>";
expectedText += expectedPostfix;
expectedMessageLength = expectedText.length();
String quotedContent = "quoted text";
if (isDraft || includeQuotedText) {
expectedHtmlContent = makeExpectedHtmlContent(expectedText, expectedSignature + quotedContent, expectedSignature.length(), true, expectedText, expectedText + expectedSignature + quotedContent);
expectedText += expectedSignature + quotedContent;
} else {
expectedHtmlContent = makeExpectedHtmlContent(expectedText, quotedContent, 0, true, "", quotedContent);
// expectedText += quotedContent;
}
}
InsertableHtmlContent insertableHtmlContent = new InsertableHtmlContent();
String quotedText = "quoted text";
insertableHtmlContent.setQuotedContent(new StringBuilder(quotedText));
String messageText = "message content";
String signatureText = "signature";
TestingTextBodyBuilder textBodyBuilder = new TestingTextBodyBuilder(includeQuotedText, isDraft, quoteStyle, isReplyAfterQuote, isSignatureBeforeQuotedText, isSignatureUse, messageText, signatureText);
textBodyBuilder.setQuotedTextHtml(insertableHtmlContent);
TextBody textBody = textBodyBuilder.buildTextHtml();
assertThat(textBody, instanceOf(TextBody.class));
assertThat(textBody.getRawText(), is(expectedText));
assertThat(textBody.getComposedMessageLength(), is(expectedMessageLength));
assertThat(textBody.getComposedMessageOffset(), is(expectedMessagePosition));
assertThat(insertableHtmlContent.toDebugString(), is(expectedHtmlContent));
}
use of com.fsck.k9.message.quote.InsertableHtmlContent in project k-9 by k9mail.
the class TextBodyBuilder method buildTextHtml.
/**
* Build the {@link Body} that will contain the text of the message.
*
* @return {@link com.fsck.k9.mail.internet.TextBody} instance that contains the entered text and
* possibly the quoted original message.
*/
public TextBody buildTextHtml() {
// The length of the formatted version of the user-supplied text/reply
int composedMessageLength;
// The offset of the user-supplied text/reply in the final text body
int composedMessageOffset = 0;
// Get the user-supplied text
String text = mMessageContent;
// Do we have to modify an existing message to include our reply?
if (mIncludeQuotedText) {
InsertableHtmlContent quotedHtmlContent = getQuotedTextHtml();
if (K9.isDebugLoggingEnabled()) {
Timber.d("insertable: %s", quotedHtmlContent.toDebugString());
}
// Convert the text to HTML
text = textToHtmlFragment(text);
// Save length of the body. This is used when thawing drafts.
composedMessageLength = text.length();
// Append signature to the reply
if (mAppendSignature && (mReplyAfterQuote || mSignatureBeforeQuotedText)) {
text += getSignatureHtml();
}
/*
* Set the insertion location based upon our reply after quote
* setting. Additionally, add some extra separators between the
* composed message and quoted message depending on the quote
* location. We only add the extra separators when we're
* sending, that way when we load a draft, we don't have to know
* the length of the separators to remove them before editing.
*/
if (mReplyAfterQuote) {
quotedHtmlContent.setInsertionLocation(InsertableHtmlContent.InsertionLocation.AFTER_QUOTE);
if (mInsertSeparator) {
final String separator = "<br clear=\"all\">";
text = separator + text;
composedMessageOffset = separator.length();
}
} else {
quotedHtmlContent.setInsertionLocation(InsertableHtmlContent.InsertionLocation.BEFORE_QUOTE);
if (mInsertSeparator) {
text += "<br><br>";
}
}
// Place signature immediately after the quoted text
if (mAppendSignature && !(mReplyAfterQuote || mSignatureBeforeQuotedText)) {
quotedHtmlContent.insertIntoQuotedFooter(getSignatureHtml());
}
quotedHtmlContent.setUserContent(text);
// Save the body's offset. This is used when thawing drafts.
composedMessageOffset += quotedHtmlContent.getInsertionPoint();
text = quotedHtmlContent.toString();
} else {
// Convert the text to HTML
text = textToHtmlFragment(text);
composedMessageLength = text.length();
composedMessageOffset = HTML_AND_BODY_START.length();
// There is no text to quote so simply append the signature if available
if (mAppendSignature) {
text += getSignatureHtml();
}
text = HTML_AND_BODY_START + text + HTML_AND_BODY_END;
}
TextBody body = new TextBody(text);
body.setComposedMessageLength(composedMessageLength);
body.setComposedMessageOffset(composedMessageOffset);
return body;
}
use of com.fsck.k9.message.quote.InsertableHtmlContent in project k-9 by k9mail.
the class HtmlQuoteCreator method quoteOriginalHtmlMessage.
/**
* Add quoting markup to a HTML message.
* @param originalMessage Metadata for message being quoted.
* @param messageBody Text of the message to be quoted.
* @param quoteStyle Style of quoting.
* @return Modified insertable message.
*/
public static InsertableHtmlContent quoteOriginalHtmlMessage(Message originalMessage, String messageBody, QuoteStyle quoteStyle) {
CoreResourceProvider resourceProvider = DI.get(CoreResourceProvider.class);
InsertableHtmlContent insertable = findInsertionPoints(messageBody);
String sentDate = new QuoteDateFormatter().format(originalMessage.getSentDate());
String fromAddress = Address.toString(originalMessage.getFrom());
if (quoteStyle == QuoteStyle.PREFIX) {
StringBuilder header = new StringBuilder();
header.append("<div class=\"gmail_quote\">");
if (sentDate.length() != 0) {
String replyHeader = resourceProvider.replyHeader(fromAddress, sentDate);
header.append(HtmlConverter.textToHtmlFragment(replyHeader));
} else {
String replyHeader = resourceProvider.replyHeader(fromAddress);
header.append(HtmlConverter.textToHtmlFragment(replyHeader));
}
header.append("<blockquote class=\"gmail_quote\" " + "style=\"margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;\">\r\n");
String footer = "</blockquote></div>";
insertable.insertIntoQuotedHeader(header.toString());
insertable.insertIntoQuotedFooter(footer);
} else if (quoteStyle == QuoteStyle.HEADER) {
StringBuilder header = new StringBuilder();
header.append("<div style='font-size:10.0pt;font-family:\"Tahoma\",\"sans-serif\";padding:3.0pt 0in 0in 0in'>\r\n");
// This gets converted into a horizontal line during html to text conversion.
header.append("<hr style='border:none;border-top:solid #E1E1E1 1.0pt'>\r\n");
if (originalMessage.getFrom() != null && fromAddress.length() != 0) {
header.append("<b>").append(resourceProvider.messageHeaderFrom()).append("</b> ").append(HtmlConverter.textToHtmlFragment(fromAddress)).append("<br>\r\n");
}
if (sentDate.length() != 0) {
header.append("<b>").append(resourceProvider.messageHeaderDate()).append("</b> ").append(sentDate).append("<br>\r\n");
}
if (originalMessage.getRecipients(RecipientType.TO) != null && originalMessage.getRecipients(RecipientType.TO).length != 0) {
header.append("<b>").append(resourceProvider.messageHeaderTo()).append("</b> ").append(HtmlConverter.textToHtmlFragment(Address.toString(originalMessage.getRecipients(RecipientType.TO)))).append("<br>\r\n");
}
if (originalMessage.getRecipients(RecipientType.CC) != null && originalMessage.getRecipients(RecipientType.CC).length != 0) {
header.append("<b>").append(resourceProvider.messageHeaderCc()).append("</b> ").append(HtmlConverter.textToHtmlFragment(Address.toString(originalMessage.getRecipients(RecipientType.CC)))).append("<br>\r\n");
}
if (originalMessage.getSubject() != null) {
header.append("<b>").append(resourceProvider.messageHeaderSubject()).append("</b> ").append(HtmlConverter.textToHtmlFragment(originalMessage.getSubject())).append("<br>\r\n");
}
header.append("</div>\r\n");
header.append("<br>\r\n");
insertable.insertIntoQuotedHeader(header.toString());
}
return insertable;
}
Aggregations