Fix quotation marks
This change * Allows snap back from symbols shifted to symbol layout. * Add "left single", "right single", "single low" and "single high reversed" quotation marks to popup characters of "single quote". * Add "double low" and "double high reversed" quatation marks to popup characters of "double quote". * Add "prime" and "double prime" to popup characters of "degree". * Disable non-ASCII key of symbol more layout on passowrd input. Bug: 4345054 Bug: 4347045 Change-Id: I8168ce6a74a9536e4966f7f9d1099ac0132925c7
This commit is contained in:
parent
1123bcaf2e
commit
717cef79ea
8 changed files with 146 additions and 44 deletions
|
@ -211,9 +211,10 @@
|
|||
latin:keyLabel="-" />
|
||||
</case>
|
||||
<default>
|
||||
<!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
|
||||
<Key
|
||||
latin:keyLabel="""
|
||||
latin:popupCharacters="“,”,«,»,˝" />
|
||||
latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛" />
|
||||
<Key
|
||||
latin:keyLabel="_" />
|
||||
</default>
|
||||
|
|
|
@ -99,7 +99,8 @@
|
|||
latin:popupCharacters="↑,↓,←,→" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="°" />
|
||||
latin:keyLabel="°"
|
||||
latin:popupCharacters="′,″" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="±"
|
||||
|
|
|
@ -312,4 +312,27 @@
|
|||
latin:popupCharacters="@string/alternates_for_smiley"
|
||||
latin:maxPopupKeyboardColumn="5"
|
||||
latin:parentStyle="functionalKeyStyle" />
|
||||
<switch>
|
||||
<case
|
||||
latin:passwordInput="true"
|
||||
>
|
||||
<key-style
|
||||
latin:styleName="nonPasswordSymbolKeyStyle"
|
||||
latin:enabled="false" />
|
||||
<key-style
|
||||
latin:styleName="nonPasswordFunctionalKeyStyle"
|
||||
latin:enabled="false"
|
||||
latin:parentStyle="functionalKeyStyle" />
|
||||
</case>
|
||||
<!-- latin:passwordInput="false" -->
|
||||
<default>
|
||||
<key-style
|
||||
latin:styleName="nonPasswordSymbolKeyStyle"
|
||||
latin:enabled="true" />
|
||||
<key-style
|
||||
latin:styleName="nonPasswordFunctionalKeyStyle"
|
||||
latin:enabled="true"
|
||||
latin:parentStyle="functionalKeyStyle" />
|
||||
</default>
|
||||
</switch>
|
||||
</merge>
|
|
@ -105,12 +105,14 @@
|
|||
<Key
|
||||
latin:keyLabel="!"
|
||||
latin:popupCharacters="¡" />
|
||||
<!-- Note: DroidSans doesn't have double-high-reversed-quotation '\u201f' glyph. -->
|
||||
<Key
|
||||
latin:keyLabel="""
|
||||
latin:popupCharacters="“,”,«,»,˝" />
|
||||
latin:popupCharacters="“,”,„,‟,«,»"
|
||||
latin:maxPopupKeyboardColumn="6" />
|
||||
<Key
|
||||
latin:keyLabel="\'"
|
||||
latin:popupCharacters="‘,’" />
|
||||
latin:popupCharacters="‘,’,‚,‛,´" />
|
||||
<Key
|
||||
latin:keyLabel=":" />
|
||||
<Key
|
||||
|
|
|
@ -42,16 +42,21 @@
|
|||
<Key
|
||||
latin:keyLabel="|" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="•"
|
||||
latin:popupCharacters="♪,♥,♠,♦,♣" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="√" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="π"
|
||||
latin:popupCharacters="Π" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="÷" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="×" />
|
||||
<Key
|
||||
latin:keyLabel="{" />
|
||||
|
@ -64,13 +69,18 @@
|
|||
latin:keyStyle="nonSpecialBackgroundTabKeyStyle"
|
||||
latin:keyEdgeFlags="left" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="£" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="¢" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="€" />
|
||||
<Key
|
||||
latin:keyLabel="°" />
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="°"
|
||||
latin:popupCharacters="′,″" />
|
||||
<Key
|
||||
latin:keyLabel="^"
|
||||
latin:popupCharacters="↑,↓,←,→" />
|
||||
|
@ -92,12 +102,16 @@
|
|||
latin:visualInsetsRight="1%p"
|
||||
latin:keyEdgeFlags="left" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="™" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="®" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="©" />
|
||||
<Key
|
||||
latin:keyStyle="nonPasswordSymbolKeyStyle"
|
||||
latin:keyLabel="¶"
|
||||
latin:popupCharacters="§" />
|
||||
<Key
|
||||
|
|
|
@ -34,13 +34,14 @@
|
|||
latin:keyEdgeFlags="left" />
|
||||
<Key
|
||||
latin:keyLabel="„"
|
||||
latin:keyStyle="functionalKeyStyle" />
|
||||
latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
|
||||
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
|
||||
<Key
|
||||
latin:keyStyle="spaceKeyStyle"
|
||||
latin:keyWidth="40%p" />
|
||||
<Key
|
||||
latin:keyLabel="…"
|
||||
latin:keyStyle="functionalKeyStyle" />
|
||||
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
|
||||
<switch>
|
||||
<case
|
||||
latin:mode="im"
|
||||
|
@ -69,13 +70,14 @@
|
|||
latin:keyStyle="settingsKeyStyle" />
|
||||
<Key
|
||||
latin:keyLabel="„"
|
||||
latin:keyStyle="functionalKeyStyle" />
|
||||
latin:popupCharacters="“,”,„,‟,«,»,‘,’,‚,‛"
|
||||
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
|
||||
<Key
|
||||
latin:keyStyle="spaceKeyStyle"
|
||||
latin:keyWidth="30%p" />
|
||||
<Key
|
||||
latin:keyLabel="…"
|
||||
latin:keyStyle="functionalKeyStyle" />
|
||||
latin:keyStyle="nonPasswordFunctionalKeyStyle" />
|
||||
<switch>
|
||||
<case
|
||||
latin:mode="im"
|
||||
|
|
|
@ -57,6 +57,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
private LatinKeyboardView mInputView;
|
||||
private LatinIME mInputMethodService;
|
||||
|
||||
// TODO: Combine these key state objects with auto mode switch state.
|
||||
private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift");
|
||||
private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol");
|
||||
|
||||
|
@ -75,13 +76,17 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
private boolean mVoiceKeyEnabled;
|
||||
private boolean mVoiceButtonOnPrimary;
|
||||
|
||||
private static final int AUTO_MODE_SWITCH_STATE_ALPHA = 0;
|
||||
private static final int AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN = 1;
|
||||
private static final int AUTO_MODE_SWITCH_STATE_SYMBOL = 2;
|
||||
// TODO: Encapsulate these state handling to separate class and combine with ShiftKeyState
|
||||
// and ModifierKeyState.
|
||||
private static final int SWITCH_STATE_ALPHA = 0;
|
||||
private static final int SWITCH_STATE_SYMBOL_BEGIN = 1;
|
||||
private static final int SWITCH_STATE_SYMBOL = 2;
|
||||
// The following states are used only on the distinct multi-touch panel devices.
|
||||
private static final int AUTO_MODE_SWITCH_STATE_MOMENTARY = 3;
|
||||
private static final int AUTO_MODE_SWITCH_STATE_CHORDING = 4;
|
||||
private int mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
|
||||
private static final int SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL = 3;
|
||||
private static final int SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE = 4;
|
||||
private static final int SWITCH_STATE_CHORDING_ALPHA = 5;
|
||||
private static final int SWITCH_STATE_CHORDING_SYMBOL = 6;
|
||||
private int mSwitchState = SWITCH_STATE_ALPHA;
|
||||
|
||||
// Indicates whether or not we have the settings key in option of settings
|
||||
private boolean mSettingsKeyEnabledInSettings;
|
||||
|
@ -124,7 +129,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
|
||||
public void loadKeyboard(EditorInfo attribute, boolean voiceKeyEnabled,
|
||||
boolean voiceButtonOnPrimary) {
|
||||
mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
|
||||
mSwitchState = SWITCH_STATE_ALPHA;
|
||||
try {
|
||||
loadKeyboardInternal(attribute, voiceKeyEnabled, voiceButtonOnPrimary, false);
|
||||
} catch (RuntimeException e) {
|
||||
|
@ -465,6 +470,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
// In symbol mode, just toggle symbol and symbol more keyboard.
|
||||
shiftKeyState.onPress();
|
||||
toggleShift();
|
||||
mSwitchState = SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -496,6 +502,12 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
// transited from automatic temporary upper case.
|
||||
toggleShift();
|
||||
}
|
||||
} else {
|
||||
// In symbol mode, snap back to the previous keyboard mode if the user chords the shift
|
||||
// key and another key, then releases the shift key.
|
||||
if (mSwitchState == SWITCH_STATE_CHORDING_SYMBOL) {
|
||||
toggleShift();
|
||||
}
|
||||
}
|
||||
shiftKeyState.onRelease();
|
||||
}
|
||||
|
@ -510,7 +522,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
+ " symbolKeyState=" + mSymbolKeyState);
|
||||
changeKeyboardMode();
|
||||
mSymbolKeyState.onPress();
|
||||
mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_MOMENTARY;
|
||||
mSwitchState = SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL;
|
||||
}
|
||||
|
||||
public void onReleaseSymbol() {
|
||||
|
@ -522,9 +534,10 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
|
||||
+ " symbolKeyState=" + mSymbolKeyState);
|
||||
// Snap back to the previous keyboard mode if the user chords the mode change key and
|
||||
// other key, then released the mode change key.
|
||||
if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_CHORDING)
|
||||
// another key, then releases the mode change key.
|
||||
if (mSwitchState == SWITCH_STATE_CHORDING_ALPHA) {
|
||||
changeKeyboardMode();
|
||||
}
|
||||
mSymbolKeyState.onRelease();
|
||||
}
|
||||
|
||||
|
@ -543,8 +556,13 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
|
||||
public void onCancelInput() {
|
||||
// Snap back to the previous keyboard mode if the user cancels sliding input.
|
||||
if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY && getPointerCount() == 1)
|
||||
changeKeyboardMode();
|
||||
if (getPointerCount() == 1) {
|
||||
if (mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL) {
|
||||
changeKeyboardMode();
|
||||
} else if (mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE) {
|
||||
toggleShift();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleShiftInSymbol() {
|
||||
|
@ -567,8 +585,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
setKeyboard(keyboard);
|
||||
}
|
||||
|
||||
public boolean isInMomentaryAutoModeSwitchState() {
|
||||
return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY;
|
||||
public boolean isInMomentarySwitchState() {
|
||||
return mSwitchState == SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL
|
||||
|| mSwitchState == SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE;
|
||||
}
|
||||
|
||||
public boolean isVibrateAndSoundFeedbackRequired() {
|
||||
|
@ -582,9 +601,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
private void toggleKeyboardMode() {
|
||||
loadKeyboardInternal(mAttribute, mVoiceKeyEnabled, mVoiceButtonOnPrimary, !mIsSymbols);
|
||||
if (mIsSymbols) {
|
||||
mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
|
||||
mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
|
||||
} else {
|
||||
mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
|
||||
mSwitchState = SWITCH_STATE_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -596,28 +615,52 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
return mInputView != null && mInputView.hasDistinctMultitouch();
|
||||
}
|
||||
|
||||
private static boolean isSpaceCharacter(int c) {
|
||||
return c == Keyboard.CODE_SPACE || c == Keyboard.CODE_ENTER;
|
||||
}
|
||||
|
||||
private static boolean isQuoteCharacter(int c) {
|
||||
// Apostrophe, quotation mark.
|
||||
if (c == '\'' || c == '"')
|
||||
return true;
|
||||
// \u2018: Left single quotation mark
|
||||
// \u2019: Right single quotation mark
|
||||
// \u201a: Single low-9 quotation mark
|
||||
// \u201b: Single high-reversed-9 quotation mark
|
||||
// \u201c: Left double quotation mark
|
||||
// \u201d: Right double quotation mark
|
||||
// \u201e: Double low-9 quotation mark
|
||||
// \u201f: Double high-reversed-9 quotation mark
|
||||
if (c >= '\u2018' && c <= '\u201f')
|
||||
return true;
|
||||
// \u00ab: Left-pointing double angle quotation mark
|
||||
// \u00bb: Right-pointing double angle quotation mark
|
||||
if (c == '\u00ab' || c == '\u00bb')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates state machine to figure out when to automatically snap back to the previous mode.
|
||||
*/
|
||||
public void onKey(int key) {
|
||||
public void onKey(int code) {
|
||||
if (DEBUG_STATE)
|
||||
Log.d(TAG, "onKey: code=" + key + " autoModeSwitchState=" + mAutoModeSwitchState
|
||||
Log.d(TAG, "onKey: code=" + code + " switchState=" + mSwitchState
|
||||
+ " pointers=" + getPointerCount());
|
||||
switch (mAutoModeSwitchState) {
|
||||
case AUTO_MODE_SWITCH_STATE_MOMENTARY:
|
||||
switch (mSwitchState) {
|
||||
case SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL:
|
||||
// Only distinct multi touch devices can be in this state.
|
||||
// On non-distinct multi touch devices, mode change key is handled by
|
||||
// {@link LatinIME#onCodeInput}, not by {@link LatinIME#onPress} and
|
||||
// {@link LatinIME#onRelease}. So, on such devices, {@link #mAutoModeSwitchState} starts
|
||||
// from {@link #AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN}, or
|
||||
// {@link #AUTO_MODE_SWITCH_STATE_ALPHA}, not from
|
||||
// {@link #AUTO_MODE_SWITCH_STATE_MOMENTARY}.
|
||||
if (key == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
|
||||
// {@link LatinIME#onRelease}. So, on such devices, {@link #mSwitchState} starts
|
||||
// from {@link #SWITCH_STATE_SYMBOL_BEGIN}, or {@link #SWITCH_STATE_ALPHA}, not from
|
||||
// {@link #SWITCH_STATE_MOMENTARY}.
|
||||
if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
|
||||
// Detected only the mode change key has been pressed, and then released.
|
||||
if (mIsSymbols) {
|
||||
mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
|
||||
mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
|
||||
} else {
|
||||
mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
|
||||
mSwitchState = SWITCH_STATE_ALPHA;
|
||||
}
|
||||
} else if (getPointerCount() == 1) {
|
||||
// Snap back to the previous keyboard mode if the user pressed the mode change key
|
||||
|
@ -628,18 +671,34 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
|||
} else {
|
||||
// Chording input is being started. The keyboard mode will be snapped back to the
|
||||
// previous mode in {@link onReleaseSymbol} when the mode change key is released.
|
||||
mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_CHORDING;
|
||||
mSwitchState = SWITCH_STATE_CHORDING_ALPHA;
|
||||
}
|
||||
break;
|
||||
case AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN:
|
||||
if (key != Keyboard.CODE_SPACE && key != Keyboard.CODE_ENTER && key >= 0) {
|
||||
mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL;
|
||||
case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE:
|
||||
if (code == Keyboard.CODE_SHIFT) {
|
||||
// Detected only the shift key has been pressed on symbol layout, and then released.
|
||||
mSwitchState = SWITCH_STATE_SYMBOL_BEGIN;
|
||||
} else if (getPointerCount() == 1) {
|
||||
// Snap back to the previous keyboard mode if the user pressed the shift key on
|
||||
// symbol mode and slid to other key, then released the finger.
|
||||
toggleShift();
|
||||
mSwitchState = SWITCH_STATE_SYMBOL;
|
||||
} else {
|
||||
// Chording input is being started. The keyboard mode will be snapped back to the
|
||||
// previous mode in {@link onReleaseShift} when the shift key is released.
|
||||
mSwitchState = SWITCH_STATE_CHORDING_SYMBOL;
|
||||
}
|
||||
break;
|
||||
case AUTO_MODE_SWITCH_STATE_SYMBOL:
|
||||
case SWITCH_STATE_SYMBOL_BEGIN:
|
||||
if (!isSpaceCharacter(code) && code >= 0) {
|
||||
mSwitchState = SWITCH_STATE_SYMBOL;
|
||||
}
|
||||
break;
|
||||
case SWITCH_STATE_SYMBOL:
|
||||
case SWITCH_STATE_CHORDING_SYMBOL:
|
||||
// Snap back to alpha keyboard mode if user types one or more non-space/enter
|
||||
// characters followed by a space/enter.
|
||||
if (key == Keyboard.CODE_ENTER || key == Keyboard.CODE_SPACE) {
|
||||
// characters followed by a space/enter or quotation mark.
|
||||
if (isSpaceCharacter(code) || isQuoteCharacter(code)) {
|
||||
changeKeyboardMode();
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -662,7 +662,7 @@ public class PointerTracker {
|
|||
// We need not start long press timer on the key which has manual temporary upper case
|
||||
// code defined and the keyboard is in manual temporary upper case mode.
|
||||
return;
|
||||
} else if (mKeyboardSwitcher.isInMomentaryAutoModeSwitchState()) {
|
||||
} else if (mKeyboardSwitcher.isInMomentarySwitchState()) {
|
||||
// We use longer timeout for sliding finger input started from the symbols mode key.
|
||||
mHandler.startLongPressTimer(mLongPressKeyTimeout * 3, keyIndex, this);
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue