From 90100e0e43d6a9b6c7e5fa9667d404943cc46caf Mon Sep 17 00:00:00 2001 From: srfwb Date: Mon, 11 May 2026 14:14:38 +0100 Subject: [PATCH 1/2] Fix silent save failure when file write is denied --- meadowpy/core/file_manager.py | 5 +++-- meadowpy/ui/controllers/workspace_controller.py | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/meadowpy/core/file_manager.py b/meadowpy/core/file_manager.py index dc77534..b997ca4 100644 --- a/meadowpy/core/file_manager.py +++ b/meadowpy/core/file_manager.py @@ -1,7 +1,7 @@ """File I/O operations: open, save, save-as.""" from PyQt6.QtCore import QObject, pyqtSignal -from PyQt6.QtWidgets import QFileDialog +from PyQt6.QtWidgets import QFileDialog, QMessageBox from meadowpy.core.settings import Settings from meadowpy.core.recent_files import RecentFilesManager @@ -41,7 +41,8 @@ def save_file(self, file_path: str, content: str) -> bool: self._recent_files.add(file_path) self.file_saved.emit(file_path) return True - except OSError: + except OSError as e: + QMessageBox.critical(None, "Error", f"Could not save file:\n{e}") return False def save_file_as(self, content: str, parent=None) -> str | None: diff --git a/meadowpy/ui/controllers/workspace_controller.py b/meadowpy/ui/controllers/workspace_controller.py index aa550a4..ab8c337 100644 --- a/meadowpy/ui/controllers/workspace_controller.py +++ b/meadowpy/ui/controllers/workspace_controller.py @@ -148,9 +148,9 @@ def action_save(self) -> None: if not editor: return if editor.file_path: - self._file_manager.save_file(editor.file_path, editor.text()) - editor.setModified(False) - self._tab_manager.update_tab_title(self._tab_manager.currentIndex()) + if self._file_manager.save_file(editor.file_path, editor.text()): + editor.setModified(False) + self._tab_manager.update_tab_title(self._tab_manager.currentIndex()) else: self.action_save_as() From 1a5c408795e3cc1c729410a2fe7e66170f742b9d Mon Sep 17 00:00:00 2001 From: srfwb Date: Tue, 12 May 2026 23:25:21 +0100 Subject: [PATCH 2/2] Move error dialog to controller and fix test --- dev/tests/test_workspace_controller.py | 2 +- meadowpy/core/file_manager.py | 5 ++--- meadowpy/ui/controllers/workspace_controller.py | 5 +++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dev/tests/test_workspace_controller.py b/dev/tests/test_workspace_controller.py index 7345ccd..92b745a 100644 --- a/dev/tests/test_workspace_controller.py +++ b/dev/tests/test_workspace_controller.py @@ -250,7 +250,7 @@ def test_save_and_save_as_update_editor_state_and_tab_title(tmp_path): tabs = WorkspaceTabs([editor]) file_manager = SimpleNamespace( saved=[], - save_file=lambda path, text: file_manager.saved.append((path, text)), + save_file=lambda path, text: file_manager.saved.append((path, text)) or True, save_file_as=lambda text, parent=None: str(tmp_path / "saved_as.py"), ) window = SimpleNamespace(_tab_manager=tabs, _file_manager=file_manager) diff --git a/meadowpy/core/file_manager.py b/meadowpy/core/file_manager.py index b997ca4..dc77534 100644 --- a/meadowpy/core/file_manager.py +++ b/meadowpy/core/file_manager.py @@ -1,7 +1,7 @@ """File I/O operations: open, save, save-as.""" from PyQt6.QtCore import QObject, pyqtSignal -from PyQt6.QtWidgets import QFileDialog, QMessageBox +from PyQt6.QtWidgets import QFileDialog from meadowpy.core.settings import Settings from meadowpy.core.recent_files import RecentFilesManager @@ -41,8 +41,7 @@ def save_file(self, file_path: str, content: str) -> bool: self._recent_files.add(file_path) self.file_saved.emit(file_path) return True - except OSError as e: - QMessageBox.critical(None, "Error", f"Could not save file:\n{e}") + except OSError: return False def save_file_as(self, content: str, parent=None) -> str | None: diff --git a/meadowpy/ui/controllers/workspace_controller.py b/meadowpy/ui/controllers/workspace_controller.py index ab8c337..7c6bb7c 100644 --- a/meadowpy/ui/controllers/workspace_controller.py +++ b/meadowpy/ui/controllers/workspace_controller.py @@ -151,6 +151,11 @@ def action_save(self) -> None: if self._file_manager.save_file(editor.file_path, editor.text()): editor.setModified(False) self._tab_manager.update_tab_title(self._tab_manager.currentIndex()) + else: + QMessageBox.critical( + self.window, "Error", + f"Could not save file:\n{editor.file_path}", + ) else: self.action_save_as()