2008-11-01 17:32:06 -04:00
|
|
|
|
2010-05-19 14:17:06 -04:00
|
|
|
package com.fsck.k9.controller;
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-01-16 11:22:20 -05:00
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
import java.io.PrintStream;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Date;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.concurrent.BlockingQueue;
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
import java.util.concurrent.CopyOnWriteArraySet;
|
|
|
|
import java.util.concurrent.CountDownLatch;
|
|
|
|
import java.util.concurrent.PriorityBlockingQueue;
|
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
2008-11-01 17:32:06 -04:00
|
|
|
import android.app.Application;
|
2008-12-19 17:30:55 -05:00
|
|
|
import android.app.Notification;
|
|
|
|
import android.app.NotificationManager;
|
|
|
|
import android.app.PendingIntent;
|
2008-11-01 17:32:06 -04:00
|
|
|
import android.content.Context;
|
2008-12-19 17:30:55 -05:00
|
|
|
import android.content.Intent;
|
2010-05-11 00:13:23 -04:00
|
|
|
import android.media.AudioManager;
|
2009-10-21 20:41:06 -04:00
|
|
|
import android.net.Uri;
|
2009-03-31 23:25:16 -04:00
|
|
|
import android.os.PowerManager;
|
2009-12-09 22:16:42 -05:00
|
|
|
import android.os.Process;
|
2009-10-21 20:41:06 -04:00
|
|
|
import android.text.TextUtils;
|
2008-11-01 17:32:06 -04:00
|
|
|
import android.util.Log;
|
2010-03-29 22:58:21 -04:00
|
|
|
|
2010-05-19 14:17:06 -04:00
|
|
|
import com.fsck.k9.Account;
|
|
|
|
import com.fsck.k9.AccountStats;
|
|
|
|
import com.fsck.k9.K9;
|
|
|
|
import com.fsck.k9.Preferences;
|
|
|
|
import com.fsck.k9.R;
|
|
|
|
import com.fsck.k9.SearchSpecification;
|
2010-01-28 22:57:37 -05:00
|
|
|
import com.fsck.k9.activity.FolderList;
|
2010-01-27 19:29:27 -05:00
|
|
|
import com.fsck.k9.activity.MessageList;
|
2010-05-19 14:17:06 -04:00
|
|
|
import com.fsck.k9.helper.Utility;
|
2010-05-16 20:30:32 -04:00
|
|
|
import com.fsck.k9.helper.power.TracingPowerManager;
|
|
|
|
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
|
2010-01-16 11:22:20 -05:00
|
|
|
import com.fsck.k9.mail.Address;
|
|
|
|
import com.fsck.k9.mail.FetchProfile;
|
|
|
|
import com.fsck.k9.mail.Flag;
|
|
|
|
import com.fsck.k9.mail.Folder;
|
|
|
|
import com.fsck.k9.mail.Message;
|
2010-02-17 22:28:31 -05:00
|
|
|
import com.fsck.k9.mail.MessagingException;
|
2010-01-16 11:22:20 -05:00
|
|
|
import com.fsck.k9.mail.Part;
|
|
|
|
import com.fsck.k9.mail.PushReceiver;
|
|
|
|
import com.fsck.k9.mail.Pusher;
|
|
|
|
import com.fsck.k9.mail.Store;
|
|
|
|
import com.fsck.k9.mail.Transport;
|
2009-12-14 21:50:53 -05:00
|
|
|
import com.fsck.k9.mail.Folder.FolderType;
|
|
|
|
import com.fsck.k9.mail.Folder.OpenMode;
|
|
|
|
import com.fsck.k9.mail.internet.MimeMessage;
|
|
|
|
import com.fsck.k9.mail.internet.MimeUtility;
|
|
|
|
import com.fsck.k9.mail.internet.TextBody;
|
|
|
|
import com.fsck.k9.mail.store.LocalStore;
|
|
|
|
import com.fsck.k9.mail.store.LocalStore.LocalFolder;
|
|
|
|
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
|
|
|
|
import com.fsck.k9.mail.store.LocalStore.PendingCommand;
|
2009-12-09 22:16:42 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
|
|
|
* Starts a long running (application) Thread that will run through commands
|
|
|
|
* that require remote mailbox access. This class is used to serialize and
|
|
|
|
* prioritize these commands. Each method that will submit a command requires a
|
|
|
|
* MessagingListener instance to be provided. It is expected that that listener
|
|
|
|
* has also been added as a registered listener using addListener(). When a
|
|
|
|
* command is to be executed, if the listener that was provided with the command
|
|
|
|
* is no longer registered the command is skipped. The design idea for the above
|
|
|
|
* is that when an Activity starts it registers as a listener. When it is paused
|
|
|
|
* it removes itself. Thus, any commands that that activity submitted are
|
|
|
|
* removed from the queue once the activity is no longer active.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public class MessagingController implements Runnable
|
|
|
|
{
|
2010-08-02 07:55:31 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Immutable empty {@link String} array
|
|
|
|
*/
|
|
|
|
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Immutable empty {@link Message} array
|
|
|
|
*/
|
|
|
|
private static final Message[] EMPTY_MESSAGE_ARRAY = new Message[0];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Immutable empty {@link Folder} array
|
|
|
|
*/
|
|
|
|
private static final Folder[] EMPTY_FOLDER_ARRAY = new Folder[0];
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
|
|
|
* The maximum message size that we'll consider to be "small". A small message is downloaded
|
|
|
|
* in full immediately instead of in pieces. Anything over this size will be downloaded in
|
|
|
|
* pieces with attachments being left off completely and downloaded on demand.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* 25k for a "small" message was picked by educated trial and error.
|
|
|
|
* http://answers.google.com/answers/threadview?id=312463 claims that the
|
|
|
|
* average size of an email is 59k, which I feel is too large for our
|
|
|
|
* blind download. The following tests were performed on a download of
|
|
|
|
* 25 random messages.
|
|
|
|
* <pre>
|
|
|
|
* 5k - 61 seconds,
|
|
|
|
* 25k - 51 seconds,
|
|
|
|
* 55k - 53 seconds,
|
|
|
|
* </pre>
|
|
|
|
* So 25k gives good performance and a reasonable data footprint. Sounds good to me.
|
|
|
|
*/
|
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
private static final String PENDING_COMMAND_MOVE_OR_COPY = "com.fsck.k9.MessagingController.moveOrCopy";
|
|
|
|
private static final String PENDING_COMMAND_MOVE_OR_COPY_BULK = "com.fsck.k9.MessagingController.moveOrCopyBulk";
|
|
|
|
private static final String PENDING_COMMAND_EMPTY_TRASH = "com.fsck.k9.MessagingController.emptyTrash";
|
|
|
|
private static final String PENDING_COMMAND_SET_FLAG_BULK = "com.fsck.k9.MessagingController.setFlagBulk";
|
|
|
|
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";
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
private static final String PENDING_COMMAND_EXPUNGE = "com.fsck.k9.MessagingController.expunge";
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
private static MessagingController inst = null;
|
2009-10-21 20:41:06 -04:00
|
|
|
private BlockingQueue<Command> mCommands = new PriorityBlockingQueue<Command>();
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
private Thread mThread;
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
private Set<MessagingListener> mListeners = new CopyOnWriteArraySet<MessagingListener>();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-02-07 14:41:33 -05:00
|
|
|
private HashMap<SORT_TYPE, Boolean> sortAscending = new HashMap<SORT_TYPE, Boolean>();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-04-09 13:48:05 -04:00
|
|
|
private ConcurrentHashMap<String, AtomicInteger> sendCount = new ConcurrentHashMap<String, AtomicInteger>();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
ConcurrentHashMap<Account, Pusher> pushers = new ConcurrentHashMap<Account, Pusher>();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
public enum SORT_TYPE
|
|
|
|
{
|
|
|
|
SORT_DATE(R.string.sort_earliest_first, R.string.sort_latest_first, false),
|
|
|
|
SORT_SUBJECT(R.string.sort_subject_alpha, R.string.sort_subject_re_alpha, true),
|
|
|
|
SORT_SENDER(R.string.sort_sender_alpha, R.string.sort_sender_re_alpha, true),
|
|
|
|
SORT_UNREAD(R.string.sort_unread_first, R.string.sort_unread_last, true),
|
|
|
|
SORT_FLAGGED(R.string.sort_flagged_first, R.string.sort_flagged_last, true),
|
|
|
|
SORT_ATTACHMENT(R.string.sort_attach_first, R.string.sort_unattached_first, true);
|
|
|
|
|
|
|
|
private int ascendingToast;
|
|
|
|
private int descendingToast;
|
|
|
|
private boolean defaultAscending;
|
|
|
|
|
|
|
|
SORT_TYPE(int ascending, int descending, boolean ndefaultAscending)
|
|
|
|
{
|
|
|
|
ascendingToast = ascending;
|
|
|
|
descendingToast = descending;
|
|
|
|
defaultAscending = ndefaultAscending;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getToast(boolean ascending)
|
|
|
|
{
|
|
|
|
if (ascending)
|
|
|
|
{
|
|
|
|
return ascendingToast;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return descendingToast;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public boolean isDefaultAscending()
|
|
|
|
{
|
|
|
|
return defaultAscending;
|
|
|
|
}
|
2009-02-07 14:41:33 -05:00
|
|
|
};
|
|
|
|
private SORT_TYPE sortType = SORT_TYPE.SORT_DATE;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-01-11 18:43:32 -05:00
|
|
|
private MessagingListener checkMailListener = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
private MemorizingListener memorizingListener = new MemorizingListener();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
private boolean mBusy;
|
|
|
|
private Application mApplication;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-01-29 08:35:43 -05:00
|
|
|
// Key is accountUuid:folderName:messageUid , value is unimportant
|
|
|
|
private ConcurrentHashMap<String, String> deletedUids = new ConcurrentHashMap<String, String>();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
private String createMessageKey(Account account, String folder, Message message)
|
|
|
|
{
|
|
|
|
return createMessageKey(account, folder, message.getUid());
|
|
|
|
}
|
|
|
|
|
|
|
|
private String createMessageKey(Account account, String folder, String uid)
|
|
|
|
{
|
|
|
|
return account.getUuid() + ":" + folder + ":" + uid;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void suppressMessage(Account account, String folder, Message message)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (account == null || folder == null || message == null)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
String messKey = createMessageKey(account, folder, message);
|
|
|
|
deletedUids.put(messKey, "true");
|
|
|
|
}
|
|
|
|
|
|
|
|
private void unsuppressMessage(Account account, String folder, String uid)
|
|
|
|
{
|
|
|
|
if (account == null || folder == null || uid == null)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
String messKey = createMessageKey(account, folder, uid);
|
|
|
|
deletedUids.remove(messKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isMessageSuppressed(Account account, String folder, Message message)
|
|
|
|
{
|
|
|
|
if (account == null || folder == null || message == null)
|
|
|
|
{
|
2009-01-29 08:35:43 -05:00
|
|
|
return false;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
String messKey = createMessageKey(account, folder, message);
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (deletedUids.containsKey(messKey))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2010-07-06 06:29:26 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
return false;
|
2009-01-29 08:35:43 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
private MessagingController(Application application)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
mApplication = application;
|
|
|
|
mThread = new Thread(this);
|
|
|
|
mThread.start();
|
2009-10-21 20:41:06 -04:00
|
|
|
if (memorizingListener != null)
|
|
|
|
{
|
|
|
|
addListener(memorizingListener);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
|
|
|
* Gets or creates the singleton instance of MessagingController. Application is used to
|
|
|
|
* provide a Context to classes that need it.
|
|
|
|
* @param application
|
|
|
|
* @return
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public synchronized static MessagingController getInstance(Application application)
|
|
|
|
{
|
|
|
|
if (inst == null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
inst = new MessagingController(application);
|
|
|
|
}
|
|
|
|
return inst;
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public boolean isBusy()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return mBusy;
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void run()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
2009-11-24 19:40:29 -05:00
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
String commandDescription = null;
|
|
|
|
try
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
Command command = mCommands.take();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
if (command != null)
|
|
|
|
{
|
|
|
|
commandDescription = command.description;
|
2010-01-02 20:50:41 -05:00
|
|
|
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Running " + (command.isForeground ? "Foreground" : "Background") + " command '" + command.description + "', seq = " + command.sequence);
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
mBusy = true;
|
|
|
|
command.runnable.run();
|
2010-01-02 20:50:41 -05:00
|
|
|
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, (command.isForeground ? "Foreground" : "Background") +
|
|
|
|
" Command '" + command.description + "' completed");
|
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(command.listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
l.controllerCommandCompleted(mCommands.size() > 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Error running command '" + commandDescription + "'", e);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
mBusy = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
private void put(String description, MessagingListener listener, Runnable runnable)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
putCommand(mCommands, description, listener, runnable, true);
|
|
|
|
}
|
2009-09-16 23:43:02 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
private void putBackground(String description, MessagingListener listener, Runnable runnable)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
putCommand(mCommands, description, listener, runnable, false);
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
private void putCommand(BlockingQueue<Command> queue, String description, MessagingListener listener, Runnable runnable, boolean isForeground)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
int retries = 10;
|
|
|
|
Exception e = null;
|
|
|
|
while (retries-- > 0)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
Command command = new Command();
|
|
|
|
command.listener = listener;
|
|
|
|
command.runnable = runnable;
|
|
|
|
command.description = description;
|
|
|
|
command.isForeground = isForeground;
|
2009-09-16 23:43:02 -04:00
|
|
|
queue.put(command);
|
2009-10-21 20:41:06 -04:00
|
|
|
return;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (InterruptedException ie)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
try
|
|
|
|
{
|
|
|
|
Thread.sleep(200);
|
|
|
|
}
|
|
|
|
catch (InterruptedException ne)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
e = ie;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw new Error(e);
|
r62972@17h: jesse | 2009-05-07 10:49:32 -0400
First stab at a folderlist that doesn't know or care about messages
r62973@17h: jesse | 2009-05-07 10:50:11 -0400
A very broken first stab at a message list that only knows about one folder.
r62974@17h: jesse | 2009-05-07 10:50:44 -0400
When you go from an account list to an individual account, open a folderlist, not an fml
r62975@17h: jesse | 2009-05-07 10:51:24 -0400
Update Welcome activity to open an ml instead of an fml
r62976@17h: jesse | 2009-05-07 10:51:59 -0400
When setting up accounts is over, open an fl instead of an fml
r62977@17h: jesse | 2009-05-07 10:52:51 -0400
Update MessageView to use folderinfoholders and messageinfoholders from the 'correct' classes.
r62978@17h: jesse | 2009-05-07 10:59:07 -0400
MailService now notifies the fl instead of the fml. Not sure if it should also notify the ml. - will require testing
r62979@17h: jesse | 2009-05-07 11:01:09 -0400
Switch MessagingController's notifications from notifying the FML to notifying an ML
r62980@17h: jesse | 2009-05-07 11:25:22 -0400
Update AndroidManifest to know about the new world order
r62981@17h: jesse | 2009-05-07 11:26:11 -0400
Try to follow the android sdk docs for intent creation
r62982@17h: jesse | 2009-05-07 11:28:30 -0400
reset MessageList for another try at the conversion
r62983@17h: jesse | 2009-05-07 11:47:33 -0400
This version doesn't crash and has a working 'folder' layer. now to clean up the message list layer
r62984@17h: jesse | 2009-05-07 15:18:04 -0400
move step 1
r62985@17h: jesse | 2009-05-07 15:18:37 -0400
move step 1
r62986@17h: jesse | 2009-05-07 15:22:47 -0400
rename step 1
r62987@17h: jesse | 2009-05-07 17:38:02 -0400
checkpoint to move
r62988@17h: jesse | 2009-05-07 17:40:01 -0400
checkpointing a state with a working folder list and a message list that doesn't explode
r62989@17h: jesse | 2009-05-07 17:40:26 -0400
Remove debugging cruft from Welcome
r62990@17h: jesse | 2009-05-07 22:00:12 -0400
Basic functionality works.
r62991@17h: jesse | 2009-05-08 04:19:52 -0400
added a tool to build a K-9 "Beta"
r62992@17h: jesse | 2009-05-08 04:20:03 -0400
remove a disused file
r62993@17h: jesse | 2009-05-09 06:07:02 -0400
upgrading build infrastructure for the 1.5 sdk
r62994@17h: jesse | 2009-05-09 06:22:02 -0400
further refine onOpenMessage, removing more folder assumptions
r62995@17h: jesse | 2009-05-09 20:07:20 -0400
Make the Welcome activity open the autoexpandfolder rather than INBOX
r62996@17h: jesse | 2009-05-09 20:14:10 -0400
MessageList now stores the Folder name it was working with across pause-reload
r62997@17h: jesse | 2009-05-09 20:14:26 -0400
Removing dead code from FolderList
r63060@17h: jesse | 2009-05-10 00:07:33 -0400
Replace the old message list refreshing code which cleared and rebuilt the list from scratch with code which updates or deletes existing messages.
Add "go back to folder list" code
r63061@17h: jesse | 2009-05-10 00:07:50 -0400
fix message list menus for new world order
r63062@17h: jesse | 2009-05-10 00:08:11 -0400
Remove message list options from folder list menus
r63063@17h: jesse | 2009-05-10 00:10:02 -0400
remove more message list options from the folder list
r63064@17h: jesse | 2009-05-10 00:10:19 -0400
fix build.xml for the new android world order
r63065@17h: jesse | 2009-05-10 00:39:23 -0400
reformatted in advance of bug tracing
r63066@17h: jesse | 2009-05-10 05:53:28 -0400
fix our 'close' behavior to not leave extra activities around
clean up more vestigal code
r63067@17h: jesse | 2009-05-10 18:44:25 -0400
Improve "back button / accounts" workflow from FolderList -> AccountList
r63068@17h: jesse | 2009-05-10 19:11:47 -0400
* Add required code for the 'k9beta' build
r63069@17h: jesse | 2009-05-10 19:12:05 -0400
Make the folder list white backgrounded.
r63070@17h: jesse | 2009-05-10 19:12:26 -0400
* Include our required libraries in build.xml
r63071@17h: jesse | 2009-05-10 19:13:07 -0400
Added directories for our built code and our generated code
r63072@17h: jesse | 2009-05-10 19:13:36 -0400
Added a "back" button image
r63073@17h: jesse | 2009-05-10 20:13:50 -0400
Switch next/prev buttons to triangles for I18N and eventual "more easy-to-hit buttons" win
r63074@17h: jesse | 2009-05-10 20:17:18 -0400
Tidy Accounts.java for some perf hacking.
r63081@17h: jesse | 2009-05-10 22:13:33 -0400
First pass reformatting of the MessagingController
r63082@17h: jesse | 2009-05-10 23:50:28 -0400
MessageList now correctly updates when a background sync happens
r63083@17h: jesse | 2009-05-10 23:50:53 -0400
Tidying FolderList
r63084@17h: jesse | 2009-05-10 23:51:09 -0400
tidy
r63085@17h: jesse | 2009-05-10 23:51:27 -0400
tidy
r63086@17h: jesse | 2009-05-11 00:17:06 -0400
Properly update unread counts in the FolderList after sync
r63087@17h: jesse | 2009-05-11 01:38:14 -0400
Minor refactoring for readability. replace a boolean with a constant.
r63090@17h: jesse | 2009-05-11 02:58:31 -0400
now that the foreground of message lists is light, we don't need the light messagebox
r63091@17h: jesse | 2009-05-11 17:15:02 -0400
Added a string for "back to folder list"
r63092@17h: jesse | 2009-05-11 17:15:24 -0400
Added a message list header with a back button
r63093@17h: jesse | 2009-05-11 17:15:54 -0400
Remove the "folder list" button from the options menu. no sense duplicating it
r63094@17h: jesse | 2009-05-11 17:17:06 -0400
Refactored views, adding our replacement scrollable header
r63184@17h: jesse | 2009-05-12 07:07:15 -0400
fix weird bug where message lists could show a header element for a child
r63185@17h: jesse | 2009-05-12 07:08:12 -0400
Add new-style headers to folder lists. reimplement "get folder by name" to not use a bloody for loop
r63211@17h: jesse | 2009-05-12 18:37:48 -0400
Restore the former glory of the "load more messages" widget. it still needs an overhaul
r63296@17h: jesse | 2009-05-12 23:23:21 -0400
Get the indeterminate progress bar to show up again when you click "get more messages"
r63297@17h: jesse | 2009-05-13 02:40:39 -0400
Fixed off-by-one errors in click and keybindings for messagelist
r63298@17h: jesse | 2009-05-13 06:04:01 -0400
Put the folder title in the name of the folderSettings popup
r63299@17h: jesse | 2009-05-13 06:04:49 -0400
Reformatting. Removing debug logging
r63300@17h: jesse | 2009-05-13 06:05:32 -0400
Fixing "wrong item selected" bugs in the FolderList
r63328@17h: jesse | 2009-05-13 13:20:00 -0400
Update MessageView for 1.5
r63329@17h: jesse | 2009-05-13 13:50:29 -0400
A couple fixes to "picking the right item"
Titles on the message context menu
r63330@17h: jesse | 2009-05-13 13:58:37 -0400
Added an "open" context menu item to the folder list
r63347@17h: jesse | 2009-05-13 18:00:02 -0400
Try to get folderlists to sort in a stable way, so they jump around less in the ui
r63349@17h: jesse | 2009-05-13 20:37:19 -0400
Switch to using non-message-passing based notifications for redisplay of message lists, cut down redisplay frequency to not overload the display
r63432@17h: jesse | 2009-05-16 13:38:49 -0400
Android 1.5 no longer gives us apache.commons.codec by default and apache.commons.logging by default. Import them so we have em.
There's probably something smarter to do here.
r63438@17h: jesse | 2009-05-16 14:12:06 -0400
removed dead code
r63439@17h: jesse | 2009-05-16 14:30:57 -0400
Minor tidy
r63440@17h: jesse | 2009-05-16 14:39:34 -0400
First pass implementation making MessageList streamy for faster startup
r63441@17h: jesse | 2009-05-16 21:57:41 -0400
There's no reason for the FolderList to list local messages
r63442@17h: jesse | 2009-05-16 21:58:57 -0400
Switch to actually refreshing the message list after each item is loaded
r63450@17h: jesse | 2009-05-16 22:34:18 -0400
Default to pulling items out of the LocalStore by date, descending. (since that's the uneditable default ordering)
This makes our messages come out of the store in the order the user should see them
r63451@17h: jesse | 2009-05-16 22:34:44 -0400
Set some new defaults for the FolderList
r63452@17h: jesse | 2009-05-16 22:35:43 -0400
set some new message list item defaults
r63456@17h: jesse | 2009-05-17 12:56:10 -0400
It's not clear that Pop and WebDav actually set us an InternalDate. I'd rather use that so that spam doesn't topsort. But I also want this to _work_
r63457@17h: jesse | 2009-05-17 12:56:47 -0400
actually check to make sure we have a message to remove before removing it.
r63458@17h: jesse | 2009-05-17 13:10:07 -0400
Flip "security type" to before the port number, since changing security type is the thing more users are likely to know/care about and resets port number
r63469@17h: jesse | 2009-05-17 18:42:39 -0400
Provisional fix for "see the FoldeRList twice" bug
r63471@17h: jesse | 2009-05-17 20:47:41 -0400
Remove title bar from the message view
r63544@17h: jesse | 2009-05-20 23:53:38 -0400
folderlist tidying before i dig into the jumpy ordering bug
r63545@17h: jesse | 2009-05-20 23:56:00 -0400
Killing dead variables
r63546@17h: jesse | 2009-05-21 00:58:36 -0400
make the whole title section clicky
r63556@17h: jesse | 2009-05-21 01:48:13 -0400
Fix where we go when someone deletes a message
r63558@17h: jesse | 2009-05-21 22:44:46 -0400
Working toward switchable themes
r63563@17h: jesse | 2009-05-21 23:53:09 -0400
Make the MessageList's colors actually just inherit from the theme, rather than hardcoding black
r63567@17h: jesse | 2009-05-22 10:14:13 -0400
Kill a now-redundant comment
r63571@17h: jesse | 2009-05-22 19:43:30 -0400
further theme-independence work
r63572@17h: jesse | 2009-05-22 19:55:23 -0400
gete -> get (typo fix)
r63573@17h: jesse | 2009-05-22 22:48:49 -0400
First cut of a global prefs system as well as a theme preference. not that it works yet
r63577@17h: jesse | 2009-05-24 14:49:52 -0400
Once a user has actually put in valid user credentials, start syncing mail and folders in the background instantly.
This gives us a much better "new startup" experience
r63578@17h: jesse | 2009-05-24 14:55:00 -0400
MessageList doesn't need FolderUpdateWorker
r63579@17h: jesse | 2009-05-24 17:57:15 -0400
Fix "get message by uid"
Switch to showing messages 10 by 10, rather than 1 by 1 for huge loadtime performance improvements
r63587@17h: jesse | 2009-05-24 19:19:56 -0400
Cut down LocalMessage creation to not generate a MessageId or date formatter.
r63589@17h: jesse | 2009-05-24 22:22:32 -0400
Switch to null-escaping email address boundaries, rather than a VERY expensive URL-encoding
r63590@17h: jesse | 2009-05-24 22:23:21 -0400
Clean up our "auto-refresh the list when adding messages after a sync"
r63593@17h: jesse | 2009-05-24 22:53:45 -0400
replace isDateToday with a "rolling 18 hour window" variant that's more likely to give the user a useful answer and is 30x faster.
r63595@17h: jesse | 2009-05-24 23:54:14 -0400
When instantiating messges from the LocalStore, there's no need to clear headers before setting them, nor is there a need to set a generated message id
r63596@17h: jesse | 2009-05-24 23:54:39 -0400
make an overridable setGeneratedMessageId
r63597@17h: jesse | 2009-05-24 23:54:55 -0400
Remove new lies from comments
r63598@17h: jesse | 2009-05-24 23:55:35 -0400
Replace insanely expensive message header "name" part quoting with something consistent and cheap that does its work on the way INTO the database
r63605@17h: jesse | 2009-05-25 17:28:24 -0400
bring back the 1.1 sdk build.xml
r63606@17h: jesse | 2009-05-25 22:32:11 -0400
Actually enable switchable themese and compilation on 1.1
r63692@17h: jesse | 2009-05-29 23:55:17 -0400
Switch back to having titles for folder and message lists.
Restore auto-open-folder functionality
r63694@17h: jesse | 2009-05-30 18:50:39 -0400
Remove several off-by-one errors introduced by yesterday's return to android titlebars
r63696@17h: jesse | 2009-05-30 23:45:03 -0400
use convertView properly for performance and memory imrpovement in FolderList and MessageList
r63698@17h: jesse | 2009-05-31 19:42:59 -0400
Switch to using background shading to indicate "not yet fetched"
r63701@17h: jesse | 2009-05-31 21:28:47 -0400
Remving code we don't actually need these bits of apache commons on 1.1
2009-05-31 21:35:05 -04:00
|
|
|
}
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void addListener(MessagingListener listener)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
mListeners.add(listener);
|
2009-10-21 20:41:06 -04:00
|
|
|
refreshListener(listener);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
public void refreshListener(MessagingListener listener)
|
|
|
|
{
|
|
|
|
if (memorizingListener != null && listener != null)
|
|
|
|
{
|
|
|
|
memorizingListener.refreshOther(listener);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void removeListener(MessagingListener listener)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
mListeners.remove(listener);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
public Set<MessagingListener> getListeners()
|
|
|
|
{
|
|
|
|
return mListeners;
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
|
|
|
|
public Set<MessagingListener> getListeners(MessagingListener listener)
|
|
|
|
{
|
2010-07-14 23:42:05 -04:00
|
|
|
if (listener == null)
|
2010-07-13 17:17:10 -04:00
|
|
|
{
|
2010-07-14 23:42:05 -04:00
|
|
|
return mListeners;
|
2010-07-13 17:17:10 -04:00
|
|
|
}
|
2010-07-14 23:42:05 -04:00
|
|
|
|
2010-07-15 20:38:32 -04:00
|
|
|
Set<MessagingListener> listeners = new HashSet<MessagingListener>(mListeners);
|
2010-07-14 23:42:05 -04:00
|
|
|
listeners.add(listener);
|
2010-07-13 17:17:10 -04:00
|
|
|
return listeners;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
|
|
|
* Lists folders that are available locally and remotely. This method calls
|
|
|
|
* listFoldersCallback for local folders before it returns, and then for
|
|
|
|
* remote folders at some later point. If there are no local folders
|
|
|
|
* includeRemote is forced by this method. This method should be called from
|
2009-11-24 19:40:29 -05:00
|
|
|
* a Thread as it may take several seconds to list the local folders.
|
2008-11-01 17:34:50 -04:00
|
|
|
* TODO this needs to cache the remote folder list
|
2008-11-01 17:32:06 -04:00
|
|
|
*
|
|
|
|
* @param account
|
|
|
|
* @param includeRemote
|
|
|
|
* @param listener
|
|
|
|
* @throws MessagingException
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public void listFolders(final Account account, final boolean refreshRemote, final MessagingListener listener)
|
|
|
|
{
|
2010-08-17 22:48:55 -04:00
|
|
|
new Thread(new Runnable()
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
public void run()
|
|
|
|
{
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
l.listFoldersStarted(account);
|
|
|
|
}
|
2010-04-21 22:20:35 -04:00
|
|
|
List<? extends Folder> localFolders = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2010-05-30 12:56:50 -04:00
|
|
|
localFolders = localStore.getPersonalNamespaces(false);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-08-02 07:55:31 -04:00
|
|
|
Folder[] folderArray = localFolders.toArray(EMPTY_FOLDER_ARRAY);
|
2010-04-21 22:20:35 -04:00
|
|
|
|
|
|
|
if (refreshRemote || localFolders == null || localFolders.size() == 0)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
doRefreshRemote(account, listener);
|
|
|
|
return;
|
|
|
|
}
|
2010-07-13 17:17:10 -04:00
|
|
|
|
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-04-21 22:20:35 -04:00
|
|
|
l.listFolders(account, folderArray);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
l.listFoldersFailed(account, e.getMessage());
|
|
|
|
}
|
2010-07-13 17:17:10 -04:00
|
|
|
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2009-10-21 20:41:06 -04:00
|
|
|
return;
|
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (localFolders != null)
|
|
|
|
{
|
|
|
|
for (Folder localFolder : localFolders)
|
|
|
|
{
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
|
|
|
localFolder.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-01-16 23:20:39 -05:00
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
l.listFoldersFinished(account);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2010-08-10 00:29:18 -04:00
|
|
|
}).start();
|
2008-11-01 17:34:50 -04:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
private void doRefreshRemote(final Account account, MessagingListener listener)
|
|
|
|
{
|
|
|
|
put("doRefreshRemote", listener, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
2010-04-21 22:20:35 -04:00
|
|
|
List<? extends Folder> localFolders = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store store = account.getRemoteStore();
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-05-30 12:56:50 -04:00
|
|
|
List<? extends Folder> remoteFolders = store.getPersonalNamespaces(false);
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
2009-11-24 19:40:29 -05:00
|
|
|
HashSet<String> remoteFolderNames = new HashSet<String>();
|
2010-04-21 22:20:35 -04:00
|
|
|
for (int i = 0, count = remoteFolders.size(); i < count; i++)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-04-21 22:20:35 -04:00
|
|
|
LocalFolder localFolder = localStore.getFolder(remoteFolders.get(i).getName());
|
2009-11-24 19:40:29 -05:00
|
|
|
if (!localFolder.exists())
|
|
|
|
{
|
|
|
|
localFolder.create(FolderType.HOLDS_MESSAGES, account.getDisplayCount());
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-04-21 22:20:35 -04:00
|
|
|
remoteFolderNames.add(remoteFolders.get(i).getName());
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-05-30 12:56:50 -04:00
|
|
|
localFolders = localStore.getPersonalNamespaces(false);
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
/*
|
|
|
|
* Clear out any folders that are no longer on the remote store.
|
|
|
|
*/
|
|
|
|
for (Folder localFolder : localFolders)
|
|
|
|
{
|
|
|
|
String localFolderName = localFolder.getName();
|
2009-12-14 21:50:53 -05:00
|
|
|
if (localFolderName.equalsIgnoreCase(K9.INBOX) ||
|
2009-11-24 19:40:29 -05:00
|
|
|
localFolderName.equals(account.getTrashFolderName()) ||
|
|
|
|
localFolderName.equals(account.getOutboxFolderName()) ||
|
|
|
|
localFolderName.equals(account.getDraftsFolderName()) ||
|
|
|
|
localFolderName.equals(account.getSentFolderName()) ||
|
|
|
|
localFolderName.equals(account.getErrorFolderName()))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!remoteFolderNames.contains(localFolder.getName()))
|
|
|
|
{
|
|
|
|
localFolder.delete(false);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-05-30 12:56:50 -04:00
|
|
|
localFolders = localStore.getPersonalNamespaces(false);
|
2010-08-02 07:55:31 -04:00
|
|
|
Folder[] folderArray = localFolders.toArray(EMPTY_FOLDER_ARRAY);
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2010-04-21 22:20:35 -04:00
|
|
|
l.listFolders(account, folderArray);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.listFoldersFinished(account);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.listFoldersFailed(account, "");
|
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (localFolders != null)
|
|
|
|
{
|
|
|
|
for (Folder localFolder : localFolders)
|
|
|
|
{
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
|
|
|
localFolder.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2008-11-01 17:34:50 -04:00
|
|
|
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
2009-12-17 21:36:37 -05:00
|
|
|
* List the messages in the local message store for the given folder asynchronously.
|
2008-11-01 17:32:06 -04:00
|
|
|
*
|
|
|
|
* @param account
|
|
|
|
* @param folder
|
|
|
|
* @param listener
|
|
|
|
* @throws MessagingException
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public void listLocalMessages(final Account account, final String folder, final MessagingListener listener)
|
|
|
|
{
|
2010-08-10 00:29:18 -04:00
|
|
|
new Thread(new Runnable()
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
2009-12-17 21:36:37 -05:00
|
|
|
listLocalMessagesSynchronous(account, folder, listener);
|
|
|
|
}
|
2010-08-10 00:29:18 -04:00
|
|
|
}).start();
|
2009-12-17 21:36:37 -05:00
|
|
|
}
|
2009-12-17 21:35:46 -05:00
|
|
|
|
|
|
|
|
2009-12-17 21:36:37 -05:00
|
|
|
/**
|
|
|
|
* List the messages in the local message store for the given folder synchronously.
|
|
|
|
*
|
|
|
|
* @param account
|
|
|
|
* @param folder
|
|
|
|
* @param listener
|
|
|
|
* @throws MessagingException
|
|
|
|
*/
|
|
|
|
public void listLocalMessagesSynchronous(final Account account, final String folder, final MessagingListener listener)
|
|
|
|
{
|
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-12-17 21:36:37 -05:00
|
|
|
{
|
|
|
|
l.listLocalMessagesStarted(account, folder);
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
|
2009-12-17 21:36:37 -05:00
|
|
|
Folder localFolder = null;
|
2009-12-27 11:51:45 -05:00
|
|
|
MessageRetrievalListener retrievalListener =
|
|
|
|
new MessageRetrievalListener()
|
2009-12-17 21:36:37 -05:00
|
|
|
{
|
2009-12-27 11:51:45 -05:00
|
|
|
List<Message> pendingMessages = new ArrayList<Message>();
|
2009-12-17 21:36:37 -05:00
|
|
|
|
|
|
|
|
2009-12-27 11:51:45 -05:00
|
|
|
int totalDone = 0;
|
2009-12-17 21:36:37 -05:00
|
|
|
|
|
|
|
|
2009-12-27 11:51:45 -05:00
|
|
|
public void messageStarted(String message, int number, int ofTotal) {}
|
|
|
|
public void messageFinished(Message message, int number, int ofTotal)
|
|
|
|
{
|
2009-12-17 21:36:37 -05:00
|
|
|
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!isMessageSuppressed(account, folder, message))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-12-27 11:51:45 -05:00
|
|
|
pendingMessages.add(message);
|
|
|
|
totalDone++;
|
|
|
|
if (pendingMessages.size() > 10)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-12-27 11:51:45 -05:00
|
|
|
addPendingMessages();
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2009-12-17 21:36:37 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-12-27 11:51:45 -05:00
|
|
|
else
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2009-12-27 11:51:45 -05:00
|
|
|
l.listLocalMessagesRemoveMessage(account, folder, message);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2009-12-27 11:51:45 -05:00
|
|
|
}
|
|
|
|
public void messagesFinished(int number)
|
|
|
|
{
|
|
|
|
addPendingMessages();
|
|
|
|
}
|
|
|
|
private void addPendingMessages()
|
|
|
|
{
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-12-27 11:51:45 -05:00
|
|
|
{
|
|
|
|
l.listLocalMessagesAddMessages(account, folder, pendingMessages);
|
|
|
|
}
|
|
|
|
pendingMessages.clear();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2009-12-27 11:51:45 -05:00
|
|
|
localFolder = localStore.getFolder(folder);
|
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
|
|
|
|
|
|
|
localFolder.getMessages(
|
|
|
|
retrievalListener,
|
|
|
|
false // Skip deleted messages
|
2009-12-17 21:36:37 -05:00
|
|
|
);
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "Got ack that callbackRunner finished");
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-12-17 21:36:37 -05:00
|
|
|
{
|
|
|
|
l.listLocalMessagesFinished(account, folder);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-12-17 21:36:37 -05:00
|
|
|
{
|
|
|
|
l.listLocalMessagesFailed(account, folder, e.getMessage());
|
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2009-12-17 21:36:37 -05:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
localFolder.close();
|
2009-12-17 21:36:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-27 11:53:59 -05:00
|
|
|
|
2010-04-21 22:20:35 -04:00
|
|
|
public void searchLocalMessages(SearchSpecification searchSpecification, final Message[] messages, final MessagingListener listener)
|
2010-04-16 23:32:17 -04:00
|
|
|
{
|
2010-04-29 00:59:14 -04:00
|
|
|
searchLocalMessages(searchSpecification.getAccountUuids(), searchSpecification.getFolderNames(), messages,
|
|
|
|
searchSpecification.getQuery(), searchSpecification.isIntegrate(), searchSpecification.getRequiredFlags(), searchSpecification.getForbiddenFlags(), listener);
|
2010-04-16 23:32:17 -04:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-12-27 11:53:59 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Find all messages in any local account which match the query 'query'
|
2010-04-24 00:35:39 -04:00
|
|
|
* @param folderNames TODO
|
2009-12-27 11:53:59 -05:00
|
|
|
* @param query
|
|
|
|
* @param listener
|
2010-04-24 00:35:39 -04:00
|
|
|
* @param searchAccounts TODO
|
2010-04-21 22:20:35 -04:00
|
|
|
* @param account TODO
|
2010-04-16 23:32:17 -04:00
|
|
|
* @param account
|
2009-12-27 11:53:59 -05:00
|
|
|
* @throws MessagingException
|
|
|
|
*/
|
2010-04-29 00:59:14 -04:00
|
|
|
public void searchLocalMessages(final String[] accountUuids, final String[] folderNames, final Message[] messages, final String query, final boolean integrate,
|
|
|
|
final Flag[] requiredFlags, final Flag[] forbiddenFlags, final MessagingListener listener)
|
2009-12-27 11:53:59 -05:00
|
|
|
{
|
2010-04-24 15:10:57 -04:00
|
|
|
if (K9.DEBUG)
|
2010-04-21 22:20:35 -04:00
|
|
|
{
|
2010-04-29 00:59:14 -04:00
|
|
|
Log.i(K9.LOG_TAG, "searchLocalMessages ("
|
|
|
|
+ "accountUuids=" + Utility.combine(accountUuids, ',')
|
|
|
|
+ ", folderNames = " + Utility.combine(folderNames, ',')
|
|
|
|
+ ", messages.size() = " + (messages != null ? messages.length : null)
|
|
|
|
+ ", query = " + query
|
|
|
|
+ ", integrate = " + integrate
|
|
|
|
+ ", requiredFlags = " + Utility.combine(requiredFlags, ',')
|
|
|
|
+ ", forbiddenFlags = " + Utility.combine(forbiddenFlags, ',')
|
|
|
|
+ ")");
|
|
|
|
}
|
|
|
|
|
2010-08-10 00:29:18 -04:00
|
|
|
new Thread(new Runnable()
|
2009-12-27 11:53:59 -05:00
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
|
2010-04-24 15:10:57 -04:00
|
|
|
final AccountStats stats = new AccountStats();
|
|
|
|
final Set<String> accountUuidsSet = new HashSet<String>();
|
|
|
|
if (accountUuids != null)
|
|
|
|
{
|
|
|
|
for (String accountUuid : accountUuids)
|
|
|
|
{
|
2010-04-29 00:59:14 -04:00
|
|
|
accountUuidsSet.add(accountUuid);
|
2010-04-24 15:10:57 -04:00
|
|
|
}
|
|
|
|
}
|
2010-04-05 22:54:48 -04:00
|
|
|
final Preferences prefs = Preferences.getPreferences(mApplication.getApplicationContext());
|
2009-12-27 11:53:59 -05:00
|
|
|
Account[] accounts = prefs.getAccounts();
|
2010-04-05 22:54:48 -04:00
|
|
|
List<LocalFolder> foldersToSearch = null;
|
|
|
|
boolean displayableOnly = false;
|
2010-04-22 00:58:50 -04:00
|
|
|
boolean noSpecialFolders = true;
|
2009-12-27 11:53:59 -05:00
|
|
|
for (final Account account : accounts)
|
|
|
|
{
|
2010-08-29 19:39:26 -04:00
|
|
|
if (accountUuids != null && !accountUuidsSet.contains(account.getUuid()))
|
2010-04-21 22:20:35 -04:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-08-29 19:39:26 -04:00
|
|
|
if (accountUuids != null && accountUuidsSet.contains(account.getUuid()))
|
2010-04-05 22:54:48 -04:00
|
|
|
{
|
2010-04-22 00:58:50 -04:00
|
|
|
displayableOnly = true;
|
|
|
|
noSpecialFolders = true;
|
|
|
|
}
|
2010-08-29 19:39:26 -04:00
|
|
|
else if (!integrate && folderNames == null)
|
2010-04-22 00:58:50 -04:00
|
|
|
{
|
|
|
|
Account.Searchable searchableFolders = account.getSearchableFolders();
|
|
|
|
switch (searchableFolders)
|
|
|
|
{
|
|
|
|
case NONE:
|
|
|
|
continue;
|
|
|
|
case DISPLAYABLE:
|
|
|
|
displayableOnly = true;
|
|
|
|
break;
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-22 00:58:50 -04:00
|
|
|
}
|
2010-04-05 22:54:48 -04:00
|
|
|
}
|
2010-05-01 16:06:52 -04:00
|
|
|
List<Message> messagesToSearch = null;
|
|
|
|
if (messages != null)
|
|
|
|
{
|
|
|
|
messagesToSearch = new LinkedList<Message>();
|
|
|
|
for (Message message : messages)
|
|
|
|
{
|
|
|
|
if (message.getFolder().getAccount().getUuid().equals(account.getUuid()))
|
|
|
|
{
|
|
|
|
messagesToSearch.add(message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (messagesToSearch.isEmpty())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2010-04-16 23:32:17 -04:00
|
|
|
if (listener != null)
|
|
|
|
{
|
|
|
|
listener.listLocalMessagesStarted(account, null);
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-24 15:10:57 -04:00
|
|
|
if (integrate || displayableOnly || folderNames != null || noSpecialFolders)
|
2010-04-05 22:54:48 -04:00
|
|
|
{
|
|
|
|
List<LocalFolder> tmpFoldersToSearch = new LinkedList<LocalFolder>();
|
|
|
|
try
|
|
|
|
{
|
|
|
|
LocalStore store = account.getLocalStore();
|
2010-05-30 12:56:50 -04:00
|
|
|
List<? extends Folder> folders = store.getPersonalNamespaces(false);
|
2010-04-24 15:10:57 -04:00
|
|
|
Set<String> folderNameSet = null;
|
2010-04-24 00:35:39 -04:00
|
|
|
if (folderNames != null)
|
|
|
|
{
|
2010-04-24 15:10:57 -04:00
|
|
|
folderNameSet = new HashSet<String>();
|
2010-04-24 00:35:39 -04:00
|
|
|
for (String folderName : folderNames)
|
|
|
|
{
|
2010-04-24 15:10:57 -04:00
|
|
|
folderNameSet.add(folderName);
|
2010-04-24 00:35:39 -04:00
|
|
|
}
|
|
|
|
}
|
2010-04-21 22:20:35 -04:00
|
|
|
for (Folder folder : folders)
|
2010-04-05 22:54:48 -04:00
|
|
|
{
|
2010-04-21 22:20:35 -04:00
|
|
|
LocalFolder localFolder = (LocalFolder)folder;
|
2010-04-05 22:54:48 -04:00
|
|
|
boolean include = true;
|
|
|
|
folder.refresh(prefs);
|
2010-04-22 00:58:50 -04:00
|
|
|
String localFolderName = localFolder.getName();
|
2010-04-24 00:35:39 -04:00
|
|
|
if (integrate)
|
2010-04-22 00:58:50 -04:00
|
|
|
{
|
2010-04-24 00:35:39 -04:00
|
|
|
include = localFolder.isIntegrate();
|
2010-04-22 00:58:50 -04:00
|
|
|
}
|
2010-04-24 00:35:39 -04:00
|
|
|
else
|
2010-04-05 22:54:48 -04:00
|
|
|
{
|
2010-04-24 15:10:57 -04:00
|
|
|
if (folderNameSet != null)
|
2010-04-24 00:35:39 -04:00
|
|
|
{
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!folderNameSet.contains(localFolderName))
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-24 15:10:57 -04:00
|
|
|
{
|
|
|
|
include = false;
|
|
|
|
}
|
2010-04-24 00:35:39 -04:00
|
|
|
}
|
2010-06-17 08:42:22 -04:00
|
|
|
// Never exclude the INBOX (see issue 1817)
|
|
|
|
else if (noSpecialFolders && !localFolderName.equals(K9.INBOX) && (
|
2010-04-29 00:59:14 -04:00
|
|
|
localFolderName.equals(account.getTrashFolderName()) ||
|
|
|
|
localFolderName.equals(account.getOutboxFolderName()) ||
|
|
|
|
localFolderName.equals(account.getDraftsFolderName()) ||
|
|
|
|
localFolderName.equals(account.getSentFolderName()) ||
|
|
|
|
localFolderName.equals(account.getErrorFolderName())))
|
2010-04-24 00:35:39 -04:00
|
|
|
{
|
|
|
|
include = false;
|
|
|
|
}
|
|
|
|
else if (displayableOnly && modeMismatch(account.getFolderDisplayMode(), folder.getDisplayClass()))
|
|
|
|
{
|
|
|
|
include = false;
|
|
|
|
}
|
2010-04-05 22:54:48 -04:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-05 22:54:48 -04:00
|
|
|
if (include)
|
|
|
|
{
|
2010-04-21 22:20:35 -04:00
|
|
|
tmpFoldersToSearch.add(localFolder);
|
2010-04-05 22:54:48 -04:00
|
|
|
}
|
|
|
|
}
|
2010-04-25 13:52:59 -04:00
|
|
|
if (tmpFoldersToSearch.size() < 1)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2010-04-05 22:54:48 -04:00
|
|
|
foldersToSearch = tmpFoldersToSearch;
|
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
|
|
|
Log.e(K9.LOG_TAG, "Unable to restrict search folders in Account " + account.getDescription() + ", searching all", me);
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
2010-04-05 22:54:48 -04:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-05 22:54:48 -04:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-12-27 11:53:59 -05:00
|
|
|
MessageRetrievalListener retrievalListener = new MessageRetrievalListener()
|
|
|
|
{
|
|
|
|
public void messageStarted(String message, int number, int ofTotal) {}
|
|
|
|
public void messageFinished(Message message, int number, int ofTotal)
|
|
|
|
{
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!isMessageSuppressed(message.getFolder().getAccount(), message.getFolder().getName(), message))
|
2010-04-16 23:32:17 -04:00
|
|
|
{
|
2010-05-30 12:56:50 -04:00
|
|
|
List<Message> messages = new ArrayList<Message>();
|
2010-07-06 06:29:26 -04:00
|
|
|
|
2010-05-30 12:56:50 -04:00
|
|
|
messages.add(message);
|
2010-08-29 19:40:00 -04:00
|
|
|
stats.unreadMessageCount += (!message.isSet(Flag.SEEN)) ? 1 : 0;
|
2010-05-30 12:56:50 -04:00
|
|
|
stats.flaggedMessageCount += (message.isSet(Flag.FLAGGED)) ? 1 : 0;
|
|
|
|
if (listener != null)
|
|
|
|
{
|
|
|
|
listener.listLocalMessagesAddMessages(account, null, messages);
|
|
|
|
}
|
2010-04-16 23:32:17 -04:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-12-27 11:53:59 -05:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
public void messagesFinished(int number)
|
2010-04-16 23:32:17 -04:00
|
|
|
{
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-16 23:32:17 -04:00
|
|
|
}
|
2009-12-27 11:53:59 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2010-05-29 17:56:17 -04:00
|
|
|
String[] queryFields = {"html_content","subject","sender_list"};
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
2010-05-29 17:56:17 -04:00
|
|
|
localStore.searchForMessages(retrievalListener, queryFields
|
2010-05-30 00:17:00 -04:00
|
|
|
, query, foldersToSearch,
|
2010-08-02 07:55:31 -04:00
|
|
|
messagesToSearch == null ? null : messagesToSearch.toArray(EMPTY_MESSAGE_ARRAY),
|
2010-05-11 22:51:59 -04:00
|
|
|
requiredFlags, forbiddenFlags);
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-12-27 11:53:59 -05:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-04-16 23:32:17 -04:00
|
|
|
if (listener != null)
|
|
|
|
{
|
|
|
|
listener.listLocalMessagesFailed(account, null, e.getMessage());
|
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2009-12-27 11:53:59 -05:00
|
|
|
}
|
2009-12-27 12:22:51 -05:00
|
|
|
finally
|
|
|
|
{
|
2010-04-16 23:32:17 -04:00
|
|
|
if (listener != null)
|
|
|
|
{
|
|
|
|
listener.listLocalMessagesFinished(account, null);
|
|
|
|
}
|
2009-12-27 12:22:51 -05:00
|
|
|
}
|
2009-12-27 11:53:59 -05:00
|
|
|
}
|
2010-04-22 00:58:50 -04:00
|
|
|
if (listener != null)
|
|
|
|
{
|
|
|
|
listener.searchStats(stats);
|
|
|
|
}
|
2009-12-27 11:53:59 -05:00
|
|
|
}
|
2010-08-10 00:29:18 -04:00
|
|
|
}).start();
|
2009-12-27 11:53:59 -05:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void loadMoreMessages(Account account, String folder, MessagingListener listener)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
|
|
|
LocalFolder localFolder = localStore.getFolder(folder);
|
2009-11-24 19:40:29 -05:00
|
|
|
localFolder.setVisibleLimit(localFolder.getVisibleLimit() + account.getDisplayCount());
|
2010-05-15 15:35:07 -04:00
|
|
|
synchronizeMailbox(account, folder, listener, null);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
throw new RuntimeException("Unable to set visible limit on folder", me);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void resetVisibleLimits(Account[] accounts)
|
|
|
|
{
|
|
|
|
for (Account account : accounts)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
2008-12-11 00:25:59 -05:00
|
|
|
localStore.resetVisibleLimits(account.getDisplayCount());
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (MessagingException e)
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to reset visible limits", e);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start background synchronization of the specified folder.
|
|
|
|
* @param account
|
|
|
|
* @param folder
|
|
|
|
* @param listener
|
2010-05-15 15:35:07 -04:00
|
|
|
* @param providedRemoteFolder TODO
|
2008-11-01 17:32:06 -04:00
|
|
|
*/
|
2010-05-15 15:35:07 -04:00
|
|
|
public void synchronizeMailbox(final Account account, final String folder, final MessagingListener listener, final Folder providedRemoteFolder)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
putBackground("synchronizeMailbox", listener, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
2010-05-15 15:35:07 -04:00
|
|
|
synchronizeMailboxSynchronous(account, folder, listener, providedRemoteFolder);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start foreground synchronization of the specified folder. This is generally only called
|
|
|
|
* by synchronizeMailbox.
|
|
|
|
* @param account
|
|
|
|
* @param folder
|
|
|
|
*
|
|
|
|
* TODO Break this method up into smaller chunks.
|
2010-05-15 15:35:07 -04:00
|
|
|
* @param providedRemoteFolder TODO
|
2008-11-01 17:32:06 -04:00
|
|
|
*/
|
2010-05-15 15:35:07 -04:00
|
|
|
private void synchronizeMailboxSynchronous(final Account account, final String folder, final MessagingListener listener, Folder providedRemoteFolder)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
Folder remoteFolder = null;
|
|
|
|
LocalFolder tLocalFolder = null;
|
2010-05-11 22:51:59 -04:00
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Synchronizing folder " + account.getDescription() + ":" + folder);
|
2009-05-10 01:47:26 -04:00
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.synchronizeMailboxStarted(account, folder);
|
|
|
|
}
|
2010-05-09 11:27:41 -04:00
|
|
|
/*
|
|
|
|
* We don't ever sync the Outbox or errors folder
|
|
|
|
*/
|
|
|
|
if (folder.equals(account.getOutboxFolderName()) || folder.equals(account.getErrorFolderName()))
|
|
|
|
{
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2010-05-09 11:27:41 -04:00
|
|
|
{
|
|
|
|
l.synchronizeMailboxFinished(account, folder, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2010-01-17 19:11:02 -05:00
|
|
|
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
Exception commandException = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
Log.d(K9.LOG_TAG, "SYNC: About to process pending commands for account " +
|
2009-12-20 00:41:43 -05:00
|
|
|
account.getDescription());
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2009-05-10 01:47:26 -04:00
|
|
|
processPendingCommandsSynchronous(account);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Failure processing command, but allow message sync attempt", e);
|
2009-05-10 01:47:26 -04:00
|
|
|
commandException = e;
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the message list from the local store and create an index of
|
|
|
|
* the uids within the list.
|
|
|
|
*/
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "SYNC: About to get local folder " + folder);
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
final LocalStore localStore = account.getLocalStore();
|
|
|
|
tLocalFolder = localStore.getFolder(folder);
|
2009-05-10 01:47:26 -04:00
|
|
|
final LocalFolder localFolder = tLocalFolder;
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
|
|
|
Message[] localMessages = localFolder.getMessages(null);
|
|
|
|
HashMap<String, Message> localUidMap = new HashMap<String, Message>();
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Message message : localMessages)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
localUidMap.put(message.getUid(), message);
|
|
|
|
}
|
|
|
|
|
2010-05-15 15:35:07 -04:00
|
|
|
if (providedRemoteFolder != null)
|
|
|
|
{
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "SYNC: using providedRemoteFolder " + folder);
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2010-05-15 15:35:07 -04:00
|
|
|
remoteFolder = providedRemoteFolder;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Store remoteStore = account.getRemoteStore();
|
2010-07-10 12:41:34 -04:00
|
|
|
|
2010-05-15 15:35:07 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "SYNC: About to get remote folder " + folder);
|
|
|
|
remoteFolder = remoteStore.getFolder(folder);
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-05-15 15:46:16 -04:00
|
|
|
|
2010-07-10 12:41:34 -04:00
|
|
|
|
|
|
|
if (! verifyOrCreateRemoteSpecialFolder(account, folder, remoteFolder, listener))
|
|
|
|
{
|
|
|
|
return;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-07-10 12:41:34 -04:00
|
|
|
|
|
|
|
|
2010-05-15 15:46:16 -04:00
|
|
|
/*
|
|
|
|
* Synchronization process:
|
|
|
|
Open the folder
|
|
|
|
Upload any local messages that are marked as PENDING_UPLOAD (Drafts, Sent, Trash)
|
|
|
|
Get the message count
|
|
|
|
Get the list of the newest K9.DEFAULT_VISIBLE_LIMIT messages
|
|
|
|
getMessages(messageCount - K9.DEFAULT_VISIBLE_LIMIT, messageCount)
|
|
|
|
See if we have each message locally, if not fetch it's flags and envelope
|
|
|
|
Get and update the unread count for the folder
|
|
|
|
Update the remote flags of any messages we have locally with an internal date
|
|
|
|
newer than the remote message.
|
|
|
|
Get the current flags for any messages we have locally but did not just download
|
|
|
|
Update local flags
|
|
|
|
For any message we have locally but not remotely, delete the local message to keep
|
|
|
|
cache clean.
|
|
|
|
Download larger parts of any new messages.
|
|
|
|
(Optional) Download small attachments in the background.
|
|
|
|
*/
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-05-15 15:46:16 -04:00
|
|
|
/*
|
|
|
|
* Open the remote folder. This pre-loads certain metadata like message count.
|
|
|
|
*/
|
2010-05-15 15:35:07 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "SYNC: About to open remote folder " + folder);
|
2010-05-15 15:46:16 -04:00
|
|
|
|
2010-05-15 15:35:07 -04:00
|
|
|
remoteFolder.open(OpenMode.READ_WRITE);
|
2010-05-30 17:20:47 -04:00
|
|
|
if (Account.EXPUNGE_ON_POLL.equals(account.getExpungePolicy()))
|
|
|
|
{
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "SYNC: Expunging folder " + account.getDescription() + ":" + folder);
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-12-27 12:22:51 -05:00
|
|
|
|
2010-05-30 17:20:47 -04:00
|
|
|
remoteFolder.expunge();
|
|
|
|
}
|
2009-12-27 12:22:51 -05:00
|
|
|
|
2010-05-30 17:20:47 -04:00
|
|
|
}
|
2010-07-06 06:29:26 -04:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* Get the remote message count.
|
|
|
|
*/
|
|
|
|
int remoteMessageCount = remoteFolder.getMessageCount();
|
|
|
|
|
|
|
|
int visibleLimit = localFolder.getVisibleLimit();
|
|
|
|
|
2010-06-07 22:37:18 -04:00
|
|
|
if (visibleLimit < 1)
|
|
|
|
{
|
2010-07-06 06:29:26 -04:00
|
|
|
visibleLimit = K9.DEFAULT_VISIBLE_LIMIT;
|
2010-06-07 22:37:18 -04:00
|
|
|
}
|
|
|
|
|
2010-08-02 07:55:31 -04:00
|
|
|
Message[] remoteMessageArray = EMPTY_MESSAGE_ARRAY;
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
final ArrayList<Message> remoteMessages = new ArrayList<Message>();
|
2009-11-24 19:40:29 -05:00
|
|
|
// final ArrayList<Message> unsyncedMessages = new ArrayList<Message>();
|
2008-11-01 17:32:06 -04:00
|
|
|
HashMap<String, Message> remoteUidMap = new HashMap<String, Message>();
|
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
2010-01-02 20:50:41 -05:00
|
|
|
Log.v(K9.LOG_TAG, "SYNC: Remote message count for folder " + folder + " is " + remoteMessageCount);
|
2010-05-30 17:20:47 -04:00
|
|
|
final Date earliestDate = account.getEarliestPollDate();
|
2009-11-24 19:40:29 -05:00
|
|
|
if (remoteMessageCount > 0)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* Message numbers start at 1.
|
|
|
|
*/
|
|
|
|
int remoteStart = Math.max(0, remoteMessageCount - visibleLimit) + 1;
|
|
|
|
int remoteEnd = remoteMessageCount;
|
2009-05-10 01:47:26 -04:00
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "SYNC: About to get messages " + remoteStart + " through " + remoteEnd + " for folder " + folder);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2010-07-13 19:59:14 -04:00
|
|
|
final AtomicInteger headerProgress = new AtomicInteger(0);
|
|
|
|
for (MessagingListener l : getListeners(listener))
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxHeadersStarted(account, folder);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-30 17:20:47 -04:00
|
|
|
remoteMessageArray = remoteFolder.getMessages(remoteStart, remoteEnd, earliestDate, null);
|
2010-07-13 19:59:14 -04:00
|
|
|
|
|
|
|
int messageCount = remoteMessageArray.length;
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Message thisMess : remoteMessageArray)
|
|
|
|
{
|
2010-07-13 19:59:14 -04:00
|
|
|
headerProgress.incrementAndGet();
|
|
|
|
for (MessagingListener l : getListeners(listener))
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxHeadersProgress(account, folder, headerProgress.get(), messageCount);
|
|
|
|
}
|
2010-05-30 17:20:47 -04:00
|
|
|
Message localMessage = localUidMap.get(thisMess.getUid());
|
2010-08-29 19:39:26 -04:00
|
|
|
if (localMessage == null || !localMessage.olderThan(earliestDate))
|
2010-05-30 17:20:47 -04:00
|
|
|
{
|
|
|
|
remoteMessages.add(thisMess);
|
|
|
|
remoteUidMap.put(thisMess.getUid(), thisMess);
|
|
|
|
}
|
2009-05-10 01:47:26 -04:00
|
|
|
}
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "SYNC: Got " + remoteUidMap.size() + " messages for folder " + folder);
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-05-20 00:27:51 -04:00
|
|
|
remoteMessageArray = null;
|
2010-07-13 19:59:14 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxHeadersFinished(account, folder, headerProgress.get(), remoteUidMap.size());
|
|
|
|
}
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else if (remoteMessageCount < 0)
|
|
|
|
{
|
2009-05-10 01:47:26 -04:00
|
|
|
throw new Exception("Message count " + remoteMessageCount + " for folder " + folder);
|
2009-04-21 00:22:02 -04:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
/*
|
2010-05-30 17:20:47 -04:00
|
|
|
* Remove any messages that are in the local store but no longer on the remote store or are too old
|
2008-11-01 17:32:06 -04:00
|
|
|
*/
|
2010-07-03 09:10:38 -04:00
|
|
|
if (account.syncRemoteDeletions())
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-07-03 09:10:38 -04:00
|
|
|
for (Message localMessage : localMessages)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-07-03 09:10:38 -04:00
|
|
|
if (remoteUidMap.get(localMessage.getUid()) == null && !localMessage.isSet(Flag.DELETED))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-07-03 09:10:38 -04:00
|
|
|
localMessage.setFlag(Flag.X_DESTROYED, true);
|
2010-07-06 06:29:26 -04:00
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2010-07-03 09:10:38 -04:00
|
|
|
{
|
|
|
|
l.synchronizeMailboxRemovedMessage(account, folder, localMessage);
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
2009-05-20 00:27:51 -04:00
|
|
|
localMessages = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* Now we download the actual content of messages.
|
|
|
|
*/
|
2009-11-26 00:10:12 -05:00
|
|
|
int newMessages = downloadMessages(account, remoteFolder, localFolder, remoteMessages, false);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-12-27 15:19:41 -05:00
|
|
|
int unreadMessageCount = setLocalUnreadCountToRemote(localFolder, remoteFolder, newMessages);
|
2010-04-16 10:33:54 -04:00
|
|
|
setLocalFlaggedCountToRemote(localFolder, remoteFolder);
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-05-10 01:47:26 -04:00
|
|
|
|
2010-01-02 20:50:51 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.folderStatusChanged(account, folder, unreadMessageCount);
|
|
|
|
}
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
2009-10-21 20:41:06 -04:00
|
|
|
* Notify listeners that we're finally done.
|
2008-11-01 17:32:06 -04:00
|
|
|
*/
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
localFolder.setLastChecked(System.currentTimeMillis());
|
|
|
|
localFolder.setStatus(null);
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
Log.d(K9.LOG_TAG, "Done synchronizing folder " +
|
2009-12-20 00:41:43 -05:00
|
|
|
account.getDescription() + ":" + folder + " @ " + new Date() +
|
|
|
|
" with " + newMessages + " new messages");
|
2009-05-10 01:47:26 -04:00
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
l.synchronizeMailboxFinished(account, folder, remoteMessageCount, newMessages);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
2009-05-10 01:47:26 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
if (commandException != null)
|
|
|
|
{
|
2009-05-10 01:47:26 -04:00
|
|
|
String rootMessage = getRootCauseMessage(commandException);
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Root cause failure in " + account.getDescription() + ":" +
|
2009-11-24 19:40:29 -05:00
|
|
|
tLocalFolder.getName() + " was '" + rootMessage + "'");
|
2009-05-10 01:47:26 -04:00
|
|
|
localFolder.setStatus(rootMessage);
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
l.synchronizeMailboxFailed(account, folder, rootMessage);
|
2009-05-10 01:47:26 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Done synchronizing folder " + account.getDescription() + ":" + folder);
|
2009-05-10 01:47:26 -04:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "synchronizeMailbox", e);
|
2009-05-10 01:47:26 -04:00
|
|
|
// If we don't set the last checked, it can try too often during
|
|
|
|
// failure conditions
|
|
|
|
String rootMessage = getRootCauseMessage(e);
|
2009-11-24 19:40:29 -05:00
|
|
|
if (tLocalFolder != null)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2009-05-10 01:47:26 -04:00
|
|
|
tLocalFolder.setStatus(rootMessage);
|
|
|
|
tLocalFolder.setLastChecked(System.currentTimeMillis());
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Could not set last checked on folder " + account.getDescription() + ":" +
|
2009-11-24 19:40:29 -05:00
|
|
|
tLocalFolder.getName(), e);
|
2009-05-10 01:47:26 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.synchronizeMailboxFailed(
|
2009-05-10 01:47:26 -04:00
|
|
|
account,
|
|
|
|
folder,
|
|
|
|
rootMessage);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Failed synchronizing folder " +
|
2009-12-20 00:41:43 -05:00
|
|
|
account.getDescription() + ":" + folder + " @ " + new Date());
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
finally
|
|
|
|
{
|
2010-05-15 15:35:07 -04:00
|
|
|
if (providedRemoteFolder == null && remoteFolder != null)
|
2010-01-16 11:22:20 -05:00
|
|
|
{
|
|
|
|
remoteFolder.close();
|
|
|
|
}
|
|
|
|
if (tLocalFolder != null)
|
|
|
|
{
|
|
|
|
tLocalFolder.close();
|
|
|
|
}
|
|
|
|
}
|
2009-05-10 01:47:26 -04:00
|
|
|
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-07-10 12:41:34 -04:00
|
|
|
/*
|
|
|
|
* If the folder is a "special" folder we need to see if it exists
|
|
|
|
* on the remote server. It if does not exist we'll try to create it. If we
|
|
|
|
* can't create we'll abort. This will happen on every single Pop3 folder as
|
|
|
|
* designed and on Imap folders during error conditions. This allows us
|
|
|
|
* to treat Pop3 and Imap the same in this code.
|
|
|
|
*/
|
|
|
|
private boolean verifyOrCreateRemoteSpecialFolder(final Account account, final String folder, final Folder remoteFolder, final MessagingListener listener) throws MessagingException
|
|
|
|
{
|
|
|
|
if (folder.equals(account.getTrashFolderName()) ||
|
|
|
|
folder.equals(account.getSentFolderName()) ||
|
|
|
|
folder.equals(account.getDraftsFolderName()))
|
|
|
|
{
|
|
|
|
if (!remoteFolder.exists())
|
|
|
|
{
|
|
|
|
if (!remoteFolder.create(FolderType.HOLDS_MESSAGES))
|
|
|
|
{
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2010-07-10 12:41:34 -04:00
|
|
|
{
|
|
|
|
l.synchronizeMailboxFinished(account, folder, 0, 0);
|
|
|
|
}
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Done synchronizing folder " + folder);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
private int setLocalUnreadCountToRemote(LocalFolder localFolder, Folder remoteFolder, int newMessageCount) throws MessagingException
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
|
|
|
int remoteUnreadMessageCount = remoteFolder.getUnreadMessageCount();
|
2009-11-24 19:40:29 -05:00
|
|
|
if (remoteUnreadMessageCount != -1)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
localFolder.setUnreadMessageCount(remoteUnreadMessageCount);
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-05-01 19:20:54 -04:00
|
|
|
int unreadCount = 0;
|
|
|
|
Message[] messages = localFolder.getMessages(null, false);
|
|
|
|
for (Message message : messages)
|
|
|
|
{
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!message.isSet(Flag.SEEN) && !message.isSet(Flag.DELETED))
|
2010-05-01 19:20:54 -04:00
|
|
|
{
|
|
|
|
unreadCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
localFolder.setUnreadMessageCount(unreadCount);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-05-01 19:20:54 -04:00
|
|
|
return localFolder.getUnreadMessageCount();
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-16 10:33:54 -04:00
|
|
|
private void setLocalFlaggedCountToRemote(LocalFolder localFolder, Folder remoteFolder) throws MessagingException
|
|
|
|
{
|
|
|
|
int remoteFlaggedMessageCount = remoteFolder.getFlaggedMessageCount();
|
|
|
|
if (remoteFlaggedMessageCount != -1)
|
|
|
|
{
|
|
|
|
localFolder.setFlaggedMessageCount(remoteFlaggedMessageCount);
|
|
|
|
}
|
2010-05-01 19:20:54 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
int flaggedCount = 0;
|
|
|
|
Message[] messages = localFolder.getMessages(null, false);
|
|
|
|
for (Message message : messages)
|
|
|
|
{
|
2010-08-29 19:39:26 -04:00
|
|
|
if (message.isSet(Flag.FLAGGED) && !message.isSet(Flag.DELETED))
|
2010-05-01 19:20:54 -04:00
|
|
|
{
|
|
|
|
flaggedCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
localFolder.setFlaggedMessageCount(flaggedCount);
|
|
|
|
}
|
2010-04-16 10:33:54 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
private int downloadMessages(final Account account, final Folder remoteFolder,
|
2009-11-26 00:10:12 -05:00
|
|
|
final LocalFolder localFolder, List<Message> inputMessages, boolean flagSyncOnly) throws MessagingException
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-05-30 17:20:47 -04:00
|
|
|
final Date earliestDate = account.getEarliestPollDate();
|
|
|
|
if (earliestDate != null)
|
|
|
|
{
|
|
|
|
if (K9.DEBUG)
|
|
|
|
{
|
|
|
|
Log.d(K9.LOG_TAG, "Only syncing messages after " + earliestDate);
|
|
|
|
}
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
final String folder = remoteFolder.getName();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-08-08 15:14:52 -04:00
|
|
|
int unreadBeforeStart = 0;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
AccountStats stats = account.getStats(mApplication);
|
|
|
|
unreadBeforeStart = stats.unreadMessageCount;
|
|
|
|
|
|
|
|
}
|
|
|
|
catch (MessagingException e)
|
|
|
|
{
|
|
|
|
Log.e(K9.LOG_TAG, "Unable to getUnreadMessageCount for account: " + account, e);
|
|
|
|
}
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
ArrayList<Message> syncFlagMessages = new ArrayList<Message>();
|
2009-11-26 00:10:12 -05:00
|
|
|
List<Message> unsyncedMessages = new ArrayList<Message>();
|
2009-10-21 20:41:06 -04:00
|
|
|
final AtomicInteger newMessages = new AtomicInteger(0);
|
|
|
|
|
|
|
|
List<Message> messages = new ArrayList<Message>(inputMessages);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
for (Message message : messages)
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2010-05-15 15:35:07 -04:00
|
|
|
if (message.isSet(Flag.DELETED))
|
|
|
|
{
|
|
|
|
syncFlagMessages.add(message);
|
|
|
|
}
|
2010-08-29 19:39:26 -04:00
|
|
|
else if (!isMessageSuppressed(account, folder, message))
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
|
|
|
Message localMessage = localFolder.getMessage(message.getUid());
|
|
|
|
|
|
|
|
if (localMessage == null)
|
|
|
|
{
|
2009-11-26 00:10:12 -05:00
|
|
|
if (!flagSyncOnly)
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2009-11-26 00:10:12 -05:00
|
|
|
if (!message.isSet(Flag.X_DOWNLOADED_FULL) && !message.isSet(Flag.X_DOWNLOADED_PARTIAL))
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
2010-07-10 12:40:55 -04:00
|
|
|
Log.v(K9.LOG_TAG, "Message with uid " + message.getUid() + " has not yet been downloaded");
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-11-26 00:10:12 -05:00
|
|
|
unsyncedMessages.add(message);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-26 00:10:12 -05:00
|
|
|
else
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "Message with uid " + message.getUid() + " is partially or fully downloaded");
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-11-26 00:10:12 -05:00
|
|
|
// Store the updated message locally
|
|
|
|
localFolder.appendMessages(new Message[] { message });
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-11-26 00:10:12 -05:00
|
|
|
localMessage = localFolder.getMessage(message.getUid());
|
2009-10-21 20:41:06 -04:00
|
|
|
|
2009-11-26 00:10:12 -05:00
|
|
|
localMessage.setFlag(Flag.X_DOWNLOADED_FULL, message.isSet(Flag.X_DOWNLOADED_FULL));
|
|
|
|
localMessage.setFlag(Flag.X_DOWNLOADED_PARTIAL, message.isSet(Flag.X_DOWNLOADED_PARTIAL));
|
2009-10-21 20:41:06 -04:00
|
|
|
|
2009-11-26 00:10:12 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-11-26 00:10:12 -05:00
|
|
|
l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage);
|
|
|
|
if (!localMessage.isSet(Flag.SEEN))
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxNewMessage(account, folder, localMessage);
|
|
|
|
}
|
2009-11-08 22:52:59 -05:00
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-08-29 19:39:26 -04:00
|
|
|
else if (!localMessage.isSet(Flag.DELETED))
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
2010-07-10 12:40:55 -04:00
|
|
|
Log.v(K9.LOG_TAG, "Message with uid " + message.getUid() + " is present in the local store");
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-12-06 19:56:06 -05:00
|
|
|
if (!localMessage.isSet(Flag.X_DOWNLOADED_FULL) && !localMessage.isSet(Flag.X_DOWNLOADED_PARTIAL))
|
2009-11-29 11:55:35 -05:00
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "Message with uid " + message.getUid()
|
2009-12-06 19:56:06 -05:00
|
|
|
+ " is not downloaded, even partially; trying again");
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-11-29 11:55:35 -05:00
|
|
|
unsyncedMessages.add(message);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-04-05 22:54:48 -04:00
|
|
|
String newPushState = remoteFolder.getNewPushState(localFolder.getPushState(), message);
|
|
|
|
if (newPushState != null)
|
|
|
|
{
|
|
|
|
localFolder.setPushState(newPushState);
|
|
|
|
}
|
2009-11-29 11:55:35 -05:00
|
|
|
syncFlagMessages.add(message);
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-20 00:41:43 -05:00
|
|
|
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
final AtomicInteger progress = new AtomicInteger(0);
|
|
|
|
final int todo = unsyncedMessages.size() + syncFlagMessages.size();
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "SYNC: Have " + unsyncedMessages.size() + " unsynced messages");
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
messages.clear();
|
|
|
|
final ArrayList<Message> largeMessages = new ArrayList<Message>();
|
|
|
|
final ArrayList<Message> smallMessages = new ArrayList<Message>();
|
2009-11-24 19:40:29 -05:00
|
|
|
if (unsyncedMessages.size() > 0)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Reverse the order of the messages. Depending on the server this may get us
|
|
|
|
* fetch results for newest to oldest. If not, no harm done.
|
|
|
|
*/
|
|
|
|
Collections.reverse(unsyncedMessages);
|
2009-11-26 00:10:12 -05:00
|
|
|
int visibleLimit = localFolder.getVisibleLimit();
|
|
|
|
int listSize = unsyncedMessages.size();
|
|
|
|
|
|
|
|
if (listSize > visibleLimit)
|
|
|
|
{
|
|
|
|
unsyncedMessages = unsyncedMessages.subList(listSize - visibleLimit, listSize);
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
FetchProfile fp = new FetchProfile();
|
2009-11-24 19:40:29 -05:00
|
|
|
if (remoteFolder.supportsFetchingFlags())
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
fp.add(FetchProfile.Item.FLAGS);
|
|
|
|
}
|
|
|
|
fp.add(FetchProfile.Item.ENVELOPE);
|
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
2010-07-10 12:40:55 -04:00
|
|
|
Log.d(K9.LOG_TAG, "SYNC: About to fetch " + unsyncedMessages.size() + " unsynced messages for folder " + folder);
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
|
2010-07-10 13:10:24 -04:00
|
|
|
fetchUnsyncedMessages(account, remoteFolder, localFolder, unsyncedMessages, smallMessages,largeMessages, progress, todo, fp);
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
// If a message didn't exist, messageFinished won't be called, but we shouldn't try again
|
|
|
|
// If we got here, nothing failed
|
|
|
|
for (Message message : unsyncedMessages)
|
|
|
|
{
|
|
|
|
String newPushState = remoteFolder.getNewPushState(localFolder.getPushState(), message);
|
|
|
|
if (newPushState != null)
|
|
|
|
{
|
|
|
|
localFolder.setPushState(newPushState);
|
|
|
|
}
|
|
|
|
}
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
{
|
|
|
|
Log.d(K9.LOG_TAG, "SYNC: Synced unsynced messages for folder " + folder);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "SYNC: Have "
|
|
|
|
+ largeMessages.size() + " large messages and "
|
|
|
|
+ smallMessages.size() + " small messages out of "
|
|
|
|
+ unsyncedMessages.size() + " unsynced messages");
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
unsyncedMessages.clear();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
/*
|
|
|
|
* Grab the content of the small messages first. This is going to
|
|
|
|
* be very fast and at very worst will be a single up of a few bytes and a single
|
|
|
|
* download of 625k.
|
|
|
|
*/
|
|
|
|
FetchProfile fp = new FetchProfile();
|
|
|
|
fp.add(FetchProfile.Item.BODY);
|
|
|
|
// fp.add(FetchProfile.Item.FLAGS);
|
|
|
|
// fp.add(FetchProfile.Item.ENVELOPE);
|
|
|
|
|
2010-08-08 14:50:31 -04:00
|
|
|
downloadSmallMessages(account, remoteFolder, localFolder, smallMessages, progress, unreadBeforeStart, newMessages, todo, fp);
|
2010-07-10 12:42:39 -04:00
|
|
|
|
|
|
|
|
|
|
|
smallMessages.clear();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now do the large messages that require more round trips.
|
|
|
|
*/
|
|
|
|
fp.clear();
|
|
|
|
fp.add(FetchProfile.Item.STRUCTURE);
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-08-08 14:50:31 -04:00
|
|
|
downloadLargeMessages(account, remoteFolder, localFolder, largeMessages, progress, unreadBeforeStart, newMessages, todo, fp);
|
2010-07-10 12:42:39 -04:00
|
|
|
largeMessages.clear();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Refresh the flags for any messages in the local store that we didn't just
|
|
|
|
* download.
|
|
|
|
*/
|
|
|
|
|
2010-07-10 12:42:54 -04:00
|
|
|
refreshLocalMessageFlags(account,remoteFolder,localFolder,syncFlagMessages,progress,todo);
|
2010-07-10 12:42:39 -04:00
|
|
|
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "SYNC: Synced remote messages for folder " + folder + ", " + newMessages.get() + " new messages");
|
|
|
|
|
|
|
|
localFolder.purgeToVisibleLimit(new MessageRemovalListener()
|
|
|
|
{
|
|
|
|
public void messageRemoved(Message message)
|
|
|
|
{
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxRemovedMessage(account, folder, message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
return newMessages.get();
|
|
|
|
}
|
|
|
|
|
2010-07-10 13:10:24 -04:00
|
|
|
private void fetchUnsyncedMessages(final Account account, final Folder remoteFolder,
|
|
|
|
final LocalFolder localFolder,
|
|
|
|
List<Message> unsyncedMessages,
|
|
|
|
final ArrayList<Message> smallMessages,
|
|
|
|
final ArrayList<Message> largeMessages,
|
|
|
|
final AtomicInteger progress,
|
|
|
|
final int todo,
|
|
|
|
FetchProfile fp) throws MessagingException
|
|
|
|
{
|
|
|
|
final String folder = remoteFolder.getName();
|
|
|
|
|
|
|
|
final Date earliestDate = account.getEarliestPollDate();
|
2010-08-02 07:55:31 -04:00
|
|
|
remoteFolder.fetch(unsyncedMessages.toArray(EMPTY_MESSAGE_ARRAY), fp,
|
2010-07-10 13:10:24 -04:00
|
|
|
new MessageRetrievalListener()
|
|
|
|
{
|
|
|
|
public void messageFinished(Message message, int number, int ofTotal)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
String newPushState = remoteFolder.getNewPushState(localFolder.getPushState(), message);
|
|
|
|
if (newPushState != null)
|
|
|
|
{
|
|
|
|
localFolder.setPushState(newPushState);
|
|
|
|
}
|
|
|
|
if (message.isSet(Flag.DELETED) || message.olderThan(earliestDate))
|
|
|
|
{
|
|
|
|
|
|
|
|
if (K9.DEBUG)
|
|
|
|
{
|
|
|
|
if (message.isSet(Flag.DELETED))
|
|
|
|
{
|
|
|
|
Log.v(K9.LOG_TAG, "Newly downloaded message " + account + ":" + folder + ":" + message.getUid()
|
|
|
|
+ " was marked deleted on server, skipping");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Log.d(K9.LOG_TAG, "Newly downloaded message " + message.getUid() + " is older than "
|
|
|
|
+ earliestDate + ", skipping");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
progress.incrementAndGet();
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-07-11 07:59:14 -04:00
|
|
|
if (message.getSize() > account.getMaximumAutoDownloadMessageSize())
|
2010-07-10 13:10:24 -04:00
|
|
|
{
|
|
|
|
largeMessages.add(message);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
smallMessages.add(message);
|
|
|
|
}
|
|
|
|
|
|
|
|
// And include it in the view
|
|
|
|
if (message.getSubject() != null &&
|
|
|
|
message.getFrom() != null)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* We check to make sure that we got something worth
|
|
|
|
* showing (subject and from) because some protocols
|
|
|
|
* (POP) may not be able to give us headers for
|
|
|
|
* ENVELOPE, only size.
|
|
|
|
*/
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!isMessageSuppressed(account, folder, message))
|
2010-07-10 13:10:24 -04:00
|
|
|
{
|
|
|
|
// Store the new message locally
|
|
|
|
localFolder.appendMessages(new Message[]
|
|
|
|
{
|
|
|
|
message
|
|
|
|
});
|
|
|
|
|
|
|
|
Message localMessage = localFolder.getMessage(message.getUid());
|
|
|
|
syncFlags(localMessage, message);
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "About to notify listeners that we got a new unsynced message "
|
|
|
|
+ account + ":" + folder + ":" + message.getUid());
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
Log.e(K9.LOG_TAG, "Error while storing downloaded message.", e);
|
|
|
|
addErrorMessage(account, null, e);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void messageStarted(String uid, int number, int ofTotal)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public void messagesFinished(int total) {}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2010-07-13 17:17:04 -04:00
|
|
|
|
|
|
|
private boolean shouldImportMessage(final Account account, final String folder, final Message message, final AtomicInteger progress, final Date earliestDate)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (isMessageSuppressed(account, folder, message))
|
|
|
|
{
|
|
|
|
if (K9.DEBUG)
|
|
|
|
{
|
|
|
|
Log.d(K9.LOG_TAG, "Message " + message.getUid() + " was suppressed "+
|
|
|
|
"but just downloaded. "+
|
|
|
|
"The race condition means we wasted some bandwidth. Oh well.");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
if (message.olderThan(earliestDate))
|
|
|
|
{
|
|
|
|
if (K9.DEBUG)
|
|
|
|
{
|
|
|
|
Log.d(K9.LOG_TAG, "Message " + message.getUid() + " is older than "
|
|
|
|
+ earliestDate + ", hence not saving");
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-07-10 12:42:39 -04:00
|
|
|
private void downloadSmallMessages(final Account account, final Folder remoteFolder,
|
|
|
|
final LocalFolder localFolder,
|
|
|
|
ArrayList<Message> smallMessages,
|
|
|
|
final AtomicInteger progress,
|
2010-08-08 14:50:31 -04:00
|
|
|
final int unreadBeforeStart,
|
2010-07-10 12:42:39 -04:00
|
|
|
final AtomicInteger newMessages,
|
|
|
|
final int todo,
|
|
|
|
FetchProfile fp) throws MessagingException
|
|
|
|
{
|
|
|
|
final String folder = remoteFolder.getName();
|
|
|
|
|
|
|
|
final Date earliestDate = account.getEarliestPollDate();
|
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "SYNC: Fetching small messages for folder " + folder);
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
remoteFolder.fetch(smallMessages.toArray(new Message[smallMessages.size()]),
|
2009-11-24 19:40:29 -05:00
|
|
|
fp, new MessageRetrievalListener()
|
|
|
|
{
|
|
|
|
public void messageFinished(Message message, int number, int ofTotal)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2010-07-08 11:49:26 -04:00
|
|
|
|
2010-07-13 17:17:04 -04:00
|
|
|
if (!shouldImportMessage(account, folder, message, progress, earliestDate))
|
2010-07-08 11:49:26 -04:00
|
|
|
{
|
2010-05-30 17:20:47 -04:00
|
|
|
progress.incrementAndGet();
|
2010-07-06 06:29:26 -04:00
|
|
|
|
2010-05-30 17:20:47 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
// Store the updated message locally
|
|
|
|
localFolder.appendMessages(new Message[] { message });
|
|
|
|
|
|
|
|
Message localMessage = localFolder.getMessage(message.getUid());
|
2010-05-30 17:20:47 -04:00
|
|
|
progress.incrementAndGet();
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
// Set a flag indicating this message has now be fully downloaded
|
|
|
|
localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "About to notify listeners that we got a new small message "
|
2009-11-24 19:40:29 -05:00
|
|
|
+ account + ":" + folder + ":" + message.getUid());
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
// Update the listener with what we've found
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage);
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
|
2009-11-24 19:40:29 -05:00
|
|
|
if (!localMessage.isSet(Flag.SEEN))
|
|
|
|
{
|
2009-11-08 22:52:59 -05:00
|
|
|
l.synchronizeMailboxNewMessage(account, folder, localMessage);
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-07-14 23:42:09 -04:00
|
|
|
// Send a notification of this message
|
2010-07-14 23:42:13 -04:00
|
|
|
|
2010-08-08 14:50:31 -04:00
|
|
|
if (shouldNotifyForMessage(account, message))
|
2010-05-22 18:00:06 -04:00
|
|
|
{
|
2010-08-08 15:43:01 -04:00
|
|
|
newMessages.incrementAndGet();
|
2010-08-08 14:50:31 -04:00
|
|
|
notifyAccount(mApplication, account, message, unreadBeforeStart, newMessages);
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
2009-10-21 20:41:06 -04:00
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "SYNC: fetch small messages", me);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void messageStarted(String uid, int number, int ofTotal)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public void messagesFinished(int total) {}
|
|
|
|
});
|
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "SYNC: Done fetching small messages for folder " + folder);
|
2010-07-10 12:42:39 -04:00
|
|
|
}
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2010-07-10 12:42:12 -04:00
|
|
|
|
|
|
|
|
|
|
|
private void downloadLargeMessages(final Account account, final Folder remoteFolder,
|
|
|
|
final LocalFolder localFolder,
|
|
|
|
ArrayList<Message> largeMessages,
|
|
|
|
final AtomicInteger progress,
|
2010-08-08 14:50:31 -04:00
|
|
|
final int unreadBeforeStart,
|
2010-07-10 12:42:12 -04:00
|
|
|
final AtomicInteger newMessages,
|
|
|
|
final int todo,
|
|
|
|
FetchProfile fp) throws MessagingException
|
|
|
|
{
|
|
|
|
final String folder = remoteFolder.getName();
|
|
|
|
|
|
|
|
final Date earliestDate = account.getEarliestPollDate();
|
2010-07-14 23:42:13 -04:00
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "SYNC: Fetching large messages for folder " + folder);
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
remoteFolder.fetch(largeMessages.toArray(new Message[largeMessages.size()]), fp, null);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Message message : largeMessages)
|
|
|
|
{
|
2010-07-13 17:17:04 -04:00
|
|
|
|
|
|
|
if (!shouldImportMessage(account, folder, message, progress, earliestDate))
|
2010-05-30 17:20:47 -04:00
|
|
|
{
|
|
|
|
progress.incrementAndGet();
|
|
|
|
continue;
|
|
|
|
}
|
2010-07-13 17:17:04 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (message.getBody() == null)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
/*
|
|
|
|
* The provider was unable to get the structure of the message, so
|
|
|
|
* we'll download a reasonable portion of the messge and mark it as
|
|
|
|
* incomplete so the entire thing can be downloaded later if the user
|
|
|
|
* wishes to download it.
|
|
|
|
*/
|
|
|
|
fp.clear();
|
|
|
|
fp.add(FetchProfile.Item.BODY_SANE);
|
|
|
|
/*
|
|
|
|
* TODO a good optimization here would be to make sure that all Stores set
|
|
|
|
* the proper size after this fetch and compare the before and after size. If
|
|
|
|
* they equal we can mark this SYNCHRONIZED instead of PARTIALLY_SYNCHRONIZED
|
|
|
|
*/
|
|
|
|
|
|
|
|
remoteFolder.fetch(new Message[] { message }, fp, null);
|
2010-07-06 06:29:26 -04:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
// Store the updated message locally
|
|
|
|
localFolder.appendMessages(new Message[] { message });
|
|
|
|
|
|
|
|
Message localMessage = localFolder.getMessage(message.getUid());
|
|
|
|
|
2010-02-07 01:05:11 -05:00
|
|
|
|
|
|
|
// Certain (POP3) servers give you the whole message even when you ask for only the first x Kb
|
|
|
|
if (!message.isSet(Flag.X_DOWNLOADED_FULL))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-07 01:05:11 -05:00
|
|
|
/*
|
|
|
|
* Mark the message as fully downloaded if the message size is smaller than
|
2010-07-11 07:59:14 -04:00
|
|
|
* the account's autodownload size limit, otherwise mark as only a partial
|
2010-02-07 01:05:11 -05:00
|
|
|
* download. This will prevent the system from downloading the same message
|
|
|
|
* twice.
|
|
|
|
*/
|
2010-07-11 07:59:14 -04:00
|
|
|
if (message.getSize() < account.getMaximumAutoDownloadMessageSize())
|
2010-02-07 01:05:11 -05:00
|
|
|
{
|
|
|
|
localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Set a flag indicating that the message has been partially downloaded and
|
|
|
|
// is ready for view.
|
|
|
|
localMessage.setFlag(Flag.X_DOWNLOADED_PARTIAL, true);
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
/*
|
|
|
|
* We have a structure to deal with, from which
|
|
|
|
* we can pull down the parts we want to actually store.
|
|
|
|
* Build a list of parts we are interested in. Text parts will be downloaded
|
|
|
|
* right now, attachments will be left for later.
|
|
|
|
*/
|
|
|
|
|
|
|
|
ArrayList<Part> viewables = new ArrayList<Part>();
|
|
|
|
ArrayList<Part> attachments = new ArrayList<Part>();
|
|
|
|
MimeUtility.collectParts(message, viewables, attachments);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Now download the parts we're interested in storing.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Part part : viewables)
|
|
|
|
{
|
2010-05-19 09:31:48 -04:00
|
|
|
remoteFolder.fetchPart(message, part, null);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
// Store the updated message locally
|
|
|
|
localFolder.appendMessages(new Message[] { message });
|
|
|
|
|
|
|
|
Message localMessage = localFolder.getMessage(message.getUid());
|
|
|
|
|
|
|
|
// Set a flag indicating this message has been fully downloaded and can be
|
|
|
|
// viewed.
|
|
|
|
localMessage.setFlag(Flag.X_DOWNLOADED_PARTIAL, true);
|
|
|
|
}
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "About to notify listeners that we got a new large message "
|
2009-11-24 19:40:29 -05:00
|
|
|
+ account + ":" + folder + ":" + message.getUid());
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
// Update the listener with what we've found
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
progress.incrementAndGet();
|
2010-05-22 18:00:06 -04:00
|
|
|
Message localMessage = localFolder.getMessage(message.getUid());
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage);
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
|
2009-11-24 19:40:29 -05:00
|
|
|
if (!localMessage.isSet(Flag.SEEN))
|
|
|
|
{
|
2009-11-08 22:52:59 -05:00
|
|
|
l.synchronizeMailboxNewMessage(account, folder, localMessage);
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-07-14 23:42:09 -04:00
|
|
|
|
|
|
|
// Send a notification of this message
|
2010-08-08 14:50:31 -04:00
|
|
|
if (shouldNotifyForMessage(account, message))
|
2010-05-22 18:00:06 -04:00
|
|
|
{
|
2010-08-08 15:43:01 -04:00
|
|
|
newMessages.incrementAndGet();
|
2010-08-08 14:50:31 -04:00
|
|
|
notifyAccount(mApplication, account, message, unreadBeforeStart, newMessages);
|
2010-05-22 18:00:06 -04:00
|
|
|
}
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
}//for large messsages
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "SYNC: Done fetching large messages for folder " + folder);
|
2009-10-21 20:41:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
|
2010-07-10 12:42:54 -04:00
|
|
|
private void refreshLocalMessageFlags(final Account account, final Folder remoteFolder,
|
|
|
|
final LocalFolder localFolder,
|
|
|
|
ArrayList<Message> syncFlagMessages,
|
|
|
|
final AtomicInteger progress,
|
|
|
|
final int todo
|
|
|
|
) throws MessagingException
|
|
|
|
{
|
|
|
|
|
|
|
|
final String folder = remoteFolder.getName();
|
|
|
|
if (remoteFolder.supportsFetchingFlags())
|
|
|
|
{
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "SYNC: About to sync flags for "
|
|
|
|
+ syncFlagMessages.size() + " remote messages for folder " + folder);
|
|
|
|
|
|
|
|
FetchProfile fp = new FetchProfile();
|
|
|
|
fp.add(FetchProfile.Item.FLAGS);
|
|
|
|
|
|
|
|
List<Message> undeletedMessages = new LinkedList<Message>();
|
|
|
|
for (Message message : syncFlagMessages)
|
|
|
|
{
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!message.isSet(Flag.DELETED))
|
2010-07-10 12:42:54 -04:00
|
|
|
{
|
|
|
|
undeletedMessages.add(message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-02 07:55:31 -04:00
|
|
|
remoteFolder.fetch(undeletedMessages.toArray(EMPTY_MESSAGE_ARRAY), fp, null);
|
2010-07-10 12:42:54 -04:00
|
|
|
for (Message remoteMessage : syncFlagMessages)
|
|
|
|
{
|
|
|
|
Message localMessage = localFolder.getMessage(remoteMessage.getUid());
|
|
|
|
boolean messageChanged = syncFlags(localMessage, remoteMessage);
|
|
|
|
if (messageChanged)
|
|
|
|
{
|
|
|
|
if (localMessage.isSet(Flag.DELETED) || isMessageSuppressed(account, folder, localMessage))
|
|
|
|
{
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxRemovedMessage(account, folder, localMessage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxAddOrUpdateMessage(account, folder, localMessage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
progress.incrementAndGet();
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxProgress(account, folder, progress.get(), todo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
private boolean syncFlags(Message localMessage, Message remoteMessage) throws MessagingException
|
|
|
|
{
|
|
|
|
boolean messageChanged = false;
|
2009-11-24 19:40:29 -05:00
|
|
|
if (localMessage == null || localMessage.isSet(Flag.DELETED))
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (remoteMessage.isSet(Flag.DELETED))
|
|
|
|
{
|
2010-07-03 09:10:38 -04:00
|
|
|
if (localMessage.getFolder().getAccount().syncRemoteDeletions())
|
|
|
|
{
|
|
|
|
localMessage.setFlag(Flag.DELETED, true);
|
|
|
|
messageChanged = true;
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-07-03 09:10:38 -04:00
|
|
|
else
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-07-03 09:10:38 -04:00
|
|
|
for (Flag flag : new Flag[] { Flag.SEEN, Flag.FLAGGED, Flag.ANSWERED })
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-07-03 09:10:38 -04:00
|
|
|
if (remoteMessage.isSet(flag) != localMessage.isSet(flag))
|
|
|
|
{
|
|
|
|
localMessage.setFlag(flag, remoteMessage.isSet(flag));
|
|
|
|
messageChanged = true;
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return messageChanged;
|
|
|
|
}
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
private String getRootCauseMessage(Throwable t)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
Throwable rootCause = t;
|
|
|
|
Throwable nextCause = rootCause;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
nextCause = rootCause.getCause();
|
|
|
|
if (nextCause != null)
|
|
|
|
{
|
|
|
|
rootCause = nextCause;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (nextCause != null);
|
|
|
|
return rootCause.getMessage();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void queuePendingCommand(Account account, PendingCommand command)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
2008-11-01 17:32:06 -04:00
|
|
|
localStore.addPendingCommand(command);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new RuntimeException("Unable to enqueue pending command", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
private void processPendingCommands(final Account account)
|
|
|
|
{
|
2009-12-24 13:08:23 -05:00
|
|
|
putBackground("processPendingCommands", null, new Runnable()
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
processPendingCommandsSynchronous(account);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "processPendingCommands", me);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* Ignore any exceptions from the commands. Commands will be processed
|
|
|
|
* on the next round.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2009-12-20 00:41:43 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
private void processPendingCommandsSynchronous(Account account) throws MessagingException
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
2008-11-01 17:32:06 -04:00
|
|
|
ArrayList<PendingCommand> commands = localStore.getPendingCommands();
|
2009-12-20 00:41:43 -05:00
|
|
|
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
int progress = 0;
|
|
|
|
int todo = commands.size();
|
|
|
|
if (todo == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2009-12-20 00:41:43 -05:00
|
|
|
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.pendingCommandsProcessing(account);
|
|
|
|
l.synchronizeMailboxProgress(account, null, progress, todo);
|
|
|
|
}
|
2009-12-20 00:41:43 -05:00
|
|
|
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
PendingCommand processingCommand = null;
|
|
|
|
try
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
for (PendingCommand command : commands)
|
|
|
|
{
|
|
|
|
processingCommand = command;
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "Processing pending command '" + command + "'");
|
2010-01-02 20:50:41 -05:00
|
|
|
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
String[] components = command.command.split("\\.");
|
|
|
|
String commandTitle = components[components.length - 1];
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.pendingCommandStarted(account, commandTitle);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
/*
|
|
|
|
* We specifically do not catch any exceptions here. If a command fails it is
|
|
|
|
* most likely due to a server or IO error and it must be retried before any
|
|
|
|
* other command processes. This maintains the order of the commands.
|
|
|
|
*/
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (PENDING_COMMAND_APPEND.equals(command.command))
|
|
|
|
{
|
|
|
|
processPendingAppend(command, account);
|
|
|
|
}
|
2009-12-05 09:17:32 -05:00
|
|
|
else if (PENDING_COMMAND_SET_FLAG_BULK.equals(command.command))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
processPendingSetFlag(command, account);
|
|
|
|
}
|
2009-12-05 09:17:32 -05:00
|
|
|
else if (PENDING_COMMAND_SET_FLAG.equals(command.command))
|
|
|
|
{
|
|
|
|
processPendingSetFlagOld(command, account);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else if (PENDING_COMMAND_MARK_ALL_AS_READ.equals(command.command))
|
|
|
|
{
|
|
|
|
processPendingMarkAllAsRead(command, account);
|
|
|
|
}
|
2009-12-05 09:17:32 -05:00
|
|
|
else if (PENDING_COMMAND_MOVE_OR_COPY_BULK.equals(command.command))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
processPendingMoveOrCopy(command, account);
|
|
|
|
}
|
2009-12-05 09:17:32 -05:00
|
|
|
else if (PENDING_COMMAND_MOVE_OR_COPY.equals(command.command))
|
|
|
|
{
|
|
|
|
processPendingMoveOrCopyOld(command, account);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else if (PENDING_COMMAND_EMPTY_TRASH.equals(command.command))
|
|
|
|
{
|
|
|
|
processPendingEmptyTrash(command, account);
|
|
|
|
}
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
else if (PENDING_COMMAND_EXPUNGE.equals(command.command))
|
|
|
|
{
|
|
|
|
processPendingExpunge(command, account);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
localStore.removePendingCommand(command);
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "Done processing pending command '" + command + "'");
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
|
|
|
if (me.isPermanentFailure())
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Failure of command '" + command + "' was permanent, removing command from queue");
|
2009-11-24 19:40:29 -05:00
|
|
|
localStore.removePendingCommand(processingCommand);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw me;
|
|
|
|
}
|
|
|
|
}
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
progress++;
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxProgress(account, null, progress, todo);
|
|
|
|
l.pendingCommandCompleted(account, commandTitle);
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Could not process command '" + processingCommand + "'", me);
|
2009-11-24 19:40:29 -05:00
|
|
|
throw me;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.pendingCommandsFinished(account);
|
|
|
|
}
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Process a pending append message command. This command uploads a local message to the
|
|
|
|
* server, first checking to be sure that the server message is not newer than
|
|
|
|
* the local message. Once the local message is successfully processed it is deleted so
|
|
|
|
* that the server message will be synchronized down without an additional copy being
|
|
|
|
* created.
|
|
|
|
* TODO update the local message UID instead of deleteing it
|
|
|
|
*
|
|
|
|
* @param command arguments = (String folder, String uid)
|
|
|
|
* @param account
|
|
|
|
* @throws MessagingException
|
|
|
|
*/
|
|
|
|
private void processPendingAppend(PendingCommand command, Account account)
|
2009-11-24 19:40:29 -05:00
|
|
|
throws MessagingException
|
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
Folder remoteFolder = null;
|
|
|
|
LocalFolder localFolder = null;
|
|
|
|
try
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
|
2010-01-16 11:22:20 -05:00
|
|
|
String folder = command.arguments[0];
|
|
|
|
String uid = command.arguments[1];
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2010-01-16 11:22:20 -05:00
|
|
|
if (account.getErrorFolderName().equals(folder))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
return;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
|
|
|
localFolder = localStore.getFolder(folder);
|
2010-01-16 11:22:20 -05:00
|
|
|
LocalMessage localMessage = (LocalMessage) localFolder.getMessage(uid);
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2010-01-16 11:22:20 -05:00
|
|
|
if (localMessage == null)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Store remoteStore = account.getRemoteStore();
|
2010-01-16 11:22:20 -05:00
|
|
|
remoteFolder = remoteStore.getFolder(folder);
|
|
|
|
if (!remoteFolder.exists())
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
if (!remoteFolder.create(FolderType.HOLDS_MESSAGES))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
remoteFolder.open(OpenMode.READ_WRITE);
|
|
|
|
if (remoteFolder.getMode() != OpenMode.READ_WRITE)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
return;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2010-01-16 11:22:20 -05:00
|
|
|
Message remoteMessage = null;
|
|
|
|
if (!localMessage.getUid().startsWith(K9.LOCAL_UID_PREFIX))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
remoteMessage = remoteFolder.getMessage(localMessage.getUid());
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2010-01-16 11:22:20 -05:00
|
|
|
if (remoteMessage == null)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
if (localMessage.isSet(Flag.X_REMOTE_COPY_STARTED))
|
|
|
|
{
|
|
|
|
Log.w(K9.LOG_TAG, "Local message with uid " + localMessage.getUid() +
|
|
|
|
" has flag " + Flag.X_REMOTE_COPY_STARTED + " already set, checking for remote message with " +
|
|
|
|
" same message id");
|
|
|
|
String rUid = remoteFolder.getUidFromMessageId(localMessage);
|
|
|
|
if (rUid != null)
|
|
|
|
{
|
|
|
|
Log.w(K9.LOG_TAG, "Local message has flag " + Flag.X_REMOTE_COPY_STARTED + " already set, and there is a remote message with " +
|
|
|
|
" uid " + rUid + ", assuming message was already copied and aborting this copy");
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2010-01-16 11:22:20 -05:00
|
|
|
String oldUid = localMessage.getUid();
|
|
|
|
localMessage.setUid(rUid);
|
|
|
|
localFolder.changeUid(localMessage);
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Log.w(K9.LOG_TAG, "No remote message with message-id found, proceeding with append");
|
|
|
|
}
|
|
|
|
}
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
2010-01-16 11:22:20 -05:00
|
|
|
* If the message does not exist remotely we just upload it and then
|
|
|
|
* update our local copy with the new uid.
|
2008-11-01 17:32:06 -04:00
|
|
|
*/
|
2010-01-16 11:22:20 -05:00
|
|
|
FetchProfile fp = new FetchProfile();
|
2008-11-01 17:32:06 -04:00
|
|
|
fp.add(FetchProfile.Item.BODY);
|
2010-01-16 11:22:20 -05:00
|
|
|
localFolder.fetch(new Message[]
|
|
|
|
{
|
|
|
|
localMessage
|
|
|
|
}
|
|
|
|
, fp, null);
|
2008-11-01 17:32:06 -04:00
|
|
|
String oldUid = localMessage.getUid();
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
localMessage.setFlag(Flag.X_REMOTE_COPY_STARTED, true);
|
2008-11-01 17:32:06 -04:00
|
|
|
remoteFolder.appendMessages(new Message[] { localMessage });
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.changeUid(localMessage);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* If the remote message exists we need to determine which copy to keep.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* See if the remote message is newer than ours.
|
|
|
|
*/
|
|
|
|
FetchProfile fp = new FetchProfile();
|
|
|
|
fp.add(FetchProfile.Item.ENVELOPE);
|
|
|
|
remoteFolder.fetch(new Message[] { remoteMessage }, fp, null);
|
|
|
|
Date localDate = localMessage.getInternalDate();
|
|
|
|
Date remoteDate = remoteMessage.getInternalDate();
|
2010-04-14 09:02:04 -04:00
|
|
|
if (remoteDate != null && remoteDate.compareTo(localDate) > 0)
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
/*
|
|
|
|
* If the remote message is newer than ours we'll just
|
|
|
|
* delete ours and move on. A sync will get the server message
|
|
|
|
* if we need to be able to see it.
|
|
|
|
*/
|
2010-04-14 09:02:04 -04:00
|
|
|
localMessage.setFlag(Flag.X_DESTROYED, true);
|
2010-01-16 11:22:20 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Otherwise we'll upload our message and then delete the remote message.
|
|
|
|
*/
|
|
|
|
fp.clear();
|
|
|
|
fp = new FetchProfile();
|
|
|
|
fp.add(FetchProfile.Item.BODY);
|
|
|
|
localFolder.fetch(new Message[] { localMessage }, fp, null);
|
|
|
|
String oldUid = localMessage.getUid();
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2010-01-16 11:22:20 -05:00
|
|
|
localMessage.setFlag(Flag.X_REMOTE_COPY_STARTED, true);
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2010-01-16 11:22:20 -05:00
|
|
|
remoteFolder.appendMessages(new Message[] { localMessage });
|
|
|
|
localFolder.changeUid(localMessage);
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
if (remoteDate != null)
|
|
|
|
{
|
|
|
|
remoteMessage.setFlag(Flag.DELETED, true);
|
|
|
|
if (Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy()))
|
|
|
|
{
|
|
|
|
remoteFolder.expunge();
|
|
|
|
}
|
|
|
|
}
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (remoteFolder != null)
|
|
|
|
{
|
|
|
|
remoteFolder.close();
|
|
|
|
}
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
|
|
|
localFolder.close();
|
|
|
|
}
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-29 13:07:34 -05:00
|
|
|
private void queueMoveOrCopy(Account account, String srcFolder, String destFolder, boolean isCopy, String uids[])
|
|
|
|
{
|
2009-12-01 23:09:51 -05:00
|
|
|
if (account.getErrorFolderName().equals(srcFolder))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2009-11-29 13:07:34 -05:00
|
|
|
PendingCommand command = new PendingCommand();
|
2009-12-05 09:17:32 -05:00
|
|
|
command.command = PENDING_COMMAND_MOVE_OR_COPY_BULK;
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-29 13:07:34 -05:00
|
|
|
int length = 3 + uids.length;
|
|
|
|
command.arguments = new String[length];
|
|
|
|
command.arguments[0] = srcFolder;
|
|
|
|
command.arguments[1] = destFolder;
|
|
|
|
command.arguments[2] = Boolean.toString(isCopy);
|
|
|
|
for (int i = 0; i < uids.length; i++)
|
|
|
|
{
|
|
|
|
command.arguments[3 + i] = uids[i];
|
|
|
|
}
|
|
|
|
queuePendingCommand(account, command);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
|
|
|
* Process a pending trash message command.
|
|
|
|
*
|
|
|
|
* @param command arguments = (String folder, String uid)
|
|
|
|
* @param account
|
|
|
|
* @throws MessagingException
|
|
|
|
*/
|
2009-03-05 02:32:45 -05:00
|
|
|
private void processPendingMoveOrCopy(PendingCommand command, Account account)
|
2009-11-24 19:40:29 -05:00
|
|
|
throws MessagingException
|
|
|
|
{
|
2009-11-29 13:07:34 -05:00
|
|
|
Folder remoteSrcFolder = null;
|
|
|
|
Folder remoteDestFolder = null;
|
|
|
|
try
|
2009-03-05 08:43:05 -05:00
|
|
|
{
|
2009-11-29 13:07:34 -05:00
|
|
|
String srcFolder = command.arguments[0];
|
2009-12-01 23:09:51 -05:00
|
|
|
if (account.getErrorFolderName().equals(srcFolder))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2009-11-29 13:07:34 -05:00
|
|
|
String destFolder = command.arguments[1];
|
|
|
|
String isCopyS = command.arguments[2];
|
2010-03-03 23:00:30 -05:00
|
|
|
Store remoteStore = account.getRemoteStore();
|
2009-11-29 13:07:34 -05:00
|
|
|
remoteSrcFolder = remoteStore.getFolder(srcFolder);
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-29 13:07:34 -05:00
|
|
|
List<Message> messages = new ArrayList<Message>();
|
|
|
|
for (int i = 3; i < command.arguments.length; i++)
|
|
|
|
{
|
|
|
|
String uid = command.arguments[i];
|
2009-12-14 21:50:53 -05:00
|
|
|
if (!uid.startsWith(K9.LOCAL_UID_PREFIX))
|
2009-11-29 13:07:34 -05:00
|
|
|
{
|
|
|
|
messages.add(remoteSrcFolder.getMessage(uid));
|
|
|
|
}
|
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-29 13:07:34 -05:00
|
|
|
boolean isCopy = false;
|
|
|
|
if (isCopyS != null)
|
|
|
|
{
|
|
|
|
isCopy = Boolean.parseBoolean(isCopyS);
|
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-29 13:07:34 -05:00
|
|
|
if (!remoteSrcFolder.exists())
|
|
|
|
{
|
|
|
|
throw new MessagingException("processingPendingMoveOrCopy: remoteFolder " + srcFolder + " does not exist", true);
|
|
|
|
}
|
|
|
|
remoteSrcFolder.open(OpenMode.READ_WRITE);
|
|
|
|
if (remoteSrcFolder.getMode() != OpenMode.READ_WRITE)
|
|
|
|
{
|
|
|
|
throw new MessagingException("processingPendingMoveOrCopy: could not open remoteSrcFolder " + srcFolder + " read/write", true);
|
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "processingPendingMoveOrCopy: source folder = " + srcFolder
|
2009-11-29 13:07:34 -05:00
|
|
|
+ ", " + messages.size() + " messages, destination folder = " + destFolder + ", isCopy = " + isCopy);
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!isCopy && destFolder.equals(account.getTrashFolderName()))
|
2009-11-29 13:07:34 -05:00
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "processingPendingMoveOrCopy doing special case for deleting message");
|
2010-01-02 20:50:41 -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.
2009-12-20 18:13:49 -05:00
|
|
|
String destFolderName = destFolder;
|
|
|
|
if (K9.FOLDER_NONE.equals(destFolderName))
|
|
|
|
{
|
|
|
|
destFolderName = null;
|
|
|
|
}
|
2010-08-02 07:55:31 -04:00
|
|
|
remoteSrcFolder.delete(messages.toArray(EMPTY_MESSAGE_ARRAY), destFolderName);
|
2009-11-29 13:07:34 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
remoteDestFolder = remoteStore.getFolder(destFolder);
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-29 13:07:34 -05:00
|
|
|
if (isCopy)
|
|
|
|
{
|
2010-08-02 07:55:31 -04:00
|
|
|
remoteSrcFolder.copyMessages(messages.toArray(EMPTY_MESSAGE_ARRAY), remoteDestFolder);
|
2009-11-29 13:07:34 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-08-02 07:55:31 -04:00
|
|
|
remoteSrcFolder.moveMessages(messages.toArray(EMPTY_MESSAGE_ARRAY), remoteDestFolder);
|
2009-11-29 13:07:34 -05:00
|
|
|
}
|
|
|
|
}
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!isCopy && Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy()))
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
{
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "processingPendingMoveOrCopy expunging folder " + account.getDescription() + ":" + srcFolder);
|
|
|
|
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
remoteSrcFolder.expunge();
|
|
|
|
}
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2009-11-29 13:07:34 -05:00
|
|
|
finally
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-11-29 13:07:34 -05:00
|
|
|
if (remoteSrcFolder != null)
|
|
|
|
{
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
remoteSrcFolder.close();
|
2009-11-29 13:07:34 -05:00
|
|
|
}
|
|
|
|
if (remoteDestFolder != null)
|
|
|
|
{
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
remoteDestFolder.close();
|
2009-11-29 13:07:34 -05:00
|
|
|
}
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
private void queueSetFlag(final Account account, final String folderName, final String newState, final String flag, final String[] uids)
|
2009-11-29 11:55:35 -05:00
|
|
|
{
|
2009-12-24 13:08:23 -05:00
|
|
|
putBackground("queueSetFlag " + account.getDescription() + ":" + folderName, null, new Runnable()
|
2009-11-29 11:55:35 -05:00
|
|
|
{
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
PendingCommand command = new PendingCommand();
|
|
|
|
command.command = PENDING_COMMAND_SET_FLAG_BULK;
|
|
|
|
int length = 3 + uids.length;
|
|
|
|
command.arguments = new String[length];
|
|
|
|
command.arguments[0] = folderName;
|
|
|
|
command.arguments[1] = newState;
|
|
|
|
command.arguments[2] = flag;
|
|
|
|
for (int i = 0; i < uids.length; i++)
|
|
|
|
{
|
|
|
|
command.arguments[3 + i] = uids[i];
|
|
|
|
}
|
|
|
|
queuePendingCommand(account, command);
|
|
|
|
processPendingCommands(account);
|
|
|
|
}
|
|
|
|
});
|
2009-11-29 11:55:35 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
|
|
|
* Processes a pending mark read or unread command.
|
|
|
|
*
|
|
|
|
* @param command arguments = (String folder, String uid, boolean read)
|
|
|
|
* @param account
|
|
|
|
*/
|
2009-01-13 00:52:37 -05:00
|
|
|
private void processPendingSetFlag(PendingCommand command, Account account)
|
2009-11-24 19:40:29 -05:00
|
|
|
throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
String folder = command.arguments[0];
|
2009-11-24 19:40:29 -05:00
|
|
|
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
if (account.getErrorFolderName().equals(folder))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-11-29 11:55:35 -05:00
|
|
|
boolean newState = Boolean.parseBoolean(command.arguments[1]);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-11-29 11:55:35 -05:00
|
|
|
Flag flag = Flag.valueOf(command.arguments[2]);
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Store remoteStore = account.getRemoteStore();
|
2008-11-01 17:32:06 -04:00
|
|
|
Folder remoteFolder = remoteStore.getFolder(folder);
|
2010-08-28 17:15:23 -04:00
|
|
|
if (!remoteFolder.exists() ||
|
2010-08-29 12:57:13 -04:00
|
|
|
/*
|
|
|
|
* Don't proceed if the remote folder doesn't support flags and
|
|
|
|
* the flag to be changed isn't the deleted flag. This avoids
|
|
|
|
* unnecessary connections to POP3 servers.
|
|
|
|
*/
|
|
|
|
// TODO: This should actually call a supportsSettingFlag(flag) method.
|
|
|
|
(!remoteFolder.supportsFetchingFlags() && !Flag.DELETED.equals(flag)))
|
2010-08-28 17:15:23 -04:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-11-29 11:55:35 -05:00
|
|
|
try
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-11-29 11:55:35 -05:00
|
|
|
remoteFolder.open(OpenMode.READ_WRITE);
|
|
|
|
if (remoteFolder.getMode() != OpenMode.READ_WRITE)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
List<Message> messages = new ArrayList<Message>();
|
|
|
|
for (int i = 3; i < command.arguments.length; i++)
|
|
|
|
{
|
|
|
|
String uid = command.arguments[i];
|
2009-12-14 21:50:53 -05:00
|
|
|
if (!uid.startsWith(K9.LOCAL_UID_PREFIX))
|
2009-11-29 11:55:35 -05:00
|
|
|
{
|
|
|
|
messages.add(remoteFolder.getMessage(uid));
|
|
|
|
}
|
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-29 11:55:35 -05:00
|
|
|
if (messages.size() == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2010-08-02 07:55:31 -04:00
|
|
|
remoteFolder.setFlags(messages.toArray(EMPTY_MESSAGE_ARRAY), new Flag[] { flag }, newState);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-29 11:55:35 -05:00
|
|
|
finally
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-11-29 11:55:35 -05:00
|
|
|
if (remoteFolder != null)
|
|
|
|
{
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
remoteFolder.close();
|
2009-11-29 11:55:35 -05:00
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
}
|
2009-12-05 09:17:32 -05:00
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-12-05 09:17:32 -05:00
|
|
|
// TODO: This method is obsolete and is only for transition from K-9 2.0 to K-9 2.1
|
|
|
|
// Eventually, it should be removed
|
|
|
|
private void processPendingSetFlagOld(PendingCommand command, Account account)
|
|
|
|
throws MessagingException
|
|
|
|
{
|
|
|
|
String folder = command.arguments[0];
|
|
|
|
String uid = command.arguments[1];
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2009-12-05 09:17:32 -05:00
|
|
|
if (account.getErrorFolderName().equals(folder))
|
|
|
|
{
|
|
|
|
return;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "processPendingSetFlagOld: folder = " + folder + ", uid = " + uid);
|
2009-12-05 09:17:32 -05:00
|
|
|
|
|
|
|
boolean newState = Boolean.parseBoolean(command.arguments[2]);
|
|
|
|
|
|
|
|
Flag flag = Flag.valueOf(command.arguments[3]);
|
2010-01-16 11:22:20 -05:00
|
|
|
Folder remoteFolder = null;
|
|
|
|
try
|
2009-12-05 09:17:32 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store remoteStore = account.getRemoteStore();
|
2010-01-16 11:22:20 -05:00
|
|
|
remoteFolder = remoteStore.getFolder(folder);
|
|
|
|
if (!remoteFolder.exists())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
remoteFolder.open(OpenMode.READ_WRITE);
|
|
|
|
if (remoteFolder.getMode() != OpenMode.READ_WRITE)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Message remoteMessage = null;
|
|
|
|
if (!uid.startsWith(K9.LOCAL_UID_PREFIX))
|
|
|
|
{
|
|
|
|
remoteMessage = remoteFolder.getMessage(uid);
|
|
|
|
}
|
|
|
|
if (remoteMessage == null)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
remoteMessage.setFlag(flag, newState);
|
2009-12-05 09:17:32 -05:00
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
finally
|
2009-12-05 09:17:32 -05:00
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
if (remoteFolder != null)
|
|
|
|
{
|
|
|
|
remoteFolder.close();
|
|
|
|
}
|
2009-12-05 09:17:32 -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.
2009-12-20 18:13:49 -05:00
|
|
|
private void queueExpunge(final Account account, final String folderName)
|
|
|
|
{
|
2009-12-24 13:08:23 -05:00
|
|
|
putBackground("queueExpunge " + account.getDescription() + ":" + folderName, null, new Runnable()
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
PendingCommand command = new PendingCommand();
|
|
|
|
command.command = PENDING_COMMAND_EXPUNGE;
|
|
|
|
|
|
|
|
command.arguments = new String[1];
|
2009-12-27 12:22: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.
2009-12-20 18:13:49 -05:00
|
|
|
command.arguments[0] = folderName;
|
|
|
|
queuePendingCommand(account, command);
|
|
|
|
processPendingCommands(account);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
private void processPendingExpunge(PendingCommand command, Account account)
|
|
|
|
throws MessagingException
|
|
|
|
{
|
|
|
|
String folder = command.arguments[0];
|
2009-12-27 12:22: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.
2009-12-20 18:13:49 -05:00
|
|
|
if (account.getErrorFolderName().equals(folder))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (K9.DEBUG)
|
2009-12-27 12:22:51 -05:00
|
|
|
Log.d(K9.LOG_TAG, "processPendingExpunge: folder = " + folder);
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Store remoteStore = account.getRemoteStore();
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
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)
|
2009-12-27 12:22:51 -05:00
|
|
|
Log.d(K9.LOG_TAG, "processPendingExpunge: complete for folder = " + folder);
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (remoteFolder != null)
|
|
|
|
{
|
|
|
|
remoteFolder.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-05 09:17:32 -05:00
|
|
|
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-12-05 09:17:32 -05:00
|
|
|
// TODO: This method is obsolete and is only for transition from K-9 2.0 to K-9 2.1
|
|
|
|
// Eventually, it should be removed
|
|
|
|
private void processPendingMoveOrCopyOld(PendingCommand command, Account account)
|
|
|
|
throws MessagingException
|
|
|
|
{
|
|
|
|
String srcFolder = command.arguments[0];
|
|
|
|
String uid = command.arguments[1];
|
|
|
|
String destFolder = command.arguments[2];
|
|
|
|
String isCopyS = command.arguments[3];
|
|
|
|
|
|
|
|
boolean isCopy = false;
|
|
|
|
if (isCopyS != null)
|
|
|
|
{
|
|
|
|
isCopy = Boolean.parseBoolean(isCopyS);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (account.getErrorFolderName().equals(srcFolder))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Store remoteStore = account.getRemoteStore();
|
2009-12-05 09:17:32 -05:00
|
|
|
Folder remoteSrcFolder = remoteStore.getFolder(srcFolder);
|
|
|
|
Folder remoteDestFolder = remoteStore.getFolder(destFolder);
|
|
|
|
|
|
|
|
if (!remoteSrcFolder.exists())
|
|
|
|
{
|
|
|
|
throw new MessagingException("processPendingMoveOrCopyOld: remoteFolder " + srcFolder + " does not exist", true);
|
|
|
|
}
|
|
|
|
remoteSrcFolder.open(OpenMode.READ_WRITE);
|
|
|
|
if (remoteSrcFolder.getMode() != OpenMode.READ_WRITE)
|
|
|
|
{
|
|
|
|
throw new MessagingException("processPendingMoveOrCopyOld: could not open remoteSrcFolder " + srcFolder + " read/write", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
Message remoteMessage = null;
|
2009-12-14 21:50:53 -05:00
|
|
|
if (!uid.startsWith(K9.LOCAL_UID_PREFIX))
|
2009-12-05 09:17:32 -05:00
|
|
|
{
|
|
|
|
remoteMessage = remoteSrcFolder.getMessage(uid);
|
|
|
|
}
|
|
|
|
if (remoteMessage == null)
|
|
|
|
{
|
|
|
|
throw new MessagingException("processPendingMoveOrCopyOld: remoteMessage " + uid + " does not exist", true);
|
|
|
|
}
|
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "processPendingMoveOrCopyOld: source folder = " + srcFolder
|
2009-12-06 19:56:06 -05:00
|
|
|
+ ", uid = " + uid + ", destination folder = " + destFolder + ", isCopy = " + isCopy);
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!isCopy && destFolder.equals(account.getTrashFolderName()))
|
2009-12-05 09:17:32 -05:00
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "processPendingMoveOrCopyOld doing special case for deleting message");
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-12-05 09:17:32 -05:00
|
|
|
remoteMessage.delete(account.getTrashFolderName());
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
remoteSrcFolder.close();
|
2009-12-05 09:17:32 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
remoteDestFolder.open(OpenMode.READ_WRITE);
|
|
|
|
if (remoteDestFolder.getMode() != OpenMode.READ_WRITE)
|
|
|
|
{
|
|
|
|
throw new MessagingException("processPendingMoveOrCopyOld: could not open remoteDestFolder " + srcFolder + " read/write", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isCopy)
|
|
|
|
{
|
|
|
|
remoteSrcFolder.copyMessages(new Message[] { remoteMessage }, remoteDestFolder);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
remoteSrcFolder.moveMessages(new Message[] { remoteMessage }, remoteDestFolder);
|
|
|
|
}
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
remoteSrcFolder.close();
|
|
|
|
remoteDestFolder.close();
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
private void processPendingMarkAllAsRead(PendingCommand command, Account account) throws MessagingException
|
|
|
|
{
|
2009-06-23 10:57:16 -04:00
|
|
|
String folder = command.arguments[0];
|
2010-01-16 11:22:20 -05:00
|
|
|
Folder remoteFolder = null;
|
|
|
|
LocalFolder localFolder = null;
|
|
|
|
try
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2010-01-16 11:22:20 -05:00
|
|
|
localFolder = (LocalFolder) localStore.getFolder(folder);
|
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
|
|
|
Message[] messages = localFolder.getMessages(null, false);
|
|
|
|
for (Message message : messages)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!message.isSet(Flag.SEEN))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
message.setFlag(Flag.SEEN, true);
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.listLocalMessagesUpdateMessage(account, folder, message);
|
|
|
|
}
|
2009-06-23 10:57:16 -04:00
|
|
|
}
|
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
localFolder.setUnreadMessageCount(0);
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.folderStatusChanged(account, folder, 0);
|
|
|
|
}
|
2010-01-17 19:11:02 -05:00
|
|
|
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (account.getErrorFolderName().equals(folder))
|
|
|
|
{
|
2009-06-23 10:57:16 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Store remoteStore = account.getRemoteStore();
|
2010-01-16 11:22:20 -05:00
|
|
|
remoteFolder = remoteStore.getFolder(folder);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (!remoteFolder.exists())
|
|
|
|
{
|
2009-06-23 10:57:16 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
remoteFolder.open(OpenMode.READ_WRITE);
|
2009-11-24 19:40:29 -05:00
|
|
|
if (remoteFolder.getMode() != OpenMode.READ_WRITE)
|
|
|
|
{
|
2009-06-23 10:57:16 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
remoteFolder.setFlags(new Flag[] {Flag.SEEN}, true);
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
remoteFolder.close();
|
2009-06-23 10:57:16 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (UnsupportedOperationException uoe)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.w(K9.LOG_TAG, "Could not mark all server-side as read because store doesn't support operation", uoe);
|
2009-06-23 10:57:16 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
if (localFolder != null)
|
|
|
|
{
|
|
|
|
localFolder.close();
|
|
|
|
}
|
|
|
|
if (remoteFolder != null)
|
|
|
|
{
|
|
|
|
remoteFolder.close();
|
|
|
|
}
|
2009-06-23 10:57:16 -04:00
|
|
|
}
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static long uidfill = 0;
|
|
|
|
static AtomicBoolean loopCatch = new AtomicBoolean();
|
2010-04-14 23:17:25 -04:00
|
|
|
public void addErrorMessage(Account account, String subject, Throwable t)
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
{
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!loopCatch.compareAndSet(false, true))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (t == null)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
|
|
PrintStream ps = new PrintStream(baos);
|
|
|
|
t.printStackTrace(ps);
|
|
|
|
ps.close();
|
|
|
|
|
2010-07-10 12:41:48 -04:00
|
|
|
if (subject == null)
|
|
|
|
{
|
2010-07-10 12:41:07 -04:00
|
|
|
subject = getRootCauseMessage(t);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-07-10 12:41:07 -04:00
|
|
|
addErrorMessage(account, subject, baos.toString());
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (Throwable it)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Could not save error message to " + account.getErrorFolderName(), it);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
loopCatch.set(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-09 13:48:05 -04:00
|
|
|
public void addErrorMessage(Account account, String subject, String body)
|
|
|
|
{
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!K9.ENABLE_ERROR_FOLDER)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!loopCatch.compareAndSet(false, true))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (body == null || body.length() < 1)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2009-11-24 19:40:29 -05:00
|
|
|
LocalFolder localFolder = (LocalFolder)localStore.getFolder(account.getErrorFolderName());
|
|
|
|
Message[] messages = new Message[1];
|
|
|
|
MimeMessage message = new MimeMessage();
|
|
|
|
|
|
|
|
|
|
|
|
message.setBody(new TextBody(body));
|
|
|
|
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
|
|
|
message.setSubject(subject);
|
|
|
|
|
|
|
|
long nowTime = System.currentTimeMillis();
|
|
|
|
Date nowDate = new Date(nowTime);
|
|
|
|
message.setInternalDate(nowDate);
|
|
|
|
message.addSentDate(nowDate);
|
|
|
|
message.setFrom(new Address(account.getEmail(), "K9mail internal"));
|
|
|
|
messages[0] = message;
|
|
|
|
|
|
|
|
localFolder.appendMessages(messages);
|
|
|
|
|
|
|
|
localFolder.deleteMessagesOlderThan(nowTime - (15 * 60 * 1000));
|
|
|
|
|
|
|
|
}
|
|
|
|
catch (Throwable it)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Could not save error message to " + account.getErrorFolderName(), it);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
loopCatch.set(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
public void markAllMessagesRead(final Account account, final String folder)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Marking all messages in " + account.getDescription() + ":" + folder + " as read");
|
2009-11-24 19:40:29 -05:00
|
|
|
List<String> args = new ArrayList<String>();
|
|
|
|
args.add(folder);
|
|
|
|
PendingCommand command = new PendingCommand();
|
|
|
|
command.command = PENDING_COMMAND_MARK_ALL_AS_READ;
|
2010-08-02 07:55:31 -04:00
|
|
|
command.arguments = args.toArray(EMPTY_STRING_ARRAY);
|
2009-11-24 19:40:29 -05:00
|
|
|
queuePendingCommand(account, command);
|
|
|
|
processPendingCommands(account);
|
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-29 11:55:35 -05:00
|
|
|
public void setFlag(
|
2009-12-06 19:56:06 -05:00
|
|
|
final Message[] messages,
|
|
|
|
final Flag flag,
|
|
|
|
final boolean newState)
|
2009-11-26 00:30:13 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
actOnMessages(messages, new MessageActor()
|
2009-11-26 00:30:13 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
@Override
|
|
|
|
public void act(final Account account, final Folder folder,
|
2010-04-29 00:59:14 -04:00
|
|
|
final List<Message> messages)
|
2010-03-03 23:00:30 -05:00
|
|
|
{
|
|
|
|
String[] uids = new String[messages.size()];
|
|
|
|
for (int i = 0; i < messages.size(); i++)
|
|
|
|
{
|
|
|
|
uids[i] = messages.get(i).getUid();
|
|
|
|
}
|
|
|
|
setFlag(account, folder.getName(), uids, flag, newState);
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
});
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-11-26 00:30:13 -05:00
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-29 11:55:35 -05:00
|
|
|
public void setFlag(
|
2009-01-13 00:52:37 -05:00
|
|
|
final Account account,
|
2009-11-29 11:55:35 -05:00
|
|
|
final String folderName,
|
|
|
|
final String[] uids,
|
2009-01-13 00:52:37 -05:00
|
|
|
final Flag flag,
|
2009-11-24 19:40:29 -05:00
|
|
|
final boolean newState)
|
|
|
|
{
|
|
|
|
// TODO: put this into the background, but right now that causes odd behavior
|
2009-11-29 11:55:35 -05:00
|
|
|
// because the FolderMessageList doesn't have its own cache of the flag states
|
|
|
|
Folder localFolder = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2009-11-29 11:55:35 -05:00
|
|
|
localFolder = localStore.getFolder(folderName);
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
2010-02-03 18:27:33 -05:00
|
|
|
ArrayList<Message> messages = new ArrayList<Message>();
|
2010-07-18 21:52:18 -04:00
|
|
|
for (String uid : uids)
|
2009-04-09 13:48:05 -04:00
|
|
|
{
|
2009-12-06 19:56:06 -05:00
|
|
|
// Allows for re-allowing sending of messages that could not be sent
|
2010-08-29 19:39:26 -04:00
|
|
|
if (flag == Flag.FLAGGED && !newState
|
2009-11-29 11:55:35 -05:00
|
|
|
&& uid != null
|
|
|
|
&& account.getOutboxFolderName().equals(folderName))
|
|
|
|
{
|
|
|
|
sendCount.remove(uid);
|
|
|
|
}
|
2010-02-03 18:27:33 -05:00
|
|
|
Message msg = localFolder.getMessage(uid);
|
|
|
|
if (msg != null)
|
|
|
|
{
|
2010-04-29 00:59:14 -04:00
|
|
|
messages.add(msg);
|
2010-02-03 18:27:33 -05:00
|
|
|
}
|
2009-04-09 13:48:05 -04:00
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2010-08-02 07:55:31 -04:00
|
|
|
localFolder.setFlags(messages.toArray(EMPTY_MESSAGE_ARRAY), new Flag[] {flag}, newState);
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-05-11 00:39:03 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
l.folderStatusChanged(account, folderName, localFolder.getUnreadMessageCount());
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2009-05-11 00:39:03 -04:00
|
|
|
|
|
|
|
if (account.getErrorFolderName().equals(folderName))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2009-05-11 00:39:03 -04:00
|
|
|
|
2009-11-29 11:55:35 -05:00
|
|
|
queueSetFlag(account, folderName, Boolean.toString(newState), flag.toString(), uids);
|
2008-11-01 17:32:06 -04:00
|
|
|
processPendingCommands(account);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new RuntimeException(me);
|
|
|
|
}
|
2009-11-29 11:55:35 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
localFolder.close();
|
2009-11-29 11:55:35 -05:00
|
|
|
}
|
|
|
|
}
|
2009-05-11 00:39:03 -04:00
|
|
|
}//setMesssageFlag
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void clearAllPending(final Account account)
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.w(K9.LOG_TAG, "Clearing pending commands!");
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
2009-11-24 19:40:29 -05:00
|
|
|
localStore.removePendingCommands();
|
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to clear pending command", me);
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-07-18 21:52:59 -04:00
|
|
|
public void loadMessageForViewRemote(final Account account, final String folder,
|
2010-07-18 21:57:49 -04:00
|
|
|
final String uid, final MessagingListener listener)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
put("loadMessageForViewRemote", listener, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
2009-05-11 00:39:03 -04:00
|
|
|
Folder remoteFolder = null;
|
|
|
|
LocalFolder localFolder = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
|
|
|
localFolder = localStore.getFolder(folder);
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
|
|
|
|
|
|
|
Message message = localFolder.getMessage(uid);
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (message.isSet(Flag.X_DOWNLOADED_FULL))
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* If the message has been synchronized since we were called we'll
|
|
|
|
* just hand it back cause it's ready to go.
|
|
|
|
*/
|
|
|
|
FetchProfile fp = new FetchProfile();
|
|
|
|
fp.add(FetchProfile.Item.ENVELOPE);
|
|
|
|
fp.add(FetchProfile.Item.BODY);
|
|
|
|
localFolder.fetch(new Message[] { message }, fp, null);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else
|
|
|
|
{
|
2009-05-11 00:39:03 -04:00
|
|
|
/*
|
|
|
|
* At this point the message is not available, so we need to download it
|
|
|
|
* fully if possible.
|
|
|
|
*/
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Store remoteStore = account.getRemoteStore();
|
2009-05-11 00:39:03 -04:00
|
|
|
remoteFolder = remoteStore.getFolder(folder);
|
|
|
|
remoteFolder.open(OpenMode.READ_WRITE);
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-05-11 00:39:03 -04:00
|
|
|
// Get the remote message and fully download it
|
|
|
|
Message remoteMessage = remoteFolder.getMessage(uid);
|
|
|
|
FetchProfile fp = new FetchProfile();
|
|
|
|
fp.add(FetchProfile.Item.BODY);
|
|
|
|
remoteFolder.fetch(new Message[] { remoteMessage }, fp, null);
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-05-11 00:39:03 -04:00
|
|
|
// Store the message locally and load the stored message into memory
|
|
|
|
localFolder.appendMessages(new Message[] { remoteMessage });
|
2010-07-18 21:52:59 -04:00
|
|
|
fp.add(FetchProfile.Item.ENVELOPE);
|
2009-05-11 00:39:03 -04:00
|
|
|
message = localFolder.getMessage(uid);
|
|
|
|
localFolder.fetch(new Message[] { message }, fp, null);
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-05-11 00:39:03 -04:00
|
|
|
// Mark that this message is now fully synched
|
|
|
|
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-07-18 21:52:59 -04:00
|
|
|
// now that we have the full message, refresh the headers
|
|
|
|
for (MessagingListener l : getListeners(listener))
|
|
|
|
{
|
|
|
|
l.loadMessageForViewHeadersAvailable(account, folder, uid, message);
|
|
|
|
}
|
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
|
|
|
}
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.loadMessageForViewFinished(account, folder, uid, message);
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-10-19 15:35:31 -04:00
|
|
|
l.loadMessageForViewFailed(account, folder, uid, e);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (remoteFolder!=null)
|
|
|
|
{
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
remoteFolder.close();
|
2009-05-11 00:39:03 -04:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (localFolder!=null)
|
|
|
|
{
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
localFolder.close();
|
2009-05-11 00:39:03 -04:00
|
|
|
}
|
|
|
|
}//finally
|
|
|
|
}//run
|
2008-11-01 17:32:06 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public void loadMessageForView(final Account account, final String folder, final String uid,
|
2009-11-24 19:40:29 -05:00
|
|
|
final MessagingListener listener)
|
|
|
|
{
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.loadMessageForViewStarted(account, folder, uid);
|
|
|
|
}
|
2010-08-08 19:49:27 -04:00
|
|
|
new Thread(new Runnable()
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
|
|
|
LocalFolder localFolder = localStore.getFolder(folder);
|
2009-10-19 15:35:31 -04:00
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-11-20 19:11:57 -05:00
|
|
|
LocalMessage message = (LocalMessage)localFolder.getMessage(uid);
|
|
|
|
if (message==null
|
2009-11-24 19:40:29 -05:00
|
|
|
|| message.getId()==0)
|
|
|
|
{
|
2009-11-20 19:11:57 -05:00
|
|
|
throw new IllegalArgumentException("Message not found: folder=" + folder + ", uid=" + uid);
|
|
|
|
}
|
2010-04-25 12:33:32 -04:00
|
|
|
if (!message.isSet(Flag.SEEN))
|
|
|
|
{
|
|
|
|
message.setFlag(Flag.SEEN, true);
|
|
|
|
setFlag(new Message[] { message }, Flag.SEEN, true);
|
|
|
|
}
|
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-10-19 15:35:31 -04:00
|
|
|
l.loadMessageForViewHeadersAvailable(account, folder, uid, message);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-19 15:35:31 -04:00
|
|
|
FetchProfile fp = new FetchProfile();
|
|
|
|
fp.add(FetchProfile.Item.ENVELOPE);
|
|
|
|
fp.add(FetchProfile.Item.BODY);
|
2009-11-24 19:40:29 -05:00
|
|
|
localFolder.fetch(new Message[]
|
2009-11-26 00:10:12 -05:00
|
|
|
{
|
|
|
|
message
|
|
|
|
}, fp, null);
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
localFolder.close();
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-10-19 15:35:31 -04:00
|
|
|
l.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-10-19 15:35:31 -04:00
|
|
|
l.loadMessageForViewFinished(account, folder, uid, message);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-19 15:35:31 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-07-13 17:17:10 -04:00
|
|
|
for (MessagingListener l : getListeners(listener))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-10-19 15:35:31 -04:00
|
|
|
l.loadMessageForViewFailed(account, folder, uid, e);
|
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-19 15:35:31 -04:00
|
|
|
}
|
|
|
|
}
|
2010-08-08 19:49:27 -04:00
|
|
|
}).start();
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Attempts to load the attachment specified by part from the given account and message.
|
|
|
|
* @param account
|
|
|
|
* @param message
|
|
|
|
* @param part
|
|
|
|
* @param listener
|
|
|
|
*/
|
|
|
|
public void loadAttachment(
|
2009-11-24 19:40:29 -05:00
|
|
|
final Account account,
|
|
|
|
final Message message,
|
|
|
|
final Part part,
|
|
|
|
final Object tag,
|
|
|
|
final MessagingListener listener)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* Check if the attachment has already been downloaded. If it has there's no reason to
|
|
|
|
* download it, so we just tell the listener that it's ready to go.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
|
|
|
if (part.getBody() != null)
|
|
|
|
{
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.loadAttachmentStarted(account, message, part, tag, false);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
if (listener != null)
|
|
|
|
{
|
2009-09-16 08:31:52 -04:00
|
|
|
listener.loadAttachmentStarted(account, message, part, tag, false);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.loadAttachmentFinished(account, message, part, tag);
|
|
|
|
}
|
2009-09-16 08:31:52 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (listener != null)
|
|
|
|
{
|
2009-09-16 08:31:52 -04:00
|
|
|
listener.loadAttachmentFinished(account, message, part, tag);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* If the header isn't there the attachment isn't downloaded yet, so just continue
|
|
|
|
* on.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.loadAttachmentStarted(account, message, part, tag, true);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
if (listener != null)
|
|
|
|
{
|
2009-09-16 08:31:52 -04:00
|
|
|
listener.loadAttachmentStarted(account, message, part, tag, false);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
put("loadAttachment", listener, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
Folder remoteFolder = null;
|
|
|
|
LocalFolder localFolder = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* We clear out any attachments already cached in the entire store and then
|
|
|
|
* we update the passed in message to reflect that there are no cached
|
|
|
|
* attachments. This is in support of limiting the account to having one
|
|
|
|
* attachment downloaded at a time.
|
|
|
|
*/
|
|
|
|
localStore.pruneCachedAttachments();
|
|
|
|
ArrayList<Part> viewables = new ArrayList<Part>();
|
|
|
|
ArrayList<Part> attachments = new ArrayList<Part>();
|
|
|
|
MimeUtility.collectParts(message, viewables, attachments);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Part attachment : attachments)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
attachment.setBody(null);
|
|
|
|
}
|
2010-03-03 23:00:30 -05:00
|
|
|
Store remoteStore = account.getRemoteStore();
|
|
|
|
localFolder = localStore.getFolder(message.getFolder().getName());
|
2010-01-16 11:22:20 -05:00
|
|
|
remoteFolder = remoteStore.getFolder(message.getFolder().getName());
|
2008-11-01 17:32:06 -04:00
|
|
|
remoteFolder.open(OpenMode.READ_WRITE);
|
|
|
|
|
2010-05-19 09:31:48 -04:00
|
|
|
//FIXME: This is an ugly hack that won't be needed once the Message objects have been united.
|
|
|
|
Message remoteMessage = remoteFolder.getMessage(message.getUid());
|
|
|
|
remoteMessage.setBody(message.getBody());
|
|
|
|
remoteFolder.fetchPart(remoteMessage, part, null);
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.updateMessage((LocalMessage)message);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.loadAttachmentFinished(account, message, part, tag);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
if (listener != null)
|
|
|
|
{
|
2009-09-16 08:31:52 -04:00
|
|
|
listener.loadAttachmentFinished(account, message, part, tag);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
2010-02-06 00:35:15 -05:00
|
|
|
Log.v(K9.LOG_TAG, "Exception loading attachment", me);
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.loadAttachmentFailed(account, message, part, tag, me.getMessage());
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
if (listener != null)
|
|
|
|
{
|
2009-09-16 08:31:52 -04:00
|
|
|
listener.loadAttachmentFailed(account, message, part, tag, me.getMessage());
|
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (remoteFolder != null)
|
|
|
|
{
|
|
|
|
remoteFolder.close();
|
|
|
|
}
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
|
|
|
localFolder.close();
|
|
|
|
}
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stores the given message in the Outbox and starts a sendPendingMessages command to
|
|
|
|
* attempt to send the message.
|
|
|
|
* @param account
|
|
|
|
* @param message
|
|
|
|
* @param listener
|
|
|
|
*/
|
|
|
|
public void sendMessage(final Account account,
|
2009-11-24 19:40:29 -05:00
|
|
|
final Message message,
|
|
|
|
MessagingListener listener)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
|
|
|
LocalFolder localFolder = localStore.getFolder(account.getOutboxFolderName());
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
2009-11-24 19:40:29 -05:00
|
|
|
localFolder.appendMessages(new Message[]
|
2009-11-26 00:10:12 -05:00
|
|
|
{
|
|
|
|
message
|
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
Message localMessage = localFolder.getMessage(message.getUid());
|
|
|
|
localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
localFolder.close();
|
2008-11-01 17:32:06 -04:00
|
|
|
sendPendingMessages(account, null);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-04-16 08:20:10 -04:00
|
|
|
/*
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
// TODO general failed
|
|
|
|
}
|
2010-04-16 08:20:10 -04:00
|
|
|
*/
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Attempt to send any messages that are sitting in the Outbox.
|
|
|
|
* @param account
|
|
|
|
* @param listener
|
|
|
|
*/
|
|
|
|
public void sendPendingMessages(final Account account,
|
2009-11-24 19:40:29 -05:00
|
|
|
MessagingListener listener)
|
|
|
|
{
|
|
|
|
putBackground("sendPendingMessages", listener, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
sendPendingMessagesSynchronous(account);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2009-11-17 22:06:23 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public boolean messagesPendingSend(final Account account)
|
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
Folder localFolder = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2009-11-17 22:06:23 -05:00
|
|
|
localFolder = localStore.getFolder(
|
2009-11-24 19:40:29 -05:00
|
|
|
account.getOutboxFolderName());
|
|
|
|
if (!localFolder.exists())
|
|
|
|
{
|
2009-11-17 22:06:23 -05:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
|
|
|
|
|
|
|
int localMessages = localFolder.getMessageCount();
|
2009-11-24 19:40:29 -05:00
|
|
|
if (localMessages > 0)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Exception while checking for unsent messages", e);
|
2009-11-17 22:06:23 -05:00
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
|
|
|
localFolder.close();
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
return false;
|
|
|
|
}
|
2009-11-17 22:06:23 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
|
|
|
* Attempt to send any messages that are sitting in the Outbox.
|
|
|
|
* @param account
|
|
|
|
* @param listener
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public void sendPendingMessagesSynchronous(final Account account)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
Folder localFolder = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2009-10-21 20:41:06 -04:00
|
|
|
localFolder = localStore.getFolder(
|
2009-11-24 19:40:29 -05:00
|
|
|
account.getOutboxFolderName());
|
|
|
|
if (!localFolder.exists())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.sendPendingMessagesStarted(account);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
|
|
|
|
|
|
|
Message[] localMessages = localFolder.getMessages(null);
|
2009-04-09 13:48:05 -04:00
|
|
|
boolean anyFlagged = false;
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
int progress = 0;
|
|
|
|
int todo = localMessages.length;
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxProgress(account, account.getSentFolderName(), progress, todo);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* The profile we will use to pull all of the content
|
|
|
|
* for a given local message into memory for sending.
|
|
|
|
*/
|
|
|
|
FetchProfile fp = new FetchProfile();
|
|
|
|
fp.add(FetchProfile.Item.ENVELOPE);
|
|
|
|
fp.add(FetchProfile.Item.BODY);
|
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Scanning folder '" + account.getOutboxFolderName() + "' (" + ((LocalFolder)localFolder).getId() + ") for messages to send");
|
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Transport transport = Transport.getInstance(account);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Message message : localMessages)
|
|
|
|
{
|
|
|
|
if (message.isSet(Flag.DELETED))
|
|
|
|
{
|
|
|
|
message.setFlag(Flag.X_DESTROYED, true);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (message.isSet(Flag.FLAGGED))
|
|
|
|
{
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Skipping sending FLAGGED message " + message.getUid());
|
2009-04-09 13:48:05 -04:00
|
|
|
continue;
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
try
|
|
|
|
{
|
|
|
|
AtomicInteger count = new AtomicInteger(0);
|
|
|
|
AtomicInteger oldCount = sendCount.putIfAbsent(message.getUid(), count);
|
|
|
|
if (oldCount != null)
|
|
|
|
{
|
|
|
|
count = oldCount;
|
|
|
|
}
|
2010-01-02 20:50:41 -05:00
|
|
|
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Send count for message " + message.getUid() + " is " + count.get());
|
2009-12-14 21:50:53 -05:00
|
|
|
if (count.incrementAndGet() > K9.MAX_SEND_ATTEMPTS)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Send count for message " + message.getUid() + " has exceeded maximum attempt threshold, flagging");
|
2009-11-24 19:40:29 -05:00
|
|
|
message.setFlag(Flag.FLAGGED, true);
|
|
|
|
anyFlagged = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.fetch(new Message[] { message }, fp, null);
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
message.setFlag(Flag.X_SEND_IN_PROGRESS, true);
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Sending message with UID " + message.getUid());
|
2008-11-01 17:32:06 -04:00
|
|
|
transport.sendMessage(message);
|
|
|
|
message.setFlag(Flag.X_SEND_IN_PROGRESS, false);
|
2009-01-24 13:52:58 -05:00
|
|
|
message.setFlag(Flag.SEEN, true);
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
progress++;
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxProgress(account, account.getSentFolderName(), progress, todo);
|
|
|
|
}
|
2010-02-08 22:03:40 -05:00
|
|
|
if (K9.FOLDER_NONE.equals(account.getSentFolderName()))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-08 22:03:40 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Sent folder set to " + K9.FOLDER_NONE + ", deleting sent message");
|
|
|
|
message.setFlag(Flag.DELETED, true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LocalFolder localSentFolder =
|
|
|
|
(LocalFolder) localStore.getFolder(
|
|
|
|
account.getSentFolderName());
|
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Moving sent message to folder '" + account.getSentFolderName() + "' (" + localSentFolder.getId() + ") ");
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-02-08 22:03:40 -05:00
|
|
|
localFolder.moveMessages(
|
|
|
|
new Message[] { message },
|
|
|
|
localSentFolder);
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-02-08 22:03:40 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Moved sent message to folder '" + account.getSentFolderName() + "' (" + localSentFolder.getId() + ") ");
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-02-08 22:03:40 -05:00
|
|
|
PendingCommand command = new PendingCommand();
|
|
|
|
command.command = PENDING_COMMAND_APPEND;
|
|
|
|
command.arguments =
|
|
|
|
new String[]
|
|
|
|
{
|
|
|
|
localSentFolder.getName(),
|
|
|
|
message.getUid()
|
|
|
|
};
|
|
|
|
queuePendingCommand(account, command);
|
|
|
|
processPendingCommands(account);
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
if (e instanceof MessagingException)
|
2009-04-10 22:11:17 -04:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
MessagingException me = (MessagingException)e;
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!me.isPermanentFailure())
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
// Decrement the counter if the message could not possibly have been sent
|
|
|
|
int newVal = count.decrementAndGet();
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Decremented send count for message " + message.getUid() + " to " + newVal
|
|
|
|
+ "; no possible send");
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2009-04-10 22:11:17 -04:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
message.setFlag(Flag.X_SEND_FAILED, true);
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Failed to send message", e);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxFailed(
|
|
|
|
account,
|
|
|
|
localFolder.getName(),
|
|
|
|
getRootCauseMessage(e));
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Failed to fetch message for sending", e);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.synchronizeMailboxFailed(
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
account,
|
|
|
|
localFolder.getName(),
|
|
|
|
getRootCauseMessage(e));
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* We ignore this exception because a future refresh will retry this
|
|
|
|
* message.
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
if (localFolder.getMessageCount() == 0)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.delete(false);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.sendPendingMessagesCompleted(account);
|
|
|
|
}
|
2009-04-09 13:48:05 -04:00
|
|
|
if (anyFlagged)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
addErrorMessage(account, mApplication.getString(R.string.send_failure_subject),
|
2009-12-14 21:50:53 -05:00
|
|
|
mApplication.getString(R.string.send_failure_body_fmt, K9.ERROR_FOLDER_NAME));
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
NotificationManager notifMgr =
|
|
|
|
(NotificationManager)mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
|
|
|
|
|
|
Notification notif = new Notification(R.drawable.stat_notify_email_generic,
|
|
|
|
mApplication.getString(R.string.send_failure_subject), System.currentTimeMillis());
|
|
|
|
|
2010-01-27 19:29:27 -05:00
|
|
|
Intent i = MessageList.actionHandleFolderIntent(mApplication, account, account.getErrorFolderName());
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
PendingIntent pi = PendingIntent.getActivity(mApplication, 0, i, 0);
|
|
|
|
|
|
|
|
notif.setLatestEventInfo(mApplication, mApplication.getString(R.string.send_failure_subject),
|
2009-12-14 21:50:53 -05:00
|
|
|
mApplication.getString(R.string.send_failure_body_abbrev, K9.ERROR_FOLDER_NAME), pi);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
notif.flags |= Notification.FLAG_SHOW_LIGHTS;
|
2009-12-14 21:50:53 -05:00
|
|
|
notif.ledARGB = K9.NOTIFICATION_LED_SENDING_FAILURE_COLOR;
|
|
|
|
notif.ledOnMS = K9.NOTIFICATION_LED_FAST_ON_TIME;
|
|
|
|
notif.ledOffMS = K9.NOTIFICATION_LED_FAST_OFF_TIME;
|
2009-11-24 19:40:29 -05:00
|
|
|
notifMgr.notify(-1000 - account.getAccountNumber(), notif);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
l.sendPendingMessagesFailed(account);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
localFolder.close();
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Exception while closing folder", e);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-16 23:32:17 -04:00
|
|
|
public void getAccountStats(final Context context, final Account account,
|
2010-04-29 00:59:14 -04:00
|
|
|
final MessagingListener l)
|
2009-02-05 23:28:29 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
Runnable unreadRunnable = new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2010-04-16 10:33:54 -04:00
|
|
|
AccountStats stats = account.getStats(context);
|
|
|
|
l.accountStatusChanged(account, stats);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Count not get unread count for account " + account.getDescription(),
|
2009-11-24 19:40:29 -05:00
|
|
|
me);
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2010-04-16 23:32:17 -04:00
|
|
|
put("getAccountStats:" + account.getDescription(), l, unreadRunnable);
|
2009-02-05 23:28:29 -05:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
public void getFolderUnreadMessageCount(final Account account, final String folderName,
|
2009-12-20 00:41:43 -05:00
|
|
|
final MessagingListener l)
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
{
|
|
|
|
Runnable unreadRunnable = new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
|
|
|
|
int unreadMessageCount = 0;
|
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Folder localFolder = account.getLocalStore().getFolder(folderName);
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
unreadMessageCount = localFolder.getUnreadMessageCount();
|
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
|
|
|
Log.e(K9.LOG_TAG, "Count not get unread count for account " + account.getDescription(), me);
|
|
|
|
}
|
|
|
|
l.folderStatusChanged(account, folderName, unreadMessageCount);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
put("getFolderUnread:" + account.getDescription() + ":" + folderName, l, unreadRunnable);
|
|
|
|
}
|
|
|
|
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public boolean isMoveCapable(Message message)
|
|
|
|
{
|
2010-08-29 19:40:14 -04:00
|
|
|
return !message.getUid().startsWith(K9.LOCAL_UID_PREFIX);
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
public boolean isCopyCapable(Message message)
|
|
|
|
{
|
|
|
|
return isMoveCapable(message);
|
|
|
|
}
|
|
|
|
|
2009-03-05 02:32:45 -05:00
|
|
|
public boolean isMoveCapable(final Account account)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
|
|
|
Store remoteStore = account.getRemoteStore();
|
2009-11-24 19:40:29 -05:00
|
|
|
return localStore.isMoveCapable() && remoteStore.isMoveCapable();
|
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2009-03-05 02:32:45 -05:00
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Exception while ascertaining move capability", me);
|
2009-11-24 19:40:29 -05:00
|
|
|
return false;
|
|
|
|
}
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
|
|
|
public boolean isCopyCapable(final Account account)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
|
|
|
Store remoteStore = account.getRemoteStore();
|
2009-11-24 19:40:29 -05:00
|
|
|
return localStore.isCopyCapable() && remoteStore.isCopyCapable();
|
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Exception while ascertaining copy capability", me);
|
2009-11-24 19:40:29 -05:00
|
|
|
return false;
|
|
|
|
}
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2010-03-03 23:00:30 -05:00
|
|
|
public void moveMessages(final Account account, final String srcFolder, final Message[] messages, final String destFolder,
|
2010-04-29 00:59:14 -04:00
|
|
|
final MessagingListener listener)
|
2009-11-26 00:30:13 -05:00
|
|
|
{
|
|
|
|
for (Message message : messages)
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
suppressMessage(account, srcFolder, message);
|
|
|
|
}
|
|
|
|
putBackground("moveMessages", null, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
2009-11-26 00:30:13 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
moveOrCopyMessageSynchronous(account, srcFolder, messages, destFolder, false, listener);
|
2009-11-26 00:30:13 -05:00
|
|
|
}
|
2010-03-03 23:00:30 -05:00
|
|
|
});
|
2009-11-26 00:30:13 -05:00
|
|
|
}
|
2010-03-03 23:00:30 -05:00
|
|
|
|
|
|
|
public void moveMessage(final Account account, final String srcFolder, final Message message, final String destFolder,
|
2010-04-29 00:59:14 -04:00
|
|
|
final MessagingListener listener)
|
2009-03-05 02:32:45 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
moveMessages(account, srcFolder, new Message[] { message }, destFolder, listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void copyMessages(final Account account, final String srcFolder, final Message[] messages, final String destFolder,
|
2010-04-29 00:59:14 -04:00
|
|
|
final MessagingListener listener)
|
2010-03-03 23:00:30 -05:00
|
|
|
{
|
|
|
|
putBackground("copyMessages", null, new Runnable()
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
public void run()
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
moveOrCopyMessageSynchronous(account, srcFolder, messages, destFolder, true, listener);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
public void copyMessage(final Account account, final String srcFolder, final Message message, final String destFolder,
|
2010-04-29 00:59:14 -04:00
|
|
|
final MessagingListener listener)
|
2010-03-03 23:00:30 -05:00
|
|
|
{
|
|
|
|
copyMessages(account, srcFolder, new Message[] { message }, destFolder, listener);
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
private void moveOrCopyMessageSynchronous(final Account account, final String srcFolder, final Message[] inMessages,
|
2009-11-24 19:40:29 -05:00
|
|
|
final String destFolder, final boolean isCopy, MessagingListener listener)
|
2009-03-05 02:32:45 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
|
|
|
Store remoteStore = account.getRemoteStore();
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!isCopy && (!remoteStore.isMoveCapable() || !localStore.isMoveCapable()))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2010-08-29 19:39:26 -04:00
|
|
|
if (isCopy && (!remoteStore.isCopyCapable() || !localStore.isCopyCapable()))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
return;
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
Folder localSrcFolder = localStore.getFolder(srcFolder);
|
|
|
|
Folder localDestFolder = localStore.getFolder(destFolder);
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
List<String> uids = new LinkedList<String>();
|
|
|
|
for (Message message : inMessages)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
String uid = message.getUid();
|
|
|
|
if (!uid.startsWith(K9.LOCAL_UID_PREFIX))
|
|
|
|
{
|
|
|
|
uids.add(uid);
|
|
|
|
}
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-08-02 07:55:31 -04:00
|
|
|
Message[] messages = localSrcFolder.getMessages(uids.toArray(EMPTY_STRING_ARRAY), null);
|
2010-03-03 23:00:30 -05:00
|
|
|
if (messages.length > 0)
|
|
|
|
{
|
|
|
|
Map<String, Message> origUidMap = new HashMap<String, Message>();
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
for (Message message : messages)
|
|
|
|
{
|
|
|
|
origUidMap.put(message.getUid(), message);
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "moveOrCopyMessageSynchronous: source folder = " + srcFolder
|
2010-03-03 23:00:30 -05:00
|
|
|
+ ", " + messages.length + " messages, " + ", destination folder = " + destFolder + ", isCopy = " + isCopy);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
if (isCopy)
|
|
|
|
{
|
|
|
|
FetchProfile fp = new FetchProfile();
|
|
|
|
fp.add(FetchProfile.Item.ENVELOPE);
|
|
|
|
fp.add(FetchProfile.Item.BODY);
|
2010-03-03 23:00:30 -05:00
|
|
|
localSrcFolder.fetch(messages, fp, null);
|
|
|
|
localSrcFolder.copyMessages(messages, localDestFolder);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
localSrcFolder.moveMessages(messages, localDestFolder);
|
|
|
|
for (String origUid : origUidMap.keySet())
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.messageUidChanged(account, srcFolder, origUid, origUidMap.get(origUid).getUid());
|
|
|
|
}
|
|
|
|
unsuppressMessage(account, srcFolder, origUid);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-08-02 07:55:31 -04:00
|
|
|
queueMoveOrCopy(account, srcFolder, destFolder, isCopy, origUidMap.keySet().toArray(EMPTY_STRING_ARRAY));
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
processPendingCommands(account);
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
2009-03-05 02:32:45 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
throw new RuntimeException("Error moving message", me);
|
|
|
|
}
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2009-12-27 12:22: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.
2009-12-20 18:13:49 -05:00
|
|
|
public void expunge(final Account account, final String folder, final MessagingListener listener)
|
2010-01-02 20:50:51 -05:00
|
|
|
{
|
2009-12-24 13:08:23 -05:00
|
|
|
putBackground("expunge", null, new Runnable()
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
queueExpunge(account, folder);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
|
|
|
public void deleteDraft(final Account account, String uid)
|
2009-11-26 00:30:13 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalFolder localFolder = null;
|
|
|
|
try
|
2009-11-26 00:30:13 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
|
|
|
localFolder = localStore.getFolder(account.getDraftsFolderName());
|
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
|
|
|
Message message = localFolder.getMessage(uid);
|
2010-04-05 22:35:42 -04:00
|
|
|
if (message != null)
|
|
|
|
{
|
|
|
|
deleteMessages(new Message[] { message }, null);
|
|
|
|
}
|
2010-03-03 23:00:30 -05:00
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
2009-11-26 00:30:13 -05:00
|
|
|
}
|
2010-03-03 23:00:30 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
|
|
|
localFolder.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
public void deleteMessages(final Message[] messages, final MessagingListener listener)
|
|
|
|
{
|
|
|
|
actOnMessages(messages, new MessageActor()
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void act(final Account account, final Folder folder,
|
2010-04-29 00:59:14 -04:00
|
|
|
final List<Message> messages)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
for (Message message : messages)
|
|
|
|
{
|
|
|
|
suppressMessage(account, folder.getName(), message);
|
|
|
|
}
|
|
|
|
|
|
|
|
putBackground("deleteMessages", null, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
2010-08-02 07:55:31 -04:00
|
|
|
deleteMessagesSynchronous(account, folder.getName(), messages.toArray(EMPTY_MESSAGE_ARRAY), listener);
|
2010-03-03 23:00:30 -05:00
|
|
|
}
|
|
|
|
});
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
});
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-01-07 01:02:04 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-11-29 13:07:34 -05:00
|
|
|
private void deleteMessagesSynchronous(final Account account, final String folder, final Message[] messages,
|
2009-12-06 19:56:06 -05:00
|
|
|
MessagingListener listener)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-11-29 13:07:34 -05:00
|
|
|
Folder localFolder = null;
|
|
|
|
Folder localTrashFolder = null;
|
|
|
|
String[] uids = getUidsFromMessages(messages);
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2009-12-14 19:03:22 -05:00
|
|
|
//We need to make these callbacks before moving the messages to the trash
|
|
|
|
//as messages get a new UID after being moved
|
|
|
|
for (Message message : messages)
|
|
|
|
{
|
|
|
|
if (listener != null)
|
|
|
|
{
|
|
|
|
listener.messageDeleted(account, folder, message);
|
|
|
|
}
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.messageDeleted(account, folder, message);
|
|
|
|
}
|
|
|
|
}
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2009-11-29 13:07:34 -05:00
|
|
|
localFolder = localStore.getFolder(folder);
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
if (folder.equals(account.getTrashFolderName()) || K9.FOLDER_NONE.equals(account.getTrashFolderName()))
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
Log.d(K9.LOG_TAG, "Deleting messages in trash folder or trash set to -None-, not copying");
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-11-29 13:07:34 -05:00
|
|
|
localFolder.setFlags(messages, new Flag[] { Flag.DELETED }, true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
localTrashFolder = localStore.getFolder(account.getTrashFolderName());
|
2010-07-26 21:27:54 -04:00
|
|
|
if (!localTrashFolder.exists())
|
2009-11-29 13:07:34 -05:00
|
|
|
{
|
|
|
|
localTrashFolder.create(Folder.FolderType.HOLDS_MESSAGES);
|
|
|
|
}
|
2010-07-26 21:27:54 -04:00
|
|
|
if (localTrashFolder.exists())
|
2009-01-29 08:35:43 -05:00
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "Deleting messages in normal folder, moving");
|
2009-03-07 02:20:15 -05:00
|
|
|
|
2009-11-29 13:07:34 -05:00
|
|
|
localFolder.moveMessages(messages, localTrashFolder);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-01-09 00:39:43 -05:00
|
|
|
}
|
2009-01-07 01:02:04 -05:00
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2010-01-03 19:41:26 -05:00
|
|
|
l.folderStatusChanged(account, folder, localFolder.getUnreadMessageCount());
|
|
|
|
if (localTrashFolder != null)
|
|
|
|
{
|
|
|
|
l.folderStatusChanged(account, account.getTrashFolderName(), localTrashFolder.getUnreadMessageCount());
|
|
|
|
}
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "Delete policy for account " + account.getDescription() + " is " + account.getDeletePolicy());
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-01-07 01:02:04 -05:00
|
|
|
if (folder.equals(account.getOutboxFolderName()))
|
|
|
|
{
|
2009-11-29 13:07:34 -05:00
|
|
|
for (Message message : messages)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-11-29 13:07:34 -05:00
|
|
|
// If the message was in the Outbox, then it has been copied to local Trash, and has
|
|
|
|
// to be copied to remote trash
|
|
|
|
PendingCommand command = new PendingCommand();
|
|
|
|
command.command = PENDING_COMMAND_APPEND;
|
|
|
|
command.arguments =
|
|
|
|
new String[]
|
|
|
|
{
|
|
|
|
account.getTrashFolderName(),
|
|
|
|
message.getUid()
|
|
|
|
};
|
|
|
|
queuePendingCommand(account, command);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
processPendingCommands(account);
|
|
|
|
}
|
|
|
|
else if (folder.equals(account.getTrashFolderName()) && account.getDeletePolicy() == Account.DELETE_POLICY_ON_DELETE)
|
|
|
|
{
|
2009-11-29 13:07:34 -05:00
|
|
|
queueSetFlag(account, folder, Boolean.toString(true), Flag.DELETED.toString(), uids);
|
2009-11-24 19:40:29 -05:00
|
|
|
processPendingCommands(account);
|
|
|
|
}
|
|
|
|
else if (account.getDeletePolicy() == Account.DELETE_POLICY_ON_DELETE)
|
|
|
|
{
|
2009-11-29 13:07:34 -05:00
|
|
|
queueMoveOrCopy(account, folder, account.getTrashFolderName(), false, uids);
|
2008-11-01 17:32:06 -04:00
|
|
|
processPendingCommands(account);
|
|
|
|
}
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
else if (account.getDeletePolicy() == Account.DELETE_POLICY_MARK_AS_READ)
|
|
|
|
{
|
2009-11-29 13:07:34 -05:00
|
|
|
queueSetFlag(account, folder, Boolean.toString(true), Flag.SEEN.toString(), uids);
|
2009-11-24 19:40:29 -05:00
|
|
|
processPendingCommands(account);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "Delete policy " + account.getDeletePolicy() + " prevents delete from server");
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
}
|
2010-03-03 23:00:30 -05:00
|
|
|
for (String uid : uids)
|
|
|
|
{
|
|
|
|
unsuppressMessage(account, folder, uid);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, me);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new RuntimeException("Error deleting message from local store.", me);
|
|
|
|
}
|
2009-11-29 13:07:34 -05:00
|
|
|
finally
|
|
|
|
{
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-11-29 13:07:34 -05:00
|
|
|
if (localFolder != null)
|
|
|
|
{
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
localFolder.close();
|
2009-11-29 13:07:34 -05:00
|
|
|
}
|
|
|
|
if (localTrashFolder != null)
|
|
|
|
{
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
localTrashFolder.close();
|
2009-11-29 13:07:34 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-29 13:07:34 -05:00
|
|
|
private String[] getUidsFromMessages(Message[] messages)
|
|
|
|
{
|
|
|
|
String[] uids = new String[messages.length];
|
|
|
|
for (int i = 0; i < messages.length; i++)
|
|
|
|
{
|
|
|
|
uids[i] = messages[i].getUid();
|
|
|
|
}
|
|
|
|
return uids;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
private void processPendingEmptyTrash(PendingCommand command, Account account) throws MessagingException
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store remoteStore = account.getRemoteStore();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
Folder remoteFolder = remoteStore.getFolder(account.getTrashFolderName());
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
try
|
2009-11-24 19:40:29 -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.
2009-12-20 18:13:49 -05:00
|
|
|
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();
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2009-01-24 13:52:58 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void emptyTrash(final Account account, MessagingListener listener)
|
|
|
|
{
|
2009-12-24 13:08:23 -05:00
|
|
|
putBackground("emptyTrash", listener, new Runnable()
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
Folder localFolder = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2010-01-16 11:22:20 -05:00
|
|
|
localFolder = localStore.getFolder(account.getTrashFolderName());
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
localFolder.setFlags(new Flag[] { Flag.DELETED }, true);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.emptyTrashCompleted(account);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-01-24 13:52:58 -05:00
|
|
|
List<String> args = new ArrayList<String>();
|
|
|
|
PendingCommand command = new PendingCommand();
|
|
|
|
command.command = PENDING_COMMAND_EMPTY_TRASH;
|
2010-08-02 07:55:31 -04:00
|
|
|
command.arguments = args.toArray(EMPTY_STRING_ARRAY);
|
2009-01-24 13:52:58 -05:00
|
|
|
queuePendingCommand(account, command);
|
|
|
|
processPendingCommands(account);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "emptyTrash failed", e);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
|
|
|
localFolder.close();
|
|
|
|
}
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void sendAlternate(final Context context, Account account, Message message)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "About to load message " + account.getDescription() + ":" + message.getFolder().getName()
|
2009-11-24 19:40:29 -05:00
|
|
|
+ ":" + message.getUid() + " for sendAlternate");
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
loadMessageForView(account, message.getFolder().getName(),
|
|
|
|
message.getUid(), new MessagingListener()
|
|
|
|
{
|
|
|
|
@Override
|
|
|
|
public void loadMessageForViewBodyAvailable(Account account, String folder, String uid,
|
|
|
|
Message message)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "Got message " + account.getDescription() + ":" + folder
|
2009-11-24 19:40:29 -05:00
|
|
|
+ ":" + message.getUid() + " for sendAlternate");
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Intent msg=new Intent(Intent.ACTION_SEND);
|
|
|
|
String quotedText = null;
|
|
|
|
Part part = MimeUtility.findFirstPartByMimeType(message,
|
|
|
|
"text/plain");
|
|
|
|
if (part == null)
|
|
|
|
{
|
|
|
|
part = MimeUtility.findFirstPartByMimeType(message, "text/html");
|
|
|
|
}
|
|
|
|
if (part != null)
|
|
|
|
{
|
|
|
|
quotedText = MimeUtility.getTextFromPart(part);
|
|
|
|
}
|
|
|
|
if (quotedText != null)
|
|
|
|
{
|
|
|
|
msg.putExtra(Intent.EXTRA_TEXT, quotedText);
|
|
|
|
}
|
|
|
|
msg.putExtra(Intent.EXTRA_SUBJECT, "Fwd: " + message.getSubject());
|
|
|
|
msg.setType("text/plain");
|
|
|
|
context.startActivity(Intent.createChooser(msg, context.getString(R.string.send_alternate_chooser_title)));
|
|
|
|
}
|
|
|
|
catch (MessagingException me)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to send email through alternate program", me);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
|
|
|
* Checks mail for one or multiple accounts. If account is null all accounts
|
|
|
|
* are checked.
|
|
|
|
*
|
|
|
|
* @param context
|
|
|
|
* @param account
|
|
|
|
* @param listener
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public void checkMail(final Context context, final Account account,
|
|
|
|
final boolean ignoreLastCheckedTime,
|
|
|
|
final boolean useManualWakeLock,
|
|
|
|
final MessagingListener listener)
|
|
|
|
{
|
|
|
|
|
2010-05-16 20:30:32 -04:00
|
|
|
TracingWakeLock twakeLock = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
if (useManualWakeLock)
|
|
|
|
{
|
2010-05-16 20:30:32 -04:00
|
|
|
TracingPowerManager pm = TracingPowerManager.getPowerManager(context);
|
2010-05-30 00:17:00 -04:00
|
|
|
|
2010-05-16 20:30:32 -04:00
|
|
|
twakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "K9 MessagingController.checkMail");
|
2009-11-24 19:40:29 -05:00
|
|
|
twakeLock.setReferenceCounted(false);
|
2009-12-14 21:50:53 -05:00
|
|
|
twakeLock.acquire(K9.MANUAL_WAKE_LOCK_TIMEOUT);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2010-05-16 20:30:32 -04:00
|
|
|
final TracingWakeLock wakeLock = twakeLock;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
l.checkMailStarted(context, account);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
putBackground("checkMail", listener, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
Complete merge of DAmail functionality into K9mail. Following
features are added to K9mail:
1) Show unread message count on each folder
2) Sum unread count of all shown folders in an account to the account display
3) Periodically check selected folders for new mail, not just Inbox
4) Don't refresh folder when opened (unless folder is empty)
5) Show date and time of last sync for each folder
6) Fix timer for automatic periodic sync (use wakelock to assure completion)
7) Optimize local folder queries (speeds up account and folder lists)
8) Show Loading... message in status bar indicating which folder is being synced
9) Eliminate redundant sync of new messages (performance enhancement)
10) Improve notification text for multiple accounts
11) Do not automatically sync folders more often than the account-specific period
12) Use user-configured date and time formats
13) Select which folders are shown, using configurable Classes
14) Select which folders are synced, using configurable Classes
15) Added context (long press) menu to folders, to provide for Refresh
and Folder Settings
16) Status light flashes purple when there are unread messages
17) Folder list more quickly eliminates display of deleted and out-of-Class folders.
18) Delete works
19) Mark all messages as read (in the folder context menu)
20) Notifications only for new unread messages
21) One minute synchronization frequency
22) Deleting an unread message decrements unread counter
23) Notifications work for POP3 accounts
24) Message deletes work for POP3 accounts
25) Explicit errors show in folder list
26) Stack traces saved to folder K9mail-errors
27) Clear pending actions (danger, for emergencies only!)
28) Delete policy in Account settings
29) DNS cache in InetAddress disabled
30) Trapped some crash-causing error conditions
31) Eliminate duplicate copies to Sent folder
32) Prevent crashes due to message listener concurrency
33) Empty Trash
34) Nuclear "Mark all messages as read" (marks all messages as read in
server-side folder, irrespective of which messages have been downloaded)
35) Forward (alternate) to allow forwarding email through other programs
36) Accept text/plain Intents to allow other programs to send email through K9mail
37) Displays Outbox sending status
38) Manual retry of outbox sending when "Refresh"ing Outbox
39) Folder error status is persisted
40) Ability to log to arbitrary file
Fixes K9 issues 11, 23, 24, 65, 69, 71, 79, 81, 82, 83, 87, 101, 104,
107, 120, 148, 154
2008-12-30 22:49:09 -05:00
|
|
|
|
|
|
|
final NotificationManager notifMgr = (NotificationManager)context
|
2009-11-24 19:40:29 -05:00
|
|
|
.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
|
|
try
|
|
|
|
{
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Starting mail check");
|
2009-11-24 19:40:29 -05:00
|
|
|
Preferences prefs = Preferences.getPreferences(context);
|
|
|
|
|
|
|
|
Account[] accounts;
|
|
|
|
if (account != null)
|
|
|
|
{
|
|
|
|
accounts = new Account[]
|
|
|
|
{
|
|
|
|
account
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
accounts = prefs.getAccounts();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (final Account account : accounts)
|
|
|
|
{
|
|
|
|
final long accountInterval = account.getAutomaticCheckIntervalMinutes() * 60 * 1000;
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!ignoreLastCheckedTime && accountInterval <= 0)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Skipping synchronizing account " + account.getDescription());
|
2009-11-24 19:40:29 -05:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Synchronizing account " + account.getDescription());
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-03-29 22:58:21 -04:00
|
|
|
account.setRingNotified(false);
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
putBackground("sendPending " + account.getDescription(), null, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
if (messagesPendingSend(account))
|
|
|
|
{
|
|
|
|
if (account.isShowOngoing())
|
|
|
|
{
|
|
|
|
Notification notif = new Notification(R.drawable.ic_menu_refresh,
|
|
|
|
context.getString(R.string.notification_bg_send_ticker, account.getDescription()), System.currentTimeMillis());
|
2010-01-27 19:29:27 -05:00
|
|
|
Intent intent = MessageList.actionHandleFolderIntent(context, account, K9.INBOX);
|
2009-11-24 19:40:29 -05:00
|
|
|
PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0);
|
|
|
|
notif.setLatestEventInfo(context, context.getString(R.string.notification_bg_send_title),
|
|
|
|
account.getDescription() , pi);
|
|
|
|
notif.flags = Notification.FLAG_ONGOING_EVENT;
|
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.NOTIFICATION_LED_WHILE_SYNCING)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
notif.flags |= Notification.FLAG_SHOW_LIGHTS;
|
2010-05-15 16:35:59 -04:00
|
|
|
notif.ledARGB = account.getLedColor();
|
2009-12-14 21:50:53 -05:00
|
|
|
notif.ledOnMS = K9.NOTIFICATION_LED_FAST_ON_TIME;
|
|
|
|
notif.ledOffMS = K9.NOTIFICATION_LED_FAST_OFF_TIME;
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
|
2010-05-11 23:06:11 -04:00
|
|
|
notifMgr.notify(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber(), notif);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
try
|
|
|
|
{
|
|
|
|
sendPendingMessagesSynchronous(account);
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (account.isShowOngoing())
|
|
|
|
{
|
2010-05-11 23:06:11 -04:00
|
|
|
notifMgr.cancel(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber());
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Account.FolderMode aDisplayMode = account.getFolderDisplayMode();
|
|
|
|
Account.FolderMode aSyncMode = account.getFolderSyncMode();
|
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2010-05-30 12:56:50 -04:00
|
|
|
for (final Folder folder : localStore.getPersonalNamespaces(false))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
folder.open(Folder.OpenMode.READ_WRITE);
|
|
|
|
folder.refresh(prefs);
|
|
|
|
|
|
|
|
Folder.FolderClass fDisplayClass = folder.getDisplayClass();
|
|
|
|
Folder.FolderClass fSyncClass = folder.getSyncClass();
|
|
|
|
|
|
|
|
if (modeMismatch(aDisplayMode, fDisplayClass))
|
|
|
|
{
|
|
|
|
// Never sync a folder that isn't displayed
|
2010-04-14 23:17:25 -04:00
|
|
|
if (K9.DEBUG && false)
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.v(K9.LOG_TAG, "Not syncing folder " + folder.getName() +
|
2009-11-24 19:40:29 -05:00
|
|
|
" which is in display mode " + fDisplayClass + " while account is in display mode " + aDisplayMode);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (modeMismatch(aSyncMode, fSyncClass))
|
|
|
|
{
|
|
|
|
// Do not sync folders in the wrong class
|
2010-04-14 23:17:25 -04:00
|
|
|
if (K9.DEBUG && false)
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.v(K9.LOG_TAG, "Not syncing folder " + folder.getName() +
|
2009-11-24 19:40:29 -05:00
|
|
|
" which is in sync mode " + fSyncClass + " while account is in sync mode " + aSyncMode);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "Folder " + folder.getName() + " was last synced @ " +
|
2009-11-24 19:40:29 -05:00
|
|
|
new Date(folder.getLastChecked()));
|
|
|
|
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!ignoreLastCheckedTime && folder.getLastChecked() >
|
2009-11-24 19:40:29 -05:00
|
|
|
(System.currentTimeMillis() - accountInterval))
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "Not syncing folder " + folder.getName()
|
2009-11-24 19:40:29 -05:00
|
|
|
+ ", previously synced @ " + new Date(folder.getLastChecked())
|
|
|
|
+ " which would be too recent for the account period");
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
putBackground("sync" + folder.getName(), null, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
2010-01-16 11:22:20 -05:00
|
|
|
LocalFolder tLocalFolder = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
|
|
|
// In case multiple Commands get enqueued, don't run more than
|
|
|
|
// once
|
2010-03-03 23:00:30 -05:00
|
|
|
final LocalStore localStore = account.getLocalStore();
|
|
|
|
tLocalFolder = localStore.getFolder(folder.getName());
|
2009-11-24 19:40:29 -05:00
|
|
|
tLocalFolder.open(Folder.OpenMode.READ_WRITE);
|
|
|
|
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!ignoreLastCheckedTime && tLocalFolder.getLastChecked() >
|
2009-11-24 19:40:29 -05:00
|
|
|
(System.currentTimeMillis() - accountInterval))
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.v(K9.LOG_TAG, "Not running Command for folder " + folder.getName()
|
2009-11-24 19:40:29 -05:00
|
|
|
+ ", previously synced @ " + new Date(folder.getLastChecked())
|
|
|
|
+ " which would be too recent for the account period");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (account.isShowOngoing())
|
|
|
|
{
|
|
|
|
Notification notif = new Notification(R.drawable.ic_menu_refresh,
|
|
|
|
context.getString(R.string.notification_bg_sync_ticker, account.getDescription(), folder.getName()),
|
|
|
|
System.currentTimeMillis());
|
2010-01-27 19:29:27 -05:00
|
|
|
Intent intent = MessageList.actionHandleFolderIntent(context, account, K9.INBOX);
|
2009-11-24 19:40:29 -05:00
|
|
|
PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0);
|
|
|
|
notif.setLatestEventInfo(context, context.getString(R.string.notification_bg_sync_title), account.getDescription()
|
|
|
|
+ context.getString(R.string.notification_bg_title_separator) + folder.getName(), pi);
|
|
|
|
notif.flags = Notification.FLAG_ONGOING_EVENT;
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.NOTIFICATION_LED_WHILE_SYNCING)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
notif.flags |= Notification.FLAG_SHOW_LIGHTS;
|
2010-05-15 16:35:59 -04:00
|
|
|
notif.ledARGB = account.getLedColor();
|
2009-12-14 21:50:53 -05:00
|
|
|
notif.ledOnMS = K9.NOTIFICATION_LED_FAST_ON_TIME;
|
|
|
|
notif.ledOffMS = K9.NOTIFICATION_LED_FAST_OFF_TIME;
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
|
2010-05-11 23:06:11 -04:00
|
|
|
notifMgr.notify(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber(), notif);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
try
|
|
|
|
{
|
2010-05-15 15:35:07 -04:00
|
|
|
synchronizeMailboxSynchronous(account, folder.getName(), listener, null);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (account.isShowOngoing())
|
|
|
|
{
|
2010-05-11 23:06:11 -04:00
|
|
|
notifMgr.cancel(K9.FETCHING_EMAIL_NOTIFICATION - account.getAccountNumber());
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Exception while processing folder " +
|
2009-11-24 19:40:29 -05:00
|
|
|
account.getDescription() + ":" + folder.getName(), e);
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2010-01-16 11:22:20 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (tLocalFolder != null)
|
|
|
|
{
|
|
|
|
tLocalFolder.close();
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (MessagingException e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to synchronize account " + account.getName(), e);
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2008-12-19 17:30:55 -05:00
|
|
|
}
|
2010-03-29 22:58:21 -04:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
putBackground("clear notification flag for " + account.getDescription(), null, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
if (K9.DEBUG)
|
2010-04-29 00:59:14 -04:00
|
|
|
Log.v(K9.LOG_TAG, "Clearing notification flag for " + account.getDescription());
|
2010-03-29 22:58:21 -04:00
|
|
|
account.setRingNotified(false);
|
2010-05-15 15:35:07 -04:00
|
|
|
try
|
|
|
|
{
|
2010-08-08 15:14:47 -04:00
|
|
|
if (account.getStats(context).unreadMessageCount == 0)
|
2010-05-15 15:35:07 -04:00
|
|
|
{
|
|
|
|
notifyAccountCancel(context, account);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (MessagingException e)
|
|
|
|
{
|
|
|
|
Log.e(K9.LOG_TAG, "Unable to getUnreadMessageCount for account: " + account, e);
|
|
|
|
}
|
2010-03-29 22:58:21 -04:00
|
|
|
}
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
);
|
2010-03-29 22:58:21 -04:00
|
|
|
}
|
|
|
|
|
2010-01-17 19:11:02 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to synchronize mail", e);
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
putBackground("finalize sync", null, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Finished mail sync");
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (wakeLock != null)
|
|
|
|
{
|
|
|
|
wakeLock.release();
|
2009-11-17 22:06:23 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.checkMailFinished(context, account);
|
2009-11-17 22:06:23 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-02-09 22:18:42 -05:00
|
|
|
public void compact(final Account account, final MessagingListener ml)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
putBackground("compact:" + account.getDescription(), ml, new Runnable()
|
2009-02-09 22:18:42 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
public void run()
|
2009-02-09 22:18:42 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
2009-11-24 19:40:29 -05:00
|
|
|
long oldSize = localStore.getSize();
|
|
|
|
localStore.compact();
|
|
|
|
long newSize = localStore.getSize();
|
|
|
|
if (ml != null)
|
|
|
|
{
|
|
|
|
ml.accountSizeChanged(account, oldSize, newSize);
|
|
|
|
}
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.accountSizeChanged(account, oldSize, newSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Failed to compact account " + account.getDescription(), e);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2009-02-09 22:18:42 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
});
|
2009-02-09 22:18:42 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-02-09 22:18:42 -05:00
|
|
|
public void clear(final Account account, final MessagingListener ml)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
putBackground("clear:" + account.getDescription(), ml, new Runnable()
|
2009-02-09 22:18:42 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
public void run()
|
2009-02-09 22:18:42 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
2009-11-24 19:40:29 -05:00
|
|
|
long oldSize = localStore.getSize();
|
|
|
|
localStore.clear();
|
|
|
|
localStore.resetVisibleLimits(account.getDisplayCount());
|
|
|
|
long newSize = localStore.getSize();
|
2010-05-02 01:37:48 -04:00
|
|
|
AccountStats stats = new AccountStats();
|
|
|
|
stats.size = newSize;
|
|
|
|
stats.unreadMessageCount = 0;
|
|
|
|
stats.flaggedMessageCount = 0;
|
2009-11-24 19:40:29 -05:00
|
|
|
if (ml != null)
|
|
|
|
{
|
|
|
|
ml.accountSizeChanged(account, oldSize, newSize);
|
2010-05-02 01:37:48 -04:00
|
|
|
ml.accountStatusChanged(account, stats);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.accountSizeChanged(account, oldSize, newSize);
|
2010-05-02 01:37:48 -04:00
|
|
|
l.accountStatusChanged(account, stats);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-05-12 00:17:52 -04:00
|
|
|
Log.e(K9.LOG_TAG, "Failed to clear account " + account.getDescription(), e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2010-05-15 15:46:16 -04:00
|
|
|
|
2010-05-12 00:17:52 -04:00
|
|
|
public void recreate(final Account account, final MessagingListener ml)
|
|
|
|
{
|
|
|
|
putBackground("recreate:" + account.getDescription(), ml, new Runnable()
|
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
LocalStore localStore = account.getLocalStore();
|
|
|
|
long oldSize = localStore.getSize();
|
|
|
|
localStore.recreate();
|
|
|
|
localStore.resetVisibleLimits(account.getDisplayCount());
|
|
|
|
long newSize = localStore.getSize();
|
|
|
|
AccountStats stats = new AccountStats();
|
|
|
|
stats.size = newSize;
|
|
|
|
stats.unreadMessageCount = 0;
|
|
|
|
stats.flaggedMessageCount = 0;
|
|
|
|
if (ml != null)
|
|
|
|
{
|
|
|
|
ml.accountSizeChanged(account, oldSize, newSize);
|
|
|
|
ml.accountStatusChanged(account, stats);
|
|
|
|
}
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
|
|
|
l.accountSizeChanged(account, oldSize, newSize);
|
|
|
|
l.accountStatusChanged(account, stats);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
Log.e(K9.LOG_TAG, "Failed to recreate account " + account.getDescription(), e);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2009-02-09 22:18:42 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
});
|
2009-02-09 22:18:42 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-08-08 14:50:31 -04:00
|
|
|
|
|
|
|
private boolean shouldNotifyForMessage(Account account, Message message)
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2010-03-29 22:58:21 -04:00
|
|
|
// Do not notify if the user does not have notifications
|
|
|
|
// enabled or if the message has been read
|
2010-08-01 21:27:40 -04:00
|
|
|
if (!account.isNotifyNewMail() || message.isSet(Flag.SEEN) || (account.getName() == null))
|
2010-03-29 22:58:21 -04:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2010-05-15 15:46:16 -04:00
|
|
|
|
2010-07-14 23:42:13 -04:00
|
|
|
|
2010-05-12 00:17:52 -04:00
|
|
|
Folder folder = message.getFolder();
|
|
|
|
if (folder != null)
|
|
|
|
{
|
2010-06-17 08:42:22 -04:00
|
|
|
// No notification for new messages in Trash, Drafts, or Sent folder.
|
|
|
|
// But do notify if it's the INBOX (see issue 1817).
|
2010-05-12 00:17:52 -04:00
|
|
|
String folderName = folder.getName();
|
2010-06-17 08:42:22 -04:00
|
|
|
if (!K9.INBOX.equals(folderName) &&
|
|
|
|
(account.getTrashFolderName().equals(folderName)
|
2010-07-06 06:29:26 -04:00
|
|
|
|| account.getDraftsFolderName().equals(folderName)
|
|
|
|
|| account.getSentFolderName().equals(folderName)))
|
2010-05-12 00:17:52 -04:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2010-01-21 13:49:11 -05:00
|
|
|
|
2010-08-08 14:50:31 -04:00
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Creates a notification of new email messages
|
|
|
|
* ringtone, lights, and vibration to be played
|
|
|
|
*/
|
|
|
|
private boolean notifyAccount(Context context, Account account, Message message, int previousUnreadMessageCount, AtomicInteger newMessageCount)
|
|
|
|
{
|
2010-01-21 13:49:11 -05:00
|
|
|
// If we have a message, set the notification to "<From>: <Subject>"
|
|
|
|
StringBuffer messageNotice = new StringBuffer();
|
2009-11-29 11:55:35 -05:00
|
|
|
try
|
|
|
|
{
|
2010-01-21 13:49:11 -05:00
|
|
|
if (message != null && message.getFrom() != null)
|
|
|
|
{
|
2010-03-29 22:58:21 -04:00
|
|
|
Address[] fromAddrs = message.getFrom();
|
2010-08-30 10:37:34 -04:00
|
|
|
String from = fromAddrs.length > 0 ? fromAddrs[0].toFriendly().toString() : null;
|
2010-01-21 13:49:11 -05:00
|
|
|
String subject = message.getSubject();
|
|
|
|
if (subject == null)
|
|
|
|
{
|
|
|
|
subject = context.getString(R.string.general_no_subject);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (from != null)
|
|
|
|
{
|
2010-03-29 22:58:21 -04:00
|
|
|
// Show From: address by default
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!account.isAnIdentity(fromAddrs))
|
2010-01-21 13:49:11 -05:00
|
|
|
{
|
|
|
|
messageNotice.append(from + ": " + subject);
|
|
|
|
}
|
2010-03-29 22:58:21 -04:00
|
|
|
// show To: if the message was sent from me
|
2010-01-21 13:49:11 -05:00
|
|
|
else
|
|
|
|
{
|
2010-03-29 22:58:21 -04:00
|
|
|
if (!account.isNotifySelfNewMail())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-01-21 13:49:11 -05:00
|
|
|
Address[] rcpts = message.getRecipients(Message.RecipientType.TO);
|
2010-08-30 10:37:34 -04:00
|
|
|
String to = rcpts.length > 0 ? rcpts[0].toFriendly().toString() : null;
|
2010-01-21 13:49:11 -05:00
|
|
|
if (to != null)
|
|
|
|
{
|
2010-01-27 19:29:12 -05:00
|
|
|
messageNotice.append(String.format(context.getString(R.string.message_list_to_fmt), to) +": "+subject);
|
2010-01-21 13:49:11 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
messageNotice.append(context.getString(R.string.general_no_sender) + ": "+subject);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-11-29 11:55:35 -05:00
|
|
|
}
|
2010-01-21 13:49:11 -05:00
|
|
|
catch (MessagingException e)
|
2009-11-29 11:55:35 -05:00
|
|
|
{
|
2010-01-21 13:49:11 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to get message information for notification.", e);
|
2009-11-29 11:55:35 -05:00
|
|
|
}
|
2010-07-14 23:42:13 -04:00
|
|
|
|
|
|
|
|
2010-01-21 13:49:11 -05:00
|
|
|
// If we could not set a per-message notification, revert to a default message
|
|
|
|
if (messageNotice.length() == 0)
|
2009-11-14 09:25:09 -05:00
|
|
|
{
|
2010-01-21 13:49:11 -05:00
|
|
|
messageNotice.append(context.getString(R.string.notification_new_title));
|
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2010-01-21 13:49:11 -05:00
|
|
|
NotificationManager notifMgr =
|
|
|
|
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
|
|
Notification notif = new Notification(R.drawable.stat_notify_email_generic, messageNotice, System.currentTimeMillis());
|
2010-08-08 14:50:31 -04:00
|
|
|
notif.number = previousUnreadMessageCount + newMessageCount.get();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-05-12 01:35:08 -04:00
|
|
|
Intent i = FolderList.actionHandleNotification(context, account, account.getAutoExpandFolderName());
|
2010-01-21 13:49:11 -05:00
|
|
|
PendingIntent pi = PendingIntent.getActivity(context, 0, i, 0);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-08-08 15:35:18 -04:00
|
|
|
String accountNotice = context.getString(R.string.notification_new_one_account_fmt, notif.number, account.getDescription());
|
2010-01-21 13:49:11 -05:00
|
|
|
notif.setLatestEventInfo(context, accountNotice, messageNotice, pi);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-03-29 22:58:21 -04:00
|
|
|
// Only ring or vibrate if we have not done so already on this
|
|
|
|
// account and fetch
|
|
|
|
if (!account.isRingNotified())
|
2010-01-21 13:49:11 -05:00
|
|
|
{
|
2010-03-29 22:58:21 -04:00
|
|
|
account.setRingNotified(true);
|
2010-07-14 23:42:01 -04:00
|
|
|
if (account.shouldRing())
|
2010-03-29 22:58:21 -04:00
|
|
|
{
|
|
|
|
String ringtone = account.getRingtone();
|
|
|
|
notif.sound = TextUtils.isEmpty(ringtone) ? null : Uri.parse(ringtone);
|
|
|
|
}
|
|
|
|
if (account.isVibrate())
|
|
|
|
{
|
2010-08-28 10:00:34 -04:00
|
|
|
long[] pattern = getVibratePattern(account.getVibratePattern(), account.getVibrateTimes());
|
|
|
|
notif.vibrate = pattern;
|
2010-03-29 22:58:21 -04:00
|
|
|
}
|
2010-01-21 13:49:11 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-03-29 22:58:21 -04:00
|
|
|
notif.flags |= Notification.FLAG_SHOW_LIGHTS;
|
2010-05-15 16:35:59 -04:00
|
|
|
notif.ledARGB = account.getLedColor();
|
2010-01-21 13:49:11 -05:00
|
|
|
notif.ledOnMS = K9.NOTIFICATION_LED_ON_TIME;
|
|
|
|
notif.ledOffMS = K9.NOTIFICATION_LED_OFF_TIME;
|
2010-05-11 00:13:23 -04:00
|
|
|
notif.audioStreamType = AudioManager.STREAM_NOTIFICATION;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-01-21 13:49:11 -05:00
|
|
|
notifMgr.notify(account.getAccountNumber(), notif);
|
2010-03-29 22:58:21 -04:00
|
|
|
return true;
|
2010-01-21 13:49:11 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-08-28 10:00:34 -04:00
|
|
|
/*
|
|
|
|
* Fetch a vibration pattern.
|
|
|
|
*
|
|
|
|
* @param vibratePattern Vibration pattern index to use.
|
|
|
|
* @param vibrateTimes Number of times to do the vibration pattern.
|
|
|
|
* @return Pattern multiplied by the number of times requested.
|
|
|
|
*/
|
|
|
|
public static long[] getVibratePattern(int vibratePattern, int vibrateTimes)
|
|
|
|
{
|
|
|
|
// These are "off, on" patterns, specified in milliseconds
|
|
|
|
long[] pattern0 = new long[] {300,200}; // like the default pattern
|
|
|
|
long[] pattern1 = new long[] {100,200};
|
|
|
|
long[] pattern2 = new long[] {100,500};
|
|
|
|
long[] pattern3 = new long[] {200,200};
|
|
|
|
long[] pattern4 = new long[] {200,500};
|
|
|
|
long[] pattern5 = new long[] {500,500};
|
|
|
|
|
|
|
|
long[] selectedPattern = pattern0; //default pattern
|
|
|
|
|
|
|
|
switch (vibratePattern)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
selectedPattern = pattern1;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
selectedPattern = pattern2;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
selectedPattern = pattern3;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
selectedPattern = pattern4;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
selectedPattern = pattern5;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
long[] repeatedPattern = new long[selectedPattern.length * vibrateTimes];
|
|
|
|
for (int n = 0; n < vibrateTimes; n++)
|
|
|
|
{
|
|
|
|
System.arraycopy(selectedPattern, 0, repeatedPattern, n * selectedPattern.length, selectedPattern.length);
|
|
|
|
}
|
|
|
|
// Do not wait before starting the vibration pattern.
|
|
|
|
repeatedPattern[0] = 0;
|
|
|
|
return repeatedPattern;
|
|
|
|
}
|
|
|
|
|
2010-01-21 13:49:11 -05:00
|
|
|
/** Cancel a notification of new email messages */
|
2010-03-13 00:00:01 -05:00
|
|
|
public void notifyAccountCancel(Context context, Account account)
|
2010-01-21 13:49:11 -05:00
|
|
|
{
|
|
|
|
NotificationManager notifMgr =
|
|
|
|
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
|
|
notifMgr.cancel(account.getAccountNumber());
|
2010-05-16 20:30:32 -04:00
|
|
|
notifMgr.cancel(-1000 - account.getAccountNumber());
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
public Message saveDraft(final Account account, final Message message)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Message localMessage = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
|
|
|
LocalFolder localFolder = localStore.getFolder(account.getDraftsFolderName());
|
2008-11-01 17:32:06 -04:00
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
2009-11-24 19:40:29 -05:00
|
|
|
localFolder.appendMessages(new Message[]
|
2009-11-26 00:10:12 -05:00
|
|
|
{
|
|
|
|
message
|
|
|
|
});
|
2010-03-03 23:00:30 -05:00
|
|
|
localMessage = localFolder.getMessage(message.getUid());
|
2008-11-01 17:32:06 -04:00
|
|
|
localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
|
|
|
|
|
|
|
PendingCommand command = new PendingCommand();
|
|
|
|
command.command = PENDING_COMMAND_APPEND;
|
2009-11-24 19:40:29 -05:00
|
|
|
command.arguments = new String[]
|
|
|
|
{
|
|
|
|
localFolder.getName(),
|
|
|
|
localMessage.getUid()
|
|
|
|
};
|
2008-11-01 17:32:06 -04:00
|
|
|
queuePendingCommand(account, command);
|
|
|
|
processPendingCommands(account);
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (MessagingException e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to save message as draft.", e);
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-03-03 23:00:30 -05:00
|
|
|
return localMessage;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
public boolean modeMismatch(Account.FolderMode aMode, Folder.FolderClass fMode)
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
|
|
|
if (aMode == Account.FolderMode.NONE
|
2009-11-24 19:40:29 -05:00
|
|
|
|| (aMode == Account.FolderMode.FIRST_CLASS &&
|
|
|
|
fMode != Folder.FolderClass.FIRST_CLASS)
|
2009-10-21 20:41:06 -04:00
|
|
|
|| (aMode == Account.FolderMode.FIRST_AND_SECOND_CLASS &&
|
2009-11-24 19:40:29 -05:00
|
|
|
fMode != Folder.FolderClass.FIRST_CLASS &&
|
|
|
|
fMode != Folder.FolderClass.SECOND_CLASS)
|
|
|
|
|| (aMode == Account.FolderMode.NOT_SECOND_CLASS &&
|
|
|
|
fMode == Folder.FolderClass.SECOND_CLASS))
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
static AtomicInteger sequencing = new AtomicInteger(0);
|
2010-04-16 08:20:10 -04:00
|
|
|
class Command implements Comparable<Command>
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
public Runnable runnable;
|
|
|
|
|
|
|
|
public MessagingListener listener;
|
|
|
|
|
|
|
|
public String description;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
boolean isForeground;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
int sequence = sequencing.getAndIncrement();
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
|
|
|
public int compareTo(Command other)
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2010-08-29 19:39:26 -04:00
|
|
|
if (other.isForeground && !isForeground)
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2010-04-16 08:20:10 -04:00
|
|
|
return 1;
|
|
|
|
}
|
2010-08-29 19:39:26 -04:00
|
|
|
else if (!other.isForeground && isForeground)
|
2010-04-16 08:20:10 -04:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return (sequence - other.sequence);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-01-11 18:43:32 -05:00
|
|
|
|
|
|
|
public MessagingListener getCheckMailListener()
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
return checkMailListener;
|
2009-01-11 18:43:32 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setCheckMailListener(MessagingListener checkMailListener)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
if (this.checkMailListener != null)
|
|
|
|
{
|
|
|
|
removeListener(this.checkMailListener);
|
|
|
|
}
|
|
|
|
this.checkMailListener = checkMailListener;
|
|
|
|
if (this.checkMailListener != null)
|
|
|
|
{
|
|
|
|
addListener(this.checkMailListener);
|
|
|
|
}
|
2009-01-11 18:43:32 -05:00
|
|
|
}
|
2009-01-31 19:08:14 -05:00
|
|
|
|
2009-02-07 14:41:33 -05:00
|
|
|
public SORT_TYPE getSortType()
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
return sortType;
|
2009-02-07 14:41:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public void setSortType(SORT_TYPE sortType)
|
2009-01-31 19:08:14 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
this.sortType = sortType;
|
2009-02-07 14:41:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isSortAscending(SORT_TYPE sortType)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
Boolean sortAsc = sortAscending.get(sortType);
|
|
|
|
if (sortAsc == null)
|
|
|
|
{
|
|
|
|
return sortType.isDefaultAscending();
|
|
|
|
}
|
|
|
|
else return sortAsc;
|
2009-01-31 19:08:14 -05:00
|
|
|
}
|
|
|
|
|
2009-02-07 14:41:33 -05:00
|
|
|
public void setSortAscending(SORT_TYPE sortType, boolean nsortAscending)
|
2009-01-31 19:08:14 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
sortAscending.put(sortType, nsortAscending);
|
2009-01-31 19:08:14 -05:00
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
public Collection<Pusher> getPushers()
|
|
|
|
{
|
|
|
|
return pushers.values();
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-11-28 09:51:44 -05:00
|
|
|
public boolean setupPushing(final Account account)
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2009-11-28 09:51:44 -05:00
|
|
|
Pusher previousPusher = pushers.remove(account);
|
|
|
|
if (previousPusher != null)
|
2009-11-22 12:01:04 -05:00
|
|
|
{
|
2009-11-28 09:51:44 -05:00
|
|
|
previousPusher.stop();
|
2009-11-22 12:01:04 -05:00
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
Preferences prefs = Preferences.getPreferences(mApplication);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
Account.FolderMode aDisplayMode = account.getFolderDisplayMode();
|
|
|
|
Account.FolderMode aPushMode = account.getFolderPushMode();
|
|
|
|
|
|
|
|
List<String> names = new ArrayList<String>();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Store localStore = account.getLocalStore();
|
2010-05-30 12:56:50 -04:00
|
|
|
for (final Folder folder : localStore.getPersonalNamespaces(false))
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2010-02-06 00:35:15 -05:00
|
|
|
if (folder.getName().equals(account.getErrorFolderName())
|
|
|
|
|| folder.getName().equals(account.getOutboxFolderName()))
|
|
|
|
{
|
2010-02-08 22:03:40 -05:00
|
|
|
if (K9.DEBUG && false)
|
2010-02-06 00:35:15 -05:00
|
|
|
Log.v(K9.LOG_TAG, "Not pushing folder " + folder.getName() +
|
|
|
|
" which should never be pushed");
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
folder.open(Folder.OpenMode.READ_WRITE);
|
|
|
|
folder.refresh(prefs);
|
|
|
|
|
|
|
|
Folder.FolderClass fDisplayClass = folder.getDisplayClass();
|
|
|
|
Folder.FolderClass fPushClass = folder.getPushClass();
|
|
|
|
|
|
|
|
if (modeMismatch(aDisplayMode, fDisplayClass))
|
|
|
|
{
|
|
|
|
// Never push a folder that isn't displayed
|
2010-02-08 22:03:40 -05:00
|
|
|
if (K9.DEBUG && false)
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.v(K9.LOG_TAG, "Not pushing folder " + folder.getName() +
|
2009-11-24 19:40:29 -05:00
|
|
|
" which is in display class " + fDisplayClass + " while account is in display mode " + aDisplayMode);
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (modeMismatch(aPushMode, fPushClass))
|
|
|
|
{
|
|
|
|
// Do not push folders in the wrong class
|
2010-02-08 22:03:40 -05:00
|
|
|
if (K9.DEBUG && false)
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.v(K9.LOG_TAG, "Not pushing folder " + folder.getName() +
|
2009-11-24 19:40:29 -05:00
|
|
|
" which is in push mode " + fPushClass + " while account is in push mode " + aPushMode);
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Starting pusher for " + account.getDescription() + ":" + folder.getName());
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
names.add(folder.getName());
|
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
if (names.size() > 0)
|
|
|
|
{
|
2009-11-28 09:51:44 -05:00
|
|
|
PushReceiver receiver = new MessagingControllerPushReceiver(mApplication, account, this);
|
2009-12-24 13:08:23 -05:00
|
|
|
int maxPushFolders = account.getMaxPushFolders();
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2009-12-24 13:08:23 -05:00
|
|
|
if (names.size() > maxPushFolders)
|
|
|
|
{
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Count of folders to push for account " + account.getDescription() + " is " + names.size()
|
|
|
|
+ ", greater than limit of " + maxPushFolders + ", truncating");
|
|
|
|
|
2009-12-24 13:08:23 -05:00
|
|
|
names = names.subList(0, maxPushFolders);
|
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-28 09:51:44 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Store store = account.getRemoteStore();
|
2010-08-29 19:39:26 -04:00
|
|
|
if (!store.isPushCapable())
|
2009-11-28 09:51:44 -05:00
|
|
|
{
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Account " + account.getDescription() + " is not push capable, skipping");
|
|
|
|
|
2009-11-28 09:51:44 -05:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Pusher pusher = store.getPusher(receiver);
|
|
|
|
if (pusher != null)
|
|
|
|
{
|
2010-05-06 09:27:42 -04:00
|
|
|
Pusher oldPusher = pushers.putIfAbsent(account, pusher);
|
|
|
|
if (oldPusher == null)
|
|
|
|
{
|
|
|
|
pusher.start(names);
|
|
|
|
}
|
|
|
|
}
|
2009-11-28 09:51:44 -05:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Could not get remote store", e);
|
2009-11-28 09:51:44 -05:00
|
|
|
return false;
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-12-06 19:56:06 -05:00
|
|
|
|
2009-11-28 09:51:44 -05:00
|
|
|
return true;
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "No folders are configured for pushing in account " + account.getDescription());
|
2009-11-28 09:51:44 -05:00
|
|
|
return false;
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Got exception while setting up pushing", e);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-28 09:51:44 -05:00
|
|
|
return false;
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
public void stopAllPushing()
|
|
|
|
{
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Stopping all pushers");
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
Iterator<Pusher> iter = pushers.values().iterator();
|
|
|
|
while (iter.hasNext())
|
|
|
|
{
|
|
|
|
Pusher pusher = iter.next();
|
|
|
|
iter.remove();
|
|
|
|
pusher.stop();
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-11-26 00:10:12 -05:00
|
|
|
public void messagesArrived(final Account account, final Folder remoteFolder, final List<Message> messages, final boolean flagSyncOnly)
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Got new pushed email messages for account " + account.getDescription()
|
|
|
|
+ ", folder " + remoteFolder.getName());
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
final CountDownLatch latch = new CountDownLatch(1);
|
2009-11-24 19:40:29 -05:00
|
|
|
putBackground("Push messageArrived of account " + account.getDescription()
|
2009-11-26 00:10:12 -05:00
|
|
|
+ ", folder " + remoteFolder.getName(), null, new Runnable()
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
LocalFolder localFolder = null;
|
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
LocalStore localStore = account.getLocalStore();
|
|
|
|
localFolder= localStore.getFolder(remoteFolder.getName());
|
2009-10-21 20:41:06 -04:00
|
|
|
localFolder.open(OpenMode.READ_WRITE);
|
|
|
|
|
2010-03-29 22:58:21 -04:00
|
|
|
account.setRingNotified(false);
|
2009-11-26 00:10:12 -05:00
|
|
|
int newCount = downloadMessages(account, remoteFolder, localFolder, messages, flagSyncOnly);
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
int unreadMessageCount = setLocalUnreadCountToRemote(localFolder, remoteFolder, messages.size());
|
2009-11-26 00:10:12 -05:00
|
|
|
|
2010-04-16 10:33:54 -04:00
|
|
|
setLocalFlaggedCountToRemote(localFolder, remoteFolder);
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
localFolder.setLastPush(System.currentTimeMillis());
|
|
|
|
localFolder.setStatus(null);
|
|
|
|
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
2010-01-21 13:49:11 -05:00
|
|
|
Log.i(K9.LOG_TAG, "messagesArrived newCount = " + newCount + ", unread count = " + unreadMessageCount);
|
2010-01-02 20:50:41 -05:00
|
|
|
|
2010-01-21 13:49:11 -05:00
|
|
|
if (unreadMessageCount == 0)
|
|
|
|
{
|
|
|
|
notifyAccountCancel(mApplication, account);
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
l.folderStatusChanged(account, remoteFolder.getName(), unreadMessageCount);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
String rootMessage = getRootCauseMessage(e);
|
|
|
|
String errorMessage = "Push failed: " + rootMessage;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
localFolder.setStatus(errorMessage);
|
|
|
|
}
|
|
|
|
catch (Exception se)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to set failed status on localFolder", se);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
for (MessagingListener l : getListeners())
|
|
|
|
{
|
2009-11-26 00:10:12 -05:00
|
|
|
l.synchronizeMailboxFailed(account, remoteFolder.getName(), errorMessage);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-04-14 23:17:25 -04:00
|
|
|
addErrorMessage(account, null, e);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (localFolder != null)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
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.
2009-12-20 18:13:49 -05:00
|
|
|
localFolder.close();
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to close localFolder", e);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
latch.countDown();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
try
|
|
|
|
{
|
|
|
|
latch.await();
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Interrupted while awaiting latch release", e);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-01-02 20:50:41 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "MessagingController.messagesArrivedLatch released");
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
enum MemorizingState { STARTED, FINISHED, FAILED };
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
class Memory
|
|
|
|
{
|
|
|
|
Account account;
|
|
|
|
String folderName;
|
|
|
|
MemorizingState syncingState = null;
|
|
|
|
MemorizingState sendingState = null;
|
|
|
|
MemorizingState pushingState = null;
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
MemorizingState processingState = null;
|
2009-10-21 20:41:06 -04:00
|
|
|
String failureMessage = null;
|
|
|
|
|
|
|
|
int syncingTotalMessagesInMailbox;
|
|
|
|
int syncingNumNewMessages;
|
2009-12-20 00:41:43 -05:00
|
|
|
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
int folderCompleted = 0;
|
|
|
|
int folderTotal = 0;
|
|
|
|
String processingCommandTitle = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
Memory(Account nAccount, String nFolderName)
|
|
|
|
{
|
|
|
|
account = nAccount;
|
|
|
|
folderName = nFolderName;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
String getKey()
|
|
|
|
{
|
|
|
|
return getMemoryKey(account, folderName);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
static String getMemoryKey(Account taccount, String tfolderName)
|
|
|
|
{
|
|
|
|
return taccount.getDescription() + ":" + tfolderName;
|
|
|
|
}
|
|
|
|
class MemorizingListener extends MessagingListener
|
|
|
|
{
|
|
|
|
HashMap<String, Memory> memories = new HashMap<String, Memory>(31);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
Memory getMemory(Account account, String folderName)
|
|
|
|
{
|
|
|
|
Memory memory = memories.get(getMemoryKey(account, folderName));
|
|
|
|
if (memory == null)
|
|
|
|
{
|
|
|
|
memory = new Memory(account, folderName);
|
|
|
|
memories.put(memory.getKey(), memory);
|
|
|
|
}
|
|
|
|
return memory;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public synchronized void synchronizeMailboxStarted(Account account, String folder)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
Memory memory = getMemory(account, folder);
|
|
|
|
memory.syncingState = MemorizingState.STARTED;
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
memory.folderCompleted = 0;
|
|
|
|
memory.folderTotal = 0;
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-10-21 20:41:06 -04:00
|
|
|
public synchronized void synchronizeMailboxFinished(Account account, String folder,
|
2009-11-24 19:40:29 -05:00
|
|
|
int totalMessagesInMailbox, int numNewMessages)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
Memory memory = getMemory(account, folder);
|
2009-11-24 19:40:29 -05:00
|
|
|
memory.syncingState = MemorizingState.FINISHED;
|
2009-10-21 20:41:06 -04:00
|
|
|
memory.syncingTotalMessagesInMailbox = totalMessagesInMailbox;
|
|
|
|
memory.syncingNumNewMessages = numNewMessages;
|
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-10-21 20:41:06 -04:00
|
|
|
public synchronized void synchronizeMailboxFailed(Account account, String folder,
|
2009-11-24 19:40:29 -05:00
|
|
|
String message)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
|
|
|
|
Memory memory = getMemory(account, folder);
|
|
|
|
memory.syncingState = MemorizingState.FAILED;
|
|
|
|
memory.failureMessage = message;
|
|
|
|
}
|
|
|
|
synchronized void refreshOther(MessagingListener other)
|
|
|
|
{
|
|
|
|
if (other != null)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
Memory syncStarted = null;
|
|
|
|
Memory sendStarted = null;
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
Memory processingStarted = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
for (Memory memory : memories.values())
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
if (memory.syncingState != null)
|
|
|
|
{
|
|
|
|
switch (memory.syncingState)
|
|
|
|
{
|
|
|
|
case STARTED:
|
|
|
|
syncStarted = memory;
|
|
|
|
break;
|
|
|
|
case FINISHED:
|
2009-11-24 19:40:29 -05:00
|
|
|
other.synchronizeMailboxFinished(memory.account, memory.folderName,
|
|
|
|
memory.syncingTotalMessagesInMailbox, memory.syncingNumNewMessages);
|
2009-10-21 20:41:06 -04:00
|
|
|
break;
|
|
|
|
case FAILED:
|
|
|
|
other.synchronizeMailboxFailed(memory.account, memory.folderName,
|
2009-11-24 19:40:29 -05:00
|
|
|
memory.failureMessage);
|
2009-10-21 20:41:06 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
if (memory.sendingState != null)
|
|
|
|
{
|
|
|
|
switch (memory.sendingState)
|
|
|
|
{
|
|
|
|
case STARTED:
|
|
|
|
sendStarted = memory;
|
|
|
|
break;
|
|
|
|
case FINISHED:
|
|
|
|
other.sendPendingMessagesCompleted(memory.account);
|
|
|
|
break;
|
|
|
|
case FAILED:
|
|
|
|
other.sendPendingMessagesFailed(memory.account);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (memory.pushingState != null)
|
|
|
|
{
|
|
|
|
switch (memory.pushingState)
|
|
|
|
{
|
|
|
|
case STARTED:
|
|
|
|
other.setPushActive(memory.account, memory.folderName, true);
|
|
|
|
break;
|
|
|
|
case FINISHED:
|
|
|
|
other.setPushActive(memory.account, memory.folderName, false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
if (memory.processingState != null)
|
|
|
|
{
|
|
|
|
switch (memory.processingState)
|
|
|
|
{
|
|
|
|
case STARTED:
|
|
|
|
processingStarted = memory;
|
|
|
|
break;
|
|
|
|
case FINISHED:
|
|
|
|
case FAILED:
|
|
|
|
other.pendingCommandsFinished(memory.account);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
Memory somethingStarted = null;
|
2009-10-21 20:41:06 -04:00
|
|
|
if (syncStarted != null)
|
|
|
|
{
|
|
|
|
other.synchronizeMailboxStarted(syncStarted.account, syncStarted.folderName);
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
somethingStarted = syncStarted;
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
if (sendStarted != null)
|
|
|
|
{
|
|
|
|
other.sendPendingMessagesStarted(sendStarted.account);
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
somethingStarted = sendStarted;
|
|
|
|
}
|
|
|
|
if (processingStarted != null)
|
|
|
|
{
|
|
|
|
other.pendingCommandsProcessing(processingStarted.account);
|
|
|
|
if (processingStarted.processingCommandTitle != null)
|
|
|
|
{
|
|
|
|
other.pendingCommandStarted(processingStarted.account, processingStarted.processingCommandTitle);
|
2009-12-20 00:41:43 -05:00
|
|
|
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
other.pendingCommandCompleted(processingStarted.account, processingStarted.processingCommandTitle);
|
|
|
|
}
|
|
|
|
somethingStarted = processingStarted;
|
|
|
|
}
|
|
|
|
if (somethingStarted != null && somethingStarted.folderTotal > 0)
|
|
|
|
{
|
|
|
|
other.synchronizeMailboxProgress(somethingStarted.account, somethingStarted.folderName, somethingStarted.folderCompleted, somethingStarted.folderTotal);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public synchronized void setPushActive(Account account, String folderName, boolean active)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
Memory memory = getMemory(account, folderName);
|
|
|
|
memory.pushingState = (active ? MemorizingState.STARTED : MemorizingState.FINISHED);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public synchronized void sendPendingMessagesStarted(Account account)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
Memory memory = getMemory(account, null);
|
|
|
|
memory.sendingState = MemorizingState.STARTED;
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
memory.folderCompleted = 0;
|
|
|
|
memory.folderTotal = 0;
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public synchronized void sendPendingMessagesCompleted(Account account)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
Memory memory = getMemory(account, null);
|
|
|
|
memory.sendingState = MemorizingState.FINISHED;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public synchronized void sendPendingMessagesFailed(Account account)
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
Memory memory = getMemory(account, null);
|
|
|
|
memory.sendingState = MemorizingState.FAILED;
|
|
|
|
}
|
2009-12-20 00:41:43 -05:00
|
|
|
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2010-01-08 11:55:36 -05:00
|
|
|
public synchronized void synchronizeMailboxProgress(Account account, String folderName, int completed, int total)
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
{
|
|
|
|
Memory memory = getMemory(account, folderName);
|
|
|
|
memory.folderCompleted = completed;
|
|
|
|
memory.folderTotal = total;
|
|
|
|
}
|
|
|
|
|
2009-12-20 00:41:43 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2010-01-08 11:55:36 -05:00
|
|
|
public synchronized void pendingCommandsProcessing(Account account)
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
{
|
|
|
|
Memory memory = getMemory(account, null);
|
|
|
|
memory.processingState = MemorizingState.STARTED;
|
|
|
|
memory.folderCompleted = 0;
|
|
|
|
memory.folderTotal = 0;
|
|
|
|
}
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2010-01-08 11:55:36 -05:00
|
|
|
public synchronized void pendingCommandsFinished(Account account)
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
{
|
|
|
|
Memory memory = getMemory(account, null);
|
|
|
|
memory.processingState = MemorizingState.FINISHED;
|
|
|
|
}
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2010-01-08 11:55:36 -05:00
|
|
|
public synchronized void pendingCommandStarted(Account account, String commandTitle)
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
{
|
|
|
|
Memory memory = getMemory(account, null);
|
|
|
|
memory.processingCommandTitle = commandTitle;
|
|
|
|
}
|
2009-12-20 00:41:43 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2010-01-08 11:55:36 -05:00
|
|
|
public synchronized void pendingCommandCompleted(Account account, String commandTitle)
|
Enhanced header in Accounts, MessageList and Folder to show the unread
count, scoped for the Activity, the in-progress operation, the account
on which the operation is in progress, the folder for the operation,
when appropriate, and the progress of the operation, when it applies
to multiple items. For the MessageList, also use the determinate
progress bar to show progress for synchronization of the folder being
displayed.
Fixes Issue 924.
Also, a minor change that might help with Issue 913, by putting the
insertion of the pending command into a background thread.
2009-12-19 19:02:46 -05:00
|
|
|
{
|
|
|
|
Memory memory = getMemory(account, null);
|
|
|
|
memory.processingCommandTitle = null;
|
|
|
|
}
|
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-01-13 20:07:28 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
private void actOnMessages(Message[] messages, MessageActor actor)
|
2010-01-06 00:41:19 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Map<Account, Map<Folder, List<Message>>> accountMap = new HashMap<Account, Map<Folder, List<Message>>>();
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-01-06 00:41:19 -05:00
|
|
|
for (Message message : messages)
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Folder folder = message.getFolder();
|
|
|
|
Account account = folder.getAccount();
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
Map<Folder, List<Message>> folderMap = accountMap.get(account);
|
|
|
|
if (folderMap == null)
|
|
|
|
{
|
|
|
|
folderMap = new HashMap<Folder, List<Message>>();
|
|
|
|
accountMap.put(account, folderMap);
|
|
|
|
}
|
|
|
|
List<Message> messageList = folderMap.get(folder);
|
|
|
|
if (messageList == null)
|
2010-01-06 00:41:19 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
messageList = new LinkedList<Message>();
|
|
|
|
folderMap.put(folder, messageList);
|
2010-01-06 00:41:19 -05:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
messageList.add(message);
|
2010-01-06 00:41:19 -05:00
|
|
|
}
|
2010-03-03 23:00:30 -05:00
|
|
|
for (Map.Entry<Account, Map<Folder, List<Message>>> entry : accountMap.entrySet())
|
|
|
|
{
|
|
|
|
Account account = entry.getKey();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
//account.refresh(Preferences.getPreferences(K9.app));
|
|
|
|
Map<Folder, List<Message>> folderMap = entry.getValue();
|
|
|
|
for (Map.Entry<Folder, List<Message>> folderEntry : folderMap.entrySet())
|
|
|
|
{
|
|
|
|
Folder folder = folderEntry.getKey();
|
|
|
|
List<Message> messageList = folderEntry.getValue();
|
|
|
|
actor.act(account, folder, messageList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
|
|
|
interface MessageActor
|
2010-03-03 23:00:30 -05:00
|
|
|
{
|
|
|
|
public void act(final Account account, final Folder folder, final List<Message> messages);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|