WordListPreference.java revision a2ec5e8338c82f1e49c3d98f502dcc30c9c12fb0
10cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard/**
20cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * Copyright (C) 2011 The Android Open Source Project
30cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard *
40cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * Licensed under the Apache License, Version 2.0 (the "License"); you may not
50cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * use this file except in compliance with the License. You may obtain a copy
60cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * of the License at
70cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard *
80cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * http://www.apache.org/licenses/LICENSE-2.0
90cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard *
100cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * Unless required by applicable law or agreed to in writing, software
110cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
120cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
130cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * License for the specific language governing permissions and limitations
140cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * under the License.
150cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard */
160cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
170cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardpackage com.android.inputmethod.dictionarypack;
180cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
190cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardimport android.content.Context;
200cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardimport android.content.SharedPreferences;
2141f505dc3e6ba7aa850e0c4dbe2d6093ddd6fc2dJean Chalardimport android.preference.Preference;
220cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardimport android.util.Log;
230cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardimport android.view.View;
240cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardimport android.view.ViewGroup;
25f8014eea341040f8d155e071e4e0c915a7ebd61dJean Chalardimport android.view.ViewParent;
26f8014eea341040f8d155e071e4e0c915a7ebd61dJean Chalardimport android.widget.ListView;
27ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalardimport android.widget.TextView;
280cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
290cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardimport com.android.inputmethod.latin.R;
300cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
310cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardimport java.util.Locale;
320cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
330cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard/**
340cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * A preference for one word list.
350cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard *
360cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * This preference refers to a single word list, as available in the dictionary
370cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * pack. Upon being pressed, it displays a menu to allow the user to install, disable,
380cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * enable or delete it as appropriate for the current state of the word list.
390cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard */
4041f505dc3e6ba7aa850e0c4dbe2d6093ddd6fc2dJean Chalardpublic final class WordListPreference extends Preference {
410cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    static final private String TAG = WordListPreference.class.getSimpleName();
420cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
430cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // What to display in the "status" field when we receive unknown data as a status from
440cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // the content provider. Empty string sounds sensible.
450cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    static final private String NO_STATUS_MESSAGE = "";
460cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
470cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    /// Actions
480cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    static final private int ACTION_UNKNOWN = 0;
490cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    static final private int ACTION_ENABLE_DICT = 1;
500cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    static final private int ACTION_DISABLE_DICT = 2;
510cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    static final private int ACTION_DELETE_DICT = 3;
520cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
530cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // Members
540cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // The context to get resources
550cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    final Context mContext;
560cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // The id of the client for which this preference is.
570cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    final String mClientId;
580cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // The metadata word list id and version of this word list.
590cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    public final String mWordlistId;
600cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    public final int mVersion;
61a2ec5e8338c82f1e49c3d98f502dcc30c9c12fb0Jean Chalard    public final Locale mLocale;
62a2ec5e8338c82f1e49c3d98f502dcc30c9c12fb0Jean Chalard    public final String mDescription;
630cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // The status
640cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    public int mStatus;
65ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard    // The size of the dictionary file
66ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard    private final int mFilesize;
670cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
68c017f18a59a6b0ba1905a67193057b5b70410e06Jean Chalard    private final DictionaryListInterfaceState mInterfaceState;
690cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private final OnWordListPreferenceClick mPreferenceClickHandler =
700cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            new OnWordListPreferenceClick();
710cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private final OnActionButtonClick mActionButtonClickHandler =
720cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            new OnActionButtonClick();
730cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
74c017f18a59a6b0ba1905a67193057b5b70410e06Jean Chalard    public WordListPreference(final Context context,
75c017f18a59a6b0ba1905a67193057b5b70410e06Jean Chalard            final DictionaryListInterfaceState dictionaryListInterfaceState, final String clientId,
76c017f18a59a6b0ba1905a67193057b5b70410e06Jean Chalard            final String wordlistId, final int version, final Locale locale,
77ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard            final String description, final int status, final int filesize) {
780cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        super(context, null);
790cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        mContext = context;
80c017f18a59a6b0ba1905a67193057b5b70410e06Jean Chalard        mInterfaceState = dictionaryListInterfaceState;
810cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        mClientId = clientId;
820cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        mVersion = version;
830cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        mWordlistId = wordlistId;
84ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard        mFilesize = filesize;
85a2ec5e8338c82f1e49c3d98f502dcc30c9c12fb0Jean Chalard        mLocale = locale;
86a2ec5e8338c82f1e49c3d98f502dcc30c9c12fb0Jean Chalard        mDescription = description;
870cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
880cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        setLayoutResource(R.layout.dictionary_line);
890cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
900cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        setTitle(description);
910cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        setStatus(status);
920cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        setKey(wordlistId);
930cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
940cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
950cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private void setStatus(final int status) {
960cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        if (status == mStatus) return;
970cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        mStatus = status;
980cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        setSummary(getSummary(status));
990cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
1000cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1010cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private String getSummary(final int status) {
1020cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        switch (status) {
1030cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // If we are deleting the word list, for the user it's like it's already deleted.
1040cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // It should be reinstallable. Exposing to the user the whole complexity of
1050cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // the delayed deletion process between the dictionary pack and Android Keyboard
1060cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // would only be confusing.
1070cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            case MetadataDbHelper.STATUS_DELETING:
1080cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            case MetadataDbHelper.STATUS_AVAILABLE:
1090cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                return mContext.getString(R.string.dictionary_available);
1100cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            case MetadataDbHelper.STATUS_DOWNLOADING:
1110cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                return mContext.getString(R.string.dictionary_downloading);
1120cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            case MetadataDbHelper.STATUS_INSTALLED:
1130cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                return mContext.getString(R.string.dictionary_installed);
1140cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            case MetadataDbHelper.STATUS_DISABLED:
1150cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                return mContext.getString(R.string.dictionary_disabled);
1160cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            default:
1170cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                return NO_STATUS_MESSAGE;
1180cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        }
1190cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
1200cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1212d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard    // The table below needs to be kept in sync with MetadataDbHelper.STATUS_* since it uses
1222d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard    // the values as indices.
1230cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private static final int sStatusActionList[][] = {
1240cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // MetadataDbHelper.STATUS_UNKNOWN
1250cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        {},
1260cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // MetadataDbHelper.STATUS_AVAILABLE
1272d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard        { ButtonSwitcher.STATUS_INSTALL, ACTION_ENABLE_DICT },
1280cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // MetadataDbHelper.STATUS_DOWNLOADING
1292d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard        { ButtonSwitcher.STATUS_CANCEL, ACTION_DISABLE_DICT },
1300cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // MetadataDbHelper.STATUS_INSTALLED
1312d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard        { ButtonSwitcher.STATUS_DELETE, ACTION_DELETE_DICT },
1320cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // MetadataDbHelper.STATUS_DISABLED
1332d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard        { ButtonSwitcher.STATUS_DELETE, ACTION_DELETE_DICT },
1340cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // MetadataDbHelper.STATUS_DELETING
1350cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // We show 'install' because the file is supposed to be deleted.
1360cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // The user may reinstall it.
1372d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard        { ButtonSwitcher.STATUS_INSTALL, ACTION_ENABLE_DICT }
1380cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    };
1390cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1402d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard    private int getButtonSwitcherStatus(final int status) {
1410cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        if (status >= sStatusActionList.length) {
1420cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            Log.e(TAG, "Unknown status " + status);
1432d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard            return ButtonSwitcher.STATUS_NO_BUTTON;
1440cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        }
1452d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard        return sStatusActionList[status][0];
1460cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
1470cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1480cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private static int getActionIdFromStatusAndMenuEntry(final int status) {
1490cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        if (status >= sStatusActionList.length) {
1500cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            Log.e(TAG, "Unknown status " + status);
1510cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            return ACTION_UNKNOWN;
1520cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        }
1530cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        return sStatusActionList[status][1];
1540cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
1550cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1560cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private void disableDict() {
1570cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        SharedPreferences prefs = CommonPreferences.getCommonPreferences(mContext);
1580cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        CommonPreferences.disable(prefs, mWordlistId);
1590cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        UpdateHandler.markAsUnused(mContext, mClientId, mWordlistId, mVersion, mStatus);
1600cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        if (MetadataDbHelper.STATUS_DOWNLOADING == mStatus) {
1610cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            setStatus(MetadataDbHelper.STATUS_AVAILABLE);
1620cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        } else if (MetadataDbHelper.STATUS_INSTALLED == mStatus) {
1630cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // Interface-wise, we should no longer be able to come here. However, this is still
1640cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // the right thing to do if we do come here.
1650cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            setStatus(MetadataDbHelper.STATUS_DISABLED);
1660cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        } else {
1670cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            Log.e(TAG, "Unexpected state of the word list for disabling " + mStatus);
1680cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        }
1690cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
1700cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private void enableDict() {
1710cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        SharedPreferences prefs = CommonPreferences.getCommonPreferences(mContext);
1720cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        CommonPreferences.enable(prefs, mWordlistId);
1730cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // Explicit enabling by the user : allow downloading on metered data connection.
1740cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        UpdateHandler.markAsUsed(mContext, mClientId, mWordlistId, mVersion, mStatus, true);
1750cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        if (MetadataDbHelper.STATUS_AVAILABLE == mStatus) {
1760cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            setStatus(MetadataDbHelper.STATUS_DOWNLOADING);
1770cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        } else if (MetadataDbHelper.STATUS_DISABLED == mStatus
1780cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                || MetadataDbHelper.STATUS_DELETING == mStatus) {
1790cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // If the status is DELETING, it means Android Keyboard
1800cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // has not deleted the word list yet, so we can safely
1810cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // turn it to 'installed'. The status DISABLED is still supported internally to
1820cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // avoid breaking older installations and all but there should not be a way to
1830cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            // disable a word list through the interface any more.
1840cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            setStatus(MetadataDbHelper.STATUS_INSTALLED);
1850cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        } else {
1860cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            Log.e(TAG, "Unexpected state of the word list for enabling " + mStatus);
1870cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        }
1880cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
1890cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private void deleteDict() {
1900cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        SharedPreferences prefs = CommonPreferences.getCommonPreferences(mContext);
1910cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        CommonPreferences.disable(prefs, mWordlistId);
1920cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        setStatus(MetadataDbHelper.STATUS_DELETING);
1930cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        UpdateHandler.markAsDeleting(mContext, mClientId, mWordlistId, mVersion, mStatus);
1940cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
1950cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1960cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    @Override
1970cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    protected void onBindView(final View view) {
1980cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        super.onBindView(view);
1990cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        ((ViewGroup)view).setLayoutTransition(null);
200ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard
201d282ebfb71ff5bdb855508b7b546dba786d7d85aJean Chalard        final DictionaryDownloadProgressBar progressBar =
202d282ebfb71ff5bdb855508b7b546dba786d7d85aJean Chalard                (DictionaryDownloadProgressBar)view.findViewById(R.id.dictionary_line_progress_bar);
203ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard        final TextView status = (TextView)view.findViewById(android.R.id.summary);
204d282ebfb71ff5bdb855508b7b546dba786d7d85aJean Chalard        progressBar.setIds(mClientId, mWordlistId);
205ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard        progressBar.setMax(mFilesize);
206ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard        final boolean showProgressBar = (MetadataDbHelper.STATUS_DOWNLOADING == mStatus);
207ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard        status.setVisibility(showProgressBar ? View.INVISIBLE : View.VISIBLE);
208ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard        progressBar.setVisibility(showProgressBar ? View.VISIBLE : View.INVISIBLE);
209ab0c66b9d1f732a0dc372abd6d113d2cac33b8acJean Chalard
2102cf450f48283bcf1452cb717b7ae3a9f0c729105Jean Chalard        final ButtonSwitcher buttonSwitcher =
2112cf450f48283bcf1452cb717b7ae3a9f0c729105Jean Chalard                (ButtonSwitcher)view.findViewById(R.id.wordlist_button_switcher);
212513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard        if (mInterfaceState.isOpen(mWordlistId)) {
213513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard            // The button is open.
214513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard            final int previousStatus = mInterfaceState.getStatus(mWordlistId);
215513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard            buttonSwitcher.setStatusAndUpdateVisuals(getButtonSwitcherStatus(previousStatus));
216513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard            if (previousStatus != mStatus) {
217513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard                // We come here if the status has changed since last time. We need to animate
218513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard                // the transition.
219513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard                buttonSwitcher.setStatusAndUpdateVisuals(getButtonSwitcherStatus(mStatus));
220513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard                mInterfaceState.setOpen(mWordlistId, mStatus);
221513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard            }
222513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard        } else {
223513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard            // The button is closed.
224513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard            buttonSwitcher.setStatusAndUpdateVisuals(ButtonSwitcher.STATUS_NO_BUTTON);
225513c63e877320bca4860dadc88e3a14ffb861e36Jean Chalard        }
2262cf450f48283bcf1452cb717b7ae3a9f0c729105Jean Chalard        buttonSwitcher.setInternalOnClickListener(mActionButtonClickHandler);
2270cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        view.setOnClickListener(mPreferenceClickHandler);
2280cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
2290cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
2300cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private class OnWordListPreferenceClick implements View.OnClickListener {
2310cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        @Override
2320cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        public void onClick(final View v) {
23343e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard            // Note : v is the preference view
234f8014eea341040f8d155e071e4e0c915a7ebd61dJean Chalard            final ViewParent parent = v.getParent();
235f8014eea341040f8d155e071e4e0c915a7ebd61dJean Chalard            // Just in case something changed in the framework, test for the concrete class
236f8014eea341040f8d155e071e4e0c915a7ebd61dJean Chalard            if (!(parent instanceof ListView)) return;
237f8014eea341040f8d155e071e4e0c915a7ebd61dJean Chalard            final ListView listView = (ListView)parent;
23843e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard            final int indexToOpen;
239cadea5d2fcd624501682d3ec3e1c67e9dcb989d1Jean Chalard            // Close all first, we'll open back any item that needs to be open.
240d4fc13d261c77b3ccf6847e69d28cb2da583fd5cJean Chalard            final boolean wasOpen = mInterfaceState.isOpen(mWordlistId);
241cadea5d2fcd624501682d3ec3e1c67e9dcb989d1Jean Chalard            mInterfaceState.closeAll();
242d4fc13d261c77b3ccf6847e69d28cb2da583fd5cJean Chalard            if (wasOpen) {
243cadea5d2fcd624501682d3ec3e1c67e9dcb989d1Jean Chalard                // This button being shown. Take note that we don't want to open any button in the
244cadea5d2fcd624501682d3ec3e1c67e9dcb989d1Jean Chalard                // loop below.
24543e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard                indexToOpen = -1;
246d98f406dd31c9f72ba3273b10b521a1a77136ac3Jean Chalard            } else {
247cadea5d2fcd624501682d3ec3e1c67e9dcb989d1Jean Chalard                // This button was not being shown. Open it, and remember the index of this
248cadea5d2fcd624501682d3ec3e1c67e9dcb989d1Jean Chalard                // child as the one to open in the following loop.
249cadea5d2fcd624501682d3ec3e1c67e9dcb989d1Jean Chalard                mInterfaceState.setOpen(mWordlistId, mStatus);
25043e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard                indexToOpen = listView.indexOfChild(v);
25143e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard            }
25243e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard            final int lastDisplayedIndex =
25343e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard                    listView.getLastVisiblePosition() - listView.getFirstVisiblePosition();
25443e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard            // The "lastDisplayedIndex" is actually displayed, hence the <=
25543e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard            for (int i = 0; i <= lastDisplayedIndex; ++i) {
2562cf450f48283bcf1452cb717b7ae3a9f0c729105Jean Chalard                final ButtonSwitcher buttonSwitcher = (ButtonSwitcher)listView.getChildAt(i)
2572cf450f48283bcf1452cb717b7ae3a9f0c729105Jean Chalard                        .findViewById(R.id.wordlist_button_switcher);
25843e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard                if (i == indexToOpen) {
2592d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard                    buttonSwitcher.setStatusAndUpdateVisuals(getButtonSwitcherStatus(mStatus));
26043e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard                } else {
2612d72590ced449e1ba0065bf63c311dae805c8290Jean Chalard                    buttonSwitcher.setStatusAndUpdateVisuals(ButtonSwitcher.STATUS_NO_BUTTON);
26243e8639e4e39defa2c6e5b0743a74cdb572adb2bJean Chalard                }
263d98f406dd31c9f72ba3273b10b521a1a77136ac3Jean Chalard            }
264f8014eea341040f8d155e071e4e0c915a7ebd61dJean Chalard        }
265f8014eea341040f8d155e071e4e0c915a7ebd61dJean Chalard    }
266f8014eea341040f8d155e071e4e0c915a7ebd61dJean Chalard
2670cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    private class OnActionButtonClick implements View.OnClickListener {
2680cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        @Override
2690cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        public void onClick(final View v) {
2700cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            switch (getActionIdFromStatusAndMenuEntry(mStatus)) {
2710cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            case ACTION_ENABLE_DICT:
2720cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                enableDict();
2730cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                break;
2740cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            case ACTION_DISABLE_DICT:
2750cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                disableDict();
2760cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                break;
2770cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            case ACTION_DELETE_DICT:
2780cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                deleteDict();
2790cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                break;
2800cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            default:
2810cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                Log.e(TAG, "Unknown menu item pressed");
2820cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            }
2830cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        }
2840cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
2850cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard}
286