diff --git a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java index c030df751..4f88cfb13 100644 --- a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java +++ b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java @@ -2299,26 +2299,28 @@ public abstract class EmailContent { // 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" // Arrays of "special_mailbox_display_names" and "special_mailbox_icons" are depends on // types Id of mailboxes. + /** No type specified */ + public static final int TYPE_NONE = -1; + /** The "main" mailbox for the account, almost always referred to as "Inbox" */ public static final int TYPE_INBOX = 0; // Types of mailboxes - // Holds mail (generic) + /** Generic mailbox that holds mail */ public static final int TYPE_MAIL = 1; - // Parent-only mailbox; holds no mail + /** Parent-only mailbox; does not hold any mail */ public static final int TYPE_PARENT = 2; - // Holds drafts + /** Drafts mailbox */ public static final int TYPE_DRAFTS = 3; - // The local outbox associated with the Account + /** Local mailbox associated with the account's outgoing mail */ public static final int TYPE_OUTBOX = 4; - // Holds sent mail + /** Sent mail; mail that was sent from the account */ public static final int TYPE_SENT = 5; - // Holds deleted mail + /** Deleted mail */ public static final int TYPE_TRASH = 6; - // Holds junk mail + /** Junk mail */ public static final int TYPE_JUNK = 7; - // A mailbox that holds search results + /** Search results */ public static final int TYPE_SEARCH = 8; // Types after this are used for non-mail mailboxes (as in EAS) @@ -2335,17 +2337,19 @@ public abstract class EmailContent { // Bit field flags; each is defined below // Warning: Do not read these flags until POP/IMAP/EAS all populate them - // This mailbox has children in the mailbox hierarchy + /** No flags set */ + public static final int FLAG_NONE = 0; + /** Has children in the mailbox hierarchy */ public static final int FLAG_HAS_CHILDREN = 1<<0; - // This mailbox's children are visible in the UI + /** Children are visible in the UI */ public static final int FLAG_CHILDREN_VISIBLE = 1<<1; - // This mailbox cannot receive "pushed" mail + /** cannot receive "pushed" mail */ public static final int FLAG_CANT_PUSH = 1<<2; - // This mailbox can hold emails (i.e. some parent mailboxes cannot themselves contain mail) + /** can hold emails (i.e. some parent mailboxes cannot themselves contain mail) */ public static final int FLAG_HOLDS_MAIL = 1<<3; - // This mailbox is a valid target for moving messages within the account + /** can be used as a target for moving messages within the account */ public static final int FLAG_ACCEPTS_MOVED_MAIL = 1<<4; - // This mailbox is a valid target for appending messages + /** can be used as a target for appending messages */ public static final int FLAG_ACCEPTS_APPENDED_MAIL = 1<<5; // Magic mailbox ID's diff --git a/src/com/android/email/activity/MailboxFragmentAdapter.java b/src/com/android/email/activity/MailboxFragmentAdapter.java index 20b7029de..dc3a3001e 100644 --- a/src/com/android/email/activity/MailboxFragmentAdapter.java +++ b/src/com/android/email/activity/MailboxFragmentAdapter.java @@ -74,7 +74,6 @@ import android.widget.TextView; listItem.mMailboxType = type; listItem.mMailboxId = id; listItem.mAdapter = this; - // Set the background depending on whether we're in drag mode, the mailbox is a valid // target, etc. mCallback.onBind(listItem); @@ -108,8 +107,8 @@ import android.widget.TextView; folderIcon.setVisibility(View.INVISIBLE); break; case ROW_TYPE_SUBMAILBOX: - if ((flags & Mailbox.FLAG_HAS_CHILDREN) != 0 && - (flags & Mailbox.FLAG_CHILDREN_VISIBLE) != 0) { + if ((flags & Mailbox.FLAG_HAS_CHILDREN) != 0 + && (flags & Mailbox.FLAG_CHILDREN_VISIBLE) != 0) { mailboxExpandedIcon.setVisibility(View.VISIBLE); mailboxExpandedIcon.setImageResource( R.drawable.ic_mailbox_collapsed_holo_light); @@ -204,7 +203,8 @@ import android.widget.TextView; throw new IllegalArgumentException(); // Must be QUERY_ALL_*, which are all negative } if (showAlways || (count > 0)) { - addMailboxRow(cursor, id, "", mailboxType, count, count, ROW_TYPE_MAILBOX, 0); + addMailboxRow( + cursor, id, "", mailboxType, count, count, ROW_TYPE_MAILBOX, Mailbox.FLAG_NONE); } } @@ -314,17 +314,12 @@ import android.widget.TextView; accounts.moveToPosition(-1); while (accounts.moveToNext()) { - RowBuilder row = combinedWithAccounts.newRow(); final long accountId = accounts.getLong(COLUMN_ACCOUND_ID); - row.add(accountId); - row.add(accountId); - row.add(accounts.getString(COLUMN_ACCOUNT_DISPLAY_NAME)); - row.add(-1); // No mailbox type. Shouldn't really be used. + final String accountName = accounts.getString(COLUMN_ACCOUNT_DISPLAY_NAME); final int unreadCount = Mailbox.getUnreadCountByAccountAndMailboxType( mContext, accountId, Mailbox.TYPE_INBOX); - row.add(unreadCount); - row.add(unreadCount); - row.add(ROW_TYPE_ACCOUNT); + addMailboxRow(combinedWithAccounts, accountId, accountName, Mailbox.TYPE_NONE, + unreadCount, unreadCount, ROW_TYPE_ACCOUNT, Mailbox.FLAG_NONE); } return Utility.CloseTraceCursorWrapper.get(combinedWithAccounts); } diff --git a/src/com/android/email/activity/MailboxListFragment.java b/src/com/android/email/activity/MailboxListFragment.java index bcb50dafe..2932c81e6 100644 --- a/src/com/android/email/activity/MailboxListFragment.java +++ b/src/com/android/email/activity/MailboxListFragment.java @@ -268,18 +268,34 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList } /** - * Selects the given mailbox ID and navigates to it. This loads any mailboxes contained - * within it. The mailbox is assumed to be associated with the account passed into - * {@link #openMailboxes(long)} - * @param mailboxId The ID of the mailbox to load. + * Selects the given mailbox ID and possibly navigates to it. This loads any mailboxes + * contained within it and may cause the mailbox list to be updated. If the current fragment + * is not in the resumed state or if the mailbox cannot be navigated to, the given mailbox + * will only be selected. The mailbox is assumed to be associated with the account passed + * into {@link #openMailboxes(long)}. + * @param mailboxId The ID of the mailbox to select and navigate to. */ public void navigateToMailbox(long mailboxId) { setSelectedMailbox(mailboxId); - if (mResumed) { + if (mResumed && isNavigable(mailboxId)) { startLoading(); } } + /** + * Returns whether or not the specified mailbox can be navigated to. + */ + private boolean isNavigable(long mailboxId) { + final int count = mListAdapter.getCount(); + for (int i = 0; i < count; i++) { + if (mListAdapter.getId(i) != mSelectedMailboxId) { + continue; + } + return mListAdapter.isNavigable(i); + } + return false; + } + /** * Sets the selected mailbox to the given ID. Sub-folders will not be loaded. * @param mailboxId The ID of the mailbox to select. @@ -502,6 +518,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList // No mailbox selected mListView.clearChoices(); } else { + // TODO Don't mix list view & list adapter indices. This is a recipe for disaster. final int count = mListView.getCount(); for (int i = 0; i < count; i++) { if (mListAdapter.getId(i) != mSelectedMailboxId) { diff --git a/src/com/android/email/activity/MailboxListItem.java b/src/com/android/email/activity/MailboxListItem.java index cecd7cfb8..cd6e33665 100644 --- a/src/com/android/email/activity/MailboxListItem.java +++ b/src/com/android/email/activity/MailboxListItem.java @@ -69,6 +69,11 @@ public class MailboxListItem extends RelativeLayout { mLabelCount = (TextView)findViewById(R.id.message_count); } + /** + * Whether or not this mailbox item is a drop target. Only valid mailboxes or those + * not forbidden by the system (see {@link Mailbox#INVALID_DROP_TARGETS}) will return + * {@code true}. + */ public boolean isDropTarget(long itemMailbox) { if ((mMailboxId < 0) || (itemMailbox == mMailboxId)) { return false; diff --git a/src/com/android/email/activity/MailboxesAdapter.java b/src/com/android/email/activity/MailboxesAdapter.java index a15db8cec..b1e8d6bc5 100644 --- a/src/com/android/email/activity/MailboxesAdapter.java +++ b/src/com/android/email/activity/MailboxesAdapter.java @@ -220,14 +220,24 @@ import android.widget.CursorAdapter; } /** - * @return ID of the mailbox (or account, if {@link #isAccountRow} == true) of the specified - * row. + * Returns the ID of the mailbox (or account, if {@link #isAccountRow} is {@code true}) + * of the given row. */ public long getId(int position) { Cursor c = (Cursor) getItem(position); return c.getLong(COLUMN_ID); } + /** + * Returns whether or not the mailbox at the given row can be navigated to. + */ + public boolean isNavigable(int row) { + final Cursor c = (Cursor) getItem(row); + final int flags = c.getInt(COLUMN_FLAGS); + return (flags & Mailbox.FLAG_HAS_CHILDREN) != 0 + && (flags & Mailbox.FLAG_CHILDREN_VISIBLE) != 0; + } + /** * Turn on and off list updates; during a drag operation, we do NOT want to the list of * mailboxes to update, as this would be visually jarring