New Features #1
@ -8,6 +8,7 @@ import com.marvinelsen.willow.ui.controllers.MenuController
|
||||
import com.marvinelsen.willow.ui.controllers.SearchController
|
||||
import com.marvinelsen.willow.ui.controllers.SearchResultsController
|
||||
import javafx.application.Application
|
||||
import javafx.application.HostServices
|
||||
import javafx.fxml.FXMLLoader
|
||||
import javafx.scene.Scene
|
||||
import javafx.scene.image.Image
|
||||
@ -46,15 +47,17 @@ class WillowApplication : Application() {
|
||||
val config = Config()
|
||||
config.load()
|
||||
|
||||
val hostServices: HostServices = hostServices
|
||||
|
||||
val fxmlLoader = FXMLLoader()
|
||||
fxmlLoader.resources = ResourceBundle.getBundle("i18n/willow", config.locale.value)
|
||||
fxmlLoader.controllerFactory = Callback { type ->
|
||||
when (type) {
|
||||
MainController::class.java -> MainController(model)
|
||||
MenuController::class.java -> MenuController(model, config)
|
||||
DetailsController::class.java -> DetailsController(model, config)
|
||||
DetailsController::class.java -> DetailsController(model, config, hostServices)
|
||||
SearchController::class.java -> SearchController(model)
|
||||
SearchResultsController::class.java -> SearchResultsController(model, config)
|
||||
SearchResultsController::class.java -> SearchResultsController(model, config, hostServices)
|
||||
else -> error("Trying to instantiate unknown controller type $type")
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import com.marvinelsen.willow.config.Pronunciation
|
||||
import com.marvinelsen.willow.config.Script
|
||||
import com.marvinelsen.willow.ui.DictionaryEntryFx
|
||||
import com.marvinelsen.willow.ui.util.createContextMenuForEntry
|
||||
import javafx.application.HostServices
|
||||
import javafx.beans.binding.Bindings
|
||||
import javafx.geometry.VPos
|
||||
import javafx.scene.control.Label
|
||||
@ -18,10 +19,11 @@ import java.util.ResourceBundle
|
||||
class DictionaryEntryCellFactory(
|
||||
private val resources: ResourceBundle,
|
||||
private val config: Config,
|
||||
private val hostServices: HostServices,
|
||||
) : Callback<ListView<DictionaryEntryFx?>, ListCell<DictionaryEntryFx?>> {
|
||||
|
||||
override fun call(listView: ListView<DictionaryEntryFx?>): ListCell<DictionaryEntryFx?> {
|
||||
val entryCell = EntryCell(resources, config)
|
||||
val entryCell = EntryCell(resources, config, hostServices)
|
||||
entryCell.prefWidthProperty().bind(listView.widthProperty().subtract(CELL_PADDING))
|
||||
return entryCell
|
||||
}
|
||||
@ -34,6 +36,7 @@ class DictionaryEntryCellFactory(
|
||||
private class EntryCell(
|
||||
private val resources: ResourceBundle,
|
||||
private val config: Config,
|
||||
private val hostServices: HostServices,
|
||||
) : ListCell<DictionaryEntryFx?>() {
|
||||
|
||||
private val labelHeadword = Label().apply {
|
||||
@ -133,7 +136,7 @@ private class EntryCell(
|
||||
}
|
||||
labelDefinition.text = definition
|
||||
|
||||
contextMenu = createContextMenuForEntry(entry, resources)
|
||||
contextMenu = createContextMenuForEntry(entry, resources, hostServices)
|
||||
graphic = root
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.marvinelsen.willow.config.Config
|
||||
import com.marvinelsen.willow.config.Script
|
||||
import com.marvinelsen.willow.ui.SentenceFx
|
||||
import com.marvinelsen.willow.ui.util.createContextMenuForSentence
|
||||
import javafx.application.HostServices
|
||||
import javafx.beans.binding.Bindings
|
||||
import javafx.scene.control.Label
|
||||
import javafx.scene.control.ListCell
|
||||
@ -15,10 +16,11 @@ import java.util.ResourceBundle
|
||||
class SentenceCellFactory(
|
||||
private val resources: ResourceBundle,
|
||||
private val config: Config,
|
||||
private val hostServices: HostServices,
|
||||
) : Callback<ListView<SentenceFx?>, ListCell<SentenceFx?>> {
|
||||
|
||||
override fun call(listView: ListView<SentenceFx?>): ListCell<SentenceFx?> {
|
||||
val sentenceCell = SentenceCell(resources, config)
|
||||
val sentenceCell = SentenceCell(resources, config, hostServices)
|
||||
sentenceCell.prefWidthProperty().bind(listView.widthProperty().subtract(CELL_PADDING))
|
||||
return sentenceCell
|
||||
}
|
||||
@ -31,6 +33,7 @@ class SentenceCellFactory(
|
||||
private class SentenceCell(
|
||||
private val resources: ResourceBundle,
|
||||
private val config: Config,
|
||||
private val hostServices: HostServices,
|
||||
) : ListCell<SentenceFx?>() {
|
||||
|
||||
private val labelSentence = Label().apply {
|
||||
@ -60,7 +63,7 @@ private class SentenceCell(
|
||||
)
|
||||
)
|
||||
|
||||
contextMenu = createContextMenuForSentence(sentence, resources)
|
||||
contextMenu = createContextMenuForSentence(sentence, resources, hostServices)
|
||||
graphic = root
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import com.marvinelsen.willow.ui.SentenceFx
|
||||
import com.marvinelsen.willow.ui.cells.DictionaryEntryCellFactory
|
||||
import com.marvinelsen.willow.ui.cells.SentenceCellFactory
|
||||
import com.marvinelsen.willow.ui.util.createContextMenuForEntry
|
||||
import javafx.application.HostServices
|
||||
import javafx.beans.binding.Bindings
|
||||
import javafx.fxml.FXML
|
||||
import javafx.scene.control.Label
|
||||
@ -31,7 +32,12 @@ import kotlinx.html.stream.createHTML
|
||||
import java.util.ResourceBundle
|
||||
|
||||
@Suppress("UnusedPrivateMember", "TooManyFunctions")
|
||||
class DetailsController(private val model: Model, private val config: Config) {
|
||||
class DetailsController(
|
||||
private val model: Model,
|
||||
private val config: Config,
|
||||
private val hostServices: HostServices,
|
||||
) {
|
||||
|
||||
@FXML
|
||||
private lateinit var resources: ResourceBundle
|
||||
|
||||
@ -192,7 +198,7 @@ class DetailsController(private val model: Model, private val config: Config) {
|
||||
|
||||
private fun initializeListViewSentences() {
|
||||
listViewSentences.apply {
|
||||
cellFactory = SentenceCellFactory(resources, config)
|
||||
cellFactory = SentenceCellFactory(resources, config, hostServices)
|
||||
items = model.sentences
|
||||
|
||||
disableProperty().bind(Bindings.or(model.isFindingSentences, Bindings.isEmpty(model.sentences)))
|
||||
@ -205,7 +211,7 @@ class DetailsController(private val model: Model, private val config: Config) {
|
||||
|
||||
private fun initializeListViewWordsContaining() {
|
||||
listViewWordsContaining.apply {
|
||||
cellFactory = DictionaryEntryCellFactory(resources, config)
|
||||
cellFactory = DictionaryEntryCellFactory(resources, config, hostServices)
|
||||
items = model.wordsContaining
|
||||
|
||||
disableProperty().bind(Bindings.or(model.isFindingWordsContaining, Bindings.isEmpty(model.wordsContaining)))
|
||||
@ -218,7 +224,7 @@ class DetailsController(private val model: Model, private val config: Config) {
|
||||
|
||||
private fun initializeListViewWordsBeginning() {
|
||||
listViewWordsBeginning.apply {
|
||||
cellFactory = DictionaryEntryCellFactory(resources, config)
|
||||
cellFactory = DictionaryEntryCellFactory(resources, config, hostServices)
|
||||
items = model.wordsBeginning
|
||||
|
||||
disableProperty().bind(Bindings.or(model.isFindingWordsBeginning, Bindings.isEmpty(model.wordsBeginning)))
|
||||
@ -231,7 +237,7 @@ class DetailsController(private val model: Model, private val config: Config) {
|
||||
|
||||
private fun initializeListViewCharacters() {
|
||||
listViewCharacters.apply {
|
||||
cellFactory = DictionaryEntryCellFactory(resources, config)
|
||||
cellFactory = DictionaryEntryCellFactory(resources, config, hostServices)
|
||||
items = model.characters
|
||||
|
||||
disableProperty().bind(Bindings.or(model.isFindingCharacters, Bindings.isEmpty(model.characters)))
|
||||
@ -258,7 +264,7 @@ class DetailsController(private val model: Model, private val config: Config) {
|
||||
private fun headerOnContextMenuRequested(contextMenuEvent: ContextMenuEvent) {
|
||||
if (model.selectedEntry.value == null) return
|
||||
|
||||
createContextMenuForEntry(model.selectedEntry.value, resources).show(
|
||||
createContextMenuForEntry(model.selectedEntry.value, resources, hostServices).show(
|
||||
flowPaneHeader.scene.window,
|
||||
contextMenuEvent.screenX,
|
||||
contextMenuEvent.screenY
|
||||
|
@ -4,6 +4,7 @@ import com.marvinelsen.willow.Model
|
||||
import com.marvinelsen.willow.config.Config
|
||||
import com.marvinelsen.willow.ui.DictionaryEntryFx
|
||||
import com.marvinelsen.willow.ui.cells.DictionaryEntryCellFactory
|
||||
import javafx.application.HostServices
|
||||
import javafx.beans.binding.Bindings
|
||||
import javafx.fxml.FXML
|
||||
import javafx.scene.control.Label
|
||||
@ -11,7 +12,12 @@ import javafx.scene.control.ListView
|
||||
import javafx.scene.control.ProgressIndicator
|
||||
import java.util.ResourceBundle
|
||||
|
||||
class SearchResultsController(private val model: Model, private val config: Config) {
|
||||
class SearchResultsController(
|
||||
private val model: Model,
|
||||
private val config: Config,
|
||||
private val hostServices: HostServices,
|
||||
) {
|
||||
|
||||
@FXML
|
||||
private lateinit var resources: ResourceBundle
|
||||
|
||||
@ -28,7 +34,7 @@ class SearchResultsController(private val model: Model, private val config: Conf
|
||||
@FXML
|
||||
@Suppress("UnusedPrivateMember")
|
||||
private fun initialize() {
|
||||
listViewSearchResults.cellFactory = DictionaryEntryCellFactory(resources, config)
|
||||
listViewSearchResults.cellFactory = DictionaryEntryCellFactory(resources, config, hostServices)
|
||||
listViewSearchResults.items = model.searchResults
|
||||
listViewSearchResults
|
||||
.disableProperty()
|
||||
|
@ -2,12 +2,19 @@ package com.marvinelsen.willow.ui.util
|
||||
|
||||
import com.marvinelsen.willow.ui.DictionaryEntryFx
|
||||
import com.marvinelsen.willow.ui.SentenceFx
|
||||
import javafx.application.HostServices
|
||||
import javafx.event.EventHandler
|
||||
import javafx.scene.control.ContextMenu
|
||||
import javafx.scene.control.MenuItem
|
||||
import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.ResourceBundle
|
||||
|
||||
fun createContextMenuForEntry(entry: DictionaryEntryFx, resourceBundle: ResourceBundle) = ContextMenu().apply {
|
||||
fun createContextMenuForEntry(
|
||||
entry: DictionaryEntryFx,
|
||||
resourceBundle: ResourceBundle,
|
||||
hostServices: HostServices,
|
||||
) = ContextMenu().apply {
|
||||
val menuItemCopyHeadword =
|
||||
MenuItem(resourceBundle.getString("menubar.edit.copy.headword")).apply {
|
||||
onAction = EventHandler { ClipboardHelper.copyString(entry.traditionalProperty.value) }
|
||||
@ -18,14 +25,34 @@ fun createContextMenuForEntry(entry: DictionaryEntryFx, resourceBundle: Resource
|
||||
onAction = EventHandler { ClipboardHelper.copyString(entry.pinyinWithToneMarksProperty.value) }
|
||||
}
|
||||
|
||||
items.addAll(menuItemCopyHeadword, menuItemCopyPronunciation)
|
||||
val menuItemSearchOnWeb =
|
||||
MenuItem(resourceBundle.getString("menubar.edit.search-web")).apply {
|
||||
onAction = EventHandler {
|
||||
val query = URLEncoder.encode(entry.traditionalProperty.value, StandardCharsets.UTF_8)
|
||||
hostServices.showDocument("https://duckduckgo.com/?q=$query")
|
||||
}
|
||||
}
|
||||
|
||||
items.addAll(menuItemCopyHeadword, menuItemCopyPronunciation, menuItemSearchOnWeb)
|
||||
}
|
||||
|
||||
fun createContextMenuForSentence(sentence: SentenceFx, resourceBundle: ResourceBundle) = ContextMenu().apply {
|
||||
fun createContextMenuForSentence(
|
||||
sentence: SentenceFx,
|
||||
resourceBundle: ResourceBundle,
|
||||
hostServices: HostServices,
|
||||
) = ContextMenu().apply {
|
||||
val menuItemCopySentence =
|
||||
MenuItem(resourceBundle.getString("menubar.edit.copy.sentence")).apply {
|
||||
onAction = EventHandler { ClipboardHelper.copyString(sentence.traditionalProperty.value) }
|
||||
}
|
||||
|
||||
items.addAll(menuItemCopySentence)
|
||||
val menuItemSearchOnWeb =
|
||||
MenuItem(resourceBundle.getString("menubar.edit.search-web")).apply {
|
||||
onAction = EventHandler {
|
||||
val query = URLEncoder.encode(sentence.traditionalProperty.value, StandardCharsets.UTF_8)
|
||||
hostServices.showDocument("https://duckduckgo.com/?q=$query")
|
||||
}
|
||||
}
|
||||
|
||||
items.addAll(menuItemCopySentence, menuItemSearchOnWeb)
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ menubar.edit=_Edit
|
||||
menubar.edit.copy.headword=Copy Headword
|
||||
menubar.edit.copy.pronunciation=Copy Pronunciation
|
||||
menubar.edit.copy.sentence=Copy Sentence
|
||||
menubar.edit.search-web=Search on Web...
|
||||
menubar.help=_Help
|
||||
menubar.help.about=_About…
|
||||
|
||||
|
@ -26,6 +26,7 @@ menubar.edit=_Bearbeiten
|
||||
menubar.edit.copy.headword=Kopiere Wort
|
||||
menubar.edit.copy.pronunciation=Kopiere Aussprache
|
||||
menubar.edit.copy.sentence=Copy Sentence
|
||||
menubar.edit.search-web=Search on Web...
|
||||
menubar.help=_Hilfe
|
||||
menubar.help.about=_Über…
|
||||
|
||||
|
@ -26,6 +26,7 @@ menubar.edit=_Edit
|
||||
menubar.edit.copy.headword=Copy Headword
|
||||
menubar.edit.copy.pronunciation=Copy Pronunciation
|
||||
menubar.edit.copy.sentence=Copy Sentence
|
||||
menubar.edit.search-web=Search on Web...
|
||||
menubar.help=_Help
|
||||
menubar.help.about=_About…
|
||||
|
||||
|
@ -26,6 +26,7 @@ menubar.edit=_編輯
|
||||
menubar.edit.copy.headword=複製 Wort
|
||||
menubar.edit.copy.pronunciation=複製 Aussprache
|
||||
menubar.edit.copy.sentence=Copy Sentence
|
||||
menubar.edit.search-web=Search on Web...
|
||||
menubar.help=_說明
|
||||
menubar.help.about=_關於 Willow…
|
||||
|
||||
|
@ -26,6 +26,7 @@ menubar.edit=_編輯
|
||||
menubar.edit.copy.headword=複製 Wort
|
||||
menubar.edit.copy.pronunciation=複製 Aussprache
|
||||
menubar.edit.copy.sentence=Copy Sentence
|
||||
menubar.edit.search-web=Search on Web...
|
||||
menubar.help=_說明
|
||||
menubar.help.about=_關於 Willow…
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user