From 6310f51f657a77cb222d67703546f88dc90b6e33 Mon Sep 17 00:00:00 2001 From: DanS Date: Sun, 12 Jul 2026 07:04:43 -0500 Subject: [PATCH] feat(wallets): fixed max-height list + manage scanned folders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two wallets-modal changes: - The wallet list now always renders at its max height (kMaxVisibleRows) instead of shrinking to the wallet count, so the modal is a consistent size whether you have one wallet or many — fewer rows leave empty space, more than 7 scroll. - Add a "Scanned folders" manager: each user-added scan folder is listed with a control to stop scanning it (removeExtraFolder + save + re-scan so its wallets drop out). Paths front-elide to keep the identifying leaf visible, with a full-path tooltip. The card-height math reserves the manager's rows so nothing clips. Two new i18n keys (wallets_scanned_folders / wallets_remove_folder), translated across all 8 languages; CJK subset rebuilt. Verified on the sweep at 1.0 and 1.5x DPI: max-height list on both the few- and many-wallet surfaces, the folder manager renders and stays clear of the footer. Co-Authored-By: Claude Opus 4.8 (1M context) --- res/fonts/NotoSansCJK-Subset.ttf | Bin 617392 -> 618560 bytes res/lang/de.json | 2 ++ res/lang/es.json | 2 ++ res/lang/fr.json | 2 ++ res/lang/ja.json | 2 ++ res/lang/ko.json | 2 ++ res/lang/pt.json | 2 ++ res/lang/ru.json | 2 ++ res/lang/zh.json | 2 ++ scripts/add_missing_translations.py | 12 +++++++ src/ui/windows/wallets_dialog.h | 54 +++++++++++++++++++++++++++- src/util/i18n.cpp | 2 ++ 12 files changed, 83 insertions(+), 1 deletion(-) diff --git a/res/fonts/NotoSansCJK-Subset.ttf b/res/fonts/NotoSansCJK-Subset.ttf index 67c89940b62d874fe079e78842688dbef86c7717..d908fd28afd13d2517f85c8ed966b89a4571bd8d 100644 GIT binary patch delta 13995 zcmbuGd016d)c@DHm$UcThgm=YLBIiV0AwCTKtTlo6-2>#)e@3cyuYK0{(-}O8PSJG8Up(v z!^aQJOG)e9kEm@4QL9U%bEb|Ov24GNXnK26maQ5ya_ERQU(2qr{Tqai!GM*$;~2~j z#`~6I#upUbzViKOGLUqH$med(gyBQ|ZY}Rf)N>V_7LOlVl&9|M30nz^5X&7pexyf> z$QC5{VT>Kfn=q-MW+4TV5D1t&3$+D4^1M%?YkRzJS%?KT7Cy4ZdpPmAOAjE^q(Z@Z(@Y3E|#na(GIRp4PW2o*)w8 z3Xv*>@B6x~mn;q4cilfi;H6naQw#fDm#4Hf zDN4n^q@pfGaYa^BA`4Fzo+$jH@bkh$g?kI%D_n?w^9yGePA4jyRXDS7M&Y!=5rxC> zZfN1a!ajxRg}rec1wsm2;it>weUrCN?m0QA;6g!V!TEx71?MJBF-!`bXgyJxNck`G zKhFOse{=rA{H*-g{D}Mx`TqGn`D)$|d1vw}@=oRL$Xk=QByVosbo?8eH!=^6kQWD{ z@|xv26HT~3;g1P-CajvUBKJ}5-Q453WjHrIcTw*A+!?ufx#M!jjL*w?oMX(HnKLRU zcudIX`~4gBx9e|^`|JBt_RH+|vUg{{o&9EZarV0GIoZ>)3$n*%56|wF9hx1I?Vs(N zbt&u1tixGvXZ6mC$_md4$@0rmvg9mXzZdtjT`(9n#?7ci!*aFlQKJJ2K2eq=c_(_GEQWClTn^=(2%hqV@Af*j42rt zGIBCTWjLfiPyZ|Zo%C(#8`IaP_f5}8@0FgE-m>?Z-kWvE zYP(dQ)K;m@Ql6zeNqLk~opLM1@LS5&lq)HhQ%hXGyg~>I^$CHmHf0DdExg`0+H!o8(5xw#hu%BB?6r zO46@M*-3qqGLpJg~oZuxy4DbFJoWCK90Q~dpq{~ z*i*45V#{NX#eN!lDE2_?hq3R)z8#w$+bcFTwrgyc*qGRsvG$$rcB<}lvD3LuqdSf0 zG_+Hnn9DIg$DE3JFJ@27u9&Sc>pLEZ9vz($9TOcH9THU)bvf$$sBfbRqlQJbjQk_= zM&vJ%TO$1;TN@%hBb_3iM?8(V6R{^^d&J6!f{2b0kr83xd&Ap=dxy6OdmMHx>_XUg zVc&!u4cix%A2uwkZ&>#*7Wy!BM#zJZyCHW%-V50svOQ!`h;#5?!B2v32VV>RHu%fn z!@&cCBZEqVN`mGDO$!?uA0SzNcM#C|DCe^)Dy3`$+UzJF#5U=CUHJ>*8I*|r` zUgOuXS_fx-@ZS?mC*S3Janeu6XRno#CMw(x6YO{+xJq(mxTc!_W97B4N3>UV#1uW- zZCZ(Kz{o~zTzkdDR2}QFHowO+otz1u7x$e^exR3%)_$J0G@u7dW5d`;Hik`QGud3W zkgaCx*ctW%JI^k#tLz$k%Kj3ci!X$$Xe!*qk$uy8W;h$hbR>Cf8Oh_?lbn-C^7zRl z=T0JdLRXUW0>KrMCpIH_(nyjEmXkbr9m$2uNS^Wz$wf&dPhCXvv;!nh??dv8G?HhI zBYD=RB+vE%pOHLgHOX@^cV0J==fmfMek3nUCVA0Jk{9nKgZ%n2l9yDIyz~~y%l;&J z`4f^?JRo@$2mg?~CZ6QAOG#cgm*n+0Z?q?QV>Zc~I*`1%5y@{fCAnCD%Or1spEs|O zy!8^v+a8m=J(}blNNQ&)$#1VBdDm+szte-{-J?j}g8<(B$UyR53zFYQ)E{J${NYfN zOVUaHs6WXcBfEWLN#4JP2a+qJNd9>X$roOdd=VM`>Q3^d;Ur&PLGqQOBwu|-@^6@b?KsKTk>w3=6J@xy ziR9bcNWOD~uj>@_)V{xn?6V zx<*VFM@)Z`n8k5o@)=^Rk{GWdrraZ@wk2jcjF?plG3#PtHrC)MG20Qu>;k|)#2QT| z=I|#mr(MLF;Mh5en2SF#S3hD+XA*P!n^-e1GBA&x#5_9_^Mdmh-2q-(E+W>-lbE*x z@V@nGVm@WW+KeaGHWnbTcFTyh_W<{a`92}$Zv(z2)&ao=;y9=Wv0x+Q4aB0pA=WX8Sj;)RiQP;r-j!JA!Nj`2Y2rv?-I9qVNyL(oS&#O_QZ5iny-X~v zf>_TliS;^6EFBIqo)gQ&B7LtC%R+Y9;l%o<5gV|Z*gzw(K_`g~QNgdoh9byeE5Soz z!)Jk)#6}t*>*%}0#vCLz7873kfY`WiiRHY&&0i+537-0O3;bSHio4JFS0i~GzIZDhy4-+V_3R@ z*wRbHmW2YyyzCLN<=NmFu@wtIHL;bDZ6%zo{GHe;D6|{Gb_3>b*h|dV4rs46xSGX-w^090Uc@#{1BZxh)`0=wLt<|T&=qU~ z2&Om#d`xUh2e6sgo3MRzDzUA4Fccgmwrw$h?OXW({B0I{EBFdXaxDD^q`IJe6{>^x4K#}(@Q8Df>4zJ_4)$vnAi}WFgp-@ciQRe)oF;Y~b-aCu*c}9MXEm{E zl&^XPxJK*`Ec^$Oxa$SB61x`wejs*#9H=7pAeY!f^v*;0H#|aJAE$%c#Qq!#@cLvf zv8MzU5_<+ko_#{>uW0ZMvFD44y%-G668pO!xJ&FG1pCqh;9^x%NSyRwI(SH2nnGOH z66_(a?+C6Ex2Pa44*}1}z!?mA2e6&E(gN%zF1mti#MRZrEfc^4;#MCMw@w6q6Su)4 zHn)h|4g+v#2WR#cU@>@3ywODPgt)_O;*R41<~vOz-Z%~*kS0yRO5)Cr2K>MxE`i`J z;;t@WK6pyJDJC|3MBFV8;MIK{@n%@0*&^_QxW{qgo?&1gaW8*RNxbQR55%0n*NF#luz`3mG7W}pNDzRp&=9a3JSHAC8eAhD9!uO1 zUPe3u3q{NYh%~Y@I7B?E6+pC6KM;?O0c(hNlt4dlf_TgzaD;d#l&;fz#AAKILICCB zvcO5=@kwAA@y<4&4_F0$CEf*n(B(to3DKy3!WQC*mS6_>i+I=h#Jj;+w;kXC@$M<$ zGvY}t!BlXAc(NZ@5AG4~foytI6Hl2(Jk=eb9BG)-Qx8@X?=_it?_dC5={U}SQW+)0 z`@mP9d#HcrI^unibzex+?-Sx#JppQzoepji?+=;#quBgCKG~2Q|dU2LfcA>k3MVPe8{{Ku{CT63-I= zLFFw07;}hk>_mK1Jn_wjUc}#U z1nBDG<;1s4CjMp|xJ!KNV&dD7#rE+4LG5^#_)cW`c3$=U>ew{xzI^1N-C0h@bEx{+$)^lR?B!4I^FwiN8-Jej3MT zAn#cu^TP?^KSHUWz9)XZG4V?HyTFP6(w6webmG63q5hX3)s?NptNIZC4F=cHOuwTa zZa}IVXp$Q>#BYuU72qcETRPAV%mXOTt(U}awYprkc(NTC+s8Yxm0DZ1|9H&XOFNwF}JB5xsu8P1Wy z-y%iXL5f&IiuxHTmN}$YrGtH>Si69Oq}W7&d!*PFl42J~ioG}ZlN5&}QXD6e;-rw$ z*q@XpD@bvEN{S1dyTZ0<7AbCiq_{_t(kv64A;n`6DV}Mhcr7Hw(7c+ImIFy?)s+q+s$M86xP_!p4UVI(O5gGdP!;5;copO6xK zij>gCq=Y$uZ%7GWKuQFHh(yql)4{i-L^*-2q(l!UgAxscj_%+iQetF)%wryr(y5q~ zSiFy&Knk9@DsgX+5}!><=ia1raU&(68Gw^Sj3r(sr7KkIrU!WK-USbHa6aixQj+_E zTcq@Wnkl_VNo@tzkdhV-E*nVc`8g@QkX3I)-5U@l06^q@ zdjKrfZxgseN*0vMwg)I){{DSaUc^ zFv1lW){!!@4M6=zg@Mzgj2;1?z!(^hZ3MQF@>(LeNXoc*;CE7ThJpvAjE7AwdLj1= zDHDc)Bc$XZiF`<&{}U+_5$Gh8svv`u$<6@fom@;xp#UvV|3cKf5YiSN1*mgTEO73AS7IlO$@v~5^{Psfls5rK>QSi33fjs-RjaZAZ?c5CJA>tWZfv1F;b zcCd5sv~{(12wS$c3wO0l+PW%`J6ihY7lv{dHGFD*TdStF(K92sv&cNq{h5ust!QRF zY?W)H)=p17T@5e4{ypiDzK5N)n~g>Dkf0kGU7DqOwr`c{-g$(Z>TMfwXNOHw>)@iv z1Dx%wBuTPuZKKmMOZ$|7c4-|Qt(&WjVp7{!J6pMjwzskJRIR)_G_`b4o3yr3Td4M7 z&G)Dd!rFs}ElG4})u_48{7LwaEGW39On(S!y+%IyG=*lqA{XOcPF}om<0gVW2tGKny%q4 zS1mk~TRZr7aPoC(>)0+k+1b+D&OK|SziY^d6sJZI)YivFFEQ0IGqi0=M@JhkwNZ3R z8z}A--NDw%L$z)n=5FI+?H%D{2|WXw?^GKJYfnwj*539$j*D`9nuK~Z3w6#hiMn6^ zDMTG-YQSl=n!c)^hpj#g&G&B!oekzbeMNW)BW6uaJ*oGK_Dq6u10$`PDIJF-I)!># zdA4*3@U-`JMgzJ9LODAR8<$AqTS;iZ=-D%Ke3V9(0kh^saTm*&#WQ`a-RwFpj)aa0 zTVgNQN!O;fN(OV8HnjAPZrnN}^<`|GqBjyAOUwKmTG{&!N^?&~VzfrIX%iCdVd-q;8R=_d<)vEr1iM)_QQZP;EIm}40QY+3I+|NuD^6pV z2zPrQ>vmFFt(rMGIg74dl>r01^y*b*v{z}eUaZhduNyBg;opvl2$3a@;o_i@T*F>k z;mA_5P-+ATSvU(9ku461GI3aZW(?+{wF4Kbuo6+CzxdSjMEi*NvNV?qf1Rw>6bmck zb|D5gRcp$HRZRuSWL;BDHehW{g)og8-Bi&AwpFlAQbmY|*%lwYpQ4>SVBIu zp{81>#y3^r-c`kPD-2t}VHq51&afJmV5TKTVCqPaTT_NJW?Pv?AgPfcA50__&UBVy z4i>M(;)^YXFAiaAEVC3X9L&?IadCVd3vEOOs`0+1a0;sPr$cZRG?ki}qNqd^m9=YC zm`18FQiT!CdAOD6h0Mz8Lo}IFO3f4MPmZ-lyRAe*Z7>h5L{@DuJ*`DZ?cow@;f}bT z2rDF@r+y~)P}W$669#i!l_Z%K(ZQ*CIX&edf$=8eYDAWU$>X)`O}gMQJ@P1n$YnGM z`4pJ6)RfJysl;d{Mzp-DOm^mxNw17bG#CCjSsOELgo8_65Zdxc9ERGFChA-p;p=4{ ztRkJ(1loyurJk547*E>>m)dmi+6ez9=9R7CNNbx3rnr%pG1ykbNvg5XR=fdotKfSHYmrGayp1`CapY(` zhx=VP^s^UUIMhZn>`kMl_O>@wM;pCpFWS`_STzzZE$SLs3&q^@mGJ#DxL^uJ>-cVs zOiia9PHQAOr`Od?+bHJn&zo%FzqYsQBCMj@^$Fn?8uk^Y*pHAS9R-+YwlLZ`2p2Sm zIZ17Mm<>x1RD*M^&#lpoHs~&`ELs31CWp7og+c(;rp?t5fccD8;wXfw_7n58jaIV|WBlDZ78fQPVuLHLftGol@;2 z0^mm5G|d}}AEcwkCyhmG{ZVn$=-EUx9eGu$QhrlzDR-6o%0uO`@(^xSmy=8{F-6s!tlzYkp<&pBI@>Katd7=Cx%Eh{o~xXitJbOwbx`e8dkRz?R0j%H zom3|ZQJvMM6so$b%_&lCuliD~>aTXBcr{kdqF(Aibs&vXhp59SN6k^k(*$*bnos%a zBy|cEs8iKxG*z8pPz^L)U8pX^*K{nDt2Nb1RZWHRTTPj|L=z4p6&NYUNJ;%jB}U3H zvI`?6B$TVuAg_sn0CSWVfp}yN2Yl+%%$TqKRCL zkrLC07WBVI%C!2|HJ5ps=DKdA0(;^TepOtCGFo_=15NxAaorSjLwK4N|87uIhhS;^ z4FEIi+PXwM#RcnG%@dq4sg3%>sg{ctr@1SOF{1TpL*$wQT2Pt-4Pk1zXbK?A+Q2GI zqG}b^G&R4|imUZbgTh*9m8y$LVMDcPvgX{JjaF;zUAbu~twx%;*`17cranLx)wNmR zH%Vw=&XYN`xa#%x?Ck-5pVg`dsV$X>0SS&cf^ zW{Lex0T&?(bP?@v)N@T zK*QB?mMPmR^K}ig8m^!9t&7|nwy5cfi|12_sqPxE2DN&kMXGj#BHc~<-5g5Y)l8GQ zAvi5R?V4cTx|&TxxY`cV&TBI&O{-|_YF5M_D`>wd`qvn$)d4uDbD?cQ?Sf&xB>y*K z^Dm{kV2jnTSL$20$;=lmEvfq5FaE^U;t5vqg}om@tKu$&pu4Nl+e>&@*WU2p_69dM zrM#nMdBZPZ*Hn8sS<8mEL1@=R9n@S=BoCpBh6DA zM(UAm8xUa*XUE+TIJAZ zYOb0`pQ{tqiF8ygzzxMHs{-K1`& zpVXb|PCAc*;IVei8N5pBM$#Emy+!HpE+SQ=iN4~vxG1W`b#X&H5YNP4;)VEI)ZoTk zr|MN3+!;ElZmO5sTn$h|)JQc(jZ>4S%S0 z>9me)@TyZSRV$;Nk7#cvbi!YBQ=`;QYJ%ETO)l->BlJ3P5FbSFPm~(_wH5At2I6Dl zc1*MogX)h4*B=e3KN^ao9VWYB^+&_&k4DrVjns~eH{sgJ>~<^$%txn>{g{sI@EJ%iJ`o2*DOQn4HpaFWj&{_DnAnFEYtI-X+Y677JIZbCvxqp3 z&koP<3E~MpK|IH2h`;f9;xRr|JjCaVTi8A)#CPJPIEC%>mH4W3U3-xyxuM?{sf)3L z?XkL zQVE|d@hs$Le2KCtUBHv82>Jz&qN3=c=qNhUuXvKxpDu}kViH|7rSl9AsXnFWcu;kO zUeqUzuf#}`@J?(xBs{oV${l=eGi`jhD!td~sRVZF}ovWM(1ZpH1CpOuSZ zvM3U>#j5(}fX5V*Kz`CXBLs?x7lmSqm?{QHhoz%Zx%9PkTskSHNoS=WrAjefx+?uH zW=Qv?=VGSLLdSJN%+lHG9CS@|E;={-eZf;0jAj19*XR){tfV={_MxJU*IeCI-Ayr1 z_lNGD?xF5a-BU4N_qVPFn|Xnr>xEcojP4-ZI*3L3F8V}$cYTUJUEfFF5B~;;*Y!j7 zBg7K@IQ<0uM16sNhJK!Yp?;-)wODGL-$C^D6w56_EW*VKix`Upi|!W57O56JE&5pW zw-{tG#A3KuX$%e%t)&ab0bzLdP#}BCE#!7$jT|5ci?wpN94SZ3F>;((Cnt#Ya*{km z9xjhmewD|{Im#umL7pg2lMV75d4arGULuV0YS}1nmbc4q%kRj0?`H8k$jT zWnIKJmMq>9+rDp`?uml?!+VlR80Ef?>L55$LTv+|25X=q6C z(SI9Kxq^ngCq6beq+G0X_*XBQT5(+|T5-?+y$g%kTmSn`L>K<62gR2v{->LZbVvKO zZaf(!yre?o-6%1hFV^?fXNe`oVbQ`L+h$F)=q{}`UW^ulM?14-;!PIIIzcmKaxc5(1)Z?j#0Ei;d4Z z;i~zz#YKxN7T3jUV|J`aH#o7z(4)h@6vOftjR`-kdmdL(r771njjTOv!$idhSIii!d)8L1Sy0hF8|I<~=Qs@3+quu`iF5q{d delta 12935 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 + Layout::spacingSm() + metaFont->LegacySize; const float cardGap = Layout::spacingMd(); // more breathing room between wallet cards @@ -81,9 +83,14 @@ public: const float ctrlRow = ImGui::GetFrameHeightWithSpacing(); const float capRow = Type().caption()->LegacySize + style.ItemSpacing.y; + const int numScanFolders = app ? (int)app->walletIndex().extraFolders().size() : 0; + const float foldersH = numScanFolders > 0 + ? (capRow + (float)numScanFolders * ctrlRow + Layout::spacingXs()) // "Scanned folders:" + one row each + : 0.0f; const float belowH = 4.0f * Layout::spacingSm() + (capRow + ctrlRow) // Create label + input row + ctrlRow // full-width "scan folder" button + + foldersH // scanned-folders manager + (style.ItemSpacing.y + 1.0f) // separator + ctrlRow // footer buttons + 6.0f * style.ItemSpacing.y; // uncounted inter-item gaps @@ -422,6 +429,51 @@ public: }); } + // ---- Manage scanned folders: list each user-added folder with a control to stop scanning it. + // (The datadir is always scanned and isn't listed here — only the folders the user added.) ----- + { + const auto& scanFolders = app->walletIndex().extraFolders(); + if (!scanFolders.empty()) { + ImGui::Dummy(ImVec2(0, Layout::spacingXs())); + Type().textColored(TypeStyle::Caption, OnSurfaceMedium(), TR("wallets_scanned_folders")); + ImFont* pf = Type().caption(); + const float bh2 = ImGui::GetFrameHeight(); + // Front-elide a long path so its identifying tail (the leaf folder) stays visible. + auto elideFront = [&](std::string s, float maxW) { + auto w = [&](const std::string& t){ return pf->CalcTextSizeA(pf->LegacySize, FLT_MAX, 0, t.c_str()).x; }; + if (w(s) <= maxW) return s; + while (s.size() > 1 && w("\xE2\x80\xA6" + s) > maxW) { + s.erase(s.begin()); + while (!s.empty() && (static_cast(s.front()) & 0xC0) == 0x80) s.erase(s.begin()); + } + return "\xE2\x80\xA6" + s; + }; + std::string toRemove; + for (const auto& folder : scanFolders) { + ImGui::PushID(folder.c_str()); + IconButtonStyle rm; + rm.color = OnSurfaceMedium(); + rm.hoverColor = Error(); + rm.hoverBg = StateHover(); + rm.bgRounding = 4.0f * dp; + rm.tooltip = TR("wallets_remove_folder"); + if (IconButton("##rmScanFolder", ICON_MD_CLOSE, Type().iconSmall(), ImVec2(bh2, bh2), rm)) + toRemove = folder; + ImGui::SameLine(0, Layout::spacingSm()); + ImGui::AlignTextToFramePadding(); + const float textW = listW - bh2 - 2.0f * Layout::spacingSm(); + Type().textColored(TypeStyle::Caption, OnSurface(), elideFront(folder, textW).c_str()); + if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", folder.c_str()); + ImGui::PopID(); + } + if (!toRemove.empty()) { + app->walletIndex().removeExtraFolder(toRemove); + app->walletIndex().save(); + s_needScan = true; // re-scan so wallets from the dropped folder disappear + } + } + } + ImGui::Dummy(ImVec2(0, Layout::spacingSm())); ImGui::Separator(); // ---- Refresh: icon-only, de-emphasized next to the text actions ----------------------- diff --git a/src/util/i18n.cpp b/src/util/i18n.cpp index b51d52f..00c78d5 100644 --- a/src/util/i18n.cpp +++ b/src/util/i18n.cpp @@ -287,6 +287,8 @@ void I18n::loadBuiltinEnglish() strings_["wallets_never"] = "Never opened"; strings_["wallets_external_tt"] = "Outside your data directory \xE2\x80\x94 Open links it in place (no copy)."; strings_["wallets_scan_folder"] = "Scan another folder for wallets\xE2\x80\xA6"; + strings_["wallets_scanned_folders"] = "Scanned folders:"; + strings_["wallets_remove_folder"] = "Stop scanning this folder"; strings_["wallets_folder_invalid"] = "That folder doesn't exist."; strings_["wallets_new_label"] = "Create a new wallet:"; strings_["wallets_new_hint"] = "Name (e.g. savings)";