CorpusSelectionDialog.java revision f95ce100dcbc77794b79b0187c566bb58b5978d3
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.content.Context; 24import android.os.Bundle; 25import android.util.Log; 26import android.view.KeyEvent; 27import android.view.Menu; 28import android.view.MotionEvent; 29import android.view.View; 30import android.view.Window; 31import android.view.WindowManager; 32import android.widget.AdapterView; 33import android.widget.GridView; 34 35/** 36 * Corpus selection dialog. 37 */ 38public class CorpusSelectionDialog extends Dialog { 39 40 private static final boolean DBG = true; 41 private static final String TAG = "QSB.SelectSearchSourceDialog"; 42 43 private static final int NUM_COLUMNS = 4; 44 45 private GridView mCorpusGrid; 46 47 private OnCorpusSelectedListener mListener; 48 49 private Corpus mCorpus; 50 51 private CorporaAdapter mAdapter; 52 53 public CorpusSelectionDialog(Context context) { 54 super(context, R.style.Theme_SelectSearchSource); 55 } 56 57 /** 58 * Shows the corpus selection dialog. 59 * 60 * @param corpus The currently selected corpus. 61 */ 62 public void show(Corpus corpus) { 63 mCorpus = corpus; 64 show(); 65 } 66 67 public void setOnCorpusSelectedListener(OnCorpusSelectedListener listener) { 68 mListener = listener; 69 } 70 71 @Override 72 protected void onCreate(Bundle savedInstanceState) { 73 setContentView(R.layout.corpus_selection_dialog); 74 mCorpusGrid = (GridView) findViewById(R.id.corpus_grid); 75 mCorpusGrid.setNumColumns(NUM_COLUMNS); 76 mCorpusGrid.setOnItemClickListener(new CorpusClickListener()); 77 // TODO: for some reason, putting this in the XML layout instead makes 78 // the list items unclickable. 79 mCorpusGrid.setFocusable(true); 80 81 Window window = getWindow(); 82 WindowManager.LayoutParams lp = window.getAttributes(); 83 lp.width = WindowManager.LayoutParams.MATCH_PARENT; 84 lp.height = WindowManager.LayoutParams.MATCH_PARENT; 85 // Put window on top of input method 86 lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 87 window.setAttributes(lp); 88 if (DBG) Log.d(TAG, "Window params: " + lp); 89 } 90 91 @Override 92 protected void onStart() { 93 super.onStart(); 94 CorporaAdapter adapter = 95 CorporaAdapter.createGridAdapter(getViewFactory(), getCorpusRanker()); 96 setAdapter(adapter); 97 mCorpusGrid.setSelection(adapter.getCorpusPosition(mCorpus)); 98 } 99 100 @Override 101 protected void onStop() { 102 setAdapter(null); 103 super.onStop(); 104 } 105 106 @Override 107 public boolean onCreateOptionsMenu(Menu menu) { 108 super.onCreateOptionsMenu(menu); 109 SearchSettings.addSearchSettingsMenuItem(getContext(), menu); 110 return true; 111 } 112 113 @Override 114 public boolean onTouchEvent(MotionEvent event) { 115 if (event.getAction() == MotionEvent.ACTION_DOWN) { 116 // Cancel dialog on any touch down event which is not handled by the corpus grid 117 cancel(); 118 return true; 119 } 120 return false; 121 } 122 123 @Override 124 public boolean onKeyDown(int keyCode, KeyEvent event) { 125 boolean handled = super.onKeyDown(keyCode, event); 126 if (handled) { 127 return handled; 128 } 129 // Dismiss dialog on up move when nothing, or an item on the top row, is selected. 130 if (keyCode == KeyEvent.KEYCODE_DPAD_UP) { 131 int selectedRow = mCorpusGrid.getSelectedItemPosition() / NUM_COLUMNS; 132 if (selectedRow <= 0) { 133 cancel(); 134 return true; 135 } 136 } 137 // Dismiss dialog when typing on hard keyboard (soft keyboard is behind the dialog, 138 // so that can't be typed on) 139 if (event.isPrintingKey()) { 140 cancel(); 141 return true; 142 } 143 return false; 144 } 145 146 private void setAdapter(CorporaAdapter adapter) { 147 if (adapter == mAdapter) return; 148 if (mAdapter != null) mAdapter.close(); 149 mAdapter = adapter; 150 mCorpusGrid.setAdapter(mAdapter); 151 } 152 153 private QsbApplication getQsbApplication() { 154 return (QsbApplication) getContext().getApplicationContext(); 155 } 156 157 private CorpusRanker getCorpusRanker() { 158 return getQsbApplication().getCorpusRanker(); 159 } 160 161 private CorpusViewFactory getViewFactory() { 162 return getQsbApplication().getCorpusViewFactory(); 163 } 164 165 protected void selectCorpus(Corpus corpus) { 166 dismiss(); 167 if (mListener != null) { 168 mListener.onCorpusSelected(corpus); 169 } 170 } 171 172 private class CorpusClickListener implements AdapterView.OnItemClickListener { 173 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 174 Corpus corpus = (Corpus) parent.getItemAtPosition(position); 175 selectCorpus(corpus); 176 } 177 } 178 179 public interface OnCorpusSelectedListener { 180 void onCorpusSelected(Corpus corpus); 181 } 182} 183