From 360b3f1be8311fb661632692a6d672a0ccc8b5d3 Mon Sep 17 00:00:00 2001 From: Andrew Chen Date: Sat, 22 Sep 2012 09:40:46 -0700 Subject: [PATCH] Add cloud search icon to local search result screen. Implement pull-to-remote-search. --- res/layout/actionbar_custom.xml | 11 ++ res/menu/message_list_option.xml | 8 ++ res/values/attrs.xml | 1 + res/values/strings.xml | 25 ++-- res/values/themes.xml | 2 + res/xml/account_settings_preferences.xml | 11 +- src/com/fsck/k9/activity/MessageList.java | 117 ++++++++++++------ .../k9/activity/setup/AccountSettings.java | 81 ++++++------ 8 files changed, 157 insertions(+), 99 deletions(-) diff --git a/res/layout/actionbar_custom.xml b/res/layout/actionbar_custom.xml index 6d7ac5677..918507286 100644 --- a/res/layout/actionbar_custom.xml +++ b/res/layout/actionbar_custom.xml @@ -39,4 +39,15 @@ android:textColor="?android:attr/textColorTertiary" android:textSize="36sp" /> + + \ No newline at end of file diff --git a/res/menu/message_list_option.xml b/res/menu/message_list_option.xml index 12a7dfadd..e292edaf1 100644 --- a/res/menu/message_list_option.xml +++ b/res/menu/message_list_option.xml @@ -1,6 +1,14 @@ + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 02359d8b5..10b99182a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1120,8 +1120,7 @@ http://k9mail.googlecode.com/ Saved image as \"%s\" Saving the image failed. - Allow remote search - Enable remote searching for this account + All 10 25 @@ -1130,19 +1129,19 @@ http://k9mail.googlecode.com/ 250 500 1000 - Results limit - All Local Folders - Remote Folder - Search Location + Server search result limit + Search will stop after %s results have been found. Remote folder searching - Can be slow - Include body text - - To perform a remote search, press your device\'s Search button while viewing a folder from this account. - \n\nNote: Remote search is NOT available from the Unified Inbox or from a list of folders. - + Include body text in server search + Full text searches can be slow. Sending query to server - Don\'t Show Again Fetching %d results Fetching %1$d of %2$d results + + Search + Enable server search + Search messages on the server in addition to those on your device + Search messages on server + Pull to search server… + Release to search server… diff --git a/res/values/themes.xml b/res/values/themes.xml index 801dcadc6..01a3f3d69 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -25,6 +25,7 @@ @drawable/ic_action_spam_light @drawable/ic_action_toggle_flag_light @drawable/ic_action_toggle_read_light + @drawable/ic_action_remote_search_light @drawable/ic_menu_add @drawable/ic_menu_attachment @drawable/ic_menu_clear @@ -67,6 +68,7 @@ @drawable/ic_action_spam_dark @drawable/ic_action_toggle_flag_dark @drawable/ic_action_toggle_read_dark + @drawable/ic_action_remote_search_dark @drawable/ic_menu_add @drawable/ic_menu_attachment @drawable/ic_menu_clear diff --git a/res/xml/account_settings_preferences.xml b/res/xml/account_settings_preferences.xml index c5ff71338..8c76d5910 100644 --- a/res/xml/account_settings_preferences.xml +++ b/res/xml/account_settings_preferences.xml @@ -462,10 +462,11 @@ - + + android:dependency="remote_search_enabled"/> + android:dependency="remote_search_enabled"/> diff --git a/src/com/fsck/k9/activity/MessageList.java b/src/com/fsck/k9/activity/MessageList.java index 3143f2d88..006932392 100644 --- a/src/com/fsck/k9/activity/MessageList.java +++ b/src/com/fsck/k9/activity/MessageList.java @@ -12,8 +12,8 @@ import java.util.Map; import android.app.AlertDialog; import android.app.Dialog; import android.app.SearchManager; +import android.content.ComponentName; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences.Editor; import android.graphics.Color; @@ -28,10 +28,8 @@ import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.util.Log; import android.util.TypedValue; -import android.view.GestureDetector; import android.view.KeyEvent; import android.view.LayoutInflater; -import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; @@ -926,14 +924,34 @@ public class MessageList extends K9ListActivity implements OnItemClickListener { mStars = K9.messageListStars(); mCheckboxes = K9.messageListCheckboxes(); - // TODO Add support for pull to fresh on searches. - if(mQueryString == null) { + final Preferences prefs = Preferences.getPreferences(getApplicationContext()); + + boolean allowRemoteSearch = false; + if (mSearchAccount != null) { + final Account searchAccount = prefs.getAccount(mSearchAccount); + if (searchAccount != null) { + allowRemoteSearch = searchAccount.allowRemoteSearch(); + } + } + + if (mQueryString == null) { mPullToRefreshView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener() { @Override public void onRefresh(PullToRefreshBase refreshView) { checkMail(mAccount, mFolderName); } }); + } else if (allowRemoteSearch && !mRemoteSearch && !mIntegrate) { + // mQueryString != null is implied if we get this far. + mPullToRefreshView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener() { + @Override + public void onRefresh(PullToRefreshBase 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)); } else { mPullToRefreshView.setMode(PullToRefreshBase.Mode.DISABLED); } @@ -943,7 +961,6 @@ public class MessageList extends K9ListActivity implements OnItemClickListener { //Cancel pending new mail notifications when we open an account Account[] accountsWithNotification; - Preferences prefs = Preferences.getPreferences(getApplicationContext()); Account account = getCurrentAccount(prefs); if (account != null) { @@ -1285,44 +1302,47 @@ public class MessageList extends K9ListActivity implements OnItemClickListener { AccountSettings.actionSettings(this, mAccount); } - @Override - public boolean onSearchRequested() { - - if (mAccount != null && mCurrentFolder != null && mAccount.allowRemoteSearch()) { - //if in a remote searchable folder, ask user what they want. - //TODO: Add ability to remember selection? - final CharSequence[] items = new CharSequence[2]; - items[0] = getString(R.string.search_mode_local_all); - items[1] = getString(R.string.search_mode_remote); - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(getString(R.string.search_mode_title)); - builder.setItems(items, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int item) { - - Bundle appData = null; - if (item == 1) { - appData = new Bundle(); - appData.putString(EXTRA_SEARCH_ACCOUNT, mAccount.getUuid()); - appData.putString(EXTRA_SEARCH_FOLDER, mCurrentFolder.name); - appData.putBoolean(EXTRA_REMOTE_SEARCH, true); - } - //else do regular search, which doesn't require any special parameter setup - - startSearch(null, false, appData, false); - } - }); - AlertDialog alert = builder.create(); - alert.show(); - - return true; + /** + * 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) { + final Bundle appData = new Bundle(); + if (fromLocalSearch) { + appData.putString(EXTRA_SEARCH_ACCOUNT, mSearchAccount); + appData.putString(EXTRA_SEARCH_FOLDER, mSearchFolder); + } else { + appData.putString(EXTRA_SEARCH_ACCOUNT, mAccount.getUuid()); + appData.putString(EXTRA_SEARCH_FOLDER, mCurrentFolder.name); } + appData.putBoolean(EXTRA_REMOTE_SEARCH, true); - startSearch(null, false, null, false); - return true; + final Intent intent = new Intent(Intent.ACTION_SEARCH); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(SearchManager.QUERY, mQueryString); + intent.putExtra(SearchManager.APP_DATA, appData); + intent.setComponent(new ComponentName(context.getApplicationContext(), MessageList.class)); + context.startActivity(intent); } + @Override + public boolean onSearchRequested() { + // If this search was started from a MessageList of a single folder, pass along that folder info + // so that we can enable remote search. + if (mAccount != null && mCurrentFolder != null) { + final Bundle appData = new Bundle(); + appData.putString(EXTRA_SEARCH_ACCOUNT, mAccount.getUuid()); + appData.putString(EXTRA_SEARCH_FOLDER, mCurrentFolder.name); + startSearch(null, false, appData, false); + } else { + // TODO Handle the case where we're searching from within a search result. + startSearch(null, false, null, false); + } + return true; + } + private void changeSort(SortType sortType) { Boolean sortAscending = (mSortType == sortType) ? !mSortAscending : null; changeSort(sortType, sortAscending); @@ -1627,6 +1647,10 @@ public class MessageList extends K9ListActivity implements OnItemClickListener { onEditPrefs(); return true; } + case R.id.search_remote: { + onRemoteSearchRequested(true); + return true; + } } if (mQueryString != null) { @@ -1679,6 +1703,21 @@ public class MessageList extends K9ListActivity implements OnItemClickListener { menu.findItem(R.id.send_messages).setVisible(false); menu.findItem(R.id.folder_settings).setVisible(false); menu.findItem(R.id.account_settings).setVisible(false); + // If this is an explicit local search, show the option to search the cloud. + + final Preferences prefs = Preferences.getPreferences(getApplicationContext()); + + boolean allowRemoteSearch = false; + if (mSearchAccount != null) { + final Account searchAccount = prefs.getAccount(mSearchAccount); + if (searchAccount != null) { + allowRemoteSearch = searchAccount.allowRemoteSearch(); + } + } + + if (allowRemoteSearch && mQueryString != null && !mRemoteSearch && !mIntegrate && mSearchFolder != null) { + menu.findItem(R.id.search_remote).setVisible(true); + } } else { if (mCurrentFolder != null && mCurrentFolder.name.equals(mAccount.getOutboxFolderName())) { menu.findItem(R.id.check_mail).setVisible(false); diff --git a/src/com/fsck/k9/activity/setup/AccountSettings.java b/src/com/fsck/k9/activity/setup/AccountSettings.java index 0ea74b7bc..d9f72e2c0 100644 --- a/src/com/fsck/k9/activity/setup/AccountSettings.java +++ b/src/com/fsck/k9/activity/setup/AccountSettings.java @@ -58,11 +58,12 @@ public class AccountSettings extends K9PreferenceActivity { private static final int ACTIVITY_MANAGE_IDENTITIES = 2; + private static final String PREFERENCE_SCREEN_MAIN = "main"; private static final String PREFERENCE_SCREEN_COMPOSING = "composing"; private static final String PREFERENCE_SCREEN_INCOMING = "incoming_prefs"; private static final String PREFERENCE_SCREEN_PUSH_ADVANCED = "push_advanced"; private static final String PREFERENCE_SCREEN_NOTIFICATIONS = "notifications"; - private static final String PREFERENCE_SCREEN_REMOTE_SEARCH = "remote_search"; + private static final String PREFERENCE_SCREEN_SEARCH = "search"; private static final String PREFERENCE_DESCRIPTION = "account_description"; private static final String PREFERENCE_MARK_MESSAGE_AS_READ_ON_VIEW = "mark_message_as_read_on_view"; @@ -112,7 +113,7 @@ public class AccountSettings extends K9PreferenceActivity { private static final String PREFERENCE_CRYPTO_APP = "crypto_app"; private static final String PREFERENCE_CRYPTO_AUTO_SIGNATURE = "crypto_auto_signature"; private static final String PREFERENCE_CRYPTO_AUTO_ENCRYPT = "crypto_auto_encrypt"; - private static final String PREFERENCE_ALLOW_REMOTE_SEARCH = "account_allow_remote_search"; + private static final String PREFERENCE_CLOUD_SEARCH_ENABLED = "cloud_search_enabled"; private static final String PREFERENCE_REMOTE_SEARCH_NUM_RESULTS = "account_remote_search_num_results"; private static final String PREFERENCE_REMOTE_SEARCH_FULL_TEXT = "account_remote_search_full_text"; @@ -131,6 +132,7 @@ public class AccountSettings extends K9PreferenceActivity { private boolean mIsPushCapable = false; private boolean mIsExpungeCapable = false; + private PreferenceScreen mMainScreen; private PreferenceScreen mComposingScreen; private EditTextPreference mAccountDescription; @@ -177,9 +179,12 @@ public class AccountSettings extends K9PreferenceActivity { private ListPreference mCryptoApp; private CheckBoxPreference mCryptoAutoSignature; private CheckBoxPreference mCryptoAutoEncrypt; - private CheckBoxPreference mAllowRemoteSearch; + + private PreferenceScreen mSearchScreen; + private CheckBoxPreference mCloudSearchEnabled; private ListPreference mRemoteSearchNumResults; private CheckBoxPreference mRemoteSearchFullText; + private ListPreference mLocalStorageProvider; private ListPreference mArchiveFolder; private ListPreference mDraftsFolder; @@ -213,6 +218,8 @@ public class AccountSettings extends K9PreferenceActivity { addPreferencesFromResource(R.xml.account_settings_preferences); + mMainScreen = (PreferenceScreen) findPreference(PREFERENCE_SCREEN_MAIN); + mAccountDescription = (EditTextPreference) findPreference(PREFERENCE_DESCRIPTION); mAccountDescription.setSummary(mAccount.getDescription()); mAccountDescription.setText(mAccount.getDescription()); @@ -415,7 +422,7 @@ public class AccountSettings extends K9PreferenceActivity { if (!mAccount.isSearchByDateCapable()) { ((PreferenceScreen) findPreference(PREFERENCE_SCREEN_INCOMING)).removePreference(mMessageAge); - } else { + } else { mMessageAge.setValue(String.valueOf(mAccount.getMaximumPolledMessageAge())); mMessageAge.setSummary(mMessageAge.getEntry()); mMessageAge.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @@ -489,27 +496,30 @@ public class AccountSettings extends K9PreferenceActivity { } }); } - // IMAP-specific preferences - mAllowRemoteSearch = (CheckBoxPreference) findPreference(PREFERENCE_ALLOW_REMOTE_SEARCH); - mAllowRemoteSearch.setOnPreferenceChangeListener( + // IMAP-specific preferences + + mSearchScreen = (PreferenceScreen) findPreference(PREFERENCE_SCREEN_SEARCH); + mCloudSearchEnabled = (CheckBoxPreference) findPreference(PREFERENCE_CLOUD_SEARCH_ENABLED); + mRemoteSearchNumResults = (ListPreference) findPreference(PREFERENCE_REMOTE_SEARCH_NUM_RESULTS); + mRemoteSearchNumResults.setOnPreferenceChangeListener( new OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newVal) { - if ((Boolean) newVal) { - showRemoteSearchHelp(); - } + updateRemoteSearchLimit((String)newVal); return true; } - }); - mRemoteSearchNumResults = (ListPreference) findPreference(PREFERENCE_REMOTE_SEARCH_NUM_RESULTS); + } + ); + updateRemoteSearchLimit(mRemoteSearchNumResults.getValue()); mRemoteSearchFullText = (CheckBoxPreference) findPreference(PREFERENCE_REMOTE_SEARCH_FULL_TEXT); + mPushPollOnConnect = (CheckBoxPreference) findPreference(PREFERENCE_PUSH_POLL_ON_CONNECT); mIdleRefreshPeriod = (ListPreference) findPreference(PREFERENCE_IDLE_REFRESH_PERIOD); mMaxPushFolders = (ListPreference) findPreference(PREFERENCE_MAX_PUSH_FOLDERS); if (mIsPushCapable) { mPushPollOnConnect.setChecked(mAccount.isPushPollOnConnect()); - mAllowRemoteSearch.setChecked(mAccount.allowRemoteSearch()); + mCloudSearchEnabled.setChecked(mAccount.allowRemoteSearch()); mRemoteSearchNumResults.setValue(Integer.toString(mAccount.getRemoteSearchNumResults())); mRemoteSearchFullText.setChecked(mAccount.isRemoteSearchFullText()); @@ -552,9 +562,7 @@ public class AccountSettings extends K9PreferenceActivity { PreferenceScreen incomingPrefs = (PreferenceScreen) findPreference(PREFERENCE_SCREEN_INCOMING); incomingPrefs.removePreference((PreferenceScreen) findPreference(PREFERENCE_SCREEN_PUSH_ADVANCED)); incomingPrefs.removePreference((ListPreference) findPreference(PREFERENCE_PUSH_MODE)); - - ((PreferenceScreen) findPreference("main")).removePreference((PreferenceScreen) findPreference(PREFERENCE_SCREEN_REMOTE_SEARCH)); - + mMainScreen.removePreference(mSearchScreen); } mAccountNotify = (CheckBoxPreference) findPreference(PREFERENCE_NOTIFY); @@ -714,31 +722,6 @@ public class AccountSettings extends K9PreferenceActivity { handleCryptoAppDependencies(); } - protected void showRemoteSearchHelp() { - final String noShowHelpPref = "account_settings_remote_search_hide_help"; - final SharedPreferences prefs = getPreferences(MODE_PRIVATE); - if (!prefs.getBoolean(noShowHelpPref, false)) { - AlertDialog.Builder adb = new AlertDialog.Builder(this); - final CheckBox noShowAgain = new CheckBox(this); - noShowAgain.setChecked(false); - noShowAgain.setText(R.string.no_show_again); - adb.setView(noShowAgain) - .setMessage(getString(R.string.account_settings_allow_remote_search_help)) - .setCancelable(false) - .setPositiveButton(R.string.okay_action, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if(noShowAgain.isChecked()){ - Editor edit = prefs.edit(); - edit.putBoolean(noShowHelpPref, true); - edit.commit(); - } - } - }); - adb.create().show(); - } - - } - private void handleCryptoAppDependencies() { if ("".equals(mCryptoApp.getValue())) { mCryptoAutoSignature.setEnabled(false); @@ -812,7 +795,7 @@ public class AccountSettings extends K9PreferenceActivity { mAccount.setPushPollOnConnect(mPushPollOnConnect.isChecked()); mAccount.setIdleRefreshMinutes(Integer.parseInt(mIdleRefreshPeriod.getValue())); mAccount.setMaxPushFolders(Integer.parseInt(mMaxPushFolders.getValue())); - mAccount.setAllowRemoteSearch(mAllowRemoteSearch.isChecked()); + mAccount.setAllowRemoteSearch(mCloudSearchEnabled.isChecked()); mAccount.setRemoteSearchNumResults(Integer.parseInt(mRemoteSearchNumResults.getValue())); mAccount.setRemoteSearchFullText(mRemoteSearchFullText.isChecked()); } @@ -989,6 +972,20 @@ public class AccountSettings extends K9PreferenceActivity { Integer.parseInt(mAccountVibrateTimes.getValue())), -1); } + /** + * Remote search result limit summary contains the current limit. On load or change, update this value. + * @param maxResults Search limit to update the summary with. + */ + private void updateRemoteSearchLimit(String maxResults) { + if (maxResults != null) { + if (maxResults.equals("0")) { + maxResults = getString(R.string.account_settings_remote_search_num_results_entries_all); + } + + mRemoteSearchNumResults.setSummary(String.format(getString(R.string.account_settings_remote_search_num_summary), maxResults)); + } + } + private class PopulateFolderPrefsTask extends AsyncTask { List folders = new LinkedList(); String[] allFolderValues;