From 04a12e598177880f6d59c437528baa5e34418254 Mon Sep 17 00:00:00 2001 From: Samer Ayadi Date: Tue, 1 Sep 2026 15:15:16 +0200 Subject: [PATCH] [FIX] VF-Linienzug: Abbruch beim Editieren brach den VF-Block auf Die interaktiven Editier-Pfade riefen den Neuaufbau ueber vl-catch-all-apply auf. Der alte Block ist dort per entdel schon entfernt, und der Catch faengt einen Abbruch (ESC -> (exit)) VOR *error* ab - der Abbruch-Wickler vfl-modus-abbruch-sichern kam damit nie zum Zug. Ergebnis: die komplette Kette blieb als lose Einzelteile ohne VF_n-Block liegen und war nicht mehr per Doppelklick editierbar. - vfl-edit-ent (Sektions-Zweig) und vfl-edit-ent2 rufen vf-linienzug-modus/-modus2 jetzt DIREKT auf. Nur der nicht-interaktive Batch-Konverter vfl-konvertiere-ent behaelt den Catch (die Batch-Schleife muss weiterlaufen) und meldet den betroffenen Block statt still zu scheitern. - Beide Abbruch-Handler setzen *ssg-ils-dim* zurueck. Das tat bisher nur der Aufrufer, der nach einem Abbruch nicht mehr erreicht wird - der Dim-Override blieb fuer die restliche Sitzung stehen. Wiederherstellung aus der Zeichnung (Sektions-XDATA): - vfl-segment-xdata-sichern schrieb nur die Slice des LETZTEN Glieds einer Schleifen-Iteration. Eine VF-Einheit mit eingebetteten Vario-Kurven verlor dadurch ihre eigenen Eingaben. Jetzt wird der komplette Journal-Abschnitt der Iteration geschrieben, indiziert mit dem ersten Glied-Index darin (neu: vfl-journal-ab-glied, vfl-steps-zaehlen). Ein Glied ohne Geometrie verbraucht seinen Abschnitt nicht mehr - er wandert in den naechsten Record, der Entities bekommt. - Neue XDATA-App SSG_VF_EDIT_PRE haelt die Praeambel (Startpunkt, Starthoehe, AS ja/nein + Winkel/Seite) auf den Entities der ersten Iteration. Ohne sie fehlte der Kopf des Journals in jeder Sektion. - Neuer Befehl VF_SEKTION_RESTORE: Auswahl der losen Geometrie -> Sektionen lueckenlos ab Glied 1 zusammensetzen -> stummer Replay -> interaktiv weiterbauen. Die alte Geometrie wird erst NACH erfolgreichem Neuaufbau geloescht, ein Abbruch laesst sie samt XDATA stehen (Versuch wiederholbar). Altbestand ohne Praeambel-XDATA wird danach gefragt. Die .dbg-Dateien bleiben reine Ausgabe und werden von keinem Befehl gelesen - Wiederherstellungs-Daten gehoeren in die XDATA der Zeichnung. tests/testdata/vfl_journal_hm05_abbruch.json: Journal der Session vom 2026-08-31 (9 Glieder), gegen das die Slice-/Join-Logik geprueft wurde. Reine Daten, wird von keinem Befehl gelesen. Co-Authored-By: Claude Opus 5 (1M context) --- CLAUDE.md | 2 +- Lisp/vf_linienzug.lsp | 318 ++++++++++++++++++- doc/variofoerderer.md | 38 +++ lang/de_DE.json | 9 + lang/en_GB.json | 9 + tests/testdata/vfl_journal_hm05_abbruch.json | 1 + 6 files changed, 360 insertions(+), 17 deletions(-) create mode 100644 tests/testdata/vfl_journal_hm05_abbruch.json diff --git a/CLAUDE.md b/CLAUDE.md index 65f8dc8..3c528fe 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -98,7 +98,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `ssg_dialog.lsp` | - | DCL-Dialog-Vorlagen und Hilfsfunktionen | | `ssg_layer.lsp` | - | Layer-Verwaltung | | `KreiselInsert.lsp` | KreiselInsert, KreiselConnect, KreiselRedraw, KreiselQuick, KreiselEdit, KreiselParams, KreiselLabelSetup, KreiselLabelPos, KreiselLabelHoehe, ILS_Eckrad | ILS Kreisel und Eckrad komplett in AutoLISP | -| `VarioFoerderer.lsp` (Wrapper fuer `vf_core.lsp`/`vf_standard.lsp`/`vf_etage.lsp`/`vf_linienzug.lsp`) | FOERDERANLAGE, VARIOFOERDERER_EDIT, VARIOFOERDERER_NACHRUESTEN, Vario_Kette_Merge, VF_WIZARD_AN, VF_WIZARD_AUS | Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standard- UND Etage-Typ: Werteingabe per DCL-Dialog. Der Dialog-Ablauf ist zentral in vf_core (`vf-dialog-ablauf`/`vf-dialog-berechnen-einfuegen`, parametrisiert ueber Typ-Registry `*vf-typ-registry*` + Flag `horizontal-p`); `vfs-standard-dialog-ablauf`/`vfe-etage-dialog-ablauf` sind nur noch duenne Wrapper darauf. Beide nutzen dieselben Dialoge `vfs-dialog-eingabe-basis`/`vfs-dialog-winkel-verteilung` und den gemeinsamen L_GF/L_VF-Solve `vf-winkel-solve` (vf_core; berechne-alle-winkel/berechne-winkel-etage teilen ihn); Doppelklick auf VF_n-Block ruft VARIOFOERDERER_EDIT, das per SSG_VF_EDIT-XDATA-Marker ("standard"/"etage"/"linienzug") in den passenden Neuaufbau-Zweig dispatcht (`vfe-edit-ent` fuer Etage, `vfl-edit-ent` fuer Linienzug); Altbestand-Bloecke ohne Marker werden abgewiesen. Linienzug (Modus 1, `vf-linienzug-modus`) zeichnet jede interaktive Eingabe in einem Journal auf (`vfl-in-point`/`-string`/`-real`/`-int`) und schreibt es als XDATA auf den fertigen `VF_n`-Block; ein Abbruch (ESC) loescht dadurch nichts mehr, sondern wickelt die bis dahin gebaute Teil-Geometrie ebenso zu einem Block (`vfl-modus-abbruch-sichern`) - sie bleibt stehen und ist sofort per Doppelklick weiter editierbar/fortsetzbar. Der komplette Linienzug-Hauptstrang (Menue-Fragen von AS-Element bis Kettenende, inkl. GF-Bogen/Vario-Kurve/VF-Einheit-Fortsetzung) laeuft per Default ueber DCL-Dialoge statt Konsole (`*vfl-wizard-mode*`, Befehle VF_WIZARD_AN/VF_WIZARD_AUS): `vfl-in-string`/`-int`/`-real` zeigen bei aktivem Wizard-Modus generische Dialoge aus `dcl/vf_linienzug_wizard.dcl` (Zahl-Eingabe bzw. Mehrfachauswahl aus `vfl-menu`/`vfl-menu-int`) statt `getstring`/`getint`/`getreal` aufzurufen; die ORIGINALEN Konsolen-Fragen (princ + get*, de/en ueber ssg-text) bleiben unveraendert im Code (Fallback bei Fehlern via `vl-catch-all-apply`, siehe `doc/variofoerderer.md`). `vfl-edit-ent` liest das Journal, zeigt die Sektionen ueber einen DCL-Dialog (`vfl-dlg-position`, `dcl/vfl_edit.dcl`) an, kuerzt bei Bedarf auf eine gewaehlte Sektion (stummer Replay der behaltenen Eingaben, umgeht den Wizard-Zweig komplett) und baut danach interaktiv weiter. Linienzug Modus 2 (Pfad+Zielhoehe-Solver, `vf-linienzug-modus2`) nutzt dieselben Wrapper PLUS die neue Objektauswahl-Wrapper-Funktion `vfl-in-selection` (Pfad-Objekte als stabile Entity-Handles journalisiert, neue Journal-Art `"OBJS"`) und schreibt sein Journal unter dem eigenen XDATA-Marker `"linienzug2"`; Doppelklick baut hier NICHT abschnittsweise, sondern per vollem Reset 1:1 aus dem Journal neu auf (`vfl-edit-ent2`, dispatcht aus `vfl-edit-ent` per Marker) - Modus 3 (Vorwaerts-Nachbau) bleibt bewusst reine Konsole (im Code selbst als Legacy/"wird umgebaut" markiert). `Vario_Kette_Merge` (in vf_linienzug.lsp) fuehrt mehrere einzeln gebaute VF_n-Bloecke ab einem gewaehlten Start-Baustein ueber die reale KS_AUS->KS_EIN-Nachbarschaft zu einem Gesamt-Block zusammen (aggregierte Attribute, Luecken-Erkennung). `vf_konstanten.lsp` (von vf_core.lsp vor den drei Submodulen geladen) sammelt alle Laengen-/Winkel-/Toleranz-Magic-Numbers aus dem VarioFoerderer-Cluster als dokumentierte `*vfk-*`-Konstanten. Die Migration ist abgeschlossen: vf_core/vf_standard/vf_etage/vf_linienzug referenzieren durchgaengig die zentralen Konstanten statt roher Literale (Winkel, Stations-/Separator-Laengen, Mindestlaengen, AS/ES-Fallback-Versaetze, Text-/Label-Masse) - Ausnahmen sind in `vf_konstanten.lsp` selbst dokumentiert (Werte mit fuehrender Config-Anbindung via `ssg-cfg-or`, itoa-/Integer-Kontexte, Blocknamen-Strings, die 2000.0-mm/m-Umrechnung). `*vfk-gf-bogen-winkel*` (30/60/90, GF-Bogen + Vario-Kurve) und `*vfk-as-es-winkel*` ("30"/"90", AS/ES; bewusst STRING, da 2-wertig und im Journal als STR gefuehrt) sind Beispiele; vf_linienzug hat fuer beide einen Fallback, falls vf_konstanten nicht geladen wurde. Details/Entscheidungsbaum: `doc/variofoerderer.md` | +| `VarioFoerderer.lsp` (Wrapper fuer `vf_core.lsp`/`vf_standard.lsp`/`vf_etage.lsp`/`vf_linienzug.lsp`) | FOERDERANLAGE, VARIOFOERDERER_EDIT, VARIOFOERDERER_NACHRUESTEN, Vario_Kette_Merge, VF_SEKTION_RESTORE, VF_WIZARD_AN, VF_WIZARD_AUS | Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standard- UND Etage-Typ: Werteingabe per DCL-Dialog. Der Dialog-Ablauf ist zentral in vf_core (`vf-dialog-ablauf`/`vf-dialog-berechnen-einfuegen`, parametrisiert ueber Typ-Registry `*vf-typ-registry*` + Flag `horizontal-p`); `vfs-standard-dialog-ablauf`/`vfe-etage-dialog-ablauf` sind nur noch duenne Wrapper darauf. Beide nutzen dieselben Dialoge `vfs-dialog-eingabe-basis`/`vfs-dialog-winkel-verteilung` und den gemeinsamen L_GF/L_VF-Solve `vf-winkel-solve` (vf_core; berechne-alle-winkel/berechne-winkel-etage teilen ihn); Doppelklick auf VF_n-Block ruft VARIOFOERDERER_EDIT, das per SSG_VF_EDIT-XDATA-Marker ("standard"/"etage"/"linienzug") in den passenden Neuaufbau-Zweig dispatcht (`vfe-edit-ent` fuer Etage, `vfl-edit-ent` fuer Linienzug); Altbestand-Bloecke ohne Marker werden abgewiesen. Linienzug (Modus 1, `vf-linienzug-modus`) zeichnet jede interaktive Eingabe in einem Journal auf (`vfl-in-point`/`-string`/`-real`/`-int`) und schreibt es als XDATA auf den fertigen `VF_n`-Block; ein Abbruch (ESC) loescht dadurch nichts mehr, sondern wickelt die bis dahin gebaute Teil-Geometrie ebenso zu einem Block (`vfl-modus-abbruch-sichern`) - sie bleibt stehen und ist sofort per Doppelklick weiter editierbar/fortsetzbar. Der komplette Linienzug-Hauptstrang (Menue-Fragen von AS-Element bis Kettenende, inkl. GF-Bogen/Vario-Kurve/VF-Einheit-Fortsetzung) laeuft per Default ueber DCL-Dialoge statt Konsole (`*vfl-wizard-mode*`, Befehle VF_WIZARD_AN/VF_WIZARD_AUS): `vfl-in-string`/`-int`/`-real` zeigen bei aktivem Wizard-Modus generische Dialoge aus `dcl/vf_linienzug_wizard.dcl` (Zahl-Eingabe bzw. Mehrfachauswahl aus `vfl-menu`/`vfl-menu-int`) statt `getstring`/`getint`/`getreal` aufzurufen; die ORIGINALEN Konsolen-Fragen (princ + get*, de/en ueber ssg-text) bleiben unveraendert im Code (Fallback bei Fehlern via `vl-catch-all-apply`, siehe `doc/variofoerderer.md`). `vfl-edit-ent` liest das Journal, zeigt die Sektionen ueber einen DCL-Dialog (`vfl-dlg-position`, `dcl/vfl_edit.dcl`) an, kuerzt bei Bedarf auf eine gewaehlte Sektion (stummer Replay der behaltenen Eingaben, umgeht den Wizard-Zweig komplett) und baut danach interaktiv weiter. Linienzug Modus 2 (Pfad+Zielhoehe-Solver, `vf-linienzug-modus2`) nutzt dieselben Wrapper PLUS die neue Objektauswahl-Wrapper-Funktion `vfl-in-selection` (Pfad-Objekte als stabile Entity-Handles journalisiert, neue Journal-Art `"OBJS"`) und schreibt sein Journal unter dem eigenen XDATA-Marker `"linienzug2"`; Doppelklick baut hier NICHT abschnittsweise, sondern per vollem Reset 1:1 aus dem Journal neu auf (`vfl-edit-ent2`, dispatcht aus `vfl-edit-ent` per Marker) - Modus 3 (Vorwaerts-Nachbau) bleibt bewusst reine Konsole (im Code selbst als Legacy/"wird umgebaut" markiert). `Vario_Kette_Merge` (in vf_linienzug.lsp) fuehrt mehrere einzeln gebaute VF_n-Bloecke ab einem gewaehlten Start-Baustein ueber die reale KS_AUS->KS_EIN-Nachbarschaft zu einem Gesamt-Block zusammen (aggregierte Attribute, Luecken-Erkennung). Die interaktiven Editier-Pfade (`vfl-edit-ent` Sektions-Zweig, `vfl-edit-ent2`) rufen den Neuaufbau BEWUSST direkt auf, NICHT ueber `vl-catch-all-apply`: der alte Block ist beim Neuaufbau schon per `entdel` weg, und ein Catch faengt den Abbruch VOR `*error*` ab - der Abbruch-Wickler `vfl-modus-abbruch-sichern` kaeme nie zum Zug und die ganze Kette bliebe als lose Einzelteile ohne Block liegen (Fehlerbild "VF-Block aufgebrochen"). Nur der nicht-interaktive Batch-Konverter `vfl-konvertiere-ent` behaelt den Catch (die Batch-Schleife muss weiterlaufen) und meldet den betroffenen Block. Die Abbruch-Handler setzen zusaetzlich `*ssg-ils-dim*` zurueck, weil der Aufrufer, der das sonst tut, nach einem Abbruch nicht mehr erreicht wird. Recovery-Pfad fuer bereits aufgebrochene Ketten: `VF_SEKTION_RESTORE` (vf_linienzug.lsp) setzt das Ketten-Journal aus der XDATA der losen Objekte zusammen - `SSG_VF_EDIT_SEG` traegt pro Entity den Journal-Abschnitt DER ITERATION, in der es entstand (indiziert mit dem ersten Glied-Index darin; eine VF-Einheit mit eingebetteten Vario-Kurven erzeugt mehrere Glieder in einer Iteration), `SSG_VF_EDIT_PRE` auf den Entities des ersten Gliedes die Praeambel (Startpunkt/Starthoehe/AS). Die `.dbg`-Dateien sind reine AUSGABE und werden von keinem Befehl gelesen (dbgopen legt sie bei jedem Lauf neu an) - Wiederherstellungs-Daten gehoeren in die XDATA. `vf_konstanten.lsp` (von vf_core.lsp vor den drei Submodulen geladen) sammelt alle Laengen-/Winkel-/Toleranz-Magic-Numbers aus dem VarioFoerderer-Cluster als dokumentierte `*vfk-*`-Konstanten. Die Migration ist abgeschlossen: vf_core/vf_standard/vf_etage/vf_linienzug referenzieren durchgaengig die zentralen Konstanten statt roher Literale (Winkel, Stations-/Separator-Laengen, Mindestlaengen, AS/ES-Fallback-Versaetze, Text-/Label-Masse) - Ausnahmen sind in `vf_konstanten.lsp` selbst dokumentiert (Werte mit fuehrender Config-Anbindung via `ssg-cfg-or`, itoa-/Integer-Kontexte, Blocknamen-Strings, die 2000.0-mm/m-Umrechnung). `*vfk-gf-bogen-winkel*` (30/60/90, GF-Bogen + Vario-Kurve) und `*vfk-as-es-winkel*` ("30"/"90", AS/ES; bewusst STRING, da 2-wertig und im Journal als STR gefuehrt) sind Beispiele; vf_linienzug hat fuer beide einen Fallback, falls vf_konstanten nicht geladen wurde. Details/Entscheidungsbaum: `doc/variofoerderer.md` | | `Gefaellestrecke.lsp` | GEFAELLESTRECKE, GEFAELLESTRECKE_EDIT | Gefaelle-Foerderanlage (AUS -> Staustrecke skaliert -> Separator -> EIN); Modus 1 per DCL-Dialog (Einfuegehoehe, Element-Winkel 30/90); Doppelklick auf GF_n-Block ruft GEFAELLESTRECKE_EDIT (Dialog vorbelegt, Neuaufbau) | | `export.lsp` | EXPORTSIVAS, EXPORTCSV, OMNI_UPDATE_ATTRIBS | JSON-Sammlung und Python-Export (Omniflo-Merkmale/Sum-Zeile via lib/export_csv.py) | | `OmniModulInsert.lsp` | OMNI_LOAD, OMNI_APB_*, OMNI_W*_*, OMNI_AP60/AP110, OMNI_TEF_*, OMNI_TV_*, OMNI_APBW_*, OMNI_EDIT | Omniflo-Komponenten: Boegen, Weichen, Verbinder, Transferwagen, Edit-Dialog | diff --git a/Lisp/vf_linienzug.lsp b/Lisp/vf_linienzug.lsp index 6af508a..e102e66 100644 --- a/Lisp/vf_linienzug.lsp +++ b/Lisp/vf_linienzug.lsp @@ -143,8 +143,15 @@ ;; "NIL" Abbruch/Default (value nil) "STEP" Glied-Checkpoint (value = Label) ;; *vfl-journal* wird in UMGEKEHRTER Reihenfolge gehalten (neuestes zuerst, cons). +;; *vfl-seg-glied-letzte* = Glied-Stand nach der vorherigen Iteration der +;; Bau-Hauptschleife (fuer die Segment-XDATA, siehe vfl-segment-xdata-sichern). +;; MUSS bei jedem Journal-Start auf 0 stehen, sonst bekaeme das erste Glied +;; eines neuen Baus einen zu hohen Index und die Praeambel wuerde nicht +;; geschrieben. +(if (not (boundp '*vfl-seg-glied-letzte*)) (setq *vfl-seg-glied-letzte* 0)) + (defun vfl-journal-reset () - (setq *vfl-journal* '() *vfl-replay-queue* nil) + (setq *vfl-journal* '() *vfl-replay-queue* nil *vfl-seg-glied-letzte* 0) (if (boundp '*vflw-pending*) (setq *vflw-pending* nil))) ;; Eintrag anhaengen (vorn, da Reverse-Reihenfolge). @@ -1287,6 +1294,7 @@ ;; forward-journal (Bau-Reihenfolge) als kompakter JSON-Array-String. (defun vfl-journal->json (forward-journal) (strcat "[" (vfl-strjoin (mapcar 'vfl-entry->json forward-journal) ",") "]")) + (defun vfl-string->journal (s / out) (setq out '()) (foreach ln (vfl-strsplit s "\n") @@ -1365,6 +1373,46 @@ nil)) nil)) +;; --- Praeambel-XDATA (eigene App "SSG_VF_EDIT_PRE") ----------------------- +;; Die Segment-XDATA (SSG_VF_EDIT_SEG) deckt nur die GLIEDER ab - alles vor +;; dem ersten STEP (Startpunkt, Starthoehe, AS ja/nein + AS-Winkel/-Seite) +;; steht in keiner Slice. Fuer eine vollstaendige Wiederherstellung aus der +;; Zeichnung allein (c:VF_SEKTION_RESTORE) fehlt damit genau der Kopf des +;; Journals. Deshalb wird die Praeambel zusaetzlich als eigene XDATA-App auf +;; die Entities des ERSTEN Gliedes geschrieben - eigene App, weil pro Entity +;; nur ein SSG_VF_EDIT_SEG-Record Platz hat (der gehoert dem Glied). +;; Layout: [0]="linienzug-pre" (Marker), [1..]=Journal-String in 250-Byte-Chunks. +;; +;; Praeambel = alle Journal-Eintraege VOR dem ersten STEP. +(defun vfl-journal-praeambel (forward-journal / out fertig) + (setq out '() fertig nil) + (foreach e forward-journal + (if (and (not fertig) (= (car e) "STEP")) (setq fertig t)) + (if (not fertig) (setq out (cons e out)))) + (reverse out)) + +(defun vfl-journal-xdata-schreiben-pre (ent pre-journal / chunks appentry) + (regapp "SSG_VF_EDIT_PRE") + (setq chunks (vfl-chunk-string (vfl-journal-list->string pre-journal) 250)) + (setq appentry + (cons "SSG_VF_EDIT_PRE" + (cons (cons 1000 "linienzug-pre") + (mapcar (function (lambda (c) (cons 1000 c))) chunks)))) + (entmod (append (entget ent) (list (list -3 appentry)))) + ent) + +;; Rueckgabe: Praeambel-Journal oder nil (keine/unbekannte Praeambel-XDATA). +(defun vfl-journal-xdata-lesen-pre (ent / xd app-data werte) + (setq xd (entget ent '("SSG_VF_EDIT_PRE"))) + (setq app-data (cdr (assoc -3 xd))) + (if app-data + (progn + (setq werte (mapcar 'cdr (cdr (car app-data)))) + (if (and werte (= (car werte) "linienzug-pre")) + (vfl-string->journal (apply 'strcat (cdr werte))) + nil)) + nil)) + ;; Wird direkt nach dem Segment-Dispatch-cond in vf-linienzug-modus aufgerufen ;; (per vl-catch-all-apply abgesichert - ein Fehler hier darf den Hauptbau nie ;; abbrechen, rein additive Zusatz-XDATA). seg-lastEnt = Schnappschuss VOR @@ -1377,13 +1425,31 @@ ;; ergaenzt) und schreibt sie auf JEDES seit seg-lastEnt neu erzeugte Entity ;; (entnext-Wanderung, gleiches Muster wie vfl-block-erstellen/ ;; vfl-modus-abbruch-sichern). -(defun vfl-segment-xdata-sichern (seg-lastEnt wahl / forward-journal seg-idx seg-journal e cnt slice-label) +(defun vfl-segment-xdata-sichern (seg-lastEnt wahl / forward-journal seg-idx seg-von + seg-journal log-slice e cnt slice-label pre-journal) (setq forward-journal (reverse *vfl-journal*)) (setq seg-idx (length (vfl-journal-glieder forward-journal))) + ;; Erstes Glied DIESER Iteration: eine Iteration kann mehrere Glieder + ;; erzeugen (VF-Einheit + eingebettete Vario-Kurven). *vfl-seg-glied-letzte* + ;; haelt den Glied-Stand der vorherigen Iteration. + (if (null *vfl-seg-glied-letzte*) (setq *vfl-seg-glied-letzte* 0)) + (setq seg-von (1+ *vfl-seg-glied-letzte*)) (setq cnt 0) - (if (> seg-idx 0) + (if (and (> seg-idx 0) (>= seg-idx seg-von)) (progn - (setq seg-journal (vfl-journal-slice forward-journal seg-idx)) + ;; XDATA: der KOMPLETTE in dieser Iteration entstandene Journal-Abschnitt + ;; (Glieder seg-von .. seg-idx), indiziert mit dem ERSTEN Glied-Index. + ;; Nur so ist die Kette spaeter luecken- und desync-frei aus der + ;; Zeichnung rekonstruierbar (c:VF_SEKTION_RESTORE). + (setq seg-journal (vfl-journal-ab-glied forward-journal seg-von)) + ;; Fuers Log/die Schema-Validierung weiterhin die Slice des LETZTEN + ;; Glieds (unveraendertes Verhalten, siehe Kommentar unten). + (setq log-slice (vfl-journal-slice forward-journal seg-idx)) + ;; Praeambel (Startpunkt/Starthoehe/AS) bei der ERSTEN Iteration + ;; mitschreiben - ohne sie waere die Kette aus der Zeichnung nicht + ;; vollstaendig rekonstruierbar (vfl-journal-xdata-schreiben-pre). + ;; Danach aendert sich die Praeambel nicht mehr. + (setq pre-journal (if (= seg-von 1) (vfl-journal-praeambel forward-journal) nil)) ;; Tatsaechliches Label der geschnittenen Slice (der STEP-Wert am Anfang). ;; Kann von wahl (dem Hauptschleifen-Label) ABWEICHEN: enthaelt die ;; VF-Einheit eine Vario-Kurve, ist DEREN STEP das letzte Glied, seg-idx @@ -1391,30 +1457,42 @@ ;; noch "Horizontal-VF"/"Linie-VF" ist. Fuers Log/die Validierung zaehlt ;; das echte Slice-Label, nicht wahl (sonst falsch etikettiert). (setq slice-label - (if (and seg-journal (= (car (car seg-journal)) "STEP")) - (cdr (car seg-journal)) wahl)) + (if (and log-slice (= (car (car log-slice)) "STEP")) + (cdr (car log-slice)) wahl)) (setq e (if seg-lastEnt (entnext seg-lastEnt) (entnext))) (while e - (vfl-journal-xdata-schreiben-seg e seg-idx seg-journal) + (vfl-journal-xdata-schreiben-seg e seg-von seg-journal) + (if pre-journal (vfl-journal-xdata-schreiben-pre e pre-journal)) (setq cnt (1+ cnt)) (setq e (entnext e)) ) + ;; Glied-Stand NUR fortschreiben, wenn wirklich Entities beschrieben + ;; wurden. Ein Glied ohne Geometrie (z.B. "VF-Einheit nicht baubar" - + ;; Menue-Antwort und Laenge sind journalisiert, gebaut wurde nichts) hat + ;; keinen Traeger fuer seine XDATA. Bliebe der Stand trotzdem stehen, + ;; waere sein Journal-Abschnitt unauffindbar und die Kette waere ab dort + ;; nur noch mit Luecke wiederherstellbar. So wandert der Abschnitt + ;; stattdessen in den naechsten Record, der Entities bekommt. + (if (> cnt 0) (setq *vfl-seg-glied-letzte* seg-idx)) ;; Diagnose: den tatsaechlichen Segment-Journal-Inhalt als JSON loggen ;; (analog zum Ketten-XDATA-JOURNAL-JSON in vfl-journal-xdata-schreiben) ;; plus die Anzahl der beschriebenen Entities. No-Op ohne offene .dbg. - (dbgmsg (strcat "SEGMENT-XDATA-JSON Glied " (itoa seg-idx) " (" - (if slice-label slice-label "?") ") auf " (itoa cnt) " Entity(s): " - (vfl-journal->json seg-journal))) + (dbgmsg (strcat "SEGMENT-XDATA-JSON Glied " (itoa seg-von) + (if (> seg-idx seg-von) (strcat ".." (itoa seg-idx)) "") + " (" (if slice-label slice-label "?") ") auf " (itoa cnt) + " Entity(s): " (vfl-journal->json seg-journal))) ;; Zusaetzlich benannt loggen (statt roher [INT]/[STR]-Zeilen). Feste ;; Glieder (AS/ES/GF-Bogen/Vario-Kurve) ueber ihr Feld-Schema ;; (GF-Bogen.winkel = 90), die VF-Einheit (Linie-VF/Horizontal-VF, variable ;; Laenge) ueber den Sub-Step-Logger (VF.menue = 4, VF.laenge = ...). Beide ;; validieren, was validierbar ist, und markieren Abweichungen (). ;; Ueber slice-label (echtes Glied), nicht wahl. + ;; Bewusst log-slice (genau EIN Glied) - die Schema-Logger erwarten die + ;; Slice eines einzelnen Glieds, nicht den Iterations-Abschnitt. (if (vfl-schema-felder slice-label) - (vfl-schema-log-slice slice-label seg-journal) + (vfl-schema-log-slice slice-label log-slice) (if (member slice-label '("Linie-VF" "Horizontal-VF")) - (vfl-schema-log-vf slice-label seg-journal))) + (vfl-schema-log-vf slice-label log-slice))) ) (dbgmsg (strcat "SEGMENT-XDATA: kein Glied vorhanden (" (if wahl wahl "?") ")")) ) @@ -1465,7 +1543,8 @@ ;; zur Lesequelle, *vfl-journal* startet leer und wird bei der erneuten ;; Ausfuehrung neu aufgebaut. Genutzt von vfl-edit-ent und der Wiederaufnahme. (defun vfl-journal-replay-start (forward-journal) - (setq *vfl-replay-queue* forward-journal *vfl-journal* '()) + (setq *vfl-replay-queue* forward-journal *vfl-journal* '() + *vfl-seg-glied-letzte* 0) (if (boundp '*vflw-pending*) (setq *vflw-pending* nil))) ;; --- Glied-Zerlegung fuer den Editier-Dialog --- @@ -1507,6 +1586,34 @@ (started (setq out (cons e out)))))) (reverse out)) +;; Journal-Eintraege AB dem (from-step-idx)-ten Glied bis zum ENDE des +;; Journals (alle folgenden STEPs inklusive). Gegenstueck zu +;; vfl-journal-slice, das bei genau einem Glied stoppt. +;; Gebraucht fuer die Segment-XDATA: eine Iteration der Bau-Hauptschleife kann +;; MEHRERE Glieder erzeugen (eine VF-Einheit mit eingebetteten Vario-Kurven +;; legt Horizontal-VF/Linie-VF + je Kurve ein eigenes STEP ab). Auf die +;; Entities dieser Iteration muss deshalb der GESAMTE in ihr entstandene +;; Journal-Abschnitt, nicht nur die Slice des letzten Glieds - sonst fehlen +;; die Eingaben der Einheit selbst und die Kette ist aus der Zeichnung nicht +;; mehr vollstaendig rekonstruierbar (c:VF_SEKTION_RESTORE). +(defun vfl-journal-ab-glied (forward-journal from-step-idx / seen out started) + (setq seen 0 out '() started nil) + (foreach e forward-journal + (if started + (setq out (cons e out)) + (if (= (car e) "STEP") + (progn + (setq seen (1+ seen)) + (if (= seen from-step-idx) + (progn (setq started t) (setq out (cons e out)))))))) + (reverse out)) + +;; Anzahl der Glieder (STEP-Eintraege) in einem Journal-Abschnitt. +(defun vfl-steps-zaehlen (journal / n) + (setq n 0) + (foreach e journal (if (= (car e) "STEP") (setq n (1+ n)))) + n) + ;; Journal-Eintraege des Glieds (seg-idx) durch (new-seg-journal) ersetzen - ;; alle anderen Glieder (davor UND danach) sowie die Praeambel bleiben ;; unveraendert. Gegenstueck zu vfl-journal-slice (welches genau dieses Glied @@ -3167,9 +3274,16 @@ ;; geschlossen (Undo-Gruppe, gesicherte Systemvariablen, *error* aus dem ;; Sitzungs-Frame) - sonst bliebe die von ssg-start geoeffnete Undo-Gruppe ;; offen. + ;; *ssg-ils-dim*: der Editier-/Konverter-Pfad setzt vor dem Replay einen + ;; Dimensions-Override und raeumt ihn NACH der Rueckkehr wieder ab. Bei einem + ;; Abbruch kehrt der Aufruf nie dorthin zurueck (der Handler beendet den + ;; Befehl), daher MUSS der Override hier zurueckgesetzt werden - sonst bliebe + ;; er fuer den Rest der Sitzung stehen und alle folgenden Einfuegungen liefen + ;; in der falschen Dimension. (setq *error* (function (lambda (msg) (setq *error* old-error) + (setq *ssg-ils-dim* nil) (vfl-modus-abbruch-sichern lastEnt vfl-nummer anzahl-gf anzahl-vf startpunkt frame as-seite es-seite "linienzug") (if dbg-an @@ -4191,7 +4305,18 @@ 'vf-linienzug-modus2 'vf-linienzug-modus))) (setq *ssg-ils-dim* nil) ; Override zuruecksetzen - (if (vl-catch-all-error-p ok) nil T)) + ;; Fehlgeschlagene Konvertierung NICHT stumm verschlucken: der alte Block + ;; ist per entdel schon weg, die Teil-Geometrie liegt frei in der + ;; Zeichnung (der *error*-Handler in vf-linienzug-modus kann hier nicht + ;; greifen, weil vl-catch-all-apply den Abbruch vorher abfaengt - das ist + ;; hier gewollt, damit die Batch-Schleife weiterlaeuft). Meldung mit + ;; Blockname, damit der betroffene Block auffindbar bleibt. + (if (vl-catch-all-error-p ok) + (progn + (princ (ssg-textf "vfl-konvert-fehler" + (list bname (vl-catch-all-error-message ok)))) + nil) + T)) nil)) (defun vfl-edit-ent (ent / xd marker journal glieder glieder-alle has-as n i pos trunc edit-modus dim) @@ -4247,7 +4372,20 @@ ;; Override auf die Dimension des Bestandsblocks, danach zuruecksetzen. (if dim (setq *ssg-ils-dim* dim)) (vfl-journal-replay-start trunc) - (vl-catch-all-apply 'vf-linienzug-modus) + ;; WICHTIG: DIREKTER Aufruf, KEIN vl-catch-all-apply! + ;; Der Neuaufbau ist interaktiv - bricht der Nutzer ihn ab (ESC -> + ;; (exit) im Bau-Ablauf), MUSS der *error*-Handler in + ;; vf-linienzug-modus laufen und die bis dahin gebaute Teil-Geometrie + ;; zu einem VF_n-Block wickeln. Ein vl-catch-all-apply faengt den + ;; Abbruch VOR *error* ab: der Handler kaeme nie zum Zug, der alte + ;; Block ist durch das entdel oben aber schon weg - die ganze Kette + ;; bliebe als loses Einzelteil-Haufen ohne Block in der Zeichnung + ;; liegen (nicht mehr per Doppelklick editierbar). Genau das war der + ;; Fehler "VF-Block aufgebrochen". + ;; Das Abraeumen des Dim-Overrides uebernimmt im Abbruchfall der + ;; Handler selbst (dort ebenfalls (setq *ssg-ils-dim* nil)), denn + ;; die naechste Zeile wird dann nicht mehr erreicht. + (vf-linienzug-modus) (setq *ssg-ils-dim* nil))))) (princ)) @@ -4265,10 +4403,154 @@ (princ (ssg-text "vfl-edit2-reset-info")) (if dim (setq *ssg-ils-dim* dim)) (vfl-journal-replay-start journal) - (vl-catch-all-apply 'vf-linienzug-modus2) + ;; DIREKTER Aufruf, KEIN vl-catch-all-apply - identische Begruendung wie im + ;; Sektions-Zweig von vfl-edit-ent (siehe dortiger Kommentar): der alte Block + ;; ist per entdel schon weg, bei einem Abbruch muss der *error*-Handler von + ;; vf-linienzug-modus2 die Teil-Geometrie wickeln. Den Dim-Override raeumt im + ;; Abbruchfall der Handler ab. + (vf-linienzug-modus2) (setq *ssg-ils-dim* nil) (princ)) +;; ============================================================ +;; RECOVERY: Kette aus der Sektions-XDATA der Zeichnung neu aufbauen +;; ============================================================ +;; Wofuer: bleibt eine Linienzug-Kette als LOSE Geometrie ohne VF_n-Block in +;; der Zeichnung liegen (der Block war schon per entdel weg, der Neuaufbau +;; wurde abgebrochen und konnte nicht gewickelt werden), ist sie nicht mehr per +;; Doppelklick editierbar. Die Eingaben sind aber nicht verloren: jedes Entity +;; traegt den Journal-Abschnitt der Iteration, in der es entstand +;; (SSG_VF_EDIT_SEG, indiziert mit dem ERSTEN Glied-Index darin - siehe +;; vfl-segment-xdata-sichern), und die Entities der ersten Iteration +;; zusaetzlich die Praeambel (SSG_VF_EDIT_PRE). Daraus laesst sich das +;; Ketten-Journal zusammensetzen und die Kette identisch neu bauen - diesmal +;; sauber als VF_n-Block mit Ketten-XDATA. +;; +;; Quelle ist AUSSCHLIESSLICH die Zeichnung selbst. Die .dbg-Dateien sind +;; reine Ausgabe und werden hier bewusst NICHT gelesen (sie werden bei jedem +;; Lauf neu angelegt, siehe dbgopen). +;; +;; Ablauf: Geometrie waehlen -> Sektionen sammeln und nach Glied-Index sortieren +;; -> Journal (Praeambel + Glieder 1..k) stumm abspielen -> danach normal +;; weiterbauen. Die alte Geometrie wird erst NACH einem erfolgreichen Neuaufbau +;; geloescht (bricht der Neuaufbau ab, bleibt sie samt ihrer XDATA stehen und +;; der Versuch ist wiederholbar). + +;; Praeambel interaktiv erfragen - nur fuer Altbestand ohne SSG_VF_EDIT_PRE +;; (Ketten, die vor der Einfuehrung der Praeambel-XDATA gebaut wurden). +;; Reihenfolge/Arten MUESSEN dem Kopf von vf-linienzug-modus entsprechen: +;; PT (Startpunkt), REAL (Starthoehe), STR (AS ja="1"/nein="2") und bei AS +;; zusaetzlich STR (Winkel "30"/"90") + STR (Seite links="1"/rechts="2"). +;; Rueckgabe: Praeambel-Journal oder nil (Abbruch). +(defun vfl-praeambel-erfragen ( / p h as w s out) + (princ (ssg-text "vfl-restore-keine-praeambel")) + (setq p (getpoint (ssg-text "vfl-prompt-startpunkt-kette"))) + (if (null p) + nil + (progn + (setq h (getreal (ssg-textf "vfl-prompt-hoehe-startpunkt-kette" + (list (rtos (caddr p) 2 1))))) + (if (null h) (setq h (caddr p))) + (initget "Ja Nein") + (setq as (getkword (ssg-text "vfl-restore-frage-as"))) + (if (null as) (setq as "Ja")) + (setq out (list (cons "PT" p) (cons "REAL" h) + (cons "STR" (if (= as "Nein") "2" "1")))) + (if (/= as "Nein") + (progn + ;; gleiche Frage wie im Bau-Ablauf (liefert "30"/"90") + (setq w (vf-frage-element-winkel "vf-winkel-aus-header")) + (initget "Links Rechts") + (setq s (getkword (ssg-text "vfl-restore-frage-as-seite"))) + (if (null s) (setq s "Links")) + (setq out (append out (list (cons "STR" w) + (cons "STR" (if (= s "Rechts") "2" "1"))))))) + out))) + +;; Sektionen aus einer Auswahl sammeln. Rueckgabe: Liste (idx . slice), +;; aufsteigend nach idx, jeder Index nur EINMAL (alle Entities eines Gliedes +;; tragen dieselbe Slice). +(defun vfl-sektionen-sammeln (ss / i n ent seg idx out) + (setq out '() i 0 n (sslength ss)) + (while (< i n) + (setq ent (ssname ss i)) + (setq seg (vfl-journal-xdata-lesen-seg ent)) + (if seg + (progn + (setq idx (car seg)) + (if (not (assoc idx out)) (setq out (cons (cons idx (cdr seg)) out))))) + (setq i (1+ i))) + (vl-sort out (function (lambda (a b) (< (car a) (car b)))))) + +;; Praeambel aus der Auswahl lesen (erstes Entity, das eine traegt). +(defun vfl-praeambel-sammeln (ss / i n pre) + (setq i 0 n (sslength ss) pre nil) + (while (and (< i n) (null pre)) + (setq pre (vfl-journal-xdata-lesen-pre (ssname ss i))) + (setq i (1+ i))) + pre) + +(defun c:VF_SEKTION_RESTORE ( / ss sektionen pre journal teile k erwartet luecke + i n sek e alt-liste) + (princ (ssg-text "vfl-restore-prompt-auswahl")) + (setq ss (ssget)) + (cond + ((null ss) (princ (ssg-text "vfl-abgebrochen"))) + ((null (setq sektionen (vfl-sektionen-sammeln ss))) + (princ (ssg-text "vfl-restore-keine-sektionen"))) + (t + ;; Sektionen aneinanderhaengen, solange sie LUECKENLOS ab Glied 1 + ;; anschliessen. Ein Sektions-Record ist mit dem Index seines ERSTEN + ;; Gliedes abgelegt und kann mehrere Glieder enthalten (VF-Einheit mit + ;; Vario-Kurven) - der naechste erwartete Index ist daher + ;; erster-Index + Anzahl der Glieder darin, nicht einfach +1. + ;; Bei einer Luecke wird nur der Anfang wiederhergestellt: ein fehlendes + ;; Glied in der Mitte wuerde alle folgenden an die falsche Position setzen. + (setq teile '() k 0 erwartet 1 luecke nil) + (foreach sek sektionen + (if (and (not luecke) (= (car sek) erwartet)) + (progn + (setq teile (cons (cdr sek) teile)) + (setq k (+ k (vfl-steps-zaehlen (cdr sek)))) + (setq erwartet (1+ k))) + (setq luecke t))) + (if luecke + (princ (ssg-textf "vfl-restore-luecke" (list (itoa erwartet) (itoa k))))) + (if (= k 0) + (princ (ssg-text "vfl-restore-keine-sektionen")) + (progn + ;; Praeambel: aus der Zeichnung, sonst erfragen (Altbestand ohne + ;; SSG_VF_EDIT_PRE). + (setq pre (vfl-praeambel-sammeln ss)) + (if (null pre) (setq pre (vfl-praeambel-erfragen))) + (if (null pre) + (princ (ssg-text "vfl-abgebrochen")) + (progn + (setq journal (apply 'append (cons pre (reverse teile)))) + (princ (ssg-textf "vfl-restore-gefunden" + (list (itoa k) (itoa (length journal))))) + ;; Enames der alten Geometrie merken - geloescht wird ERST nach + ;; einem erfolgreichen Neuaufbau (siehe unten). + (setq alt-liste '() i 0 n (sslength ss)) + (while (< i n) + (setq alt-liste (cons (ssname ss i) alt-liste)) + (setq i (1+ i))) + ;; Neu bauen. DIREKTER Aufruf: bricht der Bau ab, wickelt der + ;; *error*-Handler in vf-linienzug-modus den Zwischenstand zu + ;; einem Block - und die Zeilen danach (Loeschen) laufen NICHT + ;; mehr. Die alte Geometrie samt ihrer Sektions-XDATA bleibt also + ;; erhalten und der Versuch ist wiederholbar. + (vfl-journal-replay-start journal) + (vf-linienzug-modus) + ;; Erfolg: alte lose Geometrie entfernen. Sie liegt VOR lastEnt und + ;; ist deshalb nicht im neuen Block gelandet (vgl. + ;; vfl-block-erstellen), wuerde aber deckungsgleich darunter + ;; liegenbleiben. + (foreach e alt-liste (if e (entdel e))) + (princ (ssg-textf "vfl-restore-geloescht" + (list (itoa (length alt-liste))))))))))) + (princ)) + ;; DCL-Dialog nach Doppelklick: Editier-Modus waehlen. ;; n = Anzahl Glieder (nur fuer die Kopfzeile). Vorbelegung "rueck" (das ;; bisherige Verhalten, geringste Ueberraschung). Rueckgabe: "rueck", "glied" @@ -5310,9 +5592,13 @@ ;; dbg-Hook selbst) und uebernehmen das dbgclose gleich mit, sonst wuerde ;; bei einem Abbruch ab hier doppelt geschlossen. (setq old-error dbg-old-error) + ;; *ssg-ils-dim* hier zuruecksetzen - Begruendung siehe gleichlautende Stelle + ;; im Handler von vf-linienzug-modus (Abbruch kehrt nie zum Aufrufer zurueck, + ;; der den Override abraeumen wuerde). (setq *error* (function (lambda (msg) (setq *error* old-error) + (setq *ssg-ils-dim* nil) (vfl-modus-abbruch-sichern lastEnt vfl-nummer anzahl-gf anzahl-vf startpunkt frame as-seite es-seite "linienzug2") (if dbg-an diff --git a/doc/variofoerderer.md b/doc/variofoerderer.md index ab7c674..0b744fd 100644 --- a/doc/variofoerderer.md +++ b/doc/variofoerderer.md @@ -377,6 +377,44 @@ interaktive Linienzug-Ablauf weiter (Abschnitt 5). Einzige Eingabe — Rest laeuft automatisch (Attribute aggregiert, Luecken werden gemeldet). +**VF_SEKTION_RESTORE — lose Kette aus der Zeichnung wiederherstellen** + +| Feld | Steuerelement | Werte | +|---|---|---| +| Lose Linienzug-Geometrie | Objektauswahl (`ssget`) | die Einzelteile der Kette (Bloecke, Linien, Boegen) | +| Startpunkt / Starthoehe / AS | nur bei Altbestand ohne Praeambel-XDATA | `getpoint` / `getreal` / Ja-Nein + Winkel + Seite | + +Wofuer: bleibt eine Kette als **lose Geometrie ohne `VF_n`-Block** liegen (der +Block war beim Editieren schon per `entdel` weg, der Neuaufbau brach ab und +konnte nicht gewickelt werden), ist sie nicht mehr per Doppelklick editierbar. +Die Eingaben stecken aber weiterhin in der Zeichnung: + +| XDATA-App | Traeger | Inhalt | +|---|---|---| +| `SSG_VF_EDIT` | `VF_n`-Block | volles Ketten-Journal (Marker `linienzug`/`linienzug2`) | +| `SSG_VF_EDIT_SEG` | jedes Entity | Journal-Abschnitt **der Iteration**, in der es entstand, indiziert mit dem **ersten** Glied-Index darin | +| `SSG_VF_EDIT_PRE` | Entities des ersten Gliedes | Praeambel (Startpunkt, Starthoehe, AS ja/nein + Winkel/Seite) | + +`VF_SEKTION_RESTORE` liest die Sektionen der Auswahl, haengt sie +lueckenlos ab Glied 1 aneinander (ein Sektions-Record kann **mehrere** Glieder +enthalten — eine VF-Einheit mit eingebetteten Vario-Kurven legt pro Kurve ein +eigenes STEP ab, der naechste erwartete Index ist daher +`erster Index + Anzahl Glieder im Record`), spielt das Journal stumm ab und +baut danach normal weiter. Die alte Geometrie wird **erst nach erfolgreichem** +Neuaufbau geloescht — bricht der Bau ab, bleibt sie samt XDATA stehen und der +Versuch ist wiederholbar. + +Grenzen: nur Modus 1 (Modus 2 schreibt keine Sektions-XDATA); bei einer Luecke +wird nur der lueckenlose Anfang wiederhergestellt und die fehlende Sektion +gemeldet. Ketten, die vor der Umstellung auf Iterations-Abschnitte gebaut +wurden, haben unvollstaendige Sektions-XDATA (eine VF-Einheit hinterliess nur +die Slice ihrer letzten Vario-Kurve) und sind daher nur bis zur ersten Luecke +wiederherstellbar. + +Die `.dbg`-Dateien sind **reine Ausgabe** und werden von keinem Befehl +gelesen — sie werden bei jedem Lauf neu angelegt (`dbgopen` oeffnet mit `"w"`). +Wiederherstellungs-Daten gehoeren ausschliesslich in die XDATA der Zeichnung. + --- ## 8. Legacy-Konsolen-Pfad diff --git a/lang/de_DE.json b/lang/de_DE.json index 6c2392e..7e51b69 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -61,6 +61,15 @@ "vfl-edit-kette-header": "\n\nLinienzug mit %1 Glied(ern):", "vfl-edit-abgespielt": "\n>>> %1 Glied(er) werden abgespielt, %2 zurueckgenommen - danach interaktiv weiter.", "vfl-edit2-reset-info": "\n>>> Linienzug (Modus 2) wird mit den gespeicherten Angaben identisch neu aufgebaut...", + "vfl-konvert-fehler": "\n>>> FEHLER bei der Umwandlung von %1: %2 - der alte Block ist entfernt, die Teil-Geometrie liegt frei in der Zeichnung.", + "vfl-restore-prompt-auswahl": "\nLose Linienzug-Geometrie waehlen (die Sektions-XDATA der Objekte wird ausgelesen):", + "vfl-restore-keine-sektionen": "\n>>> In der Auswahl steckt keine Sektions-XDATA (SSG_VF_EDIT_SEG) - daraus laesst sich keine Kette wiederherstellen.", + "vfl-restore-luecke": "\n>>> WARNUNG: Sektion %1 fehlt in der Auswahl - nur die Glieder 1..%2 werden wiederhergestellt.", + "vfl-restore-gefunden": "\n>>> %1 Sektion(en) gefunden, %2 Journal-Eintraege werden abgespielt.", + "vfl-restore-keine-praeambel": "\n>>> Keine Praeambel-XDATA gefunden (Kette vor deren Einfuehrung gebaut) - Startpunkt, Starthoehe und AS-Element werden jetzt erfragt.", + "vfl-restore-frage-as": "\nAS-Element am Kettenanfang vorhanden? [Ja/Nein] : ", + "vfl-restore-frage-as-seite": "\nAS-Element Seite? [Links/Rechts] : ", + "vfl-restore-geloescht": "\n>>> Neuaufbau fertig - %1 alte lose Entity(s) geloescht.", "omni-alle-winkel": "alle Winkel", "omni-grad": " Grad", "omni-bogen-keine-gefunden": "Keine Boegen fuer %1%2 gefunden.", diff --git a/lang/en_GB.json b/lang/en_GB.json index 82d7fc0..ba8ea98 100644 --- a/lang/en_GB.json +++ b/lang/en_GB.json @@ -61,6 +61,15 @@ "vfl-edit-kette-header": "\n\nChain with %1 segment(s):", "vfl-edit-abgespielt": "\n>>> %1 segment(s) replayed, %2 undone - then continue interactively.", "vfl-edit2-reset-info": "\n>>> Rebuilding this Modus-2 chain identically from the saved inputs...", + "vfl-konvert-fehler": "\n>>> ERROR converting %1: %2 - the old block is gone, the partial geometry is loose in the drawing.", + "vfl-restore-prompt-auswahl": "\nSelect the loose chain geometry (the section XDATA of the objects is read):", + "vfl-restore-keine-sektionen": "\n>>> The selection carries no section XDATA (SSG_VF_EDIT_SEG) - no chain can be restored from it.", + "vfl-restore-luecke": "\n>>> WARNING: section %1 is missing from the selection - only segments 1..%2 will be restored.", + "vfl-restore-gefunden": "\n>>> %1 section(s) found, replaying %2 journal entries.", + "vfl-restore-keine-praeambel": "\n>>> No preamble XDATA found (chain built before it existed) - start point, start height and AS element will be asked now.", + "vfl-restore-frage-as": "\nAS element at the start of the chain? [Ja/Nein] : ", + "vfl-restore-frage-as-seite": "\nAS element side? [Links/Rechts] : ", + "vfl-restore-geloescht": "\n>>> Rebuild finished - %1 old loose entity(s) deleted.", "omni-alle-winkel": "all angles", "omni-grad": " deg", "omni-bogen-keine-gefunden": "No arcs found for %1%2.", diff --git a/tests/testdata/vfl_journal_hm05_abbruch.json b/tests/testdata/vfl_journal_hm05_abbruch.json new file mode 100644 index 0000000..4aa07a6 --- /dev/null +++ b/tests/testdata/vfl_journal_hm05_abbruch.json @@ -0,0 +1 @@ +[{"kind":"PT","value":[3745.1661,556.39254,2000]},{"kind":"REAL","value":2154},{"kind":"STR","value":"1"},{"kind":"STR","value":"90"},{"kind":"STR","value":"1"},{"kind":"STEP","value":"Linie-GF"},{"kind":"STR","value":"1"},{"kind":"DL","value":1555.085752},{"kind":"REAL","value":90},{"kind":"STR","value":"2"},{"kind":"REAL","value":3},{"kind":"STR","value":"3"},{"kind":"STEP","value":"Horizontal-VF"},{"kind":"STR","value":"4"},{"kind":"DL","value":4299.683981},{"kind":"STR","value":"2"},{"kind":"STR","value":"2"},{"kind":"STR","value":"2"},{"kind":"STR","value":"2"},{"kind":"STR","value":"2"},{"kind":"STEP","value":"Vario-Kurve"},{"kind":"INT","value":90},{"kind":"STR","value":"2"},{"kind":"STR","value":"2"},{"kind":"STR","value":"2"},{"kind":"STR","value":"1"},{"kind":"DL","value":1273.577478},{"kind":"STR","value":"2"},{"kind":"STR","value":"2"},{"kind":"STR","value":"2"},{"kind":"STR","value":"2"},{"kind":"STEP","value":"Vario-Kurve"},{"kind":"INT","value":90},{"kind":"STR","value":"2"},{"kind":"STR","value":"2"},{"kind":"STR","value":"1"},{"kind":"STR","value":"2"},{"kind":"STR","value":"1"},{"kind":"STEP","value":"Linie-GF"},{"kind":"STR","value":"2"},{"kind":"DL","value":959.99952},{"kind":"STR","value":"2"},{"kind":"REAL","value":3},{"kind":"STR","value":"3"},{"kind":"STEP","value":"Linie-VF"},{"kind":"STR","value":"3"},{"kind":"DL","value":3160},{"kind":"REAL","value":2345},{"kind":"STEP","value":"Linie-VF"},{"kind":"STR","value":"3"},{"kind":"DL","value":412.867603},{"kind":"STEP","value":"Linie-VF"},{"kind":"STR","value":"3"},{"kind":"DL","value":1900},{"kind":"REAL","value":2350},{"kind":"STEP","value":"Linie-GF"},{"kind":"STR","value":""}]