Landkreis-Dropdown, BROR-Mehrfachauswahl-Dialog und UX-Fixes
- Landkreis-Feld in den Projekteigenschaften als Dropdown statt Freitext, Landkreiskennzahl zusätzlich als eigene Projektvariable verfügbar. - ask_bror_kombination(en) auf echte Mehrfachauswahl umgestellt, inkl. Titel, Wappen-Icon, kompakter/anpassbarer Größe und Scrollbar-Fix. - Neuer Dialog ask_landkreis_objekte für die landkreisweite Objektsuche (Mehrfachauswahl, "Alle auswählen", "Nur laden ohne weiteren Ablauf"). - qt_wrapper um QDialog/QDialogButtonBox/QListWidget/QListWidgetItem/ QAbstractItemView/QIcon sowie QComboBox-userData/currentData erweitert.
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
- Landkreis-Dropdown (statt Freitext) in den Projekteigenschaften ergänzt, inkl. Landkreiskennzahl als eigene Projektvariable
|
||||
- Auswahldialog für mehrere BauRaumOderBodenordnungsrecht-Treffer auf Mehrfachauswahl umgestellt (mehrere Objekte gemeinsam laden/verschmelzen)
|
||||
- Neuer Dialog zur landkreisweiten Objektsuche (Mehrfachauswahl, "Alle auswählen", "Nur laden ohne weiteren Ablauf")
|
||||
- Dialoge: Titel, Wappen-Icon, kompaktere Größe, Scrollbar-Fix und größenveränderbare Liste ergänzt
|
||||
---
|
||||
Version 26.7.1-unstable:
|
||||
- Verfahrensgebiet als shape laden, inkl. Abgleich mit BROBOR-Objekt
|
||||
---
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
+167
-28
@@ -6,7 +6,10 @@ from typing import Literal, Optional
|
||||
from sn_basis.functions.qt_wrapper import (
|
||||
QMessageBox, YES, NO, CANCEL, QT_VERSION, exec_dialog, ICON_QUESTION,
|
||||
QProgressDialog, QCoreApplication, Qt, QInputDialog, QLineEdit,
|
||||
QDialog, QDialogButtonBox, QListWidget, QListWidgetItem, QAbstractItemView,
|
||||
QIcon, QVBoxLayout, QLabel, QCheckBox, DialogAccepted, ExtendedSelection,
|
||||
)
|
||||
import os
|
||||
|
||||
def ask_yes_no(
|
||||
title: str,
|
||||
@@ -391,15 +394,21 @@ def create_progress_dialog(total: int, title: str = "Fortschritt", label: str =
|
||||
return ProgressDialog(total, title, label)
|
||||
|
||||
|
||||
def ask_bror_kombination(
|
||||
# .../python/plugins (drei Ebenen über dieser Datei)
|
||||
_PLUGINS_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||
_WAPPEN_ICON = os.path.join(_PLUGINS_DIR, "sn_basis", "favicon.ico")
|
||||
|
||||
|
||||
def ask_bror_kombinationen(
|
||||
parent: Any,
|
||||
kombinationen: list[tuple[str, str]],
|
||||
) -> Optional[tuple[str, str]]:
|
||||
"""Zeigt Dialog zur Auswahl einer BROR-Kombination (adv_name + bezeichnung).
|
||||
) -> list[tuple[str, str]]:
|
||||
"""Zeigt Dialog zur Auswahl einer oder mehrerer BROR-Kombinationen
|
||||
(adv_name + bezeichnung).
|
||||
|
||||
Wird aufgerufen, wenn der WFS mehrere verschiedene Kombinationen aus
|
||||
``adv_name`` und ``bezeichnung`` zurückliefert, sodass der Nutzer
|
||||
entscheiden muss, welche Objekte in die Pipeline einfließen sollen.
|
||||
``adv_name`` und ``bezeichnung`` zurückliefert. Es können ein oder
|
||||
mehrere Objekte gemeinsam ausgewählt und geladen (verschmolzen) werden.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
@@ -410,33 +419,163 @@ def ask_bror_kombination(
|
||||
|
||||
Returns
|
||||
-------
|
||||
Optional[tuple[str, str]]
|
||||
Das gewählte ``(adv_name, bezeichnung)``-Tupel oder ``None`` bei
|
||||
Abbruch bzw. leerer Eingabe.
|
||||
list[tuple[str, str]]
|
||||
Die gewählten ``(adv_name, bezeichnung)``-Tupel. Leere Liste bei
|
||||
Abbruch oder wenn nichts ausgewählt wurde.
|
||||
"""
|
||||
if not kombinationen:
|
||||
return None
|
||||
return []
|
||||
|
||||
if QT_VERSION == 0: # Mock-Modus
|
||||
print(f"Mock-Modus: ask_bror_kombination → {kombinationen[0]}")
|
||||
return kombinationen[0]
|
||||
print(f"Mock-Modus: ask_bror_kombinationen → {kombinationen[:1]}")
|
||||
return kombinationen[:1]
|
||||
|
||||
items = [f"{adv} | {bez}" for adv, bez in kombinationen]
|
||||
item, ok = QInputDialog.getItem(
|
||||
parent,
|
||||
"BROR-Objekt auswählen",
|
||||
"Mehrere BauRaumOderBodenordnungsrecht-Objekte gefunden.\n"
|
||||
"Bitte wählen Sie die gewünschte Kombination\n"
|
||||
"aus ADV-Name und Bezeichnung:",
|
||||
items,
|
||||
0,
|
||||
False,
|
||||
dialog = QDialog(parent)
|
||||
dialog.setWindowTitle("Verfahrensgebiet aus ALKIS laden")
|
||||
if os.path.exists(_WAPPEN_ICON):
|
||||
dialog.setWindowIcon(QIcon(_WAPPEN_ICON))
|
||||
layout = QVBoxLayout(dialog)
|
||||
|
||||
hinweis = QLabel(
|
||||
f"Es wurden {len(kombinationen)} Objekte gefunden.\n\n"
|
||||
"Bitte wählen Sie eines oder mehrere Objekte aus:"
|
||||
)
|
||||
if not ok:
|
||||
return None
|
||||
try:
|
||||
idx = items.index(item)
|
||||
return kombinationen[idx]
|
||||
except ValueError:
|
||||
return None
|
||||
hinweis.setWordWrap(True)
|
||||
layout.addWidget(hinweis)
|
||||
|
||||
list_widget = QListWidget()
|
||||
list_widget.setSelectionMode(ExtendedSelection)
|
||||
for adv, bez in kombinationen:
|
||||
item = QListWidgetItem(f"{adv} | {bez}")
|
||||
list_widget.addItem(item)
|
||||
list_widget.item(0).setSelected(True)
|
||||
layout.addWidget(list_widget, 1) # Stretch-Faktor: wächst mit Fenstergröße
|
||||
|
||||
mehrfachauswahl_hinweis = QLabel("<small>Mehrfachauswahl mit Strg + Umschalt</small>")
|
||||
layout.addWidget(mehrfachauswahl_hinweis)
|
||||
|
||||
buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
|
||||
buttons.accepted.connect(dialog.accept)
|
||||
buttons.rejected.connect(dialog.reject)
|
||||
layout.addWidget(buttons)
|
||||
|
||||
dialog.adjustSize()
|
||||
breite = dialog.sizeHint().width()
|
||||
|
||||
# Liste auf max. 5 sichtbare Zeilen begrenzen, Rest per Scrollbar
|
||||
sichtbare_zeilen = min(len(kombinationen), 5)
|
||||
zeilenhoehe = list_widget.sizeHintForRow(0) if list_widget.count() else 20
|
||||
# + Puffer für eine ggf. eingeblendete horizontale Scrollbar (bei langen
|
||||
# Einträgen), damit diese nicht die letzte Zeile abschneidet.
|
||||
scrollbar_puffer = list_widget.horizontalScrollBar().sizeHint().height()
|
||||
list_hoehe = zeilenhoehe * sichtbare_zeilen + 2 * list_widget.frameWidth() + 4 + scrollbar_puffer
|
||||
list_widget.setMinimumHeight(list_hoehe)
|
||||
|
||||
dialog.resize(breite, dialog.sizeHint().height())
|
||||
|
||||
if exec_dialog(dialog) != DialogAccepted:
|
||||
return []
|
||||
|
||||
ausgewaehlte_indizes = sorted(list_widget.row(item) for item in list_widget.selectedItems())
|
||||
return [kombinationen[i] for i in ausgewaehlte_indizes]
|
||||
|
||||
|
||||
def ask_landkreis_objekte(
|
||||
parent: Any,
|
||||
kombinationen: list[tuple[str, str]],
|
||||
) -> tuple[list[tuple[str, str]], bool]:
|
||||
"""Zeigt Dialog zur Auswahl eines, mehrerer oder aller BROR-Objekte eines
|
||||
Landkreises (Fallback, wenn keine Verfahrensnummer gesetzt ist).
|
||||
|
||||
Wie :func:`ask_bror_kombinationen`, zusätzlich mit einer "Alle
|
||||
auswählen"-Checkbox (da hier potenziell deutlich mehr Treffer als bei der
|
||||
VKZ-Suche auftreten) und einer "Nur laden"-Checkbox, mit der gesteuert
|
||||
wird, ob nach dem Laden der weitere Workflow (Gemarkung/Flurstücke/
|
||||
Flächenvergleich) fortgesetzt werden soll.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
parent :
|
||||
Eltern-Widget oder None.
|
||||
kombinationen :
|
||||
Sortierte Liste von ``(adv_name, bezeichnung)``-Tupeln.
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple[list[tuple[str, str]], bool]
|
||||
``(ausgewaehlte_kombinationen, nur_laden)``. ``([], False)`` bei
|
||||
Abbruch oder wenn nichts ausgewählt wurde.
|
||||
"""
|
||||
if not kombinationen:
|
||||
return [], False
|
||||
|
||||
if QT_VERSION == 0: # Mock-Modus
|
||||
print(f"Mock-Modus: ask_landkreis_objekte → {kombinationen[:1]}")
|
||||
return kombinationen[:1], False
|
||||
|
||||
dialog = QDialog(parent)
|
||||
dialog.setWindowTitle("Verfahrensgebiete aus Landkreis laden")
|
||||
if os.path.exists(_WAPPEN_ICON):
|
||||
dialog.setWindowIcon(QIcon(_WAPPEN_ICON))
|
||||
layout = QVBoxLayout(dialog)
|
||||
|
||||
hinweis = QLabel(
|
||||
f"Es wurden {len(kombinationen)} Objekte gefunden.\n\n"
|
||||
"Bitte wählen Sie eines oder mehrere Objekte aus:"
|
||||
)
|
||||
hinweis.setWordWrap(True)
|
||||
layout.addWidget(hinweis)
|
||||
|
||||
alle_auswaehlen = QCheckBox("Alle auswählen")
|
||||
layout.addWidget(alle_auswaehlen)
|
||||
|
||||
list_widget = QListWidget()
|
||||
list_widget.setSelectionMode(ExtendedSelection)
|
||||
for adv, bez in kombinationen:
|
||||
item = QListWidgetItem(f"{bez} | {adv}")
|
||||
list_widget.addItem(item)
|
||||
list_widget.item(0).setSelected(True)
|
||||
layout.addWidget(list_widget, 1) # Stretch-Faktor: wächst mit Fenstergröße
|
||||
|
||||
def _alle_auswaehlen_umschalten(checked):
|
||||
if checked:
|
||||
list_widget.selectAll()
|
||||
else:
|
||||
list_widget.clearSelection()
|
||||
|
||||
alle_auswaehlen.stateChanged.connect(_alle_auswaehlen_umschalten)
|
||||
|
||||
mehrfachauswahl_hinweis = QLabel("<small>Mehrfachauswahl mit Strg + Umschalt</small>")
|
||||
layout.addWidget(mehrfachauswahl_hinweis)
|
||||
|
||||
nur_laden_checkbox = QCheckBox("Nur laden (kein weiterer Ablauf)")
|
||||
layout.addWidget(nur_laden_checkbox)
|
||||
|
||||
buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
|
||||
buttons.accepted.connect(dialog.accept)
|
||||
buttons.rejected.connect(dialog.reject)
|
||||
layout.addWidget(buttons)
|
||||
|
||||
dialog.adjustSize()
|
||||
breite = dialog.sizeHint().width()
|
||||
|
||||
# Liste auf max. 15 sichtbare Zeilen begrenzen, Rest per Scrollbar – hier
|
||||
# potenziell deutlich mehr Treffer als bei der VKZ-Suche, daher großzügiger
|
||||
# bemessen als bei ask_bror_kombinationen (dort 5).
|
||||
sichtbare_zeilen = min(len(kombinationen), 15)
|
||||
zeilenhoehe = list_widget.sizeHintForRow(0) if list_widget.count() else 20
|
||||
# + Puffer für eine ggf. eingeblendete horizontale Scrollbar (bei langen
|
||||
# Einträgen), damit diese nicht die letzte Zeile abschneidet.
|
||||
scrollbar_puffer = list_widget.horizontalScrollBar().sizeHint().height()
|
||||
list_hoehe = zeilenhoehe * sichtbare_zeilen + 2 * list_widget.frameWidth() + 4 + scrollbar_puffer
|
||||
list_widget.setMinimumHeight(list_hoehe)
|
||||
|
||||
dialog.resize(breite, dialog.sizeHint().height())
|
||||
|
||||
if exec_dialog(dialog) != DialogAccepted:
|
||||
return [], False
|
||||
|
||||
ausgewaehlte_indizes = sorted(list_widget.row(item) for item in list_widget.selectedItems())
|
||||
ausgewaehlt = [kombinationen[i] for i in ausgewaehlte_indizes]
|
||||
return ausgewaehlt, nur_laden_checkbox.isChecked()
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
"""sn_basis/functions/landkreise.py – Sächsische Landkreise/Helfer mit Kennzahl.
|
||||
|
||||
Quelle: landkreiskennzahlen.csv
|
||||
"""
|
||||
|
||||
#: Liste von (Landkreiskennzahl, Landkreis/Helfer)-Tupeln, in CSV-Reihenfolge.
|
||||
LANDKREISE: list[tuple[str, str]] = [
|
||||
("11", "Chemnitz, Stadt"),
|
||||
("12", "Dresden, Stadt"),
|
||||
("13", "Leipzig, Stadt"),
|
||||
("21", "Erzgebirgskreis"),
|
||||
("22", "Mittelsachsen"),
|
||||
("23", "Vogtlandkreis"),
|
||||
("24", "Zwickau"),
|
||||
("25", "Bautzen"),
|
||||
("26", "Görlitz"),
|
||||
("27", "Meißen"),
|
||||
("28", "Sächsische Schweiz-Osterzgebirge"),
|
||||
("29", "Leipzig"),
|
||||
("30", "Nordsachsen"),
|
||||
("80", "LfULG"),
|
||||
]
|
||||
|
||||
#: Kennzahl -> Name
|
||||
KENNZAHL_ZU_NAME: dict[str, str] = dict(LANDKREISE)
|
||||
|
||||
#: Name -> Kennzahl
|
||||
NAME_ZU_KENNZAHL: dict[str, str] = {name: kennzahl for kennzahl, name in LANDKREISE}
|
||||
+119
-10
@@ -46,6 +46,12 @@ QCheckBox: Type[Any] = object
|
||||
QHBoxLayout: Type[Any] = object
|
||||
QFont: Type[Any] = object
|
||||
QSettings: Type[Any] = object
|
||||
QDialog: Type[Any] = object
|
||||
QDialogButtonBox: Type[Any] = object
|
||||
QListWidget: Type[Any] = object
|
||||
QListWidgetItem: Type[Any] = object
|
||||
QAbstractItemView: Type[Any] = object
|
||||
QIcon: Type[Any] = object
|
||||
|
||||
|
||||
def exec_dialog(dialog: Any) -> Any:
|
||||
@@ -92,8 +98,13 @@ try:
|
||||
QComboBox as _QComboBox,
|
||||
QCheckBox as _QCheckBox,
|
||||
QHBoxLayout as _QHBoxLayout,
|
||||
QDialog as _QDialog,
|
||||
QDialogButtonBox as _QDialogButtonBox,
|
||||
QListWidget as _QListWidget,
|
||||
QListWidgetItem as _QListWidgetItem,
|
||||
QAbstractItemView as _QAbstractItemView,
|
||||
)
|
||||
from qgis.PyQt.QtGui import QFont as _QFont
|
||||
from qgis.PyQt.QtGui import QFont as _QFont, QIcon as _QIcon
|
||||
from qgis.PyQt.QtCore import (
|
||||
QEventLoop as _QEventLoop,
|
||||
QTimer as _QTimer,
|
||||
@@ -143,6 +154,12 @@ try:
|
||||
QHBoxLayout = _QHBoxLayout
|
||||
QFont = _QFont
|
||||
QSettings = _QSettings
|
||||
QDialog = _QDialog
|
||||
QDialogButtonBox = _QDialogButtonBox
|
||||
QListWidget = _QListWidget
|
||||
QListWidgetItem = _QListWidgetItem
|
||||
QAbstractItemView = _QAbstractItemView
|
||||
QIcon = _QIcon
|
||||
# ✅ QT6 ENUMS
|
||||
YES = QMessageBox.StandardButton.Yes
|
||||
NO = QMessageBox.StandardButton.No
|
||||
@@ -163,7 +180,9 @@ try:
|
||||
DockWidgetClosable = QDockWidget.DockWidgetFeature.DockWidgetClosable
|
||||
DockAreaLeft = Qt.DockWidgetArea.LeftDockWidgetArea
|
||||
DockAreaRight = Qt.DockWidgetArea.RightDockWidgetArea
|
||||
|
||||
DialogAccepted = QDialog.DialogCode.Accepted
|
||||
ExtendedSelection = QAbstractItemView.SelectionMode.ExtendedSelection
|
||||
|
||||
def exec_dialog(dialog: Any) -> Any:
|
||||
return dialog.exec()
|
||||
|
||||
@@ -194,8 +213,13 @@ except (ImportError, AttributeError):
|
||||
QComboBox as _QComboBox,
|
||||
QCheckBox as _QCheckBox,
|
||||
QHBoxLayout as _QHBoxLayout,
|
||||
QDialog as _QDialog,
|
||||
QDialogButtonBox as _QDialogButtonBox,
|
||||
QListWidget as _QListWidget,
|
||||
QListWidgetItem as _QListWidgetItem,
|
||||
QAbstractItemView as _QAbstractItemView,
|
||||
)
|
||||
from PyQt5.QtGui import QFont as _QFont
|
||||
from PyQt5.QtGui import QFont as _QFont, QIcon as _QIcon
|
||||
from PyQt5.QtCore import (
|
||||
QEventLoop as _QEventLoop,
|
||||
QTimer as _QTimer,
|
||||
@@ -243,7 +267,13 @@ except (ImportError, AttributeError):
|
||||
QHBoxLayout= _QHBoxLayout
|
||||
QFont = _QFont
|
||||
QSettings = _QSettings
|
||||
|
||||
QDialog = _QDialog
|
||||
QDialogButtonBox = _QDialogButtonBox
|
||||
QListWidget = _QListWidget
|
||||
QListWidgetItem = _QListWidgetItem
|
||||
QAbstractItemView = _QAbstractItemView
|
||||
QIcon = _QIcon
|
||||
|
||||
# ✅ PYQT5 ENUMS
|
||||
YES = QMessageBox.Yes
|
||||
NO = QMessageBox.No
|
||||
@@ -265,7 +295,9 @@ except (ImportError, AttributeError):
|
||||
DockWidgetClosable = QDockWidget.DockWidgetClosable
|
||||
DockAreaLeft = Qt.LeftDockWidgetArea
|
||||
DockAreaRight = Qt.RightDockWidgetArea
|
||||
|
||||
DialogAccepted = QDialog.Accepted
|
||||
ExtendedSelection = QAbstractItemView.ExtendedSelection
|
||||
|
||||
def exec_dialog(dialog: Any) -> Any:
|
||||
return dialog.exec_()
|
||||
|
||||
@@ -482,13 +514,19 @@ except (ImportError, AttributeError):
|
||||
|
||||
class _MockComboBox:
|
||||
def __init__(self, parent=None):
|
||||
self._items = []
|
||||
self._items = [] # Liste von (text, userData)
|
||||
self._index = -1
|
||||
self.currentTextChanged = type('Signal', (), {'connect': lambda s, cb: None, 'emit': lambda s, v: None})()
|
||||
def addItem(self, text: str) -> None: self._items.append(text)
|
||||
def addItem(self, text: str, userData=None) -> None:
|
||||
self._items.append((text, userData))
|
||||
if self._index < 0:
|
||||
self._index = 0
|
||||
def addItems(self, items): [self.addItem(it) for it in items]
|
||||
def findText(self, text: str) -> int:
|
||||
return self._items.index(text) if text in self._items else -1
|
||||
def findText(self, text: str) -> int:
|
||||
for i, (t, _) in enumerate(self._items):
|
||||
if t == text:
|
||||
return i
|
||||
return -1
|
||||
def setCurrentIndex(self, idx: int) -> None:
|
||||
if 0 <= idx < len(self._items):
|
||||
self._index = idx
|
||||
@@ -497,7 +535,11 @@ except (ImportError, AttributeError):
|
||||
idx = self.findText(text)
|
||||
if idx >= 0: self.setCurrentIndex(idx)
|
||||
def currentText(self) -> str:
|
||||
return self._items[self._index] if 0 <= self._index < len(self._items) else ""
|
||||
return self._items[self._index][0] if 0 <= self._index < len(self._items) else ""
|
||||
def currentData(self):
|
||||
return self._items[self._index][1] if 0 <= self._index < len(self._items) else None
|
||||
def count(self) -> int:
|
||||
return len(self._items)
|
||||
|
||||
QComboBox = _MockComboBox
|
||||
|
||||
@@ -605,6 +647,73 @@ except (ImportError, AttributeError):
|
||||
self._checked = checked
|
||||
|
||||
QCheckBox = _MockQCheckBox
|
||||
|
||||
DialogAccepted = 1
|
||||
ExtendedSelection = 3
|
||||
|
||||
class _MockQDialog(_MockWidget):
|
||||
DialogCode = type("DialogCode", (), {"Accepted": DialogAccepted, "Rejected": 0})
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._layout = None
|
||||
def setWindowTitle(self, title: str) -> None: pass
|
||||
def setWindowIcon(self, icon) -> None: pass
|
||||
def exec(self) -> int: return DialogAccepted
|
||||
def exec_(self) -> int: return DialogAccepted
|
||||
def accept(self) -> None: pass
|
||||
def reject(self) -> None: pass
|
||||
def resize(self, *args, **kwargs) -> None: pass
|
||||
def adjustSize(self) -> None: pass
|
||||
def sizeHint(self):
|
||||
return type("Size", (), {"width": lambda self=None: 200, "height": lambda self=None: 100})()
|
||||
|
||||
QDialog = _MockQDialog
|
||||
|
||||
class _MockQDialogButtonBox(_MockWidget):
|
||||
StandardButton = type("StandardButton", (), {"Ok": 1, "Cancel": 2})
|
||||
Ok = 1
|
||||
Cancel = 2
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.accepted = type('Signal', (), {'connect': lambda s, cb: None})()
|
||||
self.rejected = type('Signal', (), {'connect': lambda s, cb: None})()
|
||||
|
||||
QDialogButtonBox = _MockQDialogButtonBox
|
||||
|
||||
class _MockQListWidgetItem:
|
||||
def __init__(self, text: str = ""):
|
||||
self._text = text
|
||||
self._selected = False
|
||||
def setSelected(self, value: bool) -> None: self._selected = value
|
||||
def isSelected(self) -> bool: return self._selected
|
||||
|
||||
QListWidgetItem = _MockQListWidgetItem
|
||||
|
||||
class _MockQListWidget(_MockWidget):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._items = []
|
||||
def addItem(self, item) -> None: self._items.append(item)
|
||||
def item(self, index: int): return self._items[index] if 0 <= index < len(self._items) else None
|
||||
def count(self) -> int: return len(self._items)
|
||||
def row(self, item) -> int: return self._items.index(item) if item in self._items else -1
|
||||
def selectedItems(self): return [i for i in self._items if i.isSelected()]
|
||||
def setSelectionMode(self, *args, **kwargs) -> None: pass
|
||||
def sizeHintForRow(self, index: int) -> int: return 20
|
||||
def setFixedHeight(self, height: int) -> None: pass
|
||||
def frameWidth(self) -> int: return 1
|
||||
|
||||
QListWidget = _MockQListWidget
|
||||
|
||||
class _MockQAbstractItemView:
|
||||
SelectionMode = type("SelectionMode", (), {"ExtendedSelection": ExtendedSelection})
|
||||
|
||||
QAbstractItemView = _MockQAbstractItemView
|
||||
|
||||
class _MockQIcon:
|
||||
def __init__(self, *args, **kwargs): pass
|
||||
|
||||
QIcon = _MockQIcon
|
||||
|
||||
def exec_dialog(dialog: Any) -> Any:
|
||||
return YES
|
||||
# --------------------------- TEST ---------------------------
|
||||
|
||||
@@ -20,6 +20,7 @@ class SettingsLogic:
|
||||
"amt",
|
||||
"behoerde",
|
||||
"landkreis_user",
|
||||
"landkreis_kennzahl",
|
||||
"sachgebiet",
|
||||
"bezeichnung",
|
||||
"name",
|
||||
|
||||
+42
-11
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
sn_basis/ui/tabs/settings_tab.py – Einstellungen-Tab für Projekteinformationen.
|
||||
sn_basis/ui/tabs/settings_tab.py – Einstellungen-Tab für Projektinformationen.
|
||||
Verwaltet benutzerspezifische und projektspezifische Einstellungen.
|
||||
"""
|
||||
|
||||
@@ -8,28 +8,33 @@ from sn_basis.functions.qt_wrapper import (
|
||||
QGridLayout,
|
||||
QLabel,
|
||||
QLineEdit,
|
||||
QComboBox,
|
||||
QGroupBox,
|
||||
QVBoxLayout,
|
||||
QPushButton,
|
||||
)
|
||||
from sn_basis.functions.settings_logic import SettingsLogic
|
||||
from sn_basis.functions.landkreise import LANDKREISE
|
||||
|
||||
#: Feldschlüssel, die als Landkreis-Dropdown (statt Freitext) dargestellt werden.
|
||||
_LANDKREIS_DROPDOWN_FELDER = {"landkreis_user"}
|
||||
|
||||
|
||||
class SettingsTab(QWidget):
|
||||
"""
|
||||
Tab-Widget für die Verwaltung von Projekt- und Benutzereinstellungen.
|
||||
|
||||
|
||||
Attributes:
|
||||
tab_title: Anzeigetitel des Tabs ("Projekteigenschaften")
|
||||
logic: SettingsLogic-Instanz für persistente Einstellungen
|
||||
"""
|
||||
|
||||
|
||||
tab_title = "Projekteigenschaften"
|
||||
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
Initialisiert den Settings-Tab mit Eingabefeldern.
|
||||
|
||||
|
||||
Args:
|
||||
parent: Übergeordnetes Widget (Standard: None)
|
||||
"""
|
||||
@@ -64,7 +69,7 @@ class SettingsTab(QWidget):
|
||||
self.user_inputs = {}
|
||||
|
||||
for row, (key, label) in enumerate(self.user_fields.items()):
|
||||
input_widget = QLineEdit()
|
||||
input_widget = self._build_input(key)
|
||||
self.user_inputs[key] = input_widget
|
||||
|
||||
user_layout.addWidget(QLabel(label), row, 0)
|
||||
@@ -80,7 +85,7 @@ class SettingsTab(QWidget):
|
||||
self.project_inputs = {}
|
||||
|
||||
for row, (key, label) in enumerate(self.project_fields.items()):
|
||||
input_widget = QLineEdit()
|
||||
input_widget = self._build_input(key)
|
||||
self.project_inputs[key] = input_widget
|
||||
|
||||
project_layout.addWidget(QLabel(label), row, 0)
|
||||
@@ -107,14 +112,35 @@ class SettingsTab(QWidget):
|
||||
# Daten laden
|
||||
self.load_data()
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Eingabewidget je Feld erzeugen
|
||||
# ---------------------------------------------------------
|
||||
def _build_input(self, key: str):
|
||||
if key in _LANDKREIS_DROPDOWN_FELDER:
|
||||
combo = QComboBox()
|
||||
combo.addItem("", None) # Platzhalter: keine Vorbelegung bei leerem Projekt
|
||||
for kennzahl, name in LANDKREISE:
|
||||
combo.addItem(name, kennzahl)
|
||||
return combo
|
||||
return QLineEdit()
|
||||
|
||||
# ---------------------------------------------------------
|
||||
# Speichern
|
||||
# ---------------------------------------------------------
|
||||
def save_data(self):
|
||||
fields = {
|
||||
key: widget.text()
|
||||
for key, widget in {**self.user_inputs, **self.project_inputs}.items()
|
||||
}
|
||||
fields = {}
|
||||
for key, widget in {**self.user_inputs, **self.project_inputs}.items():
|
||||
if isinstance(widget, QComboBox):
|
||||
fields[key] = widget.currentText()
|
||||
else:
|
||||
fields[key] = widget.text()
|
||||
|
||||
# Landkreiskennzahl aus der Dropdown-Auswahl zusätzlich als eigene
|
||||
# Variable bereitstellen (siehe landkreise.py).
|
||||
landkreis_widget = self.user_inputs.get("landkreis_user")
|
||||
if isinstance(landkreis_widget, QComboBox):
|
||||
fields["landkreis_kennzahl"] = landkreis_widget.currentData() or ""
|
||||
|
||||
self.logic.save(fields)
|
||||
|
||||
# ---------------------------------------------------------
|
||||
@@ -123,4 +149,9 @@ class SettingsTab(QWidget):
|
||||
def load_data(self):
|
||||
data = self.logic.load()
|
||||
for key, widget in {**self.user_inputs, **self.project_inputs}.items():
|
||||
widget.setText(data.get(key, ""))
|
||||
if isinstance(widget, QComboBox):
|
||||
gespeicherter_name = data.get(key, "")
|
||||
index = widget.findText(gespeicherter_name)
|
||||
widget.setCurrentIndex(index if index >= 0 else 0)
|
||||
else:
|
||||
widget.setText(data.get(key, ""))
|
||||
|
||||
Reference in New Issue
Block a user