1
0
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:
Daniel Applebaum 2009-12-20 23:13:49 +00:00
parent 369718f8c0
commit 41d7ca51a3
18 changed files with 276 additions and 119 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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;
}
}

View File

@ -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)
{

View File

@ -123,7 +123,7 @@ public class MessagingControllerPushReceiver implements PushReceiver
{
try
{
localFolder.close(false);
localFolder.close();
}
catch (Exception e)
{

View File

@ -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();
}
}

View File

@ -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();
}
}
}

View File

@ -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()));

View File

@ -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");

View File

@ -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;

View File

@ -106,7 +106,12 @@ public abstract class Store
{
return false;
}
public boolean isExpungeCapable()
{
return false;
}
public void sendMessages(Message[] messages) throws MessagingException
{
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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

View File

@ -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)
{