From 6a2265eff292021f4a940334c079b84e17241ac7 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Tue, 19 Oct 2010 19:26:52 -0700 Subject: [PATCH] Add checkbox to include original text or not. Added the "Include text" checkbox according to the latest mock. Before: - We removed original message when the user pressed X. Now: - We save the original message all the way till the draft is sent. - The "Include text" check state is saved in the db. (to Message.mFlags) Bug 3072414 Change-Id: Ie7bcca23bb6a02d676700027b0b6cb94b6627236 --- res/layout/message_compose.xml | 32 +++++-- res/values/strings.xml | 3 + .../email/activity/MessageCompose.java | 94 +++++++++++++------ .../android/email/provider/EmailContent.java | 4 + 4 files changed, 96 insertions(+), 37 deletions(-) diff --git a/res/layout/message_compose.xml b/res/layout/message_compose.xml index 137e23a25..913ef20f7 100644 --- a/res/layout/message_compose.xml +++ b/res/layout/message_compose.xml @@ -95,26 +95,42 @@ android:imeOptions="actionDone|flagNoEnterAction" /> - - + - + + android:layout_alignParentRight="true" + /> + + android:layout_width="match_parent" + /> diff --git a/res/values/strings.xml b/res/values/strings.xml index 44b625661..f8cfcd1e7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -287,6 +287,9 @@ \n\n%s wrote:\n\n Quoted text + + Include text You must add at least one recipient. diff --git a/src/com/android/email/activity/MessageCompose.java b/src/com/android/email/activity/MessageCompose.java index c97bf823c..7fa366592 100644 --- a/src/com/android/email/activity/MessageCompose.java +++ b/src/com/android/email/activity/MessageCompose.java @@ -62,6 +62,7 @@ import android.view.View.OnClickListener; import android.view.View.OnFocusChangeListener; import android.webkit.WebView; import android.widget.Button; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageButton; import android.widget.LinearLayout; @@ -152,14 +153,14 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus private Button mSaveButton; private LinearLayout mAttachments; private View mQuotedTextBar; - private ImageButton mQuotedTextDelete; + private CheckBox mIncludeQuotedTextCheckBox; private WebView mQuotedText; private Controller mController; private boolean mDraftNeedsSaving; private boolean mMessageLoaded; private AsyncTask mLoadAttachmentsTask; - private AsyncTask mLoadMessageTask; + private AsyncTask mLoadMessageTask; private EmailAddressAdapter mAddressAdapterTo; private EmailAddressAdapter mAddressAdapterCc; @@ -314,7 +315,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus // Otherwise, handle the internal cases (Message Composer invoked from within app) long messageId = draftId != -1 ? draftId : intent.getLongExtra(EXTRA_MESSAGE_ID, -1); if (messageId != -1) { - mLoadMessageTask = new LoadMessageTask().execute(messageId); + mLoadMessageTask = new LoadMessageTask(messageId).execute(); } else { setAccount(intent); // Since this is a new message, we don't need to call LoadMessageTask. @@ -440,7 +441,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus mSaveButton = (Button)findViewById(R.id.save); mAttachments = (LinearLayout)findViewById(R.id.attachments); mQuotedTextBar = findViewById(R.id.quoted_text_bar); - mQuotedTextDelete = (ImageButton)findViewById(R.id.quoted_text_delete); + mIncludeQuotedTextCheckBox = (CheckBox) findViewById(R.id.include_quoted_text); mQuotedText = (WebView)findViewById(R.id.quoted_text); TextWatcher watcher = new TextWatcher() { @@ -524,9 +525,9 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus * needed. */ mQuotedTextBar.setVisibility(View.GONE); - mQuotedText.setVisibility(View.GONE); + setIncludeQuotedText(false); - mQuotedTextDelete.setOnClickListener(this); + mIncludeQuotedTextCheckBox.setOnClickListener(this); EmailAddressValidator addressValidator = new EmailAddressValidator(); @@ -562,9 +563,15 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus } // TODO: is there any way to unify this with MessageView.LoadMessageTask? - private class LoadMessageTask extends AsyncTask { + private class LoadMessageTask extends AsyncTask { + private final long mMessageId; + + public LoadMessageTask(long messageId) { + mMessageId = messageId; + } + @Override - protected Object[] doInBackground(Long... messageIds) { + protected Object[] doInBackground(Void... params) { synchronized (sSaveInProgressCondition) { while (sSaveInProgress) { try { @@ -574,7 +581,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus } } } - Message message = Message.restoreMessageWithId(MessageCompose.this, messageIds[0]); + Message message = Message.restoreMessageWithId(MessageCompose.this, mMessageId); if (message == null) { return new Object[] {null, null}; } @@ -619,8 +626,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus // Something unexpected happened: // the message or the body couldn't be loaded by SQLite. // Bail out. - Toast.makeText(MessageCompose.this, R.string.error_loading_message_body, - Toast.LENGTH_LONG).show(); + Utility.showToast(MessageCompose.this, R.string.error_loading_message_body); finish(); return; } @@ -755,7 +761,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus /** * @param message The message to be updated. * @param account the account (used to obtain From: address). - * @param bodyText the body text. + * @param hasAttachments true if it has one or more attachment. */ private void updateMessage(Message message, Account account, boolean hasAttachments) { if (message.mMessageId == null || message.mMessageId.length() == 0) { @@ -799,6 +805,11 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus getString(R.string.message_compose_reply_header_fmt, fromAsString); } } + if (includeQuotedText()) { + message.mFlags |= Message.FLAG_INCLUDE_QUOTED_TEXT; + } else { + message.mFlags &= ~Message.FLAG_INCLUDE_QUOTED_TEXT; + } } private Attachment[] getAttachmentsFromUI() { @@ -831,14 +842,28 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus } } - private class SendOrSaveMessageTask extends AsyncTask { + private class SendOrSaveMessageTask extends AsyncTask { + private final boolean mSend; + + public SendOrSaveMessageTask(boolean send) { + mSend = send; + } @Override - protected Boolean doInBackground(Boolean... params) { - boolean send = params[0]; + protected Void doInBackground(Void... params) { final Attachment[] attachments = getAttachmentsFromUI(); updateMessage(mDraft, mAccount, attachments.length > 0); synchronized (mDraft) { + if (mSend) { + // If sending, and "include original" isn't checked, remove the original. + // It has to be done before saving below. + if (!includeQuotedText()) { + mDraft.mIntroText = null; + mDraft.mTextReply = null; + mDraft.mHtmlReply = null; + mDraft.mSourceKey = 0; + } + } ContentResolver resolver = getContentResolver(); if (mDraft.isSaved()) { // Update the message @@ -885,7 +910,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus } } - if (send) { + if (mSend) { // Let the user know if message sending might be delayed by background // downlading of unloaded attachments if (hasUnloadedAttachments) { @@ -894,12 +919,12 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus } mController.sendMessage(mDraft.mId, mDraft.mAccountKey); } - return send; + return null; } } @Override - protected void onPostExecute(Boolean send) { + protected void onPostExecute(Void param) { synchronized (sSaveInProgressCondition) { sSaveInProgress = false; sSaveInProgressCondition.notify(); @@ -908,7 +933,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus return; } // Don't display the toast if the user is just changing the orientation - if (!send && (getChangingConfigurations() & ActivityInfo.CONFIG_ORIENTATION) == 0) { + if (!mSend && (getChangingConfigurations() & ActivityInfo.CONFIG_ORIENTATION) == 0) { Toast.makeText(MessageCompose.this, R.string.message_saved_toast, Toast.LENGTH_LONG).show(); } @@ -930,7 +955,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus synchronized (sSaveInProgressCondition) { sSaveInProgress = true; } - new SendOrSaveMessageTask().execute(send); + new SendOrSaveMessageTask(send).execute(); } private void saveIfNeeded() { @@ -1117,18 +1142,27 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus case R.id.attachment_delete: onDeleteAttachment(view); break; - case R.id.quoted_text_delete: - mQuotedTextBar.setVisibility(View.GONE); - mQuotedText.setVisibility(View.GONE); - mDraft.mIntroText = null; - mDraft.mTextReply = null; - mDraft.mHtmlReply = null; - mDraft.mSourceKey = 0; - setDraftNeedsSaving(true); + case R.id.include_quoted_text: + onIncludeQuotedTextChanged(); break; } } + private boolean includeQuotedText() { + return mIncludeQuotedTextCheckBox.isChecked(); + } + + private void setIncludeQuotedText(boolean include) { + mIncludeQuotedTextCheckBox.setChecked(include); + onIncludeQuotedTextChanged(); + } + + private void onIncludeQuotedTextChanged() { + mQuotedText.setVisibility(mIncludeQuotedTextCheckBox.isChecked() + ? View.VISIBLE : View.GONE); + setDraftNeedsSaving(true); + } + private void onDeleteAttachment(View delButtonView) { /* * The view is the delete button, and we have previously set the tag of @@ -1364,7 +1398,6 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus // text, message, 0); mQuotedTextBar.setVisibility(View.VISIBLE); if (mQuotedText != null) { - mQuotedText.setVisibility(View.VISIBLE); mQuotedText.loadDataWithBaseURL("email://", text, "text/html", "utf-8", null); } } @@ -1441,6 +1474,7 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus */ if (ACTION_EDIT_DRAFT.equals(mAction)) { displayQuotedText(message.mTextReply, message.mHtmlReply); + setIncludeQuotedText((mDraft.mFlags & Message.FLAG_INCLUDE_QUOTED_TEXT) != 0); } } @@ -1462,11 +1496,13 @@ public class MessageCompose extends Activity implements OnClickListener, OnFocus mSubjectView.setText(subject); } displayQuotedText(message.mText, message.mHtml); + setIncludeQuotedText(true); setInitialComposeText(null, (account != null) ? account.mSignature : null); } else if (ACTION_FORWARD.equals(mAction)) { mSubjectView.setText(subject != null && !subject.toLowerCase().startsWith("fwd:") ? "Fwd: " + subject : subject); displayQuotedText(message.mText, message.mHtml); + setIncludeQuotedText(true); setInitialComposeText(null, (account != null) ? account.mSignature : null); } else if (ACTION_EDIT_DRAFT.equals(mAction)) { mSubjectView.setText(subject); diff --git a/src/com/android/email/provider/EmailContent.java b/src/com/android/email/provider/EmailContent.java index 9578f8d3a..fb7b470bd 100644 --- a/src/com/android/email/provider/EmailContent.java +++ b/src/com/android/email/provider/EmailContent.java @@ -621,6 +621,10 @@ public abstract class EmailContent { // 8 general purpose flags (bits) that may be used at the discretion of the sync adapter public static final int FLAG_SYNC_ADAPTER_SHIFT = 9; public static final int FLAG_SYNC_ADAPTER_MASK = 255 << FLAG_SYNC_ADAPTER_SHIFT; + // Bit used in mFlags indicating that the outgoing message should include quoted original + // message. + public static final int FLAG_INCLUDE_QUOTED_TEXT_SHIFT = 17; + public static final int FLAG_INCLUDE_QUOTED_TEXT = 1 << FLAG_INCLUDE_QUOTED_TEXT_SHIFT; public Message() { mBaseUri = CONTENT_URI;