2008-11-01 17:32:06 -04:00
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
package com.fsck.k9.mail.store;
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
import android.app.Application;
|
|
|
|
import android.content.ContentValues;
|
2009-12-09 22:16:42 -05:00
|
|
|
import android.content.SharedPreferences;
|
2008-11-01 17:32:06 -04:00
|
|
|
import android.database.Cursor;
|
|
|
|
import android.database.sqlite.SQLiteDatabase;
|
2010-01-24 15:41:04 -05:00
|
|
|
import android.database.sqlite.SQLiteException;
|
2008-11-01 17:32:06 -04:00
|
|
|
import android.net.Uri;
|
2009-12-09 22:16:42 -05:00
|
|
|
import android.util.Log;
|
2010-03-03 23:00:30 -05:00
|
|
|
import com.fsck.k9.Account;
|
2009-12-14 21:50:53 -05:00
|
|
|
import com.fsck.k9.K9;
|
|
|
|
import com.fsck.k9.Preferences;
|
2010-05-19 14:17:06 -04:00
|
|
|
import com.fsck.k9.controller.MessageRemovalListener;
|
|
|
|
import com.fsck.k9.controller.MessageRetrievalListener;
|
2010-05-19 15:16:36 -04:00
|
|
|
import com.fsck.k9.helper.Regex;
|
2010-05-19 14:17:06 -04:00
|
|
|
import com.fsck.k9.helper.Utility;
|
2009-12-14 21:50:53 -05:00
|
|
|
import com.fsck.k9.mail.*;
|
|
|
|
import com.fsck.k9.mail.Message.RecipientType;
|
2010-05-19 14:17:06 -04:00
|
|
|
import com.fsck.k9.mail.filter.Base64OutputStream;
|
2009-12-14 21:50:53 -05:00
|
|
|
import com.fsck.k9.mail.internet.*;
|
|
|
|
import com.fsck.k9.provider.AttachmentProvider;
|
2009-12-09 22:16:42 -05:00
|
|
|
import org.apache.commons.io.IOUtils;
|
|
|
|
|
|
|
|
import java.io.*;
|
|
|
|
import java.net.URI;
|
|
|
|
import java.net.URLEncoder;
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.regex.Matcher;
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* <pre>
|
|
|
|
* Implements a SQLite database backed local store for Messages.
|
|
|
|
* </pre>
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public class LocalStore extends Store implements Serializable
|
|
|
|
{
|
2010-08-02 07:55:31 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Immutable empty {@link String} array
|
|
|
|
*/
|
|
|
|
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
|
|
|
|
2010-04-25 02:17:15 -04:00
|
|
|
private static final int DB_VERSION = 35;
|
2010-04-05 22:54:48 -04:00
|
|
|
private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.X_DESTROYED, Flag.SEEN, Flag.FLAGGED };
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
private String mPath;
|
|
|
|
private SQLiteDatabase mDb;
|
2010-02-17 22:28:31 -05:00
|
|
|
private File mAttachmentsDir;
|
2008-11-01 17:32:06 -04:00
|
|
|
private Application mApplication;
|
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 uUid = null;
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-06-08 23:11:35 -04:00
|
|
|
private static Set<String> HEADERS_TO_SAVE = new HashSet<String>();
|
|
|
|
static
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
HEADERS_TO_SAVE.add(K9.K9MAIL_IDENTITY);
|
2010-07-02 10:57:55 -04:00
|
|
|
HEADERS_TO_SAVE.add("To");
|
|
|
|
HEADERS_TO_SAVE.add("Cc");
|
|
|
|
HEADERS_TO_SAVE.add("From");
|
2009-11-17 16:13:29 -05:00
|
|
|
HEADERS_TO_SAVE.add("In-Reply-To");
|
|
|
|
HEADERS_TO_SAVE.add("References");
|
2009-11-24 19:40:29 -05:00
|
|
|
HEADERS_TO_SAVE.add("X-User-Agent");
|
2009-06-08 23:11:35 -04:00
|
|
|
}
|
2009-12-27 11:53:31 -05:00
|
|
|
/*
|
|
|
|
* a String containing the columns getMessages expects to work with
|
|
|
|
* in the correct order.
|
|
|
|
*/
|
|
|
|
static private String GET_MESSAGES_COLS =
|
|
|
|
"subject, sender_list, date, uid, flags, id, to_list, cc_list, "
|
2010-01-12 22:36:36 -05:00
|
|
|
+ "bcc_list, reply_to_list, attachment_count, internal_date, message_id, folder_id, preview ";
|
2009-12-27 11:53:31 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
2010-03-03 23:00:30 -05:00
|
|
|
* local://localhost/path/to/database/uuid.db
|
2008-11-01 17:32:06 -04:00
|
|
|
*/
|
2010-03-03 23:00:30 -05:00
|
|
|
public LocalStore(Account account, Application application) throws MessagingException
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
super(account);
|
2008-11-01 17:32:06 -04:00
|
|
|
mApplication = application;
|
|
|
|
URI uri = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
uri = new URI(mAccount.getLocalStoreUri());
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new MessagingException("Invalid uri for LocalStore");
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
if (!uri.getScheme().equals("local"))
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new MessagingException("Invalid scheme");
|
|
|
|
}
|
|
|
|
mPath = uri.getPath();
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
// We need to associate the localstore with the account. Since we don't have the account
|
|
|
|
// handy here, we'll take the filename from the DB and use the basename of the filename
|
|
|
|
// Folders probably should have references to their containing accounts
|
2010-03-03 23:00:30 -05:00
|
|
|
//TODO: We do have an account object now
|
2009-11-24 19:40:29 -05:00
|
|
|
File dbFile = new File(mPath);
|
|
|
|
String[] tokens = dbFile.getName().split("\\.");
|
|
|
|
uUid = tokens[0];
|
|
|
|
|
2010-05-12 00:17:52 -04:00
|
|
|
openOrCreateDataspace(application);
|
|
|
|
|
|
|
|
}
|
2010-05-15 15:46:16 -04:00
|
|
|
|
2010-05-12 00:17:52 -04:00
|
|
|
private void openOrCreateDataspace(Application application)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
File parentDir = new File(mPath).getParentFile();
|
2009-11-24 19:40:29 -05:00
|
|
|
if (!parentDir.exists())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
parentDir.mkdirs();
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-02-17 22:28:31 -05:00
|
|
|
mAttachmentsDir = new File(mPath + "_att");
|
|
|
|
if (!mAttachmentsDir.exists())
|
2010-02-13 14:07:10 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
mAttachmentsDir.mkdirs();
|
2010-02-13 14:07:10 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-02-24 22:35:25 -05:00
|
|
|
mDb = SQLiteDatabase.openOrCreateDatabase(mPath, null);
|
2009-11-24 19:40:29 -05:00
|
|
|
if (mDb.getVersion() != DB_VERSION)
|
|
|
|
{
|
2009-02-24 22:35:25 -05:00
|
|
|
doDbUpgrade(mDb, application);
|
2010-05-15 15:46:16 -04:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
private void doDbUpgrade(SQLiteDatabase mDb, Application application)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.i(K9.LOG_TAG, String.format("Upgrading database from version %d to version %d",
|
2009-12-20 00:41:43 -05:00
|
|
|
mDb.getVersion(), DB_VERSION));
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
AttachmentProvider.clear(application);
|
|
|
|
|
2010-01-24 15:41:04 -05:00
|
|
|
try
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-01-24 15:41:04 -05:00
|
|
|
// schema version 29 was when we moved to incremental updates
|
|
|
|
// in the case of a new db or a < v29 db, we blow away and start from scratch
|
|
|
|
if (mDb.getVersion() < 29)
|
|
|
|
{
|
2009-11-17 11:54:50 -05:00
|
|
|
|
2010-01-24 15:41:04 -05:00
|
|
|
mDb.execSQL("DROP TABLE IF EXISTS folders");
|
|
|
|
mDb.execSQL("CREATE TABLE folders (id INTEGER PRIMARY KEY, name TEXT, "
|
2010-04-17 17:27:06 -04:00
|
|
|
+ "last_updated INTEGER, unread_count INTEGER, visible_limit INTEGER, status TEXT, push_state TEXT, last_pushed INTEGER, flagged_count INTEGER default 0)");
|
2009-11-29 23:03:16 -05:00
|
|
|
|
2010-01-24 15:41:04 -05:00
|
|
|
mDb.execSQL("CREATE INDEX IF NOT EXISTS folder_name ON folders (name)");
|
|
|
|
mDb.execSQL("DROP TABLE IF EXISTS messages");
|
|
|
|
mDb.execSQL("CREATE TABLE messages (id INTEGER PRIMARY KEY, deleted INTEGER default 0, folder_id INTEGER, uid TEXT, subject TEXT, "
|
|
|
|
+ "date INTEGER, flags TEXT, sender_list TEXT, to_list TEXT, cc_list TEXT, bcc_list TEXT, reply_to_list TEXT, "
|
|
|
|
+ "html_content TEXT, text_content TEXT, attachment_count INTEGER, internal_date INTEGER, message_id TEXT, preview TEXT)");
|
|
|
|
|
|
|
|
mDb.execSQL("DROP TABLE IF EXISTS headers");
|
|
|
|
mDb.execSQL("CREATE TABLE headers (id INTEGER PRIMARY KEY, message_id INTEGER, name TEXT, value TEXT)");
|
|
|
|
mDb.execSQL("CREATE INDEX IF NOT EXISTS header_folder ON headers (message_id)");
|
|
|
|
|
|
|
|
mDb.execSQL("CREATE INDEX IF NOT EXISTS msg_uid ON messages (uid, folder_id)");
|
|
|
|
mDb.execSQL("DROP INDEX IF EXISTS msg_folder_id");
|
2009-11-29 23:03:16 -05:00
|
|
|
mDb.execSQL("DROP INDEX IF EXISTS msg_folder_id_date");
|
|
|
|
mDb.execSQL("CREATE INDEX IF NOT EXISTS msg_folder_id_deleted_date ON messages (folder_id,deleted,internal_date)");
|
2010-01-24 15:41:04 -05:00
|
|
|
mDb.execSQL("DROP TABLE IF EXISTS attachments");
|
|
|
|
mDb.execSQL("CREATE TABLE attachments (id INTEGER PRIMARY KEY, message_id INTEGER,"
|
|
|
|
+ "store_data TEXT, content_uri TEXT, size INTEGER, name TEXT,"
|
|
|
|
+ "mime_type TEXT)");
|
|
|
|
|
|
|
|
mDb.execSQL("DROP TABLE IF EXISTS pending_commands");
|
|
|
|
mDb.execSQL("CREATE TABLE pending_commands " +
|
|
|
|
"(id INTEGER PRIMARY KEY, command TEXT, arguments TEXT)");
|
2009-11-29 23:03:16 -05:00
|
|
|
|
2010-01-24 15:41:04 -05:00
|
|
|
mDb.execSQL("DROP TRIGGER IF EXISTS delete_folder");
|
|
|
|
mDb.execSQL("CREATE TRIGGER delete_folder BEFORE DELETE ON folders BEGIN DELETE FROM messages WHERE old.id = folder_id; END;");
|
|
|
|
|
|
|
|
mDb.execSQL("DROP TRIGGER IF EXISTS delete_message");
|
|
|
|
mDb.execSQL("CREATE TRIGGER delete_message BEFORE DELETE ON messages BEGIN DELETE FROM attachments WHERE old.id = message_id; "
|
|
|
|
+ "DELETE FROM headers where old.id = message_id; END;");
|
2009-11-29 23:03:16 -05:00
|
|
|
}
|
2010-01-24 15:41:04 -05:00
|
|
|
else
|
|
|
|
{ // in the case that we're starting out at 29 or newer, run all the needed updates
|
|
|
|
|
|
|
|
if (mDb.getVersion() < 30)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
mDb.execSQL("ALTER TABLE messages ADD deleted INTEGER default 0");
|
|
|
|
}
|
|
|
|
catch (SQLiteException e)
|
|
|
|
{
|
|
|
|
if (! e.toString().startsWith("duplicate column name: deleted"))
|
|
|
|
{
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (mDb.getVersion() < 31)
|
|
|
|
{
|
|
|
|
mDb.execSQL("DROP INDEX IF EXISTS msg_folder_id_date");
|
|
|
|
mDb.execSQL("CREATE INDEX IF NOT EXISTS msg_folder_id_deleted_date ON messages (folder_id,deleted,internal_date)");
|
|
|
|
}
|
|
|
|
if (mDb.getVersion() < 32)
|
|
|
|
{
|
|
|
|
mDb.execSQL("UPDATE messages SET deleted = 1 WHERE flags LIKE '%DELETED%'");
|
|
|
|
}
|
|
|
|
if (mDb.getVersion() < 33)
|
|
|
|
{
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
mDb.execSQL("ALTER TABLE messages ADD preview TEXT");
|
|
|
|
}
|
|
|
|
catch (SQLiteException e)
|
|
|
|
{
|
|
|
|
if (! e.toString().startsWith("duplicate column name: preview"))
|
|
|
|
{
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2010-04-16 10:33:54 -04:00
|
|
|
if (mDb.getVersion() < 34)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
mDb.execSQL("ALTER TABLE folders ADD flagged_count INTEGER default 0");
|
|
|
|
}
|
|
|
|
catch (SQLiteException e)
|
|
|
|
{
|
2010-05-09 20:14:26 -04:00
|
|
|
if (! e.getMessage().startsWith("duplicate column name: flagged_count"))
|
2010-04-16 10:33:54 -04:00
|
|
|
{
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-04-25 02:17:15 -04:00
|
|
|
if (mDb.getVersion() < 35)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
mDb.execSQL("update messages set flags = replace(flags, 'X_NO_SEEN_INFO', 'X_BAD_FLAG')");
|
|
|
|
}
|
|
|
|
catch (SQLiteException e)
|
|
|
|
{
|
|
|
|
Log.e(K9.LOG_TAG, "Unable to get rid of obsolete flag X_NO_SEEN_INFO", e);
|
|
|
|
}
|
|
|
|
}
|
2010-01-24 15:41:04 -05:00
|
|
|
|
2009-11-29 23:03:16 -05:00
|
|
|
|
2010-01-24 15:41:04 -05:00
|
|
|
}
|
2009-11-17 11:54:50 -05:00
|
|
|
|
2009-11-29 23:02:43 -05:00
|
|
|
}
|
2010-01-24 15:41:04 -05:00
|
|
|
catch (SQLiteException e)
|
|
|
|
{
|
|
|
|
Log.e(K9.LOG_TAG, "Exception while upgrading database. Resetting the DB to v0");
|
|
|
|
mDb.setVersion(0);
|
|
|
|
throw new Error("Database upgrade failed! Resetting your DB version to 0 to force a full schema recreation.");
|
|
|
|
}
|
|
|
|
|
2009-11-17 11:54:50 -05:00
|
|
|
|
2009-11-29 23:03:16 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
mDb.setVersion(DB_VERSION);
|
2010-01-24 15:41:04 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (mDb.getVersion() != DB_VERSION)
|
|
|
|
{
|
|
|
|
throw new Error("Database upgrade failed!");
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pruneCachedAttachments(true);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception me)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Exception while force pruning attachments during DB update", me);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-09 22:18:42 -05:00
|
|
|
public long getSize()
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
long attachmentLength = 0;
|
|
|
|
|
2010-02-17 22:28:31 -05:00
|
|
|
File[] files = mAttachmentsDir.listFiles();
|
|
|
|
for (File file : files)
|
2010-02-11 16:16:37 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
if (file.exists())
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
attachmentLength += file.length();
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-17 22:28:31 -05:00
|
|
|
|
|
|
|
File dbFile = new File(mPath);
|
|
|
|
return dbFile.length() + attachmentLength;
|
2009-02-09 22:18:42 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-02-09 22:18:42 -05:00
|
|
|
public void compact() throws MessagingException
|
|
|
|
{
|
2010-04-21 22:20:35 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Before prune size = " + getSize());
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
pruneCachedAttachments();
|
2010-04-21 22:20:35 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "After prune / before compaction size = " + getSize());
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
mDb.execSQL("VACUUM");
|
2010-04-21 22:20:35 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "After compaction size = " + getSize());
|
2009-02-09 22:18:42 -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 clear() throws MessagingException
|
|
|
|
{
|
2010-04-21 22:20:35 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.i(K9.LOG_TAG, "Before prune size = " + getSize());
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
pruneCachedAttachments(true);
|
2010-04-21 22:20:35 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
{
|
|
|
|
Log.i(K9.LOG_TAG, "After prune / before compaction size = " + getSize());
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-21 22:20:35 -04:00
|
|
|
Log.i(K9.LOG_TAG, "Before clear folder count = " + getFolderCount());
|
|
|
|
Log.i(K9.LOG_TAG, "Before clear message count = " + getMessageCount());
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-21 22:20:35 -04:00
|
|
|
Log.i(K9.LOG_TAG, "After prune / before clear size = " + getSize());
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
// don't delete messages that are Local, since there is no copy on the server.
|
|
|
|
// Don't delete deleted messages. They are essentially placeholders for UIDs of messages that have
|
2009-11-29 23:57:29 -05:00
|
|
|
// been deleted locally. They take up insignificant space
|
|
|
|
mDb.execSQL("DELETE FROM messages WHERE deleted = 0 and uid not like 'Local%'");
|
2010-05-02 01:37:48 -04:00
|
|
|
mDb.execSQL("update folders set flagged_count = 0, unread_count = 0");
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
compact();
|
2010-04-21 22:20:35 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
{
|
|
|
|
Log.i(K9.LOG_TAG, "After clear message count = " + getMessageCount());
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-21 22:20:35 -04:00
|
|
|
Log.i(K9.LOG_TAG, "After clear size = " + getSize());
|
|
|
|
}
|
2009-02-09 22:18:42 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
public int getMessageCount() throws MessagingException
|
|
|
|
{
|
2009-02-09 22:18:42 -05:00
|
|
|
Cursor cursor = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2009-02-09 22:18:42 -05:00
|
|
|
cursor = mDb.rawQuery("SELECT COUNT(*) FROM messages", null);
|
|
|
|
cursor.moveToFirst();
|
|
|
|
int messageCount = cursor.getInt(0);
|
|
|
|
return messageCount;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getFolderCount() throws MessagingException
|
|
|
|
{
|
|
|
|
Cursor cursor = null;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
cursor = mDb.rawQuery("SELECT COUNT(*) FROM folders", null);
|
|
|
|
cursor.moveToFirst();
|
|
|
|
int messageCount = cursor.getInt(0);
|
|
|
|
return messageCount;
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
2009-02-09 22:18:42 -05:00
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public LocalFolder getFolder(String name) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return new LocalFolder(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO this takes about 260-300ms, seems slow.
|
|
|
|
@Override
|
2010-05-30 12:56:50 -04:00
|
|
|
public List<? extends Folder> getPersonalNamespaces(boolean forceListAll) throws MessagingException
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-04-21 22:20:35 -04:00
|
|
|
LinkedList<LocalFolder> folders = new LinkedList<LocalFolder>();
|
2008-11-01 17:32:06 -04:00
|
|
|
Cursor cursor = null;
|
2008-11-01 17:36:23 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-04-16 10:33:54 -04:00
|
|
|
cursor = mDb.rawQuery("SELECT id, name, unread_count, visible_limit, last_updated, status, push_state, last_pushed, flagged_count FROM folders", null);
|
2009-11-24 19:40:29 -05:00
|
|
|
while (cursor.moveToNext())
|
|
|
|
{
|
2009-12-27 11:53:16 -05:00
|
|
|
LocalFolder folder = new LocalFolder(cursor.getString(1));
|
2010-04-16 10:33:54 -04:00
|
|
|
folder.open(cursor.getInt(0), cursor.getString(1), cursor.getInt(2), cursor.getInt(3), cursor.getLong(4), cursor.getString(5), cursor.getString(6), cursor.getLong(7), cursor.getInt(8));
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
folders.add(folder);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
2010-04-21 22:20:35 -04:00
|
|
|
return folders;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public void checkSettings() throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Delete the entire Store and it's backing database.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public void delete()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
mDb.close();
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
File[] attachments = mAttachmentsDir.listFiles();
|
|
|
|
for (File attachment : attachments)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
if (attachment.exists())
|
2010-02-11 16:16:37 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
attachment.delete();
|
2010-02-11 16:16:37 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-02-17 22:28:31 -05:00
|
|
|
if (mAttachmentsDir.exists())
|
|
|
|
{
|
|
|
|
mAttachmentsDir.delete();
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
}
|
|
|
|
try
|
|
|
|
{
|
|
|
|
new File(mPath).delete();
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
2010-05-15 15:46:16 -04:00
|
|
|
|
2010-05-12 00:17:52 -04:00
|
|
|
public void recreate()
|
|
|
|
{
|
|
|
|
delete();
|
|
|
|
openOrCreateDataspace(mApplication);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void pruneCachedAttachments() throws MessagingException
|
|
|
|
{
|
|
|
|
pruneCachedAttachments(false);
|
2009-02-09 22:18:42 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-02-17 22:28:31 -05:00
|
|
|
/**
|
|
|
|
* Deletes all cached attachments for the entire store.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public void pruneCachedAttachments(boolean force) throws MessagingException
|
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
|
2009-02-09 22:18:42 -05:00
|
|
|
if (force)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
ContentValues cv = new ContentValues();
|
|
|
|
cv.putNull("content_uri");
|
|
|
|
mDb.update("attachments", cv, null, null);
|
2009-02-09 22:18:42 -05:00
|
|
|
}
|
2010-02-17 22:28:31 -05:00
|
|
|
File[] files = mAttachmentsDir.listFiles();
|
|
|
|
for (File file : files)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
if (file.exists())
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
if (!force)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
Cursor cursor = null;
|
|
|
|
try
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
cursor = mDb.query(
|
|
|
|
"attachments",
|
|
|
|
new String[] { "store_data" },
|
|
|
|
"id = ?",
|
|
|
|
new String[] { file.getName() },
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null);
|
|
|
|
if (cursor.moveToNext())
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
if (cursor.getString(0) == null)
|
2010-02-11 16:16:37 -05:00
|
|
|
{
|
2010-04-21 22:20:35 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "Attachment " + file.getAbsolutePath() + " has no store data, not deleting");
|
2010-02-17 22:28:31 -05:00
|
|
|
/*
|
|
|
|
* If the attachment has no store data it is not recoverable, so
|
|
|
|
* we won't delete it.
|
|
|
|
*/
|
|
|
|
continue;
|
2010-02-11 16:16:37 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-02-17 22:28:31 -05:00
|
|
|
finally
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
if (cursor != null)
|
2010-02-11 16:16:37 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
cursor.close();
|
2010-02-11 16:16:37 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2010-02-17 22:28:31 -05:00
|
|
|
}
|
|
|
|
if (!force)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
ContentValues cv = new ContentValues();
|
|
|
|
cv.putNull("content_uri");
|
|
|
|
mDb.update("attachments", cv, "id = ?", new String[] { file.getName() });
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
/*
|
|
|
|
* If the row has gone away before we got to mark it not-downloaded that's
|
|
|
|
* okay.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2010-02-17 22:28:31 -05:00
|
|
|
if (!file.delete())
|
|
|
|
{
|
|
|
|
file.deleteOnExit();
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void resetVisibleLimits()
|
|
|
|
{
|
2010-05-30 17:20:47 -04:00
|
|
|
resetVisibleLimits(mAccount.getDisplayCount());
|
2008-12-11 00:25:59 -05:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void resetVisibleLimits(int visibleLimit)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
ContentValues cv = new ContentValues();
|
2008-12-11 00:25:59 -05:00
|
|
|
cv.put("visible_limit", Integer.toString(visibleLimit));
|
2008-11-01 17:32:06 -04:00
|
|
|
mDb.update("folders", cv, null, null);
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public ArrayList<PendingCommand> getPendingCommands()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
Cursor cursor = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor = mDb.query("pending_commands",
|
2009-11-24 19:40:29 -05:00
|
|
|
new String[] { "id", "command", "arguments" },
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
"id ASC");
|
2008-11-01 17:32:06 -04:00
|
|
|
ArrayList<PendingCommand> commands = new ArrayList<PendingCommand>();
|
2009-11-24 19:40:29 -05:00
|
|
|
while (cursor.moveToNext())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
PendingCommand command = new PendingCommand();
|
|
|
|
command.mId = cursor.getLong(0);
|
|
|
|
command.command = cursor.getString(1);
|
|
|
|
String arguments = cursor.getString(2);
|
|
|
|
command.arguments = arguments.split(",");
|
2009-11-24 19:40:29 -05:00
|
|
|
for (int i = 0; i < command.arguments.length; i++)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
command.arguments[i] = Utility.fastUrlDecode(command.arguments[i]);
|
|
|
|
}
|
|
|
|
commands.add(command);
|
|
|
|
}
|
|
|
|
return commands;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void addPendingCommand(PendingCommand command)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
for (int i = 0; i < command.arguments.length; i++)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
command.arguments[i] = URLEncoder.encode(command.arguments[i], "UTF-8");
|
|
|
|
}
|
|
|
|
ContentValues cv = new ContentValues();
|
|
|
|
cv.put("command", command.command);
|
|
|
|
cv.put("arguments", Utility.combine(command.arguments, ','));
|
|
|
|
mDb.insert("pending_commands", "command", cv);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (UnsupportedEncodingException usee)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new Error("Aparently UTF-8 has been lost to the annals of history.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void removePendingCommand(PendingCommand command)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
mDb.delete("pending_commands", "id = ?", new String[] { Long.toString(command.mId) });
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void removePendingCommands()
|
|
|
|
{
|
|
|
|
mDb.delete("pending_commands", null, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class PendingCommand
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
private long mId;
|
|
|
|
public String command;
|
|
|
|
public String[] arguments;
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public String toString()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
StringBuffer sb = new StringBuffer();
|
|
|
|
sb.append(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
|
|
|
sb.append(": ");
|
2009-11-24 19:40:29 -05:00
|
|
|
for (String argument : arguments)
|
|
|
|
{
|
2009-11-29 11:55:35 -05:00
|
|
|
sb.append(", ");
|
2008-11-01 17:32:06 -04:00
|
|
|
sb.append(argument);
|
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
|
|
|
//sb.append("\n");
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
return sb.toString();
|
|
|
|
}
|
|
|
|
}
|
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 boolean isMoveCapable()
|
|
|
|
{
|
|
|
|
return true;
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2009-12-27 11:53:37 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public boolean isCopyCapable()
|
|
|
|
{
|
|
|
|
return true;
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2010-05-29 17:56:17 -04:00
|
|
|
public Message[] searchForMessages(MessageRetrievalListener listener, String[] queryFields, String queryString,
|
2010-04-29 00:59:14 -04:00
|
|
|
List<LocalFolder> folders, Message[] messages, final Flag[] requiredFlags, final Flag[] forbiddenFlags) throws MessagingException
|
2009-12-27 11:53:37 -05:00
|
|
|
{
|
2010-04-05 22:54:48 -04:00
|
|
|
List<String> args = new LinkedList<String>();
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-05 22:54:48 -04:00
|
|
|
StringBuilder whereClause = new StringBuilder();
|
|
|
|
if (queryString != null && queryString.length() > 0)
|
|
|
|
{
|
2010-05-29 17:56:17 -04:00
|
|
|
boolean anyAdded = false;
|
2010-04-05 22:54:48 -04:00
|
|
|
String likeString = "%"+queryString+"%";
|
2010-05-29 17:56:17 -04:00
|
|
|
whereClause.append(" AND (");
|
2010-05-30 00:17:00 -04:00
|
|
|
for (String queryField : queryFields)
|
|
|
|
{
|
|
|
|
|
2010-05-29 17:56:17 -04:00
|
|
|
if (anyAdded == true)
|
|
|
|
{
|
|
|
|
whereClause.append(" OR ");
|
|
|
|
}
|
|
|
|
whereClause.append(queryField + " LIKE ? ");
|
|
|
|
args.add(likeString);
|
|
|
|
anyAdded = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
whereClause.append(" )");
|
2010-04-05 22:54:48 -04:00
|
|
|
}
|
|
|
|
if (folders != null && folders.size() > 0)
|
|
|
|
{
|
|
|
|
whereClause.append(" AND folder_id in (");
|
|
|
|
boolean anyAdded = false;
|
|
|
|
for (LocalFolder folder : folders)
|
|
|
|
{
|
|
|
|
if (anyAdded == true)
|
|
|
|
{
|
|
|
|
whereClause.append(",");
|
|
|
|
}
|
|
|
|
anyAdded = true;
|
|
|
|
whereClause.append("?");
|
|
|
|
args.add(Long.toString(folder.getId()));
|
|
|
|
}
|
|
|
|
whereClause.append(" )");
|
|
|
|
}
|
|
|
|
if (messages != null && messages.length > 0)
|
|
|
|
{
|
|
|
|
whereClause.append(" AND ( ");
|
|
|
|
boolean anyAdded = false;
|
|
|
|
for (Message message : messages)
|
|
|
|
{
|
|
|
|
if (anyAdded == true)
|
|
|
|
{
|
|
|
|
whereClause.append(" OR ");
|
|
|
|
}
|
|
|
|
anyAdded = true;
|
|
|
|
whereClause.append(" ( uid = ? AND folder_id = ? ) ");
|
|
|
|
args.add(message.getUid());
|
|
|
|
args.add(Long.toString(((LocalFolder)message.getFolder()).getId()));
|
|
|
|
}
|
|
|
|
whereClause.append(" )");
|
|
|
|
}
|
|
|
|
if (forbiddenFlags != null && forbiddenFlags.length > 0)
|
|
|
|
{
|
|
|
|
whereClause.append(" AND (");
|
|
|
|
boolean anyAdded = false;
|
|
|
|
for (Flag flag : forbiddenFlags)
|
|
|
|
{
|
|
|
|
if (anyAdded == true)
|
|
|
|
{
|
|
|
|
whereClause.append(" AND ");
|
|
|
|
}
|
|
|
|
anyAdded = true;
|
|
|
|
whereClause.append(" flags NOT LIKE ?");
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-05 22:54:48 -04:00
|
|
|
args.add("%" + flag.toString() + "%");
|
|
|
|
}
|
|
|
|
whereClause.append(" )");
|
|
|
|
}
|
|
|
|
if (requiredFlags != null && requiredFlags.length > 0)
|
|
|
|
{
|
|
|
|
whereClause.append(" AND (");
|
|
|
|
boolean anyAdded = false;
|
|
|
|
for (Flag flag : requiredFlags)
|
|
|
|
{
|
|
|
|
if (anyAdded == true)
|
|
|
|
{
|
|
|
|
whereClause.append(" OR ");
|
|
|
|
}
|
|
|
|
anyAdded = true;
|
|
|
|
whereClause.append(" flags LIKE ?");
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-05 22:54:48 -04:00
|
|
|
args.add("%" + flag.toString() + "%");
|
|
|
|
}
|
|
|
|
whereClause.append(" )");
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-21 22:20:35 -04:00
|
|
|
if (K9.DEBUG)
|
|
|
|
{
|
|
|
|
Log.v(K9.LOG_TAG, "whereClause = " + whereClause.toString());
|
|
|
|
Log.v(K9.LOG_TAG, "args = " + args);
|
|
|
|
}
|
2009-12-27 11:53:37 -05:00
|
|
|
return getMessages(
|
|
|
|
listener,
|
|
|
|
null,
|
|
|
|
"SELECT "
|
|
|
|
+ GET_MESSAGES_COLS
|
2010-04-05 22:54:48 -04:00
|
|
|
+ "FROM messages WHERE deleted = 0 " + whereClause.toString() + " ORDER BY date DESC"
|
2010-08-02 07:55:31 -04:00
|
|
|
, args.toArray(EMPTY_STRING_ARRAY)
|
2009-12-27 11:53:37 -05:00
|
|
|
);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Given a query string, actually do the query for the messages and
|
|
|
|
* call the MessageRetrievalListener for each one
|
|
|
|
*/
|
|
|
|
private Message[] getMessages(
|
|
|
|
MessageRetrievalListener listener,
|
|
|
|
LocalFolder folder,
|
|
|
|
String queryString, String[] placeHolders
|
|
|
|
) throws MessagingException
|
|
|
|
{
|
|
|
|
ArrayList<LocalMessage> messages = new ArrayList<LocalMessage>();
|
|
|
|
Cursor cursor = null;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// pull out messages most recent first, since that's what the default sort is
|
|
|
|
cursor = mDb.rawQuery(queryString, placeHolders);
|
|
|
|
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
while (cursor.moveToNext())
|
|
|
|
{
|
|
|
|
LocalMessage message = new LocalMessage(null, folder);
|
|
|
|
message.populateFromGetMessageCursor(cursor);
|
|
|
|
|
|
|
|
messages.add(message);
|
|
|
|
if (listener != null)
|
|
|
|
{
|
|
|
|
listener.messageFinished(message, i, -1);
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (listener != null)
|
|
|
|
{
|
|
|
|
listener.messagesFinished(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return messages.toArray(new Message[] {});
|
|
|
|
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
|
|
|
|
public class LocalFolder extends Folder implements Serializable
|
|
|
|
{
|
2009-12-27 12:22:26 -05:00
|
|
|
private String mName = null;
|
2008-11-01 17:32:06 -04:00
|
|
|
private long mFolderId = -1;
|
|
|
|
private int mUnreadMessageCount = -1;
|
2010-04-16 10:33:54 -04:00
|
|
|
private int mFlaggedMessageCount = -1;
|
2008-11-01 17:32:06 -04:00
|
|
|
private int mVisibleLimit = -1;
|
2009-11-24 19:40:29 -05:00
|
|
|
private FolderClass displayClass = FolderClass.NO_CLASS;
|
|
|
|
private FolderClass syncClass = FolderClass.INHERITED;
|
|
|
|
private FolderClass pushClass = FolderClass.SECOND_CLASS;
|
2010-03-07 12:02:21 -05:00
|
|
|
private boolean inTopGroup = false;
|
2009-11-24 19:40:29 -05:00
|
|
|
private String prefId = null;
|
|
|
|
private String mPushState = null;
|
2010-04-05 22:54:48 -04:00
|
|
|
private boolean mIntegrate = false;
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-12-27 11:50:14 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public LocalFolder(String name)
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
super(LocalStore.this.mAccount);
|
2008-11-01 17:32:06 -04:00
|
|
|
this.mName = name;
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.INBOX.equals(getName()))
|
2009-01-02 20:47:24 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
syncClass = FolderClass.FIRST_CLASS;
|
|
|
|
pushClass = FolderClass.FIRST_CLASS;
|
2010-03-07 12:02:21 -05:00
|
|
|
inTopGroup = true;
|
2009-01-02 20:47:24 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2009-12-27 11:53:16 -05:00
|
|
|
public LocalFolder(long id)
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
super(LocalStore.this.mAccount);
|
2009-12-27 11:53:16 -05:00
|
|
|
this.mFolderId = id;
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public long getId()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return mFolderId;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public void open(OpenMode mode) throws MessagingException
|
|
|
|
{
|
|
|
|
if (isOpen())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Cursor cursor = null;
|
|
|
|
try
|
|
|
|
{
|
2009-12-27 11:53:16 -05:00
|
|
|
String baseQuery =
|
2010-04-16 10:33:54 -04:00
|
|
|
"SELECT id, name,unread_count, visible_limit, last_updated, status, push_state, last_pushed, flagged_count FROM folders ";
|
2009-12-27 11:53:16 -05:00
|
|
|
if (mName != null)
|
|
|
|
{
|
|
|
|
cursor = mDb.rawQuery(baseQuery + "where folders.name = ?", new String[] { mName });
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cursor = mDb.rawQuery(baseQuery + "where folders.id = ?", new String[] { Long.toString(mFolderId) });
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2009-01-02 20:47:24 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (cursor.moveToFirst())
|
|
|
|
{
|
|
|
|
int folderId = cursor.getInt(0);
|
|
|
|
if (folderId > 0)
|
|
|
|
{
|
2010-04-16 10:33:54 -04:00
|
|
|
open(folderId, cursor.getString(1), cursor.getInt(2), cursor.getInt(3), cursor.getLong(4), cursor.getString(5), cursor.getString(6), cursor.getLong(7), cursor.getInt(8));
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-04-05 22:54:48 -04:00
|
|
|
Log.w(K9.LOG_TAG, "Creating folder " + getName() + " with existing id " + getId());
|
2009-11-24 19:40:29 -05:00
|
|
|
create(FolderType.HOLDS_MESSAGES);
|
|
|
|
open(mode);
|
|
|
|
}
|
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
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
|
|
|
cursor.close();
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-16 10:33:54 -04:00
|
|
|
private void open(int id, String name, int unreadCount, int visibleLimit, long lastChecked, String status, String pushState, long lastPushed, int flaggedCount) throws MessagingException
|
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
|
|
|
mFolderId = id;
|
2009-12-27 11:53:16 -05:00
|
|
|
mName = name;
|
2009-11-24 19:40:29 -05:00
|
|
|
mUnreadMessageCount = unreadCount;
|
|
|
|
mVisibleLimit = visibleLimit;
|
|
|
|
mPushState = pushState;
|
2010-04-16 10:33:54 -04:00
|
|
|
mFlaggedMessageCount = flaggedCount;
|
2009-11-24 19:40:29 -05:00
|
|
|
super.setStatus(status);
|
|
|
|
// Only want to set the local variable stored in the super class. This class
|
|
|
|
// does a DB update on setLastChecked
|
|
|
|
super.setLastChecked(lastChecked);
|
|
|
|
super.setLastPush(lastPushed);
|
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
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public boolean isOpen()
|
|
|
|
{
|
2009-12-27 12:22:26 -05:00
|
|
|
return (mFolderId != -1 && mName != null);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public OpenMode getMode() throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return OpenMode.READ_WRITE;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public String getName()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return mName;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public boolean exists() throws MessagingException
|
|
|
|
{
|
2008-11-01 23:56:13 -04:00
|
|
|
Cursor cursor = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 23:56:13 -04:00
|
|
|
cursor = mDb.rawQuery("SELECT id FROM folders "
|
2009-11-24 19:40:29 -05:00
|
|
|
+ "where folders.name = ?", new String[] { this
|
|
|
|
.getName()
|
|
|
|
});
|
|
|
|
if (cursor.moveToFirst())
|
|
|
|
{
|
2008-11-01 23:56:13 -04:00
|
|
|
int folderId = cursor.getInt(0);
|
|
|
|
return (folderId > 0) ? true : false;
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-11-01 23:56:13 -04:00
|
|
|
return false;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
2008-11-01 23:56:13 -04:00
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public boolean create(FolderType type) throws MessagingException
|
|
|
|
{
|
|
|
|
if (exists())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new MessagingException("Folder " + mName + " already exists.");
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
mDb.execSQL("INSERT INTO folders (name, visible_limit) VALUES (?, ?)", new Object[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
mName,
|
2010-05-30 17:20:47 -04:00
|
|
|
mAccount.getDisplayCount()
|
2009-12-06 19:56:06 -05:00
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public boolean create(FolderType type, int visibleLimit) throws MessagingException
|
|
|
|
{
|
|
|
|
if (exists())
|
|
|
|
{
|
2008-12-11 00:25:59 -05:00
|
|
|
throw new MessagingException("Folder " + mName + " already exists.");
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
mDb.execSQL("INSERT INTO folders (name, visible_limit) VALUES (?, ?)", new Object[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
mName,
|
|
|
|
visibleLimit
|
|
|
|
});
|
2008-12-11 00:25:59 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
@Override
|
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 close()
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
mFolderId = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public int getMessageCount() throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
Cursor cursor = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor = mDb.rawQuery("SELECT COUNT(*) FROM messages WHERE messages.folder_id = ?",
|
2009-11-24 19:40:29 -05:00
|
|
|
new String[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
Long.toString(mFolderId)
|
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor.moveToFirst();
|
|
|
|
int messageCount = cursor.getInt(0);
|
|
|
|
return messageCount;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public int getUnreadMessageCount() throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
return mUnreadMessageCount;
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-16 10:33:54 -04:00
|
|
|
@Override
|
|
|
|
public int getFlaggedMessageCount() throws MessagingException
|
|
|
|
{
|
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
return mFlaggedMessageCount;
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void setUnreadMessageCount(int unreadMessageCount) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
mUnreadMessageCount = Math.max(0, unreadMessageCount);
|
|
|
|
mDb.execSQL("UPDATE folders SET unread_count = ? WHERE id = ?",
|
2009-11-24 19:40:29 -05:00
|
|
|
new Object[] { mUnreadMessageCount, mFolderId });
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-16 10:33:54 -04:00
|
|
|
public void setFlaggedMessageCount(int flaggedMessageCount) throws MessagingException
|
|
|
|
{
|
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
mFlaggedMessageCount = Math.max(0, flaggedMessageCount);
|
|
|
|
mDb.execSQL("UPDATE folders SET flagged_count = ? WHERE id = ?",
|
|
|
|
new Object[] { mFlaggedMessageCount, mFolderId });
|
|
|
|
}
|
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 void setLastChecked(long lastChecked) throws MessagingException
|
|
|
|
{
|
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
super.setLastChecked(lastChecked);
|
|
|
|
mDb.execSQL("UPDATE folders SET last_updated = ? WHERE id = ?",
|
|
|
|
new Object[] { lastChecked, mFolderId });
|
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public void setLastPush(long lastChecked) throws MessagingException
|
|
|
|
{
|
2009-10-21 20:41:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
super.setLastPush(lastChecked);
|
|
|
|
mDb.execSQL("UPDATE folders SET last_pushed = ? WHERE id = ?",
|
2009-11-24 19:40:29 -05:00
|
|
|
new Object[] { lastChecked, mFolderId });
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public int getVisibleLimit() throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
return mVisibleLimit;
|
|
|
|
}
|
|
|
|
|
2009-11-26 00:10:12 -05:00
|
|
|
public void purgeToVisibleLimit(MessageRemovalListener listener) throws MessagingException
|
|
|
|
{
|
|
|
|
open(OpenMode.READ_WRITE);
|
2009-11-29 23:57:29 -05:00
|
|
|
Message[] messages = getMessages(null, false);
|
2009-11-29 11:55:35 -05:00
|
|
|
for (int i = mVisibleLimit; i < messages.length; i++)
|
2009-11-26 00:10:12 -05:00
|
|
|
{
|
2009-11-29 11:55:35 -05:00
|
|
|
if (listener != null)
|
2009-11-26 00:10:12 -05:00
|
|
|
{
|
2009-11-29 11:55:35 -05:00
|
|
|
listener.messageRemoved(messages[i]);
|
2009-11-26 00:10:12 -05:00
|
|
|
}
|
2009-11-29 11:55:35 -05:00
|
|
|
messages[i].setFlag(Flag.X_DESTROYED, true);
|
2009-11-29 23:03:16 -05:00
|
|
|
|
2009-11-26 00:10:12 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void setVisibleLimit(int visibleLimit) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
mVisibleLimit = visibleLimit;
|
|
|
|
mDb.execSQL("UPDATE folders SET visible_limit = ? WHERE id = ?",
|
2009-11-24 19:40:29 -05:00
|
|
|
new Object[] { mVisibleLimit, mFolderId });
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
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 setStatus(String status) throws MessagingException
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
super.setStatus(status);
|
|
|
|
mDb.execSQL("UPDATE folders SET status = ? WHERE id = ?",
|
|
|
|
new Object[] { status, mFolderId });
|
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-10-21 20:41:06 -04:00
|
|
|
public void setPushState(String pushState) throws MessagingException
|
|
|
|
{
|
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
mPushState = pushState;
|
2009-11-24 19:40:29 -05:00
|
|
|
mDb.execSQL("UPDATE folders SET push_state = ? WHERE id = ?",
|
|
|
|
new Object[] { pushState, mFolderId });
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
public String getPushState()
|
|
|
|
{
|
|
|
|
return mPushState;
|
|
|
|
}
|
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
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public FolderClass getDisplayClass()
|
|
|
|
{
|
|
|
|
return displayClass;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public FolderClass getSyncClass()
|
|
|
|
{
|
|
|
|
if (FolderClass.INHERITED == syncClass)
|
|
|
|
{
|
|
|
|
return getDisplayClass();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return syncClass;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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 FolderClass getRawSyncClass()
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
return syncClass;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-10-21 20:41:06 -04:00
|
|
|
public FolderClass getPushClass()
|
|
|
|
{
|
|
|
|
if (FolderClass.INHERITED == pushClass)
|
|
|
|
{
|
|
|
|
return getSyncClass();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return pushClass;
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
public FolderClass getRawPushClass()
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
|
|
|
return pushClass;
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
public void setDisplayClass(FolderClass displayClass)
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
this.displayClass = displayClass;
|
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
|
|
|
public void setSyncClass(FolderClass syncClass)
|
2009-02-24 00:03:28 -05:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
this.syncClass = syncClass;
|
2009-02-24 00:03:28 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
public void setPushClass(FolderClass pushClass)
|
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
|
|
|
this.pushClass = pushClass;
|
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-29 00:59:14 -04:00
|
|
|
|
2010-04-05 22:54:48 -04:00
|
|
|
public boolean isIntegrate()
|
|
|
|
{
|
|
|
|
return mIntegrate;
|
|
|
|
}
|
|
|
|
public void setIntegrate(boolean integrate)
|
|
|
|
{
|
|
|
|
mIntegrate = integrate;
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
private String getPrefId() throws MessagingException
|
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
|
|
|
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
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (prefId == null)
|
|
|
|
{
|
|
|
|
prefId = uUid + "." + mName;
|
|
|
|
}
|
|
|
|
|
|
|
|
return prefId;
|
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
|
|
|
|
|
|
|
public void delete(Preferences preferences) throws MessagingException
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
String id = getPrefId();
|
|
|
|
|
|
|
|
SharedPreferences.Editor editor = preferences.getPreferences().edit();
|
|
|
|
|
|
|
|
editor.remove(id + ".displayMode");
|
|
|
|
editor.remove(id + ".syncMode");
|
2010-03-07 12:02:21 -05:00
|
|
|
editor.remove(id + ".pushMode");
|
|
|
|
editor.remove(id + ".inTopGroup");
|
2010-04-05 22:54:48 -04:00
|
|
|
editor.remove(id + ".integrate");
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
editor.commit();
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
public void save(Preferences preferences) throws MessagingException
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
String id = getPrefId();
|
|
|
|
|
|
|
|
SharedPreferences.Editor editor = preferences.getPreferences().edit();
|
|
|
|
// there can be a lot of folders. For the defaults, let's not save prefs, saving space, except for INBOX
|
2009-12-14 21:50:53 -05:00
|
|
|
if (displayClass == FolderClass.NO_CLASS && !K9.INBOX.equals(getName()))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
editor.remove(id + ".displayMode");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
editor.putString(id + ".displayMode", displayClass.name());
|
|
|
|
}
|
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (syncClass == FolderClass.INHERITED && !K9.INBOX.equals(getName()))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
editor.remove(id + ".syncMode");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
editor.putString(id + ".syncMode", syncClass.name());
|
|
|
|
}
|
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
if (pushClass == FolderClass.SECOND_CLASS && !K9.INBOX.equals(getName()))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
editor.remove(id + ".pushMode");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
editor.putString(id + ".pushMode", pushClass.name());
|
|
|
|
}
|
2010-03-07 12:02:21 -05:00
|
|
|
editor.putBoolean(id + ".inTopGroup", inTopGroup);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-05 22:54:48 -04:00
|
|
|
editor.putBoolean(id + ".integrate", mIntegrate);
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
editor.commit();
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
|
|
|
|
2010-04-21 22:20:35 -04:00
|
|
|
public FolderClass getDisplayClass(Preferences preferences) throws MessagingException
|
|
|
|
{
|
|
|
|
String id = getPrefId();
|
|
|
|
return FolderClass.valueOf(preferences.getPreferences().getString(id + ".displayMode",
|
2010-04-29 00:59:14 -04:00
|
|
|
FolderClass.NO_CLASS.name()));
|
2010-04-21 22:20:35 -04:00
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public void refresh(Preferences preferences) throws MessagingException
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
String id = getPrefId();
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
displayClass = FolderClass.valueOf(preferences.getPreferences().getString(id + ".displayMode",
|
|
|
|
FolderClass.NO_CLASS.name()));
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to load displayMode for " + getName(), e);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
displayClass = FolderClass.NO_CLASS;
|
|
|
|
}
|
|
|
|
if (displayClass == FolderClass.NONE)
|
|
|
|
{
|
|
|
|
displayClass = FolderClass.NO_CLASS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
FolderClass defSyncClass = FolderClass.INHERITED;
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.INBOX.equals(getName()))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
defSyncClass = FolderClass.FIRST_CLASS;
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
syncClass = FolderClass.valueOf(preferences.getPreferences().getString(id + ".syncMode",
|
|
|
|
defSyncClass.name()));
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to load syncMode for " + getName(), e);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
syncClass = defSyncClass;
|
|
|
|
}
|
|
|
|
if (syncClass == FolderClass.NONE)
|
|
|
|
{
|
|
|
|
syncClass = FolderClass.INHERITED;
|
|
|
|
}
|
|
|
|
|
|
|
|
FolderClass defPushClass = FolderClass.SECOND_CLASS;
|
2010-03-07 12:02:21 -05:00
|
|
|
boolean defInTopGroup = false;
|
2010-04-05 22:54:48 -04:00
|
|
|
boolean defIntegrate = false;
|
2009-12-14 21:50:53 -05:00
|
|
|
if (K9.INBOX.equals(getName()))
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
|
|
|
defPushClass = FolderClass.FIRST_CLASS;
|
2010-03-07 12:02:21 -05:00
|
|
|
defInTopGroup = true;
|
2010-04-05 22:54:48 -04:00
|
|
|
defIntegrate = true;
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
pushClass = FolderClass.valueOf(preferences.getPreferences().getString(id + ".pushMode",
|
|
|
|
defPushClass.name()));
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, "Unable to load pushMode for " + getName(), e);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
pushClass = defPushClass;
|
|
|
|
}
|
|
|
|
if (pushClass == FolderClass.NONE)
|
|
|
|
{
|
|
|
|
pushClass = FolderClass.INHERITED;
|
|
|
|
}
|
2010-03-07 12:02:21 -05:00
|
|
|
inTopGroup = preferences.getPreferences().getBoolean(id + ".inTopGroup", defInTopGroup);
|
2010-04-05 22:54:48 -04:00
|
|
|
mIntegrate = preferences.getPreferences().getBoolean(id + ".integrate", defIntegrate);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void fetch(Message[] messages, FetchProfile fp, MessageRetrievalListener listener)
|
2009-11-24 19:40:29 -05:00
|
|
|
throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
2009-11-24 19:40:29 -05:00
|
|
|
if (fp.contains(FetchProfile.Item.BODY))
|
|
|
|
{
|
|
|
|
for (Message message : messages)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
LocalMessage localMessage = (LocalMessage)message;
|
|
|
|
Cursor cursor = null;
|
|
|
|
MimeMultipart mp = new MimeMultipart();
|
|
|
|
mp.setSubType("mixed");
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor = mDb.rawQuery("SELECT html_content, text_content FROM messages "
|
2009-11-24 19:40:29 -05:00
|
|
|
+ "WHERE id = ?",
|
|
|
|
new String[] { Long.toString(localMessage.mId) });
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor.moveToNext();
|
|
|
|
String htmlContent = cursor.getString(0);
|
|
|
|
String textContent = cursor.getString(1);
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (textContent != null)
|
|
|
|
{
|
2009-05-20 00:36:20 -04:00
|
|
|
LocalTextBody body = new LocalTextBody(textContent, htmlContent);
|
2008-11-01 17:32:06 -04:00
|
|
|
MimeBodyPart bp = new MimeBodyPart(body, "text/plain");
|
|
|
|
mp.addBodyPart(bp);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else
|
|
|
|
{
|
2009-05-20 00:36:20 -04:00
|
|
|
TextBody body = new TextBody(htmlContent);
|
|
|
|
MimeBodyPart bp = new MimeBodyPart(body, "text/html");
|
|
|
|
mp.addBodyPart(bp);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor = mDb.query(
|
2009-11-24 19:40:29 -05:00
|
|
|
"attachments",
|
|
|
|
new String[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
"id",
|
|
|
|
"size",
|
|
|
|
"name",
|
|
|
|
"mime_type",
|
|
|
|
"store_data",
|
|
|
|
"content_uri"
|
|
|
|
},
|
|
|
|
"message_id = ?",
|
|
|
|
new String[] { Long.toString(localMessage.mId) },
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
while (cursor.moveToNext())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
long id = cursor.getLong(0);
|
|
|
|
int size = cursor.getInt(1);
|
|
|
|
String name = cursor.getString(2);
|
|
|
|
String type = cursor.getString(3);
|
|
|
|
String storeData = cursor.getString(4);
|
|
|
|
String contentUri = cursor.getString(5);
|
|
|
|
Body body = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
if (contentUri != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
body = new LocalAttachmentBody(Uri.parse(contentUri), mApplication);
|
|
|
|
}
|
|
|
|
MimeBodyPart bp = new LocalAttachmentBodyPart(body, id);
|
|
|
|
bp.setHeader(MimeHeader.HEADER_CONTENT_TYPE,
|
2009-11-24 19:40:29 -05:00
|
|
|
String.format("%s;\n name=\"%s\"",
|
|
|
|
type,
|
|
|
|
name));
|
2008-11-01 17:32:06 -04:00
|
|
|
bp.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
|
|
|
|
bp.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
|
2009-11-24 19:40:29 -05:00
|
|
|
String.format("attachment;\n filename=\"%s\";\n size=%d",
|
|
|
|
name,
|
|
|
|
size));
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* HEADER_ANDROID_ATTACHMENT_STORE_DATA is a custom header we add to that
|
|
|
|
* we can later pull the attachment from the remote store if neccesary.
|
|
|
|
*/
|
|
|
|
bp.setHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA, storeData);
|
|
|
|
|
|
|
|
mp.addBodyPart(bp);
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
2010-02-03 14:56:20 -05:00
|
|
|
|
|
|
|
if (mp.getCount() == 1)
|
|
|
|
{
|
|
|
|
BodyPart part = mp.getBodyPart(0);
|
|
|
|
localMessage.setHeader(MimeHeader.HEADER_CONTENT_TYPE, part.getContentType());
|
|
|
|
localMessage.setBody(part.getBody());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
localMessage.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "multipart/mixed");
|
|
|
|
localMessage.setBody(mp);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2010-05-30 17:20:47 -04:00
|
|
|
public Message[] getMessages(int start, int end, Date earliestDate, MessageRetrievalListener listener)
|
2009-11-24 19:40:29 -05:00
|
|
|
throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
throw new MessagingException(
|
2009-11-24 19:40:29 -05:00
|
|
|
"LocalStore.getMessages(int, int, MessageRetrievalListener) not yet implemented");
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2010-05-21 11:34:29 -04:00
|
|
|
/**
|
|
|
|
* Populate the header fields of the given list of messages by reading
|
|
|
|
* the saved header data from the database.
|
2010-05-30 00:17:00 -04:00
|
|
|
*
|
2010-05-21 11:34:29 -04:00
|
|
|
* @param messages
|
|
|
|
* The messages whose headers should be loaded.
|
|
|
|
*/
|
2009-06-08 23:11:35 -04:00
|
|
|
private void populateHeaders(List<LocalMessage> messages)
|
|
|
|
{
|
|
|
|
Cursor cursor = null;
|
|
|
|
if (messages.size() == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2009-06-08 23:11:35 -04:00
|
|
|
Map<Long, LocalMessage> popMessages = new HashMap<Long, LocalMessage>();
|
|
|
|
List<String> ids = new ArrayList<String>();
|
|
|
|
StringBuffer questions = new StringBuffer();
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-06-08 23:11:35 -04:00
|
|
|
for (int i = 0; i < messages.size(); i++)
|
|
|
|
{
|
|
|
|
if (i != 0)
|
|
|
|
{
|
|
|
|
questions.append(", ");
|
|
|
|
}
|
|
|
|
questions.append("?");
|
|
|
|
LocalMessage message = messages.get(i);
|
|
|
|
Long id = message.getId();
|
|
|
|
ids.add(Long.toString(id));
|
|
|
|
popMessages.put(id, message);
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-06-08 23:11:35 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-06-08 23:11:35 -04:00
|
|
|
cursor = mDb.rawQuery(
|
2009-12-27 11:53:45 -05:00
|
|
|
"SELECT message_id, name, value FROM headers " + "WHERE message_id in ( " + questions + ") ",
|
2009-11-24 19:40:29 -05:00
|
|
|
ids.toArray(new String[] {}));
|
|
|
|
|
|
|
|
|
|
|
|
while (cursor.moveToNext())
|
|
|
|
{
|
2009-06-08 23:11:35 -04:00
|
|
|
Long id = cursor.getLong(0);
|
|
|
|
String name = cursor.getString(1);
|
|
|
|
String value = cursor.getString(2);
|
2009-12-14 21:50:53 -05:00
|
|
|
//Log.i(K9.LOG_TAG, "Retrieved header name= " + name + ", value = " + value + " for message " + id);
|
2009-06-08 23:11:35 -04:00
|
|
|
popMessages.get(id).addHeader(name, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
if (cursor != null)
|
|
|
|
{
|
2009-06-08 23:11:35 -04:00
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public Message getMessage(String uid) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
LocalMessage message = new LocalMessage(uid, this);
|
|
|
|
Cursor cursor = null;
|
2009-11-29 23:03:16 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor = mDb.rawQuery(
|
2009-12-27 11:50:14 -05:00
|
|
|
"SELECT "
|
|
|
|
+ GET_MESSAGES_COLS
|
|
|
|
+ "FROM messages WHERE uid = ? AND folder_id = ?",
|
2009-11-24 19:40:29 -05:00
|
|
|
new String[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
message.getUid(), Long.toString(mFolderId)
|
|
|
|
});
|
2009-11-24 19:40:29 -05:00
|
|
|
if (!cursor.moveToNext())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return null;
|
|
|
|
}
|
2009-12-27 11:52:57 -05:00
|
|
|
message.populateFromGetMessageCursor(cursor);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
cursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return message;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public Message[] getMessages(MessageRetrievalListener listener) throws MessagingException
|
|
|
|
{
|
|
|
|
return getMessages(listener, true);
|
|
|
|
}
|
|
|
|
|
2009-11-17 11:54:50 -05:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public Message[] getMessages(MessageRetrievalListener listener, boolean includeDeleted) throws MessagingException
|
2009-12-27 11:50:21 -05:00
|
|
|
{
|
2009-12-27 11:53:37 -05:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
return LocalStore.this.getMessages(
|
2009-12-27 11:50:21 -05:00
|
|
|
listener,
|
2009-12-27 11:53:37 -05:00
|
|
|
this,
|
2009-12-27 11:50:28 -05:00
|
|
|
"SELECT " + GET_MESSAGES_COLS
|
|
|
|
+ "FROM messages WHERE "
|
2009-12-27 11:50:21 -05:00
|
|
|
+ (includeDeleted ? "" : "deleted = 0 AND ")
|
|
|
|
+ " folder_id = ? ORDER BY date DESC"
|
|
|
|
, new String[]
|
|
|
|
{
|
|
|
|
Long.toString(mFolderId)
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
@Override
|
|
|
|
public Message[] getMessages(String[] uids, MessageRetrievalListener listener)
|
2009-11-24 19:40:29 -05:00
|
|
|
throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
2009-11-24 19:40:29 -05:00
|
|
|
if (uids == null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return getMessages(listener);
|
|
|
|
}
|
|
|
|
ArrayList<Message> messages = new ArrayList<Message>();
|
2009-11-24 19:40:29 -05:00
|
|
|
for (String uid : uids)
|
|
|
|
{
|
2010-03-03 23:00:30 -05:00
|
|
|
Message message = getMessage(uid);
|
|
|
|
if (message != null)
|
|
|
|
{
|
|
|
|
messages.add(message);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
return messages.toArray(new Message[] {});
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public void copyMessages(Message[] msgs, Folder folder) throws MessagingException
|
|
|
|
{
|
|
|
|
if (!(folder instanceof LocalFolder))
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new MessagingException("copyMessages called with incorrect Folder");
|
|
|
|
}
|
|
|
|
((LocalFolder) folder).appendMessages(msgs, true);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-03-05 02:32:45 -05:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public void moveMessages(Message[] msgs, Folder destFolder) throws MessagingException
|
|
|
|
{
|
|
|
|
if (!(destFolder instanceof LocalFolder))
|
|
|
|
{
|
2010-01-09 14:49:54 -05:00
|
|
|
throw new MessagingException("moveMessages called with non-LocalFolder");
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2009-03-07 02:20:15 -05:00
|
|
|
|
2009-03-05 02:32:45 -05:00
|
|
|
LocalFolder lDestFolder = (LocalFolder)destFolder;
|
2009-03-07 02:20:15 -05:00
|
|
|
lDestFolder.open(OpenMode.READ_WRITE);
|
2009-03-05 02:32:45 -05:00
|
|
|
for (Message message : msgs)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
LocalMessage lMessage = (LocalMessage)message;
|
|
|
|
|
|
|
|
if (!message.isSet(Flag.SEEN))
|
|
|
|
{
|
|
|
|
setUnreadMessageCount(getUnreadMessageCount() - 1);
|
|
|
|
lDestFolder.setUnreadMessageCount(lDestFolder.getUnreadMessageCount() + 1);
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-16 10:33:54 -04:00
|
|
|
if (message.isSet(Flag.FLAGGED))
|
|
|
|
{
|
|
|
|
setFlaggedMessageCount(getFlaggedMessageCount() - 1);
|
|
|
|
lDestFolder.setFlaggedMessageCount(lDestFolder.getFlaggedMessageCount() + 1);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
String oldUID = message.getUid();
|
2010-01-13 20:07:28 -05:00
|
|
|
|
2010-01-05 22:44:23 -05:00
|
|
|
if (K9.DEBUG)
|
|
|
|
Log.d(K9.LOG_TAG, "Updating folder_id to " + lDestFolder.getId() + " for message with UID "
|
2010-01-13 20:07:28 -05:00
|
|
|
+ message.getUid() + ", id " + lMessage.getId() + " currently in folder " + getName());
|
|
|
|
|
2009-12-14 21:50:53 -05:00
|
|
|
message.setUid(K9.LOCAL_UID_PREFIX + UUID.randomUUID().toString());
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
mDb.execSQL("UPDATE messages " + "SET folder_id = ?, uid = ? " + "WHERE id = ?", new Object[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
lDestFolder.getId(),
|
|
|
|
message.getUid(),
|
|
|
|
lMessage.getId()
|
|
|
|
});
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
LocalMessage placeHolder = new LocalMessage(oldUID, this);
|
|
|
|
placeHolder.setFlagInternal(Flag.DELETED, true);
|
|
|
|
placeHolder.setFlagInternal(Flag.SEEN, true);
|
|
|
|
appendMessages(new Message[] { placeHolder });
|
|
|
|
}
|
|
|
|
|
2009-03-05 02:32:45 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The method differs slightly from the contract; If an incoming message already has a uid
|
|
|
|
* assigned and it matches the uid of an existing message then this message will replace the
|
|
|
|
* old message. It is implemented as a delete/insert. This functionality is used in saving
|
|
|
|
* of drafts and re-synchronization of updated server messages.
|
2010-05-21 11:34:29 -04:00
|
|
|
*
|
|
|
|
* NOTE that although this method is located in the LocalStore class, it is not guaranteed
|
|
|
|
* that the messages supplied as parameters are actually {@link LocalMessage} instances (in
|
|
|
|
* fact, in most cases, they are not). Therefore, if you want to make local changes only to a
|
|
|
|
* message, retrieve the appropriate local message instance first (if it already exists).
|
2008-11-01 17:32:06 -04:00
|
|
|
*/
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public void appendMessages(Message[] messages) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
appendMessages(messages, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The method differs slightly from the contract; If an incoming message already has a uid
|
|
|
|
* assigned and it matches the uid of an existing message then this message will replace the
|
|
|
|
* old message. It is implemented as a delete/insert. This functionality is used in saving
|
|
|
|
* of drafts and re-synchronization of updated server messages.
|
2010-05-21 11:34:29 -04:00
|
|
|
*
|
|
|
|
* NOTE that although this method is located in the LocalStore class, it is not guaranteed
|
|
|
|
* that the messages supplied as parameters are actually {@link LocalMessage} instances (in
|
|
|
|
* fact, in most cases, they are not). Therefore, if you want to make local changes only to a
|
|
|
|
* message, retrieve the appropriate local message instance first (if it already exists).
|
2008-11-01 17:32:06 -04:00
|
|
|
*/
|
2010-03-03 23:00:30 -05:00
|
|
|
private void appendMessages(Message[] messages, boolean copy) throws MessagingException
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Message message : messages)
|
|
|
|
{
|
|
|
|
if (!(message instanceof MimeMessage))
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new Error("LocalStore can only store Messages that extend MimeMessage");
|
|
|
|
}
|
|
|
|
|
|
|
|
String uid = message.getUid();
|
2010-03-03 23:00:30 -05:00
|
|
|
if (uid == null || copy)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-12-14 21:50:53 -05:00
|
|
|
uid = K9.LOCAL_UID_PREFIX + UUID.randomUUID().toString();
|
2010-03-03 23:00:30 -05:00
|
|
|
if (!copy)
|
|
|
|
{
|
|
|
|
message.setUid(uid);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else
|
|
|
|
{
|
2009-12-07 23:58:10 -05:00
|
|
|
Message oldMessage = getMessage(uid);
|
2009-10-21 20:41:06 -04:00
|
|
|
if (oldMessage != null && oldMessage.isSet(Flag.SEEN) == false)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
setUnreadMessageCount(getUnreadMessageCount() - 1);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-04-16 10:33:54 -04:00
|
|
|
if (oldMessage != null && oldMessage.isSet(Flag.FLAGGED) == true)
|
|
|
|
{
|
|
|
|
setFlaggedMessageCount(getFlaggedMessageCount() - 1);
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* The message may already exist in this Folder, so delete it first.
|
|
|
|
*/
|
|
|
|
deleteAttachments(message.getUid());
|
|
|
|
mDb.execSQL("DELETE FROM messages WHERE folder_id = ? AND uid = ?",
|
2009-11-24 19:40:29 -05:00
|
|
|
new Object[] { mFolderId, message.getUid() });
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
ArrayList<Part> viewables = new ArrayList<Part>();
|
|
|
|
ArrayList<Part> attachments = new ArrayList<Part>();
|
|
|
|
MimeUtility.collectParts(message, viewables, attachments);
|
|
|
|
|
|
|
|
StringBuffer sbHtml = new StringBuffer();
|
|
|
|
StringBuffer sbText = new StringBuffer();
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Part viewable : viewables)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
String text = MimeUtility.getTextFromPart(viewable);
|
|
|
|
/*
|
|
|
|
* Anything with MIME type text/html will be stored as such. Anything
|
|
|
|
* else will be stored as text/plain.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
if (viewable.getMimeType().equalsIgnoreCase("text/html"))
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
sbHtml.append(text);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
sbText.append(text);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new MessagingException("Unable to get text for message part", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-20 00:39:51 -04:00
|
|
|
String text = sbText.toString();
|
|
|
|
String html = markupContent(text, sbHtml.toString());
|
2010-01-12 22:36:36 -05:00
|
|
|
String preview = calculateContentPreview(text);
|
2009-05-03 16:52:32 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
ContentValues cv = new ContentValues();
|
2009-12-07 23:58:10 -05:00
|
|
|
cv.put("uid", uid);
|
2008-11-01 17:32:06 -04:00
|
|
|
cv.put("subject", message.getSubject());
|
|
|
|
cv.put("sender_list", Address.pack(message.getFrom()));
|
|
|
|
cv.put("date", message.getSentDate() == null
|
2009-11-24 19:40:29 -05:00
|
|
|
? System.currentTimeMillis() : message.getSentDate().getTime());
|
2008-11-01 17:32:06 -04:00
|
|
|
cv.put("flags", Utility.combine(message.getFlags(), ',').toUpperCase());
|
2009-11-29 23:03:16 -05:00
|
|
|
cv.put("deleted", message.isSet(Flag.DELETED) ? 1 : 0);
|
2008-11-01 17:32:06 -04:00
|
|
|
cv.put("folder_id", mFolderId);
|
|
|
|
cv.put("to_list", Address.pack(message.getRecipients(RecipientType.TO)));
|
|
|
|
cv.put("cc_list", Address.pack(message.getRecipients(RecipientType.CC)));
|
|
|
|
cv.put("bcc_list", Address.pack(message.getRecipients(RecipientType.BCC)));
|
2009-05-20 00:39:51 -04:00
|
|
|
cv.put("html_content", html.length() > 0 ? html : null);
|
|
|
|
cv.put("text_content", text.length() > 0 ? text : null);
|
2010-01-12 22:36:36 -05:00
|
|
|
cv.put("preview", preview.length() > 0 ? preview : null);
|
2008-11-01 17:32:06 -04:00
|
|
|
cv.put("reply_to_list", Address.pack(message.getReplyTo()));
|
|
|
|
cv.put("attachment_count", attachments.size());
|
|
|
|
cv.put("internal_date", message.getInternalDate() == null
|
2010-07-14 23:47:45 -04:00
|
|
|
? System.currentTimeMillis() : message.getInternalDate().getTime());
|
|
|
|
|
2009-12-07 23:58:10 -05:00
|
|
|
String messageId = message.getMessageId();
|
2009-12-20 00:41:43 -05:00
|
|
|
if (messageId != null)
|
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-07 23:58:10 -05:00
|
|
|
cv.put("message_id", messageId);
|
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-07 23:58:10 -05:00
|
|
|
long messageUid = mDb.insert("messages", "uid", cv);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Part attachment : attachments)
|
|
|
|
{
|
2009-12-07 23:58:10 -05:00
|
|
|
saveAttachment(messageUid, attachment, copy);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-12-07 23:58:10 -05:00
|
|
|
saveHeaders(messageUid, (MimeMessage)message);
|
2009-10-21 20:41:06 -04:00
|
|
|
if (message.isSet(Flag.SEEN) == false)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
setUnreadMessageCount(getUnreadMessageCount() + 1);
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2010-04-16 10:33:54 -04:00
|
|
|
if (message.isSet(Flag.FLAGGED) == true)
|
|
|
|
{
|
|
|
|
setFlaggedMessageCount(getFlaggedMessageCount() + 1);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new MessagingException("Error appending message", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the given message in the LocalStore without first deleting the existing
|
|
|
|
* message (contrast with appendMessages). This method is used to store changes
|
|
|
|
* to the given message while updating attachments and not removing existing
|
|
|
|
* attachment data.
|
|
|
|
* TODO In the future this method should be combined with appendMessages since the Message
|
|
|
|
* contains enough data to decide what to do.
|
|
|
|
* @param message
|
|
|
|
* @throws MessagingException
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public void updateMessage(LocalMessage message) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
ArrayList<Part> viewables = new ArrayList<Part>();
|
|
|
|
ArrayList<Part> attachments = new ArrayList<Part>();
|
2009-12-07 23:58:10 -05:00
|
|
|
|
|
|
|
message.buildMimeRepresentation();
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
MimeUtility.collectParts(message, viewables, attachments);
|
|
|
|
|
|
|
|
StringBuffer sbHtml = new StringBuffer();
|
|
|
|
StringBuffer sbText = new StringBuffer();
|
2009-11-24 19:40:29 -05:00
|
|
|
for (int i = 0, count = viewables.size(); i < count; i++)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
Part viewable = viewables.get(i);
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
String text = MimeUtility.getTextFromPart(viewable);
|
|
|
|
/*
|
|
|
|
* Anything with MIME type text/html will be stored as such. Anything
|
|
|
|
* else will be stored as text/plain.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
if (viewable.getMimeType().equalsIgnoreCase("text/html"))
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
sbHtml.append(text);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
sbText.append(text);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new MessagingException("Unable to get text for message part", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-05-20 00:39:51 -04:00
|
|
|
String text = sbText.toString();
|
|
|
|
String html = markupContent(text, sbHtml.toString());
|
2010-01-12 22:36:36 -05:00
|
|
|
String preview = calculateContentPreview(text);
|
2009-05-03 16:52:32 -04:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
mDb.execSQL("UPDATE messages SET "
|
2009-11-24 19:40:29 -05:00
|
|
|
+ "uid = ?, subject = ?, sender_list = ?, date = ?, flags = ?, "
|
|
|
|
+ "folder_id = ?, to_list = ?, cc_list = ?, bcc_list = ?, "
|
2010-01-12 22:36:36 -05:00
|
|
|
+ "html_content = ?, text_content = ?, preview = ?, reply_to_list = ?, "
|
2009-11-24 19:40:29 -05:00
|
|
|
+ "attachment_count = ? WHERE id = ?",
|
|
|
|
new Object[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
message.getUid(),
|
|
|
|
message.getSubject(),
|
|
|
|
Address.pack(message.getFrom()),
|
|
|
|
message.getSentDate() == null ? System
|
|
|
|
.currentTimeMillis() : message.getSentDate()
|
|
|
|
.getTime(),
|
|
|
|
Utility.combine(message.getFlags(), ',').toUpperCase(),
|
|
|
|
mFolderId,
|
|
|
|
Address.pack(message
|
|
|
|
.getRecipients(RecipientType.TO)),
|
|
|
|
Address.pack(message
|
|
|
|
.getRecipients(RecipientType.CC)),
|
|
|
|
Address.pack(message
|
|
|
|
.getRecipients(RecipientType.BCC)),
|
|
|
|
html.length() > 0 ? html : null,
|
|
|
|
text.length() > 0 ? text : null,
|
2010-01-12 22:36:36 -05:00
|
|
|
preview.length() > 0 ? preview : null,
|
2009-12-06 19:56:06 -05:00
|
|
|
Address.pack(message.getReplyTo()),
|
|
|
|
attachments.size(),
|
|
|
|
message.mId
|
|
|
|
});
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
for (int i = 0, count = attachments.size(); i < count; i++)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
Part attachment = attachments.get(i);
|
|
|
|
saveAttachment(message.mId, attachment, false);
|
|
|
|
}
|
2009-06-08 23:11:35 -04:00
|
|
|
saveHeaders(message.getId(), message);
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new MessagingException("Error appending message", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-21 11:34:29 -04:00
|
|
|
/**
|
|
|
|
* Save the headers of the given message. Note that the message is not
|
|
|
|
* necessarily a {@link LocalMessage} instance.
|
|
|
|
*/
|
|
|
|
private void saveHeaders(long id, MimeMessage message) throws MessagingException
|
2009-06-08 23:11:35 -04:00
|
|
|
{
|
2010-05-21 11:34:29 -04:00
|
|
|
boolean saveAllHeaders = mAccount.isSaveAllHeaders();
|
|
|
|
boolean gotAdditionalHeaders = false;
|
|
|
|
|
2009-06-08 23:11:35 -04:00
|
|
|
deleteHeaders(id);
|
|
|
|
for (String name : message.getHeaderNames())
|
|
|
|
{
|
2010-05-21 11:34:29 -04:00
|
|
|
if (saveAllHeaders || HEADERS_TO_SAVE.contains(name))
|
2009-06-08 23:11:35 -04:00
|
|
|
{
|
|
|
|
String[] values = message.getHeader(name);
|
|
|
|
for (String value : values)
|
|
|
|
{
|
|
|
|
ContentValues cv = new ContentValues();
|
|
|
|
cv.put("message_id", id);
|
|
|
|
cv.put("name", name);
|
|
|
|
cv.put("value", value);
|
|
|
|
mDb.insert("headers", "name", cv);
|
|
|
|
}
|
|
|
|
}
|
2010-05-21 11:34:29 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
gotAdditionalHeaders = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!gotAdditionalHeaders)
|
2010-05-30 00:17:00 -04:00
|
|
|
{
|
2010-05-21 11:34:29 -04:00
|
|
|
// Remember that all headers for this message have been saved, so it is
|
|
|
|
// not necessary to download them again in case the user wants to see all headers.
|
|
|
|
List<Flag> appendedFlags = new ArrayList<Flag>();
|
|
|
|
appendedFlags.addAll(Arrays.asList(message.getFlags()));
|
|
|
|
appendedFlags.add(Flag.X_GOT_ALL_HEADERS);
|
|
|
|
|
|
|
|
mDb.execSQL("UPDATE messages " + "SET flags = ? " + " WHERE id = ?", new Object[]
|
2010-05-30 00:17:00 -04:00
|
|
|
{ Utility.combine(appendedFlags.toArray(), ',').toUpperCase(), id });
|
2009-06-08 23:11:35 -04:00
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-06-08 23:11:35 -04:00
|
|
|
private void deleteHeaders(long id)
|
|
|
|
{
|
|
|
|
mDb.execSQL("DELETE FROM headers WHERE id = ?",
|
2009-11-24 19:40:29 -05:00
|
|
|
new Object[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
id
|
|
|
|
});
|
2009-06-08 23:11:35 -04:00
|
|
|
}
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/**
|
|
|
|
* @param messageId
|
|
|
|
* @param attachment
|
|
|
|
* @param attachmentId -1 to create a new attachment or >= 0 to update an existing
|
|
|
|
* @throws IOException
|
|
|
|
* @throws MessagingException
|
|
|
|
*/
|
|
|
|
private void saveAttachment(long messageId, Part attachment, boolean saveAsNew)
|
2009-11-24 19:40:29 -05:00
|
|
|
throws IOException, MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
long attachmentId = -1;
|
|
|
|
Uri contentUri = null;
|
|
|
|
int size = -1;
|
|
|
|
File tempAttachmentFile = null;
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if ((!saveAsNew) && (attachment instanceof LocalAttachmentBodyPart))
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
attachmentId = ((LocalAttachmentBodyPart) attachment).getAttachmentId();
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (attachment.getBody() != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
Body body = attachment.getBody();
|
2009-11-24 19:40:29 -05:00
|
|
|
if (body instanceof LocalAttachmentBody)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
contentUri = ((LocalAttachmentBody) body).getContentUri();
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* If the attachment has a body we're expected to save it into the local store
|
|
|
|
* so we copy the data into a cached attachment file.
|
|
|
|
*/
|
|
|
|
InputStream in = attachment.getBody().getInputStream();
|
2010-02-17 22:28:31 -05:00
|
|
|
tempAttachmentFile = File.createTempFile("att", null, mAttachmentsDir);
|
2008-11-01 17:32:06 -04:00
|
|
|
FileOutputStream out = new FileOutputStream(tempAttachmentFile);
|
|
|
|
size = IOUtils.copy(in, out);
|
|
|
|
in.close();
|
|
|
|
out.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
if (size == -1)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* If the attachment is not yet downloaded see if we can pull a size
|
|
|
|
* off the Content-Disposition.
|
|
|
|
*/
|
|
|
|
String disposition = attachment.getDisposition();
|
2009-11-24 19:40:29 -05:00
|
|
|
if (disposition != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
String s = MimeUtility.getHeaderParameter(disposition, "size");
|
2009-11-24 19:40:29 -05:00
|
|
|
if (s != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
size = Integer.parseInt(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
if (size == -1)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
String storeData =
|
|
|
|
Utility.combine(attachment.getHeader(
|
2009-11-24 19:40:29 -05:00
|
|
|
MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA), ',');
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
String name = MimeUtility.getHeaderParameter(attachment.getContentType(), "name");
|
2010-07-11 09:44:16 -04:00
|
|
|
String contentId = MimeUtility.getHeaderParameter(attachment.getContentId(), null);
|
|
|
|
|
2009-01-24 14:35:57 -05:00
|
|
|
String contentDisposition = MimeUtility.unfoldAndDecode(attachment.getDisposition());
|
|
|
|
if (name == null && contentDisposition != null)
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
name = MimeUtility.getHeaderParameter(contentDisposition, "filename");
|
2009-01-24 14:35:57 -05:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
if (attachmentId == -1)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
ContentValues cv = new ContentValues();
|
|
|
|
cv.put("message_id", messageId);
|
|
|
|
cv.put("content_uri", contentUri != null ? contentUri.toString() : null);
|
|
|
|
cv.put("store_data", storeData);
|
|
|
|
cv.put("size", size);
|
|
|
|
cv.put("name", name);
|
|
|
|
cv.put("mime_type", attachment.getMimeType());
|
|
|
|
|
|
|
|
attachmentId = mDb.insert("attachments", "message_id", cv);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
ContentValues cv = new ContentValues();
|
|
|
|
cv.put("content_uri", contentUri != null ? contentUri.toString() : null);
|
|
|
|
cv.put("size", size);
|
|
|
|
mDb.update(
|
2009-11-24 19:40:29 -05:00
|
|
|
"attachments",
|
|
|
|
cv,
|
|
|
|
"id = ?",
|
|
|
|
new String[] { Long.toString(attachmentId) });
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2010-07-11 09:44:16 -04:00
|
|
|
if (attachmentId != -1 && tempAttachmentFile != null)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
File attachmentFile = new File(mAttachmentsDir, Long.toString(attachmentId));
|
2008-11-01 17:32:06 -04:00
|
|
|
tempAttachmentFile.renameTo(attachmentFile);
|
|
|
|
contentUri = AttachmentProvider.getAttachmentUri(
|
2009-11-24 19:40:29 -05:00
|
|
|
new File(mPath).getName(),
|
|
|
|
attachmentId);
|
2008-11-01 17:32:06 -04:00
|
|
|
attachment.setBody(new LocalAttachmentBody(contentUri, mApplication));
|
|
|
|
ContentValues cv = new ContentValues();
|
|
|
|
cv.put("content_uri", contentUri != null ? contentUri.toString() : null);
|
|
|
|
mDb.update(
|
2009-11-24 19:40:29 -05:00
|
|
|
"attachments",
|
|
|
|
cv,
|
|
|
|
"id = ?",
|
|
|
|
new String[] { Long.toString(attachmentId) });
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2010-07-11 09:44:16 -04:00
|
|
|
/* The message has attachment with Content-ID */
|
|
|
|
if (contentId != null && contentUri != null)
|
|
|
|
{
|
|
|
|
Cursor cursor = null;
|
|
|
|
cursor = mDb.query("messages", new String[] { "html_content" }, "id = ?", new String[] { Long.toString(messageId) }, null, null, null);
|
2010-07-13 17:16:56 -04:00
|
|
|
try
|
|
|
|
{
|
2010-07-11 09:44:16 -04:00
|
|
|
if (cursor.moveToNext())
|
|
|
|
{
|
|
|
|
String new_html;
|
|
|
|
|
|
|
|
new_html = cursor.getString(0);
|
|
|
|
new_html = new_html.replaceAll("cid:" + contentId, contentUri.toString());
|
|
|
|
|
|
|
|
ContentValues cv = new ContentValues();
|
|
|
|
cv.put("html_content", new_html);
|
|
|
|
mDb.update("messages", cv, "id = ?", new String[] { Long.toString(messageId) });
|
|
|
|
}
|
|
|
|
}
|
2010-07-13 17:16:56 -04:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (cursor != null)
|
|
|
|
{
|
|
|
|
cursor.close();
|
|
|
|
}
|
2010-07-11 09:44:16 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (attachmentId != -1 && attachment instanceof LocalAttachmentBodyPart)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
((LocalAttachmentBodyPart) attachment).setAttachmentId(attachmentId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Changes the stored uid of the given message (using it's internal id as a key) to
|
|
|
|
* the uid in the message.
|
|
|
|
* @param message
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public void changeUid(LocalMessage message) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
ContentValues cv = new ContentValues();
|
|
|
|
cv.put("uid", message.getUid());
|
|
|
|
mDb.update("messages", cv, "id = ?", new String[] { Long.toString(message.mId) });
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setFlags(Message[] messages, Flag[] flags, boolean value)
|
2009-11-24 19:40:29 -05:00
|
|
|
throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Message message : messages)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
message.setFlags(flags, value);
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
@Override
|
|
|
|
public void setFlags(Flag[] flags, boolean value)
|
2009-11-24 19:40:29 -05:00
|
|
|
throws MessagingException
|
|
|
|
{
|
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
|
|
|
open(OpenMode.READ_WRITE);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Message message : getMessages(null))
|
|
|
|
{
|
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
|
|
|
message.setFlags(flags, value);
|
|
|
|
}
|
|
|
|
}
|
2008-11-01 17:32:06 -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
|
|
|
@Override
|
|
|
|
public String getUidFromMessageId(Message message) throws MessagingException
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
throw new MessagingException("Cannot call getUidFromMessageId on LocalFolder");
|
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-27 11:50:21 -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
|
|
|
public void deleteMessagesOlderThan(long cutoff) throws MessagingException
|
|
|
|
{
|
2009-11-24 19:40:29 -05:00
|
|
|
open(OpenMode.READ_ONLY);
|
|
|
|
mDb.execSQL("DELETE FROM messages WHERE folder_id = ? and date < ?", new Object[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
Long.toString(mFolderId), new Long(cutoff)
|
|
|
|
});
|
2010-04-16 10:33:54 -04:00
|
|
|
resetUnreadAndFlaggedCounts();
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2010-04-16 10:33:54 -04:00
|
|
|
private void resetUnreadAndFlaggedCounts()
|
2009-10-21 20:41:06 -04:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
int newUnread = 0;
|
2010-04-16 10:33:54 -04:00
|
|
|
int newFlagged = 0;
|
2009-10-21 20:41:06 -04:00
|
|
|
Message[] messages = getMessages(null);
|
|
|
|
for (Message message : messages)
|
|
|
|
{
|
|
|
|
if (message.isSet(Flag.SEEN) == false)
|
|
|
|
{
|
|
|
|
newUnread++;
|
|
|
|
}
|
2010-04-16 10:33:54 -04:00
|
|
|
if (message.isSet(Flag.FLAGGED) == true)
|
|
|
|
{
|
|
|
|
newFlagged++;
|
|
|
|
}
|
2009-10-21 20:41:06 -04:00
|
|
|
}
|
|
|
|
setUnreadMessageCount(newUnread);
|
2010-04-16 10:33:54 -04:00
|
|
|
setFlaggedMessageCount(newFlagged);
|
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 fetch all messages from LocalStore", e);
|
2009-10-21 20:41:06 -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
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public void delete(boolean recurse) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
// We need to open the folder first to make sure we've got it's id
|
|
|
|
open(OpenMode.READ_ONLY);
|
|
|
|
Message[] messages = getMessages(null);
|
2009-11-24 19:40:29 -05:00
|
|
|
for (Message message : messages)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
deleteAttachments(message.getUid());
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
mDb.execSQL("DELETE FROM folders WHERE id = ?", new Object[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
Long.toString(mFolderId),
|
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public boolean equals(Object o)
|
|
|
|
{
|
|
|
|
if (o instanceof LocalFolder)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return ((LocalFolder)o).mName.equals(mName);
|
|
|
|
}
|
|
|
|
return super.equals(o);
|
|
|
|
}
|
|
|
|
|
2010-03-03 23:00:30 -05:00
|
|
|
@Override
|
|
|
|
public int hashCode()
|
|
|
|
{
|
|
|
|
return mName.hashCode();
|
|
|
|
}
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public Flag[] getPermanentFlags() throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return PERMANENT_FLAGS;
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
private void deleteAttachments(String uid) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
open(OpenMode.READ_WRITE);
|
|
|
|
Cursor messagesCursor = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
messagesCursor = mDb.query(
|
2009-11-24 19:40:29 -05:00
|
|
|
"messages",
|
|
|
|
new String[] { "id" },
|
|
|
|
"folder_id = ? AND uid = ?",
|
|
|
|
new String[] { Long.toString(mFolderId), uid },
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null);
|
|
|
|
while (messagesCursor.moveToNext())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
long messageId = messagesCursor.getLong(0);
|
|
|
|
Cursor attachmentsCursor = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
attachmentsCursor = mDb.query(
|
2009-11-24 19:40:29 -05:00
|
|
|
"attachments",
|
|
|
|
new String[] { "id" },
|
|
|
|
"message_id = ?",
|
|
|
|
new String[] { Long.toString(messageId) },
|
|
|
|
null,
|
|
|
|
null,
|
|
|
|
null);
|
|
|
|
while (attachmentsCursor.moveToNext())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
long attachmentId = attachmentsCursor.getLong(0);
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
2010-02-17 22:28:31 -05:00
|
|
|
File file = new File(mAttachmentsDir, Long.toString(attachmentId));
|
2009-11-24 19:40:29 -05:00
|
|
|
if (file.exists())
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
file.delete();
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (attachmentsCursor != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
attachmentsCursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
finally
|
|
|
|
{
|
|
|
|
if (messagesCursor != null)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
messagesCursor.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-05-03 16:52:32 -04:00
|
|
|
|
2010-01-12 22:36:36 -05:00
|
|
|
/*
|
|
|
|
* calcualteContentPreview
|
|
|
|
* Takes a plain text message body as a string.
|
|
|
|
* Returns a message summary as a string suitable for showing in a message list
|
|
|
|
*
|
|
|
|
* A message summary should be about the first 160 characters
|
|
|
|
* of unique text written by the message sender
|
|
|
|
* Quoted text, "On $date" and so on will be stripped out.
|
|
|
|
* All newlines and whitespace will be compressed.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public String calculateContentPreview(String text)
|
|
|
|
{
|
2010-01-13 20:07:28 -05:00
|
|
|
if (text == null)
|
|
|
|
{
|
2010-01-12 22:36:36 -05:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2010-06-06 18:28:29 -04:00
|
|
|
text = text.replaceAll("(?ms)^-----BEGIN PGP SIGNED MESSAGE-----.(Hash:\\s*?.*?$)?","");
|
2010-07-23 22:09:12 -04:00
|
|
|
text = text.replaceAll("https?://\\S+","...");
|
2010-06-06 17:33:15 -04:00
|
|
|
text = text.replaceAll("^.*\\w.*:","");
|
2010-01-12 22:36:36 -05:00
|
|
|
text = text.replaceAll("(?m)^>.*$","");
|
|
|
|
text = text.replaceAll("^On .*wrote.?$","");
|
|
|
|
text = text.replaceAll("(\\r|\\n)+"," ");
|
|
|
|
text = text.replaceAll("\\s+"," ");
|
2010-06-06 17:33:05 -04:00
|
|
|
if (text.length() <= 250)
|
2010-01-13 20:07:28 -05:00
|
|
|
{
|
2010-01-12 22:36:36 -05:00
|
|
|
return text;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-06 17:33:05 -04:00
|
|
|
text = text.substring(0,250);
|
2010-01-12 22:36:36 -05:00
|
|
|
return text;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
public String markupContent(String text, String html)
|
|
|
|
{
|
|
|
|
if (text.length() > 0 && html.length() == 0)
|
|
|
|
{
|
2009-05-20 00:39:51 -04:00
|
|
|
html = htmlifyString(text);
|
|
|
|
}
|
2009-05-03 16:52:32 -04:00
|
|
|
|
2010-08-01 21:24:40 -04:00
|
|
|
html = convertEmoji2ImgForDocomo(html);
|
|
|
|
|
2010-07-11 09:44:16 -04:00
|
|
|
return html;
|
2009-05-20 00:39:51 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
|
|
|
public String htmlifyString(String text)
|
|
|
|
{
|
2009-05-10 03:05:24 -04:00
|
|
|
StringReader reader = new StringReader(text);
|
|
|
|
StringBuilder buff = new StringBuilder(text.length() + 512);
|
|
|
|
int c = 0;
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
|
|
|
while ((c = reader.read()) != -1)
|
|
|
|
{
|
|
|
|
switch (c)
|
|
|
|
{
|
2009-05-10 03:05:24 -04:00
|
|
|
case '&':
|
|
|
|
buff.append("&");
|
|
|
|
break;
|
|
|
|
case '<':
|
|
|
|
buff.append("<");
|
|
|
|
break;
|
|
|
|
case '>':
|
|
|
|
buff.append(">");
|
|
|
|
break;
|
|
|
|
case '\r':
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
buff.append((char)c);
|
|
|
|
}//switch
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
2009-05-10 03:05:24 -04:00
|
|
|
//Should never happen
|
2009-12-14 21:50:53 -05:00
|
|
|
Log.e(K9.LOG_TAG, null, e);
|
2009-05-10 03:05:24 -04:00
|
|
|
}
|
|
|
|
text = buff.toString();
|
2009-11-27 23:56:47 -05:00
|
|
|
text = text.replaceAll("\\s*([-=_]{30,}+)\\s*","<hr />");
|
2009-12-01 22:16:31 -05:00
|
|
|
text = text.replaceAll("(?m)^([^\r\n]{4,}[\\s\\w,:;+/])(?:\r\n|\n|\r)(?=[a-z]\\S{0,10}[\\s\\n\\r])","$1 ");
|
|
|
|
text = text.replaceAll("(?m)(\r\n|\n|\r){4,}","\n\n");
|
2009-05-10 03:05:24 -04:00
|
|
|
|
2010-06-06 17:33:33 -04:00
|
|
|
|
2009-05-10 03:05:24 -04:00
|
|
|
Matcher m = Regex.WEB_URL_PATTERN.matcher(text);
|
|
|
|
StringBuffer sb = new StringBuffer(text.length() + 512);
|
2010-08-01 21:27:50 -04:00
|
|
|
sb.append("<html><head><meta name=\"viewport\" content=\"width=device-width, height=device-height\"></head><body>");
|
2010-06-06 17:33:33 -04:00
|
|
|
sb.append(htmlifyMessageHeader());
|
2009-11-24 19:40:29 -05:00
|
|
|
while (m.find())
|
|
|
|
{
|
2009-05-10 03:05:24 -04:00
|
|
|
int start = m.start();
|
2009-11-24 19:40:29 -05:00
|
|
|
if (start == 0 || (start != 0 && text.charAt(start - 1) != '@'))
|
|
|
|
{
|
2009-05-10 03:05:24 -04:00
|
|
|
m.appendReplacement(sb, "<a href=\"$0\">$0</a>");
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-05-10 03:05:24 -04:00
|
|
|
m.appendReplacement(sb, "$0");
|
|
|
|
}
|
|
|
|
}
|
2009-11-27 23:56:47 -05:00
|
|
|
|
2009-11-29 23:03:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
2009-05-10 03:05:24 -04:00
|
|
|
m.appendTail(sb);
|
2010-06-06 17:33:33 -04:00
|
|
|
sb.append(htmlifyMessageFooter());
|
|
|
|
sb.append("</body></html>");
|
2009-05-10 03:05:24 -04:00
|
|
|
text = sb.toString();
|
2009-05-03 16:52:32 -04:00
|
|
|
|
|
|
|
return text;
|
|
|
|
}
|
2010-03-07 12:02:21 -05:00
|
|
|
|
2010-06-06 17:33:33 -04:00
|
|
|
private String htmlifyMessageHeader()
|
|
|
|
{
|
|
|
|
if (K9.messageViewFixedWidthFont())
|
|
|
|
{
|
|
|
|
return "<pre style=\"white-space: pre-wrap; word-wrap:break-word; \">";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return "<div style=\"white-space: pre-wrap; word-wrap:break-word; \">";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private String htmlifyMessageFooter()
|
|
|
|
{
|
|
|
|
if (K9.messageViewFixedWidthFont())
|
|
|
|
{
|
|
|
|
return "</pre>";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return "</div>";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-01 21:24:40 -04:00
|
|
|
public String convertEmoji2ImgForDocomo(String html)
|
|
|
|
{
|
|
|
|
StringReader reader = new StringReader(html);
|
|
|
|
StringBuilder buff = new StringBuilder(html.length() + 512);
|
|
|
|
int c = 0;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
while ((c = reader.read()) != -1)
|
|
|
|
{
|
|
|
|
switch (c)
|
|
|
|
{
|
|
|
|
// Emoji
|
|
|
|
case 0xE63E: // Fine
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sun.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE63F: // Cloudy
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/cloud.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE640: // Rain
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/rain.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE641: // Snow
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/snow.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE642: // Thunder
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/thunder.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE643: // Typhoon
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/typhoon.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE644: // Fog
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/mist.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE645: // Drizzle
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sprinkle.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Zodiacal symbol
|
|
|
|
case 0xE646: // Aries
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/aries.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE647: // Taurus
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/taurus.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE648: // Gemini
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/gemini.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE649: // Cancer
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/cancer.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE64A: // Leo
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/leo.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE64B: // Virgo
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/virgo.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE64C: // Libra
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/libra.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE64D: // Scorpio
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/scorpius.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE64E: // Sagittarius
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sagittarius.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE64F: // Capricorn
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/capricornus.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE650: // Aquarius
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/aquarius.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE651: // Pisces
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/pisces.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE652:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sports.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE653:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/baseball.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE654:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/golf.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE655:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/tennis.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE656:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/soccer.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE657:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/ski.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE658:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/basketball.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE659:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/motorsports.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE65A:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/pocketbell.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE65B:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/train.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE65C:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/subway.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE65D:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bullettrain.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE65E:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/car.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE65F:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/rvcar.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE660:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bus.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE661:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/ship.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE662:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/airplane.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE663:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/house.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE664:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/building.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE665:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/postoffice.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE666:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/hospital.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE667:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bank.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE668:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/atm.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE669:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/hotel.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE66A:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/24hours.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE66B:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/gasstation.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE66C:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/parking.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE66D:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/signaler.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE66E:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/toilet.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE66F:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/restaurant.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE670:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/cafe.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE671:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bar.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE672:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/beer.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE673:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/fastfood.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE674:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/boutique.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE675: // Hairdresser
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/hairsalon.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE676:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/karaoke.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE677:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/movie.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE678:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/upwardright.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE679:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/carouselpony.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE67A:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/music.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE67B:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/art.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE67C:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/drama.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE67D:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/event.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE67E:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/ticket.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE67F:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/smoking.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE680:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/nosmoking.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE681:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/camera.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE682:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bag.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE683:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/book.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE684:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/ribbon.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE685:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/present.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE686:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/birthday.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE687:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/telephone.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE688:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/mobilephone.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE689:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/memo.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE68A:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/tv.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE68B:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/game.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE68C:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/cd.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE68D:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/heart.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE68E:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/spade.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE68F:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/diamond.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE690:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/club.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE691: // Eyes
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/eye.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE692: // Ear
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/ear.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE693:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/rock.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE694:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/scissors.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE695:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/paper.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE696:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/downwardright.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE697:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/upwardleft.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE698:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/foot.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE699:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/shoe.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE69A:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/eyeglass.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE69B:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/wheelchair.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE69C: // New moon
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/newmoon.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE69D: // Waning moon
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/moon1.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE69E: // Half moon
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/moon2.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE69F: // Crescent moon
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/moon3.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE6A0: // Full moon
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/fullmoon.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6A1:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/dog.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6A2:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/cat.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6A3:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/yacht.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6A4:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/xmas.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6A5:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/downwardleft.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE6AC:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/slate.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6AD:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/pouch.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6AE:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/pen.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE6B1: // Silhouette
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/shadow.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6B2:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/chair.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6B3: // Night
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/night.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE6B7:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/soon.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6B8:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/on.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6B9:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/end.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6BA: // Clock
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/clock.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE6CE:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/phoneto.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6CF:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/mailto.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE6D0:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/faxto.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6D1:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/info01.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6D2:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/info02.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6D3:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/mail.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6D4:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/by-d.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6D5:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/d-point.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6D6:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/yen.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6D7:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/free.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6D8:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/id.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6D9:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/key.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6DA:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/enter.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6DB:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/clear.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6DC:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/search.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6DD:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/new.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6DE:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/flag.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6DF:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/freedial.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE6E0:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sharp.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6E1:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/mobaq.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6E2:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/one.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6E3:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/two.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6E4:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/three.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6E5:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/four.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6E6:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/five.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6E7:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/six.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6E8:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/seven.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6E9:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/eight.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6EA:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/nine.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6EB:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/zero.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6EC: // Black heart
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/heart01.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6ED:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/heart02.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6EE:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/heart03.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6EF:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/heart04.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE6F0: // Happy face
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/happy01.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6F1:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/angry.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6F2:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/despair.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6F3:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sad.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6F4:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/wobbly.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6F5:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/up.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6F6:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/note.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6F7:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/spa.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6F8:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/cute.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6F9: // Kiss
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/kissmark.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6FA:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/shine.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6FB:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/flair.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6FC:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/annoy.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6FD:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/punch.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6FE:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bomb.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE6FF:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/notes.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE700:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/down.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE701:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sleepy.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE702:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sign01.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE703:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sign02.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE704:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sign03.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE705:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/impact.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE706:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sweat01.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE707:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sweat02.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE708:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/dash.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE709:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sign04.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE70A:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sign05.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE70B:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/ok.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE70C:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/appli01.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE70D:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/appli02.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE70E:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/t-shirt.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE70F:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/moneybag.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE710: // Make-up
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/rouge.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE711:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/denim.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE712:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/snowboard.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE713:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bell.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE714:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/door.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE715:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/dollar.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE716:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/pc.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE717:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/loveletter.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE718:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/wrench.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE719:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/pencil.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE71A:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/crown.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE71B:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/ring.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE71C: // Sandglass
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/sandclock.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE71D:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bicycle.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE71E:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/japanesetea.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE71F: // Wrist watch
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/watch.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE720:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/think.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE721:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/confident.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE722:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/coldsweats01.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE723:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/coldsweats02.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE724: // Pouting face
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/pout.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE725:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/gawk.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE726:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/lovely.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE727:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/good.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE728: // Sticking tongue out
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bleah.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE729:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/wink.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE72A:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/happy02.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE72B: // Enduring face
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bearing.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE72C:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/catface.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE72D:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/crying.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE72E: // Tear
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/weep.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE72F:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/ng.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE730:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/clip.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE731:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/copyright.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE732:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/tm.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE733:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/run.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE734:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/secret.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE735:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/recycle.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE736:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/r-mark.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE737:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/danger.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE738:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/ban.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE739:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/empty.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE73A:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/pass.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE73B:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/full.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE73C:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/leftright.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE73D:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/updown.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE73E:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/school.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE73F: // Wave
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/wave.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE740:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/fuji.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE741: // 4-leaf clover
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/clover.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE742: // Cherries
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/cherry.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE743: // Tulip
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/tulip.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE744: // Banana
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/banana.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE745: // Apple
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/apple.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE746: // Seedling
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bud.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE747: // Maple leaf
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/maple.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE748: // Cherry blossom
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/cherryblossom.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE749:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/riceball.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE74A:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/cake.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE74B:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bottle.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE74C:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/noodle.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE74D:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/bread.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE74E:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/snail.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE74F:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/chick.gif\"/>");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xE750:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/penguin.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE751:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/fish.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE752:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/delicious.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE753:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/smile.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE754:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/horse.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE755:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/pig.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE756:
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/wine.gif\"/>");
|
|
|
|
break;
|
|
|
|
case 0xE757: // Very thin
|
|
|
|
buff.append("<img src=\"file:///android_asset/emoticons/shock.gif\"/>");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
buff.append((char)c);
|
|
|
|
}//switch
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (IOException e)
|
|
|
|
{
|
|
|
|
//Should never happen
|
|
|
|
Log.e(K9.LOG_TAG, null, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
return buff.toString();
|
|
|
|
}
|
|
|
|
|
2010-03-07 12:02:21 -05:00
|
|
|
@Override
|
|
|
|
public boolean isInTopGroup()
|
|
|
|
{
|
|
|
|
return inTopGroup;
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-03-07 12:02:21 -05:00
|
|
|
public void setInTopGroup(boolean inTopGroup)
|
|
|
|
{
|
|
|
|
this.inTopGroup = inTopGroup;
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public class LocalTextBody extends TextBody
|
|
|
|
{
|
2009-05-20 00:36:20 -04:00
|
|
|
private String mBodyForDisplay;
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public LocalTextBody(String body)
|
|
|
|
{
|
2009-05-20 00:36:20 -04:00
|
|
|
super(body);
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public LocalTextBody(String body, String bodyForDisplay) throws MessagingException
|
|
|
|
{
|
2009-05-20 00:36:20 -04:00
|
|
|
super(body);
|
|
|
|
this.mBodyForDisplay = bodyForDisplay;
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public String getBodyForDisplay()
|
|
|
|
{
|
2009-05-20 00:36:20 -04:00
|
|
|
return mBodyForDisplay;
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void setBodyForDisplay(String mBodyForDisplay)
|
|
|
|
{
|
2009-05-20 00:36:20 -04:00
|
|
|
this.mBodyForDisplay = mBodyForDisplay;
|
|
|
|
}
|
|
|
|
|
|
|
|
}//LocalTextBody
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public class LocalMessage extends MimeMessage
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
private long mId;
|
|
|
|
private int mAttachmentCount;
|
2009-12-01 08:45:28 -05:00
|
|
|
private String mSubject;
|
|
|
|
|
2010-01-12 22:36:36 -05:00
|
|
|
private String mPreview = "";
|
|
|
|
|
2009-12-14 21:51:18 -05:00
|
|
|
private boolean mHeadersLoaded = false;
|
2009-12-06 23:46:42 -05:00
|
|
|
private boolean mMessageDirty = false;
|
|
|
|
|
|
|
|
public LocalMessage()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
LocalMessage(String uid, Folder folder) throws MessagingException
|
|
|
|
{
|
|
|
|
this.mUid = uid;
|
|
|
|
this.mFolder = folder;
|
|
|
|
}
|
|
|
|
|
2009-12-27 11:52:57 -05:00
|
|
|
private void populateFromGetMessageCursor(Cursor cursor)
|
|
|
|
throws MessagingException
|
|
|
|
{
|
|
|
|
this.setSubject(cursor.getString(0) == null ? "" : cursor.getString(0));
|
|
|
|
Address[] from = Address.unpack(cursor.getString(1));
|
|
|
|
if (from.length > 0)
|
|
|
|
{
|
|
|
|
this.setFrom(from[0]);
|
|
|
|
}
|
|
|
|
this.setInternalSentDate(new Date(cursor.getLong(2)));
|
|
|
|
this.setUid(cursor.getString(3));
|
|
|
|
String flagList = cursor.getString(4);
|
|
|
|
if (flagList != null && flagList.length() > 0)
|
|
|
|
{
|
|
|
|
String[] flags = flagList.split(",");
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-25 02:17:15 -04:00
|
|
|
for (String flag : flags)
|
2009-12-27 11:52:57 -05:00
|
|
|
{
|
2010-04-25 02:17:15 -04:00
|
|
|
try
|
2009-12-27 11:52:57 -05:00
|
|
|
{
|
|
|
|
this.setFlagInternal(Flag.valueOf(flag), true);
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
|
2010-04-25 02:17:15 -04:00
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
if ("X_BAD_FLAG".equals(flag) == false)
|
|
|
|
{
|
|
|
|
Log.w(K9.LOG_TAG, "Unable to parse flag " + flag);
|
|
|
|
}
|
|
|
|
}
|
2009-12-27 11:52:57 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
this.mId = cursor.getLong(5);
|
|
|
|
this.setRecipients(RecipientType.TO, Address.unpack(cursor.getString(6)));
|
|
|
|
this.setRecipients(RecipientType.CC, Address.unpack(cursor.getString(7)));
|
|
|
|
this.setRecipients(RecipientType.BCC, Address.unpack(cursor.getString(8)));
|
|
|
|
this.setReplyTo(Address.unpack(cursor.getString(9)));
|
2010-04-05 22:54:48 -04:00
|
|
|
|
2009-12-27 11:52:57 -05:00
|
|
|
this.mAttachmentCount = cursor.getInt(10);
|
|
|
|
this.setInternalDate(new Date(cursor.getLong(11)));
|
|
|
|
this.setMessageId(cursor.getString(12));
|
2010-01-12 22:36:36 -05:00
|
|
|
mPreview = (cursor.getString(14) == null ? "" : cursor.getString(14));
|
2009-12-27 12:22:26 -05:00
|
|
|
if (this.mFolder == null)
|
2009-12-27 11:53:51 -05:00
|
|
|
{
|
|
|
|
LocalFolder f = new LocalFolder(cursor.getInt(13));
|
|
|
|
f.open(LocalFolder.OpenMode.READ_WRITE);
|
|
|
|
this.mFolder = f;
|
|
|
|
}
|
2009-12-27 11:52:57 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-06 23:46:42 -05:00
|
|
|
/* Custom version of writeTo that updates the MIME message based on localMessage
|
|
|
|
* changes.
|
|
|
|
*/
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-12-06 23:46:42 -05:00
|
|
|
public void writeTo(OutputStream out) throws IOException, MessagingException
|
|
|
|
{
|
|
|
|
if (mMessageDirty) buildMimeRepresentation();
|
|
|
|
super.writeTo(out);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void buildMimeRepresentation() throws MessagingException
|
2009-12-01 08:45:28 -05:00
|
|
|
{
|
2009-12-06 23:46:42 -05:00
|
|
|
if (!mMessageDirty)
|
2009-12-01 08:45:28 -05:00
|
|
|
{
|
2009-12-06 23:46:42 -05:00
|
|
|
return;
|
2009-12-01 08:45:28 -05:00
|
|
|
}
|
2009-12-06 23:46:42 -05:00
|
|
|
|
|
|
|
super.setSubject(mSubject);
|
|
|
|
if (this.mFrom != null && this.mFrom.length > 0)
|
2009-12-01 08:45:28 -05:00
|
|
|
{
|
2009-12-06 23:46:42 -05:00
|
|
|
super.setFrom(this.mFrom[0]);
|
2009-12-01 08:45:28 -05:00
|
|
|
}
|
2009-12-06 23:46:42 -05:00
|
|
|
|
|
|
|
super.setReplyTo(mReplyTo);
|
|
|
|
super.setSentDate(this.getSentDate());
|
|
|
|
super.setRecipients(RecipientType.TO, mTo);
|
|
|
|
super.setRecipients(RecipientType.CC, mCc);
|
|
|
|
super.setRecipients(RecipientType.BCC, mBcc);
|
2009-12-07 23:58:10 -05:00
|
|
|
if (mMessageId != null) super.setMessageId(mMessageId);
|
2009-12-06 23:46:42 -05:00
|
|
|
|
|
|
|
mMessageDirty = false;
|
|
|
|
return;
|
2009-12-01 08:45:28 -05:00
|
|
|
}
|
|
|
|
|
2010-01-13 20:07:28 -05:00
|
|
|
public String getPreview()
|
|
|
|
{
|
|
|
|
return mPreview;
|
2010-01-12 22:36:36 -05:00
|
|
|
}
|
2009-12-06 23:46:42 -05:00
|
|
|
|
2009-12-01 08:45:28 -05:00
|
|
|
@Override
|
2009-12-06 23:46:42 -05:00
|
|
|
public String getSubject() throws MessagingException
|
2009-12-01 08:45:28 -05:00
|
|
|
{
|
2009-12-06 23:46:42 -05:00
|
|
|
return mSubject;
|
2009-12-01 08:45:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-06 23:46:42 -05:00
|
|
|
@Override
|
|
|
|
public void setSubject(String subject) throws MessagingException
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-12-06 23:46:42 -05:00
|
|
|
mSubject = subject;
|
|
|
|
mMessageDirty = true;
|
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
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
|
2009-12-06 23:46:42 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-12-07 23:58:10 -05:00
|
|
|
public void setMessageId(String messageId)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-12-06 23:46:42 -05:00
|
|
|
mMessageId = messageId;
|
|
|
|
mMessageDirty = true;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-12-06 23:46:42 -05:00
|
|
|
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public int getAttachmentCount()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return mAttachmentCount;
|
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-12-06 23:46:42 -05:00
|
|
|
public void setFrom(Address from) throws MessagingException
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-12-06 23:46:42 -05:00
|
|
|
this.mFrom = new Address[] { from };
|
|
|
|
mMessageDirty = true;
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2009-12-06 23:46:42 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-12-06 23:46:42 -05:00
|
|
|
public void setReplyTo(Address[] replyTo) throws MessagingException
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-12-06 23:46:42 -05:00
|
|
|
if (replyTo == null || replyTo.length == 0)
|
2009-11-24 19:40:29 -05:00
|
|
|
{
|
2009-12-06 23:46:42 -05:00
|
|
|
mReplyTo = null;
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-12-06 23:46:42 -05:00
|
|
|
mReplyTo = replyTo;
|
2009-11-24 19:40:29 -05:00
|
|
|
}
|
2009-12-06 23:46:42 -05:00
|
|
|
mMessageDirty = true;
|
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
|
|
|
}
|
|
|
|
|
2009-12-06 23:46:42 -05:00
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
/*
|
|
|
|
* For performance reasons, we add headers instead of setting them (see super implementation)
|
|
|
|
* which removes (expensive) them before adding them
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void setRecipients(RecipientType type, Address[] addresses) throws MessagingException
|
|
|
|
{
|
|
|
|
if (type == RecipientType.TO)
|
|
|
|
{
|
|
|
|
if (addresses == null || addresses.length == 0)
|
|
|
|
{
|
|
|
|
this.mTo = null;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.mTo = addresses;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (type == RecipientType.CC)
|
|
|
|
{
|
|
|
|
if (addresses == null || addresses.length == 0)
|
|
|
|
{
|
|
|
|
this.mCc = null;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.mCc = addresses;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (type == RecipientType.BCC)
|
|
|
|
{
|
|
|
|
if (addresses == null || addresses.length == 0)
|
|
|
|
{
|
|
|
|
this.mBcc = null;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this.mBcc = addresses;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new MessagingException("Unrecognized recipient type.");
|
|
|
|
}
|
2009-12-06 23:46:42 -05:00
|
|
|
mMessageDirty = true;
|
2009-06-26 02:55:32 -04:00
|
|
|
}
|
|
|
|
|
2009-12-06 23:46:42 -05:00
|
|
|
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void setFlagInternal(Flag flag, boolean set) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
super.setFlag(flag, set);
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public long getId()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return mId;
|
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public void setFlag(Flag flag, boolean set) throws MessagingException
|
|
|
|
{
|
|
|
|
if (flag == Flag.DELETED && set)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* If a message is being marked as deleted we want to clear out it's content
|
|
|
|
* and attachments as well. Delete will not actually remove the row since we need
|
|
|
|
* to retain the uid for synchronization purposes.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Delete all of the messages' content to save space.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
((LocalFolder) mFolder).deleteAttachments(getUid());
|
|
|
|
|
|
|
|
mDb.execSQL(
|
|
|
|
"UPDATE messages SET " +
|
|
|
|
"deleted = 1," +
|
|
|
|
"subject = NULL, " +
|
|
|
|
"sender_list = NULL, " +
|
|
|
|
"date = NULL, " +
|
|
|
|
"to_list = NULL, " +
|
|
|
|
"cc_list = NULL, " +
|
|
|
|
"bcc_list = NULL, " +
|
2010-01-12 22:36:36 -05:00
|
|
|
"preview = NULL, " +
|
2009-11-24 19:40:29 -05:00
|
|
|
"html_content = NULL, " +
|
|
|
|
"text_content = NULL, " +
|
|
|
|
"reply_to_list = NULL " +
|
|
|
|
"WHERE id = ?",
|
|
|
|
new Object[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
mId
|
|
|
|
});
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
/*
|
|
|
|
* Delete all of the messages' attachments to save space.
|
|
|
|
*/
|
2010-01-03 18:23:13 -05:00
|
|
|
mDb.execSQL("DELETE FROM attachments WHERE message_id = ?",
|
2009-11-24 19:40:29 -05:00
|
|
|
new Object[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
mId
|
|
|
|
});
|
2009-11-24 19:40:29 -05:00
|
|
|
|
2009-06-08 23:11:35 -04:00
|
|
|
((LocalFolder)mFolder).deleteHeaders(mId);
|
|
|
|
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else if (flag == Flag.X_DESTROYED && set)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
((LocalFolder) mFolder).deleteAttachments(getUid());
|
|
|
|
mDb.execSQL("DELETE FROM messages WHERE id = ?",
|
2009-11-24 19:40:29 -05:00
|
|
|
new Object[] { mId });
|
2009-06-08 23:11:35 -04:00
|
|
|
((LocalFolder)mFolder).deleteHeaders(mId);
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Update the unread count on the folder.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
try
|
|
|
|
{
|
|
|
|
if (flag == Flag.DELETED || flag == Flag.X_DESTROYED
|
|
|
|
|| (flag == Flag.SEEN && !isSet(Flag.DELETED)))
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
LocalFolder folder = (LocalFolder)mFolder;
|
2009-11-24 19:40:29 -05:00
|
|
|
if (set && !isSet(Flag.SEEN))
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
folder.setUnreadMessageCount(folder.getUnreadMessageCount() - 1);
|
|
|
|
}
|
2009-11-24 19:40:29 -05:00
|
|
|
else if (!set && isSet(Flag.SEEN))
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
folder.setUnreadMessageCount(folder.getUnreadMessageCount() + 1);
|
|
|
|
}
|
|
|
|
}
|
2010-04-16 10:33:54 -04:00
|
|
|
if ((flag == Flag.DELETED || flag == Flag.X_DESTROYED) && isSet(Flag.FLAGGED))
|
|
|
|
{
|
|
|
|
LocalFolder folder = (LocalFolder)mFolder;
|
|
|
|
if (set)
|
|
|
|
{
|
|
|
|
folder.setFlaggedMessageCount(folder.getFlaggedMessageCount() - 1);
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
else
|
2010-04-16 10:33:54 -04:00
|
|
|
{
|
|
|
|
folder.setFlaggedMessageCount(folder.getFlaggedMessageCount() + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (flag == Flag.FLAGGED && !isSet(Flag.DELETED))
|
|
|
|
{
|
|
|
|
LocalFolder folder = (LocalFolder)mFolder;
|
|
|
|
if (set)
|
|
|
|
{
|
|
|
|
folder.setFlaggedMessageCount(folder.getFlaggedMessageCount() + 1);
|
|
|
|
}
|
2010-04-29 00:59:14 -04:00
|
|
|
else
|
2010-04-16 10:33:54 -04:00
|
|
|
{
|
|
|
|
folder.setFlaggedMessageCount(folder.getFlaggedMessageCount() - 1);
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
Log.e(K9.LOG_TAG, "Unable to update LocalStore unread message count",
|
2009-11-24 19:40:29 -05:00
|
|
|
me);
|
2008-11-01 17:32:06 -04:00
|
|
|
throw new RuntimeException(me);
|
|
|
|
}
|
|
|
|
|
|
|
|
super.setFlag(flag, set);
|
|
|
|
/*
|
|
|
|
* Set the flags on the message.
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
mDb.execSQL("UPDATE messages " + "SET flags = ? " + " WHERE id = ?", new Object[]
|
2009-12-06 19:56:06 -05:00
|
|
|
{
|
|
|
|
Utility.combine(getFlags(), ',').toUpperCase(), mId
|
|
|
|
});
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
2009-12-14 21:51:18 -05:00
|
|
|
|
|
|
|
|
2009-12-20 00:41:43 -05:00
|
|
|
private void loadHeaders()
|
|
|
|
{
|
|
|
|
ArrayList<LocalMessage> messages = new ArrayList<LocalMessage>();
|
|
|
|
messages.add(this);
|
|
|
|
mHeadersLoaded = true; // set true before calling populate headers to stop recursion
|
|
|
|
((LocalFolder) mFolder).populateHeaders(messages);
|
2009-12-14 21:51:18 -05:00
|
|
|
|
2009-12-20 00:41:43 -05:00
|
|
|
}
|
2009-12-14 21:51:18 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-12-20 00:41:43 -05:00
|
|
|
public void addHeader(String name, String value)
|
2009-12-14 21:51:18 -05:00
|
|
|
{
|
2009-12-20 00:41:43 -05:00
|
|
|
if (!mHeadersLoaded)
|
|
|
|
loadHeaders();
|
|
|
|
super.addHeader(name, value);
|
2009-12-14 21:51:18 -05:00
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-12-20 00:41:43 -05:00
|
|
|
public void setHeader(String name, String value)
|
|
|
|
{
|
|
|
|
if (!mHeadersLoaded)
|
|
|
|
loadHeaders();
|
|
|
|
super.setHeader(name, value);
|
|
|
|
}
|
2009-12-14 21:51:18 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-12-20 00:41:43 -05:00
|
|
|
public String[] getHeader(String name)
|
|
|
|
{
|
|
|
|
if (!mHeadersLoaded)
|
|
|
|
loadHeaders();
|
|
|
|
return super.getHeader(name);
|
|
|
|
}
|
2009-12-14 21:51:18 -05:00
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-12-20 00:41:43 -05:00
|
|
|
public void removeHeader(String name)
|
|
|
|
{
|
|
|
|
if (!mHeadersLoaded)
|
|
|
|
loadHeaders();
|
|
|
|
super.removeHeader(name);
|
|
|
|
}
|
2009-12-14 21:51:18 -05:00
|
|
|
|
2010-05-21 11:34:29 -04:00
|
|
|
@Override
|
2010-05-30 00:17:00 -04:00
|
|
|
public Set<String> getHeaderNames()
|
|
|
|
{
|
2010-05-21 11:34:29 -04:00
|
|
|
if (!mHeadersLoaded)
|
|
|
|
loadHeaders();
|
|
|
|
return super.getHeaderNames();
|
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public class LocalAttachmentBodyPart extends MimeBodyPart
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
private long mAttachmentId = -1;
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public LocalAttachmentBodyPart(Body body, long attachmentId) throws MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
super(body);
|
|
|
|
mAttachmentId = attachmentId;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the local attachment id of this body, or -1 if it is not stored.
|
|
|
|
* @return
|
|
|
|
*/
|
2009-11-24 19:40:29 -05:00
|
|
|
public long getAttachmentId()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return mAttachmentId;
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void setAttachmentId(long attachmentId)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
mAttachmentId = attachmentId;
|
|
|
|
}
|
|
|
|
|
2010-04-16 08:20:10 -04:00
|
|
|
@Override
|
2009-11-24 19:40:29 -05:00
|
|
|
public String toString()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return "" + mAttachmentId;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public static class LocalAttachmentBody implements Body
|
|
|
|
{
|
2010-08-02 07:55:31 -04:00
|
|
|
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
|
2008-11-01 17:32:06 -04:00
|
|
|
private Application mApplication;
|
|
|
|
private Uri mUri;
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public LocalAttachmentBody(Uri uri, Application application)
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
mApplication = application;
|
|
|
|
mUri = uri;
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public InputStream getInputStream() throws MessagingException
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return mApplication.getContentResolver().openInputStream(mUri);
|
|
|
|
}
|
2010-02-17 22:28:31 -05:00
|
|
|
catch (FileNotFoundException fnfe)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Since it's completely normal for us to try to serve up attachments that
|
|
|
|
* have been blown away, we just return an empty stream.
|
|
|
|
*/
|
2010-08-02 07:55:31 -04:00
|
|
|
return new ByteArrayInputStream(EMPTY_BYTE_ARRAY);
|
2010-02-17 22:28:31 -05:00
|
|
|
}
|
2008-11-01 17:32:06 -04:00
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public void writeTo(OutputStream out) throws IOException, MessagingException
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
InputStream in = getInputStream();
|
|
|
|
Base64OutputStream base64Out = new Base64OutputStream(out);
|
|
|
|
IOUtils.copy(in, base64Out);
|
|
|
|
base64Out.close();
|
|
|
|
}
|
|
|
|
|
2009-11-24 19:40:29 -05:00
|
|
|
public Uri getContentUri()
|
|
|
|
{
|
2008-11-01 17:32:06 -04:00
|
|
|
return mUri;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|