diff --git a/src/ui/MainWindow.py b/src/ui/MainWindow.py index 64c182b..c21485d 100644 --- a/src/ui/MainWindow.py +++ b/src/ui/MainWindow.py @@ -675,13 +675,12 @@ class MainWindow(QMainWindow): if alpha_value <= 0: # Alpha von -100 bis 0: Übergang von ref zu diff - ref_opacity = 1.0 # - (alpha_value + 100) / 100.0 - diff_opacity = (alpha_value + 100) / 100.0 + ref_opacity = abs(alpha_value) / 100 + diff_opacity = 1.0 - abs(alpha_value) / 100.0 new_opacity = 0.0 else: - # Alpha von 0 bis 100: Übergang von diff zu new 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 # Zeichne die Ebenen mit entsprechender Transparenz @@ -1304,12 +1303,13 @@ class MainWindow(QMainWindow): 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. 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: QWidget: Container mit klickbarem Icon @@ -1324,57 +1324,160 @@ class MainWindow(QMainWindow): icon_label = QLabel() icon_label.setPixmap(QIcon.fromTheme("document-preview").pixmap(16, 16)) 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) - icon_label.mouseDoubleClickEvent = lambda event: self._open_diff_pdf(xml_file_path) + # Klick-Event für Icon (Doppelklick lädt PDF in Viewer) + icon_label.mouseDoubleClickEvent = lambda event: self._load_pdf_for_comparison(xml_file_path, xsl_id_str) layout.addWidget(icon_label) 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: 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: - # Ermittle Diff-PDF-Pfad basierend auf XML-Datei - # WICHTIG: Berücksichtige XSL-ID im Dateinamen! - # 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") + if not self.project: + QMessageBox.warning(self, "Fehler", "Kein Projekt geöffnet") return - # Bei mehreren: Nehme neueste - diff_pdf = max(matching_pdfs, key=lambda p: p.stat().st_mtime) + # Ermittle PDF-Dateinamen basierend auf XML und XSL-ID + 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 - if sys.platform == "win32": - subprocess.Popen(["start", str(diff_pdf)], shell=True) - elif sys.platform == "darwin": - subprocess.Popen(["open", str(diff_pdf)]) - else: - subprocess.Popen(["xdg-open", str(diff_pdf)]) + diff_pdf_path = diff_dir / pdf_basename + ref_pdf_path = ref_dir / pdf_basename + new_pdf_path = new_dir / pdf_basename - 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: - logger.error(f"Fehler beim Öffnen der Diff-PDF: {e}") - QMessageBox.critical(self, "Fehler", f"Konnte Diff-PDF nicht öffnen: {str(e)}") + logger.error(f"Fehler beim Laden der PDFs für Vergleich: {e}") + QMessageBox.critical(self, "Fehler", f"Konnte PDFs nicht laden:\n{str(e)}") def _update_diff_icons_for_existing_pdfs(self): """ @@ -1410,7 +1513,7 @@ class MainWindow(QMainWindow): if expected_pdf.exists(): # 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) icon_count += 1 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 if diff_pdf_str and Path(diff_pdf_str).exists(): 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) logger.debug(f"Diff-Icon für {xml_file_str} gesetzt") else: