Implement find characters
This commit is contained in:
parent
cb52240eea
commit
d9b7b82c60
@ -3,6 +3,7 @@ package com.marvinelsen.willow
|
||||
import com.marvinelsen.willow.domain.SearchMode
|
||||
import com.marvinelsen.willow.ui.DictionaryEntryFx
|
||||
import com.marvinelsen.willow.ui.util.ClipboardHelper
|
||||
import com.marvinelsen.willow.ui.util.FindCharacterService
|
||||
import com.marvinelsen.willow.ui.util.FindWordsService
|
||||
import com.marvinelsen.willow.ui.util.SearchService
|
||||
import javafx.beans.property.ObjectProperty
|
||||
@ -13,10 +14,11 @@ import javafx.collections.FXCollections
|
||||
import javafx.collections.ObservableList
|
||||
import javafx.event.EventHandler
|
||||
|
||||
class Model(private val searchService: SearchService, private val findWordsService: FindWordsService) {
|
||||
class Model(private val searchService: SearchService, private val findWordsService: FindWordsService, private val findCharacterService: FindCharacterService) {
|
||||
private val internalSelectedEntry: ObjectProperty<DictionaryEntryFx> = SimpleObjectProperty()
|
||||
private val internalSearchResults: ObservableList<DictionaryEntryFx> = FXCollections.observableArrayList()
|
||||
private val internalWordsContaining: ObservableList<DictionaryEntryFx> = FXCollections.observableArrayList()
|
||||
private val internalCharacters: ObservableList<DictionaryEntryFx> = FXCollections.observableArrayList()
|
||||
|
||||
val selectedEntry: ReadOnlyObjectProperty<DictionaryEntryFx> = internalSelectedEntry
|
||||
|
||||
@ -24,6 +26,8 @@ class Model(private val searchService: SearchService, private val findWordsServi
|
||||
FXCollections.unmodifiableObservableList(internalSearchResults)
|
||||
val wordsContaining: ObservableList<DictionaryEntryFx> =
|
||||
FXCollections.unmodifiableObservableList(internalWordsContaining)
|
||||
val characters: ObservableList<DictionaryEntryFx> =
|
||||
FXCollections.unmodifiableObservableList(internalCharacters)
|
||||
|
||||
val isSearching: ReadOnlyBooleanProperty = searchService.runningProperty()
|
||||
val isFindingWords: ReadOnlyBooleanProperty = findWordsService.runningProperty()
|
||||
@ -35,6 +39,9 @@ class Model(private val searchService: SearchService, private val findWordsServi
|
||||
findWordsService.onSucceeded = EventHandler {
|
||||
internalWordsContaining.setAll(findWordsService.value)
|
||||
}
|
||||
findCharacterService.onSucceeded = EventHandler {
|
||||
internalCharacters.setAll(findCharacterService.value)
|
||||
}
|
||||
}
|
||||
|
||||
fun search(query: String, searchMode: SearchMode) {
|
||||
@ -48,6 +55,11 @@ class Model(private val searchService: SearchService, private val findWordsServi
|
||||
findWordsService.restart()
|
||||
}
|
||||
|
||||
fun findCharacters() {
|
||||
findCharacterService.entry = internalSelectedEntry.value
|
||||
findCharacterService.restart()
|
||||
}
|
||||
|
||||
fun selectEntry(entry: DictionaryEntryFx) {
|
||||
internalSelectedEntry.value = entry
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import com.marvinelsen.willow.ui.controllers.MainController
|
||||
import com.marvinelsen.willow.ui.controllers.MenuController
|
||||
import com.marvinelsen.willow.ui.controllers.SearchController
|
||||
import com.marvinelsen.willow.ui.controllers.SearchResultsController
|
||||
import com.marvinelsen.willow.ui.util.FindCharacterService
|
||||
import com.marvinelsen.willow.ui.util.FindWordsService
|
||||
import com.marvinelsen.willow.ui.util.SearchService
|
||||
import javafx.application.Application
|
||||
@ -44,7 +45,8 @@ class WillowApplication : Application() {
|
||||
val dictionary = SqliteDictionary(connection)
|
||||
val searchService = SearchService(dictionary)
|
||||
val findWordsService = FindWordsService(dictionary)
|
||||
val model = Model(searchService, findWordsService)
|
||||
val findCharacterService = FindCharacterService(dictionary)
|
||||
val model = Model(searchService, findWordsService, findCharacterService)
|
||||
val config = Config()
|
||||
config.load()
|
||||
|
||||
|
@ -78,9 +78,11 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
||||
}
|
||||
|
||||
private val findCharacters = """
|
||||
WITH cte(id, character) AS (VALUES ?)
|
||||
SELECT traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, definitions
|
||||
FROM cedict
|
||||
WHERE traditional IN (?)
|
||||
FROM cedict INNER JOIN cte
|
||||
ON cte.character = cedict.traditional OR cte.character = cedict.simplified
|
||||
ORDER BY cte.id
|
||||
""".trimIndent()
|
||||
|
||||
override fun search(query: String, searchMode: SearchMode) = when (searchMode) {
|
||||
@ -107,7 +109,8 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
||||
val characterList = entry.traditional
|
||||
.split("")
|
||||
.filter { it.isNotBlank() }
|
||||
.joinToString(",") { "'$it'" }
|
||||
.mapIndexed { index, s -> "($index, '$s')" }
|
||||
.joinToString(",")
|
||||
|
||||
val query = findCharacters.replace("?", characterList)
|
||||
|
||||
|
@ -49,6 +49,7 @@ class DetailsController(private val model: Model, private val config: Config) {
|
||||
initializeLabelHeadword()
|
||||
initializeTabPaneDetails()
|
||||
initializeListViewWords()
|
||||
initializeListViewCharacters()
|
||||
initializeWebViewDefinition()
|
||||
|
||||
model.selectedEntry.addListener { _, _, newEntry ->
|
||||
@ -59,6 +60,10 @@ class DetailsController(private val model: Model, private val config: Config) {
|
||||
model.findWords()
|
||||
}
|
||||
|
||||
"tabCharacters" -> {
|
||||
model.findCharacters()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
webViewDefinition.engine.loadContent(newEntry.createCedictDefinitionHtml())
|
||||
@ -78,6 +83,13 @@ class DetailsController(private val model: Model, private val config: Config) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeListViewCharacters() {
|
||||
listViewCharacters.apply {
|
||||
cellFactory = DictionaryEntryCellFactory(resources, config)
|
||||
items = model.characters
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeTabPaneDetails() {
|
||||
tabPaneDetails.apply {
|
||||
disableProperty().bind(Bindings.isNull(model.selectedEntry))
|
||||
@ -90,6 +102,10 @@ class DetailsController(private val model: Model, private val config: Config) {
|
||||
model.findWords()
|
||||
}
|
||||
|
||||
"tabCharacters" -> {
|
||||
model.findCharacters()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
@ -30,3 +30,13 @@ class FindWordsService(private val dictionary: Dictionary) : Service<ObservableL
|
||||
FXCollections.observableList(dictionary.findWordsContaining(entry.toDomain()).map { it.toFx() })
|
||||
}
|
||||
}
|
||||
|
||||
class FindCharacterService(private val dictionary: Dictionary) : Service<ObservableList<DictionaryEntryFx>>() {
|
||||
lateinit var entry: DictionaryEntryFx
|
||||
|
||||
override fun createTask() = task {
|
||||
if (!this::entry.isInitialized) error("Entry is not initialized")
|
||||
|
||||
FXCollections.observableList(dictionary.findCharacters(entry.toDomain()).map { it.toFx() })
|
||||
}
|
||||
}
|
||||
|
@ -14,17 +14,16 @@
|
||||
</padding>
|
||||
</Label>
|
||||
<TabPane fx:id="tabPaneDetails" tabClosingPolicy="UNAVAILABLE" disable="true" VBox.vgrow="ALWAYS">
|
||||
<Tab closable="false" disable="false" text="%tab.definition">
|
||||
<WebView fx:id="webViewDefinition" minHeight="-1.0" minWidth="-1.0" prefHeight="-1.0"
|
||||
prefWidth="-1.0"/>
|
||||
<Tab closable="false" text="%tab.definition">
|
||||
<WebView fx:id="webViewDefinition" minHeight="-1.0" minWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0"/>
|
||||
</Tab>
|
||||
<Tab id="tabSentences" closable="false" disable="false" text="%tab.sentences">
|
||||
<Tab id="tabSentences" closable="false" text="%tab.sentences">
|
||||
<ListView fx:id="listviewSentences"/>
|
||||
</Tab>
|
||||
<Tab id="tabWords" closable="false" disable="false" text="%tab.words">
|
||||
<Tab id="tabWords" closable="false" text="%tab.words">
|
||||
<ListView fx:id="listViewWords"/>
|
||||
</Tab>
|
||||
<Tab closable="false" disable="false" text="%tab.characters">
|
||||
<Tab id="tabCharacters" closable="false" text="%tab.characters">
|
||||
<ListView fx:id="listViewCharacters"/>
|
||||
</Tab>
|
||||
</TabPane>
|
||||
|
Loading…
Reference in New Issue
Block a user