diff --git a/res/values/strings.xml b/res/values/strings.xml index 16f244fe4..3a188a5fd 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -184,6 +184,9 @@ to %1$s + + All Accounts + %1$d account @@ -216,6 +219,8 @@ Sent Junk + + Unread Version: %s diff --git a/src/com/android/email/activity/MailboxListFragment.java b/src/com/android/email/activity/MailboxListFragment.java index 25877c38f..03b456f7d 100644 --- a/src/com/android/email/activity/MailboxListFragment.java +++ b/src/com/android/email/activity/MailboxListFragment.java @@ -276,7 +276,9 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList * @return true if the top level mailboxes are shown. Safe to call even before onCreate. */ public boolean isRoot() { - return getParentMailboxId() == Mailbox.NO_MAILBOX; + // TODO if we add meta-mailboxes to the database, remove special test for account ID + return getParentMailboxId() == Mailbox.NO_MAILBOX + || getAccountId() == Account.ACCOUNT_ID_COMBINED_VIEW; } @Override diff --git a/src/com/android/email/activity/ShortcutPicker.java b/src/com/android/email/activity/ShortcutPicker.java index d68dea092..032c6057c 100644 --- a/src/com/android/email/activity/ShortcutPicker.java +++ b/src/com/android/email/activity/ShortcutPicker.java @@ -21,6 +21,7 @@ import com.android.email.activity.ShortcutPickerFragment.AccountShortcutPickerFr import com.android.email.activity.ShortcutPickerFragment.PickerCallback; import com.android.emailcommon.Logging; import com.android.emailcommon.provider.EmailContent.Account; +import com.android.emailcommon.provider.EmailContent.Message; import android.app.Activity; import android.content.Intent; @@ -121,8 +122,18 @@ public class ShortcutPicker extends Activity implements OnClickListener, PickerC shortcutIntent = MessageList.createFroyoIntent(myActivity, account); Log.d(Logging.LOG_TAG, "Created old style intent: " + shortcutIntent); } else { - String uuid = account.mCompatibilityUuid; - shortcutIntent = Welcome.createAccountShortcutIntent(myActivity, uuid, mailboxId); + // TODO if we add meta-mailboxes/accounts to the database, remove this special case + if (account.mId == Account.ACCOUNT_ID_COMBINED_VIEW) { + // For the special mailboxes, their ID is < 0. The UI list does not deal with + // negative values very well, so, add MAX_VALUE to ensure they're positive, but, + // don't clash with legitimate mailboxes. Undo that here. + long realMailboxId = mailboxId - Integer.MAX_VALUE; + shortcutIntent = Welcome.createOpenMessageIntent( + myActivity, account.mId, realMailboxId, Message.NO_MESSAGE); + } else { + String uuid = account.mCompatibilityUuid; + shortcutIntent = Welcome.createAccountShortcutIntent(myActivity, uuid, mailboxId); + } } // Then, set up the container intent (the response to the caller) diff --git a/src/com/android/email/activity/ShortcutPickerFragment.java b/src/com/android/email/activity/ShortcutPickerFragment.java index 6eb75a3ff..7cc303e44 100644 --- a/src/com/android/email/activity/ShortcutPickerFragment.java +++ b/src/com/android/email/activity/ShortcutPickerFragment.java @@ -26,10 +26,15 @@ import com.android.emailcommon.provider.Mailbox; import android.app.Activity; import android.app.ListFragment; import android.app.LoaderManager.LoaderCallbacks; +import android.content.ContentValues; import android.content.Context; import android.content.CursorLoader; import android.content.Loader; import android.database.Cursor; +import android.database.MatrixCursor; +import android.database.MergeCursor; +import android.database.MatrixCursor.RowBuilder; +import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; @@ -104,6 +109,51 @@ public abstract class ShortcutPickerFragment extends ListFragment /** Returns the cursor columns to map into list */ abstract String[] getFromColumns(); + // TODO if we add meta-accounts to the database, remove this class entirely + private static final class AccountPickerLoader extends CursorLoader { + public AccountPickerLoader(Context context, Uri uri, String[] projection, String selection, + String[] selectionArgs, String sortOrder) { + super(context, uri, projection, selection, selectionArgs, sortOrder); + } + + @Override + public Cursor loadInBackground() { + Cursor parentCursor = super.loadInBackground(); + Cursor returnCursor; + + if (parentCursor.getCount() > 1) { + // Only add "All accounts" if there is more than 1 account defined + MatrixCursor allAccountCursor = new MatrixCursor(getProjection()); + addCombinedAccountRow(allAccountCursor); + returnCursor = new MergeCursor(new Cursor[] { allAccountCursor, parentCursor }); + } else { + returnCursor = parentCursor; + } + return returnCursor; + } + + /** Adds a row for "All Accounts" into the given cursor */ + private void addCombinedAccountRow(MatrixCursor cursor) { + Context context = getContext(); + Account account = new Account(); + account.mId = Account.ACCOUNT_ID_COMBINED_VIEW; + account.mDisplayName = context.getString(R.string.account_name_display_all); + ContentValues values = account.toContentValues(); + RowBuilder row = cursor.newRow(); + for (String rowName : cursor.getColumnNames()) { + // special case some of the rows ... + if (AccountColumns.ID.equals(rowName)) { + row.add(Account.ACCOUNT_ID_COMBINED_VIEW); + continue; + } else if (AccountColumns.IS_DEFAULT.equals(rowName)) { + row.add(0); + continue; + } + row.add(values.get(rowName)); + } + } + } + /** Account picker */ public static class AccountShortcutPickerFragment extends ShortcutPickerFragment { private final static String[] ACCOUNT_FROM_COLUMNS = new String[] { @@ -125,8 +175,7 @@ public abstract class ShortcutPickerFragment extends ListFragment @Override public Loader onCreateLoader(int id, Bundle args) { Context context = getActivity(); - // TODO Add ability to insert special account "all accounts" - return new CursorLoader( + return new AccountPickerLoader( context, Account.CONTENT_URI, Account.CONTENT_PROJECTION, null, null, null); } @@ -166,6 +215,41 @@ public abstract class ShortcutPickerFragment extends ListFragment } } + // TODO if we add meta-mailboxes to the database, remove this class entirely + private static final class MailboxPickerLoader extends CursorLoader { + private final long mAccountId; + public MailboxPickerLoader(Context context, Uri uri, String[] projection, String selection, + String[] selectionArgs, String sortOrder, long accountId) { + super(context, uri, projection, selection, selectionArgs, sortOrder); + mAccountId = accountId; + } + + @Override + public Cursor loadInBackground() { + if (mAccountId == Account.ACCOUNT_ID_COMBINED_VIEW) { + // Do something special for the "combined" view + Context context = getContext(); + MatrixCursor combinedMailboxesCursor = new MatrixCursor(getProjection()); + // For the special mailboxes, their ID is < 0. The UI list does not deal with + // negative values very well, so, add MAX_VALUE to ensure they're positive, but, + // don't clash with legitimate mailboxes. + String mailboxName = context.getString(R.string.mailbox_name_display_inbox); + combinedMailboxesCursor.addRow( + new Object[] {Integer.MAX_VALUE + Mailbox.QUERY_ALL_INBOXES, mailboxName}); + // TODO Temporarily commented out. This will be added to the widget selection, so + // keeping the code around for now. If this isn't uncommented by July 1, 2011, + // feel free to remove it and this TODO +// mailboxName = context.getString(R.string.mailbox_name_display_unread); +// combinedMailboxesCursor.addRow( +// new Object[] {Integer.MAX_VALUE + Mailbox.QUERY_ALL_UNREAD, mailboxName}); + return combinedMailboxesCursor; + } + + // Loading for a regular account; perform a normal load + return super.loadInBackground(); + } + } + /** Mailbox picker */ public static class MailboxShortcutPickerFragment extends ShortcutPickerFragment { static final String ARG_ACCOUNT = "MailboxShortcutPickerFragment.account"; @@ -211,7 +295,6 @@ public abstract class ShortcutPickerFragment extends ListFragment @Override public Loader onCreateLoader(int id, Bundle args) { Context context = getActivity(); - // TODO Add ability to insert special mailboxes like "starred", etc... // TODO Create a fully-qualified path name for Exchange accounts [code should also work // for MoveMessageToDialog.java] HostAuth recvAuth = mAccount.getOrCreateHostAuthRecv(context); @@ -224,9 +307,9 @@ public abstract class ShortcutPickerFragment extends ListFragment projection = IMAP_PROJECTION; orderBy = MailboxColumns.SERVER_ID; } - return new CursorLoader( + return new MailboxPickerLoader( context, Mailbox.CONTENT_URI, projection, ALL_MAILBOX_SELECTION, - new String[] { Long.toString(mAccount.mId) }, orderBy); + new String[] { Long.toString(mAccount.mId) }, orderBy, mAccount.mId); } @Override diff --git a/src/com/android/email/activity/Welcome.java b/src/com/android/email/activity/Welcome.java index b72baf9f1..c4d4d4c91 100644 --- a/src/com/android/email/activity/Welcome.java +++ b/src/com/android/email/activity/Welcome.java @@ -221,7 +221,9 @@ public class Welcome extends Activity { // accountId will be NO_ACCOUNT if the UUID is invalid. } else if (inputAccountId != Account.NO_ACCOUNT) { - if (Account.isValidId(context, inputAccountId)) { + // TODO if we add meta-mailboxes/accounts to the database, remove this special case + if (inputAccountId == Account.ACCOUNT_ID_COMBINED_VIEW + || Account.isValidId(context, inputAccountId)) { accountId = inputAccountId; } else { accountId = Account.NO_ACCOUNT;