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