mirror of
https://github.com/moparisthebest/k-9
synced 2025-02-11 20:50:19 -05:00
For EAS accounts, display folder names in the list with parent folder information (i.e., parent/child). Also add support for updating folder names when refreshing the folder list.
This commit is contained in:
parent
4964fe9e6d
commit
0d368c916a
@ -503,19 +503,22 @@ public class MessagingController implements Runnable {
|
||||
private void syncLocalFoldersWithRemoteFolders(List<? extends Folder> localFolders,
|
||||
List<? extends Folder> remoteFolders, final Account account) throws MessagingException {
|
||||
HashSet<String> remoteFolderNames = new HashSet<String>();
|
||||
HashSet<String> localFolderNames = new HashSet<String>();
|
||||
HashMap<String, Folder> localFolderMap = new HashMap<String, Folder>();
|
||||
|
||||
List<LocalFolder> foldersToCreate = new LinkedList<LocalFolder>();
|
||||
LocalStore localStore = account.getLocalStore();
|
||||
|
||||
for (Folder localFolder : localFolders) {
|
||||
localFolderNames.add(localFolder.getRemoteName());
|
||||
localFolderMap.put(localFolder.getRemoteName(), localFolder);
|
||||
}
|
||||
|
||||
// Add any new folders in the remote store to the local store.
|
||||
for (Folder remoteFolder : remoteFolders) {
|
||||
if (!localFolderNames.contains(remoteFolder.getRemoteName())) {
|
||||
Folder localFolder = localFolderMap.get(remoteFolder.getRemoteName());
|
||||
if (localFolder == null) {
|
||||
foldersToCreate.add(localStore.getFolder(remoteFolder.getRemoteName(), remoteFolder.getName()));
|
||||
} else {
|
||||
((LocalFolder)localFolder).setName(remoteFolder.getName());
|
||||
}
|
||||
remoteFolderNames.add(remoteFolder.getRemoteName());
|
||||
}
|
||||
|
@ -219,10 +219,6 @@ public abstract class Folder {
|
||||
return mAccount;
|
||||
}
|
||||
|
||||
public boolean isSyncMode() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getPushState() {
|
||||
return null;
|
||||
}
|
||||
|
@ -91,8 +91,9 @@ public class EasStore extends Store {
|
||||
private static final Message[] EMPTY_MESSAGE_ARRAY = new Message[0];
|
||||
|
||||
// This key is sent the first time we sync the folder hierarchy, and also the first time
|
||||
// we sync the items any "collection" (emails in a folder).
|
||||
// we sync the items any "collection" (i.e., emails in a folder).
|
||||
public static final String INITIAL_SYNC_KEY = "0";
|
||||
private static final String NO_PARENT_ID = "0";
|
||||
|
||||
private static final String PING_COMMAND = "Ping";
|
||||
private static final String PROVISION_COMMAND = "Provision";
|
||||
@ -812,13 +813,12 @@ public class EasStore extends Store {
|
||||
|
||||
for (Folder folder : folderList) {
|
||||
EasFolder easFolder = (EasFolder)folder;
|
||||
// K-9 has its own special Outbox folder that works similar to the one on the
|
||||
// Exchange server. Adding this one will cause 2 Outbox folders in our list.
|
||||
if (easFolder.mType != FolderSyncParser.OUTBOX_TYPE) {
|
||||
mFolderList.put(easFolder.getRemoteName(), easFolder);
|
||||
easFolder.setSyncKey(syncKeys.get(easFolder.getRemoteName()));
|
||||
}
|
||||
mFolderList.put(easFolder.getRemoteName(), easFolder);
|
||||
easFolder.setSyncKey(syncKeys.get(easFolder.getRemoteName()));
|
||||
}
|
||||
|
||||
// We need to update all folder display names based on parenting.
|
||||
resolveFolderDisplayNames(mFolderList);
|
||||
}
|
||||
|
||||
for (Folder folder : folderList) {
|
||||
@ -893,6 +893,32 @@ public class EasStore extends Store {
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveFolderDisplayNames(HashMap<String, EasFolder> folderMap) {
|
||||
for (Entry<String, EasFolder> entry : folderMap.entrySet()) {
|
||||
String parentId = entry.getValue().getParentId();
|
||||
if (parentId != null && !parentId.equals(NO_PARENT_ID)) {
|
||||
resolveOneFolderDisplayName(entry.getValue(), folderMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveOneFolderDisplayName(EasFolder folder, HashMap<String, EasFolder> folderMap) {
|
||||
EasFolder parentFolder = folderMap.get(folder.getParentId());
|
||||
if (parentFolder != null) {
|
||||
String parentId = parentFolder.getParentId();
|
||||
if (parentId != null && !parentId.equals(NO_PARENT_ID)) {
|
||||
// Recurse to ensure the folder's name is complete before continuing.
|
||||
resolveOneFolderDisplayName(parentFolder, folderMap);
|
||||
}
|
||||
|
||||
String name = parentFolder.getName();
|
||||
folder.mName = name + "/" + folder.mName;
|
||||
// We only need to update the name once, reset the parent Id so we don't waste
|
||||
// cycles doing it again.
|
||||
folder.setParentId(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Folder getFolder(String serverId) {
|
||||
if (getStoreSyncKey().equals(INITIAL_SYNC_KEY)) {
|
||||
@ -1021,6 +1047,7 @@ public class EasStore extends Store {
|
||||
private String mName;
|
||||
private String mServerId;
|
||||
private int mType;
|
||||
private String mParentId = null;
|
||||
private boolean mIsOpen = false;
|
||||
private String mSyncKey = null;
|
||||
|
||||
@ -1035,6 +1062,14 @@ public class EasStore extends Store {
|
||||
mType = type;
|
||||
}
|
||||
|
||||
public String getParentId() {
|
||||
return mParentId;
|
||||
}
|
||||
|
||||
public void setParentId(String parentId) {
|
||||
mParentId = parentId;
|
||||
}
|
||||
|
||||
public String getSyncKey() throws MessagingException {
|
||||
if (mSyncKey == null) {
|
||||
Log.d(K9.LOG_TAG, "Reset SyncKey to 0");
|
||||
@ -1047,11 +1082,6 @@ public class EasStore extends Store {
|
||||
mSyncKey = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSyncMode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(OpenMode mode) throws MessagingException {
|
||||
mIsOpen = true;
|
||||
|
@ -1241,6 +1241,11 @@ public class LocalStore extends Store implements Serializable {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public void setName(String name) throws MessagingException {
|
||||
mName = name;
|
||||
updateFolderColumn("name", mName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() throws MessagingException {
|
||||
return database.execute(false, new DbCallback<Boolean>() {
|
||||
|
@ -19,11 +19,9 @@ package com.fsck.k9.mail.store.exchange.adapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.util.Log;
|
||||
|
||||
import com.fsck.k9.K9;
|
||||
@ -56,26 +54,10 @@ public class FolderSyncParser extends Parser {
|
||||
public static final int USER_MAILBOX_TYPE = 12;
|
||||
|
||||
public static final List<Integer> mValidFolderTypes = Arrays.asList(INBOX_TYPE, DRAFTS_TYPE,
|
||||
DELETED_TYPE, SENT_TYPE, OUTBOX_TYPE, USER_MAILBOX_TYPE);//, CALENDAR_TYPE, CONTACTS_TYPE);
|
||||
DELETED_TYPE, SENT_TYPE, USER_MAILBOX_TYPE);
|
||||
// OUTBOX_TYPE is not included because K-9 uses its own special outbox. Adding the remote folder
|
||||
// causes duplicate folder names.
|
||||
|
||||
// public static final String ALL_BUT_ACCOUNT_MAILBOX = MailboxColumns.ACCOUNT_KEY + "=? and " +
|
||||
// MailboxColumns.TYPE + "!=" + Mailbox.TYPE_EAS_ACCOUNT_MAILBOX;
|
||||
//
|
||||
// private static final String WHERE_SERVER_ID_AND_ACCOUNT = MailboxColumns.SERVER_ID + "=? and " +
|
||||
// MailboxColumns.ACCOUNT_KEY + "=?";
|
||||
//
|
||||
// private static final String WHERE_DISPLAY_NAME_AND_ACCOUNT = MailboxColumns.DISPLAY_NAME +
|
||||
// "=? and " + MailboxColumns.ACCOUNT_KEY + "=?";
|
||||
//
|
||||
// private static final String WHERE_PARENT_SERVER_ID_AND_ACCOUNT =
|
||||
// MailboxColumns.PARENT_SERVER_ID +"=? and " + MailboxColumns.ACCOUNT_KEY + "=?";
|
||||
//
|
||||
// private static final String[] MAILBOX_ID_COLUMNS_PROJECTION =
|
||||
// new String[] {MailboxColumns.ID, MailboxColumns.SERVER_ID};
|
||||
|
||||
// private long mAccountId;
|
||||
// private String mAccountIdAsString;
|
||||
// private String[] mBindArguments = new String[2];
|
||||
private List<Folder> folderList;
|
||||
|
||||
private EasStore easStore;
|
||||
@ -85,15 +67,12 @@ public class FolderSyncParser extends Parser {
|
||||
|
||||
this.easStore = easStore;
|
||||
this.folderList = folderList;
|
||||
// mAccountId = mAccount.mId;
|
||||
// mAccountIdAsString = Long.toString(mAccountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean parse() throws IOException {
|
||||
int status;
|
||||
boolean res = false;
|
||||
boolean resetFolders = false;
|
||||
if (nextTag(START_DOCUMENT) != Tags.FOLDER_FOLDER_SYNC)
|
||||
throw new EasParserException();
|
||||
while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
|
||||
@ -104,12 +83,8 @@ public class FolderSyncParser extends Parser {
|
||||
if (status == Eas.FOLDER_STATUS_INVALID_KEY) {
|
||||
easStore.setStoreSyncKey("0");
|
||||
Log.e(K9.LOG_TAG, "Bad sync key; RESET and delete all folders");
|
||||
// mContentResolver.delete(Mailbox.CONTENT_URI, ALL_BUT_ACCOUNT_MAILBOX,
|
||||
// new String[] {Long.toString(mAccountId)});
|
||||
// // Stop existing syncs and reconstruct _main
|
||||
// SyncManager.stopNonAccountMailboxSyncsForAccount(mAccountId);
|
||||
// EASTODO
|
||||
res = true;
|
||||
resetFolders = true;
|
||||
} else {
|
||||
// Other errors are at the server, so let's throw an error that will
|
||||
// cause this sync to be retried at a later time
|
||||
@ -122,54 +97,27 @@ public class FolderSyncParser extends Parser {
|
||||
userLog("New Account SyncKey: ", easStore.getStoreSyncKey());
|
||||
} else if (tag == Tags.FOLDER_CHANGES) {
|
||||
changesParser();
|
||||
} else
|
||||
} else {
|
||||
skipTag();
|
||||
}
|
||||
}
|
||||
// synchronized (mService.getSynchronizer()) {
|
||||
// if (!mService.isStopped() || resetFolders) {
|
||||
// ContentValues cv = new ContentValues();
|
||||
// cv.put(AccountColumns.SYNC_KEY, mAccount.mSyncKey);
|
||||
// mAccount.update(mContext, cv);
|
||||
// userLog("Leaving FolderSyncParser with Account syncKey=", mAccount.mSyncKey);
|
||||
// }
|
||||
// }
|
||||
return res;
|
||||
}
|
||||
|
||||
// private Cursor getServerIdCursor(String serverId) {
|
||||
// mBindArguments[0] = serverId;
|
||||
// mBindArguments[1] = mAccountIdAsString;
|
||||
// return mContentResolver.query(Mailbox.CONTENT_URI, EmailContent.ID_PROJECTION,
|
||||
// WHERE_SERVER_ID_AND_ACCOUNT, mBindArguments, null);
|
||||
// }
|
||||
//
|
||||
public void deleteParser(ArrayList<ContentProviderOperation> ops) throws IOException {
|
||||
public void deleteParser() throws IOException {
|
||||
/* Right now we only do full refreshes on the folder list.
|
||||
while (nextTag(Tags.FOLDER_DELETE) != END) {
|
||||
switch (tag) {
|
||||
case Tags.FOLDER_SERVER_ID:
|
||||
String serverId = getValue();
|
||||
// // Find the mailbox in this account with the given serverId
|
||||
// Cursor c = getServerIdCursor(serverId);
|
||||
// try {
|
||||
// if (c.moveToFirst()) {
|
||||
// userLog("Deleting ", serverId);
|
||||
// ops.add(ContentProviderOperation.newDelete(
|
||||
// ContentUris.withAppendedId(Mailbox.CONTENT_URI,
|
||||
// c.getLong(0))).build());
|
||||
// AttachmentProvider.deleteAllMailboxAttachmentFiles(mContext,
|
||||
// mAccountId, mMailbox.mId);
|
||||
// }
|
||||
// } finally {
|
||||
// c.close();
|
||||
// }
|
||||
break;
|
||||
default:
|
||||
skipTag();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
public void addParser(ArrayList<ContentProviderOperation> ops) throws IOException {
|
||||
public void addParser() throws IOException {
|
||||
String name = null;
|
||||
String serverId = null;
|
||||
String parentId = null;
|
||||
@ -198,61 +146,19 @@ public class FolderSyncParser extends Parser {
|
||||
}
|
||||
}
|
||||
if (mValidFolderTypes.contains(type)) {
|
||||
Folder folder = easStore.new EasFolder(name, serverId, type);
|
||||
EasStore.EasFolder folder = easStore.new EasFolder(name, serverId, type);
|
||||
folderList.add(folder);
|
||||
// Mailbox m = new Mailbox();
|
||||
// m.mDisplayName = name;
|
||||
// m.mServerId = serverId;
|
||||
// m.mAccountKey = mAccountId;
|
||||
// m.mType = Mailbox.TYPE_MAIL;
|
||||
// // Note that all mailboxes default to checking "never" (i.e. manual sync only)
|
||||
// // We set specific intervals for inbox, contacts, and (eventually) calendar
|
||||
// m.mSyncInterval = Mailbox.CHECK_INTERVAL_NEVER;
|
||||
// switch (type) {
|
||||
// case INBOX_TYPE:
|
||||
// m.mType = Mailbox.TYPE_INBOX;
|
||||
// m.mSyncInterval = mAccount.mSyncInterval;
|
||||
// break;
|
||||
// case CONTACTS_TYPE:
|
||||
// m.mType = Mailbox.TYPE_CONTACTS;
|
||||
// m.mSyncInterval = mAccount.mSyncInterval;
|
||||
// break;
|
||||
// case OUTBOX_TYPE:
|
||||
// // TYPE_OUTBOX mailboxes are known by SyncManager to sync whenever they aren't
|
||||
// // empty. The value of mSyncFrequency is ignored for this kind of mailbox.
|
||||
// m.mType = Mailbox.TYPE_OUTBOX;
|
||||
// break;
|
||||
// case SENT_TYPE:
|
||||
// m.mType = Mailbox.TYPE_SENT;
|
||||
// break;
|
||||
// case DRAFTS_TYPE:
|
||||
// m.mType = Mailbox.TYPE_DRAFTS;
|
||||
// break;
|
||||
// case DELETED_TYPE:
|
||||
// m.mType = Mailbox.TYPE_TRASH;
|
||||
// break;
|
||||
// case CALENDAR_TYPE:
|
||||
// m.mType = Mailbox.TYPE_CALENDAR;
|
||||
// m.mSyncInterval = mAccount.mSyncInterval;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// // Make boxes like Contacts and Calendar invisible in the folder list
|
||||
// m.mFlagVisible = (m.mType < Mailbox.TYPE_NOT_EMAIL);
|
||||
//
|
||||
// if (!parentId.equals("0")) {
|
||||
// m.mParentServerId = parentId;
|
||||
// }
|
||||
//
|
||||
// userLog("Adding mailbox: ", m.mDisplayName);
|
||||
// ops.add(ContentProviderOperation
|
||||
// .newInsert(Mailbox.CONTENT_URI).withValues(m.toContentValues()).build());
|
||||
|
||||
if (parentId != null) {
|
||||
folder.setParentId(parentId);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public void updateParser(ArrayList<ContentProviderOperation> ops) throws IOException {
|
||||
public void updateParser() throws IOException {
|
||||
/* Right now we only do full refreshes on the folder list.
|
||||
String serverId = null;
|
||||
String displayName = null;
|
||||
String parentId = null;
|
||||
@ -272,98 +178,27 @@ public class FolderSyncParser extends Parser {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We'll make a change if one of parentId or displayName are specified
|
||||
// serverId is required, but let's be careful just the same
|
||||
if (serverId != null && (displayName != null || parentId != null)) {
|
||||
// Cursor c = getServerIdCursor(serverId);
|
||||
// try {
|
||||
// // If we find the mailbox (using serverId), make the change
|
||||
// if (c.moveToFirst()) {
|
||||
// userLog("Updating ", serverId);
|
||||
// ContentValues cv = new ContentValues();
|
||||
// if (displayName != null) {
|
||||
// cv.put(Mailbox.DISPLAY_NAME, displayName);
|
||||
// }
|
||||
// if (parentId != null) {
|
||||
// cv.put(Mailbox.PARENT_SERVER_ID, parentId);
|
||||
// }
|
||||
// ops.add(ContentProviderOperation.newUpdate(
|
||||
// ContentUris.withAppendedId(Mailbox.CONTENT_URI,
|
||||
// c.getLong(0))).withValues(cv).build());
|
||||
// }
|
||||
// } finally {
|
||||
// c.close();
|
||||
// }
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
public void changesParser() throws IOException {
|
||||
// Keep track of new boxes, deleted boxes, updated boxes
|
||||
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
|
||||
|
||||
while (nextTag(Tags.FOLDER_CHANGES) != END) {
|
||||
if (tag == Tags.FOLDER_ADD) {
|
||||
addParser(ops);
|
||||
addParser();
|
||||
} else if (tag == Tags.FOLDER_DELETE) {
|
||||
deleteParser(ops);
|
||||
deleteParser();
|
||||
} else if (tag == Tags.FOLDER_UPDATE) {
|
||||
updateParser(ops);
|
||||
updateParser();
|
||||
} else if (tag == Tags.FOLDER_COUNT) {
|
||||
getValueInt();
|
||||
} else
|
||||
} else {
|
||||
skipTag();
|
||||
}
|
||||
}
|
||||
|
||||
// // The mock stream is used for junit tests, so that the parsing code can be tested
|
||||
// // separately from the provider code.
|
||||
// // TODO Change tests to not require this; remove references to the mock stream
|
||||
// if (mMock != null) {
|
||||
// mMock.setResult(null);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Create the new mailboxes in a single batch operation
|
||||
// Don't save any data if the service has been stopped
|
||||
// synchronized (mService.getSynchronizer()) {
|
||||
if (!ops.isEmpty()/* && !mService.isStopped()*/) {
|
||||
userLog("Applying ", ops.size(), " mailbox operations.");
|
||||
|
||||
// Execute the batch
|
||||
// try {
|
||||
// mContentResolver.applyBatch(EmailProvider.EMAIL_AUTHORITY, ops);
|
||||
userLog("New Account SyncKey: ", easStore.getStoreSyncKey());
|
||||
// } catch (RemoteException e) {
|
||||
// // There is nothing to be done here; fail by returning null
|
||||
// } catch (OperationApplicationException e) {
|
||||
// // There is nothing to be done here; fail by returning null
|
||||
// }
|
||||
|
||||
// // Look for sync issues and its children and delete them
|
||||
// // I'm not aware of any other way to deal with this properly
|
||||
// mBindArguments[0] = "Sync Issues";
|
||||
// mBindArguments[1] = mAccountIdAsString;
|
||||
// Cursor c = mContentResolver.query(Mailbox.CONTENT_URI,
|
||||
// MAILBOX_ID_COLUMNS_PROJECTION, WHERE_DISPLAY_NAME_AND_ACCOUNT,
|
||||
// mBindArguments, null);
|
||||
// String parentServerId = null;
|
||||
// long id = 0;
|
||||
// try {
|
||||
// if (c.moveToFirst()) {
|
||||
// id = c.getLong(0);
|
||||
// parentServerId = c.getString(1);
|
||||
// }
|
||||
// } finally {
|
||||
// c.close();
|
||||
// }
|
||||
// if (parentServerId != null) {
|
||||
// mContentResolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, id),
|
||||
// null, null);
|
||||
// mBindArguments[0] = parentServerId;
|
||||
// mContentResolver.delete(Mailbox.CONTENT_URI, WHERE_PARENT_SERVER_ID_AND_ACCOUNT,
|
||||
// mBindArguments);
|
||||
// }
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
void userLog(String ...strings) {
|
||||
@ -373,5 +208,4 @@ public class FolderSyncParser extends Parser {
|
||||
void userLog(String string, int num, String string2) {
|
||||
Log.i(K9.LOG_TAG, string + num + string2);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user