fix: VF-Linienzug 100%-Wiederherstellung aus e76e24e abgeschlossen

Restauriert alles aus e76e24e, das nach dem Reset auf master fehlte oder nur
teilweise wiederhergestellt war, und mit dem Kollegen-Umbau abgeglichen:

- vf_core.lsp: Radio-Button-Dialoge fuer Anlagen-Typ/Linienzug-Modus
  (vfc-dialog-typ-waehlen/-linienzug-modus-waehlen) + Zurueck-Schleife im
  c:VarioFoerderer-Dispatcher
- Vario-Kurve/GF-Bogen-Erkennung am Kettenanfang: vfl-eingang-modus-bestimmen
  threaded durch vfl-vf-eingang-bauen/vfl-vf-einheit/vfl-vf-einheit-abschluss,
  inkl. Punkt-7-Winkel/Hoehen-Tabelle fuer reduzierten Eingang
- Modus 2: Lauf-Anfang/Lauf-Abschluss (offener Anfang/Ende, GF-Verteilung
  "alles Auslauf", Kletter-zu-kurz-Fallback) + Separator VOR/NACH bei
  GF-Geraden
- Systemischer Bug behoben: mehrere Wizard-Dialogfunktionen nutzten noch
  start_list/add_list (Dropdown) gegen laengst auf boxed_radio_column
  umgestellte DCL-Dialoge (vflw-gruppe-as/-gefaelle/-variokurve/
  -winkel-seite-impl, vflw-seg-linie-m2/-m3/-bogen-impl,
  vfl-glied-gf-bogen/-vario/-as-es-dialog)
- Zentraler Abbruch-Trigger in vfl-in-value/-value-p wiederhergestellt (ohne
  ihn wirkte der Zurueck/Abbrechen-Button in keinem Wizard-Dialog)
- vfl-frage-ist-endpunkt/-ist-kettenende als eigene Funktionen mit
  Wizard-Dialog extrahiert (vorher Konsolen-Duplikate ohne Dialog-Hookup)
- 3 vfs-vf-entry-Aufrufe mit falscher Argumentzahl gefixt (akute
  Absturz-Bugs in Modus 2/3)
- Tote Funktion vflw-gruppe-horizontal-impl entfernt (Tiles nicht mehr im
  DCL vorhanden)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-11 18:26:48 +02:00
