MessageView: next/prev navigation.
in addition: - fix AND-OR precedence in cursor query in MessageList. - move special mailbox ids from MessageList to Mailbox - move shared code from MessageList to com.android.email.Utility - add invisible prev/next to landscape in order to avoid special-case in code - select mailbox list using IN() instead of list of OR Note: Checked in by Andy to facilitate further work on MessageView. Change-Id: I8049be2b45fed1e4e697a0ed895492c4d0e59e0a
This commit is contained in:
parent
dad47808e9
commit
e1f0b0a9bc
@ -31,7 +31,19 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="0dip"
|
||||
android:layout_weight="1">
|
||||
|
||||
<!-- put invisible views for prev/next in order to not special-case the lanscape in code -->
|
||||
<FrameLayout
|
||||
android:visibility="gone"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip">
|
||||
<View
|
||||
android:id="@+id/previous"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip" />
|
||||
<View android:id="@+id/next"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip" />
|
||||
</FrameLayout>
|
||||
<include layout="@layout/message_view_header" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -16,6 +16,15 @@
|
||||
|
||||
package com.android.email;
|
||||
|
||||
import com.android.email.provider.EmailContent;
|
||||
import com.android.email.provider.EmailContent.Mailbox;
|
||||
import com.android.email.provider.EmailContent.MailboxColumns;
|
||||
import com.android.email.provider.EmailContent.Message;
|
||||
import com.android.email.provider.EmailContent.MessageColumns;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.database.Cursor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@ -221,4 +230,47 @@ public class Utility {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// TODO: unit test this
|
||||
public static String buildMailboxIdSelection(ContentResolver resolver, long mailboxId) {
|
||||
// Setup default selection & args, then add to it as necessary
|
||||
StringBuilder selection = new StringBuilder(
|
||||
Message.FLAG_LOADED + "!=" + Message.NOT_LOADED + " AND ");
|
||||
if (mailboxId == Mailbox.QUERY_ALL_INBOXES
|
||||
|| mailboxId == Mailbox.QUERY_ALL_DRAFTS
|
||||
|| mailboxId == Mailbox.QUERY_ALL_OUTBOX) {
|
||||
// query for all mailboxes of type INBOX, DRAFTS, or OUTBOX
|
||||
int type;
|
||||
if (mailboxId == Mailbox.QUERY_ALL_INBOXES) {
|
||||
type = Mailbox.TYPE_INBOX;
|
||||
} else if (mailboxId == Mailbox.QUERY_ALL_DRAFTS) {
|
||||
type = Mailbox.TYPE_DRAFTS;
|
||||
} else {
|
||||
type = Mailbox.TYPE_OUTBOX;
|
||||
}
|
||||
StringBuilder inboxes = new StringBuilder();
|
||||
Cursor c = resolver.query(Mailbox.CONTENT_URI,
|
||||
EmailContent.ID_PROJECTION,
|
||||
MailboxColumns.TYPE + "=? AND " + MailboxColumns.FLAG_VISIBLE + "=1",
|
||||
new String[] { Integer.toString(type) }, null);
|
||||
// build an IN (mailboxId, ...) list
|
||||
// TODO do this directly in the provider
|
||||
while (c.moveToNext()) {
|
||||
if (inboxes.length() != 0) {
|
||||
inboxes.append(",");
|
||||
}
|
||||
inboxes.append(c.getLong(EmailContent.ID_PROJECTION_COLUMN));
|
||||
}
|
||||
c.close();
|
||||
selection.append(MessageColumns.MAILBOX_KEY + " IN ");
|
||||
selection.append("(").append(inboxes).append(")");
|
||||
} else if (mailboxId == Mailbox.QUERY_ALL_UNREAD) {
|
||||
selection.append(Message.FLAG_READ + "=0");
|
||||
} else if (mailboxId == Mailbox.QUERY_ALL_FAVORITES) {
|
||||
selection.append(Message.FLAG_FAVORITE + "=1");
|
||||
} else {
|
||||
selection.append(MessageColumns.MAILBOX_KEY + "=" + mailboxId);
|
||||
}
|
||||
return selection.toString();
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ public class AccountFolderList extends ListActivity
|
||||
count = getUnreadCountByMailboxType(this, Mailbox.TYPE_INBOX);
|
||||
if (count > 0) {
|
||||
row = childCursor.newRow();
|
||||
row.add(Long.valueOf(MessageList.QUERY_ALL_INBOXES)); // MAILBOX_COLUMN_ID = 0;
|
||||
row.add(Long.valueOf(Mailbox.QUERY_ALL_INBOXES)); // MAILBOX_COLUMN_ID = 0;
|
||||
row.add(getString(R.string.account_folder_list_summary_inbox)); // MAILBOX_DISPLAY_NAME
|
||||
row.add(null); // MAILBOX_ACCOUNT_KEY = 2;
|
||||
row.add(Integer.valueOf(Mailbox.TYPE_INBOX)); // MAILBOX_TYPE = 3;
|
||||
@ -301,7 +301,7 @@ public class AccountFolderList extends ListActivity
|
||||
count = EmailContent.count(this, Message.CONTENT_URI, FAVORITE_COUNT_SELECTION, null);
|
||||
if (count > 0) {
|
||||
row = childCursor.newRow();
|
||||
row.add(Long.valueOf(MessageList.QUERY_ALL_FAVORITES)); // MAILBOX_COLUMN_ID = 0;
|
||||
row.add(Long.valueOf(Mailbox.QUERY_ALL_FAVORITES)); // MAILBOX_COLUMN_ID = 0;
|
||||
// MAILBOX_DISPLAY_NAME
|
||||
row.add(getString(R.string.account_folder_list_summary_favorite));
|
||||
row.add(null); // MAILBOX_ACCOUNT_KEY = 2;
|
||||
@ -312,7 +312,7 @@ public class AccountFolderList extends ListActivity
|
||||
count = getUnreadCountByMailboxType(this, Mailbox.TYPE_DRAFTS);
|
||||
if (count > 0) {
|
||||
row = childCursor.newRow();
|
||||
row.add(Long.valueOf(MessageList.QUERY_ALL_DRAFTS)); // MAILBOX_COLUMN_ID = 0;
|
||||
row.add(Long.valueOf(Mailbox.QUERY_ALL_DRAFTS)); // MAILBOX_COLUMN_ID = 0;
|
||||
row.add(getString(R.string.account_folder_list_summary_drafts));// MAILBOX_DISPLAY_NAME
|
||||
row.add(null); // MAILBOX_ACCOUNT_KEY = 2;
|
||||
row.add(Integer.valueOf(Mailbox.TYPE_DRAFTS)); // MAILBOX_TYPE = 3;
|
||||
@ -322,7 +322,7 @@ public class AccountFolderList extends ListActivity
|
||||
count = getUnreadCountByMailboxType(this, Mailbox.TYPE_OUTBOX);
|
||||
if (count > 0) {
|
||||
row = childCursor.newRow();
|
||||
row.add(Long.valueOf(MessageList.QUERY_ALL_OUTBOX)); // MAILBOX_COLUMN_ID = 0;
|
||||
row.add(Long.valueOf(Mailbox.QUERY_ALL_OUTBOX)); // MAILBOX_COLUMN_ID = 0;
|
||||
row.add(getString(R.string.account_folder_list_summary_outbox));// MAILBOX_DISPLAY_NAME
|
||||
row.add(null); // MAILBOX_ACCOUNT_KEY = 2;
|
||||
row.add(Integer.valueOf(Mailbox.TYPE_OUTBOX)); // MAILBOX_TYPE = 3;
|
||||
|
@ -818,7 +818,8 @@ public class FolderMessageList extends ExpandableListActivity {
|
||||
for (MessageInfoHolder holder : folder.messages) {
|
||||
folderUids.add(holder.uid);
|
||||
}
|
||||
MessageView.actionView(this, mAccountId, folder.name, message.uid, folderUids);
|
||||
// deprecated
|
||||
// MessageView.actionView(this, mAccountId, folder.name, message.uid, folderUids);
|
||||
}
|
||||
}
|
||||
|
||||
@ -841,7 +842,7 @@ public class FolderMessageList extends ExpandableListActivity {
|
||||
// TODO - save enough data to recreate the cursor, to enable prev/next in MessageView
|
||||
int messageIdColumn = messageCursor.getColumnIndex(EmailContent.RECORD_ID);
|
||||
long messageId = messageCursor.getLong(messageIdColumn);
|
||||
MessageView.actionView(this, messageId);
|
||||
MessageView.actionView(this, messageId, -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -68,16 +68,6 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class MessageList extends ListActivity implements OnItemClickListener, OnClickListener {
|
||||
|
||||
// Magic mailbox ID's
|
||||
// NOTE: This is a quick solution for merged mailboxes. I would rather implement this
|
||||
// with a more generic way of packaging and sharing queries between activities
|
||||
public static final long QUERY_ALL_INBOXES = -2;
|
||||
public static final long QUERY_ALL_UNREAD = -3;
|
||||
public static final long QUERY_ALL_FAVORITES = -4;
|
||||
public static final long QUERY_ALL_DRAFTS = -5;
|
||||
public static final long QUERY_ALL_OUTBOX = -6;
|
||||
|
||||
// Intent extras (internal to this activity)
|
||||
private static final String EXTRA_ACCOUNT_ID = "com.android.email.activity._ACCOUNT_ID";
|
||||
private static final String EXTRA_MAILBOX_TYPE = "com.android.email.activity.MAILBOX_TYPE";
|
||||
@ -139,12 +129,6 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
|
||||
private SetTitleTask mSetTitleTask;
|
||||
private SetFooterTask mSetFooterTask;
|
||||
|
||||
/**
|
||||
* Reduced mailbox projection used to hunt for inboxes
|
||||
* TODO: remove this and implement a custom URI
|
||||
*/
|
||||
public final static int MAILBOX_FIND_INBOX_COLUMN_ID = 0;
|
||||
|
||||
public final static String[] MAILBOX_FIND_INBOX_PROJECTION = new String[] {
|
||||
EmailContent.RECORD_ID, MailboxColumns.TYPE, MailboxColumns.FLAG_VISIBLE
|
||||
};
|
||||
@ -491,7 +475,7 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
|
||||
if (mailbox.mType == EmailContent.Mailbox.TYPE_DRAFTS) {
|
||||
MessageCompose.actionEditDraft(this, messageId);
|
||||
} else {
|
||||
MessageView.actionView(this, messageId);
|
||||
MessageView.actionView(this, messageId, mailboxId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -671,12 +655,14 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
|
||||
*/
|
||||
private void addFooterView(long mailboxId, long accountId, int mailboxType) {
|
||||
// first, look for shortcuts that don't need us to spin up a DB access task
|
||||
if (mailboxId == QUERY_ALL_INBOXES || mailboxId == QUERY_ALL_UNREAD
|
||||
|| mailboxId == QUERY_ALL_FAVORITES || mailboxId == QUERY_ALL_DRAFTS) {
|
||||
if (mailboxId == Mailbox.QUERY_ALL_INBOXES
|
||||
|| mailboxId == Mailbox.QUERY_ALL_UNREAD
|
||||
|| mailboxId == Mailbox.QUERY_ALL_FAVORITES
|
||||
|| mailboxId == Mailbox.QUERY_ALL_DRAFTS) {
|
||||
finishFooterView(LIST_FOOTER_MODE_REFRESH);
|
||||
return;
|
||||
}
|
||||
if (mailboxId == QUERY_ALL_OUTBOX || mailboxType == Mailbox.TYPE_OUTBOX) {
|
||||
if (mailboxId == Mailbox.QUERY_ALL_OUTBOX || mailboxType == Mailbox.TYPE_OUTBOX) {
|
||||
finishFooterView(LIST_FOOTER_MODE_SEND);
|
||||
return;
|
||||
}
|
||||
@ -879,60 +865,14 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
|
||||
|
||||
@Override
|
||||
protected Cursor doInBackground(Void... params) {
|
||||
// Setup default selection & args, then add to it as necessary
|
||||
StringBuilder selection = new StringBuilder(
|
||||
Message.FLAG_LOADED + "!=" + Message.NOT_LOADED + " AND ");
|
||||
String[] selArgs = null;
|
||||
|
||||
if (mMailboxKey == QUERY_ALL_INBOXES || mMailboxKey == QUERY_ALL_DRAFTS ||
|
||||
mMailboxKey == QUERY_ALL_OUTBOX) {
|
||||
// query for all mailboxes of type INBOX, DRAFTS, or OUTBOX
|
||||
int type;
|
||||
if (mMailboxKey == QUERY_ALL_INBOXES) {
|
||||
type = Mailbox.TYPE_INBOX;
|
||||
} else if (mMailboxKey == QUERY_ALL_DRAFTS) {
|
||||
type = Mailbox.TYPE_DRAFTS;
|
||||
} else {
|
||||
type = Mailbox.TYPE_OUTBOX;
|
||||
}
|
||||
StringBuilder inboxes = new StringBuilder();
|
||||
Cursor c = MessageList.this.mResolver.query(
|
||||
Mailbox.CONTENT_URI,
|
||||
MAILBOX_FIND_INBOX_PROJECTION,
|
||||
MailboxColumns.TYPE + "=? AND " + MailboxColumns.FLAG_VISIBLE + "=1",
|
||||
new String[] { Integer.toString(type) }, null);
|
||||
// build a long WHERE list
|
||||
// TODO do this directly in the provider
|
||||
while (c.moveToNext()) {
|
||||
if (inboxes.length() != 0) {
|
||||
inboxes.append(" OR ");
|
||||
}
|
||||
inboxes.append(MessageColumns.MAILBOX_KEY + "=");
|
||||
inboxes.append(c.getLong(MAILBOX_FIND_INBOX_COLUMN_ID));
|
||||
}
|
||||
c.close();
|
||||
// This is a hack - if there were no matching mailboxes, the empty selection string
|
||||
// would match *all* messages. Instead, force a "non-matching" selection, which
|
||||
// generates an empty Message cursor.
|
||||
// TODO: handle this properly when we move the compound lookup into the provider
|
||||
if (inboxes.length() == 0) {
|
||||
inboxes.append(Message.RECORD_ID + "=-1");
|
||||
}
|
||||
// make that the selection
|
||||
selection.append(inboxes);
|
||||
} else if (mMailboxKey == QUERY_ALL_UNREAD) {
|
||||
selection.append(Message.FLAG_READ + "=0");
|
||||
} else if (mMailboxKey == QUERY_ALL_FAVORITES) {
|
||||
selection.append(Message.FLAG_FAVORITE + "=1");
|
||||
} else {
|
||||
selection.append(MessageColumns.MAILBOX_KEY + "=?");
|
||||
selArgs = new String[] { String.valueOf(mMailboxKey) };
|
||||
}
|
||||
return MessageList.this.managedQuery(
|
||||
String selection =
|
||||
Utility.buildMailboxIdSelection(MessageList.this.mResolver, mMailboxKey);
|
||||
Cursor c = MessageList.this.managedQuery(
|
||||
EmailContent.Message.CONTENT_URI,
|
||||
MessageList.this.mListAdapter.PROJECTION,
|
||||
selection.toString(), selArgs,
|
||||
selection, null,
|
||||
EmailContent.MessageColumns.TIMESTAMP + " DESC");
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -945,7 +885,7 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
|
||||
}
|
||||
|
||||
// Reset the "new messages" count in the service, since we're seeing them now
|
||||
if (mMailboxKey == QUERY_ALL_INBOXES) {
|
||||
if (mMailboxKey == Mailbox.QUERY_ALL_INBOXES) {
|
||||
MailService.resetNewMessageCount(MessageList.this, -1);
|
||||
} else if (mMailboxKey >= 0 && mAccountKey != -1) {
|
||||
MailService.resetNewMessageCount(MessageList.this, mAccountKey);
|
||||
@ -964,16 +904,16 @@ public class MessageList extends ListActivity implements OnItemClickListener, On
|
||||
@Override
|
||||
protected String[] doInBackground(Void... params) {
|
||||
// Check special Mailboxes
|
||||
if (mMailboxKey == MessageList.QUERY_ALL_INBOXES) {
|
||||
if (mMailboxKey == Mailbox.QUERY_ALL_INBOXES) {
|
||||
return new String[] {null,
|
||||
getString(R.string.account_folder_list_summary_inbox)};
|
||||
} else if (mMailboxKey == MessageList.QUERY_ALL_FAVORITES) {
|
||||
} else if (mMailboxKey == Mailbox.QUERY_ALL_FAVORITES) {
|
||||
return new String[] {null,
|
||||
getString(R.string.account_folder_list_summary_favorite)};
|
||||
} else if (mMailboxKey == MessageList.QUERY_ALL_DRAFTS) {
|
||||
} else if (mMailboxKey == Mailbox.QUERY_ALL_DRAFTS) {
|
||||
return new String[] {null,
|
||||
getString(R.string.account_folder_list_summary_drafts)};
|
||||
} else if (mMailboxKey == MessageList.QUERY_ALL_OUTBOX) {
|
||||
} else if (mMailboxKey == Mailbox.QUERY_ALL_OUTBOX) {
|
||||
return new String[] {null,
|
||||
getString(R.string.account_folder_list_summary_outbox)};
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ import com.android.email.mail.MessagingException;
|
||||
import com.android.email.mail.internet.EmailHtmlUtil;
|
||||
import com.android.email.mail.internet.MimeUtility;
|
||||
import com.android.email.provider.AttachmentProvider;
|
||||
import com.android.email.provider.EmailContent;
|
||||
import com.android.email.provider.EmailContent.Account;
|
||||
import com.android.email.provider.EmailContent.Attachment;
|
||||
import com.android.email.provider.EmailContent.Body;
|
||||
@ -83,10 +84,7 @@ public class MessageView extends Activity
|
||||
implements OnClickListener {
|
||||
private static final String EXTRA_MESSAGE_ID = "com.android.email.MessageView_message_id";
|
||||
private static final String EXTRA_ACCOUNT_ID = "com.android.email.MessageView_account_id";
|
||||
private static final String EXTRA_FOLDER = "com.android.email.MessageView_folder";
|
||||
private static final String EXTRA_MESSAGE = "com.android.email.MessageView_message";
|
||||
private static final String EXTRA_FOLDER_UIDS = "com.android.email.MessageView_folderUids";
|
||||
private static final String EXTRA_NEXT = "com.android.email.MessageView_next";
|
||||
private static final String EXTRA_MAILBOX_ID = "com.android.email.MessageView_mailbox_id";
|
||||
|
||||
private static final String[] METHODS_WITH_PRESENCE_PROJECTION = new String[] {
|
||||
People.ContactMethods._ID, // 0
|
||||
@ -127,6 +125,7 @@ public class MessageView extends Activity
|
||||
private long mAccountId;
|
||||
private Account mAccount;
|
||||
private long mMessageId;
|
||||
private long mMailboxId;
|
||||
private Message mMessage;
|
||||
|
||||
private LoadMessageTask mLoadMessageTask;
|
||||
@ -139,7 +138,6 @@ public class MessageView extends Activity
|
||||
|
||||
private String mFolder;
|
||||
private String mMessageUid;
|
||||
private Cursor mMessageListCursor;
|
||||
|
||||
private java.text.DateFormat mDateFormat;
|
||||
private java.text.DateFormat mTimeFormat;
|
||||
@ -151,6 +149,11 @@ public class MessageView extends Activity
|
||||
private MessageViewHandler mHandler = new MessageViewHandler();
|
||||
private ControllerResults mControllerCallback = new ControllerResults();
|
||||
|
||||
private View mPrevious;
|
||||
private View mNext;
|
||||
private LoadPrevNextTask mLoadPrevNextTask;
|
||||
private Cursor mPrevNextCursor;
|
||||
|
||||
class MessageViewHandler extends Handler {
|
||||
private static final int MSG_ATTACHMENT_PROGRESS = 2;
|
||||
private static final int MSG_SET_ATTACHMENTS_ENABLED = 4;
|
||||
@ -335,41 +338,60 @@ public class MessageView extends Activity
|
||||
|
||||
/**
|
||||
* View a specific message found in the Email provider.
|
||||
*
|
||||
* TODO: Find a way to pass a cursor so we can iterator prev/next as well
|
||||
* @param messageId the message to view.
|
||||
* @param mailboxId identifies the sequence of messages used for prev/next navigation.
|
||||
*/
|
||||
public static void actionView(Context context, long messageId) {
|
||||
public static void actionView(Context context, long messageId, long mailboxId) {
|
||||
Intent i = new Intent(context, MessageView.class);
|
||||
i.putExtra(EXTRA_MESSAGE_ID, messageId);
|
||||
i.putExtra(EXTRA_MAILBOX_ID, mailboxId);
|
||||
context.startActivity(i);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void actionView(Context context, long accountId,
|
||||
String folder, String messageUid, ArrayList<String> folderUids) {
|
||||
actionView(context, accountId, folder, messageUid, folderUids, null);
|
||||
/**
|
||||
* Re-init everything needed for changing message.
|
||||
*/
|
||||
private void messageChanged() {
|
||||
cancelAllTasks();
|
||||
setTitle("");
|
||||
mAttachments.setVisibility(View.GONE);
|
||||
mAttachmentIcon.setVisibility(View.GONE);
|
||||
|
||||
// are the text clear below needed?
|
||||
// likely they only add flicker as the new message is displayed quickly
|
||||
// mSubjectView.setText(null);
|
||||
// mFromView.setText(null);
|
||||
// mTimeView.setText(null);
|
||||
// mDateView.setText(null);
|
||||
// mToView.setText(null);
|
||||
// mCcView.setText(null);
|
||||
|
||||
// Start an AsyncTask to make a new cursor and load the message
|
||||
mLoadMessageTask = new LoadMessageTask(mMessageId);
|
||||
mLoadMessageTask.execute();
|
||||
updatePrevNextArrows(mPrevNextCursor);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void actionView(Context context, long accountId,
|
||||
String folder, String messageUid, ArrayList<String> folderUids, Bundle extras) {
|
||||
Intent i = new Intent(context, MessageView.class);
|
||||
i.putExtra(EXTRA_ACCOUNT_ID, accountId);
|
||||
i.putExtra(EXTRA_FOLDER, folder);
|
||||
i.putExtra(EXTRA_MESSAGE, messageUid);
|
||||
i.putExtra(EXTRA_FOLDER_UIDS, folderUids);
|
||||
if (extras != null) {
|
||||
i.putExtras(extras);
|
||||
private void updatePrevNextArrows(Cursor cursor) {
|
||||
if (cursor != null) {
|
||||
boolean hasPrev, hasNext;
|
||||
if (cursor.isAfterLast() || cursor.isBeforeFirst()) {
|
||||
// The cursor not being on a message means that the current message was not found.
|
||||
// While this should not happen, simply disable prev/next arrows in that case.
|
||||
hasPrev = hasNext = false;
|
||||
} else {
|
||||
hasPrev = !cursor.isFirst();
|
||||
hasNext = !cursor.isLast();
|
||||
}
|
||||
mPrevious.setVisibility(hasPrev ? View.VISIBLE : View.GONE);
|
||||
mNext.setVisibility(hasNext ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
context.startActivity(i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
|
||||
|
||||
setContentView(R.layout.message_view);
|
||||
|
||||
mSubjectView = (TextView) findViewById(R.id.subject);
|
||||
@ -385,14 +407,11 @@ public class MessageView extends Activity
|
||||
mFavoriteIcon = (ImageView) findViewById(R.id.favorite);
|
||||
mShowPicturesSection = findViewById(R.id.show_pictures_section);
|
||||
mSenderPresenceView = (ImageView) findViewById(R.id.presence);
|
||||
mProgressDialog = new ProgressDialog(this);
|
||||
mProgressDialog.setIndeterminate(true);
|
||||
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
||||
|
||||
mMessageContentView.setVerticalScrollBarEnabled(false);
|
||||
mAttachments.setVisibility(View.GONE);
|
||||
mAttachmentIcon.setVisibility(View.GONE);
|
||||
mNext = findViewById(R.id.next);
|
||||
mPrevious = findViewById(R.id.previous);
|
||||
|
||||
mNext.setOnClickListener(this);
|
||||
mPrevious.setOnClickListener(this);
|
||||
mFromView.setOnClickListener(this);
|
||||
mSenderPresenceView.setOnClickListener(this);
|
||||
mFavoriteIcon.setOnClickListener(this);
|
||||
@ -401,10 +420,13 @@ public class MessageView extends Activity
|
||||
findViewById(R.id.delete).setOnClickListener(this);
|
||||
findViewById(R.id.show_pictures).setOnClickListener(this);
|
||||
|
||||
mMessageContentView.setVerticalScrollBarEnabled(false);
|
||||
mMessageContentView.getSettings().setBlockNetworkImage(true);
|
||||
mMessageContentView.getSettings().setSupportZoom(false);
|
||||
|
||||
setTitle("");
|
||||
mProgressDialog = new ProgressDialog(this);
|
||||
mProgressDialog.setIndeterminate(true);
|
||||
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
||||
|
||||
mDateFormat = android.text.format.DateFormat.getDateFormat(this); // short format
|
||||
mTimeFormat = android.text.format.DateFormat.getTimeFormat(this); // 12/24 date format
|
||||
@ -414,37 +436,9 @@ public class MessageView extends Activity
|
||||
|
||||
Intent intent = getIntent();
|
||||
mMessageId = intent.getLongExtra(EXTRA_MESSAGE_ID, -1);
|
||||
// mAccountId = intent.getLongExtra(EXTRA_ACCOUNT_ID, -1);
|
||||
// mAccount = EmailStore.Account.restoreAccountWithId(this, mAccountId);
|
||||
// mFolder = intent.getStringExtra(EXTRA_FOLDER);
|
||||
// mMessageUid = intent.getStringExtra(EXTRA_MESSAGE);
|
||||
mMessageListCursor = null; // TODO - pass message list cursor so we can prev/next
|
||||
|
||||
View next = findViewById(R.id.next);
|
||||
View previous = findViewById(R.id.previous);
|
||||
/*
|
||||
* Next and Previous Message are not shown in landscape mode, so
|
||||
* we need to check before we use them.
|
||||
*/
|
||||
if (next != null && previous != null && mMessageListCursor != null) {
|
||||
// TODO analyze based on cursor, not on a big nasty array
|
||||
next.setVisibility(View.GONE);
|
||||
previous.setVisibility(View.GONE);
|
||||
/*
|
||||
next.setOnClickListener(this);
|
||||
previous.setOnClickListener(this);
|
||||
|
||||
findSurroundingMessagesUid();
|
||||
|
||||
previous.setVisibility(mPreviousMessageUid != null ? View.VISIBLE : View.GONE);
|
||||
next.setVisibility(mNextMessageUid != null ? View.VISIBLE : View.GONE);
|
||||
|
||||
boolean goNext = intent.getBooleanExtra(EXTRA_NEXT, false);
|
||||
if (goNext) {
|
||||
next.requestFocus();
|
||||
}
|
||||
*/
|
||||
}
|
||||
mMailboxId = intent.getLongExtra(EXTRA_MAILBOX_ID, -1);
|
||||
messageChanged();
|
||||
}
|
||||
|
||||
/*
|
||||
MessagingController.getInstance(getApplication()).addListener(mListener);
|
||||
@ -463,10 +457,6 @@ public class MessageView extends Activity
|
||||
}
|
||||
}.start();
|
||||
*/
|
||||
// Start an AsyncTask to make a new cursor and load the message
|
||||
mLoadMessageTask = new LoadMessageTask(mMessageId);
|
||||
mLoadMessageTask.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
@ -485,6 +475,23 @@ public class MessageView extends Activity
|
||||
Controller.getInstance(getApplication()).removeResultCallback(mControllerCallback);
|
||||
}
|
||||
|
||||
private static void cancelTask(AsyncTask task) {
|
||||
if (task != null && task.getStatus() != AsyncTask.Status.FINISHED) {
|
||||
task.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelAllTasks() {
|
||||
cancelTask(mLoadMessageTask);
|
||||
mLoadMessageTask = null;
|
||||
cancelTask(mLoadBodyTask);
|
||||
mLoadBodyTask = null;
|
||||
cancelTask(mLoadAttachmentsTask);
|
||||
mLoadAttachmentsTask = null;
|
||||
cancelTask(mLoadPrevNextTask);
|
||||
mLoadPrevNextTask = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* We override onDestroy to make sure that the WebView gets explicitly destroyed.
|
||||
* Otherwise it can leak native references.
|
||||
@ -492,28 +499,16 @@ public class MessageView extends Activity
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (mLoadMessageTask != null
|
||||
&& mLoadMessageTask.getStatus() != AsyncTask.Status.FINISHED) {
|
||||
mLoadMessageTask.cancel(true);
|
||||
mLoadMessageTask = null;
|
||||
}
|
||||
if (mLoadBodyTask != null
|
||||
&& mLoadBodyTask.getStatus() != AsyncTask.Status.FINISHED) {
|
||||
mLoadBodyTask.cancel(true);
|
||||
mLoadBodyTask = null;
|
||||
}
|
||||
if (mLoadAttachmentsTask != null
|
||||
&& mLoadAttachmentsTask.getStatus() != AsyncTask.Status.FINISHED) {
|
||||
mLoadAttachmentsTask.cancel(true);
|
||||
mLoadAttachmentsTask = null;
|
||||
}
|
||||
|
||||
cancelAllTasks();
|
||||
// This is synchronized because the listener accesses mMessageContentView from its thread
|
||||
synchronized (this) {
|
||||
mMessageContentView.destroy();
|
||||
mMessageContentView = null;
|
||||
}
|
||||
if (mPrevNextCursor != null) {
|
||||
mPrevNextCursor.close();
|
||||
mPrevNextCursor = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void onDelete() {
|
||||
@ -593,23 +588,23 @@ public class MessageView extends Activity
|
||||
}
|
||||
|
||||
private boolean onNext() {
|
||||
// TODO make this work using a cursor
|
||||
return false;
|
||||
/*
|
||||
Bundle extras = new Bundle(1);
|
||||
extras.putBoolean(EXTRA_NEXT, true);
|
||||
MessageView.actionView(this, mAccountId, mFolder, mNextMessageUid, mFolderUids, extras);
|
||||
finish();
|
||||
*/
|
||||
if (mPrevNextCursor != null && mPrevNextCursor.moveToNext()) {
|
||||
mMessageId = mPrevNextCursor.getLong(0);
|
||||
messageChanged();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean onPrevious() {
|
||||
// TODO make this work using a cursor
|
||||
return false;
|
||||
/*
|
||||
MessageView.actionView(this, mAccountId, mFolder, mPreviousMessageUid, mFolderUids);
|
||||
finish();
|
||||
*/
|
||||
if (mPrevNextCursor != null && mPrevNextCursor.moveToPrevious()) {
|
||||
mMessageId = mPrevNextCursor.getLong(0);
|
||||
messageChanged();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void onMarkAsRead(boolean isRead) {
|
||||
@ -956,6 +951,41 @@ public class MessageView extends Activity
|
||||
mSenderPresenceView.setImageResource(presenceIconId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This task finds out the messageId for the previous and next message
|
||||
* in the order given by mailboxId as used in MessageList.
|
||||
*
|
||||
* It generates the same cursor as the one used in MessageList (but with an id-only projection),
|
||||
* scans through it until finds the current messageId, and takes the previous and next ids.
|
||||
*/
|
||||
private class LoadPrevNextTask extends AsyncTask<Void, Void, Cursor> {
|
||||
private long mLocalMailboxId;
|
||||
|
||||
public LoadPrevNextTask(long mailboxId) {
|
||||
mLocalMailboxId = mailboxId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Cursor doInBackground(Void... params) {
|
||||
String selection =
|
||||
Utility.buildMailboxIdSelection(getContentResolver(), mLocalMailboxId);
|
||||
Cursor c = MessageView.this.managedQuery(EmailContent.Message.CONTENT_URI,
|
||||
EmailContent.ID_PROJECTION,
|
||||
selection, null,
|
||||
EmailContent.MessageColumns.TIMESTAMP + " DESC");
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Cursor cursor) {
|
||||
// position the cursor on the current message
|
||||
while (cursor.moveToNext() && cursor.getLong(0) != mMessageId);
|
||||
mPrevNextCursor = cursor;
|
||||
updatePrevNextArrows(mPrevNextCursor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Async task for loading a single message outside of the UI thread
|
||||
*
|
||||
@ -1071,7 +1101,15 @@ public class MessageView extends Activity
|
||||
Message message = new Message().restore(cursor);
|
||||
mMessage = message;
|
||||
mAccountId = message.mAccountKey;
|
||||
|
||||
if (mMailboxId == -1) {
|
||||
mMailboxId = message.mMailboxKey;
|
||||
}
|
||||
// only start LoadPrevNextTask once
|
||||
if (mPrevNextCursor == null) {
|
||||
mLoadPrevNextTask = new LoadPrevNextTask(mMailboxId);
|
||||
mLoadPrevNextTask.execute();
|
||||
}
|
||||
|
||||
mSubjectView.setText(message.mSubject);
|
||||
mFromView.setText(Address.toFriendly(Address.unpack(message.mFrom)));
|
||||
Date date = new Date(message.mTimeStamp);
|
||||
|
@ -1812,14 +1812,9 @@ public abstract class EmailContent {
|
||||
// Push-Hold indicates an EAS push or ping Mailbox shouldn't sync just yet
|
||||
public static final int CHECK_INTERVAL_PUSH_HOLD = -4;
|
||||
|
||||
|
||||
private static final String WHERE_TYPE_AND_ACCOUNT_KEY =
|
||||
MailboxColumns.TYPE + "=? and " + MailboxColumns.ACCOUNT_KEY + "=?";
|
||||
|
||||
public Mailbox() {
|
||||
mBaseUri = CONTENT_URI;
|
||||
}
|
||||
|
||||
// Types of mailboxes. The list is ordered to match a typical UI presentation, e.g.
|
||||
// placing the inbox at the top.
|
||||
// The "main" mailbox for the account, almost always referred to as "Inbox"
|
||||
@ -1852,6 +1847,19 @@ public abstract class EmailContent {
|
||||
public static final int FLAG_CHILDREN_VISIBLE = 1<<1;
|
||||
public static final int FLAG_CANT_PUSH = 1<<2;
|
||||
|
||||
// Magic mailbox ID's
|
||||
// NOTE: This is a quick solution for merged mailboxes. I would rather implement this
|
||||
// with a more generic way of packaging and sharing queries between activities
|
||||
public static final long QUERY_ALL_INBOXES = -2;
|
||||
public static final long QUERY_ALL_UNREAD = -3;
|
||||
public static final long QUERY_ALL_FAVORITES = -4;
|
||||
public static final long QUERY_ALL_DRAFTS = -5;
|
||||
public static final long QUERY_ALL_OUTBOX = -6;
|
||||
|
||||
public Mailbox() {
|
||||
mBaseUri = CONTENT_URI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a Mailbox from the database, given its unique id
|
||||
* @param context
|
||||
|
@ -553,7 +553,7 @@ public class MailService extends Service {
|
||||
R.plurals.notification_new_multi_account_fmt, accountsWithNewMessages,
|
||||
accountsWithNewMessages);
|
||||
intent = MessageList.actionHandleAccountIntent(this,
|
||||
-1, MessageList.QUERY_ALL_INBOXES, -1);
|
||||
-1, Mailbox.QUERY_ALL_INBOXES, -1);
|
||||
}
|
||||
|
||||
// prepare appropriate pending intent, set up notification, and send
|
||||
|
Loading…
Reference in New Issue
Block a user