Kontextmenü für Baum erstellt
This commit is contained in:
+243
-2
@@ -10,7 +10,7 @@ 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
|
from conf import app_settings, PdfProject, PdfProjectSettings, TreeNode, XslFile, XmlFile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
@@ -72,6 +72,9 @@ class MainWindow(QMainWindow):
|
|||||||
# Signale und Slots verbinden
|
# Signale und Slots verbinden
|
||||||
self._connect_signals()
|
self._connect_signals()
|
||||||
|
|
||||||
|
# Kontextmenü für TreeWidget einrichten
|
||||||
|
self._setup_tree_context_menu()
|
||||||
|
|
||||||
def _setup_theme_menu(self):
|
def _setup_theme_menu(self):
|
||||||
"""Initialisiert das Theme-Menü mit verfügbaren Themes."""
|
"""Initialisiert das Theme-Menü mit verfügbaren Themes."""
|
||||||
# Hole alle verfügbaren Themes
|
# Hole alle verfügbaren Themes
|
||||||
@@ -536,6 +539,196 @@ class MainWindow(QMainWindow):
|
|||||||
self.ui.actionNeu.triggered.connect(self.open_new_project_dialog)
|
self.ui.actionNeu.triggered.connect(self.open_new_project_dialog)
|
||||||
self.ui.actionEinstellungen.triggered.connect(self.open_settings_dialog)
|
self.ui.actionEinstellungen.triggered.connect(self.open_settings_dialog)
|
||||||
|
|
||||||
|
def _setup_tree_context_menu(self):
|
||||||
|
"""Richtet das Kontextmenü für das TreeWidget ein."""
|
||||||
|
# Aktiviere Kontextmenü für das TreeWidget
|
||||||
|
self.ui.treeWidget.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
||||||
|
self.ui.treeWidget.customContextMenuRequested.connect(self._show_tree_context_menu)
|
||||||
|
print("Kontextmenü für TreeWidget eingerichtet")
|
||||||
|
|
||||||
|
def _show_tree_context_menu(self, position):
|
||||||
|
"""
|
||||||
|
Zeigt das Kontextmenü für das TreeWidget an.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
position: Position des Rechtsklicks
|
||||||
|
"""
|
||||||
|
# Hole das Item an der Position
|
||||||
|
item = self.ui.treeWidget.itemAt(position)
|
||||||
|
if not item:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Bestimme den Node-Typ basierend auf dem Item
|
||||||
|
node_type = self._get_node_type_from_item(item)
|
||||||
|
|
||||||
|
# Erstelle das entsprechende Kontextmenü
|
||||||
|
context_menu = self._create_context_menu_for_type(node_type, item)
|
||||||
|
|
||||||
|
if context_menu:
|
||||||
|
# Zeige das Kontextmenü an der globalen Position
|
||||||
|
global_pos = self.ui.treeWidget.mapToGlobal(position)
|
||||||
|
context_menu.exec(global_pos)
|
||||||
|
|
||||||
|
def _get_node_type_from_item(self, item):
|
||||||
|
"""
|
||||||
|
Bestimmt den Node-Typ basierend auf dem TreeWidgetItem.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item: Das TreeWidgetItem
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Der Node-Typ ('TreeNode', 'XslFile', 'XmlFile' oder 'Unknown')
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Prüfe ob das Item ein Parent hat (dann ist es ein Child-Item)
|
||||||
|
parent_item = item.parent()
|
||||||
|
|
||||||
|
if parent_item:
|
||||||
|
# Child-Item - prüfe ob es ein XML-File ist
|
||||||
|
text = item.text(0)
|
||||||
|
if text.startswith("XML:"):
|
||||||
|
return "XmlFile"
|
||||||
|
else:
|
||||||
|
# Könnte ein TreeNode-Child oder XslFile-Child sein
|
||||||
|
# Prüfe den Parent-Typ
|
||||||
|
parent_type = self._get_node_type_from_item(parent_item)
|
||||||
|
if parent_type == "XslFile":
|
||||||
|
return "XmlFile"
|
||||||
|
else:
|
||||||
|
# Rekursiv bestimmen basierend auf gespeicherten Daten
|
||||||
|
return self._determine_node_type_from_data(item)
|
||||||
|
else:
|
||||||
|
# Root-Item - bestimme Typ basierend auf gespeicherten Daten
|
||||||
|
return self._determine_node_type_from_data(item)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Bestimmen des Node-Typs: {e}")
|
||||||
|
return "Unknown"
|
||||||
|
|
||||||
|
def _determine_node_type_from_data(self, item):
|
||||||
|
"""
|
||||||
|
Bestimmt den Node-Typ basierend auf den gespeicherten Daten im Item.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item: Das TreeWidgetItem
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Der Node-Typ ('TreeNode', 'XslFile' oder 'Unknown')
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Hole die gespeicherte Node-ID
|
||||||
|
node_id = item.data(0, Qt.ItemDataRole.UserRole)
|
||||||
|
if not node_id:
|
||||||
|
return "Unknown"
|
||||||
|
|
||||||
|
# Suche in den Projekt-Nodes nach der ID
|
||||||
|
if hasattr(self, 'pdf_project') and self.pdf_project and self.pdf_project.nodes:
|
||||||
|
node = self._find_node_by_id(self.pdf_project.nodes, node_id)
|
||||||
|
if node:
|
||||||
|
if isinstance(node, TreeNode):
|
||||||
|
return "TreeNode"
|
||||||
|
elif isinstance(node, XslFile):
|
||||||
|
return "XslFile"
|
||||||
|
|
||||||
|
return "Unknown"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Bestimmen des Node-Typs aus Daten: {e}")
|
||||||
|
return "Unknown"
|
||||||
|
|
||||||
|
def _find_node_by_id(self, nodes, target_id):
|
||||||
|
"""
|
||||||
|
Sucht rekursiv nach einem Node mit der angegebenen ID.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
nodes: Liste der Nodes zum Durchsuchen
|
||||||
|
target_id: Die zu suchende ID
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
TreeNode|XslFile|None: Der gefundene Node oder None
|
||||||
|
"""
|
||||||
|
for node in nodes:
|
||||||
|
if node.id == target_id:
|
||||||
|
return node
|
||||||
|
|
||||||
|
# Rekursiv in Kindern suchen (nur bei TreeNode)
|
||||||
|
if isinstance(node, TreeNode) and node.children:
|
||||||
|
found = self._find_node_by_id(node.children, target_id)
|
||||||
|
if found:
|
||||||
|
return found
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _create_context_menu_for_type(self, node_type, item):
|
||||||
|
"""
|
||||||
|
Erstellt das Kontextmenü für den angegebenen Node-Typ.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
node_type: Der Typ des Nodes ('TreeNode', 'XslFile', 'XmlFile')
|
||||||
|
item: Das TreeWidgetItem
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
QMenu: Das erstellte Kontextmenü oder None
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
menu = QMenu(self)
|
||||||
|
|
||||||
|
if node_type == "TreeNode":
|
||||||
|
# Kontextmenü für TreeNode
|
||||||
|
action_add_child = QAction("Unterknoten hinzufügen", self)
|
||||||
|
action_add_child.triggered.connect(lambda: self._add_tree_node_child(item))
|
||||||
|
menu.addAction(action_add_child)
|
||||||
|
|
||||||
|
action_add_xsl = QAction("XSL-Datei hinzufügen", self)
|
||||||
|
action_add_xsl.triggered.connect(lambda: self._add_xsl_file_to_node(item))
|
||||||
|
menu.addAction(action_add_xsl)
|
||||||
|
|
||||||
|
menu.addSeparator()
|
||||||
|
|
||||||
|
action_edit = QAction("Bearbeiten", self)
|
||||||
|
action_edit.triggered.connect(lambda: self._edit_tree_node(item))
|
||||||
|
menu.addAction(action_edit)
|
||||||
|
|
||||||
|
action_delete = QAction("Löschen", self)
|
||||||
|
action_delete.triggered.connect(lambda: self._delete_tree_node(item))
|
||||||
|
menu.addAction(action_delete)
|
||||||
|
|
||||||
|
elif node_type == "XslFile":
|
||||||
|
# Kontextmenü für XslFile
|
||||||
|
action_add_xml = QAction("XML-Datei hinzufügen", self)
|
||||||
|
action_add_xml.triggered.connect(lambda: self._add_xml_file_to_xsl(item))
|
||||||
|
menu.addAction(action_add_xml)
|
||||||
|
|
||||||
|
menu.addSeparator()
|
||||||
|
|
||||||
|
action_edit = QAction("Bearbeiten", self)
|
||||||
|
action_edit.triggered.connect(lambda: self._edit_xsl_file(item))
|
||||||
|
menu.addAction(action_edit)
|
||||||
|
|
||||||
|
action_delete = QAction("Löschen", self)
|
||||||
|
action_delete.triggered.connect(lambda: self._delete_xsl_file(item))
|
||||||
|
menu.addAction(action_delete)
|
||||||
|
|
||||||
|
elif node_type == "XmlFile":
|
||||||
|
# Kontextmenü für XmlFile
|
||||||
|
action_edit = QAction("Bearbeiten", self)
|
||||||
|
action_edit.triggered.connect(lambda: self._edit_xml_file(item))
|
||||||
|
menu.addAction(action_edit)
|
||||||
|
|
||||||
|
action_delete = QAction("Löschen", self)
|
||||||
|
action_delete.triggered.connect(lambda: self._delete_xml_file(item))
|
||||||
|
menu.addAction(action_delete)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Unbekannter Typ - kein Menü
|
||||||
|
return None
|
||||||
|
|
||||||
|
return menu
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Erstellen des Kontextmenüs: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
def on_alpha_changed(self, alpha_value):
|
def on_alpha_changed(self, alpha_value):
|
||||||
"""
|
"""
|
||||||
Wird ausgeführt, wenn der Alpha-Slider geändert wird.
|
Wird ausgeführt, wenn der Alpha-Slider geändert wird.
|
||||||
@@ -755,7 +948,7 @@ class MainWindow(QMainWindow):
|
|||||||
# Erstelle Tree-Item
|
# Erstelle Tree-Item
|
||||||
item = QTreeWidgetItem()
|
item = QTreeWidgetItem()
|
||||||
|
|
||||||
# Setze die Bezeichnung in Spalte 0 (mit expliziter UTF-8 Behandlung)
|
# Setze die Bezeichnung in Spalte 0
|
||||||
bez_text = str(node.bez) if node.bez else ""
|
bez_text = str(node.bez) if node.bez else ""
|
||||||
item.setText(0, bez_text)
|
item.setText(0, bez_text)
|
||||||
|
|
||||||
@@ -799,6 +992,54 @@ class MainWindow(QMainWindow):
|
|||||||
fallback_item.setText(1, str(e))
|
fallback_item.setText(1, str(e))
|
||||||
return fallback_item
|
return fallback_item
|
||||||
|
|
||||||
|
# Kontextmenü-Aktionen für TreeNode
|
||||||
|
def _add_tree_node_child(self, parent_item):
|
||||||
|
"""Fügt einen Unterknoten zu einem TreeNode hinzu."""
|
||||||
|
print(f"Unterknoten zu TreeNode hinzufügen: {parent_item.text(0)}")
|
||||||
|
# TODO: Dialog zum Eingeben der Node-Daten öffnen
|
||||||
|
|
||||||
|
def _add_xsl_file_to_node(self, parent_item):
|
||||||
|
"""Fügt eine XSL-Datei zu einem TreeNode hinzu."""
|
||||||
|
print(f"XSL-Datei zu TreeNode hinzufügen: {parent_item.text(0)}")
|
||||||
|
# TODO: Dialog zum Auswählen der XSL-Datei öffnen
|
||||||
|
|
||||||
|
def _edit_tree_node(self, item):
|
||||||
|
"""Bearbeitet einen TreeNode."""
|
||||||
|
print(f"TreeNode bearbeiten: {item.text(0)}")
|
||||||
|
# TODO: Dialog zum Bearbeiten der Node-Daten öffnen
|
||||||
|
|
||||||
|
def _delete_tree_node(self, item):
|
||||||
|
"""Löscht einen TreeNode."""
|
||||||
|
print(f"TreeNode löschen: {item.text(0)}")
|
||||||
|
# TODO: Bestätigungsdialog und Löschung implementieren
|
||||||
|
|
||||||
|
# Kontextmenü-Aktionen für XslFile
|
||||||
|
def _add_xml_file_to_xsl(self, parent_item):
|
||||||
|
"""Fügt eine XML-Datei zu einer XSL-Datei hinzu."""
|
||||||
|
print(f"XML-Datei zu XslFile hinzufügen: {parent_item.text(0)}")
|
||||||
|
# TODO: Dialog zum Auswählen der XML-Datei öffnen
|
||||||
|
|
||||||
|
def _edit_xsl_file(self, item):
|
||||||
|
"""Bearbeitet eine XSL-Datei."""
|
||||||
|
print(f"XslFile bearbeiten: {item.text(0)}")
|
||||||
|
# TODO: Dialog zum Bearbeiten der XSL-Datei öffnen
|
||||||
|
|
||||||
|
def _delete_xsl_file(self, item):
|
||||||
|
"""Löscht eine XSL-Datei."""
|
||||||
|
print(f"XslFile löschen: {item.text(0)}")
|
||||||
|
# TODO: Bestätigungsdialog und Löschung implementieren
|
||||||
|
|
||||||
|
# Kontextmenü-Aktionen für XmlFile
|
||||||
|
def _edit_xml_file(self, item):
|
||||||
|
"""Bearbeitet eine XML-Datei."""
|
||||||
|
print(f"XmlFile bearbeiten: {item.text(0)}")
|
||||||
|
# TODO: Dialog zum Bearbeiten der XML-Datei öffnen
|
||||||
|
|
||||||
|
def _delete_xml_file(self, item):
|
||||||
|
"""Löscht eine XML-Datei."""
|
||||||
|
print(f"XmlFile löschen: {item.text(0)}")
|
||||||
|
# TODO: Bestätigungsdialog und Löschung implementieren
|
||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
"""Wird beim Schließen der Anwendung aufgerufen."""
|
"""Wird beim Schließen der Anwendung aufgerufen."""
|
||||||
# PDF-Dokumente schließen ist bei QtPdf automatisch durch Garbage Collection
|
# PDF-Dokumente schließen ist bei QtPdf automatisch durch Garbage Collection
|
||||||
|
|||||||
Reference in New Issue
Block a user