mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-19 13:49:13 +00:00
add timestamp keycode and setting for adjusting format, fixes GH-846
This commit is contained in:
parent
525c4e59b6
commit
8932fc84e1
11 changed files with 90 additions and 24 deletions
|
@ -167,6 +167,7 @@ object KeyCode {
|
||||||
const val BACK = -10040
|
const val BACK = -10040
|
||||||
const val SELECT_LEFT = -10041
|
const val SELECT_LEFT = -10041
|
||||||
const val SELECT_RIGHT = -10042
|
const val SELECT_RIGHT = -10042
|
||||||
|
const val TIMESTAMP = -10043
|
||||||
|
|
||||||
/** to make sure a FlorisBoard code works when reading a JSON layout */
|
/** to make sure a FlorisBoard code works when reading a JSON layout */
|
||||||
fun Int.checkAndConvertCode(): Int = if (this > 0) this else when (this) {
|
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,
|
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,
|
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,
|
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
|
-> this
|
||||||
|
|
||||||
// conversion
|
// conversion
|
||||||
|
@ -194,8 +196,12 @@ object KeyCode {
|
||||||
else -> throw IllegalStateException("key code $this not yet supported")
|
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
|
// 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 */
|
/**
|
||||||
|
* 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)
|
fun Int.toKeyEventCode(): Int = if (this > 0)
|
||||||
when (this.toChar().uppercaseChar()) {
|
when (this.toChar().uppercaseChar()) {
|
||||||
'/' -> KeyEvent.KEYCODE_SLASH
|
'/' -> KeyEvent.KEYCODE_SLASH
|
||||||
|
|
|
@ -54,6 +54,7 @@ import helium314.keyboard.latin.utils.RecapitalizeStatus;
|
||||||
import helium314.keyboard.latin.utils.ScriptUtils;
|
import helium314.keyboard.latin.utils.ScriptUtils;
|
||||||
import helium314.keyboard.latin.utils.StatsUtils;
|
import helium314.keyboard.latin.utils.StatsUtils;
|
||||||
import helium314.keyboard.latin.utils.TextRange;
|
import helium314.keyboard.latin.utils.TextRange;
|
||||||
|
import helium314.keyboard.latin.utils.TimestampKt;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -775,6 +776,9 @@ public final class InputLogic {
|
||||||
case KeyCode.SPLIT_LAYOUT:
|
case KeyCode.SPLIT_LAYOUT:
|
||||||
KeyboardSwitcher.getInstance().toggleSplitKeyboardMode();
|
KeyboardSwitcher.getInstance().toggleSplitKeyboardMode();
|
||||||
break;
|
break;
|
||||||
|
case KeyCode.TIMESTAMP:
|
||||||
|
mLatinIME.onTextInput(TimestampKt.getTimestamp(mLatinIME));
|
||||||
|
break;
|
||||||
case KeyCode.VOICE_INPUT:
|
case KeyCode.VOICE_INPUT:
|
||||||
// switching to shortcut IME, shift state, keyboard,... is handled by LatinIME,
|
// 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)}.
|
// {@link KeyboardSwitcher#onEvent(Event)}, or {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}.
|
||||||
|
|
|
@ -154,6 +154,7 @@ object Defaults {
|
||||||
const val PREF_ABC_AFTER_NUMPAD_SPACE = false
|
const val PREF_ABC_AFTER_NUMPAD_SPACE = false
|
||||||
const val PREF_REMOVE_REDUNDANT_POPUPS = false
|
const val PREF_REMOVE_REDUNDANT_POPUPS = false
|
||||||
const val PREF_SPACE_BAR_TEXT = ""
|
const val PREF_SPACE_BAR_TEXT = ""
|
||||||
|
const val PREF_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss"
|
||||||
@JvmField
|
@JvmField
|
||||||
val PREF_EMOJI_MAX_SDK = Build.VERSION.SDK_INT
|
val PREF_EMOJI_MAX_SDK = Build.VERSION.SDK_INT
|
||||||
const val PREF_EMOJI_RECENT_KEYS = ""
|
const val PREF_EMOJI_RECENT_KEYS = ""
|
||||||
|
|
|
@ -164,6 +164,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||||
public static final String PREF_ABC_AFTER_NUMPAD_SPACE = "abc_after_numpad_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_REMOVE_REDUNDANT_POPUPS = "remove_redundant_popups";
|
||||||
public static final String PREF_SPACE_BAR_TEXT = "space_bar_text";
|
public static final String PREF_SPACE_BAR_TEXT = "space_bar_text";
|
||||||
|
public static final String PREF_TIMESTAMP_FORMAT = "timestamp_format";
|
||||||
|
|
||||||
// Emoji
|
// Emoji
|
||||||
public static final String PREF_EMOJI_MAX_SDK = "emoji_max_sdk";
|
public static final String PREF_EMOJI_MAX_SDK = "emoji_max_sdk";
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ import helium314.keyboard.latin.common.splitOnWhitespace
|
||||||
import helium314.keyboard.latin.settings.DebugSettings
|
import helium314.keyboard.latin.settings.DebugSettings
|
||||||
import helium314.keyboard.latin.settings.Defaults
|
import helium314.keyboard.latin.settings.Defaults
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
|
import helium314.keyboard.latin.utils.checkTimestampFormat
|
||||||
import helium314.keyboard.latin.utils.prefs
|
import helium314.keyboard.latin.utils.prefs
|
||||||
import helium314.keyboard.settings.NextScreenIcon
|
import helium314.keyboard.settings.NextScreenIcon
|
||||||
import helium314.keyboard.settings.SettingsContainer
|
import helium314.keyboard.settings.SettingsContainer
|
||||||
|
@ -45,6 +46,7 @@ import helium314.keyboard.settings.Theme
|
||||||
import helium314.keyboard.settings.dialogs.TextInputDialog
|
import helium314.keyboard.settings.dialogs.TextInputDialog
|
||||||
import helium314.keyboard.settings.preferences.BackupRestorePreference
|
import helium314.keyboard.settings.preferences.BackupRestorePreference
|
||||||
import helium314.keyboard.settings.preferences.LoadGestureLibPreference
|
import helium314.keyboard.settings.preferences.LoadGestureLibPreference
|
||||||
|
import helium314.keyboard.settings.preferences.TextInputPreference
|
||||||
import helium314.keyboard.settings.previewDark
|
import helium314.keyboard.settings.previewDark
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -71,6 +73,7 @@ fun AdvancedSettingsScreen(
|
||||||
Settings.PREF_ABC_AFTER_CLIP,
|
Settings.PREF_ABC_AFTER_CLIP,
|
||||||
Settings.PREF_CUSTOM_CURRENCY_KEY,
|
Settings.PREF_CUSTOM_CURRENCY_KEY,
|
||||||
Settings.PREF_MORE_POPUP_KEYS,
|
Settings.PREF_MORE_POPUP_KEYS,
|
||||||
|
Settings.PREF_TIMESTAMP_FORMAT,
|
||||||
SettingsWithoutKey.BACKUP_RESTORE,
|
SettingsWithoutKey.BACKUP_RESTORE,
|
||||||
if (BuildConfig.DEBUG || prefs.getBoolean(DebugSettings.PREF_SHOW_DEBUG_SETTINGS, Defaults.PREF_SHOW_DEBUG_SETTINGS))
|
if (BuildConfig.DEBUG || prefs.getBoolean(DebugSettings.PREF_SHOW_DEBUG_SETTINGS, Defaults.PREF_SHOW_DEBUG_SETTINGS))
|
||||||
SettingsWithoutKey.DEBUG_SETTINGS else null,
|
SettingsWithoutKey.DEBUG_SETTINGS else null,
|
||||||
|
@ -195,6 +198,9 @@ fun createAdvancedSettings(context: Context) = listOf(
|
||||||
Setting(context, SettingsWithoutKey.BACKUP_RESTORE, R.string.backup_restore_title) {
|
Setting(context, SettingsWithoutKey.BACKUP_RESTORE, R.string.backup_restore_title) {
|
||||||
BackupRestorePreference(it)
|
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) {
|
Setting(context, SettingsWithoutKey.DEBUG_SETTINGS, R.string.debug_settings_title) {
|
||||||
Preference(
|
Preference(
|
||||||
name = it.title,
|
name = it.title,
|
||||||
|
|
|
@ -21,6 +21,7 @@ import helium314.keyboard.latin.R
|
||||||
import helium314.keyboard.latin.settings.Defaults
|
import helium314.keyboard.latin.settings.Defaults
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.utils.Log
|
import helium314.keyboard.latin.utils.Log
|
||||||
|
import helium314.keyboard.latin.utils.checkTimestampFormat
|
||||||
import helium314.keyboard.latin.utils.getActivity
|
import helium314.keyboard.latin.utils.getActivity
|
||||||
import helium314.keyboard.latin.utils.getStringResourceOrName
|
import helium314.keyboard.latin.utils.getStringResourceOrName
|
||||||
import helium314.keyboard.latin.utils.prefs
|
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.initPreview
|
||||||
import helium314.keyboard.settings.preferences.BackgroundImagePref
|
import helium314.keyboard.settings.preferences.BackgroundImagePref
|
||||||
import helium314.keyboard.settings.preferences.CustomFontPreference
|
import helium314.keyboard.settings.preferences.CustomFontPreference
|
||||||
|
import helium314.keyboard.settings.preferences.TextInputPreference
|
||||||
import helium314.keyboard.settings.previewDark
|
import helium314.keyboard.settings.previewDark
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -263,26 +265,8 @@ fun createAppearanceSettings(context: Context) = listOf(
|
||||||
description = { "${(100 * it).toInt()}%" }
|
description = { "${(100 * it).toInt()}%" }
|
||||||
) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
) { KeyboardSwitcher.getInstance().setThemeNeedsReload() }
|
||||||
},
|
},
|
||||||
Setting(context, Settings.PREF_SPACE_BAR_TEXT, R.string.prefs_space_bar_text) { setting ->
|
Setting(context, Settings.PREF_SPACE_BAR_TEXT, R.string.prefs_space_bar_text) {
|
||||||
var showDialog by rememberSaveable { mutableStateOf(false) }
|
TextInputPreference(it, Defaults.PREF_SPACE_BAR_TEXT)
|
||||||
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, SettingsWithoutKey.CUSTOM_FONT, R.string.custom_font) {
|
Setting(context, SettingsWithoutKey.CUSTOM_FONT, R.string.custom_font) {
|
||||||
CustomFontPreference(it)
|
CustomFontPreference(it)
|
||||||
|
|
|
@ -196,6 +196,8 @@
|
||||||
<string name="button_backup">Backup</string>
|
<string name="button_backup">Backup</string>
|
||||||
<!-- restore button -->
|
<!-- restore button -->
|
||||||
<string name="button_restore">Restore</string>
|
<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 -->
|
<!-- Preferences item for choosing secondary language -->
|
||||||
<string name="secondary_locale">Multilingual typing</string>
|
<string name="secondary_locale">Multilingual typing</string>
|
||||||
<!-- Clarification which locales are available for multilingual typing -->
|
<!-- Clarification which locales are available for multilingual typing -->
|
||||||
|
|
|
@ -23,6 +23,7 @@ import helium314.keyboard.latin.inputlogic.InputLogic
|
||||||
import helium314.keyboard.latin.inputlogic.SpaceState
|
import helium314.keyboard.latin.inputlogic.SpaceState
|
||||||
import helium314.keyboard.latin.settings.Settings
|
import helium314.keyboard.latin.settings.Settings
|
||||||
import helium314.keyboard.latin.utils.ScriptUtils
|
import helium314.keyboard.latin.utils.ScriptUtils
|
||||||
|
import helium314.keyboard.latin.utils.getTimestamp
|
||||||
import helium314.keyboard.latin.utils.prefs
|
import helium314.keyboard.latin.utils.prefs
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mockito
|
import org.mockito.Mockito
|
||||||
|
@ -666,6 +667,13 @@ class InputLogicTest {
|
||||||
// need to avoid getting into the mWordComposer.isBatchMode() part of handleBackspaceEvent
|
// 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 ---------
|
// ------- helper functions ---------
|
||||||
|
|
||||||
// should be called before every test, so the same state is guaranteed
|
// should be called before every test, so the same state is guaranteed
|
||||||
|
|
|
@ -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.
|
* 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 `\`.
|
* 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`.
|
* 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`.
|
* 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`
|
* 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