VF-Linienzug: Einzelsegment-Bearbeitung (GF-Bogen) + punktfreies Journal
Doppelklick auf einen Linienzug-VF_n-Block bietet jetzt zwei Modi (neuer Dialog vfl_edit_modus.dcl / vfl-dlg-modus): auf eine Sektion zuruecksetzen (bisheriges Verhalten) ODER die Eigenschaften EINES einzelnen Glieds aendern (vfl-edit-glied). Fuer GF-Boegen laesst sich Winkel (30/60/90) und Seite (links/rechts) direkt aendern; das Glied wird per vfl-journal-splice im Ketten-Journal ersetzt und die komplette Kette 1:1 neu aufgebaut. Damit die nachfolgenden Glieder nach einer Bogen-Aenderung korrekt neu verketten, speichert das Journal fuer Linien-Segmente jetzt nur noch die relative Distanz (deltaL, neuer Journal-Kind "DL") statt eines absoluten Punkts - nur der Kettenstartpunkt bleibt ein echter Punkt. Richtung wird ohnehin vom Vorgaenger-Frame geerbt (nur das erste Segment journalisiert zusaetzlich die gesnappte Richtung). vfl-in-abstand ersetzt die punktbasierte Messung in vfl-neue-linie-messen; vfl-kettenanfang-baustein rechnet die AS-Restlaenge rein skalar (kein pick-punkt mehr). Wichtige Korrekturen: - vfl-entry->string/-entry kannten den DL-Kind nicht (wurde als NIL serialisiert -> Distanzverlust beim erneuten Lesen) - vfl-in-abstand journalisiert jetzt in BEIDEN Zweigen (Replay UND Live), wie die anderen vfl-in-*-Wrapper - sonst gingen die DL-Werte replizierter Glieder beim erneuten Speichern verloren (2. Edit stuerzte ab) Diagnose: komplettes Journal wird beim Erzeugen (XDATA-JOURNAL-JSON) und zu Beginn eines Replays (REPLAY-QUEUE-JSON) als JSON in die Debug-Datei geschrieben (No-Op ohne aktiven Debug-Schalter). dcl/vfl_edit.dcl: Popup breiter (edit_width/list_width), damit lange Sektionstexte nicht abgeschnitten werden. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+466
-67
@@ -486,12 +486,12 @@
|
||||
|
||||
;; ------------------------------------------------------------
|
||||
;; Gruppe "Gefaelle festlegen" (Linie GF): Modus(Hoehe/Winkel) + EIN
|
||||
;; Wertfeld (Beschriftung wechselt mit dem Modus). KEIN Punkt-Feld: der
|
||||
;; Endpunkt (X/Y, fuer die Fahrtrichtung/Laengenberechnung) ist an der
|
||||
;; Aufrufstelle bereits VOR dieser Gruppe ueber vfl-neue-linie-messen/
|
||||
;; vfl-in-point gepickt - dessen Z wird nie gelesen, "Hoehe" hier ist ein
|
||||
;; davon unabhaengiger Zahlenwert (siehe Kommentar bei
|
||||
;; vfl-neue-linie-messen). Original-Reihenfolge/-Journal ab hier:
|
||||
;; Wertfeld (Beschriftung wechselt mit dem Modus). KEIN Punkt-Feld: die
|
||||
;; Laenge/Fahrtrichtung ist an der Aufrufstelle bereits VOR dieser Gruppe
|
||||
;; ueber vfl-neue-linie-messen/vfl-in-abstand als deltaL/hz ermittelt (nur
|
||||
;; noch ein Skalarpaar, kein Punkt mehr - siehe Kommentar bei
|
||||
;; vfl-in-abstand) - dessen Z-Konzept existiert nicht mehr, "Hoehe" hier ist
|
||||
;; ein eigener, unabhaengiger Zahlenwert. Original-Reihenfolge/-Journal ab hier:
|
||||
;; vfl-in-string (Modus), danach vfl-in-real (Winkel ODER Hoehe).
|
||||
(defun vflw-gruppe-gefaelle-impl (hoehe-default / dat dcl-pfad ergebnis gmodus gwert winkel-default)
|
||||
(setq winkel-default (ssg-cfg-or "vario" "gefaelle_winkel" 3))
|
||||
@@ -530,9 +530,9 @@
|
||||
;; ------------------------------------------------------------
|
||||
;; Gruppe "Ziel-Hoehe": NUR die Hoehen-Zahl (kein Punkt-Feld). Wiederverwendet
|
||||
;; an mehreren Stellen (Linie-VF, VF-Einheit-Fortsetzung "Auf/Ab",
|
||||
;; vfl-body-abschluss). Der Endpunkt (X/Y, fuer die Segmentlaenge) ist an der
|
||||
;; Aufrufstelle bereits separat ueber vfl-neue-linie-messen gepickt - dessen
|
||||
;; Z wird nirgends verwendet, die Hoehe hier ist eine davon unabhaengige
|
||||
;; vfl-body-abschluss). Die Segmentlaenge ist an der Aufrufstelle bereits
|
||||
;; separat ueber vfl-neue-linie-messen/vfl-in-abstand als deltaL (Skalar,
|
||||
;; kein Punkt mehr) ermittelt - die Hoehe hier ist eine davon unabhaengige
|
||||
;; Zahl (Default = aktuelle Kettenhoehe, wie im Original-Prompt). Nutzt
|
||||
;; bewusst den generischen Einzel-Dialog vflw_zahl (kein Punkt-Button, der
|
||||
;; faelschlich eine hier moegliche Punktwahl suggerieren wuerde).
|
||||
@@ -795,6 +795,7 @@
|
||||
((= k "PT") (strcat "PT:" (rtos (car v) 2 6) "," (rtos (cadr v) 2 6) ","
|
||||
(rtos (caddr v) 2 6)))
|
||||
((= k "REAL") (strcat "REAL:" (rtos v 2 6)))
|
||||
((= k "DL") (strcat "DL:" (rtos v 2 6)))
|
||||
((= k "INT") (strcat "INT:" (itoa v)))
|
||||
((= k "STR") (strcat "STR:" v))
|
||||
((= k "STEP") (strcat "STEP:" v))
|
||||
@@ -811,13 +812,54 @@
|
||||
(setq c (vfl-strsplit pay ","))
|
||||
(cons "PT" (list (atof (nth 0 c)) (atof (nth 1 c)) (atof (nth 2 c)))))
|
||||
((= kind "REAL") (cons "REAL" (atof pay)))
|
||||
((= kind "DL") (cons "DL" (atof pay)))
|
||||
((= kind "INT") (cons "INT" (atoi pay)))
|
||||
((= kind "STR") (cons "STR" pay))
|
||||
((= kind "STEP") (cons "STEP" pay))
|
||||
((= kind "OBJS") (cons "OBJS" (if (> (strlen pay) 0) (vfl-strsplit pay ",") nil)))
|
||||
(t (cons "NIL" nil))))))
|
||||
;; forward-journal ist bereits in Bau-Reihenfolge (nicht die umgekehrte
|
||||
;; *vfl-journal*-Rohform) - gemeinsame Serialisierung fuer Ketten- UND
|
||||
;; Segment-XDATA (vfl-journal-xdata-schreiben / vfl-journal-xdata-schreiben-seg).
|
||||
(defun vfl-journal-list->string (forward-journal)
|
||||
(vfl-strjoin (mapcar 'vfl-entry->string forward-journal) "\n"))
|
||||
(defun vfl-journal->string ()
|
||||
(vfl-strjoin (mapcar 'vfl-entry->string (reverse *vfl-journal*)) "\n"))
|
||||
(vfl-journal-list->string (reverse *vfl-journal*)))
|
||||
|
||||
;; --- JSON-Dump des Journals fuer die Debug-Datei (nur Diagnose) ---
|
||||
;; Wandelt EINEN Journal-Eintrag (kind . value) in ein JSON-Objekt
|
||||
;; {"kind":"PT","value":[x,y,z]} um. String-Werte werden gequotet (mit
|
||||
;; einfachem Escaping fuer " und \), Zahlen unquotiert, PT als Zahlen-Array,
|
||||
;; OBJS als String-Array, NIL als null. Rein additive Diagnose - beruehrt die
|
||||
;; XDATA-Serialisierung (vfl-entry->string) NICHT.
|
||||
(defun vfl-json-escape (s / out c i n)
|
||||
(setq out "" i 1 n (strlen s))
|
||||
(while (<= i n)
|
||||
(setq c (substr s i 1))
|
||||
(setq out (strcat out (cond ((= c "\"") "\\\"") ((= c "\\") "\\\\") (t c))))
|
||||
(setq i (1+ i)))
|
||||
out)
|
||||
(defun vfl-json-num (x) (rtos x 2 6)) ; einheitliches Zahlformat (wie vfl-entry->string)
|
||||
(defun vfl-entry->json (e / k v)
|
||||
(setq k (car e) v (cdr e))
|
||||
(strcat "{\"kind\":\"" k "\",\"value\":"
|
||||
(cond
|
||||
((null v) "null")
|
||||
((= k "PT") (strcat "[" (vfl-json-num (car v)) "," (vfl-json-num (cadr v)) ","
|
||||
(vfl-json-num (caddr v)) "]"))
|
||||
((= k "REAL") (vfl-json-num v))
|
||||
((= k "DL") (vfl-json-num v))
|
||||
((= k "INT") (itoa v))
|
||||
((= k "STR") (strcat "\"" (vfl-json-escape v) "\""))
|
||||
((= k "STEP") (strcat "\"" (vfl-json-escape v) "\""))
|
||||
((= k "OBJS") (strcat "[" (vfl-strjoin
|
||||
(mapcar (function (lambda (h) (strcat "\"" (vfl-json-escape h) "\"")))
|
||||
v) ",") "]"))
|
||||
(t "null"))
|
||||
"}"))
|
||||
;; 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")
|
||||
@@ -843,6 +885,12 @@
|
||||
(defun vfl-journal-xdata-schreiben (ent marker / chunks appentry)
|
||||
(if (null *vf-xdata-app*) (setq *vf-xdata-app* "SSG_VF_EDIT"))
|
||||
(regapp *vf-xdata-app*)
|
||||
;; Diagnose: komplettes Journal beim Erzeugen der Geometrie als JSON in die
|
||||
;; Debug-Datei (No-Op ohne offene .dbg-Datei, siehe dbgmsg). marker + JSON-
|
||||
;; Array der Eintraege in Bau-Reihenfolge.
|
||||
(dbgmsg (strcat "XDATA-GESCHRIEBEN marker=" marker))
|
||||
(dbgmsg (strcat "XDATA-JOURNAL-JSON " (vfl-journal->json (reverse *vfl-journal*))))
|
||||
(dbgflush)
|
||||
(setq chunks (vfl-chunk-string (vfl-journal->string) 250))
|
||||
(setq appentry
|
||||
(cons *vf-xdata-app*
|
||||
@@ -857,6 +905,67 @@
|
||||
(cons (car xd) (vfl-string->journal (apply 'strcat (cdr xd))))
|
||||
nil))
|
||||
|
||||
;; --- Segment-XDATA (pro einzelnem Glied-Entity, eigener App-Name) ---
|
||||
;; Eigene App "SSG_VF_EDIT_SEG" statt SSG_VF_EDIT: sauber getrennt vom
|
||||
;; Ketten-Journal, keine Kollisionsgefahr mit dessen Marker-Schema
|
||||
;; ("linienzug"/"linienzug2"/"standard"/"etage"). Wird auf JEDES seit
|
||||
;; Glied-Start neu erzeugte Entity geschrieben, WAEHREND es noch frei in der
|
||||
;; Zeichnung liegt (vor dem finalen -BLOCK-Sweep in vfl-block-erstellen) -
|
||||
;; siehe vfl-segment-xdata-sichern. Rein additive Zusatzinformation: das
|
||||
;; bestehende Ketten-Journal (SSG_VF_EDIT) bleibt unabhaengig davon die
|
||||
;; primaere/vollstaendige Quelle, Segment-XDATA ist kein Ersatz dafuer.
|
||||
;; Layout: [0]="linienzug-seg" (Marker), [1]=Glied-Index (1-basiert, String),
|
||||
;; [2..]=Segment-Journal-String in 250-Byte-Chunks.
|
||||
(defun vfl-journal-xdata-schreiben-seg (ent seg-idx seg-journal / chunks appentry)
|
||||
(regapp "SSG_VF_EDIT_SEG")
|
||||
(setq chunks (vfl-chunk-string (vfl-journal-list->string seg-journal) 250))
|
||||
(setq appentry
|
||||
(cons "SSG_VF_EDIT_SEG"
|
||||
(cons (cons 1000 "linienzug-seg")
|
||||
(cons (cons 1000 (itoa seg-idx))
|
||||
(mapcar (function (lambda (c) (cons 1000 c))) chunks)))))
|
||||
(entmod (append (entget ent) (list (list -3 appentry))))
|
||||
ent)
|
||||
;; Rueckgabe: (seg-idx . segment-journal) oder nil (kein/unbekanntes Segment-XDATA).
|
||||
(defun vfl-journal-xdata-lesen-seg (ent / xd app-data werte)
|
||||
(setq xd (entget ent '("SSG_VF_EDIT_SEG")))
|
||||
(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-seg") (cadr werte))
|
||||
(cons (atoi (cadr werte)) (vfl-string->journal (apply 'strcat (cddr 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
|
||||
;; diesem Glied (vf-lastent-ohne-attribute, siehe Aufruf). wahl wird hier
|
||||
;; nicht mehr gebraucht (das Label steckt schon im STEP-Eintrag des Journals
|
||||
;; via vfl-journal-steplabel) - Parameter bleibt fuer eine spaetere dbgmsg-
|
||||
;; Diagnose nuetzlich, daher weiterhin uebergeben.
|
||||
;; Ermittelt Glied-Index + Journal-Teilsequenz selbst aus dem aktuellen
|
||||
;; *vfl-journal* (zu diesem Zeitpunkt bereits um dieses Glied vollstaendig
|
||||
;; 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)
|
||||
(setq forward-journal (reverse *vfl-journal*))
|
||||
(setq seg-idx (length (vfl-journal-glieder forward-journal)))
|
||||
(if (> seg-idx 0)
|
||||
(progn
|
||||
(setq seg-journal (vfl-journal-slice forward-journal seg-idx))
|
||||
(setq e (if seg-lastEnt (entnext seg-lastEnt) (entnext)))
|
||||
(while e
|
||||
(vfl-journal-xdata-schreiben-seg e seg-idx seg-journal)
|
||||
(setq e (entnext e))
|
||||
)
|
||||
)
|
||||
)
|
||||
(dbgmsg (strcat "SEGMENT-XDATA: Glied " (itoa seg-idx) " (" (if wahl wahl "?") ") gesichert"))
|
||||
(princ))
|
||||
|
||||
;; --- Abbruch-Sicherung ---
|
||||
;; Alle nach lastEnt erzeugten Entities werden NICHT geloescht, sondern
|
||||
;; GENAUSO wie beim erfolgreichen Abschluss (vfl-block-erstellen) zu einem
|
||||
@@ -925,6 +1034,40 @@
|
||||
(setq out (cons e out)))))
|
||||
(reverse out))
|
||||
|
||||
;; Journal-Eintraege GENAU eines Glieds liefern: der (from-step-idx)-te STEP
|
||||
;; (1-basiert, in Bau-Reihenfolge) bis ausschliesslich dem naechsten STEP.
|
||||
;; Praeambel-Eintraege vor dem 1. STEP gehoeren zu keinem Glied und werden
|
||||
;; hier nie zurueckgegeben (anders als vfl-journal-truncate, das sie immer
|
||||
;; mitnimmt). Genutzt fuer die Segment-XDATA (vfl-segment-xdata-sichern) und
|
||||
;; das Ersetzen eines einzelnen Glieds (vfl-journal-splice).
|
||||
(defun vfl-journal-slice (forward-journal from-step-idx / seen out started done)
|
||||
(setq seen 0 out '() started nil done nil)
|
||||
(foreach e forward-journal
|
||||
(if (not done)
|
||||
(cond
|
||||
((and (= (car e) "STEP") started) (setq done t))
|
||||
((= (car e) "STEP")
|
||||
(setq seen (1+ seen))
|
||||
(if (= seen from-step-idx) (progn (setq started t) (setq out (cons e out)))))
|
||||
(started (setq out (cons e out))))))
|
||||
(reverse out))
|
||||
|
||||
;; 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
|
||||
;; ISOLIERT liefert). Genutzt von der Einzelsegment-Bearbeitung (vfl-edit-glied).
|
||||
(defun vfl-journal-splice (forward-journal seg-idx new-seg-journal / seen out)
|
||||
(setq seen 0 out '())
|
||||
(foreach e forward-journal
|
||||
(progn
|
||||
(if (= (car e) "STEP") (setq seen (1+ seen)))
|
||||
(cond
|
||||
((< seen seg-idx) (setq out (cons e out))) ; vor dem Ziel-Glied: unveraendert
|
||||
((> seen seg-idx) (setq out (cons e out))) ; nach dem Ziel-Glied: unveraendert
|
||||
((and (= seen seg-idx) (= (car e) "STEP")) ; Ziel-Glied: einmalig durch
|
||||
(setq out (append (reverse new-seg-journal) out)))))) ; new-seg-journal ersetzen,
|
||||
(reverse out)) ; alle uebrigen Eintraege verwerfen
|
||||
|
||||
;; Internes (sprachneutrales) Glied-Token in lesbaren Text der AKTUELLEN Sprache
|
||||
;; uebersetzen. Da im Journal nur das Token steht, folgt die Anzeige immer der
|
||||
;; aktiven Sprache - ein in Deutsch aufgezeichnetes Journal zeigt in englischer
|
||||
@@ -1369,36 +1512,95 @@
|
||||
(setq gekappt (float (fix ist-hoehe)))
|
||||
(if (>= gekappt ist-hoehe) (- gekappt 1.0) gekappt))
|
||||
|
||||
;; Rueckgabe: (deltaL hz p2) oder nil bei Abbruch. p2 = der rohe gepickte
|
||||
;; Punkt (fuer Diagnose/Nachrechnung nach dem AS-Element-Insert, siehe
|
||||
;; vfl-projiziere-distanz). Foerderer-Maximallaenge 25 m: bei Ueberschreitung
|
||||
;; wird die Eingabe abgelehnt und der Endpunkt erneut abgefragt.
|
||||
(defun vfl-neue-linie-messen (p-akt hz-vorgabe / p2 rad ux uy deltaL hz-aktuell ergebnis fertig)
|
||||
;; Punkt+Prompt-Eingabe fuer eine neue Linie journalfrei in (deltaL . hz)
|
||||
;; uebersetzen: LIVE wird ganz normal ein Punkt gepickt (Gummiband), aber
|
||||
;; NICHT der Punkt selbst journalisiert, sondern nur die daraus berechnete
|
||||
;; Distanz (immer) und - NUR wenn hz-vorgabe nil war (freie Richtung, gilt
|
||||
;; ausschliesslich fuer das allererste Segment der Kette) - zusaetzlich die
|
||||
;; gesnappte Richtung. Ist hz-vorgabe bereits gesetzt (jedes Nicht-Start-
|
||||
;; Segment), journalisiert diese Funktion NUR deltaL - die Richtung ist ja
|
||||
;; ohnehin immer die des Vorgaengers, ein Journal-Eintrag dafuer waere
|
||||
;; redundant. Rueckgabe: (deltaL . hz) oder nil bei Abbruch/leerer Eingabe.
|
||||
(defun vfl-in-abstand (p-akt hz-vorgabe prompt / p2 rad ux uy deltaL hz-aktuell popped)
|
||||
(if *vfl-replay-queue*
|
||||
(progn
|
||||
;; Replay: IMMER nur deltaL aus der Queue lesen (nie einen Punkt). Bei
|
||||
;; freier Richtung (hz-vorgabe nil) steht direkt DANACH noch die
|
||||
;; gesnappte Richtung als zweiter Eintrag im Journal (siehe
|
||||
;; Live-Zweig unten) - Reihenfolge: deltaL, dann optional hz.
|
||||
(setq popped (vfl-replay-pop))
|
||||
(if (null popped)
|
||||
(setq deltaL nil)
|
||||
(setq deltaL (car popped)))
|
||||
(if (and deltaL (null hz-vorgabe))
|
||||
(progn
|
||||
(setq popped (vfl-replay-pop))
|
||||
(setq hz-aktuell (if popped (car popped) 0.0)))
|
||||
(setq hz-aktuell hz-vorgabe)))
|
||||
(progn
|
||||
;; Live/Wizard: Pending-Queue zuerst pruefen (Konsistenz mit den
|
||||
;; anderen vfl-in-*-Wrappern/Sicherheitsnetz, siehe vfl-wizard-aktiv-
|
||||
;; Kommentar oben) - aktuell legt kein Gruppen-Dialog hier einen Punkt
|
||||
;; ab, dieser Zweig bleibt also praktisch immer leer. Sonst normal
|
||||
;; picken (Gummiband). Der Punkt lebt nur hier lokal, er wird nie
|
||||
;; journalisiert.
|
||||
(setq popped (vflw-pending-pop))
|
||||
(setq p2 (if popped (car popped) (vfl-getpoint p-akt prompt)))
|
||||
(if (null p2)
|
||||
(setq deltaL nil)
|
||||
(progn
|
||||
(setq hz-aktuell (if hz-vorgabe hz-vorgabe (vfl-hz-snappen-absolut (vfl-planar-hz p-akt p2))))
|
||||
(setq rad (* (float hz-aktuell) (/ pi 180.0)) ux (cos rad) uy (sin rad))
|
||||
(setq deltaL (+ (* (- (car p2) (car p-akt)) ux) (* (- (cadr p2) (cadr p-akt)) uy)))))))
|
||||
;; Journalisieren fuer BEIDE Zweige (Replay UND Live) - wie alle anderen
|
||||
;; vfl-in-*-Wrapper (siehe vfl-in-point/-real/-int): ein beim Replay aus der
|
||||
;; alten Queue gelesener Wert MUSS ins neue *vfl-journal* uebernommen werden,
|
||||
;; sonst fehlt er beim erneuten Speichern (vfl-journal-xdata-schreiben nach
|
||||
;; einem Edit) - genau das fuehrte beim ZWEITEN Edit einer Kette zum
|
||||
;; deltaL-Desync (die replizierten DL/Richtungs-Eintraege waren im nach dem
|
||||
;; ersten Edit gespeicherten Journal verschwunden). Reihenfolge identisch zur
|
||||
;; Lese-Reihenfolge oben: erst DL, dann - nur beim ersten Segment
|
||||
;; (hz-vorgabe nil) - die gesnappte Richtung als REAL.
|
||||
(vfl-journal-record (if deltaL "DL" "NIL") deltaL)
|
||||
(if (and deltaL (null hz-vorgabe))
|
||||
(vfl-journal-record "REAL" hz-aktuell))
|
||||
(if deltaL (cons deltaL hz-aktuell) nil))
|
||||
|
||||
;; Rueckgabe: (deltaL hz) oder nil bei Abbruch. Foerderer-Maximallaenge 25 m:
|
||||
;; bei Ueberschreitung wird die Eingabe abgelehnt und der Endpunkt erneut
|
||||
;; abgefragt.
|
||||
;;
|
||||
;; WICHTIG (siehe vfl-in-abstand): journalisiert wird NUR deltaL (+ ggf. die
|
||||
;; gesnappte Richtung beim allerersten Segment), niemals ein absoluter Punkt.
|
||||
;; deltaL ist eine reine Distanz relativ zum AKTUELLEN Frame (p-akt) entlang
|
||||
;; der (ggf. vom Vorgaenger geerbten) Fahrtrichtung - eine absolute
|
||||
;; Weltkoordinate wuerde dagegen nur zur URSPRUENGLICHEN Frame-Position
|
||||
;; passen. Wird nach einem Einzelsegment-Edit (vfl-edit-glied, z.B. GF-Bogen
|
||||
;; Seite/Winkel aendern) die Kette AB einem anderen Frame neu verkettet, ist
|
||||
;; eine gespeicherte Distanz+Richtung sofort und ohne jede Umrechnung wieder
|
||||
;; korrekt - ein gespeicherter absoluter Punkt waere es nicht (siehe Bug:
|
||||
;; Neuprojektion des alten Punkts gegen den neuen Frame ergab eine falsche,
|
||||
;; teils negative Laenge und in der Folge einen Queue-Desync-Absturz).
|
||||
;; Einzige Ausnahme im ganzen Modus 1: der Kettenstartpunkt (vf-linienzug-
|
||||
;; modus, vfl-in-point auf den allerersten Klick) - er bleibt ein echter
|
||||
;; absoluter Punkt, weil er den einzigen Anker der ganzen Kette markiert und
|
||||
;; von keiner Bogen-Aenderung betroffen sein kann.
|
||||
(defun vfl-neue-linie-messen (p-akt hz-vorgabe / erg deltaL hz-aktuell ergebnis fertig)
|
||||
(vfl-view-refresh)
|
||||
(setq fertig nil)
|
||||
(while (not fertig)
|
||||
(setq p2 (vfl-in-point p-akt
|
||||
(if hz-vorgabe
|
||||
(ssg-text "vfl-prompt-endpunkt-fahrtrichtung")
|
||||
(ssg-text "vfl-prompt-endpunkt-frei"))))
|
||||
(if (null p2)
|
||||
(setq erg (vfl-in-abstand p-akt hz-vorgabe
|
||||
(if hz-vorgabe
|
||||
(ssg-text "vfl-prompt-endpunkt-fahrtrichtung")
|
||||
(ssg-text "vfl-prompt-endpunkt-frei"))))
|
||||
(if (null erg)
|
||||
(setq ergebnis nil fertig t)
|
||||
(progn
|
||||
;; Freie Richtung (nur beim allerersten Segment der Kette, hz-vorgabe
|
||||
;; noch nil): auf das feste 30-Grad-Raster des Weltkoordinatensystems
|
||||
;; snappen - im System sind Fahrtrichtungen immer 30/60/90-Grad-
|
||||
;; Vielfache relativ zur Zeichnung, nie ein freier Zwischenwert. Bei
|
||||
;; einem Retry (zu lang) bleibt hz-vorgabe bewusst nil, damit die
|
||||
;; Richtung erneut frei gewaehlt werden kann.
|
||||
(setq hz-aktuell (if hz-vorgabe hz-vorgabe (vfl-hz-snappen-absolut (vfl-planar-hz p-akt p2))))
|
||||
(setq rad (* (float hz-aktuell) (/ pi 180.0)) ux (cos rad) uy (sin rad))
|
||||
;; Skalarprojektion des gewaehlten Vektors auf die (ggf. gesnappte)
|
||||
;; Fahrtrichtung
|
||||
(setq deltaL (+ (* (- (car p2) (car p-akt)) ux) (* (- (cadr p2) (cadr p-akt)) uy)))
|
||||
(setq deltaL (car erg) hz-aktuell (cdr erg))
|
||||
(if (> deltaL 25000.0)
|
||||
(princ (ssg-textf "vfl-fehler-laenge-max" (list (rtos (/ deltaL 1000.0) 2 2))))
|
||||
(progn
|
||||
(setq ergebnis (list deltaL hz-aktuell p2))
|
||||
(setq ergebnis (list deltaL hz-aktuell))
|
||||
(setq fertig t)
|
||||
)
|
||||
)
|
||||
@@ -2136,16 +2338,25 @@
|
||||
)
|
||||
|
||||
;; Kettenanfang-Baustein: falls as-vorhanden, AS-Element einfuegen und die
|
||||
;; GF/VF-Restlaenge aus dem tatsaechlichen KS_AUS neu berechnen (siehe
|
||||
;; vfl-projiziere-distanz). Falls NICHT as-vorhanden (Nutzer hat "Kein AS-
|
||||
;; Element" gewaehlt), beginnt die Kette direkt am Startpunkt - deltaL bleibt
|
||||
;; die gemessene Rohlaenge (kein Fussabdruck abzuziehen). Rueckgabe: (frame
|
||||
;; deltaL).
|
||||
(defun vfl-kettenanfang-baustein (p-aktuell hz-neu pick-punkt deltaL as-seite as-vorhanden / frame)
|
||||
;; GF/VF-Restlaenge um den tatsaechlichen AS-Fussabdruck kuerzen. Falls NICHT
|
||||
;; as-vorhanden (Nutzer hat "Kein AS-Element" gewaehlt), beginnt die Kette
|
||||
;; direkt am Startpunkt - deltaL bleibt die gemessene Rohlaenge (kein
|
||||
;; Fussabdruck abzuziehen). Rueckgabe: (frame deltaL).
|
||||
;;
|
||||
;; deltaL kommt als reine, bereits auf hz-neu projizierte Distanz vom
|
||||
;; UNVERAENDERTEN p-aktuell herein (siehe vfl-in-abstand/vfl-neue-linie-
|
||||
;; messen - dort wird NIE mehr ein absoluter Punkt gefuehrt). Der reale
|
||||
;; AS-Austritt (car frame) liegt exakt auf derselben Achse hz-neu (das
|
||||
;; AS-Element wird flach IN hz-neu eingefuegt, siehe vfl-insert-as-element) -
|
||||
;; die noetige Restlaenge ist damit einfach die urspruengliche Distanz MINUS
|
||||
;; die tatsaechliche (gemessene) AS-Fussabdrucklaenge, keine Punkt-Projektion
|
||||
;; noetig (Ersatz fuer das fruehere vfl-projiziere-distanz auf pick-punkt).
|
||||
(defun vfl-kettenanfang-baustein (p-aktuell hz-neu deltaL as-seite as-vorhanden / frame fussabdruck)
|
||||
(if as-vorhanden
|
||||
(progn
|
||||
(setq frame (vfl-insert-as-element "GF" p-aktuell hz-neu 0.0 as-seite))
|
||||
(setq deltaL (vfl-projiziere-distanz (car frame) pick-punkt hz-neu))
|
||||
(setq fussabdruck (vfl-planar-dist p-aktuell (car frame)))
|
||||
(setq deltaL (- deltaL fussabdruck))
|
||||
(princ (ssg-textf "vfl-info-as-eingefuegt" (list (rtos deltaL 2 1))))
|
||||
)
|
||||
(progn
|
||||
@@ -2407,8 +2618,8 @@
|
||||
p-aktuell linie-mess hoehe-neu hoehe-bis deltaL deltaH richtung hz-neu
|
||||
entscheidung typ winkel L_GF L_VF vf-einheit-res
|
||||
frame letzter-typ fertig linie-ende-modus rad3
|
||||
anzahl-gf anzahl-vf vfl-nummer lastEnt
|
||||
gf-max-winkel gf-ok kettenanfang pick-punkt
|
||||
anzahl-gf anzahl-vf vfl-nummer lastEnt seg-lastEnt
|
||||
gf-max-winkel gf-ok kettenanfang
|
||||
as-vorhanden erg old-error vfl-ins dbg-an
|
||||
hoehe-vorschlaege hoehe-ab hoehe-auf hoehe-fallback)
|
||||
(princ "\n\n=========================================")
|
||||
@@ -2427,6 +2638,15 @@
|
||||
(progn
|
||||
(dbgf "vf-linienzug-modus")
|
||||
(dbgmsg "=== SESSION Modus 1 (Manuelle Eingabe) START ===")
|
||||
;; Diagnose: falls dieser Lauf ein Replay ist (Editieren/Fortsetzen,
|
||||
;; *vfl-replay-queue* gesetzt), die EINGEHENDE Replay-Queue als JSON
|
||||
;; ausgeben - VOR dem Neuaufbau, daher auch bei einem Absturz mitten im
|
||||
;; Replay sichtbar (anders als das XDATA-JOURNAL-JSON in
|
||||
;; vfl-journal-xdata-schreiben, das erst nach erfolgreichem Bau laeuft).
|
||||
;; So laesst sich ein Desync direkt an der Eingangs-Sequenz ablesen.
|
||||
(if *vfl-replay-queue*
|
||||
(dbgmsg (strcat "REPLAY-QUEUE-JSON " (vfl-journal->json *vfl-replay-queue*)))
|
||||
(dbgmsg "LIVE-BAU (kein Replay)"))
|
||||
(dbgflush)))
|
||||
|
||||
;; Abhaengigkeit: die GF-Segmente/-Boegen nutzen Funktionen aus
|
||||
@@ -2547,6 +2767,11 @@
|
||||
;; nachgetragen (vfl-journal-steplabel), damit jedes Glied seine eigene
|
||||
;; Menue-Auswahl + Segment-Eingaben vollstaendig umschliesst (fuer den
|
||||
;; gliedweisen Ruecksprung beim Editieren).
|
||||
;; seg-lastEnt: Schnappschuss VOR diesem Glied, fuer die Segment-XDATA
|
||||
;; (vfl-segment-xdata-sichern, siehe Ende der cond unten) - dieselbe
|
||||
;; Hilfsfunktion wie beim Ketten-lastEnt (oben), damit ATTRIB/SEQEND-
|
||||
;; Ketten eines vorherigen INSERTs konsistent uebersprungen werden.
|
||||
(setq seg-lastEnt (vf-lastent-ohne-attribute))
|
||||
(vfl-journal-mark "?")
|
||||
(if frame
|
||||
(progn
|
||||
@@ -2588,6 +2813,7 @@
|
||||
;; Segmenttyp steht fest -> Glied-Label nachtragen (fuer die Edit-Liste).
|
||||
(vfl-journal-steplabel wahl)
|
||||
|
||||
(progn
|
||||
(cond
|
||||
((= wahl "GF-Bogen")
|
||||
(setq frame (vfl-insert-gf-bogen frame))
|
||||
@@ -2599,14 +2825,14 @@
|
||||
(setq linie-mess (vfl-neue-linie-messen p-aktuell
|
||||
(if frame (car (frame->hz-winkel frame)) nil)))
|
||||
(if (null linie-mess) (progn (princ (ssg-text "vfl-abgebrochen")) (exit)))
|
||||
(setq deltaL (car linie-mess) hz-neu (cadr linie-mess) pick-punkt (caddr linie-mess))
|
||||
(setq deltaL (car linie-mess) hz-neu (cadr linie-mess))
|
||||
(setq kettenanfang (null frame))
|
||||
;; Kettenanfang: AS-Element (falls gewuenscht) SOFORT einfuegen, reale
|
||||
;; Restlaenge aus dem tatsaechlichen KS_AUS nachrechnen (siehe
|
||||
;; vfl-kettenanfang-baustein).
|
||||
(if kettenanfang
|
||||
(progn
|
||||
(setq erg (vfl-kettenanfang-baustein p-aktuell hz-neu pick-punkt deltaL as-seite as-vorhanden))
|
||||
(setq erg (vfl-kettenanfang-baustein p-aktuell hz-neu deltaL as-seite as-vorhanden))
|
||||
(setq frame (nth 0 erg) deltaL (nth 1 erg) p-aktuell (car frame))
|
||||
)
|
||||
)
|
||||
@@ -2644,7 +2870,7 @@
|
||||
(setq linie-mess (vfl-neue-linie-messen p-aktuell
|
||||
(if frame (car (frame->hz-winkel frame)) nil)))
|
||||
(if (null linie-mess) (progn (princ (ssg-text "vfl-abgebrochen")) (exit)))
|
||||
(setq deltaL (car linie-mess) hz-neu (cadr linie-mess) pick-punkt (caddr linie-mess))
|
||||
(setq deltaL (car linie-mess) hz-neu (cadr linie-mess))
|
||||
(setq kettenanfang (null frame))
|
||||
(setq gf-max-winkel (float (ssg-cfg-or "vario" "gefaelle_winkel" 3)))
|
||||
(if (< deltaL 1.0)
|
||||
@@ -2661,7 +2887,7 @@
|
||||
;; Versatz).
|
||||
(if kettenanfang
|
||||
(progn
|
||||
(setq erg (vfl-kettenanfang-baustein p-aktuell hz-neu pick-punkt deltaL as-seite as-vorhanden))
|
||||
(setq erg (vfl-kettenanfang-baustein p-aktuell hz-neu deltaL as-seite as-vorhanden))
|
||||
(setq frame (nth 0 erg) deltaL (nth 1 erg) p-aktuell (car frame))
|
||||
)
|
||||
)
|
||||
@@ -2790,14 +3016,14 @@
|
||||
(setq linie-mess (vfl-neue-linie-messen p-aktuell
|
||||
(if frame (car (frame->hz-winkel frame)) nil)))
|
||||
(if (null linie-mess) (progn (princ (ssg-text "vfl-abgebrochen")) (exit)))
|
||||
(setq deltaL (car linie-mess) hz-neu (cadr linie-mess) pick-punkt (caddr linie-mess))
|
||||
(setq deltaL (car linie-mess) hz-neu (cadr linie-mess))
|
||||
(setq kettenanfang (null frame))
|
||||
;; Kettenanfang: AS-Element (falls gewuenscht) SOFORT einfuegen, reale
|
||||
;; Restlaenge aus dem tatsaechlichen KS_AUS nachrechnen (siehe
|
||||
;; vfl-kettenanfang-baustein).
|
||||
(if kettenanfang
|
||||
(progn
|
||||
(setq erg (vfl-kettenanfang-baustein p-aktuell hz-neu pick-punkt deltaL as-seite as-vorhanden))
|
||||
(setq erg (vfl-kettenanfang-baustein p-aktuell hz-neu deltaL as-seite as-vorhanden))
|
||||
(setq frame (nth 0 erg) deltaL (nth 1 erg) p-aktuell (car frame))
|
||||
)
|
||||
)
|
||||
@@ -2861,7 +3087,7 @@
|
||||
(setq linie-mess (vfl-neue-linie-messen p-aktuell
|
||||
(if frame (car (frame->hz-winkel frame)) nil)))
|
||||
(if (null linie-mess) (progn (princ (ssg-text "vfl-abgebrochen")) (exit)))
|
||||
(setq deltaL (car linie-mess) hz-neu (cadr linie-mess) pick-punkt (caddr linie-mess))
|
||||
(setq deltaL (car linie-mess) hz-neu (cadr linie-mess))
|
||||
(setq kettenanfang (null frame))
|
||||
(if (< deltaL 1.0)
|
||||
(princ (ssg-text "vfl-fehler-linie-zu-kurz"))
|
||||
@@ -2873,7 +3099,7 @@
|
||||
;; vfl-kettenanfang-baustein).
|
||||
(if kettenanfang
|
||||
(progn
|
||||
(setq erg (vfl-kettenanfang-baustein p-aktuell hz-neu pick-punkt deltaL as-seite as-vorhanden))
|
||||
(setq erg (vfl-kettenanfang-baustein p-aktuell hz-neu deltaL as-seite as-vorhanden))
|
||||
(setq frame (nth 0 erg) deltaL (nth 1 erg) p-aktuell (car frame))
|
||||
)
|
||||
)
|
||||
@@ -3026,6 +3252,13 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
;; Segment-XDATA: alle seit seg-lastEnt neu erzeugten Entities dieses
|
||||
;; Glieds mit ihrer eigenen Journal-Teilsequenz markieren (rein additiv,
|
||||
;; siehe vfl-segment-xdata-sichern) - muss laufen, WAEHREND die Entities
|
||||
;; noch frei in der Zeichnung liegen (vor dem -BLOCK-Sweep in
|
||||
;; vfl-block-erstellen unten).
|
||||
(vl-catch-all-apply 'vfl-segment-xdata-sichern (list seg-lastEnt wahl))
|
||||
)
|
||||
)
|
||||
|
||||
(setq hoehe-bis (caddr (car frame)))
|
||||
@@ -3070,7 +3303,133 @@
|
||||
;; (vfl-edit-ent2) - Modus 2s Klassifizierungs-Schleife traegt keine
|
||||
;; Glied-Marker, ein Sektions-Dialog wie bei Modus 1 ist dafuer (noch) nicht
|
||||
;; vorgesehen.
|
||||
(defun vfl-edit-ent (ent / xd marker journal glieder n i pos trunc)
|
||||
;; ============================================================
|
||||
;; EINZELSEGMENT-BEARBEITUNG (ein Glied aendern, Rest behalten)
|
||||
;; ============================================================
|
||||
;; Idee: das Ketten-Journal ist die vollstaendige, wiederabspielbare Bau-
|
||||
;; Anleitung. Ein einzelnes Glied editieren = dessen Journal-Teilsequenz durch
|
||||
;; eine neue ersetzen (vfl-journal-splice) und danach das GESAMTE ersetzte
|
||||
;; Journal still abspielen (vfl-journal-replay-start + vf-linienzug-modus) -
|
||||
;; exakt derselbe Mechanismus wie der Sektions-Ruecksprung, nur mit chirurgisch
|
||||
;; ersetztem statt abgeschnittenem Journal. Die Glieder VOR dem geaenderten
|
||||
;; spielen identisch wie zuvor ab (gleicher Frame), das geaenderte Glied mit
|
||||
;; neuen Werten, die Glieder DANACH mit ihren ORIGINAL-Werten - aber ab dem
|
||||
;; neuen Austritts-Frame des geaenderten Glieds neu verkettet. Das leistet die
|
||||
;; bestehende Replay-Schleife von allein (jedes Glied baut relativ zum Frame
|
||||
;; des Vorgaengers), ohne Zusatzlogik.
|
||||
;;
|
||||
;; Umfang dieser ersten Version: sauber editierbar ist der GF-Bogen (genau eine
|
||||
;; Winkel- + eine Seiten-Entscheidung, ein eigenstaendiges Top-Level-Glied).
|
||||
;; Andere Glieder (Linie-GF/-VF, Horizontal-VF, Linie-bis-Ende) enthalten
|
||||
;; Punktwahl + Hoehen und teils VF-interne Vario-Kurven - fuer die ist der
|
||||
;; Sektions-Ruecksprung ("rueck") der passende Weg. Sie werden hier mit einem
|
||||
;; Hinweis abgewiesen (statt eine halbfertige In-Place-Bearbeitung anzubieten).
|
||||
|
||||
;; Neue Journal-Teilsequenz fuer einen GF-Bogen aus den im Dialog gewaehlten
|
||||
;; Werten bauen. Aufbau exakt wie vom Live-Bau erzeugt: STEP-Eintrag, dann
|
||||
;; ("STR" . "1") fuer die "Naechstes Element waehlen"-Menueantwort (Option 1 =
|
||||
;; GF-Bogen, siehe vf-linienzug-modus Hauptschleife - vfl-journal-mark setzt
|
||||
;; den STEP-Checkpoint VOR dieser Menuefrage, vfl-journal-steplabel schreibt
|
||||
;; danach nur das Label um, fuegt aber KEINEN neuen Eintrag ein; die
|
||||
;; Menueantwort bleibt also als eigener Journal-Eintrag direkt nach dem STEP
|
||||
;; stehen), dann ("INT" . winkel-idx) + ("STR" . seite-code) aus
|
||||
;; vfl-insert-gf-bogen (vfl-menu-int Winkel, vfl-menu Seite). winkel-idx
|
||||
;; 1/2/3 = 30/60/90, seite-code "1"=links, "2"=rechts. Ein GF-Bogen kann nie
|
||||
;; das erste Kettenglied sein (am Kettenanfang bietet das Menue "GF-Bogen"
|
||||
;; gar nicht erst an, siehe Hauptschleife) - die Menueantwort ist daher immer
|
||||
;; aus dem 5er-Menue (frame vorhanden) und immer "1". Rueckgabe: forward-order
|
||||
;; Journal-Teilsequenz.
|
||||
(defun vfl-gf-bogen-slice-bauen (winkel-idx seite-code)
|
||||
(list (cons "STEP" "GF-Bogen")
|
||||
(cons "STR" "1")
|
||||
(cons "INT" winkel-idx)
|
||||
(cons "STR" seite-code)))
|
||||
|
||||
;; Aktuelle (Winkel-Index, Seiten-Code) aus einer bestehenden GF-Bogen-Slice
|
||||
;; lesen (fuer die Dialog-Vorbelegung). Die Slice traegt ZWEI STR-Eintraege
|
||||
;; (die fuehrende "Naechstes Element waehlen"-Menueantwort, danach - NACH dem
|
||||
;; INT-Winkel - der Seiten-Code) - nur der STR NACH dem INT ist der Seiten-
|
||||
;; Code, daher explizit per Positions-Flag statt "letzter gesehener STR
|
||||
;; gewinnt" (siehe vfl-gf-bogen-slice-bauen). Faellt bei unerwartetem Aufbau
|
||||
;; auf die Live-Bau-Defaults zurueck (Winkel 90 = idx 3, Seite links = "1").
|
||||
(defun vfl-gf-bogen-slice-werte (slice / w s nach-int)
|
||||
(setq w 3 s "1" nach-int nil)
|
||||
(foreach e slice
|
||||
(cond ((= (car e) "INT") (setq w (cdr e) nach-int t))
|
||||
((and (= (car e) "STR") nach-int) (setq s (cdr e) nach-int nil))))
|
||||
(list w s))
|
||||
|
||||
;; Pre-fill-faehiger Winkel+Seite-Dialog fuer den GF-Bogen (nutzt das
|
||||
;; bestehende vflw_winkel_seite-Tile aus dem Wizard-DCL, aber mit Vorbelegung
|
||||
;; auf die aktuellen Werte - anders als vflw-gruppe-winkel-seite-impl, das
|
||||
;; immer bei 0 startet und daher nicht wiederverwendet werden kann, ohne den
|
||||
;; Live-Bau zu beruehren). Rueckgabe: (winkel-idx seite-code) oder nil bei
|
||||
;; Abbruch. winkel-idx 1/2/3, seite-code "1"/"2".
|
||||
(defun vfl-glied-gf-bogen-dialog (vor-winkel-idx vor-seite-code /
|
||||
dat dcl-pfad ergebnis gwinkel gseite)
|
||||
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/vf_linienzug_wizard.dcl"))
|
||||
(setq dat (load_dialog dcl-pfad))
|
||||
(if (not (new_dialog "vflw_winkel_seite" dat))
|
||||
(progn (if (and dat (>= dat 0)) (unload_dialog dat))
|
||||
(alert (ssg-textf "vfl-edit-dialog-fehlt" (list dcl-pfad))) nil)
|
||||
(progn
|
||||
(set_tile "kopf" (ssg-text "vfl-gf-bogen-winkel-header"))
|
||||
(start_list "winkel")
|
||||
(add_list (ssg-text "vfl-winkel-30"))
|
||||
(add_list (ssg-text "vfl-winkel-60"))
|
||||
(add_list (ssg-text "vfl-winkel-90"))
|
||||
(end_list)
|
||||
(set_tile "winkel" (itoa (1- vor-winkel-idx))) ; idx 1/2/3 -> 0-basiert 0/1/2
|
||||
(start_list "seite")
|
||||
(add_list (ssg-text "gf-seite-links"))
|
||||
(add_list (ssg-text "gf-seite-rechts"))
|
||||
(end_list)
|
||||
(set_tile "seite" (if (= vor-seite-code "2") "1" "0"))
|
||||
(action_tile "accept"
|
||||
"(setq gwinkel (get_tile \"winkel\")) (setq gseite (get_tile \"seite\")) (done_dialog 1)")
|
||||
(action_tile "cancel" "(done_dialog 0)")
|
||||
(setq ergebnis (start_dialog))
|
||||
(unload_dialog dat)
|
||||
(if (= ergebnis 1)
|
||||
(list (1+ (atoi gwinkel)) ; 0-basiert -> idx 1/2/3
|
||||
(if (= gseite "1") "2" "1")) ; Liste 0=links/1=rechts -> code "1"/"2"
|
||||
nil))))
|
||||
|
||||
;; Einzelnes Glied bearbeiten. glieder = Glied-Label-Liste (Bau-Reihenfolge).
|
||||
;; journal = volles Ketten-Journal. Waehlt per Liste ein Glied, laesst dessen
|
||||
;; Eigenschaften aendern (aktuell nur GF-Bogen), ersetzt die Teilsequenz und
|
||||
;; baut die Kette komplett neu auf (stummer Voll-Replay des gespliceten
|
||||
;; Journals). Bricht der Neuaufbau ab, wickelt der bestehende *error*-Handler
|
||||
;; in vf-linienzug-modus den Zwischenstand - kein Sonderfall noetig.
|
||||
(defun vfl-edit-glied (ent journal glieder / pos label alt-slice vorwerte
|
||||
neuwerte neu-slice spliced)
|
||||
(setq pos (vfl-dlg-position glieder))
|
||||
(if (null pos)
|
||||
(progn (princ (ssg-text "vfl-edit-abgebrochen")) (exit)))
|
||||
(setq label (nth (1- pos) glieder))
|
||||
(cond
|
||||
((= label "GF-Bogen")
|
||||
(setq alt-slice (vfl-journal-slice journal pos))
|
||||
(setq vorwerte (vfl-gf-bogen-slice-werte alt-slice))
|
||||
(setq neuwerte (vfl-glied-gf-bogen-dialog (car vorwerte) (cadr vorwerte)))
|
||||
(if (null neuwerte)
|
||||
(progn (princ (ssg-text "vfl-edit-abgebrochen")) (exit)))
|
||||
(setq neu-slice (vfl-gf-bogen-slice-bauen (car neuwerte) (cadr neuwerte)))
|
||||
(setq spliced (vfl-journal-splice journal pos neu-slice))
|
||||
(entdel ent)
|
||||
(princ (ssg-textf "vfl-glied-geaendert" (list (itoa pos))))
|
||||
;; Voller stummer Replay des gespliceten Journals: die Queue beschreibt
|
||||
;; die Kette bis zum Ende, daher faellt vf-linienzug-modus nicht in den
|
||||
;; Live-Modus, sondern baut 1:1 mit dem geaenderten Glied fertig.
|
||||
(vfl-journal-replay-start spliced)
|
||||
(vf-linienzug-modus))
|
||||
(t
|
||||
(alert (ssg-textf "vfl-glied-nicht-editierbar"
|
||||
(list (vfl-glied-label-text label))))
|
||||
(princ (ssg-text "vfl-edit-abgebrochen"))))
|
||||
(princ))
|
||||
|
||||
(defun vfl-edit-ent (ent / xd marker journal glieder n i pos trunc edit-modus)
|
||||
(setq xd (vfl-journal-xdata-lesen ent))
|
||||
(if (null xd)
|
||||
(progn (alert (ssg-text "vfl-edit-kein-journal")) (exit)))
|
||||
@@ -3080,23 +3439,34 @@
|
||||
(progn
|
||||
(setq glieder (vfl-journal-glieder journal))
|
||||
(setq n (length glieder))
|
||||
(princ (ssg-textf "vfl-edit-kette-header" (list (itoa n))))
|
||||
(setq i 1)
|
||||
(foreach g glieder
|
||||
(princ (strcat "\n " (itoa i) ") " (vfl-glied-label-text g)))
|
||||
(setq i (1+ i)))
|
||||
(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).
|
||||
;; 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 pos) (itoa (- n pos)))))
|
||||
;; Behaltene Glieder abspielen, dann live weiterbauen.
|
||||
(vfl-journal-replay-start trunc)
|
||||
(vf-linienzug-modus)))
|
||||
;; NEU: zuerst Modus waehlen (Sektion zuruecksetzen ODER ein einzelnes
|
||||
;; Glied bearbeiten). Alte Bloecke ohne Segment-XDATA funktionieren in
|
||||
;; beiden Zweigen, da beide allein aus dem Ketten-Journal arbeiten.
|
||||
(setq edit-modus (vfl-dlg-modus n))
|
||||
(cond
|
||||
((null edit-modus)
|
||||
(princ (ssg-text "vfl-edit-abgebrochen")))
|
||||
((= edit-modus "glied")
|
||||
(vfl-edit-glied ent journal glieder))
|
||||
(t
|
||||
;; --- bestehender Ablauf: Sektion zuruecksetzen (unveraendert) ---
|
||||
(princ (ssg-textf "vfl-edit-kette-header" (list (itoa n))))
|
||||
(setq i 1)
|
||||
(foreach g glieder
|
||||
(princ (strcat "\n " (itoa i) ") " (vfl-glied-label-text g)))
|
||||
(setq i (1+ i)))
|
||||
(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).
|
||||
;; 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 pos) (itoa (- n pos)))))
|
||||
;; Behaltene Glieder abspielen, dann live weiterbauen.
|
||||
(vfl-journal-replay-start trunc)
|
||||
(vf-linienzug-modus)))))
|
||||
(princ))
|
||||
|
||||
;; Modus-2-Block per Doppelklick zuruecksetzen: voller Reset - die komplette
|
||||
@@ -3111,6 +3481,35 @@
|
||||
(vf-linienzug-modus2)
|
||||
(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"
|
||||
;; oder nil (Abbrechen/Escape). Bei fehlendem/kaputtem DCL faellt der Dialog
|
||||
;; auf "rueck" zurueck (statt die Bearbeitung ganz zu blockieren) - so bleibt
|
||||
;; der bestehende Editierpfad auch dann erreichbar.
|
||||
(defun vfl-dlg-modus (n / dcl-pfad dat wahl ergebnis)
|
||||
(setq dcl-pfad (strcat (getenv "DXFM_DCL") "/vfl_edit_modus.dcl"))
|
||||
(setq dat (load_dialog dcl-pfad))
|
||||
(if (not (new_dialog "vfl_edit_modus" dat))
|
||||
(progn
|
||||
(if dat (unload_dialog dat))
|
||||
(alert (ssg-textf "vfl-edit-dialog-fehlt" (list dcl-pfad)))
|
||||
"rueck") ; Fallback: bisheriges Verhalten
|
||||
(progn
|
||||
;; Nur der Kopftext wird zur Laufzeit gesetzt; die Optionslabels stehen
|
||||
;; statisch (deutsch) im DCL - siehe vfl_edit_modus.dcl. get_tile "modus"
|
||||
;; liefert den key des gewaehlten radio_button. Default "modus_rueck" ist
|
||||
;; im DCL per value="1" vorbelegt.
|
||||
(set_tile "kopf" (ssg-textf "vfl-dlg-modus-kopf" (list (itoa n))))
|
||||
(action_tile "accept" "(setq wahl (get_tile \"modus\")) (done_dialog 1)")
|
||||
(action_tile "cancel" "(done_dialog 0)")
|
||||
(setq ergebnis (start_dialog))
|
||||
(unload_dialog dat)
|
||||
(cond
|
||||
((/= ergebnis 1) nil)
|
||||
((= wahl "modus_glied") "glied")
|
||||
(t "rueck"))))) ; modus_rueck (o. leer) = zuruecksetzen
|
||||
|
||||
;; 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
|
||||
|
||||
+3
-1
@@ -12,12 +12,14 @@ vfl_edit : dialog {
|
||||
: text {
|
||||
key = "kopf";
|
||||
label = "";
|
||||
width = 70;
|
||||
}
|
||||
|
||||
: popup_list {
|
||||
key = "position";
|
||||
label = "Zuruecksetzen zu Sektion:";
|
||||
width = 40;
|
||||
edit_width = 60;
|
||||
list_width = 60;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
// ============================================================
|
||||
// vfl_edit_modus.dcl - Linienzug-Kette (VF_n, Marker "linienzug")
|
||||
// per Doppelklick bearbeiten: zuerst den Modus waehlen -
|
||||
// key "modus_rueck" = auf eine Sektion zuruecksetzen und ab dort
|
||||
// weiterbauen (bestehendes Verhalten,
|
||||
// vfl-dlg-position/vfl-journal-truncate)
|
||||
// key "modus_glied" = Eigenschaften EINES einzelnen Glieds aendern,
|
||||
// Rest bleibt (vfl-edit-glied)
|
||||
// Aufruf ueber vfl-edit-ent -> vfl-dlg-modus (Lisp/vf_linienzug.lsp).
|
||||
// Labels stehen wie in allen DCL-Files statisch (deutsch) hier - NICHT per
|
||||
// set_tile gefuellt (set_tile kann das label eines radio_button ohnehin nicht
|
||||
// setzen, nur den Zustand). Nur der Kopftext "kopf" wird zur Laufzeit gesetzt.
|
||||
// ============================================================
|
||||
|
||||
vfl_edit_modus : dialog {
|
||||
label = "Linienzug editieren";
|
||||
|
||||
: column {
|
||||
|
||||
: text {
|
||||
key = "kopf";
|
||||
label = "";
|
||||
}
|
||||
|
||||
: boxed_radio_column {
|
||||
label = "Was moechten Sie tun?";
|
||||
key = "modus";
|
||||
|
||||
: radio_button {
|
||||
key = "modus_rueck";
|
||||
label = "Auf eine Sektion zuruecksetzen und ab dort neu bauen";
|
||||
value = "1";
|
||||
}
|
||||
|
||||
: radio_button {
|
||||
key = "modus_glied";
|
||||
label = "Nur die Eigenschaften eines einzelnen Glieds aendern";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ok_cancel;
|
||||
}
|
||||
@@ -766,6 +766,12 @@
|
||||
"vfl-edit-dialog-fehlt": "Dialog nicht gefunden: %1",
|
||||
"vfl-edit-abgebrochen": "\nEditieren abgebrochen - keine Aenderung.",
|
||||
"vfl-dlg-kopf-sektionen": "Sektionen: %1",
|
||||
"vfl-dlg-modus-kopf": "Linienzug mit %1 Glied(ern) - was moechten Sie tun?",
|
||||
"vfl-dlg-modus-rueck": "Auf eine Sektion zuruecksetzen und ab dort neu bauen",
|
||||
"vfl-dlg-modus-glied": "Nur die Eigenschaften eines einzelnen Glieds aendern",
|
||||
"vfl-glied-waehlen-kopf": "Welches Glied moechten Sie bearbeiten?",
|
||||
"vfl-glied-geaendert": "\n>>> Glied %1 geaendert - Kette wird neu aufgebaut...",
|
||||
"vfl-glied-nicht-editierbar": "Dieses Glied (%1) kann derzeit nicht einzeln bearbeitet werden.\nNur GF-Bogen-Glieder sind einzeln editierbar. Fuer alle anderen bitte den Modus 'Auf eine Sektion zuruecksetzen' verwenden.",
|
||||
"vfc-warnung-untermodule-nicht-geladen": "\n[vf_core] WARNUNG: DXFM_LISP nicht gesetzt - Untermodule konnten nicht geladen werden!",
|
||||
"vfc-linienzug-modus-header": "\n\nLinienzug-Modus waehlen:",
|
||||
"vfc-linienzug-modus-1": "\n 1 - Manuelle Eingabe (Punkte klicken)",
|
||||
|
||||
@@ -766,6 +766,12 @@
|
||||
"vfl-edit-dialog-fehlt": "Dialog not found: %1",
|
||||
"vfl-edit-abgebrochen": "\nEdit cancelled - no change.",
|
||||
"vfl-dlg-kopf-sektionen": "Sections: %1",
|
||||
"vfl-dlg-modus-kopf": "Chain with %1 segment(s) - what would you like to do?",
|
||||
"vfl-dlg-modus-rueck": "Roll back to a section and rebuild from there",
|
||||
"vfl-dlg-modus-glied": "Only change the properties of a single segment",
|
||||
"vfl-glied-waehlen-kopf": "Which segment would you like to edit?",
|
||||
"vfl-glied-geaendert": "\n>>> Segment %1 changed - rebuilding chain...",
|
||||
"vfl-glied-nicht-editierbar": "This segment (%1) cannot currently be edited individually.\nOnly GF arc segments support single-segment editing. For all others please use the 'Roll back to a section' mode.",
|
||||
"vfc-warnung-untermodule-nicht-geladen": "\n[vf_core] WARNING: DXFM_LISP not set - submodules could not be loaded!",
|
||||
"vfc-linienzug-modus-header": "\n\nSelect line-path mode:",
|
||||
"vfc-linienzug-modus-1": "\n 1 - Manual entry (click points)",
|
||||
|
||||
Reference in New Issue
Block a user