CorpusSelectionDialog.java revision fde948e69f59589cf0d217ea414af7947de600bb
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.SuggestionViewFactory;
21
22import android.app.Dialog;
23import android.app.SearchManager;
24import android.content.ActivityNotFoundException;
25import android.content.Context;
26import android.content.Intent;
27import android.content.res.Resources;
28import android.os.Bundle;
29import android.util.Log;
30import android.view.Gravity;
31import android.view.View;
32import android.view.Window;
33import android.view.WindowManager;
34import android.widget.AdapterView;
35import android.widget.GridView;
36
37
38/**
39 * Corpus selection dialog.
40 */
41public class CorpusSelectionDialog extends Dialog {
42
43    private static final boolean DBG = true;
44    private static final String TAG = "QSB.SelectSearchSourceDialog";
45
46    private GridView mCorpusGrid;
47
48    private Corpus mCorpus;
49
50    private String mQuery;
51
52    private Bundle mAppData;
53
54    public CorpusSelectionDialog(Context context) {
55        super(context, R.style.Theme_SelectSearchSource);
56        setContentView(R.layout.corpus_selection_dialog);
57        mCorpusGrid = (GridView) findViewById(R.id.corpus_grid);
58        mCorpusGrid.setOnItemClickListener(new CorpusClickListener());
59        // TODO: for some reason, putting this in the XML layout instead makes
60        // the list items unclickable.
61        mCorpusGrid.setFocusable(true);
62        setCanceledOnTouchOutside(true);
63        positionWindow();
64    }
65
66    public void setCorpus(Corpus corpus) {
67        mCorpus = corpus;
68    }
69
70    public void setQuery(String query) {
71        mQuery = query;
72    }
73
74    public void setAppData(Bundle appData) {
75        mAppData = appData;
76    }
77
78    private void positionWindow() {
79        Resources resources = getContext().getResources();
80        int x = resources.getDimensionPixelSize(R.dimen.corpus_selection_dialog_x);
81        int y = resources.getDimensionPixelSize(R.dimen.corpus_selection_dialog_y);
82        positionArrowAt(x, y);
83    }
84
85    private void positionArrowAt(int x, int y) {
86        Window window = getWindow();
87        WindowManager.LayoutParams lp = window.getAttributes();
88        lp.x = x;
89        lp.y = y;
90        lp.gravity = Gravity.TOP | Gravity.LEFT;
91        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
92        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
93        // Use screen coordinates
94        lp.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
95        lp.flags |=  WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
96        // Put window on top of input method
97        lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
98        window.setAttributes(lp);
99        if (DBG) Log.d(TAG, "Window params: " + lp);
100    }
101
102    @Override
103    protected void onStart() {
104        super.onStart();
105        updateCorpora();
106    }
107
108    private void updateCorpora() {
109        mCorpusGrid.setAdapter(
110                new CorporaAdapter(getViewFactory(), getCorpora(), getCorpusRanker()));
111    }
112
113    private QsbApplication getQsbApplication() {
114        return (QsbApplication) getContext().getApplicationContext();
115    }
116
117    private Corpora getCorpora() {
118        return getQsbApplication().getCorpora();
119    }
120
121    private CorpusRanker getCorpusRanker() {
122        return getQsbApplication().getCorpusRanker();
123    }
124
125    private SuggestionViewFactory getViewFactory() {
126        return getQsbApplication().getSuggestionViewFactory();
127    }
128
129    protected void selectCorpus(Corpus corpus) {
130        dismiss();
131        // If a new source was selected, start QSB with that source.
132        // If the old source was selected, just finish.
133        if (!isCurrentCorpus(corpus)) {
134            switchCorpus(corpus);
135        }
136    }
137
138    private boolean isCurrentCorpus(Corpus corpus) {
139        if (corpus == null) return mCorpus == null;
140        return corpus.equals(mCorpus);
141    }
142
143    private void switchCorpus(Corpus corpus) {
144        if (DBG) Log.d(TAG, "switchSource(" + corpus + ")");
145
146        Intent searchIntent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH);
147        searchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
148        searchIntent.setData(SearchActivity.getCorpusUri(corpus));
149        searchIntent.putExtra(SearchManager.QUERY, mQuery);
150        searchIntent.putExtra(SearchManager.APP_DATA, mAppData);
151
152        try {
153            if (DBG) Log.d(TAG, "startActivity(" + searchIntent.toUri(0) + ")");
154            getOwnerActivity().startActivity(searchIntent);
155        } catch (ActivityNotFoundException ex) {
156            Log.e(TAG, "Couldn't start QSB: " + ex);
157        }
158    }
159
160    private class CorpusClickListener implements AdapterView.OnItemClickListener {
161        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
162            Corpus corpus = (Corpus) parent.getItemAtPosition(position);
163            selectCorpus(corpus);
164        }
165    }
166}
167