mirror of
https://github.com/moparisthebest/k-9
synced 2024-12-24 08:38:51 -05:00
Implementation of complete IMAP two-phase "delete/expunge" behavior.
On each IMAP account, the expunge behavior can be set to expunge messages in a folder as soon as a move or delete is performed on the folder ("immediately"), each time the folder is polled, or only when executed manually. In the Message List, there is now an Expunge action in the option menu. In the Folder List, there is now an Expunge action in the context menu (long-press on the folder). For IMAP accounts, it is also possible to disable the copying of deleted messages to the Trash folder, by setting the Trash folder to -NONE-. Fixes Issue 536. Separately, in WebDAV accounts, the user can now choose the server-side equivalents of the special folders, just like for IMAP.
This commit is contained in:
parent
369718f8c0
commit
41d7ca51a3
@ -24,5 +24,9 @@
|
||||
android:id="@+id/folder_settings"
|
||||
android:title="@string/folder_settings_action"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/expunge"
|
||||
android:title="@string/expunge_action"
|
||||
/>
|
||||
|
||||
</menu>
|
||||
|
@ -130,4 +130,8 @@
|
||||
android:title="@string/account_settings_action"
|
||||
android:icon="@android:drawable/ic_menu_preferences"
|
||||
/>
|
||||
<item
|
||||
android:id="@+id/expunge"
|
||||
android:title="@string/expunge_action"
|
||||
/>
|
||||
</menu>
|
||||
|
@ -184,6 +184,18 @@
|
||||
<item>3</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="account_setup_expunge_policy_entries">
|
||||
<item>@string/account_setup_expunge_policy_immediately</item>
|
||||
<item>@string/account_setup_expunge_policy_on_poll</item>
|
||||
<item>@string/account_setup_expunge_policy_manual</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="account_setup_expunge_policy_values">
|
||||
<item>EXPUNGE_IMMEDIATELY</item>
|
||||
<item>EXPUNGE_ON_POLL</item>
|
||||
<item>EXPUNGE_MANUALLY</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="settings_theme_entries">
|
||||
<item>@string/setting_theme_light</item>
|
||||
<item>@string/setting_theme_dark</item>
|
||||
|
@ -88,6 +88,7 @@
|
||||
<string name="add_attachment_action">Add attachment</string>
|
||||
<string name="dump_settings_action">Dump settings</string>
|
||||
<string name="empty_trash_action">Empty Trash</string>
|
||||
<string name="expunge_action">Expunge</string>
|
||||
<string name="set_sort_action">Choose sort</string>
|
||||
<string name="reverse_sort_action">Reverse sort</string>
|
||||
<string name="about_action">About</string>
|
||||
@ -310,6 +311,11 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
|
||||
<string name="account_setup_incoming_delete_policy_7days_label">After 7 days</string>
|
||||
<string name="account_setup_incoming_delete_policy_delete_label">Delete from server</string>
|
||||
<string name="account_setup_incoming_delete_policy_markread_label">Mark as read on server</string>
|
||||
|
||||
<string name="account_setup_expunge_policy_label">Expunge messages</string>
|
||||
<string name="account_setup_expunge_policy_immediately">Immediately after move or copy</string>
|
||||
<string name="account_setup_expunge_policy_on_poll">During each poll</string>
|
||||
<string name="account_setup_expunge_policy_manual">Only manually</string>
|
||||
|
||||
<string name="account_setup_incoming_imap_path_prefix_label">IMAP path prefix</string>
|
||||
<string name="account_setup_incoming_imap_path_prefix_hint">(Automatic using NAMESPACE if available)</string>
|
||||
|
@ -87,6 +87,13 @@
|
||||
android:entryValues="@array/account_setup_delete_policy_values"
|
||||
android:dialogTitle="@string/account_setup_incoming_delete_policy_label" />
|
||||
|
||||
<ListPreference
|
||||
android:key="expunge_policy"
|
||||
android:title="@string/account_setup_expunge_policy_label"
|
||||
android:entries="@array/account_setup_expunge_policy_entries"
|
||||
android:entryValues="@array/account_setup_expunge_policy_values"
|
||||
android:dialogTitle="@string/account_setup_expunge_policy_label" />
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="incoming"
|
||||
android:title="@string/account_settings_incoming_label"
|
||||
|
@ -58,6 +58,7 @@ public class Account implements Serializable
|
||||
HideButtons mHideMessageViewButtons;
|
||||
boolean mIsSignatureBeforeQuotedText;
|
||||
boolean mLeftHanded;
|
||||
public String mExpungePolicy = EXPUNGE_IMMEDIATELY;
|
||||
|
||||
List<Identity> identities;
|
||||
|
||||
@ -71,6 +72,10 @@ public class Account implements Serializable
|
||||
NEVER, ALWAYS, KEYBOARD_AVAILABLE;
|
||||
}
|
||||
|
||||
public static final String EXPUNGE_IMMEDIATELY = "EXPUNGE_IMMEDIATELY";
|
||||
public static final String EXPUNGE_MANUALLY = "EXPUNGE_MANUALLY";
|
||||
public static final String EXPUNGE_ON_POLL = "EXPUNGE_ON_POLL";
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 0 Never
|
||||
@ -194,6 +199,7 @@ public class Account implements Serializable
|
||||
"Trash");
|
||||
mOutboxFolderName = preferences.getPreferences().getString(mUuid + ".outboxFolderName",
|
||||
"Outbox");
|
||||
mExpungePolicy = preferences.getPreferences().getString(mUuid + ".expungePolicy", EXPUNGE_IMMEDIATELY);
|
||||
|
||||
// Between r418 and r431 (version 0.103), folder names were set empty if the Incoming settings were
|
||||
// opened for non-IMAP accounts. 0.103 was never a market release, so perhaps this code
|
||||
@ -529,6 +535,7 @@ public class Account implements Serializable
|
||||
editor.remove(mUuid + ".folderTargetMode");
|
||||
editor.remove(mUuid + ".hideButtonsEnum");
|
||||
editor.remove(mUuid + ".signatureBeforeQuotedText");
|
||||
editor.remove(mUuid + ".expungePolicy");
|
||||
deleteIdentities(preferences.getPreferences(), editor);
|
||||
editor.commit();
|
||||
}
|
||||
@ -599,6 +606,7 @@ public class Account implements Serializable
|
||||
editor.putString(mUuid + ".folderPushMode", mFolderPushMode.name());
|
||||
editor.putString(mUuid + ".folderTargetMode", mFolderTargetMode.name());
|
||||
editor.putBoolean(mUuid + ".signatureBeforeQuotedText", this.mIsSignatureBeforeQuotedText);
|
||||
editor.putString(mUuid + ".expungePolicy", mExpungePolicy);
|
||||
|
||||
saveIdentities(preferences.getPreferences(), editor);
|
||||
|
||||
@ -933,4 +941,14 @@ public class Account implements Serializable
|
||||
mNotifySelfNewMail = notifySelfNewMail;
|
||||
}
|
||||
|
||||
public String getExpungePolicy()
|
||||
{
|
||||
return mExpungePolicy;
|
||||
}
|
||||
|
||||
public void setExpungePolicy(String expungePolicy)
|
||||
{
|
||||
mExpungePolicy = expungePolicy;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ public class MessagingController implements Runnable
|
||||
private static final String PENDING_COMMAND_SET_FLAG = "com.fsck.k9.MessagingController.setFlag";
|
||||
private static final String PENDING_COMMAND_APPEND = "com.fsck.k9.MessagingController.append";
|
||||
private static final String PENDING_COMMAND_MARK_ALL_AS_READ = "com.fsck.k9.MessagingController.markAllAsRead";
|
||||
private static final String PENDING_COMMAND_EXPUNGE = "com.fsck.k9.MessagingController.expunge";
|
||||
|
||||
private static MessagingController inst = null;
|
||||
private BlockingQueue<Command> mCommands = new PriorityBlockingQueue<Command>();
|
||||
@ -638,7 +639,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
try
|
||||
{
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -842,7 +843,13 @@ public class MessagingController implements Runnable
|
||||
}
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
|
||||
if (Account.EXPUNGE_ON_POLL.equals(account.getExpungePolicy()))
|
||||
{
|
||||
Log.i(K9.LOG_TAG, "SYNC: Expunging folder " + account.getDescription() + ":" + folder);
|
||||
remoteFolder.expunge();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the remote message count.
|
||||
*/
|
||||
@ -928,8 +935,8 @@ public class MessagingController implements Runnable
|
||||
localFolder.setLastChecked(System.currentTimeMillis());
|
||||
localFolder.setStatus(null);
|
||||
|
||||
remoteFolder.close(false);
|
||||
localFolder.close(false);
|
||||
remoteFolder.close();
|
||||
localFolder.close();
|
||||
if (K9.DEBUG)
|
||||
{
|
||||
Log.d(K9.LOG_TAG, "Done synchronizing folder " +
|
||||
@ -977,7 +984,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
tLocalFolder.setStatus(rootMessage);
|
||||
tLocalFolder.setLastChecked(System.currentTimeMillis());
|
||||
tLocalFolder.close(false);
|
||||
tLocalFolder.close();
|
||||
}
|
||||
catch (MessagingException me)
|
||||
{
|
||||
@ -1622,6 +1629,10 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
processPendingEmptyTrash(command, account);
|
||||
}
|
||||
else if (PENDING_COMMAND_EXPUNGE.equals(command.command))
|
||||
{
|
||||
processPendingExpunge(command, account);
|
||||
}
|
||||
localStore.removePendingCommand(command);
|
||||
if (K9.DEBUG)
|
||||
{
|
||||
@ -1815,7 +1826,10 @@ public class MessagingController implements Runnable
|
||||
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
||||
}
|
||||
remoteMessage.setFlag(Flag.DELETED, true);
|
||||
remoteFolder.expunge();
|
||||
if (Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy()))
|
||||
{
|
||||
remoteFolder.expunge();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1900,7 +1914,12 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
Log.d(K9.LOG_TAG, "processingPendingMoveOrCopy doing special case for deleting message");
|
||||
}
|
||||
remoteSrcFolder.delete(messages.toArray(new Message[0]), account.getTrashFolderName());
|
||||
String destFolderName = destFolder;
|
||||
if (K9.FOLDER_NONE.equals(destFolderName))
|
||||
{
|
||||
destFolderName = null;
|
||||
}
|
||||
remoteSrcFolder.delete(messages.toArray(new Message[0]), destFolderName);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1921,17 +1940,21 @@ public class MessagingController implements Runnable
|
||||
remoteSrcFolder.moveMessages(messages.toArray(new Message[0]), remoteDestFolder);
|
||||
}
|
||||
}
|
||||
remoteSrcFolder.expunge();
|
||||
if (isCopy == false && Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy()))
|
||||
{
|
||||
Log.i(K9.LOG_TAG, "processingPendingMoveOrCopy expunging folder " + account.getDescription() + ":" + srcFolder);
|
||||
remoteSrcFolder.expunge();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (remoteSrcFolder != null)
|
||||
{
|
||||
remoteSrcFolder.close(false);
|
||||
remoteSrcFolder.close();
|
||||
}
|
||||
if (remoteDestFolder != null)
|
||||
{
|
||||
remoteDestFolder.close(false);
|
||||
remoteDestFolder.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2013,7 +2036,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
if (remoteFolder != null)
|
||||
{
|
||||
remoteFolder.close(false);
|
||||
remoteFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2061,6 +2084,64 @@ public class MessagingController implements Runnable
|
||||
}
|
||||
remoteMessage.setFlag(flag, newState);
|
||||
}
|
||||
private void queueExpunge(final Account account, final String folderName)
|
||||
{
|
||||
put("queueExpunge " + account.getDescription() + ":" + folderName, null, new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
PendingCommand command = new PendingCommand();
|
||||
command.command = PENDING_COMMAND_EXPUNGE;
|
||||
|
||||
command.arguments = new String[1];
|
||||
|
||||
command.arguments[0] = folderName;
|
||||
queuePendingCommand(account, command);
|
||||
processPendingCommands(account);
|
||||
}
|
||||
});
|
||||
}
|
||||
private void processPendingExpunge(PendingCommand command, Account account)
|
||||
throws MessagingException
|
||||
{
|
||||
String folder = command.arguments[0];
|
||||
|
||||
if (account.getErrorFolderName().equals(folder))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (K9.DEBUG)
|
||||
{
|
||||
Log.d(K9.LOG_TAG, "processPendingExpunge: folder = " + folder );
|
||||
}
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||
try
|
||||
{
|
||||
if (!remoteFolder.exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
if (remoteFolder.getMode() != OpenMode.READ_WRITE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
remoteFolder.expunge();
|
||||
if (K9.DEBUG)
|
||||
{
|
||||
Log.d(K9.LOG_TAG, "processPendingExpunge: complete for folder = " + folder );
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (remoteFolder != null)
|
||||
{
|
||||
remoteFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: This method is obsolete and is only for transition from K-9 2.0 to K-9 2.1
|
||||
@ -2120,7 +2201,7 @@ public class MessagingController implements Runnable
|
||||
Log.d(K9.LOG_TAG, "processPendingMoveOrCopyOld doing special case for deleting message");
|
||||
}
|
||||
remoteMessage.delete(account.getTrashFolderName());
|
||||
remoteSrcFolder.close(true);
|
||||
remoteSrcFolder.close();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2138,8 +2219,8 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
remoteSrcFolder.moveMessages(new Message[] { remoteMessage }, remoteDestFolder);
|
||||
}
|
||||
remoteSrcFolder.close(true);
|
||||
remoteDestFolder.close(true);
|
||||
remoteSrcFolder.close();
|
||||
remoteDestFolder.close();
|
||||
}
|
||||
|
||||
private void processPendingMarkAllAsRead(PendingCommand command, Account account) throws MessagingException
|
||||
@ -2187,7 +2268,7 @@ public class MessagingController implements Runnable
|
||||
}
|
||||
|
||||
remoteFolder.setFlags(new Flag[] {Flag.SEEN}, true);
|
||||
remoteFolder.close(false);
|
||||
remoteFolder.close();
|
||||
}
|
||||
catch (UnsupportedOperationException uoe)
|
||||
{
|
||||
@ -2195,7 +2276,7 @@ public class MessagingController implements Runnable
|
||||
}
|
||||
finally
|
||||
{
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2394,7 +2475,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
if (localFolder != null)
|
||||
{
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
}//setMesssageFlag
|
||||
@ -2508,12 +2589,12 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
if (remoteFolder!=null)
|
||||
{
|
||||
remoteFolder.close(false);
|
||||
remoteFolder.close();
|
||||
}
|
||||
|
||||
if (localFolder!=null)
|
||||
{
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
}
|
||||
}//finally
|
||||
}//run
|
||||
@ -2561,7 +2642,7 @@ public class MessagingController implements Runnable
|
||||
if (!message.isSet(Flag.X_DOWNLOADED_FULL))
|
||||
{
|
||||
loadMessageForViewRemote(account, folder, uid, listener);
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2572,7 +2653,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
message
|
||||
}, fp, null);
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
if (!message.isSet(Flag.SEEN))
|
||||
{
|
||||
setFlag(account, localFolder.getName(), new Message[] { message }, Flag.SEEN, true);
|
||||
@ -2799,7 +2880,7 @@ public class MessagingController implements Runnable
|
||||
fp.add(part);
|
||||
remoteFolder.fetch(new Message[] { message }, fp, null);
|
||||
localFolder.updateMessage((LocalMessage)message);
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.loadAttachmentFinished(account, message, part, tag);
|
||||
@ -2853,7 +2934,7 @@ public class MessagingController implements Runnable
|
||||
});
|
||||
Message localMessage = localFolder.getMessage(message.getUid());
|
||||
localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
sendPendingMessages(account, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -2903,7 +2984,7 @@ public class MessagingController implements Runnable
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
int localMessages = localFolder.getMessageCount();
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
if (localMessages > 0)
|
||||
{
|
||||
return true;
|
||||
@ -3065,7 +3146,6 @@ public class MessagingController implements Runnable
|
||||
*/
|
||||
}
|
||||
}
|
||||
localFolder.expunge();
|
||||
if (localFolder.getMessageCount() == 0)
|
||||
{
|
||||
localFolder.delete(false);
|
||||
@ -3115,7 +3195,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
try
|
||||
{
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -3346,6 +3426,17 @@ public class MessagingController implements Runnable
|
||||
throw new RuntimeException("Error moving message", me);
|
||||
}
|
||||
}
|
||||
|
||||
public void expunge(final Account account, final String folder, final MessagingListener listener)
|
||||
{
|
||||
put("expunge", null, new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
queueExpunge(account, folder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteMessages(final Account account, final String folder, final Message[] messages,
|
||||
final MessagingListener listener)
|
||||
@ -3388,11 +3479,11 @@ public class MessagingController implements Runnable
|
||||
}
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
localFolder = localStore.getFolder(folder);
|
||||
if (folder.equals(account.getTrashFolderName()))
|
||||
if (folder.equals(account.getTrashFolderName()) || K9.FOLDER_NONE.equals(account.getTrashFolderName()))
|
||||
{
|
||||
if (K9.DEBUG)
|
||||
{
|
||||
Log.d(K9.LOG_TAG, "Deleting messages in trash folder, not copying");
|
||||
Log.d(K9.LOG_TAG, "Deleting messages in trash folder or trash set to -None-, not copying");
|
||||
}
|
||||
localFolder.setFlags(messages, new Flag[] { Flag.DELETED }, true);
|
||||
}
|
||||
@ -3475,11 +3566,11 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
if (localFolder != null)
|
||||
{
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
}
|
||||
if (localTrashFolder != null)
|
||||
{
|
||||
localTrashFolder.close(false);
|
||||
localTrashFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3499,11 +3590,24 @@ public class MessagingController implements Runnable
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
|
||||
Folder remoteFolder = remoteStore.getFolder(account.getTrashFolderName());
|
||||
if (remoteFolder.exists())
|
||||
try
|
||||
{
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
remoteFolder.setFlags(new Flag [] { Flag.DELETED }, true);
|
||||
remoteFolder.close(true);
|
||||
if (remoteFolder.exists())
|
||||
{
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
remoteFolder.setFlags(new Flag [] { Flag.DELETED }, true);
|
||||
if (Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy()))
|
||||
{
|
||||
remoteFolder.expunge();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (remoteFolder != null)
|
||||
{
|
||||
remoteFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3519,7 +3623,7 @@ public class MessagingController implements Runnable
|
||||
Folder localFolder = localStore.getFolder(account.getTrashFolderName());
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
localFolder.setFlags(new Flag[] { Flag.DELETED }, true);
|
||||
localFolder.close(true);
|
||||
localFolder.close();
|
||||
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
@ -4287,7 +4391,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
try
|
||||
{
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -123,7 +123,7 @@ public class MessagingControllerPushReceiver implements PushReceiver
|
||||
{
|
||||
try
|
||||
{
|
||||
localFolder.close(false);
|
||||
localFolder.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -480,6 +480,11 @@ public class FolderList extends K9ListActivity
|
||||
|
||||
MessagingController.getInstance(getApplication()).emptyTrash(account, null);
|
||||
}
|
||||
|
||||
private void onExpunge(final Account account, String folderName)
|
||||
{
|
||||
MessagingController.getInstance(getApplication()).expunge(account, folderName, null);
|
||||
}
|
||||
|
||||
private void checkMail(final Account account)
|
||||
{
|
||||
@ -601,6 +606,10 @@ public class FolderList extends K9ListActivity
|
||||
case R.id.empty_trash:
|
||||
onEmptyTrash(mAccount);
|
||||
|
||||
break;
|
||||
case R.id.expunge:
|
||||
onExpunge(mAccount, folder.name);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -707,6 +716,10 @@ public class FolderList extends K9ListActivity
|
||||
{
|
||||
menu.findItem(R.id.send_messages).setVisible(false);
|
||||
}
|
||||
if (K9.ERROR_FOLDER_NAME.equals(folder.name))
|
||||
{
|
||||
menu.findItem(R.id.expunge).setVisible(false);
|
||||
}
|
||||
|
||||
menu.setHeaderTitle(folder.displayName);
|
||||
}
|
||||
@ -1363,7 +1376,7 @@ public class FolderList extends K9ListActivity
|
||||
|
||||
this.unreadMessageCount = unreadCount;
|
||||
|
||||
folder.close(false);
|
||||
folder.close();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -990,6 +990,12 @@ public class MessageList
|
||||
{
|
||||
showDialog(DIALOG_MARK_ALL_AS_READ);
|
||||
}
|
||||
|
||||
private void onExpunge(final Account account, String folderName)
|
||||
{
|
||||
mController.expunge(account, folderName, null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(int id)
|
||||
@ -1212,6 +1218,10 @@ public class MessageList
|
||||
mSelectedWidget = WIDGET_FLAG;
|
||||
configureWidgets();
|
||||
return true;
|
||||
|
||||
case R.id.expunge:
|
||||
onExpunge(mAccount, mCurrentFolder.name);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
@ -1287,6 +1297,11 @@ public class MessageList
|
||||
{
|
||||
menu.findItem(R.id.send_messages).setVisible(false);
|
||||
}
|
||||
|
||||
if (K9.ERROR_FOLDER_NAME.equals(mCurrentFolder.name))
|
||||
{
|
||||
menu.findItem(R.id.expunge).setVisible(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1784,7 +1799,7 @@ public class MessageList
|
||||
{
|
||||
if (local_folder != null)
|
||||
{
|
||||
local_folder.close(false);
|
||||
local_folder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ public class AccountSettings extends K9PreferenceActivity
|
||||
private static final String PREFERENCE_PUSH_MODE = "folder_push_mode";
|
||||
private static final String PREFERENCE_TARGET_MODE = "folder_target_mode";
|
||||
private static final String PREFERENCE_DELETE_POLICY = "delete_policy";
|
||||
private static final String PREFERENCE_EXPUNGE_POLICY = "expunge_policy";
|
||||
private static final String PREFERENCE_AUTO_EXPAND_FOLDER = "account_setup_auto_expand_folder";
|
||||
private static final String PREFERENCE_LEFT_HANDED = "left_handed";
|
||||
|
||||
@ -63,6 +64,7 @@ public class AccountSettings extends K9PreferenceActivity
|
||||
private ListPreference mPushMode;
|
||||
private ListPreference mTargetMode;
|
||||
private ListPreference mDeletePolicy;
|
||||
private ListPreference mExpungePolicy;
|
||||
private Preference mAutoExpandFolder;
|
||||
|
||||
private CheckBoxPreference mLeftHanded;
|
||||
@ -83,11 +85,13 @@ public class AccountSettings extends K9PreferenceActivity
|
||||
mAccount = (Account)getIntent().getSerializableExtra(EXTRA_ACCOUNT);
|
||||
|
||||
boolean isPushCapable = false;
|
||||
boolean isExpungeCapable = false;
|
||||
Store store = null;
|
||||
try
|
||||
{
|
||||
store = Store.getInstance(mAccount.getStoreUri(), getApplication());
|
||||
isPushCapable = store.isPushCapable();
|
||||
isExpungeCapable = store.isExpungeCapable();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -204,7 +208,24 @@ public class AccountSettings extends K9PreferenceActivity
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
mExpungePolicy = (ListPreference) findPreference(PREFERENCE_EXPUNGE_POLICY);
|
||||
mExpungePolicy.setEnabled(isExpungeCapable);
|
||||
mExpungePolicy.setValue(mAccount.getExpungePolicy());
|
||||
mExpungePolicy.setSummary(mExpungePolicy.getEntry());
|
||||
mExpungePolicy.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
|
||||
{
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue)
|
||||
{
|
||||
final String summary = newValue.toString();
|
||||
int index = mExpungePolicy.findIndexOfValue(summary);
|
||||
mExpungePolicy.setSummary(mExpungePolicy.getEntries()[index]);
|
||||
mExpungePolicy.setValue(summary);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
mDisplayCount = (ListPreference) findPreference(PREFERENCE_DISPLAY_COUNT);
|
||||
mDisplayCount.setValue(String.valueOf(mAccount.getDisplayCount()));
|
||||
mDisplayCount.setSummary(mDisplayCount.getEntry());
|
||||
@ -342,6 +363,7 @@ public class AccountSettings extends K9PreferenceActivity
|
||||
mAccount.setFolderPushMode(Account.FolderMode.valueOf(mPushMode.getValue()));
|
||||
mAccount.setFolderTargetMode(Account.FolderMode.valueOf(mTargetMode.getValue()));
|
||||
mAccount.setDeletePolicy(Integer.parseInt(mDeletePolicy.getValue()));
|
||||
mAccount.setExpungePolicy(mExpungePolicy.getValue());
|
||||
SharedPreferences prefs = mAccountRingtone.getPreferenceManager().getSharedPreferences();
|
||||
mAccount.setRingtone(prefs.getString(PREFERENCE_RINGTONE, null));
|
||||
mAccount.setHideMessageViewButtons(Account.HideButtons.valueOf(mAccountHideButtons.getValue()));
|
||||
|
@ -274,7 +274,6 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
||||
|
||||
/** Hide the unnecessary fields */
|
||||
findViewById(R.id.imap_path_prefix_section).setVisibility(View.GONE);
|
||||
findViewById(R.id.imap_folder_setup_section).setVisibility(View.GONE);
|
||||
findViewById(R.id.account_auth_type).setVisibility(View.GONE);
|
||||
if (uri.getPath() != null && uri.getPath().length() > 0)
|
||||
{
|
||||
@ -534,6 +533,11 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
||||
}
|
||||
|
||||
Intent selectIntent = new Intent(this, ChooseFolder.class);
|
||||
String uri = mAccount.getStoreUri();
|
||||
if (uri.startsWith("imap"))
|
||||
{
|
||||
selectIntent.putExtra(ChooseFolder.EXTRA_SHOW_FOLDER_NONE, "yes");
|
||||
}
|
||||
selectIntent.putExtra(ChooseFolder.EXTRA_ACCOUNT, mAccount);
|
||||
selectIntent.putExtra(ChooseFolder.EXTRA_CUR_FOLDER, curFolder);
|
||||
selectIntent.putExtra(ChooseFolder.EXTRA_SHOW_CURRENT, "yes");
|
||||
|
@ -34,10 +34,8 @@ public abstract class Folder
|
||||
/**
|
||||
* Forces a close of the MailProvider. Any further access will attempt to
|
||||
* reopen the MailProvider.
|
||||
*
|
||||
* @param expunge If true all deleted messages will be expunged.
|
||||
*/
|
||||
public abstract void close(boolean expunge);
|
||||
public abstract void close();
|
||||
|
||||
/**
|
||||
* @return True if further commands are not expected to have to open the
|
||||
@ -119,7 +117,8 @@ public abstract class Folder
|
||||
|
||||
public abstract String getUidFromMessageId(Message message) throws MessagingException;
|
||||
|
||||
public abstract Message[] expunge() throws MessagingException;
|
||||
public void expunge() throws MessagingException
|
||||
{}
|
||||
|
||||
public abstract void fetch(Message[] messages, FetchProfile fp,
|
||||
MessageRetrievalListener listener) throws MessagingException;
|
||||
|
@ -106,7 +106,12 @@ public abstract class Store
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isExpungeCapable()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void sendMessages(Message[] messages) throws MessagingException
|
||||
{
|
||||
}
|
||||
|
@ -415,6 +415,11 @@ public class ImapStore extends Store
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean isExpungeCapable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
class ImapFolder extends Folder
|
||||
@ -585,28 +590,17 @@ public class ImapStore extends Store
|
||||
return mMode;
|
||||
}
|
||||
|
||||
public void close(boolean expunge)
|
||||
public void close()
|
||||
{
|
||||
if (mMessageCount != -1)
|
||||
{
|
||||
// close();
|
||||
mMessageCount = -1;
|
||||
}
|
||||
if (!isOpen())
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (expunge)
|
||||
{
|
||||
expunge();
|
||||
}
|
||||
}
|
||||
catch (MessagingException me)
|
||||
{
|
||||
Log.e(K9.LOG_TAG, "Unable to expunge remote folder " + getName(), me);
|
||||
}
|
||||
|
||||
synchronized (this)
|
||||
{
|
||||
releaseConnection(mConnection);
|
||||
@ -752,10 +746,9 @@ public class ImapStore extends Store
|
||||
if (messages.length == 0)
|
||||
return;
|
||||
|
||||
if (getName().equals(trashFolderName))
|
||||
if (trashFolderName == null || getName().equals(trashFolderName))
|
||||
{
|
||||
setFlags(messages, new Flag[] { Flag.DELETED }, true);
|
||||
expunge();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -780,7 +773,6 @@ public class ImapStore extends Store
|
||||
Log.d(K9.LOG_TAG, "IMAPMessage.delete: copying remote " + messages.length + " messages to '" + trashFolderName + "' for " + getLogId());
|
||||
}
|
||||
moveMessages(messages, remoteTrashFolder);
|
||||
expunge();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1594,7 +1586,7 @@ public class ImapStore extends Store
|
||||
}
|
||||
|
||||
|
||||
public Message[] expunge() throws MessagingException
|
||||
public void expunge() throws MessagingException
|
||||
{
|
||||
checkOpen();
|
||||
try
|
||||
@ -1605,20 +1597,6 @@ public class ImapStore extends Store
|
||||
{
|
||||
throw ioExceptionHandler(mConnection, ioe);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void close() throws MessagingException
|
||||
{
|
||||
checkOpen();
|
||||
try
|
||||
{
|
||||
executeSimpleCommand("CLOSE");
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private String combineFlags(Flag[] flags)
|
||||
@ -1752,7 +1730,7 @@ public class ImapStore extends Store
|
||||
{
|
||||
Log.e(K9.LOG_TAG, "IOException for " + getLogId(), ioe);
|
||||
connection.close();
|
||||
close(false);
|
||||
close();
|
||||
return new MessagingException("IO Error", ioe);
|
||||
}
|
||||
|
||||
@ -2560,7 +2538,7 @@ public class ImapStore extends Store
|
||||
receiver.setPushActive(getName(), false);
|
||||
try
|
||||
{
|
||||
close(false);
|
||||
close();
|
||||
}
|
||||
catch (Exception me)
|
||||
{
|
||||
@ -2590,7 +2568,7 @@ public class ImapStore extends Store
|
||||
try
|
||||
{
|
||||
Log.i(K9.LOG_TAG, "Pusher for " + getLogId() + " is exiting");
|
||||
close(false);
|
||||
close();
|
||||
}
|
||||
catch (Exception me)
|
||||
{
|
||||
|
@ -709,19 +709,8 @@ public class LocalStore extends Store implements Serializable
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(boolean expunge)
|
||||
public void close()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (expunge)
|
||||
{
|
||||
expunge();
|
||||
}
|
||||
}
|
||||
catch (MessagingException me)
|
||||
{
|
||||
Log.e(K9.LOG_TAG, "Unable to close LocalFolder " + getName(), me);
|
||||
}
|
||||
mFolderId = -1;
|
||||
}
|
||||
|
||||
@ -1782,18 +1771,7 @@ public class LocalStore extends Store implements Serializable
|
||||
{
|
||||
throw new MessagingException("Cannot call getUidFromMessageId on LocalFolder");
|
||||
}
|
||||
@Override
|
||||
public Message[] expunge() throws MessagingException
|
||||
{
|
||||
open(OpenMode.READ_WRITE);
|
||||
ArrayList<Message> expungedMessages = new ArrayList<Message>();
|
||||
/*
|
||||
* epunge() doesn't do anything because deleted messages are saved for their uids
|
||||
* and really, really deleted messages are "Destroyed" and removed immediately.
|
||||
*/
|
||||
return expungedMessages.toArray(new Message[] {});
|
||||
}
|
||||
|
||||
|
||||
public void deleteMessagesOlderThan(long cutoff) throws MessagingException
|
||||
{
|
||||
open(OpenMode.READ_ONLY);
|
||||
|
@ -173,7 +173,7 @@ public class Pop3Store extends Store
|
||||
folder.executeSimpleCommand("UIDL");
|
||||
|
||||
}
|
||||
folder.close(false);
|
||||
folder.close();
|
||||
}
|
||||
|
||||
class Pop3Folder extends Folder
|
||||
@ -320,7 +320,7 @@ public class Pop3Store extends Store
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(boolean expunge)
|
||||
public void close()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -839,11 +839,6 @@ public class Pop3Store extends Store
|
||||
return null;
|
||||
}
|
||||
|
||||
public Message[] expunge() throws MessagingException
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFlags(Flag[] flags, boolean value)
|
||||
throws MessagingException
|
||||
|
@ -1122,7 +1122,7 @@ public class WebDavStore extends Store
|
||||
{
|
||||
if (tmpFolder != null)
|
||||
{
|
||||
tmpFolder.close(false);
|
||||
tmpFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1348,7 +1348,7 @@ public class WebDavStore extends Store
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(boolean expunge)
|
||||
public void close()
|
||||
{
|
||||
this.mMessageCount = 0;
|
||||
this.mUnreadMessageCount = 0;
|
||||
@ -2018,13 +2018,6 @@ public class WebDavStore extends Store
|
||||
return retMessages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message[] expunge() throws MessagingException
|
||||
{
|
||||
/** Do nothing, deletes occur as soon as the call is made rather than flags on the message */
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user