diff --git a/src/ui/AppSettings.py b/src/ui/AppSettings.py index a149476..7784af5 100644 --- a/src/ui/AppSettings.py +++ b/src/ui/AppSettings.py @@ -116,7 +116,9 @@ class AppSettingsDlg(QDialog): self.ui.tableDiffPdfs.doubleClicked.connect(self._edit_diff_pdf) # PDF-Projekte Tabelle - self.ui.tablePdfProjects.setHorizontalHeaderLabels(["Name", "Projekt-Ordner", "XSL-Ordner", "Java-VM", "Saxon", "Apache FOP", "Diff-PDF"]) + self.ui.tablePdfProjects.setHorizontalHeaderLabels( + ["Name", "Projekt-Ordner", "XSL-Ordner", "Java-VM", "Saxon", "Apache FOP", "Diff-PDF"] + ) self.ui.tablePdfProjects.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers) self.ui.tablePdfProjects.doubleClicked.connect(self._edit_pdf_project) @@ -142,7 +144,7 @@ class AppSettingsDlg(QDialog): name_item = QTableWidgetItem(xsl_dir.name) name_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableXsls.setItem(row, 0, name_item) - + path_item = QTableWidgetItem(str(xsl_dir.path_to_root_dir)) path_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableXsls.setItem(row, 1, path_item) @@ -155,7 +157,7 @@ class AppSettingsDlg(QDialog): version_item = QTableWidgetItem(java_vm.version) version_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableJavaVms.setItem(row, 0, version_item) - + path_item = QTableWidgetItem(str(java_vm.path_to_binary_file)) path_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableJavaVms.setItem(row, 1, path_item) @@ -168,11 +170,11 @@ class AppSettingsDlg(QDialog): version_item = QTableWidgetItem(saxon.version) version_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableSaxons.setItem(row, 0, version_item) - + path_item = QTableWidgetItem(str(saxon.path_to_jar_file)) path_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableSaxons.setItem(row, 1, path_item) - + extension_item = QTableWidgetItem(saxon.output_file_extension) extension_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableSaxons.setItem(row, 2, extension_item) @@ -185,11 +187,11 @@ class AppSettingsDlg(QDialog): version_item = QTableWidgetItem(fop.version) version_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableApacheFops.setItem(row, 0, version_item) - + path_item = QTableWidgetItem(str(fop.path_to_dir)) path_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableApacheFops.setItem(row, 1, path_item) - + extension_item = QTableWidgetItem(fop.output_file_extension) extension_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableApacheFops.setItem(row, 2, extension_item) @@ -202,15 +204,15 @@ class AppSettingsDlg(QDialog): version_item = QTableWidgetItem(diff_pdf.version) version_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableDiffPdfs.setItem(row, 0, version_item) - + path_item = QTableWidgetItem(str(diff_pdf.path_to_binary_file)) path_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableDiffPdfs.setItem(row, 1, path_item) - + params_item = QTableWidgetItem(", ".join(diff_pdf.default_params)) params_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableDiffPdfs.setItem(row, 2, params_item) - + extension_item = QTableWidgetItem(diff_pdf.output_file_extension) extension_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tableDiffPdfs.setItem(row, 3, extension_item) @@ -223,27 +225,27 @@ class AppSettingsDlg(QDialog): name_item = QTableWidgetItem(pdf_project.name) name_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tablePdfProjects.setItem(row, 0, name_item) - + project_dir_item = QTableWidgetItem(str(pdf_project.project_dir)) project_dir_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tablePdfProjects.setItem(row, 1, project_dir_item) - + xsl_item = QTableWidgetItem(pdf_project.getXsl()) xsl_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tablePdfProjects.setItem(row, 2, xsl_item) - + java_vm_item = QTableWidgetItem(pdf_project.getJavaVm()) java_vm_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tablePdfProjects.setItem(row, 3, java_vm_item) - + saxon_item = QTableWidgetItem(pdf_project.getSaxon()) saxon_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tablePdfProjects.setItem(row, 4, saxon_item) - + apache_fop_item = QTableWidgetItem(pdf_project.getApacheFop()) apache_fop_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tablePdfProjects.setItem(row, 5, apache_fop_item) - + diff_pdf_item = QTableWidgetItem(pdf_project.getDiffPdf()) diff_pdf_item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) self.ui.tablePdfProjects.setItem(row, 6, diff_pdf_item) @@ -291,6 +293,11 @@ class AppSettingsDlg(QDialog): # FopWorkerPool-Checkbox setzen self.ui.checkBoxUseFopPool.setChecked(self.settings.use_fop_worker_pool) + def _refresh_main_window_projects_menu(self): + """Aktualisiert das Projekte-Menü im MainWindow, falls vorhanden.""" + if self.parent() and hasattr(self.parent(), "_setup_projects_menu"): + self.parent()._setup_projects_menu() + # XSL-Ordner Methoden def _add_xsl_dir(self): """Fügt einen neuen XSL-Ordner hinzu.""" @@ -303,9 +310,10 @@ class AppSettingsDlg(QDialog): new_xsl_dir = XslDir(id=new_id, name=data["name"], path_to_root_dir=data["path_to_root_dir"]) self.temp_xsl_dirs.append(new_xsl_dir) self._populate_xsl_table() - + self.settings.xsl_dirs = self.temp_xsl_dirs.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _remove_xsl_dir(self): """Entfernt den ausgewählten XSL-Ordner.""" @@ -314,9 +322,10 @@ class AppSettingsDlg(QDialog): del self.temp_xsl_dirs[current_row] self._populate_xsl_table() self._update_xsl_buttons() - + self.settings.xsl_dirs = self.temp_xsl_dirs.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _update_xsl_buttons(self): """Aktualisiert den Status der XSL-Buttons.""" @@ -336,9 +345,10 @@ class AppSettingsDlg(QDialog): ) self.temp_java_vms.append(new_java_vm) self._populate_java_vm_table() - + self.settings.java_vms = self.temp_java_vms.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _remove_java_vm(self): """Entfernt die ausgewählte Java VM.""" @@ -347,9 +357,10 @@ class AppSettingsDlg(QDialog): del self.temp_java_vms[current_row] self._populate_java_vm_table() self._update_java_vm_buttons() - + self.settings.java_vms = self.temp_java_vms.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _update_java_vm_buttons(self): """Aktualisiert den Status der Java VM-Buttons.""" @@ -372,9 +383,10 @@ class AppSettingsDlg(QDialog): ) self.temp_saxon_jars.append(new_saxon) self._populate_saxon_table() - + self.settings.saxon_jars = self.temp_saxon_jars.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _remove_saxon(self): """Entfernt die ausgewählte Saxon JAR.""" @@ -383,9 +395,10 @@ class AppSettingsDlg(QDialog): del self.temp_saxon_jars[current_row] self._populate_saxon_table() self._update_saxon_buttons() - + self.settings.saxon_jars = self.temp_saxon_jars.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _update_saxon_buttons(self): """Aktualisiert den Status der Saxon-Buttons.""" @@ -408,9 +421,10 @@ class AppSettingsDlg(QDialog): ) self.temp_apache_fops.append(new_fop) self._populate_apache_fop_table() - + self.settings.apache_fops = self.temp_apache_fops.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _remove_apache_fop(self): """Entfernt die ausgewählte Apache FOP Konfiguration.""" @@ -419,9 +433,10 @@ class AppSettingsDlg(QDialog): del self.temp_apache_fops[current_row] self._populate_apache_fop_table() self._update_apache_fop_buttons() - + self.settings.apache_fops = self.temp_apache_fops.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _update_apache_fop_buttons(self): """Aktualisiert den Status der Apache FOP-Buttons.""" @@ -445,9 +460,10 @@ class AppSettingsDlg(QDialog): ) self.temp_diff_pdfs.append(new_diff_pdf) self._populate_diff_pdf_table() - + self.settings.diff_pdfs = self.temp_diff_pdfs.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _remove_diff_pdf(self): """Entfernt die ausgewählte Diff PDF Konfiguration.""" @@ -456,9 +472,10 @@ class AppSettingsDlg(QDialog): del self.temp_diff_pdfs[current_row] self._populate_diff_pdf_table() self._update_diff_pdf_buttons() - + self.settings.diff_pdfs = self.temp_diff_pdfs.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _update_diff_pdf_buttons(self): """Aktualisiert den Status der Diff PDF-Buttons.""" @@ -471,29 +488,30 @@ class AppSettingsDlg(QDialog): dialog = PdfProjectDlg(self) if dialog.exec() == PdfProjectDlg.DialogCode.Accepted: project_data = dialog.get_project_data() - + # Neue ID generieren new_id = max([p.id for p in self.temp_pdf_projects], default=0) + 1 - + # Erstelle PdfProject-Objekt new_project = Project( id=new_id, - name=project_data['name'], - project_dir=Path(project_data['project_dir']), - java_vm_id=project_data['java_vm_id'] if project_data['java_vm_id'] != -1 else 1, - diff_pdf_id=project_data['diff_pdf_id'] if project_data['diff_pdf_id'] != -1 else 1, - saxon_jar_id=project_data['saxon_jar_id'] if project_data['saxon_jar_id'] != -1 else 1, - 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, + name=project_data["name"], + project_dir=Path(project_data["project_dir"]), + java_vm_id=project_data["java_vm_id"] if project_data["java_vm_id"] != -1 else 1, + diff_pdf_id=project_data["diff_pdf_id"] if project_data["diff_pdf_id"] != -1 else 1, + saxon_jar_id=project_data["saxon_jar_id"] if project_data["saxon_jar_id"] != -1 else 1, + 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) self._populate_pdf_project_table() - + self.settings.pdf_projects = self.temp_pdf_projects.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _remove_pdf_project(self): """Entfernt das ausgewählte PDF-Projekt.""" @@ -502,9 +520,10 @@ class AppSettingsDlg(QDialog): del self.temp_pdf_projects[current_row] self._populate_pdf_project_table() self._update_pdf_project_buttons() - + self.settings.pdf_projects = self.temp_pdf_projects.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _update_pdf_project_buttons(self): """Aktualisiert den Status der PDF-Projekt-Buttons.""" @@ -629,40 +648,57 @@ class AppSettingsDlg(QDialog): row = index.row() if 0 <= row < len(self.temp_pdf_projects): pdf_project = self.temp_pdf_projects[row] - + # Projektdaten für Dialog vorbereiten project_data = { - 'name': pdf_project.name, - 'project_dir': str(pdf_project.project_dir), - 'java_vm_id': pdf_project.java_vm_id, - '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, - '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 + "name": pdf_project.name, + "project_dir": str(pdf_project.project_dir), + "java_vm_id": pdf_project.java_vm_id, + "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, + "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) dialog = PdfProjectDlg(self, project_data, edit_mode=True) - + if dialog.exec() == PdfProjectDlg.DialogCode.Accepted: new_data = dialog.get_project_data() - + # Nur die Einstellungen aktualisieren (Name und Ordner bleiben unverändert) - pdf_project.java_vm_id = new_data['java_vm_id'] if new_data['java_vm_id'] != -1 else pdf_project.java_vm_id - pdf_project.diff_pdf_id = new_data['diff_pdf_id'] if new_data['diff_pdf_id'] != -1 else pdf_project.diff_pdf_id - 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 + pdf_project.java_vm_id = ( + new_data["java_vm_id"] if new_data["java_vm_id"] != -1 else pdf_project.java_vm_id + ) + pdf_project.diff_pdf_id = ( + new_data["diff_pdf_id"] if new_data["diff_pdf_id"] != -1 else pdf_project.diff_pdf_id + ) + 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() + self._refresh_main_window_projects_menu() # PostgreSQL Methoden def _add_postgresql_db(self): @@ -679,13 +715,14 @@ class AppSettingsDlg(QDialog): port=data["port"], database=data["database"], username=data["username"], - password=data["password"] + password=data["password"], ) self.temp_postgresql_dbs.append(new_postgresql_db) self._populate_postgresql_db_table() - + self.settings.postgresql_dbs = self.temp_postgresql_dbs.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _remove_postgresql_db(self): """Entfernt die ausgewählte PostgreSQL-Datenbank.""" @@ -694,9 +731,10 @@ class AppSettingsDlg(QDialog): del self.temp_postgresql_dbs[current_row] self._populate_postgresql_db_table() self._update_postgresql_db_buttons() - + self.settings.postgresql_dbs = self.temp_postgresql_dbs.copy() self.settings.save() + self._refresh_main_window_projects_menu() def _update_postgresql_db_buttons(self): """Aktualisiert den Status der PostgreSQL-Buttons.""" @@ -717,7 +755,7 @@ class AppSettingsDlg(QDialog): "port": postgresql_db.port, "database": postgresql_db.database, "username": postgresql_db.username, - "password": postgresql_db.password + "password": postgresql_db.password, } dialog.set_data(data) @@ -756,6 +794,7 @@ class AppSettingsDlg(QDialog): self.settings.use_fop_worker_pool = self.ui.checkBoxUseFopPool.isChecked() self.settings.save() + self._refresh_main_window_projects_menu() super().accept() diff --git a/src/ui/MainWindow.py b/src/ui/MainWindow.py index d6764e5..072454b 100644 --- a/src/ui/MainWindow.py +++ b/src/ui/MainWindow.py @@ -191,22 +191,47 @@ class MainWindow( def _setup_projects_menu(self): """Initialisiert das Vorhandene Projekte-Menü mit gespeicherten Projekten.""" + # Entferne das alte Untermenü, falls vorhanden + old_menu = self.ui.actionVorhandene_Projekte.menu() + if old_menu: + old_menu.clear() + old_menu.deleteLater() + # Prüfe ob Projekte vorhanden sind if not app_settings.pdf_projects: - # Keine Projekte vorhanden - Menü deaktiviert lassen + # Keine Projekte vorhanden - Menü deaktivieren self.ui.actionVorhandene_Projekte.setEnabled(False) self.ui.actionVorhandene_Projekte.setText("Vorhandene Projekte (keine vorhanden)") + logger.info("Projekte-Menü deaktiviert - keine Projekte vorhanden") return - # Projekte vorhanden - Menü aktivieren und Untermenü erstellen + # Filtere nur existierende Projekte + valid_projects = [] + invalid_projects = [] + + for project in app_settings.pdf_projects: + if project.project_dir.exists(): + valid_projects.append(project) + else: + invalid_projects.append(project) + logger.warning(f"Projekt-Verzeichnis existiert nicht: {project.name} → {project.project_dir}") + + # Wenn keine gültigen Projekte vorhanden sind + if not valid_projects: + self.ui.actionVorhandene_Projekte.setEnabled(False) + self.ui.actionVorhandene_Projekte.setText("Vorhandene Projekte (keine gültigen vorhanden)") + logger.warning(f"Projekte-Menü deaktiviert - {len(invalid_projects)} ungültige(s) Projekt(e) gefunden") + return + + # Gültige Projekte vorhanden - Menü aktivieren und Untermenü erstellen self.ui.actionVorhandene_Projekte.setEnabled(True) self.ui.actionVorhandene_Projekte.setText("Vorhandene Projekte") # Erstelle ein Untermenü für die Projekte projects_menu = QMenu(self) - # Füge jedes Projekt als Menü-Eintrag hinzu - for project in app_settings.pdf_projects: + # Füge jedes gültige Projekt als Menü-Eintrag hinzu + for project in valid_projects: project_action = QAction(project.name, self) project_action.setToolTip(f"Projekt-Ordner: {project.project_dir}") @@ -218,7 +243,9 @@ class MainWindow( # Setze das Untermenü für die Aktion self.ui.actionVorhandene_Projekte.setMenu(projects_menu) - logger.info(f"Projekte-Menü initialisiert mit {len(app_settings.pdf_projects)} Projekten") + logger.info(f"Projekte-Menü initialisiert mit {len(valid_projects)} gültigen Projekt(en)") + if invalid_projects: + logger.warning(f"{len(invalid_projects)} ungültige(s) Projekt(e) ausgeblendet") def open_existing_project(self, project: Project): """