parent 4a444b4858
commit 0a1d21d8c5
13 changed files with 3106 additions and 654 deletions
+181 -64
View File
@@ -598,9 +598,14 @@
;; "vf-winkel-ein-header"). Rueckgabe: "30" oder "90" (Default 90).
;; Wizard: nutzt vflw-wahl (dcl/vf_linienzug_wizard.dcl, definiert in
;; vf_linienzug.lsp) falls dieses Modul geladen und *vfl-wizard-mode* aktiv
;; ist - sonst (oder bei jedem Fehler) unveraendert die Konsolen-Fragen
;; (princ + getstring, de/en ueber ssg-text). Gemeinsam genutzt von
;; Gefaellestrecke.lsp UND vf_linienzug.lsp.
;; ist - sonst (oder bei jedem Fehler) unveraendert die Konsolen-Frage
;; (getstring, de/en ueber ssg-text). Gemeinsam genutzt von Gefaellestrecke.lsp
;; UND vf_linienzug.lsp. Druckt selbst KEINE Kopfzeile/Optionstexte mehr (das
;; macht immer der AUFRUFER, unconditional, VOR diesem Aufruf) - sonst fehlt
;; die Kopfzeile in der Konsole genau dann, wenn ein vfl-in-value-Wrapper den
;; Wert bereits aus der Pending-Queue/dem Journal-Replay liest und diese
;; Funktion dadurch gar nicht erst aufgerufen wird (Inkonsistenz Dialog vs.
;; Konsole, siehe Aufrufer in vf_linienzug.lsp/Gefaellestrecke.lsp).
(defun vf-frage-element-winkel (headerkey / antwort)
;; Wizard-Dialog nur, wenn Wizard-Modus aktiv, vflw-wahl geladen UND die GUI
;; global nicht abgeschaltet ist (Tests: (ssg-gui-aus)) - sonst Konsole/getstring.
@@ -615,12 +620,7 @@
(if (or (vl-catch-all-error-p antwort) (null antwort) (= antwort ""))
(setq antwort "1"))
)
(progn
(princ (ssg-text headerkey))
(princ (ssg-text "vf-winkel-90"))
(princ (ssg-text "vf-winkel-30"))
(setq antwort (getstring (ssg-text "prompt-wahl-1-2")))
)
(setq antwort (getstring (ssg-text "prompt-wahl-1-2")))
)
(if (= antwort "2") "30" "90"))
@@ -972,7 +972,7 @@
(setq horizontal-info nil)
(if (and horizontal-p (= richtung "Ab"))
(progn
(setq horizontal-info (berechne-horizontale-mitte deltaL deltaH "Ab"))
(setq horizontal-info (berechne-horizontale-mitte deltaL deltaH "Ab" nil))
(if (and horizontal-info (caddr horizontal-info))
(setq ergebnis-liste
(append ergebnis-liste (list (list 0 (car horizontal-info) (cadr horizontal-info) T))))
@@ -1078,6 +1078,94 @@
)
)
;; ============================================================
;; TEIL 11b: DIALOG-AUSWAHL FUER TYP/LINIENZUG-MODUS (Radio-Buttons)
;; ============================================================
;; Ersetzen die beiden Konsolen-Listen am Anfang von c:VarioFoerderer durch
;; Radio-Button-Dialoge (dcl/variofoerderer.dcl, vfc_typ/vfc_linienzug_modus)
;; - alle Optionen sofort sichtbar statt Dropdown. WICHTIG: Radio-Button-
;; Labels sind im DCL fest auf Deutsch einprogrammiert (set_tile kann das
;; Label eines radio_button nicht setzen, nur den Zustand - siehe DCL-
;; Kommentar). Beide Funktionen geben deshalb nur dann etwas anderes als nil
;; zurueck, wenn GUI erlaubt ist (Tests: ssg-gui-aus) UND Deutsch aktiv ist -
;; sonst faellt der Aufrufer automatisch auf die alte, vollstaendig
;; uebersetzte Konsolen-Liste zurueck (unveraendert im Code stehen
;; geblieben). Rueckgabe jeweils: Ergebnis bei OK, 'ABBRUCH bei Cancel, nil
;; wenn der Dialog gar nicht erst gezeigt werden konnte/durfte.
;; "Zurueck" hat an dieser allerersten Frage der ganzen Anlage nichts, wohin es
;; zurueckspringen koennte - wird daher lokal aufgeloest: der Dialog wird
;; einfach erneut gezeigt (kein Sonderfall fuer den Aufrufer noetig).
(defun vfc-dialog-typ-waehlen ( / dcl-pfad dat gtyp ergebnis fertig)
(if (and (or (not (car (atoms-family 1 '("SSG-GUI-P")))) (ssg-gui-p))
(= *ssg-lang* "de_DE")
(equal (mapcar 'car *vf-typ-registry*) '("standard" "etage" "linienzug")))
(progn
(setq fertig nil)
(while (not fertig)
(setq fertig t)
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/variofoerderer.dcl"))
(setq dat (load_dialog dcl-pfad))
(if (not (new_dialog "vfc_typ" dat))
(progn (if (and dat (>= dat 0)) (unload_dialog dat)) (setq ergebnis nil))
(progn
(set_tile "typ_standard" "1")
(action_tile "accept"
"(setq gtyp (cond ((= (get_tile \"typ_etage\") \"1\") \"etage\")
((= (get_tile \"typ_linienzug\") \"1\") \"linienzug\")
(t \"standard\")))
(done_dialog 1)")
(action_tile "cancel" "(done_dialog 0)")
(action_tile "back" "(done_dialog 2)")
(setq ergebnis (start_dialog))
(unload_dialog dat)
(cond
((= ergebnis 1) (setq ergebnis gtyp))
((= ergebnis 2) (setq fertig nil)) ;; Zurueck: Dialog erneut zeigen
(t (setq ergebnis 'ABBRUCH))
)
)
)
)
ergebnis
)
nil
)
)
;; "Zurueck" springt zur Anlagen-Typ-Frage zurueck - Rueckgabe 'ZURUECK, vom
;; Aufrufer (c:VarioFoerderer) ausgewertet (dort erneuter Aufruf von
;; vfc-dialog-typ-waehlen statt hier lokal aufzuloesen).
(defun vfc-dialog-linienzug-modus-waehlen ( / dcl-pfad dat gmodus ergebnis)
(if (and (or (not (car (atoms-family 1 '("SSG-GUI-P")))) (ssg-gui-p))
(= *ssg-lang* "de_DE"))
(progn
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/variofoerderer.dcl"))
(setq dat (load_dialog dcl-pfad))
(if (not (new_dialog "vfc_linienzug_modus" dat))
(progn (if (and dat (>= dat 0)) (unload_dialog dat)) nil)
(progn
(set_tile "modus_1" "1")
(action_tile "accept"
"(setq gmodus (cond ((= (get_tile \"modus_2\") \"1\") 2)
((= (get_tile \"modus_3\") \"1\") 3)
(t 1)))
(done_dialog 1)")
(action_tile "cancel" "(done_dialog 0)")
(action_tile "back" "(done_dialog 2)")
(setq ergebnis (start_dialog))
(unload_dialog dat)
(cond
((= ergebnis 1) gmodus)
((= ergebnis 2) 'ZURUECK)
(t 'ABBRUCH)
)
)
)
)
nil
)
)
;; ============================================================
;; TEIL 12: DISPATCHER c:VarioFoerderer
;; ============================================================
@@ -1088,7 +1176,7 @@
best-winkel L_GF L_GF1 L_GF2 L_VF
idx eintrag wahl antwort verteilung-modus
n-scanner vf-nummer hoehe-von hoehe-bis lastEnt
staustrecke-basis vf-insert)
staustrecke-basis vf-insert dlg-typ dlg-modus zurueck-zu-typ)
(princ "\n=========================================")
(princ (ssg-text "vfc-banner-titel"))
@@ -1102,61 +1190,90 @@
)
)
(if (and *vf-vorauswahl-typ* (assoc *vf-vorauswahl-typ* *vf-typ-registry*))
(progn
(setq typ-eintr (assoc *vf-vorauswahl-typ* *vf-typ-registry*))
(princ (ssg-textf "vfc-typ-vorgewaehlt" (list *vf-vorauswahl-typ*)))
(setq *vf-vorauswahl-typ* nil)
)
(progn
(setq *vf-vorauswahl-typ* nil)
(princ (ssg-text "vfc-anlagen-typ-header"))
(setq idx 1)
(foreach eintr *vf-typ-registry*
(princ (ssg-textf "vfc-typ-option" (list idx (nth 3 eintr))))
(setq idx (1+ idx))
;; Aeussere Schleife nur wegen "Zurueck" bei der Linienzug-Modus-Frage
;; (springt zurueck zur Anlagen-Typ-Frage) - fuer Standard/Etage bleibt
;; zurueck-zu-typ immer nil, die Schleife laeuft dann genau einmal.
(setq zurueck-zu-typ t)
(while zurueck-zu-typ
(setq zurueck-zu-typ nil)
(if (and *vf-vorauswahl-typ* (assoc *vf-vorauswahl-typ* *vf-typ-registry*))
(progn
(setq typ-eintr (assoc *vf-vorauswahl-typ* *vf-typ-registry*))
(princ (ssg-textf "vfc-typ-vorgewaehlt" (list *vf-vorauswahl-typ*)))
(setq *vf-vorauswahl-typ* nil)
)
(progn
(setq *vf-vorauswahl-typ* nil)
(setq dlg-typ (vfc-dialog-typ-waehlen))
(cond
((eq dlg-typ 'ABBRUCH) (exit))
(dlg-typ (setq typ-eintr (assoc dlg-typ *vf-typ-registry*)))
(t
;; Dialog nicht verfuegbar/nicht erlaubt (GUI aus, andere Sprache,
;; abweichende Registry) - alte Konsolen-Liste unveraendert.
(princ (ssg-text "vfc-anlagen-typ-header"))
(setq idx 1)
(foreach eintr *vf-typ-registry*
(princ (ssg-textf "vfc-typ-option" (list idx (nth 3 eintr))))
(setq idx (1+ idx))
)
(setq wahl (getint (ssg-textf "vfc-prompt-wahl-1-n"
(list (length *vf-typ-registry*)))))
(if (or (null wahl) (< wahl 1) (> wahl (length *vf-typ-registry*)))
(setq wahl 1))
(setq typ-eintr (nth (1- wahl) *vf-typ-registry*))
)
)
)
(setq wahl (getint (ssg-textf "vfc-prompt-wahl-1-n"
(list (length *vf-typ-registry*)))))
(if (or (null wahl) (< wahl 1) (> wahl (length *vf-typ-registry*)))
(setq wahl 1))
(setq typ-eintr (nth (1- wahl) *vf-typ-registry*))
)
)
(setq anlage-typ (nth 0 typ-eintr))
(setq berechne-fn (nth 1 typ-eintr))
(setq einfuege-fn (nth 2 typ-eintr))
(princ (ssg-textf "vfc-typ-gewaehlt" (list anlage-typ)))
(setq anlage-typ (nth 0 typ-eintr))
(setq berechne-fn (nth 1 typ-eintr))
(setq einfuege-fn (nth 2 typ-eintr))
(princ (ssg-textf "vfc-typ-gewaehlt" (list anlage-typ)))
;; Sonderfall "linienzug": eigener Befehlsablauf (interaktive Mehrsegment-
;; Kette mit gemischten GF/VF-Segmenten), passt nicht in das berechne-fn/
;; einfuege-fn-Schema fuer ein einzelnes durchgehendes Segment - siehe
;; vf_linienzug.lsp. Dispatcht hier direkt und beendet den Standard-Ablauf.
(if (= anlage-typ "linienzug")
(progn
(princ (ssg-text "vfc-linienzug-modus-header"))
(princ (ssg-text "vfc-linienzug-modus-1"))
(princ (ssg-text "vfc-linienzug-modus-2"))
(princ (ssg-text "vfc-linienzug-modus-3"))
(setq wahl (getint (ssg-text "prompt-wahl-1-2-3")))
;; Konsolen-Nummer -> interne Funktion:
;; 2 = fertiger Ziel-Hoehe-Modus (intern vf-linienzug-modus2)
;; 3 = alter Vorwaerts-Nachbau (intern vf-linienzug-modus3, wird umgebaut)
;; 1/Default = frische manuelle Eingabe. Ein abgebrochener Bau bleibt als
;; VF_n-Block stehen und wird per Doppelklick fortgesetzt/editiert
;; (vfl-edit-ent), kein separater Menuepunkt noetig.
;; Journal-Reset gilt fuer JEDEN frischen Bau, nicht nur Modus 1: Modus 2
;; schreibt sein Journal ebenfalls als XDATA (Marker "linienzug2"), erbte
;; ohne Reset aber die Eintraege des Vorlaufs als Praefix - ein spaeterer
;; Doppelklick spielte dann fremde Eingaben vor. Die Edit-/Konvertier-Pfade
;; laufen nie hier durch (sie setzen ihre Queue selbst), darum ist das
;; Hochziehen ein reiner Bugfix. Setzt zugleich *vfl-seg-glied-letzte*
;; zurueck, das sonst vom Vorlauf stehenbleibt.
(vfl-journal-reset)
(cond ((= wahl 2) (vf-linienzug-modus2))
((= wahl 3) (vf-linienzug-modus3))
(t (vf-linienzug-modus)))
(exit)
;; Sonderfall "linienzug": eigener Befehlsablauf (interaktive Mehrsegment-
;; Kette mit gemischten GF/VF-Segmenten), passt nicht in das berechne-fn/
;; einfuege-fn-Schema fuer ein einzelnes durchgehendes Segment - siehe
;; vf_linienzug.lsp. Dispatcht hier direkt und beendet den Standard-Ablauf.
(if (= anlage-typ "linienzug")
(progn
(setq dlg-modus (vfc-dialog-linienzug-modus-waehlen))
(cond
((eq dlg-modus 'ABBRUCH) (exit))
((eq dlg-modus 'ZURUECK) (setq zurueck-zu-typ t))
(dlg-modus (setq wahl dlg-modus))
(t
;; Dialog nicht verfuegbar/nicht erlaubt - alte Konsolen-Liste.
(princ (ssg-text "vfc-linienzug-modus-header"))
(princ (ssg-text "vfc-linienzug-modus-1"))
(princ (ssg-text "vfc-linienzug-modus-2"))
(princ (ssg-text "vfc-linienzug-modus-3"))
(setq wahl (getint (ssg-text "prompt-wahl-1-2-3")))
)
)
(if (not zurueck-zu-typ)
(progn
;; Konsolen-Nummer -> interne Funktion:
;; 2 = fertiger Ziel-Hoehe-Modus (intern vf-linienzug-modus2)
;; 3 = alter Vorwaerts-Nachbau (intern vf-linienzug-modus3, wird umgebaut)
;; 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.
;; Journal-Reset gilt fuer JEDEN frischen Bau, nicht nur Modus 1: Modus 2
;; schreibt sein Journal ebenfalls als XDATA (Marker "linienzug2"), erbte
;; ohne Reset aber die Eintraege des Vorlaufs als Praefix - ein spaeterer
;; Doppelklick spielte dann fremde Eingaben vor. Die Edit-/Konvertier-Pfade
;; laufen nie hier durch (sie setzen ihre Queue selbst), darum ist das
;; Hochziehen ein reiner Bugfix. Setzt zugleich *vfl-seg-glied-letzte*
;; zurueck, das sonst vom Vorlauf stehenbleibt.
(vfl-journal-reset)
(cond ((= wahl 2) (vf-linienzug-modus2))
((= wahl 3) (vf-linienzug-modus3))
(t (vf-linienzug-modus)))
(exit)
)
)
)
)
)
@@ -1223,7 +1340,7 @@
;; Bibliothek ist durch den berechne-fn-Aufruf oben bereits initialisiert.
(if (and (= anlage-typ "standard") (= richtung "Ab"))
(progn
(setq horizontal-info (berechne-horizontale-mitte deltaL deltaH "Ab"))
(setq horizontal-info (berechne-horizontale-mitte deltaL deltaH "Ab" nil))
(if (and horizontal-info (caddr horizontal-info))
(progn
(setq ergebnis-liste