mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-19 05:39:10 +00:00
Merge branch 'Helium314:main' into optimize-build
This commit is contained in:
commit
8bb8b732d8
89 changed files with 1243 additions and 449 deletions
|
@ -100,8 +100,6 @@ __Planned features and improvements:__
|
|||
* Add and enable emoji dictionaries by default (if available for language)
|
||||
* Clearer / more intuitive arrangement of settings
|
||||
* Maybe hide some less used settings by default (similar to color customization)
|
||||
* Make use of the `.com` key in URL fields (currently only available for tablets)
|
||||
* With language-dependent TLDs
|
||||
* [Bug fixes](https://github.com/Helium314/HeliBoard/issues?q=is%3Aissue+is%3Aopen+label%3Abug)
|
||||
|
||||
__What will _not_ be added:__
|
||||
|
|
|
@ -6,15 +6,15 @@ plugins {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdk = 34
|
||||
compileSdk = 35
|
||||
buildToolsVersion = "34.0.0"
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "helium314.keyboard"
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
versionCode = 3000
|
||||
versionName = "3.0-alpha1"
|
||||
targetSdk = 35
|
||||
versionCode = 3003
|
||||
versionName = "3.0-alpha3"
|
||||
ndk {
|
||||
abiFilters.clear()
|
||||
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64"))
|
||||
|
@ -58,7 +58,7 @@ android {
|
|||
path = File("src/main/jni/Android.mk")
|
||||
}
|
||||
}
|
||||
ndkVersion = "26.2.11394342"
|
||||
ndkVersion = "28.0.13004108"
|
||||
|
||||
packagingOptions {
|
||||
jniLibs {
|
||||
|
@ -96,9 +96,8 @@ android {
|
|||
|
||||
dependencies {
|
||||
// androidx
|
||||
implementation("androidx.core:core-ktx:1.13.1")
|
||||
implementation("androidx.appcompat:appcompat:1.7.0")
|
||||
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
||||
implementation("androidx.core:core-ktx:1.15.0")
|
||||
implementation("androidx.recyclerview:recyclerview:1.4.0")
|
||||
implementation("androidx.autofill:autofill:1.1.0")
|
||||
|
||||
// kotlin
|
||||
|
@ -118,7 +117,7 @@ dependencies {
|
|||
testImplementation(kotlin("test"))
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("org.mockito:mockito-core:5.15.2")
|
||||
testImplementation("org.robolectric:robolectric:4.12.1")
|
||||
testImplementation("org.robolectric:robolectric:4.14.1")
|
||||
testImplementation("androidx.test:runner:1.6.2")
|
||||
testImplementation("androidx.test:core:1.6.1")
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
{ "$": "keyboard_state_selector", "emojiKeyEnabled": { "$": "keyboard_state_selector", "alphabet": { "label": "emoji" }}},
|
||||
{ "$": "keyboard_state_selector", "symbols": { "label": "numpad" }},
|
||||
{ "label": "space" },
|
||||
{ "label": "period", "labelFlags": 1073741824 },
|
||||
{ "label": "period" },
|
||||
{ "label": "action", "width": 0.15 }
|
||||
]
|
||||
]
|
||||
|
|
31
app/src/main/assets/layouts/main/central_kurdish.txt
Normal file
31
app/src/main/assets/layouts/main/central_kurdish.txt
Normal file
|
@ -0,0 +1,31 @@
|
|||
ق
|
||||
و
|
||||
ە
|
||||
ر
|
||||
ت
|
||||
ی
|
||||
ێ
|
||||
ئ
|
||||
ۆ
|
||||
پ
|
||||
|
||||
ا
|
||||
س
|
||||
ش
|
||||
د
|
||||
ف
|
||||
ھ|ه
|
||||
ژ
|
||||
ل
|
||||
ک
|
||||
گ
|
||||
|
||||
ز
|
||||
ع
|
||||
ح
|
||||
ج
|
||||
چ
|
||||
خ
|
||||
ب
|
||||
ن
|
||||
م
|
|
@ -8,7 +8,7 @@
|
|||
ш
|
||||
щ
|
||||
з
|
||||
х
|
||||
х ъ [ {
|
||||
|
||||
ф
|
||||
ы
|
||||
|
@ -20,7 +20,7 @@
|
|||
л
|
||||
д
|
||||
ж
|
||||
э
|
||||
э э́ ] }
|
||||
|
||||
я
|
||||
ч
|
||||
|
|
34
app/src/main/assets/layouts/main/russian_extended.txt
Normal file
34
app/src/main/assets/layouts/main/russian_extended.txt
Normal file
|
@ -0,0 +1,34 @@
|
|||
й
|
||||
ц
|
||||
у
|
||||
к
|
||||
е
|
||||
н
|
||||
г
|
||||
ш
|
||||
щ
|
||||
з
|
||||
х [ {
|
||||
ъ ] }
|
||||
|
||||
ф
|
||||
ы
|
||||
в
|
||||
а
|
||||
п
|
||||
р
|
||||
о
|
||||
л
|
||||
д
|
||||
ж
|
||||
э э́
|
||||
|
||||
я
|
||||
ч
|
||||
с
|
||||
м
|
||||
и
|
||||
т
|
||||
ь
|
||||
б <
|
||||
ю >
|
|
@ -8,7 +8,8 @@
|
|||
ш
|
||||
щ
|
||||
з
|
||||
х
|
||||
х [ {
|
||||
ї ] }
|
||||
|
||||
ф
|
||||
і
|
||||
|
@ -20,7 +21,7 @@
|
|||
л
|
||||
д
|
||||
ж
|
||||
є
|
||||
є ' "
|
||||
|
||||
я
|
||||
ч
|
||||
|
@ -30,4 +31,4 @@
|
|||
т
|
||||
ь
|
||||
б <
|
||||
ю >
|
||||
ю > ґ
|
||||
|
|
35
app/src/main/assets/layouts/main/ukrainian_extended.txt
Normal file
35
app/src/main/assets/layouts/main/ukrainian_extended.txt
Normal file
|
@ -0,0 +1,35 @@
|
|||
й
|
||||
ц
|
||||
у
|
||||
к
|
||||
е
|
||||
н
|
||||
г
|
||||
ш
|
||||
щ
|
||||
з
|
||||
х [ {
|
||||
ї ] }
|
||||
|
||||
ф
|
||||
і
|
||||
в
|
||||
а
|
||||
п
|
||||
р
|
||||
о
|
||||
л
|
||||
д
|
||||
ж
|
||||
є ' "
|
||||
' "
|
||||
|
||||
я
|
||||
ч
|
||||
с
|
||||
м
|
||||
и
|
||||
т
|
||||
ь
|
||||
б <
|
||||
ю > ґ
|
44
app/src/main/assets/layouts/number_row/number_row.json
Normal file
44
app/src/main/assets/layouts/number_row/number_row.json
Normal file
|
@ -0,0 +1,44 @@
|
|||
[
|
||||
[
|
||||
{ "$": "shift_state_selector",
|
||||
"manualOrLocked": { "label": "!" },
|
||||
"default": { "label": "1", "popup": { "relevant": [{ "label": "¹" }, { "label": "½" }, { "label": "⅓" }, { "label": "¼" }, { "label": "⅛" }] } }
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"manualOrLocked": { "label": "@" },
|
||||
"default": { "label": "2", "popup": { "relevant": [{ "label": "²" }, { "label": "⅔" }] } }
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"manualOrLocked": { "label": "#" },
|
||||
"default": { "label": "3", "popup": { "relevant": [{ "label": "³" }, { "label": "¾" }, { "label": "⅜" }] } }
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"manualOrLocked": { "label": "$" },
|
||||
"default": { "label": "4", "popup": { "relevant": [{ "label": "⁴" }] } }
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"manualOrLocked": { "label": "%" },
|
||||
"default": { "label": "5", "popup": { "relevant": [{ "label": "⁵" }, { "label": "⅝" }] } }
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"manualOrLocked": { "label": "^" },
|
||||
"default": { "label": "6", "popup": { "relevant": [{ "label": "⁶" }] } }
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"manualOrLocked": { "label": "&" },
|
||||
"default": { "label": "7", "popup": { "relevant": [{ "label": "⁷" }, { "label": "⅞" }] } }
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"manualOrLocked": { "label": "*" },
|
||||
"default": { "label": "8", "popup": { "relevant": [{ "label": "⁸" }] } }
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"manualOrLocked": { "label": "(" },
|
||||
"default": { "label": "9", "popup": { "relevant": [{ "label": "⁹" }] } }
|
||||
},
|
||||
{ "$": "shift_state_selector",
|
||||
"manualOrLocked": { "label": ")" },
|
||||
"default": { "label": "0", "popup": { "relevant": [{ "label": "⁰" }, { "label": "ⁿ" }, { "label": "∅" }] } }
|
||||
}
|
||||
]
|
||||
]
|
39
app/src/main/assets/locale_key_texts/ckb.txt
Normal file
39
app/src/main/assets/locale_key_texts/ckb.txt
Normal file
|
@ -0,0 +1,39 @@
|
|||
[popup_keys]
|
||||
ق ٯ
|
||||
و وو
|
||||
ە ة ﻪ ـہ
|
||||
ر ڕ ڒ ࢪ
|
||||
ت ط
|
||||
ی ي ې ۍ
|
||||
ێ ؽ
|
||||
ئ ء ﺋ
|
||||
ۆ ؤ ۏ ۊ ۋ ۉ ۇ
|
||||
پ ث
|
||||
ا أ إ آ ٱ
|
||||
س ص
|
||||
ش ض
|
||||
د ۮ ڌ ﮆ
|
||||
ف ڤ ڡ
|
||||
ھ ھ
|
||||
ژ ━|ـ
|
||||
ل ڵ
|
||||
ک ك ڪ
|
||||
گ غ
|
||||
ز ظ
|
||||
ع ؏
|
||||
ب ى
|
||||
punctuation !autoColumnOrder!8 \؟ ! ، ٫ ؍ : ؛ ; : | - @ _ # * ٪ & ^
|
||||
« „ “ ”
|
||||
» ‚ ‘ ’ ‹ ›
|
||||
|
||||
[labels]
|
||||
alphabet: ئپگ
|
||||
symbol: ٣٢١؟
|
||||
comma: ،
|
||||
question: ؟
|
||||
|
||||
[number_row]
|
||||
١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩ ٠
|
||||
|
||||
[tlds]
|
||||
iq krd
|
|
@ -1,9 +1,19 @@
|
|||
[popup_keys]
|
||||
е ё
|
||||
ь ъ
|
||||
е ё е́ ѣ
|
||||
ф ѳ
|
||||
ы ы́
|
||||
а а́
|
||||
о о́
|
||||
я я́
|
||||
и и́
|
||||
ь ъ ы
|
||||
ю ю́
|
||||
' ’ ‚ ‘ › ‹
|
||||
" ” „ “ » «
|
||||
|
||||
і ы
|
||||
є э э́
|
||||
|
||||
[labels]
|
||||
alphabet: АБВ
|
||||
|
||||
|
|
|
@ -1,9 +1,19 @@
|
|||
[popup_keys]
|
||||
е е́
|
||||
г ґ
|
||||
ь
|
||||
ф ѳ
|
||||
і ї
|
||||
' ’ ‚ ‘
|
||||
" ” „ “
|
||||
а а́
|
||||
о о́
|
||||
я я́
|
||||
и и́ і ї
|
||||
г ґ
|
||||
ю ю́
|
||||
' ’ ‚ ‘ › ‹
|
||||
" ” „ “ » «
|
||||
|
||||
ы і ї
|
||||
э є
|
||||
|
||||
[labels]
|
||||
alphabet: АБВ
|
||||
|
|
|
@ -24,6 +24,7 @@ import helium314.keyboard.latin.common.StringUtils;
|
|||
import helium314.keyboard.latin.utils.PopupKeysUtilsKt;
|
||||
import helium314.keyboard.latin.utils.ToolbarKey;
|
||||
import helium314.keyboard.latin.utils.ToolbarUtilsKt;
|
||||
import kotlin.collections.ArraysKt;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
@ -919,7 +920,7 @@ public class Key implements Comparable<Key> {
|
|||
@NonNull final Drawable spacebarBackground,
|
||||
@NonNull final Drawable actionKeyBackground) {
|
||||
final Drawable background;
|
||||
if (isAccentColored()) {
|
||||
if (hasActionKeyBackground()) {
|
||||
background = actionKeyBackground;
|
||||
} else if (hasFunctionalBackground()) {
|
||||
background = functionalKeyBackground;
|
||||
|
@ -933,17 +934,10 @@ public class Key implements Comparable<Key> {
|
|||
return background;
|
||||
}
|
||||
|
||||
public final boolean isAccentColored() {
|
||||
if (hasActionKeyBackground()) return true;
|
||||
final String iconName = getIconName();
|
||||
if (iconName == null) return false;
|
||||
// todo: other way of identifying the color?
|
||||
// this should be done differently, as users can set any icon now
|
||||
// how is the background drawable selected? can we use the same way?
|
||||
return iconName.equals(KeyboardIconsSet.NAME_NEXT_KEY)
|
||||
|| iconName.equals(KeyboardIconsSet.NAME_PREVIOUS_KEY)
|
||||
|| iconName.equals("clipboard_action_key")
|
||||
|| iconName.equals("emoji_action_key");
|
||||
public final boolean hasActionKeyPopups() {
|
||||
if (!hasActionKeyBackground()) return false;
|
||||
// only use the special action key popups for action colored keys, and only for icon popups
|
||||
return ArraysKt.none(getPopupKeys(), (key) -> key.mIconName == null);
|
||||
}
|
||||
|
||||
public boolean hasFunctionalBackground() {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package helium314.keyboard.keyboard
|
||||
|
||||
import android.text.InputType
|
||||
import android.view.KeyEvent
|
||||
import android.view.inputmethod.InputMethodSubtype
|
||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
|
||||
|
@ -211,13 +212,24 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp
|
|||
return true
|
||||
}
|
||||
}
|
||||
if (inputLogic.moveCursorByAndReturnIfInsideComposingWord(moveSteps)) {
|
||||
|
||||
// the shortcut below causes issues due to horrible handling of text fields by Firefox and forks
|
||||
// issues:
|
||||
// * setSelection "will cause the editor to call onUpdateSelection", see: https://developer.android.com/reference/android/view/inputmethod/InputConnection#setSelection(int,%20int)
|
||||
// but Firefox is simply not doing this within the same word... WTF?
|
||||
// https://github.com/Helium314/HeliBoard/issues/1139#issuecomment-2588169384
|
||||
// * inputType is NOT if variant InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT (variant appears to always be 0)
|
||||
// so we can't even only do it for browsers (identifying by app name will break for forks)
|
||||
// best "solution" is not doing this for InputType variation 0 but this applies to the majority of text fields...
|
||||
val variation = InputType.TYPE_MASK_VARIATION and Settings.getValues().mInputAttributes.mInputType
|
||||
if (variation != 0 && inputLogic.moveCursorByAndReturnIfInsideComposingWord(moveSteps)) {
|
||||
// no need to finish input and restart suggestions if we're still in the word
|
||||
// this is a noticeable performance improvement
|
||||
// this is a noticeable performance improvement when moving through long words
|
||||
val newPosition = inputLogic.mConnection.expectedSelectionStart + moveSteps
|
||||
inputLogic.mConnection.setSelection(newPosition, newPosition)
|
||||
return true
|
||||
}
|
||||
|
||||
inputLogic.finishInput()
|
||||
val newPosition = inputLogic.mConnection.expectedSelectionStart + moveSteps
|
||||
inputLogic.mConnection.setSelection(newPosition, newPosition)
|
||||
|
|
|
@ -405,14 +405,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
}
|
||||
|
||||
fun getUnusedThemeName(initialName: String, prefs: SharedPreferences): String {
|
||||
val existingNames = prefs.all.keys.mapNotNull {
|
||||
when {
|
||||
it.startsWith(Settings.PREF_USER_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_COLORS_PREFIX)
|
||||
it.startsWith(Settings.PREF_USER_ALL_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_ALL_COLORS_PREFIX)
|
||||
it.startsWith(Settings.PREF_USER_MORE_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_MORE_COLORS_PREFIX)
|
||||
else -> null
|
||||
}
|
||||
}.toSortedSet()
|
||||
val existingNames = getExistingThemeNames(prefs)
|
||||
if (initialName !in existingNames) return initialName
|
||||
var i = 1
|
||||
while ("$initialName$i" in existingNames)
|
||||
|
@ -420,11 +413,8 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
return "$initialName$i"
|
||||
}
|
||||
|
||||
// returns false if not renamed due to invalid name or collision
|
||||
fun renameUserColors(from: String, to: String, prefs: SharedPreferences): Boolean {
|
||||
if (to.isBlank()) return false // don't want that
|
||||
if (to == from) return true // nothing to do
|
||||
val existingNames = prefs.all.keys.mapNotNull {
|
||||
private fun getExistingThemeNames(prefs: SharedPreferences) =
|
||||
prefs.all.keys.mapNotNull {
|
||||
when {
|
||||
it.startsWith(Settings.PREF_USER_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_COLORS_PREFIX)
|
||||
it.startsWith(Settings.PREF_USER_ALL_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_ALL_COLORS_PREFIX)
|
||||
|
@ -432,6 +422,12 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
|
|||
else -> null
|
||||
}
|
||||
}.toSortedSet()
|
||||
|
||||
// returns false if not renamed due to invalid name or collision
|
||||
fun renameUserColors(from: String, to: String, prefs: SharedPreferences): Boolean {
|
||||
if (to.isBlank()) return false // don't want that
|
||||
if (to == from) return true // nothing to do
|
||||
val existingNames = getExistingThemeNames(prefs)
|
||||
if (to in existingNames) return false
|
||||
// all good, now rename
|
||||
prefs.edit {
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.view.View;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import helium314.keyboard.keyboard.emoji.EmojiPageKeyboardView;
|
||||
import helium314.keyboard.keyboard.internal.KeyDrawParams;
|
||||
import helium314.keyboard.keyboard.internal.KeyVisualAttributes;
|
||||
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode;
|
||||
|
@ -34,7 +35,7 @@ import helium314.keyboard.latin.R;
|
|||
import helium314.keyboard.latin.common.ColorType;
|
||||
import helium314.keyboard.latin.common.Colors;
|
||||
import helium314.keyboard.latin.common.Constants;
|
||||
import helium314.keyboard.latin.common.StringUtils;
|
||||
import helium314.keyboard.latin.common.StringUtilsKt;
|
||||
import helium314.keyboard.latin.settings.Settings;
|
||||
import helium314.keyboard.latin.suggestions.MoreSuggestions;
|
||||
import helium314.keyboard.latin.suggestions.PopupSuggestionsView;
|
||||
|
@ -423,10 +424,14 @@ public class KeyboardView extends View {
|
|||
}
|
||||
|
||||
if (key.isEnabled()) {
|
||||
if (StringUtils.mightBeEmoji(label))
|
||||
if (StringUtilsKt.isEmoji(label))
|
||||
paint.setColor(key.selectTextColor(params) | 0xFF000000); // ignore alpha for emojis (though actually color isn't applied anyway and we could just set white)
|
||||
else if (key.hasActionKeyBackground())
|
||||
paint.setColor(mColors.get(ColorType.ACTION_KEY_ICON));
|
||||
else if (this instanceof EmojiPageKeyboardView)
|
||||
paint.setColor(mColors.get(ColorType.EMOJI_KEY_TEXT));
|
||||
else if (this instanceof PopupKeysKeyboardView)
|
||||
paint.setColor(mColors.get(ColorType.POPUP_KEY_TEXT));
|
||||
else
|
||||
paint.setColor(key.selectTextColor(params));
|
||||
// Set a drop shadow for the text if the shadow radius is positive value.
|
||||
|
@ -610,7 +615,7 @@ public class KeyboardView extends View {
|
|||
}
|
||||
|
||||
private void setKeyIconColor(Key key, Drawable icon, Keyboard keyboard) {
|
||||
if (key.isAccentColored()) {
|
||||
if (key.hasActionKeyBackground()) {
|
||||
mColors.setColor(icon, ColorType.ACTION_KEY_ICON);
|
||||
} else if (key.isShift() && keyboard != null) {
|
||||
if (keyboard.mId.mElementId == KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED
|
||||
|
|
|
@ -18,6 +18,7 @@ import android.graphics.Paint;
|
|||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
@ -25,7 +26,6 @@ import android.view.ViewGroup;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.view.ContextThemeWrapper;
|
||||
|
||||
import helium314.keyboard.accessibility.AccessibilityUtils;
|
||||
import helium314.keyboard.accessibility.MainKeyboardAccessibilityDelegate;
|
||||
|
@ -505,7 +505,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
|
|||
mPopupKeysKeyboardCache.put(key, popupKeysKeyboard);
|
||||
}
|
||||
|
||||
final View container = key.hasActionKeyBackground() ? mPopupKeysKeyboardForActionContainer
|
||||
final View container = key.hasActionKeyPopups() ? mPopupKeysKeyboardForActionContainer
|
||||
: mPopupKeysKeyboardContainer;
|
||||
final PopupKeysKeyboardView popupKeysKeyboardView =
|
||||
container.findViewById(R.id.popup_keys_keyboard_view);
|
||||
|
|
|
@ -328,12 +328,13 @@ public final class PopupKeysKeyboard extends Keyboard {
|
|||
final PopupKeysKeyboardParams params = mParams;
|
||||
final int popupKeyFlags = mParentKey.getPopupKeyLabelFlags();
|
||||
final PopupKeySpec[] popupKeys = mParentKey.getPopupKeys();
|
||||
final int background = mParentKey.hasActionKeyPopups() ? Key.BACKGROUND_TYPE_ACTION : Key.BACKGROUND_TYPE_NORMAL;
|
||||
for (int n = 0; n < popupKeys.length; n++) {
|
||||
final PopupKeySpec popupKeySpec = popupKeys[n];
|
||||
final int row = n / params.mNumColumns;
|
||||
final int x = params.getX(n, row);
|
||||
final int y = params.getY(row);
|
||||
final Key key = popupKeySpec.buildKey(x, y, popupKeyFlags, params);
|
||||
final Key key = popupKeySpec.buildKey(x, y, popupKeyFlags, background, params);
|
||||
params.markAsEdgeKey(key, row);
|
||||
params.onAddKey(key);
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ public final class KeyPreviewChoreographer {
|
|||
final boolean hasPopupKeys = (key.getPopupKeys() != null);
|
||||
keyPreviewView.setPreviewBackground(hasPopupKeys, keyPreviewPosition);
|
||||
final Colors colors = Settings.getValues().mColors;
|
||||
colors.setBackground(keyPreviewView, ColorType.KEY_PREVIEW);
|
||||
colors.setBackground(keyPreviewView, ColorType.KEY_PREVIEW_BACKGROUND);
|
||||
|
||||
// The key preview is placed vertically above the top edge of the parent key with an
|
||||
// arbitrary offset.
|
||||
|
|
|
@ -15,8 +15,7 @@ import android.text.TextUtils;
|
|||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import helium314.keyboard.keyboard.Key;
|
||||
import helium314.keyboard.latin.R;
|
||||
|
@ -25,10 +24,9 @@ import helium314.keyboard.latin.settings.Settings;
|
|||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* The pop up key preview view.
|
||||
*/
|
||||
public class KeyPreviewView extends AppCompatTextView {
|
||||
/** The pop up key preview view. */
|
||||
// Android Studio complains about TextView, but we're not using tint or auto-size that should be the relevant differences
|
||||
public class KeyPreviewView extends TextView {
|
||||
public static final int POSITION_MIDDLE = 0;
|
||||
public static final int POSITION_LEFT = 1;
|
||||
public static final int POSITION_RIGHT = 2;
|
||||
|
|
|
@ -129,7 +129,7 @@ public final class KeyVisualAttributes {
|
|||
// when? -> hasShiftedLetterHint and isShiftedLetterActivated -> both are label flags
|
||||
mShiftedLetterHintActivatedColor = keyAttr.getColor(
|
||||
R.styleable.Keyboard_Key_keyShiftedLetterHintActivatedColor, 0);
|
||||
mPreviewTextColor = colors.get(ColorType.KEY_TEXT);
|
||||
mPreviewTextColor = colors.get(ColorType.KEY_PREVIEW_TEXT);
|
||||
|
||||
mHintLabelVerticalAdjustment = ResourceUtils.getFraction(keyAttr,
|
||||
R.styleable.Keyboard_Key_keyHintLabelVerticalAdjustment, 0.0f);
|
||||
|
|
|
@ -80,6 +80,7 @@ public final class KeyboardState {
|
|||
private static final int SWITCH_STATE_SYMBOL_BEGIN = 1;
|
||||
private static final int SWITCH_STATE_SYMBOL = 2;
|
||||
private static final int SWITCH_STATE_NUMPAD = 3;
|
||||
private static final int SWITCH_STATE_NUMPAD_BEGIN = 9;
|
||||
private static final int SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL = 4;
|
||||
private static final int SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE = 5;
|
||||
private static final int SWITCH_STATE_MOMENTARY_ALPHA_SHIFT = 6;
|
||||
|
@ -403,7 +404,7 @@ public final class KeyboardState {
|
|||
mMode = MODE_NUMPAD;
|
||||
mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE;
|
||||
mSwitchActions.setNumpadKeyboard();
|
||||
mSwitchState = withSliding ? SWITCH_STATE_MOMENTARY_TO_NUMPAD : SWITCH_STATE_NUMPAD;
|
||||
mSwitchState = withSliding ? SWITCH_STATE_MOMENTARY_TO_NUMPAD : SWITCH_STATE_NUMPAD_BEGIN;
|
||||
}
|
||||
|
||||
public void toggleNumpad(final boolean withSliding, final int autoCapsFlags, final int recapitalizeMode,
|
||||
|
@ -789,6 +790,17 @@ public final class KeyboardState {
|
|||
mPrevSymbolsKeyboardWasShifted = false;
|
||||
}
|
||||
break;
|
||||
case SWITCH_STATE_NUMPAD:
|
||||
// Switch back to alpha keyboard mode if user types one or more non-space/enter
|
||||
// characters followed by a space/enter.
|
||||
if (isSpaceOrEnter(code) && Settings.getValues().mAlphaAfterNumpadAndSpace) {
|
||||
toggleNumpad(false, autoCapsFlags, recapitalizeMode, true, false);
|
||||
}
|
||||
break;
|
||||
case SWITCH_STATE_NUMPAD_BEGIN:
|
||||
if (!isSpaceOrEnter(code))
|
||||
mSwitchState = SWITCH_STATE_NUMPAD;
|
||||
break;
|
||||
}
|
||||
|
||||
// If the code is a letter, update keyboard shift state.
|
||||
|
@ -833,6 +845,7 @@ public final class KeyboardState {
|
|||
case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE -> "MOMENTARY-SYMBOL-MORE";
|
||||
case SWITCH_STATE_MOMENTARY_ALPHA_SHIFT -> "MOMENTARY-ALPHA_SHIFT";
|
||||
case SWITCH_STATE_NUMPAD -> "NUMPAD";
|
||||
case SWITCH_STATE_NUMPAD_BEGIN -> "NUMPAD-BEGIN";
|
||||
case SWITCH_STATE_MOMENTARY_TO_NUMPAD -> "MOMENTARY-TO-NUMPAD";
|
||||
case SWITCH_STATE_MOMENTARY_FROM_NUMPAD -> "MOMENTARY-FROM-NUMPAD";
|
||||
default -> null;
|
||||
|
|
|
@ -68,11 +68,9 @@ public final class PopupKeySpec {
|
|||
}
|
||||
|
||||
@NonNull
|
||||
public Key buildKey(final int x, final int y, final int labelFlags,
|
||||
@NonNull final KeyboardParams params) {
|
||||
return new Key(mLabel, mIconName, mCode, mOutputText, null /* hintLabel */, labelFlags,
|
||||
Key.BACKGROUND_TYPE_NORMAL, x, y, params.mDefaultAbsoluteKeyWidth, params.mDefaultAbsoluteRowHeight,
|
||||
params.mHorizontalGap, params.mVerticalGap);
|
||||
public Key buildKey(final int x, final int y, final int labelFlags, final int background, @NonNull final KeyboardParams params) {
|
||||
return new Key(mLabel, mIconName, mCode, mOutputText, null, labelFlags, background, x, y,
|
||||
params.mDefaultAbsoluteKeyWidth, params.mDefaultAbsoluteRowHeight, params.mHorizontalGap, params.mVerticalGap);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -237,7 +237,7 @@ class KeyboardParser(private val params: KeyboardParams, private val context: Co
|
|||
{ it.label == KeyLabel.PERIOD || it.groupId == KeyData.GROUP_PERIOD},
|
||||
{ baseKeys.last()[1].copy(newGroupId = 2, newType = baseKeys.last()[1].type ?: it.type) }
|
||||
)
|
||||
baseKeys.removeLast()
|
||||
baseKeys.removeAt(baseKeys.lastIndex)
|
||||
}
|
||||
// add zwnj key next to space if necessary
|
||||
val spaceIndex = functionalKeysBottom.indexOfFirst { it.label == KeyLabel.SPACE && it.width <= 0 } // width could be 0 or -1
|
||||
|
|
|
@ -44,7 +44,7 @@ class LocaleKeyboardInfos(dataStream: InputStream?, locale: Locale) {
|
|||
"mns" -> Key.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO
|
||||
else -> 0
|
||||
}
|
||||
val tlds = getLocaleTlds(locale) // todo: USE IT
|
||||
val tlds = getLocaleTlds(locale)
|
||||
|
||||
init {
|
||||
readStream(dataStream, false, true)
|
||||
|
@ -89,12 +89,6 @@ class LocaleKeyboardInfos(dataStream: InputStream?, locale: Locale) {
|
|||
}
|
||||
}
|
||||
|
||||
fun addDefaultTlds(locale: Locale) {
|
||||
if ((locale.language != "en" && euroLocales.matches(locale.language)) || euroCountries.matches(locale.country))
|
||||
tlds.add(".eu")
|
||||
tlds.addAll(defaultTlds.splitOnWhitespace())
|
||||
}
|
||||
|
||||
/** Pair(extraKeysLeft, extraKeysRight) */
|
||||
fun getTabletExtraKeys(elementId: Int): Pair<List<KeyData>, List<KeyData>> {
|
||||
val flags = Key.LABEL_FLAGS_FONT_DEFAULT
|
||||
|
@ -205,7 +199,6 @@ private fun createLocaleKeyTexts(context: Context, params: KeyboardParams, popup
|
|||
if (locale == params.mId.locale) return@forEach
|
||||
lkt.addFile(getStreamForLocale(locale, context), true)
|
||||
}
|
||||
lkt.addDefaultTlds(params.mId.locale)
|
||||
when (popupKeysSetting) {
|
||||
POPUP_KEYS_MAIN -> lkt.addFile(context.assets.open("$LOCALE_TEXTS_FOLDER/more_popups_main.txt"), false)
|
||||
POPUP_KEYS_MORE -> lkt.addFile(context.assets.open("$LOCALE_TEXTS_FOLDER/more_popups_more.txt"), false)
|
||||
|
@ -227,19 +220,27 @@ private fun getStreamForLocale(locale: Locale, context: Context) =
|
|||
}
|
||||
|
||||
private fun getLocaleTlds(locale: Locale): LinkedHashSet<String> {
|
||||
val tlds = getDefaultTlds(locale)
|
||||
val ccLower = locale.country.lowercase()
|
||||
val tlds = LinkedHashSet<String>()
|
||||
if (ccLower.isEmpty() || locale.language == SubtypeLocaleUtils.NO_LANGUAGE)
|
||||
return tlds
|
||||
specialCountryTlds.forEach {
|
||||
if (ccLower != it.first) return@forEach
|
||||
tlds.addAll(it.second.splitOnWhitespace())
|
||||
return tlds
|
||||
return@getLocaleTlds tlds
|
||||
}
|
||||
tlds.add(".$ccLower")
|
||||
return tlds
|
||||
}
|
||||
|
||||
private fun getDefaultTlds(locale: Locale): LinkedHashSet<String> {
|
||||
val tlds = linkedSetOf<String>()
|
||||
tlds.addAll(defaultTlds.splitOnWhitespace())
|
||||
if ((locale.language != "en" && euroLocales.matches(locale.language)) || euroCountries.matches(locale.country))
|
||||
tlds.add(".eu")
|
||||
return tlds
|
||||
}
|
||||
|
||||
fun clearCache() = localeKeyboardInfosCache.clear()
|
||||
|
||||
// cache the texts, so they don't need to be read over and over
|
||||
|
|
|
@ -167,6 +167,7 @@ object KeyCode {
|
|||
const val BACK = -10040
|
||||
const val SELECT_LEFT = -10041
|
||||
const val SELECT_RIGHT = -10042
|
||||
const val TIMESTAMP = -10043
|
||||
|
||||
/** to make sure a FlorisBoard code works when reading a JSON layout */
|
||||
fun Int.checkAndConvertCode(): Int = if (this > 0) this else when (this) {
|
||||
|
@ -182,7 +183,8 @@ object KeyCode {
|
|||
SYMBOL_ALPHA, TOGGLE_ONE_HANDED_MODE, SWITCH_ONE_HANDED_MODE, SPLIT_LAYOUT, SHIFT_ENTER,
|
||||
ACTION_NEXT, ACTION_PREVIOUS, NOT_SPECIFIED, CLIPBOARD_COPY_ALL, WORD_LEFT, WORD_RIGHT, PAGE_UP,
|
||||
PAGE_DOWN, META, TAB, ESCAPE, INSERT, SLEEP, MEDIA_PLAY, MEDIA_PAUSE, MEDIA_PLAY_PAUSE, MEDIA_NEXT,
|
||||
MEDIA_PREVIOUS, VOL_UP, VOL_DOWN, MUTE, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, BACK
|
||||
MEDIA_PREVIOUS, VOL_UP, VOL_DOWN, MUTE, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, BACK,
|
||||
TIMESTAMP
|
||||
-> this
|
||||
|
||||
// conversion
|
||||
|
@ -194,8 +196,12 @@ object KeyCode {
|
|||
else -> throw IllegalStateException("key code $this not yet supported")
|
||||
}
|
||||
|
||||
// todo: three are many more keys, see near https://developer.android.com/reference/android/view/KeyEvent#KEYCODE_0
|
||||
/** convert a keyCode / codePoint to a KeyEvent.KEYCODE_<xxx>, fallback to KeyEvent.KEYCODE_UNKNOWN */
|
||||
// todo: there are many more keys, see near https://developer.android.com/reference/android/view/KeyEvent#KEYCODE_0
|
||||
/**
|
||||
* Convert a keyCode / codePoint to a KeyEvent.KEYCODE_<xxx>.
|
||||
* Fallback to KeyEvent.KEYCODE_UNKNOWN.
|
||||
* To be uses for fake hardware key press.
|
||||
* */
|
||||
fun Int.toKeyEventCode(): Int = if (this > 0)
|
||||
when (this.toChar().uppercaseChar()) {
|
||||
'/' -> KeyEvent.KEYCODE_SLASH
|
||||
|
|
|
@ -24,6 +24,7 @@ import helium314.keyboard.latin.common.StringUtils
|
|||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.latin.spellcheck.AndroidSpellCheckerService
|
||||
import helium314.keyboard.latin.utils.InputTypeUtils
|
||||
import helium314.keyboard.latin.utils.LayoutType
|
||||
import helium314.keyboard.latin.utils.Log
|
||||
import helium314.keyboard.latin.utils.ToolbarKey
|
||||
import helium314.keyboard.latin.utils.getCodeForToolbarKey
|
||||
|
@ -482,8 +483,7 @@ sealed interface KeyData : AbstractKeyData {
|
|||
KeyLabel.DELETE -> "!icon/delete_key|!code/key_delete"
|
||||
KeyLabel.SHIFT -> "${getShiftLabel(params)}|!code/key_shift"
|
||||
// KeyLabel.EMOJI -> "!icon/emoji_normal_key|!code/key_emoji"
|
||||
// todo (later): label and popupKeys for .com should be in localeKeyTexts, handled similar to currency key
|
||||
KeyLabel.COM -> ".com"
|
||||
KeyLabel.COM -> params.mLocaleKeyboardInfos.tlds.first()
|
||||
KeyLabel.LANGUAGE_SWITCH -> "!icon/language_switch_key|!code/key_language_switch"
|
||||
KeyLabel.ZWNJ -> "!icon/zwnj_key|\u200C"
|
||||
KeyLabel.CURRENCY -> params.mLocaleKeyboardInfos.currencyKey.first
|
||||
|
@ -526,8 +526,11 @@ sealed interface KeyData : AbstractKeyData {
|
|||
return when (label) {
|
||||
KeyLabel.ALPHA, KeyLabel.SYMBOL_ALPHA, KeyLabel.SYMBOL -> Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR
|
||||
KeyLabel.COMMA -> Key.LABEL_FLAGS_HAS_POPUP_HINT
|
||||
// essentially this only changes the appearance of the armenian period key in holo theme
|
||||
KeyLabel.PERIOD -> Key.LABEL_FLAGS_HAS_POPUP_HINT and if (params.mId.isAlphabetKeyboard) params.mLocaleKeyboardInfos.labelFlags else 0
|
||||
// essentially the first term only changes the appearance of the armenian period key in holo theme
|
||||
KeyLabel.PERIOD -> (Key.LABEL_FLAGS_HAS_POPUP_HINT and
|
||||
if (params.mId.isAlphabetKeyboard) params.mLocaleKeyboardInfos.labelFlags else 0) or
|
||||
(if (shouldShowTldPopups(params)) 0 else Key.LABEL_FLAGS_DISABLE_HINT_LABEL) or
|
||||
Key.LABEL_FLAGS_PRESERVE_CASE
|
||||
KeyLabel.ACTION -> {
|
||||
Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_AUTO_X_SCALE or
|
||||
Key.LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR or
|
||||
|
@ -546,12 +549,12 @@ sealed interface KeyData : AbstractKeyData {
|
|||
|
||||
private fun getAdditionalPopupKeys(params: KeyboardParams): PopupSet<AbstractKeyData>? {
|
||||
if (groupId == GROUP_COMMA) return SimplePopups(getCommaPopupKeys(params))
|
||||
if (groupId == GROUP_PERIOD) return SimplePopups(getPunctuationPopupKeys(params))
|
||||
if (groupId == GROUP_PERIOD) return getPeriodPopups(params)
|
||||
if (groupId == GROUP_ENTER) return getActionKeyPopupKeys(params)
|
||||
if (groupId == GROUP_NO_DEFAULT_POPUP) return null
|
||||
return when (label) {
|
||||
KeyLabel.COMMA -> SimplePopups(getCommaPopupKeys(params))
|
||||
KeyLabel.PERIOD -> SimplePopups(getPunctuationPopupKeys(params))
|
||||
KeyLabel.PERIOD -> getPeriodPopups(params)
|
||||
KeyLabel.ACTION -> getActionKeyPopupKeys(params)
|
||||
KeyLabel.SHIFT -> {
|
||||
if (params.mId.isAlphabetKeyboard) SimplePopups(
|
||||
|
@ -561,13 +564,27 @@ sealed interface KeyData : AbstractKeyData {
|
|||
)
|
||||
) else null // why the alphabet popup keys actually?
|
||||
}
|
||||
KeyLabel.COM -> SimplePopups(listOf(Key.POPUP_KEYS_HAS_LABELS, ".net", ".org", ".gov", ".edu"))
|
||||
KeyLabel.COM -> SimplePopups(
|
||||
listOf(Key.POPUP_KEYS_HAS_LABELS).plus(params.mLocaleKeyboardInfos.tlds.drop(1))
|
||||
)
|
||||
|
||||
KeyLabel.ZWNJ -> SimplePopups(listOf("!icon/zwj_key|\u200D"))
|
||||
// only add currency popups if there are none defined on the key
|
||||
KeyLabel.CURRENCY -> if (popup.isEmpty()) SimplePopups(params.mLocaleKeyboardInfos.currencyKey.second) else null
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPeriodPopups(params: KeyboardParams): SimplePopups =
|
||||
SimplePopups(
|
||||
if (shouldShowTldPopups(params)) params.mLocaleKeyboardInfos.tlds
|
||||
else getPunctuationPopupKeys(params)
|
||||
)
|
||||
|
||||
private fun shouldShowTldPopups(params: KeyboardParams): Boolean =
|
||||
(Settings.getInstance().current.mShowTldPopupKeys
|
||||
&& params.mId.mSubtype.layouts[LayoutType.FUNCTIONAL] != "functional_keys_tablet"
|
||||
&& params.mId.mMode in setOf(KeyboardId.MODE_URL, KeyboardId.MODE_EMAIL))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -232,7 +232,7 @@ fun checkVersionUpgrade(context: Context) {
|
|||
KeyboardTheme.writeUserMoreColors(prefs, themeNameNight, moreColorsNight)
|
||||
}
|
||||
if (prefs.contains("theme_dark_color_all_colors")) {
|
||||
val allColorsNight = readAllColorsMap(false)
|
||||
val allColorsNight = readAllColorsMap(true)
|
||||
prefs.edit().remove("theme_dark_color_all_colors").apply()
|
||||
KeyboardTheme.writeUserAllColors(prefs, themeNameNight, allColorsNight)
|
||||
}
|
||||
|
@ -530,18 +530,29 @@ fun checkVersionUpgrade(context: Context) {
|
|||
prefs.edit().remove("auto_correction_confidence").putFloat(Settings.PREF_AUTO_CORRECT_THRESHOLD, value).apply()
|
||||
}
|
||||
}
|
||||
if (oldVersion <= 2310) {
|
||||
listOf(
|
||||
Settings.PREF_ENABLED_SUBTYPES,
|
||||
Settings.PREF_SELECTED_SUBTYPE,
|
||||
Settings.PREF_ADDITIONAL_SUBTYPES
|
||||
).forEach { key ->
|
||||
val value = prefs.getString(key, "")!!
|
||||
if ("bengali," in value) {
|
||||
prefs.edit().putString(key, value.replace("bengali,", "bengali_inscript,")).apply()
|
||||
if (oldVersion <= 2310) {
|
||||
listOf(
|
||||
Settings.PREF_ENABLED_SUBTYPES,
|
||||
Settings.PREF_SELECTED_SUBTYPE,
|
||||
Settings.PREF_ADDITIONAL_SUBTYPES
|
||||
).forEach { key ->
|
||||
val value = prefs.getString(key, "")!!
|
||||
if ("bengali," in value) {
|
||||
prefs.edit().putString(key, value.replace("bengali,", "bengali_inscript,")).apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oldVersion <= 3001 && prefs.getInt(Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, Defaults.PREF_CLIPBOARD_HISTORY_RETENTION_TIME) <= 0) {
|
||||
prefs.edit().putInt(Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, 121).apply()
|
||||
}
|
||||
if (oldVersion <= 3002) {
|
||||
prefs.all.filterKeys { it.startsWith(Settings.PREF_USER_ALL_COLORS_PREFIX) }.forEach {
|
||||
val oldValue = prefs.getString(it.key, "")!!
|
||||
if ("KEY_PREVIEW" !in oldValue) return@forEach
|
||||
val newValue = oldValue.replace("KEY_PREVIEW", "KEY_PREVIEW_BACKGROUND")
|
||||
prefs.edit().putString(it.key, newValue).apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
upgradeToolbarPrefs(prefs)
|
||||
LayoutUtilsCustom.onLayoutFileChanged() // just to be sure
|
||||
prefs.edit { putInt(Settings.PREF_VERSION_CODE, BuildConfig.VERSION_CODE) }
|
||||
|
|
|
@ -2,18 +2,12 @@
|
|||
|
||||
package helium314.keyboard.latin
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
|
||||
@Serializable
|
||||
data class ClipboardHistoryEntry (
|
||||
var timeStamp: Long,
|
||||
@Serializable(with = CharSequenceStringSerializer::class)
|
||||
val content: CharSequence,
|
||||
val content: String,
|
||||
var isPinned: Boolean = false
|
||||
) : Comparable<ClipboardHistoryEntry> {
|
||||
override fun compareTo(other: ClipboardHistoryEntry): Int {
|
||||
|
@ -21,13 +15,3 @@ data class ClipboardHistoryEntry (
|
|||
return if (result != 0) result else other.timeStamp.compareTo(timeStamp)
|
||||
}
|
||||
}
|
||||
|
||||
class CharSequenceStringSerializer : KSerializer<CharSequence> {
|
||||
override val descriptor = PrimitiveSerialDescriptor("CharSequence", PrimitiveKind.STRING)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: CharSequence) {
|
||||
encoder.encodeString(value.toString())
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder) = decoder.decodeString()
|
||||
}
|
|
@ -61,7 +61,7 @@ class ClipboardHistoryManager(
|
|||
val content = clipItem.coerceToText(latinIME)
|
||||
if (TextUtils.isEmpty(content)) return
|
||||
|
||||
val duplicateEntryIndex = historyEntries.indexOfFirst { it.content.toString() == content.toString() }
|
||||
val duplicateEntryIndex = historyEntries.indexOfFirst { it.content == content.toString() }
|
||||
if (duplicateEntryIndex != -1) {
|
||||
val existingEntry = historyEntries[duplicateEntryIndex]
|
||||
if (existingEntry.timeStamp == timeStamp) return // nothing to change (may occur frequently starting with API 30)
|
||||
|
@ -74,9 +74,9 @@ class ClipboardHistoryManager(
|
|||
onHistoryChangeListener?.onClipboardHistoryEntryMoved(duplicateEntryIndex, newIndex)
|
||||
return
|
||||
}
|
||||
if (historyEntries.any { it.content.toString() == content.toString() }) return
|
||||
if (historyEntries.any { it.content == content.toString() }) return
|
||||
|
||||
val entry = ClipboardHistoryEntry(timeStamp, content)
|
||||
val entry = ClipboardHistoryEntry(timeStamp, content.toString())
|
||||
historyEntries.add(entry)
|
||||
sortHistoryEntries()
|
||||
val at = historyEntries.indexOf(entry)
|
||||
|
@ -120,7 +120,7 @@ class ClipboardHistoryManager(
|
|||
|
||||
private fun checkClipRetentionElapsed() {
|
||||
val mins = latinIME.mSettings.current.mClipboardHistoryRetentionTime
|
||||
if (mins <= 0) return // No retention limit
|
||||
if (mins > 120) return // No retention limit, changed from <= 0 because we want it to be larger than all other choices
|
||||
val maxClipRetentionTime = mins * 60 * 1000L
|
||||
val now = System.currentTimeMillis()
|
||||
historyEntries.removeAll { !it.isPinned && (now - it.timeStamp) > maxClipRetentionTime }
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package helium314.keyboard.latin;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -100,7 +101,6 @@ import java.util.concurrent.TimeUnit;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
/**
|
||||
|
@ -523,6 +523,11 @@ public class LatinIME extends InputMethodService implements
|
|||
}
|
||||
|
||||
final class SubtypeState {
|
||||
// When HintLocales causes a subtype override, we store
|
||||
// the overridden subtype here in order to restore it when
|
||||
// we switch to another input context that has no HintLocales.
|
||||
private InputMethodSubtype mOverriddenByLocale;
|
||||
|
||||
private InputMethodSubtype mLastActiveSubtype;
|
||||
private boolean mCurrentSubtypeHasBeenUsed = true; // starting with true avoids immediate switch
|
||||
|
||||
|
@ -530,6 +535,70 @@ public class LatinIME extends InputMethodService implements
|
|||
mCurrentSubtypeHasBeenUsed = true;
|
||||
}
|
||||
|
||||
// TextFields can provide locale/language hints that the IME should use via 'hintLocales'.
|
||||
// If a matching subtype is found, we temporarily switch to that subtype until
|
||||
// we return to a context that does not provide any hints, or until the user
|
||||
// explicitly changes the language/subtype in use.
|
||||
public InputMethodSubtype getSubtypeForLocales(final RichInputMethodManager richImm, final Iterable<Locale> locales) {
|
||||
final InputMethodSubtype overriddenByLocale = mOverriddenByLocale;
|
||||
if (locales == null) {
|
||||
if (overriddenByLocale != null) {
|
||||
// no locales provided, so switch back to
|
||||
// whatever subtype was used last time.
|
||||
mOverriddenByLocale = null;
|
||||
|
||||
return overriddenByLocale;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
final InputMethodSubtype currentSubtype = richImm.getCurrentSubtype().getRawSubtype();
|
||||
final Locale currentSubtypeLocale = richImm.getCurrentSubtypeLocale();
|
||||
final int minimumMatchLevel = 3; // LocaleUtils.LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER;
|
||||
|
||||
// Try finding a subtype matching the hint language.
|
||||
for (final Locale hintLocale : locales) {
|
||||
if (LocaleUtils.INSTANCE.getMatchLevel(hintLocale, currentSubtypeLocale) >= minimumMatchLevel
|
||||
|| CollectionsKt.any(mSettings.getCurrent().mSecondaryLocales,
|
||||
(secLocale) -> LocaleUtils.INSTANCE.getMatchLevel(hintLocale, secLocale) >= minimumMatchLevel)) {
|
||||
// current locales are already a good match, and we want to avoid unnecessary layout switches.
|
||||
return null;
|
||||
}
|
||||
|
||||
final InputMethodSubtype subtypeForHintLocale = richImm.findSubtypeForHintLocale(hintLocale);
|
||||
if (subtypeForHintLocale == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (subtypeForHintLocale.equals(currentSubtype)) {
|
||||
// no need to switch, we already use the correct locale.
|
||||
return null;
|
||||
}
|
||||
|
||||
if (overriddenByLocale == null) {
|
||||
// auto-switching based on hint locale, so store
|
||||
// whatever subtype was in use so we can switch back
|
||||
// to it later when there are no hint locales.
|
||||
mOverriddenByLocale = currentSubtype;
|
||||
}
|
||||
|
||||
return subtypeForHintLocale;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onSubtypeChanged(final InputMethodSubtype oldSubtype,
|
||||
final InputMethodSubtype newSubtype) {
|
||||
if (oldSubtype != mOverriddenByLocale) {
|
||||
// Whenever the subtype is changed, clear tracking
|
||||
// the subtype that is overridden by a HintLocale as
|
||||
// we no longer have a subtype to automatically switch back to.
|
||||
mOverriddenByLocale = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void switchSubtype(final RichInputMethodManager richImm) {
|
||||
final InputMethodSubtype currentSubtype = richImm.getCurrentSubtype().getRawSubtype();
|
||||
final InputMethodSubtype lastActiveSubtype = mLastActiveSubtype;
|
||||
|
@ -858,6 +927,8 @@ public class LatinIME extends InputMethodService implements
|
|||
return;
|
||||
}
|
||||
InputMethodSubtype oldSubtype = mRichImm.getCurrentSubtype().getRawSubtype();
|
||||
|
||||
mSubtypeState.onSubtypeChanged(oldSubtype, subtype);
|
||||
StatsUtils.onSubtypeChanged(oldSubtype, subtype);
|
||||
mRichImm.onSubtypeChanged(subtype);
|
||||
mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype),
|
||||
|
@ -876,20 +947,10 @@ public class LatinIME extends InputMethodService implements
|
|||
super.onStartInput(editorInfo, restarting);
|
||||
|
||||
final List<Locale> hintLocales = EditorInfoCompatUtils.getHintLocales(editorInfo);
|
||||
if (hintLocales == null) {
|
||||
return;
|
||||
}
|
||||
// Try switching to a subtype matching the hint language.
|
||||
for (final Locale hintLocale : hintLocales) {
|
||||
if (LocaleUtils.INSTANCE.getMatchLevel(hintLocale, mRichImm.getCurrentSubtypeLocale()) >= 3
|
||||
|| CollectionsKt.any(mSettings.getCurrent().mSecondaryLocales, (secLocale) -> LocaleUtils.INSTANCE.getMatchLevel(hintLocale, secLocale) >= 3))
|
||||
return; // current locales are already a good match, and we want to avoid unnecessary layout switches
|
||||
final InputMethodSubtype newSubtype = mRichImm.findSubtypeForHintLocale(hintLocale);
|
||||
if (newSubtype == null) continue;
|
||||
if (newSubtype.equals(mRichImm.getCurrentSubtype().getRawSubtype()))
|
||||
return; // no need to switch, we already use the correct locale
|
||||
mHandler.postSwitchLanguage(newSubtype);
|
||||
break;
|
||||
final InputMethodSubtype subtypeForLocales = mSubtypeState.getSubtypeForLocales(mRichImm, hintLocales);
|
||||
if (subtypeForLocales != null) {
|
||||
// found a better subtype using hint locales that we should switch to.
|
||||
mHandler.postSwitchLanguage(subtypeForLocales);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -474,6 +474,10 @@ public final class WordComposer {
|
|||
return mIsBatchMode;
|
||||
}
|
||||
|
||||
public void unsetBatchMode() {
|
||||
mIsBatchMode = false;
|
||||
}
|
||||
|
||||
public void setRejectedBatchModeSuggestion(final String rejectedSuggestion) {
|
||||
mRejectedBatchModeSuggestion = rejectedSuggestion;
|
||||
}
|
||||
|
|
|
@ -274,10 +274,10 @@ class DynamicColors(context: Context, override val themeStyle: String, override
|
|||
override fun get(color: ColorType): Int = when (color) {
|
||||
TOOL_BAR_KEY_ENABLED_BACKGROUND, EMOJI_CATEGORY_SELECTED, ACTION_KEY_BACKGROUND,
|
||||
CLIPBOARD_PIN, SHIFT_KEY_ICON -> accent
|
||||
AUTOFILL_BACKGROUND_CHIP, GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW -> adjustedBackground
|
||||
AUTOFILL_BACKGROUND_CHIP, GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW_BACKGROUND -> adjustedBackground
|
||||
TOOL_BAR_EXPAND_KEY_BACKGROUND -> if (!isNight) accent else doubleAdjustedBackground
|
||||
GESTURE_TRAIL -> gesture
|
||||
KEY_TEXT, SUGGESTION_AUTO_CORRECT, REMOVE_SUGGESTION_ICON,
|
||||
KEY_TEXT, SUGGESTION_AUTO_CORRECT, REMOVE_SUGGESTION_ICON, EMOJI_KEY_TEXT, KEY_PREVIEW_TEXT, POPUP_KEY_TEXT,
|
||||
KEY_ICON, ONE_HANDED_MODE_BUTTON, EMOJI_CATEGORY, TOOL_BAR_KEY, FUNCTIONAL_KEY_TEXT -> keyText
|
||||
KEY_HINT_TEXT -> keyHintText
|
||||
SPACE_BAR_TEXT -> spaceBarText
|
||||
|
@ -327,7 +327,7 @@ class DynamicColors(context: Context, override val themeStyle: String, override
|
|||
EMOJI_CATEGORY_SELECTED, CLIPBOARD_PIN, SHIFT_KEY_ICON -> accentColorFilter
|
||||
REMOVE_SUGGESTION_ICON, EMOJI_CATEGORY, KEY_TEXT,
|
||||
KEY_ICON, ONE_HANDED_MODE_BUTTON, TOOL_BAR_KEY, TOOL_BAR_EXPAND_KEY -> keyTextFilter
|
||||
KEY_PREVIEW -> adjustedBackgroundFilter
|
||||
KEY_PREVIEW_BACKGROUND -> adjustedBackgroundFilter
|
||||
ACTION_KEY_ICON -> actionKeyIconColorFilter
|
||||
else -> colorFilter(get(color))
|
||||
}
|
||||
|
@ -336,7 +336,7 @@ class DynamicColors(context: Context, override val themeStyle: String, override
|
|||
if (view.background == null)
|
||||
view.setBackgroundColor(Color.WHITE) // set white to make the color filters work
|
||||
when (color) {
|
||||
KEY_PREVIEW -> view.background.colorFilter = adjustedBackgroundFilter
|
||||
KEY_PREVIEW_BACKGROUND -> view.background.colorFilter = adjustedBackgroundFilter
|
||||
FUNCTIONAL_KEY_BACKGROUND, KEY_BACKGROUND, MORE_SUGGESTIONS_WORD_BACKGROUND, SPACE_BAR_BACKGROUND, STRIP_BACKGROUND -> setColor(view.background, color)
|
||||
ONE_HANDED_MODE_BUTTON -> setColor(view.background, if (keyboardBackground == null) MAIN_BACKGROUND else STRIP_BACKGROUND)
|
||||
MORE_SUGGESTIONS_BACKGROUND -> view.background.colorFilter = backgroundFilter
|
||||
|
@ -472,10 +472,11 @@ class DefaultColors (
|
|||
TOOL_BAR_KEY_ENABLED_BACKGROUND, EMOJI_CATEGORY_SELECTED, ACTION_KEY_BACKGROUND,
|
||||
CLIPBOARD_PIN, SHIFT_KEY_ICON -> accent
|
||||
AUTOFILL_BACKGROUND_CHIP -> if (themeStyle == STYLE_MATERIAL && !hasKeyBorders) background else adjustedBackground
|
||||
GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW -> adjustedBackground
|
||||
GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW_BACKGROUND -> adjustedBackground
|
||||
TOOL_BAR_EXPAND_KEY_BACKGROUND, CLIPBOARD_SUGGESTION_BACKGROUND -> doubleAdjustedBackground
|
||||
GESTURE_TRAIL -> gesture
|
||||
KEY_TEXT, REMOVE_SUGGESTION_ICON, FUNCTIONAL_KEY_TEXT, KEY_ICON -> keyText
|
||||
KEY_TEXT, REMOVE_SUGGESTION_ICON, FUNCTIONAL_KEY_TEXT, KEY_ICON, EMOJI_KEY_TEXT,
|
||||
POPUP_KEY_TEXT, KEY_PREVIEW_TEXT -> keyText
|
||||
KEY_HINT_TEXT -> keyHintText
|
||||
SPACE_BAR_TEXT -> spaceBarText
|
||||
FUNCTIONAL_KEY_BACKGROUND -> functionalKey
|
||||
|
@ -524,7 +525,7 @@ class DefaultColors (
|
|||
if (view.background == null)
|
||||
view.setBackgroundColor(Color.WHITE) // set white to make the color filters work
|
||||
when (color) {
|
||||
KEY_PREVIEW, POPUP_KEYS_BACKGROUND -> view.background.colorFilter = adjustedBackgroundFilter
|
||||
KEY_PREVIEW_BACKGROUND, POPUP_KEYS_BACKGROUND -> view.background.colorFilter = adjustedBackgroundFilter
|
||||
FUNCTIONAL_KEY_BACKGROUND, KEY_BACKGROUND, MORE_SUGGESTIONS_WORD_BACKGROUND, SPACE_BAR_BACKGROUND, STRIP_BACKGROUND, CLIPBOARD_SUGGESTION_BACKGROUND -> setColor(view.background, color)
|
||||
ONE_HANDED_MODE_BUTTON -> setColor(view.background, if (keyboardBackground == null) MAIN_BACKGROUND else STRIP_BACKGROUND)
|
||||
MORE_SUGGESTIONS_BACKGROUND -> view.background.colorFilter = backgroundFilter
|
||||
|
@ -547,7 +548,7 @@ class DefaultColors (
|
|||
EMOJI_CATEGORY_SELECTED, CLIPBOARD_PIN, SHIFT_KEY_ICON -> accentColorFilter
|
||||
KEY_TEXT, KEY_ICON -> keyTextFilter
|
||||
REMOVE_SUGGESTION_ICON, EMOJI_CATEGORY, ONE_HANDED_MODE_BUTTON, TOOL_BAR_KEY, TOOL_BAR_EXPAND_KEY -> suggestionTextFilter
|
||||
KEY_PREVIEW -> adjustedBackgroundFilter
|
||||
KEY_PREVIEW_BACKGROUND -> adjustedBackgroundFilter
|
||||
ACTION_KEY_ICON -> actionKeyIconColorFilter
|
||||
else -> colorFilter(get(color)) // create color filter (not great for performance, so the frequently used filters should be stored)
|
||||
}
|
||||
|
@ -620,6 +621,7 @@ enum class ColorType {
|
|||
CLIPBOARD_PIN,
|
||||
EMOJI_CATEGORY,
|
||||
EMOJI_CATEGORY_SELECTED,
|
||||
EMOJI_KEY_TEXT,
|
||||
FUNCTIONAL_KEY_TEXT,
|
||||
FUNCTIONAL_KEY_BACKGROUND,
|
||||
GESTURE_TRAIL,
|
||||
|
@ -628,11 +630,13 @@ enum class ColorType {
|
|||
KEY_ICON,
|
||||
KEY_TEXT,
|
||||
KEY_HINT_TEXT,
|
||||
KEY_PREVIEW,
|
||||
KEY_PREVIEW_BACKGROUND,
|
||||
KEY_PREVIEW_TEXT,
|
||||
MORE_SUGGESTIONS_HINT,
|
||||
MORE_SUGGESTIONS_BACKGROUND,
|
||||
MORE_SUGGESTIONS_WORD_BACKGROUND,
|
||||
POPUP_KEYS_BACKGROUND,
|
||||
POPUP_KEY_TEXT,
|
||||
NAVIGATION_BAR,
|
||||
SHIFT_KEY_ICON,
|
||||
SPACE_BAR_BACKGROUND,
|
||||
|
|
|
@ -54,6 +54,7 @@ import helium314.keyboard.latin.utils.RecapitalizeStatus;
|
|||
import helium314.keyboard.latin.utils.ScriptUtils;
|
||||
import helium314.keyboard.latin.utils.StatsUtils;
|
||||
import helium314.keyboard.latin.utils.TextRange;
|
||||
import helium314.keyboard.latin.utils.TimestampKt;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
@ -323,7 +324,8 @@ public final class InputLogic {
|
|||
// Don't allow cancellation of manual pick
|
||||
mLastComposedWord.deactivate();
|
||||
// Space state must be updated before calling updateShiftState
|
||||
mSpaceState = SpaceState.PHANTOM;
|
||||
if (settingsValues.mAutospaceAfterSuggestion)
|
||||
mSpaceState = SpaceState.PHANTOM;
|
||||
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
|
||||
|
||||
// If we're not showing the "Touch again to save", then update the suggestion strip.
|
||||
|
@ -546,7 +548,8 @@ public final class InputLogic {
|
|||
|| settingsValues.isUsuallyFollowedBySpace(codePointBeforeCursor)) {
|
||||
final boolean autoShiftHasBeenOverriden = keyboardSwitcher.getKeyboardShiftMode() !=
|
||||
getCurrentAutoCapsState(settingsValues);
|
||||
mSpaceState = SpaceState.PHANTOM;
|
||||
if (settingsValues.mAutospaceBeforeGestureTyping)
|
||||
mSpaceState = SpaceState.PHANTOM;
|
||||
if (!autoShiftHasBeenOverriden) {
|
||||
// When we change the space state, we need to update the shift state of the
|
||||
// keyboard unless it has been overridden manually. This is happening for example
|
||||
|
@ -686,10 +689,7 @@ public final class InputLogic {
|
|||
if (mSuggestedWords.isPrediction()) {
|
||||
inputTransaction.setRequiresUpdateSuggestions();
|
||||
}
|
||||
// undo phantom space if it's because after punctuation
|
||||
// users who want to start a sentence with a lowercase letter may not like it
|
||||
if (mSpaceState == SpaceState.PHANTOM
|
||||
&& inputTransaction.getMSettingsValues().isUsuallyFollowedBySpace(mConnection.getCodePointBeforeCursor()))
|
||||
if (mSpaceState == SpaceState.PHANTOM && inputTransaction.getMSettingsValues().mShiftRemovesAutospace)
|
||||
mSpaceState = SpaceState.NONE;
|
||||
break;
|
||||
case KeyCode.SETTINGS:
|
||||
|
@ -776,6 +776,9 @@ public final class InputLogic {
|
|||
case KeyCode.SPLIT_LAYOUT:
|
||||
KeyboardSwitcher.getInstance().toggleSplitKeyboardMode();
|
||||
break;
|
||||
case KeyCode.TIMESTAMP:
|
||||
mLatinIME.onTextInput(TimestampKt.getTimestamp(mLatinIME));
|
||||
break;
|
||||
case KeyCode.VOICE_INPUT:
|
||||
// switching to shortcut IME, shift state, keyboard,... is handled by LatinIME,
|
||||
// {@link KeyboardSwitcher#onEvent(Event)}, or {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
|
||||
|
@ -930,6 +933,7 @@ public final class InputLogic {
|
|||
// handleNonSpecialCharacterEvent which has the same name as other handle* methods but is
|
||||
// not the same.
|
||||
boolean isComposingWord = mWordComposer.isComposingWord();
|
||||
mWordComposer.unsetBatchMode(); // relevant in case we continue a batch word with normal typing
|
||||
|
||||
// if we continue directly after a sometimesWordConnector, restart suggestions for the whole word
|
||||
// (only with URL detection and suggestions enabled)
|
||||
|
@ -949,7 +953,9 @@ public final class InputLogic {
|
|||
// TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead.
|
||||
// See onStartBatchInput() to see how to do it.
|
||||
if (SpaceState.PHANTOM == inputTransaction.getMSpaceState()
|
||||
&& !settingsValues.isWordConnector(codePoint)) {
|
||||
&& !settingsValues.isWordConnector(codePoint)
|
||||
&& !settingsValues.isUsuallyFollowedBySpace(codePoint) // only relevant in rare cases
|
||||
) {
|
||||
if (isComposingWord) {
|
||||
// Sanity check
|
||||
throw new RuntimeException("Should not be composing here");
|
||||
|
@ -1127,7 +1133,7 @@ public final class InputLogic {
|
|||
// A double quote behaves like it's usually followed by space if we're inside
|
||||
// a double quote.
|
||||
if (wasComposingWord
|
||||
&& settingsValues.mAutospaceAfterPunctuationEnabled
|
||||
&& settingsValues.mAutospaceAfterPunctuation
|
||||
&& (settingsValues.isUsuallyFollowedBySpace(codePoint) || isInsideDoubleQuoteOrAfterDigit)) {
|
||||
mSpaceState = SpaceState.PHANTOM;
|
||||
}
|
||||
|
@ -1196,7 +1202,7 @@ public final class InputLogic {
|
|||
}
|
||||
inputTransaction.setRequiresUpdateSuggestions();
|
||||
} else {
|
||||
if (mLastComposedWord.canRevertCommit()) {
|
||||
if (mLastComposedWord.canRevertCommit() && inputTransaction.getMSettingsValues().mBackspaceRevertsAutocorrect) {
|
||||
final String lastComposedWord = mLastComposedWord.mTypedWord;
|
||||
revertCommit(inputTransaction);
|
||||
StatsUtils.onRevertAutoCorrect();
|
||||
|
@ -2168,6 +2174,7 @@ public final class InputLogic {
|
|||
&& !(mConnection.getCodePointBeforeCursor() == Constants.CODE_PERIOD && mConnection.wordBeforeCursorMayBeEmail())
|
||||
) {
|
||||
mConnection.commitCodePoint(Constants.CODE_SPACE);
|
||||
// todo: why not remove phantom space state?
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2202,12 +2209,14 @@ public final class InputLogic {
|
|||
mConnection.beginBatchEdit();
|
||||
if (SpaceState.PHANTOM == mSpaceState) {
|
||||
insertAutomaticSpaceIfOptionsAndTextAllow(settingsValues);
|
||||
mSpaceState = SpaceState.NONE;
|
||||
}
|
||||
mWordComposer.setBatchInputWord(batchInputText);
|
||||
setComposingTextInternal(batchInputText, 1);
|
||||
mConnection.endBatchEdit();
|
||||
// Space state must be updated before calling updateShiftState
|
||||
mSpaceState = SpaceState.PHANTOM;
|
||||
if (settingsValues.mAutospaceAfterGestureTyping)
|
||||
mSpaceState = SpaceState.PHANTOM;
|
||||
keyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(settingsValues), getCurrentRecapitalizeState());
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import helium314.keyboard.keyboard.KeyboardTheme
|
|||
import helium314.keyboard.latin.BuildConfig
|
||||
import helium314.keyboard.latin.common.Constants.Separators
|
||||
import helium314.keyboard.latin.common.Constants.Subtype.ExtraValue
|
||||
import helium314.keyboard.latin.utils.JniUtils
|
||||
import helium314.keyboard.latin.utils.LayoutType
|
||||
import helium314.keyboard.latin.utils.POPUP_KEYS_LABEL_DEFAULT
|
||||
import helium314.keyboard.latin.utils.POPUP_KEYS_ORDER_DEFAULT
|
||||
|
@ -64,9 +63,11 @@ object Defaults {
|
|||
const val PREF_MORE_AUTO_CORRECTION = false
|
||||
const val PREF_AUTO_CORRECT_THRESHOLD = 0.185f
|
||||
const val PREF_AUTOCORRECT_SHORTCUTS = true
|
||||
const val PREF_BACKSPACE_REVERTS_AUTOCORRECT = true
|
||||
const val PREF_CENTER_SUGGESTION_TEXT_TO_ENTER = false
|
||||
const val PREF_SHOW_SUGGESTIONS = true
|
||||
const val PREF_ALWAYS_SHOW_SUGGESTIONS = false
|
||||
const val PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT = true
|
||||
const val PREF_KEY_USE_PERSONALIZED_DICTS = true
|
||||
const val PREF_KEY_USE_DOUBLE_SPACE_PERIOD = true
|
||||
const val PREF_BLOCK_POTENTIALLY_OFFENSIVE = true
|
||||
|
@ -92,6 +93,10 @@ object Defaults {
|
|||
const val PREF_SPACE_VERTICAL_SWIPE = "none"
|
||||
const val PREF_DELETE_SWIPE = true
|
||||
const val PREF_AUTOSPACE_AFTER_PUNCTUATION = false
|
||||
const val PREF_AUTOSPACE_AFTER_SUGGESTION = true
|
||||
const val PREF_AUTOSPACE_AFTER_GESTURE_TYPING = true
|
||||
const val PREF_AUTOSPACE_BEFORE_GESTURE_TYPING = true
|
||||
const val PREF_SHIFT_REMOVES_AUTOSPACE = false
|
||||
const val PREF_ALWAYS_INCOGNITO_MODE = false
|
||||
const val PREF_BIGRAM_PREDICTIONS = true
|
||||
const val PREF_SUGGEST_CLIPBOARD_CONTENT = true
|
||||
|
@ -123,6 +128,7 @@ object Defaults {
|
|||
const val PREF_POPUP_KEYS_ORDER = POPUP_KEYS_ORDER_DEFAULT
|
||||
const val PREF_POPUP_KEYS_LABELS_ORDER = POPUP_KEYS_LABEL_DEFAULT
|
||||
const val PREF_SHOW_POPUP_HINTS = false
|
||||
const val PREF_SHOW_TLD_POPUP_KEYS = true
|
||||
const val PREF_MORE_POPUP_KEYS = "main"
|
||||
const val PREF_SPACE_TO_CHANGE_LANG = true
|
||||
const val PREF_LANGUAGE_SWIPE_DISTANCE = 5
|
||||
|
@ -145,15 +151,15 @@ object Defaults {
|
|||
const val PREF_ABC_AFTER_EMOJI = false
|
||||
const val PREF_ABC_AFTER_CLIP = false
|
||||
const val PREF_ABC_AFTER_SYMBOL_SPACE = true
|
||||
const val PREF_ABC_AFTER_NUMPAD_SPACE = false
|
||||
const val PREF_REMOVE_REDUNDANT_POPUPS = false
|
||||
const val PREF_SPACE_BAR_TEXT = ""
|
||||
const val PREF_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss"
|
||||
@JvmField
|
||||
val PREF_EMOJI_MAX_SDK = Build.VERSION.SDK_INT
|
||||
const val PREF_EMOJI_RECENT_KEYS = ""
|
||||
const val PREF_LAST_SHOWN_EMOJI_CATEGORY_PAGE_ID = 0
|
||||
const val PREF_PINNED_CLIPS = ""
|
||||
@JvmField
|
||||
val PREF_LIBRARY_CHECKSUM: String = JniUtils.expectedDefaultChecksum()
|
||||
const val PREF_SHOW_DEBUG_SETTINGS = false
|
||||
val PREF_DEBUG_MODE = BuildConfig.DEBUG
|
||||
const val PREF_SHOW_SUGGESTION_INFOS = false
|
||||
|
|
|
@ -71,9 +71,11 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static final String PREF_MORE_AUTO_CORRECTION = "more_auto_correction";
|
||||
public static final String PREF_AUTO_CORRECT_THRESHOLD = "auto_correct_threshold";
|
||||
public static final String PREF_AUTOCORRECT_SHORTCUTS = "autocorrect_shortcuts";
|
||||
public static final String PREF_BACKSPACE_REVERTS_AUTOCORRECT = "backspace_reverts_autocorrect";
|
||||
public static final String PREF_CENTER_SUGGESTION_TEXT_TO_ENTER = "center_suggestion_text_to_enter";
|
||||
public static final String PREF_SHOW_SUGGESTIONS = "show_suggestions";
|
||||
public static final String PREF_ALWAYS_SHOW_SUGGESTIONS = "always_show_suggestions";
|
||||
public static final String PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT = "always_show_suggestions_except_web_text";
|
||||
public static final String PREF_KEY_USE_PERSONALIZED_DICTS = "use_personalized_dicts";
|
||||
public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD = "use_double_space_period";
|
||||
public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE = "block_potentially_offensive";
|
||||
|
@ -97,6 +99,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static final String PREF_SPACE_VERTICAL_SWIPE = "vertical_space_swipe";
|
||||
public static final String PREF_DELETE_SWIPE = "delete_swipe";
|
||||
public static final String PREF_AUTOSPACE_AFTER_PUNCTUATION = "autospace_after_punctuation";
|
||||
public static final String PREF_AUTOSPACE_AFTER_SUGGESTION = "autospace_after_suggestion";
|
||||
public static final String PREF_AUTOSPACE_AFTER_GESTURE_TYPING = "autospace_after_gesture_typing";
|
||||
public static final String PREF_AUTOSPACE_BEFORE_GESTURE_TYPING = "autospace_before_gesture_typing";
|
||||
public static final String PREF_SHIFT_REMOVES_AUTOSPACE = "shift_removes_autospace";
|
||||
public static final String PREF_ALWAYS_INCOGNITO_MODE = "always_incognito_mode";
|
||||
public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction";
|
||||
public static final String PREF_SUGGEST_CLIPBOARD_CONTENT = "suggest_clipboard_content";
|
||||
|
@ -131,6 +137,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static final String PREF_POPUP_KEYS_LABELS_ORDER = "popup_keys_labels_order";
|
||||
public static final String PREF_SHOW_POPUP_HINTS = "show_popup_hints";
|
||||
public static final String PREF_MORE_POPUP_KEYS = "more_popup_keys";
|
||||
public static final String PREF_SHOW_TLD_POPUP_KEYS = "show_tld_popup_keys";
|
||||
|
||||
public static final String PREF_SPACE_TO_CHANGE_LANG = "prefs_long_press_keyboard_to_change_lang";
|
||||
public static final String PREF_LANGUAGE_SWIPE_DISTANCE = "language_swipe_distance";
|
||||
|
@ -154,8 +161,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static final String PREF_ABC_AFTER_EMOJI = "abc_after_emoji";
|
||||
public static final String PREF_ABC_AFTER_CLIP = "abc_after_clip";
|
||||
public static final String PREF_ABC_AFTER_SYMBOL_SPACE = "abc_after_symbol_space";
|
||||
public static final String PREF_ABC_AFTER_NUMPAD_SPACE = "abc_after_numpad_space";
|
||||
public static final String PREF_REMOVE_REDUNDANT_POPUPS = "remove_redundant_popups";
|
||||
public static final String PREF_SPACE_BAR_TEXT = "space_bar_text";
|
||||
public static final String PREF_TIMESTAMP_FORMAT = "timestamp_format";
|
||||
|
||||
// Emoji
|
||||
public static final String PREF_EMOJI_MAX_SDK = "emoji_max_sdk";
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.content.Context;
|
|||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.text.InputType;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
|
@ -65,6 +66,7 @@ public class SettingsValues {
|
|||
public final boolean mShowNumberRowHints;
|
||||
public final boolean mShowsHints;
|
||||
public final boolean mShowsPopupHints;
|
||||
public final boolean mShowTldPopupKeys;
|
||||
public final boolean mSpaceForLangChange;
|
||||
public final boolean mShowsEmojiKey;
|
||||
public final boolean mVarToolbarDirection;
|
||||
|
@ -75,7 +77,11 @@ public class SettingsValues {
|
|||
public final int mSpaceSwipeVertical;
|
||||
public final int mLanguageSwipeDistance;
|
||||
public final boolean mDeleteSwipeEnabled;
|
||||
public final boolean mAutospaceAfterPunctuationEnabled;
|
||||
public final boolean mAutospaceAfterPunctuation;
|
||||
public final boolean mAutospaceAfterSuggestion;
|
||||
public final boolean mAutospaceAfterGestureTyping;
|
||||
public final boolean mAutospaceBeforeGestureTyping;
|
||||
public final boolean mShiftRemovesAutospace;
|
||||
public final boolean mClipboardHistoryEnabled;
|
||||
public final long mClipboardHistoryRetentionTime;
|
||||
public final boolean mOneHandedModeEnabled;
|
||||
|
@ -113,6 +119,7 @@ public class SettingsValues {
|
|||
public final boolean mAlphaAfterEmojiInEmojiView;
|
||||
public final boolean mAlphaAfterClipHistoryEntry;
|
||||
public final boolean mAlphaAfterSymbolAndSpace;
|
||||
public final boolean mAlphaAfterNumpadAndSpace;
|
||||
public final boolean mRemoveRedundantPopups;
|
||||
public final String mSpaceBarText;
|
||||
public final float mFontSizeMultiplier;
|
||||
|
@ -128,6 +135,7 @@ public class SettingsValues {
|
|||
public final boolean mAutoCorrectionEnabledPerUserSettings;
|
||||
public final boolean mAutoCorrectEnabled;
|
||||
public final float mAutoCorrectionThreshold;
|
||||
public final boolean mBackspaceRevertsAutocorrect;
|
||||
public final int mScoreLimitForAutocorrect;
|
||||
public final boolean mAutoCorrectShortcuts;
|
||||
private final boolean mSuggestionsEnabledPerUserSettings;
|
||||
|
@ -172,6 +180,7 @@ public class SettingsValues {
|
|||
mShowNumberRowHints = prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW_HINTS, Defaults.PREF_SHOW_NUMBER_ROW_HINTS);
|
||||
mShowsHints = prefs.getBoolean(Settings.PREF_SHOW_HINTS, Defaults.PREF_SHOW_HINTS);
|
||||
mShowsPopupHints = prefs.getBoolean(Settings.PREF_SHOW_POPUP_HINTS, Defaults.PREF_SHOW_POPUP_HINTS);
|
||||
mShowTldPopupKeys = prefs.getBoolean(Settings.PREF_SHOW_TLD_POPUP_KEYS, Defaults.PREF_SHOW_TLD_POPUP_KEYS);
|
||||
mSpaceForLangChange = prefs.getBoolean(Settings.PREF_SPACE_TO_CHANGE_LANG, Defaults.PREF_SPACE_TO_CHANGE_LANG);
|
||||
mShowsEmojiKey = prefs.getBoolean(Settings.PREF_SHOW_EMOJI_KEY, Defaults.PREF_SHOW_EMOJI_KEY);
|
||||
mVarToolbarDirection = prefs.getBoolean(Settings.PREF_VARIABLE_TOOLBAR_DIRECTION, Defaults.PREF_VARIABLE_TOOLBAR_DIRECTION);
|
||||
|
@ -191,6 +200,7 @@ public class SettingsValues {
|
|||
mScoreLimitForAutocorrect = (mAutoCorrectionThreshold < 0) ? 600000 // very aggressive
|
||||
: (mAutoCorrectionThreshold < 0.07 ? 800000 : 950000); // aggressive or modest
|
||||
mAutoCorrectShortcuts = prefs.getBoolean(Settings.PREF_AUTOCORRECT_SHORTCUTS, Defaults.PREF_AUTOCORRECT_SHORTCUTS);
|
||||
mBackspaceRevertsAutocorrect = prefs.getBoolean(Settings.PREF_BACKSPACE_REVERTS_AUTOCORRECT, Defaults.PREF_BACKSPACE_REVERTS_AUTOCORRECT);
|
||||
mBigramPredictionEnabled = prefs.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, Defaults.PREF_BIGRAM_PREDICTIONS);
|
||||
mSuggestClipboardContent = prefs.getBoolean(Settings.PREF_SUGGEST_CLIPBOARD_CONTENT, Defaults.PREF_SUGGEST_CLIPBOARD_CONTENT);
|
||||
mDoubleSpacePeriodTimeout = 1100; // ms
|
||||
|
@ -218,7 +228,10 @@ public class SettingsValues {
|
|||
mGestureFastTypingCooldown = prefs.getInt(Settings.PREF_GESTURE_FAST_TYPING_COOLDOWN, Defaults.PREF_GESTURE_FAST_TYPING_COOLDOWN);
|
||||
mGestureTrailFadeoutDuration = prefs.getInt(Settings.PREF_GESTURE_TRAIL_FADEOUT_DURATION, Defaults.PREF_GESTURE_TRAIL_FADEOUT_DURATION);
|
||||
mAccount = null; // remove? or can it be useful somewhere?
|
||||
mOverrideShowingSuggestions = mInputAttributes.mMayOverrideShowingSuggestions && prefs.getBoolean(Settings.PREF_ALWAYS_SHOW_SUGGESTIONS, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS);
|
||||
mOverrideShowingSuggestions = mInputAttributes.mMayOverrideShowingSuggestions
|
||||
&& prefs.getBoolean(Settings.PREF_ALWAYS_SHOW_SUGGESTIONS, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS)
|
||||
&& ((inputAttributes.mInputType & InputType.TYPE_MASK_VARIATION) != InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT
|
||||
|| !prefs.getBoolean(Settings.PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT));
|
||||
final boolean suggestionsEnabled = prefs.getBoolean(Settings.PREF_SHOW_SUGGESTIONS, Defaults.PREF_SHOW_SUGGESTIONS);
|
||||
mSuggestionsEnabledPerUserSettings = (mInputAttributes.mShouldShowSuggestions && suggestionsEnabled)
|
||||
|| mOverrideShowingSuggestions;
|
||||
|
@ -229,7 +242,11 @@ public class SettingsValues {
|
|||
mSpaceSwipeVertical = Settings.readVerticalSpaceSwipe(prefs);
|
||||
mLanguageSwipeDistance = prefs.getInt(Settings.PREF_LANGUAGE_SWIPE_DISTANCE, Defaults.PREF_LANGUAGE_SWIPE_DISTANCE);
|
||||
mDeleteSwipeEnabled = prefs.getBoolean(Settings.PREF_DELETE_SWIPE, Defaults.PREF_DELETE_SWIPE);
|
||||
mAutospaceAfterPunctuationEnabled = prefs.getBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, Defaults.PREF_AUTOSPACE_AFTER_PUNCTUATION);
|
||||
mAutospaceAfterPunctuation = prefs.getBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, Defaults.PREF_AUTOSPACE_AFTER_PUNCTUATION);
|
||||
mAutospaceAfterSuggestion = prefs.getBoolean(Settings.PREF_AUTOSPACE_AFTER_SUGGESTION, Defaults.PREF_AUTOSPACE_AFTER_SUGGESTION);
|
||||
mAutospaceAfterGestureTyping = prefs.getBoolean(Settings.PREF_AUTOSPACE_AFTER_GESTURE_TYPING, Defaults.PREF_AUTOSPACE_AFTER_GESTURE_TYPING);
|
||||
mAutospaceBeforeGestureTyping = prefs.getBoolean(Settings.PREF_AUTOSPACE_BEFORE_GESTURE_TYPING, Defaults.PREF_AUTOSPACE_BEFORE_GESTURE_TYPING);
|
||||
mShiftRemovesAutospace = prefs.getBoolean(Settings.PREF_SHIFT_REMOVES_AUTOSPACE, Defaults.PREF_SHIFT_REMOVES_AUTOSPACE);
|
||||
mClipboardHistoryEnabled = prefs.getBoolean(Settings.PREF_ENABLE_CLIPBOARD_HISTORY, Defaults.PREF_ENABLE_CLIPBOARD_HISTORY);
|
||||
mClipboardHistoryRetentionTime = prefs.getInt(Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, Defaults.PREF_CLIPBOARD_HISTORY_RETENTION_TIME);
|
||||
|
||||
|
@ -266,6 +283,7 @@ public class SettingsValues {
|
|||
mAlphaAfterEmojiInEmojiView = prefs.getBoolean(Settings.PREF_ABC_AFTER_EMOJI, Defaults.PREF_ABC_AFTER_EMOJI);
|
||||
mAlphaAfterClipHistoryEntry = prefs.getBoolean(Settings.PREF_ABC_AFTER_CLIP, Defaults.PREF_ABC_AFTER_CLIP);
|
||||
mAlphaAfterSymbolAndSpace = prefs.getBoolean(Settings.PREF_ABC_AFTER_SYMBOL_SPACE, Defaults.PREF_ABC_AFTER_SYMBOL_SPACE);
|
||||
mAlphaAfterNumpadAndSpace = prefs.getBoolean(Settings.PREF_ABC_AFTER_NUMPAD_SPACE, Defaults.PREF_ABC_AFTER_NUMPAD_SPACE);
|
||||
mRemoveRedundantPopups = prefs.getBoolean(Settings.PREF_REMOVE_REDUNDANT_POPUPS, Defaults.PREF_REMOVE_REDUNDANT_POPUPS);
|
||||
mSpaceBarText = prefs.getString(Settings.PREF_SPACE_BAR_TEXT, Defaults.PREF_SPACE_BAR_TEXT);
|
||||
mEmojiMaxSdk = prefs.getInt(Settings.PREF_EMOJI_MAX_SDK, Defaults.PREF_EMOJI_MAX_SDK);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package helium314.keyboard.latin.utils
|
||||
|
||||
import android.content.Context
|
||||
import androidx.appcompat.view.ContextThemeWrapper
|
||||
import android.view.ContextThemeWrapper
|
||||
import helium314.keyboard.latin.R
|
||||
|
||||
// todo: ideally the custom InputMethodPicker would be removed / replaced with compose dialog, then this can be removed
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
package helium314.keyboard.latin.utils
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.os.IBinder
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
|
@ -10,7 +11,6 @@ import android.text.style.RelativeSizeSpan
|
|||
import android.view.WindowManager
|
||||
import android.view.inputmethod.InputMethodInfo
|
||||
import android.view.inputmethod.InputMethodSubtype
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import helium314.keyboard.latin.LatinIME
|
||||
import helium314.keyboard.latin.R
|
||||
import helium314.keyboard.latin.RichInputMethodManager
|
||||
|
|
|
@ -13,7 +13,6 @@ import android.text.TextUtils;
|
|||
|
||||
import helium314.keyboard.latin.App;
|
||||
import helium314.keyboard.latin.BuildConfig;
|
||||
import helium314.keyboard.latin.settings.Defaults;
|
||||
import helium314.keyboard.latin.settings.Settings;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -63,7 +62,7 @@ public final class JniUtils {
|
|||
// we want the default preferences, because storing the checksum in device protected storage is discouraged
|
||||
// see https://developer.android.com/reference/android/content/Context#createDeviceProtectedStorageContext()
|
||||
// if device is locked, this will throw an IllegalStateException
|
||||
wantedChecksum = KtxKt.protectedPrefs(app).getString(Settings.PREF_LIBRARY_CHECKSUM, Defaults.PREF_LIBRARY_CHECKSUM);
|
||||
wantedChecksum = KtxKt.protectedPrefs(app).getString(Settings.PREF_LIBRARY_CHECKSUM, expectedDefaultChecksum());
|
||||
}
|
||||
final FileInputStream libStream = new FileInputStream(userSuppliedLibrary);
|
||||
final String checksum = ChecksumCalculator.INSTANCE.checksum(libStream);
|
||||
|
|
|
@ -162,7 +162,7 @@ object ScriptUtils {
|
|||
return SCRIPT_LATIN
|
||||
}
|
||||
return when (language) {
|
||||
"ar", "ur", "fa" -> SCRIPT_ARABIC
|
||||
"ar", "ckb", "ur", "fa" -> SCRIPT_ARABIC
|
||||
"hy" -> SCRIPT_ARMENIAN
|
||||
"bn" -> SCRIPT_BENGALI
|
||||
"sr", "mk", "ru", "uk", "mn", "be", "kk", "ky", "bg", "xdq", "cv", "mhr", "mns", "dru" -> SCRIPT_CYRILLIC
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.latin.utils
|
||||
|
||||
import android.content.Context
|
||||
import helium314.keyboard.latin.settings.Defaults
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
|
||||
fun getTimestamp(context: Context): String {
|
||||
val format = context.prefs().getString(Settings.PREF_TIMESTAMP_FORMAT, Defaults.PREF_TIMESTAMP_FORMAT)
|
||||
val formatter = runCatching { SimpleDateFormat(format, Settings.getValues().mLocale) }.getOrNull()
|
||||
?: SimpleDateFormat(Defaults.PREF_TIMESTAMP_FORMAT, Settings.getValues().mLocale)
|
||||
return formatter.format(Calendar.getInstance().time)
|
||||
}
|
||||
|
||||
fun checkTimestampFormat(format: String) = runCatching { SimpleDateFormat(format, Settings.getValues().mLocale) }.isSuccess
|
|
@ -1,13 +1,18 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.settings
|
||||
|
||||
import android.graphics.drawable.VectorDrawable
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
|
@ -17,8 +22,15 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.util.TypedValueCompat
|
||||
|
||||
@Composable
|
||||
fun WithSmallTitle(
|
||||
|
@ -31,6 +43,19 @@ fun WithSmallTitle(
|
|||
}
|
||||
}
|
||||
|
||||
/** Icon if resource is a vector image, (bitmap) Image otherwise */
|
||||
@Composable
|
||||
fun IconOrImage(@DrawableRes resId: Int, name: String?, sizeDp: Float) {
|
||||
val ctx = LocalContext.current
|
||||
val drawable = ContextCompat.getDrawable(ctx, resId)
|
||||
if (drawable is VectorDrawable)
|
||||
Icon(painterResource(resId), name, Modifier.size(sizeDp.dp))
|
||||
else {
|
||||
val px = TypedValueCompat.dpToPx(sizeDp, ctx.resources.displayMetrics).toInt()
|
||||
Image(drawable!!.toBitmap(px, px).asImageBitmap(), name)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T>DropDownField(
|
||||
items: List<T>,
|
||||
|
@ -67,3 +92,5 @@ fun <T>DropDownField(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
val contentTextDirectionStyle = TextStyle(textDirection = TextDirection.Content)
|
||||
|
|
|
@ -103,6 +103,7 @@ fun <T: Any?> SearchScreen(
|
|||
title: @Composable () -> Unit,
|
||||
filteredItems: (String) -> List<T>,
|
||||
itemContent: @Composable (T) -> Unit,
|
||||
icon: @Composable (() -> Unit)? = null,
|
||||
menu: List<Pair<String, () -> Unit>>? = null,
|
||||
content: @Composable (ColumnScope.() -> Unit)? = null,
|
||||
) {
|
||||
|
@ -137,8 +138,10 @@ fun <T: Any?> SearchScreen(
|
|||
}
|
||||
},
|
||||
actions = {
|
||||
IconButton(onClick = { setShowSearch(!showSearch) })
|
||||
{ SearchIcon() }
|
||||
if (icon == null)
|
||||
IconButton(onClick = { setShowSearch(!showSearch) }) { SearchIcon() }
|
||||
else
|
||||
icon()
|
||||
if (menu != null)
|
||||
Box {
|
||||
var showMenu by remember { mutableStateOf(false) }
|
||||
|
@ -227,7 +230,8 @@ fun ExpandableSearchField(
|
|||
else onSearchChange(TextFieldValue())
|
||||
}) { CloseIcon(android.R.string.cancel) } },
|
||||
singleLine = true,
|
||||
colors = colors
|
||||
colors = colors,
|
||||
textStyle = contentTextDirectionStyle
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.settings
|
||||
|
||||
import android.provider.Settings
|
||||
import android.provider.Settings.Global
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.slideInHorizontally
|
||||
import androidx.compose.animation.slideOutHorizontally
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
|
||||
import helium314.keyboard.latin.settings.SettingsSubtype.Companion.toSettingsSubtype
|
||||
import helium314.keyboard.settings.screens.AboutScreen
|
||||
import helium314.keyboard.settings.screens.AdvancedSettingsScreen
|
||||
import helium314.keyboard.settings.screens.AppearanceScreen
|
||||
|
@ -24,6 +30,7 @@ import helium314.keyboard.settings.screens.PersonalDictionariesScreen
|
|||
import helium314.keyboard.settings.screens.PersonalDictionaryScreen
|
||||
import helium314.keyboard.settings.screens.PreferencesScreen
|
||||
import helium314.keyboard.settings.screens.SecondaryLayoutScreen
|
||||
import helium314.keyboard.settings.screens.SubtypeScreen
|
||||
import helium314.keyboard.settings.screens.TextCorrectionScreen
|
||||
import helium314.keyboard.settings.screens.ToolbarScreen
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
@ -41,6 +48,10 @@ fun SettingsNavHost(
|
|||
val dir = if (LocalLayoutDirection.current == LayoutDirection.Ltr) 1 else -1
|
||||
val target = SettingsDestination.navTarget.collectAsState()
|
||||
|
||||
// duration does not change when system setting changes, but that's rare enough to not care
|
||||
val duration = (250 * Settings.System.getFloat(LocalContext.current.contentResolver, Global.TRANSITION_ANIMATION_SCALE, 1f)).toInt()
|
||||
val animation = tween<IntOffset>(durationMillis = duration)
|
||||
|
||||
fun goBack() {
|
||||
if (!navController.popBackStack()) onClickBack()
|
||||
}
|
||||
|
@ -48,10 +59,10 @@ fun SettingsNavHost(
|
|||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = startDestination ?: SettingsDestination.Settings,
|
||||
enterTransition = { slideInHorizontally(initialOffsetX = { +it * dir }) },
|
||||
exitTransition = { slideOutHorizontally(targetOffsetX = { -it * dir }) },
|
||||
popEnterTransition = { slideInHorizontally(initialOffsetX = { -it * dir }) },
|
||||
popExitTransition = { slideOutHorizontally(targetOffsetX = { +it * dir }) }
|
||||
enterTransition = { slideInHorizontally(initialOffsetX = { +it * dir }, animationSpec = animation) },
|
||||
exitTransition = { slideOutHorizontally(targetOffsetX = { -it * dir }, animationSpec = animation) },
|
||||
popEnterTransition = { slideInHorizontally(initialOffsetX = { -it * dir }, animationSpec = animation) },
|
||||
popExitTransition = { slideOutHorizontally(targetOffsetX = { +it * dir }, animationSpec = animation) }
|
||||
) {
|
||||
composable(SettingsDestination.Settings) {
|
||||
MainSettingsScreen(
|
||||
|
@ -117,6 +128,9 @@ fun SettingsNavHost(
|
|||
composable(SettingsDestination.ColorsNight + "{theme}") {
|
||||
ColorsScreen(isNight = true, theme = it.arguments?.getString("theme"), onClickBack = ::goBack)
|
||||
}
|
||||
composable(SettingsDestination.Subtype + "{subtype}") {
|
||||
SubtypeScreen(initialSubtype = it.arguments?.getString("subtype")!!.toSettingsSubtype(), onClickBack = ::goBack)
|
||||
}
|
||||
}
|
||||
if (target.value != SettingsDestination.Settings/* && target.value != navController.currentBackStackEntry?.destination?.route*/)
|
||||
navController.navigate(route = target.value)
|
||||
|
@ -137,6 +151,7 @@ object SettingsDestination {
|
|||
const val PersonalDictionaries = "personal_dictionaries"
|
||||
const val PersonalDictionary = "personal_dictionary/"
|
||||
const val Languages = "languages"
|
||||
const val Subtype = "subtype/"
|
||||
const val Layouts = "layouts"
|
||||
const val Dictionaries = "dictionaries"
|
||||
val navTarget = MutableStateFlow(Settings)
|
||||
|
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
|
@ -24,6 +25,7 @@ import androidx.compose.ui.graphics.PaintingStyle
|
|||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
@ -109,8 +111,12 @@ fun ColorPickerDialog(
|
|||
)
|
||||
TextField(
|
||||
value = textValue,
|
||||
// todo: KeyboardType.Password is a crappy way of avoiding suggestions... is there really no way in compose?
|
||||
keyboardOptions = KeyboardOptions(autoCorrectEnabled = false, keyboardType = KeyboardType.Password),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
autoCorrectEnabled = false,
|
||||
keyboardType = KeyboardType.Password, // todo: KeyboardType.Password is a crappy way of avoiding suggestions... is there really no way in compose?
|
||||
imeAction = ImeAction.Done,
|
||||
),
|
||||
keyboardActions = KeyboardActions(onDone = { onDismissRequest(); onConfirmed(controller.selectedColor.value.toArgb()) }),
|
||||
onValueChange = {
|
||||
textValue = it
|
||||
val androidColor = runCatching { android.graphics.Color.parseColor("#${it.text}") }.getOrNull()
|
||||
|
|
|
@ -60,6 +60,7 @@ import helium314.keyboard.settings.Theme
|
|||
import helium314.keyboard.settings.filePicker
|
||||
import helium314.keyboard.settings.previewDark
|
||||
import helium314.keyboard.settings.screens.SaveThoseColors
|
||||
import helium314.keyboard.settings.contentTextDirectionStyle
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.SerializationException
|
||||
import kotlinx.serialization.json.Json
|
||||
|
@ -187,7 +188,8 @@ private fun AddColorRow(onDismissRequest: () -> Unit, userColors: Collection<Str
|
|||
onValueChange = { textValue = it },
|
||||
modifier = Modifier.weight(1f),
|
||||
singleLine = true,
|
||||
label = label
|
||||
label = label,
|
||||
textStyle = contentTextDirectionStyle,
|
||||
)
|
||||
EditButton(currentName.isNotBlank() && currentName !in userColors) {
|
||||
onDismissRequest()
|
||||
|
|
|
@ -29,6 +29,7 @@ import helium314.keyboard.latin.utils.getStringResourceOrName
|
|||
import helium314.keyboard.settings.CloseIcon
|
||||
import helium314.keyboard.settings.SettingsActivity
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.contentTextDirectionStyle
|
||||
import helium314.keyboard.settings.initPreview
|
||||
import helium314.keyboard.settings.previewDark
|
||||
import kotlinx.coroutines.Job
|
||||
|
@ -92,6 +93,7 @@ fun LayoutEditDialog(
|
|||
isError = !nameValid,
|
||||
supportingText = { if (!nameValid) Text(stringResource(R.string.name_invalid)) },
|
||||
trailingIcon = { if (!nameValid) CloseIcon(R.string.name_invalid) },
|
||||
textStyle = contentTextDirectionStyle,
|
||||
)
|
||||
},
|
||||
checkTextValid = { text ->
|
||||
|
|
|
@ -50,6 +50,7 @@ import helium314.keyboard.settings.EditButton
|
|||
import helium314.keyboard.settings.Setting
|
||||
import helium314.keyboard.settings.SettingsActivity
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.contentTextDirectionStyle
|
||||
import helium314.keyboard.settings.layoutFilePicker
|
||||
import helium314.keyboard.settings.layoutIntent
|
||||
import helium314.keyboard.settings.previewDark
|
||||
|
@ -140,7 +141,8 @@ private fun AddLayoutRow(onNewLayout: (String) -> Unit, layoutType: LayoutType,
|
|||
value = textValue,
|
||||
onValueChange = { textValue = it },
|
||||
modifier = Modifier.weight(1f),
|
||||
singleLine = true
|
||||
singleLine = true,
|
||||
textStyle = contentTextDirectionStyle,
|
||||
)
|
||||
EditButton(textValue.text.isNotEmpty() && LayoutUtilsCustom.getLayoutName(textValue.text, layoutType) !in userLayouts) {
|
||||
onNewLayout(textValue.text)
|
||||
|
|
|
@ -22,6 +22,7 @@ import androidx.compose.ui.text.input.TextFieldValue
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.contentTextDirectionStyle
|
||||
import helium314.keyboard.settings.previewDark
|
||||
|
||||
// mostly taken from StreetComplete / SCEE
|
||||
|
@ -76,7 +77,8 @@ fun TextInputDialog(
|
|||
.focusRequester(focusRequester),
|
||||
label = textInputLabel,
|
||||
keyboardOptions = KeyboardOptions(keyboardType = keyboardType),
|
||||
singleLine = singleLine
|
||||
singleLine = singleLine,
|
||||
textStyle = contentTextDirectionStyle,
|
||||
)
|
||||
},
|
||||
properties = properties,
|
||||
|
|
|
@ -35,10 +35,13 @@ fun LoadGestureLibPreference(setting: Setting) {
|
|||
val abi = Build.SUPPORTED_ABIS[0]
|
||||
val libFile = File(ctx.filesDir?.absolutePath + File.separator + JniUtils.JNI_LIB_IMPORT_FILE_NAME)
|
||||
fun renameToLibFileAndRestart(file: File, checksum: String) {
|
||||
libFile.setWritable(true)
|
||||
libFile.delete()
|
||||
// store checksum in default preferences (soo JniUtils)
|
||||
// store checksum in default preferences (see JniUtils)
|
||||
prefs.edit().putString(Settings.PREF_LIBRARY_CHECKSUM, checksum).commit()
|
||||
file.renameTo(libFile)
|
||||
file.copyTo(libFile)
|
||||
libFile.setReadOnly()
|
||||
file.delete()
|
||||
Runtime.getRuntime().exit(0) // exit will restart the app, so library will be loaded
|
||||
}
|
||||
var tempFilePath: String? by rememberSaveable { mutableStateOf(null) }
|
||||
|
|
|
@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.RowScope
|
|||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
|
@ -29,6 +28,7 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import helium314.keyboard.latin.R
|
||||
import helium314.keyboard.settings.IconOrImage
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.previewDark
|
||||
|
||||
|
@ -64,12 +64,12 @@ fun Preference(
|
|||
.fillMaxWidth()
|
||||
.clickable { onClick() }
|
||||
.heightIn(min = 44.dp)
|
||||
.padding(12.dp),
|
||||
.padding(vertical = 10.dp, horizontal = 12.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (icon != null)
|
||||
Icon(painterResource(icon), name, modifier = Modifier.size(36.dp))
|
||||
IconOrImage(icon, name, 32f)
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(text = name, style = MaterialTheme.typography.bodyLarge)
|
||||
if (description != null) {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.settings.preferences
|
||||
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import helium314.keyboard.keyboard.KeyboardSwitcher
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
import helium314.keyboard.settings.Setting
|
||||
import helium314.keyboard.settings.dialogs.TextInputDialog
|
||||
|
||||
@Composable
|
||||
fun TextInputPreference(setting: Setting, default: String, checkTextValid: (String) -> Boolean = { true }) {
|
||||
var showDialog by rememberSaveable { mutableStateOf(false) }
|
||||
val prefs = LocalContext.current.prefs()
|
||||
Preference(
|
||||
name = setting.title,
|
||||
onClick = { showDialog = true },
|
||||
description = prefs.getString(setting.key, default)?.takeIf { it.isNotEmpty() }
|
||||
)
|
||||
if (showDialog) {
|
||||
TextInputDialog(
|
||||
onDismissRequest = { showDialog = false },
|
||||
onConfirmed = {
|
||||
prefs.edit().putString(setting.key, it).apply()
|
||||
KeyboardSwitcher.getInstance().setThemeNeedsReload()
|
||||
},
|
||||
initialText = prefs.getString(setting.key, default) ?: "",
|
||||
title = { Text(setting.title) },
|
||||
checkTextValid = checkTextValid
|
||||
)
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
package helium314.keyboard.settings.screens
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.text.method.LinkMovementMethod
|
||||
|
@ -10,7 +11,6 @@ import android.widget.TextView
|
|||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
|
@ -69,7 +69,7 @@ fun createAboutSettings(context: Context) = listOf(
|
|||
name = it.title,
|
||||
description = it.description,
|
||||
onClick = { },
|
||||
icon = R.drawable.ic_launcher_foreground // use the bitmap trick here if we really want the colored icon
|
||||
icon = R.mipmap.ic_launcher_round
|
||||
)
|
||||
},
|
||||
Setting(context, SettingsWithoutKey.VERSION, R.string.version) {
|
||||
|
|
|
@ -29,6 +29,7 @@ import helium314.keyboard.latin.common.splitOnWhitespace
|
|||
import helium314.keyboard.latin.settings.DebugSettings
|
||||
import helium314.keyboard.latin.settings.Defaults
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.latin.utils.checkTimestampFormat
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
import helium314.keyboard.settings.NextScreenIcon
|
||||
import helium314.keyboard.settings.SettingsContainer
|
||||
|
@ -45,6 +46,7 @@ import helium314.keyboard.settings.Theme
|
|||
import helium314.keyboard.settings.dialogs.TextInputDialog
|
||||
import helium314.keyboard.settings.preferences.BackupRestorePreference
|
||||
import helium314.keyboard.settings.preferences.LoadGestureLibPreference
|
||||
import helium314.keyboard.settings.preferences.TextInputPreference
|
||||
import helium314.keyboard.settings.previewDark
|
||||
|
||||
@Composable
|
||||
|
@ -66,10 +68,12 @@ fun AdvancedSettingsScreen(
|
|||
Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY,
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) Settings.PREF_SHOW_SETUP_WIZARD_ICON else null,
|
||||
Settings.PREF_ABC_AFTER_SYMBOL_SPACE,
|
||||
Settings.PREF_ABC_AFTER_NUMPAD_SPACE,
|
||||
Settings.PREF_ABC_AFTER_EMOJI,
|
||||
Settings.PREF_ABC_AFTER_CLIP,
|
||||
Settings.PREF_CUSTOM_CURRENCY_KEY,
|
||||
Settings.PREF_MORE_POPUP_KEYS,
|
||||
Settings.PREF_TIMESTAMP_FORMAT,
|
||||
SettingsWithoutKey.BACKUP_RESTORE,
|
||||
if (BuildConfig.DEBUG || prefs.getBoolean(DebugSettings.PREF_SHOW_DEBUG_SETTINGS, Defaults.PREF_SHOW_DEBUG_SETTINGS))
|
||||
SettingsWithoutKey.DEBUG_SETTINGS else null,
|
||||
|
@ -154,6 +158,11 @@ fun createAdvancedSettings(context: Context) = listOf(
|
|||
{
|
||||
SwitchPreference(it, Defaults.PREF_ABC_AFTER_SYMBOL_SPACE)
|
||||
},
|
||||
Setting(context, Settings.PREF_ABC_AFTER_NUMPAD_SPACE,
|
||||
R.string.switch_keyboard_after, R.string.after_numpad_and_space)
|
||||
{
|
||||
SwitchPreference(it, Defaults.PREF_ABC_AFTER_NUMPAD_SPACE)
|
||||
},
|
||||
Setting(context, Settings.PREF_ABC_AFTER_EMOJI, R.string.switch_keyboard_after, R.string.after_emoji) {
|
||||
SwitchPreference(it, Defaults.PREF_ABC_AFTER_EMOJI)
|
||||
},
|
||||
|
@ -189,6 +198,9 @@ fun createAdvancedSettings(context: Context) = listOf(
|
|||
Setting(context, SettingsWithoutKey.BACKUP_RESTORE, R.string.backup_restore_title) {
|
||||
BackupRestorePreference(it)
|
||||
},
|
||||
Setting(context, Settings.PREF_TIMESTAMP_FORMAT, R.string.timestamp_format_title) {
|
||||
TextInputPreference(it, Defaults.PREF_TIMESTAMP_FORMAT) { checkTimestampFormat(it) }
|
||||
},
|
||||
Setting(context, SettingsWithoutKey.DEBUG_SETTINGS, R.string.debug_settings_title) {
|
||||
Preference(
|
||||
name = it.title,
|
||||
|
|
|
@ -21,6 +21,7 @@ import helium314.keyboard.latin.R
|
|||
import helium314.keyboard.latin.settings.Defaults
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.latin.utils.Log
|
||||
import helium314.keyboard.latin.utils.checkTimestampFormat
|
||||
import helium314.keyboard.latin.utils.getActivity
|
||||
import helium314.keyboard.latin.utils.getStringResourceOrName
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
|
@ -39,6 +40,7 @@ import helium314.keyboard.settings.dialogs.TextInputDialog
|
|||
import helium314.keyboard.settings.initPreview
|
||||
import helium314.keyboard.settings.preferences.BackgroundImagePref
|
||||
import helium314.keyboard.settings.preferences.CustomFontPreference
|
||||
import helium314.keyboard.settings.preferences.TextInputPreference
|
||||
import helium314.keyboard.settings.previewDark
|
||||
|
||||
@Composable
|
||||
|
@ -263,26 +265,8 @@ fun createAppearanceSettings(context: Context) = listOf(
|
|||
description = { "${(100 * it).toInt()}%" }
|
||||
) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
},
|
||||
Setting(context, Settings.PREF_SPACE_BAR_TEXT, R.string.prefs_space_bar_text) { setting ->
|
||||
var showDialog by rememberSaveable { mutableStateOf(false) }
|
||||
val prefs = LocalContext.current.prefs()
|
||||
Preference(
|
||||
name = setting.title,
|
||||
onClick = { showDialog = true },
|
||||
description = prefs.getString(setting.key, Defaults.PREF_SPACE_BAR_TEXT)?.takeIf { it.isNotEmpty() }
|
||||
)
|
||||
if (showDialog) {
|
||||
TextInputDialog(
|
||||
onDismissRequest = { showDialog = false },
|
||||
onConfirmed = {
|
||||
prefs.edit().putString(setting.key, it).apply()
|
||||
KeyboardSwitcher.getInstance().setThemeNeedsReload()
|
||||
},
|
||||
initialText = prefs.getString(setting.key, Defaults.PREF_SPACE_BAR_TEXT) ?: "",
|
||||
title = { Text(setting.title) },
|
||||
checkTextValid = { true }
|
||||
)
|
||||
}
|
||||
Setting(context, Settings.PREF_SPACE_BAR_TEXT, R.string.prefs_space_bar_text) {
|
||||
TextInputPreference(it, Defaults.PREF_SPACE_BAR_TEXT)
|
||||
},
|
||||
Setting(context, SettingsWithoutKey.CUSTOM_FONT, R.string.custom_font) {
|
||||
CustomFontPreference(it)
|
||||
|
|
|
@ -58,6 +58,7 @@ import helium314.keyboard.settings.CloseIcon
|
|||
import helium314.keyboard.settings.SearchScreen
|
||||
import helium314.keyboard.settings.SettingsActivity
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.contentTextDirectionStyle
|
||||
import helium314.keyboard.settings.dialogs.ColorPickerDialog
|
||||
import helium314.keyboard.settings.previewDark
|
||||
import kotlinx.serialization.Serializable
|
||||
|
@ -70,6 +71,14 @@ fun ColorsScreen(
|
|||
onClickBack: () -> Unit
|
||||
) {
|
||||
val ctx = LocalContext.current
|
||||
val prefs = ctx.prefs()
|
||||
val b = (ctx.getActivity() as? SettingsActivity)?.prefChanged?.collectAsState()
|
||||
if ((b?.value ?: 0) < 0)
|
||||
Log.v("irrelevant", "stupid way to trigger recomposition on preference change")
|
||||
|
||||
val themeName = theme ?: if (isNight) prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, Defaults.PREF_THEME_COLORS_NIGHT)!!
|
||||
else prefs.getString(Settings.PREF_THEME_COLORS, Defaults.PREF_THEME_COLORS)!!
|
||||
var newThemeName by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue(themeName)) }
|
||||
|
||||
// is there really no better way of only setting forceOpposite while the screen is shown (and not paused)?
|
||||
// lifecycle stuff is weird, there is no pause and similar when activity is paused
|
||||
|
@ -82,21 +91,14 @@ fun ColorsScreen(
|
|||
val lifecycleState by lifecycleOwner.lifecycle.currentStateFlow.collectAsState()
|
||||
LaunchedEffect(lifecycleState) {
|
||||
if (lifecycleState == Lifecycle.State.RESUMED) {
|
||||
(ctx.getActivity() as? SettingsActivity)?.setForceTheme(theme, isNight)
|
||||
(ctx.getActivity() as? SettingsActivity)?.setForceTheme(newThemeName.text, isNight)
|
||||
}
|
||||
}
|
||||
|
||||
val prefs = ctx.prefs()
|
||||
val b = (ctx.getActivity() as? SettingsActivity)?.prefChanged?.collectAsState()
|
||||
if ((b?.value ?: 0) < 0)
|
||||
Log.v("irrelevant", "stupid way to trigger recomposition on preference change")
|
||||
|
||||
val themeName = theme ?: if (isNight) prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, Defaults.PREF_THEME_COLORS_NIGHT)!!
|
||||
else prefs.getString(Settings.PREF_THEME_COLORS, Defaults.PREF_THEME_COLORS)!!
|
||||
val moreColors = KeyboardTheme.readUserMoreColors(prefs, themeName)
|
||||
val userColors = KeyboardTheme.readUserColors(prefs, themeName)
|
||||
val moreColors = KeyboardTheme.readUserMoreColors(prefs, newThemeName.text)
|
||||
val userColors = KeyboardTheme.readUserColors(prefs, newThemeName.text)
|
||||
val shownColors = if (moreColors == 2) {
|
||||
val allColors = KeyboardTheme.readUserAllColors(prefs, themeName)
|
||||
val allColors = KeyboardTheme.readUserAllColors(prefs, newThemeName.text)
|
||||
ColorType.entries.map {
|
||||
ColorSetting(it.name, null, allColors[it] ?: it.default())
|
||||
}
|
||||
|
@ -113,12 +115,11 @@ fun ColorsScreen(
|
|||
fun ColorSetting.displayColor() = if (auto == true) KeyboardTheme.determineUserColor(userColors, ctx, name, isNight)
|
||||
else color ?: KeyboardTheme.determineUserColor(userColors, ctx, name, isNight)
|
||||
|
||||
var newThemeName by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue(themeName)) }
|
||||
var chosenColorString: String by rememberSaveable { mutableStateOf("") }
|
||||
val chosenColor = runCatching { Json.decodeFromString<ColorSetting?>(chosenColorString) }.getOrNull()
|
||||
val saveLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
|
||||
val uri = it.data?.data ?: return@rememberLauncherForActivityResult
|
||||
val saveLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
|
||||
val uri = result.data?.data ?: return@rememberLauncherForActivityResult
|
||||
ctx.getActivity()?.contentResolver?.openOutputStream(uri)?.writer()?.use { it.write(getColorString(prefs, newThemeName.text)) }
|
||||
}
|
||||
SearchScreen(
|
||||
|
@ -129,14 +130,17 @@ fun ColorsScreen(
|
|||
value = nameField,
|
||||
onValueChange = {
|
||||
nameValid = KeyboardTheme.renameUserColors(newThemeName.text, it.text, prefs)
|
||||
if (nameValid)
|
||||
if (nameValid) {
|
||||
newThemeName = it
|
||||
SettingsActivity.forceTheme = newThemeName.text
|
||||
}
|
||||
nameField = it
|
||||
},
|
||||
isError = !nameValid,
|
||||
// supportingText = { if (!nameValid) Text(stringResource(R.string.name_invalid)) } // todo: this is cutting off bottom half of the actual text...
|
||||
trailingIcon = { if (!nameValid) CloseIcon(R.string.name_invalid) },
|
||||
singleLine = true,
|
||||
textStyle = contentTextDirectionStyle,
|
||||
)
|
||||
},
|
||||
menu = listOf(
|
||||
|
@ -193,11 +197,11 @@ fun ColorsScreen(
|
|||
}
|
||||
}
|
||||
if (colorSetting.auto != null)
|
||||
Switch(colorSetting.auto, onCheckedChange = {
|
||||
val oldUserColors = KeyboardTheme.readUserColors(prefs, themeName)
|
||||
val newUserColors = (oldUserColors + ColorSetting(colorSetting.name, it, colorSetting.color))
|
||||
Switch(colorSetting.auto, onCheckedChange = { checked ->
|
||||
val oldUserColors = KeyboardTheme.readUserColors(prefs, newThemeName.text)
|
||||
val newUserColors = (oldUserColors + ColorSetting(colorSetting.name, checked, colorSetting.color))
|
||||
.reversed().distinctBy { it.displayName }
|
||||
KeyboardTheme.writeUserColors(prefs, themeName, newUserColors)
|
||||
KeyboardTheme.writeUserColors(prefs, newThemeName.text, newUserColors)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -207,16 +211,16 @@ fun ColorsScreen(
|
|||
onDismissRequest = { chosenColorString = "" },
|
||||
initialColor = chosenColor.displayColor(),
|
||||
title = chosenColor.displayName,
|
||||
) {
|
||||
) { color ->
|
||||
if (moreColors == 2) {
|
||||
val oldColors = KeyboardTheme.readUserAllColors(prefs, themeName)
|
||||
oldColors[ColorType.valueOf(chosenColor.name)] = it
|
||||
KeyboardTheme.writeUserAllColors(prefs, themeName, oldColors)
|
||||
val oldColors = KeyboardTheme.readUserAllColors(prefs, newThemeName.text)
|
||||
oldColors[ColorType.valueOf(chosenColor.name)] = color
|
||||
KeyboardTheme.writeUserAllColors(prefs, newThemeName.text, oldColors)
|
||||
} else {
|
||||
val oldUserColors = KeyboardTheme.readUserColors(prefs, themeName)
|
||||
val newUserColors = (oldUserColors + ColorSetting(chosenColor.name, false, it))
|
||||
val oldUserColors = KeyboardTheme.readUserColors(prefs, newThemeName.text)
|
||||
val newUserColors = (oldUserColors + ColorSetting(chosenColor.name, false, color))
|
||||
.reversed().distinctBy { it.displayName }
|
||||
KeyboardTheme.writeUserColors(prefs, themeName, newUserColors)
|
||||
KeyboardTheme.writeUserColors(prefs, newThemeName.text, newUserColors)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import androidx.compose.runtime.collectAsState
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
@ -39,15 +38,14 @@ import helium314.keyboard.latin.utils.Log
|
|||
import helium314.keyboard.latin.utils.MissingDictionaryDialog
|
||||
import helium314.keyboard.latin.utils.SubtypeLocaleUtils
|
||||
import helium314.keyboard.latin.utils.SubtypeSettings
|
||||
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
|
||||
import helium314.keyboard.latin.utils.displayName
|
||||
import helium314.keyboard.latin.utils.getActivity
|
||||
import helium314.keyboard.latin.utils.locale
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
import helium314.keyboard.settings.SearchScreen
|
||||
import helium314.keyboard.settings.SettingsActivity
|
||||
import helium314.keyboard.settings.SettingsDestination
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.dialogs.SubtypeDialog
|
||||
import helium314.keyboard.settings.initPreview
|
||||
import helium314.keyboard.settings.previewDark
|
||||
import java.util.Locale
|
||||
|
@ -57,12 +55,11 @@ fun LanguageScreen(
|
|||
onClickBack: () -> Unit,
|
||||
) {
|
||||
val ctx = LocalContext.current
|
||||
var sortedSubtypes by remember { mutableStateOf(getSortedSubtypes(ctx)) }
|
||||
val sortedSubtypes by remember { mutableStateOf(getSortedSubtypes(ctx)) }
|
||||
val prefs = ctx.prefs()
|
||||
val b = (LocalContext.current.getActivity() as? SettingsActivity)?.prefChanged?.collectAsState()
|
||||
if ((b?.value ?: 0) < 0)
|
||||
Log.v("irrelevant", "stupid way to trigger recomposition on preference change")
|
||||
var selectedSubtype: String? by rememberSaveable { mutableStateOf(null) }
|
||||
val enabledSubtypes = SubtypeSettings.getEnabledSubtypes()
|
||||
SearchScreen(
|
||||
onClickBack = onClickBack,
|
||||
|
@ -87,7 +84,9 @@ fun LanguageScreen(
|
|||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { selectedSubtype = item.toSettingsSubtype().toPref() }
|
||||
.clickable {
|
||||
SettingsDestination.navigateTo(SettingsDestination.Subtype + item.toSettingsSubtype().toPref())
|
||||
}
|
||||
.padding(vertical = 6.dp, horizontal = 16.dp)
|
||||
) {
|
||||
var showNoDictDialog by remember { mutableStateOf(false) }
|
||||
|
@ -119,19 +118,6 @@ fun LanguageScreen(
|
|||
}
|
||||
}
|
||||
)
|
||||
if (selectedSubtype != null) {
|
||||
val oldSubtype = selectedSubtype!!.toSettingsSubtype()
|
||||
SubtypeDialog(
|
||||
onDismissRequest = {
|
||||
selectedSubtype = null
|
||||
sortedSubtypes = getSortedSubtypes(ctx)
|
||||
},
|
||||
onConfirmed = {
|
||||
SubtypeUtilsAdditional.changeAdditionalSubtype(oldSubtype, it, ctx)
|
||||
},
|
||||
initialSubtype = oldSubtype
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun dictsAvailable(locale: Locale, context: Context): Boolean {
|
||||
|
|
|
@ -46,6 +46,7 @@ fun PreferencesScreen(
|
|||
Settings.PREF_POPUP_KEYS_LABELS_ORDER else null,
|
||||
Settings.PREF_POPUP_KEYS_ORDER,
|
||||
Settings.PREF_SHOW_POPUP_HINTS,
|
||||
Settings.PREF_SHOW_TLD_POPUP_KEYS,
|
||||
Settings.PREF_POPUP_ON,
|
||||
if (AudioAndHapticFeedbackManager.getInstance().hasVibrator())
|
||||
Settings.PREF_VIBRATE_ON else null,
|
||||
|
@ -89,6 +90,12 @@ fun createPreferencesSettings(context: Context) = listOf(
|
|||
Setting(context, Settings.PREF_POPUP_KEYS_ORDER, R.string.popup_order) {
|
||||
ReorderSwitchPreference(it, Defaults.PREF_POPUP_KEYS_ORDER)
|
||||
},
|
||||
Setting(
|
||||
context, Settings.PREF_SHOW_TLD_POPUP_KEYS, R.string.show_tld_popup_keys,
|
||||
R.string.show_tld_popup_keys_summary
|
||||
) {
|
||||
SwitchPreference(it, Defaults.PREF_SHOW_TLD_POPUP_KEYS) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
},
|
||||
Setting(context, Settings.PREF_SHOW_POPUP_HINTS, R.string.show_popup_hints, R.string.show_popup_hints_summary) {
|
||||
SwitchPreference(it, Defaults.PREF_SHOW_POPUP_HINTS) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||
},
|
||||
|
@ -149,10 +156,10 @@ fun createPreferencesSettings(context: Context) = listOf(
|
|||
key = setting.key,
|
||||
default = Defaults.PREF_CLIPBOARD_HISTORY_RETENTION_TIME,
|
||||
description = {
|
||||
if (it < 0) stringResource(R.string.settings_no_limit)
|
||||
if (it > 120) stringResource(R.string.settings_no_limit)
|
||||
else stringResource(R.string.abbreviation_unit_minutes, it.toString())
|
||||
},
|
||||
range = -1f..120f,
|
||||
range = 1f..121f,
|
||||
)
|
||||
},
|
||||
Setting(context, Settings.PREF_VIBRATION_DURATION_SETTINGS, R.string.prefs_keypress_vibration_duration_settings) { setting ->
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.settings.dialogs
|
||||
package helium314.keyboard.settings.screens
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.clickable
|
||||
|
@ -14,6 +13,7 @@ import androidx.compose.material3.HorizontalDivider
|
|||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
|
@ -68,22 +68,32 @@ import helium314.keyboard.latin.utils.getStringResourceOrName
|
|||
import helium314.keyboard.latin.utils.mainLayoutName
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
import helium314.keyboard.settings.DefaultButton
|
||||
import helium314.keyboard.settings.DeleteButton
|
||||
import helium314.keyboard.settings.DropDownField
|
||||
import helium314.keyboard.settings.SearchScreen
|
||||
import helium314.keyboard.settings.SettingsActivity
|
||||
import helium314.keyboard.settings.Theme
|
||||
import helium314.keyboard.settings.WithSmallTitle
|
||||
import helium314.keyboard.settings.dialogs.ConfirmationDialog
|
||||
import helium314.keyboard.settings.dialogs.LayoutEditDialog
|
||||
import helium314.keyboard.settings.dialogs.ListPickerDialog
|
||||
import helium314.keyboard.settings.dialogs.MultiListPickerDialog
|
||||
import helium314.keyboard.settings.dialogs.ReorderDialog
|
||||
import helium314.keyboard.settings.initPreview
|
||||
import helium314.keyboard.settings.layoutFilePicker
|
||||
import helium314.keyboard.settings.layoutIntent
|
||||
import helium314.keyboard.settings.previewDark
|
||||
import helium314.keyboard.settings.screens.GetIcon
|
||||
import java.util.Locale
|
||||
|
||||
// todo:
|
||||
// dropdowns are weird
|
||||
// at very least too wide and too high
|
||||
// also too wide left (anchor should be icon)
|
||||
// title shows only the layout name
|
||||
@Composable
|
||||
fun SubtypeDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
fun SubtypeScreen(
|
||||
initialSubtype: SettingsSubtype,
|
||||
onConfirmed: (SettingsSubtype) -> Unit,
|
||||
onClickBack: () -> Unit,
|
||||
) {
|
||||
val ctx = LocalContext.current
|
||||
val prefs = ctx.prefs()
|
||||
|
@ -92,7 +102,10 @@ fun SubtypeDialog(
|
|||
Log.v("irrelevant", "stupid way to trigger recomposition on preference change")
|
||||
var currentSubtypeString by rememberSaveable { mutableStateOf(initialSubtype.toPref()) }
|
||||
val currentSubtype = currentSubtypeString.toSettingsSubtype()
|
||||
fun setCurrentSubtype(subtype: SettingsSubtype) { currentSubtypeString = subtype.toPref() }
|
||||
fun setCurrentSubtype(subtype: SettingsSubtype) {
|
||||
SubtypeUtilsAdditional.changeAdditionalSubtype(currentSubtype, subtype, ctx)
|
||||
currentSubtypeString = subtype.toPref()
|
||||
}
|
||||
LaunchedEffect(currentSubtypeString) {
|
||||
if (ScriptUtils.scriptSupportsUppercase(currentSubtype.locale)) return@LaunchedEffect
|
||||
// update the noShiftKey extra value
|
||||
|
@ -120,120 +133,119 @@ fun SubtypeDialog(
|
|||
var showMorePopupsDialog by remember { mutableStateOf(false) }
|
||||
val scrollState = rememberScrollState()
|
||||
val customMainLayouts = LayoutUtilsCustom.getLayoutFiles(LayoutType.MAIN, ctx, currentSubtype.locale).map { it.name }
|
||||
ThreeButtonAlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
onConfirmed = { onConfirmed(currentSubtype) },
|
||||
neutralButtonText = if (initialSubtype.isAdditionalSubtype(prefs)) stringResource(R.string.delete) else null,
|
||||
onNeutral = {
|
||||
SubtypeUtilsAdditional.removeAdditionalSubtype(ctx, initialSubtype.toAdditionalSubtype())
|
||||
SubtypeSettings.removeEnabledSubtype(ctx, initialSubtype.toAdditionalSubtype())
|
||||
onDismissRequest()
|
||||
},
|
||||
SearchScreen(
|
||||
onClickBack = onClickBack,
|
||||
icon = { if (currentSubtype.isAdditionalSubtype(prefs)) DeleteButton {
|
||||
SubtypeUtilsAdditional.removeAdditionalSubtype(ctx, currentSubtype.toAdditionalSubtype())
|
||||
SubtypeSettings.removeEnabledSubtype(ctx, currentSubtype.toAdditionalSubtype())
|
||||
onClickBack()
|
||||
} },
|
||||
title = {
|
||||
val mainLayout = initialSubtype.mainLayoutName() ?: SubtypeLocaleUtils.QWERTY
|
||||
Text(SubtypeLocaleUtils.getDisplayNameInSystemLocale(mainLayout, initialSubtype.locale))
|
||||
val mainLayout = currentSubtype.mainLayoutName() ?: SubtypeLocaleUtils.QWERTY
|
||||
Text(SubtypeLocaleUtils.getDisplayNameInSystemLocale(mainLayout, currentSubtype.locale))
|
||||
},
|
||||
content = {
|
||||
Column(
|
||||
modifier = Modifier.verticalScroll(scrollState),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
MainLayoutRow(initialSubtype, currentSubtype, customMainLayouts) { setCurrentSubtype(it) }
|
||||
if (availableLocalesForScript.size > 1) {
|
||||
WithSmallTitle(stringResource(R.string.secondary_locale)) {
|
||||
TextButton(onClick = { showSecondaryLocaleDialog = true }) {
|
||||
val text = getSecondaryLocales(currentSubtype.extraValues).joinToString(", ") {
|
||||
it.localizedDisplayName(ctx)
|
||||
}.ifEmpty { stringResource(R.string.action_none) }
|
||||
Text(text, Modifier.fillMaxWidth(), style = MaterialTheme.typography.bodyLarge)
|
||||
}
|
||||
itemContent = { },
|
||||
filteredItems = { emptyList<String>() }
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.verticalScroll(scrollState).padding(horizontal = 12.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
MainLayoutRow(currentSubtype, customMainLayouts) { setCurrentSubtype(it) }
|
||||
if (availableLocalesForScript.size > 1) {
|
||||
WithSmallTitle(stringResource(R.string.secondary_locale)) {
|
||||
TextButton(onClick = { showSecondaryLocaleDialog = true }) {
|
||||
val text = getSecondaryLocales(currentSubtype.extraValues).joinToString(", ") {
|
||||
it.localizedDisplayName(ctx)
|
||||
}.ifEmpty { stringResource(R.string.action_none) }
|
||||
Text(text, Modifier.fillMaxWidth())
|
||||
}
|
||||
}
|
||||
Row {
|
||||
TextButton(onClick = { showKeyOrderDialog = true }, Modifier.weight(1f))
|
||||
{ Text(stringResource(R.string.popup_order), style = MaterialTheme.typography.bodyLarge) }
|
||||
DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER) == null) {
|
||||
setCurrentSubtype(currentSubtype.without(ExtraValue.POPUP_ORDER))
|
||||
}
|
||||
}
|
||||
Row {
|
||||
TextButton(onClick = { showKeyOrderDialog = true }, Modifier.weight(1f))
|
||||
{ Text(stringResource(R.string.popup_order)) }
|
||||
DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER) == null) {
|
||||
setCurrentSubtype(currentSubtype.without(ExtraValue.POPUP_ORDER))
|
||||
}
|
||||
Row {
|
||||
TextButton(onClick = { showHintOrderDialog = true }, Modifier.weight(1f))
|
||||
{ Text(stringResource(R.string.hint_source), style = MaterialTheme.typography.bodyLarge) }
|
||||
DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER) == null) {
|
||||
setCurrentSubtype(currentSubtype.without(ExtraValue.HINT_ORDER))
|
||||
}
|
||||
}
|
||||
Row {
|
||||
TextButton(onClick = { showHintOrderDialog = true }, Modifier.weight(1f))
|
||||
{ Text(stringResource(R.string.hint_source)) }
|
||||
DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER) == null) {
|
||||
setCurrentSubtype(currentSubtype.without(ExtraValue.HINT_ORDER))
|
||||
}
|
||||
if (currentSubtype.locale.script() == ScriptUtils.SCRIPT_LATIN) {
|
||||
WithSmallTitle(stringResource(R.string.show_popup_keys_title)) {
|
||||
val explicitValue = currentSubtype.getExtraValueOf(ExtraValue.MORE_POPUPS)
|
||||
val value = explicitValue ?: prefs.getString(Settings.PREF_MORE_POPUP_KEYS, Defaults.PREF_MORE_POPUP_KEYS)!!
|
||||
Row {
|
||||
TextButton(onClick = { showMorePopupsDialog = true }, Modifier.weight(1f))
|
||||
{ Text(stringResource(morePopupKeysResId(value))) }
|
||||
DefaultButton(explicitValue == null) {
|
||||
setCurrentSubtype(currentSubtype.without(ExtraValue.MORE_POPUPS))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasLocalizedNumberRow(currentSubtype.locale, ctx)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
val checked = currentSubtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean()
|
||||
Text(stringResource(R.string.localized_number_row), Modifier.weight(1f))
|
||||
Switch(
|
||||
checked = checked ?: prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, Defaults.PREF_LOCALIZED_NUMBER_ROW),
|
||||
onCheckedChange = {
|
||||
setCurrentSubtype(currentSubtype.with(ExtraValue.LOCALIZED_NUMBER_ROW, it.toString()))
|
||||
}
|
||||
)
|
||||
DefaultButton(checked == null) {
|
||||
setCurrentSubtype(currentSubtype.without(ExtraValue.LOCALIZED_NUMBER_ROW))
|
||||
}
|
||||
}
|
||||
}
|
||||
HorizontalDivider()
|
||||
Text(stringResource(R.string.settings_screen_secondary_layouts), style = MaterialTheme.typography.titleMedium)
|
||||
LayoutType.entries.forEach { type ->
|
||||
if (type == LayoutType.MAIN) return@forEach
|
||||
WithSmallTitle(stringResource(type.displayNameId)) {
|
||||
val explicitLayout = currentSubtype.layoutName(type)
|
||||
val layout = explicitLayout ?: Settings.readDefaultLayoutName(type, prefs)
|
||||
val defaultLayouts = LayoutUtils.getAvailableLayouts(type, ctx)
|
||||
val customLayouts = LayoutUtilsCustom.getLayoutFiles(type, ctx).map { it.name }
|
||||
DropDownField(
|
||||
items = defaultLayouts + customLayouts,
|
||||
selectedItem = layout,
|
||||
onSelected = {
|
||||
setCurrentSubtype(currentSubtype.withLayout(type, it))
|
||||
},
|
||||
extraButton = { DefaultButton(explicitLayout == null) {
|
||||
setCurrentSubtype(currentSubtype.withoutLayout(type))
|
||||
} },
|
||||
) {
|
||||
val displayName = if (LayoutUtilsCustom.isCustomLayout(it)) LayoutUtilsCustom.getDisplayName(it)
|
||||
else it.getStringResourceOrName("layout_", ctx)
|
||||
var showLayoutEditDialog by remember { mutableStateOf(false) }
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(displayName, Modifier.padding(end = 8.dp))
|
||||
if (LayoutUtilsCustom.isCustomLayout(it))
|
||||
Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.edit_layout), Modifier.clickable { showLayoutEditDialog = true })
|
||||
}
|
||||
if (showLayoutEditDialog)
|
||||
LayoutEditDialog(
|
||||
onDismissRequest = { showLayoutEditDialog = false },
|
||||
layoutType = type,
|
||||
initialLayoutName = it,
|
||||
isNameValid = null
|
||||
)
|
||||
}
|
||||
if (currentSubtype.locale.script() == ScriptUtils.SCRIPT_LATIN) {
|
||||
WithSmallTitle(stringResource(R.string.show_popup_keys_title)) {
|
||||
val explicitValue = currentSubtype.getExtraValueOf(ExtraValue.MORE_POPUPS)
|
||||
val value = explicitValue ?: prefs.getString(Settings.PREF_MORE_POPUP_KEYS, Defaults.PREF_MORE_POPUP_KEYS)!!
|
||||
Row {
|
||||
TextButton(onClick = { showMorePopupsDialog = true }, Modifier.weight(1f))
|
||||
{ Text(stringResource(morePopupKeysResId(value))) }
|
||||
DefaultButton(explicitValue == null) {
|
||||
setCurrentSubtype(currentSubtype.without(ExtraValue.MORE_POPUPS))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasLocalizedNumberRow(currentSubtype.locale, ctx)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
val checked = currentSubtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean()
|
||||
Text(stringResource(R.string.localized_number_row), Modifier.weight(1f))
|
||||
Switch(
|
||||
checked = checked ?: prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, Defaults.PREF_LOCALIZED_NUMBER_ROW),
|
||||
onCheckedChange = {
|
||||
setCurrentSubtype(currentSubtype.with(ExtraValue.LOCALIZED_NUMBER_ROW, it.toString()))
|
||||
}
|
||||
)
|
||||
DefaultButton(checked == null) {
|
||||
setCurrentSubtype(currentSubtype.without(ExtraValue.LOCALIZED_NUMBER_ROW))
|
||||
}
|
||||
}
|
||||
}
|
||||
HorizontalDivider()
|
||||
Text(stringResource(R.string.settings_screen_secondary_layouts), style = MaterialTheme.typography.titleMedium)
|
||||
LayoutType.entries.forEach { type ->
|
||||
if (type == LayoutType.MAIN) return@forEach
|
||||
WithSmallTitle(stringResource(type.displayNameId)) {
|
||||
val explicitLayout = currentSubtype.layoutName(type)
|
||||
val layout = explicitLayout ?: Settings.readDefaultLayoutName(type, prefs)
|
||||
val defaultLayouts = LayoutUtils.getAvailableLayouts(type, ctx)
|
||||
val customLayouts = LayoutUtilsCustom.getLayoutFiles(type, ctx).map { it.name }
|
||||
DropDownField(
|
||||
items = defaultLayouts + customLayouts,
|
||||
selectedItem = layout,
|
||||
onSelected = {
|
||||
setCurrentSubtype(currentSubtype.withLayout(type, it))
|
||||
},
|
||||
extraButton = { DefaultButton(explicitLayout == null) {
|
||||
setCurrentSubtype(currentSubtype.withoutLayout(type))
|
||||
} },
|
||||
) {
|
||||
val displayName = if (LayoutUtilsCustom.isCustomLayout(it)) LayoutUtilsCustom.getDisplayName(it)
|
||||
else it.getStringResourceOrName("layout_", ctx)
|
||||
var showLayoutEditDialog by remember { mutableStateOf(false) }
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(displayName, Modifier.padding(end = 8.dp))
|
||||
if (LayoutUtilsCustom.isCustomLayout(it))
|
||||
Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.edit_layout), Modifier.clickable { showLayoutEditDialog = true })
|
||||
}
|
||||
if (showLayoutEditDialog)
|
||||
LayoutEditDialog(
|
||||
onDismissRequest = { showLayoutEditDialog = false },
|
||||
layoutType = type,
|
||||
initialLayoutName = it,
|
||||
isNameValid = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
if (showSecondaryLocaleDialog)
|
||||
MultiListPickerDialog(
|
||||
onDismissRequest = { showSecondaryLocaleDialog = false },
|
||||
|
@ -294,6 +306,7 @@ fun SubtypeDialog(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// from ReorderSwitchPreference
|
||||
@Composable
|
||||
private fun PopupOrderDialog(
|
||||
|
@ -336,7 +349,6 @@ private fun PopupOrderDialog(
|
|||
|
||||
@Composable
|
||||
private fun MainLayoutRow(
|
||||
initialSubtype: SettingsSubtype,
|
||||
currentSubtype: SettingsSubtype,
|
||||
customLayouts: List<String>,
|
||||
setCurrentSubtype: (SettingsSubtype) -> Unit,
|
||||
|
@ -369,13 +381,13 @@ private fun MainLayoutRow(
|
|||
Text(SubtypeLocaleUtils.getDisplayNameInSystemLocale(it, currentSubtype.locale))
|
||||
Row (verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.edit_layout), Modifier.clickable { showLayoutEditDialog = it to null })
|
||||
if (it in customLayouts && initialSubtype.mainLayoutName() != it) // don't allow current main layout
|
||||
if (it in customLayouts && currentSubtype.mainLayoutName() != it) // don't allow current main layout // todo: this was initialSubtype, maybe needs adjustment now
|
||||
Icon(painterResource(R.drawable.ic_bin), stringResource(R.string.delete), Modifier.clickable { showLayoutDeleteDialog = true })
|
||||
}
|
||||
}
|
||||
if (showLayoutDeleteDialog) {
|
||||
val others = SubtypeSettings.getAdditionalSubtypes().filter { st -> st.mainLayoutName() == it }
|
||||
.any { it.toSettingsSubtype() != initialSubtype }
|
||||
.any { it.toSettingsSubtype() != currentSubtype } // todo: this was initialSubtype, maybe needs adjustment now
|
||||
ConfirmationDialog(
|
||||
onDismissRequest = { showLayoutDeleteDialog = false },
|
||||
confirmButtonText = stringResource(R.string.delete),
|
||||
|
@ -442,11 +454,14 @@ private fun MainLayoutRow(
|
|||
private fun getAvailableSecondaryLocales(context: Context, mainLocale: Locale): List<Locale> =
|
||||
getDictionaryLocales(context).filter { it != mainLocale && it.script() == mainLocale.script() }
|
||||
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
initPreview(LocalContext.current)
|
||||
Theme(previewDark) {
|
||||
SubtypeDialog({}, SettingsSubtype(Locale.ENGLISH, "")) { }
|
||||
Surface {
|
||||
SubtypeScreen(SettingsSubtype(Locale.ENGLISH, "")) { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ import helium314.keyboard.latin.R
|
|||
import helium314.keyboard.latin.permissions.PermissionsUtil
|
||||
import helium314.keyboard.latin.settings.Defaults
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.latin.utils.JniUtils
|
||||
import helium314.keyboard.latin.utils.Log
|
||||
import helium314.keyboard.latin.utils.getActivity
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
|
@ -49,6 +50,7 @@ fun TextCorrectionScreen(
|
|||
Log.v("irrelevant", "stupid way to trigger recomposition on preference change")
|
||||
val autocorrectEnabled = prefs.getBoolean(Settings.PREF_AUTO_CORRECTION, Defaults.PREF_AUTO_CORRECTION)
|
||||
val suggestionsEnabled = prefs.getBoolean(Settings.PREF_SHOW_SUGGESTIONS, Defaults.PREF_SHOW_SUGGESTIONS)
|
||||
val gestureEnabled = JniUtils.sHaveGestureLib && prefs.getBoolean(Settings.PREF_GESTURE_INPUT, Defaults.PREF_GESTURE_INPUT)
|
||||
val items = listOf(
|
||||
SettingsWithoutKey.EDIT_PERSONAL_DICTIONARY,
|
||||
R.string.settings_category_correction,
|
||||
|
@ -57,12 +59,20 @@ fun TextCorrectionScreen(
|
|||
if (autocorrectEnabled) Settings.PREF_MORE_AUTO_CORRECTION else null,
|
||||
if (autocorrectEnabled) Settings.PREF_AUTOCORRECT_SHORTCUTS else null,
|
||||
if (autocorrectEnabled) Settings.PREF_AUTO_CORRECT_THRESHOLD else null,
|
||||
if (autocorrectEnabled) Settings.PREF_BACKSPACE_REVERTS_AUTOCORRECT else null,
|
||||
Settings.PREF_AUTO_CAP,
|
||||
R.string.settings_category_space,
|
||||
Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD,
|
||||
Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION,
|
||||
Settings.PREF_AUTOSPACE_AFTER_SUGGESTION,
|
||||
if (gestureEnabled) Settings.PREF_AUTOSPACE_BEFORE_GESTURE_TYPING else null,
|
||||
if (gestureEnabled) Settings.PREF_AUTOSPACE_AFTER_GESTURE_TYPING else null,
|
||||
Settings.PREF_SHIFT_REMOVES_AUTOSPACE,
|
||||
R.string.settings_category_suggestions,
|
||||
Settings.PREF_SHOW_SUGGESTIONS,
|
||||
if (suggestionsEnabled) Settings.PREF_ALWAYS_SHOW_SUGGESTIONS else null,
|
||||
if (suggestionsEnabled && prefs.getBoolean(Settings.PREF_ALWAYS_SHOW_SUGGESTIONS, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS))
|
||||
Settings.PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT else null,
|
||||
if (suggestionsEnabled) Settings.PREF_CENTER_SUGGESTION_TEXT_TO_ENTER else null,
|
||||
Settings.PREF_KEY_USE_PERSONALIZED_DICTS,
|
||||
Settings.PREF_BIGRAM_PREDICTIONS,
|
||||
|
@ -114,6 +124,9 @@ fun createCorrectionSettings(context: Context) = listOf(
|
|||
// todo: consider making it a slider, and maybe somehow adjust range so we can show %
|
||||
ListPreference(it, items, Defaults.PREF_AUTO_CORRECT_THRESHOLD)
|
||||
},
|
||||
Setting(context, Settings.PREF_BACKSPACE_REVERTS_AUTOCORRECT, R.string.backspace_reverts_autocorrect) {
|
||||
SwitchPreference(it, Defaults.PREF_BACKSPACE_REVERTS_AUTOCORRECT)
|
||||
},
|
||||
Setting(context, Settings.PREF_AUTO_CAP,
|
||||
R.string.auto_cap, R.string.auto_cap_summary
|
||||
) {
|
||||
|
@ -129,6 +142,18 @@ fun createCorrectionSettings(context: Context) = listOf(
|
|||
) {
|
||||
SwitchPreference(it, Defaults.PREF_AUTOSPACE_AFTER_PUNCTUATION)
|
||||
},
|
||||
Setting(context, Settings.PREF_AUTOSPACE_AFTER_SUGGESTION, R.string.autospace_after_suggestion) {
|
||||
SwitchPreference(it, Defaults.PREF_AUTOSPACE_AFTER_SUGGESTION)
|
||||
},
|
||||
Setting(context, Settings.PREF_AUTOSPACE_AFTER_GESTURE_TYPING, R.string.autospace_after_gesture_typing) {
|
||||
SwitchPreference(it, Defaults.PREF_AUTOSPACE_AFTER_GESTURE_TYPING)
|
||||
},
|
||||
Setting(context, Settings.PREF_AUTOSPACE_BEFORE_GESTURE_TYPING, R.string.autospace_before_gesture_typing) {
|
||||
SwitchPreference(it, Defaults.PREF_AUTOSPACE_BEFORE_GESTURE_TYPING)
|
||||
},
|
||||
Setting(context, Settings.PREF_SHIFT_REMOVES_AUTOSPACE, R.string.shift_removes_autospace, R.string.shift_removes_autospace_summary) {
|
||||
SwitchPreference(it, Defaults.PREF_SHIFT_REMOVES_AUTOSPACE)
|
||||
},
|
||||
Setting(context, Settings.PREF_SHOW_SUGGESTIONS,
|
||||
R.string.prefs_show_suggestions, R.string.prefs_show_suggestions_summary
|
||||
) {
|
||||
|
@ -139,6 +164,11 @@ fun createCorrectionSettings(context: Context) = listOf(
|
|||
) {
|
||||
SwitchPreference(it, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS)
|
||||
},
|
||||
Setting(context, Settings.PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT,
|
||||
R.string.prefs_always_show_suggestions_except_web_text, R.string.prefs_always_show_suggestions_except_web_text_summary
|
||||
) {
|
||||
SwitchPreference(it, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT)
|
||||
},
|
||||
Setting(context, Settings.PREF_KEY_USE_PERSONALIZED_DICTS,
|
||||
R.string.use_personalized_dicts, R.string.use_personalized_dicts_summary
|
||||
) { setting ->
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
android:viewportHeight="960">
|
||||
<path android:fillColor="#FFF"
|
||||
android:pathData="M200,840Q167,840 143.5,816.5Q120,793 120,760L120,200Q120,167 143.5,143.5Q167,120 200,120L367,120Q378,85 410,62.5Q442,40 480,40Q520,40 551.5,62.5Q583,85 594,120L760,120Q793,120 816.5,143.5Q840,167 840,200L840,760Q840,793 816.5,816.5Q793,840 760,840L200,840ZM200,760L760,760Q760,760 760,760Q760,760 760,760L760,200Q760,200 760,200Q760,200 760,200L680,200L680,280Q680,297 668.5,308.5Q657,320 640,320L320,320Q303,320 291.5,308.5Q280,297 280,280L280,200L200,200Q200,200 200,200Q200,200 200,200L200,760Q200,760 200,760Q200,760 200,760ZM480,200Q497,200 508.5,188.5Q520,177 520,160Q520,143 508.5,131.5Q497,120 480,120Q463,120 451.5,131.5Q440,143 440,160Q440,177 451.5,188.5Q463,200 480,200Z"/>
|
||||
</vector>
|
|
@ -75,16 +75,16 @@
|
|||
<string name="prefs_enable_emoji_alt_physical_key">"الرموز التعبيرية للوحة مفاتيح فعلية"</string>
|
||||
<string name="prefs_enable_emoji_alt_physical_key_summary">"مفتاح Alt الفعلي يعرض لوحة الرموز التعبيرية"</string>
|
||||
<string name="button_default">"التلقائية"</string>
|
||||
<string name="setup_welcome_title">مرحبًا بكم في<xliff:g id="APPLICATION_NAME" مثال="لوحة مفاتيح أندرويد">%s</xliff:g></string>
|
||||
<string name="setup_welcome_title">مرحبًا بكم في <xliff:g id="APPLICATION_NAME" مثال="لوحة مفاتيح أندرويد">%s</xliff:g></string>
|
||||
<string name="setup_welcome_additional_description">مع الكتابة بالإيماءة</string>
|
||||
<string name="setup_start_action">"بدء الاستخدام"</string>
|
||||
<string name="setup_next_action">"الخطوة التالية"</string>
|
||||
<string name="setup_steps_title">قيد الإعداد<xliff:g id="APPLICATION_NAME" مثال="لوحة مفاتيح أندرويد">%s</xliff:g></string>
|
||||
<string name="setup_step1_title">مكِّن<xliff:g id="APPLICATION_NAME" مثال="لوحة مفاتيح أندرويد">%s</xliff:g></string>
|
||||
<string name="setup_steps_title">قيد الإعداد <xliff:g id="APPLICATION_NAME" مثال="لوحة مفاتيح أندرويد">%s</xliff:g></string>
|
||||
<string name="setup_step1_title">مكِّن <xliff:g id="APPLICATION_NAME" مثال="لوحة مفاتيح أندرويد">%s</xliff:g></string>
|
||||
<string name="setup_step1_instruction">يرجى التحقق من \\<xliff:g id="APPLICATION_NAME" مثال="لوحة مفاتيح أندرويد">%s</xliff:g>\" في إعدادات الإدخال واللغات. سيؤدي ذلك إلى تمكين لوحة المفاتيح على جهازك.\"</string>
|
||||
<string name="setup_step1_finished_instruction"><xliff:g id=\"APPLICATION_NAME\" مثال=\"لوحة مفاتيح أندرويد\">%s</xliff:g> ممكّن بالفعل في إعدادات اللغات &amp؛ إعدادات الإدخال، لذا فقد تم الانتهاء من هذه الخطوة. إلى الخطوة التالية!\"</string>
|
||||
<string name="setup_step1_action">"تفعيل في الإعدادات"</string>
|
||||
<string name="setup_step2_title">قم بالتبديل إلى<xliff:g id="APPLICATION_NAME" مثال="لوحة مفاتيح أندرويد">%s</xliff:g></string>
|
||||
<string name="setup_step2_title">بدّل إلى <xliff:g id="APPLICATION_NAME" مثال="لوحة مفاتيح أندرويد">%s</xliff:g></string>
|
||||
<string name="setup_step2_instruction">بعد ذلك، اختر \\<<xliff:g id=\"APPLICATION_NAME\" مثال=\"لوحة مفاتيح أندرويد\">%s</xliff:g>” كطريقة إدخال النص النشط.“</string>
|
||||
<string name="setup_step2_action">"تبديل أساليب الإدخال"</string>
|
||||
<string name="setup_step3_title">تهانينا ، لقد انتهيت من الإعداد!</string>
|
||||
|
@ -247,10 +247,10 @@
|
|||
<string name="layout_symbols" tools:keep="@string/layout_symbols">الرموز</string>
|
||||
<string name="layout_symbols_arabic" tools:keep="@string/layout_symbols_arabic">الرموز(العربية)</string>
|
||||
<string name="layout_number" tools:keep="@string/layout_number">ارقام</string>
|
||||
<string name="layout_numpad" tools:keep="@string/layout_numpad">لوحة ارقام</string>
|
||||
<string name="layout_numpad" tools:keep="@string/layout_numpad">لوحة الأرقام</string>
|
||||
<string name="layout_phone" tools:keep="@string/layout_phone">الهاتف</string>
|
||||
<string name="layout_phone_symbols" tools:keep="@string/layout_phone_symbols">رموز الهاتف</string>
|
||||
<string name="layout_numpad_landscape" tools:keep="@string/layout_numpad_landscape">لوحة رقمية (أفقي)</string>
|
||||
<string name="layout_numpad_landscape" tools:keep="@string/layout_numpad_landscape">لوحة الأرقام (أفقي)</string>
|
||||
<string name="remove_dictionary_message">هل تريد حقًا إزالة القاموس الذي أضافه المستخدم \"%s\"؟</string>
|
||||
<string name="dictionary_file_error">خطأ: الملف المحدد ليس ملف قاموس صالح</string>
|
||||
<string name="theme_name_black" tools:keep="@string/theme_name_black">اسود</string>
|
||||
|
@ -472,4 +472,9 @@
|
|||
<string name="locales_with_dict">اللغات مع القواميس</string>
|
||||
<string name="get_layouts_message">يمكنك العثور على المخططات ومشاركتها في %s.</string>
|
||||
<string name="discussion_section_link">قسم المناقشة</string>
|
||||
<string name="custom_subtype">نوع فرعي مخصّص</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="Bengali">%s</xliff:g> (Baishakhi)</string>
|
||||
<string name="show_tld_popup_keys">أظهِر مفاتيح TLD المنبثقة</string>
|
||||
<string name="show_tld_popup_keys_summary">استبدل مفتاح الفترة المنبثقة مع مجالات المستوى الأعلى عند كتابة عناوين URL وعناوين البريد الإلكتروني</string>
|
||||
<string name="after_numpad_and_space">الضغط على إدخال أو مساحة بعد مفاتيح أخرى في لوحة الأرقام</string>
|
||||
</resources>
|
||||
|
|
|
@ -370,5 +370,64 @@
|
|||
<string name="space_swipe_toggle_numpad_entry">Пераключыць лічбавую клавіятуру</string>
|
||||
<string name="show_popup_keys_main">Дадаць самыя распаўсюджаныя варыянты (па змаўчанні)</string>
|
||||
<string name="remove_redundant_popups">Выдаліць лішнія ўсплывальныя вокны</string>
|
||||
<string name="remove_redundant_popups_summary">Прыбраць усплывальныя клавішы, якія прысутнічаюць у базавай раскладцы</string>
|
||||
<string name="remove_redundant_popups_summary">Прыбраць усплывальныя клавішы, якія ўжо прысутнічаюць у базавай раскладцы</string>
|
||||
<string name="gesture_floating_preview_static">Плаваючы прадпрагляд</string>
|
||||
<string name="gesture_floating_preview_static_summary">Бачыць прапанаванае слова падчас набору жэстамі</string>
|
||||
<string name="split" tools:keep="@string/split">Раздзельная клавіятура</string>
|
||||
<string name="vibrate_in_dnd_mode">Вібрацыя ў рэжыме «Не турбаваць»</string>
|
||||
<string name="enable_split_keyboard_landscape">Уключыць падзеленую клавіятуру (альбомная)</string>
|
||||
<string name="split_spacer_scale_landscape">Адлегласць падзелу (альбомная)</string>
|
||||
<string name="gesture_floating_preview_dynamic_summary">Перамяшчаць прадпрагляд падчас набору жэстамі</string>
|
||||
<string name="gesture_trail_fadeout_duration">Час жыцця следа жэста</string>
|
||||
<string name="auto_correct_shortcuts">Аўтакарэкцыя спалучэнняў клавіш</string>
|
||||
<string name="auto_correct_shortcuts_summary">Калі ўключана, спалучэнні клавіш могуць быць пашыраны з дапамогай аўтакарэкцыі</string>
|
||||
<string name="prefs_bottom_padding_scale_landscape">Маштаб ніжняга водступу (альбомная)</string>
|
||||
<string name="prefs_side_padding_scale">Маштаб бакавога водступу</string>
|
||||
<string name="number_row_hints">Паказваць падказкі ў шэрагу з лічбамі</string>
|
||||
<string name="locales_with_dict">Мовы са слоўнікамі</string>
|
||||
<string name="custom_subtype">Карыстацкі падтып</string>
|
||||
<string name="layout_emoji_bottom_row" tools:keep="@string/layout_emoji_bottom_row">Радок эмодзі ўнізе</string>
|
||||
<string name="layout_clip_bottom_row" tools:keep="@string/layout_clip_bottom_row">Радок буфера абмену ўнізе</string>
|
||||
<string name="layout_in_use">Папярэджанне: раскладка ў дадзены момант выкарыстоўваецца</string>
|
||||
<string name="customize_icons">Наладзіць значкі</string>
|
||||
<string name="customize_icons_reset_message">Сапраўды скінуць усе настроеныя значкі?</string>
|
||||
<string name="layout_number_row" tools:keep="@string/layout_number_row">Шэраг з лічбамі</string>
|
||||
<string name="customize_background_image_landscape">Усталяваць фонавы малюнак (альбомная)</string>
|
||||
<string name="prefs_key_emoji_max_sdk">Перавызначыць версію эмодзі</string>
|
||||
<string name="subtype_dru">Даргінскі (Урахі)</string>
|
||||
<string name="subtype_with_layout_dru" tools:keep="@string/subtype_with_layout_dru">Урахінскі (<xliff:g id="KEYBOARD_LAYOUT" example="QWERTY">%s</xliff:g>)</string>
|
||||
<string name="key_code">Код клавішы</string>
|
||||
<string name="delete_confirmation">Сапраўды выдаліць %s?</string>
|
||||
<string name="custom_font">Усталяваць карыстацкі шрыфт з файла</string>
|
||||
<string name="summary_customize_background_image_landscape">Калі не ўстаноўлена, будзе выкарыстоўвацца партрэтны малюнак</string>
|
||||
<string name="label_zwnj_key" tools:keep="@string/label_zwnj_key">Раз\'яднальнік нулявой шырыні</string>
|
||||
<string name="customize_toolbar_key_code_reset_message">Вы сапраўды хочаце выдаліць усе настроеныя коды клавіш?</string>
|
||||
<string name="settings_screen_secondary_layouts">Дадатковыя раскладкі</string>
|
||||
<string name="layout_functional_keys_tablet" tools:keep="@string/layout_functional_keys_tablet">Функцыянальныя клавішы (вялікі экран)</string>
|
||||
<string name="icon_style">Стыль значкоў</string>
|
||||
<string name="label_zwj_key" tools:keep="@string/label_zwj_key">Злучальнік нулявой шырыні</string>
|
||||
<string name="label_bin" tools:keep="@string/label_bin">Сметніца</string>
|
||||
<string name="name_invalid">Недапушчальнае імя</string>
|
||||
<string name="label_delete_key" tools:keep="@string/label_delete_key">Выдаліць</string>
|
||||
<string name="label_enter_key" tools:keep="@string/label_enter_key">Увод</string>
|
||||
<string name="label_shift_key" tools:keep="@string/label_shift_key">Shift</string>
|
||||
<string name="label_tab_key" tools:keep="@string/label_tab_key">Табуляцыя</string>
|
||||
<string name="label_shift_key_shifted" tools:keep="@string/label_shift_key_shifted">Shift (націснута)</string>
|
||||
<string name="prefs_font_scale">Маштаб шрыфта клавіятуры</string>
|
||||
<string name="prefs_emoji_font_scale">Маштаб шрыфта адлюстравання эмодзі</string>
|
||||
<string name="prefs_side_padding_scale_landscape">Маштаб бакавога водступу (альбомная)</string>
|
||||
<string name="long_press_code">Код доўгага націску</string>
|
||||
<string name="prefs_language_swipe_distance">Адлегласць змахвання для пераключэння мовы</string>
|
||||
<string name="customize_toolbar_key_codes">Наладзіць коды клавіш панэлі інструментаў</string>
|
||||
<string name="prefs_space_bar_text">Карыстацкі тэкст на клавішы прабела</string>
|
||||
<string name="label_space_key_for_number_layout" tools:keep="@string/label_space_key_for_number_layout">Прабел (раскладка лічбаў)</string>
|
||||
<string name="label_switch_onehanded_key" tools:keep="@string/label_switch_onehanded_key">Пераключыць бок рэжыму адной рукой</string>
|
||||
<string name="get_colors_message">Знайсці і падзяліцца колерамі ў %s.</string>
|
||||
<string name="get_layouts_message">Знайсці і падзяліцца раскладкамі ў %s.</string>
|
||||
<string name="discussion_section_link">абмеркавання</string>
|
||||
<string name="label_shift_key_locked" tools:keep="@string/label_shift_key_locked">Caps lock</string>
|
||||
<string name="label_stop_onehanded_mode_key" tools:keep="@string/label_stop_onehanded_mode_key">Завяршыць рэжым адной рукой</string>
|
||||
<string name="label_resize_onehanded_key" tools:keep="@string/label_resize_onehanded_key">Змяніць памер у рэжыме адной рукой</string>
|
||||
<string name="label_shortcut_key_disabled" tools:keep="@string/label_shortcut_key_disabled">Галасавы ўвод адключаны</string>
|
||||
<string name="label_toolbar_key" tools:keep="@string/label_toolbar_key">Паказаць / схаваць панэль інструментаў</string>
|
||||
</resources>
|
||||
|
|
|
@ -467,4 +467,10 @@
|
|||
<string name="get_colors_message">Можете да намирате и споделяте цветове в %s.</string>
|
||||
<string name="custom_subtype">Персонализиран подтип</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="Бенгалски">%s</xliff:g> (Байсахи)</string>
|
||||
<string name="show_tld_popup_keys">Показване на TLD изскачащи клавиши</string>
|
||||
<string name="show_tld_popup_keys_summary">Заместване на изскачащите прозорци с клавиши за период с домейни от първо ниво при въвеждане на URL и имейл адреси</string>
|
||||
<string name="after_numpad_and_space">Натискане на въвеждане или интервал след други клавиши в цифровата клавиатура</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">Не винаги показвай предложения за полета за уеб редактиране</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Полетата за уеб редактиране (най-вече в браузърите) са много честа причина за проблеми с настройката за винаги показване на предложения</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Числов ред (основен)</string>
|
||||
</resources>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -430,4 +430,10 @@
|
|||
<string name="get_colors_message">Podeu trobar i compartir colors a %s.</string>
|
||||
<string name="get_layouts_message">Podeu trobar i compartir disposicions a %s.</string>
|
||||
<string name="discussion_section_link">secció de discussió</string>
|
||||
<string name="show_tld_popup_keys_summary">Substituir les finestres emergents de la tecla punt per dominis de primer nivell en escriure URLs i adreces de correu electrònic</string>
|
||||
<string name="show_tld_popup_keys">Mostra tecles emergents de TLD</string>
|
||||
<string name="after_numpad_and_space">Prement Intro o espai després d\'altres tecles del teclat numèric</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Els camps d\'edició web (sobretot que es troben als navegadors) són una causa molt freqüent de problemes amb la configuració Mostrar sempre suggeriments</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Fila de nombres (bàsic)</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">No mostrar sempre suggeriments per als camps d\'edició web</string>
|
||||
</resources>
|
||||
|
|
|
@ -432,4 +432,11 @@
|
|||
<string name="delete_confirmation">%s wirklich löschen?</string>
|
||||
<string name="name_invalid">Ungültiger Name</string>
|
||||
<string name="custom_subtype">Benutzerdefinierter Subtyp</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="Bengalisch">%s</xliff:g> (Baisakhi)</string>
|
||||
<string name="show_tld_popup_keys">Zeige TLD-Popup-Tasten</string>
|
||||
<string name="show_tld_popup_keys_summary">Ersetze Punkt-Tastenpopups mit Top-Level-Domains wenn URLs und Mailadressen eingegeben werden</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">Nicht immer Vorschläge für Web-Editierfelder anzeigen</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Zahlenreihe (Basis)</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Web-Eingabefelder (meist in Browsern) sind eine häufige Ursache für Probleme mit der Einstellung \"Immer Vorschläge anzeigen\"</string>
|
||||
<string name="after_numpad_and_space">Drücken der Eingabetaste oder der Leertaste nach anderen Tasten im Ziffernblock</string>
|
||||
</resources>
|
||||
|
|
|
@ -467,4 +467,10 @@
|
|||
<string name="get_colors_message">Uusi värve võid leida ja jagada %s.</string>
|
||||
<string name="custom_subtype">Sinu loodud alamtüüp</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="Bengali">%s</xliff:g> (Baishakhi)</string>
|
||||
<string name="show_tld_popup_keys">Näita tippdomeenide hüpikklahve</string>
|
||||
<string name="show_tld_popup_keys_summary">Võrgu- ja e-posti aadresside kirjutamisel asenda punktuatsiooni hüpikaknad tipptaseme domeenide omadega</string>
|
||||
<string name="after_numpad_and_space">Vajutades numbriklahvistikus peale muud sisestust tühiku- või sisestusklahvi</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Numbririda (lihtne)</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">Ära alati näita sisestuse soovitusi täites veebivormide välju</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Kui alati näitad sisestuse soovitusi veebivormide väljadel (nii nagu sa neid veebibrauseris näed), siis võib sellest tekkida probleeme</string>
|
||||
</resources>
|
||||
|
|
|
@ -437,4 +437,10 @@ Nouveau dictionnaire:
|
|||
<string name="get_colors_message">Vous pouvez trouver et partager des couleurs dans le %s.</string>
|
||||
<string name="get_layouts_message">Vous pouvez trouver et partager des dispositions dans le %s.</string>
|
||||
<string name="discussion_section_link">Section de discussion</string>
|
||||
<string name="show_tld_popup_keys">Afficher les suggestions de domaines (TLD)</string>
|
||||
<string name="show_tld_popup_keys_summary">Remplacer les suggestions de la touche point par des extensions de domaine (TLD) lors de la saisie d’URL ou d’adresses e-mail</string>
|
||||
<string name="after_numpad_and_space">Appuyer sur Entrée ou sur la barre d\'espace après d\'autres touches du pavé numérique</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Les champs d\'édition Web (principalement présents dans les navigateurs) sont une cause très courante de problèmes avec le paramètre « Toujours afficher les suggestions »</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Rangée numérique (standard)</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">Ne pas forcer l\'affichage des suggestions pour les champs de saisie web</string>
|
||||
</resources>
|
||||
|
|
|
@ -434,4 +434,16 @@
|
|||
<string name="discussion_section_link">zona de conversa</string>
|
||||
<string name="get_layouts_message">Podes atopar e compartir disposicións na %s.</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="Bengali">%s</xliff:g> (Baishakhi)</string>
|
||||
<string name="custom_subtype">Subtipo personalizado</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">Non mostrar sempre suxestións para os campos texto nas webs</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Os campos de texto nas webs (principalmente no navegador) son causa frecuente de problemas coas suxestións automáticas</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Fila de números (básica)</string>
|
||||
<string name="show_tld_popup_keys_summary">Substitúe na emerxente da tecla do punto con dominios de alto nivel ao escribir URL e enderezos de correo</string>
|
||||
<string name="show_tld_popup_keys">Mostrar teclas emerxentes TLD</string>
|
||||
<string name="after_numpad_and_space">Ao premer enter ou espazo após escribir no teclado numérico</string>
|
||||
<string name="label_zwnj_key" tools:keep="@string/label_zwnj_key">caracter separador ancho cero</string>
|
||||
<string name="delete_confirmation">Eliminar %s?</string>
|
||||
<string name="customize_toolbar_key_code_reset_message">Tes certeza de querer limpar todos os códigos personalizados?</string>
|
||||
<string name="name_invalid">Nome non válido</string>
|
||||
<string name="prefs_language_swipe_distance">Distancia de desprazamento cambio de idioma</string>
|
||||
</resources>
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
<string name="user_dict_settings_add_shortcut_option_name">"Scorciatoia:"</string>
|
||||
<string name="user_dict_settings_add_locale_option_name">"Lingua:"</string>
|
||||
<string name="user_dict_settings_add_word_hint">"Digita una parola"</string>
|
||||
<string name="user_dict_settings_add_shortcut_hint">"Scorciatoia facoltativa"</string>
|
||||
<string name="user_dict_settings_add_shortcut_hint">Scorciatoia (opzionale)</string>
|
||||
<string name="user_dict_settings_edit_dialog_title">"Modifica parola"</string>
|
||||
<string name="user_dict_settings_empty_text">Il dizionario utente è vuoto. Premi \'Aggiungi\' (+) per aggiungere manualmente una parola.</string>
|
||||
<string name="user_dict_settings_all_languages">"Per tutte le lingue"</string>
|
||||
|
@ -304,7 +304,7 @@
|
|||
<string name="dictionary_file_wrong_locale">Il dizionario è stato creato per la lingua %1$s, ma lo stai aggiungendo a %2$s. Confermi?</string>
|
||||
<string name="dialog_close">Chiudi</string>
|
||||
<string name="select_color_gesture">Traccia dell\'input gestuale</string>
|
||||
<string name="text_tap_languages">Tocca la lingua per aprire le impostazioni</string>
|
||||
<string name="text_tap_languages">Lingua: tap → impostazioni</string>
|
||||
<string name="save_log">Salva log</string>
|
||||
<string name="theme_name_holo_white" tools:keep="@string/theme_name_holo_white">Holo bianco</string>
|
||||
<string name="internal_dictionary_summary">Dizionario interno principale</string>
|
||||
|
@ -432,4 +432,17 @@
|
|||
<string name="auto_correct_shortcuts">Scorciatoie correzione</string>
|
||||
<string name="name_invalid">Nome non valido</string>
|
||||
<string name="prefs_language_swipe_distance">Distanza del trascinamento per il cambio lingua</string>
|
||||
<string name="custom_subtype">Sotto-tipo personalizzato</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="Bengalese">%s</xliff:g> (Baishakhi)</string>
|
||||
<string name="layout_in_use">Attenzione: il layout è in uso</string>
|
||||
<string name="locales_with_dict">Lingue con dizionari</string>
|
||||
<string name="discussion_section_link">discussione dedicata</string>
|
||||
<string name="get_layouts_message">Scopri nuovi layout o condividi quelli che hai creato nella %s.</string>
|
||||
<string name="get_colors_message">Scopri nuove combinazioni di colori o condividi le tue nella %s.</string>
|
||||
<string name="show_tld_popup_keys">Mostra popup con TLD</string>
|
||||
<string name="show_tld_popup_keys_summary">Sostituisce il popup standard del tasto . (punto) con desinenze TLD internazionali durante la digitazione di URL e email</string>
|
||||
<string name="after_numpad_and_space">Dopo uno spazio o la pressione di ⏎ (invio) dal tastierino numerico</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">Non forzare i suggerimenti in tutti i campi di testo</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">I campi di testo Web (specie all\'interno dei browser) sono una causa ricorrente di problemi con i suggerimenti sempre attivi</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Barra dei numeri (base)</string>
|
||||
</resources>
|
||||
|
|
|
@ -208,7 +208,7 @@
|
|||
<string name="toolbar_keys">בחירת כפתורי סרגל הכלים</string>
|
||||
<string name="prefs_narrow_key_gaps">מרווחי קלידים צרים</string>
|
||||
<string name="localized_number_row">תרגום number row</string>
|
||||
<string name="popup_keys_number" tools:keep="@string/popup_keys_number">שורת המספרים</string>
|
||||
<string name="popup_keys_number" tools:keep="@string/popup_keys_number">שורת מספרים</string>
|
||||
<string name="popup_keys_language" tools:keep="@string/popup_keys_language">שפה</string>
|
||||
<string name="popup_keys_language_priority" tools:keep="@string/popup_keys_language_priority">שפה (עדיפות)</string>
|
||||
<string name="popup_keys_layout" tools:keep="@string/popup_keys_layout">פריסה</string>
|
||||
|
@ -439,4 +439,10 @@
|
|||
<string name="get_colors_message">באפשרותך למצוא ולשתף צבעים ב %s.</string>
|
||||
<string name="get_layouts_message">באפשרותך למצוא ולשתף פריסות ב %s.</string>
|
||||
<string name="discussion_section_link">מקטע הדיונים</string>
|
||||
<string name="show_tld_popup_keys">הצגת חלון צץ של סיומות אינטרנט</string>
|
||||
<string name="show_tld_popup_keys_summary">החלפת חלון צץ של מקש נקודה ברשימת סיומות אינטרנט נפוצות בעת הקלדת כתובות אינטרנט ודוא\"ל</string>
|
||||
<string name="after_numpad_and_space">לאחר לחיצת Enter או רווח לאחר מקשים אחרים במקלדת המספרים</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">לא תמיד להציג הצעות לשדות עריכה ב-Web</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">שדות עריכה ב-Web (בדר\"כ יוצגו בדפדפן) הם גורם נפוץ מאד לבעיות בהגדרה \'הצגת הצעות תמיד\'</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">שורת המספרים (פריסת בסיס)</string>
|
||||
</resources>
|
||||
|
|
|
@ -476,4 +476,10 @@
|
|||
<string name="get_layouts_message">Je kunt lay-outs zoeken en delen in de %s.</string>
|
||||
<string name="discussion_section_link">discussiesectie</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="Bengali">%s</xliff:g> (Baishakhi)</string>
|
||||
<string name="show_tld_popup_keys">TLD-opties weergeven</string>
|
||||
<string name="show_tld_popup_keys_summary">Vervang pop-ups met interpunctie door topleveldomeinen bij het typen van URL\'s en e-mailadressen</string>
|
||||
<string name="after_numpad_and_space">Druk op enter of spatie na andere toetsen in het numpad</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Cijferregel (basis)</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">Suggesties voor webbewerkingsvelden niet altijd weergeven</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Webbewerkingsvelden (meestal te vinden in browsers) zijn een veel voorkomende oorzaak van problemen met de instelling Altijd suggesties weergeven</string>
|
||||
</resources>
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
<string name="show_setup_wizard_icon">"Pokaż ikonę aplikacji"</string>
|
||||
<string name="show_setup_wizard_icon_summary">"Wyświetlaj ikonę aplikacji w programie uruchamiającym"</string>
|
||||
<string name="dictionary_settings_title">"Słowniki dodatkowe"</string>
|
||||
<string name="dictionary_available">"Słownik dostępny"</string>
|
||||
<string name="dictionary_available">Dostępny słownik</string>
|
||||
<string name="no_dictionaries_available">"Brak słowników"</string>
|
||||
<string name="last_update">"Ostatnia aktualizacja"</string>
|
||||
<string name="settings">"Ustawienia"</string>
|
||||
|
@ -174,13 +174,13 @@
|
|||
<string name="restore_error">Błąd podczas przywracania kopii zapasowej: %s</string>
|
||||
<string name="theme_colors">Kolory</string>
|
||||
<string name="select_color_functional_key_background">Tło klawiszy funkcyjnych</string>
|
||||
<string name="subtype_generic_sebeolsik_390"><xliff:g id="LANGUAGE_NAME" example="Koreański">%s</xliff:g> (Sebeolsik 390)</string>
|
||||
<string name="subtype_generic_sebeolsik_390"><xliff:g id="LANGUAGE_NAME" example="koreański">%s</xliff:g> (Sebeolsik 390)</string>
|
||||
<string name="add_to_personal_dictionary_summary">Używaj słownika osobistego do przechowywania nauczonych słów</string>
|
||||
<string name="user_dict_word_already_present">To słowo znajduje się już w słowniku: %s. Wpisz inne.</string>
|
||||
<string name="style_name_Rounded" tools:keep="@string/style_name_Rounded">Zaokrąglony</string>
|
||||
<string name="button_backup">Kopia</string>
|
||||
<string name="theme_name_black" tools:keep="@string/theme_name_black">Czarne</string>
|
||||
<string name="subtype_generic_sebeolsik_final"><xliff:g id="LANGUAGE_NAME" example="Koreański">%s</xliff:g> (Sebeolsik Final)</string>
|
||||
<string name="subtype_generic_sebeolsik_final"><xliff:g id="LANGUAGE_NAME" example="koreański">%s</xliff:g> (Sebeolsik Final)</string>
|
||||
<string name="theme_name_chocolate" tools:keep="@string/theme_name_chocolate">Czekoladowe</string>
|
||||
<string name="remove_dictionary_message">Na pewno usunąć słownik \"%s\" dodany przez użytkownika?</string>
|
||||
<string name="theme_name_cloudy" tools:keep="@string/theme_name_cloudy">Pochmurne</string>
|
||||
|
@ -195,7 +195,7 @@
|
|||
<string name="theme_name_pink" tools:keep="@string/theme_name_pink">Różowe</string>
|
||||
<string name="language_and_layouts_title">Języki i układy</string>
|
||||
<string name="file_read_error">Nie można odczytać pliku</string>
|
||||
<string name="dictionary_link_text">stąd</string>
|
||||
<string name="dictionary_link_text">tutaj</string>
|
||||
<string name="dictionary_file_error">Błąd: wybrany plik nie jest prawidłowym plikiem słownika</string>
|
||||
<string name="hidden_features_text">chronionej pamięci urządzenia</string>
|
||||
<string name="theme_navbar">Koloruj pasek nawigacyjny</string>
|
||||
|
@ -360,7 +360,7 @@
|
|||
<string name="show_vertical_space_swipe">Spacja - przesuwanie pionowe</string>
|
||||
<string name="show_horizontal_space_swipe">Spacja - przesuwanie poziome</string>
|
||||
<string name="space_swipe_move_cursor_entry">Przesuń kursor</string>
|
||||
<string name="action_none">Brak przesuwania</string>
|
||||
<string name="action_none">Brak</string>
|
||||
<string name="var_toolbar_direction_summary">Odwróć kierunek po wybraniu układu klawiatury od prawej do lewej</string>
|
||||
<string name="var_toolbar_direction">Zmienny kierunek paska narzędzi</string>
|
||||
<string name="subtype_probhat_bn_BD"><xliff:g id="LANGUAGE_NAME" example="bengalski">%s</xliff:g> (Probhat)</string>
|
||||
|
@ -392,7 +392,7 @@
|
|||
<string name="emoji" tools:keep="@string/emoji">Emotikony</string>
|
||||
<string name="customize_currencies_detail">Ustaw główny i do 6 drugorzędnych symboli waluty, oddzielonych spacją</string>
|
||||
<string name="customize_currencies">Dostosuj waluty</string>
|
||||
<string name="load">Załaduj</string>
|
||||
<string name="load">Dodaj</string>
|
||||
<string name="copy_to_clipboard">Skopiuj do schowka</string>
|
||||
<string name="load_will_overwrite">Ładowanie spowoduje zastąpienie bieżącego motywu</string>
|
||||
<string name="button_save_file">Zapisz do pliku</string>
|
||||
|
@ -471,9 +471,13 @@
|
|||
<string name="name_invalid">Nieprawidłowa nazwa</string>
|
||||
<string name="locales_with_dict">Języki ze słownikami</string>
|
||||
<string name="layout_in_use">Ostrzeżenie: ten układ jest aktualnie używany</string>
|
||||
<string name="get_colors_message">Motywy możesz znaleźć i udostępnić w %s .</string>
|
||||
<string name="get_layouts_message">Układy możesz znaleźć i udostępnić w %s .</string>
|
||||
<string name="get_colors_message">Motywy możesz znaleźć i udostępnić w %s.</string>
|
||||
<string name="get_layouts_message">Układy możesz znaleźć i udostępnić w %s.</string>
|
||||
<string name="discussion_section_link">sekcji dyskusji</string>
|
||||
<string name="custom_subtype">Własny podtyp</string>
|
||||
<string name="custom_subtype">Własny układ</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="bengalski">%s</xliff:g> (Baishakhi)</string>
|
||||
<string name="show_tld_popup_keys">Pokaż wyskakujące okienka TLD</string>
|
||||
<string name="show_tld_popup_keys_summary">Zastąp wyskakujące okienka klawisza kropki domenami najwyższego poziomu podczas wpisywania adresów URL i adresów e-mail</string>
|
||||
<string name="after_numpad_and_space">Naciśnięciu enter lub spacji po innych klawiszach w klawiaturze numerycznej</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Rząd numeryczny (podstawowy)</string>
|
||||
</resources>
|
||||
|
|
|
@ -439,4 +439,10 @@
|
|||
<string name="discussion_section_link">seção de discussão</string>
|
||||
<string name="custom_subtype">Subtipo customizado</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="Bengali">%s</xliff:g> (Baishakhi)</string>
|
||||
<string name="show_tld_popup_keys">Mostrar teclas de TLD</string>
|
||||
<string name="show_tld_popup_keys_summary">Substituir os pop-ups da tecla de ponto com domínios de topo ao digitar URLs e endereços de e-mail</string>
|
||||
<string name="after_numpad_and_space">Pressionando enter ou espaço após outras teclas no teclado de números</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Linha de números (básica)</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">Não mostrar sugestões para campos de edição da web sempre</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Campos de edição da web (encontrados normalmente em navegadores) são uma causa comum de problemas com a configuração de sempre mostrar sugestões</string>
|
||||
</resources>
|
||||
|
|
|
@ -399,4 +399,35 @@
|
|||
<string name="label_shortcut_key_disabled" tools:keep="@string/label_shortcut_key_disabled">Introducerea vocală este dezactivată</string>
|
||||
<string name="label_toolbar_key" tools:keep="@string/label_toolbar_key">Afișează/ascunde bara de instrumente</string>
|
||||
<string name="customize_icons_reset_message">Resetezi cu adevărat toate pictogramele personalizate?</string>
|
||||
<string name="custom_subtype">Subtip personalizat</string>
|
||||
<string name="name_invalid">Nume greșit</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="Bengali">%s</xliff:g> (Baishakhi)</string>
|
||||
<string name="locales_with_dict">Limbi cu dicționare</string>
|
||||
<string name="split" tools:keep="@string/split">Tastatură împărțită</string>
|
||||
<string name="layout_in_use">AVERTIZARE: Aspectul este utilizat în prezent</string>
|
||||
<string name="customize_background_image_landscape">Setează imaginea de fundal (peisaj)</string>
|
||||
<string name="summary_customize_background_image_landscape">Dacă nu este setat, se va folosi imaginea portret</string>
|
||||
<string name="get_layouts_message">Poți găsi și împărtăși aspecte în %s.</string>
|
||||
<string name="label_zwj_key" tools:keep="@string/label_zwj_key">Conectorul lățimii zero</string>
|
||||
<string name="customize_toolbar_key_code_reset_message">Ștergi cu adevărat toate codurile cheie personalizate?</string>
|
||||
<string name="split_spacer_scale_landscape">Distanța divizării (peisaj)</string>
|
||||
<string name="enable_split_keyboard_landscape">Activează tastatura divizată (peisaj)</string>
|
||||
<string name="gesture_fast_typing_cooldown">Timp de restabilire a tastării rapide</string>
|
||||
<string name="auto_correct_shortcuts">Comenzi rapide corectare automată</string>
|
||||
<string name="auto_correct_shortcuts_summary">Dacă este activat, comenzile rapide pot fi extinse prin corecție automată</string>
|
||||
<string name="delete_confirmation">Chiar ștergi %s?</string>
|
||||
<string name="custom_font">Setează font personalizat din fișier</string>
|
||||
<string name="remove_redundant_popups_summary">Suprimă tastele pop-up care sunt deja prezente pe aspectul de bază</string>
|
||||
<string name="layout_functional_keys_tablet" tools:keep="@string/layout_functional_keys_tablet">Taste funcționale (ecran mare)</string>
|
||||
<string name="settings_screen_secondary_layouts">Aspecte secundare</string>
|
||||
<string name="prefs_bottom_padding_scale_landscape">Scală umplutură inferioară (peisaj)</string>
|
||||
<string name="prefs_font_scale">Scală font la tastatură</string>
|
||||
<string name="prefs_emoji_font_scale">Scală font vizualizare emoji</string>
|
||||
<string name="label_bin" tools:keep="@string/label_bin">Coș de reciclare</string>
|
||||
<string name="prefs_side_padding_scale_landscape">Scală umplutură laterală (peisaj)</string>
|
||||
<string name="prefs_side_padding_scale">Scală umplutură laterală</string>
|
||||
<string name="number_row_hints">Afișează indicii pe rândul cu numere</string>
|
||||
<string name="prefs_language_swipe_distance">Distanța de deplasare pentru comutarea limbii</string>
|
||||
<string name="get_colors_message">Poți găsi și împărtăși culori în %s.</string>
|
||||
<string name="discussion_section_link">secțiunea de discuții</string>
|
||||
</resources>
|
||||
|
|
|
@ -285,7 +285,7 @@
|
|||
<string name="theme_name_holo_white" tools:keep="@string/theme_name_holo_white">Holo Белая</string>
|
||||
<string name="language_switch_key_switch_both">Смена обоих</string>
|
||||
<string name="up" tools:keep="@string/up">Вверх</string>
|
||||
<string name="remove_dictionary_message">Удалить пользовательский словарь \"%s\"?</string>
|
||||
<string name="remove_dictionary_message">Удалить пользовательский словарь «%s»?</string>
|
||||
<string name="file_read_error">Не получается прочитать файл</string>
|
||||
<string name="dictionary_link_text">здесь</string>
|
||||
<string name="add_dictionary">Выберите для добавления словаря. Словари в формате .dict можно скачать %s.</string>
|
||||
|
@ -307,7 +307,7 @@
|
|||
<string name="dictionary_file_wrong_locale_ok">Всё ещё используется</string>
|
||||
<string name="dictionary_file_wrong_locale">Выбранный файл предназначен для %1$s, но ожидался %2$s. Всё ещё используете его для %2$s?</string>
|
||||
<string name="dictionary_file_error">Ошибка: выбранный файл не является корректным словарем</string>
|
||||
<string name="no_dictionary_message">"Без словаря вы будете получать предложения только для введенного ранее текста.<br>\n Вы можете загрузить словари %1$s или проверить, можно ли загрузить словарь для \"%2$s\" напрямую %3$s."</string>
|
||||
<string name="no_dictionary_message">"Без словаря вы будете получать предложения только для введенного ранее текста.<br>\n Вы можете загрузить словари %1$s или проверить, можно ли загрузить словарь для «%2$s» напрямую %3$s."</string>
|
||||
<string name="available_dictionary_experimental">%s (экспериментальный)</string>
|
||||
<string name="layout_symbols" tools:keep="@string/layout_symbols">Символы</string>
|
||||
<string name="layout_symbols_arabic" tools:keep="@string/layout_symbols_arabic">Символы (арабские)</string>
|
||||
|
@ -425,7 +425,7 @@
|
|||
<string name="label_shift_key" tools:keep="@string/label_shift_key">Shift</string>
|
||||
<string name="label_shift_key_shifted" tools:keep="@string/label_shift_key_shifted">Shift (нажат)</string>
|
||||
<string name="label_shift_key_locked" tools:keep="@string/label_shift_key_locked">Caps lock</string>
|
||||
<string name="label_shortcut_key_disabled" tools:keep="@string/label_shortcut_key_disabled">Голосовой ввод отключен</string>
|
||||
<string name="label_shortcut_key_disabled" tools:keep="@string/label_shortcut_key_disabled">Голосовой ввод отключён</string>
|
||||
<string name="label_toolbar_key" tools:keep="@string/label_toolbar_key">Показать / скрыть панель инструментов</string>
|
||||
<string name="label_zwj_key" tools:keep="@string/label_zwj_key">Соединитель нулевой ширины</string>
|
||||
<string name="customize_toolbar_key_codes">Настроить коды клавиш панели инструментов</string>
|
||||
|
@ -435,8 +435,8 @@
|
|||
<string name="label_zwnj_key" tools:keep="@string/label_zwnj_key">Разъединитель нулевой ширины</string>
|
||||
<string name="label_stop_onehanded_mode_key" tools:keep="@string/label_stop_onehanded_mode_key">Выход из режима работы одной рукой</string>
|
||||
<string name="customize_icons_reset_message">Действительно сбросить все настроенные иконки?</string>
|
||||
<string name="label_bin" tools:keep="@string/label_bin">Bin</string>
|
||||
<string name="vibrate_in_dnd_mode">Вибрировать в режиме Не беспокоить</string>
|
||||
<string name="label_bin" tools:keep="@string/label_bin">Корзина</string>
|
||||
<string name="vibrate_in_dnd_mode">Вибрация в режиме «Не беспокоить»</string>
|
||||
<string name="subtype_generic_phonetic"><xliff:g id="LANGUAGE_NAME" example="Хинди">%s</xliff:g> (Фонетика)</string>
|
||||
<string name="auto_correct_shortcuts">Автокоррекция сочетаний клавиш</string>
|
||||
<string name="custom_font">Установить пользовательский шрифт из файла</string>
|
||||
|
@ -450,7 +450,7 @@
|
|||
<string name="prefs_key_emoji_max_sdk">Переопределить версию эмодзи</string>
|
||||
<string name="summary_customize_background_image_landscape">Если не установлено, будет использоваться портретное изображение</string>
|
||||
<string name="customize_background_image_landscape">Установить фоновое изображение (ландшафт)</string>
|
||||
<string name="number_row_hints">Показывать подсказки в ряде с цифрами</string>
|
||||
<string name="number_row_hints">Показывать подсказки в ряду с цифрами</string>
|
||||
<string name="prefs_language_swipe_distance">Расстояние смахивания для переключения языка</string>
|
||||
<string name="split_spacer_scale_landscape">Расстояние разделения (ландшафт)</string>
|
||||
<string name="enable_split_keyboard_landscape">Включить разделение клавиатуры (ландшафт)</string>
|
||||
|
@ -466,4 +466,10 @@
|
|||
<string name="get_layouts_message">Найти и поделиться раскладками в %s.</string>
|
||||
<string name="discussion_section_link">обсуждения</string>
|
||||
<string name="name_invalid">Недопустимое имя</string>
|
||||
<string name="show_tld_popup_keys">Показать всплывающие клавиши TLD</string>
|
||||
<string name="show_tld_popup_keys_summary">При вводе URL и адресов электронной почты отображать домены верхнего уровня вместо всплывающих меню клавиши точки</string>
|
||||
<string name="after_numpad_and_space">Нажатие Enter или пробела после других клавиш на цифровой клавиатуре</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Поля ввода на веб-страницах (в основном в браузерах) часто вызывают проблемы с настройкой постоянного отображения подсказок</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Ряд с цифрами (основной)</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">Не всегда показывать подсказки для полей ввода на веб-страницах</string>
|
||||
</resources>
|
||||
|
|
17
app/src/main/res/values-v28/platform-theme.xml
Normal file
17
app/src/main/res/values-v28/platform-theme.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2014 The Android Open Source Project
|
||||
modified
|
||||
SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
||||
-->
|
||||
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<style name="AlertDialogTheme" parent="@android:style/Theme.Material.Dialog.Alert">
|
||||
<item name="android:colorAccent">@color/accent</item>
|
||||
<item name="android:background">@color/action_bar_color</item>
|
||||
<item name="android:textColor">@color/foreground</item>
|
||||
<item name="android:textColorAlertDialogListItem">@color/foreground</item>
|
||||
<item name="android:colorForeground">@color/foreground</item>
|
||||
<item name="android:dialogCornerRadius">10dp</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -5,12 +5,11 @@
|
|||
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<style name="platformActivityTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<style name="platformActivityTheme" parent="@android:style/Theme.Material.NoActionBar">
|
||||
<!-- Some items are duplicated from the original platform-theme file to ensure that the
|
||||
"android/system_accent_*" or "android/system_neutral_*" colors are used. -->
|
||||
|
||||
<item name="android:colorAccent">@color/accent</item>
|
||||
<item name="colorAccent">@color/accent</item>
|
||||
|
||||
<item name="android:statusBarColor">@color/action_bar_color</item>
|
||||
<item name="android:navigationBarColor">@color/setup_background</item>
|
||||
|
@ -19,7 +18,6 @@
|
|||
<item name="android:windowBackground">@color/setup_background</item>
|
||||
|
||||
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
|
||||
<item name="alertDialogTheme">@style/AlertDialogTheme</item>
|
||||
|
||||
<item name="android:buttonCornerRadius">50dp</item>
|
||||
|
||||
|
@ -27,11 +25,9 @@
|
|||
<item name="android:itemBackground">@color/drop_down_menu_background</item>
|
||||
</style>
|
||||
|
||||
<style name="AlertDialogTheme" parent="ThemeOverlay.AppCompat.Dialog.Alert">
|
||||
<style name="AlertDialogTheme" parent="@android:style/Theme.Material.Dialog.Alert">
|
||||
<item name="android:colorBackgroundFloating">@color/dialog_background</item>
|
||||
<item name="colorBackgroundFloating">@color/dialog_background</item>
|
||||
<item name="android:dialogCornerRadius">28dp</item>
|
||||
<item name="dialogCornerRadius">28dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -320,7 +320,7 @@
|
|||
<string name="switch_keyboard_after">切换到主键盘后…</string>
|
||||
<string name="after_emoji">在表情符号视图中选择表情符号</string>
|
||||
<string name="after_clip">选择剪贴板历史条目</string>
|
||||
<string name="after_symbol_and_space">在符号视图中按回车键或空格键</string>
|
||||
<string name="after_symbol_and_space">在符号视图输入内容后按回车键或空格键</string>
|
||||
<string name="add_new_dictionary_title">从文件添加词典</string>
|
||||
<string name="quick_pin_toolbar_keys_summary">这将禁用未固定工具栏键的其他长按操作</string>
|
||||
<string name="show_popup_keys_main">添加非常常见的变体(默认)</string>
|
||||
|
@ -433,4 +433,10 @@
|
|||
<string name="get_colors_message">您可以在 %s 中查找和分享颜色。</string>
|
||||
<string name="custom_subtype">自定义子类型</string>
|
||||
<string name="subtype_baishakhi_bn_IN"><xliff:g id="LANGUAGE_NAME" example="Bengali">%s</xliff:g> (Baishakhi)</string>
|
||||
<string name="show_tld_popup_keys_summary">输入 URL 和电子邮件地址时,用顶级域替换句点键弹出</string>
|
||||
<string name="show_tld_popup_keys">显示顶级域弹出键</string>
|
||||
<string name="after_numpad_and_space">在数字键盘输入内容后按回车键或空格键</string>
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">数字行(基本)</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Web 编辑字段(主要存在于浏览器中)是导致“始终显示建议”设置出现问题的一个非常常见的原因</string>
|
||||
<string name="prefs_always_show_suggestions_except_web_text">不要总是显示对 Web 编辑字段的建议</string>
|
||||
</resources>
|
||||
|
|
|
@ -6,11 +6,21 @@
|
|||
-->
|
||||
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<style name="platformActivityTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<style name="platformActivityTheme" parent="@android:style/Theme.Material.NoActionBar">
|
||||
<item name="android:colorAccent">@color/accent</item>
|
||||
<item name="colorAccent">@color/accent</item>
|
||||
|
||||
<item name="android:statusBarColor">@color/action_bar_color</item>
|
||||
<item name="android:navigationBarColor">@color/navigation_bar_color</item>
|
||||
<item name="android:colorBackground">@color/setup_background</item>
|
||||
<item name="android:colorForeground">@color/foreground</item>
|
||||
<item name="android:alertDialogTheme">@style/AlertDialogTheme</item>
|
||||
</style>
|
||||
|
||||
<style name="AlertDialogTheme" parent="@android:style/Theme.Material.Dialog.Alert">
|
||||
<item name="android:colorAccent">@color/accent</item>
|
||||
<item name="android:background">@color/action_bar_color</item>
|
||||
<item name="android:textColor">@color/foreground</item>
|
||||
<item name="android:textColorAlertDialogListItem">@color/foreground</item>
|
||||
<item name="android:colorForeground">@color/foreground</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
<string name="settings_category_clipboard_history">Clipboard history</string>
|
||||
<!-- Settings category title for Text correction/Corrections -->
|
||||
<string name="settings_category_correction">Corrections</string>
|
||||
<!-- Settings category title for Text correction/Space -->
|
||||
<string name="settings_category_space">Space</string>
|
||||
<!-- Settings category title for Text correction/Suggestions -->
|
||||
<string name="settings_category_suggestions">Suggestions</string>
|
||||
<!-- Settings category title for Advanced/Experimental -->
|
||||
|
@ -104,6 +106,10 @@
|
|||
<string name="prefs_always_show_suggestions">Always show suggestions</string>
|
||||
<!-- Description for override app flag to not show suggestions -->
|
||||
<string name="prefs_always_show_suggestions_summary">Ignore other apps’ request to disable suggestions (may cause issues)</string>
|
||||
<!-- Option to not override the above flags for InputType.WEB_EDIT_TEXT -->
|
||||
<string name="prefs_always_show_suggestions_except_web_text">Don’t always show suggestions for web edit fields</string>
|
||||
<!-- Description for prefs_always_show_suggestions_except_web_text -->
|
||||
<string name="prefs_always_show_suggestions_except_web_text_summary">Web edit fields (mostly found in browsers) are a very common cause for issues with the always show suggestions setting</string>
|
||||
<!-- Option to block potentially offensive words to be shown -->
|
||||
<string name="prefs_block_potentially_offensive_title">Block offensive words</string>
|
||||
<!-- Summary for option to block potentially offensive words to be shown -->
|
||||
|
@ -122,6 +128,8 @@
|
|||
<string name="auto_correct_shortcuts">Auto-correct shortcuts</string>
|
||||
<!-- Description for auto_correct_shortcuts -->
|
||||
<string name="auto_correct_shortcuts_summary">When enabled shortcuts might be expanded by autocorrect</string>
|
||||
<!-- Option to undo auto correction with backspace -->
|
||||
<string name="backspace_reverts_autocorrect">Backspace reverts autocorrect</string>
|
||||
<!-- Option to disable auto correction. -->
|
||||
<string name="auto_correction_threshold_mode_off">Off</string>
|
||||
<!-- Option to suggest auto correction suggestions modestly. Auto-corrects only to a word which has small edit distance from typed word. -->
|
||||
|
@ -188,6 +196,8 @@
|
|||
<string name="button_backup">Backup</string>
|
||||
<!-- restore button -->
|
||||
<string name="button_restore">Restore</string>
|
||||
<!-- Preferences item for format for timestamp keycode -->
|
||||
<string name="timestamp_format_title">Format for timestamp key</string>
|
||||
<!-- Preferences item for choosing secondary language -->
|
||||
<string name="secondary_locale">Multilingual typing</string>
|
||||
<!-- Clarification which locales are available for multilingual typing -->
|
||||
|
@ -205,10 +215,20 @@
|
|||
<string name="load_gesture_library_button_load">Load library</string>
|
||||
<!-- Button text for deleting gesture library -->
|
||||
<string name="load_gesture_library_button_delete">Delete library</string>
|
||||
<!-- Preferences item for enabling inserting more spaces key -->
|
||||
<!-- Preferences item for inserting space after punctuation -->
|
||||
<string name="autospace_after_punctuation">Autospace after punctuation</string>
|
||||
<!-- Description for "insert_more_spaces" option. -->
|
||||
<!-- Description for "autospace_after_punctuation" setting -->
|
||||
<string name="autospace_after_punctuation_summary">Automatically insert space after punctuation when typing a new word</string>
|
||||
<!-- Preferences item for inserting space after manualle picking a suggestion -->
|
||||
<string name="autospace_after_suggestion">Autospace after picking a suggestion</string>
|
||||
<!-- Preferences item for inserting space before entering a word using gesture typing -->
|
||||
<string name="autospace_before_gesture_typing">Autospace before gesture typing a word</string>
|
||||
<!-- Preferences item for inserting space after entering a word using gesture typing -->
|
||||
<string name="autospace_after_gesture_typing">Autospace after gesture typing a word</string>
|
||||
<!-- Preferences item for avoiding automatic space insertion by pressing shift -->
|
||||
<string name="shift_removes_autospace">No autospace when pressing shift</string>
|
||||
<!-- Description for "autospace_after_punctuation" setting -->
|
||||
<string name="shift_removes_autospace_summary">Shift removes pending autospace</string>
|
||||
<!-- Preferences item for showing popup keys in long-press popup -->
|
||||
<string name="show_popup_keys_title">Show more letters with diacritics in popup</string>
|
||||
<!-- Option for showing only letters defined in the current language file in long-press popup -->
|
||||
|
@ -249,6 +269,10 @@
|
|||
<string name="hint_source">Select hint source</string>
|
||||
<!-- Title of the setting to set popup key order -->
|
||||
<string name="popup_order">Select popup key order</string>
|
||||
<!-- Title of the setting to show TLD popup keys -->
|
||||
<string name="show_tld_popup_keys">Show TLD popup keys</string>
|
||||
<!-- Description of the setting to show TLD popup keys -->
|
||||
<string name="show_tld_popup_keys_summary">Replace period key popups with top level domains when typing URLs and email addresses</string>
|
||||
<!-- Names of the popup key classes -->
|
||||
<string name="popup_keys_number" tools:keep="@string/popup_keys_number">Number row</string>
|
||||
<string name="popup_keys_language" tools:keep="@string/popup_keys_language">Language</string>
|
||||
|
@ -555,6 +579,8 @@ disposition rather than other common dispositions for Latin languages. -->
|
|||
<string name="layout_numpad_landscape" tools:keep="@string/layout_numpad_landscape">Numpad (landscape)</string>
|
||||
<!-- Name for number row layout -->
|
||||
<string name="layout_number_row" tools:keep="@string/layout_number_row">Number row</string>
|
||||
<!-- Name for number row basic layout -->
|
||||
<string name="layout_number_row_basic" tools:keep="@string/layout_number_row_basic">Number row (basic)</string>
|
||||
<!-- Name for bottom row layout in emoji view -->
|
||||
<string name="layout_emoji_bottom_row" tools:keep="@string/layout_emoji_bottom_row">Emoji bottom row</string>
|
||||
<!-- Name for bottom row layout in clipboard view -->
|
||||
|
@ -577,6 +603,8 @@ disposition rather than other common dispositions for Latin languages. -->
|
|||
<string name="after_clip">Selecting clipboard history entry</string>
|
||||
<!-- Switch to main keyboard after entering a symbol in symbols layout and then pressing space or enter -->
|
||||
<string name="after_symbol_and_space">Pressing enter or space after other keys in symbols view</string>
|
||||
<!-- Switch to main keyboard after entering something in numpad layout and then pressing space or enter -->
|
||||
<string name="after_numpad_and_space">Pressing enter or space after other keys in numpad</string>
|
||||
<!-- Message for selecting day or night background image -->
|
||||
<string name="day_or_night_image">Set image for day or night mode?</string>
|
||||
<!-- Button for selecting day -->
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
bn_IN: Bengali (India)/bengali_inscript
|
||||
bn_IN: Bengali (India)/Baishakhi
|
||||
ca: Catalan/qwerty+
|
||||
ckb: Central Kurdish/central_kurdish
|
||||
cs: Czech/qwertz
|
||||
cv: Chuvash/chuvash
|
||||
da: Danish/qwerty+
|
||||
|
@ -90,6 +91,7 @@
|
|||
pt_PT: Portuguese (Portugal)/qwerty
|
||||
ro: Romanian/qwerty
|
||||
ru: Russian/russian
|
||||
ru: Russian (Extended)/russian_extended
|
||||
ru: Russian (Student)/russian_student
|
||||
si_LK: Sinhala (Sri Lanka)/sinhala # This is a preliminary keyboard layout.
|
||||
sk: Slovak/qwerty
|
||||
|
@ -107,6 +109,7 @@
|
|||
tr: Turkish/turkish
|
||||
ur_PK: Urdu Pakistan
|
||||
uk: Ukrainian/ukrainian
|
||||
uk: Ukrainian (Extended)/ukrainian_extended
|
||||
uz_UZ: Uzbek (Uzbekistan)/uzbek # This is a preliminary keyboard layout.
|
||||
vi: Vietnamese/qwerty
|
||||
zu: Zulu/qwerty
|
||||
|
@ -287,6 +290,15 @@
|
|||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:qwerty+,AsciiCapable,EmojiCapable"
|
||||
android:isAsciiCapable="true"
|
||||
/>
|
||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||
android:label="@string/subtype_generic"
|
||||
android:subtypeId="0xf40a175b"
|
||||
android:imeSubtypeLocale="ckb"
|
||||
android:languageTag="ckb"
|
||||
android:imeSubtypeMode="keyboard"
|
||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:central_kurdish|SYMBOLS:symbols_arabic,NoShiftKey,SupportTouchPositionCorrection,EmojiCapable"
|
||||
android:isAsciiCapable="false"
|
||||
/>
|
||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||
android:label="@string/subtype_generic"
|
||||
android:subtypeId="0x2d3d2ed0"
|
||||
|
@ -912,6 +924,16 @@
|
|||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:russian,SupportTouchPositionCorrection,EmojiCapable"
|
||||
android:isAsciiCapable="false"
|
||||
/>
|
||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||
android:label="@string/subtype_generic_extended"
|
||||
android:subtypeId="0x91f35a0b"
|
||||
android:imeSubtypeLocale="ru"
|
||||
android:languageTag="ru"
|
||||
android:imeSubtypeMode="keyboard"
|
||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:russian_extended,SupportTouchPositionCorrection,EmojiCapable"
|
||||
android:isAsciiCapable="false"
|
||||
|
||||
/>
|
||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||
android:label="@string/subtype_generic_student"
|
||||
android:subtypeId="0x1bc335d0"
|
||||
|
@ -1064,6 +1086,15 @@
|
|||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:ukrainian,EmojiCapable"
|
||||
android:isAsciiCapable="false"
|
||||
/>
|
||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||
android:label="@string/subtype_generic_extended"
|
||||
android:subtypeId="0x49dc95e4"
|
||||
android:imeSubtypeLocale="uk"
|
||||
android:languageTag="uk"
|
||||
android:imeSubtypeMode="keyboard"
|
||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:ukrainian_extended,EmojiCapable"
|
||||
android:isAsciiCapable="false"
|
||||
/>
|
||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||
android:label="@string/subtype_generic"
|
||||
android:subtypeId="0x1e8349fc"
|
||||
|
|
|
@ -23,6 +23,7 @@ import helium314.keyboard.latin.inputlogic.InputLogic
|
|||
import helium314.keyboard.latin.inputlogic.SpaceState
|
||||
import helium314.keyboard.latin.settings.Settings
|
||||
import helium314.keyboard.latin.utils.ScriptUtils
|
||||
import helium314.keyboard.latin.utils.getTimestamp
|
||||
import helium314.keyboard.latin.utils.prefs
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mockito
|
||||
|
@ -203,13 +204,7 @@ class InputLogicTest {
|
|||
assertEquals("example.net", composingText)
|
||||
}
|
||||
|
||||
// fails because
|
||||
// period is not handled with handleSeparatorEvent in this case
|
||||
// pickSuggestion sets phantom space state
|
||||
// insertAutomaticSpaceIfOptionsAndTextAllow allows the space
|
||||
// todo: fix it either in some of those functions, or by finally improving URL detection in a reasonable (and performant) way
|
||||
@Test fun noAutospaceInUrlFieldWhenPickingSuggestion() {
|
||||
if (BuildConfig.BUILD_TYPE == "runTests") return
|
||||
reset()
|
||||
setInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI)
|
||||
chainInput("exam")
|
||||
|
@ -262,6 +257,7 @@ class InputLogicTest {
|
|||
reset()
|
||||
latinIME.prefs().edit { putBoolean(Settings.PREF_URL_DETECTION, true) }
|
||||
latinIME.prefs().edit { putBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, true) }
|
||||
latinIME.prefs().edit { putBoolean(Settings.PREF_SHIFT_REMOVES_AUTOSPACE, true) }
|
||||
input("bla")
|
||||
input('.')
|
||||
functionalKeyPress(KeyCode.SHIFT) // should remove the phantom space (in addition to normal effect)
|
||||
|
@ -644,13 +640,20 @@ class InputLogicTest {
|
|||
|
||||
@Test fun `revert autocorrect on delete`() {
|
||||
reset()
|
||||
setInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_AUTO_CORRECT)
|
||||
chainInput("hullo")
|
||||
getAutocorrectedWithSpaceAfter("hello", "hullo")
|
||||
assertEquals("hello ", text)
|
||||
functionalKeyPress(KeyCode.DELETE)
|
||||
assertEquals("hullo", text)
|
||||
|
||||
// todo: now we want some way to disable revert on backspace, either per setting or something else
|
||||
// need to avoid getting into the mLastComposedWord.canRevertCommit() part of handleBackspaceEvent
|
||||
reset()
|
||||
setInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_AUTO_CORRECT)
|
||||
latinIME.prefs().edit { putBoolean(Settings.PREF_BACKSPACE_REVERTS_AUTOCORRECT, false) }
|
||||
chainInput("hullo")
|
||||
getAutocorrectedWithSpaceAfter("hello", "hullo")
|
||||
functionalKeyPress(KeyCode.DELETE)
|
||||
assertEquals("hello", text)
|
||||
}
|
||||
|
||||
@Test fun `remove glide typing word on delete`() {
|
||||
|
@ -664,6 +667,13 @@ class InputLogicTest {
|
|||
// need to avoid getting into the mWordComposer.isBatchMode() part of handleBackspaceEvent
|
||||
}
|
||||
|
||||
@Test fun timestamp() {
|
||||
reset()
|
||||
chainInput("hello")
|
||||
functionalKeyPress(KeyCode.TIMESTAMP)
|
||||
assertEquals("hello" + getTimestamp(latinIME), text)
|
||||
}
|
||||
|
||||
// ------- helper functions ---------
|
||||
|
||||
// should be called before every test, so the same state is guaranteed
|
||||
|
@ -808,7 +818,7 @@ class InputLogicTest {
|
|||
val info = SuggestedWordInfo(suggestion, "", 0, 0, null, 0, 0)
|
||||
val typedInfo = SuggestedWordInfo(typedWord, "", 0, 0, null, 0, 0)
|
||||
val sw = SuggestedWords(ArrayList(listOf(typedInfo, info)), null, typedInfo, false, true, false, 0, 0)
|
||||
latinIME.mInputLogic.setSuggestedWords(sw)
|
||||
latinIME.mInputLogic.setSuggestedWords(sw) // this prepares for autocorrect
|
||||
input(' ')
|
||||
checkConnectionConsistency()
|
||||
}
|
||||
|
|
|
@ -1,12 +1,23 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
package helium314.keyboard.latin
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import helium314.keyboard.ShadowInputMethodManager2
|
||||
import helium314.keyboard.latin.common.StringUtils
|
||||
import helium314.keyboard.latin.common.getFullEmojiAtEnd
|
||||
import helium314.keyboard.latin.common.nonWordCodePointAndNoSpaceBeforeCursor
|
||||
import helium314.keyboard.latin.settings.SpacingAndPunctuations
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
// todo: actually this test could/should be significantly expanded...
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(shadows = [
|
||||
ShadowInputMethodManager2::class,
|
||||
])
|
||||
class StringUtilsTest {
|
||||
@Test fun `not inside double quotes without quotes`() {
|
||||
assert(!StringUtils.isInsideDoubleQuoteOrAfterDigit("hello yes"))
|
||||
|
@ -41,6 +52,14 @@ class StringUtilsTest {
|
|||
assert(StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\", \"h"))
|
||||
}
|
||||
|
||||
@Test fun `non-word codepoints and no space`() {
|
||||
val sp = SpacingAndPunctuations(ApplicationProvider.getApplicationContext<App>().resources, false)
|
||||
assert(!nonWordCodePointAndNoSpaceBeforeCursor("this is", sp))
|
||||
assert(!nonWordCodePointAndNoSpaceBeforeCursor("this ", sp))
|
||||
assert(!nonWordCodePointAndNoSpaceBeforeCursor("th.is ", sp))
|
||||
assert(nonWordCodePointAndNoSpaceBeforeCursor("th.is", sp))
|
||||
}
|
||||
|
||||
@Test fun detectEmojisAtEnd() {
|
||||
assertEquals("", getFullEmojiAtEnd("\uD83C\uDF83 "))
|
||||
assertEquals("", getFullEmojiAtEnd("a"))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
হেলিবোর্ড গোপনীয়তা-সচেতন ওপেন সোর্স কিবোর্ড যার উৎস অ্যান্ড্রয়েড ওপেন সোর্স প্রজেক্ট এবং ওপেনবোর্ড। বাংলা (বাংলাদেশ) ভাষার জন্য এতে ইউনিজয় লেআউট যুক্ত আছে।
|
||||
হেলিবোর্ড গোপনীয়তা-সচেতন ওপেন সোর্স কিবোর্ড যার উৎস অ্যান্ড্রয়েড ওপেন সোর্স প্রজেক্ট এবং ওপেনবোর্ড। বাংলা ভাষার জন্য এতে ইউনিজয়, প্রভাত, অক্ষর, ইনস্ক্রিপ্ট, বৈশাখী লেআউট যুক্ত আছে।
|
||||
এটি ইন্টারনেটের অনুমতি ব্যবহার করে না, তাই ১০০% অফলাইন।
|
||||
|
||||
সুবিধা:
|
||||
|
|
|
@ -89,7 +89,7 @@ Usually the label is what is displayed on the key. However, there are some speci
|
|||
* _symbol_alpha_: toggle alpha / symbol keyboard
|
||||
* _numpad_: toggle numpad layout
|
||||
* _emoji_: switch to emoji view
|
||||
* _com_: display common TLDs (.com and similar, currently not localized)
|
||||
* _com_: display common TLDs (.com and similar, localized)
|
||||
* _language_switch_: language switch key
|
||||
* _action_: the action (enter) key
|
||||
* _delete_: delete key
|
||||
|
@ -103,7 +103,7 @@ Usually the label is what is displayed on the key. However, there are some speci
|
|||
* In case a label clashes with text you want to add, put a `\` in front of the text you want, e.g. `\space` will write the label `space` instead of adding a space bar.
|
||||
* Note that you need to escape the `\` in json files by adding a second `\`.
|
||||
* If you want different key label and input text, set the label to [label]|[text], e.g. `aa|bb` will show `aa`, but pressing the key will input `bb`.
|
||||
You can also specify special key codes like `a|!code/key_action_previous`, but it's cleaner to use a json layout and specify the code explicitly. Note that when specifying a code in the label, and a code in a json layout, the code in the label will be ignored.
|
||||
You can also specify special key codes like `a|!code/key_action_previous` or `abc|!code/-10043`, but it's cleaner to use a json layout and specify the code explicitly. Note that when specifying a code in the label, and a code in a json layout, the code in the label will be ignored.
|
||||
* It's also possible to specify an icon, like `!icon/previous_key|!code/key_action_previous`.
|
||||
* You can find available icon names in [KeyboardIconsSet](/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt). You can also use toolbar key icons using the uppercase name of the [toolbar key](/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt#L109), e.g. `!icon/redo`
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue