""" Info-Dialog für DocuMentor. Zeigt Programmversion, Python-Version und alle Drittanbieter-Bibliotheken mit installierten Versionen und Lizenzinformationen an. """ import logging import sys from importlib.metadata import PackageNotFoundError, version from pathlib import Path from PySide6.QtCore import Qt from PySide6.QtGui import QFont from PySide6.QtWidgets import ( QDialog, QDialogButtonBox, QFrame, QHBoxLayout, QHeaderView, QLabel, QTableWidget, QTableWidgetItem, QVBoxLayout, ) from license_parser import parse_license_file logger = logging.getLogger(__name__) class AboutDialog(QDialog): """Info-Dialog mit Versionsinformationen und Drittanbieter-Lizenzen.""" def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Über DocuMentor") self.resize(950, 620) self.setSizeGripEnabled(True) self.setModal(True) self._setup_ui() self._populate_data() def _get_app_version(self) -> str: """Ermittelt die Programmversion.""" try: return version("DocuMentor") except PackageNotFoundError: # Fallback: pyproject.toml parsen (PyInstaller-Bundle oder Entwicklungsmodus) try: import tomllib if hasattr(sys, "_MEIPASS"): pyproject = Path(sys._MEIPASS) / "pyproject.toml" # type: ignore[attr-defined] else: pyproject = Path(__file__).parent.parent.parent / "pyproject.toml" with open(pyproject, "rb") as f: return tomllib.load(f)["project"]["version"] except Exception: return "unbekannt" def _setup_ui(self): """Erstellt das Dialog-Layout programmatisch.""" layout = QVBoxLayout(self) layout.setSpacing(8) # App-Name self.app_name_label = QLabel("DocuMentor") font = QFont() font.setPointSize(18) font.setBold(True) self.app_name_label.setFont(font) self.app_name_label.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(self.app_name_label) # Beschreibung self.description_label = QLabel("Professionelle XSL-Transformations-Verwaltung und PDF-Generierung") self.description_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.description_label.setWordWrap(True) layout.addWidget(self.description_label) # Version + Python-Version self.version_label = QLabel() self.version_label.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(self.version_label) # Lizenz self.license_label = QLabel("Lizenz: MIT") self.license_label.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(self.license_label) # Separator separator = QFrame() separator.setFrameShape(QFrame.Shape.HLine) separator.setFrameShadow(QFrame.Shadow.Sunken) layout.addWidget(separator) # Überschrift für Tabelle header_layout = QHBoxLayout() table_header = QLabel("Drittanbieter-Bibliotheken:") header_font = QFont() header_font.setBold(True) table_header.setFont(header_font) header_layout.addWidget(table_header) header_layout.addStretch() layout.addLayout(header_layout) # Dependency-Tabelle self.table = QTableWidget() self.table.setColumnCount(6) self.table.setHorizontalHeaderLabels(["Name", "Lizenz", "Installiert", "Webseite", "Copyright", "Kategorie"]) self.table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers) self.table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows) self.table.setAlternatingRowColors(True) self.table.setSortingEnabled(True) self.table.verticalHeader().setVisible(False) # Spaltenbreiten header = self.table.horizontalHeader() header.resizeSection(0, 170) # Name header.resizeSection(1, 180) # Lizenz header.resizeSection(2, 80) # Installiert header.resizeSection(5, 200) # Kategorie header.setSectionResizeMode(3, QHeaderView.ResizeMode.Stretch) # Webseite header.setSectionResizeMode(4, QHeaderView.ResizeMode.Stretch) # Copyright layout.addWidget(self.table) # Schließen-Button button_box = QDialogButtonBox(QDialogButtonBox.StandardButton.Close) button_box.rejected.connect(self.reject) button_box.setCenterButtons(True) layout.addWidget(button_box) def _populate_data(self): """Befüllt den Dialog mit Versions- und Lizenzinformationen.""" # Version setzen app_version = self._get_app_version() python_version = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}" self.version_label.setText(f"Version: {app_version} | Python: {python_version}") # Lizenzdaten laden und Tabelle befüllen parsed = parse_license_file() self.table.setRowCount(len(parsed.entries)) for row, entry in enumerate(parsed.entries): self.table.setItem(row, 0, QTableWidgetItem(entry.name)) self.table.setItem(row, 1, QTableWidgetItem(entry.license)) self.table.setItem(row, 2, QTableWidgetItem(entry.installed_version or "—")) if entry.website: website_label = QLabel(f'{entry.website}') website_label.setOpenExternalLinks(True) website_label.setTextInteractionFlags(Qt.TextInteractionFlag.TextBrowserInteraction) self.table.setCellWidget(row, 3, website_label) else: self.table.setItem(row, 3, QTableWidgetItem("")) self.table.setItem(row, 4, QTableWidgetItem(entry.copyright)) self.table.setItem(row, 5, QTableWidgetItem(entry.category))