Merge remote-tracking branch 'origin/main'
# Conflicts: # src/main/kotlin/main/Main.ktmain
commit
69dd7abaa7
|
@ -20,7 +20,7 @@ import java.io.IOException
|
|||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun formPage(onCancelClick: () -> Unit) {
|
||||
fun formPage(glossary: Glossary, onCancelClick: () -> Unit) {
|
||||
// State to track whether to show the snackbar
|
||||
val requiredFieldsSnackbarVisibleState = remember { mutableStateOf(false) }
|
||||
val alreadyExistSnackbarVisibleState = remember { mutableStateOf(false) }
|
||||
|
@ -172,7 +172,7 @@ fun formPage(onCancelClick: () -> Unit) {
|
|||
return@Button
|
||||
}
|
||||
|
||||
val wordsList = loadDatasFromFile().toMutableList()
|
||||
val wordsList = loadDatasFromFile(glossary.jsonFilePath).toMutableList()
|
||||
|
||||
// Transform name to lowercase to avoid duplicates
|
||||
name.value = name.value.lowercase()
|
||||
|
@ -194,7 +194,7 @@ fun formPage(onCancelClick: () -> Unit) {
|
|||
antonym = antonym.value
|
||||
)
|
||||
|
||||
addWordToGlossary(newWord)
|
||||
addWordToGlossary(glossary.jsonFilePath, newWord)
|
||||
openDialog.value = true
|
||||
|
||||
},
|
||||
|
@ -267,8 +267,8 @@ fun resetFields(
|
|||
antonym.value = ""
|
||||
}
|
||||
|
||||
fun addWordToGlossary(newWord: Word) {
|
||||
val wordsList = loadDatasFromFile().toMutableList()
|
||||
fun addWordToGlossary(filePath: String, newWord: Word) {
|
||||
val wordsList = loadDatasFromFile(filePath).toMutableList()
|
||||
|
||||
// Verify if the word already exists in the glossary
|
||||
if (wordsList.any { it.name.equals(newWord.name, ignoreCase = true) }) {
|
||||
|
@ -278,28 +278,28 @@ fun addWordToGlossary(newWord: Word) {
|
|||
|
||||
// Add the new word to the glossary
|
||||
wordsList.add(newWord)
|
||||
saveDatasInFile(wordsList)
|
||||
saveDatasInFile(filePath, wordsList)
|
||||
|
||||
println("Mot ajouté avec succès : ${newWord.name}")
|
||||
}
|
||||
|
||||
fun saveDatasInFile(listeWords: List<Word>) {
|
||||
fun saveDatasInFile(filePath: String, listeWords: List<Word>) {
|
||||
val json = Json { prettyPrint = true }
|
||||
try {
|
||||
val content = json.encodeToString(listeWords)
|
||||
File("glossaire.json").writeText(content)
|
||||
File(filePath).writeText(content)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun loadDatasFromFile(): List<Word> {
|
||||
fun loadDatasFromFile(filePath: String): List<Word> {
|
||||
// If file is empty, return empty list
|
||||
if (!File("glossaire.json").exists() || File("glossaire.json").length() == 0L) {
|
||||
if (!File(filePath).exists() || File(filePath).length() == 0L) {
|
||||
return emptyList()
|
||||
}
|
||||
return try {
|
||||
val content = File("glossaire.json").readText()
|
||||
val content = File(filePath).readText()
|
||||
Json.decodeFromString<List<Word>>(content)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
|
|
|
@ -5,7 +5,7 @@ import androidx.compose.material.Button
|
|||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
@ -20,6 +20,9 @@ import java.io.FileInputStream
|
|||
import java.io.FileWriter
|
||||
import java.io.IOException
|
||||
|
||||
data class Glossary(val name: String, val jsonFilePath: String)
|
||||
|
||||
|
||||
@Composable
|
||||
fun glossaryPage(
|
||||
languageManager: LanguageManager,
|
||||
|
@ -27,9 +30,11 @@ fun glossaryPage(
|
|||
onImportClick: () -> Unit,
|
||||
onExportClick: () -> Unit,
|
||||
onSeeGlossaryClick: () -> Unit,
|
||||
onBackClick: () -> Unit
|
||||
onBackClick: () -> Unit,
|
||||
selectedGlossary: Glossary
|
||||
) {
|
||||
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Top, // Align content at the top
|
||||
|
@ -139,8 +144,8 @@ fun selectFile(extensions: Set<String>, onFileSelected: (String) -> Unit) {
|
|||
}
|
||||
}
|
||||
|
||||
fun exportToCSV(csvFilePath: String) {
|
||||
val glossary = loadDatasFromFile()
|
||||
fun exportToCSV(glossary: Glossary, csvFilePath: String) {
|
||||
val glossary = loadDatasFromFile(glossary.jsonFilePath)
|
||||
val csvContent = buildString {
|
||||
appendLine("Mot;Description;Contexte principal;Contexte 2;Lié à;Synonyme;Antonyme;")
|
||||
glossary.forEach { entry ->
|
||||
|
@ -159,16 +164,16 @@ fun exportToCSV(csvFilePath: String) {
|
|||
}
|
||||
}
|
||||
|
||||
fun importFile(filePath: String) {
|
||||
fun importFile(glossary: Glossary, filePath: String) {
|
||||
val fileExtension = File(filePath).extension.lowercase()
|
||||
|
||||
when (fileExtension) {
|
||||
"csv" -> {
|
||||
importCSVFile(filePath)
|
||||
importCSVFile(glossary, filePath)
|
||||
}
|
||||
|
||||
"xlsx" -> {
|
||||
importXLSXFile(filePath)
|
||||
importXLSXFile(glossary, filePath)
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
@ -177,7 +182,7 @@ fun importFile(filePath: String) {
|
|||
}
|
||||
}
|
||||
|
||||
fun importCSVFile(filePath: String) {
|
||||
fun importCSVFile(glossary : Glossary, filePath: String) {
|
||||
val file = File(filePath).readText(Charsets.UTF_8)
|
||||
|
||||
val lines = file.split("\n")
|
||||
|
@ -212,12 +217,12 @@ fun importCSVFile(filePath: String) {
|
|||
if (!verifyRequiredFields(mot)) {
|
||||
return
|
||||
}
|
||||
addWordToGlossary(nouveauWord)
|
||||
addWordToGlossary(glossary.jsonFilePath, nouveauWord)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun importXLSXFile(cheminFichier: String) {
|
||||
private fun importXLSXFile(glossary: Glossary, cheminFichier: String) {
|
||||
val workbook: Workbook
|
||||
try {
|
||||
FileInputStream(cheminFichier).use { fileInputStream ->
|
||||
|
@ -266,7 +271,7 @@ private fun importXLSXFile(cheminFichier: String) {
|
|||
)
|
||||
|
||||
if (newWord.name.isNotBlank() && verifyRequiredFields(line)) {
|
||||
addWordToGlossary(newWord)
|
||||
addWordToGlossary(glossary.jsonFilePath, newWord)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ fun homePage(
|
|||
if (isCompareClicked) {
|
||||
println(mostUsedWordList.keys.toList())
|
||||
compareResults(
|
||||
glossaryWords = loadDatasFromFile(),
|
||||
glossaryWords = loadDatasFromFile("glossaire.json"),
|
||||
codeWords = mostUsedWordList.keys.toList(),
|
||||
onBackClick = { isCompareClicked = false }
|
||||
)
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
package main
|
||||
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.*
|
||||
import java.awt.FileDialog
|
||||
import java.awt.Frame
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
val customRedColor = Color(0xFFB70D1B)
|
||||
|
||||
|
@ -17,30 +23,187 @@ val customRedColor = Color(0xFFB70D1B)
|
|||
@Composable
|
||||
@Preview
|
||||
fun app() {
|
||||
val languageManager = LanguageManager()
|
||||
MaterialTheme {
|
||||
val currentPage = remember { mutableStateOf("accueil") }
|
||||
|
||||
var glossaryDetail: List<Word> by remember { mutableStateOf(emptyList()) }
|
||||
var isJavaScriptFileSelected by remember { mutableStateOf(false) }
|
||||
|
||||
var glossaries by remember { mutableStateOf(emptyList<Glossary>()) }
|
||||
|
||||
var selectedGlossary by remember { mutableStateOf<Glossary?>(null) }
|
||||
|
||||
val isEmptySnackbarVisibleState = remember { mutableStateOf(false) }
|
||||
val containsSpaceSnackbarVisibleState = remember { mutableStateOf(false) }
|
||||
val glossaryAlreadyExistsSnackbarVisibleState = remember { mutableStateOf(false) }
|
||||
|
||||
|
||||
|
||||
//Récupérer tous les glossaires à la racine du projet et les ajouter à la liste glossaries
|
||||
glossaries = loadGlossaries()
|
||||
|
||||
|
||||
when (currentPage.value) {
|
||||
"accueil" -> {
|
||||
homePage(
|
||||
languageManager,
|
||||
onGlossaryClick = { currentPage.value = "glossaire" },
|
||||
onGlossaryClick = { currentPage.value = "glossaires" },
|
||||
onCodeToVerifyClick = { currentPage.value = "choixLangage" }
|
||||
)
|
||||
}
|
||||
|
||||
"glossaire" -> {
|
||||
"glossaires" -> {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text("Sélectionnez un glossaire", style = MaterialTheme.typography.h5)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier.padding(10.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||
) {
|
||||
items(glossaries) { glossary ->
|
||||
Button(
|
||||
onClick = {
|
||||
selectedGlossary = glossary
|
||||
currentPage.value = "glossaireOptions"
|
||||
},
|
||||
modifier = Modifier
|
||||
.width(200.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = customRedColor,
|
||||
contentColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text(glossary.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
currentPage.value = "nouveauGlossaire"
|
||||
},
|
||||
modifier = Modifier
|
||||
.width(300.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = customRedColor,
|
||||
contentColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text("Créer un nouveau glossaire")
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
currentPage.value = "accueil"
|
||||
},
|
||||
modifier = Modifier
|
||||
.width(250.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = customRedColor,
|
||||
contentColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text("Retour")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nouvelle page pour créer un nouveau glossaire
|
||||
"nouveauGlossaire" -> {
|
||||
var nouveauGlossaireName by remember { mutableStateOf("") }
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
TextField(
|
||||
value = nouveauGlossaireName,
|
||||
onValueChange = { nouveauGlossaireName = it },
|
||||
label = { Text("Nom du nouveau glossaire") },
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.fillMaxWidth(),
|
||||
colors = TextFieldDefaults.textFieldColors(
|
||||
backgroundColor = Color.White,
|
||||
focusedIndicatorColor = customRedColor,
|
||||
unfocusedIndicatorColor = Color.Gray
|
||||
)
|
||||
)
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
// Ajouter le code pour créer un nouveau glossaire avec le nom saisi
|
||||
//first check if the name is not empty, if there is space or if the name already exists
|
||||
if (nouveauGlossaireName.isEmpty()) {
|
||||
println("Veuillez saisir un nom pour le nouveau glossaire")
|
||||
isEmptySnackbarVisibleState.value = true
|
||||
return@Button
|
||||
}
|
||||
if (nouveauGlossaireName.contains(" ")) {
|
||||
println("Le nom du glossaire ne doit pas contenir d'espace")
|
||||
containsSpaceSnackbarVisibleState.value = true
|
||||
return@Button
|
||||
}
|
||||
glossaries.forEach { glossary ->
|
||||
nouveauGlossaireName = nouveauGlossaireName.lowercase(Locale.getDefault())
|
||||
if (glossary.name == nouveauGlossaireName) {
|
||||
println("Le nom du glossaire existe déjà")
|
||||
glossaryAlreadyExistsSnackbarVisibleState.value = true
|
||||
return@Button
|
||||
}
|
||||
}
|
||||
val newGlossary = Glossary(nouveauGlossaireName, "$nouveauGlossaireName.json")
|
||||
glossaries = glossaries + newGlossary
|
||||
//create new json file
|
||||
val newFile = File(newGlossary.jsonFilePath)
|
||||
newFile.createNewFile()
|
||||
//update glossaries list
|
||||
glossaries = loadGlossaries()
|
||||
currentPage.value = "glossaires" // Revenir à la liste des glossaires
|
||||
},
|
||||
modifier = Modifier
|
||||
.width(200.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = customRedColor,
|
||||
contentColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text("Créer")
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
currentPage.value = "glossaires"
|
||||
},
|
||||
modifier = Modifier
|
||||
.width(200.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = customRedColor,
|
||||
contentColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text("Annuler")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"glossaireOptions" -> {
|
||||
glossaryPage(
|
||||
languageManager,
|
||||
onAddWordClick = { currentPage.value = "formulaire" },
|
||||
onImportClick = {
|
||||
selectFile(setOf("csv", "xlsx")) { filePath ->
|
||||
println("Importing file: $filePath")
|
||||
importFile(filePath)
|
||||
selectedGlossary?.let { importFile(it, filePath) }
|
||||
}
|
||||
},
|
||||
onExportClick = {
|
||||
|
@ -52,27 +215,28 @@ fun app() {
|
|||
if (selectedFile != null) {
|
||||
val csvFilePath = "$selectedDirectory$selectedFile"
|
||||
println("Exporting to: $csvFilePath")
|
||||
exportToCSV(csvFilePath)
|
||||
selectedGlossary?.let { exportToCSV(it, csvFilePath) }
|
||||
} else {
|
||||
println("Export command cancelled by user.")
|
||||
}
|
||||
},
|
||||
onSeeGlossaryClick = {
|
||||
glossaryDetail = loadDatasFromFile()
|
||||
glossaryDetail = selectedGlossary?.let { loadDatasFromFile(it.jsonFilePath) }!!
|
||||
currentPage.value = "glossaireDetail"
|
||||
},
|
||||
onBackClick = { currentPage.value = "accueil" }
|
||||
onBackClick = { currentPage.value = "glossaires" },
|
||||
selectedGlossary = selectedGlossary!!
|
||||
)
|
||||
}
|
||||
"glossaireDetail" -> {
|
||||
glossaryDetailedPage(
|
||||
glossary = glossaryDetail,
|
||||
onBackClick = { currentPage.value = "glossaire" }
|
||||
onBackClick = { currentPage.value = "glossaireOptions" }
|
||||
)
|
||||
}
|
||||
|
||||
"formulaire" -> {
|
||||
formPage(onCancelClick = { currentPage.value = "glossaire" })
|
||||
selectedGlossary?.let { formPage(it, onCancelClick = { currentPage.value = "glossaireOptions" }) }
|
||||
}
|
||||
|
||||
"choixLangage" -> {
|
||||
|
@ -80,7 +244,6 @@ fun app() {
|
|||
val javaExtensions = setOf("java")
|
||||
val jsExtensions = setOf("js", "html")
|
||||
choixLangagePage(
|
||||
languageManager,
|
||||
onBackClick = { currentPage.value = "accueil" },
|
||||
onPythonClick = {
|
||||
selectFile(pythonExtensions) { filePath ->
|
||||
|
@ -130,8 +293,77 @@ fun app() {
|
|||
}
|
||||
)
|
||||
}
|
||||
if (isEmptySnackbarVisibleState.value) {
|
||||
Snackbar(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
action = {
|
||||
Button(
|
||||
onClick = { isEmptySnackbarVisibleState.value = false },
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = customRedColor,
|
||||
contentColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text("OK")
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text("Veuillez entrer un nom de glossaire.")
|
||||
}
|
||||
}
|
||||
if (containsSpaceSnackbarVisibleState.value) {
|
||||
Snackbar(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
action = {
|
||||
Button(
|
||||
onClick = { containsSpaceSnackbarVisibleState.value = false },
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = customRedColor,
|
||||
contentColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text("OK")
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text("Veuillez ne pas mettre d'espace dans le nom du glossaire.")
|
||||
}
|
||||
}
|
||||
if (glossaryAlreadyExistsSnackbarVisibleState.value) {
|
||||
Snackbar(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
action = {
|
||||
Button(
|
||||
onClick = { glossaryAlreadyExistsSnackbarVisibleState.value = false },
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = customRedColor,
|
||||
contentColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text("OK")
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text("Ce glossaire existe déjà.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadGlossaries(): List<Glossary> {
|
||||
val glossaries = mutableListOf<Glossary>()
|
||||
//Récupérer tous les fichiers json à la racine du projet
|
||||
val glossaryFiles = File(".").listFiles { file ->
|
||||
file.extension == "json"
|
||||
}
|
||||
glossaryFiles?.forEach { file ->
|
||||
val glossary = Glossary(file.nameWithoutExtension, file.name)
|
||||
glossaries.add(glossary)
|
||||
}
|
||||
println(glossaries)
|
||||
return glossaries
|
||||
}
|
||||
|
||||
|
||||
fun main() = application {
|
||||
val state = rememberWindowState(
|
||||
|
|
Loading…
Reference in New Issue