package main import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.foundation.layout.padding import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi 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 val customRedColor = Color(0xFFB70D1B) val customGreenColor = Color(0xFF33b249) val customYellowColor = Color(0xFFffbd03) val currentPage = mutableStateOf("accueil") const val glossaryPath : String = "src/main/resources/projects/" // Classe pour stocker l'état global object AppState { var selectedProject: Project? = null var selectedGlossary: Glossary? = null } @OptIn(ExperimentalMaterialApi::class, ExperimentalComposeUiApi::class) @Composable @Preview fun app() { val languageManager = remember { LanguageManager() } MaterialTheme { var isJavaScriptFileSelected by remember { mutableStateOf(false) } val isEmptySnackbarVisibleState = remember { mutableStateOf(false) } val containsSpaceSnackbarVisibleState = remember { mutableStateOf(false) } val glossaryAlreadyExistsSnackbarVisibleState = remember { mutableStateOf(false) } val invalidCharacterSnackbarVisibleState = remember { mutableStateOf(false) } when (currentPage.value) { "accueil" -> { homePage( languageManager, onProjectClick = { currentPage.value = "projects" }, onCodeToVerifyClick = { currentPage.value = "choixLangage" }, ) } "glossaires" -> { glossariesPage( languageManager, currentPage = currentPage, onProjectClick = { currentPage.value = "projets" }, onCodeToVerifyClick = { currentPage.value = "choixLangage" }, ) } // Nouvelle page pour créer un nouveau glossaire "nouveauGlossaire" -> { newGlossary( languageManager, currentPage = currentPage, ) } "projects" -> { projectsPage( onProjectClick = { currentPage.value = "projects" }, onCodeToVerifyClick = { currentPage.value = "choixLangage" }, languageManager = languageManager, currentPage = currentPage, ) } "nouveauProjet" ->{ newProject( languageManager, currentPage = currentPage ) } "glossaireDetail" -> { appState.selectedGlossary?.let { loadDatasFromFile(it.jsonFilePath) }?.let { glossaryDetailedPage( glossary = it, glossaryName = appState.selectedGlossary?.name ?: "", onBackClick = { currentPage.value = "glossaires" }, onAddWordClick = { currentPage.value = "formulaire" }, onExportClick = { val fileDialog = FileDialog(Frame(), "Save as CSV", FileDialog.SAVE) fileDialog.file = appState.selectedGlossary?.name // 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") appState.selectedGlossary?.let { exportToCSV(it, csvFilePath) } } else { println("Export command cancelled by user.") } }, onImportClick = { selectFile(setOf("csv", "xlsx")) { filePath -> println("Importing file: $filePath") appState.selectedGlossary?.let { importFile(it, filePath) } } }, onProjectClick = { currentPage.value = "projects" }, languageManager = languageManager, onCodeToVerifyClick = { currentPage.value = "choixLangage" }, ) } } "formulaire" -> { appState.selectedGlossary?.let { formPage(it, onCancelClick = { currentPage.value = "glossaireDetail" }) } } "choixLangage" -> { val pythonExtensions = setOf("py") val javaExtensions = setOf("java") val jsExtensions = setOf("js", "html") choixLangagePage( languageManager, onBackClick = { currentPage.value = "accueil" }, onPythonClick = { selectFile(pythonExtensions) { filePath -> println("Python file selected: $filePath") // Change by parser functions } }, onJavaClick = { selectFile(javaExtensions) { filePath -> println("Java file selected: $filePath") // Change by parser functions } }, onJavaScriptClick = { selectFile(jsExtensions) { filePath -> mostUsedWordList = parser(filePath) // Change by parser functions isJavaScriptFileSelected = true } }, onProjectClick = { currentPage.value = "projects" }, onCodeToVerifyClick = { currentPage.value = "choixLangage" }, ) } "occurrence" -> { parsedWordsTable( languageManager, mostUsedWordList, onBackClick = { currentPage.value = "choixLangage" }, onProjectClick = { currentPage.value = "projects" }, onCodeToVerifyClick = { currentPage.value = "choixLangage" }, ) } } if (isJavaScriptFileSelected) { AlertDialog( onDismissRequest = { // Handle dialog dismissal if needed isJavaScriptFileSelected = false }, title = { Text("Le fichier a été importé avec succès") }, text = { Text("Vous pouvez maintenant comparer votre code avec le glossaire") }, confirmButton = { Button( onClick = { // Handle the confirm button action isJavaScriptFileSelected = false }, colors = ButtonDefaults.buttonColors( backgroundColor = customRedColor, contentColor = Color.White ) ) { Text("Ok") } } ) } 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à.") } } if (invalidCharacterSnackbarVisibleState.value) { Snackbar( modifier = Modifier.padding(16.dp), action = { Button( onClick = { invalidCharacterSnackbarVisibleState.value = false }, colors = ButtonDefaults.buttonColors( backgroundColor = customRedColor, contentColor = Color.White ) ) { Text("OK") } } ) { Text("Le nom du glossaire contient des caractères non autorisés (caractères spéciaux).") } } } } fun isValidFileName(name: String): Boolean { val regex = Regex("[^a-zA-Z0-9._-]") return !regex.containsMatchIn(name) } fun loadGlossaries(project: Project): List { val glossaries = mutableListOf() //Récupérer tous les fichiers json à la racine du projet val glossaryFiles = File(glossaryPath + project.name).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( placement = WindowPlacement.Floating, position = WindowPosition(Alignment.Center), isMinimized = false, width = 1280.dp, height = 720.dp ) Window( title = "Quali'Nomme", resizable = true, state = state, icon = painterResource("assets/logo/logo.png"), onCloseRequest = ::exitApplication ) { app() } }