Hinzufügen der XML-Dateien

Klassen zur besseren Unterscheidung umbenant
This commit is contained in:
2025-08-10 17:32:22 +02:00
parent 5285e92757
commit 8b576b3fa7
3 changed files with 135 additions and 32 deletions
+3 -3
View File
@@ -82,7 +82,7 @@ class PostgreSqlDb(BaseModel):
ssl_mode: SSLMode = SSLMode.PREFER ssl_mode: SSLMode = SSLMode.PREFER
class PdfProject(BaseModel): class Project(BaseModel):
id: int = Field(..., description="Eindeutige Projekt-ID", gt=0) id: int = Field(..., description="Eindeutige Projekt-ID", gt=0)
name: str = Field(..., description="Projekt-Name", min_length=1, max_length=255) name: str = Field(..., description="Projekt-Name", min_length=1, max_length=255)
project_dir: Path = Field(..., description="Pfad zum Projekt-Verzeichnis") project_dir: Path = Field(..., description="Pfad zum Projekt-Verzeichnis")
@@ -136,7 +136,7 @@ class AppSettings(BaseSettings):
saxon_jars: list[SaxonJar] = [] saxon_jars: list[SaxonJar] = []
apache_fops: list[ApacheFop] = [] apache_fops: list[ApacheFop] = []
xsl_dirs: list[XslDir] = [] xsl_dirs: list[XslDir] = []
pdf_projects: list[PdfProject] = [] pdf_projects: list[Project] = []
postgresql_dbs: list[PostgreSqlDb] = [] postgresql_dbs: list[PostgreSqlDb] = []
theme: str | None = None theme: str | None = None
@@ -186,7 +186,7 @@ class TreeNode(BaseModel):
children: list["TreeNode|XslFile"] children: list["TreeNode|XslFile"]
class PdfProjectSettings(BaseModel): class ProjectData(BaseModel):
""" """
Speichert die Projekteinstellungen direkt im Projektordner in einer .yaml-Datei. Speichert die Projekteinstellungen direkt im Projektordner in einer .yaml-Datei.
""" """
+2 -2
View File
@@ -10,7 +10,7 @@ from ui.ApacheFopConfigDialog import ApacheFopConfigDialog
from ui.XslDirConfigDialog import XslDirConfigDialog from ui.XslDirConfigDialog import XslDirConfigDialog
from ui.PostgreSqlConfigDialog import PostgreSqlConfigDialog from ui.PostgreSqlConfigDialog import PostgreSqlConfigDialog
from ui.PdfProject import PdfProjectDlg from ui.PdfProject import PdfProjectDlg
from conf import AppSettings, JavaVm, DiffPdf, SaxonJar, ApacheFop, XslDir, PdfProject, PostgreSqlDb from conf import AppSettings, JavaVm, DiffPdf, SaxonJar, ApacheFop, XslDir, Project, PostgreSqlDb
class AppSettingsDlg(QDialog): class AppSettingsDlg(QDialog):
@@ -456,7 +456,7 @@ class AppSettingsDlg(QDialog):
new_id = max([p.id for p in self.temp_pdf_projects], default=0) + 1 new_id = max([p.id for p in self.temp_pdf_projects], default=0) + 1
# Erstelle PdfProject-Objekt # Erstelle PdfProject-Objekt
new_project = PdfProject( new_project = Project(
id=new_id, id=new_id,
name=project_data['name'], name=project_data['name'],
project_dir=Path(project_data['project_dir']), project_dir=Path(project_data['project_dir']),
+130 -27
View File
@@ -2,16 +2,17 @@ import glob
import os import os
import time import time
import polars as pl import polars as pl
import shutil
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, QMessageBox from PySide6.QtWidgets import QLabel, QMainWindow, QApplication, QStyleFactory, QMenu, QTreeWidgetItem, QMessageBox, QFileDialog
from PySide6.QtPdf import QPdfDocument from PySide6.QtPdf import QPdfDocument
from ui.MainWinddow_ui import Ui_MainWindow from ui.MainWinddow_ui import Ui_MainWindow
from ui.AppSettings import AppSettingsDlg from ui.AppSettings import AppSettingsDlg
from ui.PdfProject import PdfProjectDlg from ui.PdfProject import PdfProjectDlg
from conf import app_settings, PdfProject, PdfProjectSettings, TreeNode, XslFile, XmlFile from conf import app_settings, Project, ProjectData, TreeNode, XslFile, XmlFile
from pathlib import Path from pathlib import Path
@@ -54,7 +55,13 @@ class MainWindow(QMainWindow):
self.last_drag_position = None self.last_drag_position = None
self.drag_threshold = 3 # Mindestbewegung in Pixeln vor dem Scrollen self.drag_threshold = 3 # Mindestbewegung in Pixeln vor dem Scrollen
self.scroll_sensitivity = 0.7 # Reduzierte Empfindlichkeit für sanfteres Scrollen self.scroll_sensitivity = 0.7 # Reduzierte Empfindlichkeit für sanfteres Scrollen
# Das aktuelle Projekt (Project) aus app_settings
self.project = None
# Das aktuelle ProjectData
self.pdf_project = None
# Theme-Menü initialisieren # Theme-Menü initialisieren
self._setup_theme_menu() self._setup_theme_menu()
@@ -133,7 +140,7 @@ class MainWindow(QMainWindow):
print(f"Projekte-Menü initialisiert mit {len(app_settings.pdf_projects)} Projekten") print(f"Projekte-Menü initialisiert mit {len(app_settings.pdf_projects)} Projekten")
def open_existing_project(self, project: PdfProject): def open_existing_project(self, project: Project):
""" """
Öffnet ein vorhandenes Projekt. Öffnet ein vorhandenes Projekt.
@@ -151,12 +158,12 @@ class MainWindow(QMainWindow):
if project_yaml_path.exists() and project_yaml_path.stat().st_size > 0: if project_yaml_path.exists() and project_yaml_path.stat().st_size > 0:
# Versuche die Projekt-Einstellungen zu laden # Versuche die Projekt-Einstellungen zu laden
self.pdf_project = PdfProjectSettings.readSettings(project_dir=project.project_dir) self.pdf_project = ProjectData.readSettings(project_dir=project.project_dir)
print(f"Projekt-Einstellungen aus {project_yaml_path} geladen!") print(f"Projekt-Einstellungen aus {project_yaml_path} geladen!")
else: else:
# Erstelle Standard-Projekt-Einstellungen wenn Datei leer oder nicht vorhanden # Erstelle Standard-Projekt-Einstellungen wenn Datei leer oder nicht vorhanden
print("project.yaml ist leer oder nicht vorhanden, erstelle Standard-Einstellungen") print("project.yaml ist leer oder nicht vorhanden, erstelle Standard-Einstellungen")
self.pdf_project = PdfProjectSettings() self.pdf_project = ProjectData()
# Speichere die Standard-Einstellungen in die project.yaml # Speichere die Standard-Einstellungen in die project.yaml
self.pdf_project.writeSettings(project_dir=project.project_dir) self.pdf_project.writeSettings(project_dir=project.project_dir)
@@ -169,7 +176,7 @@ class MainWindow(QMainWindow):
print(f"Fehler beim Laden des Projekts '{project.name}': {e}") print(f"Fehler beim Laden des Projekts '{project.name}': {e}")
# Fallback: Erstelle Standard-Einstellungen # Fallback: Erstelle Standard-Einstellungen
try: try:
self.pdf_project = PdfProjectSettings() self.pdf_project = ProjectData()
print("Fallback: Standard-Projekt-Einstellungen erstellt") print("Fallback: Standard-Projekt-Einstellungen erstellt")
# Auch bei Fallback die Nodes laden # Auch bei Fallback die Nodes laden
self._load_nodes_to_tree() self._load_nodes_to_tree()
@@ -789,7 +796,7 @@ class MainWindow(QMainWindow):
new_id = max([p.id for p in app_settings.pdf_projects], default=0) + 1 new_id = max([p.id for p in app_settings.pdf_projects], default=0) + 1
# Erstelle PdfProject-Objekt # Erstelle PdfProject-Objekt
new_project = PdfProject( new_project = Project(
id=new_id, id=new_id,
name=project_data['name'], name=project_data['name'],
project_dir=Path(project_data['project_dir']), project_dir=Path(project_data['project_dir']),
@@ -820,7 +827,7 @@ class MainWindow(QMainWindow):
except Exception as e: except Exception as e:
print(f"Fehler beim Erstellen des neuen Projekts: {e}") print(f"Fehler beim Erstellen des neuen Projekts: {e}")
def _create_project_structure(self, project: PdfProject): def _create_project_structure(self, project: Project):
""" """
Erstellt die Ordnerstruktur und project.yaml-Datei für ein neues Projekt. Erstellt die Ordnerstruktur und project.yaml-Datei für ein neues Projekt.
@@ -842,7 +849,7 @@ class MainWindow(QMainWindow):
# Erstelle Standard-Projekt-Einstellungen und speichere sie # Erstelle Standard-Projekt-Einstellungen und speichere sie
if not project_yaml_path.exists(): if not project_yaml_path.exists():
# Erstelle Standard-PdfProjectSettings # Erstelle Standard-PdfProjectSettings
default_settings = PdfProjectSettings() default_settings = ProjectData()
# Speichere die Standard-Einstellungen in die project.yaml # Speichere die Standard-Einstellungen in die project.yaml
default_settings.writeSettings(project_dir=project_dir) default_settings.writeSettings(project_dir=project_dir)
@@ -1035,9 +1042,120 @@ class MainWindow(QMainWindow):
# Kontextmenü-Aktionen für XslFile # Kontextmenü-Aktionen für XslFile
def _add_xml_file_to_xsl(self, parent_item): def _add_xml_file_to_xsl(self, parent_item):
"""Fügt eine XML-Datei zu einer XSL-Datei hinzu.""" """
Fügt eine XML-Datei zu einer XSL-Datei hinzu.
Args:
parent_item: Das TreeWidgetItem des XslFile-Nodes
"""
print(f"XML-Datei zu XslFile hinzufügen: {parent_item.text(0)}") print(f"XML-Datei zu XslFile hinzufügen: {parent_item.text(0)}")
# TODO: Dialog zum Auswählen der XML-Datei öffnen
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
if not hasattr(self, 'pdf_project') or not self.pdf_project:
QMessageBox.warning(self, "Warnung", "Keine Projekt-Einstellungen geladen.")
return
# Hole die XslFile-Node-ID aus dem TreeWidgetItem
xsl_node_id = parent_item.data(0, Qt.ItemDataRole.UserRole)
if not xsl_node_id:
QMessageBox.warning(self, "Warnung", "Keine Node-ID gefunden für das ausgewählte Element.")
return
# Finde den XslFile-Node in den Projekt-Daten
xsl_node = self._find_node_by_id(self.pdf_project.nodes, xsl_node_id)
if not xsl_node or not isinstance(xsl_node, XslFile):
QMessageBox.warning(self, "Warnung", "XSL-Datei-Node nicht gefunden oder falscher Typ.")
return
# Öffne Datei-Dialog zum Auswählen der XML-Datei
xml_file_path, _ = QFileDialog.getOpenFileName(
self,
"XML-Datei auswählen",
"",
"XML-Dateien (*.xml);;Alle Dateien (*)"
)
if not xml_file_path:
# Benutzer hat abgebrochen
return
xml_file_path = Path(xml_file_path)
# Prüfe ob die Datei existiert
if not xml_file_path.exists():
QMessageBox.critical(self, "Fehler", f"Die ausgewählte XML-Datei existiert nicht:\n{xml_file_path}")
return
# Erstelle xml-Ordner im Projekt-Verzeichnis falls er nicht existiert
xml_dir = Path(self.project.project_dir) / "xml"
xml_dir.mkdir(parents=True, exist_ok=True)
# Bestimme den Ziel-Pfad in xml-Ordner
target_xml_path = xml_dir / xml_file_path.name
# Prüfe ob eine Datei mit gleichem Namen bereits existiert
if target_xml_path.exists():
reply = QMessageBox.question(
self,
"Datei existiert bereits",
f"Eine XML-Datei mit dem Namen '{xml_file_path.name}' existiert bereits im xml-Ordner.\n\n"
"Möchten Sie sie überschreiben?",
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
QMessageBox.StandardButton.No
)
if reply != QMessageBox.StandardButton.Yes:
return
# Kopiere die XML-Datei in den xml-Ordner
shutil.copy2(xml_file_path, target_xml_path)
print(f"XML-Datei kopiert: {xml_file_path} -> {target_xml_path}")
# Erstelle relatives Path zur XML-Datei (relativ zum xml-Ordner)
relative_xml_path = Path("xml") / xml_file_path.name
# Prüfe ob diese XML-Datei bereits in der XslFile-Node vorhanden ist
existing_xml = None
for xml_file in xsl_node.xmls:
if xml_file.xml == relative_xml_path:
existing_xml = xml_file
break
if existing_xml:
QMessageBox.information(
self,
"XML-Datei bereits vorhanden",
f"Die XML-Datei '{xml_file_path.name}' ist bereits in dieser XSL-Datei enthalten."
)
return
# Erstelle neues XmlFile-Objekt und füge es zur XslFile-Node hinzu
new_xml_file = XmlFile(xml=relative_xml_path)
xsl_node.xmls.append(new_xml_file)
print(f"XML-Datei '{xml_file_path.name}' zu XslFile-Node '{xsl_node.bez}' hinzugefügt")
# Speichere die aktualisierten Projekt-Einstellungen
self._save_project_settings()
# Aktualisiere das TreeWidget
self._load_nodes_to_tree()
QMessageBox.information(
self,
"Erfolg",
f"XML-Datei '{xml_file_path.name}' wurde erfolgreich hinzugefügt und in den xml-Ordner kopiert."
)
except Exception as e:
error_msg = f"Fehler beim Hinzufügen der XML-Datei: {str(e)}"
print(error_msg)
QMessageBox.critical(self, "Fehler", error_msg)
def _edit_xsl_file(self, item): def _edit_xsl_file(self, item):
"""Bearbeitet eine XSL-Datei.""" """Bearbeitet eine XSL-Datei."""
@@ -1113,21 +1231,6 @@ class MainWindow(QMainWindow):
print(f"Fehler beim Laden aus FN2: {e}") print(f"Fehler beim Laden aus FN2: {e}")
QMessageBox.critical(self, "Fehler", f"Fehler beim Laden aus FN2:\n{str(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): def _get_database_config(self, db_id):
""" """
Holt die Datenbank-Konfiguration anhand der ID. Holt die Datenbank-Konfiguration anhand der ID.