Die Drag&Drop-Funktionalität für XML-Dateien
This commit is contained in:
+12
-6
@@ -1,8 +1,14 @@
|
||||
# Projekt allgemeines
|
||||
- In diesem Projekt wirt uv Packetmanager verwendet.
|
||||
# agents.md
|
||||
|
||||
Entwicklung mit Python und PySide6
|
||||
|
||||
## Richtlinien
|
||||
|
||||
### Allgemeines zum Projekt
|
||||
- In diesem Projekt wird der uv Packetmanager verwendet.
|
||||
|
||||
## PySide6-GUI
|
||||
- Beim Erstellen neuer Dialoge sollte stets eine passende UI-Datei erstellt werden.
|
||||
- Der Entwickler soll den neuen Dialog später über die UI-Datei gestalten können.
|
||||
- Die UI-Datei wird in Visual Studio Code durch eine Erweiterung automatisch als .py-Datei generiert.
|
||||
- Die automatisch generierte .py-Datei muss in den Code eingebunden und genutzt werden.
|
||||
- Beim Erstellen neuer Dialoge sollte immer eine passende UI-Datei erstellt werden.
|
||||
- Der Entwickler sollte später in der Lage sein, den neuen Dialog über die UI-Datei zu gestalten.
|
||||
- Aus der UI-Datei wird in Visual Studio Code über eine Erweiterung automatisch eine .py-Datei erzeugt.
|
||||
- Die automatisch generierte .py-Datei muss in den Code eingebunden und verwendet werden.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# agents.md
|
||||
|
||||
Entwickeln mit Python und PySide6
|
||||
Entwicklung mit Python und PySide6
|
||||
|
||||
## Richtlinien
|
||||
|
||||
### Projekt allgemeines
|
||||
- In diesem Projekt wirt uv Packetmanager verwendet.
|
||||
### Allgemeines zum Projekt
|
||||
- In diesem Projekt wird der uv Packetmanager verwendet.
|
||||
|
||||
### PySide6-GUI
|
||||
- Beim Erstellen neuer Dialoge sollte stets eine passende UI-Datei erstellt werden.
|
||||
- Der Entwickler soll den neuen Dialog später über die UI-Datei gestalten können.
|
||||
- Die UI-Datei wird in Visual Studio Code durch eine Erweiterung automatisch als .py-Datei generiert.
|
||||
- Die automatisch generierte .py-Datei muss in den Code eingebunden und genutzt werden.
|
||||
## PySide6-GUI
|
||||
- Beim Erstellen neuer Dialoge sollte immer eine passende UI-Datei erstellt werden.
|
||||
- Der Entwickler sollte später in der Lage sein, den neuen Dialog über die UI-Datei zu gestalten.
|
||||
- Aus der UI-Datei wird in Visual Studio Code über eine Erweiterung automatisch eine .py-Datei erzeugt.
|
||||
- Die automatisch generierte .py-Datei muss in den Code eingebunden und verwendet werden.
|
||||
+256
-2
@@ -4,8 +4,8 @@ import time
|
||||
import polars as pl
|
||||
import shutil
|
||||
|
||||
from PySide6.QtCore import Qt, QSize
|
||||
from PySide6.QtGui import QCursor, QPixmap, QPainter, QAction, QIcon
|
||||
from PySide6.QtCore import Qt, QSize, QUrl
|
||||
from PySide6.QtGui import QCursor, QPixmap, QPainter, QAction, QIcon, QDragEnterEvent, QDropEvent
|
||||
from PySide6.QtWidgets import QLabel, QMainWindow, QApplication, QStyleFactory, QMenu, QTreeWidgetItem, QMessageBox, QFileDialog
|
||||
from PySide6.QtPdf import QPdfDocument
|
||||
|
||||
@@ -14,6 +14,7 @@ from ui.AppSettings import AppSettingsDlg
|
||||
from ui.PdfProject import PdfProjectDlg
|
||||
from ui.TreeNodeEditDialog import TreeNodeEditDialog
|
||||
from ui.XslFileEditDialog import XslFileEditDialog
|
||||
from ui.XmlToXslAssignDialog import XmlToXslAssignDialog
|
||||
from conf import app_settings, Project, ProjectData, TreeNode, XslFile, XmlFile
|
||||
from pathlib import Path
|
||||
|
||||
@@ -87,6 +88,9 @@ class MainWindow(QMainWindow):
|
||||
|
||||
# TreeWidget Styling für größeren vertikalen Abstand
|
||||
self._setup_tree_widget_styling()
|
||||
|
||||
# Drag&Drop für TreeWidget aktivieren
|
||||
self._setup_drag_drop()
|
||||
|
||||
def _setup_theme_menu(self):
|
||||
"""Initialisiert das Theme-Menü mit verfügbaren Themes."""
|
||||
@@ -1604,6 +1608,256 @@ class MainWindow(QMainWindow):
|
||||
print(f"Fehler beim Speichern der Projekt-Einstellungen: {e}")
|
||||
raise
|
||||
|
||||
def _setup_drag_drop(self):
|
||||
"""Aktiviert Drag&Drop für das TreeWidget."""
|
||||
try:
|
||||
# Aktiviere Drag&Drop für das TreeWidget
|
||||
self.ui.treeWidget.setAcceptDrops(True)
|
||||
self.ui.treeWidget.setDragDropMode(self.ui.treeWidget.DragDropMode.DropOnly)
|
||||
|
||||
# Überschreibe die Drag&Drop-Events
|
||||
self.ui.treeWidget.dragEnterEvent = self.tree_drag_enter_event
|
||||
self.ui.treeWidget.dragMoveEvent = self.tree_drag_move_event
|
||||
self.ui.treeWidget.dropEvent = self.tree_drop_event
|
||||
|
||||
print("Drag&Drop für TreeWidget aktiviert")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Aktivieren von Drag&Drop: {e}")
|
||||
|
||||
def tree_drag_enter_event(self, event: QDragEnterEvent):
|
||||
"""
|
||||
Wird ausgeführt, wenn ein Drag-Vorgang über das TreeWidget beginnt.
|
||||
|
||||
Args:
|
||||
event: Das Drag-Enter-Event
|
||||
"""
|
||||
try:
|
||||
# Prüfe ob URLs (Dateien) gedraggt werden
|
||||
if event.mimeData().hasUrls():
|
||||
urls = event.mimeData().urls()
|
||||
|
||||
# Prüfe ob mindestens eine XML-Datei dabei ist
|
||||
xml_files = [url.toLocalFile() for url in urls
|
||||
if url.toLocalFile().lower().endswith('.xml')]
|
||||
|
||||
if xml_files:
|
||||
event.acceptProposedAction()
|
||||
print(f"Drag-Enter akzeptiert: {len(xml_files)} XML-Dateien")
|
||||
else:
|
||||
event.ignore()
|
||||
print("Drag-Enter ignoriert: Keine XML-Dateien")
|
||||
else:
|
||||
event.ignore()
|
||||
print("Drag-Enter ignoriert: Keine URLs")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler in tree_drag_enter_event: {e}")
|
||||
event.ignore()
|
||||
|
||||
def tree_drag_move_event(self, event):
|
||||
"""
|
||||
Wird ausgeführt, wenn ein Drag-Vorgang über das TreeWidget bewegt wird.
|
||||
|
||||
Args:
|
||||
event: Das Drag-Move-Event
|
||||
"""
|
||||
try:
|
||||
# Prüfe ob URLs (Dateien) gedraggt werden
|
||||
if event.mimeData().hasUrls():
|
||||
urls = event.mimeData().urls()
|
||||
|
||||
# Prüfe ob mindestens eine XML-Datei dabei ist
|
||||
xml_files = [url.toLocalFile() for url in urls
|
||||
if url.toLocalFile().lower().endswith('.xml')]
|
||||
|
||||
if xml_files:
|
||||
event.acceptProposedAction()
|
||||
else:
|
||||
event.ignore()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler in tree_drag_move_event: {e}")
|
||||
event.ignore()
|
||||
|
||||
def tree_drop_event(self, event: QDropEvent):
|
||||
"""
|
||||
Wird ausgeführt, wenn Dateien auf das TreeWidget gedroppt werden.
|
||||
|
||||
Args:
|
||||
event: Das Drop-Event
|
||||
"""
|
||||
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.")
|
||||
event.ignore()
|
||||
return
|
||||
|
||||
if not hasattr(self, 'pdf_project') or not self.pdf_project:
|
||||
QMessageBox.warning(self, "Warnung", "Keine Projekt-Einstellungen geladen.")
|
||||
event.ignore()
|
||||
return
|
||||
|
||||
# Hole die URLs aus dem Drop-Event
|
||||
if not event.mimeData().hasUrls():
|
||||
event.ignore()
|
||||
return
|
||||
|
||||
urls = event.mimeData().urls()
|
||||
xml_files = []
|
||||
|
||||
# Sammle alle XML-Dateien
|
||||
for url in urls:
|
||||
file_path = url.toLocalFile()
|
||||
if file_path.lower().endswith('.xml'):
|
||||
xml_files.append(Path(file_path))
|
||||
|
||||
if not xml_files:
|
||||
QMessageBox.information(self, "Information", "Keine XML-Dateien zum Hinzufügen gefunden.")
|
||||
event.ignore()
|
||||
return
|
||||
|
||||
print(f"Drop-Event: {len(xml_files)} XML-Dateien erkannt")
|
||||
|
||||
# Verarbeite jede XML-Datei einzeln
|
||||
for xml_file_path in xml_files:
|
||||
self._handle_xml_file_drop(xml_file_path)
|
||||
|
||||
event.acceptProposedAction()
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Fehler beim Verarbeiten des Drop-Events: {str(e)}"
|
||||
print(error_msg)
|
||||
QMessageBox.critical(self, "Fehler", error_msg)
|
||||
event.ignore()
|
||||
|
||||
def _handle_xml_file_drop(self, xml_file_path: Path):
|
||||
"""
|
||||
Verarbeitet eine einzelne XML-Datei, die per Drag&Drop hinzugefügt wurde.
|
||||
|
||||
Args:
|
||||
xml_file_path: Pfad zur XML-Datei
|
||||
"""
|
||||
try:
|
||||
print(f"Verarbeite XML-Datei: {xml_file_path}")
|
||||
|
||||
# Prüfe ob die Datei existiert
|
||||
if not xml_file_path.exists():
|
||||
QMessageBox.critical(self, "Fehler", f"Die XML-Datei existiert nicht:\n{xml_file_path}")
|
||||
return
|
||||
|
||||
# Öffne den Dialog zur Zuordnung zu XSL-Knoten
|
||||
dialog = XmlToXslAssignDialog(
|
||||
parent=self,
|
||||
xml_file_path=xml_file_path,
|
||||
project_nodes=self.pdf_project.nodes
|
||||
)
|
||||
|
||||
if dialog.exec() == XmlToXslAssignDialog.DialogCode.Accepted:
|
||||
# Hole die ausgewählten XSL-Knoten
|
||||
selected_xsl_nodes = dialog.get_selected_xsl_nodes()
|
||||
|
||||
if selected_xsl_nodes:
|
||||
# Verarbeite die Zuordnung
|
||||
self._assign_xml_to_xsl_nodes(xml_file_path, selected_xsl_nodes)
|
||||
else:
|
||||
print("Keine XSL-Knoten ausgewählt")
|
||||
else:
|
||||
print("Dialog abgebrochen")
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Fehler beim Verarbeiten der XML-Datei '{xml_file_path}': {str(e)}"
|
||||
print(error_msg)
|
||||
QMessageBox.critical(self, "Fehler", error_msg)
|
||||
|
||||
def _assign_xml_to_xsl_nodes(self, xml_file_path: Path, selected_xsl_nodes: list):
|
||||
"""
|
||||
Ordnet eine XML-Datei den ausgewählten XSL-Knoten zu.
|
||||
|
||||
Args:
|
||||
xml_file_path: Pfad zur XML-Datei
|
||||
selected_xsl_nodes: Liste der ausgewählten XSL-Knoten
|
||||
"""
|
||||
try:
|
||||
print(f"Ordne XML-Datei '{xml_file_path.name}' zu {len(selected_xsl_nodes)} XSL-Knoten zu")
|
||||
|
||||
# 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
|
||||
copy_file = True
|
||||
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:
|
||||
copy_file = False
|
||||
|
||||
# Kopiere die XML-Datei in den xml-Ordner (falls gewünscht)
|
||||
if copy_file:
|
||||
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
|
||||
|
||||
# Füge die XML-Datei zu allen ausgewählten XSL-Knoten hinzu
|
||||
added_count = 0
|
||||
for xsl_node in selected_xsl_nodes:
|
||||
# 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 not existing_xml:
|
||||
# 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)
|
||||
added_count += 1
|
||||
print(f"XML-Datei '{xml_file_path.name}' zu XslFile-Node '{xsl_node.bez}' hinzugefügt")
|
||||
else:
|
||||
print(f"XML-Datei '{xml_file_path.name}' bereits in XslFile-Node '{xsl_node.bez}' vorhanden")
|
||||
|
||||
if added_count > 0:
|
||||
# Speichere die aktualisierten Projekt-Einstellungen
|
||||
self._save_project_settings()
|
||||
|
||||
# Aktualisiere das TreeWidget
|
||||
self._load_nodes_to_tree()
|
||||
|
||||
# Zeige Erfolgsmeldung
|
||||
QMessageBox.information(
|
||||
self,
|
||||
"Erfolg",
|
||||
f"XML-Datei '{xml_file_path.name}' wurde erfolgreich zu {added_count} XSL-Knoten hinzugefügt."
|
||||
)
|
||||
else:
|
||||
QMessageBox.information(
|
||||
self,
|
||||
"Information",
|
||||
f"XML-Datei '{xml_file_path.name}' war bereits in allen ausgewählten XSL-Knoten vorhanden."
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Fehler beim Zuordnen der XML-Datei: {str(e)}"
|
||||
print(error_msg)
|
||||
QMessageBox.critical(self, "Fehler", error_msg)
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""Wird beim Schließen der Anwendung aufgerufen."""
|
||||
# PDF-Dokumente schließen ist bei QtPdf automatisch durch Garbage Collection
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
from PySide6.QtWidgets import QDialog, QTreeWidgetItem, QCheckBox, QMessageBox
|
||||
from PySide6.QtCore import Qt
|
||||
from pathlib import Path
|
||||
|
||||
from ui.XmlToXslAssignDialog_ui import Ui_XmlToXslAssignDialog
|
||||
from conf import TreeNode, XslFile, XmlFile
|
||||
|
||||
|
||||
class XmlToXslAssignDialog(QDialog):
|
||||
"""Dialog zur Zuordnung einer XML-Datei zu XSL-Knoten."""
|
||||
|
||||
def __init__(self, parent=None, xml_file_path=None, project_nodes=None):
|
||||
"""
|
||||
Initialisiert den Dialog.
|
||||
|
||||
Args:
|
||||
parent: Übergeordnetes Widget
|
||||
xml_file_path: Pfad zur XML-Datei
|
||||
project_nodes: Liste der Projekt-Knoten
|
||||
"""
|
||||
super().__init__(parent)
|
||||
|
||||
# UI einrichten
|
||||
self.ui = Ui_XmlToXslAssignDialog()
|
||||
self.ui.setupUi(self)
|
||||
|
||||
# Parameter speichern
|
||||
self.xml_file_path = Path(xml_file_path) if xml_file_path else None
|
||||
self.project_nodes = project_nodes or []
|
||||
|
||||
# Dictionary zum Speichern der Checkbox-Referenzen
|
||||
self.xsl_checkboxes = {} # {xsl_node_id: checkbox}
|
||||
|
||||
# Signale verbinden
|
||||
self.ui.selectAllButton.clicked.connect(self.select_all)
|
||||
self.ui.deselectAllButton.clicked.connect(self.deselect_all)
|
||||
|
||||
# Baum konfigurieren
|
||||
self._setup_tree()
|
||||
|
||||
# Daten laden
|
||||
self._load_data()
|
||||
|
||||
def _setup_tree(self):
|
||||
"""Konfiguriert das TreeWidget."""
|
||||
# Spaltenbreiten setzen
|
||||
self.ui.xslNodesTree.setColumnWidth(0, 300) # XSL-Knoten
|
||||
self.ui.xslNodesTree.setColumnWidth(1, 200) # Details
|
||||
self.ui.xslNodesTree.setColumnWidth(2, 100) # Auswählen
|
||||
|
||||
# Header-Eigenschaften
|
||||
self.ui.xslNodesTree.header().setStretchLastSection(False)
|
||||
|
||||
def _load_data(self):
|
||||
"""Lädt die Daten in den Dialog."""
|
||||
# XML-Datei-Label setzen
|
||||
if self.xml_file_path:
|
||||
self.ui.xmlFileLabel.setText(f"XML-Datei: {self.xml_file_path.name}")
|
||||
|
||||
# Projekt-Knoten in Baum laden
|
||||
self._load_project_nodes()
|
||||
|
||||
def _load_project_nodes(self):
|
||||
"""Lädt die Projekt-Knoten in das TreeWidget (ohne XML-Knoten)."""
|
||||
if not self.project_nodes:
|
||||
return
|
||||
|
||||
# TreeWidget leeren
|
||||
self.ui.xslNodesTree.clear()
|
||||
self.xsl_checkboxes.clear()
|
||||
|
||||
# Alle Root-Nodes laden
|
||||
for node in self.project_nodes:
|
||||
tree_item = self._create_tree_item_from_node(node)
|
||||
if tree_item: # Nur hinzufügen wenn Item erstellt wurde
|
||||
self.ui.xslNodesTree.addTopLevelItem(tree_item)
|
||||
|
||||
# Baum expandieren
|
||||
self.ui.xslNodesTree.expandAll()
|
||||
|
||||
def _create_tree_item_from_node(self, node):
|
||||
"""
|
||||
Erstellt ein QTreeWidgetItem aus einem TreeNode oder XslFile.
|
||||
XML-Knoten werden ausgeschlossen.
|
||||
|
||||
Args:
|
||||
node: TreeNode oder XslFile Objekt
|
||||
|
||||
Returns:
|
||||
QTreeWidgetItem: Das erstellte Tree-Item oder None wenn ausgeschlossen
|
||||
"""
|
||||
try:
|
||||
# Erstelle Tree-Item
|
||||
item = QTreeWidgetItem()
|
||||
|
||||
# Setze die Bezeichnung in Spalte 0
|
||||
bez_text = str(node.bez) if node.bez else ""
|
||||
item.setText(0, bez_text)
|
||||
|
||||
# Speichere das komplette Node-Objekt
|
||||
item.setData(0, Qt.ItemDataRole.UserRole, node)
|
||||
|
||||
if isinstance(node, TreeNode):
|
||||
# TreeNode: Zeige Anzahl der Knoten
|
||||
child_count = len(node.children) if node.children else 0
|
||||
item.setText(1, f"{child_count} Knoten")
|
||||
|
||||
# Lade Knoten rekursiv (nur TreeNode und XslFile, keine XML)
|
||||
if node.children:
|
||||
for child in node.children:
|
||||
# Nur TreeNode und XslFile hinzufügen, keine XmlFile
|
||||
if isinstance(child, (TreeNode, XslFile)):
|
||||
child_item = self._create_tree_item_from_node(child)
|
||||
if child_item:
|
||||
item.addChild(child_item)
|
||||
|
||||
elif isinstance(node, XslFile):
|
||||
# XslFile: Zeige XSL-Datei-Pfad und füge Checkbox hinzu
|
||||
item.setText(1, str(node.xsl_file))
|
||||
|
||||
# Aktiviere Checkbox für dieses Item in Spalte 2
|
||||
item.setFlags(item.flags() | Qt.ItemFlag.ItemIsUserCheckable)
|
||||
item.setCheckState(2, Qt.CheckState.Unchecked)
|
||||
|
||||
# Speichere Item-Referenz für XSL-Knoten
|
||||
self.xsl_checkboxes[id(node)] = item
|
||||
|
||||
# Keine Knoten für XslFile hinzufügen (XML-Dateien werden ausgeschlossen)
|
||||
|
||||
return item
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Erstellen des Tree-Items: {e}")
|
||||
return None
|
||||
|
||||
def select_all(self):
|
||||
"""Wählt alle XSL-Knoten aus."""
|
||||
for item in self.xsl_checkboxes.values():
|
||||
item.setCheckState(2, Qt.CheckState.Checked)
|
||||
|
||||
def deselect_all(self):
|
||||
"""Wählt alle XSL-Knoten ab."""
|
||||
for item in self.xsl_checkboxes.values():
|
||||
item.setCheckState(2, Qt.CheckState.Unchecked)
|
||||
|
||||
def get_selected_xsl_nodes(self):
|
||||
"""
|
||||
Gibt die ausgewählten XSL-Knoten zurück.
|
||||
|
||||
Returns:
|
||||
list[XslFile]: Liste der ausgewählten XSL-Knoten
|
||||
"""
|
||||
selected_nodes = []
|
||||
|
||||
try:
|
||||
# Durchlaufe alle XSL-Items
|
||||
for node_id, item in self.xsl_checkboxes.items():
|
||||
if item.checkState(2) == Qt.CheckState.Checked:
|
||||
# Finde den entsprechenden XSL-Knoten
|
||||
xsl_node = self._find_xsl_node_by_id(node_id)
|
||||
if xsl_node:
|
||||
selected_nodes.append(xsl_node)
|
||||
|
||||
return selected_nodes
|
||||
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Sammeln der ausgewählten XSL-Knoten: {e}")
|
||||
return []
|
||||
|
||||
def _find_xsl_node_by_id(self, node_id):
|
||||
"""
|
||||
Findet einen XSL-Knoten anhand seiner ID.
|
||||
|
||||
Args:
|
||||
node_id: Die ID des Knotens (Python id())
|
||||
|
||||
Returns:
|
||||
XslFile: Der gefundene XSL-Knoten oder None
|
||||
"""
|
||||
return self._find_xsl_node_recursive(self.project_nodes, node_id)
|
||||
|
||||
def _find_xsl_node_recursive(self, nodes, target_id):
|
||||
"""
|
||||
Sucht rekursiv nach einem XSL-Knoten mit der angegebenen ID.
|
||||
|
||||
Args:
|
||||
nodes: Liste der Nodes zum Durchsuchen
|
||||
target_id: Die zu suchende ID
|
||||
|
||||
Returns:
|
||||
XslFile: Der gefundene XSL-Knoten oder None
|
||||
"""
|
||||
for node in nodes:
|
||||
if isinstance(node, XslFile) and id(node) == target_id:
|
||||
return node
|
||||
|
||||
# Rekursiv in Knoten suchen (nur bei TreeNode)
|
||||
if isinstance(node, TreeNode) and node.children:
|
||||
found = self._find_xsl_node_recursive(node.children, target_id)
|
||||
if found:
|
||||
return found
|
||||
|
||||
return None
|
||||
|
||||
def get_xml_file_path(self):
|
||||
"""
|
||||
Gibt den Pfad zur XML-Datei zurück.
|
||||
|
||||
Returns:
|
||||
Path: Pfad zur XML-Datei
|
||||
"""
|
||||
return self.xml_file_path
|
||||
|
||||
def accept(self):
|
||||
"""Überschreibt accept() um Validierung durchzuführen."""
|
||||
selected_nodes = self.get_selected_xsl_nodes()
|
||||
|
||||
if not selected_nodes:
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"Warnung",
|
||||
"Bitte wählen Sie mindestens einen XSL-Knoten aus."
|
||||
)
|
||||
return
|
||||
|
||||
super().accept()
|
||||
@@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>XmlToXslAssignDialog</class>
|
||||
<widget class="QDialog" name="XmlToXslAssignDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>700</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>XML-Datei zu XSL-Knoten zuordnen</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="infoLabel">
|
||||
<property name="text">
|
||||
<string>Wählen Sie die XSL-Knoten aus, denen die XML-Datei zugeordnet werden soll:</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="xmlFileLabel">
|
||||
<property name="styleSheet">
|
||||
<string>font-weight: bold; color: #0066cc;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>XML-Datei: [wird zur Laufzeit gesetzt]</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="xslNodesTree">
|
||||
<property name="headerHidden">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerVisible">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>XSL-Knoten</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Details</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Auswählen</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="buttonLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="selectAllButton">
|
||||
<property name="text">
|
||||
<string>Alle auswählen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deselectAllButton">
|
||||
<property name="text">
|
||||
<string>Alle abwählen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>XmlToXslAssignDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>XmlToXslAssignDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
@@ -0,0 +1,99 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'XmlToXslAssignDialog.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.9.1
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QFont, QFontDatabase, QGradient, QIcon,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QAbstractButton, QApplication, QDialog, QDialogButtonBox,
|
||||
QHBoxLayout, QHeaderView, QLabel, QPushButton,
|
||||
QSizePolicy, QSpacerItem, QTreeWidget, QTreeWidgetItem,
|
||||
QVBoxLayout, QWidget)
|
||||
|
||||
class Ui_XmlToXslAssignDialog(object):
|
||||
def setupUi(self, XmlToXslAssignDialog):
|
||||
if not XmlToXslAssignDialog.objectName():
|
||||
XmlToXslAssignDialog.setObjectName(u"XmlToXslAssignDialog")
|
||||
XmlToXslAssignDialog.resize(700, 500)
|
||||
XmlToXslAssignDialog.setModal(True)
|
||||
self.verticalLayout = QVBoxLayout(XmlToXslAssignDialog)
|
||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||
self.infoLabel = QLabel(XmlToXslAssignDialog)
|
||||
self.infoLabel.setObjectName(u"infoLabel")
|
||||
self.infoLabel.setWordWrap(True)
|
||||
|
||||
self.verticalLayout.addWidget(self.infoLabel)
|
||||
|
||||
self.xmlFileLabel = QLabel(XmlToXslAssignDialog)
|
||||
self.xmlFileLabel.setObjectName(u"xmlFileLabel")
|
||||
self.xmlFileLabel.setWordWrap(True)
|
||||
|
||||
self.verticalLayout.addWidget(self.xmlFileLabel)
|
||||
|
||||
self.xslNodesTree = QTreeWidget(XmlToXslAssignDialog)
|
||||
self.xslNodesTree.setObjectName(u"xslNodesTree")
|
||||
self.xslNodesTree.setHeaderHidden(False)
|
||||
self.xslNodesTree.setColumnCount(3)
|
||||
self.xslNodesTree.setAlternatingRowColors(True)
|
||||
self.xslNodesTree.header().setVisible(True)
|
||||
|
||||
self.verticalLayout.addWidget(self.xslNodesTree)
|
||||
|
||||
self.buttonLayout = QHBoxLayout()
|
||||
self.buttonLayout.setObjectName(u"buttonLayout")
|
||||
self.selectAllButton = QPushButton(XmlToXslAssignDialog)
|
||||
self.selectAllButton.setObjectName(u"selectAllButton")
|
||||
|
||||
self.buttonLayout.addWidget(self.selectAllButton)
|
||||
|
||||
self.deselectAllButton = QPushButton(XmlToXslAssignDialog)
|
||||
self.deselectAllButton.setObjectName(u"deselectAllButton")
|
||||
|
||||
self.buttonLayout.addWidget(self.deselectAllButton)
|
||||
|
||||
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
||||
|
||||
self.buttonLayout.addItem(self.horizontalSpacer)
|
||||
|
||||
|
||||
self.verticalLayout.addLayout(self.buttonLayout)
|
||||
|
||||
self.buttonBox = QDialogButtonBox(XmlToXslAssignDialog)
|
||||
self.buttonBox.setObjectName(u"buttonBox")
|
||||
self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QDialogButtonBox.StandardButton.Cancel|QDialogButtonBox.StandardButton.Ok)
|
||||
self.buttonBox.setCenterButtons(True)
|
||||
|
||||
self.verticalLayout.addWidget(self.buttonBox)
|
||||
|
||||
|
||||
self.retranslateUi(XmlToXslAssignDialog)
|
||||
self.buttonBox.accepted.connect(XmlToXslAssignDialog.accept)
|
||||
self.buttonBox.rejected.connect(XmlToXslAssignDialog.reject)
|
||||
|
||||
QMetaObject.connectSlotsByName(XmlToXslAssignDialog)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, XmlToXslAssignDialog):
|
||||
XmlToXslAssignDialog.setWindowTitle(QCoreApplication.translate("XmlToXslAssignDialog", u"XML-Datei zu XSL-Knoten zuordnen", None))
|
||||
self.infoLabel.setText(QCoreApplication.translate("XmlToXslAssignDialog", u"W\u00e4hlen Sie die XSL-Knoten aus, denen die XML-Datei zugeordnet werden soll:", None))
|
||||
self.xmlFileLabel.setStyleSheet(QCoreApplication.translate("XmlToXslAssignDialog", u"font-weight: bold; color: #0066cc;", None))
|
||||
self.xmlFileLabel.setText(QCoreApplication.translate("XmlToXslAssignDialog", u"XML-Datei: [wird zur Laufzeit gesetzt]", None))
|
||||
___qtreewidgetitem = self.xslNodesTree.headerItem()
|
||||
___qtreewidgetitem.setText(2, QCoreApplication.translate("XmlToXslAssignDialog", u"Ausw\u00e4hlen", None));
|
||||
___qtreewidgetitem.setText(1, QCoreApplication.translate("XmlToXslAssignDialog", u"Details", None));
|
||||
___qtreewidgetitem.setText(0, QCoreApplication.translate("XmlToXslAssignDialog", u"XSL-Knoten", None));
|
||||
self.selectAllButton.setText(QCoreApplication.translate("XmlToXslAssignDialog", u"Alle ausw\u00e4hlen", None))
|
||||
self.deselectAllButton.setText(QCoreApplication.translate("XmlToXslAssignDialog", u"Alle abw\u00e4hlen", None))
|
||||
# retranslateUi
|
||||
|
||||
Reference in New Issue
Block a user