TreeNode-Kontextmenü: Transformations-Aktionen für alle untergeordneten XML-Dateien
Neue Funktionalität: - TreeNode-Kontextmenü hat jetzt "Alle XML-Dateien transformieren" Aktionen - Beide Aktionen (normal und force) transformieren rekursiv alle untergeordneten XML-Dateien - Menüpunkte sind nur aktiv, wenn mindestens eine XML-Datei vorhanden ist Implementierung: - _has_xml_files_recursive(): Prüft rekursiv auf vorhandene XML-Dateien - _collect_all_xsl_xml_pairs_recursive(): Sammelt alle XSL/XML-Paare im Teilbaum - _transform_tree_node(): Transformiert alle gefundenen XML-Dateien - Kontextmenü erweitert mit intelligenter Aktivierung/Deaktivierung 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -912,6 +912,24 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
menu.addSeparator()
|
menu.addSeparator()
|
||||||
|
|
||||||
|
# Transformations-Aktionen (nur aktiv wenn XML-Dateien vorhanden)
|
||||||
|
tree_node_obj = item.data(0, Qt.ItemDataRole.UserRole) if item else None
|
||||||
|
has_xml_files = tree_node_obj and self._has_xml_files_recursive(tree_node_obj)
|
||||||
|
|
||||||
|
action_transform = QAction("Alle XML-Dateien transformieren", self)
|
||||||
|
action_transform.setIcon(QIcon(QIcon.fromTheme("system-run")))
|
||||||
|
action_transform.triggered.connect(lambda: self._transform_tree_node(item))
|
||||||
|
action_transform.setEnabled(has_xml_files)
|
||||||
|
menu.addAction(action_transform)
|
||||||
|
|
||||||
|
action_transform_force = QAction("Alle XML-Dateien neu transformieren (force)", self)
|
||||||
|
action_transform_force.setIcon(QIcon(QIcon.fromTheme("view-refresh")))
|
||||||
|
action_transform_force.triggered.connect(lambda: self._transform_tree_node(item, force=True))
|
||||||
|
action_transform_force.setEnabled(has_xml_files)
|
||||||
|
menu.addAction(action_transform_force)
|
||||||
|
|
||||||
|
menu.addSeparator()
|
||||||
|
|
||||||
action_edit = QAction("Bearbeiten", self)
|
action_edit = QAction("Bearbeiten", self)
|
||||||
action_edit.setIcon(QIcon(QIcon.fromTheme(QIcon.ThemeIcon.DocumentProperties)))
|
action_edit.setIcon(QIcon(QIcon.fromTheme(QIcon.ThemeIcon.DocumentProperties)))
|
||||||
action_edit.triggered.connect(lambda: self._edit_tree_node(item))
|
action_edit.triggered.connect(lambda: self._edit_tree_node(item))
|
||||||
@@ -3070,6 +3088,112 @@ class MainWindow(QMainWindow):
|
|||||||
logger.error(f"Fehler beim Transformieren der XSL-Datei: {e}")
|
logger.error(f"Fehler beim Transformieren der XSL-Datei: {e}")
|
||||||
QMessageBox.critical(self, "Fehler", f"Fehler beim Transformieren: {str(e)}")
|
QMessageBox.critical(self, "Fehler", f"Fehler beim Transformieren: {str(e)}")
|
||||||
|
|
||||||
|
def _has_xml_files_recursive(self, node: TreeNode) -> bool:
|
||||||
|
"""
|
||||||
|
Prüft rekursiv, ob unter einem TreeNode mindestens eine XML-Datei vorhanden ist.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
node: Der TreeNode
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True wenn mindestens eine XML-Datei gefunden wurde
|
||||||
|
"""
|
||||||
|
if not hasattr(node, 'children') or not node.children:
|
||||||
|
return False
|
||||||
|
|
||||||
|
for child in node.children:
|
||||||
|
if isinstance(child, XslFile):
|
||||||
|
if child.xmls:
|
||||||
|
return True
|
||||||
|
elif isinstance(child, TreeNode):
|
||||||
|
if self._has_xml_files_recursive(child):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _collect_all_xsl_xml_pairs_recursive(
|
||||||
|
self, tree_node: TreeNode, tree_item: QTreeWidgetItem
|
||||||
|
) -> list[tuple[XslFile, XmlFile, QTreeWidgetItem]]:
|
||||||
|
"""
|
||||||
|
Sammelt rekursiv alle (XslFile, XmlFile, XslFileItem) Tupel unter einem TreeNode.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tree_node: Der TreeNode
|
||||||
|
tree_item: Das TreeWidgetItem des TreeNode
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list: Liste von (XslFile, XmlFile, XslFileItem) Tupeln
|
||||||
|
"""
|
||||||
|
pairs = []
|
||||||
|
|
||||||
|
if not hasattr(tree_node, 'children') or not tree_node.children:
|
||||||
|
return pairs
|
||||||
|
|
||||||
|
# Durchlaufe alle Kinder des TreeNode
|
||||||
|
for i in range(tree_item.childCount()):
|
||||||
|
child_item = tree_item.child(i)
|
||||||
|
child_node = child_item.data(0, Qt.ItemDataRole.UserRole)
|
||||||
|
|
||||||
|
if isinstance(child_node, XslFile):
|
||||||
|
# XslFile gefunden - sammle alle XML-Dateien
|
||||||
|
for xml_file_obj in child_node.xmls:
|
||||||
|
pairs.append((child_node, xml_file_obj, child_item))
|
||||||
|
|
||||||
|
elif isinstance(child_node, TreeNode):
|
||||||
|
# Rekursiv in Unterknoten suchen
|
||||||
|
pairs.extend(self._collect_all_xsl_xml_pairs_recursive(child_node, child_item))
|
||||||
|
|
||||||
|
return pairs
|
||||||
|
|
||||||
|
def _transform_tree_node(self, item: QTreeWidgetItem, force: bool = False):
|
||||||
|
"""
|
||||||
|
Transformiert alle XML-Dateien unter einem TreeNode (rekursiv).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item: Das TreeWidgetItem des TreeNode
|
||||||
|
force: Wenn True, wird Transformation auch bei aktuellem Output durchgeführt
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Hole TreeNode-Objekt
|
||||||
|
tree_node_obj = item.data(0, Qt.ItemDataRole.UserRole)
|
||||||
|
if not isinstance(tree_node_obj, TreeNode):
|
||||||
|
logger.error(f"Item ist kein TreeNode: {type(tree_node_obj)}")
|
||||||
|
QMessageBox.warning(self, "Fehler", "Konnte TreeNode nicht ermitteln")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Prüfe ob XML-Dateien vorhanden sind
|
||||||
|
if not self._has_xml_files_recursive(tree_node_obj):
|
||||||
|
QMessageBox.information(self, "Info", "Keine XML-Dateien unter diesem Knoten gefunden")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Sammle alle XSL/XML-Paare rekursiv
|
||||||
|
xsl_xml_pairs = self._collect_all_xsl_xml_pairs_recursive(tree_node_obj, item)
|
||||||
|
|
||||||
|
if not xsl_xml_pairs:
|
||||||
|
QMessageBox.information(self, "Info", "Keine XML-Dateien gefunden")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Erstelle TransformationJobs für alle XML-Dateien
|
||||||
|
jobs = []
|
||||||
|
for xsl_file_obj, xml_file_obj, xsl_file_item in xsl_xml_pairs:
|
||||||
|
# Übergebe das XslFile-TreeWidgetItem für Parameter-Sammlung
|
||||||
|
job = self._create_transformation_job(xsl_file_obj, xml_file_obj, xsl_file_item)
|
||||||
|
if job:
|
||||||
|
jobs.append(job)
|
||||||
|
|
||||||
|
if not jobs:
|
||||||
|
QMessageBox.warning(self, "Fehler", "Konnte keine Transformations-Jobs erstellen")
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(f"Starte Transformation für {len(jobs)} XML-Dateien unter TreeNode '{tree_node_obj.bez}'")
|
||||||
|
|
||||||
|
# Starte Transformation in separatem Thread
|
||||||
|
self._start_transformation(jobs, force=force)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Fehler beim Transformieren des TreeNode: {e}")
|
||||||
|
QMessageBox.critical(self, "Fehler", f"Fehler beim Transformieren: {str(e)}")
|
||||||
|
|
||||||
def _create_transformation_job(
|
def _create_transformation_job(
|
||||||
self, xsl_file_obj: XslFile, xml_file_obj: XmlFile, xsl_file_item: QTreeWidgetItem | None = None
|
self, xsl_file_obj: XslFile, xml_file_obj: XmlFile, xsl_file_item: QTreeWidgetItem | None = None
|
||||||
) -> TransformationJob | None:
|
) -> TransformationJob | None:
|
||||||
|
|||||||
Reference in New Issue
Block a user