diff --git a/.clinerules/agents.md b/.clinerules/agents.md index 63c8ae7..7e6d31b 100644 --- a/.clinerules/agents.md +++ b/.clinerules/agents.md @@ -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. \ No newline at end of file + - 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. diff --git a/.kilocode/rules/agents.md b/.kilocode/rules/agents.md index 802a3f2..7b377b0 100644 --- a/.kilocode/rules/agents.md +++ b/.kilocode/rules/agents.md @@ -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. \ No newline at end of file +## 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. \ No newline at end of file diff --git a/src/ui/MainWindow.py b/src/ui/MainWindow.py index dbfb0c3..81f549f 100644 --- a/src/ui/MainWindow.py +++ b/src/ui/MainWindow.py @@ -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 diff --git a/src/ui/XmlToXslAssignDialog.py b/src/ui/XmlToXslAssignDialog.py new file mode 100644 index 0000000..5966421 --- /dev/null +++ b/src/ui/XmlToXslAssignDialog.py @@ -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() diff --git a/src/ui/XmlToXslAssignDialog.ui b/src/ui/XmlToXslAssignDialog.ui new file mode 100644 index 0000000..ec1b7d7 --- /dev/null +++ b/src/ui/XmlToXslAssignDialog.ui @@ -0,0 +1,155 @@ + + + XmlToXslAssignDialog + + + + 0 + 0 + 700 + 500 + + + + XML-Datei zu XSL-Knoten zuordnen + + + true + + + + + + Wählen Sie die XSL-Knoten aus, denen die XML-Datei zugeordnet werden soll: + + + true + + + + + + + font-weight: bold; color: #0066cc; + + + XML-Datei: [wird zur Laufzeit gesetzt] + + + true + + + + + + + false + + + 3 + + + true + + + true + + + + XSL-Knoten + + + + + Details + + + + + Auswählen + + + + + + + + + + Alle auswählen + + + + + + + Alle abwählen + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Orientation::Horizontal + + + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + + + true + + + + + + + + + buttonBox + accepted() + XmlToXslAssignDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + XmlToXslAssignDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/ui/XmlToXslAssignDialog_ui.py b/src/ui/XmlToXslAssignDialog_ui.py new file mode 100644 index 0000000..feaa4ff --- /dev/null +++ b/src/ui/XmlToXslAssignDialog_ui.py @@ -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 +