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>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</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>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -354,8 +377,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>625</width>
|
<width>726</width>
|
||||||
<height>700</height>
|
<height>695</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
|||||||
@@ -209,6 +209,16 @@ class Ui_MainWindow(object):
|
|||||||
|
|
||||||
self.horizontalLayout_3.addItem(self.horizontalSpacer_5)
|
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)
|
self.verticalLayout_4.addWidget(self.frame_4)
|
||||||
|
|
||||||
@@ -217,7 +227,7 @@ class Ui_MainWindow(object):
|
|||||||
self.scrollArea_2.setWidgetResizable(True)
|
self.scrollArea_2.setWidgetResizable(True)
|
||||||
self.scrollAreaWidgetContents_2 = QWidget()
|
self.scrollAreaWidgetContents_2 = QWidget()
|
||||||
self.scrollAreaWidgetContents_2.setObjectName(u"scrollAreaWidgetContents_2")
|
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 = QVBoxLayout(self.scrollAreaWidgetContents_2)
|
||||||
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||||
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
|
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_6.setText(QCoreApplication.translate("MainWindow", u"Vorher (Referenz)", None))
|
||||||
self.label_7.setText(QCoreApplication.translate("MainWindow", u"Nachher (Neu)", None))
|
self.label_7.setText(QCoreApplication.translate("MainWindow", u"Nachher (Neu)", None))
|
||||||
self.label_5.setText(QCoreApplication.translate("MainWindow", u"Zoom", 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_3.setText(QCoreApplication.translate("MainWindow", u"TextLabel", None))
|
||||||
self.label_4.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))
|
self.menuProjekt.setTitle(QCoreApplication.translate("MainWindow", u"Projekt", None))
|
||||||
|
|||||||
@@ -209,6 +209,10 @@ class MainWindow(QMainWindow):
|
|||||||
self.current_page = 0
|
self.current_page = 0
|
||||||
self.current_pdf = None
|
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)
|
# Cache für die aktuell gerenderten Pixmaps (Performance-Optimierung)
|
||||||
self.current_rendered_pixmaps = None
|
self.current_rendered_pixmaps = None
|
||||||
|
|
||||||
@@ -752,6 +756,9 @@ class MainWindow(QMainWindow):
|
|||||||
# Button "lade aus FN2" verbinden
|
# Button "lade aus FN2" verbinden
|
||||||
self.ui.pB_lade_aus_fn2.clicked.connect(self.on_load_from_fn2_clicked)
|
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):
|
def _setup_tree_context_menu(self):
|
||||||
"""Richtet das Kontextmenü für das TreeWidget ein."""
|
"""Richtet das Kontextmenü für das TreeWidget ein."""
|
||||||
# Aktiviere Kontextmenü für das TreeWidget
|
# Aktiviere Kontextmenü für das TreeWidget
|
||||||
@@ -1532,6 +1539,13 @@ class MainWindow(QMainWindow):
|
|||||||
# Setze die aktuelle PDF
|
# Setze die aktuelle PDF
|
||||||
self.current_pdf = pdf_basename
|
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
|
# Zeige die erste Seite initial an
|
||||||
self.render_and_display_page(pdf_basename, 0)
|
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",
|
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):
|
def closeEvent(self, event):
|
||||||
"""Wird beim Schließen der Anwendung aufgerufen."""
|
"""Wird beim Schließen der Anwendung aufgerufen."""
|
||||||
# UI-Zustände speichern
|
# UI-Zustände speichern
|
||||||
|
|||||||
Reference in New Issue
Block a user