Fix reply/forward for both SMTP and EAS; fixes #2138725

* Add new introText column in the Body database
* Reply/Forward put the appropriate String into this new column
* Rfc822Output uses this when required when streaming the message

Change-Id: I34602fdb3f91692c46fc8bc31ba0e6f680d445a0
This commit is contained in:
Marc Blank 2009-09-22 18:38:28 -07:00
parent 0d00889f83
commit 5fc57eccef
7 changed files with 62 additions and 22 deletions

View File

@ -642,10 +642,20 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
//message.mHtmlReply = mSource.mHtml;
message.mTextReply = mSource.mText;
}
String fromAsString = Address.unpackToString(mSource.mFrom);
if (ACTION_FORWARD.equals(action)) {
message.mFlags |= Message.FLAG_TYPE_FORWARD;
String subject = mSource.mSubject;
String to = Address.unpackToString(mSource.mTo);
String cc = Address.unpackToString(mSource.mCc);
message.mIntroText =
getString(R.string.message_compose_fwd_header_fmt, subject, fromAsString,
to != null ? to : "", cc != null ? cc : "");
} else {
message.mFlags |= Message.FLAG_TYPE_REPLY;
message.mIntroText =
getString(R.string.message_compose_reply_header_fmt, fromAsString);
}
}
}
@ -683,6 +693,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus
values.put(BodyColumns.TEXT_CONTENT, mDraft.mText);
values.put(BodyColumns.TEXT_REPLY, mDraft.mTextReply);
values.put(BodyColumns.HTML_REPLY, mDraft.mHtmlReply);
values.put(BodyColumns.INTRO_TEXT, mDraft.mIntroText);
Body.updateBodyWithMessageId(MessageCompose.this, mDraft.mId, values);
} else {
// mDraft.mId is set upon return of saveToMailbox()

View File

@ -16,7 +16,6 @@
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;
@ -67,11 +66,10 @@ public class Rfc822Output {
}
String text = body.mTextContent;
String fromAsString = Address.unpackToString(message.mFrom);
int flags = message.mFlags;
boolean isReply = (flags & Message.FLAG_TYPE_REPLY) != 0;
boolean isForward = (flags & Message.FLAG_TYPE_FORWARD) != 0;
String intro = body.mIntroText == null ? "" : body.mIntroText;
if (!appendQuotedText) {
// appendQuotedText is set to false for use by SmartReply/SmartForward in EAS.
// SmartReply doesn't appear to work properly, so we will still add the header into
@ -79,7 +77,7 @@ public class Rfc822Output {
// SmartForward doesn't put any kind of break between the original and the new text,
// so we add a CRLF
if (isReply) {
text += context.getString(R.string.message_compose_reply_header_fmt, fromAsString);
text += intro;
} else if (isForward) {
text += "\r\n";
}
@ -93,17 +91,13 @@ public class Rfc822Output {
quotedText = matcher.replaceAll("\n");
}
if (isReply) {
text += context.getString(R.string.message_compose_reply_header_fmt, fromAsString);
text += intro;
if (quotedText != null) {
Matcher matcher = PATTERN_START_OF_LINE.matcher(quotedText);
text += matcher.replaceAll(">");
}
} else if (isForward) {
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 : "");
text += intro;
if (quotedText != null) {
text += quotedText;
}

View File

@ -16,8 +16,6 @@
package com.android.email.provider;
import com.android.email.R;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
@ -189,6 +187,8 @@ public abstract class EmailContent {
public static final String TEXT_REPLY = "textReply";
// Message id of the source (if this is a reply/forward)
public static final String SOURCE_MESSAGE_KEY = "sourceMessageKey";
// The text to be placed between a reply/forward response and the original message
public static final String INTRO_TEXT = "introText";
}
public static final class Body extends EmailContent implements BodyColumns {
@ -203,9 +203,11 @@ public abstract class EmailContent {
public static final int CONTENT_HTML_REPLY_COLUMN = 4;
public static final int CONTENT_TEXT_REPLY_COLUMN = 5;
public static final int CONTENT_SOURCE_KEY_COLUMN = 6;
public static final int CONTENT_INTRO_TEXT_COLUMN = 7;
public static final String[] CONTENT_PROJECTION = new String[] {
RECORD_ID, BodyColumns.MESSAGE_KEY, BodyColumns.HTML_CONTENT, BodyColumns.TEXT_CONTENT,
BodyColumns.HTML_REPLY, BodyColumns.TEXT_REPLY, BodyColumns.SOURCE_MESSAGE_KEY
BodyColumns.HTML_REPLY, BodyColumns.TEXT_REPLY, BodyColumns.SOURCE_MESSAGE_KEY,
BodyColumns.INTRO_TEXT
};
public static final int TEXT_TEXT_COLUMN = 1;
@ -226,6 +228,7 @@ public abstract class EmailContent {
public String mHtmlReply;
public String mTextReply;
public long mSourceKey;
public String mIntroText;
public Body() {
mBaseUri = CONTENT_URI;
@ -242,7 +245,7 @@ public abstract class EmailContent {
values.put(BodyColumns.HTML_REPLY, mHtmlReply);
values.put(BodyColumns.TEXT_REPLY, mTextReply);
values.put(BodyColumns.SOURCE_MESSAGE_KEY, mSourceKey);
values.put(BodyColumns.INTRO_TEXT, mIntroText);
return values;
}
@ -337,6 +340,7 @@ public abstract class EmailContent {
mHtmlReply = c.getString(CONTENT_HTML_REPLY_COLUMN);
mTextReply = c.getString(CONTENT_TEXT_REPLY_COLUMN);
mSourceKey = c.getLong(CONTENT_SOURCE_KEY_COLUMN);
mIntroText = c.getString(CONTENT_INTRO_TEXT_COLUMN);
return this;
}
@ -501,6 +505,7 @@ public abstract class EmailContent {
transient public String mHtmlReply;
transient public long mSourceKey;
transient public ArrayList<Attachment> mAttachments = null;
transient public String mIntroText;
// Values used in mFlagRead
public static final int UNREAD = 0;
@ -684,6 +689,9 @@ public abstract class EmailContent {
if (mSourceKey != 0) {
cv.put(Body.SOURCE_MESSAGE_KEY, mSourceKey);
}
if (mIntroText != null) {
cv.put(Body.INTRO_TEXT, mIntroText);
}
b = ContentProviderOperation.newInsert(Body.CONTENT_URI);
b.withValues(cv);
ContentValues backValues = new ContentValues();

View File

@ -69,7 +69,8 @@ public class EmailProvider extends ContentProvider {
// Version 3: Add "sourceKey" column
// Version 4: Database wipe required; changing AccountManager interface w/Exchange
// Version 5: Database wipe required; changing AccountManager interface w/Exchange
public static final int BODY_DATABASE_VERSION = 5;
// Version 6: Adding Body.mIntroText column
public static final int BODY_DATABASE_VERSION = 6;
public static final String EMAIL_AUTHORITY = "com.android.email.provider";
@ -494,7 +495,8 @@ public class EmailProvider extends ContentProvider {
+ BodyColumns.TEXT_CONTENT + " text, "
+ BodyColumns.HTML_REPLY + " text, "
+ BodyColumns.TEXT_REPLY + " text, "
+ BodyColumns.SOURCE_MESSAGE_KEY + " text"
+ BodyColumns.SOURCE_MESSAGE_KEY + " text, "
+ BodyColumns.INTRO_TEXT + " text"
+ ");";
db.execSQL("create table " + Body.TABLE_NAME + s);
db.execSQL(createIndex(Body.TABLE_NAME, BodyColumns.MESSAGE_KEY));
@ -507,6 +509,15 @@ public class EmailProvider extends ContentProvider {
createBodyTable(db);
} catch (SQLException e) {
}
} else if (oldVersion == 5) {
try {
db.execSQL("alter table " + Body.TABLE_NAME
+ " add " + BodyColumns.INTRO_TEXT + " text");
} catch (SQLException e) {
// Shouldn't be needed unless we're debugging and interrupt the process
Log.w(TAG, "Exception upgrading EmailProviderBody.db from v5 to v6", e);
}
oldVersion = 6;
}
}
@ -590,12 +601,17 @@ public class EmailProvider extends ContentProvider {
}
if (oldVersion == 5) {
// Message Tables: Add SyncColumns.SERVER_TIMESTAMP
db.execSQL("alter table " + Message.TABLE_NAME
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
db.execSQL("alter table " + Message.UPDATED_TABLE_NAME
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
db.execSQL("alter table " + Message.DELETED_TABLE_NAME
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
try {
db.execSQL("alter table " + Message.TABLE_NAME
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
db.execSQL("alter table " + Message.UPDATED_TABLE_NAME
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
db.execSQL("alter table " + Message.DELETED_TABLE_NAME
+ " add column " + SyncColumns.SERVER_TIMESTAMP + " integer" + ";");
} catch (SQLException e) {
// Shouldn't be needed unless we're debugging and interrupt the process
Log.w(TAG, "Exception upgrading EmailProvider.db from v5 to v6", e);
}
oldVersion = 6;
}
}

View File

@ -62,6 +62,7 @@ public class Rfc822OutputTests extends AndroidTestCase {
msg.mFrom = SENDER;
msg.mFlags = Message.FLAG_TYPE_REPLY;
msg.mTextReply = BODY;
msg.mIntroText = REPLY_BODY_SHORT;
msg.save(getContext());
String body = Rfc822Output.buildBodyText(getContext(), msg, true);
@ -87,6 +88,7 @@ public class Rfc822OutputTests extends AndroidTestCase {
msg.mFrom = SENDER;
msg.mFlags = Message.FLAG_TYPE_REPLY;
msg.mTextReply = BODY;
msg.mIntroText = REPLY_BODY_SHORT;
msg.save(getContext());
String body = Rfc822Output.buildBodyText(getContext(), msg, false);

View File

@ -151,6 +151,7 @@ public class ProviderTestUtils extends Assert {
message.mTextReply = "reply text " + name;
message.mHtmlReply = "reply html " + name;
message.mSourceKey = 400 + name.length();
message.mIntroText = "intro text " + name;
}
if (saveIt) {
@ -314,6 +315,7 @@ public class ProviderTestUtils extends Assert {
assertEquals(caller + " mTextReply", expect.mTextReply, actual.mTextReply);
assertEquals(caller + " mHtmlReply", expect.mHtmlReply, actual.mHtmlReply);
assertEquals(caller + " mSourceKey", expect.mSourceKey, actual.mSourceKey);
assertEquals(caller + " mIntroText", expect.mIntroText, actual.mIntroText);
}
/**

View File

@ -234,11 +234,13 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
String textReply2 = message2.mTextReply;
String htmlReply2 = message2.mHtmlReply;
long sourceKey2 = message2.mSourceKey;
String introText2 = message2.mIntroText;
message2.mText = null;
message2.mHtml = null;
message2.mTextReply = null;
message2.mHtmlReply = null;
message2.mSourceKey = 0;
message2.mIntroText = null;
Message message2get = EmailContent.Message.restoreMessageWithId(mMockContext, message2Id);
ProviderTestUtils.assertMessageEqual("testMessageSave", message2, message2get);
@ -249,6 +251,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
assertEquals("reply text", textReply2, body2.mTextReply);
assertEquals("reply html", htmlReply2, body2.mHtmlReply);
assertEquals("source key", sourceKey2, body2.mSourceKey);
assertEquals("intro text", introText2, body2.mIntroText);
// Message with attachments and body
Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id, true,
@ -432,6 +435,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
final String htmlContent = "and some html";
final String textReply = "plain text reply";
final String htmlReply = "or the html reply";
final String introText = "fred wrote:";
ContentValues values = new ContentValues();
values.put(BodyColumns.TEXT_CONTENT, textContent);
@ -439,6 +443,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
values.put(BodyColumns.TEXT_REPLY, textReply);
values.put(BodyColumns.HTML_REPLY, htmlReply);
values.put(BodyColumns.SOURCE_MESSAGE_KEY, 17);
values.put(BodyColumns.INTRO_TEXT, introText);
// 1
Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
@ -454,6 +459,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
assertEquals(body1.mTextReply, textReply);
assertEquals(body1.mHtmlReply, htmlReply);
assertEquals(body1.mSourceKey, 17);
assertEquals(body1.mIntroText, introText);
// 2
Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
@ -470,6 +476,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
assertEquals(body2.mTextReply, textReply);
assertEquals(body2.mHtmlReply, htmlReply);
assertEquals(body2.mSourceKey, 17);
assertEquals(body2.mIntroText, introText);
}
/**