diff --git a/src/conf.py b/src/conf.py index 723c2ea..34a6766 100644 --- a/src/conf.py +++ b/src/conf.py @@ -93,6 +93,7 @@ class Project(BaseModel): apache_fop_id: int = Field(..., description="ID der Apache FOP Konfiguration", gt=0) xsl_dir_id: int = Field(..., description="ID des XSL-Verzeichnisses", gt=0) postgre_sql_db_id: int = Field(..., description="ID der PostgreSQL Datenbank", gt=0) + fop_config_dir: Path | None = Field(None, description="Optionaler Pfad zum Apache FOP Config-Verzeichnis") def getXsl(self) -> str: global app_settings diff --git a/src/transform.py b/src/transform.py index ea0b1ff..81760be 100644 --- a/src/transform.py +++ b/src/transform.py @@ -35,6 +35,7 @@ class TransformationJob: diff_pdf_path: Path, diff_pdf_params: list[str], xsl_id: tuple | None = None, + fop_config_dir: Path | None = None, ): """ Initialisiert einen Transformations-Job. @@ -50,6 +51,7 @@ class TransformationJob: diff_pdf_path: Pfad zur diff-pdf Binary diff_pdf_params: Standard-Parameter für diff-pdf xsl_id: ID der XSL-Datei (als Tuple) + fop_config_dir: Optionaler Pfad zum FOP-Config-Verzeichnis (überschreibt Standardpfad) """ self.project_dir = project_dir self.xml_file = xml_file # Relativ @@ -61,6 +63,7 @@ class TransformationJob: self.java_vm_path = java_vm_path self.saxon_jar_path = saxon_jar_path self.apache_fop_dir = apache_fop_dir + self.fop_config_dir = fop_config_dir self.diff_pdf_path = diff_pdf_path self.diff_pdf_params = diff_pdf_params @@ -98,7 +101,11 @@ class TransformationJob: else: self.fop_cmd = self.apache_fop_dir / "fop" - self.fop_conf = self.apache_fop_dir / "conf" / "fop.xconf" + # FOP-Konfigurationsdatei: Verwende fop_config_dir falls angegeben, sonst Standardpfad + if self.fop_config_dir: + self.fop_conf = self.fop_config_dir / "fop.xconf" + else: + self.fop_conf = self.apache_fop_dir / "conf" / "fop.xconf" def is_up_to_date(self) -> bool: """ @@ -200,6 +207,12 @@ class TransformationJob: timeout=120, # 2 Minuten Timeout ) + # Saxon Ausgaben loggen + if result.stdout: + logger.debug(f"Saxon StdOut:\n{result.stdout}") + if result.stderr: + logger.debug(f"Saxon StdErr:\n{result.stderr}") + if result.returncode == 0: logger.info(f"Saxon-Transformation erfolgreich: {self.xml_file.name}") return True, "Erfolgreich" @@ -266,6 +279,12 @@ class TransformationJob: timeout=180, # 3 Minuten Timeout ) + # Apache FOP Ausgaben loggen + if result.stdout: + logger.debug(f"FOP StdOut:\n{result.stdout}") + if result.stderr: + logger.debug(f"FOP StdErr:\n{result.stderr}") + # Temporäre FO-Datei löschen if self.temp_fo.exists(): try: diff --git a/src/ui/AppSettings.py b/src/ui/AppSettings.py index 7310a6a..09c791e 100644 --- a/src/ui/AppSettings.py +++ b/src/ui/AppSettings.py @@ -466,6 +466,7 @@ class AppSettingsDlg(QDialog): apache_fop_id=project_data['apache_fop_id'] if project_data['apache_fop_id'] != -1 else 1, xsl_dir_id=project_data['xsl_dir_id'] if project_data['xsl_dir_id'] != -1 else 1, postgre_sql_db_id=project_data['postgre_sql_db_id'] if project_data['postgre_sql_db_id'] != -1 else 1, + fop_config_dir=Path(project_data['fop_config_dir']) if project_data.get('fop_config_dir') else None, ) self.temp_pdf_projects.append(new_project) @@ -617,7 +618,9 @@ class AppSettingsDlg(QDialog): 'diff_pdf_id': pdf_project.diff_pdf_id, 'saxon_jar_id': pdf_project.saxon_jar_id, 'apache_fop_id': pdf_project.apache_fop_id, - 'xsl_dir_id': pdf_project.xsl_dir_id + 'xsl_dir_id': pdf_project.xsl_dir_id, + 'postgre_sql_db_id': pdf_project.postgre_sql_db_id, + 'fop_config_dir': str(pdf_project.fop_config_dir) if pdf_project.fop_config_dir else None } # Dialog im Edit-Modus öffnen (Projekt-Name und -Ordner deaktiviert) @@ -632,9 +635,15 @@ class AppSettingsDlg(QDialog): pdf_project.saxon_jar_id = new_data['saxon_jar_id'] if new_data['saxon_jar_id'] != -1 else pdf_project.saxon_jar_id pdf_project.apache_fop_id = new_data['apache_fop_id'] if new_data['apache_fop_id'] != -1 else pdf_project.apache_fop_id pdf_project.xsl_dir_id = new_data['xsl_dir_id'] if new_data['xsl_dir_id'] != -1 else pdf_project.xsl_dir_id - + pdf_project.postgre_sql_db_id = new_data['postgre_sql_db_id'] if new_data['postgre_sql_db_id'] != -1 else pdf_project.postgre_sql_db_id + pdf_project.fop_config_dir = Path(new_data['fop_config_dir']) if new_data.get('fop_config_dir') else None + self._populate_pdf_project_table() + # Einstellungen speichern + self.settings.pdf_projects = self.temp_pdf_projects.copy() + self.settings.save() + # PostgreSQL Methoden def _add_postgresql_db(self): """Fügt eine neue PostgreSQL-Datenbank hinzu.""" diff --git a/src/ui/MainWindow.py b/src/ui/MainWindow.py index 0a14c69..b129ebb 100644 --- a/src/ui/MainWindow.py +++ b/src/ui/MainWindow.py @@ -1000,6 +1000,7 @@ class MainWindow(QMainWindow): postgre_sql_db_id=project_data["postgre_sql_db_id"] if project_data["postgre_sql_db_id"] != -1 else 1, + fop_config_dir=Path(project_data["fop_config_dir"]) if project_data.get("fop_config_dir") else None, ) # Erstelle Projekt-Ordnerstruktur @@ -3348,6 +3349,7 @@ class MainWindow(QMainWindow): diff_pdf_path=diff_pdf.path_to_binary_file, diff_pdf_params=diff_pdf.default_params, xsl_id=xsl_file_obj.id, + fop_config_dir=self.project.fop_config_dir, ) return job diff --git a/src/ui/PdfProject.py b/src/ui/PdfProject.py index 1cd004f..21af868 100644 --- a/src/ui/PdfProject.py +++ b/src/ui/PdfProject.py @@ -49,11 +49,14 @@ class PdfProjectDlg(QDialog): """Verbindet die Signale mit den entsprechenden Slots.""" # Browse-Button für Projekt-Ordner self.ui.pushButton.clicked.connect(self.browse_project_dir) - + + # Browse-Button für FOP-Config-Ordner + self.ui.btnBrowseFopConfig.clicked.connect(self.browse_fop_config_dir) + # OK/Cancel Buttons sind bereits in der UI-Datei verbunden # self.ui.buttonBox.accepted.connect(self.accept) # self.ui.buttonBox.rejected.connect(self.reject) - + # Überschreibe accept() für Validierung self.ui.buttonBox.accepted.disconnect() self.ui.buttonBox.accepted.connect(self.validate_and_accept) @@ -132,6 +135,10 @@ class PdfProjectDlg(QDialog): if 'postgre_sql_db_id' in self.project_data: self._select_combo_by_data(self.ui.cB_Postgres, self.project_data['postgre_sql_db_id']) + + # FOP-Config-Ordner + if 'fop_config_dir' in self.project_data and self.project_data['fop_config_dir']: + self.ui.lineFopConfigDir.setText(str(self.project_data['fop_config_dir'])) def _select_combo_by_data(self, combo_box, data_value): """ @@ -166,7 +173,23 @@ class PdfProjectDlg(QDialog): if not self.ui.lineProjectName.text(): project_name = os.path.basename(selected_dir) self.ui.lineProjectName.setText(project_name) - + + def browse_fop_config_dir(self): + """Öffnet einen Dialog zum Auswählen des FOP-Config-Ordners.""" + current_dir = self.ui.lineFopConfigDir.text() + if not current_dir or not os.path.exists(current_dir): + current_dir = os.path.expanduser("~") + + selected_dir = QFileDialog.getExistingDirectory( + self, + "FOP-Config-Ordner auswählen", + current_dir, + QFileDialog.Option.ShowDirsOnly | QFileDialog.Option.DontResolveSymlinks + ) + + if selected_dir: + self.ui.lineFopConfigDir.setText(selected_dir) + def validate_and_accept(self): """Validiert die Eingaben und akzeptiert den Dialog.""" # Projekt-Name prüfen @@ -232,10 +255,11 @@ class PdfProjectDlg(QDialog): def get_project_data(self): """ Gibt die eingegebenen Projektdaten zurück. - + Returns: dict: Dictionary mit allen Projektdaten """ + fop_config_dir = self.ui.lineFopConfigDir.text().strip() return { 'name': self.ui.lineProjectName.text().strip(), 'project_dir': self.ui.lineProjectDir.text().strip(), @@ -244,7 +268,8 @@ class PdfProjectDlg(QDialog): 'saxon_jar_id': self.ui.cB_SaxonJar.currentData(), 'apache_fop_id': self.ui.cB_ApacheFop.currentData(), 'diff_pdf_id': self.ui.cB_Diff_Pdf.currentData(), - 'postgre_sql_db_id': self.ui.cB_Postgres.currentData() + 'postgre_sql_db_id': self.ui.cB_Postgres.currentData(), + 'fop_config_dir': fop_config_dir if fop_config_dir else None } def _configure_edit_mode(self): diff --git a/src/ui/PdfProject.ui b/src/ui/PdfProject.ui index a9a8f7f..37eecbd 100644 --- a/src/ui/PdfProject.ui +++ b/src/ui/PdfProject.ui @@ -7,7 +7,7 @@ 0 0 608 - 299 + 331 @@ -109,25 +109,66 @@ + + + FOP-Config-Ordner: + + + + diff-pdf: - + - + Postgres: - + + + + + QFrame::Shape::StyledPanel + + + QFrame::Shadow::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + Durchsuchen ... + + + + + + diff --git a/src/ui/PdfProject_ui.py b/src/ui/PdfProject_ui.py index 9054cfc..9045736 100644 --- a/src/ui/PdfProject_ui.py +++ b/src/ui/PdfProject_ui.py @@ -3,7 +3,7 @@ ################################################################################ ## Form generated from reading UI file 'PdfProject.ui' ## -## Created by: Qt User Interface Compiler version 6.9.1 +## Created by: Qt User Interface Compiler version 6.9.2 ## ## WARNING! All changes made in this file will be lost when recompiling UI file! ################################################################################ @@ -24,7 +24,7 @@ class Ui_projectDlg(object): def setupUi(self, projectDlg): if not projectDlg.objectName(): projectDlg.setObjectName(u"projectDlg") - projectDlg.resize(608, 299) + projectDlg.resize(608, 331) self.verticalLayout = QVBoxLayout(projectDlg) self.verticalLayout.setObjectName(u"verticalLayout") self.widget = QWidget(projectDlg) @@ -106,25 +106,50 @@ class Ui_projectDlg(object): self.formLayout.setWidget(5, QFormLayout.ItemRole.FieldRole, self.cB_ApacheFop) + self.label_9 = QLabel(self.widget) + self.label_9.setObjectName(u"label_9") + + self.formLayout.setWidget(6, QFormLayout.ItemRole.LabelRole, self.label_9) + self.label_7 = QLabel(self.widget) self.label_7.setObjectName(u"label_7") - self.formLayout.setWidget(6, QFormLayout.ItemRole.LabelRole, self.label_7) + self.formLayout.setWidget(7, QFormLayout.ItemRole.LabelRole, self.label_7) self.cB_Diff_Pdf = QComboBox(self.widget) self.cB_Diff_Pdf.setObjectName(u"cB_Diff_Pdf") - self.formLayout.setWidget(6, QFormLayout.ItemRole.FieldRole, self.cB_Diff_Pdf) + self.formLayout.setWidget(7, QFormLayout.ItemRole.FieldRole, self.cB_Diff_Pdf) self.label_8 = QLabel(self.widget) self.label_8.setObjectName(u"label_8") - self.formLayout.setWidget(7, QFormLayout.ItemRole.LabelRole, self.label_8) + self.formLayout.setWidget(8, QFormLayout.ItemRole.LabelRole, self.label_8) self.cB_Postgres = QComboBox(self.widget) self.cB_Postgres.setObjectName(u"cB_Postgres") - self.formLayout.setWidget(7, QFormLayout.ItemRole.FieldRole, self.cB_Postgres) + self.formLayout.setWidget(8, QFormLayout.ItemRole.FieldRole, self.cB_Postgres) + + self.frame_2 = QFrame(self.widget) + self.frame_2.setObjectName(u"frame_2") + self.frame_2.setFrameShape(QFrame.Shape.StyledPanel) + self.frame_2.setFrameShadow(QFrame.Shadow.Raised) + self.horizontalLayout_2 = QHBoxLayout(self.frame_2) + self.horizontalLayout_2.setObjectName(u"horizontalLayout_2") + self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0) + self.lineFopConfigDir = QLineEdit(self.frame_2) + self.lineFopConfigDir.setObjectName(u"lineFopConfigDir") + + self.horizontalLayout_2.addWidget(self.lineFopConfigDir) + + self.btnBrowseFopConfig = QPushButton(self.frame_2) + self.btnBrowseFopConfig.setObjectName(u"btnBrowseFopConfig") + + self.horizontalLayout_2.addWidget(self.btnBrowseFopConfig) + + + self.formLayout.setWidget(6, QFormLayout.ItemRole.FieldRole, self.frame_2) self.verticalLayout.addWidget(self.widget) @@ -154,7 +179,9 @@ class Ui_projectDlg(object): self.label_4.setText(QCoreApplication.translate("projectDlg", u"Java VM:", None)) self.label_5.setText(QCoreApplication.translate("projectDlg", u"Saxon Jar:", None)) self.label_6.setText(QCoreApplication.translate("projectDlg", u"Apache FOP:", None)) + self.label_9.setText(QCoreApplication.translate("projectDlg", u"FOP-Config-Ordner:", None)) self.label_7.setText(QCoreApplication.translate("projectDlg", u"diff-pdf:", None)) self.label_8.setText(QCoreApplication.translate("projectDlg", u"Postgres:", None)) + self.btnBrowseFopConfig.setText(QCoreApplication.translate("projectDlg", u"Durchsuchen ...", None)) # retranslateUi