diff options
-rw-r--r-- | AndroidManifest.xml | 13 | ||||
-rw-r--r-- | res/values/strings.xml | 6 | ||||
-rw-r--r-- | res/xml/language_settings.xml | 7 | ||||
-rw-r--r-- | src/com/android/settings/Settings.java | 1 | ||||
-rw-r--r-- | src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java | 153 | ||||
-rw-r--r-- | src/com/android/settings/inputmethod/KeyboardLayoutPicker.java | 131 |
6 files changed, 264 insertions, 47 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index fea3b01..8a54d3e 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -396,6 +396,19 @@ android:resource="@id/language_settings" /> </activity> + <activity android:name="Settings$KeyboardLayoutPickerActivity" + android:label="@string/keyboard_layout_picker_title" + android:clearTaskOnLaunch="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <meta-data android:name="com.android.settings.FRAGMENT_CLASS" + android:value="com.android.settings.inputmethod.KeyboardLayoutPicker" /> + <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID" + android:resource="@id/language_settings" /> + </activity> + <!-- Keep compatibility with old shortcuts. --> <activity-alias android:name="LanguageSettings" android:label="@string/language_keyboard_settings_title" diff --git a/res/values/strings.xml b/res/values/strings.xml index d080d59..9569dfb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2614,6 +2614,12 @@ <!-- On Language & input settings screen, setting summary. Setting for mouse pointer speed. [CHAR LIMIT=35] --> <string name="pointer_speed">Pointer speed</string> + <!-- Keyboard Layout Picker --> <skip /> + <!-- Title for the keyboard layout picker activity. [CHAR LIMIT=35] --> + <string name="keyboard_layout_picker_title">Choose keyboard layout</string> + <!-- String to show when no keyboard layouts are available. [CHAR LIMIT=60] --> + <string name="keyboard_layout_picker_empty_text">No keyboard layouts are available.</string> + <!-- User dictionary settings --><skip /> <!-- User dictionary settings, The titlebar text of the User dictionary settings screen. --> <string name="user_dict_settings_titlebar">User dictionary</string> diff --git a/res/xml/language_settings.xml b/res/xml/language_settings.xml index fbfb3d7..cfcc341 100644 --- a/res/xml/language_settings.xml +++ b/res/xml/language_settings.xml @@ -36,27 +36,34 @@ <PreferenceScreen android:key="current_input_method" android:title="@string/current_input_method" /> </PreferenceCategory> + <PreferenceCategory android:key="hard_keyboard" android:title="@string/builtin_keyboard_settings_title" android:persistent="false"> + <!-- Additional preference screens are inserted here programmatically + with low order values to set the key map of each attached keyboard. --> + <CheckBoxPreference android:key="auto_replace" android:title="@string/auto_replace" android:summaryOn="@string/auto_replace_summary" android:summaryOff="@string/auto_replace_summary" + android:order="1000" android:persistent="false"/> <CheckBoxPreference android:key="auto_caps" android:title="@string/auto_caps" android:summaryOn="@string/auto_caps_summary" android:summaryOff="@string/auto_caps_summary" + android:order="1001" android:persistent="false"/> <CheckBoxPreference android:key="auto_punctuate" android:title="@string/auto_punctuate" android:summaryOn="@string/auto_punctuate_summary" android:summaryOff="@string/auto_punctuate_summary" + android:order="1002" android:persistent="false"/> </PreferenceCategory> diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index 3513dcc..9d00024 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -609,6 +609,7 @@ public class Settings extends PreferenceActivity implements ButtonBarHandler { public static class WifiSettingsActivity extends Settings { /* empty */ } public static class WifiP2pSettingsActivity extends Settings { /* empty */ } public static class InputMethodAndLanguageSettingsActivity extends Settings { /* empty */ } + public static class KeyboardLayoutPickerActivity extends Settings { /* empty */ } public static class InputMethodAndSubtypeEnablerActivity extends Settings { /* empty */ } public static class SpellCheckersSettingsActivity extends Settings { /* empty */ } public static class LocalePickerActivity extends Settings { /* empty */ } diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java index 4454389..cc2cf0a 100644 --- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java +++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java @@ -17,6 +17,7 @@ package com.android.settings.inputmethod; import com.android.settings.R; +import com.android.settings.Settings.KeyboardLayoutPickerActivity; import com.android.settings.Settings.SpellCheckersSettingsActivity; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; @@ -29,6 +30,8 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.database.ContentObserver; +import android.hardware.input.InputManager; +import android.hardware.input.InputManager.KeyboardLayout; import android.os.Bundle; import android.os.Handler; import android.preference.CheckBoxPreference; @@ -40,11 +43,15 @@ import android.preference.PreferenceScreen; import android.provider.Settings; import android.provider.Settings.System; import android.text.TextUtils; +import android.view.InputDevice; +import android.view.KeyCharacterMap; +import android.view.KeyCharacterMap.UnavailableException; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Set; @@ -68,11 +75,13 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment private int mDefaultInputMethodSelectorVisibility = 0; private ListPreference mShowInputMethodSelectorPref; + private PreferenceCategory mKeyboardSettingsCategory; + private PreferenceCategory mHardKeyboardCategory; private Preference mLanguagePref; - private ArrayList<InputMethodPreference> mInputMethodPreferenceList = + private final ArrayList<InputMethodPreference> mInputMethodPreferenceList = new ArrayList<InputMethodPreference>(); - private boolean mHaveHardKeyboard; - private PreferenceCategory mHardKeyboardCategory; + private final ArrayList<PreferenceScreen> mHardKeyboardPreferenceList = + new ArrayList<PreferenceScreen>(); private InputMethodManager mImm; private List<InputMethodInfo> mImis; private boolean mIsOnlyImeSettings; @@ -108,18 +117,55 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment new VoiceInputOutputSettings(this).onCreate(); - // Hard keyboard - final Configuration config = getResources().getConfiguration(); - mHaveHardKeyboard = (config.keyboard == Configuration.KEYBOARD_QWERTY); + // Get references to dynamically constructed categories. + mHardKeyboardCategory = (PreferenceCategory)findPreference("hard_keyboard"); + mKeyboardSettingsCategory = (PreferenceCategory)findPreference( + "keyboard_settings_category"); - // IME + // Filter out irrelevant features if invoked from IME settings button. mIsOnlyImeSettings = Settings.ACTION_INPUT_METHOD_SETTINGS.equals( getActivity().getIntent().getAction()); getActivity().getIntent().setAction(null); + if (mIsOnlyImeSettings) { + getPreferenceScreen().removeAll(); + getPreferenceScreen().addPreference(mHardKeyboardCategory); + if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) { + getPreferenceScreen().addPreference(mShowInputMethodSelectorPref); + } + getPreferenceScreen().addPreference(mKeyboardSettingsCategory); + } + + // Build IME preference category. mImm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); mImis = mImm.getInputMethodList(); - createImePreferenceHierarchy((PreferenceGroup)findPreference("keyboard_settings_category")); + mKeyboardSettingsCategory.removeAll(); + if (!mIsOnlyImeSettings) { + final PreferenceScreen currentIme = new PreferenceScreen(getActivity(), null); + currentIme.setKey(KEY_CURRENT_INPUT_METHOD); + currentIme.setTitle(getResources().getString(R.string.current_input_method)); + mKeyboardSettingsCategory.addPreference(currentIme); + } + + mInputMethodPreferenceList.clear(); + final int N = (mImis == null ? 0 : mImis.size()); + for (int i = 0; i < N; ++i) { + final InputMethodInfo imi = mImis.get(i); + final InputMethodPreference pref = getInputMethodPreference(imi, N); + mInputMethodPreferenceList.add(pref); + } + + if (!mInputMethodPreferenceList.isEmpty()) { + Collections.sort(mInputMethodPreferenceList); + for (int i = 0; i < N; ++i) { + mKeyboardSettingsCategory.addPreference(mInputMethodPreferenceList.get(i)); + } + } + + // Build hard keyboard preference category. + updateHardKeyboards(); + + // Spell Checker final Intent intent = new Intent(Intent.ACTION_MAIN); intent.setClass(getActivity(), SpellCheckersSettingsActivity.class); final SpellCheckersPreference scp = ((SpellCheckersPreference)findPreference( @@ -189,7 +235,7 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment } // Hard keyboard - if (mHaveHardKeyboard) { + if (!mHardKeyboardPreferenceList.isEmpty()) { for (int i = 0; i < sHardKeyboardKeys.length; ++i) { CheckBoxPreference chkPref = (CheckBoxPreference) mHardKeyboardCategory.findPreference(sHardKeyboardKeys[i]); @@ -198,6 +244,8 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment } } + updateHardKeyboards(); + // IME InputMethodAndSubtypeUtil.loadInputMethodSubtypeList( this, getContentResolver(), mImis, null); @@ -211,7 +259,7 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment mShowInputMethodSelectorPref.setOnPreferenceChangeListener(null); } InputMethodAndSubtypeUtil.saveInputMethodSubtypeList( - this, getContentResolver(), mImis, mHaveHardKeyboard); + this, getContentResolver(), mImis, !mHardKeyboardPreferenceList.isEmpty()); } @Override @@ -230,7 +278,7 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment } } else if (preference instanceof CheckBoxPreference) { final CheckBoxPreference chkPref = (CheckBoxPreference) preference; - if (mHaveHardKeyboard) { + if (!mHardKeyboardPreferenceList.isEmpty()) { for (int i = 0; i < sHardKeyboardKeys.length; ++i) { if (chkPref == mHardKeyboardCategory.findPreference(sHardKeyboardKeys[i])) { System.putInt(getContentResolver(), sSystemSettingNames[i], @@ -315,46 +363,57 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment return pref; } - private void createImePreferenceHierarchy(PreferenceGroup root) { - final Preference hardKeyPref = findPreference("hard_keyboard"); - if (mIsOnlyImeSettings) { - getPreferenceScreen().removeAll(); - if (hardKeyPref != null && mHaveHardKeyboard) { - getPreferenceScreen().addPreference(hardKeyPref); - } - if (SHOW_INPUT_METHOD_SWITCHER_SETTINGS) { - getPreferenceScreen().addPreference(mShowInputMethodSelectorPref); - } - getPreferenceScreen().addPreference(root); - } - if (hardKeyPref != null) { - if (mHaveHardKeyboard) { - mHardKeyboardCategory = (PreferenceCategory) hardKeyPref; - } else { - getPreferenceScreen().removePreference(hardKeyPref); + private void updateHardKeyboards() { + mHardKeyboardPreferenceList.clear(); + if (getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY) { + final InputManager im = + (InputManager)getActivity().getSystemService(Context.INPUT_SERVICE); + + final int[] devices = InputDevice.getDeviceIds(); + for (int i = 0; i < devices.length; i++) { + InputDevice device = InputDevice.getDevice(devices[i]); + if (device != null + && (device.getSources() & InputDevice.SOURCE_KEYBOARD) != 0 + && device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) { + final String inputDeviceDescriptor = device.getDescriptor(); + final String keyboardLayoutDescriptor = + im.getInputDeviceKeyboardLayoutDescriptor(inputDeviceDescriptor); + final KeyboardLayout keyboardLayout = keyboardLayoutDescriptor != null ? + im.getKeyboardLayout(keyboardLayoutDescriptor) : null; + + final Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setClass(getActivity(), KeyboardLayoutPickerActivity.class); + intent.putExtra(KeyboardLayoutPicker.EXTRA_INPUT_DEVICE_DESCRIPTOR, + inputDeviceDescriptor); + + final PreferenceScreen pref = new PreferenceScreen(getActivity(), null); + pref.setTitle(device.getName()); + if (keyboardLayout != null) { + pref.setSummary(keyboardLayout.getLabel()); + } + pref.setIntent(intent); + mHardKeyboardPreferenceList.add(pref); + } } } - root.removeAll(); - mInputMethodPreferenceList.clear(); - - if (!mIsOnlyImeSettings) { - // Current IME selection - final PreferenceScreen currentIme = new PreferenceScreen(getActivity(), null); - currentIme.setKey(KEY_CURRENT_INPUT_METHOD); - currentIme.setTitle(getResources().getString(R.string.current_input_method)); - root.addPreference(currentIme); - } - final int N = (mImis == null ? 0 : mImis.size()); - for (int i = 0; i < N; ++i) { - final InputMethodInfo imi = mImis.get(i); - final InputMethodPreference pref = getInputMethodPreference(imi, N); - mInputMethodPreferenceList.add(pref); - } + if (!mHardKeyboardPreferenceList.isEmpty()) { + for (int i = mHardKeyboardCategory.getPreferenceCount(); i-- > 0; ) { + final Preference pref = mHardKeyboardCategory.getPreference(i); + if (pref.getOrder() < 1000) { + mHardKeyboardCategory.removePreference(pref); + } + } - Collections.sort(mInputMethodPreferenceList); - for (int i = 0; i < N; ++i) { - root.addPreference(mInputMethodPreferenceList.get(i)); + Collections.sort(mHardKeyboardPreferenceList); + final int count = mHardKeyboardPreferenceList.size(); + for (int i = 0; i < count; i++) { + final Preference pref = mHardKeyboardPreferenceList.get(i); + pref.setOrder(i); + mHardKeyboardCategory.addPreference(pref); + } + } else { + getPreferenceScreen().removePreference(mHardKeyboardCategory); } } diff --git a/src/com/android/settings/inputmethod/KeyboardLayoutPicker.java b/src/com/android/settings/inputmethod/KeyboardLayoutPicker.java new file mode 100644 index 0000000..472df3a --- /dev/null +++ b/src/com/android/settings/inputmethod/KeyboardLayoutPicker.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.inputmethod; + +import com.android.settings.R; + +import android.app.ListFragment; +import android.app.LoaderManager.LoaderCallbacks; +import android.content.AsyncTaskLoader; +import android.content.Context; +import android.content.Loader; +import android.hardware.input.InputManager; +import android.hardware.input.InputManager.KeyboardLayout; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.ListAdapter; +import android.widget.ListView; + +import java.util.Collections; +import java.util.List; + +public class KeyboardLayoutPicker extends ListFragment + implements LoaderCallbacks<List<KeyboardLayout>> { + private static final String TAG = "KeyboardLayoutPicker"; + + private String mInputDeviceDescriptor; + + /** + * Intent extra: The input device descriptor of the keyboard whose keyboard + * layout is to be changed. + */ + public static final String EXTRA_INPUT_DEVICE_DESCRIPTOR = "input_device_descriptor"; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mInputDeviceDescriptor = getActivity().getIntent().getStringExtra( + EXTRA_INPUT_DEVICE_DESCRIPTOR); + if (mInputDeviceDescriptor == null) { + Log.e(TAG, "Missing expected intent parameter: " + EXTRA_INPUT_DEVICE_DESCRIPTOR); + getActivity().finish(); + } + + setEmptyText(getActivity().getText(R.string.keyboard_layout_picker_empty_text)); + getLoaderManager().initLoader(0, null, this); + } + + @Override + public void onResume() { + super.onResume(); + getListView().requestFocus(); + } + + @Override + public void onListItemClick(ListView l, View v, int position, long id) { + if (mInputDeviceDescriptor != null) { + KeyboardLayout c = (KeyboardLayout)l.getItemAtPosition(position); + InputManager im = (InputManager)getActivity().getSystemService(Context.INPUT_SERVICE); + im.setInputDeviceKeyboardLayoutDescriptor(mInputDeviceDescriptor, c.getDescriptor()); + } + + getActivity().finish(); + } + + @Override + public Loader<List<KeyboardLayout>> onCreateLoader(int id, Bundle args) { + return new KeyboardLayoutLoader(getActivity()); + } + + @Override + public void onLoadFinished(Loader<List<KeyboardLayout>> loader, + List<KeyboardLayout> data) { + setListAdapter(new KeyboardLayoutAdapter(getActivity(), data)); + } + + @Override + public void onLoaderReset(Loader<List<KeyboardLayout>> loader) { + setListAdapter(null); + } + + private static final class KeyboardLayoutAdapter + extends ArrayAdapter<KeyboardLayout> { + public KeyboardLayoutAdapter(Context context, List<KeyboardLayout> list) { + super(context, android.R.layout.simple_list_item_1, list); + } + } + + private static final class KeyboardLayoutLoader + extends AsyncTaskLoader<List<KeyboardLayout>> { + public KeyboardLayoutLoader(Context context) { + super(context); + } + + @Override + public List<KeyboardLayout> loadInBackground() { + InputManager im = (InputManager)getContext().getSystemService(Context.INPUT_SERVICE); + List<KeyboardLayout> list = im.getKeyboardLayouts(); + Collections.sort(list); + return list; + } + + @Override + protected void onStartLoading() { + super.onStartLoading(); + forceLoad(); + } + + @Override + protected void onStopLoading() { + super.onStopLoading(); + cancelLoad(); + } + } +} |