Files
Teletext-Editor/src/teletext/ui.py

153 lines
5.4 KiB
Python
Raw Normal View History

import os
from PyQt6.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
QTreeWidget, QTreeWidgetItem, QFileDialog, QMenuBar, QMenu, QMessageBox)
from PyQt6.QtGui import QAction, QKeyEvent
from PyQt6.QtCore import Qt
from .io import load_t42, save_t42
from .renderer import TeletextCanvas
from .models import TeletextService, Page, Packet
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Teletext Editor")
self.resize(1024, 768)
self.service = TeletextService()
self.current_page: Page = None
# UI Components
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QHBoxLayout(self.central_widget)
# Left Panel: Page Tree
self.tree = QTreeWidget()
self.tree.setHeaderLabel("Pages")
self.tree.setFixedWidth(200)
self.tree.itemClicked.connect(self.on_page_selected)
self.layout.addWidget(self.tree)
# Center: Teletext Canvas
self.canvas = TeletextCanvas()
self.layout.addWidget(self.canvas, 1) # Expand
# Menus
self.create_menus()
def create_menus(self):
menu_bar = self.menuBar()
file_menu = menu_bar.addMenu("File")
open_action = QAction("Open T42...", self)
open_action.triggered.connect(self.open_file)
file_menu.addAction(open_action)
save_action = QAction("Save T42...", self)
save_action.triggered.connect(self.save_file)
file_menu.addAction(save_action)
exit_action = QAction("Exit", self)
exit_action.triggered.connect(self.close)
file_menu.addAction(exit_action)
view_menu = menu_bar.addMenu("View")
lang_menu = view_menu.addMenu("Language")
langs = ["English", "German", "Swedish/Finnish", "Italian", "French", "Portuguese/Spanish", "Turkish", "Romania"]
for i, lang in enumerate(langs):
action = QAction(lang, self)
action.setData(i)
action.triggered.connect(self.set_language)
lang_menu.addAction(action)
def set_language(self):
action = self.sender()
if action:
idx = action.data()
self.canvas.subset_idx = idx
self.canvas.redraw()
self.canvas.update()
def open_file(self):
fname, _ = QFileDialog.getOpenFileName(self, "Open T42", "", "Teletext Files (*.t42);;All Files (*)")
if fname:
try:
self.service = load_t42(fname)
self.populate_tree()
QMessageBox.information(self, "Loaded", f"Loaded {len(self.service.pages)} pages.")
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to load file: {e}")
def save_file(self):
fname, _ = QFileDialog.getSaveFileName(self, "Save T42", "", "Teletext Files (*.t42);;All Files (*)")
if fname:
try:
save_t42(fname, self.service)
QMessageBox.information(self, "Saved", "File saved successfully.")
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to save file: {e}")
def populate_tree(self):
self.tree.clear()
# Group by Magazine
mags = {}
for p in self.service.pages:
if p.magazine not in mags:
mags[p.magazine] = QTreeWidgetItem([f"Magazine {p.magazine}"])
self.tree.addTopLevelItem(mags[p.magazine])
# Format: PPP-SS (Page-Subcode)
# Create Item
# Subcode is complicated to display "nicely" without decoding,
# let's just show hex or raw for now if not standard 0000.
label = f"{p.page_number:02d} (Sub: {p.sub_code:04X})"
item = QTreeWidgetItem([label])
item.setData(0, Qt.ItemDataRole.UserRole, p)
mags[p.magazine].addChild(item)
self.tree.expandAll()
def on_page_selected(self, item, column):
page = item.data(0, Qt.ItemDataRole.UserRole)
if isinstance(page, Page):
self.current_page = page
self.canvas.set_page(page)
# Also set window focus to canvas or handle key events?
self.canvas.setFocus()
# Input Handling (Editor Logic)
def keyPressEvent(self, event: QKeyEvent):
if not self.current_page:
return
key = event.key()
text = event.text()
# Navigation
if key == Qt.Key.Key_Up:
self.canvas.move_cursor(0, -1)
elif key == Qt.Key.Key_Down:
self.canvas.move_cursor(0, 1)
elif key == Qt.Key.Key_Left:
self.canvas.move_cursor(-1, 0)
elif key == Qt.Key.Key_Right:
self.canvas.move_cursor(1, 0)
else:
# Typing
# Filter non-printable
if text and len(text) == 1 and 32 <= ord(text) <= 126:
self.canvas.handle_input(text)
elif key == Qt.Key.Key_Backspace:
# Move back and delete
self.canvas.move_cursor(-1, 0)
self.canvas.handle_input(' ')
self.canvas.move_cursor(-1, 0) # Compensate for the auto-advance logic if any