Accept-Changes-Button: Änderungen akzeptieren und automatisch zur nächsten Diff-PDF springen

Neuer Button zum Akzeptieren von PDF-Änderungen mit automatischem Workflow:
- Verschiebt new-PDF nach ref (alte ref-PDF wird gelöscht)
- Löscht diff-PDF
- Entfernt Diff-Icon beim aktuellen XML-Knoten
- Aktualisiert Diff-PDF-Anzahl auf übergeordneten Ebenen
- Lädt automatisch nächste Diff-PDF oder leert Viewer falls keine mehr vorhanden
- Wählt den entsprechenden XML-Knoten im Baum aus für visuelle Rückmeldung

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-15 21:10:15 +01:00
parent 1fc7decace
commit 5b64cf5890
3 changed files with 187 additions and 3 deletions
+25 -2
View File
@@ -341,6 +341,29 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="accept_changes">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>✅ Änderungen übernehmen</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
@@ -354,8 +377,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>625</width>
<height>700</height>
<width>726</width>
<height>695</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
+12 -1
View File
@@ -209,6 +209,16 @@ class Ui_MainWindow(object):
self.horizontalLayout_3.addItem(self.horizontalSpacer_5)
self.accept_changes = QPushButton(self.frame_4)
self.accept_changes.setObjectName(u"accept_changes")
self.accept_changes.setEnabled(False)
self.horizontalLayout_3.addWidget(self.accept_changes)
self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
self.horizontalLayout_3.addItem(self.horizontalSpacer_3)
self.verticalLayout_4.addWidget(self.frame_4)
@@ -217,7 +227,7 @@ class Ui_MainWindow(object):
self.scrollArea_2.setWidgetResizable(True)
self.scrollAreaWidgetContents_2 = QWidget()
self.scrollAreaWidgetContents_2.setObjectName(u"scrollAreaWidgetContents_2")
self.scrollAreaWidgetContents_2.setGeometry(QRect(0, 0, 625, 700))
self.scrollAreaWidgetContents_2.setGeometry(QRect(0, 0, 726, 695))
self.verticalLayout_3 = QVBoxLayout(self.scrollAreaWidgetContents_2)
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
@@ -293,6 +303,7 @@ class Ui_MainWindow(object):
self.label_6.setText(QCoreApplication.translate("MainWindow", u"Vorher (Referenz)", None))
self.label_7.setText(QCoreApplication.translate("MainWindow", u"Nachher (Neu)", None))
self.label_5.setText(QCoreApplication.translate("MainWindow", u"Zoom", None))
self.accept_changes.setText(QCoreApplication.translate("MainWindow", u"\u2705 \u00c4nderungen \u00fcbernehmen", None))
self.label_3.setText(QCoreApplication.translate("MainWindow", u"TextLabel", None))
self.label_4.setText(QCoreApplication.translate("MainWindow", u"TextLabel", None))
self.menuProjekt.setTitle(QCoreApplication.translate("MainWindow", u"Projekt", None))
+150
View File
@@ -209,6 +209,10 @@ class MainWindow(QMainWindow):
self.current_page = 0
self.current_pdf = None
# Aktuelle Diff-PDF-Informationen (für Accept Changes)
self.current_diff_xml_path = None
self.current_diff_xsl_id = None
# Cache für die aktuell gerenderten Pixmaps (Performance-Optimierung)
self.current_rendered_pixmaps = None
@@ -752,6 +756,9 @@ class MainWindow(QMainWindow):
# Button "lade aus FN2" verbinden
self.ui.pB_lade_aus_fn2.clicked.connect(self.on_load_from_fn2_clicked)
# Button "Accept Changes" verbinden
self.ui.accept_changes.clicked.connect(self._on_accept_changes_clicked)
def _setup_tree_context_menu(self):
"""Richtet das Kontextmenü für das TreeWidget ein."""
# Aktiviere Kontextmenü für das TreeWidget
@@ -1532,6 +1539,13 @@ class MainWindow(QMainWindow):
# Setze die aktuelle PDF
self.current_pdf = pdf_basename
# Speichere Diff-PDF-Informationen für Accept Changes
self.current_diff_xml_path = xml_file_path
self.current_diff_xsl_id = xsl_id_str
# Aktiviere Accept-Changes-Button
self.ui.accept_changes.setEnabled(True)
# Zeige die erste Seite initial an
self.render_and_display_page(pdf_basename, 0)
@@ -3576,6 +3590,142 @@ class MainWindow(QMainWindow):
f"{successful_count} von {total_count} Transformationen erfolgreich\n{failed_count} fehlgeschlagen",
)
def _find_next_diff_pdf(self) -> tuple[Path, str] | None:
"""
Findet die nächste Diff-PDF im Projekt.
Returns:
tuple[Path, str] | None: (xml_file_path, xsl_id_str) der nächsten Diff-PDF oder None
"""
if not self.project:
return None
diff_dir = self.project.project_dir / "diff"
if not diff_dir.exists():
return None
# Durchlaufe xml_item_map und prüfe welche Items Diff-PDFs haben
for map_key, tree_item in self.xml_item_map.items():
# Map-Key hat Format "xml_path|xsl_id"
parts = map_key.split("|")
if len(parts) != 2:
continue
xml_path_str = parts[0]
xsl_id_str = parts[1]
# Konvertiere zu Path
xml_file_path = Path(xml_path_str)
# Prüfe ob Diff-PDF existiert
xml_stem = xml_file_path.stem
pdf_basename = f"{xml_stem}_xsl_{xsl_id_str}.pdf"
diff_pdf_path = diff_dir / pdf_basename
if diff_pdf_path.exists():
return (xml_file_path, xsl_id_str)
return None
def _clear_pdf_viewer(self):
"""Leert den PDF-Viewer und alle Thumbnails."""
# Entferne Widgets aus Layouts
self._clear_layout(self.ui.verticalLayout_2)
self._clear_layout(self.ui.verticalLayout_3)
# Zurücksetzen der Datenstrukturen
self.thumbnail_to_page = {}
self.pdf_documents = {}
self.current_rendered_pixmaps = None
self.fullsize_label = None
self.current_pdf = None
self.current_diff_xml_path = None
self.current_diff_xsl_id = None
logger.info("PDF-Viewer geleert")
def _on_accept_changes_clicked(self):
"""
Handler für Accept-Changes-Button.
Verschiebt new PDF nach ref, löscht diff PDF, aktualisiert Icons und lädt nächste Diff-PDF.
"""
try:
if not self.project or not self.current_diff_xml_path or not self.current_diff_xsl_id:
logger.warning("Keine aktuelle Diff-PDF zum Akzeptieren")
return
# PDF-Dateinamen ermitteln
xml_stem = self.current_diff_xml_path.stem
pdf_basename = f"{xml_stem}_xsl_{self.current_diff_xsl_id}.pdf"
# Pfade
diff_dir = self.project.project_dir / "diff"
ref_dir = self.project.project_dir / "ref"
new_dir = self.project.project_dir / "new"
diff_pdf_path = diff_dir / pdf_basename
ref_pdf_path = ref_dir / pdf_basename
new_pdf_path = new_dir / pdf_basename
logger.info(f"Akzeptiere Änderungen für: {pdf_basename}")
# Prüfe ob new-PDF existiert
if not new_pdf_path.exists():
QMessageBox.warning(self, "Fehler", f"New-PDF nicht gefunden:\n{pdf_basename}")
return
# Lösche alte ref-PDF falls vorhanden
if ref_pdf_path.exists():
ref_pdf_path.unlink()
logger.info(f"Alte Ref-PDF gelöscht: {ref_pdf_path}")
# Verschiebe new-PDF nach ref
shutil.move(str(new_pdf_path), str(ref_pdf_path))
logger.info(f"New-PDF verschoben nach Ref: {new_pdf_path} -> {ref_pdf_path}")
# Lösche diff-PDF
if diff_pdf_path.exists():
diff_pdf_path.unlink()
logger.info(f"Diff-PDF gelöscht: {diff_pdf_path}")
# Diff-Icon beim aktuellen XML-Knoten entfernen
map_key = f"{self.current_diff_xml_path}|{self.current_diff_xsl_id}"
if map_key in self.xml_item_map:
tree_item = self.xml_item_map[map_key]
# Entferne Icon-Widget aus Spalte 2
tree_item.setData(2, Qt.ItemDataRole.UserRole, None)
self.ui.treeWidget.setItemWidget(tree_item, 2, None)
logger.info(f"Diff-Icon entfernt für: {map_key}")
# Diff-PDF-Anzahl auf übergeordneten Ebenen aktualisieren
self._update_all_diff_pdf_counts()
# Finde nächste Diff-PDF
next_diff = self._find_next_diff_pdf()
if next_diff:
# Lade nächste Diff-PDF
next_xml_path, next_xsl_id = next_diff
logger.info(f"Lade nächste Diff-PDF: {next_xml_path} / {next_xsl_id}")
self._load_pdf_for_comparison(next_xml_path, next_xsl_id)
# Wähle den entsprechenden XML-Knoten im Baum aus
map_key = f"{next_xml_path}|{next_xsl_id}"
if map_key in self.xml_item_map:
tree_item = self.xml_item_map[map_key]
self.ui.treeWidget.setCurrentItem(tree_item)
self.ui.treeWidget.scrollToItem(tree_item)
logger.info(f"TreeWidget-Item ausgewählt: {map_key}")
else:
# Keine weiteren Diff-PDFs, Button deaktivieren und Viewer leeren
logger.info("Keine weiteren Diff-PDFs vorhanden")
self.ui.accept_changes.setEnabled(False)
self._clear_pdf_viewer()
except Exception as e:
logger.error(f"Fehler beim Akzeptieren der Änderungen: {e}")
QMessageBox.critical(self, "Fehler", f"Fehler beim Akzeptieren der Änderungen:\n{str(e)}")
def closeEvent(self, event):
"""Wird beim Schließen der Anwendung aufgerufen."""
# UI-Zustände speichern