/src/com/android/inputmethod/norwegian/NorwegianIME.java
http://scandinavian-keyboard.googlecode.com/ · Java · 1712 lines · 1451 code · 141 blank · 120 comment · 408 complexity · 7552d7c9bed3038f311fb6cbb6b6b6f4 MD5 · raw file
- /*
- * Copyright (C) 2008-2009 Google Inc.
- *
- * 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.inputmethod.norwegian;
- import java.io.FileDescriptor;
- import java.io.PrintWriter;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Timer;
- import java.util.TimerTask;
- import android.app.AlertDialog;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.content.SharedPreferences;
- import android.content.pm.PackageManager.NameNotFoundException;
- import android.content.res.Configuration;
- import android.content.res.Resources;
- import android.inputmethodservice.InputMethodService;
- import android.inputmethodservice.Keyboard;
- import android.inputmethodservice.KeyboardView;
- import android.media.AudioManager;
- import android.os.Debug;
- import android.os.Handler;
- import android.os.Message;
- import android.os.SystemClock;
- import android.os.Vibrator;
- import android.preference.PreferenceManager;
- import android.text.AutoText;
- import android.text.TextUtils;
- import android.util.Log;
- import android.util.PrintWriterPrinter;
- import android.util.Printer;
- import android.view.KeyEvent;
- import android.view.View;
- import android.view.Window;
- import android.view.WindowManager;
- import android.view.inputmethod.CompletionInfo;
- import android.view.inputmethod.EditorInfo;
- import android.view.inputmethod.InputConnection;
- import android.view.inputmethod.InputMethodManager;
- /**
- * Input method implementation for Qwerty'ish keyboard.
- */
- public class NorwegianIME extends InputMethodService
- implements KeyboardView.OnKeyboardActionListener {
- static final boolean DEBUG = false;
- static final boolean TRACE = false;
-
- private static final String PREF_KEYBOARD_TYPE = "keyboard_type";
- private static final String PREF_KEYBOARD_LAYOUT = "keyboard_layout";
- private static final String PREF_DICTIONARY_MANUALLY = "dictionary_manually";
- private static final String PREF_DICTIONARY = "dictionary";
- private static final String PREF_VIBRATE_ON = "vibrate_enable";
- private static final String PREF_VIBRATE_DURATION = "vibrate_duration";
- private static final String PREF_VIBRATE_BUG_FIX = "vibrate_bug_fix";
- private static final String PREF_SOUND_ON = "sound_on";
- private static final String PREF_AUTO_CAP = "auto_cap";
- private static final String PREF_SWIPE_ENABLED = "swipe_enabled";
- private static final String PREF_SWIPE_UP = "swipe_up";
- private static final String PREF_SWIPE_DOWN = "swipe_down";
- private static final String PREF_SWIPE_LEFT = "swipe_left";
- private static final String PREF_SWIPE_RIGHT = "swipe_right";
- private static final String PREF_SWIPE_KEYBOARD_LAYOUT = "swipe_keyboard_layout";
- private static final String PREF_SWIPE_DICTIONARY = "swipe_dictionary";
- private static final String PREF_SKIN = "skin";
- private static final String PREF_QUICK_FIXES = "quick_fixes";
- private static final String PREF_SHOW_SUGGESTIONS = "show_suggestions";
- private static final String PREF_AUTO_COMPLETE = "auto_complete";
- private static final String PREF_AUTO_DICTIONARY_ENABLE = "auto_dictionary_enable";
- private static final String PREF_AUTO_DICTIONARY_LIMIT = "auto_dictionary_limit";
- private static final String PREF_AUTO_DICTIONARY_CASE_SENSITIVE = "auto_dictionary_case_sensitive";
- private static final String PREF_SPACE_AFTER_PREDICTION = "space_after_prediction";
- private static final String PREF_SWAP_COLON = "swap_colon";
- private static final String PREF_AT_IS_WORD_SEPARATOR = "at_is_word_separator";
- private static final int MSG_UPDATE_SUGGESTIONS = 0;
- private static final int MSG_START_TUTORIAL = 1;
- private static final int MSG_UPDATE_SHIFT_STATE = 2;
-
- // How many continuous deletes at which to start deleting at a higher speed.
- private static final int DELETE_ACCELERATE_AT = 20;
- // Key events coming any faster than this are long-presses.
- private static final int QUICK_PRESS = 200;
- // Weight added to a user picking a new word from the suggestion strip
- static final int FREQUENCY_FOR_PICKED = 3;
- // Weight added to a user typing a new word that doesn't get corrected (or is reverted)
- static final int FREQUENCY_FOR_TYPED = 3; //1;
- // A word that is frequently typed and get's promoted to the user dictionary, uses this
- // frequency.
- static final int FREQUENCY_FOR_AUTO_ADD = 250;
-
- static final int KEYCODE_ENTER = '\n';
- static final int KEYCODE_SPACE = ' ';
- // Contextual menu positions
- private static final int POS_SETTINGS = 0;
- private static final int POS_METHOD = 1;
- private static final int POS_USER_DICTIONARY = 2;
- private static final int POS_LAYOUT = 3;
- private static final int POS_DICTIONARY = 4;
-
- private NorwegianKeyboardView mInputView;
- private CandidateViewContainer mCandidateViewContainer;
- private CandidateView mCandidateView;
- private Suggest mSuggest;
- private CompletionInfo[] mCompletions;
-
- private AlertDialog mOptionsDialog;
-
- KeyboardSwitcher mKeyboardSwitcher;
-
- private UserDictionary mUserDictionary;
- private AutoDictionary mAutoDictionary;
-
- private String mLocale;
- private StringBuilder mComposing = new StringBuilder();
- private WordComposer mWord = new WordComposer();
- private int mCommittedLength;
- private boolean mPredicting;
- private CharSequence mBestWord;
- private boolean mPredictionOn;
- private boolean mCompletionOn;
- private boolean mAutoSpace;
- private boolean mAutoCorrectOn;
- private boolean mCapsLock;
- private int mKeyboardType;
- private int mKeyboardLayout;
- private boolean mDictionaryManually;
- private String mDictionary;
- private CharSequence[] mAvailableDictionaries;
- private CharSequence[] mAvailableDictionaryValues;
- private boolean mVibrateOn;
- private boolean mSoundOn;
- private boolean mAutoCap;
- private boolean mSwipeEnabled;
- private int mSwipeUp;
- private int mSwipeDown;
- private int mSwipeLeft;
- private int mSwipeRight;
- private String mSwipeKeyboardLayout;
- private String mSwipeDictionary;
- private String mSkin;
- private String mLastSkin;
- private boolean mQuickFixes;
- private boolean mShowSuggestions;
- private boolean mAutoDictionaryEnabled;
- private int mAutoDictionaryLimit;
- private boolean mAutoDictionaryCaseSensitive;
- private boolean mSpaceAfterPrediction;
- private boolean mSwapColon;
- private int mCorrectionMode;
- private int mOrientation;
- // Indicates whether the suggestion strip is to be on in landscape
- private boolean mJustAccepted;
- private CharSequence mJustRevertedSeparator;
- private int mDeleteCount;
- private long mLastKeyTime;
- private int mLastOnKeyCode;
- private int mKeyPressesCount;
-
- private Tutorial mTutorial;
- private Vibrator mVibrator;
- private long mVibrateDuration = 0;
- private long mVibrateStart;
- private Timer mVibrateTimer;
- private boolean mVibrateBugFix;
- private AudioManager mAudioManager;
- // Align sound effect volume on music volume
- private final float FX_VOLUME = -1.0f;
- private boolean mSilentMode;
- private String mWordSeparators;
- private String mSentenceSeparators;
-
- private String pkgNameLast;
- private int resIdLast;
- private int lastKeyPressed;
- private ArrayList<Integer> validKeyCodes;
- private HashMap<Integer, Integer> letterSymbolArray;
-
- Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_UPDATE_SUGGESTIONS:
- updateSuggestions();
- break;
- case MSG_START_TUTORIAL:
- if (mTutorial == null) {
- if (mInputView.isShown()) {
- mTutorial = new Tutorial(NorwegianIME.this, mInputView);
- mTutorial.start();
- } else {
- // Try again soon if the view is not yet showing
- sendMessageDelayed(obtainMessage(MSG_START_TUTORIAL), 100);
- }
- }
- break;
- case MSG_UPDATE_SHIFT_STATE:
- updateShiftKeyState(getCurrentInputEditorInfo());
- break;
- }
- }
- };
- @Override public void onCreate() {
- super.onCreate();
- //setStatusIcon(R.drawable.ime_qwerty);
- mKeyboardSwitcher = new KeyboardSwitcher(this);
- final Configuration conf = getResources().getConfiguration();
- initSuggest(conf.locale.toString(), true);
- mOrientation = conf.orientation;
-
- mVibrateDuration = getResources().getInteger(R.integer.vibrate_duration_ms);
-
- // register to receive ringer mode changes for silent mode
- IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
- registerReceiver(mReceiver, filter);
- }
-
- private void initSuggest(String locale, boolean doAll) {
- String pkgName;
- FindDictionary dictionaries = new FindDictionary(this);
- mAvailableDictionaries = dictionaries.getAppNames();
- mAvailableDictionaryValues = dictionaries.getPackageNames();
- if(mDictionaryManually)
- pkgName = mDictionary;
- else {
- int index = 0;
- CharSequence[] keyboardLayouts = getResources().getStringArray(R.array.keyboard_layouts_values);
- for (int i = 0; i < keyboardLayouts.length; i++)
- if(mKeyboardLayout == Integer.parseInt(keyboardLayouts[i].toString()))
- index = i;
- pkgName = dictionaries.findPackageName(getResources().getStringArray(R.array.keyboard_layouts)[index]);
- }
- int resId = dictionaries.getResId(pkgName);
- if(doAll || pkgName != pkgNameLast) {
- Resources res;
- try {
- res = getPackageManager().getResourcesForApplication(pkgName);
- } catch(NameNotFoundException notFound) {
- res = getResources();
- resId = 0;
- }
-
- if(doAll || resId != resIdLast || (pkgName != pkgNameLast && resId != 0)) {
- mLocale = locale;
- mSuggest = new Suggest(this, res, resId); //(this, R.raw.main);
- mSuggest.setCorrectionMode(mCorrectionMode, mQuickFixes);
- mUserDictionary = new UserDictionary(this);
- mAutoDictionary = new AutoDictionary(this);
- mSuggest.setUserDictionary(mUserDictionary);
- mSuggest.setAutoDictionary(mAutoDictionary);
- mWordSeparators = getResources().getString(R.string.word_separators);
- mSentenceSeparators = getResources().getString(R.string.sentence_separators);
- }
- if(resId != 0) pkgNameLast = pkgName;
- else pkgNameLast = "";
- resIdLast = resId;
- }
- }
-
- @Override public void onDestroy() {
- mUserDictionary.close();
- unregisterReceiver(mReceiver);
- super.onDestroy();
- }
- @Override
- public void onConfigurationChanged(Configuration conf) {
- if (!TextUtils.equals(conf.locale.toString(), mLocale)) {
- initSuggest(conf.locale.toString(), true);
- }
- // If orientation changed while predicting, commit the change
- if (conf.orientation != mOrientation) {
- commitTyped(getCurrentInputConnection());
- mOrientation = conf.orientation;
- }
- if (mKeyboardSwitcher == null) {
- mKeyboardSwitcher = new KeyboardSwitcher(this);
- }
- mKeyboardSwitcher.makeKeyboards(true);
- super.onConfigurationChanged(conf);
- }
-
- @Override
- public View onCreateInputView() {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
- mSkin = sp.getString(PREF_SKIN, "input_standard");
- int layout_input;
- boolean changeIcons = true;
- if("input_htc".equals(mSkin)) layout_input = R.layout.input_htc;
- else if("input_iphone".equals(mSkin)) layout_input = R.layout.input_iphone;
- else if("input_light".equals(mSkin)) layout_input = R.layout.input_light;
- else {
- layout_input = R.layout.input_standard;
- changeIcons = false;
- }
- mLastSkin = mSkin;
-
- mInputView = (NorwegianKeyboardView) getLayoutInflater().inflate(
- layout_input, null);
- mKeyboardSwitcher.setInputView(mInputView);
- mKeyboardSwitcher.makeKeyboards(true);
- mInputView.setOnKeyboardActionListener(this);
- mKeyboardSwitcher.setKeyboardType(mKeyboardType);
- mKeyboardSwitcher.setKeyboardLayout(mKeyboardLayout);
- mKeyboardSwitcher.setKeyboardModeChangeIcons(KeyboardSwitcher.MODE_TEXT, 0, changeIcons);
- return mInputView;
- }
- @Override
- public View onCreateCandidatesView() {
- mKeyboardSwitcher.makeKeyboards(true);
- mCandidateViewContainer = (CandidateViewContainer) getLayoutInflater().inflate(
- R.layout.candidates, null);
- mCandidateViewContainer.initViews();
- mCandidateView = (CandidateView) mCandidateViewContainer.findViewById(R.id.candidates);
- mCandidateView.setService(this);
- setCandidatesViewShown(true);
- return mCandidateViewContainer;
- }
- @Override
- public void onStartInputView(EditorInfo attribute, boolean restarting) {
- // In landscape mode, this method gets called without the input view being created.
- if (mInputView == null) {
- return;
- }
- loadSettings();
- if(mSkin != null && !mSkin.equals(mLastSkin))
- setInputView(onCreateInputView());
- initSuggest(getResources().getConfiguration().locale.toString(), false);
- mKeyboardSwitcher.setKeyboardType(mKeyboardType);
- mKeyboardSwitcher.setKeyboardLayout(mKeyboardLayout);
- mKeyboardSwitcher.makeKeyboards(false);
-
- TextEntryState.newSession(this);
-
- boolean disableAutoCorrect = false;
- mPredictionOn = false;
- mCompletionOn = false;
- mCompletions = null;
- mCapsLock = false;
- switch (attribute.inputType&EditorInfo.TYPE_MASK_CLASS) {
- case EditorInfo.TYPE_CLASS_NUMBER:
- case EditorInfo.TYPE_CLASS_DATETIME:
- mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_SYMBOLS,
- attribute.imeOptions);
- break;
- case EditorInfo.TYPE_CLASS_PHONE:
- mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_PHONE,
- attribute.imeOptions);
- break;
- case EditorInfo.TYPE_CLASS_TEXT:
- mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT,
- attribute.imeOptions);
- //startPrediction();
- mPredictionOn = true;
- // Make sure that passwords are not displayed in candidate view
- int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION;
- if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD ||
- variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ) {
- mPredictionOn = false;
- }
- if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
- || variation == EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME) {
- mAutoSpace = false;
- } else {
- mAutoSpace = true;
- }
- if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) {
- mPredictionOn = false;
- mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_EMAIL,
- attribute.imeOptions);
- } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) {
- mPredictionOn = false;
- mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_URL,
- attribute.imeOptions);
- } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) {
- mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_IM,
- attribute.imeOptions);
- } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) {
- mPredictionOn = false;
- } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) {
- // If it's a browser edit field and auto correct is not ON explicitly, then
- // disable auto correction, but keep suggestions on.
- if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
- disableAutoCorrect = true;
- }
- }
- // If NO_SUGGESTIONS is set, don't do prediction.
- /*if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
- mPredictionOn = false;
- disableAutoCorrect = true;
- }*/
- // If it's not multiline and the autoCorrect flag is not set, then don't correct
- if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 &&
- (attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
- disableAutoCorrect = true;
- }
- if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
- mPredictionOn = false;
- mCompletionOn = true && isFullscreenMode();
- }
- updateShiftKeyState(attribute);
- break;
- default:
- mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT,
- attribute.imeOptions);
- updateShiftKeyState(attribute);
- }
- mInputView.closing();
- mComposing.setLength(0);
- mPredicting = false;
- mDeleteCount = 0;
- setCandidatesViewShown(false);
- if (mCandidateView != null) mCandidateView.setSuggestions(null, false, false, false);
- //loadSettings();
- // Override auto correct
- if (disableAutoCorrect) {
- mAutoCorrectOn = false;
- if (mCorrectionMode == Suggest.CORRECTION_FULL) {
- mCorrectionMode = Suggest.CORRECTION_BASIC;
- }
- }
- mInputView.setProximityCorrectionEnabled(true);
- if (mSuggest != null) {
- mSuggest.setCorrectionMode(mCorrectionMode, mQuickFixes);
- }
- mPredictionOn = mPredictionOn && mCorrectionMode > 0;
- checkTutorial(attribute.privateImeOptions);
- if (TRACE) Debug.startMethodTracing("/data/trace/norwegianime");
- }
- @Override
- public void onFinishInput() {
- super.onFinishInput();
- if (mInputView != null) {
- mInputView.closing();
- }
- }
- @Override
- public void onUpdateSelection(int oldSelStart, int oldSelEnd,
- int newSelStart, int newSelEnd,
- int candidatesStart, int candidatesEnd) {
- super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd,
- candidatesStart, candidatesEnd);
- // If the current selection in the text view changes, we should
- // clear whatever candidate text we have.
- if (mComposing.length() > 0 && mPredicting && (newSelStart != candidatesEnd
- || newSelEnd != candidatesEnd)) {
- mComposing.setLength(0);
- mPredicting = false;
- updateSuggestions();
- TextEntryState.reset();
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) {
- ic.finishComposingText();
- }
- } else if (!mPredicting && !mJustAccepted
- && TextEntryState.getState() == TextEntryState.STATE_ACCEPTED_DEFAULT) {
- TextEntryState.reset();
- }
- mJustAccepted = false;
- postUpdateShiftKeyState();
- }
- @Override
- public void hideWindow() {
- if (TRACE) Debug.stopMethodTracing();
- if (mOptionsDialog != null && mOptionsDialog.isShowing()) {
- mOptionsDialog.dismiss();
- mOptionsDialog = null;
- }
- if (mTutorial != null) {
- mTutorial.close();
- mTutorial = null;
- }
- super.hideWindow();
- TextEntryState.endSession();
- }
- @Override
- public void onDisplayCompletions(CompletionInfo[] completions) {
- if (false) {
- Log.i("foo", "Received completions:");
- for (int i=0; i<(completions != null ? completions.length : 0); i++) {
- Log.i("foo", " #" + i + ": " + completions[i]);
- }
- }
- if (mCompletionOn) {
- mCompletions = completions;
- if (completions == null) {
- mCandidateView.setSuggestions(null, false, false, false);
- return;
- }
-
- List<CharSequence> stringList = new ArrayList<CharSequence>();
- for (int i=0; i<(completions != null ? completions.length : 0); i++) {
- CompletionInfo ci = completions[i];
- if (ci != null) stringList.add(ci.getText());
- }
- //CharSequence typedWord = mWord.getTypedWord();
- mCandidateView.setSuggestions(stringList, true, true, true);
- mBestWord = null;
- setCandidatesViewShown(isCandidateStripVisible() || mCompletionOn);
- }
- }
- @Override
- public void setCandidatesViewShown(boolean shown) {
- // TODO: Remove this if we support candidates with hard keyboard
- if (onEvaluateInputViewShown()) {
- super.setCandidatesViewShown(shown);
- }
- }
-
- @Override
- public void onComputeInsets(InputMethodService.Insets outInsets) {
- super.onComputeInsets(outInsets);
- if (!isFullscreenMode()) {
- outInsets.contentTopInsets = outInsets.visibleTopInsets;
- }
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_BACK:
- if (event.getRepeatCount() == 0 && mInputView != null) {
- if (mInputView.handleBack()) {
- return true;
- } else if (mTutorial != null) {
- mTutorial.close();
- mTutorial = null;
- }
- }
- break;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_LEFT:
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- // If tutorial is visible, don't allow dpad to work
- if (mTutorial != null) {
- return true;
- }
- break;
- }
- return super.onKeyDown(keyCode, event);
- }
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_LEFT:
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- // If tutorial is visible, don't allow dpad to work
- if (mTutorial != null) {
- return true;
- }
- // Enable shift key and DPAD to do selections
- if (mInputView != null && mInputView.isShown() && mInputView.isShifted()) {
- event = new KeyEvent(event.getDownTime(), event.getEventTime(),
- event.getAction(), event.getKeyCode(), event.getRepeatCount(),
- event.getDeviceId(), event.getScanCode(),
- KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON);
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) ic.sendKeyEvent(event);
- return true;
- }
- break;
- }
- return super.onKeyUp(keyCode, event);
- }
- private void commitTyped(InputConnection inputConnection) {
- if (mPredicting) {
- mPredicting = false;
- if (mComposing.length() > 0) {
- if (inputConnection != null) {
- inputConnection.commitText(mComposing, 1);
- }
- mCommittedLength = mComposing.length();
- TextEntryState.acceptedTyped(mComposing);
- if(mAutoDictionaryEnabled)
- mAutoDictionary.addWord(mComposing.toString(), FREQUENCY_FOR_TYPED);
- }
- updateSuggestions();
- }
- }
- private void postUpdateShiftKeyState() {
- mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE);
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SHIFT_STATE), 300);
- }
- public void updateShiftKeyState(EditorInfo attr) {
- InputConnection ic = getCurrentInputConnection();
- if (attr != null && mInputView != null && mKeyboardSwitcher.isAlphabetMode()
- && ic != null) {
- int caps = 0;
- EditorInfo ei = getCurrentInputEditorInfo();
- if (mAutoCap && ei != null && ei.inputType != EditorInfo.TYPE_NULL) {
- caps = ic.getCursorCapsMode(attr.inputType);
- }
- mInputView.setShifted(mCapsLock || caps != 0);
- }
- }
-
- private void swapPunctuationAndSpace() {
- final InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
- CharSequence lastTwo = ic.getTextBeforeCursor(2, 0);
- if (lastTwo != null && lastTwo.length() == 2
- && lastTwo.charAt(0) == KEYCODE_SPACE && isSentenceSeparator(lastTwo.charAt(1))) {
- ic.beginBatchEdit();
- ic.deleteSurroundingText(2, 0);
- ic.commitText(lastTwo.charAt(1) + " ", 1);
- ic.endBatchEdit();
- updateShiftKeyState(getCurrentInputEditorInfo());
- }
- }
-
- private void doubleSpace() {
- //if (!mAutoPunctuate) return;
- if (mCorrectionMode == Suggest.CORRECTION_NONE) return;
- final InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
- CharSequence lastThree = ic.getTextBeforeCursor(3, 0);
- if (lastThree != null && lastThree.length() == 3
- && Character.isLetterOrDigit(lastThree.charAt(0))
- && lastThree.charAt(1) == KEYCODE_SPACE && lastThree.charAt(2) == KEYCODE_SPACE) {
- ic.beginBatchEdit();
- ic.deleteSurroundingText(2, 0);
- ic.commitText(". ", 1);
- ic.endBatchEdit();
- updateShiftKeyState(getCurrentInputEditorInfo());
- }
- }
-
- public boolean addWordToDictionary(String word) {
- mUserDictionary.addWord(word, 128);
- return true;
- }
- private boolean isAlphabet(int code) {
- if (Character.isLetter(code)) {
- return true;
- } else {
- return false;
- }
- }
-
- // Implementation of KeyboardViewListener
- public void onKey(int primaryCode, int[] keyCodes) {
- long when = SystemClock.uptimeMillis();
- if (primaryCode != Keyboard.KEYCODE_DELETE ||
- when > mLastKeyTime + QUICK_PRESS) {
- mDeleteCount = 0;
- }
-
- switch (primaryCode) {
- case Keyboard.KEYCODE_DELETE:
- handleBackspace();
- mDeleteCount++;
- break;
- case Keyboard.KEYCODE_SHIFT:
- handleShift();
- break;
- case Keyboard.KEYCODE_CANCEL:
- if (mOptionsDialog == null || !mOptionsDialog.isShowing()) {
- handleClose();
- }
- break;
- case NorwegianKeyboardView.KEYCODE_OPTIONS:
- showOptionsMenu();
- break;
- case NorwegianKeyboardView.KEYCODE_SHIFT_LONGPRESS:
- if (mCapsLock) {
- handleShift();
- } else {
- toggleCapsLock();
- }
- break;
- case Keyboard.KEYCODE_MODE_CHANGE:
- changeKeyboardMode();
- break;
- default:
- if (isWordSeparator(primaryCode)) {
- handleSeparator(primaryCode);
- } else {
- handleCharacter(primaryCode, keyCodes);
- // Postponed until next version. Testing of phone layout
- // if(mKeyboardType == 2) {
- // mKeyPressesCount++;
- // if(primaryCode != mLastOnKeyCode || when > mLastKeyTime + 1000)
- // mKeyPressesCount = 0;
- // switch(mKeyPressesCount) {
- // case 0:
- // handleCharacter(primaryCode, keyCodes);
- // break;
- // case 1:
- // replaceLastCharacter(primaryCode + 1, keyCodes);
- // break;
- // case 2:
- // replaceLastCharacter(primaryCode + 2, keyCodes);
- // break;
- // }
- // } else {
- // String k = primaryCode + " ";
- // for (int i : keyCodes)
- // k += i + " ";
- // Log.d("SK", k);
- // handleCharacter(primaryCode, keyCodes);
- // }
- }
- // Cancel the just reverted state
- mJustRevertedSeparator = null;
- }
- mLastKeyTime = when;
- mLastOnKeyCode = primaryCode;
- if (mKeyboardSwitcher.onKey(primaryCode)) {
- //changeKeyboardMode();
- }
- }
-
- public void onText(CharSequence text) {
- InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
- ic.beginBatchEdit();
- if (mPredicting) {
- commitTyped(ic);
- }
- ic.commitText(text, 1);
- ic.endBatchEdit();
- updateShiftKeyState(getCurrentInputEditorInfo());
- mJustRevertedSeparator = null;
- }
- private void handleBackspace() {
- boolean deleteChar = false;
- InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
- if (mPredicting) {
- final int length = mComposing.length();
- if (length > 0) {
- mComposing.delete(length - 1, length);
- mWord.deleteLast();
- ic.setComposingText(mComposing, 1);
- if (mComposing.length() == 0) {
- mPredicting = false;
- }
- postUpdateSuggestions();
- } else {
- ic.deleteSurroundingText(1, 0);
- }
- } else {
- deleteChar = true;
- }
- postUpdateShiftKeyState();
- TextEntryState.backspace();
- if (TextEntryState.getState() == TextEntryState.STATE_UNDO_COMMIT) {
- revertLastWord(deleteChar);
- return;
- } else if (deleteChar) {
- sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
- if (mDeleteCount > DELETE_ACCELERATE_AT) {
- sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
- }
- }
- mJustRevertedSeparator = null;
- }
- private void handleShift() {
- Keyboard currentKeyboard = mInputView.getKeyboard();
- if (mKeyboardSwitcher.isAlphabetMode()) {
- // Alphabet keyboard
- checkToggleCapsLock();
- mInputView.setShifted(mCapsLock || !mInputView.isShifted());
- } else {
- mKeyboardSwitcher.toggleShift();
- }
- }
-
- private void handleCharacter(int primaryCode, int[] keyCodes) {
- if (isAlphabet(primaryCode) && isPredictionOn() && !isCursorTouchingWord()) {
- if (!mPredicting) {
- mPredicting = true;
- mComposing.setLength(0);
- mWord.reset();
- }
- }
- if (mInputView.isShifted()) {
- // TODO: This doesn't work with ß, need to fix it in the next release.
- if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT
- || keyCodes[0] > Character.MAX_CODE_POINT) {
- return;
- }
- primaryCode = new String(keyCodes, 0, 1).toUpperCase().charAt(0);
- }
- if (mPredicting) {
- if (mInputView.isShifted() && mComposing.length() == 0) {
- mWord.setCapitalized(true);
- }
- mComposing.append((char) primaryCode);
- mWord.add(primaryCode, keyCodes);
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) {
- ic.setComposingText(mComposing, 1);
- }
- postUpdateSuggestions();
- } else {
- sendKeyChar((char)primaryCode);
- }
- updateShiftKeyState(getCurrentInputEditorInfo());
- measureCps();
- TextEntryState.typedCharacter((char) primaryCode, isWordSeparator(primaryCode));
- }
- private void handleSeparator(int primaryCode) {
- boolean pickedDefault = false;
- // Handle separator
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) {
- ic.beginBatchEdit();
- }
- if (mPredicting) {
- // In certain languages where single quote is a separator, it's better
- // not to auto correct, but accept the typed word. For instance,
- // in Italian dov' should not be expanded to dove' because the elision
- // requires the last vowel to be removed.
- if (mAutoCorrectOn && primaryCode != '\'' &&
- (mJustRevertedSeparator == null
- || mJustRevertedSeparator.length() == 0
- || mJustRevertedSeparator.charAt(0) != primaryCode)) {
- pickDefaultSuggestion();
- pickedDefault = true;
- } else {
- commitTyped(ic);
- }
- }
- sendKeyChar((char)primaryCode);
- TextEntryState.typedCharacter((char) primaryCode, true);
- if (TextEntryState.getState() == TextEntryState.STATE_PUNCTUATION_AFTER_ACCEPTED
- && primaryCode != KEYCODE_ENTER) {
- if(mSwapColon || !":".equals(String.valueOf((char)primaryCode)) && !";".equals(String.valueOf((char)primaryCode)))
- swapPunctuationAndSpace();
- } else if (isPredictionOn() && primaryCode == ' ') {
- //else if (TextEntryState.STATE_SPACE_AFTER_ACCEPTED) {
- doubleSpace();
- }
- if (pickedDefault && mBestWord != null) {
- TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord);
- }
- updateShiftKeyState(getCurrentInputEditorInfo());
- if (ic != null) {
- ic.endBatchEdit();
- }
- }
-
- private void replaceLastCharacter(int primaryCode, int[] keyCodes) {
- InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
-
- if (mInputView.isShifted()) {
- // TODO: This doesn't work with ß, need to fix it in the next release.
- if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT
- || keyCodes[0] > Character.MAX_CODE_POINT) {
- return;
- }
- primaryCode = new String(keyCodes, 0, 1).toUpperCase().charAt(0);
- }
-
- if (mPredicting) {
- final int length = mComposing.length();
- if (length > 0) {
- mComposing.delete(length - 1, length);
- mWord.deleteLast();
- } else {
- ic.deleteSurroundingText(1, 0);
- }
-
- if (mInputView.isShifted() && mComposing.length() == 0) {
- mWord.setCapitalized(true);
- }
- mComposing.append((char) primaryCode);
- mWord.add(primaryCode, keyCodes);
- ic.setComposingText(mComposing, 1);
- postUpdateSuggestions();
- } else {
- sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
- sendKeyChar((char)primaryCode);
- }
-
- updateShiftKeyState(getCurrentInputEditorInfo());
- measureCps();
- TextEntryState.typedCharacter((char) primaryCode, isWordSeparator(primaryCode));
- }
-
- private void handleClose() {
- commitTyped(getCurrentInputConnection());
- requestHideSelf(0);
- mInputView.closing();
- TextEntryState.endSession();
- }
- private void checkToggleCapsLock() {
- if (mInputView.getKeyboard().isShifted()) {
- toggleCapsLock();
- }
- }
-
- private void toggleCapsLock() {
- mCapsLock = !mCapsLock;
- if (mKeyboardSwitcher.isAlphabetMode()) {
- mInputView.setShifted(mCapsLock); //Needed for 1.5, since keys don't get updated at longpress.
- ((NorwegianKeyboard) mInputView.getKeyboard()).setShiftLocked(mCapsLock);
- }
- }
- private void postUpdateSuggestions() {
- mHandler.removeMessages(MSG_UPDATE_SUGGESTIONS);
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UPDATE_SUGGESTIONS), 100);
- }
-
- private boolean isPredictionOn() {
- boolean predictionOn = mPredictionOn;
- //if (isFullscreenMode()) predictionOn &= mPredictionLandscape;
- return predictionOn;
- }
-
- private boolean isCandidateStripVisible() {
- return isPredictionOn() && mShowSuggestions;
- }
- private void updateSuggestions() {
- // Check if we have a suggestion engine attached.
- if (mSuggest == null || !isPredictionOn()) {
- return;
- }
-
- if (!mPredicting) {
- mCandidateView.setSuggestions(null, false, false, false);
- return;
- }
- List<CharSequence> stringList = mSuggest.getSuggestions(mInputView, mWord, false);
- boolean correctionAvailable = mSuggest.hasMinimalCorrection();
- //|| mCorrectionMode == mSuggest.CORRECTION_FULL;
- CharSequence typedWord = mWord.getTypedWord();
- // If we're in basic correct
- boolean typedWordValid = mSuggest.isValidWord(typedWord) ||
- (preferCapitalization() && mSuggest.isValidWord(typedWord.toString().toLowerCase()));
- if (mCorrectionMode == Suggest.CORRECTION_FULL) {
- correctionAvailable |= typedWordValid;
- }
- // Don't auto-correct words with multiple capital letter
- correctionAvailable &= !mWord.isMostlyCaps();
-
- mCandidateView.setSuggestions(stringList, false, typedWordValid, correctionAvailable);
- if (stringList.size() > 0) {
- if (correctionAvailable && !typedWordValid && stringList.size() > 1) {
- mBestWord = stringList.get(1);
- } else {
- mBestWord = typedWord;
- }
- } else {
- mBestWord = null;
- }
- setCandidatesViewShown(isCandidateStripVisible() || mCompletionOn);
- }
- private void pickDefaultSuggestion() {
- // Complete any pending candidate query first
- if (mHandler.hasMessages(MSG_UPDATE_SUGGESTIONS)) {
- mHandler.removeMessages(MSG_UPDATE_SUGGESTIONS);
- updateSuggestions();
- }
- if (mBestWord != null) {
- TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord);
- mJustAccepted = true;
- pickSuggestion(mBestWord);
- }
- }
- public void pickSuggestionManually(int index, CharSequence suggestion) {
- if (mCompletionOn && mCompletions != null && index >= 0
- && index < mCompletions.length) {
- CompletionInfo ci = mCompletions[index];
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) {
- ic.commitCompletion(ci);
- }
- mCommittedLength = suggestion.length();
- if (mCandidateView != null) {
- mCandidateView.clear();
- }
- updateShiftKeyState(getCurrentInputEditorInfo());
- return;
- }
- pickSuggestion(suggestion);
- TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion);
- // Follow it with a space
- if (mAutoSpace && mSpaceAfterPrediction) {
- sendSpace();
- }
- // Fool the state watcher so that a subsequent backspace will not do a revert
- TextEntryState.typedCharacter((char) KEYCODE_SPACE, true);
- }
-
- private void pickSuggestion(CharSequence suggestion) {
- if (mCapsLock) {
- suggestion = suggestion.toString().toUpperCase();
- } else if (preferCapitalization()
- || (mKeyboardSwitcher.isAlphabetMode() && mInputView.isShifted())) {
- suggestion = suggestion.toString().toUpperCase().charAt(0)
- + suggestion.subSequence(1, suggestion.length()).toString();
- }
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) {
- ic.commitText(suggestion, 1);
- }
- // Add the word to the auto dictionary if it's not a known word
- if (mAutoDictionaryEnabled && (mAutoDictionary.isValidWord(suggestion) || !mSuggest.isValidWord(suggestion))) {
- mAutoDictionary.addWord(suggestion.toString(), FREQUENCY_FOR_PICKED);
- }
- mPredicting = false;
- mCommittedLength = suggestion.length();
- if (mCandidateView != null) {
- mCandidateView.setSuggestions(null, false, false, false);
- }
- updateShiftKeyState(getCurrentInputEditorInfo());
- }
- private boolean isCursorTouchingWord() {
- InputConnection ic = getCurrentInputConnection();
- if (ic == null) return false;
- CharSequence toLeft = ic.getTextBeforeCursor(1, 0);
- CharSequence toRight = ic.getTextAfterCursor(1, 0);
- if (!TextUtils.isEmpty(toLeft)
- && !isWordSeparator(toLeft.charAt(0))) {
- return true;
- }
- if (!TextUtils.isEmpty(toRight)
- && !isWordSeparator(toRight.charAt(0))) {
- return true;
- }
- return false;
- }
-
- public void revertLastWord(boolean deleteChar) {
- final int length = mComposing.length();
- if (!mPredicting && length > 0) {
- final InputConnection ic = getCurrentInputConnection();
- mPredicting = true;
- ic.beginBatchEdit();
- mJustRevertedSeparator = ic.getTextBeforeCursor(1, 0);
- if (deleteChar) ic.deleteSurroundingText(1, 0);
- int toDelete = mCommittedLength;
- CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0);
- if (toTheLeft != null && toTheLeft.length() > 0
- && isWordSeparator(toTheLeft.charAt(0))) {
- toDelete--;
- }
- ic.deleteSurroundingText(toDelete, 0);
- ic.setComposingText(mComposing, 1);
- TextEntryState.backspace();
- ic.endBatchEdit();
- postUpdateSuggestions();
- } else {
- sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
- mJustRevertedSeparator = null;
- }
- }
- protected String getWordSeparators() {
- return mWordSeparators;
- }
-
- public boolean isWordSeparator(int code) {
- String separators = getWordSeparators();
- return separators.contains(String.valueOf((char)code));
- }
- public boolean isSentenceSeparator(int code) {
- return mSentenceSeparators.contains(String.valueOf((char)code));
- }
- private void sendSpace() {
- sendKeyChar((char)KEYCODE_SPACE);
- updateShiftKeyState(getCurrentInputEditorInfo());
- //onKey(KEY_SPACE[0], KEY_SPACE);
- }
- public boolean preferCapitalization() {
- return mWord.isCapitalized();
- }
- public void swipeRight() {
- // if (NorwegianKeyboardView.DEBUG_AUTO_PLAY) {
- // ClipboardManager cm = ((ClipboardManager)getSystemService(CLIPBOARD_SERVICE));
- // CharSequence text = cm.getText();
- // if (!TextUtils.isEmpty(text)) {
- // mInputView.startPlaying(text.toString());
- // }
- // }
- swipe(mSwipeRight);
- }
-
- public void swipeLeft() {
- swipe(mSwipeLeft);
- }
- public void swipeDown() {
- //handleClose();
- swipe(mSwipeDown);
- }
- public void swipeUp() {
- //launchSettings();
- swipe(mSwipeUp);
- }
-
- public void swipe(int type) {
- if(mSwipeEnabled) {
- switch(type) {
- case 1:
- if(lastKeyPressed > 0) {
- mInputView.setShifted(!mInputView.isShifted());
- onKey(lastKeyPressed, new int[] { lastKeyPressed });
- }
- return;
- case 2:
- if(96 < lastKeyPressed && lastKeyPressed < 123 || validKeyCodes.contains(lastKeyPressed))
- onKey(letterSymbolArray.get(lastKeyPressed), new int[] { letterSymbolArray.get(lastKeyPressed) });
- return;
- case 3:
- handleBackspace();
- return;
- case 4:
- onKey(KEYCODE_SPACE, new int[] { KEYCODE_SPACE } );
- return;
- case 6:
- handleClose();
- return;
- case 7:
- case 8:
- int newKeyboardLayoutIndex = 0;
- CharSequence[] keyboardLayouts = ListPreferenceMultiSelect.parseStoredValue(mSwipeKeyboardLayout);
- for (int i = 0; i < keyboardLayouts.length; i++)
- if(mKeyboardLayout == Integer.parseInt(keyboardLayouts[i].toString()))
- newKeyboardLayoutIndex = i;
- newKeyboardLayoutIndex = newKeyboardLayoutIndex + (type == 7 ? -1 : 1);
-
- if(newKeyboardLayoutIndex >= keyboardLayouts.length)
- newKeyboardLayoutIndex = 0;
- else if(newKeyboardLayoutIndex < 0)
- newKeyboardLayoutIndex = keyboardLayouts.length - 1;
- changePreference(PREF_KEYBOARD_LAYOUT, keyboardLayouts[newKeyboardLayoutIndex].toString());
- return;
- case 9:
- case 10:
- int newDictionaryIndex = 0;
- CharSequence[] selectedDictionaries = ListPreferenceMultiSelect.parseStoredValue(mSwipeDictionary);
- for (int i = 0; i < selectedDictionaries.length; i++)
- if(mDictionary.equals(selectedDictionaries[i]))
- newDictionaryIndex = i;
- newDictionaryIndex = newDictionaryIndex + (type == 9 ? -1 : 1);
-
- if(newDictionaryIndex >= selectedDictionaries.length)
- newDictionaryIndex = 0;
- else if(newDictionaryIndex < 0)
- newDictionaryIndex = selectedDictionaries.length - 1;
- if(!mDictionaryManually) {
- mDictionaryManually = true;
- changePreference(PREF_DICTIONARY_MANUALLY, true);
- }
- changePreference(PREF_DICTIONARY, selectedDictionaries[newDictionaryIndex].toString());
- return;
- case 11:
- getCurrentInputConnection().sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT));
- return;
- case 12:
- getCurrentInputConnection().sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT));
- return;
- case 13:
- getCurrentInputConnection().sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP));
- return;
- case 14:
- getCurrentInputConnection().sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN));
- return;
- }
- }
- }
- public void onPress(int primaryCode) {
- vibrate();
- playKeyClick(primaryCode);
- lastKeyPressed = primaryCode;
- }
- public void onRelease(int primaryCode) {
- //vibrate();
- }
- // receive ringer mode changes to detect silent mode
- private BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- updateRingerMode();
- }
- };
- // update flags for silent mode
- private void updateRingerMode() {
- if (mAudioManager == null) {
- mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
- }
- if (mAudioManager != null) {
- mSilentMode = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL);
- }
- }
- private void playKeyClick(int primaryCode) {
- // if mAudioManager is null, we don't have the ringer state yet
- // mAudioManager will be set by updateRingerMode
- if (mAudioManager == null) {
- if (mInputView != null) {
- updateRingerMode();
- }
- }
- if (mSoundOn && !mSilentMode) {
- // FIXME: Volume and enable should come from UI settings
- // FIXME: These should be triggered after auto-repeat logic
- int sound = AudioManager.FX_KEYPRESS_STANDARD;
- switch (primaryCode) {
- case Keyboard.KEYCODE_DELETE:
- sound = AudioManager.FX_KEYPRESS_DELETE;
- break;
- case KEYCODE_ENTER:
- sound = AudioManager.FX_KEYPRESS_RETURN;
- break;
- case KEYCODE_SPACE:
- sound = AudioManager.FX_KEYPRESS_SPACEBAR;
- break;
- }
- mAudioManager.playSoundEffect(sound, FX_VOLUME);
- }
- }
- private void vibrate() {
- if (!mVibrateOn || mVibrateDuration > 100)
- return;
-
- if (mVibrator == null)
- mVibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
-
- mVibrator.vibrate(mVibrateDuration);
-
- if(mVibrateBugFix) {
- if (mVibrateTimer == null)
- mVibrateTimer = new Timer();
- mVibrateStart = (new Date()).getTime();
- mVibrateTimer.schedule(new TimerTask() {
- @Override
- public void run() {
- if(mVibrateStart == 0) {
- this.cancel();
- mVibrateTimer.purge();
- } else if((new Date()).getTime() > (mVibrateStart + mVibrateDuration)) {
- mVibrateStart = 0;
- mVibrator.cancel();
- this.cancel();
- mVibrateTimer.purge();
- }
- }
- }, mVibrateDuration, 1);
- }
- }
- private void checkTutorial(String privateImeOptions) {
- if (privateImeOptions == null) return;
- if (privateImeOptions.equals("com.android.setupwizard:ShowTutorial")) {
- if (mTutorial == null) startTutorial();
- } else if (privateImeOptions.equals("com.android.setupwizard:HideTutorial")) {
- if (mTutorial != null) {
- if (mTutorial.close()) {
- mTutorial = null;
- }
- }
- }
- }
-
- private void startTutorial() {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_TUTORIAL), 500);
- }
- void tutorialDone() {
- mTutorial = null;
- }
- void promoteToUserDictionary(String word, int frequency) {
- if (mUserDictionary.isValidWord(word)) return;
- mUserDictionary.addWord(word, frequency);
- }
-
- private void launchSettings() {
- handleClose();
- Intent intent = new Intent();
- intent.setClass(NorwegianIME.this, NorwegianIMESettings.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(intent);
- }
- private void loadSettings() {
- // Get the settings preferences
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
- mKeyboardType = Integer.parseInt(sp.getString(PREF_KEYBOARD_TYPE, getResources().getString(R.string.keyboard_type_list_default_value)));
- mVibrateOn = sp.getBoolean(PREF_VIBRATE_ON, true);
- mVibrateDuration = sp.getInt(PREF_VIBRATE_DURATION, getResources().getInteger(R.integer.vibrate_duration_ms));
- mVibrateBugFix = sp.getBoolean(PREF_VIBRATE_BUG_FIX, false);
- mSoundOn = sp.getBoolean(PREF_SOUND_ON, false);
- mAutoCap = sp.getBoolean(PREF_AUTO_CAP, true);
-
- mSwipeEnabled = sp.getBoolean(PREF_SWIPE_ENABLED, true);
- mSwipeUp = Integer.parseInt(sp.getString(PREF_SWIPE_UP, getResources().getString(R.string.swipe_up_default)));
- mSwipeDown = Integer.parseInt(sp.getString(PREF_SWIPE_DOWN, getResources().getString(R.string.swipe_down_default)));
- mSwipeLeft = Integer.parseInt(sp.getString(PREF_SWIPE_LEFT, getResources().getString(R.string.swipe_left_default)));
- mSwipeRight = Integer.parseInt(sp.getString(PREF_SWIPE_RIGHT, getResources().getString(R.string.swipe_right_default)));
- mSwipeKeyboardLayout = sp.getString(PREF_SWIPE_KEYBOARD_LAYOUT, getResources().getString(R.string.swipe_keyboard_layout));
- mSwipeDictionary = sp.getString(PREF_SWIPE_DICTIONARY, getResources().getString(R.string.swipe_dictionary));
- mSkin = sp.getString(PREF_SKIN, getResources().getString(R.string.skin_default_value));
-
- mKeyboardLayout = Integer.parseInt(sp.getString(PREF_KEYBOARD_LAYOUT, getResources().getString(R.string.keyboard_layout_list_default_value)));
- mDictionaryManually = sp.getBoolean(PREF_DICTIONARY_MANUALLY, false);
- mDictionary = sp.getString(PREF_DICTIONARY, getResources().getString(R.string.dictionary_list_default_value));
- createLetterSymbolArray();
-
- mQuickFixes = sp.getBoolean(PREF_QUICK_FIXES, false);
- // If there is no auto text data, then quickfix is forced to "on", so that the other options
- // will continue to work
- if (AutoText.getSize(mInputView) < 1) mQuickFixes = true;
- if(mKeyboardLayout != 2 && !mDictionaryManually || mDictionaryManually &&
- !(mDictionary.contains(getResources().getString(R.string.dictionary_builtin_name)) || mDictionary.equals(getResources().getString(R.string.dictionary_builtin_pkg))))
- mQuickFixes = false;
- mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, true);// & mQuickFixes;
- boolean autoComplete = sp.getBoolean(PREF_AUTO_COMPLETE,
- getResources().getBoolean(R.bool.enable_autocorrect));// & mShowSuggestions;
- mAutoCorrectOn = mSuggest != null && (autoComplete || mQuickFixes);
- mCorrectionMode = autoComplete
- ? Suggest.CORRECTION_FULL
- : ((mQuickFixes || mShowSuggestions) ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
- mAutoDictionaryEnabled = sp.getBoolean(PREF_AUTO_DICTIONARY_ENABLE, true);
- mAutoDictionaryLimit = Integer.parseInt(sp.getString(PREF_AUTO_DICTIONARY_LIMIT, getResources().getString(R.string.auto_dictionary_limit_default)));
- mAutoDictionaryCaseSensitive = sp.getBoolean(PREF_AUTO_DICTIONARY_CASE_SENSITIVE, false);
- mAutoDictionary.loadSettings();
- mSpaceAfterPrediction = sp.getBoolean(PREF_SPACE_AFTER_PREDICTION, true);;
- mSwapColon = sp.getBoolean(PREF_SWAP_COLON, true);
-
- boolean atIsWordSeparator = sp.getBoolean(PREF_AT_IS_WORD_SEPARATOR, true);
- if(!atIsWordSeparator)
- mWordSeparators = mWordSeparators.replace("@", "");
- else if(!mWordSeparators.contains("@"))
- mWordSeparators += "@";
- }
- private void showOptionsMenu() {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setCancelable(true);
- builder.setIcon(R.drawable.ic_dialog_keyboard);
- builder.setNegativeButton(android.R.string.cancel, null);
- CharSequence itemSettings = getString(R.string.english_ime_settings);
- CharSequence itemInputMethod = getString(R.string.input_method);
- CharSequence itemKeyboardLayout = getString(R.string.keyboard_layout);
- CharSequence itemDictionaryLanguage = getString(R.string.dictionary);
- CharSequence itemUserDictionary = getString(R.string.user_dict_settings_title);
- CharSequence[] items;
- if(mDictionaryManually)
- items = new CharSequence[] {itemSettings, itemInputMethod, itemUserDictionary, itemKeyboardLayout, itemDictionaryLanguage};
- else
- items = new CharSequence[] {itemSettings, itemInputMethod, itemUserDictionary, itemKeyboardLayout};
- builder.setItems(items,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface di, int position) {
- di.dismiss();
- switch (position) {
- case POS_SETTINGS:
- launchSettings();
- break;
- case POS_METHOD:
- ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE))
- .showInputMethodPicker();
- break;
- case POS_USER_DICTIONARY:
- launchUserDictionary();
- break;
- case POS_LAYOUT:
- launchChooseLayout();
- break;
- case POS_DICTIONARY:
- launchChooseDictionary();
- break;
- }
- }
- });
- builder.setTitle(getResources().getString(R.string.english_ime_name));
- mOptionsDialog = builder.create();
- Window window = mOptionsDialog.getWindow();
- WindowManager.LayoutParams lp = window.getAttributes();
- lp.token = mInputView.getWindowToken();
- lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
- window.setAttributes(lp);
- window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
- mOptionsDialog.show();
- }
-
- private void launchUserDictionary() {
- handleClose();
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setClass(NorwegianIME.this, UserDictionarySettings.class);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(intent);
- }
-
- private void launchChooseLayout() {
- CharSequence[] keyboardLayoutValues = getResources().getTextArray(R.array.keyboard_layouts_values);
- int selectedLayoutIndex = -1;
- for(int i = 0; i < keyboardLayoutValues.length; i++)
- if(Integer.parseInt(keyboardLayoutValues[i].toString()) == mKeyboardLayout)
- selectedLayoutIndex = i;
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("Change keyboard layout")
- .setCancelable(true)
- .setNegativeButton(android.R.string.cancel, null)
- .setSingleChoiceItems(R.array.keyboard_layouts, selectedLayoutIndex,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface di, int position) {
- changePreference(PREF_KEYBOARD_LAYOUT, getResources().getTextArray(R.array.keyboard_layouts_values)[position].toString());
- di.dismiss();
- }
- });
- mOptionsDialog = builder.create();
- Window window = mOptionsDialog.getWindow();
- WindowManager.LayoutParams lp = window.getAttributes();
- lp.token = mInputView.getWindowToken();
- lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
- window.setAttributes(lp);
- window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
- mOptionsDialog.show();
- }
- private void launchChooseDictionary() {
- int selectedDictionaryIndex = -1;
- for(int i = 0; i < mAvailableDictionaryValues.length; i++)
- if(mDictionary.equals(mAvailableDictionaryValues[i]))
- selectedDictionaryIndex = i;
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("Change dictionary")
- .setCancelable(true)
- .setNegativeButton(android.R.string.cancel, null)
- .setSingleChoiceItems(mAvailableDictionaries, selectedDictionaryIndex,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface di, int position) {
- changePreference(PREF_DICTIONARY, mAvailableDictionaryValues[position].toString());
- di.dismiss();
- }
- });
- mOptionsDialog = builder.create();
- Window window = mOptionsDialog.getWindow();
- WindowManager.LayoutParams lp = window.getAttributes();
- lp.token = mInputView.getWindowToken();
- lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
- window.setAttributes(lp);
- window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
- mOptionsDialog.show();
- }
-
- private void changePreference(String preference, String value) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(NorwegianIME.this);
- SharedPreferences.Editor editor = sp.edit();
- editor.putString(preference, value);
- editor.commit();
- onStartInputView(getCurrentInputEditorInfo(), true);
- }
-
- private void changePreference(String preference, boolean value) {
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(NorwegianIME.this);
- SharedPreferences.Editor editor = sp.edit();
- editor.putBoolean(preference, value);
- editor.commit();
- onStartInputView(getCurrentInputEditorInfo(), true);
- }
- private void changeKeyboardMode() {
- mKeyboardSwitcher.toggleSymbols();
- if (mCapsLock && mKeyboardSwitcher.isAlphabetMode()) {
- ((NorwegianKeyboard) mInputView.getKeyboard()).setShiftLocked(mCapsLock);
- }
- updateShiftKeyState(getCurrentInputEditorInfo());
- }
-
- @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
- super.dump(fd, fout, args);
-
- final Printer p = new PrintWriterPrinter(fout);
- p.println("NorwegianIME state :");
- p.println(" Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode());
- p.println(" mCapsLock=" + mCapsLock);
- p.println(" mComposing=" + mComposing.toString());
- p.println(" mPredictionOn=" + mPredictionOn);
- p.println(" mCorrectionMode=" + mCorrectionMode);
- p.println(" mPredicting=" + mPredicting);
- p.println(" mAutoCorrectOn=" + mAutoCorrectOn);
- p.println(" mAutoSpace=" + mAutoSpace);
- p.println(" mCompletionOn=" + mCompletionOn);
- p.println(" TextEntryState.state=" + TextEntryState.getState());
- p.println(" mSoundOn=" + mSoundOn);
- p.println(" mVibrateOn=" + mVibrateOn);
- p.println(" mKeyboardLayout=" + mKeyboardLayout);
- }
- // Characters per second measurement
-
- private static final boolean PERF_DEBUG = false;
- private long mLastCpsTime;
- private static final int CPS_BUFFER_SIZE = 16;
- private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE];
- private int mCpsIndex;
-
- private void measureCps() {
- if (!NorwegianIME.PERF_DEBUG) return;
- long now = System.currentTimeMillis();
- if (mLastCpsTime == 0) mLastCpsTime = now - 100; // Initial
- mCpsIntervals[mCpsIndex] = now - mLastCpsTime;
- mLastCpsTime = now;
- mCpsIndex = (mCpsIndex + 1) % CPS_BUFFER_SIZE;
- long total = 0;
- for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i];
- System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total));
- }
- class AutoDictionary extends ExpandableDictionary {
- // If the user touches a typed word 2 times or more, it will become valid.
- private int VALIDITY_THRESHOLD = 2 * FREQUENCY_FOR_PICKED;
- // If the user touches a typed word 5 times or more, it will be added to the user dict.
- private int PROMOTION_THRESHOLD = 5 * FREQUENCY_FOR_PICKED;
- public AutoDictionary(Context context) {
- super(context);
- this.loadSettings();
- }
-
- public void loadSettings() {
- VALIDITY_THRESHOLD = mAutoDictionaryLimit * FREQUENCY_FOR_PICKED;
- PROMOTION_THRESHOLD = mAutoDictionaryLimit * FREQUENCY_FOR_PICKED;
- }
- @Override
- public boolean isValidWord(CharSequence word) {
- if(!mAutoDictionaryCaseSensitive)
- word = word.toString().toLowerCase();
- final int frequency = getWordFrequency(word);
- return frequency >= VALIDITY_THRESHOLD;
- }
- @Override
- public void addWord(String word, int addFrequency) {
- if(!mAutoDictionaryCaseSensitive)
- word = word.toLowerCase();
- final int length = word.length();
- // Don't add very short or very long words.
- if (length < 2 || length > getMaxWordLength()) return;
- final int freq = getWordFrequency(word);
- int newFreq = freq == -1 ? addFrequency : freq + addFrequency;
- super.addWord(word, newFreq);
- if (newFreq >= PROMOTION_THRESHOLD) {
- NorwegianIME.this.promoteToUserDictionary(word, FREQUENCY_FOR_AUTO_ADD);
- }
- }
- }
-
- private void createLetterSymbolArray() {
- validKeyCodes = new ArrayList<Integer>();
- letterSymbolArray = new HashMap<Integer, Integer>();
- letterSymbolArray.put(97, 64);
- letterSymbolArray.put(98, 59);
- letterSymbolArray.put(99, 39);
- letterSymbolArray.put(100, 36);
- letterSymbolArray.put(101, 51);
- letterSymbolArray.put(102, 37);
- letterSymbolArray.put(103, 38);
- letterSymbolArray.put(104, 42);
- letterSymbolArray.put(105, 56);
- letterSymbolArray.put(106, 45);
- letterSymbolArray.put(107, 43);
- letterSymbolArray.put(108, 40);
- letterSymbolArray.put(109, 63);
- letterSymbolArray.put(110, 47);
- letterSymbolArray.put(111, 57);
- letterSymbolArray.put(112, 48);
- letterSymbolArray.put(113, 49);
- letterSymbolArray.put(114, 52);
- letterSymbolArray.put(115, 35);
- letterSymbolArray.put(116, 53);
- letterSymbolArray.put(117, 55);
- letterSymbolArray.put(118, 58);
- letterSymbolArray.put(119, 50);
- letterSymbolArray.put(120, 34);
- letterSymbolArray.put(121, 54);
- letterSymbolArray.put(122, 33);
-
- switch(mKeyboardLayout) {
- case 1:
- case 5:
- case 6:
- letterSymbolArray.put(230, 41);
- letterSymbolArray.put(248, 95);
- validKeyCodes.clear();
- validKeyCodes.add(230);
- validKeyCodes.add(248);
- break;
- case 3:
- case 4:
- letterSymbolArray.put(228, 95);
- letterSymbolArray.put(246, 41);
- validKeyCodes.clear();
- validKeyCodes.add(228);
- validKeyCodes.add(246);
- break;
- case 7:
- letterSymbolArray.put(121, 33);
- letterSymbolArray.put(122, 54);
- letterSymbolArray.put(228, 95);
- letterSymbolArray.put(246, 41);
- validKeyCodes.clear();
- validKeyCodes.add(228);
- validKeyCodes.add(246);
- break;
- case 8:
- letterSymbolArray.put(225, 49);
- letterSymbolArray.put(353, 50);
- letterSymbolArray.put(359, 54);
- letterSymbolArray.put(248, 41);
- letterSymbolArray.put(230, 95);
- letterSymbolArray.put(382, 33);
- letterSymbolArray.put(122, 34);
- letterSymbolArray.put(269, 39);
- letterSymbolArray.put(99, 58);
- letterSymbolArray.put(118, 59);
- letterSymbolArray.put(98, 47);
- letterSymbolArray.put(110, 63);
- validKeyCodes.clear();
- validKeyCodes.add(225);
- validKeyCodes.add(230);
- validKeyCodes.add(248);
- validKeyCodes.add(269);
- validKeyCodes.add(353);
- validKeyCodes.add(359);
- validKeyCodes.add(382);
- break;
- default:
- letterSymbolArray.put(230, 95);
- letterSymbolArray.put(248, 41);
- validKeyCodes.clear();
- validKeyCodes.add(230);
- validKeyCodes.add(248);
- break;
- }
- }
- }