From 9c9906df162690108982b74c1a5770b3a9e9b76c Mon Sep 17 00:00:00 2001 From: CAPEL Maxime <83071634+fortyup@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:42:12 +0100 Subject: [PATCH 1/4] Remove code duplication --- src/main/kotlin/main/Main.kt | 40 +++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/main/Main.kt b/src/main/kotlin/main/Main.kt index f7c2bf7..75578b9 100644 --- a/src/main/kotlin/main/Main.kt +++ b/src/main/kotlin/main/Main.kt @@ -7,6 +7,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Close import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment @@ -205,11 +206,11 @@ fun exportToCSV(csvFilePath: String) { fun importFile(cheminFichier: String) { val fileExtension = File(cheminFichier).extension.lowercase() - when { - fileExtension == "csv" -> { + when (fileExtension) { + "csv" -> { importCSVFile(cheminFichier) } - fileExtension == "xlsx" -> { + "xlsx" -> { importXLSXFile(cheminFichier) } else -> { @@ -494,6 +495,23 @@ fun glossairePage( } +fun resetFields( + nom: MutableState, + description: MutableState, + contextePrincipal: MutableState, + contexte2: MutableState, + lieA: MutableState, + synonyme: MutableState, + antonyme: MutableState +) { + nom.value = "" + description.value = "" + contextePrincipal.value = "" + contexte2.value = "" + lieA.value = "" + synonyme.value = "" + antonyme.value = "" +} @OptIn(ExperimentalMaterialApi::class) @Composable @@ -525,13 +543,7 @@ fun formulairePage(onAnnulerClick: () -> Unit) { Button( onClick = { openDialog.value = false - nom.value = "" - description.value = "" - contextePrincipal.value = "" - contexte2.value = "" - lieA.value = "" - synonyme.value = "" - antonyme.value = "" + resetFields(nom, description, contextePrincipal, contexte2, lieA, synonyme, antonyme) }, colors = ButtonDefaults.buttonColors( @@ -657,13 +669,7 @@ fun formulairePage(onAnnulerClick: () -> Unit) { openDialog.value = true // Réinitialiser les champs après l'ajout - nom.value = "" - description.value = "" - contextePrincipal.value = "" - contexte2.value = "" - lieA.value = "" - synonyme.value = "" - antonyme.value = "" + resetFields(nom, description, contextePrincipal, contexte2, lieA, synonyme, antonyme) }, colors = ButtonDefaults.buttonColors( From 9e407d78ccba81f44f46cf1908946021902652e6 Mon Sep 17 00:00:00 2001 From: cemal Date: Thu, 7 Dec 2023 14:58:24 +0100 Subject: [PATCH 2/4] Window size change + snackbar when sending formular --- src/main/kotlin/main/Main.kt | 37 +++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/main/Main.kt b/src/main/kotlin/main/Main.kt index 75578b9..fd29300 100644 --- a/src/main/kotlin/main/Main.kt +++ b/src/main/kotlin/main/Main.kt @@ -517,7 +517,8 @@ fun resetFields( @Composable fun formulairePage(onAnnulerClick: () -> Unit) { // State to track whether to show the snackbar - val snackbarVisibleState = remember { mutableStateOf(false) } + val ChampsObligatoireSnackbarVisibleState = remember { mutableStateOf(false) } + val ExisteDejaSnackbarVisibleState = remember { mutableStateOf(false) } val nom = remember { mutableStateOf("") } val description = remember { mutableStateOf("") } @@ -651,7 +652,16 @@ fun formulairePage(onAnnulerClick: () -> Unit) { // Validation du formulaire if (nom.value.isBlank() || contextePrincipal.value.isBlank()) { // Show the snackbar when validation fails - snackbarVisibleState.value = true + ChampsObligatoireSnackbarVisibleState.value = true + return@Button + } + + val listeMots = chargerDonneesDepuisFichier().toMutableList() + + // Vérifier si le mot existe déjà dans le glossaire + if (listeMots.any { it.nom.equals(nom.value, ignoreCase = true) }) { + println("Le mot '${nom.value}' existe déjà dans le glossaire. Ajout annulé.") + ExisteDejaSnackbarVisibleState.value = true return@Button } @@ -668,9 +678,6 @@ fun formulairePage(onAnnulerClick: () -> Unit) { ajouterMotAuGlossaire(nouveauMot) openDialog.value = true - // Réinitialiser les champs après l'ajout - resetFields(nom, description, contextePrincipal, contexte2, lieA, synonyme, antonyme) - }, colors = ButtonDefaults.buttonColors( backgroundColor = customRedColor, @@ -683,11 +690,11 @@ fun formulairePage(onAnnulerClick: () -> Unit) { } // Show the snackbar when the state is true - if (snackbarVisibleState.value) { + if (ChampsObligatoireSnackbarVisibleState.value) { Snackbar( modifier = Modifier.padding(16.dp), action = { - Button(onClick = { snackbarVisibleState.value = false }) { + Button(onClick = { ChampsObligatoireSnackbarVisibleState.value = false }) { Text("OK") } } @@ -695,6 +702,18 @@ fun formulairePage(onAnnulerClick: () -> Unit) { Text("Les champs 'Mot' et 'Contexte principal' sont obligatoires.") } } + if (ExisteDejaSnackbarVisibleState.value) { + Snackbar( + modifier = Modifier.padding(16.dp), + action = { + Button(onClick = { ExisteDejaSnackbarVisibleState.value = false }) { + Text("OK") + } + } + ) { + Text("Le mot '${nom.value}' existe déjà dans le glossaire. Ajout annulé.") + } + } } } } @@ -747,8 +766,8 @@ fun main() = application { placement = WindowPlacement.Floating, position = WindowPosition(Alignment.Center), isMinimized = false, - width = 800.dp, - height = 600.dp + width = 1280.dp, + height = 720.dp ) Window( From 87ed353f9ecb84b8943bd0b267324819f2d3f9b9 Mon Sep 17 00:00:00 2001 From: cemal Date: Thu, 7 Dec 2023 16:17:39 +0100 Subject: [PATCH 3/4] Comparing Javascript code words with glossary words --- src/main/kotlin/main/Main.kt | 90 +++++++++++++++++++++++++++++++--- src/main/kotlin/main/parser.kt | 6 ++- 2 files changed, 86 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/main/Main.kt b/src/main/kotlin/main/Main.kt index fd29300..60c41b9 100644 --- a/src/main/kotlin/main/Main.kt +++ b/src/main/kotlin/main/Main.kt @@ -4,12 +4,10 @@ import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.filled.Close -import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -30,8 +28,6 @@ import java.io.FileInputStream val customRedColor = Color(0xFFB70D1B) - - @Composable fun homePage( onGlossaireClick: () -> Unit, @@ -46,6 +42,8 @@ fun homePage( ) { Text("Quali'Nomme", style = MaterialTheme.typography.h3) + var isCompareClicked by remember { mutableStateOf(false) } + Spacer(modifier = Modifier.height(16.dp)) Row( @@ -72,7 +70,10 @@ fun homePage( } Button( - onClick = { /* Action de Comparer */ }, + onClick = { + isCompareClicked = true + + }, colors = ButtonDefaults.buttonColors( backgroundColor = customRedColor, contentColor = Color.White @@ -80,16 +81,89 @@ fun homePage( ) { Text("Comparer") } + + if (isCompareClicked) { + println(mostUsedWordList.keys.toList()) + compareResults( + motsGlossaire = chargerDonneesDepuisFichier(), + motsCode = mostUsedWordList.keys.toList(), + onRetourClick = { isCompareClicked = false } + ) + } } } } + + +@Composable +fun compareResults( + motsGlossaire: List, + motsCode: List, + onRetourClick: () -> Unit, + navigationIcon: @Composable () -> Unit = { Icon(Icons.Filled.ArrowBack, contentDescription = null) } + +) { + Column( + modifier = Modifier.fillMaxSize(), + verticalArrangement = Arrangement.Top, // Align content at the top + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text(text = "Le code contient ${comparerMots(motsGlossaire, motsCode)}% des mots du glossaire\"", style = MaterialTheme.typography.h3) + } + + Column( + modifier = Modifier + .fillMaxSize() // Fills the maximum available width + .padding(16.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + + ) { + Text(text = "Le code contient ${comparerMots(motsGlossaire, motsCode)}% des mots du glossaire") + } + + // Bouton retour positionné tout en bas et centré horizontalement + Column( + modifier = Modifier.fillMaxSize().padding(20.dp), + verticalArrangement = Arrangement.Bottom, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Button( + onClick = onRetourClick, + colors = ButtonDefaults.buttonColors( + backgroundColor = customRedColor, + contentColor = Color.White + ) + ) { + Text("Retour") + } + } + +} + +fun comparerMots(motsGlossaire: List, motsCode: List): Int { + var motsTrouves = 0 + motsCode.forEach { motCode -> + motsGlossaire.forEach { mot -> + if (motCode.equals(mot.nom, ignoreCase = true)) { + motsTrouves++ + } + } + } + println(motsTrouves*100/motsCode.size) + return motsTrouves*100/motsCode.size +} + +var mostUsedWordList = mutableMapOf() @Composable @Preview fun app() { MaterialTheme { val currentPage = remember { mutableStateOf("accueil") } + + when (currentPage.value) { "accueil" -> { homePage( @@ -147,7 +221,7 @@ fun app() { }, onJavaScriptClick = { selectFile(jsExtensions) { filePath -> - parser(filePath) // Change by parser functions + mostUsedWordList = parser(filePath) // Change by parser functions } } ) diff --git a/src/main/kotlin/main/parser.kt b/src/main/kotlin/main/parser.kt index 7744535..837196f 100644 --- a/src/main/kotlin/main/parser.kt +++ b/src/main/kotlin/main/parser.kt @@ -47,7 +47,7 @@ fun splitLanguages(file : String){ -fun parser(fileName : String) { +fun parser(fileName : String) : MutableMap { val delimiter1 = " " val regex = "[^a-zA-Z^é^à]".toRegex() val array = mutableListOf() @@ -61,8 +61,10 @@ fun parser(fileName : String) { } val map = jsWords(array.groupingBy { it }.eachCount()) - val sortedMap = map.toList().take(10).sortedBy { (_, value) -> value }.toMap() + var sortedMap = map.toList().take(10).sortedBy { (_, value) -> value }.toMap() sortedMap.forEach() { (t, u) -> println("$t : $u") } // affiche le nombre d'occurence de chaque mot + sortedMap = sortedMap.toMutableMap() + return sortedMap } From dbc1f8a35469fd6511badbbf86251494b84e0c5a Mon Sep 17 00:00:00 2001 From: Thomas BREIL Date: Thu, 7 Dec 2023 16:21:48 +0100 Subject: [PATCH 4/4] Allow Multiple files to parse --- src/main/kotlin/main/Main.kt | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/main/Main.kt b/src/main/kotlin/main/Main.kt index 60c41b9..6114fce 100644 --- a/src/main/kotlin/main/Main.kt +++ b/src/main/kotlin/main/Main.kt @@ -233,24 +233,24 @@ fun app() { fun selectFile(extensions: Set, onFileSelected: (String) -> Unit) { val fileDialog = FileDialog(Frame(), "Select a file", FileDialog.LOAD) - fileDialog.isMultipleMode = false // To enable selecting only one file + fileDialog.isMultipleMode = true // To enable selecting only one file fileDialog.file = "*." + extensions.joinToString(";*.") fileDialog.isVisible = true - val selectedFile = fileDialog.file - val selectedDirectory = fileDialog.directory + val selectedFiles = fileDialog.files - if (selectedFile != null) { - val filePath = "$selectedDirectory$selectedFile" - - // Vérifier si l'extension est autorisée - val fileExtension = File(filePath).extension.lowercase() - if (extensions.contains(fileExtension)) { - println("Opening: $filePath") - onFileSelected(filePath) - } else { - println("Invalid file extension.") + if (selectedFiles != null) { + for (file in selectedFiles) { + println("Selected file: $file") + // Vérifier si l'extension est autorisée + val fileExtension = File(file.absolutePath).extension.lowercase() + if (extensions.contains(fileExtension)) { + println("Opening: $file") + onFileSelected(file.absolutePath) + } else { + println("Invalid file extension.") + } } } else { println("Open command cancelled by user.")