am 403a45e7
: Merge change 24844 into eclair
Merge commit '403a45e73606f3d41624c3e3ac02597c08145281' into eclair-plus-aosp * commit '403a45e73606f3d41624c3e3ac02597c08145281': Reimplement reply/forward to use mTextReply/mHtmlReply
This commit is contained in:
commit
677755c376
@ -72,8 +72,6 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class MessageCompose extends Activity implements OnClickListener, OnFocusChangeListener {
|
||||
@ -101,9 +99,6 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
||||
|
||||
private static final int ACTIVITY_REQUEST_PICK_ATTACHMENT = 1;
|
||||
|
||||
private static final Pattern PATTERN_START_OF_LINE = Pattern.compile("(?m)^");
|
||||
private static final Pattern PATTERN_ENDLINE_CRLF = Pattern.compile("\r\n");
|
||||
|
||||
private static final String[] ATTACHMENT_META_COLUMNS = {
|
||||
OpenableColumns.DISPLAY_NAME,
|
||||
OpenableColumns.SIZE
|
||||
@ -572,45 +567,6 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
||||
return addresses;
|
||||
}
|
||||
|
||||
/*
|
||||
* Takes care to append source info and text in a REPLY or FORWARD situation.
|
||||
*/
|
||||
/* package */ String buildBodyText(Message sourceMessage) {
|
||||
/*
|
||||
* Build the Body that will contain the text of the message. We'll decide where to
|
||||
* include it later.
|
||||
*/
|
||||
final String action = getIntent().getAction();
|
||||
String text = mMessageContentView.getText().toString();
|
||||
|
||||
if (mQuotedTextBar.getVisibility() == View.VISIBLE && sourceMessage != null) {
|
||||
String quotedText = sourceMessage.mText;
|
||||
if (quotedText != null) {
|
||||
// fix CR-LF line endings to LF-only needed by EditText.
|
||||
Matcher matcher = PATTERN_ENDLINE_CRLF.matcher(quotedText);
|
||||
quotedText = matcher.replaceAll("\n");
|
||||
}
|
||||
String fromAsString = Address.unpackToString(sourceMessage.mFrom);
|
||||
if (ACTION_REPLY.equals(action) || ACTION_REPLY_ALL.equals(action)) {
|
||||
text += getString(R.string.message_compose_reply_header_fmt, fromAsString);
|
||||
if (quotedText != null) {
|
||||
Matcher matcher = PATTERN_START_OF_LINE.matcher(quotedText);
|
||||
text += matcher.replaceAll(">");
|
||||
}
|
||||
} else if (ACTION_FORWARD.equals(action)) {
|
||||
String subject = sourceMessage.mSubject;
|
||||
String to = Address.unpackToString(sourceMessage.mTo);
|
||||
String cc = Address.unpackToString(sourceMessage.mCc);
|
||||
text += getString(R.string.message_compose_fwd_header_fmt, subject, fromAsString,
|
||||
to != null ? to : "", cc != null ? cc : "");
|
||||
if (quotedText != null) {
|
||||
text += quotedText;
|
||||
}
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private ContentValues getUpdateContentValues(Message message) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(MessageColumns.TIMESTAMP, message.mTimeStamp);
|
||||
@ -656,15 +612,14 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
||||
* @param account the account (used to obtain From: address).
|
||||
* @param bodyText the body text.
|
||||
*/
|
||||
private void updateMessage(Message message, Account account, String bodyText,
|
||||
boolean hasAttachments) {
|
||||
private void updateMessage(Message message, Account account, boolean hasAttachments) {
|
||||
message.mTimeStamp = System.currentTimeMillis();
|
||||
message.mFrom = new Address(account.getEmailAddress(), account.getSenderName()).pack();
|
||||
message.mTo = getPackedAddresses(mToView);
|
||||
message.mCc = getPackedAddresses(mCcView);
|
||||
message.mBcc = getPackedAddresses(mBccView);
|
||||
message.mSubject = mSubjectView.getText().toString();
|
||||
message.mText = bodyText;
|
||||
message.mText = mMessageContentView.getText().toString();
|
||||
message.mAccountKey = account.mId;
|
||||
message.mDisplayName = makeDisplayName(message.mTo, message.mCc, message.mBcc);
|
||||
message.mFlagLoaded = Message.FLAG_LOADED_COMPLETE;
|
||||
@ -672,13 +627,19 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
||||
String action = getIntent().getAction();
|
||||
// Use the Intent to set flags saying this message is a reply or a forward and save the
|
||||
// unique id of the source message
|
||||
if (mSource != null) {
|
||||
if (ACTION_REPLY.equals(action) || ACTION_REPLY_ALL.equals(action)) {
|
||||
message.mFlags |= Message.FLAG_TYPE_REPLY;
|
||||
if (mSource != null && mQuotedTextBar.getVisibility() == View.VISIBLE) {
|
||||
if (ACTION_REPLY.equals(action) || ACTION_REPLY_ALL.equals(action)
|
||||
|| ACTION_FORWARD.equals(action)) {
|
||||
message.mSourceKey = mSource.mId;
|
||||
} else if (ACTION_FORWARD.equals(action)) {
|
||||
// Get the body of the source message here
|
||||
// Note that the following commented line will be useful when we use HTML in replies
|
||||
//message.mHtmlReply = mSource.mHtml;
|
||||
message.mTextReply = mSource.mText;
|
||||
}
|
||||
if (ACTION_FORWARD.equals(action)) {
|
||||
message.mFlags |= Message.FLAG_TYPE_FORWARD;
|
||||
message.mSourceKey = mSource.mId;
|
||||
} else {
|
||||
message.mFlags |= Message.FLAG_TYPE_REPLY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -704,7 +665,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
||||
mDraft = new Message();
|
||||
}
|
||||
final Attachment[] attachments = getAttachmentsFromUI();
|
||||
updateMessage(mDraft, mAccount, buildBodyText(mSource), attachments.length > 0);
|
||||
updateMessage(mDraft, mAccount, attachments.length > 0);
|
||||
|
||||
mSaveMessageTask = new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
@ -714,6 +675,8 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
|
||||
mDraft.update(MessageCompose.this, getUpdateContentValues(mDraft));
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(BodyColumns.TEXT_CONTENT, mDraft.mText);
|
||||
values.put(BodyColumns.TEXT_REPLY, mDraft.mTextReply);
|
||||
values.put(BodyColumns.HTML_REPLY, mDraft.mHtmlReply);
|
||||
Body.updateBodyWithMessageId(MessageCompose.this, mDraft.mId, values);
|
||||
} else {
|
||||
// mDraft.mId is set upon return of saveToMailbox()
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.email.mail.transport;
|
||||
|
||||
import com.android.email.R;
|
||||
import com.android.email.codec.binary.Base64;
|
||||
import com.android.email.codec.binary.Base64OutputStream;
|
||||
import com.android.email.mail.Address;
|
||||
@ -42,17 +43,53 @@ import java.io.Writer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Utility class to output RFC 822 messages from provider email messages
|
||||
*/
|
||||
public class Rfc822Output {
|
||||
|
||||
private static final Pattern PATTERN_START_OF_LINE = Pattern.compile("(?m)^");
|
||||
private static final Pattern PATTERN_ENDLINE_CRLF = Pattern.compile("\r\n");
|
||||
|
||||
// In MIME, en_US-like date format should be used. In other words "MMM" should be encoded to
|
||||
// "Jan", not the other localized format like "Ene" (meaning January in locale es).
|
||||
static final SimpleDateFormat mDateFormat =
|
||||
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
|
||||
|
||||
/*package*/ static String buildBodyText(Context context, Message message) {
|
||||
int flags = message.mFlags;
|
||||
Body body = Body.restoreBodyWithMessageId(context, message.mId);
|
||||
String text = body.mTextContent;
|
||||
|
||||
String quotedText = body.mTextReply;
|
||||
if (quotedText != null) {
|
||||
// fix CR-LF line endings to LF-only needed by EditText.
|
||||
Matcher matcher = PATTERN_ENDLINE_CRLF.matcher(quotedText);
|
||||
quotedText = matcher.replaceAll("\n");
|
||||
}
|
||||
String fromAsString = Address.unpackToString(message.mFrom);
|
||||
if ((flags & Message.FLAG_TYPE_REPLY) != 0) {
|
||||
text += context.getString(R.string.message_compose_reply_header_fmt, fromAsString);
|
||||
if (quotedText != null) {
|
||||
Matcher matcher = PATTERN_START_OF_LINE.matcher(quotedText);
|
||||
text += matcher.replaceAll(">");
|
||||
}
|
||||
} else if ((flags & Message.FLAG_TYPE_FORWARD) != 0) {
|
||||
String subject = message.mSubject;
|
||||
String to = Address.unpackToString(message.mTo);
|
||||
String cc = Address.unpackToString(message.mCc);
|
||||
text += context.getString(R.string.message_compose_fwd_header_fmt, subject,
|
||||
fromAsString, to != null ? to : "", cc != null ? cc : "");
|
||||
if (quotedText != null) {
|
||||
text += quotedText;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the entire message to an output stream. This method provides buffering, so it is
|
||||
* not necessary to pass in a buffered output stream here.
|
||||
@ -92,7 +129,7 @@ public class Rfc822Output {
|
||||
writeAddressHeader(writer, "Reply-To", message.mReplyTo);
|
||||
|
||||
// Analyze message and determine if we have multiparts
|
||||
String text = Body.restoreBodyTextWithMessageId(context, messageId);
|
||||
String text = buildBodyText(context, message);
|
||||
|
||||
Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, messageId);
|
||||
Cursor attachmentsCursor = context.getContentResolver().query(uri,
|
||||
|
@ -164,36 +164,7 @@ public class MessageComposeInstrumentationTests
|
||||
assertEquals(0, mMessageView.length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for buildBodyText().
|
||||
* Compare with expected values.
|
||||
* Also test the situation where the message has no body.
|
||||
*/
|
||||
public void testBuildBodyText() throws MessagingException, Throwable {
|
||||
final Message message = buildTestMessage(RECIPIENT_TO, SENDER, SUBJECT, BODY);
|
||||
Intent intent = new Intent(ACTION_REPLY);
|
||||
final MessageCompose a = getActivity();
|
||||
a.setIntent(intent);
|
||||
|
||||
runTestOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
a.processSourceMessage(message, null);
|
||||
String body = a.buildBodyText(message);
|
||||
assertEquals(REPLY_BODY, body);
|
||||
}
|
||||
});
|
||||
|
||||
message.mText = null;
|
||||
runTestOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
a.processSourceMessage(message, null);
|
||||
String body = a.buildBodyText(message);
|
||||
assertEquals(REPLY_BODY_SHORT, body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Test a couple of variations of processSourceMessage() for REPLY
|
||||
* To = Reply-To or From: (if REPLY)
|
||||
* To = (Reply-To or From:) + To: + Cc: (if REPLY_ALL)
|
||||
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.email.mail.transport;
|
||||
|
||||
import com.android.email.provider.EmailContent.Message;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
/**
|
||||
* Tests of the Rfc822Output (used for sending mail)
|
||||
*
|
||||
* You can run this entire test case with:
|
||||
* runtest -c com.android.email.mail.transport.Rfc822OutputTests email
|
||||
*/
|
||||
public class Rfc822OutputTests extends AndroidTestCase {
|
||||
private static final String SENDER = "sender@android.com";
|
||||
private static final String REPLYTO = "replyto@android.com";
|
||||
private static final String RECIPIENT_TO = "recipient-to@android.com";
|
||||
private static final String RECIPIENT_CC = "recipient-cc@android.com";
|
||||
private static final String RECIPIENT_BCC = "recipient-bcc@android.com";
|
||||
private static final String SUBJECT = "This is the subject";
|
||||
private static final String BODY = "This is the body. This is also the body.";
|
||||
private static final String REPLY_BODY_SHORT = "\n\n" + SENDER + " wrote:\n\n";
|
||||
private static final String REPLY_BODY = REPLY_BODY_SHORT + ">" + BODY;
|
||||
|
||||
// TODO Create more tests here. Specifically, we should test to make sure that forward works
|
||||
// properly instead of just reply
|
||||
|
||||
/**
|
||||
* Test for buildBodyText().
|
||||
* Compare with expected values.
|
||||
* Also test the situation where the message has no body.
|
||||
*/
|
||||
public void testBuildBodyText() {
|
||||
// Create the least necessary; sender, flags, and the body of the reply
|
||||
Message msg = new Message();
|
||||
msg.mText = "";
|
||||
msg.mFrom = SENDER;
|
||||
msg.mFlags = Message.FLAG_TYPE_REPLY;
|
||||
msg.mTextReply = BODY;
|
||||
msg.save(getContext());
|
||||
|
||||
String body = Rfc822Output.buildBodyText(getContext(), msg);
|
||||
assertEquals(REPLY_BODY, body);
|
||||
|
||||
// Save a different message with no reply body (so we reset the id)
|
||||
msg.mId = -1;
|
||||
msg.mTextReply = null;
|
||||
msg.save(getContext());
|
||||
body = Rfc822Output.buildBodyText(getContext(), msg);
|
||||
assertEquals(REPLY_BODY_SHORT, body);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user