Laden der Daten aus Datenbank.
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1263</width>
|
<width>1263</width>
|
||||||
<height>921</height>
|
<height>774</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -142,7 +142,7 @@
|
|||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="pushButton_3">
|
<widget class="QPushButton" name="pB_lade_aus_fn2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>lade aus FN2</string>
|
<string>lade aus FN2</string>
|
||||||
</property>
|
</property>
|
||||||
@@ -172,7 +172,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>54</width>
|
<width>54</width>
|
||||||
<height>865</height>
|
<height>718</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
@@ -350,7 +350,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>649</width>
|
<width>649</width>
|
||||||
<height>837</height>
|
<height>690</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class Ui_MainWindow(object):
|
|||||||
def setupUi(self, MainWindow):
|
def setupUi(self, MainWindow):
|
||||||
if not MainWindow.objectName():
|
if not MainWindow.objectName():
|
||||||
MainWindow.setObjectName(u"MainWindow")
|
MainWindow.setObjectName(u"MainWindow")
|
||||||
MainWindow.resize(1263, 921)
|
MainWindow.resize(1263, 774)
|
||||||
self.actionNeu = QAction(MainWindow)
|
self.actionNeu = QAction(MainWindow)
|
||||||
self.actionNeu.setObjectName(u"actionNeu")
|
self.actionNeu.setObjectName(u"actionNeu")
|
||||||
icon = QIcon(QIcon.fromTheme(u"folder-new"))
|
icon = QIcon(QIcon.fromTheme(u"folder-new"))
|
||||||
@@ -110,12 +110,12 @@ class Ui_MainWindow(object):
|
|||||||
|
|
||||||
self.horizontalLayout_2.addItem(self.horizontalSpacer)
|
self.horizontalLayout_2.addItem(self.horizontalSpacer)
|
||||||
|
|
||||||
self.pushButton_3 = QPushButton(self.frame_2)
|
self.pB_lade_aus_fn2 = QPushButton(self.frame_2)
|
||||||
self.pushButton_3.setObjectName(u"pushButton_3")
|
self.pB_lade_aus_fn2.setObjectName(u"pB_lade_aus_fn2")
|
||||||
icon6 = QIcon(QIcon.fromTheme(QIcon.ThemeIcon.GoDown))
|
icon6 = QIcon(QIcon.fromTheme(QIcon.ThemeIcon.GoDown))
|
||||||
self.pushButton_3.setIcon(icon6)
|
self.pB_lade_aus_fn2.setIcon(icon6)
|
||||||
|
|
||||||
self.horizontalLayout_2.addWidget(self.pushButton_3)
|
self.horizontalLayout_2.addWidget(self.pB_lade_aus_fn2)
|
||||||
|
|
||||||
|
|
||||||
self.verticalLayout.addWidget(self.frame_2)
|
self.verticalLayout.addWidget(self.frame_2)
|
||||||
@@ -131,7 +131,7 @@ class Ui_MainWindow(object):
|
|||||||
self.scrollArea.setWidgetResizable(True)
|
self.scrollArea.setWidgetResizable(True)
|
||||||
self.scrollAreaWidgetContents = QWidget()
|
self.scrollAreaWidgetContents = QWidget()
|
||||||
self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents")
|
self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents")
|
||||||
self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 54, 865))
|
self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 54, 718))
|
||||||
self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents)
|
self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents)
|
||||||
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||||
self.label = QLabel(self.scrollAreaWidgetContents)
|
self.label = QLabel(self.scrollAreaWidgetContents)
|
||||||
@@ -216,7 +216,7 @@ class Ui_MainWindow(object):
|
|||||||
self.scrollArea_2.setWidgetResizable(True)
|
self.scrollArea_2.setWidgetResizable(True)
|
||||||
self.scrollAreaWidgetContents_2 = QWidget()
|
self.scrollAreaWidgetContents_2 = QWidget()
|
||||||
self.scrollAreaWidgetContents_2.setObjectName(u"scrollAreaWidgetContents_2")
|
self.scrollAreaWidgetContents_2.setObjectName(u"scrollAreaWidgetContents_2")
|
||||||
self.scrollAreaWidgetContents_2.setGeometry(QRect(0, 0, 649, 837))
|
self.scrollAreaWidgetContents_2.setGeometry(QRect(0, 0, 649, 690))
|
||||||
self.verticalLayout_3 = QVBoxLayout(self.scrollAreaWidgetContents_2)
|
self.verticalLayout_3 = QVBoxLayout(self.scrollAreaWidgetContents_2)
|
||||||
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||||
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
|
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
|
||||||
@@ -286,7 +286,7 @@ class Ui_MainWindow(object):
|
|||||||
self.actionVorhandene_Projekte.setText(QCoreApplication.translate("MainWindow", u"Vorhandene Projekte", None))
|
self.actionVorhandene_Projekte.setText(QCoreApplication.translate("MainWindow", u"Vorhandene Projekte", None))
|
||||||
self.pushButton.setText(QCoreApplication.translate("MainWindow", u"nur ge\u00e4nderte generieren", None))
|
self.pushButton.setText(QCoreApplication.translate("MainWindow", u"nur ge\u00e4nderte generieren", None))
|
||||||
self.pushButton_2.setText(QCoreApplication.translate("MainWindow", u"Alle generieren", None))
|
self.pushButton_2.setText(QCoreApplication.translate("MainWindow", u"Alle generieren", None))
|
||||||
self.pushButton_3.setText(QCoreApplication.translate("MainWindow", u"lade aus FN2", None))
|
self.pB_lade_aus_fn2.setText(QCoreApplication.translate("MainWindow", u"lade aus FN2", None))
|
||||||
self.label.setText("")
|
self.label.setText("")
|
||||||
self.label_2.setText("")
|
self.label_2.setText("")
|
||||||
self.label_6.setText(QCoreApplication.translate("MainWindow", u"Vorher (Referenz)", None))
|
self.label_6.setText(QCoreApplication.translate("MainWindow", u"Vorher (Referenz)", None))
|
||||||
|
|||||||
+287
-1
@@ -1,10 +1,11 @@
|
|||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import polars as pl
|
||||||
|
|
||||||
from PySide6.QtCore import Qt, QSize
|
from PySide6.QtCore import Qt, QSize
|
||||||
from PySide6.QtGui import QCursor, QPixmap, QPainter, QAction, QIcon
|
from PySide6.QtGui import QCursor, QPixmap, QPainter, QAction, QIcon
|
||||||
from PySide6.QtWidgets import QLabel, QMainWindow, QApplication, QStyleFactory, QMenu, QTreeWidgetItem
|
from PySide6.QtWidgets import QLabel, QMainWindow, QApplication, QStyleFactory, QMenu, QTreeWidgetItem, QMessageBox
|
||||||
from PySide6.QtPdf import QPdfDocument
|
from PySide6.QtPdf import QPdfDocument
|
||||||
|
|
||||||
from ui.MainWinddow_ui import Ui_MainWindow
|
from ui.MainWinddow_ui import Ui_MainWindow
|
||||||
@@ -142,6 +143,8 @@ class MainWindow(QMainWindow):
|
|||||||
print(f"Öffne Projekt: {project.name}")
|
print(f"Öffne Projekt: {project.name}")
|
||||||
print(f"Projekt-Ordner: {project.project_dir}")
|
print(f"Projekt-Ordner: {project.project_dir}")
|
||||||
|
|
||||||
|
self.project = project
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Prüfe ob project.yaml existiert und nicht leer ist
|
# Prüfe ob project.yaml existiert und nicht leer ist
|
||||||
project_yaml_path = Path(project.project_dir) / 'project.yaml'
|
project_yaml_path = Path(project.project_dir) / 'project.yaml'
|
||||||
@@ -538,6 +541,9 @@ class MainWindow(QMainWindow):
|
|||||||
# Menü-Aktionen verbinden
|
# Menü-Aktionen verbinden
|
||||||
self.ui.actionNeu.triggered.connect(self.open_new_project_dialog)
|
self.ui.actionNeu.triggered.connect(self.open_new_project_dialog)
|
||||||
self.ui.actionEinstellungen.triggered.connect(self.open_settings_dialog)
|
self.ui.actionEinstellungen.triggered.connect(self.open_settings_dialog)
|
||||||
|
|
||||||
|
# Button "lade aus FN2" verbinden
|
||||||
|
self.ui.pB_lade_aus_fn2.clicked.connect(self.on_load_from_fn2_clicked)
|
||||||
|
|
||||||
def _setup_tree_context_menu(self):
|
def _setup_tree_context_menu(self):
|
||||||
"""Richtet das Kontextmenü für das TreeWidget ein."""
|
"""Richtet das Kontextmenü für das TreeWidget ein."""
|
||||||
@@ -1060,6 +1066,286 @@ class MainWindow(QMainWindow):
|
|||||||
print("Neuen TreeNode als Root-Element hinzufügen")
|
print("Neuen TreeNode als Root-Element hinzufügen")
|
||||||
# TODO: Dialog zum Eingeben der TreeNode-Daten öffnen
|
# TODO: Dialog zum Eingeben der TreeNode-Daten öffnen
|
||||||
|
|
||||||
|
def on_load_from_fn2_clicked(self):
|
||||||
|
"""
|
||||||
|
Wird ausgeführt, wenn der Button "lade aus FN2" geklickt wird.
|
||||||
|
Führt SQL-Abfrage aus und aktualisiert die Projekt-Nodes.
|
||||||
|
"""
|
||||||
|
print("Button 'lade aus FN2' wurde geklickt!")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Prüfe ob ein Projekt geladen ist
|
||||||
|
if not hasattr(self, 'project') or not self.project:
|
||||||
|
QMessageBox.warning(self, "Warnung", "Kein Projekt geladen. Bitte öffnen Sie zuerst ein Projekt.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Hole das aktuelle Projekt aus app_settings
|
||||||
|
if not self.project:
|
||||||
|
QMessageBox.warning(self, "Warnung", "Aktuelles Projekt nicht in den Einstellungen gefunden.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Hole die PostgreSQL-Datenbank-Konfiguration
|
||||||
|
db_config = self._get_database_config(self.project.postgre_sql_db_id)
|
||||||
|
if not db_config:
|
||||||
|
QMessageBox.warning(self, "Warnung", "PostgreSQL-Datenbank-Konfiguration nicht gefunden.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Führe SQL-Abfrage aus
|
||||||
|
df = self._execute_sql_query(db_config)
|
||||||
|
if df is None:
|
||||||
|
return # Fehler bereits angezeigt
|
||||||
|
|
||||||
|
# Verarbeite die Daten wie in readCsv.py
|
||||||
|
new_nodes = self._process_sql_data(df)
|
||||||
|
|
||||||
|
# Merge mit vorhandenen Nodes
|
||||||
|
self._merge_nodes_with_existing(new_nodes)
|
||||||
|
|
||||||
|
# Speichere die aktualisierten Projekt-Einstellungen
|
||||||
|
self._save_project_settings()
|
||||||
|
|
||||||
|
# Lade das Projekt neu
|
||||||
|
self._load_nodes_to_tree()
|
||||||
|
|
||||||
|
QMessageBox.information(self, "Erfolg", "Daten erfolgreich aus FN2 geladen und Projekt aktualisiert!")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Laden aus FN2: {e}")
|
||||||
|
QMessageBox.critical(self, "Fehler", f"Fehler beim Laden aus FN2:\n{str(e)}")
|
||||||
|
|
||||||
|
# def _get_current_project(self):
|
||||||
|
# """
|
||||||
|
# Ermittelt das aktuell geladene Projekt aus app_settings.
|
||||||
|
|
||||||
|
# Returns:
|
||||||
|
# PdfProject|None: Das aktuelle Projekt oder None
|
||||||
|
# """
|
||||||
|
# # Da wir kein direktes Attribut für das aktuelle Projekt haben,
|
||||||
|
# # nehmen wir das erste Projekt als Fallback oder implementieren eine bessere Logik
|
||||||
|
# if app_settings.pdf_projects:
|
||||||
|
# # TODO: Hier sollte eine bessere Logik implementiert werden,
|
||||||
|
# # um das tatsächlich aktuelle Projekt zu ermitteln
|
||||||
|
# return app_settings.pdf_projects[0]
|
||||||
|
# return None
|
||||||
|
|
||||||
|
def _get_database_config(self, db_id):
|
||||||
|
"""
|
||||||
|
Holt die Datenbank-Konfiguration anhand der ID.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db_id: ID der PostgreSQL-Datenbank
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
PostgreSqlDb|None: Die Datenbank-Konfiguration oder None
|
||||||
|
"""
|
||||||
|
for db in app_settings.postgresql_dbs:
|
||||||
|
if db.id == db_id:
|
||||||
|
return db
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _execute_sql_query(self, db_config):
|
||||||
|
"""
|
||||||
|
Führt die SQL-Abfrage aus der data.sql Datei aus.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db_config: PostgreSQL-Datenbank-Konfiguration
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
pl.DataFrame|None: Die Abfrageergebnisse oder None bei Fehler
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Lade SQL-Abfrage aus Datei
|
||||||
|
sql_file_path = Path("src/res/data.sql")
|
||||||
|
if not sql_file_path.exists():
|
||||||
|
QMessageBox.critical(self, "Fehler", f"SQL-Datei nicht gefunden: {sql_file_path}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
with open(sql_file_path, 'r', encoding='utf-8') as f:
|
||||||
|
sql_query = f.read()
|
||||||
|
|
||||||
|
print(f"SQL-Abfrage geladen: {len(sql_query)} Zeichen")
|
||||||
|
|
||||||
|
# Verbindung zur PostgreSQL-Datenbank herstellen
|
||||||
|
connection_string = ("postgresql://"
|
||||||
|
f"{db_config.username}:"
|
||||||
|
f"{db_config.password}@"
|
||||||
|
f"{db_config.host}:"
|
||||||
|
f"{db_config.port}/"
|
||||||
|
f"{db_config.database}?"
|
||||||
|
f"sslmode={db_config.ssl_mode.value}"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(f"Verbinde zu PostgreSQL: {db_config.host}:{db_config.port}/{db_config.database}")
|
||||||
|
|
||||||
|
df = pl.read_database_uri(sql_query, connection_string, engine='connectorx').sort(["reporttyp_bez", "report_bez", "repfile_bez"])
|
||||||
|
return df
|
||||||
|
except Exception as e:
|
||||||
|
error_msg = f"Fehler beim Ausführen der SQL-Abfrage: {str(e)}"
|
||||||
|
print(error_msg)
|
||||||
|
QMessageBox.critical(self, "Fehler", error_msg)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _process_sql_data(self, df):
|
||||||
|
"""
|
||||||
|
Verarbeitet die SQL-Daten wie in readCsv.py und erstellt Node-Struktur.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
df: Polars DataFrame mit den SQL-Ergebnissen
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[TreeNode]: Liste der erstellten Root-Nodes
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
# Gruppiere die Daten wie in readCsv.py
|
||||||
|
ebene_1 = df.group_by(["reporttyp", "reporttyp_bez"]).len()
|
||||||
|
ebene_2 = df.group_by(["reporttyp", "report", "report_bez"]).len()
|
||||||
|
ebene_3 = df.group_by(["reporttyp", "report", "repfile", "repfile_bez", "xsl_datei"]).len()
|
||||||
|
|
||||||
|
group_time = time.time() - start_time
|
||||||
|
print(f"Performance: Gruppierung in {group_time:.3f}s")
|
||||||
|
|
||||||
|
new_nodes = []
|
||||||
|
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
# Erstelle Node-Struktur wie in readCsv.py
|
||||||
|
for r1 in ebene_1.rows(named=True):
|
||||||
|
tn_1 = TreeNode(id=(r1["reporttyp"],), bez=r1["reporttyp_bez"], children=[])
|
||||||
|
r1_children = ebene_2.filter(pl.col("reporttyp") == r1["reporttyp"])
|
||||||
|
|
||||||
|
for r2 in r1_children.rows(named=True):
|
||||||
|
tn_2 = TreeNode(id=(r2["reporttyp"], r2["report"]), bez=r2["report_bez"], children=[])
|
||||||
|
r2_children = ebene_3.filter((pl.col("reporttyp") == r1["reporttyp"]) & (pl.col("report") == r2["report"]))
|
||||||
|
|
||||||
|
for r3 in r2_children.rows(named=True):
|
||||||
|
x = XslFile(
|
||||||
|
id=(r3["reporttyp"], r3["report"], r3["repfile"]),
|
||||||
|
bez=r3["repfile_bez"],
|
||||||
|
xsl_file=Path(r3["xsl_datei"]),
|
||||||
|
xmls=[]
|
||||||
|
)
|
||||||
|
|
||||||
|
tn_2.children.append(x)
|
||||||
|
tn_1.children.append(tn_2)
|
||||||
|
new_nodes.append(tn_1)
|
||||||
|
|
||||||
|
nodes_time = time.time() - start_time
|
||||||
|
print(f"Performance: Node-Erstellung in {nodes_time:.3f}s")
|
||||||
|
print(f"Erstellt: {len(new_nodes)} Root-Nodes")
|
||||||
|
|
||||||
|
return new_nodes
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Verarbeiten der SQL-Daten: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def _merge_nodes_with_existing(self, new_nodes):
|
||||||
|
"""
|
||||||
|
Merged neue Nodes mit vorhandenen Nodes basierend auf IDs.
|
||||||
|
Überschreibt nur einzelne Eigenschaften, nicht ganze Nodes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
new_nodes: Liste der neuen Nodes
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
print("Merge neue Nodes mit vorhandenen...")
|
||||||
|
|
||||||
|
# Erstelle ein Dictionary der neuen Nodes für schnellen Zugriff
|
||||||
|
new_nodes_dict = {}
|
||||||
|
self._build_nodes_dict(new_nodes, new_nodes_dict)
|
||||||
|
|
||||||
|
print(f"Neue Nodes Dictionary erstellt: {len(new_nodes_dict)} Einträge")
|
||||||
|
|
||||||
|
# Merge mit vorhandenen Nodes
|
||||||
|
if self.pdf_project.nodes:
|
||||||
|
self._merge_nodes_recursive(self.pdf_project.nodes, new_nodes_dict)
|
||||||
|
|
||||||
|
# Füge komplett neue Root-Nodes hinzu
|
||||||
|
existing_root_ids = {node.id for node in self.pdf_project.nodes}
|
||||||
|
for new_node in new_nodes:
|
||||||
|
if new_node.id not in existing_root_ids:
|
||||||
|
self.pdf_project.nodes.append(new_node)
|
||||||
|
print(f"Neue Root-Node hinzugefügt: {new_node.bez}")
|
||||||
|
|
||||||
|
print("Merge abgeschlossen")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Mergen der Nodes: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def _build_nodes_dict(self, nodes, nodes_dict):
|
||||||
|
"""
|
||||||
|
Erstellt rekursiv ein Dictionary aller Nodes für schnellen ID-basierten Zugriff.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nodes: Liste der Nodes
|
||||||
|
nodes_dict: Dictionary zum Füllen
|
||||||
|
"""
|
||||||
|
for node in nodes:
|
||||||
|
nodes_dict[node.id] = node
|
||||||
|
|
||||||
|
if isinstance(node, TreeNode) and node.children:
|
||||||
|
self._build_nodes_dict(node.children, nodes_dict)
|
||||||
|
|
||||||
|
def _merge_nodes_recursive(self, existing_nodes, new_nodes_dict):
|
||||||
|
"""
|
||||||
|
Merged rekursiv vorhandene Nodes mit neuen Nodes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
existing_nodes: Liste der vorhandenen Nodes
|
||||||
|
new_nodes_dict: Dictionary der neuen Nodes
|
||||||
|
"""
|
||||||
|
for existing_node in existing_nodes:
|
||||||
|
if existing_node.id in new_nodes_dict:
|
||||||
|
new_node = new_nodes_dict[existing_node.id]
|
||||||
|
|
||||||
|
# Aktualisiere nur die Bezeichnung, falls sie sich geändert hat
|
||||||
|
if existing_node.bez != new_node.bez:
|
||||||
|
print(f"Aktualisiere Bezeichnung für Node {existing_node.id}: '{existing_node.bez}' -> '{new_node.bez}'")
|
||||||
|
existing_node.bez = new_node.bez
|
||||||
|
|
||||||
|
# Für XslFile: Aktualisiere xsl_file Pfad
|
||||||
|
if isinstance(existing_node, XslFile) and isinstance(new_node, XslFile):
|
||||||
|
if existing_node.xsl_file != new_node.xsl_file:
|
||||||
|
print(f"Aktualisiere XSL-Datei für Node {existing_node.id}: '{existing_node.xsl_file}' -> '{new_node.xsl_file}'")
|
||||||
|
existing_node.xsl_file = new_node.xsl_file
|
||||||
|
|
||||||
|
# Rekursiv für Kinder (nur bei TreeNode)
|
||||||
|
if isinstance(existing_node, TreeNode) and existing_node.children:
|
||||||
|
self._merge_nodes_recursive(existing_node.children, new_nodes_dict)
|
||||||
|
|
||||||
|
# Füge neue Kinder hinzu, die noch nicht existieren
|
||||||
|
if existing_node.id in new_nodes_dict:
|
||||||
|
new_node = new_nodes_dict[existing_node.id]
|
||||||
|
if isinstance(new_node, TreeNode) and new_node.children:
|
||||||
|
existing_child_ids = {child.id for child in existing_node.children}
|
||||||
|
for new_child in new_node.children:
|
||||||
|
if new_child.id not in existing_child_ids:
|
||||||
|
existing_node.children.append(new_child)
|
||||||
|
print(f"Neues Kind hinzugefügt zu Node {existing_node.id}: {new_child.bez}")
|
||||||
|
|
||||||
|
def _save_project_settings(self):
|
||||||
|
"""
|
||||||
|
Speichert die aktualisierten Projekt-Einstellungen.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
current_project: Das aktuelle Projekt
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
# Speichere in project.yaml im Projekt-Verzeichnis
|
||||||
|
self.pdf_project.writeSettings(project_dir=self.project.project_dir)
|
||||||
|
|
||||||
|
dump_time = time.time() - start_time
|
||||||
|
print(f"Performance: Projekt-Einstellungen gespeichert in {dump_time:.3f}s")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Speichern der Projekt-Einstellungen: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
"""Wird beim Schließen der Anwendung aufgerufen."""
|
"""Wird beim Schließen der Anwendung aufgerufen."""
|
||||||
# PDF-Dokumente schließen ist bei QtPdf automatisch durch Garbage Collection
|
# PDF-Dokumente schließen ist bei QtPdf automatisch durch Garbage Collection
|
||||||
|
|||||||
Reference in New Issue
Block a user