PDF-Vergleich in integrierten Viewer umgeleitet und Alpha-Blending verbessert
Das Diff-PDF-Icon lädt nun alle drei PDFs (diff, ref, new) direkt in den eingebauten Vergleichs-Viewer, statt ein externes Programm zu öffnen. Zusätzlich wurde die Alpha-Blending-Logik für sanftere Übergänge zwischen den Ansichten korrigiert. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
+143
-40
@@ -675,13 +675,12 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
if alpha_value <= 0:
|
if alpha_value <= 0:
|
||||||
# Alpha von -100 bis 0: Übergang von ref zu diff
|
# Alpha von -100 bis 0: Übergang von ref zu diff
|
||||||
ref_opacity = 1.0 # - (alpha_value + 100) / 100.0
|
ref_opacity = abs(alpha_value) / 100
|
||||||
diff_opacity = (alpha_value + 100) / 100.0
|
diff_opacity = 1.0 - abs(alpha_value) / 100.0
|
||||||
new_opacity = 0.0
|
new_opacity = 0.0
|
||||||
else:
|
else:
|
||||||
# Alpha von 0 bis 100: Übergang von diff zu new
|
|
||||||
ref_opacity = 0.0
|
ref_opacity = 0.0
|
||||||
diff_opacity = 1.0 # - alpha_value / 100.0
|
diff_opacity = 1.0 - alpha_value / 100.0
|
||||||
new_opacity = alpha_value / 100.0
|
new_opacity = alpha_value / 100.0
|
||||||
|
|
||||||
# Zeichne die Ebenen mit entsprechender Transparenz
|
# Zeichne die Ebenen mit entsprechender Transparenz
|
||||||
@@ -1304,12 +1303,13 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
return container, progress_bar
|
return container, progress_bar
|
||||||
|
|
||||||
def _create_centered_diff_icon(self, xml_file_path: Path) -> QWidget:
|
def _create_centered_diff_icon(self, xml_file_path: Path, xsl_id_str: str) -> QWidget:
|
||||||
"""
|
"""
|
||||||
Erstellt ein zentriertes, klickbares Icon für Diff-PDF.
|
Erstellt ein zentriertes, klickbares Icon für Diff-PDF.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
xml_file_path: Pfad zur XML-Datei (für Event-Handler)
|
xml_file_path: Pfad zur XML-Datei (relativ)
|
||||||
|
xsl_id_str: XSL-ID als String (z.B. "2002_1_128")
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
QWidget: Container mit klickbarem Icon
|
QWidget: Container mit klickbarem Icon
|
||||||
@@ -1324,57 +1324,160 @@ class MainWindow(QMainWindow):
|
|||||||
icon_label = QLabel()
|
icon_label = QLabel()
|
||||||
icon_label.setPixmap(QIcon.fromTheme("document-preview").pixmap(16, 16))
|
icon_label.setPixmap(QIcon.fromTheme("document-preview").pixmap(16, 16))
|
||||||
icon_label.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
|
icon_label.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
|
||||||
icon_label.setToolTip("Diff-PDF öffnen (Doppelklick)")
|
icon_label.setToolTip("Diff-PDF in Viewer laden (Doppelklick)")
|
||||||
|
|
||||||
# Klick-Event für Icon (Doppelklick öffnet PDF)
|
# Klick-Event für Icon (Doppelklick lädt PDF in Viewer)
|
||||||
icon_label.mouseDoubleClickEvent = lambda event: self._open_diff_pdf(xml_file_path)
|
icon_label.mouseDoubleClickEvent = lambda event: self._load_pdf_for_comparison(xml_file_path, xsl_id_str)
|
||||||
|
|
||||||
layout.addWidget(icon_label)
|
layout.addWidget(icon_label)
|
||||||
|
|
||||||
return container
|
return container
|
||||||
|
|
||||||
def _open_diff_pdf(self, xml_file_path: Path):
|
def _load_pdf_for_comparison(self, xml_file_path: Path, xsl_id_str: str):
|
||||||
"""
|
"""
|
||||||
Öffnet die Diff-PDF für eine XML-Datei mit dem Standard-PDF-Viewer.
|
Lädt die PDFs (diff, ref, new) einer Transformation in den Vergleichs-Viewer.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
xml_file_path: Pfad zur XML-Datei (relativ)
|
xml_file_path: Pfad zur XML-Datei (relativ)
|
||||||
|
xsl_id_str: XSL-ID als String (z.B. "2002_1_128")
|
||||||
"""
|
"""
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Ermittle Diff-PDF-Pfad basierend auf XML-Datei
|
if not self.project:
|
||||||
# WICHTIG: Berücksichtige XSL-ID im Dateinamen!
|
QMessageBox.warning(self, "Fehler", "Kein Projekt geöffnet")
|
||||||
# Vereinfachung: Suche nach allen PDFs die mit xml_stem beginnen
|
|
||||||
xml_stem = xml_file_path.stem
|
|
||||||
diff_dir = self.project.project_dir / "diff"
|
|
||||||
|
|
||||||
# Finde passende Diff-PDF (könnte mehrere geben bei verschiedenen XSL-IDs)
|
|
||||||
matching_pdfs = list(diff_dir.glob(f"{xml_stem}*.pdf"))
|
|
||||||
|
|
||||||
if not matching_pdfs:
|
|
||||||
QMessageBox.information(self, "Keine Diff-PDF", f"Keine Diff-PDF für {xml_file_path.name} gefunden")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Bei mehreren: Nehme neueste
|
# Ermittle PDF-Dateinamen basierend auf XML und XSL-ID
|
||||||
diff_pdf = max(matching_pdfs, key=lambda p: p.stat().st_mtime)
|
xml_stem = xml_file_path.stem
|
||||||
|
pdf_basename = f"{xml_stem}_xsl_{xsl_id_str}.pdf"
|
||||||
|
|
||||||
logger.info(f"Öffne Diff-PDF: {diff_pdf}")
|
# Pfade zu den drei PDFs
|
||||||
|
diff_dir = self.project.project_dir / "diff"
|
||||||
|
ref_dir = self.project.project_dir / "ref"
|
||||||
|
new_dir = self.project.project_dir / "new"
|
||||||
|
|
||||||
# Öffne PDF mit Plattform-spezifischem Befehl
|
diff_pdf_path = diff_dir / pdf_basename
|
||||||
if sys.platform == "win32":
|
ref_pdf_path = ref_dir / pdf_basename
|
||||||
subprocess.Popen(["start", str(diff_pdf)], shell=True)
|
new_pdf_path = new_dir / pdf_basename
|
||||||
elif sys.platform == "darwin":
|
|
||||||
subprocess.Popen(["open", str(diff_pdf)])
|
|
||||||
else:
|
|
||||||
subprocess.Popen(["xdg-open", str(diff_pdf)])
|
|
||||||
|
|
||||||
logger.info(f"Diff-PDF geöffnet: {diff_pdf}")
|
# Prüfe ob PDFs existieren
|
||||||
|
if not diff_pdf_path.exists():
|
||||||
|
QMessageBox.information(self, "Keine Diff-PDF", f"Diff-PDF nicht gefunden:\n{pdf_basename}")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not ref_pdf_path.exists() or not new_pdf_path.exists():
|
||||||
|
QMessageBox.warning(
|
||||||
|
self,
|
||||||
|
"Fehlende PDFs",
|
||||||
|
f"Ref-PDF oder New-PDF nicht gefunden:\n{pdf_basename}\n\nNur Diff-PDF vorhanden.",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(f"Lade PDFs für Vergleich: {pdf_basename}")
|
||||||
|
|
||||||
|
# Entferne bestehende Widgets aus den Layouts
|
||||||
|
self._clear_layout(self.ui.verticalLayout_2)
|
||||||
|
self._clear_layout(self.ui.verticalLayout_3)
|
||||||
|
|
||||||
|
# Dicts zurücksetzen
|
||||||
|
self.thumbnail_to_page = {}
|
||||||
|
self.pdf_documents = {}
|
||||||
|
self.current_rendered_pixmaps = None
|
||||||
|
|
||||||
|
# Alle drei PDF-Dateien öffnen mit QtPdf
|
||||||
|
diff_doc = QPdfDocument()
|
||||||
|
ref_doc = QPdfDocument()
|
||||||
|
new_doc = QPdfDocument()
|
||||||
|
|
||||||
|
# PDF-Dateien laden
|
||||||
|
diff_doc.load(str(diff_pdf_path))
|
||||||
|
ref_doc.load(str(ref_pdf_path))
|
||||||
|
new_doc.load(str(new_pdf_path))
|
||||||
|
|
||||||
|
# Warten bis PDFs geladen sind
|
||||||
|
if (
|
||||||
|
diff_doc.status() != QPdfDocument.Status.Ready
|
||||||
|
or ref_doc.status() != QPdfDocument.Status.Ready
|
||||||
|
or new_doc.status() != QPdfDocument.Status.Ready
|
||||||
|
):
|
||||||
|
QMessageBox.critical(self, "Fehler", f"Fehler beim Laden der PDFs:\n{pdf_basename}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# PDF-Dokumente speichern
|
||||||
|
self.pdf_documents[pdf_basename] = {"diff": diff_doc, "ref": ref_doc, "new": new_doc}
|
||||||
|
|
||||||
|
logger.info(f"PDFs geladen: {pdf_basename}")
|
||||||
|
logger.info(f" diff: {diff_doc.pageCount()} Seiten")
|
||||||
|
logger.info(f" ref: {ref_doc.pageCount()} Seiten")
|
||||||
|
logger.info(f" new: {new_doc.pageCount()} Seiten")
|
||||||
|
|
||||||
|
# Nehme die Seitenzahl der diff-PDF als Basis
|
||||||
|
max_pages = diff_doc.pageCount()
|
||||||
|
|
||||||
|
# Erstelle Thumbnails für alle Seiten
|
||||||
|
for page_num in range(max_pages):
|
||||||
|
# Nur diff-Seite für Thumbnail rendern
|
||||||
|
page_size = diff_doc.pagePointSize(page_num)
|
||||||
|
|
||||||
|
# Skalierung für Thumbnail
|
||||||
|
scale_factor = 200.0 / page_size.width() # 200 Pixel Breite
|
||||||
|
|
||||||
|
# Seite rendern
|
||||||
|
page_image = diff_doc.render(
|
||||||
|
page_num,
|
||||||
|
QSize(int(page_size.width() * scale_factor), int(page_size.height() * scale_factor)),
|
||||||
|
)
|
||||||
|
|
||||||
|
diff_pixmap = QPixmap.fromImage(page_image)
|
||||||
|
|
||||||
|
# Thumbnail erstellen und zur linken Spalte hinzufügen
|
||||||
|
thumbnail = QLabel()
|
||||||
|
thumbnail.setObjectName(f"thumbnail_{pdf_basename}_page_{page_num + 1}")
|
||||||
|
thumbnail.setPixmap(diff_pixmap.scaledToWidth(200, Qt.TransformationMode.SmoothTransformation))
|
||||||
|
thumbnail.setCursor(QCursor(Qt.CursorShape.PointingHandCursor))
|
||||||
|
thumbnail.setMouseTracking(True)
|
||||||
|
self.ui.verticalLayout_2.addWidget(thumbnail)
|
||||||
|
|
||||||
|
# Seitennummer für Thumbnail anzeigen
|
||||||
|
thumbnail_info = QLabel(f"Seite {page_num + 1}")
|
||||||
|
thumbnail_info.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||||
|
self.ui.verticalLayout_2.addWidget(thumbnail_info)
|
||||||
|
|
||||||
|
# Beziehung zwischen Thumbnail und Seitennummer speichern
|
||||||
|
self.thumbnail_to_page[thumbnail] = {"pdf_filename": pdf_basename, "page_num": page_num}
|
||||||
|
|
||||||
|
# Click-Event für das Thumbnail einrichten
|
||||||
|
thumbnail.mousePressEvent = lambda event, t=thumbnail: self.on_thumbnail_clicked(event, t)
|
||||||
|
|
||||||
|
# Erstelle das Vollbild-Label für die rechte Spalte (falls noch nicht vorhanden)
|
||||||
|
if self.fullsize_label is None:
|
||||||
|
self.fullsize_label = QLabel()
|
||||||
|
self.fullsize_label.setObjectName("fullsize_current_page")
|
||||||
|
self.fullsize_label.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
||||||
|
self.fullsize_label.setCursor(QCursor(Qt.CursorShape.OpenHandCursor))
|
||||||
|
self.ui.verticalLayout_3.addWidget(self.fullsize_label)
|
||||||
|
|
||||||
|
# Drag-to-Scroll Events für das große Bild einrichten
|
||||||
|
self.fullsize_label.mousePressEvent = lambda event: self.on_fullsize_mouse_press(
|
||||||
|
event, self.fullsize_label
|
||||||
|
)
|
||||||
|
self.fullsize_label.mouseMoveEvent = lambda event: self.on_fullsize_mouse_move(
|
||||||
|
event, self.fullsize_label
|
||||||
|
)
|
||||||
|
self.fullsize_label.mouseReleaseEvent = lambda event: self.on_fullsize_mouse_release(
|
||||||
|
event, self.fullsize_label
|
||||||
|
)
|
||||||
|
|
||||||
|
# Setze die aktuelle PDF
|
||||||
|
self.current_pdf = pdf_basename
|
||||||
|
|
||||||
|
# Zeige die erste Seite initial an
|
||||||
|
self.render_and_display_page(pdf_basename, 0)
|
||||||
|
|
||||||
|
logger.info(f"PDF-Vergleich geladen: {pdf_basename}")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Fehler beim Öffnen der Diff-PDF: {e}")
|
logger.error(f"Fehler beim Laden der PDFs für Vergleich: {e}")
|
||||||
QMessageBox.critical(self, "Fehler", f"Konnte Diff-PDF nicht öffnen: {str(e)}")
|
QMessageBox.critical(self, "Fehler", f"Konnte PDFs nicht laden:\n{str(e)}")
|
||||||
|
|
||||||
def _update_diff_icons_for_existing_pdfs(self):
|
def _update_diff_icons_for_existing_pdfs(self):
|
||||||
"""
|
"""
|
||||||
@@ -1410,7 +1513,7 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
if expected_pdf.exists():
|
if expected_pdf.exists():
|
||||||
# Icon setzen
|
# Icon setzen
|
||||||
icon_widget = self._create_centered_diff_icon(xml_path)
|
icon_widget = self._create_centered_diff_icon(xml_path, xsl_id_str)
|
||||||
self.ui.treeWidget.setItemWidget(tree_item, 2, icon_widget)
|
self.ui.treeWidget.setItemWidget(tree_item, 2, icon_widget)
|
||||||
icon_count += 1
|
icon_count += 1
|
||||||
logger.debug(f"Diff-Icon für existierende PDF gesetzt: {map_key}")
|
logger.debug(f"Diff-Icon für existierende PDF gesetzt: {map_key}")
|
||||||
@@ -3138,7 +3241,7 @@ class MainWindow(QMainWindow):
|
|||||||
# Wenn Diff-PDF existiert, zeige Icon
|
# Wenn Diff-PDF existiert, zeige Icon
|
||||||
if diff_pdf_str and Path(diff_pdf_str).exists():
|
if diff_pdf_str and Path(diff_pdf_str).exists():
|
||||||
xml_file_path = Path(xml_file_str)
|
xml_file_path = Path(xml_file_str)
|
||||||
icon_widget = self._create_centered_diff_icon(xml_file_path)
|
icon_widget = self._create_centered_diff_icon(xml_file_path, xsl_id_str)
|
||||||
self.ui.treeWidget.setItemWidget(tree_item, 2, icon_widget)
|
self.ui.treeWidget.setItemWidget(tree_item, 2, icon_widget)
|
||||||
logger.debug(f"Diff-Icon für {xml_file_str} gesetzt")
|
logger.debug(f"Diff-Icon für {xml_file_str} gesetzt")
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user