11808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita/*
21808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * Copyright (C) 2016 The Android Open Source Project
31808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita *
41808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * Licensed under the Apache License, Version 2.0 (the "License");
51808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * you may not use this file except in compliance with the License.
61808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * You may obtain a copy of the License at
71808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita *
81808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita *      http://www.apache.org/licenses/LICENSE-2.0
91808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita *
101808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * Unless required by applicable law or agreed to in writing, software
111808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * distributed under the License is distributed on an "AS IS" BASIS,
121808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * See the License for the specific language governing permissions and
141808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * limitations under the License.
151808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita */
161808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
171808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitapackage com.android.internal.app;
181808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
1924215ecadce5f44de33959b4f512482f39ac4c92Mihai Nitaimport android.text.TextUtils;
201808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport android.view.LayoutInflater;
211808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport android.view.View;
221808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport android.view.ViewGroup;
231808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport android.widget.BaseAdapter;
241808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport android.widget.Filter;
251808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport android.widget.Filterable;
261808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport android.widget.TextView;
271808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
281808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport com.android.internal.R;
291808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
301808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport java.util.ArrayList;
311808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport java.util.Collections;
321808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport java.util.Locale;
331808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nitaimport java.util.Set;
341808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
351808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
361808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita/**
371808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * This adapter wraps around a regular ListAdapter for LocaleInfo, and creates 2 sections.
381808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita *
391808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * <p>The first section contains "suggested" languages (usually including a region),
401808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * the second section contains all the languages within the original adapter.
411808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * The "others" might still include languages that appear in the "suggested" section.</p>
421808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita *
431808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * <p>Example: if we show "German Switzerland" as "suggested" (based on SIM, let's say),
441808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * then "German" will still show in the "others" section, clicking on it will only show the
451808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * countries for all the other German locales, but not Switzerland
461808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita * (Austria, Belgium, Germany, Liechtenstein, Luxembourg)</p>
471808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita */
48137b96e3a41edc19a53f7218ef3e53adbfcfd340Mihai Nitapublic class SuggestedLocaleAdapter extends BaseAdapter implements Filterable {
491808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    private static final int TYPE_HEADER_SUGGESTED = 0;
501808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    private static final int TYPE_HEADER_ALL_OTHERS = 1;
511808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    private static final int TYPE_LOCALE = 2;
5286235d497007ad17ddec7e659fb0e0c36b010745Mihai Nita    private static final int MIN_REGIONS_FOR_SUGGESTIONS = 6;
531808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
541808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    private ArrayList<LocaleStore.LocaleInfo> mLocaleOptions;
551808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    private ArrayList<LocaleStore.LocaleInfo> mOriginalLocaleOptions;
561808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    private int mSuggestionCount;
571808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    private final boolean mCountryMode;
581808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    private LayoutInflater mInflater;
591808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
60137b96e3a41edc19a53f7218ef3e53adbfcfd340Mihai Nita    public SuggestedLocaleAdapter(Set<LocaleStore.LocaleInfo> localeOptions, boolean countryMode) {
611808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        mCountryMode = countryMode;
621808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        mLocaleOptions = new ArrayList<>(localeOptions.size());
631808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        for (LocaleStore.LocaleInfo li : localeOptions) {
641808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            if (li.isSuggested()) {
651808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                mSuggestionCount++;
661808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            }
671808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            mLocaleOptions.add(li);
681808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        }
691808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
701808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
711808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    @Override
721808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    public boolean areAllItemsEnabled() {
731808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        return false;
741808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
751808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
761808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    @Override
771808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    public boolean isEnabled(int position) {
781808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        return getItemViewType(position) == TYPE_LOCALE;
791808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
801808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
811808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    @Override
821808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    public int getItemViewType(int position) {
831808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        if (!showHeaders()) {
841808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            return TYPE_LOCALE;
851808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        } else {
861808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            if (position == 0) {
871808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                return TYPE_HEADER_SUGGESTED;
881808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            }
891808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            if (position == mSuggestionCount + 1) {
901808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                return TYPE_HEADER_ALL_OTHERS;
911808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            }
921808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            return TYPE_LOCALE;
931808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        }
941808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
951808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
961808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    @Override
971808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    public int getViewTypeCount() {
981808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        if (showHeaders()) {
991808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            return 3; // Two headers in addition to the locales
1001808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        } else {
1011808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            return 1; // Locales items only
1021808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        }
1031808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
1041808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
1051808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    @Override
1061808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    public int getCount() {
1071808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        if (showHeaders()) {
1081808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            return mLocaleOptions.size() + 2; // 2 extra for the headers
1091808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        } else {
1101808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            return mLocaleOptions.size();
1111808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        }
1121808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
1131808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
1141808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    @Override
1151808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    public Object getItem(int position) {
1161808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        int offset = 0;
1171808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        if (showHeaders()) {
1181808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            offset = position > mSuggestionCount ? -2 : -1;
1191808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        }
1201808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
1211808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        return mLocaleOptions.get(position + offset);
1221808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
1231808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
1241808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    @Override
1251808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    public long getItemId(int position) {
1261808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        return position;
1271808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
1281808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
1291808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    @Override
1301808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    public View getView(int position, View convertView, ViewGroup parent) {
1311808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        if (convertView == null && mInflater == null) {
1321808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            mInflater = LayoutInflater.from(parent.getContext());
1331808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        }
1341808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
1351808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        int itemType = getItemViewType(position);
1361808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        switch (itemType) {
1371808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            case TYPE_HEADER_SUGGESTED: // intentional fallthrough
1381808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            case TYPE_HEADER_ALL_OTHERS:
1391808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                // Covers both null, and "reusing" a wrong kind of view
1401808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                if (!(convertView instanceof TextView)) {
1411808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    convertView = mInflater.inflate(R.layout.language_picker_section_header,
1421808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                            parent, false);
1431808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                }
1441808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                TextView textView = (TextView) convertView;
1451808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                if (itemType == TYPE_HEADER_SUGGESTED) {
1461808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    textView.setText(R.string.language_picker_section_suggested);
1471808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                } else {
1481808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    textView.setText(R.string.language_picker_section_all);
1491808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                }
1501808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                textView.setTextLocale(Locale.getDefault());
1511808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                break;
1521808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            default:
1531808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                // Covers both null, and "reusing" a wrong kind of view
1541808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                if (!(convertView instanceof ViewGroup)) {
1551808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    convertView = mInflater.inflate(R.layout.language_picker_item, parent, false);
1561808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                }
1571808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
1581808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                TextView text = (TextView) convertView.findViewById(R.id.locale);
1591808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                LocaleStore.LocaleInfo item = (LocaleStore.LocaleInfo) getItem(position);
160f1f39cf1936df2d28133e43390f72f3dbb40ffc8Mihai Nita                text.setText(item.getLabel(mCountryMode));
161502141d50bbd188a37b59f2ea9fa794a296f7247Mihai Nita                text.setTextLocale(item.getLocale());
16243af6366f2aad8c0c0a8ae1367215961ccd75c29Mihai Nita                text.setContentDescription(item.getContentDescription(mCountryMode));
16324215ecadce5f44de33959b4f512482f39ac4c92Mihai Nita                if (mCountryMode) {
16424215ecadce5f44de33959b4f512482f39ac4c92Mihai Nita                    int layoutDir = TextUtils.getLayoutDirectionFromLocale(item.getParent());
16524215ecadce5f44de33959b4f512482f39ac4c92Mihai Nita                    //noinspection ResourceType
16624215ecadce5f44de33959b4f512482f39ac4c92Mihai Nita                    convertView.setLayoutDirection(layoutDir);
16724215ecadce5f44de33959b4f512482f39ac4c92Mihai Nita                    text.setTextDirection(layoutDir == View.LAYOUT_DIRECTION_RTL
16824215ecadce5f44de33959b4f512482f39ac4c92Mihai Nita                            ? View.TEXT_DIRECTION_RTL
16924215ecadce5f44de33959b4f512482f39ac4c92Mihai Nita                            : View.TEXT_DIRECTION_LTR);
17024215ecadce5f44de33959b4f512482f39ac4c92Mihai Nita                }
1711808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        }
1721808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        return convertView;
1731808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
1741808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
1751808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    private boolean showHeaders() {
17686235d497007ad17ddec7e659fb0e0c36b010745Mihai Nita        // We don't want to show suggestions for locales with very few regions
17786235d497007ad17ddec7e659fb0e0c36b010745Mihai Nita        // (e.g. Romanian, with 2 regions)
17886235d497007ad17ddec7e659fb0e0c36b010745Mihai Nita        // So we put a (somewhat) arbitrary limit.
17986235d497007ad17ddec7e659fb0e0c36b010745Mihai Nita        //
18086235d497007ad17ddec7e659fb0e0c36b010745Mihai Nita        // The initial idea was to make that limit dependent on the screen height.
18186235d497007ad17ddec7e659fb0e0c36b010745Mihai Nita        // But that would mean rotating the screen could make the suggestions disappear,
18286235d497007ad17ddec7e659fb0e0c36b010745Mihai Nita        // as the number of countries that fits on the screen would be different in portrait
18386235d497007ad17ddec7e659fb0e0c36b010745Mihai Nita        // and landscape mode.
18486235d497007ad17ddec7e659fb0e0c36b010745Mihai Nita        if (mCountryMode && mLocaleOptions.size() < MIN_REGIONS_FOR_SUGGESTIONS) {
185f1f39cf1936df2d28133e43390f72f3dbb40ffc8Mihai Nita            return false;
186f1f39cf1936df2d28133e43390f72f3dbb40ffc8Mihai Nita        }
1871808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        return mSuggestionCount != 0 && mSuggestionCount != mLocaleOptions.size();
1881808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
1891808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
190137b96e3a41edc19a53f7218ef3e53adbfcfd340Mihai Nita    /**
191137b96e3a41edc19a53f7218ef3e53adbfcfd340Mihai Nita     * Sorts the items in the adapter using a locale-aware comparator.
192137b96e3a41edc19a53f7218ef3e53adbfcfd340Mihai Nita     * @param comp The locale-aware comparator to use.
193137b96e3a41edc19a53f7218ef3e53adbfcfd340Mihai Nita     */
1941808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    public void sort(LocaleHelper.LocaleInfoComparator comp) {
1951808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        Collections.sort(mLocaleOptions, comp);
1961808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
1971808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
1981808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    class FilterByNativeAndUiNames extends Filter {
1991808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2001808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        @Override
2011808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        protected FilterResults performFiltering(CharSequence prefix) {
2021808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            FilterResults results = new FilterResults();
2031808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2041808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            if (mOriginalLocaleOptions == null) {
2051808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                mOriginalLocaleOptions = new ArrayList<>(mLocaleOptions);
2061808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            }
2071808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2081808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            ArrayList<LocaleStore.LocaleInfo> values;
2091808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            values = new ArrayList<>(mOriginalLocaleOptions);
2101808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            if (prefix == null || prefix.length() == 0) {
2111808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                results.values = values;
2121808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                results.count = values.size();
2131808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            } else {
2141808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                // TODO: decide if we should use the string's locale
2151808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                Locale locale = Locale.getDefault();
2161808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                String prefixString = LocaleHelper.normalizeForSearch(prefix.toString(), locale);
2171808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2181808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                final int count = values.size();
2191808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                final ArrayList<LocaleStore.LocaleInfo> newValues = new ArrayList<>();
2201808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2211808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                for (int i = 0; i < count; i++) {
2221808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    final LocaleStore.LocaleInfo value = values.get(i);
2231808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    final String nameToCheck = LocaleHelper.normalizeForSearch(
2241808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                            value.getFullNameInUiLanguage(), locale);
2251808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    final String nativeNameToCheck = LocaleHelper.normalizeForSearch(
2261808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                            value.getFullNameNative(), locale);
2271808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    if (wordMatches(nativeNameToCheck, prefixString)
2281808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                            || wordMatches(nameToCheck, prefixString)) {
2291808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                        newValues.add(value);
2301808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    }
2311808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                }
2321808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2331808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                results.values = newValues;
2341808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                results.count = newValues.size();
2351808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            }
2361808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2371808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            return results;
2381808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        }
2391808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2401808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        // TODO: decide if this is enough, or we want to use a BreakIterator...
2411808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        boolean wordMatches(String valueText, String prefixString) {
242137b96e3a41edc19a53f7218ef3e53adbfcfd340Mihai Nita            // First match against the whole, non-split value
2431808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            if (valueText.startsWith(prefixString)) {
2441808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                return true;
2451808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            }
2461808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2471808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            final String[] words = valueText.split(" ");
2481808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            // Start at index 0, in case valueText starts with space(s)
2491808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            for (String word : words) {
2501808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                if (word.startsWith(prefixString)) {
2511808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    return true;
2521808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                }
2531808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            }
2541808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2551808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            return false;
2561808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        }
2571808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2581808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        @Override
2591808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        protected void publishResults(CharSequence constraint, FilterResults results) {
2601808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            mLocaleOptions = (ArrayList<LocaleStore.LocaleInfo>) results.values;
2611808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2621808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            mSuggestionCount = 0;
2631808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            for (LocaleStore.LocaleInfo li : mLocaleOptions) {
2641808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                if (li.isSuggested()) {
2651808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                    mSuggestionCount++;
2661808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                }
2671808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            }
2681808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2691808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            if (results.count > 0) {
2701808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                notifyDataSetChanged();
2711808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            } else {
2721808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita                notifyDataSetInvalidated();
2731808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita            }
2741808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        }
2751808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
2761808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita
2771808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    @Override
2781808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    public Filter getFilter() {
2791808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita        return new FilterByNativeAndUiNames();
2801808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita    }
2811808ff7cde452d4831dcfbc6b99afc57f66daedfMihai Nita}
282