diff --git a/src/ui/mixins/tree_manager.py b/src/ui/mixins/tree_manager.py index c83c8cb..3a868dc 100644 --- a/src/ui/mixins/tree_manager.py +++ b/src/ui/mixins/tree_manager.py @@ -958,9 +958,126 @@ class TreeManagerMixin: QMessageBox.critical(self, "Fehler", error_msg) def _delete_xsl_file(self, item): - """Löscht eine XSL-Datei.""" + """ + Löscht eine XSL-Datei aus einem Baumknoten. + + Die XSL-Datei wird nur aus dem Baum entfernt, nicht physisch gelöscht. + Zugehörige PDF-Dateien werden automatisch bereinigt. + XML-Dateien, die nirgends mehr verwendet werden, können optional physisch gelöscht werden. + + Args: + item: Das TreeWidgetItem der XSL-Datei + """ logger.debug(f"XslFile löschen: {item.text(0)}") - # TODO: Bestätigungsdialog und Löschung implementieren + + 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.") + return + + if not hasattr(self, "pdf_project") or not self.pdf_project: + QMessageBox.warning(self, "Warnung", "Keine Projekt-Einstellungen geladen.") + return + + # Hole das XslFile-Objekt aus dem TreeWidgetItem + xsl_file_obj = item.data(0, Qt.ItemDataRole.UserRole) + if not xsl_file_obj or not isinstance(xsl_file_obj, XslFile): + QMessageBox.warning(self, "Warnung", "Keine gültige XSL-Datei gefunden.") + return + + # Hole das Eltern-Item (sollte ein TreeNode sein) + parent_item = item.parent() + if not parent_item: + QMessageBox.warning(self, "Warnung", "Eltern-Knoten nicht gefunden.") + return + + parent_node = parent_item.data(0, Qt.ItemDataRole.UserRole) + if not parent_node or not isinstance(parent_node, TreeNode): + QMessageBox.warning(self, "Warnung", "Kein gültiger Eltern-Knoten gefunden.") + return + + # Bestätigungsdialog anzeigen + xml_count = len(xsl_file_obj.xmls) + xml_info = f"\n\nDer XSL-Datei sind {xml_count} XML-Datei(en) zugeordnet." if xml_count > 0 else "" + reply = QMessageBox.question( + self, + "XSL-Datei entfernen", + f"Möchten Sie die XSL-Datei '{xsl_file_obj.bez}' aus dem Baum entfernen?\n\n" + f"Die XSL-Datei selbst wird nicht physisch gelöscht.{xml_info}", + QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, + QMessageBox.StandardButton.No, + ) + + if reply != QMessageBox.StandardButton.Yes: + logger.debug("Löschung abgebrochen") + return + + # PDF-Bereinigung für alle zugehörigen XML-Dateien + xsl_id = xsl_file_obj.id + total_deleted_pdfs = 0 + for xml_file_obj in xsl_file_obj.xmls: + is_combination_used = self._is_xml_xsl_combination_used_elsewhere( + xml_file_obj.xml, xsl_id, xsl_file_obj + ) + if not is_combination_used: + deleted_pdfs = self._delete_pdf_files_for_xml_xsl_combination(xml_file_obj.xml, xsl_id) + total_deleted_pdfs += deleted_pdfs + + if total_deleted_pdfs > 0: + logger.info(f"{total_deleted_pdfs} PDF-Datei(en) für XSL '{xsl_file_obj.bez}' gelöscht") + + # Sammle XML-Dateien, die nirgends mehr verwendet werden + unused_xml_files = [] + for xml_file_obj in xsl_file_obj.xmls: + xml_file_path = Path(self.project.project_dir) / xml_file_obj.xml + if xml_file_path.exists(): + is_used = self._is_xml_file_used_elsewhere(xml_file_obj.xml, xsl_file_obj) + if not is_used: + unused_xml_files.append((xml_file_obj, xml_file_path)) + + # Optionale physische Löschung nicht mehr verwendeter XML-Dateien + if unused_xml_files: + file_list = "\n".join(f" - {p.name}" for _, p in unused_xml_files) + delete_reply = QMessageBox.question( + self, + "Physische XML-Dateien löschen", + f"Folgende {len(unused_xml_files)} XML-Datei(en) werden in keiner anderen " + f"XSL-Datei mehr verwendet:\n\n{file_list}\n\n" + "Möchten Sie diese physisch löschen?", + QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, + QMessageBox.StandardButton.No, + ) + + if delete_reply == QMessageBox.StandardButton.Yes: + for xml_file_obj, xml_file_path in unused_xml_files: + try: + xml_file_path.unlink() + logger.info(f"Physische XML-Datei gelöscht: {xml_file_path}") + except Exception as e: + logger.warning(f"Konnte XML-Datei nicht löschen: {xml_file_path} - {e}") + + # Entferne das XslFile aus dem Eltern-TreeNode + children_before = len(parent_node.children) + parent_node.children = [child for child in parent_node.children if child is not xsl_file_obj] + children_after = len(parent_node.children) + + if children_before == children_after: + QMessageBox.warning(self, "Warnung", "XSL-Datei konnte nicht aus dem Knoten entfernt werden.") + return + + logger.info(f"XSL-Datei '{xsl_file_obj.bez}' aus Knoten '{parent_node.bez}' entfernt") + + # Speichere und aktualisiere + self._save_project_settings() + self._load_nodes_to_tree() + + logger.info(f"XSL-Datei '{xsl_file_obj.bez}' erfolgreich entfernt") + + except Exception as e: + error_msg = f"Fehler beim Löschen der XSL-Datei: {str(e)}" + logger.error(error_msg) + QMessageBox.critical(self, "Fehler", error_msg) # Kontextmenü-Aktionen für XmlFile def _edit_xml_file(self, item):