From 82ce795b53c6b756fe466c3e570f4b5340c2a0bb Mon Sep 17 00:00:00 2001 From: Michael Stangl Date: Tue, 25 Aug 2026 22:06:17 +0200 Subject: [PATCH] Linienzug: Abbruch wickelt Teil-Geometrie statt sie zu loeschen; Editieren per DCL-Dialog Abbruch (ESC) im Linienzug-Baumodus loescht die bereits eingefuegte Geometrie nicht mehr, sondern wickelt sie wie ein fertiger Bau zu einem VF_n-Block und schreibt das volle Eingabe-Journal als XDATA drauf (vfl-modus-abbruch-sichern, ersetzt das bisherige Loesch-Rollback). Die Teil-Kette bleibt damit stehen und ist sofort per Doppelklick weiter editierbar/fortsetzbar - unabhaengig davon, ob der Abbruch beim frischen Bauen oder mitten in einem Editier-Neuaufbau passiert. Der bisherige Menuepunkt "Letzten Abbruch fortsetzen" (Session-Variable) entfaellt dadurch ersatzlos. vfl-edit-ent (Doppelklick-Editieren) fragt die Sektion, auf die zurueckgesetzt werden soll, jetzt per neuem DCL-Dialog ab (dcl/vfl_edit.dcl, vfl-dlg-position: Combobox 1..N + OK/Abbrechen) statt per Text-Prompt. Vorbelegung auf die letzte Sektion, damit Doppelklick + sofort OK einen abgebrochenen Bau nahtlos fortsetzt. Die *error*-Handler-Installation wandert vor den allerersten Prompt (vorher: nach Startpunkt/AS-Frage), damit ein ESC in diesem Fenster nicht mehr auf den ungeschuetzten vorherigen Handler faellt. Das Wickeln im Abbruch-Pfad ist per vl-catch-all-apply abgesichert, da vfl-block-erstellen intern einen BKS-Wechsel per (command "_.UCS" ...) macht. Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 3 +- Lisp/vf_core.lsp | 11 +-- Lisp/vf_linienzug.lsp | 202 ++++++++++++++++++++++++------------------ dcl/vfl_edit.dcl | 26 ++++++ lang/de_DE.json | 15 ++-- lang/en_GB.json | 15 ++-- 6 files changed, 164 insertions(+), 108 deletions(-) create mode 100644 dcl/vfl_edit.dcl diff --git a/CLAUDE.md b/CLAUDE.md index fc945ae..e47713e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -93,7 +93,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 | Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standard- UND Etage-Typ: Werteingabe per DCL-Dialog (`vfs-standard-dialog-ablauf` in vf_standard.lsp bzw. `vfe-etage-dialog-ablauf` in vf_etage.lsp, beide nutzen dieselben Dialoge `vfs-dialog-eingabe-basis`/`vfs-dialog-winkel-verteilung`); Doppelklick auf VF_n-Block ruft VARIOFOERDERER_EDIT, das per SSG_VF_EDIT-XDATA-Marker ("standard"/"etage") in den passenden Neuaufbau-Zweig dispatcht (`vfe-edit-ent` fuer Etage); Linienzug-/Altbestand-Bloecke ohne Marker werden abgewiesen; `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) | +| `VarioFoerderer.lsp` (Wrapper fuer `vf_core.lsp`/`vf_standard.lsp`/`vf_etage.lsp`/`vf_linienzug.lsp`) | FOERDERANLAGE, VARIOFOERDERER_EDIT, VARIOFOERDERER_NACHRUESTEN, Vario_Kette_Merge | Vario-Foerderanlagen Generator (Typen Standard/Etage/Linienzug); Standard- UND Etage-Typ: Werteingabe per DCL-Dialog (`vfs-standard-dialog-ablauf` in vf_standard.lsp bzw. `vfe-etage-dialog-ablauf` in vf_etage.lsp, beide nutzen dieselben Dialoge `vfs-dialog-eingabe-basis`/`vfs-dialog-winkel-verteilung`); 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. `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) und baut danach interaktiv weiter; `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) | | `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 | @@ -113,6 +113,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `sprache.dcl` | SSG_SPRACHE (SSG_LIB_Commands.lsp) | | `tro_insert.dcl` | TRO_INSERT (Tro_Edit.lsp) | | `tro_edit.dcl` | TRO_EDIT (Tro_Edit.lsp) | +| `vfl_edit.dcl` | Linienzug-Editieren/Fortsetzen (vf_linienzug.lsp, `vfl-dlg-position`, aufgerufen aus `vfl-edit-ent`) | ## Menue (SSG_LIB.mnu + SSG_LIB.mnl) diff --git a/Lisp/vf_core.lsp b/Lisp/vf_core.lsp index 5f30c50..072bb2e 100644 --- a/Lisp/vf_core.lsp +++ b/Lisp/vf_core.lsp @@ -1273,18 +1273,15 @@ (princ "\n 1 - Manuelle Eingabe (Punkte klicken)") (princ "\n 2 - 3D-Objekte + Ziel-Hoehe (Randwert-Solver, fertig)") (princ "\n 3 - 3D-Objekte stueckweise (Vorwaerts-Nachbau, in Arbeit)") - ;; Option 4 nur anbieten, wenn ein abgebrochener Linienzug fortsetzbar ist. - (if (and (boundp '*vfl-journal-letzter-abbruch*) *vfl-journal-letzter-abbruch*) - (princ (ssg-text "vfc-linienzug-modus-fortsetzen"))) - (setq wahl (getint "\nIhre Wahl (1/2/3/4) [1]: ")) + (setq wahl (getint "\nIhre Wahl (1/2/3) [1]: ")) ;; Konsolen-Nummer -> interne Funktion: ;; 2 = fertiger Ziel-Hoehe-Modus (intern vf-linienzug-modus2) ;; 3 = alter Vorwaerts-Nachbau (intern vf-linienzug-modus3, wird umgebaut) - ;; 4 = zuletzt abgebrochene Kette fortsetzen (Replay + interaktiv weiter) - ;; 1/Default = frische manuelle Eingabe (Journal vorher zuruecksetzen) + ;; 1/Default = frische manuelle Eingabe (Journal vorher zuruecksetzen). Ein + ;; abgebrochener Bau bleibt als VF_n-Block stehen und wird per Doppelklick + ;; fortgesetzt/editiert (vfl-edit-ent), kein separater Menuepunkt noetig. (cond ((= wahl 2) (vf-linienzug-modus2)) ((= wahl 3) (vf-linienzug-modus3)) - ((= wahl 4) (vfl-modus-fortsetzen)) (t (vfl-journal-reset) (vf-linienzug-modus))) (exit) ) diff --git a/Lisp/vf_linienzug.lsp b/Lisp/vf_linienzug.lsp index 39cb48f..dbb40ae 100644 --- a/Lisp/vf_linienzug.lsp +++ b/Lisp/vf_linienzug.lsp @@ -132,7 +132,7 @@ ;; *vfl-journal* wird in UMGEKEHRTER Reihenfolge gehalten (neuestes zuerst, cons). (defun vfl-journal-reset () - (setq *vfl-journal* '() *vfl-replay-queue* nil *vfl-edit-orig-ent* nil)) + (setq *vfl-journal* '() *vfl-replay-queue* nil)) ;; Eintrag anhaengen (vorn, da Reverse-Reihenfolge). (defun vfl-journal-record (kind val) @@ -285,33 +285,44 @@ (vfl-string->journal (apply 'strcat (cdr xd))) nil)) -;; --- Abbruch-Rollback --- -;; Alle nach lastEnt erzeugten Entities loeschen (Transaktions-Rollback der -;; Teil-Geometrie) und das Journal der vollstaendig abgeschlossenen Glieder -;; (*vfl-journal-commit*) fuer die Wiederaufnahme sichern. Aufgerufen aus dem -;; *error*-Handler von vf-linienzug-modus. -(defun vfl-modus-cleanup (lastEnt / e nxt cnt) +;; --- Abbruch-Sicherung --- +;; Alle nach lastEnt erzeugten Entities werden NICHT geloescht, sondern +;; GENAUSO wie beim erfolgreichen Abschluss (vfl-block-erstellen) zu einem +;; neuen VF_n-Block gewickelt, mit dem VOLLEN aktuellen Eingabe-Journal +;; (inkl. des angefangenen, noch unfertigen letzten Gliedes) als XDATA. Die +;; Geometrie bleibt in der Zeichnung stehen und ist sofort per Doppelklick +;; weiter editierbar/fortsetzbar (vfl-edit-ent) - unabhaengig davon, ob es +;; sich um einen frischen Bau oder einen Editier-Neuaufbau handelte (kein +;; Sonderfall mehr noetig). Aufgerufen aus dem *error*-Handler von +;; vf-linienzug-modus. +(defun vfl-modus-abbruch-sichern (lastEnt vfl-nummer anzahl-gf anzahl-vf + startpunkt frame as-seite es-seite / + e cnt vfl-ins wickel-erg) (setq cnt 0 e (if lastEnt (entnext lastEnt) (entnext))) - (while e - (setq nxt (entnext e)) - (if (not (vl-catch-all-error-p (vl-catch-all-apply 'entdel (list e)))) - (setq cnt (1+ cnt))) - (setq e nxt)) - (if (and (boundp '*vfl-edit-orig-ent*) *vfl-edit-orig-ent*) - ;; EDIT-Abbruch: den beim Edit vorab geloeschten Original-Block - ;; wiederherstellen (entdel ist im laufenden Befehl umkehrbar) und KEIN - ;; Resume anbieten - der Ausgangszustand ist ja komplett zurueck. - (progn - (vl-catch-all-apply 'entdel (list *vfl-edit-orig-ent*)) - (setq *vfl-edit-orig-ent* nil) - (princ (ssg-textf "vfl-abbruch-edit" (list (itoa cnt))))) - ;; FRESH/RESUME-Abbruch: Journal der abgeschlossenen Glieder fuer die - ;; Wiederaufnahme sichern. - (if *vfl-journal-commit* - (progn - (setq *vfl-journal-letzter-abbruch* (reverse *vfl-journal-commit*)) - (princ (ssg-textf "vfl-abbruch-resume" (list (itoa cnt))))) - (princ (ssg-textf "vfl-abbruch-simpel" (list (itoa cnt)))))) + (while e (setq cnt (1+ cnt)) (setq e (entnext e))) + (cond + ((or (= cnt 0) (null frame)) + (princ (ssg-text "vfl-abbruch-nichts-gebaut"))) + (t + ;; vfl-block-erstellen nutzt intern (command "_.UCS" ...) fuer den + ;; BKS-Wechsel (ssg-block-wrap-welt) - im *error*-Handler-Kontext + ;; riskanter als eine einfache Loesch-Schleife, daher abgesichert. + (setq wickel-erg + (vl-catch-all-apply + (function (lambda () + (setq vfl-ins + (vfl-block-erstellen vfl-nummer anzahl-gf anzahl-vf + (caddr startpunkt) (caddr (car frame)) + (vfl-planar-dist startpunkt (car frame)) + as-seite es-seite startpunkt lastEnt)) + (if vfl-ins (vfl-journal-xdata-schreiben vfl-ins)))) + nil)) + (if (vl-catch-all-error-p wickel-erg) + (princ (ssg-textf "vfl-abbruch-wickeln-fehler" + (list (vl-catch-all-error-message wickel-erg)))) + (princ (ssg-textf "vfl-abbruch-gesichert" (list (itoa cnt))))) + ) + ) (princ)) ;; Replay-Modus scharf schalten: die uebergebene (Vorwaerts-)Journalliste wird @@ -1495,6 +1506,43 @@ (if (or (not *lib-initialized*) (null bogen-auf)) (init-bibliothek)) + ;; --- Abbruch-Sicherung scharf schalten (VOR dem ersten Prompt!) --- + ;; Ab hier kann jederzeit Geometrie entstehen. Ein *error*-Handler faengt + ;; jeden Abbruch (ESC / (exit) / Laufzeitfehler) ab und WICKELT die bereits + ;; eingefuegte Teil-Geometrie (alles nach lastEnt) zu einem VF_n-Block mit + ;; dem vollen aktuellen Eingabe-Journal als XDATA (vfl-modus-abbruch-sichern) + ;; - die Geometrie bleibt stehen und ist per Doppelklick sofort weiter + ;; editierbar/fortsetzbar (kein Rollback mehr, kein separater + ;; "Fortsetzen"-Mechanismus noetig). + ;; Die Installation MUSS vor dem allerersten vfl-in-*-Aufruf erfolgen: ein + ;; echtes ESC (nicht ein leeres Enter) loest bei JEDEM get*-Aufruf sofort + ;; *error* aus (nicht nil) - ohne den Handler wuerde ein ESC in diesem + ;; Fenster auf den vorherigen Handler zurueckfallen (im Editier-Pfad: der + ;; ssg-start-Handler ohne Wickeln - der bereits geloeschte Original-Block + ;; waere dann ersatzlos weg). lastEnt/old-error/vfl-nummer/anzahl-gf/ + ;; anzahl-vf/startpunkt/frame/as-seite/es-seite sind zur Aufrufzeit + ;; dynamisch gebunden und daher im Handler-Lambda sichtbar (AutoLISP + ;; dynamic scoping, gilt fuer die gesamte Laufzeit dieses Aufrufs, auch + ;; tief verschachtelt z.B. in vfl-vf-einheit). + (setq vfl-nummer (vf-next-number)) + (setq lastEnt (vf-lastent-ohne-attribute)) + (setq anzahl-gf 0 anzahl-vf 0 frame nil) + (setq old-error *error*) + ;; Abbruch-Handler: zuerst *error* zuruecksetzen (kein rekursiver + ;; Wiedereintritt bei einem Fehler waehrend des Wickelns), dann wickeln. + ;; Laeuft der Aufruf innerhalb einer ssg-start-Sitzung (Editier-Pfad via + ;; c:VARIOFOERDERER_EDIT -> vfl-edit-ent), wird diese mit ssg-end sauber + ;; geschlossen (Undo-Gruppe, gesicherte Systemvariablen, *error* aus dem + ;; Sitzungs-Frame) - sonst bliebe die von ssg-start geoeffnete Undo-Gruppe + ;; offen. + (setq *error* + (function (lambda (msg) + (setq *error* old-error) + (vfl-modus-abbruch-sichern lastEnt vfl-nummer anzahl-gf anzahl-vf + startpunkt frame as-seite es-seite) + (if (and (boundp '*ssg-start-stack*) *ssg-start-stack*) (ssg-end)) + (princ)))) + (setq startpunkt (vfl-in-point nil (ssg-text "vfl-prompt-startpunkt-kette"))) (if (null startpunkt) (progn (princ (ssg-text "vfl-abgebrochen")) (exit))) ;; Hoehe (Z) des Startpunkts abfragen und in die Z-Koordinate uebernehmen. @@ -1524,29 +1572,6 @@ ;; ES-Seite wird erst am Kettenende abgefragt (siehe vfl-frage-es-seite), ;; da das ES-Element erst dort eingefuegt wird. - (setq vfl-nummer (vf-next-number)) - (setq lastEnt (vf-lastent-ohne-attribute)) - ;; --- Abbruch-Rollback + Wiederaufnahme scharf schalten --- - ;; Ab hier wird Geometrie gebaut. Ein *error*-Handler faengt jeden Abbruch - ;; (ESC / (exit) / Laufzeitfehler) ab, entfernt die bereits eingefuegte - ;; Teil-Geometrie (alles nach lastEnt, siehe vfl-modus-cleanup) und sichert - ;; das Journal der bis dahin VOLLSTAENDIG abgeschlossenen Glieder - ;; (*vfl-journal-commit*) fuer die Wiederaufnahme. lastEnt/old-error sind zur - ;; Aufrufzeit dynamisch gebunden und daher im Handler sichtbar. - (setq *vfl-journal-commit* nil) - (setq old-error *error*) - ;; Abbruch-Handler: zuerst *error* zuruecksetzen (kein rekursiver Wiedereintritt - ;; bei einem Cleanup-Fehler), dann Teil-Geometrie zuruecknehmen. Laeuft der - ;; Aufruf innerhalb einer ssg-start-Sitzung (Edit-Pfad via c:VARIOFOERDERER_EDIT - ;; -> vfl-edit-ent), wird diese mit ssg-end sauber geschlossen (Undo-Gruppe, - ;; gesicherte Systemvariablen, *error* aus dem Sitzungs-Frame) - sonst bliebe - ;; die von ssg-start geoeffnete Undo-Gruppe offen. - (setq *error* - (function (lambda (msg) - (setq *error* old-error) - (vfl-modus-cleanup lastEnt) - (if (and (boundp '*ssg-start-stack*) *ssg-start-stack*) (ssg-end)) - (princ)))) (setq p-aktuell startpunkt) (setq letzter-typ nil fertig nil frame nil) (setq anzahl-gf 0 anzahl-vf 0) @@ -1568,11 +1593,6 @@ ;; nutzt weiterhin vfl-segment-entscheidung). (princ (ssg-text "vfl-naechstes-element-header")) (setq linie-ende-modus nil) - ;; Commit-Schnappschuss: Journalstand NACH dem letzten vollstaendig - ;; abgeschlossenen Glied (vor dem Marker der neuen, noch offenen Iteration). - ;; Bei Abbruch wird genau dieser Stand als Wiederaufnahme-Journal gesichert - ;; (das angefangene Glied faellt weg). - (setq *vfl-journal-commit* *vfl-journal*) ;; Glied-Checkpoint am Iterationskopf setzen; Label wird nach der Auswahl ;; nachgetragen (vfl-journal-steplabel), damit jedes Glied seine eigene ;; Menue-Auswahl + Segment-Eingaben vollstaendig umschliesst (fuer den @@ -1930,12 +1950,8 @@ ;; Eingabe-Journal am fertigen Block persistieren (Marker "linienzug" + ;; Chunks) -> spaeter per Doppelklick editierbar (vfl-edit-ent). (if vfl-ins (vfl-journal-xdata-schreiben vfl-ins)) - ;; Erfolgreicher Abschluss: *error* zuruecksetzen, evtl. offenes Abbruch- - ;; Journal verwerfen (die Kette ist fertiggestellt), Editier-Marker loeschen - ;; (der Original-Block bleibt im Edit-Fall geloescht - der Neuaufbau ersetzt ihn). + ;; Erfolgreicher Abschluss: *error* zuruecksetzen. (setq *error* old-error) - (setq *vfl-journal-letzter-abbruch* nil) - (setq *vfl-edit-orig-ent* nil) (princ "\n\n=========================================") (princ (ssg-text "vfl-kette-eingefuegt")) @@ -1947,11 +1963,14 @@ ;; EDITIEREN: gliedweise zuruecknehmen + Neuaufbau per Replay ;; ============================================================ ;; Aufgerufen aus c:VARIOFOERDERER_EDIT (Doppelklick auf VF_n mit XDATA-Marker -;; "linienzug"). Liest das Eingabe-Journal vom Block, listet die Glieder, laesst -;; k Glieder vom Ende zuruecknehmen, loescht den alten Block und baut die Kette -;; neu: die behaltenen Glieder werden stumm abgespielt, danach laeuft die -;; Eingabe interaktiv fuer die geaenderten/neuen Glieder weiter. -(defun vfl-edit-ent (ent / journal glieder n i k trunc) +;; "linienzug", egal ob fertiggestellt oder durch einen Abbruch gewickelt). +;; Liest das Eingabe-Journal vom Block, listet die Glieder, laesst per +;; DCL-Dialog (vfl-dlg-position) eine Sektion waehlen, auf die zurueckgesetzt +;; wird, loescht den alten Block und baut die Kette neu: die behaltenen +;; Glieder werden stumm abgespielt, danach laeuft die Eingabe interaktiv fuer +;; die geaenderten/neuen Glieder weiter. Vorbelegung im Dialog = voller Stand +;; -> Doppelklick + sofort OK setzt einen abgebrochenen Bau nahtlos fort. +(defun vfl-edit-ent (ent / journal glieder n i pos trunc) (setq journal (vfl-journal-xdata-lesen ent)) (if (null journal) (progn (alert (ssg-text "vfl-edit-kein-journal")) (exit))) @@ -1962,33 +1981,48 @@ (foreach g glieder (princ (strcat "\n " (itoa i) ") " (vfl-glied-label-text g))) (setq i (1+ i))) - (setq k (getint (ssg-textf "vfl-edit-wieviele" (list (itoa n))))) - (if (or (null k) (< k 0)) (setq k 0)) - (if (> k n) (setq k n)) - (setq trunc (vfl-journal-truncate journal (- n k))) + (setq pos (vfl-dlg-position glieder)) + (if (null pos) + (progn (princ (ssg-text "vfl-edit-abgebrochen")) (exit))) + (setq trunc (vfl-journal-truncate journal pos)) ;; Alten Block entfernen (wie Standard/Etage: entdel + kompletter Neuaufbau). - ;; *vfl-edit-orig-ent* merken, damit ein Abbruch waehrend des Neuaufbaus den - ;; Original-Block wiederherstellen kann (vfl-modus-cleanup). - (setq *vfl-edit-orig-ent* ent) + ;; Bricht der Neuaufbau selbst ab, wickelt vfl-modus-abbruch-sichern den + ;; Zwischenstand automatisch zu einem neuen Block - kein Sonderfall noetig. (entdel ent) - (princ (ssg-textf "vfl-edit-abgespielt" (list (itoa (- n k)) (itoa k)))) + (princ (ssg-textf "vfl-edit-abgespielt" (list (itoa pos) (itoa (- n pos))))) ;; Behaltene Glieder abspielen, dann live weiterbauen. (vfl-journal-replay-start trunc) (vf-linienzug-modus) (princ)) -;; Wiederaufnahme des zuletzt abgebrochenen Linienzugs: das beim Abbruch -;; gesicherte Journal abspielen und danach interaktiv weiterbauen. -(defun vfl-modus-fortsetzen ( / ) - (if (and (boundp '*vfl-journal-letzter-abbruch*) *vfl-journal-letzter-abbruch*) +;; DCL-Dialog: Sektion waehlen, auf die die Kette zurueckgesetzt wird. +;; glieder = Liste der Glied-Labels (interne Tokens, vfl-journal-glieder), in +;; Bau-Reihenfolge. Vorbelegung auf den letzten Eintrag (voller Stand = reines +;; Fortsetzen ohne Kuerzung). Rueckgabe: gewaehlte Position (1-basiert) oder +;; nil bei Abbrechen/Escape. +(defun vfl-dlg-position (glieder / n dcl-pfad dat idx ergebnis i) + (setq n (length glieder)) + (setq dcl-pfad (strcat (getenv "DXFM_DCL") "/vfl_edit.dcl")) + (setq dat (load_dialog dcl-pfad)) + (if (not (new_dialog "vfl_edit" dat)) + (progn (alert (ssg-textf "vfl-edit-dialog-fehlt" (list dcl-pfad))) nil) (progn - (princ (ssg-text "vfl-fortsetzen-start")) - (setq *vfl-edit-orig-ent* nil) ; Wiederaufnahme ist kein Edit -> kein Original restaurieren - (vfl-journal-replay-start *vfl-journal-letzter-abbruch*) - (vf-linienzug-modus)) - (progn - (princ (ssg-text "vfl-fortsetzen-keiner")) - (princ)))) + (set_tile "kopf" (ssg-textf "vfl-dlg-kopf-sektionen" (list (itoa n)))) + (start_list "position") + (setq i 1) + (foreach g glieder + (add_list (strcat (itoa i) " - " (vfl-glied-label-text g))) + (setq i (1+ i))) + (end_list) + (set_tile "position" (itoa (1- n))) ; letzter Eintrag vorbelegt (0-basierter Index) + (action_tile "accept" "(setq idx (atoi (get_tile \"position\"))) (done_dialog 1)") + (action_tile "cancel" "(done_dialog 0)") + (setq ergebnis (start_dialog)) + (unload_dialog dat) + (if (= ergebnis 1) (1+ idx) nil) + ) + ) +) ;; ============================================================ ;; DIAGNOSE: Blockstruktur (KS_EIN/KS_AUS) untersuchen diff --git a/dcl/vfl_edit.dcl b/dcl/vfl_edit.dcl new file mode 100644 index 0000000..9f497f4 --- /dev/null +++ b/dcl/vfl_edit.dcl @@ -0,0 +1,26 @@ +// ============================================================ +// vfl_edit.dcl - Linienzug-Kette (VF_n mit XDATA-Marker "linienzug") +// bearbeiten/fortsetzen: Sektion waehlen, auf die zurueckgesetzt wird. +// Aufruf ueber vfl-edit-ent -> vfl-dlg-position (Lisp/vf_linienzug.lsp). +// ============================================================ + +vfl_edit : dialog { + label = "Linienzug editieren"; + + : column { + + : text { + key = "kopf"; + label = ""; + } + + : popup_list { + key = "position"; + label = "Zuruecksetzen zu Sektion:"; + width = 40; + } + + } + + ok_cancel; +} diff --git a/lang/de_DE.json b/lang/de_DE.json index 8317ad2..24312a1 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -54,14 +54,7 @@ "vfl-glied-offen": "(offen)", "vfl-edit-kein-journal": "Dieser Linienzug-Block traegt kein Eingabe-Journal (Altbestand) und kann nicht schrittweise editiert werden.", "vfl-edit-kette-header": "\n\nLinienzug mit %1 Glied(ern):", - "vfl-edit-wieviele": "\n\nWie viele Glieder vom Ende zuruecknehmen? (0..%1) [0]: ", "vfl-edit-abgespielt": "\n>>> %1 Glied(er) werden abgespielt, %2 zurueckgenommen - danach interaktiv weiter.", - "vfl-abbruch-edit": "\n>>> Editieren abgebrochen: %1 neue Teil-Objekt(e) entfernt, Original-Linienzug wiederhergestellt.", - "vfl-abbruch-resume": "\n>>> Linienzug abgebrochen: %1 Teil-Objekt(e) entfernt (Rollback). Menuepunkt 'Letzten Abbruch fortsetzen' spielt die bisherigen Eingaben erneut ab.", - "vfl-abbruch-simpel": "\n>>> Linienzug abgebrochen: %1 Teil-Objekt(e) entfernt.", - "vfl-fortsetzen-start": "\n>>> Setze zuletzt abgebrochenen Linienzug fort (Eingaben werden abgespielt)...", - "vfl-fortsetzen-keiner": "\nKein abgebrochener Linienzug zum Fortsetzen vorhanden.", - "vfc-linienzug-modus-fortsetzen": "\n 4 - Letzten Abbruch fortsetzen (bisherige Eingaben abspielen)", "omni-alle-winkel": "alle Winkel", "omni-grad": " Grad", "omni-bogen-keine-gefunden": "Keine Boegen fuer %1%2 gefunden.", @@ -760,6 +753,12 @@ "tro-insert-hinweis": "Die Blockform muss bereits in der Zeichnung vorhanden sein (aus einem frueheren Lauf von tro_annotate.py).", "tro-insert-kein-block": "Kein Symbol fuer diesen Typ in der Zeichnung (%1) - bitte tro_annotate.py mit diesem Typ laufen lassen.", "tro-insert-prompt-punkt": "\nEinfuegepunkt: ", - "tro-insert-eingefuegt": "\nTRO eingefuegt: ID = %1, TYP = %2" + "tro-insert-eingefuegt": "\nTRO eingefuegt: ID = %1, TYP = %2", + "vfl-abbruch-gesichert": "\n>>> Linienzug abgebrochen: %1 Objekt(e) als Block gesichert (per Doppelklick editierbar/fortsetzbar).", + "vfl-abbruch-nichts-gebaut": "\n>>> Abgebrochen - es wurde noch keine Geometrie erzeugt.", + "vfl-abbruch-wickeln-fehler": "\n>>> FEHLER beim Sichern der Teil-Geometrie als Block: %1", + "vfl-edit-dialog-fehlt": "Dialog nicht gefunden: %1", + "vfl-edit-abgebrochen": "\nEditieren abgebrochen - keine Aenderung.", + "vfl-dlg-kopf-sektionen": "Sektionen: %1" } } diff --git a/lang/en_GB.json b/lang/en_GB.json index 52cf3aa..1c64a1b 100644 --- a/lang/en_GB.json +++ b/lang/en_GB.json @@ -54,14 +54,7 @@ "vfl-glied-offen": "(open)", "vfl-edit-kein-journal": "This chain block carries no input journal (legacy) and cannot be edited step by step.", "vfl-edit-kette-header": "\n\nChain with %1 segment(s):", - "vfl-edit-wieviele": "\n\nHow many segments to undo from the end? (0..%1) [0]: ", "vfl-edit-abgespielt": "\n>>> %1 segment(s) replayed, %2 undone - then continue interactively.", - "vfl-abbruch-edit": "\n>>> Edit cancelled: %1 new partial object(s) removed, original chain restored.", - "vfl-abbruch-resume": "\n>>> Chain cancelled: %1 partial object(s) removed (rollback). Menu item 'Resume last cancellation' replays the previous input.", - "vfl-abbruch-simpel": "\n>>> Chain cancelled: %1 partial object(s) removed.", - "vfl-fortsetzen-start": "\n>>> Resuming last cancelled chain (replaying input)...", - "vfl-fortsetzen-keiner": "\nNo cancelled chain available to resume.", - "vfc-linienzug-modus-fortsetzen": "\n 4 - Resume last cancellation (replay previous input)", "omni-alle-winkel": "all angles", "omni-grad": " deg", "omni-bogen-keine-gefunden": "No arcs found for %1%2.", @@ -760,6 +753,12 @@ "tro-insert-hinweis": "The block shape must already exist in the drawing (from an earlier tro_annotate.py run).", "tro-insert-kein-block": "No symbol for this type in the drawing (%1) - run tro_annotate.py with this type first.", "tro-insert-prompt-punkt": "\nInsertion point: ", - "tro-insert-eingefuegt": "\nTRO inserted: ID = %1, TYPE = %2" + "tro-insert-eingefuegt": "\nTRO inserted: ID = %1, TYPE = %2", + "vfl-abbruch-gesichert": "\n>>> Chain cancelled: %1 object(s) saved as a block (editable/resumable via double-click).", + "vfl-abbruch-nichts-gebaut": "\n>>> Cancelled - no geometry was created yet.", + "vfl-abbruch-wickeln-fehler": "\n>>> ERROR saving the partial geometry as a block: %1", + "vfl-edit-dialog-fehlt": "Dialog not found: %1", + "vfl-edit-abgebrochen": "\nEdit cancelled - no change.", + "vfl-dlg-kopf-sektionen": "Sections: %1" } }