From 56657efa7c277abf5b529c305ecf7ab8ad7c71ab Mon Sep 17 00:00:00 2001 From: Daniel Dybing Date: Sat, 31 Jan 2026 13:20:11 +0100 Subject: [PATCH] Implement 'Set Language' UI to persist language changes to page header --- src/teletext/ui.py | 88 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/teletext/ui.py b/src/teletext/ui.py index 7e7fe7e..99c5b15 100644 --- a/src/teletext/ui.py +++ b/src/teletext/ui.py @@ -298,6 +298,26 @@ class MainWindow(QMainWindow): btn_release.clicked.connect(lambda: self.insert_char(0x1F)) right_layout.addWidget(btn_release) + right_layout.addSpacing(10) + + # Page Language Setting + lang_group_label = QLabel("Page Language:") + right_layout.addWidget(lang_group_label) + + lang_layout = QHBoxLayout() + self.lang_combo = QComboBox() + self.lang_combo.addItems(self.language_names) + self.lang_combo.setToolTip("Select the National Option Character Set for this page.") + + btn_set_lang = QPushButton("Set") + btn_set_lang.setFixedWidth(40) + btn_set_lang.clicked.connect(self.apply_language_change) + btn_set_lang.setToolTip("Apply this language setting to the page header.") + + lang_layout.addWidget(self.lang_combo) + lang_layout.addWidget(btn_set_lang) + right_layout.addLayout(lang_layout) + right_layout.addStretch() self.layout.addLayout(center_layout, 1) @@ -330,6 +350,7 @@ class MainWindow(QMainWindow): idx = self.canvas.subset_idx if 0 <= idx < len(self.language_names): self.language_label.setText(f"Lang: {self.language_names[idx]}") + self.lang_combo.setCurrentIndex(idx) else: self.language_label.setText(f"Lang: Unknown ({idx})") @@ -453,6 +474,73 @@ class MainWindow(QMainWindow): self.canvas.update() self.update_language_label() + def apply_language_change(self): + if not self.current_page: + return + + idx = self.lang_combo.currentIndex() + if idx < 0: return + + # Update the model + self.current_page.language = idx + + # Also update the session override/viewer to match + self.canvas.subset_idx = idx + key = (self.current_page.magazine, self.current_page.page_number) + self.language_overrides[key] = idx + + # Patch Row 0 packet data to persist language selection to file + # Language bits are in Byte 8 (Control Bits 2): C12, C13, C14 + # We need to preserve C11 (bit 3 of encoded 4-bit val) which is "Inhibit Display" usually 0 + + # Find Row 0 packet + header_packet = None + for p in self.current_page.packets: + if p.row == 0: + header_packet = p + break + + if header_packet and len(header_packet.data) > 8: + try: + old_val = decode_hamming_8_4(header_packet.data[8]) + # Encoded nibble structure: D1(b0), D2(b1), D3(b2), D4(b3) + # D1 maps to C12 + # D2 maps to C13 + # D3 maps to C14 + # D4 maps to C11 + + # io.py logic for reading: + # language = ((c_bits_2 & 1) << 1) | ((c_bits_2 & 2) >> 1) | (c_bits_2 & 4) + # i.e. Lang Bit 0 comes from D2, Lang Bit 1 comes from D1, Lang Bit 2 comes from D3 + + # So for writing: + # D1 = Lang Bit 1 + # D2 = Lang Bit 0 + # D3 = Lang Bit 2 + + l0 = (idx >> 0) & 1 + l1 = (idx >> 1) & 1 + l2 = (idx >> 2) & 1 + + d1 = l1 + d2 = l0 + d3 = l2 + d4 = (old_val >> 3) & 1 # Preserve C11 + + new_val = d1 | (d2 << 1) | (d3 << 2) | (d4 << 3) + + header_packet.data[8] = encode_hamming_8_4(new_val) + self.set_modified(True) + self.status_label.setText(f"Language set to {self.language_names[idx]} (saved to header).") + except Exception as e: + self.status_label.setText(f"Error setting language: {e}") + else: + self.status_label.setText("No header packet found to update.") + + self.canvas.redraw() + self.canvas.update() + self.update_language_label() + def prev_subpage(self): count = self.subpage_combo.count() if count <= 1: return