SearchActivity.java revision d6b9bd42f22582a8ccec657bd6d715465de98ec9
13e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert/* 23e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Copyright (C) 2009 The Android Open Source Project 33e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * 43e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 53e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * you may not use this file except in compliance with the License. 63e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * You may obtain a copy of the License at 73e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * 83e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 93e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * 103e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 113e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 123e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * See the License for the specific language governing permissions and 143e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * limitations under the License. 153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 173e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertpackage com.android.quicksearchbox; 183e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 193f71a11f8858b9164ca83e8d2f558dd8a8a5e2deBjorn Bringertimport com.android.common.Search; 20c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringertimport com.android.quicksearchbox.ui.CorpusViewFactory; 21185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionClickListener; 227b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionSelectionListener; 23185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionsAdapter; 24883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringertimport com.android.quicksearchbox.ui.SuggestionsFooter; 25185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionsView; 26185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.app.Activity; 283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.app.SearchManager; 29dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringertimport android.content.DialogInterface; 303e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.content.Intent; 31d7a95801d20a9405b4ab9c9b4beecd106e880166Bryan Mawhinneyimport android.graphics.drawable.Drawable; 32fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.net.Uri; 333e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.os.Bundle; 3411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringertimport android.os.Debug; 354ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringertimport android.os.Handler; 363e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.text.Editable; 373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.text.TextUtils; 383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.text.TextWatcher; 393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.util.Log; 403e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.KeyEvent; 413e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.Menu; 423e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.View; 43883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringertimport android.view.ViewGroup; 443e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.View.OnFocusChangeListener; 453e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.inputmethod.InputMethodManager; 46145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringertimport android.widget.AbsListView; 473e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.widget.EditText; 483e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.widget.ImageButton; 493e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 5011234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringertimport java.io.File; 51e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringertimport java.util.Collection; 5247d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringertimport java.util.Collections; 5347d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringertimport java.util.List; 54ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 553e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert/** 563e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * The main activity for Quick Search Box. Shows the search UI. 573e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * 583e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 593e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertpublic class SearchActivity extends Activity { 603e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 61b5fc08b7f16a32d3865f44b7f26d8aaa5304a2adBjorn Bringert private static final boolean DBG = false; 620484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert private static final String TAG = "QSB.SearchActivity"; 6311234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert private static final boolean TRACE = false; 643e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 65fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String SCHEME_CORPUS = "qsb.corpus"; 66fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 67fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public static final String INTENT_ACTION_QSB_AND_SELECT_CORPUS 68fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert = "com.android.quicksearchbox.action.QSB_AND_SELECT_CORPUS"; 693e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 70c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert // The string used for privateImeOptions to identify to the IME that it should not show 71c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert // a microphone button since one already exists in the search dialog. 72c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert // TODO: This should move to android-common or something. 73c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert private static final String IME_OPTION_NO_MICROPHONE = "nm"; 74c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert 759ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Keys for the saved instance state. 76fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String INSTANCE_KEY_CORPUS = "corpus"; 779ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert private static final String INSTANCE_KEY_USER_QUERY = "query"; 78713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 79f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // Measures time from for last onCreate()/onNewIntent() call. 80f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private LatencyTracker mStartLatencyTracker; 81ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // Whether QSB is starting. True between the calls to onCreate()/onNewIntent() and onResume(). 82ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private boolean mStarting; 83ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // True if the user has taken some action, e.g. launching a search, voice search, 84ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // or suggestions, since QSB was last started. 85ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private boolean mTookAction; 86ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 87f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private CorpusSelectionDialog mCorpusSelectionDialog; 88f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert 89185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert protected SuggestionsAdapter mSuggestionsAdapter; 90185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 913e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected EditText mQueryTextView; 92e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert // True if the query was empty on the previous call to updateQuery() 93e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert protected boolean mQueryWasEmpty = true; 943e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected SuggestionsView mSuggestionsView; 96883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert protected SuggestionsFooter mSuggestionsFooter; 973e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 983e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected ImageButton mSearchGoButton; 993e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected ImageButton mVoiceSearchButton; 100a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert protected ImageButton mCorpusIndicator; 1013e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 1023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private Launcher mLauncher; 1033e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 104fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Corpus mCorpus; 1052617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert private Bundle mAppSearchData; 106713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private boolean mUpdateSuggestions; 107713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private String mUserQuery; 108713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private boolean mSelectAll; 1093e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 110d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Handler mHandler = new Handler(); 111d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Runnable mUpdateSuggestionsTask = new Runnable() { 1124ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert public void run() { 1134ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert updateSuggestions(getQuery()); 1144ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 1154ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert }; 1164ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 117d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Runnable mShowInputMethodTask = new Runnable() { 118d98911178013162737fbba74387b51d2a08b0493Amith Yamasani public void run() { 119d98911178013162737fbba74387b51d2a08b0493Amith Yamasani showInputMethodForQuery(); 120d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 121d98911178013162737fbba74387b51d2a08b0493Amith Yamasani }; 122d98911178013162737fbba74387b51d2a08b0493Amith Yamasani 1233e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** Called when the activity is first created. */ 1243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 1253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onCreate(Bundle savedInstanceState) { 12611234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (TRACE) startMethodTracing(); 127ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert recordStartTime(); 1283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "onCreate()"); 1293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onCreate(savedInstanceState); 130713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 131e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert setContentView(R.layout.search_activity); 1323e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 133816804b67619af133860a1e28e92f58bc642260dBjorn Bringert mSuggestionsAdapter = getQsbApplication().createSuggestionsAdapter(); 134185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 1353e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mQueryTextView = (EditText) findViewById(R.id.search_src_text); 1363e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mSuggestionsView = (SuggestionsView) findViewById(R.id.suggestions); 137782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mSuggestionsView.setSuggestionClickListener(new ClickHandler()); 1387b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert mSuggestionsView.setSuggestionSelectionListener(new SelectionHandler()); 139145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert mSuggestionsView.setOnScrollListener(new InputMethodCloser()); 140713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert mSuggestionsView.setOnKeyListener(new SuggestionsViewKeyListener()); 1417b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert mSuggestionsView.setOnFocusChangeListener(new SuggestListFocusListener()); 1423e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 143883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert mSuggestionsFooter = getQsbApplication().createSuggestionsFooter(); 144dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert ViewGroup footerFrame = (ViewGroup) findViewById(R.id.footer); 145dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert mSuggestionsFooter.addToContainer(footerFrame); 146883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringert 1473e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mSearchGoButton = (ImageButton) findViewById(R.id.search_go_btn); 1483e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mVoiceSearchButton = (ImageButton) findViewById(R.id.search_voice_btn); 149a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert mCorpusIndicator = (ImageButton) findViewById(R.id.corpus_indicator); 1503e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 1519ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert mLauncher = new Launcher(this); 1523e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 153782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mQueryTextView.addTextChangedListener(new SearchTextWatcher()); 154782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mQueryTextView.setOnKeyListener(new QueryTextViewKeyListener()); 1557b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert mQueryTextView.setOnFocusChangeListener(new QueryTextViewFocusListener()); 156782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 157fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mCorpusIndicator.setOnClickListener(new CorpusIndicatorClickListener()); 1582617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 159782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mSearchGoButton.setOnClickListener(new SearchGoButtonClickListener()); 160782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 161782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mVoiceSearchButton.setOnClickListener(new VoiceSearchButtonClickListener()); 1627be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 1637be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert ButtonsKeyListener buttonsKeyListener = new ButtonsKeyListener(); 1647be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert mSearchGoButton.setOnKeyListener(buttonsKeyListener); 1657be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert mVoiceSearchButton.setOnKeyListener(buttonsKeyListener); 166fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mCorpusIndicator.setOnKeyListener(buttonsKeyListener); 167713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 1689ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert mUpdateSuggestions = true; 1699ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 1709ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // First get setup from intent 1719ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert Intent intent = getIntent(); 1729ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setupFromIntent(intent); 1739ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Then restore any saved instance state 1749ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert restoreInstanceState(savedInstanceState); 1759ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 176713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert // Do this at the end, to avoid updating the list view when setSource() 177713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert // is called. 178713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert mSuggestionsView.setAdapter(mSuggestionsAdapter); 179dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert mSuggestionsFooter.setAdapter(mSuggestionsAdapter); 1809ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 181713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 18211234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert private void startMethodTracing() { 18311234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert File traceDir = getDir("traces", 0); 18411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert String traceFile = new File(traceDir, "qsb.trace").getAbsolutePath(); 18511234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert Debug.startMethodTracing(traceFile); 18611234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert } 18711234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert 1889ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert @Override 1899ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void onNewIntent(Intent intent) { 190ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert recordStartTime(); 1919ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setIntent(intent); 1929ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setupFromIntent(intent); 1939ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 1949ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 195ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private void recordStartTime() { 196f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mStartLatencyTracker = new LatencyTracker(); 197ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mStarting = true; 198ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = false; 199ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert } 200ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 2019ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void restoreInstanceState(Bundle savedInstanceState) { 2029ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (savedInstanceState == null) return; 203fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert String corpusName = savedInstanceState.getString(INSTANCE_KEY_CORPUS); 2049ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert String query = savedInstanceState.getString(INSTANCE_KEY_USER_QUERY); 205fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert setCorpus(getCorpus(corpusName)); 2069ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setUserQuery(query); 207713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 208713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 209713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert @Override 2109ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void onSaveInstanceState(Bundle outState) { 2119ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert super.onSaveInstanceState(outState); 2129ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // We don't save appSearchData, since we always get the value 2139ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // from the intent and the user can't change it. 214fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 215fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert String corpusName = mCorpus == null ? null : mCorpus.getName(); 216fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert outState.putString(INSTANCE_KEY_CORPUS, corpusName); 2179ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert outState.putString(INSTANCE_KEY_USER_QUERY, mUserQuery); 218713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 219713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 220713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private void setupFromIntent(Intent intent) { 221713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert if (DBG) Log.d(TAG, "setupFromIntent(" + intent.toUri(0) + ")"); 222fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert Corpus corpus = getCorpusFromUri(intent.getData()); 2232617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert String query = intent.getStringExtra(SearchManager.QUERY); 2242617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert Bundle appSearchData = intent.getBundleExtra(SearchManager.APP_DATA); 2252617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 226fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert setCorpus(corpus); 2272617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert setUserQuery(query); 228154017089860da89ec020ed37e502d194253cc67Bjorn Bringert mSelectAll = intent.getBooleanExtra(SearchManager.EXTRA_SELECT_QUERY, false); 229c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert mAppSearchData = appSearchData; 2302617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 23111c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert if (startedIntoCorpusSelectionDialog()) { 23241fe9d1fc461c42907250d44d3537909e4c46a7dBjorn Bringert showCorpusSelectionDialog(); 2332617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 2349ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 2359ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 23611c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert public boolean startedIntoCorpusSelectionDialog() { 23711c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert return INTENT_ACTION_QSB_AND_SELECT_CORPUS.equals(getIntent().getAction()); 23811c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert } 23911c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert 240dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert /** 241dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert * Removes corpus selector intent action, so that BACK works normally after 242dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert * dismissing and reopening the corpus selector. 243dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert */ 244dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert private void clearStartedIntoCorpusSelectionDialog() { 245dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert Intent oldIntent = getIntent(); 246dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (SearchActivity.INTENT_ACTION_QSB_AND_SELECT_CORPUS.equals(oldIntent.getAction())) { 247dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert Intent newIntent = new Intent(oldIntent); 248dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert newIntent.setAction(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); 249dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert setIntent(newIntent); 250dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 251dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 252dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 253fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public static Uri getCorpusUri(Corpus corpus) { 254fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (corpus == null) return null; 255fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return new Uri.Builder() 256fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .scheme(SCHEME_CORPUS) 257fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .authority(corpus.getName()) 258fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .build(); 259fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 260fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 261fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Corpus getCorpusFromUri(Uri uri) { 262fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (uri == null) return null; 263fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (!SCHEME_CORPUS.equals(uri.getScheme())) return null; 264fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert String name = uri.getAuthority(); 265fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return getCorpus(name); 266fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 267fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 268fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Corpus getCorpus(String sourceName) { 2690ccab5903ba2c64ec4cdd33dbcea91b1e279d556Bjorn Bringert if (sourceName == null) return null; 270fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert Corpus corpus = getCorpora().getCorpus(sourceName); 271fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (corpus == null) { 272fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert Log.w(TAG, "Unknown corpus " + sourceName); 2739ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert return null; 274713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 275fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return corpus; 276713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 277713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 278fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private void setCorpus(Corpus corpus) { 279fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (DBG) Log.d(TAG, "setCorpus(" + corpus + ")"); 280fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mCorpus = corpus; 2819ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert Drawable sourceIcon; 282fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (corpus == null) { 283c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert sourceIcon = getCorpusViewFactory().getGlobalSearchIcon(); 284713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } else { 285fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert sourceIcon = corpus.getCorpusIcon(); 286713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 287fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mSuggestionsAdapter.setCorpus(corpus); 288a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert mCorpusIndicator.setImageDrawable(sourceIcon); 2893e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 2905691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateUi(getQuery().length() == 0); 2910484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert } 2920484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 2933e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private QsbApplication getQsbApplication() { 2943e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return (QsbApplication) getApplication(); 2953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 2963e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 2974ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert private Config getConfig() { 2984ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert return getQsbApplication().getConfig(); 2994ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 3004ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 301fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Corpora getCorpora() { 302fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return getQsbApplication().getCorpora(); 303fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 304fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 3053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private ShortcutRepository getShortcutRepository() { 3063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return getQsbApplication().getShortcutRepository(); 3073e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3083e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 309ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private SuggestionsProvider getSuggestionsProvider() { 31047d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert return getQsbApplication().getSuggestionsProvider(); 31147d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert } 31247d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert 31347d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert private CorpusRanker getCorpusRanker() { 31447d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert return getQsbApplication().getCorpusRanker(); 3153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 317c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert private CorpusViewFactory getCorpusViewFactory() { 318c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert return getQsbApplication().getCorpusViewFactory(); 319185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 320185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 321ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private Logger getLogger() { 322ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert return getQsbApplication().getLogger(); 323ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert } 324ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 3253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onDestroy() { 3273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "onDestroy()"); 3283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onDestroy(); 329dbdffd8316e75bc2813dbbcbef13d357970e8c84Bjorn Bringert mSuggestionsFooter.setAdapter(null); 330185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert mSuggestionsView.setAdapter(null); // closes mSuggestionsAdapter 3313e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3323e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3333e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3343e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onStop() { 3359ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (DBG) Log.d(TAG, "onStop()"); 336f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (!mTookAction) { 337f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // TODO: This gets logged when starting other activities, e.g. by opening he search 338f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // settings, or clicking a notification in the status bar. 339f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert getLogger().logExit(getCurrentSuggestions(), getQuery().length()); 340f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 3419ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Close all open suggestion cursors. The query will be redone in onResume() 3423e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert // if we come back to this activity. 343185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert mSuggestionsAdapter.setSuggestions(null); 34494e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney getQsbApplication().getShortcutRefresher().reset(); 345f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert dismissCorpusSelectionDialog(); 3463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onStop(); 3473e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3483e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3493e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 350b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert protected void onResume() { 3519ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (DBG) Log.d(TAG, "onResume()"); 352b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert super.onResume(); 3539ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setQuery(mUserQuery, mSelectAll); 3549ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Only select everything the first time after creating the activity. 3559ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert mSelectAll = false; 35611234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert updateSuggestionsBuffered(); 357dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (!isCorpusSelectionDialogShowing()) { 358dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert mQueryTextView.requestFocus(); 359dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 36011234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (TRACE) Debug.stopMethodTracing(); 361b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert } 362b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert 363b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert @Override 3643e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public boolean onCreateOptionsMenu(Menu menu) { 3653e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onCreateOptionsMenu(menu); 36626d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert SearchSettings.addSearchSettingsMenuItem(this, menu); 3673e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return true; 3683e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3693e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 370d98911178013162737fbba74387b51d2a08b0493Amith Yamasani @Override 371d98911178013162737fbba74387b51d2a08b0493Amith Yamasani public void onWindowFocusChanged(boolean hasFocus) { 372d98911178013162737fbba74387b51d2a08b0493Amith Yamasani super.onWindowFocusChanged(hasFocus); 373d98911178013162737fbba74387b51d2a08b0493Amith Yamasani if (hasFocus) { 374d98911178013162737fbba74387b51d2a08b0493Amith Yamasani // Launch the IME after a bit 375d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.postDelayed(mShowInputMethodTask, 0); 376d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 377d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 378d98911178013162737fbba74387b51d2a08b0493Amith Yamasani 3799ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert /** 3809ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert * Sets the query as typed by the user. Does not update the suggestions 3819ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert * or the text in the query box. 3829ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert */ 3839ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void setUserQuery(String userQuery) { 3849ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (userQuery == null) userQuery = ""; 3859ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert mUserQuery = userQuery; 3869ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 3879ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 388713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert protected String getQuery() { 3893e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert CharSequence q = mQueryTextView.getText(); 3903e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return q == null ? "" : q.toString(); 3913e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3923e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3933e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 3943e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Restores the query entered by the user. 3953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 3963e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private void restoreUserQuery() { 3973e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Restoring query to '" + mUserQuery + "'"); 3983e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert setQuery(mUserQuery, false); 3993e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4003e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4013e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 4023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Sets the text in the query box. Does not update the suggestions, 4033e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * and does not change the saved user-entered query. 4043e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * {@link #restoreUserQuery()} will restore the query to the last 4053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * user-entered query. 4063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 4073e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private void setQuery(String query, boolean selectAll) { 4083e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mUpdateSuggestions = false; 4093e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mQueryTextView.setText(query); 4103e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert setTextSelection(selectAll); 4113e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mUpdateSuggestions = true; 4123e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4133e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4143e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 4153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Sets the text selection in the query text view. 4163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * 4173e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * @param selectAll If {@code true}, selects the entire query. 4183e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * If {@false}, no characters are selected, and the cursor is placed 4193e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * at the end of the query. 4203e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 4213e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private void setTextSelection(boolean selectAll) { 4223e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (selectAll) { 4235691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.selectAll(); 4243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } else { 4253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mQueryTextView.setSelection(mQueryTextView.length()); 4263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4295691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert private void updateUi(boolean queryEmpty) { 4305691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateQueryTextView(queryEmpty); 4315691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateSearchGoButton(queryEmpty); 4325691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateVoiceSearchButton(queryEmpty); 4335691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert } 4345691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert 435e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert private void updateQueryTextView(boolean queryEmpty) { 436e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert if (queryEmpty) { 4375691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert if (mCorpus == null || mCorpus.isWebCorpus()) { 4385691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setBackgroundResource(R.drawable.textfield_search_empty_google); 4395691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setHint(null); 4405691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert } else { 4415691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setBackgroundResource(R.drawable.textfield_search_empty); 4425691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setHint(mCorpus.getHint()); 4435691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert } 444e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } else { 445e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryTextView.setBackgroundResource(R.drawable.textfield_search); 446e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 447e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 448e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 449e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert private void updateSearchGoButton(boolean queryEmpty) { 450e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert if (queryEmpty) { 451e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mSearchGoButton.setVisibility(View.GONE); 452e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } else { 453e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mSearchGoButton.setVisibility(View.VISIBLE); 454e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 455e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 456e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 457e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert protected void updateVoiceSearchButton(boolean queryEmpty) { 458c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (queryEmpty && mLauncher.shouldShowVoiceSearch(mCorpus)) { 459e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mVoiceSearchButton.setVisibility(View.VISIBLE); 460e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryTextView.setPrivateImeOptions(IME_OPTION_NO_MICROPHONE); 461e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } else { 462e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mVoiceSearchButton.setVisibility(View.GONE); 463e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryTextView.setPrivateImeOptions(null); 464e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 465e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 466e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 46741fe9d1fc461c42907250d44d3537909e4c46a7dBjorn Bringert protected void showCorpusSelectionDialog() { 468f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (mCorpusSelectionDialog == null) { 469f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog = new CorpusSelectionDialog(this); 470f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.setOwnerActivity(this); 471dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert mCorpusSelectionDialog.setOnDismissListener(new CorpusSelectorDismissListener()); 472f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.setOnCorpusSelectedListener(new CorpusSelectionListener()); 4732617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 474f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.show(mCorpus); 4752617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 4762617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 477dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert protected boolean isCorpusSelectionDialogShowing() { 478dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert return mCorpusSelectionDialog != null && mCorpusSelectionDialog.isShowing(); 479dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 480dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 481f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert protected void dismissCorpusSelectionDialog() { 482f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (mCorpusSelectionDialog != null) { 483f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.dismiss(); 4842617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 4852617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 4862617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 487ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert protected void onSearchClicked(int method) { 4883e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert String query = getQuery(); 4893e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Search clicked, query=" + query); 490eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert 491eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert // Don't do empty queries 492eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert if (TextUtils.getTrimmedLength(query) == 0) return; 493eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert 494535931433926d342c6277034cad91143ae28b72dBjorn Bringert Corpus searchCorpus = mLauncher.getSearchCorpus(getCorpora(), mCorpus); 495c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (searchCorpus == null) return; 496c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 497ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = true; 498c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 499c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log search start 500fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert getLogger().logSearch(mCorpus, method, query.length()); 501c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 502c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Create shortcut 503c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert SuggestionData searchShortcut = searchCorpus.createSearchShortcut(query); 504c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (searchShortcut != null) { 505c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert DataSuggestionCursor cursor = new DataSuggestionCursor(query); 506c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert cursor.add(searchShortcut); 507c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert getShortcutRepository().reportClick(cursor, 0); 508c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert } 509c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 510c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Start search 511c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = searchCorpus.createSearchIntent(query, mAppSearchData); 512c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert mLauncher.launchIntent(intent); 5133e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5143e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 5153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onVoiceSearchClicked() { 5163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Voice Search clicked"); 517535931433926d342c6277034cad91143ae28b72dBjorn Bringert Corpus searchCorpus = mLauncher.getSearchCorpus(getCorpora(), mCorpus); 518c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (searchCorpus == null) return; 519c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 520535931433926d342c6277034cad91143ae28b72dBjorn Bringert mTookAction = true; 521535931433926d342c6277034cad91143ae28b72dBjorn Bringert 522c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log voice search start 523c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert getLogger().logVoiceSearch(searchCorpus); 524ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 525c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Start voice search 526c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = searchCorpus.createVoiceSearchIntent(mAppSearchData); 527c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert mLauncher.launchIntent(intent); 528c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert } 529c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 530e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert protected SuggestionCursor getCurrentSuggestions() { 531fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return mSuggestionsAdapter.getCurrentSuggestions(); 532782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 533782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 534fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert protected boolean launchSuggestion(int position) { 5356f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert SuggestionCursor suggestions = getCurrentSuggestions(); 5366f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert if (position < 0 || position >= suggestions.getCount()) { 5376f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert Log.w(TAG, "Tried to launch invalid suggestion " + position); 5386f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert return false; 5396f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert } 5406f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert 541fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (DBG) Log.d(TAG, "Launching suggestion " + position); 542ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = true; 543e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert 544c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log suggestion click 545e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert Collection<Corpus> corpora = mSuggestionsAdapter.getSuggestions().getIncludedCorpora(); 546fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert getLogger().logSuggestionClick(position, suggestions, corpora); 547ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 548c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Create shortcut 549fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert getShortcutRepository().reportClick(suggestions, position); 550c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 551c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Launch intent 552c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = mLauncher.getSuggestionIntent(suggestions, position, mAppSearchData); 553c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert mLauncher.launchIntent(intent); 554c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 5553e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return true; 5563e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5573e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 558fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert protected boolean onSuggestionLongClicked(int position) { 559fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (DBG) Log.d(TAG, "Long clicked on suggestion " + position); 5603e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return false; 5613e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5623e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 563fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert protected boolean onSuggestionKeyDown(int position, int keyCode, KeyEvent event) { 564782dd228e78e9294692d639597f96c26283968bbBjorn Bringert // Treat enter or search as a click 565782dd228e78e9294692d639597f96c26283968bbBjorn Bringert if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_SEARCH) { 566fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return launchSuggestion(position); 567782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 568782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 5696f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert if (keyCode == KeyEvent.KEYCODE_DPAD_UP && position == 0) { 5707b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert // Moved up from the top suggestion, restore the user query and focus query box 5717b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (DBG) Log.d(TAG, "Up and out"); 5727b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert restoreUserQuery(); 5737b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert return false; // let the framework handle the move 5747b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 5757b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 5767b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT 5777b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { 5787b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert // Moved left / right from a suggestion, keep current query, move 5797b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert // focus to query box, and move cursor to far left / right 5807b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (DBG) Log.d(TAG, "Left/right on a suggestion"); 5814afd6f1587b1c2f3686190d55f1640ecfba03699Bjorn Bringert String query = getQuery(); 5824afd6f1587b1c2f3686190d55f1640ecfba03699Bjorn Bringert int cursorPos = (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) ? 0 : query.length(); 5837b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert mQueryTextView.setSelection(cursorPos); 5847b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert mQueryTextView.requestFocus(); 5854afd6f1587b1c2f3686190d55f1640ecfba03699Bjorn Bringert updateSuggestions(query); 5867b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert return true; 5877b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 5887b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 589782dd228e78e9294692d639597f96c26283968bbBjorn Bringert return false; 590782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 591782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 5923e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onSourceSelected() { 5933e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "No suggestion selected"); 5943e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert restoreUserQuery(); 5953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5963e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 597782dd228e78e9294692d639597f96c26283968bbBjorn Bringert protected int getSelectedPosition() { 598782dd228e78e9294692d639597f96c26283968bbBjorn Bringert return mSuggestionsView.getSelectedPosition(); 599782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 600782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 6013e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 6023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Hides the input method. 6033e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 6043e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void hideInputMethod() { 6053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); 6063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (imm != null) { 6073e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert imm.hideSoftInputFromWindow(mQueryTextView.getWindowToken(), 0); 6083e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6093e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6103e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 6117b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert protected void showInputMethodForQuery() { 6127b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); 6137b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (imm != null) { 614d98911178013162737fbba74387b51d2a08b0493Amith Yamasani imm.showSoftInput(mQueryTextView, 0); 6157b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6167b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6177b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 6183e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 6193e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Hides the input method when the suggestions get focus. 6203e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 6213e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class SuggestListFocusListener implements OnFocusChangeListener { 6223e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onFocusChange(View v, boolean focused) { 6237b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (DBG) Log.d(TAG, "Suggestions focus change, now: " + focused); 6247b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (focused) { 6257b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert // The suggestions list got focus, hide the input method 6267b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert hideInputMethod(); 6277b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6287b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6297b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6307b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 6317b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert private class QueryTextViewFocusListener implements OnFocusChangeListener { 6327b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert public void onFocusChange(View v, boolean focused) { 6337b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (DBG) Log.d(TAG, "Query focus change, now: " + focused); 6347b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (focused) { 635dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert // The query box got focus, show the input method 6367b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert showInputMethodForQuery(); 6373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6403e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 64147d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert private List<Corpus> getCorporaToQuery() { 64247d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert if (mCorpus == null) { 64347d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert return getCorpusRanker().getRankedCorpora(); 64447d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert } else { 64547d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert return Collections.singletonList(mCorpus); 64647d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert } 64747d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert } 64847d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert 649e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney private int getMaxSuggestions() { 650e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney Config config = getConfig(); 651e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney return mCorpus == null 652e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney ? config.getMaxPromotedSuggestions() 653e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney : config.getMaxResultsPerSource(); 654e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney } 655e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney 6564ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert private void updateSuggestionsBuffered() { 657d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.removeCallbacks(mUpdateSuggestionsTask); 6584ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert long delay = getConfig().getTypingUpdateSuggestionsDelayMillis(); 659d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.postDelayed(mUpdateSuggestionsTask, delay); 6604ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 6614ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 6623e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private void updateSuggestions(String query) { 66311234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert // Log start latency if this is the first suggestions update 66411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (mStarting) { 66511234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert mStarting = false; 66611234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert String source = getIntent().getStringExtra(Search.SOURCE); 66711234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert List<Corpus> rankedCorpora = getCorpusRanker().getRankedCorpora(); 66811234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert int latency = mStartLatencyTracker.getLatency(); 66911234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert getLogger().logStart(latency, source, mCorpus, rankedCorpora); 67011234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert } 67111234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert 6723d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney query = ltrim(query); 67347d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert List<Corpus> corporaToQuery = getCorporaToQuery(); 674e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney Suggestions suggestions = getSuggestionsProvider().getSuggestions( 675e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney query, corporaToQuery, getMaxSuggestions()); 676185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert mSuggestionsAdapter.setSuggestions(suggestions); 6773e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6783e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 6797be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert private boolean forwardKeyToQueryTextView(int keyCode, KeyEvent event) { 6807be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert if (!event.isSystem() && !isDpadKey(keyCode)) { 6817be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert if (DBG) Log.d(TAG, "Forwarding key to query box: " + event); 6827be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert if (mQueryTextView.requestFocus()) { 6837be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return mQueryTextView.dispatchKeyEvent(event); 6847be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 6857be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 6867be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return false; 6877be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 6887be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 6897be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert private boolean isDpadKey(int keyCode) { 6907be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert switch (keyCode) { 6917be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_UP: 6927be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_DOWN: 6937be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_LEFT: 6947be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_RIGHT: 6957be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_CENTER: 6967be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return true; 6977be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert default: 6987be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return false; 6997be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7007be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7017be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 7023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 7033e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Filters the suggestions list when the search text changes. 7043e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 7053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class SearchTextWatcher implements TextWatcher { 7063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void afterTextChanged(Editable s) { 707e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert boolean empty = s.length() == 0; 708e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert if (empty != mQueryWasEmpty) { 709e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryWasEmpty = empty; 7105691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateUi(empty); 711e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 7123e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (mUpdateSuggestions) { 7133e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert String query = s == null ? "" : s.toString(); 7149ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setUserQuery(query); 7154ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert updateSuggestionsBuffered(); 7163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7173e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7183e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7193e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void beforeTextChanged(CharSequence s, int start, int count, int after) { 7203e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7213e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7223e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onTextChanged(CharSequence s, int start, int before, int count) { 7233e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 7273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Handles non-text keys in the query text view. 7283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 7293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class QueryTextViewKeyListener implements View.OnKeyListener { 7303e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public boolean onKey(View view, int keyCode, KeyEvent event) { 7313e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert // Handle IME search action key 7323e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) { 733ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert onSearchClicked(Logger.SEARCH_METHOD_KEYBOARD); 734d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood // if no action was taken, consume the key event so that the keyboard 735d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood // remains on screen. 736d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood return !mTookAction; 7373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return false; 7393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7403e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7413e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 742782dd228e78e9294692d639597f96c26283968bbBjorn Bringert /** 743782dd228e78e9294692d639597f96c26283968bbBjorn Bringert * Handles key events on the search and voice search buttons, 744782dd228e78e9294692d639597f96c26283968bbBjorn Bringert * by refocusing to EditText. 745782dd228e78e9294692d639597f96c26283968bbBjorn Bringert */ 746782dd228e78e9294692d639597f96c26283968bbBjorn Bringert private class ButtonsKeyListener implements View.OnKeyListener { 747782dd228e78e9294692d639597f96c26283968bbBjorn Bringert public boolean onKey(View v, int keyCode, KeyEvent event) { 7487be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return forwardKeyToQueryTextView(keyCode, event); 749782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 750782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 751782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 752782dd228e78e9294692d639597f96c26283968bbBjorn Bringert /** 753782dd228e78e9294692d639597f96c26283968bbBjorn Bringert * Handles key events on the suggestions list view. 754782dd228e78e9294692d639597f96c26283968bbBjorn Bringert */ 755713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private class SuggestionsViewKeyListener implements View.OnKeyListener { 756782dd228e78e9294692d639597f96c26283968bbBjorn Bringert public boolean onKey(View v, int keyCode, KeyEvent event) { 757782dd228e78e9294692d639597f96c26283968bbBjorn Bringert if (event.getAction() == KeyEvent.ACTION_DOWN) { 758fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert int position = getSelectedPosition(); 759fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (onSuggestionKeyDown(position, keyCode, event)) { 7607be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return true; 761782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 762782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 7637be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return forwardKeyToQueryTextView(keyCode, event); 764782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 765782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 766782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 767145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert private class InputMethodCloser implements SuggestionsView.OnScrollListener { 768145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 769145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 770145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert int totalItemCount) { 771145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert } 772145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 773145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert public void onScrollStateChanged(AbsListView view, int scrollState) { 774185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert hideInputMethod(); 775185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 776185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 777185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 778185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert private class ClickHandler implements SuggestionClickListener { 779fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public void onSuggestionClicked(int position) { 780fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert launchSuggestion(position); 7813e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7823e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 783fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public boolean onSuggestionLongClicked(int position) { 784fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return SearchActivity.this.onSuggestionLongClicked(position); 785713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 786145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 787145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert public void onSuggestionQueryRefineClicked(int position) { 788145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert if (DBG) Log.d(TAG, "query refine clicked, pos " + position); 789145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert SuggestionCursor suggestions = getCurrentSuggestions(); 790145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert if (suggestions != null) { 791145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert suggestions.moveTo(position); 792145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert String query = suggestions.getSuggestionQuery(); 793145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert if (!TextUtils.isEmpty(query)) { 794145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert query += " "; 795145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert setUserQuery(query); 796145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert setQuery(query, false); 797145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert updateSuggestions(query); 798145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert } 799145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert } 800145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert } 8013e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 8037b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert private class SelectionHandler implements SuggestionSelectionListener { 804fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public void onSuggestionSelected(int position) { 805e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert SuggestionCursor suggestions = getCurrentSuggestions(); 806fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert suggestions.moveTo(position); 807fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert String displayQuery = suggestions.getSuggestionDisplayQuery(); 808fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (TextUtils.isEmpty(displayQuery)) { 809fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert restoreUserQuery(); 810fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } else { 811fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert setQuery(displayQuery, false); 812fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 813fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 814fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 815fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public void onNothingSelected() { 816fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert // This happens when a suggestion has been selected with the 817fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert // dpad / trackball and then a different UI element is touched. 818fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert // Do nothing, since we want to keep the query of the selection 819fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert // in the search box. 8207b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 8217b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 8227b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 8233e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 8242617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert * Listens for clicks on the source selector. 8253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 8263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class SearchGoButtonClickListener implements View.OnClickListener { 8273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onClick(View view) { 828ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert onSearchClicked(Logger.SEARCH_METHOD_BUTTON); 8293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8303e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8313e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 8323e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 8332617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert * Listens for clicks on the search button. 8342617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert */ 835fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private class CorpusIndicatorClickListener implements View.OnClickListener { 8362617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert public void onClick(View view) { 83741fe9d1fc461c42907250d44d3537909e4c46a7dBjorn Bringert showCorpusSelectionDialog(); 8382617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 839f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 840f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert 841dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert private class CorpusSelectorDismissListener implements DialogInterface.OnDismissListener { 842dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert public void onDismiss(DialogInterface dialog) { 843dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (DBG) Log.d(TAG, "Corpus selector dismissed"); 844dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert clearStartedIntoCorpusSelectionDialog(); 845dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 846dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 847dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 848f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private class CorpusSelectionListener 849f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert implements CorpusSelectionDialog.OnCorpusSelectedListener { 850f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert public void onCorpusSelected(Corpus corpus) { 851f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert setCorpus(corpus); 852f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert updateSuggestions(getQuery()); 853f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mQueryTextView.requestFocus(); 854dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert showInputMethodForQuery(); 855f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 8562617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 8572617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 8582617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert /** 8593e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Listens for clicks on the voice search button. 8603e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 8613e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class VoiceSearchButtonClickListener implements View.OnClickListener { 8623e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onClick(View view) { 8633e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert onVoiceSearchClicked(); 8643e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8653e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8663e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 8673d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney private static String ltrim(String text) { 8683d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney int start = 0; 8693d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney int length = text.length(); 8703d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney while (start < length && Character.isWhitespace(text.charAt(start))) { 8713d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney start++; 8723d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney } 8733d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney return start > 0 ? text.substring(start, length) : text; 8743d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney } 8753d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney 8763e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert} 877