1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-23 18:02:15 -05:00

Addresses Issue 1348 and Issue 95

Not done, yet, but available for developers to use.

Definite things to be done in the short term:
1) Allow user to hide canned searches in Accounts Activity
2) Make newly arrived mail immediately appear in search results.

Possible improvements:
3) User-definable searches
4) Make newly deleted mail immediately disappear search results.
5) Make message with flag changes immediately appear/disappear from
   search results.
6) Show search result size in Accounts Activity.
This commit is contained in:
Daniel Applebaum 2010-04-06 02:54:48 +00:00
parent d08c9d6ce2
commit 9a8126d89c
14 changed files with 431 additions and 48 deletions

View File

@ -7,7 +7,6 @@
android:icon="@drawable/ic_menu_compose"
/>
<item
android:id="@+id/display_1st_class"
android:title="@string/folder_list_display_mode_label"
android:icon="@drawable/ic_show_folders"
>

View File

@ -91,6 +91,18 @@
<item>KEYBOARD_AVAILABLE</item>
<item>ALWAYS</item>
</string-array>
<string-array name="account_settings_searchable_entries">
<item>@string/account_settings_searchable_all</item>
<item>@string/account_settings_searchable_displayable</item>
<item>@string/account_settings_searchable_none</item>
</string-array>
<string-array name="account_settings_searchable_values">
<item>ALL</item>
<item>DISPLAYABLE</item>
<item>NONE</item>
</string-array>
<string-array name="account_settings_folder_sync_mode_entries">
<item>@string/account_settings_folder_sync_mode_all</item>

View File

@ -678,7 +678,27 @@ Welcome to K-9 Mail setup. K-9 is an open source mail client for Android origin
<string name="animations_summary">Use gaudy visual effects</string>
<string name="gestures_title">Gestures</string>
<string name="gestures_summary">Accept gesture control</string>
<string name="search_unread_messages_title">All unread messages</string>
<string name="search_unread_messages_detail">Unread messages in searchable accounts</string>
<string name="search_starred_messages_title">All starred messages</string>
<string name="search_starred_messages_detail">Starred messages in searchable accounts</string>
<string name="integrated_inbox_title">Integrated Inbox (unread)</string>
<string name="integrated_inbox_detail">All unread messages in integrated folders</string>
<string name="integrated_inbox_starred_title">Integrated Inbox (starred)</string>
<string name="integrated_inbox_starred_detail">All starred messages in integrated folders</string>
<string name="folder_settings_include_in_integrated_inbox_label">Integrate</string>
<string name="folder_settings_include_in_integrated_inbox_summary">Unread messages are shown in Integrated Inbox</string>
<string name="account_settings_searchable_label">Folders to search</string>
<string name="account_settings_searchable_all">All</string>
<string name="account_settings_searchable_displayable">Displayable</string>
<string name="account_settings_searchable_none">None</string>
<string name="remote_control_label">K-9 Mail remote control</string>
<string name="remote_control_desc">Allows this application to control K-9 Mail activities and settings.</string>
</resources>

View File

@ -125,6 +125,13 @@
android:entries="@array/account_settings_folder_target_mode_entries"
android:entryValues="@array/account_settings_folder_target_mode_values"
android:dialogTitle="@string/account_settings_folder_target_mode_label" />
<ListPreference
android:key="searchable_folders"
android:title="@string/account_settings_searchable_label"
android:entries="@array/account_settings_searchable_entries"
android:entryValues="@array/account_settings_searchable_values"
android:dialogTitle="@string/account_settings_searchable_label" />
</PreferenceCategory>

View File

