CorpusSelectionDialog.java revision 62adab88055fd0ef6779242245cdc8c3ae5f999c
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.quicksearchbox; 18 19import com.android.quicksearchbox.ui.CorporaAdapter; 20import com.android.quicksearchbox.ui.CorpusViewFactory; 21 22import android.app.Dialog; 23import android.app.SearchManager; 24import android.content.ActivityNotFoundException; 25import android.content.Context; 26import android.content.Intent; 27import android.os.Bundle; 28import android.util.Log; 29import android.view.KeyEvent; 30import android.view.Menu; 31import android.view.MotionEvent; 32import android.view.View; 33import android.view.Window; 34import android.view.WindowManager; 35import android.widget.AdapterView; 36import android.widget.GridView; 37 38 39/** 40 * Corpus selection dialog. 41 */ 42public class CorpusSelectionDialog extends Dialog { 43 44 private static final boolean DBG = true; 45 private static final String TAG = "QSB.SelectSearchSourceDialog"; 46 47 private static final int NUM_COLUMNS = 4; 48 49 private GridView mCorpusGrid; 50 51 private Corpus mCorpus; 52 53 private String mQuery; 54 55 private Bundle mAppData; 56 57 private CorporaAdapter mAdapter; 58 59 public CorpusSelectionDialog(Context context) { 60 super(context, R.style.Theme_SelectSearchSource); 61 setContentView(R.layout.corpus_selection_dialog); 62 mCorpusGrid = (GridView) findViewById(R.id.corpus_grid); 63 mCorpusGrid.setNumColumns(NUM_COLUMNS); 64 mCorpusGrid.setOnItemClickListener(new CorpusClickListener()); 65 // TODO: for some reason, putting this in the XML layout instead makes 66 // the list items unclickable. 67 mCorpusGrid.setFocusable(true); 68 positionWindow(); 69 } 70 71 public void setCorpus(Corpus corpus) { 72 mCorpus = corpus; 73 } 74 75 public void setQuery(String query) { 76 mQuery = query; 77 } 78 79 public void setAppData(Bundle appData) { 80 mAppData = appData; 81 } 82 83 private void positionWindow() { 84 Window window = getWindow(); 85 WindowManager.LayoutParams lp = window.getAttributes(); 86 lp.width = WindowManager.LayoutParams.MATCH_PARENT; 87 lp.height = WindowManager.LayoutParams.MATCH_PARENT; 88 // Put window on top of input method 89 lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 90 window.setAttributes(lp); 91 if (DBG) Log.d(TAG, "Window params: " + lp); 92 } 93 94 @Override 95 protected void onStart() { 96 super.onStart(); 97 CorporaAdapter adapter = 98 CorporaAdapter.createGridAdapter(getViewFactory(), getCorpusRanker()); 99 setAdapter(adapter); 100 mCorpusGrid.setSelection(adapter.getCorpusPosition(mCorpus)); 101 } 102 103 @Override 104 protected void onStop() { 105 setAdapter(null); 106 super.onStop(); 107 } 108 109 @Override 110 public boolean onCreateOptionsMenu(Menu menu) { 111 super.onCreateOptionsMenu(menu); 112 SearchSettings.addSearchSettingsMenuItem(getContext(), menu); 113 return true; 114 } 115 116 @Override 117 public boolean onTouchEvent(MotionEvent event) { 118 if (event.getAction() == MotionEvent.ACTION_DOWN) { 119 // Cancel dialog on any touch down event which is not handled by the corpus grid 120 cancel(); 121 return true; 122 } 123 return false; 124 } 125 126 @Override 127 public boolean onKeyDown(int keyCode, KeyEvent event) { 128 boolean handled = super.onKeyDown(keyCode, event); 129 if (handled) { 130 return handled; 131 } 132 // Dismiss dialog on up move when nothing, or an item on the top row, is selected. 133 if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { 134 int selectedRow = mCorpusGrid.getSelectedItemPosition() / NUM_COLUMNS; 135 if (selectedRow <= 0) { 136 cancel(); 137 return true; 138 } 139 } 140 // Dismiss dialog when typing on hard keyboard (soft keyboard is behind the dialog, 141 // so that can't be typed on) 142 if (event.isPrintingKey()) { 143 cancel(); 144 return true; 145 } 146 return false; 147 } 148 149 private void setAdapter(CorporaAdapter adapter) { 150 if (adapter == mAdapter) return; 151 if (mAdapter != null) mAdapter.close(); 152 mAdapter = adapter; 153 mCorpusGrid.setAdapter(mAdapter); 154 } 155 156 private QsbApplication getQsbApplication() { 157 return (QsbApplication) getContext().getApplicationContext(); 158 } 159 160 private CorpusRanker getCorpusRanker() { 161 return getQsbApplication().getCorpusRanker(); 162 } 163 164 private CorpusViewFactory getViewFactory() { 165 return getQsbApplication().getCorpusViewFactory(); 166 } 167 168 protected void selectCorpus(Corpus corpus) { 169 dismiss(); 170 // If a new source was selected, start QSB with that source. 171 // If the old source was selected, just finish. 172 if (!isCurrentCorpus(corpus)) { 173 switchCorpus(corpus); 174 } 175 } 176 177 private boolean isCurrentCorpus(Corpus corpus) { 178 if (corpus == null) return mCorpus == null; 179 return corpus.equals(mCorpus); 180 } 181 182 private void switchCorpus(Corpus corpus) { 183 if (DBG) Log.d(TAG, "switchSource(" + corpus + ")"); 184 185 Intent searchIntent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); 186 searchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 187 searchIntent.setData(SearchActivity.getCorpusUri(corpus)); 188 searchIntent.putExtra(SearchManager.QUERY, mQuery); 189 searchIntent.putExtra(SearchManager.APP_DATA, mAppData); 190 191 try { 192 if (DBG) Log.d(TAG, "startActivity(" + searchIntent.toUri(0) + ")"); 193 getOwnerActivity().startActivity(searchIntent); 194 } catch (ActivityNotFoundException ex) { 195 Log.e(TAG, "Couldn't start QSB: " + ex); 196 } 197 } 198 199 private class CorpusClickListener implements AdapterView.OnItemClickListener { 200 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 201 Corpus corpus = (Corpus) parent.getItemAtPosition(position); 202 selectCorpus(corpus); 203 } 204 } 205} 206