Save/restore instance state for SingleMessageView

This commit is contained in:
cketti 2012-02-24 03:43:42 +01:00
parent 2c09d75afa
commit 4e12dc154e
2 changed files with 157 additions and 69 deletions

View File

@ -7,7 +7,6 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Config;
import android.util.Log;
import android.view.*;
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.FileBrowserFailOverCallback;
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.view.AttachmentView;
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_NEXT = "com.fsck.k9.MessageView_next";
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 int ACTIVITY_CHOOSE_FOLDER_MOVE = 1;
private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
@ -417,10 +415,10 @@ public class MessageView extends K9Activity implements OnClickListener {
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(EXTRA_MESSAGE_REFERENCE, mMessageReference);
outState.putParcelableArrayList(EXTRA_MESSAGE_REFERENCES, mMessageReferences);
outState.putSerializable(STATE_PGP_DATA, mPgpData);
outState.putBoolean(SHOW_PICTURES, mMessageView.showPictures());
}
@Override
@ -428,7 +426,6 @@ public class MessageView extends K9Activity implements OnClickListener {
super.onRestoreInstanceState(savedInstanceState);
mPgpData = (PgpData) savedInstanceState.getSerializable(STATE_PGP_DATA);
mMessageView.updateCryptoLayout(mAccount.getCryptoProvider(), mPgpData, mMessage);
mMessageView.setLoadPictures(savedInstanceState.getBoolean(SHOW_PICTURES));
}
private void displayMessage(MessageReference ref) {
@ -439,7 +436,11 @@ public class MessageView extends K9Activity implements OnClickListener {
findSurroundingMessagesUid();
// start with fresh, empty PGP data
mPgpData = new PgpData();
mMessageView.showMessageWebView(true);
// Clear previous message
mMessageView.resetView();
mMessageView.resetHeaderView();
mController.loadMessageForView(mAccount, mMessageReference.folderName, mMessageReference.uid, mListener);
setupDisplayMessageButtons();
}
@ -949,46 +950,6 @@ public class MessageView extends K9Activity implements OnClickListener {
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 {
@Override
public void loadMessageForViewHeadersAvailable(final Account account, String folder, String uid,
@ -1030,17 +991,28 @@ public class MessageView extends K9Activity implements OnClickListener {
}
@Override
public void loadMessageForViewBodyAvailable(Account account, String folder, String uid,
Message message) {
if (!mMessageReference.uid.equals(uid) || !mMessageReference.folderName.equals(folder)
|| !mMessageReference.accountUuid.equals(account.getUuid())) {
public void loadMessageForViewBodyAvailable(final Account account, String folder,
String uid, final Message message) {
if (!mMessageReference.uid.equals(uid) ||
!mMessageReference.folderName.equals(folder) ||
!mMessageReference.accountUuid.equals(account.getUuid())) {
return;
}
displayMessageBody(account, folder, uid, message);
}//loadMessageForViewBodyAvailable
runOnUiThread(new Runnable() {
@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
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
public void onDecryptDone(PgpData pgpData) {
Account account = mAccount;
Message message = mMessage;
LocalMessage message = (LocalMessage) mMessage;
MessagingController controller = mController;
Listener listener = mListener;
try {
mMessageView.displayMessageBody(account, message, pgpData);
mMessageView.setMessage(account, message, pgpData, controller, listener);
} catch (MessagingException e) {
Log.e(K9.LOG_TAG, "displayMessageBody failed", e);
}

View File

@ -7,6 +7,8 @@ import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
@ -27,6 +29,7 @@ import com.fsck.k9.helper.Contacts;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.*;
import com.fsck.k9.mail.store.LocalStore;
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
import java.util.List;
@ -51,6 +54,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
private LinearLayout mHeaderPlaceHolder;
private LinearLayout mTitleBarHeaderContainer;
private View mAttachmentsContainer;
private SavedState mSavedState;
public void initialize(Activity activity) {
mMessageContentView = (MessageWebView) findViewById(R.id.message_content);
@ -258,8 +262,8 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
return mHeaderContainer.additionalHeadersVisible();
}
public void displayMessageBody(Account account, Message message, PgpData pgpData)
throws MessagingException {
public void setMessage(Account account, LocalMessage message, PgpData pgpData,
MessagingController controller, MessagingListener listener) throws MessagingException {
resetView();
String type;
@ -268,14 +272,49 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
type = "text/plain";
} else {
// getTextForDisplay() always returns HTML-ified content.
text = ((LocalStore.LocalMessage) message).getTextForDisplay();
text = message.getTextForDisplay();
type = "text/html";
}
if (text != null) {
final String emailText = text;
final String contentType = type;
loadBodyFromText(message, emailText, contentType);
loadBodyFromText(emailText, contentType);
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"
// button wasn't already pressed, see if the user's preferences has us
// showing them anyway.
@ -291,12 +330,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
showShowPicturesAction(true);
}
}
mHasAttachments = ((LocalStore.LocalMessage) message).hasAttachments();
} else {
loadBodyFromUrl("file:///android_asset/empty.html");
}
onShowMessage();
}
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) {
mAccessibleMessageContentView.loadDataWithBaseURL("http://", emailText, contentType, "utf-8", null);
} else {
@ -321,14 +355,14 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
public void showAttachments(boolean show) {
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);
if (show) {
moveHeaderToLayout();
} else {
moveHeaderToWebViewTitleBar();
mHiddenAttachments.setVisibility(View.GONE);
}
}
@ -395,10 +429,22 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
}
public void resetView() {
mMessageContentView.scrollTo(0, 0);
mMessageContentView.clearView();
mDownloadRemainder.setVisibility(View.GONE);
setLoadPictures(false);
showShowAttachmentsAction(false);
showShowMessageAction(false);
showShowPicturesAction(false);
mAttachments.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() {
@ -427,4 +473,72 @@ public class SingleMessageView extends LinearLayout implements OnClickListener {
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);
}
}
}