Add various virtual folders
* Added a starred folder for each account (only shows up if there are any starred messages) * Added a combined starred folder in the "combined" account * Use proper icon for the starred folders * Set proper counts for these folders TODO: There are probably a bunch of loose ends related to how the counts in these virtual folders get updated Change-Id: I72fcf543716583bdfcbdd50ffcac3b023a9b59e6
This commit is contained in:
parent
06fbb1354b
commit
3a4448facc
@ -178,6 +178,8 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns
|
||||
public static final int TYPE_JUNK = 7;
|
||||
/** Search results */
|
||||
public static final int TYPE_SEARCH = 8;
|
||||
/** Starred (virtual */
|
||||
public static final int TYPE_STARRED = 9;
|
||||
|
||||
// Types after this are used for non-mail mailboxes (as in EAS)
|
||||
public static final int TYPE_NOT_EMAIL = 0x40;
|
||||
@ -649,6 +651,7 @@ public class Mailbox extends EmailContent implements SyncColumns, MailboxColumns
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[Mailbox " + mId + ": " + mDisplayName + "]";
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import android.content.UriMatcher;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.database.MatrixCursor;
|
||||
import android.database.MergeCursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.net.Uri;
|
||||
@ -1192,7 +1193,6 @@ public class EmailProvider extends ContentProvider {
|
||||
case UI_UNDO:
|
||||
return uiUndo(uri, projection);
|
||||
case UI_SUBFOLDERS:
|
||||
case UI_FOLDERS:
|
||||
case UI_MESSAGES:
|
||||
case UI_MESSAGE:
|
||||
case UI_FOLDER:
|
||||
@ -1207,6 +1207,9 @@ public class EmailProvider extends ContentProvider {
|
||||
}
|
||||
c = uiQuery(match, uri, projection);
|
||||
return c;
|
||||
case UI_FOLDERS:
|
||||
c = uiFolders(uri, projection);
|
||||
return c;
|
||||
case UI_FOLDER_LOAD_MORE:
|
||||
c = uiFolderLoadMore(uri);
|
||||
return c;
|
||||
@ -2053,6 +2056,7 @@ outer:
|
||||
+ " WHEN " + Mailbox.TYPE_DRAFTS + " THEN " + R.drawable.ic_folder_drafts_holo_light
|
||||
+ " WHEN " + Mailbox.TYPE_OUTBOX + " THEN " + R.drawable.ic_folder_outbox_holo_light
|
||||
+ " WHEN " + Mailbox.TYPE_SENT + " THEN " + R.drawable.ic_folder_sent_holo_light
|
||||
+ " WHEN " + Mailbox.TYPE_STARRED + " THEN " + R.drawable.ic_menu_star_holo_light
|
||||
+ " ELSE -1 END";
|
||||
|
||||
private static final ProjectionMap sFolderListMap = ProjectionMap.builder()
|
||||
@ -2281,17 +2285,47 @@ outer:
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the "combined message list" SQLite query, given a projection from UnifiedEmail
|
||||
* Generate various virtual mailbox SQLite queries, given a projection from UnifiedEmail
|
||||
*
|
||||
* @param uiProjection as passed from UnifiedEmail
|
||||
* @param id the id of the virtual mailbox
|
||||
* @return the SQLite query to be executed on the EmailProvider database
|
||||
*/
|
||||
// TODO: This is ALL messages; should be inboxes
|
||||
private String genQueryAllMessages(String[] uiProjection) {
|
||||
private Cursor getVirtualMailboxMessagesCursor(SQLiteDatabase db, String[] uiProjection,
|
||||
long mailboxId) {
|
||||
StringBuilder sb = genSelect(sMessageListMap, uiProjection);
|
||||
sb.append(" FROM " + Message.TABLE_NAME + " ORDER BY " +
|
||||
MessageColumns.TIMESTAMP + " DESC");
|
||||
return sb.toString();
|
||||
if (isCombinedMailbox(mailboxId)) {
|
||||
switch (getVirtualMailboxType(mailboxId)) {
|
||||
case Mailbox.TYPE_INBOX:
|
||||
sb.append(" FROM " + Message.TABLE_NAME + " WHERE " +
|
||||
MessageColumns.MAILBOX_KEY + " IN (SELECT " + MailboxColumns.ID +
|
||||
" FROM " + Mailbox.TABLE_NAME + " WHERE " + MailboxColumns.TYPE +
|
||||
"=" + Mailbox.TYPE_INBOX + ") ORDER BY " + MessageColumns.TIMESTAMP +
|
||||
" DESC");
|
||||
break;
|
||||
case Mailbox.TYPE_STARRED:
|
||||
sb.append(" FROM " + Message.TABLE_NAME + " WHERE " +
|
||||
MessageColumns.FLAG_FAVORITE + "=1 ORDER BY " +
|
||||
MessageColumns.TIMESTAMP + " DESC");
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("No virtual mailbox for: " + mailboxId);
|
||||
}
|
||||
return db.rawQuery(sb.toString(), null);
|
||||
} else {
|
||||
switch (getVirtualMailboxType(mailboxId)) {
|
||||
case Mailbox.TYPE_STARRED:
|
||||
sb.append(" FROM " + Message.TABLE_NAME + " WHERE " +
|
||||
MessageColumns.ACCOUNT_KEY + "=? AND " +
|
||||
MessageColumns.FLAG_FAVORITE + "=1 ORDER BY " +
|
||||
MessageColumns.TIMESTAMP + " DESC");
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("No virtual mailbox for: " + mailboxId);
|
||||
}
|
||||
return db.rawQuery(sb.toString(),
|
||||
new String[] {getVirtualMailboxAccountIdString(mailboxId)});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2356,7 +2390,11 @@ outer:
|
||||
} else {
|
||||
Context context = getContext();
|
||||
Mailbox mailbox = Mailbox.restoreMailboxWithId(context, mailboxId);
|
||||
String protocol = Account.getProtocol(context, mailbox.mAccountKey);
|
||||
// Make sure we can't get NPE if mailbox has disappeared (the result will end up moot)
|
||||
String protocol = "eas";
|
||||
if (mailbox != null) {
|
||||
protocol = Account.getProtocol(context, mailbox.mAccountKey);
|
||||
}
|
||||
// "load more" is valid for IMAP/POP3
|
||||
if (HostAuth.SCHEME_IMAP.equals(protocol) || HostAuth.SCHEME_POP3.equals(protocol)) {
|
||||
values.put(UIProvider.FolderColumns.LOAD_MORE_URI,
|
||||
@ -2513,6 +2551,8 @@ outer:
|
||||
return "content://" + EmailContent.AUTHORITY + "/" + type + "/" + id;
|
||||
}
|
||||
|
||||
private static final long COMBINED_ACCOUNT_ID = 0x10000000;
|
||||
|
||||
/**
|
||||
* Generate an id for a combined mailbox of a given type
|
||||
* @param type the mailbox type for the combined mailbox
|
||||
@ -2522,6 +2562,34 @@ outer:
|
||||
return Long.toString(Account.ACCOUNT_ID_COMBINED_VIEW + type);
|
||||
}
|
||||
|
||||
private static String getVirtualMailboxIdString(long accountId, int type) {
|
||||
return Long.toString(getVirtualMailboxId(accountId, type));
|
||||
}
|
||||
|
||||
private static long getVirtualMailboxId(long accountId, int type) {
|
||||
return (accountId << 32) + type;
|
||||
}
|
||||
|
||||
private static boolean isVirtualMailbox(long mailboxId) {
|
||||
return mailboxId >= 0x100000000L;
|
||||
}
|
||||
|
||||
private static boolean isCombinedMailbox(long mailboxId) {
|
||||
return (mailboxId >> 32) == COMBINED_ACCOUNT_ID;
|
||||
}
|
||||
|
||||
private static long getVirtualMailboxAccountId(long mailboxId) {
|
||||
return mailboxId >> 32;
|
||||
}
|
||||
|
||||
private static String getVirtualMailboxAccountIdString(long mailboxId) {
|
||||
return Long.toString(mailboxId >> 32);
|
||||
}
|
||||
|
||||
private static int getVirtualMailboxType(long mailboxId) {
|
||||
return (int)(mailboxId & 0xF);
|
||||
}
|
||||
|
||||
private void addCombinedAccountRow(MatrixCursor mc) {
|
||||
long id = Account.getDefaultAccountId(getContext());
|
||||
if (id == Account.NO_ACCOUNT) return;
|
||||
@ -2569,18 +2637,25 @@ outer:
|
||||
mc.addRow(values);
|
||||
}
|
||||
|
||||
private void addCombinedInboxRow(MatrixCursor mc) {
|
||||
private Cursor getVirtualMailboxCursor(long mailboxId) {
|
||||
MatrixCursor mc = new MatrixCursor(UIProvider.FOLDERS_PROJECTION, 1);
|
||||
mc.addRow(getVirtualMailboxRow(getVirtualMailboxAccountId(mailboxId),
|
||||
getVirtualMailboxType(mailboxId)));
|
||||
return mc;
|
||||
}
|
||||
|
||||
private Object[] getVirtualMailboxRow(long accountId, int mailboxType) {
|
||||
String idString = getVirtualMailboxIdString(accountId, mailboxType);
|
||||
Object[] values = new Object[UIProvider.FOLDERS_PROJECTION.length];
|
||||
values[UIProvider.FOLDER_ID_COLUMN] = 0;
|
||||
values[UIProvider.FOLDER_URI_COLUMN] = combinedUriString("uifolder",
|
||||
combinedMailboxId(Mailbox.TYPE_INBOX));
|
||||
values[UIProvider.FOLDER_NAME_COLUMN] = getContext().getString(R.string.widget_all_mail);
|
||||
values[UIProvider.FOLDER_URI_COLUMN] = combinedUriString("uifolder", idString);
|
||||
values[UIProvider.FOLDER_NAME_COLUMN] = getMailboxNameForType(mailboxType);
|
||||
values[UIProvider.FOLDER_HAS_CHILDREN_COLUMN] = 0;
|
||||
values[UIProvider.FOLDER_CAPABILITIES_COLUMN] = 0;
|
||||
values[UIProvider.FOLDER_CONVERSATION_LIST_URI_COLUMN] = combinedUriString("uimessages",
|
||||
combinedMailboxId(Mailbox.TYPE_INBOX));
|
||||
idString);
|
||||
values[UIProvider.FOLDER_ID_COLUMN] = 0;
|
||||
mc.addRow(values);
|
||||
return values;
|
||||
}
|
||||
|
||||
private Cursor uiAccounts(String[] uiProjection) {
|
||||
@ -2662,14 +2737,48 @@ outer:
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static final String COMBINED_ACCOUNT_ID_STRING =
|
||||
Long.toString(Account.ACCOUNT_ID_COMBINED_VIEW);
|
||||
private static final String COMBINED_ACCOUNT_ID_STRING = Long.toString(COMBINED_ACCOUNT_ID);
|
||||
|
||||
|
||||
private Cursor getCombinedInboxCursor() {
|
||||
MatrixCursor mc = new MatrixCursor(UIProvider.FOLDERS_PROJECTION, 1);
|
||||
addCombinedInboxRow(mc);
|
||||
return mc;
|
||||
private Cursor uiFolders(Uri uri, String[] uiProjection) {
|
||||
Context context = getContext();
|
||||
SQLiteDatabase db = getDatabase(context);
|
||||
String id = uri.getPathSegments().get(1);
|
||||
if (id.equals(COMBINED_ACCOUNT_ID_STRING)) {
|
||||
MatrixCursor mc = new MatrixCursor(UIProvider.FOLDERS_PROJECTION, 2);
|
||||
Object[] row = getVirtualMailboxRow(COMBINED_ACCOUNT_ID, Mailbox.TYPE_INBOX);
|
||||
int numUnread = EmailContent.count(context, Message.CONTENT_URI,
|
||||
MessageColumns.MAILBOX_KEY + " IN (SELECT " + MailboxColumns.ID +
|
||||
" FROM " + Mailbox.TABLE_NAME + " WHERE " + MailboxColumns.TYPE +
|
||||
"=" + Mailbox.TYPE_INBOX + ") AND " + MessageColumns.FLAG_READ + "=0", null);
|
||||
row[UIProvider.FOLDER_UNREAD_COUNT_COLUMN] = numUnread;
|
||||
mc.addRow(row);
|
||||
int numStarred = EmailContent.count(context, Message.CONTENT_URI,
|
||||
MessageColumns.FLAG_FAVORITE + "=1", null);
|
||||
if (numStarred > 0) {
|
||||
row = getVirtualMailboxRow(COMBINED_ACCOUNT_ID, Mailbox.TYPE_STARRED);
|
||||
row[UIProvider.FOLDER_UNREAD_COUNT_COLUMN] = numStarred;
|
||||
mc.addRow(row);
|
||||
}
|
||||
return mc;
|
||||
} else {
|
||||
Cursor c = db.rawQuery(genQueryAccountMailboxes(uiProjection), new String[] {id});
|
||||
int numStarred = EmailContent.count(context, Message.CONTENT_URI,
|
||||
MessageColumns.ACCOUNT_KEY + "=? AND " + MessageColumns.FLAG_FAVORITE + "=1",
|
||||
new String[] {id});
|
||||
if (numStarred == 0) {
|
||||
return c;
|
||||
} else {
|
||||
// Add starred virtual folder to the cursor
|
||||
// Show number of messages as unread count (for backward compatibility)
|
||||
MatrixCursor starCursor = new MatrixCursor(uiProjection, 1);
|
||||
Object[] row = getVirtualMailboxRow(Long.parseLong(id), Mailbox.TYPE_STARRED);
|
||||
row[UIProvider.FOLDER_UNREAD_COUNT_COLUMN] = numStarred;
|
||||
row[UIProvider.FOLDER_ICON_RES_ID_COLUMN] = R.drawable.ic_menu_star_holo_light;
|
||||
starCursor.addRow(row);
|
||||
Cursor[] cursors = new Cursor[] {starCursor, c};
|
||||
return new MergeCursor(cursors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2689,13 +2798,6 @@ outer:
|
||||
String id = uri.getPathSegments().get(1);
|
||||
Uri notifyUri = null;
|
||||
switch(match) {
|
||||
case UI_FOLDERS:
|
||||
if (id.equals(COMBINED_ACCOUNT_ID_STRING)) {
|
||||
c = getCombinedInboxCursor();
|
||||
} else {
|
||||
c = db.rawQuery(genQueryAccountMailboxes(uiProjection), new String[] {id});
|
||||
}
|
||||
break;
|
||||
case UI_RECENT_FOLDERS:
|
||||
c = db.rawQuery(genQueryRecentMailboxes(uiProjection), new String[] {id});
|
||||
break;
|
||||
@ -2703,8 +2805,9 @@ outer:
|
||||
c = db.rawQuery(genQuerySubfolders(uiProjection), new String[] {id});
|
||||
break;
|
||||
case UI_MESSAGES:
|
||||
if (id.equals(COMBINED_ACCOUNT_ID_STRING)) {
|
||||
c = db.rawQuery(genQueryAllMessages(uiProjection), null);
|
||||
long mailboxId = Long.parseLong(id);
|
||||
if (isVirtualMailbox(mailboxId)) {
|
||||
c = getVirtualMailboxMessagesCursor(db, uiProjection, mailboxId);
|
||||
} else {
|
||||
c = db.rawQuery(genQueryMailboxMessages(uiProjection), new String[] {id});
|
||||
}
|
||||
@ -2722,8 +2825,9 @@ outer:
|
||||
notifyUri = UIPROVIDER_ATTACHMENT_NOTIFIER.buildUpon().appendPath(id).build();
|
||||
break;
|
||||
case UI_FOLDER:
|
||||
if (id.equals(combinedMailboxId(Mailbox.TYPE_INBOX))) {
|
||||
c = getCombinedInboxCursor();
|
||||
mailboxId = Long.parseLong(id);
|
||||
if (isVirtualMailbox(mailboxId)) {
|
||||
c = getVirtualMailboxCursor(mailboxId);
|
||||
} else {
|
||||
c = db.rawQuery(genQueryMailbox(uiProjection, id), new String[] {id});
|
||||
notifyUri = UIPROVIDER_FOLDER_NOTIFIER.buildUpon().appendPath(id).build();
|
||||
@ -2765,12 +2869,9 @@ outer:
|
||||
return att;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mailbox given the account and mailboxType.
|
||||
*/
|
||||
private Mailbox createMailbox(long accountId, int mailboxType) {
|
||||
private String getMailboxNameForType(int mailboxType) {
|
||||
Context context = getContext();
|
||||
int resId = -1;
|
||||
int resId;
|
||||
switch (mailboxType) {
|
||||
case Mailbox.TYPE_INBOX:
|
||||
resId = R.string.mailbox_name_server_inbox;
|
||||
@ -2790,10 +2891,22 @@ outer:
|
||||
case Mailbox.TYPE_JUNK:
|
||||
resId = R.string.mailbox_name_server_junk;
|
||||
break;
|
||||
case Mailbox.TYPE_STARRED:
|
||||
resId = R.string.widget_starred;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Illegal mailbox type");
|
||||
}
|
||||
Mailbox box = Mailbox.newSystemMailbox(accountId, mailboxType, context.getString(resId));
|
||||
return context.getString(resId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mailbox given the account and mailboxType.
|
||||
*/
|
||||
private Mailbox createMailbox(long accountId, int mailboxType) {
|
||||
Context context = getContext();
|
||||
Mailbox box = Mailbox.newSystemMailbox(accountId, mailboxType,
|
||||
getMailboxNameForType(mailboxType));
|
||||
// Make sure drafts and save will show up in recents...
|
||||
// If these already exist (from old Email app), they will have touch times
|
||||
switch (mailboxType) {
|
||||
|
Loading…
Reference in New Issue
Block a user