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