Refactor UI: Replace Page Tree with List+Dropdown. Fix header rendering and crash.
This commit is contained in:
Binary file not shown.
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
from PyQt6.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
from PyQt6.QtWidgets import (QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||||||
QTreeWidget, QTreeWidgetItem, QFileDialog, QMenuBar, QMenu, QMessageBox)
|
QListWidget, QListWidgetItem, QComboBox, QLabel, QFileDialog, QMenuBar, QMenu, QMessageBox)
|
||||||
from PyQt6.QtGui import QAction, QKeyEvent
|
from PyQt6.QtGui import QAction, QKeyEvent
|
||||||
from PyQt6.QtCore import Qt
|
from PyQt6.QtCore import Qt
|
||||||
|
|
||||||
@@ -24,16 +24,38 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
self.layout = QHBoxLayout(self.central_widget)
|
self.layout = QHBoxLayout(self.central_widget)
|
||||||
|
|
||||||
# Left Panel: Page Tree
|
# Left Panel: Page List
|
||||||
self.tree = QTreeWidget()
|
left_layout = QVBoxLayout()
|
||||||
self.tree.setHeaderLabel("Pages")
|
left_label = QLabel("Pages")
|
||||||
self.tree.setFixedWidth(200)
|
left_layout.addWidget(left_label)
|
||||||
self.tree.itemClicked.connect(self.on_page_selected)
|
|
||||||
self.layout.addWidget(self.tree)
|
|
||||||
|
|
||||||
# Center: Teletext Canvas
|
self.page_list = QListWidget()
|
||||||
|
self.page_list.setFixedWidth(150)
|
||||||
|
self.page_list.itemClicked.connect(self.on_page_selected)
|
||||||
|
left_layout.addWidget(self.page_list)
|
||||||
|
|
||||||
|
self.layout.addLayout(left_layout)
|
||||||
|
|
||||||
|
# Center Area Layout (Top Bar + Canvas)
|
||||||
|
center_layout = QVBoxLayout()
|
||||||
|
|
||||||
|
# Top Bar: Subpage Selector
|
||||||
|
top_bar = QHBoxLayout()
|
||||||
|
self.subpage_label = QLabel("Subpage:")
|
||||||
|
self.subpage_combo = QComboBox()
|
||||||
|
self.subpage_combo.setMinimumWidth(250)
|
||||||
|
self.subpage_combo.currentIndexChanged.connect(self.on_subpage_changed)
|
||||||
|
top_bar.addWidget(self.subpage_label)
|
||||||
|
top_bar.addWidget(self.subpage_combo)
|
||||||
|
top_bar.addStretch()
|
||||||
|
|
||||||
|
center_layout.addLayout(top_bar)
|
||||||
|
|
||||||
|
# Canvas
|
||||||
self.canvas = TeletextCanvas()
|
self.canvas = TeletextCanvas()
|
||||||
self.layout.addWidget(self.canvas, 1) # Expand
|
center_layout.addWidget(self.canvas, 1) # Expand
|
||||||
|
|
||||||
|
self.layout.addLayout(center_layout, 1)
|
||||||
|
|
||||||
# Menus
|
# Menus
|
||||||
self.create_menus()
|
self.create_menus()
|
||||||
@@ -78,7 +100,7 @@ class MainWindow(QMainWindow):
|
|||||||
if fname:
|
if fname:
|
||||||
try:
|
try:
|
||||||
self.service = load_t42(fname)
|
self.service = load_t42(fname)
|
||||||
self.populate_tree()
|
self.populate_list()
|
||||||
QMessageBox.information(self, "Loaded", f"Loaded {len(self.service.pages)} pages.")
|
QMessageBox.information(self, "Loaded", f"Loaded {len(self.service.pages)} pages.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
QMessageBox.critical(self, "Error", f"Failed to load file: {e}")
|
QMessageBox.critical(self, "Error", f"Failed to load file: {e}")
|
||||||
@@ -92,34 +114,55 @@ class MainWindow(QMainWindow):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
QMessageBox.critical(self, "Error", f"Failed to save file: {e}")
|
QMessageBox.critical(self, "Error", f"Failed to save file: {e}")
|
||||||
|
|
||||||
def populate_tree(self):
|
def populate_list(self):
|
||||||
self.tree.clear()
|
self.page_list.clear()
|
||||||
|
|
||||||
|
# Group pages by Mag+PageNum
|
||||||
|
# We want unique list items
|
||||||
|
self.page_groups = {} # Key: (mag, page_num) -> List[Page]
|
||||||
|
|
||||||
# Group by Magazine
|
|
||||||
mags = {}
|
|
||||||
for p in self.service.pages:
|
for p in self.service.pages:
|
||||||
if p.magazine not in mags:
|
key = (p.magazine, p.page_number)
|
||||||
mags[p.magazine] = QTreeWidgetItem([f"Magazine {p.magazine}"])
|
if key not in self.page_groups:
|
||||||
self.tree.addTopLevelItem(mags[p.magazine])
|
self.page_groups[key] = []
|
||||||
|
self.page_groups[key].append(p)
|
||||||
|
|
||||||
# Format: PPP-SS (Page-Subcode)
|
# Sort keys
|
||||||
# Create Item
|
sorted_keys = sorted(self.page_groups.keys())
|
||||||
# Subcode is complicated to display "nicely" without decoding,
|
|
||||||
# let's just show hex or raw for now if not standard 0000.
|
for mag, pnum in sorted_keys:
|
||||||
|
label = f"{mag}{pnum:02d}"
|
||||||
label = f"{p.page_number:02d} (Sub: {p.sub_code:04X})"
|
item = QListWidgetItem(label)
|
||||||
item = QTreeWidgetItem([label])
|
item.setData(Qt.ItemDataRole.UserRole, (mag, pnum))
|
||||||
item.setData(0, Qt.ItemDataRole.UserRole, p)
|
self.page_list.addItem(item)
|
||||||
mags[p.magazine].addChild(item)
|
|
||||||
|
|
||||||
self.tree.expandAll()
|
|
||||||
|
|
||||||
def on_page_selected(self, item, column):
|
def on_page_selected(self, item):
|
||||||
page = item.data(0, Qt.ItemDataRole.UserRole)
|
mag, pnum = item.data(Qt.ItemDataRole.UserRole)
|
||||||
|
pages = self.page_groups.get((mag, pnum), [])
|
||||||
|
|
||||||
|
# Populate Subpage Combo
|
||||||
|
self.subpage_combo.blockSignals(True)
|
||||||
|
self.subpage_combo.clear()
|
||||||
|
|
||||||
|
for i, p in enumerate(pages):
|
||||||
|
# Display format: Index or Subcode?
|
||||||
|
# Subcode is often 0000. Index 1/N is clearer for editing.
|
||||||
|
label = f"{i+1}/{len(pages)} (Sub {p.sub_code:04X})"
|
||||||
|
self.subpage_combo.addItem(label, p)
|
||||||
|
|
||||||
|
self.subpage_combo.blockSignals(False)
|
||||||
|
|
||||||
|
if pages:
|
||||||
|
self.subpage_combo.setCurrentIndex(0)
|
||||||
|
# Trigger update (manual because blockSignals)
|
||||||
|
self.on_subpage_changed(0)
|
||||||
|
|
||||||
|
def on_subpage_changed(self, index):
|
||||||
|
if index < 0: return
|
||||||
|
page = self.subpage_combo.itemData(index)
|
||||||
if isinstance(page, Page):
|
if isinstance(page, Page):
|
||||||
self.current_page = page
|
self.current_page = page
|
||||||
self.canvas.set_page(page)
|
self.canvas.set_page(page)
|
||||||
# Also set window focus to canvas or handle key events?
|
|
||||||
self.canvas.setFocus()
|
self.canvas.setFocus()
|
||||||
|
|
||||||
# Input Handling (Editor Logic)
|
# Input Handling (Editor Logic)
|
||||||
|
|||||||
Reference in New Issue
Block a user