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
This commit is contained in:
Todd Kennedy 2011-04-11 16:43:24 -07:00
parent 1d1b7a070a
commit f7036b7379
5 changed files with 65 additions and 34 deletions

View File

@ -2299,26 +2299,28 @@ public abstract class EmailContent {
// Types of mailboxes. The list is ordered to match a typical UI presentation, e.g. // Types of mailboxes. The list is ordered to match a typical UI presentation, e.g.
// placing the inbox at the top. // 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 // Arrays of "special_mailbox_display_names" and "special_mailbox_icons" are depends on
// types Id of mailboxes. // 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; public static final int TYPE_INBOX = 0;
// Types of mailboxes // Types of mailboxes
// Holds mail (generic) /** Generic mailbox that holds mail */
public static final int TYPE_MAIL = 1; 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; public static final int TYPE_PARENT = 2;
// Holds drafts /** Drafts mailbox */
public static final int TYPE_DRAFTS = 3; 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; 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; public static final int TYPE_SENT = 5;
// Holds deleted mail /** Deleted mail */
public static final int TYPE_TRASH = 6; public static final int TYPE_TRASH = 6;
// Holds junk mail /** Junk mail */
public static final int TYPE_JUNK = 7; public static final int TYPE_JUNK = 7;
// A mailbox that holds search results /** Search results */
public static final int TYPE_SEARCH = 8; public static final int TYPE_SEARCH = 8;
// Types after this are used for non-mail mailboxes (as in EAS) // 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 // Bit field flags; each is defined below
// Warning: Do not read these flags until POP/IMAP/EAS all populate them // 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; 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; 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; 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; 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; 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; public static final int FLAG_ACCEPTS_APPENDED_MAIL = 1<<5;
// Magic mailbox ID's // Magic mailbox ID's

View File

@ -74,7 +74,6 @@ import android.widget.TextView;
listItem.mMailboxType = type; listItem.mMailboxType = type;
listItem.mMailboxId = id; listItem.mMailboxId = id;
listItem.mAdapter = this; listItem.mAdapter = this;
// Set the background depending on whether we're in drag mode, the mailbox is a valid // Set the background depending on whether we're in drag mode, the mailbox is a valid
// target, etc. // target, etc.
mCallback.onBind(listItem); mCallback.onBind(listItem);
@ -108,8 +107,8 @@ import android.widget.TextView;
folderIcon.setVisibility(View.INVISIBLE); folderIcon.setVisibility(View.INVISIBLE);
break; break;
case ROW_TYPE_SUBMAILBOX: case ROW_TYPE_SUBMAILBOX:
if ((flags & Mailbox.FLAG_HAS_CHILDREN) != 0 && if ((flags & Mailbox.FLAG_HAS_CHILDREN) != 0
(flags & Mailbox.FLAG_CHILDREN_VISIBLE) != 0) { && (flags & Mailbox.FLAG_CHILDREN_VISIBLE) != 0) {
mailboxExpandedIcon.setVisibility(View.VISIBLE); mailboxExpandedIcon.setVisibility(View.VISIBLE);
mailboxExpandedIcon.setImageResource( mailboxExpandedIcon.setImageResource(
R.drawable.ic_mailbox_collapsed_holo_light); 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 throw new IllegalArgumentException(); // Must be QUERY_ALL_*, which are all negative
} }
if (showAlways || (count > 0)) { 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); accounts.moveToPosition(-1);
while (accounts.moveToNext()) { while (accounts.moveToNext()) {
RowBuilder row = combinedWithAccounts.newRow();
final long accountId = accounts.getLong(COLUMN_ACCOUND_ID); final long accountId = accounts.getLong(COLUMN_ACCOUND_ID);
row.add(accountId); final String accountName = accounts.getString(COLUMN_ACCOUNT_DISPLAY_NAME);
row.add(accountId);
row.add(accounts.getString(COLUMN_ACCOUNT_DISPLAY_NAME));
row.add(-1); // No mailbox type. Shouldn't really be used.
final int unreadCount = Mailbox.getUnreadCountByAccountAndMailboxType( final int unreadCount = Mailbox.getUnreadCountByAccountAndMailboxType(
mContext, accountId, Mailbox.TYPE_INBOX); mContext, accountId, Mailbox.TYPE_INBOX);
row.add(unreadCount); addMailboxRow(combinedWithAccounts, accountId, accountName, Mailbox.TYPE_NONE,
row.add(unreadCount); unreadCount, unreadCount, ROW_TYPE_ACCOUNT, Mailbox.FLAG_NONE);
row.add(ROW_TYPE_ACCOUNT);
} }
return Utility.CloseTraceCursorWrapper.get(combinedWithAccounts); return Utility.CloseTraceCursorWrapper.get(combinedWithAccounts);
} }

View File

@ -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 * Selects the given mailbox ID and possibly navigates to it. This loads any mailboxes
* within it. The mailbox is assumed to be associated with the account passed into * contained within it and may cause the mailbox list to be updated. If the current fragment
* {@link #openMailboxes(long)} * is not in the resumed state or if the mailbox cannot be navigated to, the given mailbox
* @param mailboxId The ID of the mailbox to load. * 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) { public void navigateToMailbox(long mailboxId) {
setSelectedMailbox(mailboxId); setSelectedMailbox(mailboxId);
if (mResumed) { if (mResumed && isNavigable(mailboxId)) {
startLoading(); 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. * Sets the selected mailbox to the given ID. Sub-folders will not be loaded.
* @param mailboxId The ID of the mailbox to select. * @param mailboxId The ID of the mailbox to select.
@ -502,6 +518,7 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList
// No mailbox selected // No mailbox selected
mListView.clearChoices(); mListView.clearChoices();
} else { } else {
// TODO Don't mix list view & list adapter indices. This is a recipe for disaster.
final int count = mListView.getCount(); final int count = mListView.getCount();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
if (mListAdapter.getId(i) != mSelectedMailboxId) { if (mListAdapter.getId(i) != mSelectedMailboxId) {

View File

@ -69,6 +69,11 @@ public class MailboxListItem extends RelativeLayout {
mLabelCount = (TextView)findViewById(R.id.message_count); 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) { public boolean isDropTarget(long itemMailbox) {
if ((mMailboxId < 0) || (itemMailbox == mMailboxId)) { if ((mMailboxId < 0) || (itemMailbox == mMailboxId)) {
return false; return false;

View File

@ -220,14 +220,24 @@ import android.widget.CursorAdapter;
} }
/** /**
* @return ID of the mailbox (or account, if {@link #isAccountRow} == true) of the specified * Returns the ID of the mailbox (or account, if {@link #isAccountRow} is {@code true})
* row. * of the given row.
*/ */
public long getId(int position) { public long getId(int position) {
Cursor c = (Cursor) getItem(position); Cursor c = (Cursor) getItem(position);
return c.getLong(COLUMN_ID); 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 * 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 * mailboxes to update, as this would be visually jarring