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.ui;
18713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
1922da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringertimport com.android.quicksearchbox.Corpora;
20fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport com.android.quicksearchbox.Corpus;
218b2936607176720172aee068abc5631bdf77e843Bjorn Bringertimport com.android.quicksearchbox.R;
22713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
238b2936607176720172aee068abc5631bdf77e843Bjorn Bringertimport android.content.Context;
2426d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringertimport android.database.DataSetObserver;
25a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringertimport android.graphics.drawable.Drawable;
26a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringertimport android.util.Log;
278b2936607176720172aee068abc5631bdf77e843Bjorn Bringertimport android.view.LayoutInflater;
28713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertimport android.view.View;
29713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertimport android.view.ViewGroup;
30713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringertimport android.widget.BaseAdapter;
31713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
3296c7058210699c82445169048b7c0fdfb16f59eeBjorn Bringertimport java.util.ArrayList;
3322da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringertimport java.util.Collections;
3422da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringertimport java.util.Comparator;
35ce4cdcf739b57563ddcdbed6944128b8c1f7522aBjorn Bringertimport java.util.List;
36713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
37713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert/**
38713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert * Adapter for showing a list of sources in the source selection activity.
39713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert */
40fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertpublic class CorporaAdapter extends BaseAdapter {
41713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
42a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert    private static final String TAG = "CorporaAdapter";
43b5fc08b7f16a32d3865f44b7f26d8aaa5304a2adBjorn Bringert    private static final boolean DBG = false;
44a576b1abd602c08dcf0d470facc43fac0243b07cBjorn Bringert
458b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    private final Context mContext;
46713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
4722da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert    private final Corpora mCorpora;
486859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert
498b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    private final int mCorpusViewRes;
506859aead3af0680b2c9dc326244aa89835c2c852Bjorn Bringert
5126d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    private final DataSetObserver mCorporaObserver = new CorporaObserver();
5226d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert
5322da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert    private List<Corpus> mSortedCorpora;
54713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
558b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    private String mCurrentCorpusName;
568b2936607176720172aee068abc5631bdf77e843Bjorn Bringert
578b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    public CorporaAdapter(Context context, Corpora corpora, int corpusViewRes) {
588b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        mContext = context;
5922da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        mCorpora = corpora;
608b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        mCorpusViewRes = corpusViewRes;
6122da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        mCorpora.registerDataSetObserver(mCorporaObserver);
6226d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        updateCorpora();
63c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert    }
64c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert
658b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    public void setCurrentCorpus(Corpus corpus) {
668b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        mCurrentCorpusName = corpus == null ? null : corpus.getName();
678b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        notifyDataSetChanged();
688b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    }
698b2936607176720172aee068abc5631bdf77e843Bjorn Bringert
7026d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    private void updateCorpora() {
7122da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        List<Corpus> enabledCorpora = mCorpora.getEnabledCorpora();
7222da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        ArrayList<Corpus> sorted = new ArrayList<Corpus>(enabledCorpora.size());
7322da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        for (Corpus corpus : enabledCorpora) {
7422da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert            if (!corpus.isCorpusHidden()) {
7522da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert                sorted.add(corpus);
7696c7058210699c82445169048b7c0fdfb16f59eeBjorn Bringert            }
7722da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        }
7822da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        Collections.sort(sorted, new CorpusComparator());
7922da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        mSortedCorpora = sorted;
8022da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        notifyDataSetChanged();
8122da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert    }
8222da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert
8322da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert    private static class CorpusComparator implements Comparator<Corpus> {
8422da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        public int compare(Corpus corpus1, Corpus corpus2) {
8522da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert            // Comparing a corpus against itself
8622da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert            if (corpus1 == corpus2) return 0;
8722da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert            // Web always comes first
8822da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert            if (corpus1.isWebCorpus()) return -1;
8922da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert            if (corpus2.isWebCorpus()) return 1;
9022da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert            // Alphabetically by name
9122da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert            return corpus1.getLabel().toString().compareTo(corpus2.getLabel().toString());
9222da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        }
9326d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    }
9426d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert
9526d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    public void close() {
9622da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        mCorpora.unregisterDataSetObserver(mCorporaObserver);
9726d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    }
9826d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert
99713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    public int getCount() {
10022da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert        return 1 + (mSortedCorpora == null ? 0 : mSortedCorpora.size());
101713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    }
102713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
103fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert    public Corpus getItem(int position) {
104713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        if (position == 0) {
105713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert            return null;
106713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        } else {
10722da5e41bec9a5d36388c1e6f99bca392c3ac63eBjorn Bringert            return mSortedCorpora.get(position - 1);
108713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        }
109713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    }
110713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
111713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    public long getItemId(int position) {
112713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        return position;
113713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    }
114713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert
115f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert    /**
116f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert     * Gets the position of the given corpus.
117f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert     */
118f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert    public int getCorpusPosition(Corpus corpus) {
119f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        if (corpus == null) {
120f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert            return 0;
121f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        }
122f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        int count = getCount();
123f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        for (int i = 0; i < count; i++) {
124f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert            if (corpus.equals(getItem(i))) {
125f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert                return i;
126f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert            }
127f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        }
128f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        Log.w(TAG, "Corpus not in adapter: " + corpus);
129f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert        return 0;
130f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert    }
131f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert
132713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    public View getView(int position, View convertView, ViewGroup parent) {
133fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        CorpusView view = (CorpusView) convertView;
134713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        if (view == null) {
135c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert            view = createView(parent);
136713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        }
137fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        Corpus corpus = getItem(position);
1388b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        if (DBG) Log.d(TAG, "Binding " + position + ", corpus=" + corpus);
1398b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        bindView(view, corpus);
1408b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        return view;
1418b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    }
1428b2936607176720172aee068abc5631bdf77e843Bjorn Bringert
1438b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    protected void bindView(CorpusView view, Corpus corpus) {
1448b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        Drawable icon = getCorpusIcon(corpus);
1458b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        CharSequence label = getCorpusLabel(corpus);
1468b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        boolean isCurrent = isCurrentCorpus(corpus);
1478b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        if (DBG) Log.d(TAG, "bind:name=" + corpus + ",label=" + label + ",current=" + isCurrent);
1488b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        view.setIcon(icon);
1498b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        view.setLabel(label);
1508b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        view.setChecked(isCurrent);
1518b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    }
1528b2936607176720172aee068abc5631bdf77e843Bjorn Bringert
1538b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    protected Drawable getCorpusIcon(Corpus corpus) {
154fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert        if (corpus == null) {
155138c0a8d821f02d13e73bfc579ad9bded7d4d683Ying Wang            return mContext.getResources().getDrawable(R.mipmap.search_app_icon);
156713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        } else {
1578b2936607176720172aee068abc5631bdf77e843Bjorn Bringert            return corpus.getCorpusIcon();
158713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert        }
159713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert    }
160c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert
1618b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    protected CharSequence getCorpusLabel(Corpus corpus) {
1628b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        if (corpus == null) {
1638b2936607176720172aee068abc5631bdf77e843Bjorn Bringert            return mContext.getText(R.string.corpus_label_global);
164c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert        } else {
165cefec1fa95fe5f66b2f4a379406db485da5b4a7dBjorn Bringert            return corpus.getLabel();
166c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert        }
167c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert    }
168c5a3ecb62318a6be1d1a626a36b52829e989f740Bjorn Bringert
1698b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    protected boolean isCurrentCorpus(Corpus corpus) {
1708b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        if (corpus == null) {
1718b2936607176720172aee068abc5631bdf77e843Bjorn Bringert            return mCurrentCorpusName == null;
1728b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        } else {
1738b2936607176720172aee068abc5631bdf77e843Bjorn Bringert            return corpus.getName().equals(mCurrentCorpusName);
1748b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        }
1758b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    }
1768b2936607176720172aee068abc5631bdf77e843Bjorn Bringert
1778b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    protected CorpusView createView(ViewGroup parent) {
1788b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        return (CorpusView) LayoutInflater.from(mContext).inflate(mCorpusViewRes, parent, false);
1798b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    }
1808b2936607176720172aee068abc5631bdf77e843Bjorn Bringert
1818b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    protected LayoutInflater getInflater() {
1828b2936607176720172aee068abc5631bdf77e843Bjorn Bringert        return (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
1838b2936607176720172aee068abc5631bdf77e843Bjorn Bringert    }
1848b2936607176720172aee068abc5631bdf77e843Bjorn Bringert
18526d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    private class CorporaObserver extends DataSetObserver {
18626d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        @Override
18726d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        public void onChanged() {
18826d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert            updateCorpora();
18926d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        }
19026d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert
19126d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        @Override
19226d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        public void onInvalidated() {
19326d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert            updateCorpora();
19426d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert        }
19526d85260316193a1aeff5d407d4f32f5297be012Bjorn Bringert    }
196f69873ae02e6d8f8a550f5fa43b5b1f2cbea96ffBjorn Bringert
197713194910648268c094fa81b81f40ce2f7e39333Bjorn Bringert}
198