Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ android {
flavorDimensions.add("variants")

sourceSets {
getByName("main").java.srcDirs("src/main/kotlin")
getByName("main").java.srcDirs("src/main/java", "src/main/kotlin")
named("test") {
java.srcDirs("src/test/java", "src/test/kotlin")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import android.view.KeyEvent
import android.view.inputmethod.InputConnection
import android.widget.Button
import androidx.test.ext.junit.runners.AndroidJUnit4
import be.scri.models.ScribeState
import be.scri.services.GeneralKeyboardIME
import be.scri.services.GeneralKeyboardIME.ScribeState
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
Expand Down
111 changes: 111 additions & 0 deletions app/src/keyboards/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application>
<service
android:name=".services.EnglishKeyboardIME"
android:exported="true"
android:label="Scribe"
android:permission="android.permission.BIND_INPUT_METHOD" >
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>

<meta-data
android:name="android.view.im"
android:resource="@xml/method_english" />
</service>
<service
android:name=".services.FrenchKeyboardIME"
android:exported="true"
android:label="Scribe"
android:permission="android.permission.BIND_INPUT_METHOD" >
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>

<meta-data
android:name="android.view.im"
android:resource="@xml/method_french" />
</service>
<service
android:name=".services.GermanKeyboardIME"
android:exported="true"
android:label="Scribe"
android:permission="android.permission.BIND_INPUT_METHOD" >
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>

<meta-data
android:name="android.view.im"
android:resource="@xml/method_german" />
</service>
<service
android:name=".services.PortugueseKeyboardIME"
android:exported="true"
android:label="Scribe"
android:permission="android.permission.BIND_INPUT_METHOD" >
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>

<meta-data
android:name="android.view.im"
android:resource="@xml/method_portuguese" />
</service>
<service
android:name=".services.RussianKeyboardIME"
android:exported="true"
android:label="Scribe"
android:permission="android.permission.BIND_INPUT_METHOD" >
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>

<meta-data
android:name="android.view.im"
android:resource="@xml/method_russian" />
</service>
<service
android:name=".services.SpanishKeyboardIME"
android:exported="true"
android:label="Scribe"
android:permission="android.permission.BIND_INPUT_METHOD" >
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>

<meta-data
android:name="android.view.im"
android:resource="@xml/method_spanish" />
</service>
<service
android:name=".services.SwedishKeyboardIME"
android:exported="true"
android:label="Scribe"
android:permission="android.permission.BIND_INPUT_METHOD" >
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>

<meta-data
android:name="android.view.im"
android:resource="@xml/method_swedish" />
</service>
<service
android:name=".services.ItalianKeyboardIME"
android:exported="true"
android:label="Scribe"
android:permission="android.permission.BIND_INPUT_METHOD" >
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>

<meta-data
android:name="android.view.im"
android:resource="@xml/method_italian" />
</service>
</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package be.scri.helpers
import android.os.Handler
import android.os.Looper
import be.scri.services.GeneralKeyboardIME
import be.scri.services.GeneralKeyboardIME.ScribeState
import be.scri.models.ScribeState

/**
* Handles autocompletion when user is typing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package be.scri.helpers
import android.text.TextUtils
import android.view.inputmethod.InputConnection
import be.scri.helpers.PreferencesHelper.getIsWordByWordDeletionEnabled
import be.scri.models.ScribeState
import be.scri.services.GeneralKeyboardIME
import be.scri.services.GeneralKeyboardIME.Companion.MAX_TEXT_LENGTH

Expand Down Expand Up @@ -91,7 +92,7 @@ class BackspaceHandler(
val finalCommandBarText = ime.getCommandBarTextWithoutCursor()
val isEmptyOrAHint = finalCommandBarText.isEmpty() || finalCommandBarText == ime.currentCommandBarHint
val isGerman = ime.language == "German"
val isPluralState = ime.currentState == GeneralKeyboardIME.ScribeState.PLURAL
val isPluralState = ime.currentState == ScribeState.PLURAL

if (isEmptyOrAHint && isGerman && isPluralState) {
ime.keyboard?.mShiftState = SHIFT_ON_ONE_CHAR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import android.content.Context
import android.util.Log
import android.view.inputmethod.InputConnection
import be.scri.services.GeneralKeyboardIME
import be.scri.services.GeneralKeyboardIME.ScribeState
import be.scri.models.ScribeState

/**
* Handles key events for the [GeneralKeyboardIME].
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: GPL-3.0-or-later
package be.scri.helpers

import be.scri.helpers.english.ENInterfaceVariables
import be.scri.helpers.french.FRInterfaceVariables
import be.scri.helpers.german.DEInterfaceVariables
import be.scri.helpers.italian.ITInterfaceVariables
import be.scri.helpers.portuguese.PTInterfaceVariables
import be.scri.helpers.russian.RUInterfaceVariables
import be.scri.helpers.spanish.ESInterfaceVariables
import be.scri.helpers.swedish.SVInterfaceVariables

/**
* Object containing keyboard-specific constant mappings related to language-specific UI elements.
*/
object KeyboardLanguageMappingConstants {
val translatePlaceholder =
mapOf(
"EN" to ENInterfaceVariables.TRANSLATE_KEY_LBL,
"ES" to ESInterfaceVariables.TRANSLATE_KEY_LBL,
"DE" to DEInterfaceVariables.TRANSLATE_KEY_LBL,
"IT" to ITInterfaceVariables.TRANSLATE_KEY_LBL,
"FR" to FRInterfaceVariables.TRANSLATE_KEY_LBL,
"PT" to PTInterfaceVariables.TRANSLATE_KEY_LBL,
"RU" to RUInterfaceVariables.TRANSLATE_KEY_LBL,
"SV" to SVInterfaceVariables.TRANSLATE_KEY_LBL,
)

val conjugatePlaceholder =
mapOf(
"EN" to ENInterfaceVariables.CONJUGATE_KEY_LBL,
"ES" to ESInterfaceVariables.CONJUGATE_KEY_LBL,
"DE" to DEInterfaceVariables.CONJUGATE_KEY_LBL,
"IT" to ITInterfaceVariables.CONJUGATE_KEY_LBL,
"FR" to FRInterfaceVariables.CONJUGATE_KEY_LBL,
"PT" to PTInterfaceVariables.CONJUGATE_KEY_LBL,
"RU" to RUInterfaceVariables.CONJUGATE_KEY_LBL,
"SV" to SVInterfaceVariables.CONJUGATE_KEY_LBL,
)

val pluralPlaceholder =
mapOf(
"EN" to ENInterfaceVariables.PLURAL_KEY_LBL,
"ES" to ESInterfaceVariables.PLURAL_KEY_LBL,
"DE" to DEInterfaceVariables.PLURAL_KEY_LBL,
"IT" to ITInterfaceVariables.PLURAL_KEY_LBL,
"FR" to FRInterfaceVariables.PLURAL_KEY_LBL,
"PT" to PTInterfaceVariables.PLURAL_KEY_LBL,
"RU" to RUInterfaceVariables.PLURAL_KEY_LBL,
"SV" to SVInterfaceVariables.PLURAL_KEY_LBL,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package be.scri.helpers

import be.scri.services.GeneralKeyboardIME
import be.scri.services.GeneralKeyboardIME.ScribeState
import be.scri.models.ScribeState

/**
* Processes key events specifically related to the space key.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package be.scri.helpers
import android.os.Handler
import android.os.Looper
import be.scri.services.GeneralKeyboardIME
import be.scri.services.GeneralKeyboardIME.ScribeState
import be.scri.models.ScribeState

/**
* Handles auto-suggestions such as noun gender, plurality, case, and emojis.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import be.scri.helpers.portuguese.PTInterfaceVariables
import be.scri.helpers.russian.RUInterfaceVariables
import be.scri.helpers.spanish.ESInterfaceVariables
import be.scri.helpers.swedish.SVInterfaceVariables
import be.scri.services.GeneralKeyboardIME
import be.scri.models.ScribeState
import kotlin.collections.get

/**
Expand Down Expand Up @@ -47,12 +47,12 @@ object HintUtils {
* @return The appropriate hint message for the given state and language.
*/
fun getCommandBarHint(
currentState: GeneralKeyboardIME.ScribeState,
currentState: ScribeState,
language: String,
word: String?,
): String =
when (currentState) {
GeneralKeyboardIME.ScribeState.SELECT_VERB_CONJUNCTION -> word ?: ""
ScribeState.SELECT_VERB_CONJUNCTION -> word ?: ""
else -> getHintForState(currentState)[language] ?: ""
}

Expand All @@ -63,11 +63,11 @@ object HintUtils {
*
* @return A map of language codes to hint strings for the current state.
*/
private fun getHintForState(currentState: GeneralKeyboardIME.ScribeState): Map<String, String> =
private fun getHintForState(currentState: ScribeState): Map<String, String> =
when (currentState) {
GeneralKeyboardIME.ScribeState.TRANSLATE -> getTranslateHints()
GeneralKeyboardIME.ScribeState.CONJUGATE -> getConjugateHints()
GeneralKeyboardIME.ScribeState.PLURAL -> getPluralHints()
ScribeState.TRANSLATE -> getTranslateHints()
ScribeState.CONJUGATE -> getConjugateHints()
ScribeState.PLURAL -> getPluralHints()
else -> emptyMap()
}

Expand Down Expand Up @@ -311,16 +311,16 @@ object HintUtils {
* @return The appropriate prompt text for the given state and language.
*/
fun getPromptText(
currentState: GeneralKeyboardIME.ScribeState,
currentState: ScribeState,
language: String,
context: Context,
text: String?,
): String =
when (currentState) {
GeneralKeyboardIME.ScribeState.TRANSLATE -> getTranslationPrompt(language, context)
GeneralKeyboardIME.ScribeState.CONJUGATE -> getConjugationPrompt(language)
GeneralKeyboardIME.ScribeState.PLURAL -> getPluralPrompt(language)
GeneralKeyboardIME.ScribeState.SELECT_VERB_CONJUNCTION -> text!!
ScribeState.TRANSLATE -> getTranslationPrompt(language, context)
ScribeState.CONJUGATE -> getConjugationPrompt(language)
ScribeState.PLURAL -> getPluralPrompt(language)
ScribeState.SELECT_VERB_CONJUNCTION -> text!!
else -> ""
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ import be.scri.R
import be.scri.R.color.white
import be.scri.databinding.InputMethodViewBinding
import be.scri.helpers.KeyboardBase
import be.scri.helpers.LanguageMappingConstants.conjugatePlaceholder
import be.scri.helpers.KeyboardLanguageMappingConstants.conjugatePlaceholder
import be.scri.helpers.LanguageMappingConstants.getLanguageAlias
import be.scri.helpers.LanguageMappingConstants.pluralPlaceholder
import be.scri.helpers.LanguageMappingConstants.translatePlaceholder
import be.scri.helpers.KeyboardLanguageMappingConstants.pluralPlaceholder
import be.scri.helpers.KeyboardLanguageMappingConstants.translatePlaceholder
import be.scri.helpers.PreferencesHelper
import be.scri.helpers.PreferencesHelper.getIsDarkModeOrNot
import be.scri.helpers.english.ENInterfaceVariables.ALREADY_PLURAL_MSG
import be.scri.models.ScribeState
import be.scri.services.GeneralKeyboardIME
import be.scri.services.GeneralKeyboardIME.ScribeState
import be.scri.views.KeyboardView

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import be.scri.helpers.SuggestionHandler
import be.scri.helpers.data.AutocompletionDataManager
import be.scri.helpers.english.ENInterfaceVariables.ALREADY_PLURAL_MSG
import be.scri.helpers.ui.KeyboardUIManager
import be.scri.models.ScribeState
import be.scri.views.KeyboardView
import java.util.Locale

Expand All @@ -65,14 +66,15 @@ private const val DATA_CONSTANT_3 = 3

@Suppress("TooManyFunctions", "LargeClass")
abstract class GeneralKeyboardIME(
var language: String,
override var language: String,
) : InputMethodService(),
KeyboardView.OnKeyboardActionListener,
KeyboardUIManager.KeyboardUIListener {
KeyboardUIManager.KeyboardUIListener,
KeyboardBase.KeyboardContextProvider {
// Abstract members required by subclasses (like EnglishKeyboardIME)
abstract override fun getKeyboardLayoutXML(): Int

abstract val keyboardLetters: Int
abstract override val keyboardLetters: Int
abstract val keyboardSymbols: Int
abstract val keyboardSymbolShift: Int

Expand All @@ -83,7 +85,7 @@ abstract class GeneralKeyboardIME(
lateinit var uiManager: KeyboardUIManager

abstract var lastShiftPressTS: Long
abstract var keyboardMode: Int
abstract override var keyboardMode: Int
abstract var inputTypeClass: Int
abstract var enterKeyType: Int
abstract var switchToLetters: Boolean
Expand Down Expand Up @@ -175,7 +177,7 @@ abstract class GeneralKeyboardIME(
internal const val CUSTOM_CURSOR = "│" // special tall cursor character
}

enum class ScribeState { IDLE, SELECT_COMMAND, TRANSLATE, CONJUGATE, PLURAL, SELECT_VERB_CONJUNCTION, INVALID, ALREADY_PLURAL }


// MARK: Lifecycle Methods

Expand Down Expand Up @@ -470,7 +472,7 @@ abstract class GeneralKeyboardIME(
*
* @return true if the current input field is likely a search or address bar, false otherwise.
*/
fun isSearchBar(): Boolean {
override fun isSearchBar(): Boolean {
val editorInfo = currentInputEditorInfo
val isActionSearch = (enterKeyType == EditorInfo.IME_ACTION_SEARCH)
val isUriType = editorInfo?.let { (it.inputType and InputType.TYPE_TEXT_VARIATION_URI) != 0 } == true
Expand Down Expand Up @@ -929,7 +931,7 @@ abstract class GeneralKeyboardIME(
* Sets the flag to indicate that the delete key is currently repeating (long press).
* Delegated to BackspaceHandler.
*/
fun setDeleteRepeating(repeating: Boolean) {
override fun setDeleteRepeating(repeating: Boolean) {
backspaceHandler.isDeleteRepeating = repeating
}

Expand Down
Loading
Loading