First attempt at making the fragmented messagelist and remote search play nice with the new search framework. Works partially.

This commit is contained in:
Sander Bogaert 2012-10-13 15:07:28 -04:00
parent bf82d0af7c
commit 49197b4f1c
3 changed files with 294 additions and 405 deletions

View file

@ -34,7 +34,11 @@ import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.store.StorageManager;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchSpecification;
import com.fsck.k9.search.SearchSpecification.ATTRIBUTE;
import com.fsck.k9.search.SearchSpecification.SEARCHFIELD;
import com.fsck.k9.search.SearchSpecification.SearchCondition;
/**
@ -44,86 +48,36 @@ import com.fsck.k9.search.SearchSpecification;
*/
public class MessageList extends K9FragmentActivity implements MessageListFragmentListener,
OnBackStackChangedListener, OnSwipeGestureListener {
private static final String EXTRA_ACCOUNT = "account";
private static final String EXTRA_FOLDER = "folder";
// for this activity
private static final String EXTRA_SEARCH = "search";
// used for remote search
private static final String EXTRA_SEARCH_ACCOUNT = "com.fsck.k9.search_account";
private static final String EXTRA_SEARCH_FOLDER = "com.fsck.k9.search_folder";
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_ACCOUNT_UUIDS = "accountUuids";
private static final String EXTRA_FOLDER_NAMES = "folderNames";
private static final String EXTRA_TITLE = "title";
public static void actionHandleFolder(Context context, Account account, String folder) {
Intent intent = new Intent(context, MessageList.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(EXTRA_ACCOUNT, account.getUuid());
if (folder != null) {
intent.putExtra(EXTRA_FOLDER, folder);
}
context.startActivity(intent);
public static void actionDisplaySearch(Context context, SearchSpecification search, boolean newTask) {
actionDisplaySearch(context, search, newTask, true);
}
public static Intent actionHandleFolderIntent(Context context, Account account, String folder) {
public static void actionDisplaySearch(Context context, SearchSpecification search, boolean newTask, boolean clearTop) {
context.startActivity(intentDisplaySearch(context, search, newTask, clearTop));
}
public static Intent intentDisplaySearch(Context context, SearchSpecification search, boolean newTask, boolean clearTop) {
Intent intent = new Intent(context, MessageList.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(EXTRA_ACCOUNT, account.getUuid());
if (folder != null) {
intent.putExtra(EXTRA_FOLDER, folder);
intent.putExtra(EXTRA_SEARCH, search);
if (clearTop) {
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
}
if (newTask) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
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.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(SearchManager.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);
}
/**
* Creates and returns an intent that opens Unified Inbox or All Messages screen.
*/
public static Intent actionHandleAccountIntent(Context context, String title,
SearchSpecification searchSpecification) {
Intent intent = new Intent(context, MessageList.class);
intent.putExtra(SearchManager.QUERY, searchSpecification.getQuery());
if (searchSpecification.getRequiredFlags() != null) {
intent.putExtra(EXTRA_QUERY_FLAGS, Utility.combine(searchSpecification.getRequiredFlags(), ','));
}
if (searchSpecification.getForbiddenFlags() != null) {
intent.putExtra(EXTRA_FORBIDDEN_FLAGS, Utility.combine(searchSpecification.getForbiddenFlags(), ','));
}
intent.putExtra(EXTRA_INTEGRATE, searchSpecification.isIntegrate());
intent.putExtra(EXTRA_ACCOUNT_UUIDS, searchSpecification.getAccountUuids());
intent.putExtra(EXTRA_FOLDER_NAMES, searchSpecification.getFolderNames());
intent.putExtra(EXTRA_TITLE, title);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
return intent;
}
public static void actionHandle(Context context, String title,
SearchSpecification searchSpecification) {
Intent intent = actionHandleAccountIntent(context, title, searchSpecification);
context.startActivity(intent);
}
private StorageManager.StorageListener mStorageListener = new StorageListenerImplementation();
@ -131,31 +85,22 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
private TextView mActionBarTitle;
private TextView mActionBarSubTitle;
private TextView mActionBarUnread;
private String mTitle;
private Menu mMenu;
private MessageListFragment mMessageListFragment;
private Account mAccount;
private String mQueryString;
private String mFolderName;
private Flag[] mQueryFlags;
private Flag[] mForbiddenFlags;
private String mSearchAccount = null;
private String mSearchFolder = null;
private boolean mIntegrate;
private String[] mAccountUuids;
private String[] mFolderNames;
private LocalSearch mSearch;
private boolean mSingleFolderMode;
private boolean mSingleAccountMode;
private boolean mIsRemote;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.message_list);
// need this for actionbar initialization
mQueryString = getIntent().getStringExtra(SearchManager.QUERY);
mActionBar = getSupportActionBar();
initializeActionBar();
@ -171,76 +116,56 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
if (mMessageListFragment == null) {
FragmentTransaction ft = fragmentManager.beginTransaction();
if (mQueryString == null) {
mMessageListFragment = MessageListFragment.newInstance(mAccount, mFolderName);
} else if (mSearchAccount != null) {
mMessageListFragment = MessageListFragment.newInstance(mSearchAccount,
mSearchFolder, mQueryString, false);
} else {
mMessageListFragment = MessageListFragment.newInstance(mTitle, mAccountUuids,
mFolderNames, mQueryString, mQueryFlags, mForbiddenFlags, mIntegrate);
}
mMessageListFragment = MessageListFragment.newInstance(mSearch, mIsRemote);
ft.add(R.id.message_list_container, mMessageListFragment);
ft.commit();
}
}
private void decodeExtras(Intent intent) {
mQueryString = intent.getStringExtra(SearchManager.QUERY);
mFolderName = null;
mSearchAccount = null;
mSearchFolder = null;
if (mQueryString != null) {
// check if this intent comes from the system search ( remote )
if (intent.getStringExtra(SearchManager.QUERY) != null) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
//Query was received from Search Dialog
Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
if (appData != null) {
mSearchAccount = appData.getString(EXTRA_SEARCH_ACCOUNT);
mSearchFolder = appData.getString(EXTRA_SEARCH_FOLDER);
mSearch = new LocalSearch();
mSearch.addAccountUuid(appData.getString(EXTRA_SEARCH_ACCOUNT));
mSearch.addAllowedFolder(appData.getString(EXTRA_SEARCH_FOLDER));
String query = intent.getStringExtra(SearchManager.QUERY);
mSearch.or(new SearchCondition(SEARCHFIELD.SENDER, ATTRIBUTE.CONTAINS, query));
mSearch.or(new SearchCondition(SEARCHFIELD.SUBJECT, ATTRIBUTE.CONTAINS, query));
mIsRemote = true;
}
} else {
mSearchAccount = intent.getStringExtra(EXTRA_SEARCH_ACCOUNT);
mSearchFolder = intent.getStringExtra(EXTRA_SEARCH_FOLDER);
}
} else {
// regular LocalSearch object was passed
mSearch = intent.getParcelableExtra(EXTRA_SEARCH);
}
String accountUuid = intent.getStringExtra(EXTRA_ACCOUNT);
mFolderName = intent.getStringExtra(EXTRA_FOLDER);
mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
if (mAccount != null && !mAccount.isAvailable(this)) {
Log.i(K9.LOG_TAG, "not opening MessageList of unavailable account");
onAccountUnavailable();
return;
}
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);
mAccountUuids = intent.getStringArrayExtra(EXTRA_ACCOUNT_UUIDS);
mFolderNames = intent.getStringArrayExtra(EXTRA_FOLDER_NAMES);
mTitle = intent.getStringExtra(EXTRA_TITLE);
// Take the initial folder into account only if we are *not* restoring
// the activity already.
if (mFolderName == null && mQueryString == null) {
mFolderName = mAccount.getAutoExpandFolderName();
}
String[] accounts = mSearch.getAccountUuids();
mSingleAccountMode = ( accounts != null && accounts.length == 1
&& !accounts[0].equals(SearchSpecification.ALL_ACCOUNTS));
mSingleFolderMode = mSingleAccountMode && (mSearch.getFolderNames().size() == 1);
if (mSingleAccountMode) {
mAccount = Preferences.getPreferences(this).getAccount(accounts[0]);
if (mAccount != null && !mAccount.isAvailable(this)) {
Log.i(K9.LOG_TAG, "not opening MessageList of unavailable account");
onAccountUnavailable();
return;
}
}
if (mSingleFolderMode) {
mFolderName = mSearch.getFolderNames().get(0);
}
// now we know if we are in single account mode and need a subtitle
mActionBarSubTitle.setVisibility((!mSingleFolderMode) ? View.GONE : View.VISIBLE);
}
@Override
@ -276,10 +201,6 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
mActionBarSubTitle = (TextView) customView.findViewById(R.id.actionbar_title_sub);
mActionBarUnread = (TextView) customView.findViewById(R.id.actionbar_unread_count);
if (mQueryString != null) {
mActionBarSubTitle.setVisibility(View.GONE);
}
mActionBar.setDisplayHomeAsUpEnabled(true);
}
@ -407,17 +328,11 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 0) {
fragmentManager.popBackStack();
} else if (mIntegrate) {
// If we were in one of the integrated mailboxes (think All Mail or Integrated Inbox), then
// go to accounts.
onAccounts();
} else if (mQueryString != null) {
// We did a search of some sort. Go back to wherever the user searched from.
onBackPressed();
} else {
// In a standard message list of a folder. Go to folder list.
onShowFolderList();
}
} else if (!mSingleFolderMode) {
onBackPressed();
} else {
onShowFolderList();
}
return true;
}
case R.id.compose: {
@ -470,7 +385,7 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
}
}
if (mQueryString != null) {
if (!mSingleFolderMode) {
// None of the options after this point are "safe" for search results
//TODO: This is not true for "unread" and "starred" searches in regular folders
return false;
@ -534,7 +449,7 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
menu.findItem(R.id.select_all).setVisible(true);
menu.findItem(R.id.settings).setVisible(true);
if (mMessageListFragment.isSearchQuery()) {
if (!mSingleAccountMode) {
menu.findItem(R.id.expunge).setVisible(false);
menu.findItem(R.id.check_mail).setVisible(false);
menu.findItem(R.id.send_messages).setVisible(false);
@ -666,8 +581,11 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
@Override
public void showMoreFromSameSender(String senderAddress) {
MessageListFragment fragment = MessageListFragment.newInstance("From " + senderAddress,
null, null, senderAddress, null, null, false);
LocalSearch tmpSearch = new LocalSearch("From " + senderAddress);
tmpSearch.addAccountUuids(mSearch.getAccountUuids());
tmpSearch.and(SEARCHFIELD.SENDER, senderAddress, ATTRIBUTE.CONTAINS);
MessageListFragment fragment = MessageListFragment.newInstance(tmpSearch, false);
addMessageListFragment(fragment);
}
@ -716,8 +634,7 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
@Override
public void remoteSearch(String searchAccount, String searchFolder, String queryString) {
MessageListFragment fragment = MessageListFragment.newInstance(searchAccount, searchFolder,
queryString, true);
MessageListFragment fragment = MessageListFragment.newInstance(mSearch, true);
addMessageListFragment(fragment);
}
@ -751,9 +668,11 @@ public class MessageList extends K9FragmentActivity implements MessageListFragme
@Override
public void showThread(Account account, String folderName, long threadRootId) {
MessageListFragment fragment = MessageListFragment.newInstance(account, folderName,
threadRootId);
LocalSearch tmpSearch = new LocalSearch();
tmpSearch.addAccountUuids(mSearch.getAccountUuids());
tmpSearch.and(SEARCHFIELD.THREAD_ROOT, String.valueOf(threadRootId), ATTRIBUTE.EQUALS);
MessageListFragment fragment = MessageListFragment.newInstance(tmpSearch, false);
addMessageListFragment(fragment);
}
}

View file

@ -77,6 +77,12 @@ import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.store.LocalStore;
import com.fsck.k9.mail.store.LocalStore.LocalFolder;
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
import com.fsck.k9.search.ConditionsTreeNode;
import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchSpecification;
import com.fsck.k9.search.SearchSpecification.ATTRIBUTE;
import com.fsck.k9.search.SearchSpecification.SEARCHFIELD;
import com.fsck.k9.search.SearchSpecification.SearchCondition;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
@ -84,67 +90,14 @@ import com.handmark.pulltorefresh.library.PullToRefreshListView;
public class MessageListFragment extends SherlockFragment implements OnItemClickListener,
ConfirmationDialogFragmentListener {
public static MessageListFragment newInstance(Account account, String folderName) {
public static MessageListFragment newInstance(LocalSearch search, boolean remoteSearch) {
MessageListFragment fragment = new MessageListFragment();
Bundle args = new Bundle();
args.putString(ARG_ACCOUNT, account.getUuid());
args.putString(ARG_FOLDER, folderName);
fragment.setArguments(args);
return fragment;
}
public static MessageListFragment newInstance(Account account, String folderName,
long threadRootId) {
MessageListFragment fragment = new MessageListFragment();
Bundle args = new Bundle();
args.putString(ARG_ACCOUNT, account.getUuid());
args.putString(ARG_FOLDER, folderName);
args.putLong(ARG_THREAD_ID, threadRootId);
fragment.setArguments(args);
return fragment;
}
public static MessageListFragment newInstance(String title, String[] accountUuids,
String[] folderNames, String queryString, Flag[] flags,
Flag[] forbiddenFlags, boolean integrate) {
MessageListFragment fragment = new MessageListFragment();
Bundle args = new Bundle();
args.putStringArray(ARG_ACCOUNT_UUIDS, accountUuids);
args.putStringArray(ARG_FOLDER_NAMES, folderNames);
args.putString(ARG_QUERY, queryString);
if (flags != null) {
args.putString(ARG_QUERY_FLAGS, Utility.combine(flags, ','));
}
if (forbiddenFlags != null) {
args.putString(ARG_FORBIDDEN_FLAGS, Utility.combine(forbiddenFlags, ','));
}
args.putBoolean(ARG_INTEGRATE, integrate);
args.putString(ARG_TITLE, title);
fragment.setArguments(args);
return fragment;
}
public static MessageListFragment newInstance(String searchAccount, String searchFolder,
String queryString, boolean remoteSearch) {
MessageListFragment fragment = new MessageListFragment();
Bundle args = new Bundle();
args.putString(ARG_SEARCH_ACCOUNT, searchAccount);
args.putString(ARG_SEARCH_FOLDER, searchFolder);
args.putString(ARG_QUERY, queryString);
args.putParcelable(ARG_SEARCH, search);
args.putBoolean(ARG_REMOTE_SEARCH, remoteSearch);
fragment.setArguments(args);
return fragment;
}
return fragment;
}
/**
* Reverses the result of a {@link Comparator}.
@ -292,20 +245,8 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
private static final int ACTIVITY_CHOOSE_FOLDER_MOVE = 1;
private static final int ACTIVITY_CHOOSE_FOLDER_COPY = 2;
private static final String ARG_ACCOUNT = "account";
private static final String ARG_FOLDER = "folder";
private static final String ARG_REMOTE_SEARCH = "remote_search";
private static final String ARG_QUERY = "query";
private static final String ARG_SEARCH_ACCOUNT = "search_account";
private static final String ARG_SEARCH_FOLDER = "search_folder";
private static final String ARG_QUERY_FLAGS = "queryFlags";
private static final String ARG_FORBIDDEN_FLAGS = "forbiddenFlags";
private static final String ARG_INTEGRATE = "integrate";
private static final String ARG_ACCOUNT_UUIDS = "accountUuids";
private static final String ARG_FOLDER_NAMES = "folderNames";
private static final String ARG_TITLE = "title";
private static final String ARG_THREAD_ID = "thread_id";
private static final String ARG_SEARCH = "searchObject";
private static final String ARG_REMOTE_SEARCH = "remoteSearch";
private static final String STATE_LIST_POSITION = "listPosition";
/**
@ -356,18 +297,14 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
/**
* If we're doing a search, this contains the query string.
*/
private String mQueryString;
private Flag[] mQueryFlags = null;
private Flag[] mForbiddenFlags = null;
private boolean mRemoteSearch = false;
private String mSearchAccount = null;
private String mSearchFolder = null;
private Future mRemoteSearchFuture = null;
private boolean mIntegrate = false;
private String[] mAccountUuids = null;
private String[] mFolderNames = null;
private String mTitle;
private LocalSearch mSearch = null;
private boolean mSingleAccountMode;
private boolean mSingleFolderMode;
private MessageListHandler mHandler = new MessageListHandler();
private SortType mSortType = SortType.SORT_DATE;
@ -596,7 +533,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
private void setWindowTitle() {
// regular folder content display
if (mFolderName != null) {
if (mSingleFolderMode) {
Activity activity = getActivity();
String displayName = FolderInfoHolder.getDisplayName(activity, mAccount,
mFolderName);
@ -609,7 +546,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
} else {
mFragmentListener.setMessageListSubTitle(operation);
}
} else if (mQueryString != null) {
} else {
// query result display. This may be for a search folder as opposed to a user-initiated search.
if (mTitle != null) {
// This was a search folder; the search folder has overridden our title.
@ -626,8 +563,8 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
if (mUnreadMessageCount == 0) {
mFragmentListener.setUnreadCount(0);
} else {
if (mQueryString != null && mTitle == null) {
// This is a search result. The unread message count is easily confused
if (!mSingleFolderMode && mTitle == null) {
// The unread message count is easily confused
// with total number of messages in the search result, so let's hide it.
mFragmentListener.setUnreadCount(0);
} else {
@ -665,15 +602,14 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
if (view == mFooterView) {
if (mCurrentFolder != null && !mRemoteSearch) {
mController.loadMoreMessages(mAccount, mFolderName, mAdapter.mListener);
} else if (mRemoteSearch && mAdapter.mExtraSearchResults != null && mAdapter.mExtraSearchResults.size() > 0 && mSearchAccount != null) {
} else if (mRemoteSearch && mAdapter.mExtraSearchResults != null && mAdapter.mExtraSearchResults.size() > 0 && mAccount != null) {
int numResults = mAdapter.mExtraSearchResults.size();
Context appContext = getActivity().getApplicationContext();
Account account = Preferences.getPreferences(appContext).getAccount(mSearchAccount);
if (account == null) {
if (mAccount == null) {
mHandler.updateFooter("", false);
return;
}
int limit = account.getRemoteSearchNumResults();
int limit = mAccount.getRemoteSearchNumResults();
List<Message> toProcess = mAdapter.mExtraSearchResults;
if (limit > 0 && numResults > limit) {
toProcess = toProcess.subList(0, limit);
@ -682,7 +618,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
mAdapter.mExtraSearchResults = null;
mHandler.updateFooter("", false);
}
mController.loadSearchResults(account, mSearchFolder, toProcess, mAdapter.mListener);
mController.loadSearchResults(mAccount, mCurrentFolder.name, toProcess, mAdapter.mListener);
}
return;
}
@ -754,56 +690,58 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
private void decodeArguments() {
Bundle args = getArguments();
mQueryString = args.getString(SearchManager.QUERY);
mFolderName = args.getString(ARG_FOLDER);
mRemoteSearch = args.getBoolean(ARG_REMOTE_SEARCH, false);
mSearchAccount = args.getString(ARG_SEARCH_ACCOUNT);
mSearchFolder = args.getString(ARG_SEARCH_FOLDER);
mThreadId = args.getLong(ARG_THREAD_ID, -1);
String accountUuid = args.getString(ARG_ACCOUNT);
Context appContext = getActivity().getApplicationContext();
mAccount = Preferences.getPreferences(appContext).getAccount(accountUuid);
String queryFlags = args.getString(ARG_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 = args.getString(ARG_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 = args.getBoolean(ARG_INTEGRATE, false);
mAccountUuids = args.getStringArray(ARG_ACCOUNT_UUIDS);
mFolderNames = args.getStringArray(ARG_FOLDER_NAMES);
mTitle = args.getString(ARG_TITLE);
mSearch = args.getParcelable(ARG_SEARCH);
mTitle = args.getString(mSearch.getName());
Context appContext = getActivity().getApplicationContext();
String[] accounts = mSearch.getAccountUuids();
mSingleAccountMode = false;
if (accounts != null && accounts.length == 1
&& !accounts[0].equals(SearchSpecification.ALL_ACCOUNTS)) {
mSingleAccountMode = true;
mAccount = Preferences.getPreferences(appContext).getAccount(accounts[0]);
}
mSingleFolderMode = false;
if (mSingleAccountMode && (mSearch.getFolderNames().size() == 1)) {
mSingleFolderMode = true;
mFolderName = mSearch.getFolderNames().get(0);
mCurrentFolder = getFolder(mFolderName, mAccount);
}
}
private void initializeMessageList() {
mAdapter = new MessageListAdapter();
if (mFolderName != null) {
mCurrentFolder = mAdapter.getFolder(mFolderName, mAccount);
mCurrentFolder = getFolder(mFolderName, mAccount);
}
// Hide "Load up to x more" footer for search views
mFooterView.setVisibility((mQueryString != null) ? View.GONE : View.VISIBLE);
// Hide "Load up to x more" footer for search views
mFooterView.setVisibility((!mSingleFolderMode) ? View.GONE : View.VISIBLE);
mController = MessagingController.getInstance(getActivity().getApplication());
mListView.setAdapter(mAdapter);
}
private FolderInfoHolder getFolder(String folder, Account account) {
LocalFolder local_folder = null;
try {
LocalStore localStore = account.getLocalStore();
local_folder = localStore.getFolder(folder);
return new FolderInfoHolder(mContext, local_folder, account);
} catch (Exception e) {
Log.e(K9.LOG_TAG, "getFolder(" + folder + ") goes boom: ", e);
return null;
} finally {
if (local_folder != null) {
local_folder.close();
}
}
}
@Override
public void onPause() {
super.onPause();
@ -851,14 +789,6 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
final Preferences prefs = Preferences.getPreferences(appContext);
boolean allowRemoteSearch = false;
if (mSearchAccount != null) {
final Account searchAccount = prefs.getAccount(mSearchAccount);
if (searchAccount != null) {
allowRemoteSearch = searchAccount.allowRemoteSearch();
}
}
// Check if we have connectivity. Cache the value.
if (mHasConnectivity == null) {
final ConnectivityManager connectivityManager =
@ -872,24 +802,26 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
}
if (mQueryString == null) {
mPullToRefreshView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() {
@Override
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
checkMail();
}
});
} else if (allowRemoteSearch && !mRemoteSearch && !mIntegrate && mHasConnectivity) {
// mQueryString != null is implied if we get this far.
mPullToRefreshView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() {
@Override
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
mPullToRefreshView.onRefreshComplete();
onRemoteSearchRequested(true);
}
});
mPullToRefreshView.setPullLabel(getString(R.string.pull_to_refresh_remote_search_from_local_search_pull));
mPullToRefreshView.setReleaseLabel(getString(R.string.pull_to_refresh_remote_search_from_local_search_release));
if (mSingleFolderMode) {
if (!mAccount.allowRemoteSearch()) {
mPullToRefreshView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() {
@Override
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
checkMail();
}
});
// TODO this has to go! find better remote search integration
} else {
mPullToRefreshView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() {
@Override
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
mPullToRefreshView.onRefreshComplete();
onRemoteSearchRequested();
}
});
mPullToRefreshView.setPullLabel(getString(R.string.pull_to_refresh_remote_search_from_local_search_pull));
mPullToRefreshView.setReleaseLabel(getString(R.string.pull_to_refresh_remote_search_from_local_search_release));
}
} else {
mPullToRefreshView.setMode(PullToRefreshBase.Mode.DISABLED);
}
@ -899,7 +831,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
//Cancel pending new mail notifications when we open an account
Account[] accountsWithNotification;
Account account = getCurrentAccount(prefs);
Account account = mAccount;
if (account != null) {
accountsWithNotification = new Account[] { account };
@ -918,9 +850,40 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
if (mAdapter.isEmpty()) {
mController.searchLocalMessages(mSearch, mAdapter.mListener);
if (mRemoteSearch) {
//TODO: Support flag based search
mRemoteSearchFuture = mController.searchRemoteMessages(mSearchAccount, mSearchFolder, mQueryString, null, null, mAdapter.mListener);
/* mRemoteSearchFuture = mController.searchRemoteMessages(mAccount.getUuid(), mCurrentFolder.name, mSearch.getRemoteSearchArguments(),
null, null, mAdapter.mListener);*/
}
} else {
// reread the selected date format preference in case it has changed
mMessageHelper.refresh();
mAdapter.markAllMessagesAsDirty();
new Thread() {
@Override
public void run() {
mController.searchLocalMessages(mSearch, mAdapter.mListener);
mHandler.post(new Runnable() {
@Override
public void run() {
mAdapter.pruneDirtyMessages();
mAdapter.notifyDataSetChanged();
restoreListState();
}
});
}
}.start();
}
/*if (mAdapter.isEmpty()) {
if (mRemoteSearch) {
//TODO: Support flag based search
mRemoteSearchFuture = mController.searchRemoteMessages(mAccount.getUuid(), mCurrentFolder.name, mSearch.getRemoteSearchArguments(),
null, null, mAdapter.mListener);
} else if (mFolderName != null) {
mController.listLocalMessages(mAccount, mFolderName, mAdapter.mListener, mThreadViewEnabled, mThreadId);
@ -928,8 +891,8 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
if (!mAccount.hasArchiveFolder()) {
// mBatchArchiveButton.setVisibility(View.GONE);
}
} else if (mQueryString != null) {
mController.searchLocalMessages(mAccountUuids, mFolderNames, null, mQueryString, mIntegrate, mQueryFlags, mForbiddenFlags, mAdapter.mListener);
} else {
mController.searchLocalMessages(mSearch, mAdapter.mListener);
// Don't show the archive button if this is a search.
// mBatchArchiveButton.setVisibility(View.GONE);
}
@ -944,11 +907,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
new Thread() {
@Override
public void run() {
if (mFolderName != null) {
mController.listLocalMessagesSynchronous(mAccount, mFolderName, mAdapter.mListener, mThreadViewEnabled, mThreadId);
} else if (mQueryString != null) {
mController.searchLocalMessagesSynchronous(mAccountUuids, mFolderNames, null, mQueryString, mIntegrate, mQueryFlags, mForbiddenFlags, mAdapter.mListener);
}
mController.searchLocalMessages(mSearch, mAdapter.mListener);
mHandler.post(new Runnable() {
@Override
@ -963,7 +922,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
.start();
}
}
}*/
if (mAccount != null && mFolderName != null && !mRemoteSearch) {
mController.getFolderUnreadMessageCount(mAccount, mFolderName, mAdapter.mListener);
@ -989,7 +948,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
public void onCompose() {
if (mQueryString != null) {
if (!mSingleAccountMode) {
/*
* If we have a query string, we don't have an account to let
* compose start the default action.
@ -1023,22 +982,15 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
/**
* User has requested a remote search. Setup the bundle and start the intent.
* @param fromLocalSearch true if this is being called from a local search result screen. This affects
* where we pull the account and folder info used for the next search.
*/
public void onRemoteSearchRequested(final boolean fromLocalSearch) {
public void onRemoteSearchRequested() {
String searchAccount;
String searchFolder;
if (fromLocalSearch) {
searchAccount = mSearchAccount;
searchFolder = mSearchFolder;
} else {
searchAccount = mAccount.getUuid();
searchFolder = mCurrentFolder.name;
}
searchAccount = mAccount.getUuid();
searchFolder = mCurrentFolder.name;
mFragmentListener.remoteSearch(searchAccount, searchFolder, mQueryString);
mFragmentListener.remoteSearch(searchAccount, searchFolder, mSearch.getRemoteSearchArguments());
}
/**
@ -1055,7 +1007,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
mSortType = sortType;
Preferences prefs = Preferences.getPreferences(getActivity().getApplicationContext());
Account account = getCurrentAccount(prefs);
Account account = mAccount;
if (account != null) {
account.setSortType(mSortType);
@ -1247,7 +1199,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
}
if (mQueryString != null) {
if (!mSingleAccountMode) {
// None of the options after this point are "safe" for search results
//TODO: This is not true for "unread" and "starred" searches in regular folders
return false;
@ -1531,7 +1483,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
@Override
public void listLocalMessagesStarted(Account account, String folder) {
if ((mQueryString != null && folder == null) || (account != null && account.equals(mAccount))) {
if ((!mSingleAccountMode && folder == null) || (account != null && account.equals(mAccount))) {
mHandler.progress(true);
if (folder != null) {
mHandler.folderLoading(folder, true);
@ -1541,7 +1493,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
@Override
public void listLocalMessagesFailed(Account account, String folder, String message) {
if ((mQueryString != null && folder == null) || (account != null && account.equals(mAccount))) {
if ((!mSingleAccountMode && folder == null) || (account != null && account.equals(mAccount))) {
mHandler.sortMessages();
mHandler.progress(false);
if (folder != null) {
@ -1552,7 +1504,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
@Override
public void listLocalMessagesFinished(Account account, String folder) {
if ((mQueryString != null && folder == null) || (account != null && account.equals(mAccount))) {
if ((!mSingleAccountMode && folder == null) || (account != null && account.equals(mAccount))) {
mHandler.sortMessages();
mHandler.progress(false);
if (folder != null) {
@ -1601,12 +1553,17 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
};
private boolean updateForMe(Account account, String folder) {
private boolean updateForMe(Account account, String folder) {
// TODO get a contentprovider :D
return true;
/*
if ((account.equals(mAccount) && mFolderName != null && folder.equals(mFolderName))) {
return true;
} else {
return false;
}
*/
}
public List<MessageInfoHolder> getMessages() {
@ -1726,7 +1683,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
public void resetUnreadCount() {
if (mQueryString != null) {
if (!mSingleFolderMode) {
int unreadCount = 0;
for (MessageInfoHolder holder : mMessages) {
@ -1802,7 +1759,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
} else {
messagesToAdd.add(m);
}
} else {
} /*else {
if (mQueryString != null) {
if (verifyAgainstSearch) {
messagesToSearch.add(message);
@ -1815,7 +1772,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
messagesToAdd.add(m);
}
}
}
}*/
} else {
m.dirty = false; // as we reload the message, unset its dirty flag
FolderInfoHolder folderInfoHolder = new FolderInfoHolder(mContext,
@ -1827,9 +1784,29 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
if (!messagesToSearch.isEmpty()) {
mController.searchLocalMessages(mAccountUuids, mFolderNames,
messagesToSearch.toArray(EMPTY_MESSAGE_ARRAY), mQueryString, mIntegrate,
mQueryFlags, mForbiddenFlags,
// building a tree with all possible message id's we want to search in
ConditionsTreeNode msgIdTree = new ConditionsTreeNode(
new SearchCondition(SEARCHFIELD.UID, ATTRIBUTE.EQUALS,
String.valueOf(messagesToSearch.get(0).getUid())));
if (messagesToSearch.size() > 1) {
for(int i=1; i<messagesToSearch.size(); ++i) {
msgIdTree.or(new SearchCondition(SEARCHFIELD.UID, ATTRIBUTE.EQUALS,
String.valueOf(messagesToSearch.get(i).getUid())));
}
}
// construct a new search with existing conditions and the message id narrowing
LocalSearch tmpSearch = null;
try {
tmpSearch = new LocalSearch(MessageListFragment.this.mSearch.getName());
tmpSearch.and(msgIdTree);
} catch (Exception e) {
// impossible, we created it here locally, parent = null
}
// search
mController.searchLocalMessages(tmpSearch,
new MessagingListener() {
@Override
public void listLocalMessagesAddMessages(Account account, String folder,
@ -1921,23 +1898,6 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
return null;
}
public FolderInfoHolder getFolder(String folder, Account account) {
LocalFolder local_folder = null;
try {
LocalStore localStore = account.getLocalStore();
local_folder = localStore.getFolder(folder);
return new FolderInfoHolder(mContext, local_folder, account);
} catch (Exception e) {
Log.e(K9.LOG_TAG, "getFolder(" + folder + ") goes boom: ", e);
return null;
} finally {
if (local_folder != null) {
local_folder.close();
}
}
}
@Override
public int getCount() {
return mMessages.size();
@ -2674,7 +2634,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
*
* @return The {@code Account} all displayed messages belong to.
*/
private Account getCurrentAccount(Preferences prefs) {
/*private Account getCurrentAccount(Preferences prefs) {
Account account = null;
if (mQueryString != null && !mIntegrate && mAccountUuids != null &&
mAccountUuids.length == 1) {
@ -2685,7 +2645,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
return account;
}
}*/
class ActionModeCallback implements ActionMode.Callback {
@ -2703,7 +2663,8 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
mFlag = menu.findItem(R.id.flag);
mUnflag = menu.findItem(R.id.unflag);
if (mQueryString != null) {
// we don't support cross account actions atm
if (!mSingleAccountMode) {
// show all
menu.findItem(R.id.move).setVisible(true);
menu.findItem(R.id.archive).setVisible(true);
@ -2744,9 +2705,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
inflater.inflate(R.menu.message_list_context, menu);
// check capabilities
if (mQueryString == null) {
setContextCapabilities(mAccount, menu);
}
setContextCapabilities(mAccount, menu);
return true;
}
@ -2764,33 +2723,32 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
* TODO get rid of this when we finally split the messagelist into
* a folder content display and a search result display
*/
if (mQueryString != null) {
if (!mSingleAccountMode) {
menu.findItem(R.id.move).setVisible(false);
menu.findItem(R.id.copy).setVisible(false);
menu.findItem(R.id.archive).setVisible(false);
menu.findItem(R.id.spam).setVisible(false);
return;
}
// hide unsupported
if (!mController.isCopyCapable(mAccount)) {
menu.findItem(R.id.copy).setVisible(false);
}
if (!mController.isMoveCapable(mAccount)) {
menu.findItem(R.id.move).setVisible(false);
menu.findItem(R.id.archive).setVisible(false);
menu.findItem(R.id.spam).setVisible(false);
}
if (!mAccount.hasArchiveFolder()) {
menu.findItem(R.id.archive).setVisible(false);
}
if (!mAccount.hasSpamFolder()) {
menu.findItem(R.id.spam).setVisible(false);
} else {
// hide unsupported
if (!mController.isCopyCapable(mAccount)) {
menu.findItem(R.id.copy).setVisible(false);
}
if (!mController.isMoveCapable(mAccount)) {
menu.findItem(R.id.move).setVisible(false);
menu.findItem(R.id.archive).setVisible(false);
menu.findItem(R.id.spam).setVisible(false);
}
if (!mAccount.hasArchiveFolder()) {
menu.findItem(R.id.archive).setVisible(false);
}
if (!mAccount.hasSpamFolder()) {
menu.findItem(R.id.spam).setVisible(false);
}
}
}
@ -2922,7 +2880,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
@Override
public void onStop() {
// If we represent a remote search, then kill that before going back.
if (mSearchAccount != null && mSearchFolder != null && mRemoteSearchFuture != null) {
if (isRemoteSearch() && mRemoteSearchFuture != null) {
try {
Log.i(K9.LOG_TAG, "Remote search in progress, attempting to abort...");
// Canceling the future stops any message fetches in progress.
@ -2931,13 +2889,11 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
Log.e(K9.LOG_TAG, "Could not cancel remote search future.");
}
// Closing the folder will kill off the connection if we're mid-search.
Context appContext = getActivity().getApplicationContext();
final Account searchAccount = Preferences.getPreferences(appContext).getAccount(mSearchAccount);
final Store remoteStore = searchAccount.getRemoteStore();
final Folder remoteFolder = remoteStore.getFolder(mSearchFolder);
final Account searchAccount = mAccount;
final Folder remoteFolder = mCurrentFolder.folder;
remoteFolder.close();
// Send a remoteSearchFinished() message for good measure.
mAdapter.mListener.remoteSearchFinished(searchAccount, mSearchFolder, 0, null);
mAdapter.mListener.remoteSearchFinished(searchAccount, mCurrentFolder.name, 0, null);
} catch (Exception e) {
// Since the user is going back, log and squash any exceptions.
Log.e(K9.LOG_TAG, "Could not abort remote search before going back", e);
@ -3057,7 +3013,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
public boolean isSearchQuery() {
return (mQueryString != null || mIntegrate);
return (mSearch.getRemoteSearchArguments() != null || !mSingleAccountMode);
}
public boolean isOutbox() {
@ -3092,7 +3048,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
public void onRemoteSearch() {
// Remote search is useless without the network.
if (mHasConnectivity) {
onRemoteSearchRequested(true);
onRemoteSearchRequested();
} else {
Toast.makeText(getActivity(), getText(R.string.remote_search_unavailable_no_network),
Toast.LENGTH_SHORT).show();
@ -3104,7 +3060,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
}
public boolean isRemoteSearchAllowed() {
if (!isSearchQuery() || mRemoteSearch || mSearchFolder == null || mSearchAccount == null) {
if (!isSearchQuery() || mRemoteSearch || !mSingleFolderMode) {
return false;
}
@ -3112,7 +3068,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick
final Preferences prefs = Preferences.getPreferences(appContext);
boolean allowRemoteSearch = false;
final Account searchAccount = prefs.getAccount(mSearchAccount);
final Account searchAccount = mAccount;
if (searchAccount != null) {
allowRemoteSearch = searchAccount.allowRemoteSearch();
}

View file

@ -292,6 +292,20 @@ public class LocalSearch implements SearchSpecification {
///////////////////////////////////////////////////////////////
// Public accesor methods
///////////////////////////////////////////////////////////////
/**
* TODO THIS HAS TO GO!!!!
* very dirty fix for remotesearch support atm
*/
public String getRemoteSearchArguments() {
for (ConditionsTreeNode node : getLeafSet()) {
if (node.getCondition().field == SEARCHFIELD.SUBJECT
|| node.getCondition().field == SEARCHFIELD.SENDER ) {
return node.getCondition().value;
}
}
return null;
}
/**
* Returns the name of the saved search.
*