use of com.fsck.k9.Account.QuoteStyle 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.message, SimpleMessageFormat.TEXT));
forcePlainText = true;
showOrHideQuotedText(quotedMode);
return;
}
if (messageFormat == MessageFormat.HTML) {
Part part = MimeUtility.findFirstPartByMimeType(messageViewInfo.message, "text/html");
if (part != null) {
// Shouldn't happen if we were the one who saved it.
quotedTextFormat = SimpleMessageFormat.HTML;
String text = MessageExtractor.getTextFromPart(part);
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.
String 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.Account.QuoteStyle 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(resources, 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(resources, 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(resources, messageViewInfo.message, content, quoteStyle, account.getQuotePrefix()));
}
if (showQuotedText) {
showOrHideQuotedText(QuotedTextMode.SHOW);
} else {
showOrHideQuotedText(QuotedTextMode.HIDE);
}
}
use of com.fsck.k9.Account.QuoteStyle in project k-9 by k9mail.
the class Account method delete.
protected synchronized void delete(Preferences preferences) {
deleteCertificates();
// Get the list of account UUIDs
String[] uuids = preferences.getStorage().getString("accountUuids", "").split(",");
// Create a list of all account UUIDs excluding this account
List<String> newUuids = new ArrayList<>(uuids.length);
for (String uuid : uuids) {
if (!uuid.equals(mUuid)) {
newUuids.add(uuid);
}
}
StorageEditor editor = preferences.getStorage().edit();
// Only change the 'accountUuids' value if this account's UUID was listed before
if (newUuids.size() < uuids.length) {
String accountUuids = Utility.combine(newUuids.toArray(), ',');
editor.putString("accountUuids", accountUuids);
}
editor.remove(mUuid + ".storeUri");
editor.remove(mUuid + ".transportUri");
editor.remove(mUuid + ".description");
editor.remove(mUuid + ".name");
editor.remove(mUuid + ".email");
editor.remove(mUuid + ".alwaysBcc");
editor.remove(mUuid + ".automaticCheckIntervalMinutes");
editor.remove(mUuid + ".pushPollOnConnect");
editor.remove(mUuid + ".idleRefreshMinutes");
editor.remove(mUuid + ".lastAutomaticCheckTime");
editor.remove(mUuid + ".latestOldMessageSeenTime");
editor.remove(mUuid + ".notifyNewMail");
editor.remove(mUuid + ".notifySelfNewMail");
editor.remove(mUuid + ".deletePolicy");
editor.remove(mUuid + ".draftsFolderName");
editor.remove(mUuid + ".sentFolderName");
editor.remove(mUuid + ".trashFolderName");
editor.remove(mUuid + ".archiveFolderName");
editor.remove(mUuid + ".spamFolderName");
editor.remove(mUuid + ".autoExpandFolderName");
editor.remove(mUuid + ".accountNumber");
editor.remove(mUuid + ".vibrate");
editor.remove(mUuid + ".vibratePattern");
editor.remove(mUuid + ".vibrateTimes");
editor.remove(mUuid + ".ring");
editor.remove(mUuid + ".ringtone");
editor.remove(mUuid + ".folderDisplayMode");
editor.remove(mUuid + ".folderSyncMode");
editor.remove(mUuid + ".folderPushMode");
editor.remove(mUuid + ".folderTargetMode");
editor.remove(mUuid + ".signatureBeforeQuotedText");
editor.remove(mUuid + ".expungePolicy");
editor.remove(mUuid + ".syncRemoteDeletions");
editor.remove(mUuid + ".maxPushFolders");
editor.remove(mUuid + ".searchableFolders");
editor.remove(mUuid + ".chipColor");
editor.remove(mUuid + ".led");
editor.remove(mUuid + ".ledColor");
editor.remove(mUuid + ".goToUnreadMessageSearch");
editor.remove(mUuid + ".subscribedFoldersOnly");
editor.remove(mUuid + ".maximumPolledMessageAge");
editor.remove(mUuid + ".maximumAutoDownloadMessageSize");
editor.remove(mUuid + ".messageFormatAuto");
editor.remove(mUuid + ".quoteStyle");
editor.remove(mUuid + ".quotePrefix");
editor.remove(mUuid + ".sortTypeEnum");
editor.remove(mUuid + ".sortAscending");
editor.remove(mUuid + ".showPicturesEnum");
editor.remove(mUuid + ".replyAfterQuote");
editor.remove(mUuid + ".stripSignature");
// this is no longer set, but cleans up legacy values
editor.remove(mUuid + ".cryptoApp");
editor.remove(mUuid + ".cryptoAutoSignature");
editor.remove(mUuid + ".cryptoAutoEncrypt");
editor.remove(mUuid + ".cryptoApp");
editor.remove(mUuid + ".cryptoKey");
editor.remove(mUuid + ".cryptoSupportSignOnly");
editor.remove(mUuid + ".enabled");
editor.remove(mUuid + ".markMessageAsReadOnView");
editor.remove(mUuid + ".alwaysShowCcBcc");
editor.remove(mUuid + ".allowRemoteSearch");
editor.remove(mUuid + ".remoteSearchFullText");
editor.remove(mUuid + ".remoteSearchNumResults");
editor.remove(mUuid + ".defaultQuotedTextShown");
editor.remove(mUuid + ".displayCount");
editor.remove(mUuid + ".inboxFolderName");
editor.remove(mUuid + ".localStorageProvider");
editor.remove(mUuid + ".messageFormat");
editor.remove(mUuid + ".messageReadReceipt");
editor.remove(mUuid + ".notifyMailCheck");
for (NetworkType type : NetworkType.values()) {
editor.remove(mUuid + ".useCompression." + type.name());
}
deleteIdentities(preferences.getStorage(), editor);
// TODO: Remove preference settings that may exist for individual
// folders in the account.
editor.commit();
}
use of com.fsck.k9.Account.QuoteStyle in project k-9 by k9mail.
the class Account method save.
public synchronized void save(Preferences preferences) {
StorageEditor editor = preferences.getStorage().edit();
if (!preferences.getStorage().getString("accountUuids", "").contains(mUuid)) {
/*
* When the account is first created we assign it a unique account number. The
* account number will be unique to that account for the lifetime of the account.
* So, we get all the existing account numbers, sort them ascending, loop through
* the list and check if the number is greater than 1 + the previous number. If so
* we use the previous number + 1 as the account number. This refills gaps.
* mAccountNumber starts as -1 on a newly created account. It must be -1 for this
* algorithm to work.
*
* I bet there is a much smarter way to do this. Anyone like to suggest it?
*/
List<Account> accounts = preferences.getAccounts();
int[] accountNumbers = new int[accounts.size()];
for (int i = 0; i < accounts.size(); i++) {
accountNumbers[i] = accounts.get(i).getAccountNumber();
}
Arrays.sort(accountNumbers);
for (int accountNumber : accountNumbers) {
if (accountNumber > mAccountNumber + 1) {
break;
}
mAccountNumber = accountNumber;
}
mAccountNumber++;
String accountUuids = preferences.getStorage().getString("accountUuids", "");
accountUuids += (accountUuids.length() != 0 ? "," : "") + mUuid;
editor.putString("accountUuids", accountUuids);
}
editor.putString(mUuid + ".storeUri", Base64.encode(mStoreUri));
editor.putString(mUuid + ".localStorageProvider", mLocalStorageProviderId);
editor.putString(mUuid + ".transportUri", Base64.encode(mTransportUri));
editor.putString(mUuid + ".description", mDescription);
editor.putString(mUuid + ".alwaysBcc", mAlwaysBcc);
editor.putInt(mUuid + ".automaticCheckIntervalMinutes", mAutomaticCheckIntervalMinutes);
editor.putInt(mUuid + ".idleRefreshMinutes", mIdleRefreshMinutes);
editor.putBoolean(mUuid + ".pushPollOnConnect", mPushPollOnConnect);
editor.putInt(mUuid + ".displayCount", mDisplayCount);
editor.putLong(mUuid + ".latestOldMessageSeenTime", mLatestOldMessageSeenTime);
editor.putBoolean(mUuid + ".notifyNewMail", mNotifyNewMail);
editor.putString(mUuid + ".folderNotifyNewMailMode", mFolderNotifyNewMailMode.name());
editor.putBoolean(mUuid + ".notifySelfNewMail", mNotifySelfNewMail);
editor.putBoolean(mUuid + ".notifyContactsMailOnly", mNotifyContactsMailOnly);
editor.putBoolean(mUuid + ".notifyMailCheck", mNotifySync);
editor.putInt(mUuid + ".deletePolicy", mDeletePolicy.setting);
editor.putString(mUuid + ".inboxFolderName", mInboxFolderName);
editor.putString(mUuid + ".draftsFolderName", mDraftsFolderName);
editor.putString(mUuid + ".sentFolderName", mSentFolderName);
editor.putString(mUuid + ".trashFolderName", mTrashFolderName);
editor.putString(mUuid + ".archiveFolderName", mArchiveFolderName);
editor.putString(mUuid + ".spamFolderName", mSpamFolderName);
editor.putString(mUuid + ".autoExpandFolderName", mAutoExpandFolderName);
editor.putInt(mUuid + ".accountNumber", mAccountNumber);
editor.putString(mUuid + ".sortTypeEnum", mSortType.name());
editor.putBoolean(mUuid + ".sortAscending", mSortAscending.get(mSortType));
editor.putString(mUuid + ".showPicturesEnum", mShowPictures.name());
editor.putString(mUuid + ".folderDisplayMode", mFolderDisplayMode.name());
editor.putString(mUuid + ".folderSyncMode", mFolderSyncMode.name());
editor.putString(mUuid + ".folderPushMode", mFolderPushMode.name());
editor.putString(mUuid + ".folderTargetMode", mFolderTargetMode.name());
editor.putBoolean(mUuid + ".signatureBeforeQuotedText", this.mIsSignatureBeforeQuotedText);
editor.putString(mUuid + ".expungePolicy", mExpungePolicy.name());
editor.putBoolean(mUuid + ".syncRemoteDeletions", mSyncRemoteDeletions);
editor.putInt(mUuid + ".maxPushFolders", mMaxPushFolders);
editor.putString(mUuid + ".searchableFolders", searchableFolders.name());
editor.putInt(mUuid + ".chipColor", mChipColor);
editor.putBoolean(mUuid + ".goToUnreadMessageSearch", goToUnreadMessageSearch);
editor.putBoolean(mUuid + ".subscribedFoldersOnly", subscribedFoldersOnly);
editor.putInt(mUuid + ".maximumPolledMessageAge", maximumPolledMessageAge);
editor.putInt(mUuid + ".maximumAutoDownloadMessageSize", maximumAutoDownloadMessageSize);
if (MessageFormat.AUTO.equals(mMessageFormat)) {
// saving MessageFormat.AUTO as is to the database will cause downgrades to crash on
// startup, so we save as MessageFormat.TEXT instead with a separate flag for auto.
editor.putString(mUuid + ".messageFormat", Account.MessageFormat.TEXT.name());
mMessageFormatAuto = true;
} else {
editor.putString(mUuid + ".messageFormat", mMessageFormat.name());
mMessageFormatAuto = false;
}
editor.putBoolean(mUuid + ".messageFormatAuto", mMessageFormatAuto);
editor.putBoolean(mUuid + ".messageReadReceipt", mMessageReadReceipt);
editor.putString(mUuid + ".quoteStyle", mQuoteStyle.name());
editor.putString(mUuid + ".quotePrefix", mQuotePrefix);
editor.putBoolean(mUuid + ".defaultQuotedTextShown", mDefaultQuotedTextShown);
editor.putBoolean(mUuid + ".replyAfterQuote", mReplyAfterQuote);
editor.putBoolean(mUuid + ".stripSignature", mStripSignature);
editor.putLong(mUuid + ".cryptoKey", mCryptoKey);
editor.putBoolean(mUuid + ".allowRemoteSearch", mAllowRemoteSearch);
editor.putBoolean(mUuid + ".remoteSearchFullText", mRemoteSearchFullText);
editor.putInt(mUuid + ".remoteSearchNumResults", mRemoteSearchNumResults);
editor.putBoolean(mUuid + ".enabled", mEnabled);
editor.putBoolean(mUuid + ".markMessageAsReadOnView", mMarkMessageAsReadOnView);
editor.putBoolean(mUuid + ".alwaysShowCcBcc", mAlwaysShowCcBcc);
editor.putBoolean(mUuid + ".vibrate", mNotificationSetting.shouldVibrate());
editor.putInt(mUuid + ".vibratePattern", mNotificationSetting.getVibratePattern());
editor.putInt(mUuid + ".vibrateTimes", mNotificationSetting.getVibrateTimes());
editor.putBoolean(mUuid + ".ring", mNotificationSetting.shouldRing());
editor.putString(mUuid + ".ringtone", mNotificationSetting.getRingtone());
editor.putBoolean(mUuid + ".led", mNotificationSetting.isLed());
editor.putInt(mUuid + ".ledColor", mNotificationSetting.getLedColor());
for (NetworkType type : NetworkType.values()) {
Boolean useCompression = compressionMap.get(type);
if (useCompression != null) {
editor.putBoolean(mUuid + ".useCompression." + type, useCompression);
}
}
saveIdentities(preferences.getStorage(), editor);
editor.commit();
}
use of com.fsck.k9.Account.QuoteStyle in project k-9 by k9mail.
the class MessageBuilder method buildText.
/**
* Build the {@link Body} that will contain the text of the message.
*
* <p>
* Draft messages are treated somewhat differently in that signatures are not appended and HTML
* separators between composed text and quoted text are not added.
* </p>
*
* @param isDraft
* If {@code true} we build a message that will be saved as a draft (as opposed to
* sent).
* @param simpleMessageFormat
* Specifies what type of message to build ({@code text/plain} vs. {@code text/html}).
*
* @return {@link TextBody} instance that contains the entered text and possibly the quoted
* original message.
*/
private TextBody buildText(boolean isDraft, SimpleMessageFormat simpleMessageFormat) {
String messageText = text;
TextBodyBuilder textBodyBuilder = new TextBodyBuilder(messageText);
/*
* Find out if we need to include the original message as quoted text.
*
* We include the quoted text in the body if the user didn't choose to
* hide it. We always include the quoted text when we're saving a draft.
* That's so the user is able to "un-hide" the quoted text if (s)he
* opens a saved draft.
*/
boolean includeQuotedText = (isDraft || quotedTextMode == QuotedTextMode.SHOW);
boolean isReplyAfterQuote = (quoteStyle == QuoteStyle.PREFIX && this.isReplyAfterQuote);
textBodyBuilder.setIncludeQuotedText(false);
if (includeQuotedText) {
if (simpleMessageFormat == SimpleMessageFormat.HTML && quotedHtmlContent != null) {
textBodyBuilder.setIncludeQuotedText(true);
textBodyBuilder.setQuotedTextHtml(quotedHtmlContent);
textBodyBuilder.setReplyAfterQuote(isReplyAfterQuote);
}
if (simpleMessageFormat == SimpleMessageFormat.TEXT && quotedText.length() > 0) {
textBodyBuilder.setIncludeQuotedText(true);
textBodyBuilder.setQuotedText(quotedText);
textBodyBuilder.setReplyAfterQuote(isReplyAfterQuote);
}
}
textBodyBuilder.setInsertSeparator(!isDraft);
boolean useSignature = (!isDraft && identity.getSignatureUse());
if (useSignature) {
textBodyBuilder.setAppendSignature(true);
textBodyBuilder.setSignature(signature);
textBodyBuilder.setSignatureBeforeQuotedText(isSignatureBeforeQuotedText);
} else {
textBodyBuilder.setAppendSignature(false);
}
TextBody body;
if (simpleMessageFormat == SimpleMessageFormat.HTML) {
body = textBodyBuilder.buildTextHtml();
} else {
body = textBodyBuilder.buildTextPlain();
}
return body;
}
Aggregations