SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/table/HighlightWord.kt

237 lines
6.2 KiB
Kotlin

package jp.juggler.subwaytooter.table
import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.provider.BaseColumns
import org.json.JSONObject
import jp.juggler.subwaytooter.App1
import jp.juggler.util.*
import java.util.concurrent.atomic.AtomicReference
class HighlightWord {
companion object : TableCompanion {
private val log = LogCategory("HighlightWord")
const val SOUND_TYPE_NONE = 0
const val SOUND_TYPE_DEFAULT = 1
const val SOUND_TYPE_CUSTOM = 2
const val table = "highlight_word"
const val COL_ID = BaseColumns._ID
const val COL_NAME = "name"
private const val COL_TIME_SAVE = "time_save"
private const val COL_COLOR_BG = "color_bg"
private const val COL_COLOR_FG = "color_fg"
private const val COL_SOUND_TYPE = "sound_type"
private const val COL_SOUND_URI = "sound_uri"
private const val COL_SPEECH = "speech"
private const val selection_name = "$COL_NAME=?"
private const val selection_speech = "$COL_SPEECH<>0"
private const val selection_id = "$COL_ID=?"
private val columns_name = arrayOf(COL_NAME)
override fun onDBCreate(db : SQLiteDatabase) {
log.d("onDBCreate!")
db.execSQL(
"""create table if not exists $table
($COL_ID INTEGER PRIMARY KEY
,$COL_NAME text not null
,$COL_TIME_SAVE integer not null
,$COL_COLOR_BG integer not null default 0
,$COL_COLOR_FG integer not null default 0
,$COL_SOUND_TYPE integer not null default 1
,$COL_SOUND_URI text default null
,$COL_SPEECH integer default 0
)"""
)
db.execSQL(
"create unique index if not exists ${table}_name on $table(name)"
)
}
override fun onDBUpgrade(db : SQLiteDatabase, oldVersion : Int, newVersion : Int) {
if(oldVersion < 21 && newVersion >= 21) {
onDBCreate(db)
}
if(oldVersion < 43 && newVersion >= 43) {
try {
db.execSQL("alter table $table add column $COL_SPEECH integer default 0")
} catch(ex : Throwable) {
log.trace(ex)
}
}
}
fun load(name : String) : HighlightWord? {
try {
App1.database.query(table, null, selection_name, arrayOf(name), null, null, null)
.use { cursor ->
if(cursor.moveToNext()) {
return HighlightWord(cursor)
}
}
} catch(ex : Throwable) {
log.trace(ex)
}
return null
}
fun createCursor() : Cursor {
return App1.database.query(table, null, null, null, null, null, "$COL_NAME asc")
}
val nameSet : WordTrieTree?
get() {
val dst = WordTrieTree()
try {
App1.database.query(table, columns_name, null, null, null, null, null)
.use { cursor ->
val idx_name = cursor.getColumnIndex(COL_NAME)
while(cursor.moveToNext()) {
val s = cursor.getString(idx_name)
dst.add(s)
}
}
} catch(ex : Throwable) {
log.trace(ex)
}
return if(dst.isEmpty) null else dst
}
private val hasTextToSpeechHighlightWordCache = AtomicReference<Boolean>(null)
fun hasTextToSpeechHighlightWord() : Boolean {
synchronized(this) {
var cached = hasTextToSpeechHighlightWordCache.get()
if(cached == null) {
cached = false
try {
App1.database.query(
table,
columns_name,
selection_speech,
null,
null,
null,
null
)
.use { cursor ->
while(cursor.moveToNext()) {
cached = true
}
}
} catch(ex : Throwable) {
log.trace(ex)
}
hasTextToSpeechHighlightWordCache.set(cached)
}
return cached
}
}
}
var id = - 1L
var name : String
var color_bg = 0
var color_fg = 0
var sound_type = 0
var sound_uri : String? = null
var speech = 0
fun encodeJson() : JSONObject {
val dst = JSONObject()
dst.put(COL_ID, id)
dst.put(COL_NAME, name)
dst.put(COL_COLOR_BG, color_bg)
dst.put(COL_COLOR_FG, color_fg)
dst.put(COL_SOUND_TYPE, sound_type)
dst.put(COL_SPEECH, speech)
if(sound_uri != null) dst.put(COL_SOUND_URI, sound_uri)
return dst
}
constructor(src : JSONObject) {
this.id = src.parseLong(COL_ID) ?: - 1L
this.name = src.notEmptyOrThrow(COL_NAME)
this.color_bg = src.optInt(COL_COLOR_BG)
this.color_fg = src.optInt(COL_COLOR_FG)
this.sound_type = src.optInt(COL_SOUND_TYPE)
this.sound_uri = src.parseString(COL_SOUND_URI)
this.speech = src.optInt(COL_SPEECH)
}
constructor(name : String) {
this.name = name
this.sound_type = SOUND_TYPE_DEFAULT
this.color_fg = - 0x10000
}
constructor(cursor : Cursor) {
this.id = cursor.getLong(COL_ID)
this.name = cursor.getString(COL_NAME)
this.color_bg = cursor.getInt(COL_COLOR_BG)
this.color_fg = cursor.getInt(COL_COLOR_FG)
this.sound_type = cursor.getInt(COL_SOUND_TYPE)
this.sound_uri = cursor.getStringOrNull(COL_SOUND_URI)
this.speech = cursor.getInt(COL_SPEECH)
}
fun save(context : Context) {
if(name.isEmpty()) throw RuntimeException("HighlightWord.save(): name is empty")
try {
val cv = ContentValues()
cv.put(COL_NAME, name)
cv.put(COL_TIME_SAVE, System.currentTimeMillis())
cv.put(COL_COLOR_BG, color_bg)
cv.put(COL_COLOR_FG, color_fg)
cv.put(COL_SOUND_TYPE, sound_type)
val sound_uri = this.sound_uri
if(sound_uri?.isEmpty() != false) {
cv.putNull(COL_SOUND_URI)
} else {
cv.put(COL_SOUND_URI, sound_uri)
}
cv.put(COL_SPEECH, speech)
if(id == - 1L) {
id = App1.database.replace(table, null, cv)
} else {
App1.database.update(table, cv, selection_id, arrayOf(id.toString()))
}
} catch(ex : Throwable) {
log.e(ex, "save failed.")
}
synchronized(Companion) {
hasTextToSpeechHighlightWordCache.set(null)
}
App1.getAppState(context).enableSpeech()
}
fun delete(context : Context) {
try {
App1.database.delete(table, selection_id, arrayOf(id.toString()))
} catch(ex : Throwable) {
log.e(ex, "delete failed.")
}
synchronized(Companion) {
hasTextToSpeechHighlightWordCache.set(null)
}
App1.getAppState(context).enableSpeech()
}
}