Compare commits
9 Commits
bc9d09c39f
...
7add73fe28
Author | SHA1 | Date | |
---|---|---|---|
7add73fe28 | |||
62c57d1e85 | |||
387e10dd50 | |||
6f5b8427e0 | |||
c9c794604b | |||
039efe8b6c | |||
8c5ac438c2 | |||
cb5eb95b04 | |||
6446c2d9c8 |
@ -28,6 +28,8 @@ dependencies {
|
|||||||
implementation(libs.kotlinx.serialization.json)
|
implementation(libs.kotlinx.serialization.json)
|
||||||
implementation(libs.kotlinx.html.jvm)
|
implementation(libs.kotlinx.html.jvm)
|
||||||
|
|
||||||
|
implementation(libs.segment)
|
||||||
|
|
||||||
testImplementation(libs.kotest.core)
|
testImplementation(libs.kotest.core)
|
||||||
testImplementation(libs.kotest.assertions)
|
testImplementation(libs.kotest.assertions)
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ sqlite-jdbc = "3.46.0.1"
|
|||||||
kotlinx-serialization-json = "1.7.1"
|
kotlinx-serialization-json = "1.7.1"
|
||||||
kotlinx-html-jvm = "0.11.0"
|
kotlinx-html-jvm = "0.11.0"
|
||||||
|
|
||||||
|
segment = "0.3.1"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
chinese-transliteration = { module = "com.marvinelsen:chinese-transliteration", version.ref = "chinese-transliteration" }
|
chinese-transliteration = { module = "com.marvinelsen:chinese-transliteration", version.ref = "chinese-transliteration" }
|
||||||
cedict-parser = { module = "com.marvinelsen:cedict-parser", version.ref = "cedict-parser" }
|
cedict-parser = { module = "com.marvinelsen:cedict-parser", version.ref = "cedict-parser" }
|
||||||
@ -28,6 +30,8 @@ sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite-jdbc" }
|
|||||||
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
|
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
|
||||||
kotlinx-html-jvm = { module = "org.jetbrains.kotlinx:kotlinx-html-jvm", version.ref = "kotlinx-html-jvm" }
|
kotlinx-html-jvm = { module = "org.jetbrains.kotlinx:kotlinx-html-jvm", version.ref = "kotlinx-html-jvm" }
|
||||||
|
|
||||||
|
segment = { module = "com.github.houbb:segment", version.ref = "segment" }
|
||||||
|
|
||||||
# Detekt
|
# Detekt
|
||||||
# See: https://detekt.dev
|
# See: https://detekt.dev
|
||||||
detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" }
|
detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" }
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
package com.marvinelsen.willow
|
|
||||||
|
|
||||||
import javafx.beans.property.IntegerProperty
|
|
||||||
import javafx.beans.property.SimpleIntegerProperty
|
|
||||||
import java.util.prefs.Preferences
|
|
||||||
|
|
||||||
class Config {
|
|
||||||
companion object {
|
|
||||||
private const val DETAIL_HEADWORD_FONT_SIZE_KEY = "detailHeadwordFontSize"
|
|
||||||
|
|
||||||
private const val DEFAULT_DETAIL_HEADWORD_FONT_SIZE = 16
|
|
||||||
}
|
|
||||||
|
|
||||||
private val preferences = Preferences.userNodeForPackage(this::class.java)
|
|
||||||
|
|
||||||
val detailHeadwordFontSize: IntegerProperty = SimpleIntegerProperty(DEFAULT_DETAIL_HEADWORD_FONT_SIZE)
|
|
||||||
|
|
||||||
fun save() {
|
|
||||||
preferences.putInt(DETAIL_HEADWORD_FONT_SIZE_KEY, detailHeadwordFontSize.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun load() {
|
|
||||||
detailHeadwordFontSize.value = preferences.getInt(
|
|
||||||
DETAIL_HEADWORD_FONT_SIZE_KEY,
|
|
||||||
DEFAULT_DETAIL_HEADWORD_FONT_SIZE
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun reset() {
|
|
||||||
detailHeadwordFontSize.value = DEFAULT_DETAIL_HEADWORD_FONT_SIZE
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,12 @@
|
|||||||
package com.marvinelsen.willow
|
package com.marvinelsen.willow
|
||||||
|
|
||||||
|
import com.marvinelsen.willow.config.Config
|
||||||
import com.marvinelsen.willow.domain.SqliteDictionary
|
import com.marvinelsen.willow.domain.SqliteDictionary
|
||||||
import com.marvinelsen.willow.ui.controllers.DetailsController
|
import com.marvinelsen.willow.ui.controllers.DetailsController
|
||||||
import com.marvinelsen.willow.ui.controllers.ListController
|
|
||||||
import com.marvinelsen.willow.ui.controllers.MainController
|
import com.marvinelsen.willow.ui.controllers.MainController
|
||||||
import com.marvinelsen.willow.ui.controllers.MenuController
|
import com.marvinelsen.willow.ui.controllers.MenuController
|
||||||
import com.marvinelsen.willow.ui.controllers.SearchController
|
import com.marvinelsen.willow.ui.controllers.SearchController
|
||||||
|
import com.marvinelsen.willow.ui.controllers.SearchResultsController
|
||||||
import com.marvinelsen.willow.ui.util.FindWordsService
|
import com.marvinelsen.willow.ui.util.FindWordsService
|
||||||
import com.marvinelsen.willow.ui.util.SearchService
|
import com.marvinelsen.willow.ui.util.SearchService
|
||||||
import javafx.application.Application
|
import javafx.application.Application
|
||||||
@ -16,7 +17,6 @@ import javafx.scene.text.Font
|
|||||||
import javafx.stage.Stage
|
import javafx.stage.Stage
|
||||||
import javafx.util.Callback
|
import javafx.util.Callback
|
||||||
import java.sql.DriverManager
|
import java.sql.DriverManager
|
||||||
import java.util.Locale
|
|
||||||
import java.util.ResourceBundle
|
import java.util.ResourceBundle
|
||||||
|
|
||||||
class WillowApplication : Application() {
|
class WillowApplication : Application() {
|
||||||
@ -48,14 +48,14 @@ class WillowApplication : Application() {
|
|||||||
config.load()
|
config.load()
|
||||||
|
|
||||||
val fxmlLoader = FXMLLoader()
|
val fxmlLoader = FXMLLoader()
|
||||||
fxmlLoader.resources = ResourceBundle.getBundle("i18n/willow", Locale.getDefault())
|
fxmlLoader.resources = ResourceBundle.getBundle("i18n/willow", config.locale.value)
|
||||||
fxmlLoader.controllerFactory = Callback { type ->
|
fxmlLoader.controllerFactory = Callback { type ->
|
||||||
when (type) {
|
when (type) {
|
||||||
MainController::class.java -> MainController(model)
|
MainController::class.java -> MainController(model)
|
||||||
MenuController::class.java -> MenuController(model, config)
|
MenuController::class.java -> MenuController(model, config)
|
||||||
DetailsController::class.java -> DetailsController(model, config)
|
DetailsController::class.java -> DetailsController(model, config)
|
||||||
SearchController::class.java -> SearchController(model)
|
SearchController::class.java -> SearchController(model)
|
||||||
ListController::class.java -> ListController(model)
|
SearchResultsController::class.java -> SearchResultsController(model, config)
|
||||||
else -> error("Trying to instantiate unknown controller type $type")
|
else -> error("Trying to instantiate unknown controller type $type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
146
src/main/kotlin/com/marvinelsen/willow/config/Config.kt
Normal file
146
src/main/kotlin/com/marvinelsen/willow/config/Config.kt
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
package com.marvinelsen.willow.config
|
||||||
|
|
||||||
|
import javafx.beans.property.BooleanProperty
|
||||||
|
import javafx.beans.property.IntegerProperty
|
||||||
|
import javafx.beans.property.ObjectProperty
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty
|
||||||
|
import javafx.beans.property.SimpleIntegerProperty
|
||||||
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
|
import java.util.Locale
|
||||||
|
import java.util.prefs.Preferences
|
||||||
|
|
||||||
|
class Config {
|
||||||
|
companion object {
|
||||||
|
private const val LOCALE_KEY = "locale"
|
||||||
|
private const val THEME_KEY = "theme"
|
||||||
|
private const val SCRIPT_KEY = "script"
|
||||||
|
private const val DETAIL_HEADWORD_FONT_SIZE_KEY = "detailHeadwordFontSize"
|
||||||
|
private const val DETAIL_PRONUNCIATION_FONT_SIZE_KEY = "detailPronunciationFontSize"
|
||||||
|
|
||||||
|
private const val DEFAULT_DETAIL_HEADWORD_FONT_SIZE = 40
|
||||||
|
private const val DEFAULT_DETAIL_PRONUNCIATION_FONT_SIZE = 16
|
||||||
|
private val DEFAULT_THEME = Theme.SYSTEM
|
||||||
|
private val DEFAULT_SCRIPT = Script.SIMPLIFIED
|
||||||
|
private val DEFAULT_LOCALE = Locale.ENGLISH
|
||||||
|
}
|
||||||
|
|
||||||
|
private val preferences = Preferences.userNodeForPackage(this::class.java)
|
||||||
|
val searchResults = SearchResultsConfig(preferences)
|
||||||
|
|
||||||
|
val locale: ObjectProperty<Locale> = SimpleObjectProperty(DEFAULT_LOCALE)
|
||||||
|
val theme: ObjectProperty<Theme> = SimpleObjectProperty(DEFAULT_THEME)
|
||||||
|
val script: ObjectProperty<Script> = SimpleObjectProperty(DEFAULT_SCRIPT)
|
||||||
|
val detailHeadwordFontSize: IntegerProperty = SimpleIntegerProperty(DEFAULT_DETAIL_HEADWORD_FONT_SIZE)
|
||||||
|
val detailPronunciationFontSize: IntegerProperty = SimpleIntegerProperty(DEFAULT_DETAIL_PRONUNCIATION_FONT_SIZE)
|
||||||
|
|
||||||
|
fun save() {
|
||||||
|
preferences.put(LOCALE_KEY, locale.value.toLanguageTag())
|
||||||
|
preferences.put(THEME_KEY, theme.value.name)
|
||||||
|
preferences.put(SCRIPT_KEY, script.value.name)
|
||||||
|
preferences.putInt(DETAIL_HEADWORD_FONT_SIZE_KEY, detailHeadwordFontSize.value)
|
||||||
|
preferences.putInt(DETAIL_PRONUNCIATION_FONT_SIZE_KEY, detailPronunciationFontSize.value)
|
||||||
|
|
||||||
|
searchResults.save()
|
||||||
|
|
||||||
|
preferences.flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun load() {
|
||||||
|
preferences.sync()
|
||||||
|
|
||||||
|
detailHeadwordFontSize.value = preferences.getInt(
|
||||||
|
DETAIL_HEADWORD_FONT_SIZE_KEY,
|
||||||
|
DEFAULT_DETAIL_HEADWORD_FONT_SIZE
|
||||||
|
)
|
||||||
|
|
||||||
|
detailPronunciationFontSize.value = preferences.getInt(
|
||||||
|
DETAIL_PRONUNCIATION_FONT_SIZE_KEY,
|
||||||
|
DEFAULT_DETAIL_PRONUNCIATION_FONT_SIZE
|
||||||
|
)
|
||||||
|
|
||||||
|
theme.value = Theme.valueOf(
|
||||||
|
preferences.get(
|
||||||
|
THEME_KEY,
|
||||||
|
DEFAULT_THEME.name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
script.value = Script.valueOf(
|
||||||
|
preferences.get(
|
||||||
|
SCRIPT_KEY,
|
||||||
|
DEFAULT_SCRIPT.name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
locale.value = Locale.forLanguageTag(preferences.get(LOCALE_KEY, DEFAULT_LOCALE.toLanguageTag()))
|
||||||
|
|
||||||
|
searchResults.load()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
|
detailHeadwordFontSize.value = DEFAULT_DETAIL_HEADWORD_FONT_SIZE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchResultsConfig(private val preferences: Preferences) {
|
||||||
|
companion object {
|
||||||
|
private const val PRONUNCIATION_KEY = "searchResultsPronunciation"
|
||||||
|
private const val HEADWORD_FONT_SIZE_KEY = "searchResultsHeadwordFontSize"
|
||||||
|
private const val PRONUNCIATION_FONT_SIZE_KEY = "searchResultsPronunciationFontSize"
|
||||||
|
private const val DEFINITION_FONT_SIZE_KEY = "searchResultsDefinitionFontSize"
|
||||||
|
private const val SHOULD_SHOW_PRONUNCIATION_KEY = "searchResultsShouldShowPronunciation"
|
||||||
|
private const val SHOULD_SHOW_DEFINITION_KEY = "searchResultsShouldShowDefinition"
|
||||||
|
|
||||||
|
private val DEFAULT_PRONUNCIATION = Pronunciation.PINYIN_WITH_TONE_MARKS
|
||||||
|
private const val DEFAULT_HEADWORD_FONT_SIZE = 20
|
||||||
|
private const val DEFAULT_PRONUNCIATION_FONT_SIZE = 14
|
||||||
|
private const val DEFAULT_DEFINITION_FONT_SIZE = 14
|
||||||
|
private const val DEFAULT_SHOULD_SHOW_PRONUNCIATION = true
|
||||||
|
private const val DEFAULT_SHOULD_SHOW_DEFINITION = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val pronunciation: ObjectProperty<Pronunciation> = SimpleObjectProperty(DEFAULT_PRONUNCIATION)
|
||||||
|
val headwordFontSize: IntegerProperty = SimpleIntegerProperty(DEFAULT_HEADWORD_FONT_SIZE)
|
||||||
|
val pronunciationFontSize: IntegerProperty = SimpleIntegerProperty(DEFAULT_PRONUNCIATION_FONT_SIZE)
|
||||||
|
val definitionFontSize: IntegerProperty = SimpleIntegerProperty(DEFAULT_DEFINITION_FONT_SIZE)
|
||||||
|
val shouldShowPronunciation: BooleanProperty = SimpleBooleanProperty(DEFAULT_SHOULD_SHOW_PRONUNCIATION)
|
||||||
|
val shouldShowDefinition: BooleanProperty = SimpleBooleanProperty(DEFAULT_SHOULD_SHOW_DEFINITION)
|
||||||
|
|
||||||
|
fun save() {
|
||||||
|
preferences.put(PRONUNCIATION_KEY, pronunciation.value.name)
|
||||||
|
preferences.putInt(HEADWORD_FONT_SIZE_KEY, headwordFontSize.value)
|
||||||
|
preferences.putInt(PRONUNCIATION_FONT_SIZE_KEY, pronunciationFontSize.value)
|
||||||
|
preferences.putInt(DEFINITION_FONT_SIZE_KEY, definitionFontSize.value)
|
||||||
|
preferences.putBoolean(SHOULD_SHOW_PRONUNCIATION_KEY, shouldShowPronunciation.value)
|
||||||
|
preferences.putBoolean(SHOULD_SHOW_DEFINITION_KEY, shouldShowDefinition.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun load() {
|
||||||
|
headwordFontSize.value = preferences.getInt(
|
||||||
|
HEADWORD_FONT_SIZE_KEY,
|
||||||
|
DEFAULT_HEADWORD_FONT_SIZE
|
||||||
|
)
|
||||||
|
pronunciationFontSize.value = preferences.getInt(
|
||||||
|
PRONUNCIATION_FONT_SIZE_KEY,
|
||||||
|
DEFAULT_PRONUNCIATION_FONT_SIZE
|
||||||
|
)
|
||||||
|
definitionFontSize.value = preferences.getInt(
|
||||||
|
DEFINITION_FONT_SIZE_KEY,
|
||||||
|
DEFAULT_DEFINITION_FONT_SIZE
|
||||||
|
)
|
||||||
|
shouldShowPronunciation.value = preferences.getBoolean(
|
||||||
|
SHOULD_SHOW_PRONUNCIATION_KEY,
|
||||||
|
DEFAULT_SHOULD_SHOW_PRONUNCIATION
|
||||||
|
)
|
||||||
|
shouldShowDefinition.value = preferences.getBoolean(
|
||||||
|
SHOULD_SHOW_DEFINITION_KEY,
|
||||||
|
DEFAULT_SHOULD_SHOW_DEFINITION
|
||||||
|
)
|
||||||
|
pronunciation.value = Pronunciation.valueOf(
|
||||||
|
preferences.get(
|
||||||
|
PRONUNCIATION_KEY,
|
||||||
|
DEFAULT_PRONUNCIATION.name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.marvinelsen.willow.config
|
||||||
|
|
||||||
|
enum class Pronunciation {
|
||||||
|
PINYIN_WITH_TONE_MARKS,
|
||||||
|
PINYIN_WITH_TONE_NUMBERS,
|
||||||
|
ZHUYIN
|
||||||
|
}
|
5
src/main/kotlin/com/marvinelsen/willow/config/Script.kt
Normal file
5
src/main/kotlin/com/marvinelsen/willow/config/Script.kt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package com.marvinelsen.willow.config
|
||||||
|
|
||||||
|
enum class Script {
|
||||||
|
SIMPLIFIED, TRADITIONAL
|
||||||
|
}
|
5
src/main/kotlin/com/marvinelsen/willow/config/Theme.kt
Normal file
5
src/main/kotlin/com/marvinelsen/willow/config/Theme.kt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package com.marvinelsen.willow.config
|
||||||
|
|
||||||
|
enum class Theme {
|
||||||
|
SYSTEM, LIGHT, DARK
|
||||||
|
}
|
@ -5,4 +5,5 @@ interface Dictionary {
|
|||||||
fun findWordsContaining(entry: DictionaryEntry): List<DictionaryEntry>
|
fun findWordsContaining(entry: DictionaryEntry): List<DictionaryEntry>
|
||||||
fun findSentencesContaining(entry: DictionaryEntry): List<DictionaryEntry>
|
fun findSentencesContaining(entry: DictionaryEntry): List<DictionaryEntry>
|
||||||
fun findCharacters(entry: DictionaryEntry): List<DictionaryEntry>
|
fun findCharacters(entry: DictionaryEntry): List<DictionaryEntry>
|
||||||
|
fun searchSegments(phrase: String): List<DictionaryEntry>
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
package com.marvinelsen.willow.domain
|
package com.marvinelsen.willow.domain
|
||||||
|
|
||||||
enum class SearchMode {
|
enum class SearchMode {
|
||||||
PINYIN, SIMPLIFIED, TRADITIONAL, ENGLISH
|
PINYIN, SIMPLIFIED, TRADITIONAL, ENGLISH, SEGMENTS
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
package com.marvinelsen.willow.domain
|
package com.marvinelsen.willow.domain
|
||||||
|
|
||||||
|
import com.github.houbb.segment.bs.SegmentBs
|
||||||
|
import com.github.houbb.segment.data.phrase.core.data.SegmentPhraseDatas
|
||||||
|
import com.github.houbb.segment.data.pos.core.data.SegmentPosDatas
|
||||||
|
import com.github.houbb.segment.support.format.impl.SegmentFormats
|
||||||
|
import com.github.houbb.segment.support.segment.impl.Segments
|
||||||
|
import com.github.houbb.segment.support.segment.mode.impl.SegmentModes
|
||||||
|
import com.github.houbb.segment.support.segment.result.impl.SegmentResultHandlers
|
||||||
|
import com.github.houbb.segment.support.tagging.pos.tag.impl.SegmentPosTaggings
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import java.sql.Connection
|
import java.sql.Connection
|
||||||
import java.sql.PreparedStatement
|
import java.sql.PreparedStatement
|
||||||
@ -8,6 +16,14 @@ import java.sql.ResultSet
|
|||||||
class SqliteDictionary(private val connection: Connection) : Dictionary {
|
class SqliteDictionary(private val connection: Connection) : Dictionary {
|
||||||
private val whitespaceRegex = """\s+""".toRegex()
|
private val whitespaceRegex = """\s+""".toRegex()
|
||||||
|
|
||||||
|
private val segmentBs = SegmentBs.newInstance()
|
||||||
|
.segment(Segments.defaults())
|
||||||
|
.segmentData(SegmentPhraseDatas.define())
|
||||||
|
.segmentMode(SegmentModes.dict())
|
||||||
|
.segmentFormat(SegmentFormats.chineseSimple())
|
||||||
|
.posTagging(SegmentPosTaggings.simple())
|
||||||
|
.posData(SegmentPosDatas.define())
|
||||||
|
|
||||||
private val searchSimplifiedPreparedStatement: PreparedStatement by lazy {
|
private val searchSimplifiedPreparedStatement: PreparedStatement by lazy {
|
||||||
connection.prepareStatement(
|
connection.prepareStatement(
|
||||||
"""
|
"""
|
||||||
@ -42,6 +58,14 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val searchSegments = """
|
||||||
|
WITH cte(id, segment) AS (VALUES ?)
|
||||||
|
SELECT cedict.traditional, simplified, pinyin_with_tone_marks, pinyin_with_tone_numbers, zhuyin, definitions
|
||||||
|
FROM cedict INNER JOIN cte
|
||||||
|
ON cte.segment = cedict.traditional OR cte.segment = cedict.simplified
|
||||||
|
ORDER BY cte.id
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
private val findWordsContaining: PreparedStatement by lazy {
|
private val findWordsContaining: PreparedStatement by lazy {
|
||||||
connection.prepareStatement(
|
connection.prepareStatement(
|
||||||
"""
|
"""
|
||||||
@ -63,6 +87,7 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
|||||||
SearchMode.PINYIN -> searchPinyin(query)
|
SearchMode.PINYIN -> searchPinyin(query)
|
||||||
SearchMode.SIMPLIFIED -> searchSimplified(query)
|
SearchMode.SIMPLIFIED -> searchSimplified(query)
|
||||||
SearchMode.TRADITIONAL -> searchTraditional(query)
|
SearchMode.TRADITIONAL -> searchTraditional(query)
|
||||||
|
SearchMode.SEGMENTS -> searchSegments(query)
|
||||||
SearchMode.ENGLISH -> TODO()
|
SearchMode.ENGLISH -> TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +116,20 @@ class SqliteDictionary(private val connection: Connection) : Dictionary {
|
|||||||
return resultSet.toListOfDictionaryEntries()
|
return resultSet.toListOfDictionaryEntries()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun searchSegments(phrase: String): List<DictionaryEntry> {
|
||||||
|
val segments = segmentBs.segment(phrase, SegmentResultHandlers.word())
|
||||||
|
|
||||||
|
val segmentsListString = segments
|
||||||
|
.mapIndexed { index, s -> "($index, '$s')" }
|
||||||
|
.joinToString(",")
|
||||||
|
|
||||||
|
val query = searchSegments.replace("?", segmentsListString)
|
||||||
|
|
||||||
|
val resultSet: ResultSet = connection.createStatement().executeQuery(query)
|
||||||
|
|
||||||
|
return resultSet.toListOfDictionaryEntries()
|
||||||
|
}
|
||||||
|
|
||||||
private fun searchSimplified(query: String): List<DictionaryEntry> {
|
private fun searchSimplified(query: String): List<DictionaryEntry> {
|
||||||
searchSimplifiedPreparedStatement.setString(1, "$query*")
|
searchSimplifiedPreparedStatement.setString(1, "$query*")
|
||||||
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
package com.marvinelsen.willow.ui
|
|
||||||
|
|
||||||
data class Configuration(
|
|
||||||
val preferredScript: Script = Script.SIMPLIFIED,
|
|
||||||
)
|
|
||||||
|
|
||||||
enum class Script {
|
|
||||||
SIMPLIFIED, TRADITIONAL
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Pronunciation {
|
|
||||||
PINYIN_WITH_TONE_MARKS,
|
|
||||||
PINYIN_WITH_TONE_NUMBERS,
|
|
||||||
ZHUYIN
|
|
||||||
}
|
|
@ -1,7 +1,11 @@
|
|||||||
package com.marvinelsen.willow.ui.cells
|
package com.marvinelsen.willow.ui.cells
|
||||||
|
|
||||||
|
import com.marvinelsen.willow.config.Config
|
||||||
|
import com.marvinelsen.willow.config.Pronunciation
|
||||||
|
import com.marvinelsen.willow.config.Script
|
||||||
import com.marvinelsen.willow.ui.DictionaryEntryFx
|
import com.marvinelsen.willow.ui.DictionaryEntryFx
|
||||||
import com.marvinelsen.willow.ui.util.createContextMenuForEntry
|
import com.marvinelsen.willow.ui.util.createContextMenuForEntry
|
||||||
|
import javafx.beans.binding.Bindings
|
||||||
import javafx.geometry.VPos
|
import javafx.geometry.VPos
|
||||||
import javafx.scene.control.Label
|
import javafx.scene.control.Label
|
||||||
import javafx.scene.control.ListCell
|
import javafx.scene.control.ListCell
|
||||||
@ -11,10 +15,10 @@ import javafx.scene.layout.VBox
|
|||||||
import javafx.util.Callback
|
import javafx.util.Callback
|
||||||
import java.util.ResourceBundle
|
import java.util.ResourceBundle
|
||||||
|
|
||||||
class DictionaryEntryCellFactory(private val resources: ResourceBundle) :
|
class DictionaryEntryCellFactory(private val resources: ResourceBundle, private val config: Config) :
|
||||||
Callback<ListView<DictionaryEntryFx?>, ListCell<DictionaryEntryFx?>> {
|
Callback<ListView<DictionaryEntryFx?>, ListCell<DictionaryEntryFx?>> {
|
||||||
override fun call(listView: ListView<DictionaryEntryFx?>): ListCell<DictionaryEntryFx?> {
|
override fun call(listView: ListView<DictionaryEntryFx?>): ListCell<DictionaryEntryFx?> {
|
||||||
val entryCell = EntryCell(resources)
|
val entryCell = EntryCell(resources, config)
|
||||||
entryCell.prefWidthProperty().bind(listView.widthProperty().subtract(CELL_PADDING))
|
entryCell.prefWidthProperty().bind(listView.widthProperty().subtract(CELL_PADDING))
|
||||||
return entryCell
|
return entryCell
|
||||||
}
|
}
|
||||||
@ -24,17 +28,43 @@ class DictionaryEntryCellFactory(private val resources: ResourceBundle) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class EntryCell(private val resources: ResourceBundle) : ListCell<DictionaryEntryFx?>() {
|
internal class EntryCell(private val resources: ResourceBundle, private val config: Config) :
|
||||||
|
ListCell<DictionaryEntryFx?>() {
|
||||||
private val labelHeadword = Label().apply {
|
private val labelHeadword = Label().apply {
|
||||||
styleClass.add("list-view-entry")
|
styleClass.add("headword")
|
||||||
|
styleProperty().bind(
|
||||||
|
Bindings.concat(
|
||||||
|
"-fx-font-size: ",
|
||||||
|
config.searchResults.headwordFontSize.asString(),
|
||||||
|
"px;"
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val labelDefinition = Label().apply {
|
private val labelDefinition = Label().apply {
|
||||||
styleClass.add("list-view-definition")
|
styleClass.add("definition")
|
||||||
|
styleProperty().bind(
|
||||||
|
Bindings.concat(
|
||||||
|
"-fx-font-size: ",
|
||||||
|
config.searchResults.definitionFontSize.asString(),
|
||||||
|
"px;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
visibleProperty().bind(config.searchResults.shouldShowDefinition)
|
||||||
|
managedProperty().bind(config.searchResults.shouldShowDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val labelPronunciation = Label().apply {
|
private val labelPronunciation = Label().apply {
|
||||||
styleClass.add("list-view-pronunciation")
|
styleClass.add("pronunciation")
|
||||||
|
styleProperty().bind(
|
||||||
|
Bindings.concat(
|
||||||
|
"-fx-font-size: ",
|
||||||
|
config.searchResults.pronunciationFontSize.asString(),
|
||||||
|
"px;"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
visibleProperty().bind(config.searchResults.shouldShowPronunciation)
|
||||||
|
managedProperty().bind(config.searchResults.shouldShowPronunciation)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val flowPane = FlowPane(labelHeadword, labelPronunciation).apply {
|
private val flowPane = FlowPane(labelHeadword, labelPronunciation).apply {
|
||||||
@ -42,7 +72,9 @@ internal class EntryCell(private val resources: ResourceBundle) : ListCell<Dicti
|
|||||||
rowValignment = VPos.BASELINE
|
rowValignment = VPos.BASELINE
|
||||||
}
|
}
|
||||||
|
|
||||||
private val root = VBox(flowPane, labelDefinition)
|
private val root = VBox(flowPane, labelDefinition).apply {
|
||||||
|
styleClass.add("search-result")
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
text = null
|
text = null
|
||||||
@ -54,8 +86,29 @@ internal class EntryCell(private val resources: ResourceBundle) : ListCell<Dicti
|
|||||||
graphic = null
|
graphic = null
|
||||||
contextMenu = null
|
contextMenu = null
|
||||||
} else {
|
} else {
|
||||||
labelHeadword.text = entry.traditionalProperty.value
|
labelHeadword.textProperty().bind(
|
||||||
labelPronunciation.text = entry.pinyinWithToneMarksProperty.value
|
Bindings.createStringBinding(
|
||||||
|
{
|
||||||
|
when (config.script.value!!) {
|
||||||
|
Script.SIMPLIFIED -> entry.simplifiedProperty.value
|
||||||
|
Script.TRADITIONAL -> entry.traditionalProperty.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
config.script
|
||||||
|
)
|
||||||
|
)
|
||||||
|
labelPronunciation.textProperty().bind(
|
||||||
|
Bindings.createStringBinding(
|
||||||
|
{
|
||||||
|
when (config.searchResults.pronunciation.value!!) {
|
||||||
|
Pronunciation.PINYIN_WITH_TONE_MARKS -> entry.pinyinWithToneMarksProperty.value
|
||||||
|
Pronunciation.PINYIN_WITH_TONE_NUMBERS -> entry.pinyinWithToneNumbersProperty.value
|
||||||
|
Pronunciation.ZHUYIN -> entry.zhuyinProperty.value
|
||||||
|
}
|
||||||
|
},
|
||||||
|
config.searchResults.pronunciation
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val definition = entry.definitions.joinToString(separator = " / ") { it.joinToString(separator = "; ") }
|
val definition = entry.definitions.joinToString(separator = " / ") { it.joinToString(separator = "; ") }
|
||||||
labelDefinition.text = definition
|
labelDefinition.text = definition
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package com.marvinelsen.willow.ui.controllers
|
package com.marvinelsen.willow.ui.controllers
|
||||||
|
|
||||||
import com.marvinelsen.willow.Config
|
|
||||||
import com.marvinelsen.willow.Model
|
import com.marvinelsen.willow.Model
|
||||||
|
import com.marvinelsen.willow.config.Config
|
||||||
|
import com.marvinelsen.willow.config.Script
|
||||||
import com.marvinelsen.willow.ui.DictionaryEntryFx
|
import com.marvinelsen.willow.ui.DictionaryEntryFx
|
||||||
import com.marvinelsen.willow.ui.cells.DictionaryEntryCellFactory
|
import com.marvinelsen.willow.ui.cells.DictionaryEntryCellFactory
|
||||||
import javafx.beans.binding.Bindings
|
import javafx.beans.binding.Bindings
|
||||||
@ -45,46 +46,14 @@ class DetailsController(private val model: Model, private val config: Config) {
|
|||||||
@FXML
|
@FXML
|
||||||
@Suppress("UnusedPrivateMember")
|
@Suppress("UnusedPrivateMember")
|
||||||
private fun initialize() {
|
private fun initialize() {
|
||||||
val headwordObjectBinding =
|
initializeLabelHeadword()
|
||||||
Bindings.createStringBinding({ model.selectedEntry.value?.traditionalProperty?.value }, model.selectedEntry)
|
initializeTabPaneDetails()
|
||||||
|
initializeListViewWords()
|
||||||
|
initializeWebViewDefinition()
|
||||||
|
|
||||||
labelHeadword.textProperty().bind(headwordObjectBinding)
|
model.selectedEntry.addListener { _, _, newEntry ->
|
||||||
labelHeadword
|
if (newEntry == null) return@addListener
|
||||||
.styleProperty()
|
|
||||||
.bind(
|
|
||||||
Bindings.concat(
|
|
||||||
"-fx-font-size: ",
|
|
||||||
config.detailHeadwordFontSize.asString(),
|
|
||||||
"px;"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
tabPaneDetails.disableProperty().bind(Bindings.isNull(model.selectedEntry))
|
|
||||||
|
|
||||||
listViewWords.cellFactory = DictionaryEntryCellFactory(resources)
|
|
||||||
listViewWords.items = model.wordsContaining
|
|
||||||
tabPaneDetails.selectionModel.selectedItemProperty().addListener { _, _, selectedTab ->
|
|
||||||
if (model.selectedEntry.value == null) return@addListener
|
|
||||||
|
|
||||||
when (selectedTab.id) {
|
|
||||||
"tabWords" -> {
|
|
||||||
model.findWords()
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
webViewDefinition.apply {
|
|
||||||
isContextMenuEnabled = false
|
|
||||||
engine.userStyleSheetLocation =
|
|
||||||
this::class.java.getResource("/css/definitions.css")!!.toExternalForm()
|
|
||||||
}
|
|
||||||
|
|
||||||
model.selectedEntry.addListener { _, _, newValue ->
|
|
||||||
if (newValue == null) {
|
|
||||||
return@addListener
|
|
||||||
}
|
|
||||||
when (tabPaneDetails.selectionModel.selectedItem.id) {
|
when (tabPaneDetails.selectionModel.selectedItem.id) {
|
||||||
"tabWords" -> {
|
"tabWords" -> {
|
||||||
model.findWords()
|
model.findWords()
|
||||||
@ -92,22 +61,71 @@ class DetailsController(private val model: Model, private val config: Config) {
|
|||||||
|
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
webViewDefinition.engine.loadContent(
|
webViewDefinition.engine.loadContent(newEntry.createCedictDefinitionHtml())
|
||||||
createHTML().html {
|
}
|
||||||
body {
|
}
|
||||||
h1 {
|
|
||||||
+"CC-CEDICT"
|
private fun initializeWebViewDefinition() {
|
||||||
}
|
webViewDefinition.apply {
|
||||||
ol {
|
engine.userStyleSheetLocation = this::class.java.getResource("/css/definitions.css")!!.toExternalForm()
|
||||||
for (definition in newValue.definitions) {
|
}
|
||||||
li {
|
}
|
||||||
+definition.joinToString(separator = "; ")
|
|
||||||
}
|
private fun initializeListViewWords() {
|
||||||
}
|
listViewWords.apply {
|
||||||
|
cellFactory = DictionaryEntryCellFactory(resources, config)
|
||||||
|
items = model.wordsContaining
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeTabPaneDetails() {
|
||||||
|
tabPaneDetails.apply {
|
||||||
|
disableProperty().bind(Bindings.isNull(model.selectedEntry))
|
||||||
|
|
||||||
|
selectionModel.selectedItemProperty().addListener { _, _, selectedTab ->
|
||||||
|
if (model.selectedEntry.value == null) return@addListener
|
||||||
|
|
||||||
|
when (selectedTab.id) {
|
||||||
|
"tabWords" -> {
|
||||||
|
model.findWords()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeLabelHeadword() {
|
||||||
|
labelHeadword.apply {
|
||||||
|
textProperty().bind(
|
||||||
|
Bindings.createStringBinding(
|
||||||
|
{
|
||||||
|
when (config.script.value!!) {
|
||||||
|
Script.SIMPLIFIED -> model.selectedEntry.value?.simplifiedProperty?.value
|
||||||
|
Script.TRADITIONAL -> model.selectedEntry.value?.traditionalProperty?.value
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
config.script,
|
||||||
|
model.selectedEntry
|
||||||
|
)
|
||||||
|
)
|
||||||
|
styleProperty().bind(Bindings.concat("-fx-font-size: ", config.detailHeadwordFontSize.asString(), "px;"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun DictionaryEntryFx.createCedictDefinitionHtml() = createHTML().html {
|
||||||
|
body {
|
||||||
|
h1 {
|
||||||
|
+"CC-CEDICT"
|
||||||
|
}
|
||||||
|
ol {
|
||||||
|
for (definition in this@createCedictDefinitionHtml.definitions) {
|
||||||
|
li {
|
||||||
|
+definition.joinToString(separator = "; ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.marvinelsen.willow.ui.controllers
|
package com.marvinelsen.willow.ui.controllers
|
||||||
|
|
||||||
import com.marvinelsen.willow.Config
|
|
||||||
import com.marvinelsen.willow.Model
|
import com.marvinelsen.willow.Model
|
||||||
|
import com.marvinelsen.willow.config.Config
|
||||||
import com.marvinelsen.willow.ui.dialogs.PreferencesDialog
|
import com.marvinelsen.willow.ui.dialogs.PreferencesDialog
|
||||||
import javafx.application.Platform
|
import javafx.application.Platform
|
||||||
import javafx.beans.binding.Bindings
|
import javafx.beans.binding.Bindings
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.marvinelsen.willow.ui.controllers
|
package com.marvinelsen.willow.ui.controllers
|
||||||
|
|
||||||
import com.marvinelsen.willow.Model
|
import com.marvinelsen.willow.Model
|
||||||
|
import com.marvinelsen.willow.config.Config
|
||||||
import com.marvinelsen.willow.ui.DictionaryEntryFx
|
import com.marvinelsen.willow.ui.DictionaryEntryFx
|
||||||
import com.marvinelsen.willow.ui.cells.DictionaryEntryCellFactory
|
import com.marvinelsen.willow.ui.cells.DictionaryEntryCellFactory
|
||||||
import javafx.beans.binding.Bindings
|
import javafx.beans.binding.Bindings
|
||||||
@ -10,7 +11,7 @@ import javafx.scene.control.ListView
|
|||||||
import javafx.scene.control.ProgressIndicator
|
import javafx.scene.control.ProgressIndicator
|
||||||
import java.util.ResourceBundle
|
import java.util.ResourceBundle
|
||||||
|
|
||||||
class ListController(private val model: Model) {
|
class SearchResultsController(private val model: Model, private val config: Config) {
|
||||||
@FXML
|
@FXML
|
||||||
private lateinit var resources: ResourceBundle
|
private lateinit var resources: ResourceBundle
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ class ListController(private val model: Model) {
|
|||||||
@FXML
|
@FXML
|
||||||
@Suppress("UnusedPrivateMember")
|
@Suppress("UnusedPrivateMember")
|
||||||
private fun initialize() {
|
private fun initialize() {
|
||||||
listViewSearchResults.cellFactory = DictionaryEntryCellFactory(resources)
|
listViewSearchResults.cellFactory = DictionaryEntryCellFactory(resources, config)
|
||||||
listViewSearchResults.items = model.searchResults
|
listViewSearchResults.items = model.searchResults
|
||||||
listViewSearchResults
|
listViewSearchResults
|
||||||
.disableProperty()
|
.disableProperty()
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.marvinelsen.willow.ui.converters
|
||||||
|
|
||||||
|
import javafx.util.StringConverter
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
class LocaleStringConverter : StringConverter<Locale>() {
|
||||||
|
override fun toString(locale: Locale): String = locale.displayName
|
||||||
|
override fun fromString(string: String) = null
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package com.marvinelsen.willow.ui.converters
|
package com.marvinelsen.willow.ui.converters
|
||||||
|
|
||||||
import com.marvinelsen.willow.ui.Pronunciation
|
import com.marvinelsen.willow.config.Pronunciation
|
||||||
import javafx.util.StringConverter
|
import javafx.util.StringConverter
|
||||||
|
|
||||||
class PronunciationStringConverter : StringConverter<Pronunciation>() {
|
class PronunciationStringConverter : StringConverter<Pronunciation>() {
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.marvinelsen.willow.ui.converters
|
||||||
|
|
||||||
|
import com.marvinelsen.willow.config.Script
|
||||||
|
import javafx.util.StringConverter
|
||||||
|
|
||||||
|
class ScriptStringConverter : StringConverter<Script>() {
|
||||||
|
override fun toString(script: Script): String = when (script) {
|
||||||
|
Script.SIMPLIFIED -> "Simplified"
|
||||||
|
Script.TRADITIONAL -> "Traditional"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromString(string: String) = null
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.marvinelsen.willow.ui.converters
|
||||||
|
|
||||||
|
import com.marvinelsen.willow.config.Theme
|
||||||
|
import javafx.util.StringConverter
|
||||||
|
|
||||||
|
class ThemeStringConverter : StringConverter<Theme>() {
|
||||||
|
override fun toString(theme: Theme): String = when (theme) {
|
||||||
|
Theme.SYSTEM -> "System"
|
||||||
|
Theme.LIGHT -> "Light"
|
||||||
|
Theme.DARK -> "Dark"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun fromString(string: String) = null
|
||||||
|
}
|
@ -1,9 +1,12 @@
|
|||||||
package com.marvinelsen.willow.ui.dialogs
|
package com.marvinelsen.willow.ui.dialogs
|
||||||
|
|
||||||
import com.marvinelsen.willow.Config
|
|
||||||
import com.marvinelsen.willow.WillowApplication
|
import com.marvinelsen.willow.WillowApplication
|
||||||
import com.marvinelsen.willow.ui.Pronunciation
|
import com.marvinelsen.willow.config.Config
|
||||||
|
import com.marvinelsen.willow.config.Pronunciation
|
||||||
|
import com.marvinelsen.willow.config.Script
|
||||||
|
import com.marvinelsen.willow.config.Theme
|
||||||
import com.marvinelsen.willow.ui.formatters.FontSizeTextFormatter
|
import com.marvinelsen.willow.ui.formatters.FontSizeTextFormatter
|
||||||
|
import javafx.fxml.FXML
|
||||||
import javafx.fxml.FXMLLoader
|
import javafx.fxml.FXMLLoader
|
||||||
import javafx.scene.control.ButtonType
|
import javafx.scene.control.ButtonType
|
||||||
import javafx.scene.control.CheckBox
|
import javafx.scene.control.CheckBox
|
||||||
@ -15,8 +18,8 @@ import javafx.stage.Modality
|
|||||||
import javafx.stage.Stage
|
import javafx.stage.Stage
|
||||||
import javafx.stage.Window
|
import javafx.stage.Window
|
||||||
import javafx.util.Callback
|
import javafx.util.Callback
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
|
||||||
class PreferencesDialog(owner: Window?, config: Config) : Dialog<PreferencesDialog.Result>() {
|
class PreferencesDialog(owner: Window?, config: Config) : Dialog<PreferencesDialog.Result>() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val DIALOG_MIN_HEIGHT = 400.0
|
private const val DIALOG_MIN_HEIGHT = 400.0
|
||||||
@ -27,22 +30,48 @@ class PreferencesDialog(owner: Window?, config: Config) : Dialog<PreferencesDial
|
|||||||
CHANGES, NO_CHANGES
|
CHANGES, NO_CHANGES
|
||||||
}
|
}
|
||||||
|
|
||||||
lateinit var comboBoxEntryPronunciation: ComboBox<Pronunciation>
|
@FXML
|
||||||
lateinit var comboBoxListPronunciation: ComboBox<Pronunciation>
|
private lateinit var comboBoxLocale: ComboBox<Locale>
|
||||||
|
|
||||||
lateinit var checkBoxListShowPronunciation: CheckBox
|
@FXML
|
||||||
lateinit var checkBoxListShowDefinition: CheckBox
|
private lateinit var comboBoxTheme: ComboBox<Theme>
|
||||||
|
|
||||||
lateinit var spinnerEntryHeadwordFontSize: Spinner<Int>
|
@FXML
|
||||||
lateinit var spinnerEntryPronunciationFontSize: Spinner<Int>
|
private lateinit var comboBoxScript: ComboBox<Script>
|
||||||
lateinit var spinnerListHeadwordFontSize: Spinner<Int>
|
|
||||||
lateinit var spinnerListPronunciationFontSize: Spinner<Int>
|
@FXML
|
||||||
lateinit var spinnerListDefinitionFontSize: Spinner<Int>
|
private lateinit var comboBoxPronunciationSearchResults: ComboBox<Pronunciation>
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private lateinit var checkBoxShowPronunciationSearchResults: CheckBox
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private lateinit var checkBoxShowDefinitionSearchResults: CheckBox
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private lateinit var spinnerHeadwordFontSizeDetails: Spinner<Int>
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private lateinit var spinnerPronunciationFontSizeDetails: Spinner<Int>
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private lateinit var spinnerHeadwordFontSizeSearchResults: Spinner<Int>
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private lateinit var spinnerPronunciationFontSizeSearchResults: Spinner<Int>
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private lateinit var spinnerDefinitionFontSizeSearchResults: Spinner<Int>
|
||||||
|
|
||||||
private val entryHeadwordFontSizeObjectProperty = config.detailHeadwordFontSize.asObject()
|
private val entryHeadwordFontSizeObjectProperty = config.detailHeadwordFontSize.asObject()
|
||||||
|
private val entryPronunciationFontSizeObjectProperty = config.detailPronunciationFontSize.asObject()
|
||||||
|
|
||||||
|
private val searchResultHeadwordFontSizeObjectProperty = config.searchResults.headwordFontSize.asObject()
|
||||||
|
private val searchResultPronunciationFontSizeObjectProperty = config.searchResults.pronunciationFontSize.asObject()
|
||||||
|
private val searchResultDefinitionFontSizeObjectProperty = config.searchResults.definitionFontSize.asObject()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val loader = FXMLLoader(WillowApplication::class.java.getResource("/fxml/preferences-dialog.fxml"))
|
val loader = FXMLLoader(WillowApplication::class.java.getResource("/fxml/dialogs/preferences.fxml"))
|
||||||
loader.setController(this)
|
loader.setController(this)
|
||||||
val root: DialogPane = loader.load()
|
val root: DialogPane = loader.load()
|
||||||
|
|
||||||
@ -58,11 +87,52 @@ class PreferencesDialog(owner: Window?, config: Config) : Dialog<PreferencesDial
|
|||||||
minHeight = DIALOG_MIN_HEIGHT
|
minHeight = DIALOG_MIN_HEIGHT
|
||||||
}
|
}
|
||||||
|
|
||||||
with(spinnerEntryHeadwordFontSize) {
|
comboBoxLocale.items.addAll(
|
||||||
|
setOf(
|
||||||
|
Locale.ENGLISH,
|
||||||
|
Locale.GERMAN,
|
||||||
|
Locale.CHINA,
|
||||||
|
Locale.TAIWAN
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
comboBoxTheme.valueProperty().bindBidirectional(config.theme)
|
||||||
|
comboBoxScript.valueProperty().bindBidirectional(config.script)
|
||||||
|
comboBoxLocale.valueProperty().bindBidirectional(config.locale)
|
||||||
|
comboBoxPronunciationSearchResults.valueProperty().bindBidirectional(config.searchResults.pronunciation)
|
||||||
|
|
||||||
|
checkBoxShowDefinitionSearchResults
|
||||||
|
.selectedProperty()
|
||||||
|
.bindBidirectional(config.searchResults.shouldShowDefinition)
|
||||||
|
checkBoxShowPronunciationSearchResults
|
||||||
|
.selectedProperty()
|
||||||
|
.bindBidirectional(config.searchResults.shouldShowPronunciation)
|
||||||
|
|
||||||
|
with(spinnerHeadwordFontSizeDetails) {
|
||||||
editor.textFormatter = FontSizeTextFormatter()
|
editor.textFormatter = FontSizeTextFormatter()
|
||||||
valueFactory.valueProperty().bindBidirectional(entryHeadwordFontSizeObjectProperty)
|
valueFactory.valueProperty().bindBidirectional(entryHeadwordFontSizeObjectProperty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
with(spinnerPronunciationFontSizeDetails) {
|
||||||
|
editor.textFormatter = FontSizeTextFormatter()
|
||||||
|
valueFactory.valueProperty().bindBidirectional(entryPronunciationFontSizeObjectProperty)
|
||||||
|
}
|
||||||
|
|
||||||
|
with(spinnerHeadwordFontSizeSearchResults) {
|
||||||
|
editor.textFormatter = FontSizeTextFormatter()
|
||||||
|
valueFactory.valueProperty().bindBidirectional(searchResultHeadwordFontSizeObjectProperty)
|
||||||
|
}
|
||||||
|
|
||||||
|
with(spinnerPronunciationFontSizeSearchResults) {
|
||||||
|
editor.textFormatter = FontSizeTextFormatter()
|
||||||
|
valueFactory.valueProperty().bindBidirectional(searchResultPronunciationFontSizeObjectProperty)
|
||||||
|
}
|
||||||
|
|
||||||
|
with(spinnerDefinitionFontSizeSearchResults) {
|
||||||
|
editor.textFormatter = FontSizeTextFormatter()
|
||||||
|
valueFactory.valueProperty().bindBidirectional(searchResultDefinitionFontSizeObjectProperty)
|
||||||
|
}
|
||||||
|
|
||||||
resultConverter = Callback(::convertToResult)
|
resultConverter = Callback(::convertToResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
src/main/resources/css/dark.css
Normal file
20
src/main/resources/css/dark.css
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
JavaFX CSS Reference Guide
|
||||||
|
https://openjfx.io/javadoc/23/javafx.graphics/javafx/scene/doc-files/cssref.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
.root {
|
||||||
|
willow-background: #2D2D30;
|
||||||
|
willow-foreground: #ffffff;
|
||||||
|
|
||||||
|
-fx-background-color: willow-background;
|
||||||
|
background-color: willow-background;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
-fx-text-fill: willow-foreground;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-button {
|
||||||
|
-fx-text-fill: willow-foreground;
|
||||||
|
}
|
@ -2,41 +2,6 @@
|
|||||||
-fx-font-family: "Inter Variable";
|
-fx-font-family: "Inter Variable";
|
||||||
}
|
}
|
||||||
|
|
||||||
.chinese {
|
.details-pronunciation {
|
||||||
-fx-font-family: "Noto Sans CJK TC";
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-view {
|
|
||||||
-fx-selection-bar: #B8EEFF;
|
|
||||||
/*-fx-selection-bar-non-focused: green;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-view-entry {
|
|
||||||
-fx-font-family: "Noto Sans TC";
|
|
||||||
-fx-font-size: 20;
|
|
||||||
-fx-font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-view-definition {
|
|
||||||
-fx-font-size: 14;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-view-pronunciation {
|
|
||||||
-fx-font-size: 14;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-view-sentence-cell {
|
|
||||||
-fx-font-size: 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
.moe-definition {
|
|
||||||
-fx-font-size: 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pronunciation {
|
|
||||||
-fx-font: 16 "Noto Sans TC";
|
-fx-font: 16 "Noto Sans TC";
|
||||||
}
|
}
|
||||||
|
|
||||||
.preferences-dialog .content {
|
|
||||||
-fx-padding: 0;
|
|
||||||
}
|
|
||||||
|
3
src/main/resources/css/preferences.css
Normal file
3
src/main/resources/css/preferences.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.preferences-dialog .content {
|
||||||
|
-fx-padding: 0;
|
||||||
|
}
|
17
src/main/resources/css/search-results.css
Normal file
17
src/main/resources/css/search-results.css
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
.list-view:focused .list-cell:filled:focused:selected .search-result {
|
||||||
|
/*-fx-text-fill: red;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.headword {
|
||||||
|
-fx-font-family: "Noto Sans TC";
|
||||||
|
-fx-font-weight: bold;
|
||||||
|
/*-fx-text-fill: inherit;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.pronunciation {
|
||||||
|
/*-fx-text-fill: inherit;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.definition {
|
||||||
|
/*-fx-text-fill: inherit;*/
|
||||||
|
}
|
@ -1,24 +1,73 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
<?import com.marvinelsen.willow.ui.converters.PronunciationStringConverter?>
|
<?import com.marvinelsen.willow.config.*?>
|
||||||
<?import com.marvinelsen.willow.ui.*?>
|
<?import com.marvinelsen.willow.ui.converters.*?>
|
||||||
<?import javafx.collections.FXCollections?>
|
<?import javafx.collections.FXCollections?>
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.*?>
|
<?import javafx.scene.control.*?>
|
||||||
<?import javafx.scene.layout.*?>
|
<?import javafx.scene.layout.*?>
|
||||||
<DialogPane styleClass="preferences-dialog" xmlns="http://javafx.com/javafx/23" xmlns:fx="http://javafx.com/fxml/1"
|
<DialogPane styleClass="preferences-dialog" xmlns="http://javafx.com/javafx/23" xmlns:fx="http://javafx.com/fxml/1"
|
||||||
stylesheets="/css/main.css">
|
stylesheets="/css/preferences.css">
|
||||||
<fx:define>
|
<fx:define>
|
||||||
<FXCollections fx:factory="observableArrayList" fx:id="phoneticAlphabets">
|
<FXCollections fx:factory="observableArrayList" fx:id="phoneticAlphabets">
|
||||||
<Pronunciation fx:value="PINYIN_WITH_TONE_MARKS"/>
|
<Pronunciation fx:value="PINYIN_WITH_TONE_MARKS"/>
|
||||||
<Pronunciation fx:value="PINYIN_WITH_TONE_NUMBERS"/>
|
<Pronunciation fx:value="PINYIN_WITH_TONE_NUMBERS"/>
|
||||||
<Pronunciation fx:value="ZHUYIN"/>
|
<Pronunciation fx:value="ZHUYIN"/>
|
||||||
</FXCollections>
|
</FXCollections>
|
||||||
|
<FXCollections fx:factory="observableArrayList" fx:id="themes">
|
||||||
|
<Theme fx:value="SYSTEM"/>
|
||||||
|
<Theme fx:value="LIGHT"/>
|
||||||
|
<Theme fx:value="DARK"/>
|
||||||
|
</FXCollections>
|
||||||
|
<FXCollections fx:factory="observableArrayList" fx:id="scripts">
|
||||||
|
<Script fx:value="SIMPLIFIED"/>
|
||||||
|
<Script fx:value="TRADITIONAL"/>
|
||||||
|
</FXCollections>
|
||||||
</fx:define>
|
</fx:define>
|
||||||
<content>
|
<content>
|
||||||
<TabPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
|
<TabPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
|
||||||
tabClosingPolicy="UNAVAILABLE">
|
tabClosingPolicy="UNAVAILABLE">
|
||||||
<Tab closable="false" text="Entry">
|
<Tab closable="false" text="General">
|
||||||
|
<GridPane alignment="TOP_CENTER" hgap="8.0" vgap="8.0">
|
||||||
|
<columnConstraints>
|
||||||
|
<ColumnConstraints halignment="RIGHT" hgrow="ALWAYS"/>
|
||||||
|
<ColumnConstraints halignment="LEFT" hgrow="ALWAYS"/>
|
||||||
|
</columnConstraints>
|
||||||
|
<rowConstraints>
|
||||||
|
<RowConstraints minHeight="10.0" prefHeight="30.0" valignment="BASELINE" vgrow="NEVER"/>
|
||||||
|
<RowConstraints minHeight="10.0" prefHeight="30.0" valignment="BASELINE" vgrow="NEVER"/>
|
||||||
|
</rowConstraints>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="12.0" left="12.0" right="12.0" top="12.0"/>
|
||||||
|
</padding>
|
||||||
|
<Label text="Script:" GridPane.rowIndex="3"/>
|
||||||
|
<ComboBox fx:id="comboBoxScript" items="$scripts" GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||||
|
<value>
|
||||||
|
<Script fx:value="SIMPLIFIED"/>
|
||||||
|
</value>
|
||||||
|
<converter>
|
||||||
|
<ScriptStringConverter/>
|
||||||
|
</converter>
|
||||||
|
</ComboBox>
|
||||||
|
<Separator prefWidth="200.0" GridPane.columnSpan="2147483647" GridPane.rowIndex="2"/>
|
||||||
|
<Label text="Language:" GridPane.rowIndex="0"/>
|
||||||
|
<ComboBox fx:id="comboBoxLocale" GridPane.rowIndex="0" GridPane.columnIndex="1">
|
||||||
|
<converter>
|
||||||
|
<LocaleStringConverter/>
|
||||||
|
</converter>
|
||||||
|
</ComboBox>
|
||||||
|
<Label text="Theme:" GridPane.rowIndex="1"/>
|
||||||
|
<ComboBox fx:id="comboBoxTheme" items="$themes" GridPane.rowIndex="1" GridPane.columnIndex="1">
|
||||||
|
<value>
|
||||||
|
<Theme fx:value="SYSTEM"/>
|
||||||
|
</value>
|
||||||
|
<converter>
|
||||||
|
<ThemeStringConverter/>
|
||||||
|
</converter>
|
||||||
|
</ComboBox>
|
||||||
|
</GridPane>
|
||||||
|
</Tab>
|
||||||
|
<Tab closable="false" text="Details View">
|
||||||
<GridPane alignment="TOP_CENTER" hgap="8.0" vgap="8.0">
|
<GridPane alignment="TOP_CENTER" hgap="8.0" vgap="8.0">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints halignment="RIGHT" hgrow="ALWAYS"/>
|
<ColumnConstraints halignment="RIGHT" hgrow="ALWAYS"/>
|
||||||
@ -34,7 +83,7 @@
|
|||||||
<Insets bottom="12.0" left="12.0" right="12.0" top="12.0"/>
|
<Insets bottom="12.0" left="12.0" right="12.0" top="12.0"/>
|
||||||
</padding>
|
</padding>
|
||||||
<Label text="Pronunciation:"/>
|
<Label text="Pronunciation:"/>
|
||||||
<ComboBox fx:id="comboBoxEntryPronunciation" GridPane.columnIndex="1">
|
<ComboBox fx:id="comboBoxPronunciationDetails" items="$phoneticAlphabets" GridPane.columnIndex="1">
|
||||||
<value>
|
<value>
|
||||||
<Pronunciation fx:value="PINYIN_WITH_TONE_MARKS"/>
|
<Pronunciation fx:value="PINYIN_WITH_TONE_MARKS"/>
|
||||||
</value>
|
</value>
|
||||||
@ -44,13 +93,13 @@
|
|||||||
</ComboBox>
|
</ComboBox>
|
||||||
<Label text="Headword font size:" GridPane.rowIndex="2"/>
|
<Label text="Headword font size:" GridPane.rowIndex="2"/>
|
||||||
<Label text="Pronunciation font size:" GridPane.rowIndex="3"/>
|
<Label text="Pronunciation font size:" GridPane.rowIndex="3"/>
|
||||||
<Spinner fx:id="spinnerEntryPronunciationFontSize" editable="true" GridPane.columnIndex="1"
|
<Spinner fx:id="spinnerPronunciationFontSizeDetails" editable="true" GridPane.columnIndex="1"
|
||||||
GridPane.rowIndex="3">
|
GridPane.rowIndex="3">
|
||||||
<valueFactory>
|
<valueFactory>
|
||||||
<SpinnerValueFactory.IntegerSpinnerValueFactory amountToStepBy="1" max="300" min="1"/>
|
<SpinnerValueFactory.IntegerSpinnerValueFactory amountToStepBy="1" max="300" min="1"/>
|
||||||
</valueFactory>
|
</valueFactory>
|
||||||
</Spinner>
|
</Spinner>
|
||||||
<Spinner fx:id="spinnerEntryHeadwordFontSize" editable="true" GridPane.columnIndex="1"
|
<Spinner fx:id="spinnerHeadwordFontSizeDetails" editable="true" GridPane.columnIndex="1"
|
||||||
GridPane.rowIndex="2">
|
GridPane.rowIndex="2">
|
||||||
<valueFactory>
|
<valueFactory>
|
||||||
<SpinnerValueFactory.IntegerSpinnerValueFactory amountToStepBy="1" max="300" min="1"/>
|
<SpinnerValueFactory.IntegerSpinnerValueFactory amountToStepBy="1" max="300" min="1"/>
|
||||||
@ -59,7 +108,7 @@
|
|||||||
<Separator prefWidth="200.0" GridPane.columnSpan="2147483647" GridPane.rowIndex="1"/>
|
<Separator prefWidth="200.0" GridPane.columnSpan="2147483647" GridPane.rowIndex="1"/>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab closable="false" text="List">
|
<Tab closable="false" text="Search Results">
|
||||||
<GridPane alignment="TOP_CENTER" hgap="8.0" vgap="8.0">
|
<GridPane alignment="TOP_CENTER" hgap="8.0" vgap="8.0">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
<ColumnConstraints halignment="RIGHT" hgrow="ALWAYS"/>
|
<ColumnConstraints halignment="RIGHT" hgrow="ALWAYS"/>
|
||||||
@ -79,7 +128,8 @@
|
|||||||
<Insets bottom="12.0" left="12.0" right="12.0" top="12.0"/>
|
<Insets bottom="12.0" left="12.0" right="12.0" top="12.0"/>
|
||||||
</padding>
|
</padding>
|
||||||
<Label text="Pronunciation:"/>
|
<Label text="Pronunciation:"/>
|
||||||
<ComboBox fx:id="comboBoxListPronunciation" GridPane.columnIndex="1">
|
<ComboBox fx:id="comboBoxPronunciationSearchResults" items="$phoneticAlphabets"
|
||||||
|
GridPane.columnIndex="1">
|
||||||
<value>
|
<value>
|
||||||
<Pronunciation fx:value="PINYIN_WITH_TONE_MARKS"/>
|
<Pronunciation fx:value="PINYIN_WITH_TONE_MARKS"/>
|
||||||
</value>
|
</value>
|
||||||
@ -89,19 +139,19 @@
|
|||||||
</ComboBox>
|
</ComboBox>
|
||||||
<Label text="Headword font size:" GridPane.rowIndex="5"/>
|
<Label text="Headword font size:" GridPane.rowIndex="5"/>
|
||||||
<Label text="Pronunciation font size:" GridPane.rowIndex="6"/>
|
<Label text="Pronunciation font size:" GridPane.rowIndex="6"/>
|
||||||
<Spinner fx:id="spinnerListPronunciationFontSize" editable="true" GridPane.columnIndex="1"
|
<Spinner fx:id="spinnerPronunciationFontSizeSearchResults" editable="true" GridPane.columnIndex="1"
|
||||||
GridPane.rowIndex="6">
|
GridPane.rowIndex="6">
|
||||||
<valueFactory>
|
<valueFactory>
|
||||||
<SpinnerValueFactory.IntegerSpinnerValueFactory amountToStepBy="1" max="300" min="1"/>
|
<SpinnerValueFactory.IntegerSpinnerValueFactory amountToStepBy="1" max="300" min="1"/>
|
||||||
</valueFactory>
|
</valueFactory>
|
||||||
</Spinner>
|
</Spinner>
|
||||||
<Spinner fx:id="spinnerListHeadwordFontSize" editable="true" GridPane.columnIndex="1"
|
<Spinner fx:id="spinnerHeadwordFontSizeSearchResults" editable="true" GridPane.columnIndex="1"
|
||||||
GridPane.rowIndex="5">
|
GridPane.rowIndex="5">
|
||||||
<valueFactory>
|
<valueFactory>
|
||||||
<SpinnerValueFactory.IntegerSpinnerValueFactory amountToStepBy="1" max="300" min="1"/>
|
<SpinnerValueFactory.IntegerSpinnerValueFactory amountToStepBy="1" max="300" min="1"/>
|
||||||
</valueFactory>
|
</valueFactory>
|
||||||
</Spinner>
|
</Spinner>
|
||||||
<Spinner fx:id="spinnerListDefinitionFontSize" editable="true" GridPane.columnIndex="1"
|
<Spinner fx:id="spinnerDefinitionFontSizeSearchResults" editable="true" GridPane.columnIndex="1"
|
||||||
GridPane.rowIndex="7">
|
GridPane.rowIndex="7">
|
||||||
<valueFactory>
|
<valueFactory>
|
||||||
<SpinnerValueFactory.IntegerSpinnerValueFactory amountToStepBy="1" max="300" min="1"/>
|
<SpinnerValueFactory.IntegerSpinnerValueFactory amountToStepBy="1" max="300" min="1"/>
|
||||||
@ -110,9 +160,9 @@
|
|||||||
<Separator prefWidth="200.0" GridPane.columnSpan="2147483647" GridPane.rowIndex="4"/>
|
<Separator prefWidth="200.0" GridPane.columnSpan="2147483647" GridPane.rowIndex="4"/>
|
||||||
<Label text="Definition font size:" GridPane.rowIndex="7"/>
|
<Label text="Definition font size:" GridPane.rowIndex="7"/>
|
||||||
<Label text="Display:" GridPane.rowIndex="2"/>
|
<Label text="Display:" GridPane.rowIndex="2"/>
|
||||||
<CheckBox fx:id="checkBoxListShowPronunciation" mnemonicParsing="false" selected="true"
|
<CheckBox fx:id="checkBoxShowPronunciationSearchResults" mnemonicParsing="false" selected="true"
|
||||||
text="Show pronunciation" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
|
text="Show pronunciation" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
|
||||||
<CheckBox fx:id="checkBoxListShowDefinition" mnemonicParsing="false" selected="true"
|
<CheckBox fx:id="checkBoxShowDefinitionSearchResults" mnemonicParsing="false" selected="true"
|
||||||
text="Show definition" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
|
text="Show definition" GridPane.columnIndex="1" GridPane.rowIndex="3"/>
|
||||||
<Separator prefWidth="200.0" GridPane.columnSpan="2147483647" GridPane.rowIndex="1"/>
|
<Separator prefWidth="200.0" GridPane.columnSpan="2147483647" GridPane.rowIndex="1"/>
|
||||||
</GridPane>
|
</GridPane>
|
@ -16,7 +16,7 @@
|
|||||||
</BorderPane.margin>
|
</BorderPane.margin>
|
||||||
<fx:include source="/fxml/search.fxml"/>
|
<fx:include source="/fxml/search.fxml"/>
|
||||||
<SplitPane dividerPositions="0.33" VBox.vgrow="ALWAYS">
|
<SplitPane dividerPositions="0.33" VBox.vgrow="ALWAYS">
|
||||||
<fx:include source="/fxml/list.fxml"/>
|
<fx:include source="/fxml/search-results.fxml"/>
|
||||||
<fx:include source="/fxml/details.fxml"/>
|
<fx:include source="/fxml/details.fxml"/>
|
||||||
</SplitPane>
|
</SplitPane>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<?import javafx.scene.control.ProgressIndicator?>
|
<?import javafx.scene.control.ProgressIndicator?>
|
||||||
<?import javafx.scene.layout.StackPane?>
|
<?import javafx.scene.layout.StackPane?>
|
||||||
<StackPane xmlns="http://javafx.com/javafx/23" xmlns:fx="http://javafx.com/fxml/1"
|
<StackPane xmlns="http://javafx.com/javafx/23" xmlns:fx="http://javafx.com/fxml/1"
|
||||||
fx:controller="com.marvinelsen.willow.ui.controllers.ListController"
|
fx:controller="com.marvinelsen.willow.ui.controllers.SearchResultsController"
|
||||||
stylesheets="/css/main.css">
|
stylesheets="/css/search-results.css">
|
||||||
<ListView fx:id="listViewSearchResults" disable="true"/>
|
<ListView fx:id="listViewSearchResults" disable="true"/>
|
||||||
<Label fx:id="labelNoEntriesFound" text="%list.no_entries_found" textAlignment="CENTER"
|
<Label fx:id="labelNoEntriesFound" text="%list.no_entries_found" textAlignment="CENTER"
|
||||||
visible="false" wrapText="true">
|
visible="false" wrapText="true">
|
@ -30,6 +30,12 @@
|
|||||||
<SearchMode fx:value="PINYIN"/>
|
<SearchMode fx:value="PINYIN"/>
|
||||||
</userData>
|
</userData>
|
||||||
</RadioButton>
|
</RadioButton>
|
||||||
|
<RadioButton mnemonicParsing="false" text="%search.mode.phrase"
|
||||||
|
toggleGroup="$searchModeToggleGroup">
|
||||||
|
<userData>
|
||||||
|
<SearchMode fx:value="SEGMENTS"/>
|
||||||
|
</userData>
|
||||||
|
</RadioButton>
|
||||||
<RadioButton mnemonicParsing="false" text="%search.mode.english"
|
<RadioButton mnemonicParsing="false" text="%search.mode.english"
|
||||||
toggleGroup="$searchModeToggleGroup"
|
toggleGroup="$searchModeToggleGroup"
|
||||||
disable="true">
|
disable="true">
|
||||||
|
@ -17,3 +17,4 @@ menubar.edit.copy.pronunciation=Copy Pronunciation
|
|||||||
menubar.help=_Help
|
menubar.help=_Help
|
||||||
menubar.help.about=_About…
|
menubar.help.about=_About…
|
||||||
list.no_entries_found=No matching entries found
|
list.no_entries_found=No matching entries found
|
||||||
|
search.mode.phrase=Phrase
|
||||||
|
@ -17,3 +17,4 @@ menubar.edit.copy.pronunciation=Kopiere Aussprache
|
|||||||
menubar.help=_Hilfe
|
menubar.help=_Hilfe
|
||||||
menubar.help.about=_Über…
|
menubar.help.about=_Über…
|
||||||
list.no_entries_found=No matching entries found
|
list.no_entries_found=No matching entries found
|
||||||
|
search.mode.phrase=Phrase
|
||||||
|
@ -17,3 +17,4 @@ menubar.edit.copy.pronunciation=Copy Pronunciation
|
|||||||
menubar.help=_Help
|
menubar.help=_Help
|
||||||
menubar.help.about=_About…
|
menubar.help.about=_About…
|
||||||
list.no_entries_found=No matching entries found
|
list.no_entries_found=No matching entries found
|
||||||
|
search.mode.phrase=Phrase
|
||||||
|
@ -17,3 +17,4 @@ menubar.edit.copy.pronunciation=複製 Aussprache
|
|||||||
menubar.help=_說明
|
menubar.help=_說明
|
||||||
menubar.help.about=_關於 Willow…
|
menubar.help.about=_關於 Willow…
|
||||||
list.no_entries_found=No matching entries found
|
list.no_entries_found=No matching entries found
|
||||||
|
search.mode.phrase=Phrase
|
||||||
|
@ -17,3 +17,4 @@ menubar.edit.copy.pronunciation=複製 Aussprache
|
|||||||
menubar.help=_說明
|
menubar.help=_說明
|
||||||
menubar.help.about=_關於 Willow…
|
menubar.help.about=_關於 Willow…
|
||||||
list.no_entries_found=No matching entries found
|
list.no_entries_found=No matching entries found
|
||||||
|
search.mode.phrase=Phrase
|
||||||
|
119393
src/main/resources/segment_phrase_dict_define.txt
Normal file
119393
src/main/resources/segment_phrase_dict_define.txt
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user