From 7f9d8304bef685073205e2bb35a174bc350b5185 Mon Sep 17 00:00:00 2001 From: Daniel Dybing Date: Wed, 31 Dec 2025 14:20:01 +0100 Subject: [PATCH] Feat: Add Unsaved Changes warning on Exit/Close/Open --- src/teletext/ui.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/teletext/ui.py b/src/teletext/ui.py index b9ad22e..d14d505 100644 --- a/src/teletext/ui.py +++ b/src/teletext/ui.py @@ -29,6 +29,7 @@ class MainWindow(QMainWindow): self.clipboard = [] # List of (row, data_bytes) self.undo_stack = [] self.redo_stack = [] + self.is_modified = False # UI Components self.central_widget = QWidget() @@ -130,6 +131,40 @@ class MainWindow(QMainWindow): # Menus self.create_menus() + def set_modified(self, modified: bool): + self.is_modified = modified + title = "Teletext Editor" + if self.current_file_path: + title += f" - {os.path.basename(self.current_file_path)}" + else: + title += " - Untitled" + + if self.is_modified: + title += " *" + self.setWindowTitle(title) + + def maybe_save_changes(self) -> bool: + if not self.is_modified: + return True + + ret = QMessageBox.warning(self, "Unsaved Changes", + "The document has been modified.\nDo you want to save your changes?", + QMessageBox.StandardButton.Save | QMessageBox.StandardButton.Discard | QMessageBox.StandardButton.Cancel) + + if ret == QMessageBox.StandardButton.Save: + self.save_file() + return True # check if save succeeded? save_file catches exceptions but we might want to check + elif ret == QMessageBox.StandardButton.Discard: + return True + else: + return False # Cancel + + def closeEvent(self, event): + if self.maybe_save_changes(): + event.accept() + else: + event.ignore() + def update_progress(self, current, total): self.progress_bar.setMaximum(total) self.progress_bar.setValue(current) @@ -220,6 +255,9 @@ class MainWindow(QMainWindow): self.subpage_combo.setCurrentIndex(new_index) def close_file(self): + if not self.maybe_save_changes(): + return + # Reset everything self.service = TeletextService() self.current_page = None @@ -231,10 +269,19 @@ class MainWindow(QMainWindow): self.canvas.set_page(None) # Maybe reset text of hex input self.hex_input.clear() + + self.undo_stack.clear() + self.redo_stack.clear() + QMessageBox.information(self, "Closed", "File closed.") self.status_label.setText("Ready") + self.set_modified(False) + def open_file(self): + if not self.maybe_save_changes(): + return + fname, _ = QFileDialog.getOpenFileName(self, "Open T42", "", "Teletext Files (*.t42);;All Files (*)") if fname: try: @@ -248,6 +295,10 @@ class MainWindow(QMainWindow): self.progress_bar.setVisible(False) self.status_label.setText(f"Loaded {len(self.service.pages)} pages from {os.path.basename(fname)}") + + self.undo_stack.clear() + self.redo_stack.clear() + self.set_modified(False) except Exception as e: self.progress_bar.setVisible(False) QMessageBox.critical(self, "Error", f"Failed to load file: {e}") @@ -274,6 +325,7 @@ class MainWindow(QMainWindow): self.progress_bar.setVisible(False) self.status_label.setText(f"Saved {len(self.service.pages)} pages to {os.path.basename(self.current_file_path)}") + self.set_modified(False) except Exception as e: self.progress_bar.setVisible(False) QMessageBox.critical(self, "Error", f"Failed to save file: {e}") @@ -349,6 +401,7 @@ class MainWindow(QMainWindow): # Limit stack size if len(self.undo_stack) > 50: self.undo_stack.pop(0) + self.set_modified(True) def undo(self): if not self.undo_stack: @@ -362,6 +415,7 @@ class MainWindow(QMainWindow): snapshot = self.undo_stack.pop() self.restore_snapshot(snapshot) self.status_label.setText("Undone.") + self.set_modified(True) def redo(self): if not self.redo_stack: @@ -375,6 +429,7 @@ class MainWindow(QMainWindow): snapshot = self.redo_stack.pop() self.restore_snapshot(snapshot) self.status_label.setText("Redone.") + self.set_modified(True) def restore_snapshot(self, snapshot: Page): # We need to update self.current_page content