only allow navigating to mailboxes w/ children
If a mailbox doesn't have any sub-mailboxes, only allow selecting them to view
any contained messages. Do not update the mailbox list.
Change-Id: I6f469bf20a57dc440885402084c21ff184f13dff
diff --git a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java
index c030df7..4f88cfb 100644
--- a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java
+++ b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java
@@ -2299,26 +2299,28 @@
// 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 @@
// 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 20b7029..dc3a300 100644
--- a/src/com/android/email/activity/MailboxFragmentAdapter.java
+++ b/src/com/android/email/activity/MailboxFragmentAdapter.java
@@ -74,7 +74,6 @@
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 @@
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 @@
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 @@
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 bcb50da..2932c81 100644
--- a/src/com/android/email/activity/MailboxListFragment.java
+++ b/src/com/android/email/activity/MailboxListFragment.java
@@ -268,19 +268,35 @@
}
/**
- * 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 @@
// 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 cecd7cf..cd6e336 100644
--- a/src/com/android/email/activity/MailboxListItem.java
+++ b/src/com/android/email/activity/MailboxListItem.java
@@ -69,6 +69,11 @@
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 a15db8c..b1e8d6b 100644
--- a/src/com/android/email/activity/MailboxesAdapter.java
+++ b/src/com/android/email/activity/MailboxesAdapter.java
@@ -220,8 +220,8 @@
}
/**
- * @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);
@@ -229,6 +229,16 @@
}
/**
+ * 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
* @param state whether or not the MailboxList can be updated