PageRenderTime 40ms CodeModel.GetById 1ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 1ms

/ime/latinime/src/com/googlecode/eyesfree/inputmethod/KeyCodeDescriptionMapper.java

http://eyes-free.googlecode.com/
Java | 191 lines | 100 code | 26 blank | 65 comment | 22 complexity | d35531a67dc11752484293c072bc890b MD5 | raw file
  1/*
  2 * Copyright (C) 2011 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.googlecode.eyesfree.inputmethod;
 18
 19import android.content.Context;
 20import android.content.res.Resources;
 21import android.inputmethodservice.Keyboard.Key;
 22import android.text.TextUtils;
 23
 24import com.googlecode.eyesfree.inputmethod.latin.KeyboardSwitcher;
 25import com.googlecode.eyesfree.inputmethod.latin.LatinKeyboardView;
 26import com.googlecode.eyesfree.inputmethod.latin.R;
 27
 28import java.util.HashMap;
 29
 30public class KeyCodeDescriptionMapper {
 31    private static KeyCodeDescriptionMapper sInstance;
 32
 33    public static KeyCodeDescriptionMapper getInstance(Context context) {
 34        if (sInstance == null) {
 35            sInstance = new KeyCodeDescriptionMapper(context);
 36        }
 37
 38        return sInstance;
 39    }
 40
 41    // Map of key labels to spoken description resource IDs
 42    private final HashMap<CharSequence, Integer> mKeyLabelMap;
 43
 44    // Map of key codes to spoken description resource IDs
 45    private final HashMap<Integer, Integer> mKeyCodeMap;
 46
 47    // Map of shifted key codes to spoken description resource IDs
 48    private final HashMap<Integer, Integer> mShiftedKeyCodeMap;
 49
 50    // Map of shift-locked key codes to spoken description resource IDs
 51    private final HashMap<Integer, Integer> mShiftLockedKeyCodeMap;
 52
 53    private KeyCodeDescriptionMapper(Context context) {
 54        final Resources res = context.getResources();
 55
 56        mKeyLabelMap = new HashMap<CharSequence, Integer>();
 57        mKeyCodeMap = new HashMap<Integer, Integer>();
 58        mShiftedKeyCodeMap = new HashMap<Integer, Integer>();
 59        mShiftLockedKeyCodeMap = new HashMap<Integer, Integer>();
 60
 61        // Label substitutions for when the key label should not be spoken
 62        mKeyLabelMap.put(res.getText(R.string.label_alpha_key),
 63                R.string.spoken_description_to_alpha);
 64        mKeyLabelMap.put(res.getText(R.string.label_symbol_key),
 65                R.string.spoken_description_to_symbol);
 66        mKeyLabelMap.put(res.getText(R.string.label_phone_key),
 67                R.string.spoken_description_to_numeric);
 68
 69        // Manual label substitutions for key labels with no string resource
 70        mKeyLabelMap.put(":-)", R.string.spoken_description_smiley);
 71
 72        // Symbols that most TTS engines can't speak
 73        mKeyCodeMap.put((int) '.', R.string.spoken_description_period);
 74        mKeyCodeMap.put((int) ',', R.string.spoken_description_comma);
 75        mKeyCodeMap.put((int) '(', R.string.spoken_description_left_parenthesis);
 76        mKeyCodeMap.put((int) ')', R.string.spoken_description_right_parenthesis);
 77        mKeyCodeMap.put((int) ':', R.string.spoken_description_colon);
 78        mKeyCodeMap.put((int) ';', R.string.spoken_description_semicolon);
 79        mKeyCodeMap.put((int) '!', R.string.spoken_description_exclamation_mark);
 80        mKeyCodeMap.put((int) '?', R.string.spoken_description_question_mark);
 81        mKeyCodeMap.put((int) '\"', R.string.spoken_description_double_quote);
 82        mKeyCodeMap.put((int) '\'', R.string.spoken_description_single_quote);
 83        mKeyCodeMap.put((int) '*', R.string.spoken_description_star);
 84        mKeyCodeMap.put((int) '#', R.string.spoken_description_pound);
 85        mKeyCodeMap.put((int) ' ', R.string.spoken_description_space);
 86
 87        // Non-ASCII symbols (must use escape codes!)
 88        mKeyCodeMap.put((int) '\u2022', R.string.spoken_description_dot);
 89        mKeyCodeMap.put((int) '\u221A', R.string.spoken_description_square_root);
 90        mKeyCodeMap.put((int) '\u03C0', R.string.spoken_description_pi);
 91        mKeyCodeMap.put((int) '\u0394', R.string.spoken_description_delta);
 92        mKeyCodeMap.put((int) '\u2122', R.string.spoken_description_trademark);
 93        mKeyCodeMap.put((int) '\u2105', R.string.spoken_description_care_of);
 94        mKeyCodeMap.put((int) '\u2026', R.string.spoken_description_ellipsis);
 95        mKeyCodeMap.put((int) '\u201E', R.string.spoken_description_low_double_quote);
 96
 97        // Special non-character codes defined in Keyboard
 98        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_DELETE, R.string.spoken_description_delete);
 99        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_RETURN, R.string.spoken_description_return);
100        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_OPTIONS, R.string.spoken_description_settings);
101        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_SHIFT, R.string.spoken_description_shift);
102        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_VOICE, R.string.spoken_description_mic);
103        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_TAB, R.string.spoken_description_tab);
104
105        // Additional TalkBack-specific keys
106        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_BACK, R.string.spoken_description_back);
107        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_HOME, R.string.spoken_description_home);
108        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_SEARCH, R.string.spoken_description_search);
109        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_MENU, R.string.spoken_description_menu);
110        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_CALL, R.string.spoken_description_call);
111        mKeyCodeMap.put(LatinKeyboardView.KEYCODE_ENDCALL, R.string.spoken_description_end_call);
112
113        // Shifted versions of non-character codes defined in LatinKeyboardView
114        mShiftedKeyCodeMap.put(LatinKeyboardView.KEYCODE_SHIFT, R.string.spoken_description_shift_shifted);
115
116        // Shift-locked versions of non-character codes defined in LatinKeyboardView
117        mShiftLockedKeyCodeMap.put(LatinKeyboardView.KEYCODE_SHIFT, R.string.spoken_description_caps_lock);
118    }
119
120    /**
121     * Returns the description of the action performed by a specified key based
122     * on the current keyboard state.
123     * <p>
124     * The order of precedence for key descriptions is:
125     * <ol>
126     * <li>Manually-defined based on the key label</li>
127     * <li>Automatic or manually-defined based on the key code</li>
128     * <li>Automatically based on the key label</li>
129     * <li>{code null} for keys with no label or key code defined</li>
130     * </p>
131     *
132     * @param res The package's resources.
133     * @param switcher The keyboard switcher for the keyboard on which the key resides.
134     * @param key The key from which to obtain a description.
135     * @return a character sequence describing the action performed by pressing
136     *         the key
137     */
138    public CharSequence getDescriptionForKey(Resources res, KeyboardSwitcher switcher, Key key) {
139        if (!TextUtils.isEmpty(key.label)) {
140            final String label = key.label.toString().trim();
141
142            if (mKeyLabelMap.containsKey(label)) {
143                return res.getText(mKeyLabelMap.get(label));
144            } else if (label.length() == 1) {
145                return getDescriptionForKeyCode(res, switcher, key);
146            } else {
147                return label;
148            }
149        } else if (key.codes != null) {
150            return getDescriptionForKeyCode(res, switcher, key);
151        }
152
153        return null;
154    }
155
156    /**
157     * Returns a character sequence describing what will happen when the
158     * specified key is pressed based on its key code.
159     * <p>
160     * The order of precedence for key code descriptions is:
161     * <ol>
162     * <li>Manually-defined shift-locked description</li>
163     * <li>Manually-defined shifted description</li>
164     * <li>Manually-defined normal description</li>
165     * <li>Automatic based on the character represented by the key code</li>
166     * <li>Fall-back for undefined or control characters</li>
167     * </ol>
168     * </p>
169     *
170     * @param res The package's resources.
171     * @param switcher The keyboard switcher for the keyboard on which the key resides.
172     * @param key The key from which to obtain a description.
173     * @return a character sequence describing the action performed by pressing
174     *         the key
175     */
176    private CharSequence getDescriptionForKeyCode(Resources res, KeyboardSwitcher switcher, Key key) {
177        final int code = key.codes[0];
178
179        if (switcher.isShiftLocked() && mShiftLockedKeyCodeMap.containsKey(code)) {
180            return res.getText(mShiftLockedKeyCodeMap.get(code));
181        } else if (switcher.isShiftedOrShiftLocked() && mShiftedKeyCodeMap.containsKey(code)) {
182            return res.getText(mShiftedKeyCodeMap.get(code));
183        } else if (mKeyCodeMap.containsKey(code)) {
184            return res.getText(mKeyCodeMap.get(code));
185        } else if (Character.isDefined(code) && !Character.isISOControl(code)) {
186            return Character.toString((char) code);
187        } else {
188            return res.getString(R.string.spoken_description_unknown, code);
189        }
190    }
191}