Die Drag&Drop-Funktionalität für XML-Dateien
This commit is contained in:
@@ -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()
|
||||
Reference in New Issue
Block a user