Fix #36: Falscher Verwerfen-Dialog beim Klick auf Dateiname uebernehmen

Nach erfolgreicher Umbenennung loeste resultItems.set() in
upsertResultRowByFingerprint() den selectedItemProperty-Listener aus,
der handleSelectionChange() mit noch aktivem Dirty-State aufrief.

Drei Korrekturen:
1. fileNameEditor.clearDirtyState() in handleRenameResult() vor dem
   Zeilen-Upsert: setzt lastSavedName = aktueller Textfeldinhalt, damit
   isDirty() false ist bevor die Tabellenzeile ersetzt wird.
2. selectionSyncInProgress-Schutz um resultItems.set() in
   upsertResultRowByFingerprint(): unterbindet mehrfache JavaFX-interne
   Change-Events (oldRow > null > newRow) waehrend des Upserts.
3. Neue Methode FileNameEditorPane.clearDirtyState() eingeführt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-27 08:47:58 +02:00
parent 5165ea6f1d
commit 3feafcbce8
2 changed files with 26 additions and 1 deletions
@@ -252,6 +252,19 @@ public final class FileNameEditorPane {
return !current.equals(saved); return !current.equals(saved);
} }
/**
* Setzt den Dirty-State zurück, ohne das Textfeld neu zu laden. Wird aufgerufen,
* nachdem eine Umbenennung erfolgreich abgeschlossen wurde, damit ein anschließendes
* Ersetzen der Tabellenzeile keinen Verwerfen-Dialog auslöst. Der angezeigte Text
* im Textfeld bleibt unverändert; {@code lastSavedName} wird auf den aktuellen
* Textfeldinhalt gesetzt.
*/
public void clearDirtyState() {
String current = textField.getText() == null ? "" : textField.getText();
this.lastSavedName = current.isBlank() ? Optional.empty() : Optional.of(current);
refreshUiState();
}
/** /**
* Liefert {@code true} wenn für die aktuelle Zeile ein KI-Vorschlag vorliegt. * Liefert {@code true} wenn für die aktuelle Zeile ein KI-Vorschlag vorliegt.
* *
@@ -792,6 +792,10 @@ public final class GuiBatchRunTab {
row.processingDuration(), row.processingDuration(),
row.resetPending()); row.resetPending());
currentlySelectedRow = updatedRow; currentlySelectedRow = updatedRow;
// Dirty-State vor dem Zeilen-Upsert zurücksetzen, damit das folgende
// resultItems.set() keinen Verwerfen-Dialog über den selectedItemProperty-Listener
// auslöst (isDirty() wäre sonst noch true, obwohl die Umbenennung erfolgreich war).
fileNameEditor.clearDirtyState();
upsertResultRowByFingerprint(updatedRow); upsertResultRowByFingerprint(updatedRow);
// Editor-Zustand auf neuen Namen zurücksetzen // Editor-Zustand auf neuen Namen zurücksetzen
String targetFolder = targetFolderSupplier.get().orElse(""); String targetFolder = targetFolderSupplier.get().orElse("");
@@ -1114,7 +1118,15 @@ public final class GuiBatchRunTab {
void upsertResultRowByFingerprint(GuiBatchRunResultRow newRow) { void upsertResultRowByFingerprint(GuiBatchRunResultRow newRow) {
for (int i = 0; i < resultItems.size(); i++) { for (int i = 0; i < resultItems.size(); i++) {
if (resultItems.get(i).fingerprint().equals(newRow.fingerprint())) { if (resultItems.get(i).fingerprint().equals(newRow.fingerprint())) {
// resultItems.set() feuert selectedItemProperty mehrfach (JavaFX-intern:
// oldRow → null → newRow), was ohne diesen Schutz handleSelectionChange()
// und damit fälschlicherweise den Verwerfen-Dialog auslösen würde.
selectionSyncInProgress = true;
try {
resultItems.set(i, newRow); resultItems.set(i, newRow);
} finally {
selectionSyncInProgress = false;
}
// Falls die aktuell selektierte Zeile aktualisiert wurde, Referenz erneuern // Falls die aktuell selektierte Zeile aktualisiert wurde, Referenz erneuern
if (currentlySelectedRow != null if (currentlySelectedRow != null
&& currentlySelectedRow.fingerprint().equals(newRow.fingerprint())) { && currentlySelectedRow.fingerprint().equals(newRow.fingerprint())) {