173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin/*
273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * Copyright (C) 2009 The Android Open Source Project
373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin *
473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * Licensed under the Apache License, Version 2.0 (the "License");
573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * you may not use this file except in compliance with the License.
673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * You may obtain a copy of the License at
773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin *
873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin *      http://www.apache.org/licenses/LICENSE-2.0
973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin *
1073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * Unless required by applicable law or agreed to in writing, software
1173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * distributed under the License is distributed on an "AS IS" BASIS,
1273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * See the License for the specific language governing permissions and
1473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * limitations under the License.
1573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin */
1673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
1773e782de608cbe2ddffd75c055009ff2e208f78bOwen Linpackage com.android.camera;
1873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
1973e782de608cbe2ddffd75c055009ff2e208f78bOwen Linimport android.content.Context;
2073e782de608cbe2ddffd75c055009ff2e208f78bOwen Linimport android.content.SharedPreferences;
2173e782de608cbe2ddffd75c055009ff2e208f78bOwen Linimport android.content.res.TypedArray;
2273e782de608cbe2ddffd75c055009ff2e208f78bOwen Linimport android.util.AttributeSet;
23d456809fe6646db9ed759ecc6457f9280d18f2a6Wu-cheng Liimport android.util.Log;
2460dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Changimport android.util.TypedValue;
2573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
261e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Linimport java.util.ArrayList;
271e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Linimport java.util.List;
281e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin
2973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin/**
3073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * A type of <code>CameraPreference</code> whose number of possible values
3173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin * is limited.
3273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin */
3373e782de608cbe2ddffd75c055009ff2e208f78bOwen Linpublic class ListPreference extends CameraPreference {
34d456809fe6646db9ed759ecc6457f9280d18f2a6Wu-cheng Li    private final String TAG = "ListPreference";
3533be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin    private final String mKey;
3673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    private String mValue;
3760dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang    private final CharSequence[] mDefaultValues;
3873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
3973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    private CharSequence[] mEntries;
4073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    private CharSequence[] mEntryValues;
4173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    private boolean mLoaded = false;
4273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
4373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public ListPreference(Context context, AttributeSet attrs) {
4473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        super(context, attrs);
4573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
4673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        TypedArray a = context.obtainStyledAttributes(
4773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                attrs, R.styleable.ListPreference, 0, 0);
4873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
4973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        mKey = Util.checkNotNull(
5073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                a.getString(R.styleable.ListPreference_key));
5160dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang
5260dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        // We allow the defaultValue attribute to be a string or an array of
5360dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        // strings. The reason we need multiple default values is that some
5460dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        // of them may be unsupported on a specific platform (for example,
5560dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        // continuous auto-focus). In that case the first supported value
5660dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        // in the array will be used.
5760dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        int attrDefaultValue = R.styleable.ListPreference_defaultValue;
5860dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        TypedValue tv = a.peekValue(attrDefaultValue);
5960dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        if (tv != null && tv.type == TypedValue.TYPE_REFERENCE) {
6060dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang            mDefaultValues = a.getTextArray(attrDefaultValue);
6160dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        } else {
6260dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang            mDefaultValues = new CharSequence[1];
6360dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang            mDefaultValues[0] = a.getString(attrDefaultValue);
6460dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        }
6573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
6673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        setEntries(a.getTextArray(R.styleable.ListPreference_entries));
6773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        setEntryValues(a.getTextArray(
6873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin                R.styleable.ListPreference_entryValues));
6973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        a.recycle();
7073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
7173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
7273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public String getKey() {
7373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        return mKey;
7473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
7573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
7673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public CharSequence[] getEntries() {
7773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        return mEntries;
7873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
7973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
8073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public CharSequence[] getEntryValues() {
8173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        return mEntryValues;
8273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
8373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
8473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public void setEntries(CharSequence entries[]) {
8533be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        mEntries = entries == null ? new CharSequence[0] : entries;
8673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
8773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
8873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public void setEntryValues(CharSequence values[]) {
8933be45a1abaf6a8d611fb87b18945c84ab76c229Owen Lin        mEntryValues = values == null ? new CharSequence[0] : values;
9073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
9173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
9273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public String getValue() {
9373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        if (!mLoaded) {
9460dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang            mValue = getSharedPreferences().getString(mKey,
9560dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang                    findSupportedDefaultValue());
9673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            mLoaded = true;
9773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        }
9873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        return mValue;
9973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
10073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
10160dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang    // Find the first value in mDefaultValues which is supported.
10260dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang    private String findSupportedDefaultValue() {
10360dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        for (int i = 0; i < mDefaultValues.length; i++) {
10460dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang            for (int j = 0; j < mEntryValues.length; j++) {
10560dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang                // Note that mDefaultValues[i] may be null (if unspecified
10660dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang                // in the xml file).
10760dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang                if (mEntryValues[j].equals(mDefaultValues[i])) {
10860dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang                    return mDefaultValues[i].toString();
10960dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang                }
11060dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang            }
11160dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        }
11260dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang        return null;
11360dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang    }
11460dc073ff3087af41f9cf3b738eaa74bb2212f95Chih-Chung Chang
11573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public void setValue(String value) {
11673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        if (findIndexOfValue(value) < 0) throw new IllegalArgumentException();
11773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        mValue = value;
11873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        persistStringValue(value);
11973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
12073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
12173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public void setValueIndex(int index) {
12273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        setValue(mEntryValues[index].toString());
12373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
12473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
12573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public int findIndexOfValue(String value) {
12673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        for (int i = 0, n = mEntryValues.length; i < n; ++i) {
12773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin            if (Util.equals(mEntryValues[i], value)) return i;
12873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        }
12973e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        return -1;
13073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
13173e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
13273e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    public String getEntry() {
13373e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        return mEntries[findIndexOfValue(getValue())].toString();
13473e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
13573e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin
13673e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    protected void persistStringValue(String value) {
13773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        SharedPreferences.Editor editor = getSharedPreferences().edit();
13873e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin        editor.putString(mKey, value);
1394e5aa452a0e2438f9af1f08c56b1a7b414e561d9Brad Fitzpatrick        editor.apply();
14073e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin    }
14152064aa4bacfae605823b99f675649b1786e8c8aOwen Lin
14252064aa4bacfae605823b99f675649b1786e8c8aOwen Lin    @Override
14352064aa4bacfae605823b99f675649b1786e8c8aOwen Lin    public void reloadValue() {
14452064aa4bacfae605823b99f675649b1786e8c8aOwen Lin        this.mLoaded = false;
14552064aa4bacfae605823b99f675649b1786e8c8aOwen Lin    }
1461e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin
1471e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin    public void filterUnsupported(List<String> supported) {
1481e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin        ArrayList<CharSequence> entries = new ArrayList<CharSequence>();
1491e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin        ArrayList<CharSequence> entryValues = new ArrayList<CharSequence>();
1501e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin        for (int i = 0, len = mEntryValues.length; i < len; i++) {
1511e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin            if (supported.indexOf(mEntryValues[i].toString()) >= 0) {
1521e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin                entries.add(mEntries[i]);
1531e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin                entryValues.add(mEntryValues[i]);
1541e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin            }
1551e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin        }
1561e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin        int size = entries.size();
1571e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin        mEntries = entries.toArray(new CharSequence[size]);
1581e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin        mEntryValues = entryValues.toArray(new CharSequence[size]);
1591e7d70c59c3547db7589c1cae977e98d9b4e95b9Owen Lin    }
160d456809fe6646db9ed759ecc6457f9280d18f2a6Wu-cheng Li
161d456809fe6646db9ed759ecc6457f9280d18f2a6Wu-cheng Li    public void print() {
162d456809fe6646db9ed759ecc6457f9280d18f2a6Wu-cheng Li        Log.v(TAG, "Preference key=" + getKey() + ". value=" + getValue());
163d456809fe6646db9ed759ecc6457f9280d18f2a6Wu-cheng Li        for (int i = 0; i < mEntryValues.length; i++) {
164d456809fe6646db9ed759ecc6457f9280d18f2a6Wu-cheng Li            Log.v(TAG, "entryValues[" + i + "]=" + mEntryValues[i]);
165d456809fe6646db9ed759ecc6457f9280d18f2a6Wu-cheng Li        }
166d456809fe6646db9ed759ecc6457f9280d18f2a6Wu-cheng Li    }
16773e782de608cbe2ddffd75c055009ff2e208f78bOwen Lin}
168