Skip to content
Merged
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
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ android {
applicationId "com.kazumaproject.markdownhelperkeyboard"
minSdk 24
targetSdk 36
versionCode 744
versionName "1.7.50"
versionCode 746
versionName "1.7.52"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

Expand Down
3 changes: 3 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
-keep class com.kazumaproject.markdownhelperkeyboard.user_dictionary.database.UserWord { *; }
-keep class com.kazumaproject.markdownhelperkeyboard.user_template.database.UserTemplate { *; }
-keep class com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.** { *; }
-keep class com.kazumaproject.markdownhelperkeyboard.custom_keyboard.import_export.** { *; }
-keep class com.kazumaproject.markdownhelperkeyboard.learning.database.LearnEntity { *; }
-keep class com.kazumaproject.markdownhelperkeyboard.clipboard_history.database.ClipboardHistoryItem { *; }
-keep class com.kazumaproject.markdownhelperkeyboard.custom_romaji.database.RomajiMapEntity { *; }
Expand All @@ -37,6 +38,8 @@

# Keep Gson generic type metadata and annotations used by backup import/export parsing.
-keepattributes Signature
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
-keepattributes *Annotation*
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,15 @@ data class FullKeyboardLayout(
entity = KeyDefinition::class,
entityColumn = "ownerLayoutId"
)
val keysWithFlicks: List<KeyWithFlicks>
val keysWithFlicks: List<KeyWithFlicks>,
/**
* Layout-level SpacerItems (visual gaps that occupy grid cells but
* don't render content). Stored in `spacer_definitions` and joined by
* Room via the [SpacerDefinition.ownerLayoutId] foreign key.
*/
@Relation(
parentColumn = "layoutId",
entityColumn = "ownerLayoutId"
)
val spacers: List<SpacerDefinition> = emptyList()
)
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,9 @@ data class KeyDefinition(
val isSpecialKey: Boolean = false,
val drawableResId: Int? = null,
val keyIdentifier: String,
val action: String? = null
val action: String? = null,
val rowUnits: Int? = null,
val columnUnits: Int? = null,
val rowSpanUnits: Int? = null,
val columnSpanUnits: Int? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data

import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey

/**
* SpacerItem (KeyboardLayout の中で空き領域を占める「描画されないキー」)
* を永続化するためのエンティティ。
*
* KeyDefinition と並列にレイアウトに紐づく。
*
* 行内 Spacer (Shift と文字キーの間など) も先頭 Spacer も、すべてここに保存される。
*/
@Entity(
tableName = "spacer_definitions",
foreignKeys = [ForeignKey(
entity = CustomKeyboardLayout::class,
parentColumns = ["layoutId"],
childColumns = ["ownerLayoutId"],
onDelete = ForeignKey.CASCADE
)],
indices = [Index(value = ["ownerLayoutId"])]
)
data class SpacerDefinition(
@PrimaryKey(autoGenerate = true)
val spacerId: Long = 0,
val ownerLayoutId: Long,
/** stable id used in KeyboardLayoutItem.id (helps debugging / round-trip). */
val itemIdentifier: String,
val rowUnits: Int,
val columnUnits: Int,
val rowSpanUnits: Int,
val columnSpanUnits: Int,
val sortOrder: Int = 0
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.FlickMappin
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.FullKeyboardLayout
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.KeyDefinition
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.LongPressFlickMapping
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.SpacerDefinition
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.TwoStepFlickMapping
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.TwoStepLongPressMappingEntity
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -43,10 +44,15 @@ interface KeyboardLayoutDao {
circularFlicksMap: Map<String, List<CircularFlickMapping>>,
twoStepFlicksMap: Map<String, List<TwoStepFlickMapping>>,
longPressFlicksMap: Map<String, List<LongPressFlickMapping>>,
twoStepLongPressFlicksMap: Map<String, List<TwoStepLongPressMappingEntity>>
twoStepLongPressFlicksMap: Map<String, List<TwoStepLongPressMappingEntity>>,
spacers: List<SpacerDefinition> = emptyList()
) {
val layoutId = insertLayout(layout)

if (spacers.isNotEmpty()) {
insertSpacers(spacers.map { it.copy(spacerId = 0, ownerLayoutId = layoutId) })
}

val keysWithLayoutId = keys.map { it.copy(ownerLayoutId = layoutId) }
val newKeyIds = insertKeys(keysWithLayoutId)

Expand Down Expand Up @@ -126,6 +132,12 @@ interface KeyboardLayoutDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertTwoStepLongPressFlickMappings(mappings: List<TwoStepLongPressMappingEntity>)

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertSpacers(spacers: List<SpacerDefinition>)

@Query("DELETE FROM spacer_definitions WHERE ownerLayoutId = :layoutId")
suspend fun deleteSpacersForLayout(layoutId: Long)

@Query("DELETE FROM keyboard_layouts WHERE layoutId = :layoutId")
suspend fun deleteLayout(layoutId: Long)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.kazumaproject.markdownhelperkeyboard.custom_keyboard.import_export

import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.CircularFlickMapping
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.CustomKeyboardLayout
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.FlickMapping
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.KeyDefinition
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.LongPressFlickMapping
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.SpacerDefinition
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.TwoStepFlickMapping
import com.kazumaproject.markdownhelperkeyboard.custom_keyboard.data.TwoStepLongPressMappingEntity

/**
* Import 用の正規化済み内部モデル。
*
* 外部 JSON ([KeyboardLayoutExportDto])を読み込み、欠損や null を
* すべて埋めて非 null 化したものをこの型で表す。
*
* Repository 以降ではこのモデルだけを使うため、null 防御を都度書く必要はない。
*/
data class ImportableKeyboardLayout(
val layout: CustomKeyboardLayout,
val keysWithFlicks: List<ImportableKeyWithFlicks>,
val spacers: List<SpacerDefinition>
)

/**
* Import 用の正規化済み key + flick 系マッピング。
*
* 各 List は non-null。
*/
data class ImportableKeyWithFlicks(
val key: KeyDefinition,
val flicks: List<FlickMapping>,
val circularFlicks: List<CircularFlickMapping>,
val twoStepFlicks: List<TwoStepFlickMapping>,
val longPressFlicks: List<LongPressFlickMapping>,
val twoStepLongPressFlicks: List<TwoStepLongPressMappingEntity>
)
Loading
Loading