From 56c0a137a85a0f434cb623ee730ae2c820d6ba7e Mon Sep 17 00:00:00 2001 From: Daniel Dybing Date: Wed, 31 Dec 2025 11:45:17 +0100 Subject: [PATCH] Feat: Add Copy/Paste Page Content to Edit menu --- src/teletext/ui.py | 67 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/teletext/ui.py b/src/teletext/ui.py index 588d6c8..5e61d7a 100644 --- a/src/teletext/ui.py +++ b/src/teletext/ui.py @@ -12,7 +12,7 @@ from PyQt6.QtGui import QAction, QKeyEvent from PyQt6.QtCore import Qt from .io import load_t42, save_t42 -from .renderer import TeletextCanvas +from .renderer import TeletextCanvas, create_blank_packet import sys import os from .models import TeletextService, Page, Packet @@ -25,6 +25,7 @@ class MainWindow(QMainWindow): self.service = TeletextService() self.current_page: Page = None + self.clipboard = [] # List of (row, data_bytes) # UI Components self.central_widget = QWidget() @@ -158,6 +159,17 @@ class MainWindow(QMainWindow): exit_action.triggered.connect(self.close) file_menu.addAction(exit_action) + # Edit Menu + edit_menu = menu_bar.addMenu("Edit") + + copy_action = QAction("Copy Page Content", self) + copy_action.triggered.connect(self.copy_page_content) + edit_menu.addAction(copy_action) + + paste_action = QAction("Paste Page Content", self) + paste_action.triggered.connect(self.paste_page_content) + edit_menu.addAction(paste_action) + view_menu = menu_bar.addMenu("View") lang_menu = view_menu.addMenu("Language") @@ -252,6 +264,59 @@ class MainWindow(QMainWindow): QMessageBox.critical(self, "Error", f"Failed to save file: {e}") self.status_label.setText("Error saving file") + def copy_page_content(self): + if not self.current_page: + return + + self.clipboard = [] + # Copy rows 1 to 24 (or up to 25 if exists) + # Skip row 0 (Header) + for packet in self.current_page.packets: + if 1 <= packet.row <= 24: + # Store row number and copy of data + self.clipboard.append((packet.row, bytearray(packet.data))) + + self.status_label.setText(f"Copied {len(self.clipboard)} rows to clipboard.") + + def paste_page_content(self): + if not self.current_page: + return + + if not self.clipboard: + self.status_label.setText("Clipboard is empty.") + return + + # Paste content + # Strategy: For each copied row, update existing packet or create new one. + + # Create a map of existing packets by row for quick lookup + existing_packets = {p.row: p for p in self.current_page.packets} + + modified_count = 0 + + for row, data in self.clipboard: + if row in existing_packets: + # Update existing + packet = existing_packets[row] + packet.data = bytearray(data) # Clone again to be safe + # Note: Packet header (original_data) is now stale if we just update .data + # but save functionality reconstructs header from .magazine and .row + # so it should be fine. + modified_count += 1 + else: + # Create new packet + new_packet = create_blank_packet(self.current_page.magazine, row) + new_packet.data = bytearray(data) + self.current_page.packets.append(new_packet) + # Update lookup map just in case (though we won't hit it again usually) + existing_packets[row] = new_packet + modified_count += 1 + + # Force redraw + self.canvas.redraw() + self.canvas.update() + self.status_label.setText(f"Pasted {modified_count} rows.") + def populate_list(self): self.page_list.clear()