Add button to allow editing of quoted message in HTML mode by dropping user back to text mode. Fixes issue 2959.
BIN
images/drawable-src/btn_edit.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
images/drawable-src/btn_empty_disable.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
images/drawable-src/btn_empty_normal.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
images/drawable-src/btn_empty_pressed.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
images/drawable-src/btn_empty_selected.png
Normal file
After Width: | Height: | Size: 4 KiB |
BIN
res/drawable-hdpi/btn_edit_disable.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
res/drawable-hdpi/btn_edit_normal.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
res/drawable-hdpi/btn_edit_pressed.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
res/drawable-hdpi/btn_edit_selected.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
28
res/drawable/btn_edit.xml
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2007 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.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_window_focused="false" android:state_enabled="true"
|
||||
android:drawable="@drawable/btn_edit_normal" />
|
||||
<item android:state_window_focused="false" android:state_enabled="false"
|
||||
android:drawable="@drawable/btn_edit_disable" />
|
||||
<item android:state_pressed="true"
|
||||
android:drawable="@drawable/btn_edit_pressed" />
|
||||
<item android:state_enabled="true" android:state_focused="true"
|
||||
android:drawable="@drawable/btn_edit_selected" />
|
||||
<item android:drawable="@drawable/btn_edit_normal" />
|
||||
</selector>
|
||||
|
|
@ -213,6 +213,22 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/quoted_text_buttons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/quoted_text_edit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginRight="8dip"
|
||||
android:background="@drawable/btn_edit" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/quoted_text_delete"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -221,6 +237,8 @@
|
|||
android:layout_alignParentRight="true"
|
||||
android:background="@drawable/btn_dialog" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<EditText
|
||||
|
|
|
@ -104,6 +104,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
private static final String STATE_PGP_DATA = "pgpData";
|
||||
private static final String STATE_IN_REPLY_TO = "com.fsck.k9.activity.MessageCompose.inReplyTo";
|
||||
private static final String STATE_REFERENCES = "com.fsck.k9.activity.MessageCompose.references";
|
||||
private static final String STATE_KEY_MESSAGE_FORMAT = "com.fsck.k9.activity.MessageCompose.messageFormat";
|
||||
|
||||
private static final int MSG_PROGRESS_ON = 1;
|
||||
private static final int MSG_PROGRESS_OFF = 2;
|
||||
|
@ -164,6 +165,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
private EditText mMessageContentView;
|
||||
private LinearLayout mAttachments;
|
||||
private View mQuotedTextBar;
|
||||
private ImageButton mQuotedTextEdit;
|
||||
private ImageButton mQuotedTextDelete;
|
||||
private EditText mQuotedText;
|
||||
private MessageWebView mQuotedHTML;
|
||||
|
@ -179,6 +181,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
private String mReferences;
|
||||
private String mInReplyTo;
|
||||
|
||||
private boolean mSourceProcessed = false;
|
||||
private MessageFormat mMessageFormat;
|
||||
|
||||
private boolean mDraftNeedsSaving = false;
|
||||
private boolean mPreventDraftSaving = false;
|
||||
|
||||
|
@ -381,6 +386,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
mMessageContentView.getInputExtras(true).putBoolean("allowEmoji", true);
|
||||
mAttachments = (LinearLayout)findViewById(R.id.attachments);
|
||||
mQuotedTextBar = findViewById(R.id.quoted_text_bar);
|
||||
mQuotedTextEdit = (ImageButton)findViewById(R.id.quoted_text_edit);
|
||||
mQuotedTextDelete = (ImageButton)findViewById(R.id.quoted_text_delete);
|
||||
mQuotedText = (EditText)findViewById(R.id.quoted_text);
|
||||
mQuotedText.getInputExtras(true).putBoolean("allowEmoji", true);
|
||||
|
@ -442,7 +448,9 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
mQuotedTextBar.setVisibility(View.GONE);
|
||||
mQuotedText.setVisibility(View.GONE);
|
||||
mQuotedHTML.setVisibility(View.GONE);
|
||||
mQuotedTextEdit.setVisibility(View.GONE);
|
||||
|
||||
mQuotedTextEdit.setOnClickListener(this);
|
||||
mQuotedTextDelete.setOnClickListener(this);
|
||||
|
||||
mFromView.setVisibility(View.GONE);
|
||||
|
@ -496,6 +504,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
mSignatureView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
mMessageFormat = mAccount.getMessageFormat();
|
||||
|
||||
if (!mSourceMessageProcessed)
|
||||
{
|
||||
updateFrom();
|
||||
|
@ -830,6 +840,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
outState.putString(STATE_IN_REPLY_TO, mInReplyTo);
|
||||
outState.putString(STATE_REFERENCES, mReferences);
|
||||
outState.putSerializable(STATE_KEY_HTML_QUOTE, mQuotedHtmlContent);
|
||||
outState.putSerializable(STATE_KEY_MESSAGE_FORMAT, mMessageFormat);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -844,9 +855,10 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
addAttachment(uri);
|
||||
}
|
||||
|
||||
mMessageFormat = (MessageFormat)savedInstanceState.getSerializable(STATE_KEY_MESSAGE_FORMAT);
|
||||
mCcView.setVisibility(savedInstanceState.getBoolean(STATE_KEY_CC_SHOWN) ? View.VISIBLE : View.GONE);
|
||||
mBccView.setVisibility(savedInstanceState.getBoolean(STATE_KEY_BCC_SHOWN) ? View.VISIBLE : View.GONE);
|
||||
if (mAccount.getMessageFormat() == MessageFormat.HTML)
|
||||
if (mMessageFormat == MessageFormat.HTML)
|
||||
{
|
||||
mQuotedHtmlContent = (InsertableHtmlContent) savedInstanceState.getSerializable(STATE_KEY_HTML_QUOTE);
|
||||
mQuotedTextBar.setVisibility(savedInstanceState.getBoolean(STATE_KEY_QUOTED_TEXT_SHOWN) ? View.VISIBLE : View.GONE);
|
||||
|
@ -854,6 +866,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
if (mQuotedHtmlContent != null && mQuotedHtmlContent.getQuotedContent() != null)
|
||||
{
|
||||
mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
|
||||
mQuotedTextEdit.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -940,7 +953,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
// Handle HTML separate from the rest of the text content. HTML mode doesn't allow signature after the quoted
|
||||
// text, nor does it allow reply after quote. Users who want that functionality will need to stick with text
|
||||
// mode.
|
||||
if (mAccount.getMessageFormat() == MessageFormat.HTML)
|
||||
if (mMessageFormat == MessageFormat.HTML)
|
||||
{
|
||||
// Add the signature.
|
||||
if (!isDraft)
|
||||
|
@ -1000,7 +1013,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
return body;
|
||||
}
|
||||
}
|
||||
else if (mAccount.getMessageFormat() == MessageFormat.TEXT)
|
||||
else if (mMessageFormat == MessageFormat.TEXT)
|
||||
{
|
||||
// Capture composed message length before we start attaching quoted parts and signatures.
|
||||
Integer composedMessageLength = text.length();
|
||||
|
@ -1097,7 +1110,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
|
||||
final boolean hasAttachments = mAttachments.getChildCount() > 0;
|
||||
|
||||
if (mAccount.getMessageFormat() == MessageFormat.HTML)
|
||||
if (mMessageFormat == MessageFormat.HTML)
|
||||
{
|
||||
// HTML message (with alternative text part)
|
||||
|
||||
|
@ -1265,7 +1278,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
uri.appendQueryParameter(IdentityField.OFFSET.value(), Integer.toString(0));
|
||||
}
|
||||
// Save the message format for this offset.
|
||||
uri.appendQueryParameter(IdentityField.MESSAGE_FORMAT.value(), mAccount.getMessageFormat().name());
|
||||
uri.appendQueryParameter(IdentityField.MESSAGE_FORMAT.value(), mMessageFormat.name());
|
||||
|
||||
// If we're not using the standard identity of signature, append it on to the identity blob.
|
||||
if (mSignatureChanged)
|
||||
|
@ -1806,11 +1819,35 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
mDraftNeedsSaving = true;
|
||||
break;
|
||||
case R.id.quoted_text_delete:
|
||||
deleteQuotedText();
|
||||
mDraftNeedsSaving = true;
|
||||
break;
|
||||
case R.id.quoted_text_edit:
|
||||
mMessageFormat = MessageFormat.TEXT;
|
||||
if (mMessageReference != null) // shouldn't happen...
|
||||
{
|
||||
// TODO - Should we check if mSourceMessageBody is already present and bypass the MessagingController call?
|
||||
MessagingController.getInstance(getApplication()).addListener(mListener);
|
||||
final Account account = Preferences.getPreferences(this).getAccount(mMessageReference.accountUuid);
|
||||
final String folderName = mMessageReference.folderName;
|
||||
final String sourceMessageUid = mMessageReference.uid;
|
||||
MessagingController.getInstance(getApplication()).loadMessageForView(account, folderName, sourceMessageUid, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the quoted text.
|
||||
*/
|
||||
private void deleteQuotedText()
|
||||
{
|
||||
mQuotedTextBar.setVisibility(View.GONE);
|
||||
mQuotedText.setVisibility(View.GONE);
|
||||
mQuotedHTML.setVisibility(View.GONE);
|
||||
mDraftNeedsSaving = true;
|
||||
break;
|
||||
if (mQuotedHtmlContent != null)
|
||||
{
|
||||
mQuotedHtmlContent.clearQuotedContent();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2292,7 +2329,7 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
// 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.
|
||||
if (mAccount.getMessageFormat() == MessageFormat.HTML)
|
||||
if (mMessageFormat == MessageFormat.HTML)
|
||||
{
|
||||
if (k9identity.get(IdentityField.MESSAGE_FORMAT) == null || !MessageFormat.valueOf(k9identity.get(IdentityField.MESSAGE_FORMAT)).equals(MessageFormat.HTML))
|
||||
{
|
||||
|
@ -2330,11 +2367,12 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
mQuotedHTML.loadDataWithBaseURL("http://", mQuotedHtmlContent.getQuotedContent(), "text/html", "utf-8", null);
|
||||
mQuotedHTML.setVisibility(View.VISIBLE);
|
||||
mQuotedTextBar.setVisibility(View.VISIBLE);
|
||||
mQuotedTextEdit.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mAccount.getMessageFormat() == MessageFormat.TEXT)
|
||||
else if (mMessageFormat == MessageFormat.TEXT)
|
||||
{
|
||||
MessageFormat format = k9identity.get(IdentityField.MESSAGE_FORMAT) != null
|
||||
? MessageFormat.valueOf(k9identity.get(IdentityField.MESSAGE_FORMAT))
|
||||
|
@ -2431,8 +2469,8 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
// If we already have mSourceMessageBody, use that. It's pre-populated if we've got crypto going on.
|
||||
String content = mSourceMessageBody != null
|
||||
? mSourceMessageBody
|
||||
: getBodyTextFromMessage(mSourceMessage, mAccount.getMessageFormat());
|
||||
if (mAccount.getMessageFormat() == MessageFormat.HTML)
|
||||
: getBodyTextFromMessage(mSourceMessage, mMessageFormat);
|
||||
if (mMessageFormat == MessageFormat.HTML)
|
||||
{
|
||||
// Add the HTML reply header to the top of the content.
|
||||
mQuotedHtmlContent = quoteOriginalHtmlMessage(mSourceMessage, content, mAccount.getQuoteStyle());
|
||||
|
@ -2441,13 +2479,20 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
|
||||
mQuotedTextBar.setVisibility(View.VISIBLE);
|
||||
mQuotedHTML.setVisibility(View.VISIBLE);
|
||||
mQuotedTextEdit.setVisibility(View.VISIBLE);
|
||||
|
||||
mQuotedText.setVisibility(View.GONE);
|
||||
}
|
||||
else if (mAccount.getMessageFormat() == MessageFormat.TEXT)
|
||||
else if (mMessageFormat == MessageFormat.TEXT)
|
||||
{
|
||||
mQuotedText.setText(quoteOriginalTextMessage(mSourceMessage, content, mAccount.getQuoteStyle()));
|
||||
|
||||
mQuotedTextBar.setVisibility(View.VISIBLE);
|
||||
mQuotedText.setVisibility(View.VISIBLE);
|
||||
|
||||
mQuotedHtmlContent = null;
|
||||
mQuotedTextEdit.setVisibility(View.GONE);
|
||||
mQuotedHTML.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2688,8 +2733,28 @@ public class MessageCompose extends K9Activity implements OnClickListener, OnFoc
|
|||
runOnUiThread(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
// We check to see if we've previously processed the source message since this
|
||||
// could be called when switching from HTML to text replies. If that happens, we
|
||||
// only want to update the UI with quoted text (which picks the appropriate
|
||||
// part).
|
||||
if (mSourceProcessed)
|
||||
{
|
||||
try
|
||||
{
|
||||
populateUIWithQuotedMessage();
|
||||
} catch (MessagingException e)
|
||||
{
|
||||
// Hm, if we couldn't populate the UI after source reprocessing, let's just delete it?
|
||||
deleteQuotedText();
|
||||
Log.e(K9.LOG_TAG, "Could not re-process source message; deleting quoted text to be safe.", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
processSourceMessage(message);
|
||||
mSourceProcessed = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|