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:
+25
-2
@@ -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">
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user