diff --git a/src/main/kotlin/main/Main.kt b/src/main/kotlin/main/Main.kt index 9ecd153..9502e96 100644 --- a/src/main/kotlin/main/Main.kt +++ b/src/main/kotlin/main/Main.kt @@ -13,6 +13,10 @@ import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.runtime.* +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.* import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier @@ -61,6 +65,8 @@ fun homePage( ) { Text("Quali'Nomme", style = MaterialTheme.typography.h3) + var isCompareClicked by remember { mutableStateOf(false) } + Spacer(modifier = Modifier.height(16.dp)) Row( @@ -87,7 +93,10 @@ fun homePage( } Button( - onClick = { /* Action de Comparer */ }, + onClick = { + isCompareClicked = true + + }, colors = ButtonDefaults.buttonColors( backgroundColor = customRedColor, contentColor = Color.White @@ -95,10 +104,81 @@ 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() { @@ -125,8 +205,18 @@ fun app() { } }, onExporterClick = { - FileDialog(Frame(), "Save as CSV", FileDialog.SAVE) - // ... (unchanged) + val fileDialog = FileDialog(Frame(), "Save as CSV", FileDialog.SAVE) + fileDialog.file = "glossaire_exporte.csv" // Initial file name + fileDialog.isVisible = true + val selectedFile = fileDialog.file + val selectedDirectory = fileDialog.directory + if (selectedFile != null) { + val csvFilePath = "$selectedDirectory$selectedFile" + println("Exporting to: $csvFilePath") + exportToCSV(csvFilePath) + } else { + println("Export command cancelled by user.") + } }, onVoirGlossaireClick = { glossaireDetail = chargerDonneesDepuisFichier() @@ -164,7 +254,7 @@ fun app() { }, onJavaScriptClick = { selectFile(jsExtensions) { filePath -> - parser(filePath) // Change by parser functions + mostUsedWordList = parser(filePath) // Change by parser functions } } ) @@ -176,38 +266,58 @@ 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.") } } +fun exportToCSV(csvFilePath: String) { + val glossary = chargerDonneesDepuisFichier() + val csvContent = buildString { + appendLine("Mot;Description;Contexte principal;Contexte 2;Lié à;Synonyme;Antonyme;") + glossary.forEach { entry -> + appendLine( + "${entry.nom};${entry.description};${entry.contextePrincipal};" + + "${entry.contexte2};${entry.lieA};${entry.synonyme};${entry.antonyme}" + ) + } + } + try { + FileWriter(csvFilePath).use { fileWriter -> + fileWriter.write(csvContent) + } + } catch (e: IOException) { + e.printStackTrace() + } +} + fun importFile(cheminFichier: String) { val fileExtension = File(cheminFichier).extension.lowercase() - when { - fileExtension == "csv" -> { + when (fileExtension) { + "csv" -> { importCSVFile(cheminFichier) } - fileExtension == "xlsx" -> { + "xlsx" -> { importXLSXFile(cheminFichier) } else -> { @@ -421,7 +531,6 @@ fun glossairePage( onAjouterMotClick: () -> Unit, onImporterClick: () -> Unit, onExporterClick: () -> Unit, - onVoirGlossaireClick: () -> Unit, onRetourClick: () -> Unit ) { @@ -691,12 +800,30 @@ fun GlossaireCard(mot: Mot, onSupprimerClick: (Mot) -> Unit) { } } +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 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("") } @@ -722,13 +849,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( @@ -836,7 +957,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 } @@ -853,15 +983,6 @@ fun formulairePage(onAnnulerClick: () -> Unit) { ajouterMotAuGlossaire(nouveauMot) 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 = "" - }, colors = ButtonDefaults.buttonColors( backgroundColor = customRedColor, @@ -874,11 +995,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") } } @@ -886,6 +1007,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é.") + } + } } } } @@ -938,8 +1071,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( @@ -951,4 +1084,4 @@ fun main() = application { ) { app() } -} \ No newline at end of file +} 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 }