mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-22 18:20:30 +02:00
Filter text from clipboard
This commit is contained in:
parent
b10630b9c7
commit
74cc7336fb
@ -20,11 +20,43 @@ package com.sadellie.unitto.feature.calculator
|
|||||||
|
|
||||||
import androidx.compose.ui.text.TextRange
|
import androidx.compose.ui.text.TextRange
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
|
import com.sadellie.unitto.core.base.KEY_0
|
||||||
|
import com.sadellie.unitto.core.base.KEY_1
|
||||||
|
import com.sadellie.unitto.core.base.KEY_2
|
||||||
|
import com.sadellie.unitto.core.base.KEY_3
|
||||||
|
import com.sadellie.unitto.core.base.KEY_4
|
||||||
|
import com.sadellie.unitto.core.base.KEY_5
|
||||||
|
import com.sadellie.unitto.core.base.KEY_6
|
||||||
|
import com.sadellie.unitto.core.base.KEY_7
|
||||||
|
import com.sadellie.unitto.core.base.KEY_8
|
||||||
|
import com.sadellie.unitto.core.base.KEY_9
|
||||||
|
import com.sadellie.unitto.core.base.KEY_BASE_A
|
||||||
|
import com.sadellie.unitto.core.base.KEY_BASE_B
|
||||||
|
import com.sadellie.unitto.core.base.KEY_BASE_C
|
||||||
|
import com.sadellie.unitto.core.base.KEY_BASE_D
|
||||||
|
import com.sadellie.unitto.core.base.KEY_BASE_E
|
||||||
|
import com.sadellie.unitto.core.base.KEY_BASE_F
|
||||||
import com.sadellie.unitto.core.base.KEY_COS
|
import com.sadellie.unitto.core.base.KEY_COS
|
||||||
|
import com.sadellie.unitto.core.base.KEY_DIVIDE
|
||||||
|
import com.sadellie.unitto.core.base.KEY_DIVIDE_DISPLAY
|
||||||
import com.sadellie.unitto.core.base.KEY_DOT
|
import com.sadellie.unitto.core.base.KEY_DOT
|
||||||
|
import com.sadellie.unitto.core.base.KEY_EXPONENT
|
||||||
|
import com.sadellie.unitto.core.base.KEY_E_SMALL
|
||||||
|
import com.sadellie.unitto.core.base.KEY_FACTORIAL
|
||||||
|
import com.sadellie.unitto.core.base.KEY_LEFT_BRACKET
|
||||||
import com.sadellie.unitto.core.base.KEY_LN
|
import com.sadellie.unitto.core.base.KEY_LN
|
||||||
import com.sadellie.unitto.core.base.KEY_LOG
|
import com.sadellie.unitto.core.base.KEY_LOG
|
||||||
|
import com.sadellie.unitto.core.base.KEY_MINUS
|
||||||
|
import com.sadellie.unitto.core.base.KEY_MINUS_DISPLAY
|
||||||
|
import com.sadellie.unitto.core.base.KEY_MODULO
|
||||||
|
import com.sadellie.unitto.core.base.KEY_MULTIPLY
|
||||||
|
import com.sadellie.unitto.core.base.KEY_MULTIPLY_DISPLAY
|
||||||
|
import com.sadellie.unitto.core.base.KEY_PERCENT
|
||||||
|
import com.sadellie.unitto.core.base.KEY_PI
|
||||||
|
import com.sadellie.unitto.core.base.KEY_PLUS
|
||||||
|
import com.sadellie.unitto.core.base.KEY_RIGHT_BRACKET
|
||||||
import com.sadellie.unitto.core.base.KEY_SIN
|
import com.sadellie.unitto.core.base.KEY_SIN
|
||||||
|
import com.sadellie.unitto.core.base.KEY_SQRT
|
||||||
import com.sadellie.unitto.core.base.KEY_TAN
|
import com.sadellie.unitto.core.base.KEY_TAN
|
||||||
import com.sadellie.unitto.core.ui.UnittoFormatter
|
import com.sadellie.unitto.core.ui.UnittoFormatter
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@ -33,6 +65,8 @@ import javax.inject.Inject
|
|||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
class TextFieldController @Inject constructor() {
|
class TextFieldController @Inject constructor() {
|
||||||
|
var input: MutableStateFlow<TextFieldValue> = MutableStateFlow(TextFieldValue())
|
||||||
|
|
||||||
// Internally we don't care about user preference here, because during composition this
|
// Internally we don't care about user preference here, because during composition this
|
||||||
// symbols will be replaced to those that user wanted.
|
// symbols will be replaced to those that user wanted.
|
||||||
// We do this because it adds unnecessary logic: it requires additional logic to observe and
|
// We do this because it adds unnecessary logic: it requires additional logic to observe and
|
||||||
@ -46,7 +80,19 @@ class TextFieldController @Inject constructor() {
|
|||||||
|
|
||||||
private val cursorFixer by lazy { CursorFixer() }
|
private val cursorFixer by lazy { CursorFixer() }
|
||||||
|
|
||||||
var input: MutableStateFlow<TextFieldValue> = MutableStateFlow(TextFieldValue())
|
private val knownSymbols: List<String> by lazy {
|
||||||
|
listOf(
|
||||||
|
KEY_SIN, KEY_COS, KEY_TAN, KEY_LN, KEY_LOG,
|
||||||
|
KEY_LEFT_BRACKET, KEY_RIGHT_BRACKET,
|
||||||
|
KEY_EXPONENT, KEY_SQRT, KEY_FACTORIAL,
|
||||||
|
KEY_MODULO, KEY_E_SMALL, KEY_PERCENT, KEY_PI,
|
||||||
|
KEY_MULTIPLY, KEY_MULTIPLY_DISPLAY,
|
||||||
|
KEY_PLUS, KEY_MINUS, KEY_MINUS_DISPLAY, KEY_DIVIDE, KEY_DIVIDE_DISPLAY,
|
||||||
|
KEY_BASE_A, KEY_BASE_B, KEY_BASE_C, KEY_BASE_D, KEY_BASE_E, KEY_BASE_F,
|
||||||
|
KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0,
|
||||||
|
KEY_DOT,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun addToInput(symbols: String) {
|
fun addToInput(symbols: String) {
|
||||||
|
|
||||||
@ -71,6 +117,11 @@ class TextFieldController @Inject constructor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to call when pasting from clipbaord. It filters input before calling [addToInput].
|
||||||
|
*/
|
||||||
|
fun pasteSymbols(symbols: String) = addToInput(symbols.filterUnknownSymbols())
|
||||||
|
|
||||||
fun moveCursor(newPosition: IntRange) {
|
fun moveCursor(newPosition: IntRange) {
|
||||||
val currentInput = input.value.text
|
val currentInput = input.value.text
|
||||||
val fixedLeftCursor = cursorFixer.fixCursorIfNeeded(currentInput, newPosition.first)
|
val fixedLeftCursor = cursorFixer.fixCursorIfNeeded(currentInput, newPosition.first)
|
||||||
@ -126,6 +177,28 @@ class TextFieldController @Inject constructor() {
|
|||||||
|
|
||||||
private fun String.fixFormat(): String = localFormatter.reFormat(this)
|
private fun String.fixFormat(): String = localFormatter.reFormat(this)
|
||||||
|
|
||||||
|
private fun String.filterUnknownSymbols(): String {
|
||||||
|
var clearStr = this.replace(" ", "")
|
||||||
|
var garbage = clearStr
|
||||||
|
|
||||||
|
// String with unknown symbols
|
||||||
|
knownSymbols.forEach {
|
||||||
|
garbage = garbage.replace(it, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove unknown symbols from input
|
||||||
|
garbage.split(" ").forEach {
|
||||||
|
clearStr = clearStr.replace(it, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
clearStr = clearStr
|
||||||
|
.replace(KEY_DIVIDE, KEY_DIVIDE_DISPLAY)
|
||||||
|
.replace(KEY_MULTIPLY, KEY_MULTIPLY_DISPLAY)
|
||||||
|
.replace(KEY_MINUS, KEY_MINUS_DISPLAY)
|
||||||
|
|
||||||
|
return clearStr
|
||||||
|
}
|
||||||
|
|
||||||
inner class CursorFixer {
|
inner class CursorFixer {
|
||||||
val illegalTokens by lazy {
|
val illegalTokens by lazy {
|
||||||
listOf(
|
listOf(
|
||||||
|
@ -189,7 +189,7 @@ internal class TextFieldControllerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `placed cursor illegally`() {
|
fun `Place cursor illegally`() {
|
||||||
textFieldController.addToInput("123456.789")
|
textFieldController.addToInput("123456.789")
|
||||||
// Input is 123,456.789
|
// Input is 123,456.789
|
||||||
textFieldController.moveCursor(4..4)
|
textFieldController.moveCursor(4..4)
|
||||||
@ -211,4 +211,34 @@ internal class TextFieldControllerTest {
|
|||||||
// Input is 123,456.789
|
// Input is 123,456.789
|
||||||
assertEquals("123456.789+cos(..)", textFieldController.inputTextWithoutFormatting())
|
assertEquals("123456.789+cos(..)", textFieldController.inputTextWithoutFormatting())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Paste completely weird stuff`() {
|
||||||
|
textFieldController.pasteSymbols("crazy stuff from clipboard")
|
||||||
|
assertEquals("", textFieldController.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Paste partially weird stuff`() {
|
||||||
|
textFieldController.pasteSymbols("some crazy stuff cos(8+9)*7= that user may have in clipboard")
|
||||||
|
assertEquals("ecos(8+9)×7ee", textFieldController.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Paste acceptable stuff that needs symbol replacement`() {
|
||||||
|
textFieldController.pasteSymbols("cos(8+9)*7")
|
||||||
|
assertEquals("cos(8+9)×7", textFieldController.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Paste acceptable stuff that does not need replacement`() {
|
||||||
|
textFieldController.pasteSymbols("cos(8+9)×7")
|
||||||
|
assertEquals("cos(8+9)×7", textFieldController.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Paste nothing`() {
|
||||||
|
textFieldController.pasteSymbols("")
|
||||||
|
assertEquals("", textFieldController.text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user