@ -45,7 +45,10 @@
android:entryValues="@array/folder_settings_folder_push_mode_values"
android:dialogTitle="@string/folder_settings_folder_push_mode_label" />
<CheckBoxPreference
android:key="folder_settings_include_in_integrated_inbox"
android:title="@string/folder_settings_include_in_integrated_inbox_label"
android:summary="@string/folder_settings_include_in_integrated_inbox_summary" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -5,6 +5,8 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.util.Log;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.MessagingException;
@ -38,7 +40,8 @@ public class Account
public static final String TYPE_MOBILE = "MOBILE";
public static final String TYPE_OTHER = "OTHER";
private static String[] networkTypes = { TYPE_WIFI, TYPE_MOBILE, TYPE_OTHER };
/**
* <pre>
* 0 - Never (DELETE_POLICY_NEVER)
@ -79,6 +82,7 @@ public class Account
private String mExpungePolicy = EXPUNGE_IMMEDIATELY;
private int mMaxPushFolders;
private Map<String, Boolean> compressionMap = new ConcurrentHashMap<String, Boolean>();
private Searchable searchableFolders;
// Tracks if we have sent a notification for this account for
// current set of fetched messages
private boolean mRingNotified;
@ -93,9 +97,13 @@ public class Account
public enum HideButtons
{
NEVER, ALWAYS, KEYBOARD_AVAILABLE;
}
public enum Searchable
{
ALL, DISPLAYABLE, NONE
}
protected Account(Context context)
{
// TODO Change local store path to something readable / recognizable
@ -119,6 +127,7 @@ public class Account
mExpungePolicy = EXPUNGE_IMMEDIATELY;
mAutoExpandFolderName = "INBOX";
mMaxPushFolders = 10;
searchableFolders = Searchable.ALL;
identities = new ArrayList<Identity>();
@ -257,6 +266,16 @@ public class Account
{
mFolderTargetMode = FolderMode.NOT_SECOND_CLASS;
}
try
{
searchableFolders = Searchable.valueOf(preferences.getPreferences().getString(mUuid + ".searchableFolders",
Searchable.ALL.name()));
}
catch (Exception e)
{
searchableFolders = Searchable.ALL;
}
mIsSignatureBeforeQuotedText = preferences.getPreferences().getBoolean(mUuid + ".signatureBeforeQuotedText", false);
identities = loadIdentities(preferences.getPreferences());
@ -312,6 +331,7 @@ public class Account
editor.remove(mUuid + ".signatureBeforeQuotedText");
editor.remove(mUuid + ".expungePolicy");
editor.remove(mUuid + ".maxPushFolders");
editor.remove(mUuid + ".searchableFolders");
for (String type : networkTypes)
{
editor.remove(mUuid + ".useCompression." + type);
@ -388,6 +408,7 @@ public class Account
editor.putBoolean(mUuid + ".signatureBeforeQuotedText", this.mIsSignatureBeforeQuotedText);
editor.putString(mUuid + ".expungePolicy", mExpungePolicy);
editor.putInt(mUuid + ".maxPushFolders", mMaxPushFolders);
editor.putString(mUuid + ".searchableFolders", searchableFolders.name());
for (String type : networkTypes)
{
Boolean useCompression = compressionMap.get(type);
@ -403,6 +424,7 @@ public class Account
}
//TODO: Shouldn't this live in MessagingController?
// Why should everything be in MessagingController? This is an Account-specific operation. --danapple0
public int getUnreadMessageCount(Context context) throws MessagingException
{
int unreadMessageCount = 0;
@ -1042,4 +1064,14 @@ public class Account
}
return null;
}
public Searchable getSearchableFolders()
{
return searchableFolders;
}
public void setSearchableFolders(Searchable searchableFolders)
{
this.searchableFolders = searchableFolders;
}
}

View File

@ -714,9 +714,9 @@ public class MessagingController implements Runnable
* @param listener
* @throws MessagingException
*/
public void searchLocalMessages(final Account account, final String query, final MessagingListener listener)
public void searchLocalMessages(final String query, final Message[] messages, final boolean integrate, final Flag[] requiredFlags, final Flag[] forbiddenFlags,
final MessagingListener listener)
{
if (listener == null)
{
return;
@ -726,38 +726,85 @@ public class MessagingController implements Runnable
public void run()
{
Preferences prefs = Preferences.getPreferences(mApplication.getApplicationContext());
final Preferences prefs = Preferences.getPreferences(mApplication.getApplicationContext());
Account[] accounts = prefs.getAccounts();
listener.listLocalMessagesStarted(account, null);
List<LocalFolder> foldersToSearch = null;
boolean displayableOnly = false;
for (final Account account : accounts)
{
Account.Searchable searchableFolders = account.getSearchableFolders();
switch (searchableFolders)
{
case NONE:
continue;
case DISPLAYABLE:
displayableOnly = true;
break;
}
listener.listLocalMessagesStarted(account, null);
if (integrate || displayableOnly)
{
List<LocalFolder> tmpFoldersToSearch = new LinkedList<LocalFolder>();
try
{
LocalStore store = account.getLocalStore();
LocalFolder[] folders = store.getPersonalNamespaces();
for (LocalFolder folder : folders)
{
boolean include = true;
folder.refresh(prefs);
if (displayableOnly && modeMismatch(account.getFolderDisplayMode(), folder.getDisplayClass()))
{
include = false;
}
if (integrate && folder.isIntegrate() == false)
{
include = false;
}
if (include)
{
tmpFoldersToSearch.add(folder);
}
}
foldersToSearch = tmpFoldersToSearch;
}
catch (MessagingException me)
{
Log.e(K9.LOG_TAG, "Unable to restrict search folders in Account " + account.getDescription() + ", searching all", me);
addErrorMessage(account, me);
}
}
MessageRetrievalListener retrievalListener = new MessageRetrievalListener()
{
int totalDone = 0;
public void messageStarted(String message, int number, int ofTotal) {}
public void messageFinished(Message message, int number, int ofTotal)
{
List<Message> messages = new ArrayList<Message>();
LocalFolder localFolder = (LocalStore.LocalFolder)message.getFolder();
if (localFolder.getName().equals(localFolder.getAccount().getErrorFolderName()))
{
return;
}
messages.add(message);
listener.listLocalMessagesAddMessages(account, null, messages);
}
public void messagesFinished(int number) {}
private void addPendingMessages() {}
};
try
{
LocalStore localStore = account.getLocalStore();
localStore.searchForMessages(retrievalListener, query);
localStore.searchForMessages(retrievalListener, query, foldersToSearch, messages, requiredFlags, forbiddenFlags);
}
catch (Exception e)
{
@ -1213,11 +1260,6 @@ public class MessagingController implements Runnable
if (K9.DEBUG)
Log.v(K9.LOG_TAG, "Message with uid " + message.getUid() + " is already locally present");
String newPushState = remoteFolder.getNewPushState(localFolder.getPushState(), message);
if (newPushState != null)
{
localFolder.setPushState(newPushState);
}
if (!localMessage.isSet(Flag.X_DOWNLOADED_FULL) && !localMessage.isSet(Flag.X_DOWNLOADED_PARTIAL))
{
if (K9.DEBUG)
@ -1228,6 +1270,11 @@ public class MessagingController implements Runnable
}
else
{
String newPushState = remoteFolder.getNewPushState(localFolder.getPushState(), message);
if (newPushState != null)
{
localFolder.setPushState(newPushState);
}
syncFlagMessages.add(message);
}
}

View File

@ -21,6 +21,8 @@ import com.fsck.k9.*;
import com.fsck.k9.activity.setup.AccountSettings;
import com.fsck.k9.activity.setup.AccountSetupBasics;
import com.fsck.k9.activity.setup.Prefs;
import com.fsck.k9.mail.Flag;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -36,6 +38,10 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
private AccountsHandler mHandler = new AccountsHandler();
private AccountsAdapter mAdapter;
private SearchAccount unreadAccount = null;
private SearchAccount flaggedAccount = null;
private SearchAccount integratedInboxAccount = null;
private SearchAccount integratedInboxStarredAccount = null;
class AccountsHandler extends Handler
@ -269,6 +275,22 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
@Override
public void onCreate(Bundle icicle)
{
unreadAccount = new SearchAccount(this, false, null, new Flag[] { Flag.SEEN } );
unreadAccount.setDescription(getString(R.string.search_unread_messages_title));
unreadAccount.setEmail(getString(R.string.search_unread_messages_detail));
flaggedAccount = new SearchAccount(this, false, new Flag[] { Flag.FLAGGED }, null);
flaggedAccount.setDescription(getString(R.string.search_starred_messages_title));
flaggedAccount.setEmail(getString(R.string.search_starred_messages_detail));
integratedInboxAccount = new SearchAccount(this, true, null, new Flag[] { Flag.SEEN });
integratedInboxAccount.setDescription(getString(R.string.integrated_inbox_title));
integratedInboxAccount.setEmail(getString(R.string.integrated_inbox_detail));
integratedInboxStarredAccount = new SearchAccount(this, true, new Flag[] { Flag.FLAGGED }, null);
integratedInboxStarredAccount.setDescription(getString(R.string.integrated_inbox_starred_title));
integratedInboxStarredAccount.setEmail(getString(R.string.integrated_inbox_starred_detail));
super.onCreate(icicle);
Account[] accounts = Preferences.getPreferences(this).getAccounts();
@ -339,7 +361,15 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
private void refresh()
{
Account[] accounts = Preferences.getPreferences(this).getAccounts();
mAdapter = new AccountsAdapter(accounts);
Account[] newAccounts = new Account[accounts.length + 4];
newAccounts[0] = integratedInboxAccount;
newAccounts[1] = integratedInboxStarredAccount;
newAccounts[2] = unreadAccount;
newAccounts[3] = flaggedAccount;
System.arraycopy(accounts, 0, newAccounts, 4, accounts.length);
mAdapter = new AccountsAdapter(newAccounts);
getListView().setAdapter(mAdapter);
if (accounts.length > 0)
{
@ -355,6 +385,7 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
MessagingController.getInstance(getApplication()).getAccountUnreadCount(Accounts.this, account, mListener);
}
}
private void onAddNewAccount()
@ -409,7 +440,12 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
private void onOpenAccount(Account account)
{
if (K9.FOLDER_NONE.equals(account.getAutoExpandFolderName()))
if (account instanceof SearchAccount)
{
SearchAccount searchAccount = (SearchAccount)account;
MessageList.actionHandle(this, searchAccount.getDescription(), "", searchAccount.isIntegrate(), searchAccount.getRequiredFlags(), searchAccount.getForbiddenFlags());
}
else if (K9.FOLDER_NONE.equals(account.getAutoExpandFolderName()))
{
FolderList.actionHandleAccount(this, account);
}
@ -649,6 +685,20 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle(R.string.accounts_context_menu_title);
getMenuInflater().inflate(R.menu.accounts_context, menu);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
Account account = (Account) mAdapter.getItem(info.position);
if (account instanceof SearchAccount)
{
for (int i = 0; i < menu.size(); i++)
{
MenuItem item = menu.getItem(i);
if (item.getItemId() != R.id.open)
{
item.setVisible(false);
}
}
}
}
class AccountsAdapter extends ArrayAdapter<Account>
@ -701,7 +751,10 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
//holder.newMessageCount.setText("-");
holder.newMessageCount.setVisibility(View.GONE);
}
holder.chip.setBackgroundResource(K9.COLOR_CHIP_RES_IDS[account.getAccountNumber() % K9.COLOR_CHIP_RES_IDS.length]);
if (!(account instanceof SearchAccount))
{
holder.chip.setBackgroundResource(K9.COLOR_CHIP_RES_IDS[account.getAccountNumber() % K9.COLOR_CHIP_RES_IDS.length]);
}
if (unreadMessageCount == null)
{
@ -728,4 +781,43 @@ public class Accounts extends K9ListActivity implements OnItemClickListener, OnC
public View chip;
}
}
private class SearchAccount extends Account
{
private Flag[] mRequiredFlags = null;
private Flag[] mForbiddenFlags = null;
private String email = null;
private boolean mIntegrate = false;
private SearchAccount(Context context, boolean integrate, Flag[] requiredFlags, Flag[] forbiddenFlags)
{
super(context);
mRequiredFlags = requiredFlags;
mForbiddenFlags = forbiddenFlags;
mIntegrate = integrate;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public Flag[] getRequiredFlags()
{
return mRequiredFlags;
}
public Flag[] getForbiddenFlags()
{
return mForbiddenFlags;
}
public boolean isIntegrate()
{
return mIntegrate;
}
public void setIntegrate(boolean integrate)
{
this.mIntegrate = integrate;
}
}
}

View File

@ -812,12 +812,12 @@ public class FolderList extends K9ListActivity
List<FolderInfoHolder> topFolders = new LinkedList<FolderInfoHolder>();
Account.FolderMode aMode = account.getFolderDisplayMode();
Preferences prefs = Preferences.getPreferences(getApplication().getApplicationContext());
for (Folder folder : folders)
{
try
{
folder.refresh(Preferences.getPreferences(getApplication().getApplicationContext()));
folder.refresh(prefs);
Folder.FolderClass fMode = folder.getDisplayClass();

View File

@ -66,6 +66,11 @@ public class MessageList
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_FOLDER = "folder";
private static final String EXTRA_QUERY = "query";
private static final String EXTRA_QUERY_FLAGS = "queryFlags";
private static final String EXTRA_FORBIDDEN_FLAGS = "forbiddenFlags";
private static final String EXTRA_INTEGRATE = "integrate";
private static final String EXTRA_TITLE = "title";
private ListView mListView;
@ -92,6 +97,10 @@ public class MessageList
/* if we're doing a search, this contains the query string */
private String mQueryString;
private Flag[] mQueryFlags = null;
private Flag[] mForbiddenFlags = null;
private boolean mIntegrate = false;
private String mTitle;
private MessageListHandler mHandler = new MessageListHandler();
@ -253,7 +262,14 @@ public class MessageList
}
else if (mQueryString != null)
{
setTitle(getString(R.string.search_results) + ": "+ mQueryString);
if (mTitle != null)
{
setTitle(mTitle);
}
else
{
setTitle(getString(R.string.search_results) + ": "+ mQueryString);
}
}
}
@ -292,6 +308,24 @@ public class MessageList
}
return intent;
}
public static void actionHandle(Context context, String title, String queryString, boolean integrate, Flag[] flags, Flag[] forbiddenFlags)
{
Intent intent = new Intent(context, MessageList.class);
intent.putExtra(EXTRA_QUERY, queryString);
if (flags != null)
{
intent.putExtra(EXTRA_QUERY_FLAGS, Utility.combine(flags, ','));
}
if (forbiddenFlags != null)
{
intent.putExtra(EXTRA_FORBIDDEN_FLAGS, Utility.combine(forbiddenFlags, ','));
}
intent.putExtra(EXTRA_INTEGRATE, integrate);
intent.putExtra(EXTRA_TITLE, title);
context.startActivity(intent);
}
public void onItemClick(AdapterView parent, View v, int position, long id)
{
@ -335,7 +369,30 @@ public class MessageList
mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
mFolderName = intent.getStringExtra(EXTRA_FOLDER);
mQueryString = intent.getStringExtra(EXTRA_QUERY);
String queryFlags = intent.getStringExtra(EXTRA_QUERY_FLAGS);
if (queryFlags != null)
{
String[] flagStrings = queryFlags.split(",");
mQueryFlags = new Flag[flagStrings.length];
for (int i = 0; i < flagStrings.length; i++)
{
mQueryFlags[i] = Flag.valueOf(flagStrings[i]);
}
}
String forbiddenFlags = intent.getStringExtra(EXTRA_FORBIDDEN_FLAGS);
if (forbiddenFlags != null)
{
String[] flagStrings = forbiddenFlags.split(",");
mForbiddenFlags = new Flag[flagStrings.length];
for (int i = 0; i < flagStrings.length; i++)
{
mForbiddenFlags[i] = Flag.valueOf(flagStrings[i]);
}
}
mIntegrate = intent.getBooleanExtra(EXTRA_INTEGRATE, false);
mTitle = intent.getStringExtra(EXTRA_TITLE);
// Take the initial folder into account only if we are *not* restoring the
// activity already
@ -407,8 +464,7 @@ public class MessageList
}
else if (mQueryString != null)
{
mController.searchLocalMessages(mAccount, mQueryString, mAdapter.mListener);
mController.searchLocalMessages(mQueryString, null, mIntegrate, mQueryFlags, mForbiddenFlags, mAdapter.mListener);
}
mHandler.refreshTitle();

View File

@ -47,6 +47,7 @@ public class AccountSettings extends K9PreferenceActivity
private static final String PREFERENCE_DELETE_POLICY = "delete_policy";
private static final String PREFERENCE_EXPUNGE_POLICY = "expunge_policy";
private static final String PREFERENCE_AUTO_EXPAND_FOLDER = "account_setup_auto_expand_folder";
private static final String PREFERENCE_SEARCHABLE_FOLDERS = "searchable_folders";
private Account mAccount;
@ -68,6 +69,7 @@ public class AccountSettings extends K9PreferenceActivity
private ListPreference mTargetMode;
private ListPreference mDeletePolicy;
private ListPreference mExpungePolicy;
private ListPreference mSearchableFolders;
private Preference mAutoExpandFolder;
private boolean mIncomingChanged = false;
@ -244,6 +246,21 @@ public class AccountSettings extends K9PreferenceActivity
return false;
}
});
mSearchableFolders = (ListPreference) findPreference(PREFERENCE_SEARCHABLE_FOLDERS);
mSearchableFolders.setValue(mAccount.getSearchableFolders().name());
mSearchableFolders.setSummary(mSearchableFolders.getEntry());
mSearchableFolders.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
{
public boolean onPreferenceChange(Preference preference, Object newValue)
{
final String summary = newValue.toString();
int index = mSearchableFolders.findIndexOfValue(summary);
mSearchableFolders.setSummary(mSearchableFolders.getEntries()[index]);
mSearchableFolders.setValue(summary);
return false;
}
});
mDisplayCount = (ListPreference) findPreference(PREFERENCE_DISPLAY_COUNT);
mDisplayCount.setValue(String.valueOf(mAccount.getDisplayCount()));
@ -379,6 +396,7 @@ public class AccountSettings extends K9PreferenceActivity
mAccount.setFolderTargetMode(Account.FolderMode.valueOf(mTargetMode.getValue()));
mAccount.setDeletePolicy(Integer.parseInt(mDeletePolicy.getValue()));
mAccount.setExpungePolicy(mExpungePolicy.getValue());
mAccount.setSearchableFolders(Account.Searchable.valueOf(mSearchableFolders.getValue()));
boolean needsRefresh = mAccount.setAutomaticCheckIntervalMinutes(Integer.parseInt(mCheckFrequency.getValue()));
needsRefresh |= mAccount.setFolderSyncMode(Account.FolderMode.valueOf(mSyncMode.getValue()));

