import os from qgis.PyQt.QtWidgets import ( QWidget, QVBoxLayout, QLabel, QMessageBox, QPushButton, QFileDialog, QToolButton, QSizePolicy ) from qgis.PyQt.QtCore import Qt from qgis.gui import QgsFileWidget, QgsMapLayerComboBox from qgis.core import QgsProject, QgsMapLayerProxyModel class TabA(QWidget): tab_title = "Daten" def __init__(self, parent=None): super().__init__(parent) # Variablen initialisieren self.verfahrens_db = None self.lokale_linkliste = None # --------------------------------------------------------- # Hauptlayout # --------------------------------------------------------- main_layout = QVBoxLayout() main_layout.setSpacing(4) main_layout.setContentsMargins(4, 4, 4, 4) # --------------------------------------------------------- # COLLAPSIBLE GRUPPE: Verfahrens-Datenbank # --------------------------------------------------------- self.group_button = QToolButton() self.group_button.setText("Verfahrens-Datenbank") self.group_button.setCheckable(True) self.group_button.setChecked(True) self.group_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.group_button.setArrowType(Qt.DownArrow) self.group_button.setStyleSheet("font-weight: bold;") self.group_button.toggled.connect(self.toggle_group) main_layout.addWidget(self.group_button, 0) # Inhalt der Gruppe self.group_content = QWidget() self.group_content.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) group_layout = QVBoxLayout() group_layout.setSpacing(2) group_layout.setContentsMargins(10, 4, 4, 4) # Hinweis hinweis1 = QLabel("bestehende Datei auswählen") group_layout.addWidget(hinweis1) # Datei-Auswahl self.file_widget = QgsFileWidget() self.file_widget.setStorageMode(QgsFileWidget.GetFile) self.file_widget.setFilter("Geopackage (*.gpkg)") self.file_widget.fileChanged.connect(self.on_file_changed) group_layout.addWidget(self.file_widget) # Hinweis "-oder-" hinweis2 = QLabel("-oder-") group_layout.addWidget(hinweis2) # Button: Neue Datei self.btn_new = QPushButton("Neue Verfahrens-DB anlegen") self.btn_new.clicked.connect(self.create_new_gpkg) group_layout.addWidget(self.btn_new) self.group_content.setLayout(group_layout) main_layout.addWidget(self.group_content, 0) # --------------------------------------------------------- # COLLAPSIBLE Optional-Bereich # --------------------------------------------------------- self.optional_button = QToolButton() self.optional_button.setText("Optional: Lokale Linkliste") self.optional_button.setCheckable(True) self.optional_button.setChecked(False) self.optional_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.optional_button.setArrowType(Qt.RightArrow) self.optional_button.setStyleSheet("font-weight: bold; margin-top: 6px;") self.optional_button.toggled.connect(self.toggle_optional) main_layout.addWidget(self.optional_button, 0) # Inhalt optional self.optional_content = QWidget() self.optional_content.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) optional_layout = QVBoxLayout() optional_layout.setSpacing(2) optional_layout.setContentsMargins(10, 4, 4, 20) # Hinweistext optional_hint = QLabel("(frei lassen für globale Linkliste)") optional_layout.addWidget(optional_hint) # Datei-Auswahl für Linkliste self.linkliste_widget = QgsFileWidget() self.linkliste_widget.setStorageMode(QgsFileWidget.GetFile) self.linkliste_widget.setFilter("Excelliste (*.xlsx)") self.linkliste_widget.fileChanged.connect(self.on_linkliste_changed) optional_layout.addWidget(self.linkliste_widget) main_layout.addWidget(self.optional_content, 0) # --------------------------------------------------------- # Layer-Auswahlfeld # --------------------------------------------------------- layer_label = QLabel("Verfahrensgebiet-Layer auswählen") layer_label.setStyleSheet("font-weight: bold; margin-top: 6px;") main_layout.addWidget(layer_label) self.layer_combo = QgsMapLayerComboBox() self.layer_combo.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Maximum) # ✅ QGIS 3.22–3.46 kompatibel self.layer_combo.setFilters(QgsMapLayerProxyModel.VectorLayer) # Layerwechsel speichern self.layer_combo.layerChanged.connect(self.on_layer_changed) main_layout.addWidget(self.layer_combo) self.optional_content.setLayout(optional_layout) self.optional_content.setVisible(False) # Spacer main_layout.addStretch(1) self.setLayout(main_layout) # ✅ gespeicherte Werte wiederherstellen (jetzt existieren die Widgets!) self.restore_saved_values() # ✅ Layer-Vorauswahl durchführen self.preselect_verfahrensgebiet_layer() # --------------------------------------------------------- # Collapsible Gruppe ein-/ausblenden # --------------------------------------------------------- def toggle_group(self, checked): self.group_button.setArrowType(Qt.DownArrow if checked else Qt.RightArrow) self.group_content.setVisible(checked) def toggle_optional(self, checked): self.optional_button.setArrowType(Qt.DownArrow if checked else Qt.RightArrow) self.optional_content.setVisible(checked) # --------------------------------------------------------- # Datei-Auswahl: Verfahrens-DB # --------------------------------------------------------- def on_file_changed(self, path: str): if not path: self.verfahrens_db = None # ✅ Projektvariable löschen vars = QgsProject.instance().customVariables() if "sn_verfahrens_db" in vars: del vars["sn_verfahrens_db"] QgsProject.instance().setCustomVariables(vars) self.update_group_button_color() return if not path.lower().endswith(".gpkg"): path += ".gpkg" self.file_widget.setFilePath(path) if os.path.exists(path): self.verfahrens_db = path else: self.verfahrens_db = None QMessageBox.warning(self, "Datei nicht gefunden", f"Die Datei existiert nicht:\n{path}") self.file_widget.setFilePath("") # ✅ speichern vars = QgsProject.instance().customVariables() vars["sn_verfahrens_db"] = self.verfahrens_db QgsProject.instance().setCustomVariables(vars) self.update_group_button_color() # --------------------------------------------------------- # Datei-Auswahl: Lokale Linkliste # --------------------------------------------------------- def on_linkliste_changed(self, path: str): if not path: self.lokale_linkliste = None vars = QgsProject.instance().customVariables() if "sn_linkliste" in vars: del vars["sn_linkliste"] QgsProject.instance().setCustomVariables(vars) return if not path.lower().endswith(".xlsx"): path += ".xlsx" self.linkliste_widget.setFilePath(path) if os.path.exists(path): self.lokale_linkliste = path else: self.lokale_linkliste = None QMessageBox.warning(self, "Datei nicht gefunden", f"Die Datei existiert nicht:\n{path}") self.linkliste_widget.setFilePath("") # ✅ speichern vars = QgsProject.instance().customVariables() vars["sn_linkliste"] = self.lokale_linkliste QgsProject.instance().setCustomVariables(vars) # --------------------------------------------------------- # Layer-Auswahl speichern # --------------------------------------------------------- def on_layer_changed(self, layer): if layer: vars = QgsProject.instance().customVariables() vars["sn_verfahrensgebiet_layer"] = layer.id() QgsProject.instance().setCustomVariables(vars) # --------------------------------------------------------- # Button-Farbe aktualisieren # --------------------------------------------------------- def update_group_button_color(self): if self.verfahrens_db: self.group_button.setStyleSheet("font-weight: bold; background-color: #c4f7c4;") else: self.group_button.setStyleSheet("font-weight: bold;") # --------------------------------------------------------- # Vorauswahl des Layers "Verfahrensgebiet" # --------------------------------------------------------- def preselect_verfahrensgebiet_layer(self): project = QgsProject.instance() # ✅ zuerst gespeicherten Layer wiederherstellen saved_layer_id = project.customVariables().get("sn_verfahrensgebiet_layer", None) if saved_layer_id: layer = project.mapLayer(saved_layer_id) if layer: self.layer_combo.setLayer(layer) return # ✅ sonst nach Namen suchen for layer in project.mapLayers().values(): if "verfahrensgebiet" in layer.name().lower(): self.layer_combo.setLayer(layer) return # ✅ Fallback: erster Layer if self.layer_combo.count() > 0: self.layer_combo.setCurrentIndex(0) # --------------------------------------------------------- # Werte wiederherstellen # --------------------------------------------------------- def restore_saved_values(self): project = QgsProject.instance() vars = project.customVariables() # ✅ Verfahrens-DB saved_db = vars.get("sn_verfahrens_db", None) if saved_db and os.path.exists(saved_db): self.verfahrens_db = saved_db self.file_widget.setFilePath(saved_db) self.update_group_button_color() # ✅ Linkliste saved_link = vars.get("sn_linkliste", None) if saved_link and os.path.exists(saved_link): self.lokale_linkliste = saved_link self.linkliste_widget.setFilePath(saved_link) def create_new_gpkg(self): """Öffnet einen Save-Dialog und legt eine neue GPKG-Datei an.""" file_path, _ = QFileDialog.getSaveFileName( self, "Neue Verfahrens-Datenbank anlegen", "", "Geopackage (*.gpkg);;Alle Dateien (*)" ) if not file_path: return # Abbruch # Automatisch .gpkg anhängen if not file_path.lower().endswith(".gpkg"): file_path += ".gpkg" # Existiert Datei bereits? if os.path.exists(file_path): overwrite = QMessageBox.question( self, "Datei existiert bereits", f"Die Datei existiert bereits:\n\n{file_path}\n\nSoll sie überschrieben werden?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No ) if overwrite != QMessageBox.Yes: return # Datei anlegen try: open(file_path, "w").close() except Exception as e: QMessageBox.critical(self, "Fehler", f"Die Datei konnte nicht angelegt werden:\n{e}") return # Datei übernehmen self.verfahrens_db = file_path self.file_widget.setFilePath(file_path) self.update_group_button_color() QMessageBox.information(self, "Projekt-DB angelegt", f"Neue Projekt-Datenbank wurde angelegt:\n{file_path}")