mirror of
https://github.com/moparisthebest/k-9
synced 2024-12-25 09:08:49 -05:00
Save/restore instance state for SingleMessageView
This commit is contained in:
parent
2c09d75afa
commit
4e12dc154e
@ -7,7 +7,6 @@ import android.content.Intent;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.Config;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
@ -19,7 +18,7 @@ import com.fsck.k9.crypto.PgpData;
|
|||||||
import com.fsck.k9.helper.FileBrowserHelper;
|
import com.fsck.k9.helper.FileBrowserHelper;
|
||||||
import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback;
|
import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback;
|
||||||
import com.fsck.k9.mail.*;
|
import com.fsck.k9.mail.*;
|
||||||
import com.fsck.k9.mail.store.LocalStore;
|
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
|
||||||
import com.fsck.k9.mail.store.StorageManager;
|
import com.fsck.k9.mail.store.StorageManager;
|
||||||
import com.fsck.k9.view.AttachmentView;
|
import com.fsck.k9.view.AttachmentView;
|
||||||
import com.fsck.k9.view.SingleMessageView;
|
import com.fsck.k9.view.SingleMessageView;
|
||||||
@ -33,7 +32,6 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
private static final String EXTRA_MESSAGE_REFERENCES = "com.fsck.k9.MessageView_messageReferences";
|
private static final String EXTRA_MESSAGE_REFERENCES = "com.fsck.k9.MessageView_messageReferences";
|
||||||
private static final String EXTRA_NEXT = "com.fsck.k9.MessageView_next";
|
private static final String EXTRA_NEXT = "com.fsck.k9.MessageView_next";
|
||||||
private static final String EXTRA_MESSAGE_LIST_EXTRAS = "com.fsck.k9.MessageView_messageListExtras";
|
private static final String EXTRA_MESSAGE_LIST_EXTRAS = "com.fsck.k9.MessageView_messageListExtras";
|
||||||
private static final String SHOW_PICTURES = "showPictures";
|
|
||||||
private static final String STATE_PGP_DATA = "pgpData";
|
private static final String STATE_PGP_DATA = "pgpData";
|
||||||
private static final int ACTIVITY_CHOOSE_FOLDER_MOVE = 1;
|
private static final int ACTIVITY_CHOOSE_FOLDER_MOVE = 1;
|
||||||
private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
|
private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
|
||||||
@ -417,10 +415,10 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onSaveInstanceState(Bundle outState) {
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
outState.putParcelable(EXTRA_MESSAGE_REFERENCE, mMessageReference);
|
outState.putParcelable(EXTRA_MESSAGE_REFERENCE, mMessageReference);
|
||||||
outState.putParcelableArrayList(EXTRA_MESSAGE_REFERENCES, mMessageReferences);
|
outState.putParcelableArrayList(EXTRA_MESSAGE_REFERENCES, mMessageReferences);
|
||||||
outState.putSerializable(STATE_PGP_DATA, mPgpData);
|
outState.putSerializable(STATE_PGP_DATA, mPgpData);
|
||||||
outState.putBoolean(SHOW_PICTURES, mMessageView.showPictures());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -428,7 +426,6 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
super.onRestoreInstanceState(savedInstanceState);
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
mPgpData = (PgpData) savedInstanceState.getSerializable(STATE_PGP_DATA);
|
mPgpData = (PgpData) savedInstanceState.getSerializable(STATE_PGP_DATA);
|
||||||
mMessageView.updateCryptoLayout(mAccount.getCryptoProvider(), mPgpData, mMessage);
|
mMessageView.updateCryptoLayout(mAccount.getCryptoProvider(), mPgpData, mMessage);
|
||||||
mMessageView.setLoadPictures(savedInstanceState.getBoolean(SHOW_PICTURES));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayMessage(MessageReference ref) {
|
private void displayMessage(MessageReference ref) {
|
||||||
@ -439,7 +436,11 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
findSurroundingMessagesUid();
|
findSurroundingMessagesUid();
|
||||||
// start with fresh, empty PGP data
|
// start with fresh, empty PGP data
|
||||||
mPgpData = new PgpData();
|
mPgpData = new PgpData();
|
||||||
mMessageView.showMessageWebView(true);
|
|
||||||
|
// Clear previous message
|
||||||
|
mMessageView.resetView();
|
||||||
|
mMessageView.resetHeaderView();
|
||||||
|
|
||||||
mController.loadMessageForView(mAccount, mMessageReference.folderName, mMessageReference.uid, mListener);
|
mController.loadMessageForView(mAccount, mMessageReference.folderName, mMessageReference.uid, mListener);
|
||||||
setupDisplayMessageButtons();
|
setupDisplayMessageButtons();
|
||||||
}
|
}
|
||||||
@ -949,46 +950,6 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
return super.onPrepareOptionsMenu(menu);
|
return super.onPrepareOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayMessageBody(final Account account, final String folder, final String uid, final Message message) {
|
|
||||||
runOnUiThread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
boolean resetMessageViewState = true;
|
|
||||||
|
|
||||||
// Did we just completely download a previously incomplete message?
|
|
||||||
if (mMessage != null && mMessage.isSet(Flag.X_DOWNLOADED_PARTIAL) &&
|
|
||||||
message.isSet(Flag.X_DOWNLOADED_FULL)) {
|
|
||||||
// Update the headers
|
|
||||||
mMessageView.setHeaders(message, account);
|
|
||||||
|
|
||||||
// Keep the current view state (i.e. if the attachment view was visible,
|
|
||||||
// keep it that way)
|
|
||||||
resetMessageViewState = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mMessage = message;
|
|
||||||
|
|
||||||
mMessageView.displayMessageBody(account, message, mPgpData);
|
|
||||||
|
|
||||||
boolean hasAttachments = ((LocalStore.LocalMessage) message).hasAttachments();
|
|
||||||
|
|
||||||
if (hasAttachments) {
|
|
||||||
mMessageView.renderAttachments(mMessage, 0, mMessage, mAccount, mController, mListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resetMessageViewState) {
|
|
||||||
mMessageView.onShowMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (MessagingException e) {
|
|
||||||
if (Config.LOGV) {
|
|
||||||
Log.v(K9.LOG_TAG, "loadMessageForViewBodyAvailable", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
class Listener extends MessagingListener {
|
class Listener extends MessagingListener {
|
||||||
@Override
|
@Override
|
||||||
public void loadMessageForViewHeadersAvailable(final Account account, String folder, String uid,
|
public void loadMessageForViewHeadersAvailable(final Account account, String folder, String uid,
|
||||||
@ -1030,17 +991,28 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadMessageForViewBodyAvailable(Account account, String folder, String uid,
|
public void loadMessageForViewBodyAvailable(final Account account, String folder,
|
||||||
Message message) {
|
String uid, final Message message) {
|
||||||
if (!mMessageReference.uid.equals(uid) || !mMessageReference.folderName.equals(folder)
|
if (!mMessageReference.uid.equals(uid) ||
|
||||||
|| !mMessageReference.accountUuid.equals(account.getUuid())) {
|
!mMessageReference.folderName.equals(folder) ||
|
||||||
|
!mMessageReference.accountUuid.equals(account.getUuid())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
displayMessageBody(account, folder, uid, message);
|
runOnUiThread(new Runnable() {
|
||||||
}//loadMessageForViewBodyAvailable
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
mMessage = message;
|
||||||
|
mMessageView.setMessage(account, (LocalMessage) message, mPgpData,
|
||||||
|
mController, mListener);
|
||||||
|
|
||||||
|
} catch (MessagingException e) {
|
||||||
|
Log.v(K9.LOG_TAG, "loadMessageForViewBodyAvailable", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadMessageForViewFailed(Account account, String folder, String uid, final Throwable t) {
|
public void loadMessageForViewFailed(Account account, String folder, String uid, final Throwable t) {
|
||||||
@ -1146,9 +1118,11 @@ public class MessageView extends K9Activity implements OnClickListener {
|
|||||||
// This REALLY should be in MessageCryptoView
|
// This REALLY should be in MessageCryptoView
|
||||||
public void onDecryptDone(PgpData pgpData) {
|
public void onDecryptDone(PgpData pgpData) {
|
||||||
Account account = mAccount;
|
Account account = mAccount;
|
||||||
Message message = mMessage;
|
LocalMessage message = (LocalMessage) mMessage;
|
||||||
|
MessagingController controller = mController;
|
||||||
|
Listener listener = mListener;
|
||||||
try {
|
try {
|
||||||
mMessageView.displayMessageBody(account, message, pgpData);
|
mMessageView.setMessage(account, message, pgpData, controller, listener);
|
||||||
} catch (MessagingException e) {
|
} catch (MessagingException e) {
|
||||||
Log.e(K9.LOG_TAG, "displayMessageBody failed", e);
|
Log.e(K9.LOG_TAG, "displayMessageBody failed", e);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ import android.content.Intent;
|
|||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@ -27,6 +29,7 @@ import com.fsck.k9.helper.Contacts;
|
|||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.*;
|
import com.fsck.k9.mail.*;
|
||||||
import com.fsck.k9.mail.store.LocalStore;
|
import com.fsck.k9.mail.store.LocalStore;
|
||||||
|
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@ -51,6 +54,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
|
|||||||
private LinearLayout mHeaderPlaceHolder;
|
private LinearLayout mHeaderPlaceHolder;
|
||||||
private LinearLayout mTitleBarHeaderContainer;
|
private LinearLayout mTitleBarHeaderContainer;
|
||||||
private View mAttachmentsContainer;
|
private View mAttachmentsContainer;
|
||||||
|
private SavedState mSavedState;
|
||||||
|
|
||||||
public void initialize(Activity activity) {
|
public void initialize(Activity activity) {
|
||||||
mMessageContentView = (MessageWebView) findViewById(R.id.message_content);
|
mMessageContentView = (MessageWebView) findViewById(R.id.message_content);
|
||||||
@ -258,8 +262,8 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
|
|||||||
return mHeaderContainer.additionalHeadersVisible();
|
return mHeaderContainer.additionalHeadersVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayMessageBody(Account account, Message message, PgpData pgpData)
|
public void setMessage(Account account, LocalMessage message, PgpData pgpData,
|
||||||
throws MessagingException {
|
MessagingController controller, MessagingListener listener) throws MessagingException {
|
||||||
resetView();
|
resetView();
|
||||||
|
|
||||||
String type;
|
String type;
|
||||||
@ -268,14 +272,49 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
|
|||||||
type = "text/plain";
|
type = "text/plain";
|
||||||
} else {
|
} else {
|
||||||
// getTextForDisplay() always returns HTML-ified content.
|
// getTextForDisplay() always returns HTML-ified content.
|
||||||
text = ((LocalStore.LocalMessage) message).getTextForDisplay();
|
text = message.getTextForDisplay();
|
||||||
type = "text/html";
|
type = "text/html";
|
||||||
}
|
}
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
final String emailText = text;
|
final String emailText = text;
|
||||||
final String contentType = type;
|
final String contentType = type;
|
||||||
loadBodyFromText(message, emailText, contentType);
|
loadBodyFromText(emailText, contentType);
|
||||||
updateCryptoLayout(account.getCryptoProvider(), pgpData, message);
|
updateCryptoLayout(account.getCryptoProvider(), pgpData, message);
|
||||||
|
} else {
|
||||||
|
loadBodyFromUrl("file:///android_asset/empty.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
mHasAttachments = message.hasAttachments();
|
||||||
|
|
||||||
|
if (mHasAttachments) {
|
||||||
|
renderAttachments(message, 0, message, account, controller, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
mHiddenAttachments.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
boolean lookForImages = true;
|
||||||
|
if (mSavedState != null) {
|
||||||
|
if (mSavedState.showPictures) {
|
||||||
|
setLoadPictures(true);
|
||||||
|
lookForImages = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSavedState.attachmentViewVisible) {
|
||||||
|
onShowAttachments();
|
||||||
|
} else {
|
||||||
|
onShowMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSavedState.hiddenAttachmentsVisible) {
|
||||||
|
onShowHiddenAttachments();
|
||||||
|
}
|
||||||
|
|
||||||
|
mSavedState = null;
|
||||||
|
} else {
|
||||||
|
onShowMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text != null && lookForImages) {
|
||||||
// If the message contains external pictures and the "Show pictures"
|
// If the message contains external pictures and the "Show pictures"
|
||||||
// button wasn't already pressed, see if the user's preferences has us
|
// button wasn't already pressed, see if the user's preferences has us
|
||||||
// showing them anyway.
|
// showing them anyway.
|
||||||
@ -291,12 +330,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
|
|||||||
showShowPicturesAction(true);
|
showShowPicturesAction(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mHasAttachments = ((LocalStore.LocalMessage) message).hasAttachments();
|
|
||||||
} else {
|
|
||||||
loadBodyFromUrl("file:///android_asset/empty.html");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onShowMessage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadBodyFromUrl(String url) {
|
public void loadBodyFromUrl(String url) {
|
||||||
@ -305,7 +339,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadBodyFromText(Message message, String emailText, String contentType) {
|
private void loadBodyFromText(String emailText, String contentType) {
|
||||||
if (mScreenReaderEnabled) {
|
if (mScreenReaderEnabled) {
|
||||||
mAccessibleMessageContentView.loadDataWithBaseURL("http://", emailText, contentType, "utf-8", null);
|
mAccessibleMessageContentView.loadDataWithBaseURL("http://", emailText, contentType, "utf-8", null);
|
||||||
} else {
|
} else {
|
||||||
@ -321,14 +355,14 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
|
|||||||
|
|
||||||
public void showAttachments(boolean show) {
|
public void showAttachments(boolean show) {
|
||||||
mAttachmentsContainer.setVisibility(show ? View.VISIBLE : View.GONE);
|
mAttachmentsContainer.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||||
boolean showHidden = (show && mHiddenAttachments.getChildCount() > 0);
|
boolean showHidden = (show && mHiddenAttachments.getVisibility() == View.GONE &&
|
||||||
|
mHiddenAttachments.getChildCount() > 0);
|
||||||
mShowHiddenAttachments.setVisibility(showHidden ? View.VISIBLE : View.GONE);
|
mShowHiddenAttachments.setVisibility(showHidden ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
if (show) {
|
if (show) {
|
||||||
moveHeaderToLayout();
|
moveHeaderToLayout();
|
||||||
} else {
|
} else {
|
||||||
moveHeaderToWebViewTitleBar();
|
moveHeaderToWebViewTitleBar();
|
||||||
mHiddenAttachments.setVisibility(View.GONE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,10 +429,22 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void resetView() {
|
public void resetView() {
|
||||||
mMessageContentView.scrollTo(0, 0);
|
mDownloadRemainder.setVisibility(View.GONE);
|
||||||
mMessageContentView.clearView();
|
setLoadPictures(false);
|
||||||
|
showShowAttachmentsAction(false);
|
||||||
|
showShowMessageAction(false);
|
||||||
|
showShowPicturesAction(false);
|
||||||
mAttachments.removeAllViews();
|
mAttachments.removeAllViews();
|
||||||
mHiddenAttachments.removeAllViews();
|
mHiddenAttachments.removeAllViews();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear the WebView content
|
||||||
|
*
|
||||||
|
* For some reason WebView.clearView() doesn't clear the contents when the WebView changes
|
||||||
|
* its size because the button to download the complete message was previously shown and
|
||||||
|
* is now hidden.
|
||||||
|
*/
|
||||||
|
loadBodyFromText("", "text/plain");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetHeaderView() {
|
public void resetHeaderView() {
|
||||||
@ -427,4 +473,72 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
|
|||||||
mTitleBarHeaderContainer.addView(mHeaderContainer);
|
mTitleBarHeaderContainer.addView(mHeaderContainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Parcelable onSaveInstanceState() {
|
||||||
|
Parcelable superState = super.onSaveInstanceState();
|
||||||
|
|
||||||
|
SavedState savedState = new SavedState(superState);
|
||||||
|
|
||||||
|
savedState.attachmentViewVisible = (mAttachmentsContainer != null &&
|
||||||
|
mAttachmentsContainer.getVisibility() == View.VISIBLE);
|
||||||
|
savedState.hiddenAttachmentsVisible = (mHiddenAttachments != null &&
|
||||||
|
mHiddenAttachments.getVisibility() == View.VISIBLE);
|
||||||
|
savedState.showPictures = mShowPictures;
|
||||||
|
|
||||||
|
return savedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRestoreInstanceState(Parcelable state) {
|
||||||
|
if(!(state instanceof SavedState)) {
|
||||||
|
super.onRestoreInstanceState(state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SavedState savedState = (SavedState)state;
|
||||||
|
super.onRestoreInstanceState(savedState.getSuperState());
|
||||||
|
|
||||||
|
mSavedState = savedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class SavedState extends BaseSavedState {
|
||||||
|
boolean attachmentViewVisible;
|
||||||
|
boolean hiddenAttachmentsVisible;
|
||||||
|
boolean showPictures;
|
||||||
|
|
||||||
|
@SuppressWarnings("hiding")
|
||||||
|
public static final Parcelable.Creator<SavedState> CREATOR =
|
||||||
|
new Parcelable.Creator<SavedState>() {
|
||||||
|
@Override
|
||||||
|
public SavedState createFromParcel(Parcel in) {
|
||||||
|
return new SavedState(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SavedState[] newArray(int size) {
|
||||||
|
return new SavedState[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SavedState(Parcelable superState) {
|
||||||
|
super(superState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SavedState(Parcel in) {
|
||||||
|
super(in);
|
||||||
|
this.attachmentViewVisible = (in.readInt() != 0);
|
||||||
|
this.hiddenAttachmentsVisible = (in.readInt() != 0);
|
||||||
|
this.showPictures = (in.readInt() != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
|
super.writeToParcel(out, flags);
|
||||||
|
out.writeInt((this.attachmentViewVisible) ? 1 : 0);
|
||||||
|
out.writeInt((this.hiddenAttachmentsVisible) ? 1 : 0);
|
||||||
|
out.writeInt((this.showPictures) ? 1 : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user