View File

@ -28,10 +28,12 @@ public class FolderSettings extends K9PreferenceActivity
private static final String PREFERENCE_SYNC_CLASS = "folder_settings_folder_sync_mode";
private static final String PREFERENCE_PUSH_CLASS = "folder_settings_folder_push_mode";
private static final String PREFERENCE_IN_TOP_GROUP = "folder_settings_in_top_group";
private static final String PREFERENCE_INTEGRATE = "folder_settings_include_in_integrated_inbox";
private LocalFolder mFolder;
private CheckBoxPreference mInTopGroup;
private CheckBoxPreference mIntegrate;
private ListPreference mDisplayClass;
private ListPreference mSyncClass;
private ListPreference mPushClass;
@ -85,6 +87,8 @@ public class FolderSettings extends K9PreferenceActivity
mInTopGroup = (CheckBoxPreference)findPreference(PREFERENCE_IN_TOP_GROUP);
mInTopGroup.setChecked(mFolder.isInTopGroup());
mIntegrate = (CheckBoxPreference)findPreference(PREFERENCE_INTEGRATE);
mIntegrate.setChecked(mFolder.isIntegrate());
mDisplayClass = (ListPreference) findPreference(PREFERENCE_DISPLAY_CLASS);
mDisplayClass.setValue(mFolder.getDisplayClass().name());
@ -150,6 +154,7 @@ public class FolderSettings extends K9PreferenceActivity
private void saveSettings()
{
mFolder.setInTopGroup(mInTopGroup.isChecked());
mFolder.setIntegrate(mIntegrate.isChecked());
// We call getPushClass() because display class changes can affect push class when push class is set to inherit
FolderClass oldPushClass = mFolder.getPushClass();
FolderClass oldDisplayClass = mFolder.getDisplayClass();

View File

@ -28,7 +28,7 @@ public abstract class Store
//Matching MessagingController.MAX_SMALL_MESSAGE_SIZE
public static final int FETCH_BODY_SANE_SUGGESTED_SIZE = (50 * 1024);
protected static final int SOCKET_CONNECT_TIMEOUT = 10000;
protected static final int SOCKET_CONNECT_TIMEOUT = 30000;
protected static final int SOCKET_READ_TIMEOUT = 60000;
private static HashMap<String, Store> mStores = new HashMap<String, Store>();

View File

@ -35,7 +35,7 @@ import java.util.regex.Matcher;
public class LocalStore extends Store implements Serializable
{
private static final int DB_VERSION = 33;
private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.X_DESTROYED, Flag.SEEN };
private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.X_DESTROYED, Flag.SEEN, Flag.FLAGGED };
private String mPath;
private SQLiteDatabase mDb;
@ -594,22 +594,97 @@ public class LocalStore extends Store implements Serializable
return true;
}
public Message[] searchForMessages(MessageRetrievalListener listener, String queryString) throws MessagingException
public Message[] searchForMessages(MessageRetrievalListener listener, String queryString,
List<LocalFolder> folders, Message[] messages, final Flag[] requiredFlags, final Flag[] forbiddenFlags) throws MessagingException
{
queryString = "%"+queryString+"%";
List<String> args = new LinkedList<String>();
StringBuilder whereClause = new StringBuilder();
if (queryString != null && queryString.length() > 0)
{
String likeString = "%"+queryString+"%";
whereClause.append(" AND (html_content LIKE ? OR subject LIKE ? OR sender_list LIKE ?)");
args.add(likeString);
args.add(likeString);
args.add(likeString);
}
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 ?");
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 ?");
args.add("%" + flag.toString() + "%");
}
whereClause.append(" )");
}
Log.i(K9.LOG_TAG, "whereClause = " + whereClause.toString());
Log.i(K9.LOG_TAG, "args = " + args);
return getMessages(
listener,
null,
"SELECT "
+ GET_MESSAGES_COLS
+ "FROM messages WHERE deleted = 0 AND (html_content LIKE ? OR subject LIKE ? OR sender_list LIKE ?) ORDER BY date DESC"
, new String[]
{
queryString,
queryString,
queryString
}
+ "FROM messages WHERE deleted = 0 " + whereClause.toString() + " ORDER BY date DESC"
, args.toArray(new String[0])
);
}
/*
@ -631,7 +706,6 @@ public class LocalStore extends Store implements Serializable
int i = 0;
ArrayList<LocalMessage> messagesForHeaders = new ArrayList<LocalMessage>();
while (cursor.moveToNext())
{
LocalMessage message = new LocalMessage(null, folder);
@ -674,6 +748,7 @@ public class LocalStore extends Store implements Serializable
private boolean inTopGroup = false;
private String prefId = null;
private String mPushState = null;
private boolean mIntegrate = false;
public LocalFolder(String name)
@ -735,6 +810,7 @@ public class LocalStore extends Store implements Serializable
}
else
{
Log.w(K9.LOG_TAG, "Creating folder " + getName() + " with existing id " + getId());
create(FolderType.HOLDS_MESSAGES);
open(mode);
}
@ -1005,7 +1081,16 @@ public class LocalStore extends Store implements Serializable
{
this.pushClass = pushClass;
}
public boolean isIntegrate()
{
return mIntegrate;
}
public void setIntegrate(boolean integrate)
{
mIntegrate = integrate;
}
private String getPrefId() throws MessagingException
{
open(OpenMode.READ_WRITE);
@ -1028,6 +1113,7 @@ public class LocalStore extends Store implements Serializable
editor.remove(id + ".syncMode");
editor.remove(id + ".pushMode");
editor.remove(id + ".inTopGroup");
editor.remove(id + ".integrate");
editor.commit();
}
@ -1066,6 +1152,8 @@ public class LocalStore extends Store implements Serializable
}
editor.putBoolean(id + ".inTopGroup", inTopGroup);
editor.putBoolean(id + ".integrate", mIntegrate);
editor.commit();
}
public void refresh(Preferences preferences) throws MessagingException
@ -1114,10 +1202,12 @@ public class LocalStore extends Store implements Serializable
FolderClass defPushClass = FolderClass.SECOND_CLASS;
boolean defInTopGroup = false;
boolean defIntegrate = false;
if (K9.INBOX.equals(getName()))
{
defPushClass = FolderClass.FIRST_CLASS;
defInTopGroup = true;
defIntegrate = true;
}
try
@ -1136,6 +1226,7 @@ public class LocalStore extends Store implements Serializable
pushClass = FolderClass.INHERITED;
}
inTopGroup = preferences.getPreferences().getBoolean(id + ".inTopGroup", defInTopGroup);
mIntegrate = preferences.getPreferences().getBoolean(id + ".integrate", defIntegrate);
}
@ -2202,6 +2293,7 @@ public class LocalStore extends Store implements Serializable
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)));
this.mAttachmentCount = cursor.getInt(10);
this.setInternalDate(new Date(cursor.getLong(11)));
this.setMessageId(cursor.getString(12));