2009-12-14 21:50:53 -05:00
|
|
|
package com.fsck.k9.activity;
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2012-07-12 12:29:41 -04:00
|
|
|
import java.io.File;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.List;
|
|
|
|
|
2010-09-01 16:59:09 -04:00
|
|
|
import android.app.Dialog;
|
2011-02-20 12:49:55 -05:00
|
|
|
import android.app.ProgressDialog;
|
2008-11-01 17:32:06 -04:00
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.net.Uri;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.util.Log;
|
2012-07-12 12:29:41 -04:00
|
|
|
import android.view.GestureDetector;
|
|
|
|
import android.view.KeyEvent;
|
|
|
|
import android.view.MotionEvent;
|
|
|
|
import android.view.View;
|
2008-11-01 17:32:06 -04:00
|
|
|
import android.view.View.OnClickListener;
|
2012-07-12 12:29:41 -04:00
|
|
|
import android.widget.Toast;
|
|
|
|
|
2012-09-07 23:33:53 -04:00
|
|
|
import com.actionbarsherlock.app.ActionBar;
|
2012-07-12 12:29:41 -04:00
|
|
|
import com.actionbarsherlock.view.Menu;
|
|
|
|
import com.actionbarsherlock.view.MenuItem;
|
|
|
|
import com.actionbarsherlock.view.Window;
|
|
|
|
import com.fsck.k9.Account;
|
|
|
|
import com.fsck.k9.K9;
|
|
|
|
import com.fsck.k9.Preferences;
|
|
|
|
import com.fsck.k9.R;
|
2010-05-19 14:17:06 -04:00
|
|
|
import com.fsck.k9.controller.MessagingController;
|
|
|
|
import com.fsck.k9.controller.MessagingListener;
|
2010-08-22 05:51:17 -04:00
|
|
|
import com.fsck.k9.crypto.PgpData;
|
2011-04-24 00:00:10 -04:00
|
|
|
import com.fsck.k9.helper.FileBrowserHelper;
|
|
|
|
import com.fsck.k9.helper.FileBrowserHelper.FileBrowserFailOverCallback;
|
2012-07-12 12:29:41 -04:00
|
|
|
import com.fsck.k9.mail.Flag;
|
|
|
|
import com.fsck.k9.mail.Message;
|
|
|
|
import com.fsck.k9.mail.MessagingException;
|
|
|
|
import com.fsck.k9.mail.Part;
|
2012-02-23 21:43:42 -05:00
|
|
|
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
|
2011-01-06 11:56:20 -05:00
|
|
|
import com.fsck.k9.mail.store.StorageManager;
|
|
|
|
import com.fsck.k9.view.AttachmentView;
|
2011-04-24 00:00:10 -04:00
|
|
|
import com.fsck.k9.view.AttachmentView.AttachmentFileDownloadCallback;
|
2012-09-07 23:33:53 -04:00
|
|
|
import com.fsck.k9.view.MessageTitleView;
|
2012-07-12 12:29:41 -04:00
|
|
|
import com.fsck.k9.view.SingleMessageView;
|
2010-12-28 04:07:59 -05:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
public class MessageView extends K9Activity implements OnClickListener {
|
2010-04-24 10:59:27 -04:00
|
|
|
private static final String EXTRA_MESSAGE_REFERENCE = "com.fsck.k9.MessageView_messageReference";
|
|
|
|
private static final String EXTRA_MESSAGE_REFERENCES = "com.fsck.k9.MessageView_messageReferences";
|
2011-12-05 12:16:43 -05:00
|
|
|
private static final String EXTRA_MESSAGE_LIST_EXTRAS = "com.fsck.k9.MessageView_messageListExtras";
|
2010-08-22 05:51:17 -04:00
|
|
|
private static final String STATE_PGP_DATA = "pgpData";
|
2009-03-05 02:32:45 -05:00
|
|
|
private static final int ACTIVITY_CHOOSE_FOLDER_MOVE = 1;
|
|
|
|
private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
|
2011-04-24 00:00:10 -04:00
|
|
|
private static final int ACTIVITY_CHOOSE_DIRECTORY = 3;
|
2011-02-11 10:09:15 -05:00
|
|
|
|
|
|
|
private SingleMessageView mMessageView;
|
2012-09-07 23:33:53 -04:00
|
|
|
private MessageTitleView mTitleView;
|
2011-02-11 10:09:15 -05:00
|
|
|
|
|
|
|
private PgpData mPgpData;
|
2012-08-22 09:43:18 -04:00
|
|
|
private Menu mMenu;
|
2008-11-01 17:32:06 -04:00
|
|
|
private Account mAccount;
|
2010-04-24 10:59:27 -04:00
|
|
|
private MessageReference mMessageReference;
|
|
|
|
private ArrayList<MessageReference> mMessageReferences;
|
2008-11-01 17:32:06 -04:00
|
|
|
private Message mMessage;
|
2009-11-29 23:03:00 -05:00
|
|
|
private static final int PREVIOUS = 1;
|
2009-11-29 23:14:24 -05:00
|
|
|
private static final int NEXT = 2;
|
2011-10-11 05:01:06 -04:00
|
|
|
private int mLastDirection = (K9.messageViewShowNext()) ? NEXT : PREVIOUS;
|
2011-01-06 11:56:02 -05:00
|
|
|
private MessagingController mController = MessagingController.getInstance(getApplication());
|
2010-04-24 10:59:27 -04:00
|
|
|
private MessageReference mNextMessage = null;
|
|
|
|
private MessageReference mPreviousMessage = null;
|
2008-11-01 17:32:06 -04:00
|
|
|
private Listener mListener = new Listener();
|
|
|
|
private MessageViewHandler mHandler = new MessageViewHandler();
|
2010-11-13 16:40:56 -05:00
|
|
|
private StorageManager.StorageListener mStorageListener = new StorageListenerImplementation();
|
|
|
|
|
2011-04-24 00:00:10 -04:00
|
|
|
/** this variable is used to save the calling AttachmentView
|
|
|
|
* until the onActivityResult is called.
|
|
|
|
* => with this reference we can identity the caller
|
|
|
|
*/
|
|
|
|
private AttachmentView attachmentTmpStore;
|
|
|
|
|
2011-03-31 22:21:27 -04:00
|
|
|
/**
|
|
|
|
* Used to temporarily store the destination folder for refile operations if a confirmation
|
|
|
|
* dialog is shown.
|
|
|
|
*/
|
|
|
|
private String mDstFolder;
|
|
|
|
|
2011-12-05 12:16:43 -05:00
|
|
|
/**
|
|
|
|
* The extras used to create the {@link MessageList} instance that created this activity. May
|
|
|
|
* be {@code null}.
|
|
|
|
*
|
|
|
|
* @see MessageList#actionHandleFolder(Context, Bundle)
|
|
|
|
*/
|
|
|
|
private Bundle mMessageListExtras;
|
|
|
|
|
2012-05-04 10:32:39 -04:00
|
|
|
/**
|
|
|
|
* Screen width in pixels.
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* Used to detect right-to-left bezel swipes.
|
|
|
|
* </p>
|
|
|
|
*
|
|
|
|
* @see #onSwipeRightToLeft(MotionEvent, MotionEvent)
|
|
|
|
*/
|
|
|
|
private int mScreenWidthInPixels;
|
|
|
|
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private final class StorageListenerImplementation implements StorageManager.StorageListener {
|
2010-11-13 16:40:56 -05:00
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
public void onUnmount(String providerId) {
|
|
|
|
if (!providerId.equals(mAccount.getLocalStorageProviderId())) {
|
2011-01-06 11:55:34 -05:00
|
|
|
return;
|
2010-11-13 16:40:56 -05:00
|
|
|
}
|
2011-02-06 17:09:48 -05:00
|
|
|
runOnUiThread(new Runnable() {
|
2011-01-06 11:55:34 -05:00
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
public void run() {
|
2011-01-06 11:55:34 -05:00
|
|
|
onAccountUnavailable();
|
|
|
|
}
|
|
|
|
});
|
2010-11-13 16:40:56 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2011-08-30 20:17:45 -04:00
|
|
|
public void onMount(String providerId) { /* no-op */ }
|
2010-11-13 16:40:56 -05:00
|
|
|
}
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
public boolean dispatchKeyEvent(KeyEvent event) {
|
2009-11-21 17:45:14 -05:00
|
|
|
boolean ret = false;
|
2011-02-06 17:09:48 -05:00
|
|
|
if (KeyEvent.ACTION_DOWN == event.getAction()) {
|
2011-11-20 15:29:18 -05:00
|
|
|
ret = onCustomKeyDown(event.getKeyCode(), event);
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
2011-02-06 17:09:48 -05:00
|
|
|
if (!ret) {
|
2009-11-21 17:45:14 -05:00
|
|
|
ret = super.dispatchKeyEvent(event);
|
|
|
|
}
|
|
|
|
return ret;
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
|
2011-11-20 15:29:18 -05:00
|
|
|
/**
|
|
|
|
* Handle hotkeys
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* This method is called by {@link #dispatchKeyEvent(KeyEvent)} before any view had the chance
|
|
|
|
* to consume this key event.
|
|
|
|
* </p>
|
|
|
|
*
|
|
|
|
* @param keyCode
|
|
|
|
* The value in {@code event.getKeyCode()}.
|
|
|
|
* @param event
|
|
|
|
* Description of the key event.
|
|
|
|
*
|
|
|
|
* @return {@code true} if this event was consumed.
|
|
|
|
*/
|
|
|
|
public boolean onCustomKeyDown(final int keyCode, final KeyEvent event) {
|
2011-02-06 17:09:48 -05:00
|
|
|
switch (keyCode) {
|
|
|
|
case KeyEvent.KEYCODE_VOLUME_UP: {
|
|
|
|
if (K9.useVolumeKeysForNavigationEnabled()) {
|
|
|
|
onNext();
|
2009-11-24 19:40:29 -05:00
|
|
|
return true;
|
|
|
|
}
|
2011-11-20 15:29:18 -05:00
|
|
|
break;
|
2011-02-06 17:09:48 -05:00
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_VOLUME_DOWN: {
|
|
|
|
if (K9.useVolumeKeysForNavigationEnabled()) {
|
2010-12-12 19:37:31 -05:00
|
|
|
onPrevious();
|
2009-11-24 19:40:29 -05:00
|
|
|
return true;
|
|
|
|
}
|
2011-11-20 15:29:18 -05:00
|
|
|
break;
|
2011-02-06 17:09:48 -05:00
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_DEL: {
|
|
|
|
onDelete();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_D: {
|
|
|
|
onDelete();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_F: {
|
|
|
|
onForward();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_A: {
|
|
|
|
onReplyAll();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_R: {
|
|
|
|
onReply();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_G: {
|
|
|
|
onFlag();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_M: {
|
|
|
|
onMove();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_S: {
|
|
|
|
onRefile(mAccount.getSpamFolderName());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_V: {
|
|
|
|
onRefile(mAccount.getArchiveFolderName());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_Y: {
|
|
|
|
onCopy();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_J:
|
|
|
|
case KeyEvent.KEYCODE_P: {
|
|
|
|
onPrevious();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_N:
|
|
|
|
case KeyEvent.KEYCODE_K: {
|
|
|
|
onNext();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_Z: {
|
|
|
|
mHandler.post(new Runnable() {
|
|
|
|
public void run() {
|
2011-02-11 10:09:15 -05:00
|
|
|
mMessageView.zoom(event);
|
2011-02-06 17:09:48 -05:00
|
|
|
}
|
|
|
|
});
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case KeyEvent.KEYCODE_H: {
|
|
|
|
Toast toast = Toast.makeText(this, R.string.message_help_key, Toast.LENGTH_LONG);
|
|
|
|
toast.show();
|
|
|
|
return true;
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2011-11-20 15:29:18 -05:00
|
|
|
return false;
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
2008-12-21 12:44:18 -05:00
|
|
|
|
2010-08-29 22:16:20 -04:00
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
2010-08-29 22:16:20 -04:00
|
|
|
// Swallow these events too to avoid the audible notification of a volume change
|
2011-02-06 17:09:48 -05:00
|
|
|
if (K9.useVolumeKeysForNavigationEnabled()) {
|
|
|
|
if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
|
2010-08-29 22:16:20 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "Swallowed key up.");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2010-12-25 22:49:23 -05:00
|
|
|
return super.onKeyUp(keyCode, event);
|
2010-08-29 22:16:20 -04:00
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
class MessageViewHandler extends Handler {
|
2011-01-10 12:47:28 -05:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
public void progress(final boolean progress) {
|
|
|
|
runOnUiThread(new Runnable() {
|
|
|
|
public void run() {
|
2012-08-24 12:39:23 -04:00
|
|
|
setSupportProgressBarIndeterminateVisibility(progress);
|
2010-01-03 21:06:40 -05:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
public void addAttachment(final View attachmentView) {
|
|
|
|
runOnUiThread(new Runnable() {
|
|
|
|
public void run() {
|
2011-02-11 10:09:15 -05:00
|
|
|
mMessageView.addAttachment(attachmentView);
|
2010-01-03 21:06:40 -05:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-02-14 20:26:00 -05:00
|
|
|
/* A helper for a set of "show a toast" methods */
|
|
|
|
private void showToast(final String message, final int toastLength) {
|
2011-02-06 17:09:48 -05:00
|
|
|
runOnUiThread(new Runnable() {
|
|
|
|
public void run() {
|
2011-02-14 20:26:00 -05:00
|
|
|
Toast.makeText(MessageView.this, message, toastLength).show();
|
2010-01-03 21:06:40 -05:00
|
|
|
}
|
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2011-02-14 20:26:00 -05:00
|
|
|
public void networkError() {
|
|
|
|
showToast(getString(R.string.status_network_error), Toast.LENGTH_LONG);
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
public void invalidIdError() {
|
2011-02-14 20:26:00 -05:00
|
|
|
showToast(getString(R.string.status_invalid_id_error), Toast.LENGTH_LONG);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
public void fetchingAttachment() {
|
2011-02-14 20:26:00 -05:00
|
|
|
showToast(getString(R.string.message_view_fetching_attachment_toast), Toast.LENGTH_SHORT);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-30 20:17:45 -04:00
|
|
|
public static void actionView(Context context, MessageReference messRef,
|
2011-12-05 12:16:43 -05:00
|
|
|
ArrayList<MessageReference> messReferences, Bundle messageListExtras) {
|
2008-11-01 17:32:06 -04:00
|
|
|
Intent i = new Intent(context, MessageView.class);
|
2012-09-06 20:39:57 -04:00
|
|
|
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
2011-12-05 12:16:43 -05:00
|
|
|
i.putExtra(EXTRA_MESSAGE_LIST_EXTRAS, messageListExtras);
|
2010-04-24 10:59:27 -04:00
|
|
|
i.putExtra(EXTRA_MESSAGE_REFERENCE, messRef);
|
2011-02-19 13:59:38 -05:00
|
|
|
i.putParcelableArrayListExtra(EXTRA_MESSAGE_REFERENCES, messReferences);
|
2008-11-01 17:32:06 -04:00
|
|
|
context.startActivity(i);
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
public void onCreate(Bundle icicle) {
|
2012-04-02 21:41:44 -04:00
|
|
|
super.onCreate(icicle);
|
2008-11-01 17:32:06 -04:00
|
|
|
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
|
|
|
|
setContentView(R.layout.message_view);
|
2009-11-19 01:03:59 -05:00
|
|
|
|
2011-02-11 10:09:15 -05:00
|
|
|
mMessageView = (SingleMessageView) findViewById(R.id.message_view);
|
|
|
|
|
2011-04-24 00:00:10 -04:00
|
|
|
//set a callback for the attachment view. With this callback the attachmentview
|
|
|
|
//request the start of a filebrowser activity.
|
|
|
|
mMessageView.setAttachmentCallback(new AttachmentFileDownloadCallback() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void showFileBrowser(final AttachmentView caller) {
|
|
|
|
FileBrowserHelper.getInstance()
|
|
|
|
.showFileBrowserActivity(MessageView.this,
|
|
|
|
null,
|
|
|
|
MessageView.ACTIVITY_CHOOSE_DIRECTORY,
|
|
|
|
callback);
|
|
|
|
attachmentTmpStore = caller;
|
|
|
|
}
|
|
|
|
FileBrowserFailOverCallback callback = new FileBrowserFailOverCallback() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onPathEntered(String path) {
|
|
|
|
attachmentTmpStore.writeFile(new File(path));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onCancel() {
|
|
|
|
// canceled, do nothing
|
|
|
|
}
|
|
|
|
};
|
|
|
|
});
|
2011-11-02 19:39:23 -04:00
|
|
|
|
2011-02-14 11:54:01 -05:00
|
|
|
mMessageView.initialize(this);
|
2012-09-09 19:04:47 -04:00
|
|
|
mMessageView.downloadRemainderButton().setOnClickListener(this);
|
2012-09-07 23:33:53 -04:00
|
|
|
initializeActionBar();
|
|
|
|
|
2010-12-25 22:51:33 -05:00
|
|
|
setTitle("");
|
2011-06-08 16:53:23 -04:00
|
|
|
final Intent intent = getIntent();
|
|
|
|
|
2011-12-05 12:16:43 -05:00
|
|
|
mMessageListExtras = intent.getParcelableExtra(EXTRA_MESSAGE_LIST_EXTRAS);
|
|
|
|
|
2010-12-25 22:51:33 -05:00
|
|
|
Uri uri = intent.getData();
|
2011-02-06 17:09:48 -05:00
|
|
|
if (icicle != null) {
|
2011-11-03 12:14:42 -04:00
|
|
|
// TODO This code seems unnecessary since the icicle should already be thawed in onRestoreInstanceState().
|
2011-02-20 00:23:06 -05:00
|
|
|
mMessageReference = icicle.getParcelable(EXTRA_MESSAGE_REFERENCE);
|
|
|
|
mMessageReferences = icicle.getParcelableArrayList(EXTRA_MESSAGE_REFERENCES);
|
2011-02-11 10:09:15 -05:00
|
|
|
mPgpData = (PgpData) icicle.getSerializable(STATE_PGP_DATA);
|
2011-02-06 17:09:48 -05:00
|
|
|
} else {
|
|
|
|
if (uri == null) {
|
2011-02-20 00:23:06 -05:00
|
|
|
mMessageReference = intent.getParcelableExtra(EXTRA_MESSAGE_REFERENCE);
|
|
|
|
mMessageReferences = intent.getParcelableArrayListExtra(EXTRA_MESSAGE_REFERENCES);
|
2011-02-06 17:09:48 -05:00
|
|
|
} else {
|
2010-12-25 22:51:33 -05:00
|
|
|
List<String> segmentList = uri.getPathSegments();
|
2011-02-06 17:09:48 -05:00
|
|
|
if (segmentList.size() != 3) {
|
2011-08-30 20:17:45 -04:00
|
|
|
//TODO: Use resource to externalize message
|
2010-12-25 22:51:33 -05:00
|
|
|
Toast.makeText(this, "Invalid intent uri: " + uri.toString(), Toast.LENGTH_LONG).show();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
String accountId = segmentList.get(0);
|
|
|
|
Collection<Account> accounts = Preferences.getPreferences(this).getAvailableAccounts();
|
|
|
|
boolean found = false;
|
2011-02-06 17:09:48 -05:00
|
|
|
for (Account account : accounts) {
|
|
|
|
if (String.valueOf(account.getAccountNumber()).equals(accountId)) {
|
2010-12-25 22:51:33 -05:00
|
|
|
mAccount = account;
|
|
|
|
found = true;
|
|
|
|
break;
|
2010-07-27 08:10:09 -04:00
|
|
|
}
|
|
|
|
}
|
2011-02-06 17:09:48 -05:00
|
|
|
if (!found) {
|
2011-08-30 20:17:45 -04:00
|
|
|
//TODO: Use resource to externalize message
|
2010-12-25 22:51:33 -05:00
|
|
|
Toast.makeText(this, "Invalid account id: " + accountId, Toast.LENGTH_LONG).show();
|
|
|
|
return;
|
2010-07-27 08:10:09 -04:00
|
|
|
}
|
2010-12-25 22:51:33 -05:00
|
|
|
|
|
|
|
mMessageReference = new MessageReference();
|
|
|
|
mMessageReference.accountUuid = mAccount.getUuid();
|
|
|
|
mMessageReference.folderName = segmentList.get(1);
|
|
|
|
mMessageReference.uid = segmentList.get(2);
|
|
|
|
mMessageReferences = new ArrayList<MessageReference>();
|
2010-07-27 08:10:09 -04:00
|
|
|
}
|
2010-12-25 22:51:33 -05:00
|
|
|
}
|
2010-07-27 08:10:09 -04:00
|
|
|
|
2010-12-25 22:51:33 -05:00
|
|
|
mAccount = Preferences.getPreferences(this).getAccount(mMessageReference.accountUuid);
|
2012-05-04 10:32:39 -04:00
|
|
|
mScreenWidthInPixels = getResources().getDisplayMetrics().widthPixels;
|
|
|
|
|
Fix gesture detection
This commit addresses 2 issues:
1) Before, a general GestureDetector was registered on the highest level in K9Activity
This resulted in EVERY inherited activity to have a useless, unused gesture detector.
But more than that, in MessageList, a second GestureDetector was assigned to the ListView.
On every fling gesture, both detectors called the onSwipe() methods,
which technically did the following:
- The one directly assigned to the ListView would work corectly by mapping the
(local) event coordinates to the right entry in the ListView
- The global one worked on screen coordinates, so the onSwipe() method would
likely select the wrong ListView entry (system menu bar offset).
- For some reason this "worked" fine, and only the correct entry was selected,
despite two detectors used.
2) The gesture detection for the MessageView caused problems when the message
itself was scrollable, i.e. wide HTML mails. A fling gesture inside the WebView
would scroll the message, but also switch the message.
This commit fixes all those by doing the following:
- Don't register the GestureDetector in K9Activity, instead make the member variable
accessible by subclasses.
- In the subclasses that need a detector register it
- In K9Activity.dispatchTouchEvent() check for mGestureDetector being null
- For MessageList:
* Remove the duplicate gesture detector assigned to the ListView
* in the handleSwipe() methods: calclulate pixel offset of the ListView to make
it work using the global screen coordinates
- For MessageView: Limit sensitive area to the message header, to prevent interference
with the WebView scrolling
- Respect current behavior:
* Force-enable gestures for the MessageList
* Respect user setting in MessageView
- Make sure that after a successful swipe gesture, any pending action is cancelled, to
prevent unwanted things to happen (such as expanding the header after changing
the message, or a context menu popping up in the MessageList).
See http://code.google.com/p/android/issues/detail?id=8497
2012-04-30 19:56:06 -04:00
|
|
|
// Enable gesture detection for MessageViews
|
|
|
|
mGestureDetector = new GestureDetector(new MyGestureDetector(false));
|
|
|
|
|
2010-12-25 22:51:33 -05:00
|
|
|
displayMessage(mMessageReference);
|
|
|
|
}
|
|
|
|
|
2009-10-22 11:54:49 -04:00
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
protected void onSaveInstanceState(Bundle outState) {
|
2012-02-23 21:43:42 -05:00
|
|
|
super.onSaveInstanceState(outState);
|
2011-02-19 13:59:38 -05:00
|
|
|
outState.putParcelable(EXTRA_MESSAGE_REFERENCE, mMessageReference);
|
|
|
|
outState.putParcelableArrayList(EXTRA_MESSAGE_REFERENCES, mMessageReferences);
|
2011-02-11 10:09:15 -05:00
|
|
|
outState.putSerializable(STATE_PGP_DATA, mPgpData);
|
2010-07-27 08:10:09 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
2010-07-27 08:10:09 -04:00
|
|
|
super.onRestoreInstanceState(savedInstanceState);
|
2011-02-11 10:09:15 -05:00
|
|
|
mPgpData = (PgpData) savedInstanceState.getSerializable(STATE_PGP_DATA);
|
|
|
|
mMessageView.updateCryptoLayout(mAccount.getCryptoProvider(), mPgpData, mMessage);
|
2009-10-22 11:54:49 -04:00
|
|
|
}
|
|
|
|
|
2012-09-07 23:33:53 -04:00
|
|
|
private void initializeActionBar() {
|
|
|
|
final ActionBar actionBar = getSupportActionBar();
|
|
|
|
|
|
|
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
|
|
|
actionBar.setDisplayShowCustomEnabled(true);
|
|
|
|
actionBar.setCustomView(R.layout.actionbar_message_view);
|
|
|
|
|
|
|
|
final View customView = actionBar.getCustomView();
|
|
|
|
mTitleView = (MessageTitleView) customView.findViewById(android.R.id.title);
|
|
|
|
mTitleView.setMessageHeader(mMessageView.getMessageHeaderView());
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void displayMessage(MessageReference ref) {
|
2010-04-24 10:59:27 -04:00
|
|
|
mMessageReference = ref;
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "MessageView displaying message " + mMessageReference);
|
2010-08-08 23:16:40 -04:00
|
|
|
mAccount = Preferences.getPreferences(this).getAccount(mMessageReference.accountUuid);
|
2009-05-03 00:36:33 -04:00
|
|
|
findSurroundingMessagesUid();
|
2010-08-22 05:51:17 -04:00
|
|
|
// start with fresh, empty PGP data
|
2011-02-11 10:09:15 -05:00
|
|
|
mPgpData = new PgpData();
|
2012-02-23 21:43:42 -05:00
|
|
|
|
|
|
|
// Clear previous message
|
|
|
|
mMessageView.resetView();
|
|
|
|
mMessageView.resetHeaderView();
|
|
|
|
|
2011-02-11 10:09:15 -05:00
|
|
|
mController.loadMessageForView(mAccount, mMessageReference.folderName, mMessageReference.uid, mListener);
|
2012-08-22 09:43:18 -04:00
|
|
|
configureMenu(mMenu);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void findSurroundingMessagesUid() {
|
2010-04-24 10:59:27 -04:00
|
|
|
mNextMessage = mPreviousMessage = null;
|
|
|
|
int i = mMessageReferences.indexOf(mMessageReference);
|
2009-11-21 17:45:14 -05:00
|
|
|
if (i < 0)
|
2009-05-03 00:36:33 -04:00
|
|
|
return;
|
2009-11-21 17:45:14 -05:00
|
|
|
if (i != 0)
|
2010-04-24 10:59:27 -04:00
|
|
|
mNextMessage = mMessageReferences.get(i - 1);
|
|
|
|
if (i != (mMessageReferences.size() - 1))
|
|
|
|
mPreviousMessage = mMessageReferences.get(i + 1);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
public void onResume() {
|
2008-11-01 17:32:06 -04:00
|
|
|
super.onResume();
|
2011-02-06 17:09:48 -05:00
|
|
|
if (!mAccount.isAvailable(this)) {
|
2010-11-13 16:40:56 -05:00
|
|
|
onAccountUnavailable();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
StorageManager.getInstance(getApplication()).addListener(mStorageListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
protected void onPause() {
|
2010-11-13 16:40:56 -05:00
|
|
|
StorageManager.getInstance(getApplication()).removeListener(mStorageListener);
|
|
|
|
super.onPause();
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
protected void onAccountUnavailable() {
|
2010-11-13 16:40:56 -05:00
|
|
|
finish();
|
|
|
|
// TODO inform user about account unavailability using Toast
|
|
|
|
Accounts.listAccounts(this);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-10-22 11:54:49 -04:00
|
|
|
|
2010-09-01 16:59:09 -04:00
|
|
|
/**
|
|
|
|
* Called from UI thread when user select Delete
|
|
|
|
*/
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onDelete() {
|
2011-11-15 01:28:41 -05:00
|
|
|
if (K9.confirmDelete() || (K9.confirmDeleteStarred() && mMessage.isSet(Flag.FLAGGED))) {
|
2010-09-01 16:59:09 -04:00
|
|
|
showDialog(R.id.dialog_confirm_delete);
|
2011-02-06 17:09:48 -05:00
|
|
|
} else {
|
2010-09-01 16:59:09 -04:00
|
|
|
delete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void delete() {
|
|
|
|
if (mMessage != null) {
|
2010-07-11 15:40:48 -04:00
|
|
|
// Disable the delete button after it's tapped (to try to prevent
|
|
|
|
// accidental clicks)
|
2012-08-22 09:43:18 -04:00
|
|
|
mMenu.findItem(R.id.delete).setEnabled(false);
|
2009-11-21 17:45:14 -05:00
|
|
|
Message messageToDelete = mMessage;
|
2010-08-18 23:14:27 -04:00
|
|
|
showNextMessageOrReturn();
|
2011-02-14 20:45:08 -05:00
|
|
|
mController.deleteMessages(new Message[] {messageToDelete}, null);
|
2010-06-14 09:46:08 -04:00
|
|
|
}
|
|
|
|
}
|
2009-11-29 23:03:00 -05:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onRefile(String dstFolder) {
|
|
|
|
if (!mController.isMoveCapable(mAccount)) {
|
2010-07-05 09:41:52 -04:00
|
|
|
return;
|
|
|
|
}
|
2011-02-06 17:09:48 -05:00
|
|
|
if (!mController.isMoveCapable(mMessage)) {
|
2010-07-05 09:41:52 -04:00
|
|
|
Toast toast = Toast.makeText(this, R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
|
|
|
|
toast.show();
|
|
|
|
return;
|
|
|
|
}
|
2011-03-31 22:21:27 -04:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
if (K9.FOLDER_NONE.equalsIgnoreCase(dstFolder)) {
|
2010-07-05 09:41:52 -04:00
|
|
|
return;
|
|
|
|
}
|
2011-03-31 22:21:27 -04:00
|
|
|
|
|
|
|
if (mAccount.getSpamFolderName().equals(dstFolder) && K9.confirmSpam()) {
|
|
|
|
mDstFolder = dstFolder;
|
|
|
|
showDialog(R.id.dialog_confirm_spam);
|
|
|
|
} else {
|
|
|
|
refileMessage(dstFolder);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void refileMessage(String dstFolder) {
|
|
|
|
String srcFolder = mMessageReference.folderName;
|
|
|
|
Message messageToMove = mMessage;
|
2010-08-18 23:14:27 -04:00
|
|
|
showNextMessageOrReturn();
|
2011-02-14 20:45:08 -05:00
|
|
|
mController.moveMessage(mAccount, srcFolder, messageToMove, dstFolder, null);
|
2010-07-05 09:41:52 -04:00
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void showNextMessageOrReturn() {
|
|
|
|
if (K9.messageViewReturnToList()) {
|
2010-08-18 23:14:27 -04:00
|
|
|
finish();
|
2011-02-06 17:09:48 -05:00
|
|
|
} else {
|
2010-08-18 23:14:27 -04:00
|
|
|
showNextMessage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void showNextMessage() {
|
2010-06-14 09:46:08 -04:00
|
|
|
findSurroundingMessagesUid();
|
|
|
|
mMessageReferences.remove(mMessageReference);
|
2011-02-06 17:09:48 -05:00
|
|
|
if (mLastDirection == NEXT && mNextMessage != null) {
|
2010-12-12 19:37:31 -05:00
|
|
|
onNext();
|
2011-02-06 17:09:48 -05:00
|
|
|
} else if (mLastDirection == PREVIOUS && mPreviousMessage != null) {
|
2010-12-12 19:37:31 -05:00
|
|
|
onPrevious();
|
2011-02-06 17:09:48 -05:00
|
|
|
} else if (mNextMessage != null) {
|
2010-12-12 19:37:31 -05:00
|
|
|
onNext();
|
2011-02-06 17:09:48 -05:00
|
|
|
} else if (mPreviousMessage != null) {
|
2010-12-12 19:37:31 -05:00
|
|
|
onPrevious();
|
2011-02-06 17:09:48 -05:00
|
|
|
} else {
|
2010-06-14 09:46:08 -04:00
|
|
|
finish();
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
2010-07-05 09:41:52 -04:00
|
|
|
|
2009-06-06 11:55:26 -04:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onReply() {
|
|
|
|
if (mMessage != null) {
|
2011-02-11 10:09:15 -05:00
|
|
|
MessageCompose.actionReply(this, mAccount, mMessage, false, mPgpData.getDecryptedData());
|
2008-11-01 17:32:06 -04:00
|
|
|
finish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onReplyAll() {
|
|
|
|
if (mMessage != null) {
|
2011-02-11 10:09:15 -05:00
|
|
|
MessageCompose.actionReply(this, mAccount, mMessage, true, mPgpData.getDecryptedData());
|
2008-11-01 17:32:06 -04:00
|
|
|
finish();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onForward() {
|
|
|
|
if (mMessage != null) {
|
2011-02-11 10:09:15 -05:00
|
|
|
MessageCompose.actionForward(this, mAccount, mMessage, mPgpData.getDecryptedData());
|
2008-11-01 17:32:06 -04:00
|
|
|
finish();
|
|
|
|
}
|
|
|
|
}
|
2009-11-21 17:45:14 -05:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onFlag() {
|
|
|
|
if (mMessage != null) {
|
2012-01-27 02:39:10 -05:00
|
|
|
boolean newState = !mMessage.isSet(Flag.FLAGGED);
|
|
|
|
mController.setFlag(mAccount, mMessage.getFolder().getName(),
|
2012-02-04 08:52:45 -05:00
|
|
|
new Message[] { mMessage }, Flag.FLAGGED, newState);
|
|
|
|
mMessageView.setHeaders(mMessage, mAccount);
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2009-11-21 17:45:14 -05:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onMove() {
|
2011-01-06 11:56:02 -05:00
|
|
|
if ((!mController.isMoveCapable(mAccount))
|
2011-02-06 17:09:48 -05:00
|
|
|
|| (mMessage == null)) {
|
2009-11-21 17:45:14 -05:00
|
|
|
return;
|
|
|
|
}
|
2011-02-06 17:09:48 -05:00
|
|
|
if (!mController.isMoveCapable(mMessage)) {
|
2009-11-21 17:45:14 -05:00
|
|
|
Toast toast = Toast.makeText(this, R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
|
|
|
|
toast.show();
|
|
|
|
return;
|
|
|
|
}
|
2010-12-25 22:49:13 -05:00
|
|
|
|
|
|
|
startRefileActivity(ACTIVITY_CHOOSE_FOLDER_MOVE);
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onCopy() {
|
2011-01-06 11:56:02 -05:00
|
|
|
if ((!mController.isCopyCapable(mAccount))
|
2011-02-06 17:09:48 -05:00
|
|
|
|| (mMessage == null)) {
|
2009-11-21 17:45:14 -05:00
|
|
|
return;
|
|
|
|
}
|
2011-02-06 17:09:48 -05:00
|
|
|
if (!mController.isCopyCapable(mMessage)) {
|
2009-11-21 17:45:14 -05:00
|
|
|
Toast toast = Toast.makeText(this, R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
|
|
|
|
toast.show();
|
|
|
|
return;
|
|
|
|
}
|
2010-12-25 22:49:13 -05:00
|
|
|
|
|
|
|
startRefileActivity(ACTIVITY_CHOOSE_FOLDER_COPY);
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void startRefileActivity(int activity) {
|
2009-03-05 02:32:45 -05:00
|
|
|
Intent intent = new Intent(this, ChooseFolder.class);
|
2010-03-03 23:00:30 -05:00
|
|
|
intent.putExtra(ChooseFolder.EXTRA_ACCOUNT, mAccount.getUuid());
|
2010-04-24 10:59:27 -04:00
|
|
|
intent.putExtra(ChooseFolder.EXTRA_CUR_FOLDER, mMessageReference.folderName);
|
2010-07-04 19:29:57 -04:00
|
|
|
intent.putExtra(ChooseFolder.EXTRA_SEL_FOLDER, mAccount.getLastSelectedFolderName());
|
2010-05-01 16:06:52 -04:00
|
|
|
intent.putExtra(ChooseFolder.EXTRA_MESSAGE, mMessageReference);
|
2010-12-25 22:49:13 -05:00
|
|
|
startActivityForResult(intent, activity);
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
|
|
|
|
2010-05-21 11:34:29 -04:00
|
|
|
|
2009-11-21 17:45:14 -05:00
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
2011-02-11 10:09:15 -05:00
|
|
|
if (mAccount.getCryptoProvider().onActivityResult(this, requestCode, resultCode, data, mPgpData)) {
|
2010-07-27 08:10:09 -04:00
|
|
|
return;
|
|
|
|
}
|
2009-11-21 17:45:14 -05:00
|
|
|
if (resultCode != RESULT_OK)
|
|
|
|
return;
|
2011-02-06 17:09:48 -05:00
|
|
|
switch (requestCode) {
|
2011-04-24 00:00:10 -04:00
|
|
|
case ACTIVITY_CHOOSE_DIRECTORY:
|
|
|
|
if (resultCode == RESULT_OK && data != null) {
|
|
|
|
// obtain the filename
|
|
|
|
Uri fileUri = data.getData();
|
|
|
|
if (fileUri != null) {
|
|
|
|
String filePath = fileUri.getPath();
|
|
|
|
if (filePath != null) {
|
|
|
|
attachmentTmpStore.writeFile(new File(filePath));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
2011-02-06 17:09:48 -05:00
|
|
|
case ACTIVITY_CHOOSE_FOLDER_MOVE:
|
|
|
|
case ACTIVITY_CHOOSE_FOLDER_COPY:
|
|
|
|
if (data == null)
|
|
|
|
return;
|
|
|
|
String destFolderName = data.getStringExtra(ChooseFolder.EXTRA_NEW_FOLDER);
|
|
|
|
String srcFolderName = data.getStringExtra(ChooseFolder.EXTRA_CUR_FOLDER);
|
2011-02-19 13:59:38 -05:00
|
|
|
MessageReference ref = data.getParcelableExtra(ChooseFolder.EXTRA_MESSAGE);
|
2011-02-06 17:09:48 -05:00
|
|
|
if (mMessageReference.equals(ref)) {
|
|
|
|
mAccount.setLastSelectedFolderName(destFolderName);
|
|
|
|
switch (requestCode) {
|
|
|
|
case ACTIVITY_CHOOSE_FOLDER_MOVE:
|
|
|
|
Message messageToMove = mMessage;
|
|
|
|
showNextMessageOrReturn();
|
2011-02-14 20:45:08 -05:00
|
|
|
mController.moveMessage(mAccount, srcFolderName, messageToMove, destFolderName, null);
|
2011-02-06 17:09:48 -05:00
|
|
|
break;
|
|
|
|
case ACTIVITY_CHOOSE_FOLDER_COPY:
|
2011-02-14 20:45:08 -05:00
|
|
|
mController.copyMessage(mAccount, srcFolderName, mMessage, destFolderName, null);
|
2011-02-06 17:09:48 -05:00
|
|
|
break;
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
2011-02-06 17:09:48 -05:00
|
|
|
}
|
|
|
|
break;
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onSendAlternate() {
|
|
|
|
if (mMessage != null) {
|
2011-01-06 11:56:02 -05:00
|
|
|
mController.sendAlternate(this, mAccount, mMessage);
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2011-11-01 19:44:33 -04:00
|
|
|
/**
|
2012-05-04 10:32:39 -04:00
|
|
|
* Handle a right-to-left swipe starting at the edge of the screen as "move to next message."
|
2011-11-01 19:44:33 -04:00
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
protected void onSwipeRightToLeft(MotionEvent e1, MotionEvent e2) {
|
2012-05-04 10:32:39 -04:00
|
|
|
if ((int) e1.getRawX() > mScreenWidthInPixels - BEZEL_SWIPE_THRESHOLD) {
|
Fix gesture detection
This commit addresses 2 issues:
1) Before, a general GestureDetector was registered on the highest level in K9Activity
This resulted in EVERY inherited activity to have a useless, unused gesture detector.
But more than that, in MessageList, a second GestureDetector was assigned to the ListView.
On every fling gesture, both detectors called the onSwipe() methods,
which technically did the following:
- The one directly assigned to the ListView would work corectly by mapping the
(local) event coordinates to the right entry in the ListView
- The global one worked on screen coordinates, so the onSwipe() method would
likely select the wrong ListView entry (system menu bar offset).
- For some reason this "worked" fine, and only the correct entry was selected,
despite two detectors used.
2) The gesture detection for the MessageView caused problems when the message
itself was scrollable, i.e. wide HTML mails. A fling gesture inside the WebView
would scroll the message, but also switch the message.
This commit fixes all those by doing the following:
- Don't register the GestureDetector in K9Activity, instead make the member variable
accessible by subclasses.
- In the subclasses that need a detector register it
- In K9Activity.dispatchTouchEvent() check for mGestureDetector being null
- For MessageList:
* Remove the duplicate gesture detector assigned to the ListView
* in the handleSwipe() methods: calclulate pixel offset of the ListView to make
it work using the global screen coordinates
- For MessageView: Limit sensitive area to the message header, to prevent interference
with the WebView scrolling
- Respect current behavior:
* Force-enable gestures for the MessageList
* Respect user setting in MessageView
- Make sure that after a successful swipe gesture, any pending action is cancelled, to
prevent unwanted things to happen (such as expanding the header after changing
the message, or a context menu popping up in the MessageList).
See http://code.google.com/p/android/issues/detail?id=8497
2012-04-30 19:56:06 -04:00
|
|
|
onNext();
|
2012-05-04 10:32:39 -04:00
|
|
|
}
|
2011-11-01 19:44:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-05-04 10:32:39 -04:00
|
|
|
* Handle a left-to-right swipe starting at the edge of the screen as
|
|
|
|
* "move to previous message."
|
2011-11-01 19:44:33 -04:00
|
|
|
*/
|
2010-03-07 18:43:27 -05:00
|
|
|
@Override
|
2011-11-01 19:44:33 -04:00
|
|
|
protected void onSwipeLeftToRight(MotionEvent e1, MotionEvent e2) {
|
2012-05-04 10:32:39 -04:00
|
|
|
if ((int) e1.getRawX() < BEZEL_SWIPE_THRESHOLD) {
|
Fix gesture detection
This commit addresses 2 issues:
1) Before, a general GestureDetector was registered on the highest level in K9Activity
This resulted in EVERY inherited activity to have a useless, unused gesture detector.
But more than that, in MessageList, a second GestureDetector was assigned to the ListView.
On every fling gesture, both detectors called the onSwipe() methods,
which technically did the following:
- The one directly assigned to the ListView would work corectly by mapping the
(local) event coordinates to the right entry in the ListView
- The global one worked on screen coordinates, so the onSwipe() method would
likely select the wrong ListView entry (system menu bar offset).
- For some reason this "worked" fine, and only the correct entry was selected,
despite two detectors used.
2) The gesture detection for the MessageView caused problems when the message
itself was scrollable, i.e. wide HTML mails. A fling gesture inside the WebView
would scroll the message, but also switch the message.
This commit fixes all those by doing the following:
- Don't register the GestureDetector in K9Activity, instead make the member variable
accessible by subclasses.
- In the subclasses that need a detector register it
- In K9Activity.dispatchTouchEvent() check for mGestureDetector being null
- For MessageList:
* Remove the duplicate gesture detector assigned to the ListView
* in the handleSwipe() methods: calclulate pixel offset of the ListView to make
it work using the global screen coordinates
- For MessageView: Limit sensitive area to the message header, to prevent interference
with the WebView scrolling
- Respect current behavior:
* Force-enable gestures for the MessageList
* Respect user setting in MessageView
- Make sure that after a successful swipe gesture, any pending action is cancelled, to
prevent unwanted things to happen (such as expanding the header after changing
the message, or a context menu popping up in the MessageList).
See http://code.google.com/p/android/issues/detail?id=8497
2012-04-30 19:56:06 -04:00
|
|
|
onPrevious();
|
2012-05-04 10:32:39 -04:00
|
|
|
}
|
2011-11-01 19:44:33 -04:00
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
protected void onNext() {
|
2011-11-02 19:39:23 -04:00
|
|
|
// Reset scroll percentage when we change messages
|
2011-02-06 17:09:48 -05:00
|
|
|
if (mNextMessage == null) {
|
2009-05-03 00:36:33 -04:00
|
|
|
Toast.makeText(this, getString(R.string.end_of_folder), Toast.LENGTH_SHORT).show();
|
|
|
|
return;
|
|
|
|
}
|
2009-11-29 23:03:00 -05:00
|
|
|
mLastDirection = NEXT;
|
2012-08-22 09:43:18 -04:00
|
|
|
//toggleActionsState(mMenu, false);
|
2011-02-06 17:09:48 -05:00
|
|
|
if (K9.showAnimations()) {
|
2012-02-24 19:08:55 -05:00
|
|
|
mMessageView.startAnimation(outToLeftAnimation());
|
2009-12-26 13:31:55 -05:00
|
|
|
}
|
2010-04-24 10:59:27 -04:00
|
|
|
displayMessage(mNextMessage);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
protected void onPrevious() {
|
2011-11-02 19:39:23 -04:00
|
|
|
// Reset scroll percentage when we change messages
|
2011-02-06 17:09:48 -05:00
|
|
|
if (mPreviousMessage == null) {
|
2009-05-03 00:36:33 -04:00
|
|
|
Toast.makeText(this, getString(R.string.end_of_folder), Toast.LENGTH_SHORT).show();
|
|
|
|
return;
|
|
|
|
}
|
2009-11-29 23:03:00 -05:00
|
|
|
mLastDirection = PREVIOUS;
|
2012-08-22 09:43:18 -04:00
|
|
|
//toggleActionsState(mMenu, false);
|
2011-02-06 17:09:48 -05:00
|
|
|
if (K9.showAnimations()) {
|
2012-02-24 19:08:55 -05:00
|
|
|
mMessageView.startAnimation(inFromRightAnimation());
|
2009-12-26 13:31:55 -05:00
|
|
|
}
|
2010-04-24 10:59:27 -04:00
|
|
|
displayMessage(mPreviousMessage);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2012-03-18 23:44:41 -04:00
|
|
|
private void onToggleRead() {
|
2011-02-06 17:09:48 -05:00
|
|
|
if (mMessage != null) {
|
2012-01-27 02:39:10 -05:00
|
|
|
mController.setFlag(mAccount, mMessage.getFolder().getName(),
|
2012-03-18 23:44:41 -04:00
|
|
|
new Message[] { mMessage }, Flag.SEEN, !mMessage.isSet(Flag.SEEN));
|
2012-02-04 08:52:45 -05:00
|
|
|
mMessageView.setHeaders(mMessage, mAccount);
|
|
|
|
String subject = mMessage.getSubject();
|
|
|
|
setTitle(subject);
|
2012-09-09 18:11:54 -04:00
|
|
|
updateUnreadToggleTitle();
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
private void onDownloadRemainder() {
|
|
|
|
if (mMessage.isSet(Flag.X_DOWNLOADED_FULL)) {
|
2010-07-18 21:57:49 -04:00
|
|
|
return;
|
|
|
|
}
|
2011-02-11 10:09:15 -05:00
|
|
|
mMessageView.downloadRemainderButton().setEnabled(false);
|
|
|
|
mController.loadMessageForViewRemote(mAccount, mMessageReference.folderName, mMessageReference.uid, mListener);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2011-02-11 10:09:15 -05:00
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
public void onClick(View view) {
|
|
|
|
switch (view.getId()) {
|
|
|
|
case R.id.download:
|
|
|
|
((AttachmentView)view).saveFile();
|
|
|
|
break;
|
|
|
|
case R.id.download_remainder:
|
|
|
|
onDownloadRemainder();
|
|
|
|
break;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
|
|
switch (item.getItemId()) {
|
2012-07-17 10:59:55 -04:00
|
|
|
case android.R.id.home:
|
|
|
|
finish();
|
|
|
|
break;
|
2012-08-22 09:43:18 -04:00
|
|
|
case R.id.next_message:
|
2012-09-09 17:25:52 -04:00
|
|
|
onNext();
|
|
|
|
break;
|
2012-08-22 09:43:18 -04:00
|
|
|
case R.id.previous_message:
|
2012-09-09 17:25:52 -04:00
|
|
|
onPrevious();
|
|
|
|
break;
|
2011-02-06 17:09:48 -05:00
|
|
|
case R.id.delete:
|
|
|
|
onDelete();
|
|
|
|
break;
|
|
|
|
case R.id.reply:
|
|
|
|
onReply();
|
|
|
|
break;
|
|
|
|
case R.id.reply_all:
|
|
|
|
onReplyAll();
|
|
|
|
break;
|
|
|
|
case R.id.forward:
|
|
|
|
onForward();
|
|
|
|
break;
|
2012-08-22 09:43:18 -04:00
|
|
|
case R.id.share:
|
2011-02-06 17:09:48 -05:00
|
|
|
onSendAlternate();
|
|
|
|
break;
|
2012-08-22 09:43:18 -04:00
|
|
|
case R.id.toggle_unread:
|
2012-03-18 23:44:41 -04:00
|
|
|
onToggleRead();
|
2011-02-06 17:09:48 -05:00
|
|
|
break;
|
|
|
|
case R.id.archive:
|
|
|
|
onRefile(mAccount.getArchiveFolderName());
|
|
|
|
break;
|
|
|
|
case R.id.spam:
|
|
|
|
onRefile(mAccount.getSpamFolderName());
|
|
|
|
break;
|
|
|
|
case R.id.move:
|
|
|
|
onMove();
|
|
|
|
break;
|
|
|
|
case R.id.copy:
|
|
|
|
onCopy();
|
|
|
|
break;
|
|
|
|
case R.id.select_text:
|
2011-02-11 10:09:15 -05:00
|
|
|
mMessageView.beginSelectingText();
|
2011-02-06 17:09:48 -05:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return super.onOptionsItemSelected(item);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-11-16 14:27:57 -05:00
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
2008-11-01 17:32:06 -04:00
|
|
|
super.onCreateOptionsMenu(menu);
|
2012-07-12 12:29:41 -04:00
|
|
|
getSupportMenuInflater().inflate(R.menu.message_view_option, menu);
|
2012-08-22 09:43:18 -04:00
|
|
|
mMenu = menu;
|
|
|
|
configureMenu(menu);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-09-09 17:25:52 -04:00
|
|
|
private void configureMenu(Menu menu) {
|
|
|
|
// first run displayMessage() gets called before onCreateOptionMenu()
|
|
|
|
if (menu == null) {
|
|
|
|
return;
|
|
|
|
}
|
2012-08-22 09:43:18 -04:00
|
|
|
|
2012-09-09 17:25:52 -04:00
|
|
|
// enable them all
|
|
|
|
menu.findItem(R.id.copy).setVisible(true);
|
|
|
|
menu.findItem(R.id.move).setVisible(true);
|
|
|
|
menu.findItem(R.id.archive).setVisible(true);
|
|
|
|
menu.findItem(R.id.spam).setVisible(true);
|
2012-08-22 09:43:18 -04:00
|
|
|
toggleActionsState(menu, true);
|
|
|
|
|
2012-09-09 17:25:52 -04:00
|
|
|
if (mNextMessage != null) {
|
2012-09-08 23:16:32 -04:00
|
|
|
|
2012-09-09 17:25:52 -04:00
|
|
|
menu.findItem(R.id.next_message).setEnabled(true);
|
|
|
|
menu.findItem(R.id.next_message).getIcon().setAlpha(255);
|
2012-09-08 23:16:32 -04:00
|
|
|
} else {
|
2012-09-09 17:25:52 -04:00
|
|
|
menu.findItem(R.id.next_message).getIcon().setAlpha(127);
|
|
|
|
menu.findItem(R.id.next_message).setEnabled(false);
|
2012-09-08 23:16:32 -04:00
|
|
|
}
|
|
|
|
|
2012-09-09 17:25:52 -04:00
|
|
|
if (mPreviousMessage != null) {
|
|
|
|
menu.findItem(R.id.previous_message).setEnabled(true);
|
|
|
|
menu.findItem(R.id.previous_message).getIcon().setAlpha(255);
|
2012-09-08 23:16:32 -04:00
|
|
|
} else {
|
2012-09-09 17:25:52 -04:00
|
|
|
menu.findItem(R.id.previous_message).getIcon().setAlpha(127);
|
|
|
|
menu.findItem(R.id.previous_message).setEnabled(false);
|
2012-09-08 23:16:32 -04:00
|
|
|
}
|
2012-08-22 09:43:18 -04:00
|
|
|
|
2012-09-09 18:11:54 -04:00
|
|
|
updateUnreadToggleTitle();
|
|
|
|
|
2012-08-22 09:43:18 -04:00
|
|
|
// comply with the setting
|
|
|
|
if (!mAccount.getEnableMoveButtons()) {
|
2009-11-21 17:45:14 -05:00
|
|
|
menu.findItem(R.id.move).setVisible(false);
|
2010-07-05 09:41:52 -04:00
|
|
|
menu.findItem(R.id.archive).setVisible(false);
|
|
|
|
menu.findItem(R.id.spam).setVisible(false);
|
2012-08-22 09:43:18 -04:00
|
|
|
} else {
|
2012-09-09 17:25:52 -04:00
|
|
|
// check message, folder capability
|
2012-08-22 09:43:18 -04:00
|
|
|
if (!mController.isCopyCapable(mAccount)) {
|
|
|
|
menu.findItem(R.id.copy).setVisible(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mController.isMoveCapable(mAccount)) {
|
|
|
|
menu.findItem(R.id.move).setVisible(true);
|
|
|
|
|
|
|
|
menu.findItem(R.id.archive).setVisible(
|
2012-09-09 17:25:52 -04:00
|
|
|
!mMessageReference.folderName.equals(mAccount.getArchiveFolderName())
|
|
|
|
&& mAccount.hasArchiveFolder());
|
2012-08-22 09:43:18 -04:00
|
|
|
|
|
|
|
menu.findItem(R.id.spam).setVisible(
|
2012-09-09 17:25:52 -04:00
|
|
|
!mMessageReference.folderName.equals(mAccount.getSpamFolderName())
|
|
|
|
&& mAccount.hasSpamFolder());
|
2012-08-22 09:43:18 -04:00
|
|
|
} else {
|
2012-09-09 17:25:52 -04:00
|
|
|
menu.findItem(R.id.copy).setVisible(false);
|
|
|
|
menu.findItem(R.id.move).setVisible(false);
|
|
|
|
menu.findItem(R.id.archive).setVisible(false);
|
|
|
|
menu.findItem(R.id.spam).setVisible(false);
|
2012-08-22 09:43:18 -04:00
|
|
|
}
|
2010-07-05 09:41:52 -04:00
|
|
|
}
|
2012-08-22 09:43:18 -04:00
|
|
|
}
|
|
|
|
|
2012-09-09 18:11:54 -04:00
|
|
|
/**
|
|
|
|
* Set the title of the "Toggle Unread" menu item based upon the current read state of the message.
|
|
|
|
*/
|
|
|
|
public void updateUnreadToggleTitle() {
|
|
|
|
if (mMessage != null && mMenu != null) {
|
|
|
|
if (mMessage.isSet(Flag.SEEN)) {
|
|
|
|
mMenu.findItem(R.id.toggle_unread).setTitle(R.string.mark_as_unread_action);
|
|
|
|
} else {
|
|
|
|
mMenu.findItem(R.id.toggle_unread).setTitle(R.string.mark_as_read_action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-09 17:25:52 -04:00
|
|
|
private void toggleActionsState(Menu menu, boolean state) {
|
|
|
|
for (int i = 0; i < menu.size(); ++i) {
|
|
|
|
menu.getItem(i).setEnabled(state);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-16 14:27:57 -05:00
|
|
|
|
2010-12-24 19:27:09 -05:00
|
|
|
// TODO: when switching to API version 8, override onCreateDialog(int, Bundle)
|
2010-12-25 22:49:23 -05:00
|
|
|
|
2010-09-01 16:59:09 -04:00
|
|
|
/**
|
2010-12-25 22:49:23 -05:00
|
|
|
* @param id The id of the dialog.
|
2010-09-01 16:59:09 -04:00
|
|
|
* @return The dialog. If you return null, the dialog will not be created.
|
2010-12-24 19:27:09 -05:00
|
|
|
* @see android.app.Activity#onCreateDialog(int)
|
2010-09-01 16:59:09 -04:00
|
|
|
*/
|
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
protected Dialog onCreateDialog(final int id) {
|
|
|
|
switch (id) {
|
2011-03-22 03:07:32 -04:00
|
|
|
case R.id.dialog_confirm_delete:
|
2011-03-31 21:17:47 -04:00
|
|
|
return ConfirmationDialog.create(this, id,
|
2011-04-12 08:16:22 -04:00
|
|
|
R.string.dialog_confirm_delete_title,
|
|
|
|
R.string.dialog_confirm_delete_message,
|
|
|
|
R.string.dialog_confirm_delete_confirm_button,
|
|
|
|
R.string.dialog_confirm_delete_cancel_button,
|
|
|
|
new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
delete();
|
|
|
|
}
|
|
|
|
});
|
2011-03-31 22:21:27 -04:00
|
|
|
case R.id.dialog_confirm_spam:
|
|
|
|
return ConfirmationDialog.create(this, id,
|
2011-04-12 08:16:22 -04:00
|
|
|
R.string.dialog_confirm_spam_title,
|
2011-06-04 19:35:11 -04:00
|
|
|
getResources().getQuantityString(R.plurals.dialog_confirm_spam_message, 1),
|
2011-04-12 08:16:22 -04:00
|
|
|
R.string.dialog_confirm_spam_confirm_button,
|
|
|
|
R.string.dialog_confirm_spam_cancel_button,
|
|
|
|
new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
refileMessage(mDstFolder);
|
|
|
|
mDstFolder = null;
|
|
|
|
}
|
|
|
|
});
|
2011-03-22 03:07:32 -04:00
|
|
|
case R.id.dialog_attachment_progress:
|
|
|
|
ProgressDialog d = new ProgressDialog(this);
|
|
|
|
d.setIndeterminate(true);
|
|
|
|
d.setTitle(R.string.dialog_attachment_progress_title);
|
|
|
|
return d;
|
2010-09-01 16:59:09 -04:00
|
|
|
}
|
|
|
|
return super.onCreateDialog(id);
|
|
|
|
}
|
|
|
|
|
2011-02-06 17:09:48 -05:00
|
|
|
class Listener extends MessagingListener {
|
2008-11-01 17:32:06 -04:00
|
|
|
@Override
|
2011-02-11 10:09:15 -05:00
|
|
|
public void loadMessageForViewHeadersAvailable(final Account account, String folder, String uid,
|
2011-02-06 17:09:48 -05:00
|
|
|
final Message message) {
|
2010-04-29 00:59:14 -04:00
|
|
|
if (!mMessageReference.uid.equals(uid) || !mMessageReference.folderName.equals(folder)
|
2011-02-06 17:09:48 -05:00
|
|
|
|| !mMessageReference.accountUuid.equals(account.getUuid())) {
|
2009-07-01 17:31:51 -04:00
|
|
|
return;
|
|
|
|
}
|
2012-01-03 20:27:51 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Clone the message object because the original could be modified by
|
|
|
|
* MessagingController later. This could lead to a ConcurrentModificationException
|
|
|
|
* when that same object is accessed by the UI thread (below).
|
|
|
|
*
|
|
|
|
* See issue 3953
|
|
|
|
*
|
|
|
|
* This is just an ugly hack to get rid of the most pressing problem. A proper way to
|
|
|
|
* fix this is to make Message thread-safe. Or, even better, rewriting the UI code to
|
|
|
|
* access messages via a ContentProvider.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
final Message clonedMessage = message.clone();
|
|
|
|
|
2011-02-14 12:27:40 -05:00
|
|
|
runOnUiThread(new Runnable() {
|
2011-02-11 10:09:15 -05:00
|
|
|
public void run() {
|
2012-01-03 20:27:51 -05:00
|
|
|
if (!clonedMessage.isSet(Flag.X_DOWNLOADED_FULL) &&
|
|
|
|
!clonedMessage.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
|
2012-04-04 04:04:57 -04:00
|
|
|
String text = getString(R.string.message_view_downloading);
|
|
|
|
mMessageView.showStatusMessage(text);
|
2009-11-21 17:45:14 -05:00
|
|
|
}
|
2012-01-03 20:27:51 -05:00
|
|
|
mMessageView.setHeaders(clonedMessage, account);
|
2012-09-06 21:04:59 -04:00
|
|
|
final String subject = clonedMessage.getSubject();
|
|
|
|
if (subject == null || subject.equals("")) {
|
|
|
|
setTitle(getString(R.string.general_no_subject));
|
|
|
|
} else {
|
|
|
|
setTitle(clonedMessage.getSubject());
|
|
|
|
}
|
2011-02-11 12:10:45 -05:00
|
|
|
mMessageView.setOnFlagListener(new OnClickListener() {
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
onFlag();
|
|
|
|
}
|
|
|
|
});
|
2011-02-11 10:09:15 -05:00
|
|
|
}
|
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2012-02-23 21:43:42 -05:00
|
|
|
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())) {
|
2009-07-01 17:31:51 -04:00
|
|
|
return;
|
|
|
|
}
|
2011-01-06 11:56:55 -05:00
|
|
|
|
2012-02-23 21:43:42 -05:00
|
|
|
runOnUiThread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
try {
|
|
|
|
mMessage = message;
|
|
|
|
mMessageView.setMessage(account, (LocalMessage) message, mPgpData,
|
|
|
|
mController, mListener);
|
2012-09-09 18:11:54 -04:00
|
|
|
updateUnreadToggleTitle();
|
2010-12-28 04:07:59 -05:00
|
|
|
|
2012-02-23 21:43:42 -05:00
|
|
|
} catch (MessagingException e) {
|
|
|
|
Log.v(K9.LOG_TAG, "loadMessageForViewBodyAvailable", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2009-05-03 16:52:32 -04:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
@Override
|
2011-02-14 20:45:08 -05:00
|
|
|
public void loadMessageForViewFailed(Account account, String folder, String uid, final Throwable t) {
|
2010-04-29 00:59:14 -04:00
|
|
|
if (!mMessageReference.uid.equals(uid) || !mMessageReference.folderName.equals(folder)
|
2011-02-06 17:09:48 -05:00
|
|
|
|| !mMessageReference.accountUuid.equals(account.getUuid())) {
|
2009-07-01 17:31:51 -04:00
|
|
|
return;
|
|
|
|
}
|
2011-02-06 17:09:48 -05:00
|
|
|
mHandler.post(new Runnable() {
|
|
|
|
public void run() {
|
2012-08-24 12:39:23 -04:00
|
|
|
setSupportProgressBarIndeterminateVisibility(false);
|
2011-02-06 17:09:48 -05:00
|
|
|
if (t instanceof IllegalArgumentException) {
|
2009-10-19 15:35:31 -04:00
|
|
|
mHandler.invalidIdError();
|
2011-02-06 17:09:48 -05:00
|
|
|
} else {
|
2009-11-21 17:45:14 -05:00
|
|
|
mHandler.networkError();
|
2009-10-19 15:35:31 -04:00
|
|
|
}
|
2010-07-10 12:41:48 -04:00
|
|
|
if ((MessageView.this.mMessage == null) ||
|
2011-02-06 17:09:48 -05:00
|
|
|
!MessageView.this.mMessage.isSet(Flag.X_DOWNLOADED_PARTIAL)) {
|
2012-04-04 04:04:57 -04:00
|
|
|
mMessageView.showStatusMessage(getString(R.string.webview_empty_message));
|
2010-02-06 09:49:36 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2011-02-14 20:45:08 -05:00
|
|
|
public void loadMessageForViewFinished(Account account, String folder, String uid, final Message message) {
|
2010-04-29 00:59:14 -04:00
|
|
|
if (!mMessageReference.uid.equals(uid) || !mMessageReference.folderName.equals(folder)
|
2011-02-06 17:09:48 -05:00
|
|
|
|| !mMessageReference.accountUuid.equals(account.getUuid())) {
|
2009-07-01 17:31:51 -04:00
|
|
|
return;
|
|
|
|
}
|
2011-02-06 17:09:48 -05:00
|
|
|
mHandler.post(new Runnable() {
|
|
|
|
public void run() {
|
2012-08-24 12:39:23 -04:00
|
|
|
setSupportProgressBarIndeterminateVisibility(false);
|
2011-02-11 12:11:21 -05:00
|
|
|
mMessageView.setShowDownloadButton(message);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2011-02-06 17:09:48 -05:00
|
|
|
public void loadMessageForViewStarted(Account account, String folder, String uid) {
|
2010-04-29 00:59:14 -04:00
|
|
|
if (!mMessageReference.uid.equals(uid) || !mMessageReference.folderName.equals(folder)
|
2011-02-06 17:09:48 -05:00
|
|
|
|| !mMessageReference.accountUuid.equals(account.getUuid())) {
|
2009-07-01 17:31:51 -04:00
|
|
|
return;
|
|
|
|
}
|
2011-02-06 17:09:48 -05:00
|
|
|
mHandler.post(new Runnable() {
|
|
|
|
public void run() {
|
2012-08-24 12:39:23 -04:00
|
|
|
setSupportProgressBarIndeterminateVisibility(true);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2011-02-20 12:49:55 -05:00
|
|
|
public void loadAttachmentStarted(Account account, Message message, Part part, Object tag, final boolean requiresDownload) {
|
2011-02-06 17:09:48 -05:00
|
|
|
if (mMessage != message) {
|
2009-07-01 17:31:51 -04:00
|
|
|
return;
|
|
|
|
}
|
2011-02-20 12:49:55 -05:00
|
|
|
mHandler.post(new Runnable() {
|
|
|
|
public void run() {
|
|
|
|
mMessageView.setAttachmentsEnabled(false);
|
|
|
|
showDialog(R.id.dialog_attachment_progress);
|
|
|
|
if (requiresDownload) {
|
|
|
|
mHandler.fetchingAttachment();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2011-02-20 12:49:55 -05:00
|
|
|
public void loadAttachmentFinished(Account account, Message message, Part part, final Object tag) {
|
2011-02-06 17:09:48 -05:00
|
|
|
if (mMessage != message) {
|
2009-07-01 17:31:51 -04:00
|
|
|
return;
|
|
|
|
}
|
2011-02-20 12:49:55 -05:00
|
|
|
mHandler.post(new Runnable() {
|
|
|
|
public void run() {
|
|
|
|
mMessageView.setAttachmentsEnabled(true);
|
|
|
|
removeDialog(R.id.dialog_attachment_progress);
|
|
|
|
Object[] params = (Object[]) tag;
|
|
|
|
boolean download = (Boolean) params[0];
|
|
|
|
AttachmentView attachment = (AttachmentView) params[1];
|
|
|
|
if (download) {
|
|
|
|
attachment.writeFile();
|
|
|
|
} else {
|
|
|
|
attachment.showFile();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2011-02-14 20:45:08 -05:00
|
|
|
public void loadAttachmentFailed(Account account, Message message, Part part, Object tag, String reason) {
|
2011-02-06 17:09:48 -05:00
|
|
|
if (mMessage != message) {
|
2009-07-01 17:31:51 -04:00
|
|
|
return;
|
|
|
|
}
|
2011-02-20 12:49:55 -05:00
|
|
|
mHandler.post(new Runnable() {
|
|
|
|
public void run() {
|
|
|
|
mMessageView.setAttachmentsEnabled(true);
|
|
|
|
removeDialog(R.id.dialog_attachment_progress);
|
|
|
|
mHandler.networkError();
|
|
|
|
}
|
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-10 12:03:10 -05:00
|
|
|
// This REALLY should be in MessageCryptoView
|
|
|
|
public void onDecryptDone(PgpData pgpData) {
|
2012-02-20 22:56:05 -05:00
|
|
|
Account account = mAccount;
|
2012-02-23 21:43:42 -05:00
|
|
|
LocalMessage message = (LocalMessage) mMessage;
|
|
|
|
MessagingController controller = mController;
|
|
|
|
Listener listener = mListener;
|
2012-02-20 22:56:05 -05:00
|
|
|
try {
|
2012-02-23 21:43:42 -05:00
|
|
|
mMessageView.setMessage(account, message, pgpData, controller, listener);
|
2012-02-20 22:56:05 -05:00
|
|
|
} catch (MessagingException e) {
|
|
|
|
Log.e(K9.LOG_TAG, "displayMessageBody failed", e);
|
|
|
|
}
|
2010-07-27 08:10:09 -04:00
|
|
|
}
|
2012-09-07 23:33:53 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the title of the view. Since we're using a custom ActionBar view, the normal setTitle() doesn't do what we
|
|
|
|
* think. This version sets the text value into the proper ActionBar title view.
|
|
|
|
* @param title Title to set.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void setTitle(CharSequence title) {
|
|
|
|
mTitleView.setText(title);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|