Move the CAD dialog to dxfmakros and target DXFM_LISP

The TRO edit dialog belongs with the other SSG_LIB edit commands, so
cad/tro_edit.lsp and cad/tro_edit.dcl move to dxfmakros (Lisp/Tro_Edit.lsp,
dcl/tro_edit.dcl) where they use the ssg_* helpers, the DXFM_DCL path and the
existing SSG_BLOCKEDIT dispatcher instead of standing on their own. Keeping a
second copy here would only let the two drift apart before the repos are merged.

--emit-lisp now writes the generated type list to DXFM_LISP when that variable is
set, so it lands next to the SSG_LIB modules that read it. Without the variable it
still writes to cad/ and says where the file actually belongs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-03 12:06:55 +02:00
parent 0f02fd83aa
commit ecc9c8fb53
3 changed files with 22 additions and 199 deletions
-35
View File
@@ -1,35 +0,0 @@
// ================================================================
// SPS_SKEL - Dialog zum Bearbeiten eines TRO-Markers
// ================================================================
// Wird von cad/tro_edit.lsp geladen (Befehl TROEDIT).
// Bearbeitet werden die Attribute ID und TYPE eines TRO_SYM_*-Blocks.
// ================================================================
tro_edit : dialog {
label = "TRO bearbeiten";
: boxed_column {
label = "Block";
: text { key = "blockname"; label = ""; }
: text { key = "position"; label = ""; }
}
: boxed_column {
label = "Attribute";
: edit_box {
key = "id";
label = "&ID";
edit_width = 24;
}
: popup_list {
key = "type";
label = "&Typ";
width = 26;
}
}
: text { key = "hint"; label = ""; }
spacer;
ok_cancel;
}
-160
View File
@@ -1,160 +0,0 @@
;; ================================================================
;; SPS_SKEL - TROEDIT: Attribute eines TRO-Markers bearbeiten
;; ================================================================
;; Befehl: TROEDIT -> Marker waehlen -> Dialog -> OK schreibt zurueck
;;
;; Bearbeitet die Attribute ID und TYPE eines Blocks TRO_SYM_*, die von
;; lib/tro_annotate.py eingefuegt wurden. Die Auswahlliste der Typen kommt aus
;; cad/tro_types.lsp (erzeugt mit "tro_annotate.py --emit-lisp"); fehlt die
;; Datei, ist TYPE ein freies Eingabefeld.
;;
;; Laden in BricsCAD:
;; (load "<Pfad>/cad/tro_edit.lsp")
;; oder cad/ in die Supportpfade aufnehmen und per APPLOAD dauerhaft laden.
;;
;; Doppelklick statt Befehl: in der CUI unter "Doppelklick-Aktionen" fuer den
;; Objekttyp "Block-Referenz" den Befehl TROEDIT hinterlegen.
;;
;; Hinweis: der Dialog aendert nur die Attribute. Die *Form* des Markers gehoert
;; zur Blockdefinition des Typs - nach einer Typaenderung passt sie erst wieder,
;; wenn tro_annotate.py neu laeuft. Dasselbe gilt fuer FB_BLOCK, das aus dem Typ
;; abgeleitet ist.
;; ================================================================
(setq TRO:PREFIX "TRO_SYM_")
;; --- Hilfsfunktionen -------------------------------------------------------
(defun tro:attribs (blk / ent typ res)
"Alle ATTRIB-Unterobjekte einer Blockreferenz als ((Tag . Entity) ...)."
(setq ent (entnext blk) res '())
(while (and ent
(setq typ (cdr (assoc 0 (entget ent))))
(= typ "ATTRIB"))
(setq res (cons (cons (strcase (cdr (assoc 2 (entget ent)))) ent) res))
(setq ent (entnext ent)))
(reverse res))
(defun tro:get (attlist tag / pair)
"Wert eines Attributs lesen, sonst \"\"."
(if (setq pair (assoc (strcase tag) attlist))
(cdr (assoc 1 (entget (cdr pair))))
""))
(defun tro:put (attlist tag value / pair data)
"Wert eines Attributs schreiben. Gibt T zurueck, wenn das Attribut existiert."
(if (setq pair (assoc (strcase tag) attlist))
(progn
(setq data (entget (cdr pair)))
(entmod (subst (cons 1 value) (assoc 1 data) data))
(entupd (cdr pair))
T)
nil))
(defun tro:index (item lst / i found)
"Position von item in lst, sonst nil."
(setq i 0 found nil)
(foreach x lst
(if (and (not found) (= (strcase x) (strcase item))) (setq found i))
(setq i (1+ i)))
found)
(defun tro:types ()
"Gueltige Typen aus cad/tro_types.lsp, sonst nil."
(if (not *TRO-TYPES*)
(if (setq f (findfile "tro_types.lsp")) (load f)))
*TRO-TYPES*)
;; --- Befehl ----------------------------------------------------------------
(defun c:TROEDIT (/ sel blk data name attlist types dcl dlg
cur-id cur-type new-id new-type idx result)
;; 1. Marker waehlen
(setq sel (entsel "\nTRO-Marker waehlen: "))
(if (not sel)
(progn (princ "\nAbgebrochen.") (exit)))
(setq blk (car sel)
data (entget blk))
(if (/= (cdr (assoc 0 data)) "INSERT")
(progn (princ "\nDas ist keine Blockreferenz.") (exit)))
(setq name (cdr (assoc 2 data)))
(if (/= (substr name 1 (strlen TRO:PREFIX)) TRO:PREFIX)
(progn
(princ (strcat "\nBlock \"" name "\" ist kein TRO-Marker (erwartet "
TRO:PREFIX "*)."))
(exit)))
(setq attlist (tro:attribs blk))
(if (not (assoc "ID" attlist))
(progn
(princ "\nBlock hat kein Attribut ID - bitte neu beschriften lassen.")
(exit)))
(setq cur-id (tro:get attlist "ID")
cur-type (tro:get attlist "TYPE")
types (tro:types))
;; Typ des Blocks ergaenzen, falls er nicht in der Liste steht
(if (and types (/= cur-type "") (not (tro:index cur-type types)))
(setq types (append types (list cur-type))))
(if (not types) (setq types (list cur-type)))
;; 2. Dialog laden
(setq dcl (findfile "tro_edit.dcl"))
(if (not dcl)
(progn
(princ "\ntro_edit.dcl nicht gefunden - cad/ in die Supportpfade legen.")
(exit)))
(setq dlg (load_dialog dcl))
(if (not (new_dialog "tro_edit" dlg))
(progn (unload_dialog dlg) (princ "\nDialog nicht ladbar.") (exit)))
;; 3. Felder fuellen
(set_tile "blockname" (strcat "Block: " name))
(set_tile "position"
(strcat "Position: "
(rtos (car (cdr (assoc 10 data))) 2 1) " / "
(rtos (cadr (cdr (assoc 10 data))) 2 1)))
(set_tile "hint" "Form und FB_BLOCK folgen erst beim naechsten Lauf.")
(set_tile "id" cur-id)
(start_list "type")
(foreach t types (add_list t))
(end_list)
(setq idx (tro:index cur-type types))
(set_tile "type" (itoa (if idx idx 0)))
;; 4. Eingaben abholen
(setq new-id cur-id new-type cur-type)
(action_tile "id" "(setq new-id (get_tile \"id\"))")
(action_tile "type" "(setq new-type (nth (atoi (get_tile \"type\")) types))")
(action_tile "accept"
"(setq new-id (get_tile \"id\")
new-type (nth (atoi (get_tile \"type\")) types))
(done_dialog 1)")
(action_tile "cancel" "(done_dialog 0)")
(setq result (start_dialog))
(unload_dialog dlg)
;; 5. Zurueckschreiben
(if (= result 1)
(progn
(if (= (vl-string-trim " " new-id) "")
(princ "\nID darf nicht leer sein - nichts geaendert.")
(progn
(tro:put attlist "ID" new-id)
(tro:put attlist "TYPE" new-type)
(entupd blk)
(princ (strcat "\n" name ": ID = " new-id ", TYPE = " new-type))
(if (/= new-type cur-type)
(princ "\nTyp geaendert - tro_annotate.py neu laufen lassen, damit Form und FB passen."))))
)
(princ "\nAbgebrochen."))
(princ))
(princ "\nTROEDIT geladen. Befehl: TROEDIT")
(princ)
+22 -4
View File
@@ -61,6 +61,7 @@ import collections
import csv as csv_module
import json
import math
import os
import sys
from pathlib import Path
@@ -101,13 +102,27 @@ def hex_to_rgb(value: str) -> tuple[int, int, int]:
return (int(text[0:2], 16), int(text[2:4], 16), int(text[4:6], 16))
def lisp_dir() -> Path:
"""
Zielordner fuer die erzeugte LISP-Typliste.
Bevorzugt DXFM_LISP - dort liegen die SSG_LIB-Module in dxfmakros, die den
Dialog TRO_EDIT bereitstellen. Ohne die Variable landet die Datei in
<SPS_SKEL>/cad, damit der Lauf auch ohne dxfmakros funktioniert.
"""
env = os.environ.get("DXFM_LISP")
if env:
return Path(env)
return Path(__file__).resolve().parent.parent / "cad"
def emit_lisp(cad_dir: Path) -> Path:
"""
Typliste fuer den DCL-Dialog schreiben.
Der Dialog TROEDIT bietet TYPE als Auswahlliste an. Damit sie nicht von der
Typdefinition abweicht, wird sie hier aus TRO_CATALOG erzeugt statt in der
LISP-Datei gepflegt.
Der Dialog TRO_EDIT (dxfmakros/Lisp/Tro_Edit.lsp) bietet TYPE als
Auswahlliste an. Damit sie nicht von der Typdefinition abweicht, wird sie
hier aus TRO_CATALOG erzeugt statt in der LISP-Datei gepflegt.
"""
cad_dir.mkdir(parents=True, exist_ok=True)
path = cad_dir / "tro_types.lsp"
@@ -546,8 +561,11 @@ def main(argv: list[str] | None = None) -> int:
warnings: list[str] = []
if args.emit_lisp:
path = emit_lisp(Path(__file__).resolve().parent.parent / "cad")
path = emit_lisp(lisp_dir())
print(f"Typliste geschrieben: {path} ({len(TRO_CATALOG)} Typen)")
if not os.environ.get("DXFM_LISP"):
print("HINWEIS: DXFM_LISP nicht gesetzt - die Datei gehoert neben die "
"SSG_LIB-Module (dxfmakros/Lisp), damit TRO_EDIT sie findet.")
return 0
if not args.dxf: