Skip to content
This repository has been archived by the owner on Jun 17, 2023. It is now read-only.

Commit

Permalink
新增功能:
Browse files Browse the repository at this point in the history
  1. 增加熟悉词库
  2. 增加过滤 BNC 和 COCA 词频前 1000 的单词
修复:
  1. 生成词库时,先用鼠标单击单词的右上角的删除按钮,再点击左边的过滤区过滤单词,手动选择删除的单词会再次出现(#76)。
  • Loading branch information
tangshimin committed Aug 5, 2022
1 parent 45ba023 commit 2ad4c15
Show file tree
Hide file tree
Showing 6 changed files with 641 additions and 57 deletions.
9 changes: 9 additions & 0 deletions src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,9 @@ private fun FrameWindowScope.WindowMenuBar(
Item("过滤词库(F)", mnemonic = 'F', onClick = {
state.filterVocabulary = true
})
Item("导入词库到熟悉词库(I)", mnemonic = 'F', onClick = {
state.importFamiliarVocabulary = true
})
Separator()
Item("从文档生成词库(D)", mnemonic = 'D', onClick = {
state.generateVocabularyFromDocument = true
Expand Down Expand Up @@ -615,6 +618,12 @@ fun MenuDialogs(state: AppState) {
type = VocabularyType.DOCUMENT
)
}
if (state.importFamiliarVocabulary) {
FamiliarDialog(
futureFileChooser = state.futureFileChooser,
close = { state.importFamiliarVocabulary = false }
)
}
if (state.generateVocabularyFromDocument) {
GenerateVocabularyDialog(
state = state,
Expand Down
24 changes: 17 additions & 7 deletions src/main/kotlin/data/Vocabulary.kt
Original file line number Diff line number Diff line change
Expand Up @@ -200,31 +200,34 @@ fun loadVocabulary(path: String): Vocabulary {
}

}
/** 主要加载困难词库和熟悉词库 */
fun loadMutableVocabularyByName(name: String):MutableVocabulary{
val file = if (name == "FamiliarVocabulary") {
getFamiliarVocabularyFile()
} else getHardVocabularyFile()

fun loadHardMutableVocabulary():MutableVocabulary{
val hardFile = getHardVocabularyFile()
return if (hardFile.exists()) {
return if (file.exists()) {
try {
val vocabulary = Json.decodeFromString<Vocabulary>(hardFile.readText())
val vocabulary = Json.decodeFromString<Vocabulary>(file.readText())
MutableVocabulary(vocabulary)
} catch (exception: Exception) {
exception.printStackTrace()
val vocabulary = Vocabulary(
name = "HardVocabulary",
name = name,
type = VocabularyType.DOCUMENT,
language = "",
size = 0,
relateVideoPath = "",
subtitlesTrackId = 0,
wordList = mutableListOf()
)
JOptionPane.showMessageDialog(null, "词库解析错误:\n地址:${hardFile.absoluteFile}\n" + exception.message)
JOptionPane.showMessageDialog(null, "词库解析错误:\n地址:${file.absoluteFile}\n" + exception.message)
MutableVocabulary(vocabulary)
}

} else {
val vocabulary = Vocabulary(
name = "HardVocabulary",
name = name,
type = VocabularyType.DOCUMENT,
language = "",
size = 0,
Expand All @@ -235,6 +238,13 @@ fun loadHardMutableVocabulary():MutableVocabulary{
MutableVocabulary(vocabulary)
}}


/** 返回熟悉词库文件 */
fun getFamiliarVocabularyFile():File{
val settingsDir = getSettingsDirectory()
return File(settingsDir, "FamiliarVocabulary.json")
}
/** 返回困难词库文件 */
fun getHardVocabularyFile():File{
val settingsDir = getSettingsDirectory()
return File(settingsDir, "HardVocabulary.json")
Expand Down
196 changes: 196 additions & 0 deletions src/main/kotlin/dialog/FamiliarDialog.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package dialog

import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.rememberDialogState
import components.createTransferHandler
import data.*
import java.io.File
import java.util.concurrent.FutureTask
import javax.swing.JFileChooser
import javax.swing.JOptionPane
import javax.swing.filechooser.FileNameExtensionFilter
import javax.swing.filechooser.FileSystemView

/**
* 导入词库到熟悉词库
*/
@Composable
fun FamiliarDialog(
futureFileChooser: FutureTask<JFileChooser>,
close: () -> Unit
){
Dialog(
title = "导入词库到熟悉词库",
icon = painterResource("logo/logo.png"),
onCloseRequest = { close() },
resizable = false,
state = rememberDialogState(
position = WindowPosition(Alignment.Center),
size = DpSize(600.dp, 600.dp)
),
) {
var importing by remember { mutableStateOf(false) }
var processingFile by remember { mutableStateOf("") }

/** 熟悉词库 */
val familiarVocabulary = loadMutableVocabularyByName("FamiliarVocabulary")

/** 导入词库 */
val import:(List<File>) -> Unit = {files ->
if(files.size>100){
JOptionPane.showMessageDialog(null,"一次最多导入 100 个词库")
}else{
files.forEach { file ->
processingFile = file.nameWithoutExtension
val vocabulary = loadVocabulary(file.absolutePath)
vocabulary.wordList.forEach { word ->
val index = familiarVocabulary.wordList.indexOf(word)
// wordList 没有这个单词
if (index == -1) {
// 如果是视频词库或字幕词库,需要把字幕变成外部字幕
if (word.captions.isNotEmpty()) {
word.captions.forEach { caption ->
// 创建一条外部字幕
val externalCaption = ExternalCaption(
relateVideoPath = vocabulary.relateVideoPath,
subtitlesTrackId = vocabulary.subtitlesTrackId,
subtitlesName = vocabulary.name,
start = caption.start,
end = caption.end,
content = caption.content
)
word.externalCaptions.add(externalCaption)
}
word.captions.clear()
}
familiarVocabulary.wordList.add(word)
// wordList 有这个单词
} else {
val oldWord = familiarVocabulary.wordList[index]
// 如果单词有外部字幕,同时已经加入到列表的单词的外部字幕没有超过3个就导入
if (word.externalCaptions.isNotEmpty()) {
word.externalCaptions.forEach { externalCaption ->
if (oldWord.externalCaptions.size < 3) {
oldWord.externalCaptions.add(externalCaption)
}
}
// 如果单词是视频或字幕词库中的单词
} else if (word.captions.isNotEmpty()) {
word.captions.forEach { caption ->
// 创建一条外部字幕
val externalCaption = ExternalCaption(
relateVideoPath = vocabulary.relateVideoPath,
subtitlesTrackId = vocabulary.subtitlesTrackId,
subtitlesName = vocabulary.name,
start = caption.start,
end = caption.end,
content = caption.content
)
if (oldWord.externalCaptions.size < 3) {
oldWord.externalCaptions.add(externalCaption)
}
}
}

}
}
}

familiarVocabulary.size = familiarVocabulary.wordList.size
val familiarFile = getFamiliarVocabularyFile()
saveVocabulary(familiarVocabulary.serializeVocabulary, familiarFile.absolutePath)
importing = false
}
}

/** 打开文件对话框 */
val openFileChooser:()-> Unit = {
Thread(Runnable {
val fileChooser = futureFileChooser.get()
fileChooser.dialogTitle = "选择词库"
fileChooser.fileSystemView = FileSystemView.getFileSystemView()
fileChooser.fileSelectionMode = JFileChooser.FILES_ONLY
fileChooser.isAcceptAllFileFilterUsed = false
fileChooser.isMultiSelectionEnabled = true
val fileFilter = FileNameExtensionFilter("词库", "json")
fileChooser.addChoosableFileFilter(fileFilter)
fileChooser.selectedFile = null
if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
val files = fileChooser.selectedFiles.toList()
importing = true
import(files)
}
fileChooser.selectedFile = null
fileChooser.isMultiSelectionEnabled = false
fileChooser.removeChoosableFileFilter(fileFilter)
}).start()
}

/** 处理拖放文件的函数 */
val transferHandler = createTransferHandler(
singleFile = false,
showWrongMessage = { message ->
JOptionPane.showMessageDialog(window, message)
},
parseImportFile = { files ->
Thread(Runnable {
importing = true
import(files)
}).start()
}
)
window.transferHandler = transferHandler

Surface(
elevation = 5.dp,
shape = RectangleShape,
) {
Box{
Divider(Modifier.align(Alignment.TopCenter))

Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxSize()
){
Text("熟悉词库现在有 ${familiarVocabulary.wordList.size} 个单词",
modifier = Modifier.padding(bottom = if(importing) 90.dp else 20.dp))
if (importing) {
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth().padding(bottom = 20.dp)
) {
Text(text = "正在读取 $processingFile")
}
}
Row{
OutlinedButton(
onClick = { openFileChooser() },
){
Text("导入")
}
Spacer(Modifier.width(20.dp))
OutlinedButton(
onClick = { close() },
){
Text("关闭")
}
}
}
if (importing) {
CircularProgressIndicator(Modifier.align(Alignment.Center).padding(bottom = 70.dp))
}
}
}
}
}
Loading

0 comments on commit 2ad4c15

Please sign in to comment.