Use MoreKeySpecParser to parse puctuations strip resources
This change also * Doesn't use Key.getRtlParenthesisCode to get correct parentheses code in RTL context. Intead uses the outputText feature of moreKeys specification. * Move CVS string parser from KeyStyles to Utils. Bug: 5948247 Change-Id: I45752c7d01b4f7d3f3da900b110a2185b336a1f0main
parent
a5c96f376a
commit
ff858c7ff5
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<!-- The all letters need to be mirrored are found at
|
||||||
|
http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedBinaryProperties.txt -->
|
||||||
|
<!-- Symbols that are suggested between words -->
|
||||||
|
<string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(|),)|(,\u0027,-,/,@,_</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
/*
|
||||||
|
**
|
||||||
|
** Copyright 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.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
|
<!-- The all letters need to be mirrored are found at
|
||||||
|
http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedBinaryProperties.txt -->
|
||||||
|
<!-- Symbols that are suggested between words -->
|
||||||
|
<string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(|),)|(,\u0027,-,/,@,_</string>
|
||||||
|
</resources>
|
|
@ -19,7 +19,7 @@
|
||||||
-->
|
-->
|
||||||
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<!-- Symbols that are suggested between words -->
|
<!-- Symbols that are suggested between words -->
|
||||||
<string name="suggested_punctuations">!?,:;\u0022()\u0027-/@_</string>
|
<string name="suggested_punctuations">!,?,\\,,:,;,\u0022,(,),\u0027,-,/,@,_</string>
|
||||||
<!-- Symbols that should be swapped with a magic space -->
|
<!-- Symbols that should be swapped with a magic space -->
|
||||||
<string name="magic_space_swapping_symbols">.,;:!?)]}\u0022</string>
|
<string name="magic_space_swapping_symbols">.,;:!?)]}\u0022</string>
|
||||||
<!-- Symbols that should strip a magic space -->
|
<!-- Symbols that should strip a magic space -->
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package com.android.inputmethod.keyboard.internal;
|
package com.android.inputmethod.keyboard.internal;
|
||||||
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
@ -28,7 +27,6 @@ import com.android.inputmethod.latin.XmlParseUtils;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class KeyStyles {
|
public class KeyStyles {
|
||||||
|
@ -74,63 +72,8 @@ public class KeyStyles {
|
||||||
protected static String[] parseStringArray(TypedArray a, int index) {
|
protected static String[] parseStringArray(TypedArray a, int index) {
|
||||||
if (!a.hasValue(index))
|
if (!a.hasValue(index))
|
||||||
return null;
|
return null;
|
||||||
return parseCsvString(a.getString(index), a.getResources(), R.string.english_ime_name);
|
return Utils.parseCsvString(
|
||||||
}
|
a.getString(index), a.getResources(), R.string.english_ime_name);
|
||||||
}
|
|
||||||
|
|
||||||
/* package for test */
|
|
||||||
static String[] parseCsvString(String rawText, Resources res, int packageNameResId) {
|
|
||||||
final String text = Utils.resolveStringResource(rawText, res, packageNameResId);
|
|
||||||
final int size = text.length();
|
|
||||||
if (size == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (size == 1) {
|
|
||||||
return new String[] { text };
|
|
||||||
}
|
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
ArrayList<String> list = null;
|
|
||||||
int start = 0;
|
|
||||||
for (int pos = 0; pos < size; pos++) {
|
|
||||||
final char c = text.charAt(pos);
|
|
||||||
if (c == ',') {
|
|
||||||
if (list == null) {
|
|
||||||
list = new ArrayList<String>();
|
|
||||||
}
|
|
||||||
if (sb.length() == 0) {
|
|
||||||
list.add(text.substring(start, pos));
|
|
||||||
} else {
|
|
||||||
list.add(sb.toString());
|
|
||||||
sb.setLength(0);
|
|
||||||
}
|
|
||||||
start = pos + 1;
|
|
||||||
continue;
|
|
||||||
} else if (c == Utils.ESCAPE_CHAR) {
|
|
||||||
if (start == pos) {
|
|
||||||
// Skip escape character at the beginning of the value.
|
|
||||||
start++;
|
|
||||||
pos++;
|
|
||||||
} else {
|
|
||||||
if (start < pos && sb.length() == 0) {
|
|
||||||
sb.append(text.subSequence(start, pos));
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
if (pos < size) {
|
|
||||||
sb.append(text.charAt(pos));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (sb.length() > 0) {
|
|
||||||
sb.append(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (list == null) {
|
|
||||||
return new String[] {
|
|
||||||
sb.length() > 0 ? sb.toString() : text.substring(start)
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
list.add(sb.length() > 0 ? sb.toString() : text.substring(start));
|
|
||||||
return list.toArray(new String[list.size()]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,6 @@ import com.android.inputmethod.compat.SuggestionSpanUtils;
|
||||||
import com.android.inputmethod.compat.VibratorCompatWrapper;
|
import com.android.inputmethod.compat.VibratorCompatWrapper;
|
||||||
import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
|
import com.android.inputmethod.deprecated.LanguageSwitcherProxy;
|
||||||
import com.android.inputmethod.deprecated.VoiceProxy;
|
import com.android.inputmethod.deprecated.VoiceProxy;
|
||||||
import com.android.inputmethod.keyboard.Key;
|
|
||||||
import com.android.inputmethod.keyboard.Keyboard;
|
import com.android.inputmethod.keyboard.Keyboard;
|
||||||
import com.android.inputmethod.keyboard.KeyboardActionListener;
|
import com.android.inputmethod.keyboard.KeyboardActionListener;
|
||||||
import com.android.inputmethod.keyboard.KeyboardId;
|
import com.android.inputmethod.keyboard.KeyboardId;
|
||||||
|
@ -1897,16 +1896,13 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
// So, LatinImeLogger logs "" as a user's input.
|
// So, LatinImeLogger logs "" as a user's input.
|
||||||
LatinImeLogger.logOnManualSuggestion(
|
LatinImeLogger.logOnManualSuggestion(
|
||||||
"", suggestion.toString(), index, suggestions.mWords);
|
"", suggestion.toString(), index, suggestions.mWords);
|
||||||
|
final CharSequence outputText = mSettingsValues.mSuggestPuncOutputTextList
|
||||||
|
.getWord(index);
|
||||||
|
final int primaryCode = outputText.charAt(0);
|
||||||
// Find out whether the previous character is a space. If it is, as a special case
|
// Find out whether the previous character is a space. If it is, as a special case
|
||||||
// for punctuation entered through the suggestion strip, it should be swapped
|
// for punctuation entered through the suggestion strip, it should be swapped
|
||||||
// if it was a magic or a weak space. This is meant to help in case the user
|
// if it was a magic or a weak space. This is meant to help in case the user
|
||||||
// pressed space on purpose of displaying the suggestion strip punctuation.
|
// pressed space on purpose of displaying the suggestion strip punctuation.
|
||||||
final int rawPrimaryCode = suggestion.charAt(0);
|
|
||||||
// Maybe apply the "bidi mirrored" conversions for parentheses
|
|
||||||
final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
|
|
||||||
final boolean isRtl = keyboard != null && keyboard.mIsRtlKeyboard;
|
|
||||||
final int primaryCode = Key.getRtlParenthesisCode(rawPrimaryCode, isRtl);
|
|
||||||
|
|
||||||
insertPunctuationFromSuggestionStrip(ic, primaryCode);
|
insertPunctuationFromSuggestionStrip(ic, primaryCode);
|
||||||
// TODO: the following endBatchEdit seems useless, check
|
// TODO: the following endBatchEdit seems useless, check
|
||||||
if (ic != null) {
|
if (ic != null) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import android.view.inputmethod.EditorInfo;
|
||||||
|
|
||||||
import com.android.inputmethod.compat.InputTypeCompatUtils;
|
import com.android.inputmethod.compat.InputTypeCompatUtils;
|
||||||
import com.android.inputmethod.compat.VibratorCompatWrapper;
|
import com.android.inputmethod.compat.VibratorCompatWrapper;
|
||||||
|
import com.android.inputmethod.keyboard.internal.MoreKeySpecParser;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -36,8 +37,9 @@ public class SettingsValues {
|
||||||
public final int mDelayUpdateOldSuggestions;
|
public final int mDelayUpdateOldSuggestions;
|
||||||
public final String mMagicSpaceStrippers;
|
public final String mMagicSpaceStrippers;
|
||||||
public final String mMagicSpaceSwappers;
|
public final String mMagicSpaceSwappers;
|
||||||
public final String mSuggestPuncs;
|
private final String mSuggestPuncs;
|
||||||
public final SuggestedWords mSuggestPuncList;
|
public final SuggestedWords mSuggestPuncList;
|
||||||
|
public final SuggestedWords mSuggestPuncOutputTextList;
|
||||||
private final String mSymbolsExcludedFromWordSeparators;
|
private final String mSymbolsExcludedFromWordSeparators;
|
||||||
public final String mWordSeparators;
|
public final String mWordSeparators;
|
||||||
public final CharSequence mHintToSaveText;
|
public final CharSequence mHintToSaveText;
|
||||||
|
@ -98,9 +100,11 @@ public class SettingsValues {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mSuggestPuncs = res.getString(R.string.suggested_punctuations);
|
final String[] suggestPuncsSpec = Utils.parseCsvString(
|
||||||
// TODO: it would be nice not to recreate this each time we change the configuration
|
res.getString(R.string.suggested_punctuations), res, R.string.english_ime_name);
|
||||||
mSuggestPuncList = createSuggestPuncList(mSuggestPuncs);
|
mSuggestPuncs = createSuggestPuncs(suggestPuncsSpec);
|
||||||
|
mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
|
||||||
|
mSuggestPuncOutputTextList = createSuggestPuncOutputTextList(suggestPuncsSpec);
|
||||||
mSymbolsExcludedFromWordSeparators =
|
mSymbolsExcludedFromWordSeparators =
|
||||||
res.getString(R.string.symbols_excluded_from_word_separators);
|
res.getString(R.string.symbols_excluded_from_word_separators);
|
||||||
mWordSeparators = createWordSeparators(mMagicSpaceStrippers, mMagicSpaceSwappers,
|
mWordSeparators = createWordSeparators(mMagicSpaceStrippers, mMagicSpaceSwappers,
|
||||||
|
@ -150,11 +154,36 @@ public class SettingsValues {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper functions to create member values.
|
// Helper functions to create member values.
|
||||||
private static SuggestedWords createSuggestPuncList(final String puncs) {
|
private static String createSuggestPuncs(final String[] puncs) {
|
||||||
SuggestedWords.Builder builder = new SuggestedWords.Builder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
if (puncs != null) {
|
if (puncs != null) {
|
||||||
for (int i = 0; i < puncs.length(); i++) {
|
for (final String puncSpec : puncs) {
|
||||||
builder.addWord(puncs.subSequence(i, i + 1));
|
sb.append(MoreKeySpecParser.getLabel(puncSpec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SuggestedWords createSuggestPuncList(final String[] puncs) {
|
||||||
|
final SuggestedWords.Builder builder = new SuggestedWords.Builder();
|
||||||
|
if (puncs != null) {
|
||||||
|
for (final String puncSpec : puncs) {
|
||||||
|
builder.addWord(MoreKeySpecParser.getLabel(puncSpec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.setIsPunctuationSuggestions().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SuggestedWords createSuggestPuncOutputTextList(final String[] puncs) {
|
||||||
|
final SuggestedWords.Builder builder = new SuggestedWords.Builder();
|
||||||
|
if (puncs != null) {
|
||||||
|
for (final String puncSpec : puncs) {
|
||||||
|
final String outputText = MoreKeySpecParser.getOutputText(puncSpec);
|
||||||
|
if (outputText != null) {
|
||||||
|
builder.addWord(outputText);
|
||||||
|
} else {
|
||||||
|
builder.addWord(MoreKeySpecParser.getLabel(puncSpec));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.setIsPunctuationSuggestions().build();
|
return builder.setIsPunctuationSuggestions().build();
|
||||||
|
|
|
@ -857,4 +857,59 @@ public class Utils {
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String[] parseCsvString(String rawText, Resources res, int packageNameResId) {
|
||||||
|
final String text = resolveStringResource(rawText, res, packageNameResId);
|
||||||
|
final int size = text.length();
|
||||||
|
if (size == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (size == 1) {
|
||||||
|
return new String[] { text };
|
||||||
|
}
|
||||||
|
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
ArrayList<String> list = null;
|
||||||
|
int start = 0;
|
||||||
|
for (int pos = 0; pos < size; pos++) {
|
||||||
|
final char c = text.charAt(pos);
|
||||||
|
if (c == ',') {
|
||||||
|
if (list == null) {
|
||||||
|
list = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
if (sb.length() == 0) {
|
||||||
|
list.add(text.substring(start, pos));
|
||||||
|
} else {
|
||||||
|
list.add(sb.toString());
|
||||||
|
sb.setLength(0);
|
||||||
|
}
|
||||||
|
start = pos + 1;
|
||||||
|
continue;
|
||||||
|
} else if (c == ESCAPE_CHAR) {
|
||||||
|
if (start == pos) {
|
||||||
|
// Skip escape character at the beginning of the value.
|
||||||
|
start++;
|
||||||
|
pos++;
|
||||||
|
} else {
|
||||||
|
if (start < pos && sb.length() == 0) {
|
||||||
|
sb.append(text.subSequence(start, pos));
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
if (pos < size) {
|
||||||
|
sb.append(text.charAt(pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (sb.length() > 0) {
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (list == null) {
|
||||||
|
return new String[] {
|
||||||
|
sb.length() > 0 ? sb.toString() : text.substring(start)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
list.add(sb.length() > 0 ? sb.toString() : text.substring(start));
|
||||||
|
return list.toArray(new String[list.size()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import android.content.res.Resources;
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.Utils;
|
||||||
import com.android.inputmethod.latin.tests.R;
|
import com.android.inputmethod.latin.tests.R;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -39,7 +40,7 @@ public class KeyStylesTests extends AndroidTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertTextArray(String message, String value, String ... expected) {
|
private void assertTextArray(String message, String value, String ... expected) {
|
||||||
final String actual[] = KeyStyles.parseCsvString(value, mTestResources,
|
final String actual[] = Utils.parseCsvString(value, mTestResources,
|
||||||
R.string.empty_string);
|
R.string.empty_string);
|
||||||
if (expected.length == 0) {
|
if (expected.length == 0) {
|
||||||
assertNull(message, actual);
|
assertNull(message, actual);
|
||||||
|
|
Loading…
Reference in New Issue