From 1be69784396f194419adda53331d5fee02ea062b Mon Sep 17 00:00:00 2001 From: Acid-Burn Date: Tue, 4 Nov 2008 12:13:37 +0100 Subject: [PATCH 1/1] add virtual keyboard as easy input help add icons for virtual keyboard network fixes wlan fixeS --- data/skin_default.xml | 11 +- data/skin_default/vkey_backspace.png | Bin 0 -> 783 bytes data/skin_default/vkey_bg.png | Bin 0 -> 577 bytes data/skin_default/vkey_clr.png | Bin 0 -> 955 bytes data/skin_default/vkey_esc.png | Bin 0 -> 1321 bytes data/skin_default/vkey_icon.png | Bin 0 -> 2512 bytes data/skin_default/vkey_left.png | Bin 0 -> 819 bytes data/skin_default/vkey_ok.png | Bin 0 -> 990 bytes data/skin_default/vkey_right.png | Bin 0 -> 817 bytes data/skin_default/vkey_sel.png | Bin 0 -> 173 bytes data/skin_default/vkey_shift.png | Bin 0 -> 767 bytes data/skin_default/vkey_shift_sel.png | Bin 0 -> 1395 bytes data/skin_default/vkey_space.png | Bin 0 -> 577 bytes data/skin_default/vkey_text.png | Bin 0 -> 262 bytes lib/python/Components/HelpMenuList.py | 25 +- lib/python/Components/Network.py | 331 +++++++++----- lib/python/Screens/Makefile.am | 2 +- lib/python/Screens/NetworkSetup.py | 604 +++++++++++++++++++------- lib/python/Screens/VirtualKeyBoard.py | 287 ++++++++++++ 19 files changed, 978 insertions(+), 282 deletions(-) mode change 100644 => 100755 data/skin_default.xml create mode 100755 data/skin_default/vkey_backspace.png create mode 100755 data/skin_default/vkey_bg.png create mode 100755 data/skin_default/vkey_clr.png create mode 100755 data/skin_default/vkey_esc.png create mode 100755 data/skin_default/vkey_icon.png create mode 100755 data/skin_default/vkey_left.png create mode 100755 data/skin_default/vkey_ok.png create mode 100755 data/skin_default/vkey_right.png create mode 100755 data/skin_default/vkey_sel.png create mode 100755 data/skin_default/vkey_shift.png create mode 100755 data/skin_default/vkey_shift_sel.png create mode 100755 data/skin_default/vkey_space.png create mode 100755 data/skin_default/vkey_text.png mode change 100644 => 100755 lib/python/Components/HelpMenuList.py mode change 100644 => 100755 lib/python/Components/Network.py mode change 100644 => 100755 lib/python/Screens/Makefile.am mode change 100644 => 100755 lib/python/Screens/NetworkSetup.py create mode 100755 lib/python/Screens/VirtualKeyBoard.py diff --git a/data/skin_default.xml b/data/skin_default.xml old mode 100644 new mode 100755 index 88cf8b40..41a7e4c9 --- a/data/skin_default.xml +++ b/data/skin_default.xml @@ -42,6 +42,9 @@ + + + @@ -568,7 +571,7 @@ self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y())) - + @@ -1157,4 +1160,10 @@ self.instance.move(ePoint(orgpos.x() + (orgwidth - newwidth)/2, orgpos.y())) + + + + + + diff --git a/data/skin_default/vkey_backspace.png b/data/skin_default/vkey_backspace.png new file mode 100755 index 0000000000000000000000000000000000000000..ed49159ffbc15996158704e9319c20b9a2a5914a GIT binary patch literal 783 zcmV+q1MvKbP)oHxVB;5FRxU z9yAagG!Gmz4;(W8|NnG+hzk`c2oE6&5+w>0CkPKB2Mr$y5hDl?A_ff}3KJ#?5hMcz z3B^DGU}W3>Pd77%dGLE)E$l4jM2H8!^w()(aFP2@)VfPGJfYAwy1I z3l$_pP-8zwRtOIqLQGu>5+OrRVFd{lL{DN16e2xCQbSH)?(gsf2^2z1Ua76MtFX8R z3l|9x9z#uEs;#wAT5Du%dj$y>eua=BD?dC!P&`9XJVH@CK~MDb^*%&XJV8zc3Kc&` zS3pTwK1NmJ<>x9iN7&ll0tE{-KvcfK#yLV&1PBr+Ge;5}F)BApJ3vlBN?e$nr5`Im z1`HT>evCj#S_TanK}uVyuC@dS6F*2FhyET?h^v%+AxRueSsU6#4r4tFX5R z4H-K>P44gU1`8IdueS&f9o^sJK1Eas5g#HiMX9Z{7$Y}ze2E7Q8sF^jbpQYXF-b&0 zRCwC7(^XdjQ4|H>ZR@qWXek910|c?VySuwP{=7qsjEFOv2fw$w)_%C_oPE%r%iBU@ z4$p>;Y@Q8WS-d7VGkFfQXYd@br}J82Pvcq9oXWGJC52~219Y&{3o>3vhg;u|#x6^wig~fx`?L_YKL&W*x zE>A6z6>ognlE@1-%pprB;f%LVW=a zJ%&no6BsVyc`%sI^I)Wg=fik4&xhk;-X+${c!#*H;w_`Ek~jY)zyRgihS+^yvNZqz N002ovPDHLkV1nC7CT{=$ literal 0 HcmV?d00001 diff --git a/data/skin_default/vkey_bg.png b/data/skin_default/vkey_bg.png new file mode 100755 index 0000000000000000000000000000000000000000..5151da4ca63656e9ee2eb9d74df0c921a2ab5274 GIT binary patch literal 577 zcmV-H0>1r;P)#4;(WQ zA2$#lH4-2=5FIoM5+w>0CkhiL4Hzy54j%>#9SIR60|g8S4h4j>L1 zFb*3r3>GR26(|fBEC~@K3l%8{4g^&jg8azQx1ql}g3Kc<0TpueyJVQ|g2oeYm z8$d}~1`Qbm2oyj`SwTu$1`8HELQy+FPCrOlK1EbKLQp(FP6P-OK15R*BB?+C007BJ zL_t(|+O*S0T7m%#MbWERuoo1&=ntr%6npPt@7?`xM3!(f;EXfK_wvHUxOdBThgV>$ z(<`vjv!yT zVt;uu=^b!0;njH^^Xfbfct^bCyfU9NUYX-5?}5skcS&X1JL9y^d*Z9#+vl&>E3rB3 zHK%92H|`d_Yu-n_8sGC?jq|Km*&FiiX^eP>{{jpE$*Xw368eeq P00000NkvXXu0mjf(U7?+ literal 0 HcmV?d00001 diff --git a/data/skin_default/vkey_clr.png b/data/skin_default/vkey_clr.png new file mode 100755 index 0000000000000000000000000000000000000000..0c7734bf47aebba998b627ace8d80cbddefb664e GIT binary patch literal 955 zcmV;s14R6ZP)GR05hDio8!-+VFb)|n4HzvA7%soV$-cqIzrx516eI8O@z2rL z3KJniPGJcWAWl|h&(YNj6(o=l$=$eBaTr!@n%<$)qCra5@%yPGyq60r`8fxF^vLc6n4Q`uRZl z0F{Xp3rc0_bwxWE?e}*!>)Nbq3zdl!TXZdKSF_*I-N~{|*Pb5B%CXl(z06rwTb56v zyA$0@GVF46P2+CAHy;=8m&+ ze-n-j;+GxB^J%}`-_6^0ny!glrfoaJd^j?Q4^H4)hF;QR#&OcR(T1HQ(~fhG{1J>S z;Z`CvwAD@T!B8SGVm>aJNODBy!@4utv2a+f9rGvUZerq~+$<&z$bH29O1UpsJSKM) z>$P&7ICor5PoI*T!HXku*YK`Nt`9Fy$o1h)jocJoRme@@(;>N^_Jj13;;HTl!cXJsAT{E002ovPDHLkV1jHsbE^OV literal 0 HcmV?d00001 diff --git a/data/skin_default/vkey_esc.png b/data/skin_default/vkey_esc.png new file mode 100755 index 0000000000000000000000000000000000000000..56c52d301b0195a366571bc1e26ad9b5f5e2b138 GIT binary patch literal 1321 zcmV+^1=jkBP)8>CI}B92oNF+7Agu9CkPKB3l%8|5hDi< z9|;j83KAs@7c37PGY}m#4jM2H87~eSF%1|k4Hz!p;pFe|@xQ{zzr)GC!N-1tkP8$e z-{9kZg^>yqAwf)DLr!6Uhm#2sAb*CEL{MW36(m4QT`xLLPFH6L4;%&!9tjX02Mr$t z2^0kh6$T3zLQGu?6e6#)x}Kw}9w|Nw5+OrQUq44yP+M$7Phvt$UQJbGLr!3ThLb~2 zVJ33U67EF zk&%&-l9H2?la!Q{m6es2mX?>7mzbECnVFfInwp!No1C1Sot>SYo}QndpP-Ll?si~=|s;aB2tE{Z7t*x!DuCA}IuduMNv9YnTva++Y zv$V9dwY9ajwzjvox45{txw*Nzy1Ki&yS%)-y}iA@zP`V|zreu2!NI}8!otJD!^FhI z#l^+O#>U6T$H>UY$;rve%F4^j%goHo&CSiu&d$%z&(P4&(b3V;($dq@)6~?|)z#J3 z*4Ee8*Vx$D+1c6J+S=RO+uYpT-QC^Z-rnEe-{9cj;o;%p;^O1ulq(=H}<; z=jiC@>FMd}>gwz3>+J08?d|RE?(XmJ@9^;O@$vEU^78ZZ^Yrxe_4W1k_V)Mp_xSku z`T6eQ4~f`4@J^y&vR9! zlI#La6Lis|?Lr$x1l{OHL=Z(3#Q_yT!C|2bZQ7rF{p!7{B($5Gg$M4t->aNOQtv*( z$pt@OIBNLmb0fn`*5`Kaw)3l8n}Hb*(zdwSgr)~+TWlwgc#w95?MayQAg#x(DVXvg zt;h9gnD!v8$HfVl@F4Bdf3?T^-s8QK@!oehORI<>Nd`F?eiY6!&WTw$3RZ_^+}iM& z#W{&HXjYC{xr7vUgIIQpGg!`do|~!iz%bg#lROXeUEZB6GgD;&#bFxh;qDwYpwS3F zq`H0ogxIC^`O}7W+f3Dt*x3-fv}e3&L91n^YDLVf4x?S#9*+ws3bR5~OWYJ^y0ksM zccI%g>k6wY?CMr^X&-ssflkM)BdiKmZNpl3X*)bfA+3)$9W0i{oDRCQ9Ud*gk_Tx& zI9`QS57ItyJPWfPq`l(pGAw(L_Ko}VFz-RyZ+>mUrUz-4xw8Qq9;C@$gEbG*PI&Y+5u12VcmnY1K#hu|I_wA^I_L*@4n#Yc|Ujg fdd|JR3t5qez}e0tZ9l;mGbJC%%al)g0jfLNhE-j$kw$f@8r+ zd`pZI)S3;!GOX|%IFSbsy@*T+i7mBbNhn;IgPYt{9N{U65-SqISFVjp%3g|e z2IE~Y>~J{A6M~~7$XeC-4)?Zxp#cO{7z%nDR{#}+#I#(IQigsd)z z%`A;yUtam!Nx)tTP$Wx9LKBAo6SCNp7HCQfFmntta||?hQkYT1=0-r1En@_O7z#^f z2-rym<%C1op)h6;%vpxuhQiqj1V@Q>3rBI4SodGBuEqf(Q4BwVceJA^$XkDyaC6j>?vn4pV+#AAmr%I6Jra zm5zV{a&O*Xpo)|2twZX)*WJCh;_T6MN6`I2h$&{~)996gnT78k2}4yiyqT|&lUq6p zCN$(C!@7y~g!}c$ua1Z8r;DDOo5Jiw4LqnkH#_Fpo@ahFf=gD?fdgKiP20fa^yj?I zQ{(dee~RjNwRT>~eblr4F3v9L96X3CEGm4|J7Aq0GBZecn%y3E0RiHN^SDFjHuM`N zs=cxbFX!~%xLKXwAkIUZ0i6}aV}R+Tz?T>>y(b~8G4t1{H8brAmo^GF8)ko&P%HL) z5?$Z5bdL*31a_#l_1@L8xp!gP>f@1om$=UNH521L3rD|h8o6;;kTf~GW#Yl)vqOJs)aHha4~O;DM=sZQ z&))8@!#zlTDxCOow~qULvZyoT`>DG8MB&K%%iI0>utv?u^!wf_eO=?HXVYsYdTyTn z)FA6G9D`d=4)JEc>=9KTNgQ2rF73l@vjVTI;eyFqpAHK?H~9MIPc+sEEcN9)CF5$)tXqRcN`t82C%8sjWs|Hdn*TXJp%3V)2$V>)r44lWq%=?! z-xVlPNwkGR_)VIFpts=q^-U~sMa$2$#Dw{Y*7rR-1}9IP=z`4t;Nvch>2~axYdLXZ z@IdSpm$U;HHY@qG`y{=sj0=(y{#MH zTT@^BW&%?+e{J$w?)x5(sZy$a%Z865>jpAAa{p_;R@*~8FnoS)>LX7(9oaKoEIGf> zmaePQ2A!RfD>@Ws6;mAw#grVZoI2B?ozCe{DDMP;gF3WRQ*v#N$;dMz2j~V{%)ZZA?|Ff?5xS?X`xItjdUIL;n z9^(&nHVFzkBQ^#HCu<_}qN0O?H|*1>G&y;p8}ouUG$$yCeP=Uzb8;+tb9R1tbhYz* z)g#5e-Z_d&SMGm2m9n6!z1paYrrfE$s(7!XRHi0=t9+tM)LFf0e`3|xQCq2KYMXfU z>bK>7Wp&D+vTaIf&9=aW`yae$GTHIk6j|yGa%Lu^*RS2W{K#}}WrR?O6shL+iI5FN zb3dkDT@$9-0^MKZ8)H_SAP}<%^XE7{G}b$%`fvTr^v;2<$X&}5WC@4sVi;vrTXj|{{rEg5GB2tHSY2=tQ3HS8%JIwWa z&W8oG5685vyz=5nIrM_21WtMK&&#O)e01pm{EC+Vq3YDVyJToHxVB;5FRxU z9yAagG!Gmz|Ns9F95M$EAas0)2Mr$y5hDl>Aqf#A2oE9(5+w=~CI$^21`Hht5F!T- z9|Hvp3KS;`6(|c8DGU}W3>Pd77%dGLE)E(n4jVBJ882^lgwN5{3lt*?6Cp!RVF?l- z3l$_pP-6%W90UmzL{DNrM^*+47eh{8Lr-BsOkJw2wX3kWLr!1?2^Bp62Sw2NnA1gppTWR_F`V=BKeua=gNm@QeRR|6nK}%g_Y+#u?lpMz9DZ1Pj4}ySux) zyW1ZpgsQFGO{Qvc;Jdy)yqf93ZHn9_YLn!gXiSuIqA5YH8P)M}cGSno+2M$lYk?z1 z&W4(3IU6dYAb$;FEGY`jxgO5hapMT*YwVNwEqER`r0 zr~Y2M%e0h$A9q%jgZPLn&sYM$IUPBP_u*iV=9VK`aN xjlq05HwIGW#xR>BH-zV0xltSx$W8wUFaV4%h@1r)UIqXF002ovPDHLkV1g!BHjw}T literal 0 HcmV?d00001 diff --git a/data/skin_default/vkey_ok.png b/data/skin_default/vkey_ok.png new file mode 100755 index 0000000000000000000000000000000000000000..2c0c7e88623bd76821d25099a1b1887e4397fcc0 GIT binary patch literal 990 zcmV<410np0P)5g#@W z95N6dH4q*&|NsAVe24}N9Rmdn2M!+!6D9}`Aqo;D2oE9*7AgxBDGL=S2oNF(5hDr| zCkGB72@xa=7c37PGY}m#4jM2G7%dJPF%B6o4Hz!(@bL>2BfrAP3KJm-5+FlPVL(e= z3l$`elbu9RV?$102Mr$x4;%&y7rw#AkCdJY5+OoNT}@SFzr)E36e1odJqZvV1`QtX z@bXYwY(h+4Z+C@IS!x6c6yM?Ge}8h(V3uClpscZESpTpueyJV8z`I!;bjW}l<10tE{P4H-N_P(e#wpQWxqNm?v6 zNIyqc2o4)OLs33PRept#JVH?h3l?36epCPe0pCePK~#9!wAEL0(?AqJ;ghZlq<2e- zZP{^5AR!?MqyR|>HHF@L@4a_I{oPz?EDlYBBuXnxJ1)U3dVG^9)RNucdMz~5x(m82H2cZdPUy7I>;ykrq18gO72Y>PvxR0W zoa=!e3(aPE*$9mmn$2=($o!u+bdj@D=6dQTkJj5=oHxVB;5FRxU z9yAagG!Gmz|Ns9F95M$EAas0)2Mr$y5hDl>Aqf#A2oE9(5+w=~CI$^21`Hht5F!T- z9|Hvp3KS;`6(|c8DGU}W3>Pd77%dGLE)E(n4jVBJ882^lgwN5{3lt*?6Cp!RVF?l- z3l$_pP-6%W90UmzL{DNrM^*+47eh{8Lr-BsOkJw2wX3kWLr!1?2^Bp62Sw2NnA1gppTWR_F`V=BKeua=gNm@QeRR|6nK}%g_Y z7Sx2wSx^}wXF&zz%Kx<;+`EID2|w?3lX>%h>F&4*_)C6I+%(f=+!KBWKZ&+q4Liv1 z_a+hbw5j{e-_D+|P0K6F?da~ZRMr05rpaUdT|O3T$kh9WRyf6ck;c4Dom#<*r4mh< zs{5}zwWt-mxGUt;`O6EsWCU{s9Dn;mpE%H(&*>++eo_(#cJerV^me5t4{+sjCbrHE z$q`&RoWmDmvWxp{&R0Ovi;GmbZ>*)rRiPnC&eu+mJHu**+&E5>C#5QQ z<|d}62BjvZR2H60wE-$(3-AeX{eK3?V#sw9zX_z6N`m}?|1&(@Zr}yv>3h03hE&{2 zN>E`nn6PSAV}!%BtVc11tExi2u6PxAb@3|qQ2v&zTUQ%QR_|nF;$aYXW7{NHXjuv} N(9_k=Wt~$(69BOAG`;`; literal 0 HcmV?d00001 diff --git a/data/skin_default/vkey_shift.png b/data/skin_default/vkey_shift.png new file mode 100755 index 0000000000000000000000000000000000000000..477f8db2646ec5834d0ef516715e3b3f2f4007e5 GIT binary patch literal 767 zcmVGQ|3>^&^E(Z=D3KJ#^6)6i8Bl-IJ3KJm-5+MHm{#0IX zLr!5;UvNZFV+$1|1`8Kzbc17UeMC=U`1tu(VR8it6+=&9`~3VMEkynO{rvp>JwsCW z_xM_6b_59&R9|mHO`?JV8!8LQp_SSp*0YKSx&v3>ZL3T0u%%JU~u7 zLQx43AESs8ZU6uQMM*?KRCwBy)5lr@Q49s(qapjQirxNhZ3;I)}AftNA98$5LJWpOpc zm&MZv-xiXSd!+yRKym#|?ao^78#cm5< x1b5?n5xn*AZQ`ttZy(#Ee2+M7;yeBnU;zISjHO2#_2U2l002ovPDHLkV1h%u6q5h| literal 0 HcmV?d00001 diff --git a/data/skin_default/vkey_shift_sel.png b/data/skin_default/vkey_shift_sel.png new file mode 100755 index 0000000000000000000000000000000000000000..339ddb465f891c2e2474f65344dc8dacbfa6fcba GIT binary patch literal 1395 zcmV-(1&sQMP)5g#@W z95N6dH4q*&|NsAVe24}N9Rmdn2M!+!6D9}`Aqo;D2oE9*7AgxBDGL=S2oNF(5hDr| zCkGB72@xa=7c37PGY}m#4jM2G7%dJPF%B6o4Hz!(@bL>2BfrAP3KJm-5+FlPVL(e= z3l$`elbu9RV?$102Mr$x4;%&y7rw#AkCdJY5+OoNT}@SFzr)E36e1odJqZvV1`QtX z@bXYwY(h+4Z+C@IS!x6c6yM?Ge}8h(V3uClpscZESpTpueyJV8z`I!;bjW}l<10tE{P4H-N_P(e#wpQWxqNm?v6 zNIyqc2o4)OLs33PRept#JVH?h3l@imhlq%XiHV7dii(Sii;Rqnjg5_tj*gFykC2d% zk&%&-l9H2?la!Q{m6es2mX?>7mzbECnVFfInwp!No1C1Sot>SYo}QndpP-Ll?si~=|s;aB2tE{Z7t*x!DuCA}IuduMNv9YnTva++Y zv$V9dwY9ajwzjvox45{txw*Nzy1Ki&yS%)-y}iA@zP`V|zreu2!NI}8!otJD!^FhI z#l^+O#>U6T$H>UY$;rve%F4^j%goHo&CSiu&d$%z&(P4&(b3V;($dq@)6~?|)z#J3 z*4Ee8*Vx$D+1c6J+S=RO+uYpT-QC^Z-rnEe-{9cj;o;%p;^O1ulq(=H}<; z=jiC@>FMd}>gwz3>+J08?d|RE?(XmJ@9^;O@$vEU^78ZZ^Yrxe_4W1k_V)Mp_xSku z`T6;M1)2}wjjRCwBqmFr6sQ5c7xxvWa%{qD@V zD~l^x8YF}^fe=B3m;|QXq1qxM3aOATMEC#Hf1od>&USitF1tr|gZKF|XPAfio%5de z%<$ucp0_M@>8WxlKub{NdZ@O;^IYwL9u1<+a<&_~HHbFLTmcFiM7zM83$E*S40mlr zt8m!|-}jq=ySuG$-$t|w*F5k%FVBni_oHUGXCqpLGY&Y8lf^}Uj5&z%aK}cp)483d zMMp+BjI!|m+DTYcH)dzYm^ezq+wE-Ljr&?`>hq2>|JT%OiO@dptS0hoJ2nS38Mw7W z6K^}s>De{O>g_mN#$0@oEX=+2+tjyOOSkHs?WGsRW^Y4Yk<4mi&m2XqvbOdz>l5E3 zq@nq^y-%_pbWK8_|}zU50YG-0_Q0wh?Wa&oeNiL9`d# zn}%r(qAl`#3Z^uOw#b(u7}6lxSJsAMSc7P1r;P)#4;(WQ zA2$#lH4-2=5FIoM5+w>0CkhiL4Hzy54j%>#9SIR60|g8S4h4j>L1 zFb*3r3>GR26(|fBEC~@K3l%8{4g^&jg8azQx1ql}g3Kc<0TpueyJVQ|g2oeYm z8$d}~1`Qbm2oyj`SwTu$1`8HELQy+FPCrOlK1EbKLQp(FP6P-OK15R*BB?+C007BJ zL_t(|+O*S0T7m%#MbWERuoo1&=ntr%6npPt@7?`xM3!(f;EXfK_wvHUxOdBThgV>$ z(<`vjv!yT zVt;uu=^b!0;njH^^Xfbfct^bCyfU9NUYX-5?}5skcS&X1JL9y^d*Z9#+vl&>E3rB3 zHK%92H|`d_Yu-n_8sGC?jq|Km*&FiiX^eP>{{jpE$*Xw368eeq P00000NkvXXu0mjf(U7?+ literal 0 HcmV?d00001 diff --git a/data/skin_default/vkey_text.png b/data/skin_default/vkey_text.png new file mode 100755 index 0000000000000000000000000000000000000000..6bdb8c84bbdf44f1706d5f8667a227274cbd6e92 GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0y~yV3Gr}O*oi=W!8`Xu4J;;nJ-=9SGW#b7xf9Hl3j9wR zZ6>gPVt})t!svXU8k`!|oH@+VQyJ4SC(*EyiHG6#LDN%Ew-NNAM>gTe~DWM4f D01I24 literal 0 HcmV?d00001 diff --git a/lib/python/Components/HelpMenuList.py b/lib/python/Components/HelpMenuList.py old mode 100644 new mode 100755 index 25c9b8b6..04815c8d --- a/lib/python/Components/HelpMenuList.py +++ b/lib/python/Components/HelpMenuList.py @@ -1,7 +1,6 @@ from GUIComponent import GUIComponent from enigma import eListboxPythonMultiContent, eListbox, gFont - from Tools.KeyBindings import queryKeyBinding, getKeyDescription #getKeyPositions @@ -13,6 +12,7 @@ class HelpMenuList(GUIComponent): self.onSelChanged = [ ] self.l = eListboxPythonMultiContent() self.callback = callback + self.extendedHelp = False l = [ ] for (actionmap, context, actions) in list: @@ -36,17 +36,26 @@ class HelpMenuList(GUIComponent): if flags & 8: # for long keypresses, prepend l_ into the key name. name = (name[0], "long") - print "name:", name - entry.append( (actionmap, context, action, name ) ) - entry.append( (eListboxPythonMultiContent.TYPE_TEXT, 0, 0, 400, 28, 0, 0, help) ) - + + if type(help).__name__== 'list': + self.extendedHelp = True + print "extendedHelpEntry found" + entry.append( (eListboxPythonMultiContent.TYPE_TEXT, 0, 0, 400, 26, 0, 0, help[0]) ) + entry.append( (eListboxPythonMultiContent.TYPE_TEXT, 0, 28, 400, 20, 1, 0, help[1]) ) + else: + entry.append( (eListboxPythonMultiContent.TYPE_TEXT, 0, 0, 400, 28, 0, 0, help) ) + l.append(entry) self.l.setList(l) - - self.l.setFont(0, gFont("Regular", 24)) - self.l.setItemHeight(38) + if self.extendedHelp is True: + self.l.setFont(0, gFont("Regular", 24)) + self.l.setFont(1, gFont("Regular", 18)) + self.l.setItemHeight(50) + else: + self.l.setFont(0, gFont("Regular", 24)) + self.l.setItemHeight(38) def ok(self): # a list entry has a "private" tuple as first entry... diff --git a/lib/python/Components/Network.py b/lib/python/Components/Network.py old mode 100644 new mode 100755 index bed9d95f..e10c6a0e --- a/lib/python/Components/Network.py +++ b/lib/python/Components/Network.py @@ -7,11 +7,19 @@ from Components.Console import Console class Network: def __init__(self): self.ifaces = {} - self.configuredInterfaces = [] + self.configuredInterfaces = [] + self.configuredNetworkAdapters = [] + self.NetworkState = 0 + self.DnsState = 0 self.nameservers = [] self.ethtool_bin = "/usr/sbin/ethtool" self.container = eConsoleAppContainer() self.Console = Console() + self.LinkConsole = Console() + self.restartConsole = Console() + self.deactivateConsole = Console() + self.activateConsole = Console() + self.resetNetworkConsole = Console() self.getInterfaces() def getInterfaces(self, callback = None): @@ -28,6 +36,11 @@ class Network: self.getDataForInterface(device, callback) except AttributeError: pass + #print "self.ifaces:", self.ifaces + #self.writeNetworkConfig() + #print ord(' ') + #for line in result: + # print ord(line[0]) # helper function def regExpMatch(self, pattern, string): @@ -46,66 +59,58 @@ class Network: ip.append(int(x)) return ip + def getDataForInterface(self, iface,callback): + #get ip out of ip addr, as avahi sometimes overrides it in ifconfig. + cmd = "ip -o addr" + self.Console.ePopen(cmd, self.IPaddrFinished, [iface,callback]) + def IPaddrFinished(self, result, retval, extra_args): (iface, callback ) = extra_args data = { 'up': False, 'dhcp': False, 'preup' : False, 'postdown' : False } globalIPpattern = re_compile("scope global") ipRegexp = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' - ipLinePattern = re_compile('inet ' + ipRegexp +'/') + netRegexp = '[0-9]{1,2}' + macRegexp = '[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}' + ipLinePattern = re_compile('inet ' + ipRegexp + '/') ipPattern = re_compile(ipRegexp) - + netmaskLinePattern = re_compile('/' + netRegexp + ' brd ') + netmaskPattern = re_compile(netRegexp) + bcastLinePattern = re_compile(' brd ' + ipRegexp) + upPattern = re_compile('UP') + macPattern = re_compile('[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}\:[a-z0-9]{2}') + macLinePattern = re_compile('link/ether ' + macRegexp) + for line in result.splitlines(): split = line.strip().split(' ',2) + if (split[1][:-1] == iface): + up = self.regExpMatch(upPattern, split[2]) + mac = self.regExpMatch(macPattern, self.regExpMatch(macLinePattern, split[2])) + if up is not None: + data['up'] = True + if iface is not 'lo': + self.configuredInterfaces.append(iface) + if mac is not None: + data['mac'] = mac if (split[1] == iface): if re_search(globalIPpattern, split[2]): ip = self.regExpMatch(ipPattern, self.regExpMatch(ipLinePattern, split[2])) + netmask = self.calc_netmask(self.regExpMatch(netmaskPattern, self.regExpMatch(netmaskLinePattern, split[2]))) + bcast = self.regExpMatch(ipPattern, self.regExpMatch(bcastLinePattern, split[2])) if ip is not None: data['ip'] = self.convertIP(ip) + if netmask is not None: + data['netmask'] = self.convertIP(netmask) + if bcast is not None: + data['bcast'] = self.convertIP(bcast) + if not data.has_key('ip'): data['dhcp'] = True data['ip'] = [0, 0, 0, 0] data['netmask'] = [0, 0, 0, 0] data['gateway'] = [0, 0, 0, 0] - cmd = "ifconfig " + iface - self.Console.ePopen(cmd, self.ifconfigFinished, [iface, data, callback]) - - def getDataForInterface(self, iface,callback): - #get ip out of ip addr, as avahi sometimes overrides it in ifconfig. - cmd = "ip -o addr" - self.Console.ePopen(cmd, self.IPaddrFinished, [iface,callback]) - - def ifconfigFinished(self, result, retval, extra_args ): - (iface, data, callback ) = extra_args - ipRegexp = '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' - ipLinePattern = re_compile('inet addr:' + ipRegexp) - netmaskLinePattern = re_compile('Mask:' + ipRegexp) - bcastLinePattern = re_compile('Bcast:' + ipRegexp) - ipPattern = re_compile(ipRegexp) - upPattern = re_compile('UP ') - macPattern = re_compile('[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[0-9]{2}\:[0-9]{2}') - - for line in result.splitlines(): - #ip = self.regExpMatch(ipPattern, self.regExpMatch(ipLinePattern, line)) - netmask = self.regExpMatch(ipPattern, self.regExpMatch(netmaskLinePattern, line)) - bcast = self.regExpMatch(ipPattern, self.regExpMatch(bcastLinePattern, line)) - up = self.regExpMatch(upPattern, line) - mac = self.regExpMatch(macPattern, line) - #if ip is not None: - # data['ip'] = self.convertIP(ip) - if netmask is not None: - data['netmask'] = self.convertIP(netmask) - if bcast is not None: - data['bcast'] = self.convertIP(bcast) - if up is not None: - data['up'] = True - if iface is not 'lo': - self.configuredInterfaces.append(iface) - if mac is not None: - data['mac'] = mac - cmd = "route -n | grep " + iface - self.Console.ePopen(cmd,self.routeFinished,[iface,data,callback]) + self.Console.ePopen(cmd,self.routeFinished, [iface, data, callback]) def routeFinished(self, result, retval, extra_args): (iface, data, callback) = extra_args @@ -119,16 +124,7 @@ class Network: gateway = self.regExpMatch(ipPattern, line[16:31]) if gateway is not None: data['gateway'] = self.convertIP(gateway) - - for line in result.splitlines(): #get real netmask in case avahi has overridden ifconfig netmask - split = line.strip().split(' ') - if re_search(ipPattern, split[0]): - foundip = self.convertIP(split[0]) - if (foundip[0] == data['ip'][0] and foundip[1] == data['ip'][1]): - if re_search(ipPattern, split[4]): - mask = self.regExpMatch(ipPattern, self.regExpMatch(ipLinePattern, split[4])) - if mask is not None: - data['netmask'] = self.convertIP(mask) + self.ifaces[iface] = data self.loadNetworkConfig(iface,callback) @@ -203,7 +199,7 @@ class Network: ifaces[currif]["gateway"] = map(int, split[1].split('.')) if self.ifaces[currif].has_key("gateway"): if self.ifaces[currif]["gateway"] != ifaces[currif]["gateway"] and ifaces[currif]["dhcp"] == False: - self.ifaces[currif]["gateway"] = map(int, split[1].split('.')) + self.ifaces[currif]["gateway"] = map(int, split[1].split('.')) if (split[0] == "pre-up"): if self.ifaces[currif].has_key("preup"): self.ifaces[currif]["preup"] = i @@ -215,7 +211,9 @@ class Network: if self.ifaces.has_key(ifacename): self.ifaces[ifacename]["dhcp"] = iface["dhcp"] if len(self.Console.appContainers) == 0: - # load ns only once + # save configured interfacelist + self.configuredNetworkAdapters = self.configuredInterfaces + # load ns only once self.loadNameserverConfig() print "read configured interfac:", ifaces print "self.ifaces after loading:", self.ifaces @@ -244,16 +242,39 @@ class Network: print "nameservers:", self.nameservers - def deactivateNetworkConfig(self): + def deactivateNetworkConfig(self, callback = None): + self.deactivateConsole = Console() + self.commands = [] + self.commands.append("/etc/init.d/avahi-daemon stop") for iface in self.ifaces.keys(): - system("ip addr flush " + iface) - system("/etc/init.d/networking stop") - system("killall -9 udhcpc") - system("rm /var/run/udhcpc*") + cmd = "ip addr flush " + iface + self.commands.append(cmd) + self.commands.append("/etc/init.d/networking stop") + self.commands.append("killall -9 udhcpc") + self.commands.append("rm /var/run/udhcpc*") + self.deactivateConsole.eBatch(self.commands, self.deactivateNetworkFinished, callback, debug=True) + + def deactivateNetworkFinished(self,extra_args): + callback = extra_args + if len(self.deactivateConsole.appContainers) == 0: + if callback is not None: + callback(True) - def activateNetworkConfig(self): - system("/etc/init.d/networking start") - self.getInterfaces() + def activateNetworkConfig(self, callback = None): + self.activateConsole = Console() + self.commands = [] + self.commands.append("/etc/init.d/networking start") + self.commands.append("/etc/init.d/avahi-daemon start") + self.activateConsole.eBatch(self.commands, self.activateNetworkFinished, callback, debug=True) + + def activateNetworkFinished(self,extra_args): + callback = extra_args + if len(self.activateConsole.appContainers) == 0: + if callback is not None: + callback(True) + + def getConfiguredAdapters(self): + return self.configuredNetworkAdapters def getNumberOfAdapters(self): return len(self.ifaces) @@ -312,7 +333,24 @@ class Network: if self.nameservers[i] == oldnameserver: self.nameservers[i] = newnameserver - def writeDefaultNetworkConfig(self,mode='lan'): + def resetNetworkConfig(self, mode='lan', callback = None): + self.resetNetworkConsole = Console() + self.commands = [] + self.commands.append("/etc/init.d/avahi-daemon stop") + for iface in self.ifaces.keys(): + cmd = "ip addr flush " + iface + self.commands.append(cmd) + self.commands.append("/etc/init.d/networking stop") + self.commands.append("killall -9 udhcpc") + self.commands.append("rm /var/run/udhcpc*") + self.resetNetworkConsole.eBatch(self.commands, self.resetNetworkFinishedCB, [mode, callback], debug=True) + + def resetNetworkFinishedCB(self, extra_args): + (mode, callback) = extra_args + if len(self.resetNetworkConsole.appContainers) == 0: + self.writeDefaultNetworkConfig(mode, callback) + + def writeDefaultNetworkConfig(self,mode='lan', callback = None): fp = file('/etc/network/interfaces', 'w') fp.write("# automatically generated by enigma 2\n# do NOT change manually!\n\n") fp.write("auto lo\n") @@ -329,50 +367,95 @@ class Network: fp.write("\n") fp.close() - def resetNetworkConfig(self,mode='lan'): - self.deactivateNetworkConfig() - self.writeDefaultNetworkConfig(mode) + self.resetNetworkConsole = Console() + self.commands = [] if mode == 'wlan': - system("ifconfig eth0 down") - system("ifconfig ath0 down") - system("ifconfig wlan0 up") + self.commands.append("ifconfig eth0 down") + self.commands.append("ifconfig ath0 down") + self.commands.append("ifconfig wlan0 up") if mode == 'wlan-mpci': - system("ifconfig eth0 down") - system("ifconfig wlan0 down") - system("ifconfig ath0 up") + self.commands.append("ifconfig eth0 down") + self.commands.append("ifconfig wlan0 down") + self.commands.append("ifconfig ath0 up") if mode == 'lan': - system("ifconfig eth0 up") - system("ifconfig wlan0 down") - system("ifconfig ath0 down") - self.getInterfaces() - - def checkNetworkState(self): - # www.dream-multimedia-tv.de, www.heise.de, www.google.de - return system("ping -c 1 82.149.226.170") == 0 or \ - system("ping -c 1 193.99.144.85") == 0 or \ - system("ping -c 1 209.85.135.103") == 0 - - def restartNetwork(self): - iNetwork.deactivateNetworkConfig() - iNetwork.activateNetworkConfig() + self.commands.append("ifconfig eth0 up") + self.commands.append("ifconfig wlan0 down") + self.commands.append("ifconfig ath0 down") + self.commands.append("/etc/init.d/avahi-daemon start") + self.resetNetworkConsole.eBatch(self.commands, self.resetNetworkFinished, [mode,callback], debug=True) + + def resetNetworkFinished(self,extra_args): + (mode, callback) = extra_args + if len(self.resetNetworkConsole.appContainers) == 0: + if callback is not None: + callback(True,mode) + + def checkNetworkState(self,statecallback): + # www.dream-multimedia-tv.de, www.heise.de, www.google.de + cmd1 = "ping -c 1 82.149.226.170" + cmd2 = "ping -c 1 193.99.144.85" + cmd3 = "ping -c 1 209.85.135.103" + self.PingConsole = Console() + self.PingConsole.ePopen(cmd1, self.checkNetworkStateFinished,statecallback) + self.PingConsole.ePopen(cmd2, self.checkNetworkStateFinished,statecallback) + self.PingConsole.ePopen(cmd3, self.checkNetworkStateFinished,statecallback) + + def checkNetworkStateFinished(self, result, retval,extra_args): + (statecallback) = extra_args + if self.PingConsole is not None: + if retval == 0: + self.PingConsole = None + statecallback(self.NetworkState) + else: + self.NetworkState += 1 + if len(self.PingConsole.appContainers) == 0: + statecallback(self.NetworkState) + + def restartNetwork(self,callback): + self.restartConsole = Console() + self.commands = [] + self.commands.append("/etc/init.d/avahi-daemon stop") + for iface in self.ifaces.keys(): + cmd = "ip addr flush " + iface + self.commands.append(cmd) + self.commands.append("/etc/init.d/networking stop") + self.commands.append("killall -9 udhcpc") + self.commands.append("rm /var/run/udhcpc*") + self.commands.append("/etc/init.d/networking start") + self.commands.append("/etc/init.d/avahi-daemon start") + self.restartConsole.eBatch(self.commands, self.restartNetworkFinished, callback, debug=True) + + def restartNetworkFinished(self,extra_args): + callback = extra_args + if len(self.restartConsole.appContainers) == 0: + callback(True) def getLinkState(self,iface,callback): - self.dataAvail = callback cmd = self.ethtool_bin + " " + iface - self.container.appClosed.append(self.cmdFinished) - self.container.dataAvail.append(callback) - self.container.execute(cmd) - - def cmdFinished(self,retval): - self.container.appClosed.remove(self.cmdFinished) - self.container.dataAvail.remove(self.dataAvail) - - def stopContainer(self): - self.container.kill() - - def ContainerRunning(self): - return self.container.running() - + self.LinkConsole = Console() + self.LinkConsole.ePopen(cmd, self.getLinkStateFinished,callback) + + def getLinkStateFinished(self, result, retval,extra_args): + (callback) = extra_args + if self.LinkConsole is not None: + if len(self.LinkConsole.appContainers) == 0: + callback(result) + + def stopLinkStateConsole(self): + if self.LinkConsole is not None: + self.LinkConsole = None + + def stopRestartConsole(self): + if self.restartConsole is not None: + self.restartConsole = None + + def RestartConsoleRunning(self): + if self.restartConsole is not None: + if len(self.restartConsole.appContainers) == 0: + return False + else: + return True + def checkforInterface(self,iface): if self.getAdapterAttribute(iface, 'up') is True: return True @@ -384,13 +467,37 @@ class Network: else: return False - def checkDNSLookup(self): - return system("nslookup www.dream-multimedia-tv.de") == 0 or \ - system("nslookup www.heise.de") == 0 or \ - system("nslookup www.google.de") + def checkDNSLookup(self,statecallback): + cmd1 = "nslookup www.dream-multimedia-tv.de" + cmd2 = "nslookup www.heise.de" + cmd3 = "nslookup www.google.de" + self.DnsConsole = Console() + self.DnsConsole.ePopen(cmd1, self.checkDNSLookupFinished,statecallback) + self.DnsConsole.ePopen(cmd2, self.checkDNSLookupFinished,statecallback) + self.DnsConsole.ePopen(cmd3, self.checkDNSLookupFinished,statecallback) + + def checkDNSLookupFinished(self, result, retval,extra_args): + (statecallback) = extra_args + if self.DnsConsole is not None: + if retval == 0: + self.DnsConsole = None + statecallback(self.DnsState) + else: + self.DnsState += 1 + if len(self.DnsConsole.appContainers) == 0: + statecallback(self.DnsState) def deactivateInterface(self,iface): - system("ifconfig " + iface + " down") + self.deactivateInterfaceConsole = Console() + self.commands = [] + cmd1 = "ip addr flush " + iface + cmd2 = "ifconfig " + iface + " down" + self.commands.append(cmd1) + self.commands.append(cmd2) + self.deactivateInterfaceConsole.eBatch(self.commands, self.deactivateInterfaceFinished, extra_args = None, debug=True) + + def deactivateInterfaceFinished(self,extra_args): + pass def detectWlanModule(self): self.wlanmodule = None @@ -411,6 +518,20 @@ class Network: self.wlanmodule = 'zydas' return self.wlanmodule + def calc_netmask(self,nmask): + from struct import pack, unpack + from socket import inet_ntoa, inet_aton + mask = 1L<<31 + xnet = (1L<<32)-1 + cidr_range = range(0, 32) + cidr = long(nmask) + if cidr not in cidr_range: + print 'cidr invalid: %d' % cidr + return None + else: + nm = ((1L<L', nm))) + return netmask iNetwork = Network() diff --git a/lib/python/Screens/Makefile.am b/lib/python/Screens/Makefile.am old mode 100644 new mode 100755 index 186c6f32..a3cf70bb --- a/lib/python/Screens/Makefile.am +++ b/lib/python/Screens/Makefile.am @@ -13,5 +13,5 @@ install_PYTHON = \ TimerSelection.py PictureInPicture.py TimeDateInput.py \ SubtitleDisplay.py SubservicesQuickzap.py ParentalControlSetup.py NumericalTextInputHelpDialog.py \ SleepTimerEdit.py Ipkg.py RdsDisplay.py Globals.py DefaultWizard.py \ - SessionGlobals.py LocationBox.py WizardLanguage.py TaskView.py Rc.py + SessionGlobals.py LocationBox.py WizardLanguage.py TaskView.py Rc.py VirtualKeyBoard.py diff --git a/lib/python/Screens/NetworkSetup.py b/lib/python/Screens/NetworkSetup.py old mode 100644 new mode 100755 index 862bce46..c26302fa --- a/lib/python/Screens/NetworkSetup.py +++ b/lib/python/Screens/NetworkSetup.py @@ -1,25 +1,25 @@ from Screen import Screen -from Components.ActionMap import ActionMap,NumberActionMap from Screens.MessageBox import MessageBox from Screens.InputBox import InputBox from Screens.Standby import * +from Screens.VirtualKeyBoard import VirtualKeyBoard +from Screens.HelpMenu import HelpableScreen from Components.Network import iNetwork from Components.Label import Label,MultiColorLabel from Components.Pixmap import Pixmap,MultiPixmap from Components.MenuList import MenuList -from Components.config import config, ConfigYesNo, ConfigIP, NoSave, ConfigText, ConfigSelection, getConfigListEntry, ConfigNothing +from Components.config import config, ConfigYesNo, ConfigIP, NoSave, ConfigText, ConfigPassword, ConfigSelection, getConfigListEntry, ConfigNothing from Components.ConfigList import ConfigListScreen from Components.PluginComponent import plugins from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest +from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap +from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE +from Tools.LoadPixmap import LoadPixmap from Plugins.Plugin import PluginDescriptor -from enigma import eTimer +from enigma import eTimer, ePoint, eSize, RT_HALIGN_LEFT, eListboxPythonMultiContent, gFont from os import path as os_path, system as os_system, unlink from re import compile as re_compile, search as re_search -from Tools.Directories import resolveFilename, SCOPE_PLUGINS -from Tools.Directories import SCOPE_SKIN_IMAGE,SCOPE_PLUGINS, resolveFilename -from Tools.LoadPixmap import LoadPixmap -from enigma import RT_HALIGN_LEFT, eListboxPythonMultiContent, gFont class InterfaceList(MenuList): def __init__(self, list, enableWrapAround=False): @@ -30,11 +30,13 @@ class InterfaceList(MenuList): def InterfaceEntryComponent(index,name,default,active ): res = [ (index) ] res.append(MultiContentEntryText(pos=(80, 5), size=(430, 25), font=0, text=name)) - if default is True: - png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/buttons/button_blue.png")) - if default is False: - png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/buttons/button_blue_off.png")) - res.append(MultiContentEntryPixmapAlphaTest(pos=(10, 5), size=(25, 25), png = png)) + num_configured_if = len(iNetwork.getConfiguredAdapters()) + if num_configured_if >= 2: + if default is True: + png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/buttons/button_blue.png")) + if default is False: + png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/buttons/button_blue_off.png")) + res.append(MultiContentEntryPixmapAlphaTest(pos=(10, 5), size=(25, 25), png = png)) if active is True: png2 = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/lock_on.png")) if active is False: @@ -43,41 +45,64 @@ def InterfaceEntryComponent(index,name,default,active ): return res -class NetworkAdapterSelection(Screen): +class NetworkAdapterSelection(Screen,HelpableScreen): def __init__(self, session): Screen.__init__(self, session) - + HelpableScreen.__init__(self) + self.wlan_errortext = _("No working wireless networkadapter found.\nPlease verify that you have attached a compatible WLAN USB Stick and your Network is configured correctly.") self.lan_errortext = _("No working local networkadapter found.\nPlease verify that you have attached a network cable and your Network is configured correctly.") + self.oktext = _("Press OK on your remote control to continue.") + self.restartLanRef = None self["ButtonBluetext"] = Label(_("Set as default Interface")) + self["ButtonBlue"] = Pixmap() self["ButtonRedtext"] = Label(_("Close")) self["introduction"] = Label(_("Press OK to edit the settings.")) self.adapters = [(iNetwork.getFriendlyAdapterName(x),x) for x in iNetwork.getAdapterList()] - + if len(self.adapters) == 0: self.onFirstExecBegin.append(self.NetworkFallback) - + + self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", + { + "cancel": (self.close, _("exit networkinterface list")), + "ok": (self.okbuttonClick, _("select interface")), + }) + + self["ColorActions"] = HelpableActionMap(self, "ColorActions", + { + "red": (self.close, _("exit networkinterface list")), + }) + + self["DefaultInterfaceAction"] = HelpableActionMap(self, "ColorActions", + { + "blue": (self.setDefaultInterface, [_("Set interface as default Interface"),_("* Only available if more then one interface is active.")] ), + }) + self.list = [] self["list"] = InterfaceList(self.list) self.updateList() - self["actions"] = ActionMap(["OkCancelActions", "ColorActions"], - { - "ok": self.okbuttonClick, - "cancel": self.close, - "blue": self.setDefaultInterface, - "red": self.close - }, -2) - + if len(self.adapters) == 1: self.onFirstExecBegin.append(self.okbuttonClick) - + self.onClose.append(self.cleanup) + def updateList(self): iNetwork.getInterfaces() self.list = [] default_gw = None - num_configured_if = len(iNetwork.configuredInterfaces) + num_configured_if = len(iNetwork.getConfiguredAdapters()) + if num_configured_if >= 2: + self["ButtonBlue"].show() + self["ButtonBluetext"].show() + self["DefaultInterfaceAction"].setEnabled(True) + else: + self["ButtonBlue"].hide() + self["ButtonBluetext"].hide() + self["DefaultInterfaceAction"].setEnabled(False) + if num_configured_if < 2 and os_path.exists("/etc/default_gw"): unlink("/etc/default_gw") @@ -86,7 +111,7 @@ class NetworkAdapterSelection(Screen): result = fp.read() fp.close() default_gw = result - + if len(self.adapters) == 0: # no interface available => display only eth0 self.list.append(InterfaceEntryComponent("eth0",iNetwork.getFriendlyAdapterName('eth0'),True,True )) else: @@ -106,24 +131,22 @@ class NetworkAdapterSelection(Screen): selection = self["list"].getCurrent() num_if = len(self.list) old_default_gw = None + num_configured_if = len(iNetwork.getConfiguredAdapters()) if os_path.exists("/etc/default_gw"): fp = open('/etc/default_gw', 'r') old_default_gw = fp.read() fp.close() - if num_if > 1 and (not old_default_gw or old_default_gw != selection[0]): + if num_configured_if > 1 and (not old_default_gw or old_default_gw != selection[0]): fp = open('/etc/default_gw', 'w+') fp.write(selection[0]) fp.close() - iNetwork.restartNetwork() - self.updateList() - elif old_default_gw and num_if < 2: + self.restartLan() + elif old_default_gw and num_configured_if < 2: unlink("/etc/default_gw") - iNetwork.restartNetwork() - self.updateList() + self.restartLan() def okbuttonClick(self): selection = self["list"].getCurrent() - print "selection",selection if selection is not None: self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetupConfiguration, selection[0]) @@ -134,25 +157,47 @@ class NetworkAdapterSelection(Screen): self.updateList() def NetworkFallback(self): - if iNetwork.configuredInterfaces.has_key('wlan0') is True: + if iNetwork.configuredNetworkAdapters.has_key('wlan0') is True: self.session.openWithCallback(self.ErrorMessageClosed, MessageBox, self.wlan_errortext, type = MessageBox.TYPE_INFO,timeout = 10) - if iNetwork.configuredInterfaces.has_key('ath0') is True: + if iNetwork.configuredNetworkAdapters.has_key('ath0') is True: self.session.openWithCallback(self.ErrorMessageClosed, MessageBox, self.wlan_errortext, type = MessageBox.TYPE_INFO,timeout = 10) else: self.session.openWithCallback(self.ErrorMessageClosed, MessageBox, self.lan_errortext, type = MessageBox.TYPE_INFO,timeout = 10) def ErrorMessageClosed(self, *ret): - if iNetwork.configuredInterfaces.has_key('wlan0') is True: + if iNetwork.configuredNetworkAdapters.has_key('wlan0') is True: self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetupConfiguration, 'wlan0') - elif iNetwork.configuredInterfaces.has_key('ath0') is True: + elif iNetwork.configuredNetworkAdapters.has_key('ath0') is True: self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetupConfiguration, 'ath0') else: self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetupConfiguration, 'eth0') -class NameserverSetup(Screen, ConfigListScreen): + def cleanup(self): + iNetwork.stopLinkStateConsole() + iNetwork.stopRestartConsole() + + def restartLan(self): + iNetwork.restartNetwork(self.restartLanDataAvail) + self.restartLanRef = self.session.openWithCallback(self.restartfinishedCB, MessageBox, _("Please wait while we configure your network..."), type = MessageBox.TYPE_INFO, enable_input = False) + + def restartLanDataAvail(self, data): + if data is True: + iNetwork.getInterfaces(self.getInterfacesDataAvail) + + def getInterfacesDataAvail(self, data): + if data is True: + self.restartLanRef.close(True) + + def restartfinishedCB(self,data): + if data is True: + self.updateList() + self.session.open(MessageBox, _("Finished configuring your network"), type = MessageBox.TYPE_INFO, timeout = 10, default = False) + + +class NameserverSetup(Screen, ConfigListScreen, HelpableScreen): def __init__(self, session): Screen.__init__(self, session) - iNetwork.getInterfaces() + HelpableScreen.__init__(self) self.backupNameserverList = iNetwork.getNameserverList()[:] print "backup-list:", self.backupNameserverList @@ -162,14 +207,19 @@ class NameserverSetup(Screen, ConfigListScreen): self["introduction"] = Label(_("Press OK to activate the settings.")) self.createConfig() - self["actions"] = ActionMap(["OkCancelActions", "ColorActions"], - { - "ok": self.ok, - "cancel": self.cancel, - "red": self.cancel, - "green": self.add, - "yellow": self.remove - }, -2) + self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", + { + "cancel": (self.cancel, _("exit nameserver configuration")), + "ok": (self.ok, _("activate current configuration")), + }) + + self["ColorActions"] = HelpableActionMap(self, "ColorActions", + { + "red": (self.cancel, _("exit nameserver configuration")), + "green": (self.add, _("add a nameserver entry")), + "yellow": (self.remove, _("remove a nameserver entry")), + }) + self.list = [] ConfigListScreen.__init__(self, self.list) @@ -222,31 +272,51 @@ class NameserverSetup(Screen, ConfigListScreen): self.createConfig() self.createSetup() -class AdapterSetup(Screen, ConfigListScreen): +class AdapterSetup(Screen, ConfigListScreen, HelpableScreen): def __init__(self, session, iface,essid=None, aplist=None): Screen.__init__(self, session) + HelpableScreen.__init__(self) self.session = session self.iface = iface self.essid = essid self.aplist = aplist self.extended = None + self.applyConfigRef = None + self.finished_cb = None + self.oktext = _("Press OK on your remote control to continue.") self.oldInterfaceState = iNetwork.getAdapterAttribute(self.iface, "up") - iNetwork.getInterfaces() - - self.createConfig() + #iNetwork.getInterfaces() - self["actions"] = NumberActionMap(["SetupActions", "ColorActions"], + self.createConfig() + + self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", + { + "cancel": (self.close, _("exit networkadapter setup menu")), + "ok": (self.ok, _("select menu entry")), + }) + + self["ColorActions"] = HelpableActionMap(self, "ColorActions", + { + "red": (self.cancel, _("exit networkadapter configuration")), + "blue": (self.KeyBlue, _("open nameserver configuration")), + }) + + self["VirtualKB"] = HelpableActionMap(self, "ColorActions", + { + "green": (self.KeyGreen, [_("open virtual keyboard input help"),_("* Only available when entering hidden ssid or network key")] ), + }) + + self["actions"] = NumberActionMap(["SetupActions"], { "ok": self.ok, - "cancel": self.cancel, - "red": self.cancel, - "blue": self.KeyBlue, }, -2) + self.list = [] ConfigListScreen.__init__(self, self.list,session = self.session) self.createSetup() self.onLayoutFinish.append(self.layoutFinished) + self.onClose.append(self.cleanup) self["DNS1text"] = Label(_("Primary DNS")) self["DNS2text"] = Label(_("Secondary DNS")) @@ -271,56 +341,81 @@ class AdapterSetup(Screen, ConfigListScreen): self["ButtonRedtext"] = Label(_("Close")) self["ButtonBlue"] = Pixmap() self["ButtonBluetext"] = Label(_("Edit DNS")) + self["ButtonGreen"] = Pixmap() + self["VKeyIcon"] = Pixmap() + self["HelpWindow"] = Pixmap() def layoutFinished(self): self["DNS1"].setText(self.primaryDNS.getText()) self["DNS2"].setText(self.secondaryDNS.getText()) if self.ipConfigEntry.getText() is not None: - self["IP"].setText(self.ipConfigEntry.getText()) + if self.ipConfigEntry.getText() == "0.0.0.0": + self["IP"].setText(_("N/A")) + else: + self["IP"].setText(self.ipConfigEntry.getText()) else: - self["IP"].setText([0,0,0,0]) - self["Mask"].setText(self.netmaskConfigEntry.getText()) + self["IP"].setText(_("N/A")) + if self.netmaskConfigEntry.getText() is not None: + if self.netmaskConfigEntry.getText() == "0.0.0.0": + self["Mask"].setText(_("N/A")) + else: + self["Mask"].setText(self.netmaskConfigEntry.getText()) + else: + self["IP"].setText(_("N/A")) if iNetwork.getAdapterAttribute(self.iface, "gateway"): - self["Gateway"].setText(self.gatewayConfigEntry.getText()) + if self.gatewayConfigEntry.getText() == "0.0.0.0": + self["Gateway"].setText(_("N/A")) + else: + self["Gateway"].setText(self.gatewayConfigEntry.getText()) else: self["Gateway"].hide() self["Gatewaytext"].hide() self["Adapter"].setText(iNetwork.getFriendlyAdapterName(self.iface)) + self["ButtonGreen"].hide() + self["VKeyIcon"].hide() + self["VirtualKB"].setEnabled(False) + self["HelpWindow"].hide() def createConfig(self): self.InterfaceEntry = None self.dhcpEntry = None self.gatewayEntry = None - self.SSIDscan = None + self.hiddenSSID = None self.wlanSSID = None - self.manualwlanSSID = None self.encryptionEnabled = None self.encryptionKey = None + self.encryptionType = None self.nwlist = None + self.encryptionlist = None + self.weplist = None self.wsconfig = None self.default = None if self.iface == "wlan0" or self.iface == "ath0" : from Plugins.SystemPlugins.WirelessLan.Wlan import wpaSupplicant,Wlan + self.w = Wlan(self.iface) self.ws = wpaSupplicant() - list = [] - list.append(_("WEP")) - list.append(_("WPA")) - list.append(_("WPA2")) + self.encryptionlist = [] + self.encryptionlist.append(("WEP", _("WEP"))) + self.encryptionlist.append(("WPA", _("WPA"))) + self.encryptionlist.append(("WPA2", _("WPA2"))) + self.encryptionlist.append(("WPA/WPA2", _("WPA or WPA2"))) + self.weplist = [] + self.weplist.append("ASCII") + self.weplist.append("HEX") if self.aplist is not None: self.nwlist = self.aplist self.nwlist.sort(key = lambda x: x[0]) else: self.nwlist = [] - self.w = None self.aps = None try: - self.w = Wlan(self.iface) self.aps = self.w.getNetworkList() if self.aps is not None: print "[NetworkSetup.py] got Accespoints!" - for ap in aps: - a = aps[ap] + print self.aps + for ap in self.aps: + a = self.aps[ap] if a['active']: if a['essid'] == "": a['essid'] = a['bssid'] @@ -330,17 +425,23 @@ class AdapterSetup(Screen, ConfigListScreen): self.nwlist.append("No Networks found") self.wsconfig = self.ws.loadConfig() - self.default = self.essid or self.wsconfig['ssid'] + if self.essid is not None: # ssid from wlan scan + self.default = self.essid + else: + self.default = self.wsconfig['ssid'] + + if "hidden..." not in self.nwlist: + self.nwlist.append("hidden...") if self.default not in self.nwlist: self.nwlist.append(self.default) - config.plugins.wlan.essidscan = NoSave(ConfigYesNo(default = self.wsconfig['ssidscan'])) - if self.wsconfig['ssidscan'] is True: - config.plugins.wlan.essid = NoSave(ConfigSelection(self.nwlist, default = self.default )) - else: - config.plugins.wlan.essid = NoSave(ConfigText(default = self.default, visible_width = 50, fixed_size = False)) + + config.plugins.wlan.essid = NoSave(ConfigSelection(self.nwlist, default = self.default )) + config.plugins.wlan.hiddenessid = NoSave(ConfigText(default = self.wsconfig['hiddenessid'], visible_width = 50, fixed_size = False)) + config.plugins.wlan.encryption.enabled = NoSave(ConfigYesNo(default = self.wsconfig['encryption'] )) - config.plugins.wlan.encryption.type = NoSave(ConfigSelection(list, default = self.wsconfig['encryption_type'] )) - config.plugins.wlan.encryption.psk = NoSave(ConfigText(default = self.wsconfig['key'], visible_width = 50, fixed_size = False)) + config.plugins.wlan.encryption.type = NoSave(ConfigSelection(self.encryptionlist, default = self.wsconfig['encryption_type'] )) + config.plugins.wlan.encryption.wepkeytype = NoSave(ConfigSelection(self.weplist, default = self.wsconfig['encryption_wepkeytype'] )) + config.plugins.wlan.encryption.psk = NoSave(ConfigPassword(default = self.wsconfig['key'], visible_width = 50, fixed_size = False)) self.activateInterfaceEntry = NoSave(ConfigYesNo(default=iNetwork.getAdapterAttribute(self.iface, "up") or False)) self.dhcpConfigEntry = NoSave(ConfigYesNo(default=iNetwork.getAdapterAttribute(self.iface, "dhcp") or False)) @@ -382,26 +483,56 @@ class AdapterSetup(Screen, ConfigListScreen): self.configStrings = p.__call__["configStrings"] else: self.configStrings = None - self.SSIDscan = getConfigListEntry(_("Automatic SSID lookup"), config.plugins.wlan.essidscan) - self.list.append(self.SSIDscan) - self.wlanSSID = getConfigListEntry(_("Network SSID"), config.plugins.wlan.essid) - self.list.append(self.wlanSSID) + if config.plugins.wlan.essid.value == 'hidden...': + self.wlanSSID = getConfigListEntry(_("Network SSID"), config.plugins.wlan.essid) + self.list.append(self.wlanSSID) + self.hiddenSSID = getConfigListEntry(_("Hidden network SSID"), config.plugins.wlan.hiddenessid) + self.list.append(self.hiddenSSID) + else: + self.wlanSSID = getConfigListEntry(_("Network SSID"), config.plugins.wlan.essid) + self.list.append(self.wlanSSID) self.encryptionEnabled = getConfigListEntry(_("Encryption"), config.plugins.wlan.encryption.enabled) self.list.append(self.encryptionEnabled) if config.plugins.wlan.encryption.enabled.value: - self.list.append(getConfigListEntry(_("Encryption Type"), config.plugins.wlan.encryption.type)) - self.encryptionKey = getConfigListEntry(_("Encryption Key"), config.plugins.wlan.encryption.psk) - self.list.append(self.encryptionKey) + self.encryptionType = getConfigListEntry(_("Encryption Type"), config.plugins.wlan.encryption.type) + self.list.append(self.encryptionType) + if config.plugins.wlan.encryption.type.value == 'WEP': + self.list.append(getConfigListEntry(_("Encryption Keytype"), config.plugins.wlan.encryption.wepkeytype)) + self.encryptionKey = getConfigListEntry(_("Encryption Key"), config.plugins.wlan.encryption.psk) + self.list.append(self.encryptionKey) + else: + self.encryptionKey = getConfigListEntry(_("Encryption Key"), config.plugins.wlan.encryption.psk) + self.list.append(self.encryptionKey) + self["config"].list = self.list self["config"].l.setList(self.list) + if not self.selectionChanged in self["config"].onSelectionChanged: + self["config"].onSelectionChanged.append(self.selectionChanged) def KeyBlue(self): self.session.openWithCallback(self.NameserverSetupClosed, NameserverSetup) + def KeyGreen(self): + if self.iface == "wlan0" or self.iface == "ath0" : + if self["config"].getCurrent() == self.hiddenSSID: + if config.plugins.wlan.essid.value == 'hidden...': + self.session.openWithCallback(self.VirtualKeyBoardSSIDCallback, VirtualKeyBoard, title = (_("Enter WLAN networkname/SSID:")), text = config.plugins.wlan.essid.value) + if self["config"].getCurrent() == self.encryptionKey: + self.session.openWithCallback(self.VirtualKeyBoardKeyCallback, VirtualKeyBoard, title = (_("Enter WLAN passphrase/key:")), text = config.plugins.wlan.encryption.psk.value) + + def VirtualKeyBoardSSIDCallback(self, callback = None): + if callback is not None and len(callback): + config.plugins.wlan.hiddenessid = NoSave(ConfigText(default = callback, visible_width = 50, fixed_size = False)) + self.createSetup() + + def VirtualKeyBoardKeyCallback(self, callback = None): + if callback is not None and len(callback): + config.plugins.wlan.encryption.psk = NoSave(ConfigPassword(default = callback, visible_width = 50, fixed_size = False)) + self.createSetup() + def newConfig(self): - print self["config"].getCurrent() if self["config"].getCurrent() == self.InterfaceEntry: self.createSetup() if self["config"].getCurrent() == self.dhcpEntry: @@ -409,15 +540,12 @@ class AdapterSetup(Screen, ConfigListScreen): if self["config"].getCurrent() == self.gatewayEntry: self.createSetup() if self.iface == "wlan0" or self.iface == "ath0" : - if self["config"].getCurrent() == self.SSIDscan: - if config.plugins.wlan.essidscan.value is True: - config.plugins.wlan.essid = NoSave(ConfigSelection(self.nwlist, default = self.default )) - else: - config.plugins.wlan.essid = NoSave(ConfigText(default = self.default, visible_width = 50, fixed_size = False)) + if self["config"].getCurrent() == self.wlanSSID: self.createSetup() if self["config"].getCurrent() == self.encryptionEnabled: self.createSetup() - + if self["config"].getCurrent() == self.encryptionType: + self.createSetup() def keyLeft(self): ConfigListScreen.keyLeft(self) self.newConfig() @@ -426,24 +554,92 @@ class AdapterSetup(Screen, ConfigListScreen): ConfigListScreen.keyRight(self) self.newConfig() + def selectionChanged(self): + current = self["config"].getCurrent() + if current == self.hiddenSSID and config.plugins.wlan.essid.value == 'hidden...': + helpwindowpos = self["HelpWindow"].getPosition() + if current[1].help_window.instance is not None: + current[1].help_window.instance.move(ePoint(helpwindowpos[0],helpwindowpos[1])) + self["ButtonGreen"].show() + self["VKeyIcon"].show() + self["VirtualKB"].setEnabled(True) + elif current == self.encryptionKey and config.plugins.wlan.encryption.enabled.value: + helpwindowpos = self["HelpWindow"].getPosition() + if current[1].help_window.instance is not None: + current[1].help_window.instance.move(ePoint(helpwindowpos[0],helpwindowpos[1])) + self["ButtonGreen"].show() + self["VKeyIcon"].show() + self["VirtualKB"].setEnabled(True) + else: + self["ButtonGreen"].hide() + self["VKeyIcon"].hide() + self["VirtualKB"].setEnabled(False) + def ok(self): - iNetwork.setAdapterAttribute(self.iface, "up", self.activateInterfaceEntry.value) - iNetwork.setAdapterAttribute(self.iface, "dhcp", self.dhcpConfigEntry.value) - iNetwork.setAdapterAttribute(self.iface, "ip", self.ipConfigEntry.value) - iNetwork.setAdapterAttribute(self.iface, "netmask", self.netmaskConfigEntry.value) - if self.hasGatewayConfigEntry.value: - iNetwork.setAdapterAttribute(self.iface, "gateway", self.gatewayConfigEntry.value) + current = self["config"].getCurrent() + if current == self.hiddenSSID and config.plugins.wlan.essid.value == 'hidden...': + if current[1].help_window.instance is not None: + current[1].help_window.instance.hide() + elif current == self.encryptionKey and config.plugins.wlan.encryption.enabled.value: + if current[1].help_window.instance is not None: + current[1].help_window.instance.hide() + self.session.openWithCallback(self.applyConfig, MessageBox, (_("Are you sure you want to activate this network configuration?\n\n") + self.oktext ) ) + + def applyConfig(self, ret = False): + if (ret == True): + iNetwork.setAdapterAttribute(self.iface, "up", self.activateInterfaceEntry.value) + iNetwork.setAdapterAttribute(self.iface, "dhcp", self.dhcpConfigEntry.value) + iNetwork.setAdapterAttribute(self.iface, "ip", self.ipConfigEntry.value) + iNetwork.setAdapterAttribute(self.iface, "netmask", self.netmaskConfigEntry.value) + if self.hasGatewayConfigEntry.value: + iNetwork.setAdapterAttribute(self.iface, "gateway", self.gatewayConfigEntry.value) + else: + iNetwork.removeAdapterAttribute(self.iface, "gateway") + if self.extended is not None and self.configStrings is not None: + iNetwork.setAdapterAttribute(self.iface, "configStrings", self.configStrings(self.iface)) + self.ws.writeConfig() + if self.activateInterfaceEntry.value is False: + iNetwork.deactivateInterface(self.iface) + iNetwork.writeNetworkConfig() + iNetwork.restartNetwork(self.applyConfigDataAvail) + self.applyConfigRef = self.session.openWithCallback(self.applyConfigfinishedCB, MessageBox, _("Please wait while activating your network configuration..."), type = MessageBox.TYPE_INFO, enable_input = False) else: - iNetwork.removeAdapterAttribute(self.iface, "gateway") - if self.extended is not None and self.configStrings is not None: - iNetwork.setAdapterAttribute(self.iface, "configStrings", self.configStrings(self.iface)) - self.ws.writeConfig() - if self.activateInterfaceEntry.value is False: - iNetwork.deactivateInterface(self.iface) - iNetwork.writeNetworkConfig() - iNetwork.deactivateNetworkConfig() - iNetwork.activateNetworkConfig() - self.close() + self.cancel() + + def applyConfigDataAvail(self, data): + if data is True: + iNetwork.getInterfaces(self.getInterfacesDataAvail) + + def getInterfacesDataAvail(self, data): + if data is True: + self.applyConfigRef.close(True) + + def applyConfigfinishedCB(self,data): + if data is True: + num_configured_if = len(iNetwork.getConfiguredAdapters()) + if num_configured_if >= 2: + self.session.openWithCallback(self.secondIfaceFoundCB, MessageBox, _("Your network configuration has been activated.\nA second configured interface has been found.\n\nDo you want to disable the second networkinterface?"), default = True) + else: + if self.finished_cb: + self.session.openWithCallback(self.finished_cb, MessageBox, _("Your network configuration has been activated."), type = MessageBox.TYPE_INFO, timeout = 10) + else: + self.session.openWithCallback(self.ConfigfinishedCB, MessageBox, _("Your network configuration has been activated."), type = MessageBox.TYPE_INFO, timeout = 10) + + def secondIfaceFoundCB(self,data): + if data is False: + self.close('ok') + else: + configuredInterfaces = configuredNetworkAdapters + for interface in configuredInterfaces: + if interface == self.iface: + continue + iNetwork.setAdapterAttribute(interface, "up", False) + iNetwork.deactivateInterface(interface) + self.applyConfig(True) + + def ConfigfinishedCB(self,data): + if data is True: + self.close('ok') def cancel(self): iNetwork.setAdapterAttribute(self.iface, "up", self.oldInterfaceState) @@ -451,11 +647,12 @@ class AdapterSetup(Screen, ConfigListScreen): if self.activateInterfaceEntry.value is False: iNetwork.deactivateInterface(self.iface) iNetwork.getInterfaces() - self.close() + self.close('cancel') - def run(self): + def runAsync(self, finished_cb): + self.finished_cb = finished_cb self.ok() - + def NameserverSetupClosed(self, *ret): iNetwork.loadNameserverConfig() nameserver = (iNetwork.getNameserverList() + [[0,0,0,0]] * 2)[0:2] @@ -463,13 +660,18 @@ class AdapterSetup(Screen, ConfigListScreen): self.secondaryDNS = NoSave(ConfigIP(default=nameserver[1])) self.createSetup() self.layoutFinished() - + + def cleanup(self): + iNetwork.stopLinkStateConsole() + iNetwork.stopRestartConsole() -class AdapterSetupConfiguration(Screen): +class AdapterSetupConfiguration(Screen, HelpableScreen): def __init__(self, session,iface): Screen.__init__(self, session) + HelpableScreen.__init__(self) self.session = session self.iface = iface + self.restartLanRef = None self.mainmenu = self.genMainMenu() self["menulist"] = MenuList(self.mainmenu) self["description"] = Label() @@ -485,8 +687,27 @@ class AdapterSetupConfiguration(Screen): self.oktext = _("Press OK on your remote control to continue.") self.reboottext = _("Your Dreambox will restart after pressing OK on your remote control.") - self.errortext = _("No working wireless interface found.\n Please verify that you have attached a compatible WLAN device or enable your local network interface.") + self.errortext = _("No working wireless interface found.\n Please verify that you have attached a compatible WLAN device or enable you local network interface.") + + self["WizardActions"] = HelpableActionMap(self, "WizardActions", + { + "up": (self.up, _("move up to previous entry")), + "down": (self.down, _("move down to next entry")), + "left": (self.left, _("move up to first entry")), + "right": (self.right, _("move down to last entry")), + }) + self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", + { + "cancel": (self.close, _("exit networkadapter setup menu")), + "ok": (self.ok, _("select menu entry")), + }) + + self["ColorActions"] = HelpableActionMap(self, "ColorActions", + { + "red": (self.close, _("exit networkadapter setup menu")), + }) + self["actions"] = NumberActionMap(["WizardActions","ShortcutActions"], { "ok": self.ok, @@ -498,9 +719,10 @@ class AdapterSetupConfiguration(Screen): "right": self.right, }, -2) - iNetwork.getInterfaces() + iNetwork.getInterfaces(self.updateStatusbar) self.onLayoutFinish.append(self.layoutFinished) - self.updateStatusbar() + self.onClose.append(self.cleanup) + self.onHide.append(self.cleanup) def ok(self): if self["menulist"].getCurrent()[1] == 'edit': @@ -549,7 +771,6 @@ class AdapterSetupConfiguration(Screen): self.wlanresponse = ifobj.getStatistics() if self.wlanresponse[0] != 19: self.session.openWithCallback(self.AdapterSetupClosed, WlanStatus,self.iface) - #self.session.open(WlanStatus,self.iface) else: # Display Wlan not available Message self.showErrorMessage() @@ -584,6 +805,7 @@ class AdapterSetupConfiguration(Screen): self.loadDescription() def loadDescription(self): + print self["menulist"].getCurrent()[1] if self["menulist"].getCurrent()[1] == 'edit': self["description"].setText(_("Edit the network configuration of your Dreambox.\n" ) + self.oktext ) if self["menulist"].getCurrent()[1] == 'test': @@ -601,7 +823,7 @@ class AdapterSetupConfiguration(Screen): if self["menulist"].getCurrent()[1][0] == 'extendedSetup': self["description"].setText(_(self["menulist"].getCurrent()[1][1]) + self.oktext ) - def updateStatusbar(self): + def updateStatusbar(self, data = None): self["IFtext"].setText(_("Network:")) self["IF"].setText(iNetwork.getFriendlyAdapterName(self.iface)) self["Statustext"].setText(_("Link:")) @@ -661,21 +883,52 @@ class AdapterSetupConfiguration(Screen): return menu def AdapterSetupClosed(self, *ret): - self.mainmenu = self.genMainMenu() - self["menulist"].l.setList(self.mainmenu) - iNetwork.getInterfaces() - self.updateStatusbar() + if ret is not None and len(ret): + if ret[0] == 'ok' and (self.iface == 'wlan0' or self.iface == 'ath0') and iNetwork.getAdapterAttribute(self.iface, "up") is True: + try: + from Plugins.SystemPlugins.WirelessLan.plugin import WlanStatus + from Plugins.SystemPlugins.WirelessLan.iwlibs import Wireless + except ImportError: + self.session.open(MessageBox, _("The wireless LAN plugin is not installed!\nPlease install it."), type = MessageBox.TYPE_INFO,timeout = 10 ) + else: + ifobj = Wireless(self.iface) # a Wireless NIC Object + self.wlanresponse = ifobj.getStatistics() + if self.wlanresponse[0] != 19: + self.session.openWithCallback(self.AdapterSetupClosed, WlanStatus,self.iface) + else: + # Display Wlan not available Message + self.showErrorMessage() + else: + self.mainmenu = self.genMainMenu() + self["menulist"].l.setList(self.mainmenu) + iNetwork.getInterfaces(self.updateStatusbar) + else: + self.mainmenu = self.genMainMenu() + self["menulist"].l.setList(self.mainmenu) + iNetwork.getInterfaces(self.updateStatusbar) def WlanScanClosed(self,*ret): if ret[0] is not None: self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface,ret[0],ret[1]) else: - self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface,None,ret[0]) - + self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface,None,None) def restartLan(self, ret = False): if (ret == True): - iNetwork.restartNetwork() + iNetwork.restartNetwork(self.restartLanDataAvail) + self.restartLanRef = self.session.openWithCallback(self.restartfinishedCB, MessageBox, _("Please wait while your network is restarting..."), type = MessageBox.TYPE_INFO, enable_input = False) + + def restartLanDataAvail(self, data): + if data is True: + iNetwork.getInterfaces(self.getInterfacesDataAvail) + + def getInterfacesDataAvail(self, data): + if data is True: + self.restartLanRef.close(True) + + def restartfinishedCB(self,data): + if data is True: + self.session.open(MessageBox, _("Finished restarting your network"), type = MessageBox.TYPE_INFO, timeout = 10, default = False) def getLinkState(self,iface): iNetwork.getLinkState(iface,self.dataAvail) @@ -693,12 +946,16 @@ class AdapterSetupConfiguration(Screen): def showErrorMessage(self): self.session.open(MessageBox, self.errortext, type = MessageBox.TYPE_INFO,timeout = 10 ) + + def cleanup(self): + iNetwork.stopLinkStateConsole() class NetworkAdapterTest(Screen): def __init__(self, session,iface): Screen.__init__(self, session) self.iface = iface + self.oldInterfaceState = iNetwork.getAdapterAttribute(self.iface, "up") iNetwork.getInterfaces() self.setLabels() @@ -713,8 +970,8 @@ class NetworkAdapterTest(Screen): self["shortcuts"] = ActionMap(["ShortcutActions","WizardActions"], { - "red": self.close, - "back": self.close, + "red": self.cancel, + "back": self.cancel, }, -2) self["infoshortcuts"] = ActionMap(["ShortcutActions","WizardActions"], { @@ -745,6 +1002,12 @@ class NetworkAdapterTest(Screen): self.nextStepTimer = eTimer() self.nextStepTimer.callback.append(self.nextStepTimerFire) + def cancel(self): + if self.oldInterfaceState is False: + iNetwork.setAdapterAttribute(self.iface, "up", self.oldInterfaceState) + iNetwork.deactivateInterface(self.iface) + self.close() + def closeInfo(self): self["shortcuts"].setEnabled(True) self["infoshortcuts"].setEnabled(False) @@ -874,48 +1137,15 @@ class NetworkAdapterTest(Screen): def doStep5(self): self["IPtext"].setForegroundColorNum(1) - ret = iNetwork.checkNetworkState() - if ret == True: - self["IP"].setForegroundColorNum(2) - self["IP"].setText(_("confirmed")) - self["IPInfo_Check"].setPixmapNum(0) - else: - self["IP"].setForegroundColorNum(1) - self["IP"].setText(_("unconfirmed")) - self["IPInfo_Check"].setPixmapNum(1) - self["IPInfo_Check"].show() - self["IPInfo_Text"].setForegroundColorNum(1) - self.steptimer = True - self.nextStepTimer.start(3000) + self["IP"].setText(_("Please wait...")) + iNetwork.checkNetworkState(self.NetworkStatedataAvail) def doStep6(self): self.steptimer = False self.nextStepTimer.stop() self["DNStext"].setForegroundColorNum(1) - ret = iNetwork.checkDNSLookup() - if ret == True: - self["DNS"].setForegroundColorNum(2) - self["DNS"].setText(_("confirmed")) - self["DNSInfo_Check"].setPixmapNum(0) - else: - self["DNS"].setForegroundColorNum(1) - self["DNS"].setText(_("unconfirmed")) - self["DNSInfo_Check"].setPixmapNum(1) - self["DNSInfo_Check"].show() - self["DNSInfo_Text"].setForegroundColorNum(1) - - self["EditSettings_Text"].show() - self["EditSettingsButton"].setPixmapNum(1) - self["EditSettings_Text"].setForegroundColorNum(2) # active - self["EditSettingsButton"].show() - self["ButtonYellow_Check"].setPixmapNum(1) - self["ButtonGreentext"].setText(_("Restart test")) - self["ButtonGreen_Check"].setPixmapNum(0) - self["shortcutsgreen"].setEnabled(False) - self["shortcutsgreen_restart"].setEnabled(True) - self["shortcutsyellow"].setEnabled(False) - self["updown_actions"].setEnabled(True) - self.activebutton = 6 + self["DNS"].setText(_("Please wait...")) + iNetwork.checkDNSLookup(self.DNSLookupdataAvail) def KeyGreen(self): self["shortcutsgreen"].setEnabled(False) @@ -1076,9 +1306,9 @@ class NetworkAdapterTest(Screen): self["NetworkInfo_Check"].setPixmapNum(1) self["NetworkInfo_Check"].show() else: - iNetwork.getLinkState(iface,self.dataAvail) + iNetwork.getLinkState(iface,self.LinkStatedataAvail) - def dataAvail(self,data): + def LinkStatedataAvail(self,data): self.output = data.strip() result = self.output.split('\n') pattern = re_compile("Link detected: yes") @@ -1093,4 +1323,44 @@ class NetworkAdapterTest(Screen): self["NetworkInfo_Check"].setPixmapNum(1) self["NetworkInfo_Check"].show() - + def NetworkStatedataAvail(self,data): + print "DATA",data + if data <= 2: + self["IP"].setForegroundColorNum(2) + self["IP"].setText(_("confirmed")) + self["IPInfo_Check"].setPixmapNum(0) + else: + self["IP"].setForegroundColorNum(1) + self["IP"].setText(_("unconfirmed")) + self["IPInfo_Check"].setPixmapNum(1) + self["IPInfo_Check"].show() + self["IPInfo_Text"].setForegroundColorNum(1) + self.steptimer = True + self.nextStepTimer.start(3000) + + def DNSLookupdataAvail(self,data): + print "DATA",data + if data <= 2: + self["DNS"].setForegroundColorNum(2) + self["DNS"].setText(_("confirmed")) + self["DNSInfo_Check"].setPixmapNum(0) + else: + self["DNS"].setForegroundColorNum(1) + self["DNS"].setText(_("unconfirmed")) + self["DNSInfo_Check"].setPixmapNum(1) + self["DNSInfo_Check"].show() + self["DNSInfo_Text"].setForegroundColorNum(1) + self["EditSettings_Text"].show() + self["EditSettingsButton"].setPixmapNum(1) + self["EditSettings_Text"].setForegroundColorNum(2) # active + self["EditSettingsButton"].show() + self["ButtonYellow_Check"].setPixmapNum(1) + self["ButtonGreentext"].setText(_("Restart test")) + self["ButtonGreen_Check"].setPixmapNum(0) + self["shortcutsgreen"].setEnabled(False) + self["shortcutsgreen_restart"].setEnabled(True) + self["shortcutsyellow"].setEnabled(False) + self["updown_actions"].setEnabled(True) + self.activebutton = 6 + + \ No newline at end of file diff --git a/lib/python/Screens/VirtualKeyBoard.py b/lib/python/Screens/VirtualKeyBoard.py new file mode 100755 index 00000000..53970ab8 --- /dev/null +++ b/lib/python/Screens/VirtualKeyBoard.py @@ -0,0 +1,287 @@ +# -*- coding: iso-8859-1 -*- +from Components.Language import language +from Components.ActionMap import ActionMap +from Components.Label import Label +from Components.Pixmap import Pixmap +from Components.MenuList import MenuList +from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest +from enigma import eListboxPythonMultiContent, gFont, loadPNG, RT_HALIGN_CENTER, RT_VALIGN_CENTER +from Screen import Screen +from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE + +key_backspace = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/vkey_backspace.png")) +key_bg = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/vkey_bg.png")) +key_clr = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/vkey_clr.png")) +key_esc = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/vkey_esc.png")) +key_ok = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/vkey_ok.png")) +key_sel = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/vkey_sel.png")) +key_shift = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/vkey_shift.png")) +key_shift_sel = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/vkey_shift_sel.png")) +key_space = loadPNG(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/vkey_space.png")) + +class VirtualKeyBoardList(MenuList): + def __init__(self, list, enableWrapAround=False): + MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent) + self.l.setFont(0, gFont("Regular", 22)) + self.l.setItemHeight(45) + +def VirtualKeyBoardEntryComponent(keys, selectedKey,shiftMode=False): + res = [ (keys) ] + + x = 0 + count = 0 + if shiftMode: + shiftkey_png = key_shift_sel + else: + shiftkey_png = key_shift + for key in keys: + if key == "EXIT": + res.append(MultiContentEntryPixmapAlphaTest(pos=(x, 0), size=(45, 45), png=key_esc)) + elif key == "BACKSPACE": + res.append(MultiContentEntryPixmapAlphaTest(pos=(x, 0), size=(45, 45), png=key_backspace)) + elif key == "CLEAR": + res.append(MultiContentEntryPixmapAlphaTest(pos=(x, 0), size=(45, 45), png=key_clr)) + elif key == "SHIFT": + res.append(MultiContentEntryPixmapAlphaTest(pos=(x, 0), size=(45, 45), png=shiftkey_png)) + elif key == "SPACE": + res.append(MultiContentEntryPixmapAlphaTest(pos=(x, 0), size=(45, 45), png=key_space)) + elif key == "OK": + res.append(MultiContentEntryPixmapAlphaTest(pos=(x, 0), size=(45, 45), png=key_ok)) + #elif key == "<-": + # res.append(MultiContentEntryPixmapAlphaTest(pos=(x, 0), size=(45, 45), png=key_left)) + #elif key == "->": + # res.append(MultiContentEntryPixmapAlphaTest(pos=(x, 0), size=(45, 45), png=key_right)) + + else: + res.append(MultiContentEntryPixmapAlphaTest(pos=(x, 0), size=(45, 45), png=key_bg)) + res.append(MultiContentEntryText(pos=(x, 0), size=(45, 45), font=0, text=key.encode("utf-8"), flags=RT_HALIGN_CENTER | RT_VALIGN_CENTER)) + + if selectedKey == count: + res.append(MultiContentEntryPixmapAlphaTest(pos=(x, 0), size=(45, 45), png=key_sel)) + + x += 45 + count += 1 + + return res + + +class VirtualKeyBoard(Screen): + + def __init__(self, session, title="", text=""): + Screen.__init__(self, session) + self.keys_list = [] + self.shiftkeys_list = [] + self.lang = language.getLanguage() + if self.lang == 'de_DE': + self.keys_list = [ + [u"EXIT", u"1", u"2", u"3", u"4", u"5", u"6", u"7", u"8", u"9", u"0", u"BACKSPACE"], + [u"q", u"w", u"e", u"r", u"t", u"z", u"u", u"i", u"o", u"p", u"ü", u"+"], + [u"a", u"s", u"d", u"f", u"g", u"h", u"j", u"k", u"l", u"ö", u"ä", u"#"], + [u"<", u"y", u"x", u"c", u"v", u"b", u"n", u"m", u",", ".", u"-", u"CLEAR"], + [u"SHIFT", u"SPACE", u"@", u"ß", u"OK"]] + + self.shiftkeys_list = [ + [u"EXIT", u"!", u'"', u"§", u"$", u"%", u"&", u"/", u"(", u")", u"=", u"BACKSPACE"], + [u"Q", u"W", u"E", u"R", u"T", u"Z", u"U", u"I", u"O", u"P", u"Ü", u"*"], + [u"A", u"S", u"D", u"F", u"G", u"H", u"J", u"K", u"L", u"Ö", u"Ä", u"'"], + [u">", u"Y", u"X", u"C", u"V", u"B", u"N", u"M", u";", u":", u"_", u"CLEAR"], + [u"SHIFT", u"SPACE", u"?", u"\\", u"OK"]] + + elif self.lang == 'es_ES': + #still missing keys (u"ùÙ") + self.keys_list = [ + [u"EXIT", u"1", u"2", u"3", u"4", u"5", u"6", u"7", u"8", u"9", u"0", u"BACKSPACE"], + [u"q", u"w", u"e", u"r", u"t", u"z", u"u", u"i", u"o", u"p", u"ú", u"+"], + [u"a", u"s", u"d", u"f", u"g", u"h", u"j", u"k", u"l", u"ó", u"á", u"#"], + [u"<", u"y", u"x", u"c", u"v", u"b", u"n", u"m", u",", ".", u"-", u"CLEAR"], + [u"SHIFT", u"SPACE", u"@", u"£", u"à", u"é", u"è", u"í", u"ì", u"ñ", u"ò", u"OK"]] + + self.shiftkeys_list = [ + [u"EXIT", u"!", u'"', u"§", u"$", u"%", u"&", u"/", u"(", u")", u"=", u"BACKSPACE"], + [u"Q", u"W", u"E", u"R", u"T", u"Z", u"U", u"I", u"O", u"P", u"Ú", u"*"], + [u"A", u"S", u"D", u"F", u"G", u"H", u"J", u"K", u"L", u"Ó", u"Á", u"'"], + [u">", u"Y", u"X", u"C", u"V", u"B", u"N", u"M", u";", u":", u"_", u"CLEAR"], + [u"SHIFT", u"SPACE", u"?", u"\\", u"À", u"É", u"È", u"Í", u"Ì", u"Ñ", u"Ò", u"OK"]] + + elif self.lang in ['sv_SE', 'fi_FI']: + self.keys_list = [ + [u"EXIT", u"1", u"2", u"3", u"4", u"5", u"6", u"7", u"8", u"9", u"0", u"BACKSPACE"], + [u"q", u"w", u"e", u"r", u"t", u"z", u"u", u"i", u"o", u"p", u"é", u"+"], + [u"a", u"s", u"d", u"f", u"g", u"h", u"j", u"k", u"l", u"ö", u"ä", u"#"], + [u"<", u"y", u"x", u"c", u"v", u"b", u"n", u"m", u",", ".", u"-", u"CLEAR"], + [u"SHIFT", u"SPACE", u"@", u"ß", u"å", u"OK"]] + + self.shiftkeys_list = [ + [u"EXIT", u"!", u'"', u"§", u"$", u"%", u"&", u"/", u"(", u")", u"=", u"BACKSPACE"], + [u"Q", u"W", u"E", u"R", u"T", u"Z", u"U", u"I", u"O", u"P", u"É", u"*"], + [u"A", u"S", u"D", u"F", u"G", u"H", u"J", u"K", u"L", u"Ö", u"Ä", u"'"], + [u">", u"Y", u"X", u"C", u"V", u"B", u"N", u"M", u";", u":", u"_", u"CLEAR"], + [u"SHIFT", u"SPACE", u"?", u"\\", u"Å", u"OK"]] + else: + self.keys_list = [ + [u"EXIT", u"1", u"2", u"3", u"4", u"5", u"6", u"7", u"8", u"9", u"0", u"BACKSPACE"], + [u"q", u"w", u"e", u"r", u"t", u"z", u"u", u"i", u"o", u"p", u"+", u"@"], + [u"a", u"s", u"d", u"f", u"g", u"h", u"j", u"k", u"l", u"#", u"\\"], + [u"<", u"y", u"x", u"c", u"v", u"b", u"n", u"m", u",", ".", u"-", u"CLEAR"], + [u"SHIFT", u"SPACE", u"OK"]] + + self.shiftkeys_list = [ + [u"EXIT", u"!", u'"', u"§", u"$", u"%", u"&", u"/", u"(", u")", u"=", u"BACKSPACE"], + [u"Q", u"W", u"E", u"R", u"T", u"Z", u"U", u"I", u"O", u"P", u"*"], + [u"A", u"S", u"D", u"F", u"G", u"H", u"J", u"K", u"L", u"'", u"?"], + [u">", u"Y", u"X", u"C", u"V", u"B", u"N", u"M", u";", u":", u"_", u"CLEAR"], + [u"SHIFT", u"SPACE", u"OK"]] + + self.shiftMode = False + self.text = text + self.selectedKey = 0 + + self["header"] = Label(title) + self["text"] = Label(self.text) + self["list"] = VirtualKeyBoardList([]) + + self["actions"] = ActionMap(["OkCancelActions", "WizardActions", "ColorActions"], + { + "ok": self.okClicked, + "cancel": self.exit, + "left": self.left, + "right": self.right, + "up": self.up, + "down": self.down, + "red": self.backClicked, + "green": self.ok + }, -2) + + self.onLayoutFinish.append(self.buildVirtualKeyBoard) + + def buildVirtualKeyBoard(self, selectedKey=0): + list = [] + + if self.shiftMode: + self.k_list = self.shiftkeys_list + for keys in self.k_list: + if selectedKey < 12 and selectedKey > -1: + list.append(VirtualKeyBoardEntryComponent(keys, selectedKey,True)) + else: + list.append(VirtualKeyBoardEntryComponent(keys, -1,True)) + selectedKey -= 12 + else: + self.k_list = self.keys_list + for keys in self.k_list: + if selectedKey < 12 and selectedKey > -1: + list.append(VirtualKeyBoardEntryComponent(keys, selectedKey)) + else: + list.append(VirtualKeyBoardEntryComponent(keys, -1)) + selectedKey -= 12 + + self["list"].setList(list) + + + def backClicked(self): + self.text = self["text"].getText()[:-1] + self["text"].setText(self.text) + + def okClicked(self): + if self.shiftMode: + list = self.shiftkeys_list + else: + list = self.keys_list + + selectedKey = self.selectedKey + + for x in list: + if selectedKey < 12: + text = x[selectedKey] + break + else: + selectedKey -= 12 + + text = text.encode("utf-8") + + if text == "EXIT": + self.close(None) + + elif text == "BACKSPACE": + self.text = self["text"].getText()[:-1] + self["text"].setText(self.text) + + elif text == "CLEAR": + self.text = "" + self["text"].setText(self.text) + + elif text == "SHIFT": + if self.shiftMode: + self.shiftMode = False + else: + self.shiftMode = True + + self.buildVirtualKeyBoard(self.selectedKey) + + elif text == "SPACE": + self.text += " " + self["text"].setText(self.text) + + elif text == "OK": + self.close(self["text"].getText()) + + else: + self.text = self["text"].getText() + self.text += text + self["text"].setText(self.text) + + def ok(self): + self.close(self["text"].getText()) + + def exit(self): + self.close(None) + + def left(self): + self.selectedKey -= 1 + + if self.selectedKey == -1: + self.selectedKey = 11 + elif self.selectedKey == 11: + self.selectedKey = 23 + elif self.selectedKey == 23: + self.selectedKey = 35 + elif self.selectedKey == 35: + self.selectedKey = 47 + elif self.selectedKey == 47: + self.selectedKey = 59 + + self.showActiveKey() + + def right(self): + self.selectedKey += 1 + + if self.selectedKey == 12: + self.selectedKey = 0 + elif self.selectedKey == 24: + self.selectedKey = 12 + elif self.selectedKey == 36: + self.selectedKey = 24 + elif self.selectedKey == 48: + self.selectedKey = 36 + elif self.selectedKey == 60: + self.selectedKey = 48 + + self.showActiveKey() + + def up(self): + self.selectedKey -= 12 + + if self.selectedKey < 0: + self.selectedKey += 60 + + self.showActiveKey() + + def down(self): + self.selectedKey += 12 + + if self.selectedKey > 59: + self.selectedKey -= 60 + + self.showActiveKey() + + def showActiveKey(self): + self.buildVirtualKeyBoard(self.selectedKey) -- 2.30.2