Fix editing notes

This commit is contained in:
Hasinjato 2026-05-12 15:30:05 +03:00
parent 68dd6216b2
commit 65c56db655

View file

@ -1,15 +1,9 @@
package mg.dot.feufaro.solfa
import SharedScreenModel
import androidx.compose.runtime.remember
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.*
import mg.dot.feufaro.FileRepository
import mg.dot.feufaro.SaveSettings
import mg.dot.feufaro.data.GridTUOData
import mg.dot.feufaro.launchFilePicker
import mg.dot.feufaro.midi.MidiPitch
import mg.dot.feufaro.midi.MidiWriterKotlin
@ -450,11 +444,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
MODIF NOTES N1 N2 N3 N4
*/
// println("taille tA: ${templatArray.size} et le trgt $targetIdx")
val originalBlock = templatArray[targetIdx]
val markerRegex = Regex("""\$\{.*?\}|\$\w+""")
val deleteCount = originalBlock.replace(markerRegex, "").count { it.isLetter() }
val updatedNotes = updateSourceLines(lines, templatArray, targetIdx, deleteCount, editState)
val updatedNotes = updateSourceLines(lines, templatArray, targetIdx, editState)
// RESTAURATION DES TEMPLATES
if (templateString != "") {
@ -523,11 +513,10 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
lines: MutableList<String>,
fragments: List<String>,
targetIdx: Int,
deleteCount: Int,
editState: TUOEditState
): MutableList<String> {
/* Notes N1 N2 N3 N4 */
updateNotesInLines(lines, fragments, targetIdx, deleteCount, editState)
updateNotesInLines(lines, fragments, targetIdx, editState)
/* MODIF LYRICS */
//updateLyricsInLines(lines, fragments, targetIdx, deleteCount, editState)
return lines
@ -632,7 +621,6 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
lines: MutableList<String>,
fragments: List<String>,
targetIdx: Int,
deleteCount: Int,
editState: TUOEditState
) {
val notesByVoice = editState.notesByVoice
@ -647,7 +635,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
val prefix = currentLine.substringBefore(":") + ":"
val noteBody = currentLine.substringAfter(":")
val hasAnchor = noteBody.contains("#")
val noteExpanded = expandNotes(noteBody)
val noteExpanded = expandNotes(noteBody.replace(Regex("\\s+"), ""))
// println("Notes===>$noteExpanded")
val newNot = notesByVoice[voiceNum] ?: ""
@ -666,10 +654,11 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
val cleanNewNote = revertMusicalInput(newNote)
val regex = Regex("#\\S[',]*|\\s#\\S[',]*|/|\\(|\\)|[drmfsltDRFSTzw][0-9'¹²³⁴⁵₁₂₃₄₅,]*|[-.]")
val allTokens = regex.findAll(noteExpanded).map { it.value }.toList()
val regex = Regex("#\\S[',]*|\\s#\\S[',]*|/|\\(|\\)|[drmfsltDRFSTzw][0-9'¹²³⁴⁵₁₂₃₄₅,]*|[-.―•]")
val allTokens = regex.findAll(noteExpanded)
.map { it.value }
.filter { it != "." }
.toList()
val targetPointer = getNotePointer(fragments, targetIdx, currentLine)
@ -693,7 +682,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
val isStructural = token.contains("#") || token == "/" || token == "(" || token == ")"
if (isStructural) {
// println(String.format("%-5d | %-10s | %-8s | %-12s | %-10s", i, token, "STRUCT", "-", "Keep"))
println(String.format("%-5d | %-10s | %-8s | %-12s | %-10s", i, token, "STRUCT", "-", "Keep"))
resultTokens.add(token)
i++
continue
@ -701,65 +690,62 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
if (currentLogicalIdx == targetPointer) {
val originalToken = allTokens[i]
var replacement = if (!hasAnchor) {
val (newBase, newLevel) = parseNoteAndOctave(revertMusicalInput(newNot))
val (oldBase, oldLevel) = parseNoteAndOctave(revertMusicalInput(oldNot))
val octaveDiff = newLevel - oldLevel
val (tokenBase, tokenLevel) = parseNoteAndOctave(originalToken)
newBase + formatOctave(tokenLevel + octaveDiff)
//println("Insertition Multiples : $newNot")
val rawUserTokens = regex.findAll(revertMusicalInput(newNot)).map { it.value }.toList()
/** Si y a '-' dans template inutile d' ajouter au notes */
val hasDashInTemplate = editState.templateFragment.contains("-")
val newUserTokens = if (hasDashInTemplate) {
rawUserTokens.filter { it.matches(Regex("[drmfsltDRFSTzw].*")) }
} else {
// SI y a '#'
val anchorMatch = Regex("#([drmfsltDRFST])[',]*").find(noteBody)
val anchorLevel = if (anchorMatch != null) {
val anchorStr = anchorMatch.value
anchorStr.count { it == '\'' } - anchorStr.count { it == ',' }
} else 0
rawUserTokens
}
//val newUserTokens = regex.findAll(revertMusicalInput(newNot)).map { it.value }.toList()
val oldUserTokens = regex.findAll(revertMusicalInput(oldNot)).map { it.value }.toList()
val newNotCleaned = revertMusicalInput(newNot)
val oldNotCleaned = revertMusicalInput(oldNot)
val firstNewNote = newUserTokens.firstOrNull { it.matches(Regex("[drmfsltDRFSTzw].*")) } ?: ""
val firstOldNote = oldUserTokens.firstOrNull { it.matches(Regex("[drmfsltDRFSTzw].*")) } ?: ""
val (newBase, newLevel) = parseNoteAndOctave(newNotCleaned)
val (oldBase, oldLevel) = parseNoteAndOctave(oldNotCleaned)
val (_, newLvl) = parseNoteAndOctave(firstNewNote)
val (_, oldLvl) = parseNoteAndOctave(firstOldNote)
val octaveDiff = newLvl - oldLvl
val sourceLevel = newLevel - anchorLevel
val formattedOctave = formatOctave(sourceLevel)
val finalPureNew = newBase + formattedOctave
val pureOldBase = oldBase + formatOctave(oldLevel - anchorLevel)
val oldTokensForThisFragment = regex.findAll(revertMusicalInput(oldNot))
.map { it.value }
.filter { it.matches(Regex("[drmfsltDRFSTzw].*|[-―]")) }
.toList()
val dynamicDeleteCount = oldTokensForThisFragment.size
// println("Ancre niveau: $anchorLevel | UI Level: $newLevel -> Source Level: $sourceLevel")
//
if (finalPureNew.startsWith(pureOldBase) && pureOldBase.isNotEmpty()) {
val addedPart = finalPureNew.substring(pureOldBase.length)
originalToken + addedPart
newUserTokens.forEach { ut ->
val processedToken = if (ut.matches(Regex("[drmfsltDRFSTzw].*"))) {
val (fileBase, fileLvl) = parseNoteAndOctave(allTokens[i])
val (uBase, _) = parseNoteAndOctave(ut)
uBase + formatOctave(fileLvl + octaveDiff)
} else {
finalPureNew
ut
}
// println("j'aoute $processedToken")
resultTokens.add(processedToken)
if (processedToken.matches(Regex("[drmfsltDRFSTzw].*|[-―]"))) {
println(String.format("NEW | %-10s | INSERT | %-12d | REPLACE", processedToken, currentLogicalIdx))
currentLogicalIdx++
}
}
// println(
// String.format(
// "%-5s | %-10s | %-8s | %-12s | %-10s",
// "NEW", replacement, "INSERT", currentLogicalIdx, "REPLACE ($originalToken)"
// )
// )
resultTokens.add(replacement)
var notesSkipped = 0
while (notesSkipped < deleteCount && i < allTokens.size) {
val nextToken = allTokens[i]
val isNextStructural =
nextToken.contains("#") || nextToken == "/" || nextToken == "(" || nextToken == ")"
if (!isNextStructural) {
notesSkipped++
var skipped = 0
while (skipped < dynamicDeleteCount && i < allTokens.size) {
val nextT = allTokens[i]
if (!nextT.contains("#") && nextT != "/" && nextT != "(" && nextT != ")") {
skipped++
} else if (hasAnchor) {
resultTokens.add(nextToken)
resultTokens.add(nextT) // Garder les ancres si on est en mode ancre
}
i++
}
currentLogicalIdx += deleteCount
} else {
// AFFICHAGE NOTE NORMALE
// println(
@ -804,7 +790,7 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
private fun revertMusicalInput(input: String): String {
return input
.replace("• ,", "")
.replace("", "")
.replace("", "")
.replace("", "-")
.replace("", "")
.replace("³", "'''")