268 lines
8.8 KiB
Python
268 lines
8.8 KiB
Python
# omniflo_weichen.py
|
|
# Omniflo Weichen-Auswahl-Dialog (wx) und Weichen-Commands
|
|
# Ersetzt die Weichen-Teile von OmniModulInsert.lsp + omniflo_weichen.dcl
|
|
# ============================================
|
|
|
|
import wx
|
|
|
|
import PyRx as Rx
|
|
import PyDb as Db
|
|
import PyEd as Ed
|
|
|
|
from elemente.omniflo import (
|
|
load_weichen,
|
|
filter_by,
|
|
insert_from_entry,
|
|
sivasnr_to_str,
|
|
)
|
|
|
|
|
|
# ============================================================
|
|
# Weichen-Auswahl-Dialog (ersetzt omniflo_weichen.dcl)
|
|
# ============================================================
|
|
|
|
class WeichenSelectDialog(wx.Dialog):
|
|
"""Weichen-Auswahl-Dialog mit Filtern.
|
|
|
|
Layout:
|
|
- Dropdown: ProfilTyp (gefiltert)
|
|
- Filter-Gruppe Schaltungstyp: Alle / M / P (wx.RadioBox)
|
|
- Filter-Gruppe Richtung: Alle / Links / Rechts (wx.RadioBox)
|
|
- Detail-Felder (readonly): SivasNr, Winkel, Breite, Laenge
|
|
- OK / Abbrechen
|
|
"""
|
|
|
|
def __init__(self, parent, basis_liste):
|
|
super().__init__(parent, title="Omniflo Weiche auswaehlen",
|
|
size=(500, 320),
|
|
style=wx.DEFAULT_DIALOG_STYLE)
|
|
self._basis = basis_liste
|
|
self._gefiltert = list(basis_liste)
|
|
self._selected_idx = 0
|
|
|
|
panel = wx.Panel(self)
|
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
|
|
|
# Dropdown: ProfilTyp
|
|
row_profil = wx.BoxSizer(wx.HORIZONTAL)
|
|
row_profil.Add(wx.StaticText(panel, label="Profiltyp:"), 0,
|
|
wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
|
|
self.cb_profil = wx.Choice(panel, choices=[])
|
|
self.cb_profil.Bind(wx.EVT_CHOICE, self._on_selection)
|
|
row_profil.Add(self.cb_profil, 1)
|
|
sizer.Add(row_profil, 0, wx.EXPAND | wx.ALL, 5)
|
|
|
|
# Filter-Gruppe: Schaltungstyp + Richtung nebeneinander
|
|
filter_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
|
|
|
self.rb_schaltung = wx.RadioBox(panel, label="Schaltungstyp",
|
|
choices=["Alle", "M", "P"],
|
|
majorDimension=1,
|
|
style=wx.RA_SPECIFY_COLS)
|
|
self.rb_schaltung.Bind(wx.EVT_RADIOBOX, self._apply_filter)
|
|
filter_sizer.Add(self.rb_schaltung, 1, wx.EXPAND | wx.RIGHT, 5)
|
|
|
|
self.rb_richtung = wx.RadioBox(panel, label="Richtung",
|
|
choices=["Alle", "Links", "Rechts"],
|
|
majorDimension=1,
|
|
style=wx.RA_SPECIFY_COLS)
|
|
self.rb_richtung.Bind(wx.EVT_RADIOBOX, self._apply_filter)
|
|
filter_sizer.Add(self.rb_richtung, 1, wx.EXPAND)
|
|
|
|
sizer.Add(filter_sizer, 0, wx.EXPAND | wx.ALL, 5)
|
|
|
|
# Detail-Felder (2 Spalten)
|
|
grid = wx.FlexGridSizer(cols=4, hgap=10, vgap=5)
|
|
grid.AddGrowableCol(1)
|
|
grid.AddGrowableCol(3)
|
|
|
|
grid.Add(wx.StaticText(panel, label="SivasNr:"), 0, wx.ALIGN_CENTER_VERTICAL)
|
|
self.txt_sivasnr = wx.TextCtrl(panel, style=wx.TE_READONLY, size=(140, -1))
|
|
grid.Add(self.txt_sivasnr, 0)
|
|
|
|
grid.Add(wx.StaticText(panel, label="Winkel:"), 0, wx.ALIGN_CENTER_VERTICAL)
|
|
self.txt_winkel = wx.TextCtrl(panel, style=wx.TE_READONLY, size=(100, -1))
|
|
grid.Add(self.txt_winkel, 0)
|
|
|
|
grid.Add(wx.StaticText(panel, label="Breite:"), 0, wx.ALIGN_CENTER_VERTICAL)
|
|
self.txt_breite = wx.TextCtrl(panel, style=wx.TE_READONLY, size=(100, -1))
|
|
grid.Add(self.txt_breite, 0)
|
|
|
|
grid.Add(wx.StaticText(panel, label="Laenge:"), 0, wx.ALIGN_CENTER_VERTICAL)
|
|
self.txt_laenge = wx.TextCtrl(panel, style=wx.TE_READONLY, size=(100, -1))
|
|
grid.Add(self.txt_laenge, 0)
|
|
|
|
sizer.Add(grid, 0, wx.EXPAND | wx.ALL, 5)
|
|
|
|
# OK / Cancel
|
|
btn_sizer = self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL)
|
|
sizer.Add(btn_sizer, 0, wx.EXPAND | wx.ALL, 10)
|
|
|
|
panel.SetSizer(sizer)
|
|
self.Fit()
|
|
self.CenterOnScreen()
|
|
|
|
# Initiale Befuellung
|
|
self._refresh_dropdown()
|
|
|
|
def _apply_filter(self, event=None):
|
|
"""Filter anwenden und Dropdown neu befuellen."""
|
|
self._refresh_dropdown()
|
|
|
|
def _refresh_dropdown(self):
|
|
"""Dropdown mit gefilterter Liste neu fuellen."""
|
|
sch_idx = self.rb_schaltung.GetSelection()
|
|
ri_idx = self.rb_richtung.GetSelection()
|
|
|
|
# Schaltungstyp-Filter
|
|
sch_filter = {0: None, 1: "M", 2: "P"}.get(sch_idx)
|
|
# Richtungs-Filter (1=links, 2=rechts)
|
|
ri_filter = {0: None, 1: 1, 2: 2}.get(ri_idx)
|
|
|
|
self._gefiltert = []
|
|
for e in self._basis:
|
|
if sch_filter and e.get("Schaltungstyp") != sch_filter:
|
|
continue
|
|
if ri_filter and e.get("KurvenRichtung") != ri_filter:
|
|
continue
|
|
self._gefiltert.append(e)
|
|
|
|
# Dropdown neu befuellen
|
|
self.cb_profil.Clear()
|
|
for e in self._gefiltert:
|
|
self.cb_profil.Append(e.get("ProfilTyp", "?"))
|
|
|
|
if self._gefiltert:
|
|
self.cb_profil.SetSelection(0)
|
|
self._selected_idx = 0
|
|
self._update_details(0)
|
|
else:
|
|
self._selected_idx = -1
|
|
self.txt_sivasnr.SetValue("---")
|
|
self.txt_winkel.SetValue("---")
|
|
self.txt_breite.SetValue("---")
|
|
self.txt_laenge.SetValue("---")
|
|
|
|
def _on_selection(self, event):
|
|
self._selected_idx = self.cb_profil.GetSelection()
|
|
self._update_details(self._selected_idx)
|
|
|
|
def _update_details(self, idx):
|
|
if idx < 0 or idx >= len(self._gefiltert):
|
|
return
|
|
e = self._gefiltert[idx]
|
|
self.txt_sivasnr.SetValue(sivasnr_to_str(e.get("Sivasnr")))
|
|
wkl = e.get("KurvenWinkel", 0)
|
|
self.txt_winkel.SetValue(f"{wkl} Grad")
|
|
self.txt_breite.SetValue(str(e.get("Breite", "?")))
|
|
self.txt_laenge.SetValue(str(e.get("Länge", "?")))
|
|
|
|
def get_selected(self):
|
|
"""Gewaehlten Weichen-Eintrag zurueckgeben."""
|
|
if 0 <= self._selected_idx < len(self._gefiltert):
|
|
return self._gefiltert[self._selected_idx]
|
|
return None
|
|
|
|
|
|
# ============================================================
|
|
# Generische Weichen-Einfuege-Logik
|
|
# ============================================================
|
|
|
|
def _weichen_command(winkel, weichentyp):
|
|
"""Weichen-Dialog oeffnen, Auswahl einfuegen."""
|
|
alle = load_weichen()
|
|
|
|
# Nach Winkel filtern (None = alle Winkel)
|
|
if winkel is not None:
|
|
basis = filter_by(alle, "KurvenWinkel", winkel)
|
|
else:
|
|
basis = list(alle)
|
|
|
|
# Nach WeichenTyp filtern
|
|
if weichentyp:
|
|
basis = [e for e in basis if e.get("WeichenTyp") == weichentyp]
|
|
|
|
if not basis:
|
|
wkl_str = "alle Winkel" if winkel is None else f"{winkel} Grad"
|
|
typ_str = f" / {weichentyp}" if weichentyp else ""
|
|
print(f"\nKeine Weichen fuer {wkl_str}{typ_str} gefunden.")
|
|
return
|
|
|
|
dlg = WeichenSelectDialog(None, basis)
|
|
if dlg.ShowModal() == wx.ID_OK:
|
|
eintrag = dlg.get_selected()
|
|
dlg.Destroy()
|
|
if eintrag:
|
|
insert_from_entry(eintrag)
|
|
else:
|
|
print("\n[WEICHE] Kein Eintrag ausgewaehlt.")
|
|
else:
|
|
dlg.Destroy()
|
|
print("\n[WEICHE] Abgebrochen.")
|
|
|
|
|
|
# ============================================================
|
|
# Weichen-Commands (gleiche Namen wie LISP)
|
|
# ============================================================
|
|
|
|
# --- 90 Grad ---
|
|
@Rx.command("OMNI_W90_Einfach")
|
|
def cmd_w90_einfach():
|
|
_weichen_command(90, "Einzelweiche")
|
|
|
|
@Rx.command("OMNI_W90_Doppel")
|
|
def cmd_w90_doppel():
|
|
_weichen_command(90, "Doppelweiche")
|
|
|
|
@Rx.command("OMNI_W90_Dreiwege")
|
|
def cmd_w90_dreiwege():
|
|
_weichen_command(90, "Dreiwegeweiche")
|
|
|
|
# --- 45 Grad ---
|
|
@Rx.command("OMNI_W45_Einfach")
|
|
def cmd_w45_einfach():
|
|
_weichen_command(45, "Einzelweiche")
|
|
|
|
@Rx.command("OMNI_W45_Doppel")
|
|
def cmd_w45_doppel():
|
|
_weichen_command(45, "Doppelweiche")
|
|
|
|
@Rx.command("OMNI_W45_Dreiwege")
|
|
def cmd_w45_dreiwege():
|
|
_weichen_command(45, "Dreiwegeweiche")
|
|
|
|
# --- Parallel (KurvenWinkel=0) ---
|
|
@Rx.command("OMNI_WP_Einfach")
|
|
def cmd_wp_einfach():
|
|
_weichen_command(0, "Einzelweiche")
|
|
|
|
@Rx.command("OMNI_WP_Doppel")
|
|
def cmd_wp_doppel():
|
|
_weichen_command(0, "Doppelweiche")
|
|
|
|
@Rx.command("OMNI_WP_Dreiwege")
|
|
def cmd_wp_dreiwege():
|
|
_weichen_command(0, "Dreiwegeweiche")
|
|
|
|
# --- Weichenkoerper (KurvenWinkel=22.5) ---
|
|
@Rx.command("OMNI_WK_Einfach")
|
|
def cmd_wk_einfach():
|
|
_weichen_command(22.5, "Einzelweiche")
|
|
|
|
@Rx.command("OMNI_WK_Doppel")
|
|
def cmd_wk_doppel():
|
|
_weichen_command(22.5, "Doppelweiche")
|
|
|
|
@Rx.command("OMNI_WK_Dreiwege")
|
|
def cmd_wk_dreiwege():
|
|
_weichen_command(22.5, "Dreiwegeweiche")
|
|
|
|
# --- Weichenkombinationen ---
|
|
@Rx.command("OMNI_WKomb_Delta")
|
|
def cmd_wkomb_delta():
|
|
_weichen_command(None, "Deltaweiche")
|
|
|
|
@Rx.command("OMNI_WKomb_Star")
|
|
def cmd_wkomb_star():
|
|
_weichen_command(None, "Sternweiche")
|