/ime/latinime/src/com/googlecode/eyesfree/inputmethod/KeyCodeDescriptionMapper.java
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}