diff --git a/CLAUDE.md b/CLAUDE.md index 52ca296..902a3a7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -114,7 +114,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `export.lsp` | EXPORTSIVAS, EXPORTCSV, OMNI_UPDATE_ATTRIBS, CSV_EXPORT_KONFIG | JSON-Sammlung und Python-Export (Omniflo-Merkmale/Sum-Zeile via lib/export_csv.py). **Gefrorene Layer**: `csv:collect-export-blocks` laesst Bloecke auf gefrorenen Layern aus (ausgeschaltete Layer zaehlen NICHT), Schalter `*csv-gefrorene-ausschliessen*` (Standard an, Toggle im Dialog CSV_EXPORT_KONFIG). Die Hilfsobjekte eines gefrorenen VF_n/GF_n (Separator-/Element-Kopien, Einheiten-/AS-ES-Marker) liegen auf eigenen Layern und werden darum ueber `*csv-ausschluss-enames*` mit ausgelassen (gesetzt in `csv:export-vorbereiten` per `csv:hilfskopien-ausschluss`); erzeugt und nummeriert werden sie trotzdem, damit IDs stabil bleiben. DrawPlanquadrate nutzt dieselbe Sammlung und folgt dem Filter. **Hoehen-Neuberechnung**: erster Schritt von `csv:export-vorbereiten` ist `csv:hoehen-aktualisieren` - in Z verschobene `KREISEL_*`/`ECKRAD_*`/`VF_*`/`GF_*` bekommen ihre Hoehen-Attribute aus der Einfuege-Z neu (reiner Kern `csv:hoehen-werte`, getestet; Formeln/Rundung wie beim Bau: Kreisel HOEHE + MONTAGEHOEHE_m=z/1000, Eckrad HOEHE, GF/VF HOEHE_VON_mm=(fix z), MONTAGEHOEHE_m GF=z/1000 bzw. VF=(VON+BIS)/2000). HOEHE_BIS_mm = VON - (VON_alt - BIS_alt), bewusst NICHT z - DELTA_H_mm (ohne Vorzeichen -> steigende VF falsch, separat abgeschnitten -> 1 mm Abweichung); DELTA_H_mm nur Rueckfall. Nicht verschobene Bloecke (Attribut passt zu z) bleiben unangetastet, damit Bau-Werte und Hand-Korrekturen (z.B. Buehnen-Abzug aus HOEHEN_CHECK) bit-genau erhalten bleiben | | `OmniModulInsert.lsp` | OMNI_LOAD, OMNI_APB_*, OMNI_W*_*, OMNI_AP60/AP110, OMNI_TEF_*, OMNI_TV_*, OMNI_APBW_*, OMNI_LADESCHLEIFE_AP110, OMNI_EDIT | Omniflo-Komponenten: Boegen, Weichen, Verbinder (`OMNI_TV_*`: DWGs dimensionsunabhaengig in `data/omniflo/Verbinder`, `omni:insert-verbinder` -> gemeinsamer Einfuegekern `omni:insert-datei`, den auch `omni:insert-dxf` nutzt; im Export ueber `pattern_verbinder` = `VB_*, TV_*` gesammelt (`csv:collect-export-blocks`, `ssg-id-collect-blocks`), Sivas-Zeilen ueber TEILEART/ARTINR wie alle Omniflo-Teile), Transferwagen, Ladeschleifen (`data/json/omniflo_ladeschleifen.json`, per `ssg-json-laden`, da die Beschreibungen Kommas enthalten; Blockdatei darf `.dwg` statt `.dxf` sein), Edit-Dialog | | `SSG_LIB_Commands.lsp` | ILS_BTMT_Beladung, ILS_BTMT_Entladung, ILS_SCANNER_INSERT, ILS_SEPARATOR_INSERT, ILS_EINGANG_INSERT, ILS_AUSGANG_INSERT, SSG_BLOCKEDIT, SSG_DIM_SWITCH, SSG_SPRACHE | BTMT Be-/Entladung (`ils-insert-station`: wiederholtes Einfuegen von `BTMT-Beladung` bzw. `SC_Entladung`, Drehung interaktiv, Layer aus `LAYER`-Attribut, Dimension via `ssg-ils-block-laden`) + Sensoren (`ils-insert-sensor`) + Eingang-/Ausgang-Symbol (frei platzierbar wie BTMT Be-/Entladung, ueber `ils-insert-station` mit den Rohnamen `Eingang`/`Ausgang`, Bloecke `Eingang_.dwg`/`Ausgang_.dwg` in data/ils) + Doppelklick/Kontextmenue-Dispatcher + Konfiguration (2D/3D, Sprache) | -| `Tro_Edit.lsp` | TRO_INSERT, TRO_EDIT | TRO-Marker (Block `TRO_SYM_`) fuer sps_skel (lib/tro_annotate.py): TRO_INSERT fuegt eine bestehende Blockdefinition an einem gewaehlten Punkt ein und setzt ID/TYPE (bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat - die entsteht nur ueber tro_annotate.py); TRO_EDIT aendert ID/TYPE eines bestehenden Markers per Dialog. Typliste aus `tro_types.lsp` (von `tro_annotate.py --emit-lisp` nach DXFM_LISP geschrieben). Der Dispatcher SSG_BLOCKEDIT leitet Blocknamen `TRO_*` zu TRO_EDIT. | +| `Tro_Edit.lsp` | TRO_INSERT, TRO_EDIT | TRO-Marker (Block `TRO_SYM_`) fuer sps_skel (lib/tro_annotate.py): TRO_EDIT/TRO_INSERT teilen EINEN Dialog (`tro_edit.dcl`) fuer alle Typen: Kennung, Typ und eine Slot-Liste (Bauteil-TeileId je `separator`/`switch`/`scanner`/`drive`/`line`, Attribut `SLOTS`), die Slots kommen aus dem Typ (`*TRO-SLOTS*`), gleichnamige Slots bleiben beim Typwechsel; +/- fuer Lagerlinien; "Im Plan waehlen <" (done_dialog 2 -> getpoint -> naechstes Bauteil passender Art aus dem XRECORD `SPS_SKEL_PARTS`, Pruefung ueber `*TRO-SLOT-KINDS*`); Warnzeile fuer leere Separatoren/doppelte Bauteile, speichern geht trotzdem. TRO_INSERT setzt eine bestehende Blockdefinition ein (Enter = Mitte der Bauteile; bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat - die entsteht nur ueber tro_annotate.py), `KEY` bleibt leer = neuer TRO. Zurueck nach sps_skel: DXF speichern, `tro_annotate --read-tros`. Typliste/Slots aus `tro_types.lsp` (von `tro_annotate.py --emit-lisp` nach DXFM_LISP geschrieben). Der Dispatcher SSG_BLOCKEDIT leitet Blocknamen `TRO_*` zu TRO_EDIT. | | `Connection_Edit.lsp` | CONNECTION_INSERT, CONNECTION_EDIT | Verbindung zwischen zwei TRO-Markern als Block `CONNECTION_ARROW` (Pfeilmitte); Beziehung ueber die INTERNEN IDs der TROs (`FROM_ID`/`TO_ID`, sichtbar `FROM_TRO`/`TO_TRO`, `KIND` flow/colocated), damit Umbenennen/Verschieben die Zuordnung nicht bricht. Dialog `connection_edit.dcl`; SSG_BLOCKEDIT leitet `CONNECTION_*` hierher (vor dem TRO-Zweig) | | `Jam_Edit.lsp` | JAM_EDIT | Staubereich `JAM_AREA` aus sps_skel (`tro_annotate.py --anlage`, Name `Jam_`) bearbeiten: Foerderer und laufende Nummer per Dialog `jam_edit.dcl`, Knopf zurueck auf den abgeleiteten Wert (`AUTO`), Warnung bei doppeltem Namen. `TRO`/`ENTRY` sind stabiler Schluessel und werden nicht geaendert. SSG_BLOCKEDIT leitet `JAM_*` hierher; in die SCL kommt die Aenderung ueber `tro_annotate --read-jams` | | `TEFInsert.lsp` | TEF_FOERDERER_LINIE | Linie zwischen zwei Punkten zeichnen und mit 1000-mm-TEF-Geraden (`0_B10030`) belegen; Rest ueber ein zurueckversetztes Element, damit der Foerderer exakt am Linienende endet; geneigte Linien per Rz*Ry wie `ssg_ks_insert.lsp` | @@ -136,8 +136,7 @@ Detaillierte Dokumentation aller Funktionen und Befehle: siehe `Lisp/README.md`. | `omniflo_weichen.dcl` | OMNI_W*_* (OmniModulInsert.lsp) | | `omniflo_ladeschleifen.dcl` | OMNI_LADESCHLEIFE_* (OmniModulInsert.lsp, `omni:ladeschleifen-dialog`) | | `sprache.dcl` | SSG_SPRACHE (SSG_LIB_Commands.lsp) | -| `tro_insert.dcl` | TRO_INSERT (Tro_Edit.lsp) | -| `tro_edit.dcl` | TRO_EDIT (Tro_Edit.lsp) | +| `tro_edit.dcl` | TRO_EDIT und TRO_INSERT (Tro_Edit.lsp) - ein Dialog fuer alle TRO-Typen | | `connection_edit.dcl` | CONNECTION_INSERT/CONNECTION_EDIT (Connection_Edit.lsp) | | `jam_edit.dcl` | JAM_EDIT (Jam_Edit.lsp) | | `csv_export_konfig.dcl` | CSV_EXPORT_KONFIG (export.lsp) | diff --git a/Lisp/README.md b/Lisp/README.md index a693db8..817c961 100644 --- a/Lisp/README.md +++ b/Lisp/README.md @@ -826,12 +826,33 @@ TRO-Marker (Block `TRO_SYM_`) fuer `sps_skel`/`lib/tro_annotate.py`. | Befehl | Beschreibung | | --- | --- | -| `c:TRO_INSERT` | Bestehende Blockdefinition an gewaehltem Punkt einfuegen, setzt ID/TYPE; bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat (entsteht nur ueber `tro_annotate.py`) | -| `c:TRO_EDIT` | ID/TYPE eines bestehenden Markers per Dialog aendern | +| `c:TRO_INSERT` | Neuen Marker anlegen: Dialog wie TRO_EDIT, dann Einfuegepunkt (Enter = Mitte der gewaehlten Bauteile); bricht ab, wenn der Typ noch keine Blockdefinition in der Zeichnung hat (entsteht nur ueber `tro_annotate.py`) | +| `c:TRO_EDIT` | Kennung, Typ und Bauteile je Slot eines bestehenden Markers per Dialog aendern | -Typliste kommt aus [`tro_types.lsp`](../Lisp/tro_types.lsp) (von -`tro_annotate.py --emit-lisp` nach `DXFM_LISP` geschrieben). `SSG_BLOCKEDIT` -leitet Blocknamen `TRO_*` zu `TRO_EDIT`. +Ein Dialog (`dcl/tro_edit.dcl`) fuer alle TRO-Typen: statt einer Maske je +Typ zeigt eine Liste die Slots des Typs (`separator1`, `switch1`, +`scanner1`, `drive`, Lagerlinien `line1..N`) mit ihrem Bauteil (TeileId). +Die Zeile darunter bearbeitet den gewaehlten Slot: + +- **Im Plan waehlen <** schliesst den Dialog, nimmt einen Punkt und setzt + das naechste Bauteil der passenden Art aus der Bauteiltabelle (XRECORD + `SPS_SKEL_PARTS`, von `tro_annotate.py` in die Zeichnung gelegt) - eine + Weiche laesst sich nicht in einen Separator-Slot waehlen. +- **+ / - Lagerlinie** nur bei Typen mit Lagerlinien (PinStore_Auto, + EmptyCarrBuffer); die Katalogzahl ist nur die Vorgabe. +- Beim Typwechsel behalten gleichnamige Slots ihr Bauteil. +- Leere Separatoren, doppelte Bauteile und Bauteile anderer Marker stehen + als Warnung im Dialog; speichern geht trotzdem. + +Gespeichert wird im Attribut `SLOTS` (`separator1=0010;switch1=0061;lines=0066,0069`); +`KEY` ist der Schluessel fuer sps_skel und bleibt bei TRO_INSERT leer. +Zurueck nach sps_skel: Zeichnung als DXF speichern, +`tro_annotate --file --read-tros` (schreibt `cfg/tro_overrides.ini`). + +Typliste, Slots je Typ (`*TRO-SLOTS*`) und Bauteilarten je Slot +(`*TRO-SLOT-KINDS*`) kommen aus [`tro_types.lsp`](../Lisp/tro_types.lsp) +(von `tro_annotate.py --emit-lisp` nach `DXFM_LISP` geschrieben). +`SSG_BLOCKEDIT` leitet Blocknamen `TRO_*` zu `TRO_EDIT`. --- diff --git a/Lisp/Tro_Edit.lsp b/Lisp/Tro_Edit.lsp index b60294c..b7ada63 100644 --- a/Lisp/Tro_Edit.lsp +++ b/Lisp/Tro_Edit.lsp @@ -1,23 +1,35 @@ ;; ============================================================ ;; TRO_EDIT.LSP - TRO-Marker einfuegen und bearbeiten ;; -;; Verwaltet die Attribute ID und TYPE eines TRO_*-Blocks. Die Marker -;; werden in der Regel von sps_skel (lib/tro_annotate.py) in eine Kopie der -;; Zeichnung eingefuegt; ein Marker ist ein Block TRO_SYM_ mit den -;; Attributen +;; Verwaltet die Attribute eines TRO_*-Blocks. Die Marker werden in der +;; Regel von sps_skel (lib/tro_annotate.py) in eine Kopie der Zeichnung +;; eingefuegt; ein Marker ist ein Block TRO_SYM_ mit den Attributen ;; ID, TYPE sichtbar ;; FB_BLOCK sichtbar (nur wenn mit --fb beschriftet) -;; ITEMS, CONFIDENCE, SEPARATORS unsichtbar, reine Daten +;; UID, ITEMS, CONFIDENCE unsichtbar, reine Daten +;; KEY unsichtbar, Schluessel fuer sps_skel (ID der +;; ID-Datei); leer bei einem mit TRO_INSERT gesetzten +;; SLOTS unsichtbar, Bauteil (TeileId) je Slot: +;; "separator1=0010;switch1=0061;lines=0066,0069" +;; +;; Ein Dialog fuer alle Typen (dcl/tro_edit.dcl): die Slot-Liste kommt aus +;; dem Typ (*TRO-SLOTS*), nicht aus einer eigenen Maske je Typ. Bei einem +;; Typwechsel behalten gleichnamige Slots ihr Bauteil. Typen mit +;; Lagerlinien (PinStore_Auto, EmptyCarrBuffer) bekommen +/- fuer die +;; Linien. "Im Plan waehlen <" schliesst den Dialog, nimmt einen Punkt und +;; setzt das naechste Bauteil der passenden Art aus der Bauteiltabelle +;; (XRECORD SPS_SKEL_PARTS, von tro_annotate.py in die Zeichnung gelegt). +;; Leere Separatoren und Bauteile, die schon in einem anderen Marker +;; stecken, zeigt der Dialog als Warnung - speichern geht trotzdem. ;; ;; Aufruf TRO_INSERT (neuen Marker einfuegen): ;; - Menue SSG_LIB > TRO > Marker einfuegen ;; - direkt: TRO_INSERT ;; Fuegt eine bestehende TRO_SYM_-Blockdefinition ein - die Form ;; entsteht nur ueber tro_annotate.py, TRO_INSERT zeichnet keine neue. -;; Ohne einen frueheren Lauf mit dem gewuenschten Typ bricht der Befehl -;; mit einem Hinweis ab. +;; Enter beim Einfuegepunkt setzt den Marker in die Mitte seiner Bauteile. ;; -;; Aufruf TRO_EDIT (Attribute eines bestehenden Markers aendern): +;; Aufruf TRO_EDIT (bestehenden Marker aendern): ;; - Doppelklick auf den Marker -> ***DOUBLECLICK [INSERT] -> SSG_BLOCKEDIT ;; - EATTEDIT -> c:EATTEDIT -> SSG_BLOCKEDIT ;; - Menue SSG_LIB > TRO > Marker bearbeiten @@ -25,21 +37,30 @@ ;; Der Dispatcher SSG_BLOCKEDIT (SSG_LIB_Commands.lsp) leitet Blocknamen ;; "TRO_*" hierher. ;; -;; Die Auswahlliste der Typen kommt aus tro_types.lsp, die sps_skel mit +;; Zurueck nach sps_skel: Zeichnung als DXF speichern, dann +;; tro_annotate --file --read-tros +;; schreibt die Aenderungen (auch geloeschte Marker) nach +;; cfg/tro_overrides.ini; tro_flow wendet sie beim naechsten Lauf an. +;; +;; Typliste, Slots je Typ und Bauteilarten je Slot kommen aus tro_types.lsp, +;; die sps_skel mit ;; lib/tro_annotate.py --emit-lisp ;; nach DXFM_LISP schreibt. Fehlt die Datei, bleibt bei TRO_EDIT nur der -;; aktuelle Typ des Blocks in der Liste; TRO_INSERT bricht dann ab (siehe +;; aktuelle Typ mit den Slots des Markers; TRO_INSERT bricht dann ab (siehe ;; tro-insert-kein-typ). ;; -;; Grenze: TRO_EDIT aendert nur die Attribute, TRO_INSERT nur die Position - -;; die *Form* des Markers gehoert zur Blockdefinition des Typs und +;; Grenze: die *Form* des Markers gehoert zur Blockdefinition des Typs und ;; FB_BLOCK ist aus dem Typ abgeleitet; beides passt erst nach einem neuen ;; Lauf von tro_annotate.py wieder. ;; -;; Setzt ssg_core.lsp (ssg-start/ssg-end, ssg-attrib-*) und ssg_lang.lsp voraus. +;; Setzt ssg_core.lsp (ssg-start/ssg-end, ssg-attrib-*, ssg-join) und +;; ssg_lang.lsp voraus. ;; ============================================================ (setq *tro-block-prefix* "TRO_SYM_") +(setq *tro-parts-xrecord* "SPS_SKEL_PARTS") +;; Umkreis (Zeichnungseinheiten = mm), in dem "Im Plan waehlen" ein Bauteil sucht +(setq *tro-pick-radius* 1000.0) ;; ------------------------------------------------------------ @@ -147,16 +168,410 @@ ) +;; ============================================================ +;; SLOTS - Bauteile je Slot +;; Ein Slot-Zustand ist eine Assoziationsliste (("separator1" . "0010") +;; ("switch1" . "") ("line1" . "0066") ...); "" = Slot leer. +;; ============================================================ + +;; Text an einem Trennzeichen zerlegen: (tro-split "a;b;" ";") -> ("a" "b" "") +(defun tro-split (text sep / pos res) + (while (setq pos (vl-string-search sep text)) + (setq res (cons (substr text 1 pos) res) + text (substr text (+ pos 1 (strlen sep)))) + ) + (reverse (cons text res)) +) + +;; Slot-Art ohne Nummer: "separator2" -> "separator", "line17" -> "line" +(defun tro-slot-art (slot) + (vl-string-right-trim "0123456789" slot) +) + +(defun tro-ist-linie (slot) + (= (tro-slot-art slot) "line") +) + +;; Definition eines Typs aus *TRO-SLOTS*: (Linien-Vorgabe "separator1" ...) +(defun tro-slot-def (typ) + (if (and (boundp '*TRO-SLOTS*) *TRO-SLOTS*) + (cdr (assoc typ *TRO-SLOTS*)) + ) +) + +(defun tro-linien-vorgabe (typ / def) + (setq def (tro-slot-def typ)) + (if def (car def) 0) +) + +(defun tro-linien-zahl (slots / n) + (setq n 0) + (foreach p slots (if (tro-ist-linie (car p)) (setq n (1+ n)))) + n +) + +;; Attribut SLOTS lesen: "separator1=0010;lines=0066,0069" -> Slot-Zustand +(defun tro-slots-lesen (text / pos k v n res) + (foreach teil (tro-split (if text text "") ";") + (if (setq pos (vl-string-search "=" teil)) + (progn + (setq k (strcase (vl-string-trim " " (substr teil 1 pos)) T) + v (vl-string-trim " " (substr teil (+ pos 2)))) + (if (= k "lines") + (progn + (setq n 0) + (foreach x (tro-split v ",") + (setq x (vl-string-trim " " x)) + (if (/= x "") + (setq n (1+ n) + res (cons (cons (strcat "line" (itoa n)) x) res)) + ) + ) + ) + (setq res (cons (cons k v) res)) + ) + ) + ) + ) + (reverse res) +) + +;; Slot-Zustand -> Attribut SLOTS. Nie leer ("-"), weil ssg-attrib-set-on +;; leere Werte nicht schreibt. +(defun tro-slots-text (slots / teile linien) + (foreach p slots + (if (tro-ist-linie (car p)) + (if (/= (cdr p) "") (setq linien (cons (cdr p) linien))) + (setq teile (cons (strcat (car p) "=" (cdr p)) teile)) + ) + ) + (setq teile (reverse teile)) + (if linien + (setq teile (append teile (list (strcat "lines=" (ssg-join (reverse linien) ","))))) + ) + (if teile (ssg-join teile ";") "-") +) + +;; Lagerlinien fortlaufend nummerieren (nach + / -) +(defun tro-linien-nummerieren (slots / n res) + (setq n 0) + (foreach p slots + (if (tro-ist-linie (car p)) + (setq n (1+ n) + res (cons (cons (strcat "line" (itoa n)) (cdr p)) res)) + (setq res (cons p res)) + ) + ) + (reverse res) +) + +;; Slots eines Typs aufbauen; gleichnamige Slots behalten ihr Bauteil aus +;; `alt`, Lagerlinien bleiben. Hat der Typ Lagerlinien und `alt` keine, +;; kommt die Vorgabe des Katalogs als leere Linien dazu. Ohne tro_types.lsp +;; bleibt `alt` unveraendert. +(defun tro-slots-fuer-typ (typ alt / def res linien n) + (setq def (tro-slot-def typ)) + (if (null def) + alt + (progn + (foreach s (cdr def) + (setq res (cons (cons s (if (assoc s alt) (cdr (assoc s alt)) "")) res)) + ) + (if (> (car def) 0) + (progn + (foreach p alt (if (tro-ist-linie (car p)) (setq linien (cons p linien)))) + (if linien + (setq res (append (reverse linien) res)) + (progn + (setq n 0) + (repeat (car def) + (setq n (1+ n) + res (cons (cons (strcat "line" (itoa n)) "") res)) + ) + ) + ) + ) + ) + (reverse res) + ) + ) +) + + +;; ============================================================ +;; BAUTEILTABELLE (XRECORD SPS_SKEL_PARTS von tro_annotate.py) +;; Je Bauteil (1 . TeileId) (3 . Art) (10 . Punkt) (40 . halbe Breite) +;; (41 . halbe Hoehe), Punkt in Zeichnungskoordinaten. +;; ============================================================ + +;; -> Liste von (TeileId Art (x y z) halbeBreite halbeHoehe) +(defun tro-teile-laden ( / xr teil res) + (if (setq xr (dictsearch (namedobjdict) *tro-parts-xrecord*)) + (foreach g xr + (cond + ((= (car g) 1) + (if teil (setq res (cons (reverse teil) res))) + (setq teil (list (cdr g)))) + ((and teil (member (car g) '(3 10 40 41))) + (setq teil (cons (cdr g) teil))) + ) + ) + ) + (if teil (setq res (cons (reverse teil) res))) + (reverse res) +) + +;; Abstand eines Punkts zum Bauteil (0 innerhalb seiner Huellbox) +(defun tro-teil-abstand (pt teil / p hw hh) + (setq p (nth 2 teil) hw (nth 3 teil) hh (nth 4 teil)) + (if (and hw hh (> hw 0) (> hh 0) + (<= (abs (- (car pt) (car p))) hw) + (<= (abs (- (cadr pt) (cadr p))) hh)) + 0.0 + (distance (list (car pt) (cadr pt)) (list (car p) (cadr p))) + ) +) + +;; Naechstes Bauteil am Punkt, nur Arten aus `arten` (nil = alle). +;; -> (teil . abstand) oder nil +(defun tro-teil-am-punkt (pt teile arten / best d) + (foreach teil teile + (if (or (null arten) (member (cadr teil) arten)) + (progn + (setq d (tro-teil-abstand pt teil)) + (if (or (null best) (< d (cdr best))) (setq best (cons teil d))) + ) + ) + ) + best +) + +;; Mitte der gesetzten Bauteile eines Slot-Zustands (Einfuegepunkt) oder nil +(defun tro-teile-mitte (slots teile / sx sy n teil) + (setq sx 0.0 sy 0.0 n 0) + (foreach p slots + (if (and (/= (cdr p) "") (setq teil (assoc (cdr p) teile))) + (setq sx (+ sx (car (nth 2 teil))) + sy (+ sy (cadr (nth 2 teil))) + n (1+ n)) + ) + ) + (if (> n 0) (list (/ sx n) (/ sy n) 0.0)) +) + + +;; ============================================================ +;; DIALOG - Zustand in globalen Variablen, weil action_tile-Ausdruecke +;; ausserhalb der aufrufenden Funktion laufen und der Dialog fuer +;; "Im Plan waehlen" geschlossen und neu geoeffnet wird. +;; *tro-st-id* *tro-st-type* *tro-st-slots* *tro-st-sel* (Index der +;; gewaehlten Zeile) *tro-st-liste* (Typliste) *tro-st-fremd* +;; ((TeileId . TRO-Kennung) der anderen Marker) +;; ============================================================ + +;; Bauteile aller anderen Marker sammeln (ent = eigener Marker oder nil) +(defun tro-fremde-teile (ent / ss i e a res) + (if (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat *tro-block-prefix* "*"))))) + (progn + (setq i 0) + (while (setq e (ssname ss i)) + (if (not (equal e ent)) + (progn + (setq a (ssg-attrib-read e)) + (foreach p (tro-slots-lesen (cdr (assoc "SLOTS" a))) + (if (/= (cdr p) "") + (setq res (cons (cons (cdr p) (cdr (assoc "ID" a))) res)) + ) + ) + ) + ) + (setq i (1+ i)) + ) + ) + ) + res +) + +;; Warnzeile: leere Separatoren/Linien, doppelte Bauteile, Bauteile anderer Marker +(defun tro-pruefen ( / leer doppelt fremd gesehen f teile) + (foreach p *tro-st-slots* + (cond + ((= (cdr p) "") + (if (wcmatch (car p) "separator*,line*") (setq leer (cons (car p) leer)))) + ((member (cdr p) gesehen) (setq doppelt (cons (cdr p) doppelt))) + (t + (setq gesehen (cons (cdr p) gesehen)) + (if (setq f (assoc (cdr p) *tro-st-fremd*)) + (setq fremd (cons (ssg-textf "tro-edit-fremd" (list (car f) (cdr f))) fremd)))) + ) + ) + (if leer + (setq teile (cons (ssg-textf "tro-edit-leer" (list (ssg-join (reverse leer) ", "))) teile))) + (if doppelt + (setq teile (cons (ssg-textf "tro-edit-doppelt" (list (ssg-join (reverse doppelt) ", "))) teile))) + (if fremd + (setq teile (cons (ssg-join (reverse fremd) ", ") teile))) + (if teile + (strcat "! " (ssg-join (reverse teile) "; ")) + (ssg-text "tro-edit-ok") + ) +) + +;; Liste und alles, was von ihr abhaengt, neu anzeigen +(defun tro-liste-zeigen ( / vorgabe) + (start_list "slots") + (foreach p *tro-st-slots* + (add_list (strcat (car p) "\t" (if (= (cdr p) "") "-" (cdr p)))) + ) + (end_list) + (if (null *tro-st-slots*) + (setq *tro-st-sel* nil) + (progn + (if (or (null *tro-st-sel*) (>= *tro-st-sel* (length *tro-st-slots*))) + (setq *tro-st-sel* 0)) + (set_tile "slots" (itoa *tro-st-sel*)) + ) + ) + (tro-auswahl-zeigen) + (setq vorgabe (tro-linien-vorgabe *tro-st-type*)) + (mode_tile "plus" (if (> vorgabe 0) 0 1)) + (mode_tile "minus" (if (> (tro-linien-zahl *tro-st-slots*) 0) 0 1)) + (set_tile "linien" + (if (> vorgabe 0) + (ssg-textf "tro-edit-linien" + (list (itoa (tro-linien-zahl *tro-st-slots*)) (itoa vorgabe))) + "")) + (set_tile "warnung" (tro-pruefen)) +) + +;; Edit-Zeile zur gewaehlten Zeile +(defun tro-auswahl-zeigen () + (set_tile "teil" (if *tro-st-sel* (cdr (nth *tro-st-sel* *tro-st-slots*)) "")) + (foreach k '("teil" "pick" "leeren") (mode_tile k (if *tro-st-sel* 0 1))) +) + +;; Bauteil der gewaehlten Zeile setzen +(defun tro-slot-setzen (wert / p) + (if *tro-st-sel* + (progn + (setq p (nth *tro-st-sel* *tro-st-slots*)) + (setq *tro-st-slots* + (subst (cons (car p) (vl-string-trim " " wert)) p *tro-st-slots*)) + ) + ) +) + +(defun tro-typ-wechseln (typ) + (setq *tro-st-slots* (tro-slots-fuer-typ typ *tro-st-slots*) + *tro-st-type* typ) + (tro-liste-zeigen) +) + +;; + Lagerlinie: neue leere Linie am Ende, gewaehlt +(defun tro-linie-plus () + (setq *tro-st-slots* + (tro-linien-nummerieren (append *tro-st-slots* (list (cons "line0" "")))) + *tro-st-sel* (1- (length *tro-st-slots*))) + (tro-liste-zeigen) +) + +;; - Lagerlinie: die gewaehlte Linie, sonst die letzte +(defun tro-linie-minus ( / weg) + (if (and *tro-st-sel* (tro-ist-linie (car (nth *tro-st-sel* *tro-st-slots*)))) + (setq weg (nth *tro-st-sel* *tro-st-slots*)) + (foreach p *tro-st-slots* (if (tro-ist-linie (car p)) (setq weg p))) + ) + (if weg + (setq *tro-st-slots* (tro-linien-nummerieren (vl-remove weg *tro-st-slots*)))) + (tro-liste-zeigen) +) + +;; "Im Plan waehlen" - laeuft bei geschlossenem Dialog (done_dialog 2) +(defun tro-waehlen ( / slot arten teile pt ok anderes) + (setq slot (car (nth *tro-st-sel* *tro-st-slots*)) + arten (cdr (assoc (tro-slot-art slot) + (if (boundp '*TRO-SLOT-KINDS*) *TRO-SLOT-KINDS*)))) + (setq teile (tro-teile-laden)) + (cond + ((null teile) (alert (ssg-text "tro-edit-keine-teile"))) + ((setq pt (getpoint (ssg-textf "tro-edit-prompt-teil" + (list slot (if arten (ssg-join arten "/") "?"))))) + (setq ok (tro-teil-am-punkt pt teile arten) + anderes (tro-teil-am-punkt pt teile nil)) + (cond + ((and ok (<= (cdr ok) *tro-pick-radius*)) + (tro-slot-setzen (car (car ok))) + (princ (ssg-textf "tro-edit-gewaehlt" + (list slot (car (car ok)) (cadr (car ok)))))) + ((and anderes (<= (cdr anderes) *tro-pick-radius*)) + (alert (ssg-textf "tro-edit-falsche-art" + (list (car (car anderes)) (cadr (car anderes)) slot + (ssg-join arten "/"))))) + (t (alert (ssg-textf "tro-edit-kein-teil" (list (rtos *tro-pick-radius* 2 0))))) + )) + ) +) + +;; Dialog mit dem aktuellen Zustand zeigen, bis OK (1) oder Abbruch (0). +;; Gibt 1 oder 0 zurueck; der Zustand steht danach in *tro-st-...*. +(defun tro-dialog (kopf fb hinweis / dcl-pfad dat ergebnis idx) + (setq dcl-pfad (strcat (getenv "DXFM_DCL") "/tro_edit.dcl")) + (setq dat (load_dialog dcl-pfad)) + (setq ergebnis 2) + (while (= ergebnis 2) + (if (or (< dat 0) (not (new_dialog "tro_edit" dat))) + (progn + (alert (ssg-textf "tro-edit-dialog-fehlt" (list dcl-pfad))) + (setq ergebnis 0) + ) + (progn + (set_tile "blockname" kopf) + (set_tile "fb" fb) + (set_tile "hinweis" hinweis) + (set_tile "id" *tro-st-id*) + (start_list "type") + (foreach typ *tro-st-liste* (add_list typ)) + (end_list) + (setq idx (tro-index *tro-st-type* *tro-st-liste*)) + (set_tile "type" (itoa (if idx idx 0))) + (tro-liste-zeigen) + + (action_tile "id" "(setq *tro-st-id* $value)") + (action_tile "type" "(tro-typ-wechseln (nth (atoi $value) *tro-st-liste*))") + (action_tile "slots" "(setq *tro-st-sel* (atoi $value)) (tro-auswahl-zeigen)") + (action_tile "teil" "(tro-slot-setzen $value) (tro-liste-zeigen)") + (action_tile "leeren" "(tro-slot-setzen \"\") (tro-liste-zeigen)") + (action_tile "plus" "(tro-linie-plus)") + (action_tile "minus" "(tro-linie-minus)") + (action_tile "pick" + "(setq *tro-st-id* (get_tile \"id\")) (done_dialog 2)") + (action_tile "accept" + (strcat "(setq *tro-st-id* (get_tile \"id\"))" + "(tro-slot-setzen (get_tile \"teil\"))" + "(done_dialog 1)")) + (action_tile "cancel" "(done_dialog 0)") + + (setq ergebnis (start_dialog)) + (if (= ergebnis 2) (tro-waehlen)) + ) + ) + ) + (if (>= dat 0) (unload_dialog dat)) + ergebnis +) + + ;; ------------------------------------------------------------ ;; C:TRO_INSERT - neuen TRO-Marker einfuegen ;; -;; Fuegt eine bestehende TRO_SYM_-Blockdefinition an einem gewaehlten -;; Punkt ein und setzt ID und TYPE. Die Blockdefinition (Form, Farbe) -;; entsteht nur ueber sps_skel (lib/tro_annotate.py) - ohne einen frueheren -;; Lauf mit dem gewuenschten Typ bricht der Befehl mit einem Hinweis ab. +;; Fragt Typ, Kennung und Bauteile im selben Dialog wie TRO_EDIT ab und +;; fuegt eine bestehende TRO_SYM_-Blockdefinition ein. Die +;; Blockdefinition (Form, Farbe) entsteht nur ueber sps_skel +;; (lib/tro_annotate.py) - ohne einen frueheren Lauf mit dem gewuenschten +;; Typ bricht der Befehl mit einem Hinweis ab. KEY bleibt leer: fuer +;; --read-tros ist der Marker damit ein neuer TRO. ;; ------------------------------------------------------------ -(defun c:TRO_INSERT ( / liste dcl-pfad dat ergebnis typ id pt bname lay - oldAttreq oldAttdia) +(defun c:TRO_INSERT ( / liste ergebnis bname pt lay oldAttreq oldAttdia) (ssg-start "TRO_INSERT" nil) @@ -169,45 +584,24 @@ ) ) - ;; --- Dialog: Typ + Kennung --------------------------------------------- - (setq dcl-pfad (strcat (getenv "DXFM_DCL") "/tro_insert.dcl")) - (setq dat (load_dialog dcl-pfad)) - (if (not (new_dialog "tro_insert" dat)) - (progn - (alert (ssg-textf "tro-edit-dialog-fehlt" (list dcl-pfad))) - (ssg-end) - (exit) - ) - ) - - (start_list "type") - (foreach typname liste (add_list typname)) - (end_list) - (set_tile "type" "0") - (set_tile "id" (tro-naechste-id)) - (set_tile "hinweis" (ssg-text "tro-insert-hinweis")) - - (setq typ (car liste)) - (action_tile "type" "(setq typ (nth (atoi (get_tile \"type\")) liste))") - (action_tile "id" "(setq id (get_tile \"id\"))") - (action_tile "accept" - (strcat "(setq typ (nth (atoi (get_tile \"type\")) liste)" - " id (get_tile \"id\"))" - "(done_dialog 1)")) - (action_tile "cancel" "(done_dialog 0)") - - (setq ergebnis (start_dialog)) - (unload_dialog dat) - + ;; --- Dialog: Typ, Kennung, Bauteile ------------------------------------- + (setq *tro-st-liste* liste + *tro-st-type* (car liste) + *tro-st-id* (tro-naechste-id) + *tro-st-slots* (tro-slots-fuer-typ (car liste) nil) + *tro-st-sel* 0 + *tro-st-fremd* (tro-fremde-teile nil)) + (setq ergebnis (tro-dialog (ssg-text "tro-edit-neu") "" + (ssg-text "tro-insert-hinweis"))) (if (/= ergebnis 1) (progn (ssg-end) (exit)) ) - (if (= (vl-string-trim " " id) "") + (if (= (vl-string-trim " " *tro-st-id*) "") (progn (alert (ssg-text "tro-edit-id-leer")) (ssg-end) (exit)) ) ;; --- Blockdefinition pruefen -------------------------------------------- - (setq bname (strcat *tro-block-prefix* typ)) + (setq bname (strcat *tro-block-prefix* *tro-st-type*)) (if (not (tblsearch "BLOCK" bname)) (progn (alert (ssg-textf "tro-insert-kein-block" (list bname))) @@ -216,8 +610,11 @@ ) ) - ;; --- Einfuegepunkt ------------------------------------------------------- + ;; --- Einfuegepunkt (Enter = Mitte der gewaehlten Bauteile) -------------- (setq pt (getpoint (ssg-text "tro-insert-prompt-punkt"))) + (if (null pt) + (setq pt (tro-teile-mitte *tro-st-slots* (tro-teile-laden))) + ) (if (null pt) (progn (ssg-end) (exit)) ) @@ -233,10 +630,12 @@ (setvar "ATTDIA" oldAttdia) (ssg-attrib-set-on (entlast) - (list (cons "ID" id) (cons "TYPE" typ) (cons "CONFIDENCE" "manuell"))) + (list (cons "ID" *tro-st-id*) (cons "TYPE" *tro-st-type*) + (cons "CONFIDENCE" "manuell") + (cons "SLOTS" (tro-slots-text *tro-st-slots*)))) (entupd (entlast)) - (princ (ssg-textf "tro-insert-eingefuegt" (list id typ))) + (princ (ssg-textf "tro-insert-eingefuegt" (list *tro-st-id* *tro-st-type*))) (ssg-end) ) @@ -245,9 +644,7 @@ ;; C:TRO_EDIT - Dialog fuer einen TRO-Marker ;; ------------------------------------------------------------ (defun c:TRO_EDIT ( / ss ent ed bname attribs - alt-id alt-type alt-fb int-id - neu-id neu-type - liste idx dcl-pfad dat ergebnis) + alt-id alt-type alt-fb int-id ergebnis) ;; Implied Selection VOR ssg-start pruefen (ssg-start hebt Selektion auf) (setq ss (ssget "I")) @@ -294,53 +691,40 @@ (exit) ) ) - (if (null alt-type) (setq alt-type "")) - - ;; --- Dialog ----------------------------------------------------------- - (setq dcl-pfad (strcat (getenv "DXFM_DCL") "/tro_edit.dcl")) - (setq dat (load_dialog dcl-pfad)) - (if (not (new_dialog "tro_edit" dat)) + ;; Marker aus einer Beschriftung vor den Slots: Bauteile nicht speicherbar + (if (null (assoc "SLOTS" attribs)) (progn - (alert (ssg-textf "tro-edit-dialog-fehlt" (list dcl-pfad))) + (alert (ssg-textf "tro-edit-keine-slots" (list alt-id))) (ssg-end) (exit) ) ) + (if (null alt-type) (setq alt-type "")) - (setq liste (tro-typliste alt-type) - idx (tro-index alt-type liste)) - - (set_tile "blockname" (ssg-textf "tro-edit-block" (list bname))) - (set_tile "fb" (ssg-textf "tro-edit-fb" - (list (if alt-fb alt-fb "-") (if int-id int-id "-")))) - (set_tile "hinweis" (ssg-text "tro-edit-hinweis")) - (set_tile "id" alt-id) - (start_list "type") - (foreach typ liste (add_list typ)) - (end_list) - (set_tile "type" (itoa (if idx idx 0))) - - (setq neu-id alt-id neu-type alt-type) - (action_tile "id" "(setq neu-id (get_tile \"id\"))") - (action_tile "type" "(setq neu-type (nth (atoi (get_tile \"type\")) liste))") - (action_tile "accept" - (strcat "(setq neu-id (get_tile \"id\")" - " neu-type (nth (atoi (get_tile \"type\")) liste))" - "(done_dialog 1)")) - (action_tile "cancel" "(done_dialog 0)") - - (setq ergebnis (start_dialog)) - (unload_dialog dat) + ;; --- Dialog ----------------------------------------------------------- + (setq *tro-st-liste* (tro-typliste alt-type) + *tro-st-type* alt-type + *tro-st-id* alt-id + *tro-st-slots* (tro-slots-fuer-typ alt-type + (tro-slots-lesen (cdr (assoc "SLOTS" attribs)))) + *tro-st-sel* 0 + *tro-st-fremd* (tro-fremde-teile ent)) + (setq ergebnis + (tro-dialog (ssg-textf "tro-edit-block" (list bname)) + (ssg-textf "tro-edit-fb" (list (if alt-fb alt-fb "-") (if int-id int-id "-"))) + (ssg-text "tro-edit-hinweis"))) ;; --- zurueckschreiben ------------------------------------------------- (if (= ergebnis 1) - (if (= (vl-string-trim " " neu-id) "") + (if (= (vl-string-trim " " *tro-st-id*) "") (alert (ssg-text "tro-edit-id-leer")) (progn - (ssg-attrib-set-on ent (list (cons "ID" neu-id) (cons "TYPE" neu-type))) + (ssg-attrib-set-on ent + (list (cons "ID" *tro-st-id*) (cons "TYPE" *tro-st-type*) + (cons "SLOTS" (tro-slots-text *tro-st-slots*)))) (entupd ent) - (princ (ssg-textf "tro-edit-gespeichert" (list neu-id neu-type))) - (if (/= neu-type alt-type) + (princ (ssg-textf "tro-edit-gespeichert" (list *tro-st-id* *tro-st-type*))) + (if (/= *tro-st-type* alt-type) (princ (ssg-text "tro-edit-typ-geaendert")) ) ) diff --git a/Lisp/tro_types.lsp b/Lisp/tro_types.lsp index e6c7142..4938452 100644 --- a/Lisp/tro_types.lsp +++ b/Lisp/tro_types.lsp @@ -1,4 +1,28 @@ ;; Automatisch erzeugt von lib/tro_annotate.py --emit-lisp -;; Quelle: TRO_CATALOG in lib/tro_catalog.py - nicht manuell aendern. -(setq *TRO-TYPES* (list "1Sep" "1Sep1Swi" "1Sep2Swi" "1Sep_SSCC" "Vario" "PinStore_Auto" "Vario_workStation" "EmptyCarrBuffer" "LoadingBoom" "2Sep1Swi")) +;; Quelle: TRO_CATALOG in lib/tro_catalog.py, Slots aus lib/model.py +;; (slot_names, SLOT_PART_KINDS) - nicht manuell aendern. +(setq *TRO-TYPES* (list "1Sep" "1Sep1Swi" "1Sep2Swi" "1Sep_SSCC" "Vario" "PinStore_Auto" "Vario_workStation" "EmptyCarrBuffer" "LoadingBoom" "2Sep1Swi" "2Sep2Swi" "3Sep2Swi")) +;; (Typ Lagerlinien-Vorgabe Slot ...) - Lagerlinien heissen line1..lineN +(setq *TRO-SLOTS* '( + ("1Sep" 0 "separator1") + ("1Sep1Swi" 0 "separator1" "switch1") + ("1Sep2Swi" 0 "separator1" "switch1" "switch2" "scanner1") + ("1Sep_SSCC" 0 "separator1" "scanner1") + ("Vario" 0 "separator1" "drive") + ("PinStore_Auto" 19 "separator1" "scanner1") + ("Vario_workStation" 0 "separator1" "scanner1" "drive") + ("EmptyCarrBuffer" 5) + ("LoadingBoom" 0) + ("2Sep1Swi" 0 "separator1" "separator2" "switch1" "scanner1" "scanner2") + ("2Sep2Swi" 0 "separator1" "separator2" "switch1" "switch2" "scanner1" "scanner2") + ("3Sep2Swi" 0 "separator1" "separator2" "separator3" "switch1" "switch2" "scanner1" "scanner2" "scanner3") +)) +;; (Slot-Art Bauteilart ...) - Pruefung beim Waehlen im Plan +(setq *TRO-SLOT-KINDS* '( + ("separator" "Separator") + ("line" "Separator") + ("switch" "Ausschleus" "Weiche") + ("scanner" "Scanner") + ("drive" "Strecke" "Gefaellestrecke" "Kreisel") +)) (princ) diff --git a/dcl/tro_edit.dcl b/dcl/tro_edit.dcl index 6e318bc..01524f5 100644 --- a/dcl/tro_edit.dcl +++ b/dcl/tro_edit.dcl @@ -1,8 +1,12 @@ // ============================================================ -// tro_edit.dcl - TRO-Marker bearbeiten -// Aendert ID und TYPE eines TRO_*-Blocks, den die Beschriftung -// aus sps_skel (lib/tro_annotate.py) eingefuegt hat. -// Aufruf ueber c:TRO_EDIT (Lisp/Tro_Edit.lsp). +// tro_edit.dcl - TRO-Marker bearbeiten bzw. neu anlegen +// Ein Dialog fuer alle TRO-Typen: die Slot-Liste (Separatoren, Weichen, +// Scanner, Antrieb, Lagerlinien) baut Tro_Edit.lsp aus dem Typ auf +// (*TRO-SLOTS* aus tro_types.lsp, erzeugt von sps_skel +// lib/tro_annotate.py --emit-lisp). Die Zeile darunter bearbeitet den +// gewaehlten Slot; "Im Plan waehlen" schliesst den Dialog kurz +// (done_dialog 2) und oeffnet ihn nach der Auswahl wieder. +// Aufruf ueber c:TRO_EDIT und c:TRO_INSERT (Lisp/Tro_Edit.lsp). // ============================================================ tro_edit : dialog { @@ -15,16 +19,67 @@ tro_edit : dialog { label = ""; } - : edit_box { - key = "id"; - label = "TRO-Kennung:"; - edit_width = 30; + : row { + : edit_box { + key = "id"; + label = "TRO-Kennung:"; + edit_width = 18; + } + : popup_list { + key = "type"; + label = "TRO-Typ:"; + width = 30; + } } - : popup_list { - key = "type"; - label = "TRO-Typ:"; - width = 30; + : boxed_column { + label = "Bauteile je Slot"; + + : list_box { + key = "slots"; + height = 10; + width = 50; + tabs = "14"; + fixed_width_font = true; + } + + : row { + : edit_box { + key = "teil"; + label = "TeileId:"; + edit_width = 10; + } + : button { + key = "pick"; + label = "Im Plan waehlen <"; + } + : button { + key = "leeren"; + label = "Leeren"; + } + } + + : row { + : button { + key = "plus"; + label = "+ Lagerlinie"; + } + : button { + key = "minus"; + label = "- Lagerlinie"; + } + : text { + key = "linien"; + label = ""; + width = 22; + } + } + } + + : text { + key = "warnung"; + label = ""; + width = 62; } : text { diff --git a/dcl/tro_insert.dcl b/dcl/tro_insert.dcl deleted file mode 100644 index 6395c38..0000000 --- a/dcl/tro_insert.dcl +++ /dev/null @@ -1,34 +0,0 @@ -// ============================================================ -// tro_insert.dcl - Neuen TRO-Marker einfuegen -// Fragt Typ und Kennung fuer einen neuen TRO_SYM_-Marker ab. Die -// Blockdefinition (Form, Farbe) muss aus einem frueheren Lauf von -// sps_skel (lib/tro_annotate.py) bereits in der Zeichnung vorhanden sein. -// Aufruf ueber c:TRO_INSERT (Lisp/Tro_Edit.lsp). -// ============================================================ - -tro_insert : dialog { - label = "TRO einfuegen"; - - : column { - - : popup_list { - key = "type"; - label = "TRO-Typ:"; - width = 30; - } - - : edit_box { - key = "id"; - label = "TRO-Kennung:"; - edit_width = 30; - } - - : text { - key = "hinweis"; - label = ""; - } - - } - - ok_cancel; -} diff --git a/doc/kommandos.md b/doc/kommandos.md index d4ab2fb..8d0f1aa 100644 --- a/doc/kommandos.md +++ b/doc/kommandos.md @@ -128,8 +128,8 @@ Gross-/Kleinschreibung spielt an der Kommandozeile keine Rolle. | Befehl | Beschreibung | |---|---| -| `TRO_INSERT` | TRO-Marker (`TRO_SYM_`) einfuegen und ID/TYPE setzen (Blockdefinition muss existieren) | -| `TRO_EDIT` | ID/TYPE eines TRO-Markers per Dialog aendern | +| `TRO_INSERT` | TRO-Marker (`TRO_SYM_`) einfuegen: Kennung, Typ, Bauteile je Slot (Blockdefinition muss existieren) | +| `TRO_EDIT` | Kennung, Typ und Bauteile je Slot (Separatoren, Weichen, Scanner, Lagerlinien) eines TRO-Markers per Dialog aendern; Bauteile im Plan waehlbar | | `CONNECTION_INSERT` | Verbindungspfeil (Fluss) zwischen zwei Elementen zeichnen | | `CONNECTION_EDIT` | Quelle/Ziel einer Verbindung aendern | | `JAM_EDIT` (`Jam_Edit.lsp`) | Staubereich (`JAM_AREA` aus sps_skel) bearbeiten: Foerderer und laufende Nummer; auch per Doppelklick | diff --git a/lang/de_DE.json b/lang/de_DE.json index d742073..af331b7 100644 --- a/lang/de_DE.json +++ b/lang/de_DE.json @@ -937,15 +937,27 @@ "tro-edit-modul-fehlt": "%1 nicht geladen - Attribute werden mit EATTEDIT bearbeitet.", "tro-edit-block": "Block: %1", "tro-edit-fb": "Funktionsbaustein: %1 UID: %2", - "tro-edit-hinweis": "Symbol und FB folgen erst beim naechsten Lauf von tro_annotate.py.", + "tro-edit-hinweis": "Uebernehmen nach sps_skel: als DXF speichern, tro_annotate --read-tros. Symbol/FB folgen beim naechsten Lauf.", "tro-edit-id-leer": "Die TRO-Kennung darf nicht leer sein - nichts geaendert.", "tro-edit-gespeichert": "\nTRO gespeichert: ID = %1, TYP = %2", "tro-edit-typ-geaendert": "\nTyp geaendert - tro_annotate.py neu laufen lassen, damit Symbol und FB passen.", "tro-insert-kein-typ": "Keine TRO-Typen verfuegbar (tro_types.lsp fehlt) - bitte lib/tro_annotate.py --emit-lisp ausfuehren.", "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-prompt-punkt": "\nEinfuegepunkt : ", "tro-insert-eingefuegt": "\nTRO eingefuegt: ID = %1, TYP = %2", + "tro-edit-neu": "Neuer TRO - wird von tro_annotate --read-tros als neuer TRO uebernommen", + "tro-edit-keine-slots": "Marker %1 hat kein Attribut SLOTS (Beschriftung vor 2026-10-26) - bitte tro_annotate.py neu laufen lassen.", + "tro-edit-keine-teile": "Bauteiltabelle SPS_SKEL_PARTS fehlt in der Zeichnung - mit tro_annotate.py neu beschriften oder die TeileId eintippen.", + "tro-edit-prompt-teil": "\n%1: %2 im Plan waehlen: ", + "tro-edit-gewaehlt": "\n%1 = %2 (%3)", + "tro-edit-kein-teil": "Kein passendes Bauteil im Umkreis von %1 mm.", + "tro-edit-falsche-art": "%1 ist ein %2 - in %3 gehoert ein %4.", + "tro-edit-linien": "%1 Linien (Vorgabe %2)", + "tro-edit-leer": "leer: %1", + "tro-edit-doppelt": "doppelt: %1", + "tro-edit-fremd": "%1 steckt in %2", + "tro-edit-ok": "Bauteile ok.", "cmd-jam-bearbeiten": "\nStaubereich bearbeiten: %1", "jam-edit-kein-jam": "Block %1 ist kein Staubereich (erwartet JAM_*).", "jam-edit-dialog-fehlt": "Dialogdatei nicht gefunden:\n%1\nDXFM_DCL pruefen (setenv.bat).", diff --git a/lang/en_GB.json b/lang/en_GB.json index dfb6aae..a02ce84 100644 --- a/lang/en_GB.json +++ b/lang/en_GB.json @@ -937,15 +937,27 @@ "tro-edit-modul-fehlt": "%1 not loaded - editing attributes with EATTEDIT instead.", "tro-edit-block": "Block: %1", "tro-edit-fb": "Function block: %1 UID: %2", - "tro-edit-hinweis": "Symbol and FB follow on the next tro_annotate.py run.", + "tro-edit-hinweis": "Back to sps_skel: save as DXF, run tro_annotate --read-tros. Symbol/FB follow on the next run.", "tro-edit-id-leer": "The TRO id must not be empty - nothing changed.", "tro-edit-gespeichert": "\nTRO saved: ID = %1, TYPE = %2", "tro-edit-typ-geaendert": "\nType changed - re-run tro_annotate.py so symbol and FB match.", "tro-insert-kein-typ": "No TRO types available (tro_types.lsp missing) - run lib/tro_annotate.py --emit-lisp.", "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-prompt-punkt": "\nInsertion point : ", "tro-insert-eingefuegt": "\nTRO inserted: ID = %1, TYPE = %2", + "tro-edit-neu": "New TRO - tro_annotate --read-tros takes it over as a new TRO", + "tro-edit-keine-slots": "Marker %1 has no SLOTS attribute (annotated before 2026-10-26) - please re-run tro_annotate.py.", + "tro-edit-keine-teile": "Part table SPS_SKEL_PARTS is missing in the drawing - re-annotate with tro_annotate.py or type the part ID.", + "tro-edit-prompt-teil": "\n%1: pick %2 in the drawing: ", + "tro-edit-gewaehlt": "\n%1 = %2 (%3)", + "tro-edit-kein-teil": "No matching part within %1 mm.", + "tro-edit-falsche-art": "%1 is a %2 - %3 needs a %4.", + "tro-edit-linien": "%1 lines (default %2)", + "tro-edit-leer": "empty: %1", + "tro-edit-doppelt": "twice: %1", + "tro-edit-fremd": "%1 is in %2", + "tro-edit-ok": "Parts ok.", "cmd-jam-bearbeiten": "\nEdit jam area: %1", "jam-edit-kein-jam": "Block %1 is not a jam area (expected JAM_*).", "jam-edit-dialog-fehlt": "Dialog file not found:\n%1\nCheck DXFM_DCL (setenv.bat).",