1713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert/*
2713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert * Copyright (C) 2009 The Android Open Source Project
3713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert *
4713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
5713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert * you may not use this file except in compliance with the License.
6713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert * You may obtain a copy of the License at
7713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert *
8713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert *      http://www.apache.org/licenses/LICENSE-2.0
9713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert *
10713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
11713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
12713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert * See the License for the specific language governing permissions and
14713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert * limitations under the License.
15713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert */
16713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
17713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertpackage com.android.quicksearchbox;
18713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
19fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport com.android.quicksearchbox.ui.CorporaAdapter;
20713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
212617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringertimport android.app.Dialog;
22b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringertimport android.content.Context;
231d870d9687e1831241e528a558fcd008f8309604Bjorn Bringertimport android.content.Intent;
24713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertimport android.os.Bundle;
25713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertimport android.util.Log;
26f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringertimport android.view.KeyEvent;
2726d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringertimport android.view.Menu;
28f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringertimport android.view.MotionEvent;
29713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertimport android.view.View;
30713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertimport android.view.Window;
31713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertimport android.view.WindowManager;
32713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertimport android.widget.AdapterView;
33713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertimport android.widget.GridView;
34a3fdfe2d947db90faab3333abd593c2d3e5382a8Amith Yamasaniimport android.widget.ImageView;
35713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
36713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert/**
37fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * Corpus selection dialog.
38713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert */
39fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertpublic class CorpusSelectionDialog extends Dialog {
40713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
41b5fc08b7f16a32d3865f44b7f26d8aaa5304a2adBjorn Bringert    private static final boolean DBG = false;
422617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert    private static final String TAG = "QSB.SelectSearchSourceDialog";
43713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
4496fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert    private final SearchSettings mSettings;
4596fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert
46fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    private GridView mCorpusGrid;
47713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
48a3fdfe2d947db90faab3333abd593c2d3e5382a8Amith Yamasani    private ImageView mEditItems;
491a9de3a4cfc0d6142c961ae11f940f1f77910afdMathew Inwood
50f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    private OnCorpusSelectedListener mListener;
512617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert
52f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    private Corpus mCorpus;
53713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
5426d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    private CorporaAdapter mAdapter;
5526d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert
5696fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert    public CorpusSelectionDialog(Context context, SearchSettings settings) {
57b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert        super(context, R.style.Theme_SelectSearchSource);
5896fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert        mSettings = settings;
5996fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert    }
6096fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert
6196fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert    protected SearchSettings getSettings() {
6296fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert        return mSettings;
632617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert    }
649ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert
65f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    /**
66f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert     * Shows the corpus selection dialog.
67f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert     *
68f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert     * @param corpus The currently selected corpus.
69f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert     */
70f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    public void show(Corpus corpus) {
71fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        mCorpus = corpus;
72f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        show();
739ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert    }
749ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert
75f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    public void setOnCorpusSelectedListener(OnCorpusSelectedListener listener) {
76f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        mListener = listener;
779ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert    }
789ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert
79f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    @Override
80f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    protected void onCreate(Bundle savedInstanceState) {
81f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        setContentView(R.layout.corpus_selection_dialog);
82f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        mCorpusGrid = (GridView) findViewById(R.id.corpus_grid);
83f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        mCorpusGrid.setOnItemClickListener(new CorpusClickListener());
84f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        // TODO: for some reason, putting this in the XML layout instead makes
85f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        // the list items unclickable.
86f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        mCorpusGrid.setFocusable(true);
879ad03a750a66b26441a19ff54b6057729c145eaeBjorn Bringert
88a3fdfe2d947db90faab3333abd593c2d3e5382a8Amith Yamasani        mEditItems = (ImageView) findViewById(R.id.corpus_edit_items);
89b6aa0562dd2067537eb8a38403c13f9ea2c100f7Mathew Inwood        mEditItems.setOnClickListener(new CorpusEditListener());
901d870d9687e1831241e528a558fcd008f8309604Bjorn Bringert
912617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert        Window window = getWindow();
92713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        WindowManager.LayoutParams lp = window.getAttributes();
93ac17ac866d6f543c3a136e1e2361c01004c6547eBjorn Bringert        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
94f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        lp.height = WindowManager.LayoutParams.MATCH_PARENT;
95ac17ac866d6f543c3a136e1e2361c01004c6547eBjorn Bringert        // Put window on top of input method
96ac17ac866d6f543c3a136e1e2361c01004c6547eBjorn Bringert        lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
97713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        window.setAttributes(lp);
98713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        if (DBG) Log.d(TAG, "Window params: " + lp);
99713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    }
100713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
1012617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert    @Override
1022617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert    protected void onStart() {
1032617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert        super.onStart();
1048b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        Corpora corpora = getQsbApplication().getCorpora();
1058b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        CorporaAdapter adapter =
1068b2936607176720172aee068abc5631bdf77e843Bjorn Bringert                new CorporaAdapter(getContext(), corpora, R.layout.corpus_grid_item);
1078b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        adapter.setCurrentCorpus(mCorpus);
108f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        setAdapter(adapter);
109f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        mCorpusGrid.setSelection(adapter.getCorpusPosition(mCorpus));
11026d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    }
11126d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert
11226d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    @Override
11326d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    protected void onStop() {
11426d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        setAdapter(null);
11526d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        super.onStop();
11626d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    }
11726d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert
11826d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    @Override
11996fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert    public boolean onPrepareOptionsMenu(Menu menu) {
12073a375928e0b8f0b2bfa09e4b252cfcbdad4ef84Bjorn Bringert        menu.clear();
12173a375928e0b8f0b2bfa09e4b252cfcbdad4ef84Bjorn Bringert        getSettings().addMenuItems(menu, true);
12226d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        return true;
1232617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert    }
1242617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert
125f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert    @Override
126f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert    public boolean onTouchEvent(MotionEvent event) {
127f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        if (event.getAction() == MotionEvent.ACTION_DOWN) {
128f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert            // Cancel dialog on any touch down event which is not handled by the corpus grid
129f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert            cancel();
130f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert            return true;
131f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        }
132f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        return false;
133f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert    }
134f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert
135f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert    @Override
136f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert    public boolean onKeyDown(int keyCode, KeyEvent event) {
137f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        boolean handled = super.onKeyDown(keyCode, event);
138f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        if (handled) {
139f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert            return handled;
140f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        }
141f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        // Dismiss dialog on up move when nothing, or an item on the top row, is selected.
142f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
143b6aa0562dd2067537eb8a38403c13f9ea2c100f7Mathew Inwood            if (mEditItems.isFocused()) {
144f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert                cancel();
145f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert                return true;
146f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert            }
147f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        }
148f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        // Dismiss dialog when typing on hard keyboard (soft keyboard is behind the dialog,
149f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        // so that can't be typed on)
150f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        if (event.isPrintingKey()) {
151f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert            cancel();
152f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert            return true;
153f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        }
154f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        return false;
155f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert    }
156f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert
15711c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert    @Override
15811c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert    public void onBackPressed() {
15911c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert        SearchActivity searchActivity = getSearchActivity();
16011c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert        if (searchActivity.startedIntoCorpusSelectionDialog()) {
161dfe0df4a730c54bdc963b891f9a3080c38055ebbBjorn Bringert            searchActivity.onBackPressed();
16211c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert        }
16311c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert        cancel();
16411c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert    }
16511c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert
16611c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert    private SearchActivity getSearchActivity() {
16711c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert        return (SearchActivity) getOwnerActivity();
16811c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert    }
16911c44a74cb2519c0c8630486784aa916b964070eBjorn Bringert
17026d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    private void setAdapter(CorporaAdapter adapter) {
17126d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        if (adapter == mAdapter) return;
17226d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        if (mAdapter != null) mAdapter.close();
17326d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        mAdapter = adapter;
17426d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        mCorpusGrid.setAdapter(mAdapter);
175abd33f7f8d8e56348a8a87bb9e7af491d83ee833Bjorn Bringert    }
176abd33f7f8d8e56348a8a87bb9e7af491d83ee833Bjorn Bringert
177713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    private QsbApplication getQsbApplication() {
17849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert        return QsbApplication.get(getContext());
179713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    }
180713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
181fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    protected void selectCorpus(Corpus corpus) {
1822617a0177a6088d5aaf381263229bf5a62d2238dBjorn Bringert        dismiss();
183f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert        if (mListener != null) {
18421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert            String corpusName = corpus == null ? null : corpus.getName();
18521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert            mListener.onCorpusSelected(corpusName);
186713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        }
187713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    }
188713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
189fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    private class CorpusClickListener implements AdapterView.OnItemClickListener {
190713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
191fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            Corpus corpus = (Corpus) parent.getItemAtPosition(position);
1922fd5aa82682f077660faa8ec60c04238026a8731Mathew Inwood            if (DBG) Log.d(TAG, "Corpus selected: " + corpus);
193fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert            selectCorpus(corpus);
194713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        }
195713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    }
196f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert
1971d870d9687e1831241e528a558fcd008f8309604Bjorn Bringert    private class CorpusEditListener implements View.OnClickListener {
1981d870d9687e1831241e528a558fcd008f8309604Bjorn Bringert        public void onClick(View v) {
19996fec862c3d494aebcb4e1d93589a241385a2ba7Bjorn Bringert            Intent intent = getSettings().getSearchableItemsIntent();
2001d870d9687e1831241e528a558fcd008f8309604Bjorn Bringert            getContext().startActivity(intent);
2011d870d9687e1831241e528a558fcd008f8309604Bjorn Bringert        }
2021d870d9687e1831241e528a558fcd008f8309604Bjorn Bringert    }
2031d870d9687e1831241e528a558fcd008f8309604Bjorn Bringert
204f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    public interface OnCorpusSelectedListener {
20521bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert        void onCorpusSelected(String corpusName);
206f95ce100dcbc77794b79b0187c566bb58b5978d3Bjorn Bringert    }
207713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert}
208