From e2ed4dd1e2828b05c51e93d2e3e8d82f9d862f01 Mon Sep 17 00:00:00 2001 From: Daniel Dybing Date: Sun, 28 Dec 2025 21:41:09 +0100 Subject: [PATCH] Refactor UI: Replace Page Tree with List+Dropdown. Fix header rendering and crash. --- src/teletext/__pycache__/ui.cpython-312.pyc | Bin 9007 -> 10914 bytes src/teletext/ui.py | 105 ++++++++++++++------ 2 files changed, 74 insertions(+), 31 deletions(-) diff --git a/src/teletext/__pycache__/ui.cpython-312.pyc b/src/teletext/__pycache__/ui.cpython-312.pyc index cf192a226ab4688a8b6c4f1278e99e45389ab56c..f2056a06255e3af11a2d4730471c87cd0c3e08b2 100644 GIT binary patch delta 3928 zcmZ`+YfM|`89txSvHckz->|vZ*w`3CFn3atESILqpk-N7QbraZ(ZzieY3Rl^9QbHFa6hjhqgT z3vuE@H_=)0Tl9qM3KOh~8U*8nCR%lc3-Wp9G76eTnShaaHGaq29K*bUt}+t!rH*;+ z+BuCIxwA-WsO&|#o2WF;YBFfbLu>}SNmJQFjN~O@)?Q_;+|Q7IvjOrEYe7EpGHXXI zRFW6CTGU29!ydM5f@P+BbWOenCmq!2If%Pt1dKW>=5CfJSyrm~(jK=fOkG7g!-Q%p zH>DmLoT)El(?&u#T z;aWSZzo{WlaNg3B+1MzoOLq|iF+2{o+}tb^z{IOc zo;>%Oc?0vWo9E3%+#=(al~Fj_+40NRU&QS)ZeQ&$b{v;Gju-HW2WFx-lGl<2+_ec7 zjPu5_@rwoAeox0ZTXM^$ya{IZM$(nn-}N-Fe0|;1ljjQ9b=T9n{G2)iUq$Sav8#x? zW!zoF2V{KUmQ*}AEFT;$;4>T8Qp8RfJC|CDu1?w23I6`?9<@`z?oC`%#9sLb_O9p) zxD7(6+p}KV3J+`CC>_BG_aoz5#?_Gm?s+);gu1u(zW$f2&7y)u5@VB-f+$4A4)Tie z8ML2l7<0NKa3=PX^Sm1!Tbtt#A#`-@CnhaIkCC67{hs~w_<5?&#-f+gEX?2&iK^BJ z`NHf*&yrfpIZ%pQHc_vU-n0N$otYMrPsQTGa5y1|c51{=k4)34>6thM4n?hKCK+2l z1oEEERSM)3k!?;CUi+)s6Ylj7k&VsPS^Z zDjL#d^^%~+UNy*^KgTdxltIMib^t9Bo7K@ep#g@}fEIQ3$aoQnmPu-nqf}?m9EJ1B zN~3X-WA3`@%q{|aZH!|i8|gE9$+ND8^A&E(vKbbfzrZlhLx@=}tIcrBOhy|;%iNoq ztnL9vW_I{6tIz1C>K=&)mQsZk$xCc4xzK2LWVnoWLh}$)m0rNFS$i&{uLOaZ*S^Iu zz+ReRh3(xJ4OqoCu%~DvaRCzAsB+Szn3|bRtKVEq&{LcUPlo4WNuhipIg=O{L`4^# z2B1V0T{X=|=Wi_I7nweqh5=P1C+zhCfUD zMqB#=SG4+Mt8c|FTlZ}6)*|ngdH2$&%r_PJHkof*wcX)6whUnJo|&ohES)WSx^l9o ztLWJ$d-kn+`qyjs=Z%}r7V0xFe=VPJ>Fd=uyw|)%XP@lsyEX8EAO|3O zJ+##4cJ0m5tS}6pRZIAN)HA2^wLw|;L7Mb`^F9hZB~n)bix`3*724u==x zFsIlpd`I73C89%3ldp-3t!h~FKfYfD;?26k0+u@833St8C; zweM5$3KcXP#UK^mqaqLDf8++VK`vkJReJaZ2*?3P{ne9;C$Ep+NL@=68xP2h2i6@2 z=M8x_e|E#_D8adCZIP`lE0NXymFI5x*RA{W+ASSpFjXq!UK#IQg|vanw^J>BGWHd) z|6_+|NmzHNc&nb(_zvGo)2DBXf7HLWfV=-_wC>XBmig}0O9j4flV)PG z%r~!`xWl(@8TAZrD<=Y(b~Q$iaIOJSudmX0OU zQaBkAM9T4EGZl}KTdw*XTOvsy50`HWk~z;V{`+$OcLT1ZDOdmiM(aY~ ztA`dQHZ1m{rAf9l6)lv_R`;)4`tsaeW6eVJ`e4D>wBc*X4;FYb)L^fpD7KJMyNPN z1?>n#S`WldD(IUL>Ay7MJ0KKOxkrr%@pvc{K;mK8O;Z9qUaBN6dX);E9?;W&Tw(5M zdbIBCapcstZ6DBSo3^c3JA$^!Kbs8Af$dJacJFq(PTRay?bP{Mln7!J0czE9+8G-Vj^wm)BqK}vOSOzh0^QN#8Rb>i#A3IhCUyNLJ-US zdjeiiR?{UfH~6UP4$)A9$VPiFe=aWfj!v(WH&hW@H9{tMlV`+Wca delta 2582 zcmZ8iYfN0n6`t99clYl53A-%2czK#junh@$88;z*Kq?*%wP~u2qV2NxLKolNrE_fMwU>!3zn+rD<(%dkJ|e!Jlhd>t zui+tj55Me}tz!l-&Btu>=qircFCo!NdkhW!T?0Zt!z(DqJm_NqZ%i4&*j+$z#{sW^ zCPH*L;-hc#KDWfL;j#duL&1+iKI(K>O^>k}c|XOxj|ZJ5+QEhCulNA%=c{oDs7P2m zFuqn`&63x_UZnE70K5+wx0orG7!+uK4 z7ei)XXnYP1M{}xj?o~M<$z&igDl7DF<}*V1#0dP55DFMHUX_(G%@U6%m4vFs<0|t< z?+JZ4LQh#Dn5To5e6cD@2j}@~mR-TVXj!oA2+@)dT@7pt;vwf)NjSF3Z3|6@oJdKC z>Y3VMtbZ-l1nAEml+Yy-bUFpNr_0+b|`oM$&&0Ezi;KTN$#+B<=j5j*B zg%cb9wch4D>}E7ej-(rv`Jo&L|$5IM zQO!yk2kG1ORgOx#0s9rVCgygc7KA>UvfH?8Tf80_bbz0j9YyodjAbw}o|s8x);7ioq`GbR-|LCS|e${0ervYQBubR{I|a&~e+o{|;T zyENNmVqA`A^662TXo8v_jVH5E!WTf9xDedFW@mcm6S>4UvWlz;BdScwD=>BLJ1Ird zEb`UKL`Hf=QA8urlaB|ls)i>uqr!TD#;3rBY6PP!3oB_Dr*pM6MV7a55UBS7-a?gv zUUV(EwuPEK6LNd!`CU)dN_aWE<7q5;8uyXI(mwynuFJhRvoN#jFS(jOYkc}<>Nftp z^;7Gu!e-aN<}-s^jYCWP((p=bIaYEk+@Lz#V2Z?X(BzZ)(Eum`=kd8ivY=V1hf5#pz*`s&u4SN=3Zy=o;e`vVFJwH#elx>* zuisd=-)=HC?s;pBr&eElh+xvwNw*``(jSU_Ma}lw^lQ-QCQ#B1R`gk0my{-7->pFJ5W@@+F3ahs@aM~{1Ga9WpCFb;S4C|75OFd z3m|bHfO;BWkHZ-M6 List[Page] - # 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]) + key = (p.magazine, p.page_number) + if key not in self.page_groups: + self.page_groups[key] = [] + self.page_groups[key].append(p) - # 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() + # Sort keys + sorted_keys = sorted(self.page_groups.keys()) + + for mag, pnum in sorted_keys: + label = f"{mag}{pnum:02d}" + item = QListWidgetItem(label) + item.setData(Qt.ItemDataRole.UserRole, (mag, pnum)) + self.page_list.addItem(item) - def on_page_selected(self, item, column): - page = item.data(0, Qt.ItemDataRole.UserRole) + def on_page_selected(self, item): + 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): 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)