SearchActivity.java revision 18959800eddb7127e4fd9b24e91458d0584cc257
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; 24185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringertimport com.android.quicksearchbox.ui.SuggestionsView; 25185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.app.Activity; 273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.app.SearchManager; 28dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringertimport android.content.DialogInterface; 293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.content.Intent; 3021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringertimport android.database.DataSetObserver; 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; 433e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.View.OnFocusChangeListener; 443e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.view.inputmethod.InputMethodManager; 45145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringertimport android.widget.AbsListView; 463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.widget.EditText; 473e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertimport android.widget.ImageButton; 483e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4911234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringertimport java.io.File; 50e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringertimport java.util.Collection; 5147d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringertimport java.util.List; 52ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 533e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert/** 543e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * The main activity for Quick Search Box. Shows the search UI. 553e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * 563e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 573e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringertpublic class SearchActivity extends Activity { 583e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 59b5fc08b7f16a32d3865f44b7f26d8aaa5304a2adBjorn Bringert private static final boolean DBG = false; 600484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert private static final String TAG = "QSB.SearchActivity"; 6111234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert private static final boolean TRACE = false; 623e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 63fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String SCHEME_CORPUS = "qsb.corpus"; 64fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 65fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public static final String INTENT_ACTION_QSB_AND_SELECT_CORPUS 66fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert = "com.android.quicksearchbox.action.QSB_AND_SELECT_CORPUS"; 673e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 68c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert // The string used for privateImeOptions to identify to the IME that it should not show 69c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert // a microphone button since one already exists in the search dialog. 70c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert // TODO: This should move to android-common or something. 71c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert private static final String IME_OPTION_NO_MICROPHONE = "nm"; 72c15f386b167efb3f7559f2f7ee362497040b7fe6Bjorn Bringert 739ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Keys for the saved instance state. 74fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String INSTANCE_KEY_CORPUS = "corpus"; 759ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert private static final String INSTANCE_KEY_USER_QUERY = "query"; 76713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 77f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // Measures time from for last onCreate()/onNewIntent() call. 78f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private LatencyTracker mStartLatencyTracker; 79ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // Whether QSB is starting. True between the calls to onCreate()/onNewIntent() and onResume(). 80ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private boolean mStarting; 81ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // True if the user has taken some action, e.g. launching a search, voice search, 82ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert // or suggestions, since QSB was last started. 83ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private boolean mTookAction; 84ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 85f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private CorpusSelectionDialog mCorpusSelectionDialog; 86f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert 87185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert protected SuggestionsAdapter mSuggestionsAdapter; 88185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 8921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private CorporaObserver mCorporaObserver; 9021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn 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; 963e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 973e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected ImageButton mSearchGoButton; 983e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected ImageButton mVoiceSearchButton; 99a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert protected ImageButton mCorpusIndicator; 1003e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 10181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert private VoiceSearch mVoiceSearch; 1023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 103fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Corpus mCorpus; 1042617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert private Bundle mAppSearchData; 105713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private boolean mUpdateSuggestions; 106713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private String mUserQuery; 107713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private boolean mSelectAll; 1083e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 109d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Handler mHandler = new Handler(); 110d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Runnable mUpdateSuggestionsTask = new Runnable() { 1114ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert public void run() { 1124ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert updateSuggestions(getQuery()); 1134ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 1144ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert }; 1154ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 116d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood private final Runnable mShowInputMethodTask = new Runnable() { 117d98911178013162737fbba74387b51d2a08b0493Amith Yamasani public void run() { 118d98911178013162737fbba74387b51d2a08b0493Amith Yamasani showInputMethodForQuery(); 119d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 120d98911178013162737fbba74387b51d2a08b0493Amith Yamasani }; 121d98911178013162737fbba74387b51d2a08b0493Amith Yamasani 1223e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** Called when the activity is first created. */ 1233e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 1243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onCreate(Bundle savedInstanceState) { 12511234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (TRACE) startMethodTracing(); 126ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert recordStartTime(); 1273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "onCreate()"); 1283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onCreate(savedInstanceState); 129713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 130e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert setContentView(R.layout.search_activity); 1313e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 132816804b67619af133860a1e28e92f58bc642260dBjorn Bringert mSuggestionsAdapter = getQsbApplication().createSuggestionsAdapter(); 133185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 1343e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mQueryTextView = (EditText) findViewById(R.id.search_src_text); 1353e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mSuggestionsView = (SuggestionsView) findViewById(R.id.suggestions); 136782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mSuggestionsView.setSuggestionClickListener(new ClickHandler()); 1371aef21f8a84380351c7dd7c9bf66f80659d0d42eMathew Inwood mSuggestionsView.addSuggestionSelectionListener(new SelectionHandler()); 138145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert mSuggestionsView.setOnScrollListener(new InputMethodCloser()); 139713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert mSuggestionsView.setOnKeyListener(new SuggestionsViewKeyListener()); 1407b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert mSuggestionsView.setOnFocusChangeListener(new SuggestListFocusListener()); 1413e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 1423e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mSearchGoButton = (ImageButton) findViewById(R.id.search_go_btn); 1433e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mVoiceSearchButton = (ImageButton) findViewById(R.id.search_voice_btn); 144a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert mCorpusIndicator = (ImageButton) findViewById(R.id.corpus_indicator); 1453e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 14681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert mVoiceSearch = new VoiceSearch(this); 1473e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 148782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mQueryTextView.addTextChangedListener(new SearchTextWatcher()); 149782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mQueryTextView.setOnKeyListener(new QueryTextViewKeyListener()); 1507b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert mQueryTextView.setOnFocusChangeListener(new QueryTextViewFocusListener()); 151782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 152fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mCorpusIndicator.setOnClickListener(new CorpusIndicatorClickListener()); 1532617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 154782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mSearchGoButton.setOnClickListener(new SearchGoButtonClickListener()); 155782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 156782dd228e78e9294692d639597f96c26283968bbBjorn Bringert mVoiceSearchButton.setOnClickListener(new VoiceSearchButtonClickListener()); 1577be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 1587be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert ButtonsKeyListener buttonsKeyListener = new ButtonsKeyListener(); 1597be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert mSearchGoButton.setOnKeyListener(buttonsKeyListener); 1607be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert mVoiceSearchButton.setOnKeyListener(buttonsKeyListener); 161fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mCorpusIndicator.setOnKeyListener(buttonsKeyListener); 162713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 1639ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert mUpdateSuggestions = true; 1649ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 1659ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // First get setup from intent 1669ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert Intent intent = getIntent(); 1679ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setupFromIntent(intent); 1689ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Then restore any saved instance state 1699ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert restoreInstanceState(savedInstanceState); 1709ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 171713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert // Do this at the end, to avoid updating the list view when setSource() 172713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert // is called. 173713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert mSuggestionsView.setAdapter(mSuggestionsAdapter); 17421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 17521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert mCorporaObserver = new CorporaObserver(); 17621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert getCorpora().registerDataSetObserver(mCorporaObserver); 1779ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 178713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 17911234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert private void startMethodTracing() { 18011234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert File traceDir = getDir("traces", 0); 18111234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert String traceFile = new File(traceDir, "qsb.trace").getAbsolutePath(); 18211234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert Debug.startMethodTracing(traceFile); 18311234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert } 18411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert 1859ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert @Override 1869ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void onNewIntent(Intent intent) { 187ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert recordStartTime(); 1889ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setIntent(intent); 1899ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setupFromIntent(intent); 1909ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 1919ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 192ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private void recordStartTime() { 193f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mStartLatencyTracker = new LatencyTracker(); 194ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mStarting = true; 195ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = false; 196ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert } 197ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 1989ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void restoreInstanceState(Bundle savedInstanceState) { 1999ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (savedInstanceState == null) return; 200fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert String corpusName = savedInstanceState.getString(INSTANCE_KEY_CORPUS); 2019ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert String query = savedInstanceState.getString(INSTANCE_KEY_USER_QUERY); 20221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(corpusName); 2039ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setUserQuery(query); 204713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 205713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 206713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert @Override 2079ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void onSaveInstanceState(Bundle outState) { 2089ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert super.onSaveInstanceState(outState); 2099ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // We don't save appSearchData, since we always get the value 2109ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // from the intent and the user can't change it. 211fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 21221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert outState.putString(INSTANCE_KEY_CORPUS, getCorpusName()); 2139ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert outState.putString(INSTANCE_KEY_USER_QUERY, mUserQuery); 214713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 215713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 216713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private void setupFromIntent(Intent intent) { 217713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert if (DBG) Log.d(TAG, "setupFromIntent(" + intent.toUri(0) + ")"); 21821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert String corpusName = getCorpusNameFromUri(intent.getData()); 2192617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert String query = intent.getStringExtra(SearchManager.QUERY); 2202617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert Bundle appSearchData = intent.getBundleExtra(SearchManager.APP_DATA); 2212617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 22221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(corpusName); 2232617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert setUserQuery(query); 224154017089860da89ec020ed37e502d194253cc67Bjorn Bringert mSelectAll = intent.getBooleanExtra(SearchManager.EXTRA_SELECT_QUERY, false); 225c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert mAppSearchData = appSearchData; 2262617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 22711c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert if (startedIntoCorpusSelectionDialog()) { 22841fe9d1fc461c42907250d44d3537909e4c46a7dBjorn Bringert showCorpusSelectionDialog(); 2292617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 2309ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 2319ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 23211c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert public boolean startedIntoCorpusSelectionDialog() { 23311c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert return INTENT_ACTION_QSB_AND_SELECT_CORPUS.equals(getIntent().getAction()); 23411c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert } 23511c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert 236dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert /** 237dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert * Removes corpus selector intent action, so that BACK works normally after 238dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert * dismissing and reopening the corpus selector. 239dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert */ 240dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert private void clearStartedIntoCorpusSelectionDialog() { 241dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert Intent oldIntent = getIntent(); 242dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (SearchActivity.INTENT_ACTION_QSB_AND_SELECT_CORPUS.equals(oldIntent.getAction())) { 243dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert Intent newIntent = new Intent(oldIntent); 244dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert newIntent.setAction(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); 245dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert setIntent(newIntent); 246dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 247dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 248dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 249fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public static Uri getCorpusUri(Corpus corpus) { 250fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (corpus == null) return null; 251fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return new Uri.Builder() 252fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .scheme(SCHEME_CORPUS) 253fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .authority(corpus.getName()) 254fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert .build(); 255fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 256fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 25721bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private String getCorpusNameFromUri(Uri uri) { 258fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (uri == null) return null; 259fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (!SCHEME_CORPUS.equals(uri.getScheme())) return null; 26021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert return uri.getAuthority(); 261fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 262fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 263fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Corpus getCorpus(String sourceName) { 2640ccab5903ba2c64ec4cdd33dbcea91b1e279d556Bjorn Bringert if (sourceName == null) return null; 265fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert Corpus corpus = getCorpora().getCorpus(sourceName); 266fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (corpus == null) { 267fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert Log.w(TAG, "Unknown corpus " + sourceName); 2689ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert return null; 269713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 270fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return corpus; 271713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 272713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert 27321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private void setCorpus(String corpusName) { 27421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert if (DBG) Log.d(TAG, "setCorpus(" + corpusName + ")"); 27521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert mCorpus = getCorpus(corpusName); 2769ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert Drawable sourceIcon; 27721bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert if (mCorpus == null) { 278c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert sourceIcon = getCorpusViewFactory().getGlobalSearchIcon(); 279713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } else { 28021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert sourceIcon = mCorpus.getCorpusIcon(); 281713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 28221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert mSuggestionsAdapter.setCorpus(mCorpus); 283a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert mCorpusIndicator.setImageDrawable(sourceIcon); 2843e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 2855691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateUi(getQuery().length() == 0); 2860484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert } 2870484fb4d652bfa9d5c7fb238a7cec1a6f2244e44Bjorn Bringert 28821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private String getCorpusName() { 28921bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert return mCorpus == null ? null : mCorpus.getName(); 29021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 29121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 2923e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private QsbApplication getQsbApplication() { 2933e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return (QsbApplication) getApplication(); 2943e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 2953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 2964ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert private Config getConfig() { 2974ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert return getQsbApplication().getConfig(); 2984ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 2994ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 300fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Corpora getCorpora() { 301fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return getQsbApplication().getCorpora(); 302fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 303fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 3043e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private ShortcutRepository getShortcutRepository() { 3053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return getQsbApplication().getShortcutRepository(); 3063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3073e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 308ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private SuggestionsProvider getSuggestionsProvider() { 30947d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert return getQsbApplication().getSuggestionsProvider(); 31047d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert } 31147d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert 31247d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert private CorpusRanker getCorpusRanker() { 31347d02f7285794bb39b2a2d828d32b5329dd8ecb0Bjorn Bringert return getQsbApplication().getCorpusRanker(); 3143e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 316c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert private CorpusViewFactory getCorpusViewFactory() { 317c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert return getQsbApplication().getCorpusViewFactory(); 318185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 319185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 320ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert private Logger getLogger() { 321ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert return getQsbApplication().getLogger(); 322ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert } 323ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 3243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onDestroy() { 3263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "onDestroy()"); 3273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onDestroy(); 32821bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert getCorpora().unregisterDataSetObserver(mCorporaObserver); 329185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert mSuggestionsView.setAdapter(null); // closes mSuggestionsAdapter 3303e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3313e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3323e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 3333e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onStop() { 3349ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (DBG) Log.d(TAG, "onStop()"); 335f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (!mTookAction) { 336f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // TODO: This gets logged when starting other activities, e.g. by opening he search 337f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert // settings, or clicking a notification in the status bar. 338f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert getLogger().logExit(getCurrentSuggestions(), getQuery().length()); 339f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 3409ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Close all open suggestion cursors. The query will be redone in onResume() 3413e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert // if we come back to this activity. 342185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert mSuggestionsAdapter.setSuggestions(null); 34394e8a2be78530170f50e7895a558bf8011bbf8e8Bryan Mawhinney getQsbApplication().getShortcutRefresher().reset(); 344f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert dismissCorpusSelectionDialog(); 3453e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onStop(); 3463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3473e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3483e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert @Override 349b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert protected void onResume() { 3509ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (DBG) Log.d(TAG, "onResume()"); 351b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert super.onResume(); 3529ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setQuery(mUserQuery, mSelectAll); 3539ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert // Only select everything the first time after creating the activity. 3549ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert mSelectAll = false; 35511234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert updateSuggestionsBuffered(); 356dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (!isCorpusSelectionDialogShowing()) { 357dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert mQueryTextView.requestFocus(); 358dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 35911234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (TRACE) Debug.stopMethodTracing(); 360b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert } 361b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert 362b32ee8f1b45c65daff18b40c0614cf18843b8c17Bjorn Bringert @Override 3633e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public boolean onCreateOptionsMenu(Menu menu) { 3643e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert super.onCreateOptionsMenu(menu); 36526d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert SearchSettings.addSearchSettingsMenuItem(this, menu); 3663e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return true; 3673e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3683e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 369d98911178013162737fbba74387b51d2a08b0493Amith Yamasani @Override 370d98911178013162737fbba74387b51d2a08b0493Amith Yamasani public void onWindowFocusChanged(boolean hasFocus) { 371d98911178013162737fbba74387b51d2a08b0493Amith Yamasani super.onWindowFocusChanged(hasFocus); 372d98911178013162737fbba74387b51d2a08b0493Amith Yamasani if (hasFocus) { 373d98911178013162737fbba74387b51d2a08b0493Amith Yamasani // Launch the IME after a bit 374d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.postDelayed(mShowInputMethodTask, 0); 375d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 376d98911178013162737fbba74387b51d2a08b0493Amith Yamasani } 377d98911178013162737fbba74387b51d2a08b0493Amith Yamasani 3789ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert /** 3799ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert * Sets the query as typed by the user. Does not update the suggestions 3809ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert * or the text in the query box. 3819ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert */ 3829ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert protected void setUserQuery(String userQuery) { 3839ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert if (userQuery == null) userQuery = ""; 3849ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert mUserQuery = userQuery; 3859ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert } 3869ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert 387713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert protected String getQuery() { 3883e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert CharSequence q = mQueryTextView.getText(); 3893e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return q == null ? "" : q.toString(); 3903e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3913e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 3923e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 3933e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Restores the query entered by the user. 3943e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 3953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private void restoreUserQuery() { 3963e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Restoring query to '" + mUserQuery + "'"); 3973e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert setQuery(mUserQuery, false); 3983e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 3993e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4003e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 4013e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Sets the text in the query box. Does not update the suggestions, 4023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * and does not change the saved user-entered query. 4033e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * {@link #restoreUserQuery()} will restore the query to the last 4043e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * user-entered query. 4053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 4063e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private void setQuery(String query, boolean selectAll) { 4073e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mUpdateSuggestions = false; 4083e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mQueryTextView.setText(query); 4093e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert setTextSelection(selectAll); 4103e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mUpdateSuggestions = true; 4113e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4123e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 4133e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 4143e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Sets the text selection in the query text view. 4153e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * 4163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * @param selectAll If {@code true}, selects the entire query. 4173e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * If {@false}, no characters are selected, and the cursor is placed 4183e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * at the end of the query. 4193e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 4203e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private void setTextSelection(boolean selectAll) { 4213e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (selectAll) { 4225691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.selectAll(); 4233e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } else { 4243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert mQueryTextView.setSelection(mQueryTextView.length()); 4253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 4273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 42818959800eddb7127e4fd9b24e91458d0584cc257Mathew Inwood protected void updateUi(boolean queryEmpty) { 4295691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateQueryTextView(queryEmpty); 4305691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateSearchGoButton(queryEmpty); 4315691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateVoiceSearchButton(queryEmpty); 4325691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert } 4335691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert 434e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert private void updateQueryTextView(boolean queryEmpty) { 435e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert if (queryEmpty) { 4365691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert if (mCorpus == null || mCorpus.isWebCorpus()) { 4375691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setBackgroundResource(R.drawable.textfield_search_empty_google); 4385691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setHint(null); 4395691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert } else { 4405691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setBackgroundResource(R.drawable.textfield_search_empty); 4415691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert mQueryTextView.setHint(mCorpus.getHint()); 4425691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert } 443e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } else { 444e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryTextView.setBackgroundResource(R.drawable.textfield_search); 445e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 446e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 447e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 448e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert private void updateSearchGoButton(boolean queryEmpty) { 449e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert if (queryEmpty) { 450e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mSearchGoButton.setVisibility(View.GONE); 451e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } else { 452e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mSearchGoButton.setVisibility(View.VISIBLE); 453e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 454e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 455e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 456e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert protected void updateVoiceSearchButton(boolean queryEmpty) { 45781a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert if (queryEmpty && mVoiceSearch.shouldShowVoiceSearch(mCorpus)) { 458e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mVoiceSearchButton.setVisibility(View.VISIBLE); 459e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryTextView.setPrivateImeOptions(IME_OPTION_NO_MICROPHONE); 460e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } else { 461e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mVoiceSearchButton.setVisibility(View.GONE); 462e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryTextView.setPrivateImeOptions(null); 463e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 464e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 465e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert 46641fe9d1fc461c42907250d44d3537909e4c46a7dBjorn Bringert protected void showCorpusSelectionDialog() { 467f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (mCorpusSelectionDialog == null) { 468f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog = new CorpusSelectionDialog(this); 469f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.setOwnerActivity(this); 470dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert mCorpusSelectionDialog.setOnDismissListener(new CorpusSelectorDismissListener()); 471f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.setOnCorpusSelectedListener(new CorpusSelectionListener()); 4722617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 473f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.show(mCorpus); 4742617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 4752617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 476dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert protected boolean isCorpusSelectionDialogShowing() { 477dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert return mCorpusSelectionDialog != null && mCorpusSelectionDialog.isShowing(); 478dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 479dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 480f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert protected void dismissCorpusSelectionDialog() { 481f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert if (mCorpusSelectionDialog != null) { 482f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mCorpusSelectionDialog.dismiss(); 4832617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 4842617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 4852617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 486dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood /** 487dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood * @return true if a search was performed as a result of this click, false otherwise. 488dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood */ 489dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood protected boolean onSearchClicked(int method) { 4903e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert String query = getQuery(); 4913e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Search clicked, query=" + query); 492eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert 493eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert // Don't do empty queries 494dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood if (TextUtils.getTrimmedLength(query) == 0) return false; 495eba26da75665ac3b9a411e74267395f332ff851aBjorn Bringert 49681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Corpus searchCorpus = getSearchCorpus(); 497dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood if (searchCorpus == null) return false; 498c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 499ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = true; 500c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 501c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log search start 502fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert getLogger().logSearch(mCorpus, method, query.length()); 503c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 504c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Create shortcut 505c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert SuggestionData searchShortcut = searchCorpus.createSearchShortcut(query); 506c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (searchShortcut != null) { 507c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert DataSuggestionCursor cursor = new DataSuggestionCursor(query); 508c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert cursor.add(searchShortcut); 509c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert getShortcutRepository().reportClick(cursor, 0); 510c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert } 511c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 512c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Start search 513c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = searchCorpus.createSearchIntent(query, mAppSearchData); 51481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 515dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood return true; 5163e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5173e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 5183e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onVoiceSearchClicked() { 5193e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "Voice Search clicked"); 52081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Corpus searchCorpus = getSearchCorpus(); 521c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert if (searchCorpus == null) return; 522c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 523535931433926d342c6277034cad91143ae28b72dBjorn Bringert mTookAction = true; 524535931433926d342c6277034cad91143ae28b72dBjorn Bringert 525c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log voice search start 526c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert getLogger().logVoiceSearch(searchCorpus); 527ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 528c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Start voice search 529c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert Intent intent = searchCorpus.createVoiceSearchIntent(mAppSearchData); 53081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 53181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 53281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert 53381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert /** 53481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert * Gets the corpus to use for any searches. This is the web corpus in "All" mode, 53581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert * and the selected corpus otherwise. 53681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert */ 53781a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert private Corpus getSearchCorpus() { 53881a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert if (mCorpus != null) { 53981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert return mCorpus; 54081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } else { 54181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Corpus webCorpus = getCorpora().getWebCorpus(); 54281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert if (webCorpus == null) { 54381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Log.e(TAG, "No web corpus"); 54481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 54581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert return webCorpus; 54681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 547c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert } 548c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 549e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert protected SuggestionCursor getCurrentSuggestions() { 550fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return mSuggestionsAdapter.getCurrentSuggestions(); 551782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 552782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 55381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert protected void launchIntent(Intent intent) { 55481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert if (intent == null) { 55581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert return; 55681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 55781a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert try { 55881a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert startActivity(intent); 55981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } catch (RuntimeException ex) { 56081a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert // Since the intents for suggestions specified by suggestion providers, 56181a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert // guard against them not being handled, not allowed, etc. 56281a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Log.e(TAG, "Failed to start " + intent.toUri(0), ex); 56381a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 56481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert } 56581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert 566fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert protected boolean launchSuggestion(int position) { 5676f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert SuggestionCursor suggestions = getCurrentSuggestions(); 5686f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert if (position < 0 || position >= suggestions.getCount()) { 5696f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert Log.w(TAG, "Tried to launch invalid suggestion " + position); 5706f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert return false; 5716f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert } 5726f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert 573fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (DBG) Log.d(TAG, "Launching suggestion " + position); 574ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert mTookAction = true; 575e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert 576c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Log suggestion click 577e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert Collection<Corpus> corpora = mSuggestionsAdapter.getSuggestions().getIncludedCorpora(); 578fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert getLogger().logSuggestionClick(position, suggestions, corpora); 579ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert 580c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Create shortcut 581fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert getShortcutRepository().reportClick(suggestions, position); 582c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 583c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert // Launch intent 58481a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert suggestions.moveTo(position); 58581a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert Intent intent = suggestions.getSuggestionIntent(mAppSearchData); 58681a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert launchIntent(intent); 587c29c9f854db8fa0c85f17cc32bae33dc17c6b127Bjorn Bringert 5883e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return true; 5893e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5903e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 591fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert protected boolean onSuggestionLongClicked(int position) { 592fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (DBG) Log.d(TAG, "Long clicked on suggestion " + position); 5933e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return false; 5943e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 5953e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 596fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert protected boolean onSuggestionKeyDown(int position, int keyCode, KeyEvent event) { 597782dd228e78e9294692d639597f96c26283968bbBjorn Bringert // Treat enter or search as a click 598782dd228e78e9294692d639597f96c26283968bbBjorn Bringert if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_SEARCH) { 599fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return launchSuggestion(position); 600782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 601782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 6026f8fc42e68237bfb6f474faff8086d910d2934d5Bjorn Bringert if (keyCode == KeyEvent.KEYCODE_DPAD_UP && position == 0) { 6037b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert // Moved up from the top suggestion, restore the user query and focus query box 6047b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (DBG) Log.d(TAG, "Up and out"); 6057b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert restoreUserQuery(); 6067b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert return false; // let the framework handle the move 6077b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6087b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 6097b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT 6107b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { 6117b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert // Moved left / right from a suggestion, keep current query, move 6127b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert // focus to query box, and move cursor to far left / right 6137b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (DBG) Log.d(TAG, "Left/right on a suggestion"); 6144afd6f1587b1c2f3686190d55f1640ecfba03699Bjorn Bringert String query = getQuery(); 6154afd6f1587b1c2f3686190d55f1640ecfba03699Bjorn Bringert int cursorPos = (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) ? 0 : query.length(); 6167b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert mQueryTextView.setSelection(cursorPos); 6177b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert mQueryTextView.requestFocus(); 6184afd6f1587b1c2f3686190d55f1640ecfba03699Bjorn Bringert updateSuggestions(query); 6197b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert return true; 6207b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6217b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 622782dd228e78e9294692d639597f96c26283968bbBjorn Bringert return false; 623782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 624782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 6253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void onSourceSelected() { 6263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (DBG) Log.d(TAG, "No suggestion selected"); 6273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert restoreUserQuery(); 6283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 630782dd228e78e9294692d639597f96c26283968bbBjorn Bringert protected int getSelectedPosition() { 631782dd228e78e9294692d639597f96c26283968bbBjorn Bringert return mSuggestionsView.getSelectedPosition(); 632782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 633782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 6343e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 6353e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Hides the input method. 6363e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 6373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert protected void hideInputMethod() { 6383e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); 6393e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (imm != null) { 6403e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert imm.hideSoftInputFromWindow(mQueryTextView.getWindowToken(), 0); 6413e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6423e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6433e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 6447b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert protected void showInputMethodForQuery() { 6457b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); 6467b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (imm != null) { 647d98911178013162737fbba74387b51d2a08b0493Amith Yamasani imm.showSoftInput(mQueryTextView, 0); 6487b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6497b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6507b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 6513e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 6523e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Hides the input method when the suggestions get focus. 6533e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 6543e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class SuggestListFocusListener implements OnFocusChangeListener { 6553e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onFocusChange(View v, boolean focused) { 6567b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (DBG) Log.d(TAG, "Suggestions focus change, now: " + focused); 6577b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (focused) { 6587b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert // The suggestions list got focus, hide the input method 6597b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert hideInputMethod(); 6607b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6617b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6627b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 6637b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 6647b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert private class QueryTextViewFocusListener implements OnFocusChangeListener { 6657b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert public void onFocusChange(View v, boolean focused) { 6667b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (DBG) Log.d(TAG, "Query focus change, now: " + focused); 6677b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert if (focused) { 668dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert // The query box got focus, show the input method 6697b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert showInputMethodForQuery(); 6703e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6713e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6723e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 6733e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 674e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney private int getMaxSuggestions() { 675e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney Config config = getConfig(); 676e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney return mCorpus == null 677e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney ? config.getMaxPromotedSuggestions() 678e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney : config.getMaxResultsPerSource(); 679e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney } 680e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney 6814ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert private void updateSuggestionsBuffered() { 682d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.removeCallbacks(mUpdateSuggestionsTask); 6834ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert long delay = getConfig().getTypingUpdateSuggestionsDelayMillis(); 684d98911178013162737fbba74387b51d2a08b0493Amith Yamasani mHandler.postDelayed(mUpdateSuggestionsTask, delay); 6854ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert } 6864ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert 6873e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private void updateSuggestions(String query) { 68811234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert // Log start latency if this is the first suggestions update 68911234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert if (mStarting) { 69011234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert mStarting = false; 69111234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert String source = getIntent().getStringExtra(Search.SOURCE); 69211234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert List<Corpus> rankedCorpora = getCorpusRanker().getRankedCorpora(); 69311234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert int latency = mStartLatencyTracker.getLatency(); 69411234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert getLogger().logStart(latency, source, mCorpus, rankedCorpora); 69511234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert } 69611234b9966c6b0e5c17d00e3b973c0d49a8d1f57Bjorn Bringert 6973d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney query = ltrim(query); 698e6f46632869a288c82b75187af166931f82a6e12Bryan Mawhinney Suggestions suggestions = getSuggestionsProvider().getSuggestions( 69981a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert query, mCorpus, getMaxSuggestions()); 700185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert mSuggestionsAdapter.setSuggestions(suggestions); 7013e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7023e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7037be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert private boolean forwardKeyToQueryTextView(int keyCode, KeyEvent event) { 7047be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert if (!event.isSystem() && !isDpadKey(keyCode)) { 7057be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert if (DBG) Log.d(TAG, "Forwarding key to query box: " + event); 7067be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert if (mQueryTextView.requestFocus()) { 7077be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return mQueryTextView.dispatchKeyEvent(event); 7087be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7097be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7107be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return false; 7117be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7127be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 7137be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert private boolean isDpadKey(int keyCode) { 7147be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert switch (keyCode) { 7157be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_UP: 7167be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_DOWN: 7177be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_LEFT: 7187be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_RIGHT: 7197be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert case KeyEvent.KEYCODE_DPAD_CENTER: 7207be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return true; 7217be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert default: 7227be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return false; 7237be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7247be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert } 7257be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert 7263e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 7273e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Filters the suggestions list when the search text changes. 7283e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 7293e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class SearchTextWatcher implements TextWatcher { 7303e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void afterTextChanged(Editable s) { 731e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert boolean empty = s.length() == 0; 732e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert if (empty != mQueryWasEmpty) { 733e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert mQueryWasEmpty = empty; 7345691f9062b2a558ba39c700d65bc522d397ebc75Bjorn Bringert updateUi(empty); 735e4f5c630a1c9cdf75fe751dc728729c3ecb7ae07Bjorn Bringert } 7363e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (mUpdateSuggestions) { 7373e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert String query = s == null ? "" : s.toString(); 7389ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert setUserQuery(query); 7394ef1338a23b040df2ef180c48ff85e14a9d70906Bjorn Bringert updateSuggestionsBuffered(); 7403e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7413e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7423e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7433e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void beforeTextChanged(CharSequence s, int start, int count, int after) { 7443e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7453e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onTextChanged(CharSequence s, int start, int before, int count) { 7473e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7483e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7493e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 7503e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 7513e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Handles non-text keys in the query text view. 7523e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 7533e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class QueryTextViewKeyListener implements View.OnKeyListener { 7543e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public boolean onKey(View view, int keyCode, KeyEvent event) { 7553e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert // Handle IME search action key 7563e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) { 757d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood // if no action was taken, consume the key event so that the keyboard 758d6b9bd42f22582a8ccec657bd6d715465de98ec9Mathew Inwood // remains on screen. 759dd6d9a1a8d559c87f54412eb4e6569ed62193d60Mathew Inwood return !onSearchClicked(Logger.SEARCH_METHOD_KEYBOARD); 7603e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7613e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert return false; 7623e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7633e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 7643e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 765782dd228e78e9294692d639597f96c26283968bbBjorn Bringert /** 766782dd228e78e9294692d639597f96c26283968bbBjorn Bringert * Handles key events on the search and voice search buttons, 767782dd228e78e9294692d639597f96c26283968bbBjorn Bringert * by refocusing to EditText. 768782dd228e78e9294692d639597f96c26283968bbBjorn Bringert */ 769782dd228e78e9294692d639597f96c26283968bbBjorn Bringert private class ButtonsKeyListener implements View.OnKeyListener { 770782dd228e78e9294692d639597f96c26283968bbBjorn Bringert public boolean onKey(View v, int keyCode, KeyEvent event) { 7717be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return forwardKeyToQueryTextView(keyCode, event); 772782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 773782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 774782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 775782dd228e78e9294692d639597f96c26283968bbBjorn Bringert /** 776782dd228e78e9294692d639597f96c26283968bbBjorn Bringert * Handles key events on the suggestions list view. 777782dd228e78e9294692d639597f96c26283968bbBjorn Bringert */ 778713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert private class SuggestionsViewKeyListener implements View.OnKeyListener { 779782dd228e78e9294692d639597f96c26283968bbBjorn Bringert public boolean onKey(View v, int keyCode, KeyEvent event) { 780782dd228e78e9294692d639597f96c26283968bbBjorn Bringert if (event.getAction() == KeyEvent.ACTION_DOWN) { 781fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert int position = getSelectedPosition(); 782fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (onSuggestionKeyDown(position, keyCode, event)) { 7837be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return true; 784782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 785782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 7867be9c66fdc2e4df2e998d79a11bcf737ffddc2dcBjorn Bringert return forwardKeyToQueryTextView(keyCode, event); 787782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 788782dd228e78e9294692d639597f96c26283968bbBjorn Bringert } 789782dd228e78e9294692d639597f96c26283968bbBjorn Bringert 790145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert private class InputMethodCloser implements SuggestionsView.OnScrollListener { 791145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 792145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, 793145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert int totalItemCount) { 794145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert } 795145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 796145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert public void onScrollStateChanged(AbsListView view, int scrollState) { 797185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert hideInputMethod(); 798185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 799185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert } 800185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert 801185bb2e3881452c084fde44d9bee657f65881b0eBjorn Bringert private class ClickHandler implements SuggestionClickListener { 802fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public void onSuggestionClicked(int position) { 803fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert launchSuggestion(position); 8043e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8053e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 806fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public boolean onSuggestionLongClicked(int position) { 807fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return SearchActivity.this.onSuggestionLongClicked(position); 808713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert } 809145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert 810145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert public void onSuggestionQueryRefineClicked(int position) { 811145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert if (DBG) Log.d(TAG, "query refine clicked, pos " + position); 812145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert SuggestionCursor suggestions = getCurrentSuggestions(); 813145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert if (suggestions != null) { 814145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert suggestions.moveTo(position); 815145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert String query = suggestions.getSuggestionQuery(); 816145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert if (!TextUtils.isEmpty(query)) { 817145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert query += " "; 818145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert setUserQuery(query); 819145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert setQuery(query, false); 820145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert updateSuggestions(query); 821145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert } 822145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert } 823145693e12b77c193a65b7eaa038a272dd1f48f33Bjorn Bringert } 8243e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8253e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 8267b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert private class SelectionHandler implements SuggestionSelectionListener { 827fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public void onSuggestionSelected(int position) { 828e06b7cbf55301a24cfd7525a91107e3cd2c9f48eBjorn Bringert SuggestionCursor suggestions = getCurrentSuggestions(); 829fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert suggestions.moveTo(position); 830fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert String displayQuery = suggestions.getSuggestionDisplayQuery(); 831fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (TextUtils.isEmpty(displayQuery)) { 832fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert restoreUserQuery(); 833fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } else { 834fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert setQuery(displayQuery, false); 835fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 836fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 837fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 838fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public void onNothingSelected() { 839fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert // This happens when a suggestion has been selected with the 840fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert // dpad / trackball and then a different UI element is touched. 841fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert // Do nothing, since we want to keep the query of the selection 842fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert // in the search box. 8437b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 8447b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert } 8457b9d59cd76eecd7645072c6728e2faf9ff9e180aBjorn Bringert 8463e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 8472617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert * Listens for clicks on the source selector. 8483e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 8493e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class SearchGoButtonClickListener implements View.OnClickListener { 8503e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onClick(View view) { 851ca78085bb2127559e6f55276a307bfa857018ecaBjorn Bringert onSearchClicked(Logger.SEARCH_METHOD_BUTTON); 8523e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8533e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8543e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 8553e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert /** 8562617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert * Listens for clicks on the search button. 8572617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert */ 858fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private class CorpusIndicatorClickListener implements View.OnClickListener { 8592617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert public void onClick(View view) { 86041fe9d1fc461c42907250d44d3537909e4c46a7dBjorn Bringert showCorpusSelectionDialog(); 8612617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 862f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 863f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert 864dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert private class CorpusSelectorDismissListener implements DialogInterface.OnDismissListener { 865dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert public void onDismiss(DialogInterface dialog) { 866dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert if (DBG) Log.d(TAG, "Corpus selector dismissed"); 867dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert clearStartedIntoCorpusSelectionDialog(); 868dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 869dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert } 870dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert 871f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert private class CorpusSelectionListener 872f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert implements CorpusSelectionDialog.OnCorpusSelectedListener { 87321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert public void onCorpusSelected(String corpusName) { 87421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(corpusName); 875f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert updateSuggestions(getQuery()); 876f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert mQueryTextView.requestFocus(); 877dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert showInputMethodForQuery(); 878f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert } 8792617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert } 8802617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert 8812617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert /** 8823e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert * Listens for clicks on the voice search button. 8833e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert */ 8843e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert private class VoiceSearchButtonClickListener implements View.OnClickListener { 8853e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert public void onClick(View view) { 8863e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert onVoiceSearchClicked(); 8873e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8883e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert } 8893e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert 89021bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert private class CorporaObserver extends DataSetObserver { 89121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert @Override 89221bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert public void onChanged() { 89321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert setCorpus(getCorpusName()); 89421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert updateSuggestions(getQuery()); 89521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 89621bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert } 89721bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert 8983d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney private static String ltrim(String text) { 8993d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney int start = 0; 9003d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney int length = text.length(); 9013d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney while (start < length && Character.isWhitespace(text.charAt(start))) { 9023d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney start++; 9033d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney } 9043d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney return start > 0 ? text.substring(start, length) : text; 9053d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney } 9063d382f0ca49a8150d504cf2629124a7f13175e1eBryan Mawhinney 9073e44ff1f2a204db3f479698cf0b3eab3d451dec2Bjorn Bringert} 908